Documentation updates; almost done updating everything for 0.83

slava 2006-06-06 19:54:07 +00:00
parent d92a955283
commit bc3cafbcd9
24 changed files with 310 additions and 216 deletions

View File

@ -1,3 +1,5 @@
- in the ui, run a bunch of files, unfocus; when its done caret appears
- fix this:
[ 1 2 3 4 5 6 7 8 9 10 10 10 10 10 10 10 10 10 10 11 11 11 113 ] .

View File

@ -1,135 +1,52 @@
USING: hashtables hashtables-internals help io-internals kernel
kernel-internals namespaces queues ;
USING: graphs hashtables hashtables-internals help io-internals
kernel kernel-internals namespaces queues ;
ARTICLE: "collections" "Collections"
"Classical data structures:"
{ $subsection "sequences" }
{ $subsection "queues" }
{ $subsection "hashtables" }
"An abstraction on hashtables:"
{ $subsection "namespaces" }
"Special-purpose data structures:"
{ $subsection "queues" }
{ $subsection "graphs" }
"A low-level facility:"
{ $subsection "buffers" } ;
ARTICLE: "queues" "Queues"
"A simple last-in-first-out queue data structure."
"Last-in-first-out queues can be found in the " { $snippet "queues" } " vocabulary."
{ $subsection queue? }
{ $subsection <queue> }
{ $subsection queue-empty? }
{ $subsection deque }
{ $subsection enque }
{ $subsection deque } ;
"An example:"
{ $snippet
"<queue> \"q\" set"
"5 \"q\" get enque"
"3 \"q\" get enque"
"7 \"q\" get enque"
"\"q\" get deque ."
" 5"
"\"q\" get deque ."
" 3"
"\"q\" get deque ."
" 7"
} ;
ARTICLE: "hashtables" "Hashtables"
"A hashtable provides efficient (expected constant time) lookup and storage of key/value pairs. Keys are compared for equality, and a hashing function is used to reduce the number of comparisons made."
ARTICLE: "graphs" "Directed graphs"
"A minimalist directed graph data type can be found in the " { $snippet "graphs" } " vocabulary. A directed graph is represented as a hashtable mapping each vertex to a set of edges entering that vertex, where the set is represented as a hashtable with equal keys and values."
$terpri
"Hashtable words are in the " { $snippet "hashtables" } " vocabulary. Unsafe implementation words are in the " { $snippet "hashtables-internals" } " vocabulary."
$terpri
"Hashtables form a class of objects."
{ $subsection hashcode }
{ $subsection hashtable? }
{ $subsection <hashtable> }
"There are some primitive operations on hashes, and many utilities."
{ $subsection "hashtables-lookup" }
{ $subsection "hashtables-mutation" }
{ $subsection "hashtables-combinators" }
{ $subsection "hashtables-utilities" }
{ $subsection "hashtables-internals" } ;
ARTICLE: "hashtables-lookup" "Looking up keys in hashtables"
{ $subsection hash }
{ $subsection hash* }
{ $subsection ?hash }
{ $subsection ?hash* }
{ $subsection hash-member? } ;
ARTICLE: "hashtables-mutation" "Storing keys in hashtables"
{ $subsection set-hash }
{ $subsection remove-hash }
{ $subsection clear-hash } ;
ARTICLE: "hashtables-combinators" "Hashtable combinators"
"We have the standard functional programming idioms."
{ $subsection hash-each }
{ $subsection hash-all? }
{ $subsection hash-subset }
"There are curried forms of the above."
{ $subsection hash-each-with }
{ $subsection hash-all-with? }
{ $subsection hash-subset-with }
"Two oddball combinators."
{ $subsection cache }
{ $subsection map>hash } ;
ARTICLE: "hashtables-utilities" "Hashtable utilities"
"Set-theoretic operations exploit the expected constant lookup time of a hashtable."
{ $subsection hash-intersect }
{ $subsection hash-diff }
{ $subsection hash-union }
{ $subsection hash-concat }
{ $subsection hash-update }
{ $subsection remove-all }
"A combinator used to implement notions of nested scope. This includes various fundamental abstractions like variables, vocabulary search and cascading styles."
{ $subsection hash-stack } ;
ARTICLE: "hashtables-internals" "Hashtable implementation details"
"This hashtable implementation uses only one auxilliary array in addition to the hashtable tuple itself. The array stores keys in even slots and values in odd slots. Values are looked up with a hashing strategy that uses linear probing to resolve collisions."
{ $terpri }
"There are two special objects: the " { $link ((tombstone)) } " marker and the " { $link ((empty)) } " marker. Neither of these markers can be used as hashtable keys."
{ $terpri }
"The " { $link hash-count } " slot is the number of entries including deleted entries, and " { $link hash-deleted } " is the number of deleted entries."
{ $subsection <hash-array> }
{ $subsection nth-pair }
{ $subsection set-nth-pair }
{ $subsection each-pair }
{ $subsection all-pairs? } ;
ARTICLE: "namespaces" "Variables and namespaces"
"A variable is an entry in a hashtable of bindings, with the hashtable being implicit rather than passed on the stack. These hashtables are termed " { $emphasis "namespaces" } ". Nesting of scopes is implemented with a search order on namespaces, defined by a " { $emphasis "namestack" } ". Since namespaces are just hashtables, any object can be used as a variable, however by convention, variables are keyed by symbols (see " { $link "symbols" } ")."
$terpri
"The " { $snippet "get" } " and " { $snippet "set" } " words read and write variable values. The " { $snippet "get" } " word searches up the chain of nested namespaces, while " { $snippet "set" } " always sets variable values in the current namespace only. Namespaces are dynamically scoped; when a quotation is called from a nested scope, any words called by the quotation also execute in that scope."
{ $subsection get }
{ $subsection set }
"Various utility words abstract away common variable access patterns:"
{ $subsection "namespaces-change" }
{ $subsection "namespaces-combinators" }
{ $subsection "namespaces-utilities" }
"A useful facility for constructing sequences by holding an accumulator sequence in a variable:"
{ $subsection "namespaces-make" }
"Implementation details your code probably does not care about:"
{ $subsection "namespaces-internals" } ;
ARTICLE: "namespaces-combinators" "Namespace combinators"
{ $subsection make-hash }
{ $subsection with-scope }
{ $subsection bind } ;
ARTICLE: "namespaces-change" "Ways to change variable values"
{ $subsection on }
{ $subsection off }
{ $subsection inc }
{ $subsection dec }
{ $subsection change } ;
ARTICLE: "namespaces-utilities" "Namespace utilities"
{ $subsection namespace }
{ $subsection nest }
{ $subsection global }
{ $subsection set-global } ;
ARTICLE: "namespaces-make" "Constructing sequences"
"There is a lexicon of words for constructing sequences without passing the partial sequence being built on the stack. This reduces stack noise."
{ $subsection make }
{ $subsection , }
{ $subsection % }
{ $subsection # } ;
ARTICLE: "namespaces-internals" "Namespace implementation details"
"The namestack holds namespaces."
{ $subsection namestack }
{ $subsection set-namestack }
"A pair of words push and pop namespaces on the namestack."
{ $subsection >n }
{ $subsection n> } ;
"To create a new graph, just call " { $link <hashtable> } " or construct a hashtable by some other means. To add vertices and edges to a graph:"
{ $subsection add-vertex }
{ $subsection build-graph }
"To remove vertices from the graph:"
{ $subsection remove-vertex }
{ $subsection clear-hash }
"You can perform queries on the graph:"
{ $subsection in-edges }
{ $subsection closure }
"Directed graphs are used to maintain cross-referencing information for words (" { $link "word-crossref" } ")." ;
ARTICLE: "buffers" "Locked I/O buffers"
"I/O buffers are a circular ring structure, a fixed-size queue of characters. Their key feature is that they are backed by manually allocated storage that does not get moved by the garbage collector. They are typically used for asynchronous I/O in conjunction with the C library interface in Factor's implementation."

View File

@ -5,6 +5,7 @@ ARTICLE: "dataflow" "Data and control flow"
{ $subsection "quotations" }
{ $subsection "combinators" }
{ $subsection "conditionals" }
{ $subsection "interpreter" }
{ $subsection "continuations" } ;
ARTICLE: "shuffle-words" "Shuffle words"
@ -42,29 +43,15 @@ $terpri
} ;
ARTICLE: "quotations" "Quotations"
"A quotation is a sequence of objects, some of which may be words. When evaluating a quotation, the interpreter looks at each element in turn, and executes words while pushing other types of objects on the stack."
"Conceptually, a quotation is a snippet of code which can be passed around and called. Concretely, a quotation is a sequence of objects, some of which may be words. When evaluating a quotation, the interpreter looks at each element in turn, and executes words while pushing other types of objects on the stack. Details can be found in " { $link "interpreter" } "."
$terpri
"Quotation literal syntax is documented in " { $link "quotation-syntax" } "."
"Quotation literal syntax is documented in " { $link "syntax-quots" } "."
$terpri
"More precisely, the interpreter runs in a loop which repeatedly performs the following steps:"
{ $list
{ "If the end of the current quotation has been reached, the parent quotation is popped from the call stack and execution resumes from the saved location" }
{ "Otherwise, the interpreter performs an action depending on the type of the object at the instruction pointer:"
{ $list
{ { $emphasis "Symbol word" } " - pushed on the datastack. See " { $link "symbols" } }
{ { $emphasis "Compound word" } " - the associated quotation is called. See " { $link "colon-definition" } }
{ { $emphasis "Compiled or primitive word" } " - the interpreter jumps to machine code. See " { $link "primitives" } }
{ { $emphasis "Undefined word" } " - an error is raised. See " { $link "deferred" } }
{ { $emphasis "Wrapper" } " - the wrapped object is pushed on the data stack. Wrappers are used to push word objects directly on the stack when they would otherwise execute. See the " { $link POSTPONE: \ } " parsing word." }
{ "All other types of objects are pushed on the data stack." }
}
}
}
"At each stage, the instruction pointer is advanced by one position."
$terpri
"If the instruction pointer is at the end of a quotation when a nested quotation is called, the quotation which just finished executing is not pushed on the call stack. Therefore the last call in a quotation does not grow the call stack, and tail recursion executes in bounded space."
$terpri
"The compiler generates machine code which perform the steps in a more efficient manner than the interpreter, however the observable semantics remain the same." ;
"Quotations implement the sequence protocol (" { $link "sequences" } "). Much of the power of Factor comes from the fact that not only can you have literal quotations in your program, but you can also construct new quotations at run time using general sequence words, or the following quotation-specific words:"
{ $subsection unit }
{ $subsection literalize }
{ $subsection curry }
{ $subsection alist>quot } ;
ARTICLE: "combinators" "Combinators"
"The following pair of words invoke the interpreter reflectively:"
@ -107,6 +94,27 @@ $terpri
{ $subsection and }
{ $subsection or } ;
ARTICLE: "interpreter" "The interpreter"
"The interpreter runs in a loop which repeatedly performs the following steps:"
{ $list
{ "If the end of the current quotation has been reached, the parent quotation is popped from the call stack and execution resumes from the saved location" }
{ "Otherwise, the interpreter performs an action depending on the type of the object at the instruction pointer:"
{ $list
{ { $emphasis "Symbol word" } " - pushed on the datastack. See " { $link "symbols" } }
{ { $emphasis "Compound word" } " - the associated quotation is called. See " { $link "colon-definition" } }
{ { $emphasis "Compiled or primitive word" } " - the interpreter jumps to machine code. See " { $link "primitives" } }
{ { $emphasis "Undefined word" } " - an error is raised. See " { $link "deferred" } }
{ { $emphasis "Wrapper" } " - the wrapped object is pushed on the data stack. Wrappers are used to push word objects directly on the stack when they would otherwise execute. See the " { $link POSTPONE: \ } " parsing word." }
{ "All other types of objects are pushed on the data stack." }
}
}
}
"At each stage, the instruction pointer is advanced by one position."
$terpri
"If the instruction pointer is at the end of a quotation when a nested quotation is called, the quotation which just finished executing is not pushed on the call stack. Therefore the last call in a quotation does not grow the call stack, and tail recursion executes in bounded space."
$terpri
"The compiler generates machine code which perform the steps in a more efficient manner than the interpreter, however the observable semantics remain the same." ;
ARTICLE: "continuations" "Continuations"
"At any point in the execution of a program, the " { $emphasis "current continuation" } " represents the future of the computation. This object can be reified with the following two words:"
{ $subsection callcc0 }

View File

@ -0,0 +1,116 @@
USING: hashtables hashtables-internals help io-internals kernel
kernel-internals namespaces queues ;
ARTICLE: "hashtables" "Hashtables"
"A hashtable provides efficient (expected constant time) lookup and storage of key/value pairs. Keys are compared for equality, and a hashing function is used to reduce the number of comparisons made."
$terpri
"Hashtable words are in the " { $snippet "hashtables" } " vocabulary. Unsafe implementation words are in the " { $snippet "hashtables-internals" } " vocabulary."
$terpri
"Hashtables form a class of objects."
{ $subsection hashcode }
{ $subsection hashtable? }
{ $subsection <hashtable> }
"If you don't care about initial capacity, a more elegant way to create a new hashtable is to write:"
{ $code "H{ } clone" }
"There are some primitive operations on hashes, and many utilities."
{ $subsection "hashtables-lookup" }
{ $subsection "hashtables-mutation" }
{ $subsection "hashtables-combinators" }
{ $subsection "hashtables-utilities" }
{ $subsection "hashtables-internals" } ;
ARTICLE: "hashtables-lookup" "Looking up keys in hashtables"
{ $subsection hash }
{ $subsection hash* }
{ $subsection ?hash }
{ $subsection ?hash* }
{ $subsection hash-member? } ;
ARTICLE: "hashtables-mutation" "Storing keys in hashtables"
{ $subsection set-hash }
{ $subsection remove-hash }
{ $subsection clear-hash } ;
ARTICLE: "hashtables-combinators" "Hashtable combinators"
"We have the standard functional programming idioms."
{ $subsection hash-each }
{ $subsection hash-all? }
{ $subsection hash-subset }
"There are curried forms of the above."
{ $subsection hash-each-with }
{ $subsection hash-all-with? }
{ $subsection hash-subset-with }
"Two oddball combinators."
{ $subsection cache }
{ $subsection map>hash } ;
ARTICLE: "hashtables-utilities" "Hashtable utilities"
"Set-theoretic operations exploit the expected constant lookup time of a hashtable."
{ $subsection hash-intersect }
{ $subsection hash-diff }
{ $subsection hash-union }
{ $subsection hash-concat }
{ $subsection hash-update }
{ $subsection remove-all }
"A combinator used to implement notions of nested scope. This includes various fundamental abstractions like variables, vocabulary search and cascading styles."
{ $subsection hash-stack } ;
ARTICLE: "hashtables-internals" "Hashtable implementation details"
"This hashtable implementation uses only one auxilliary array in addition to the hashtable tuple itself. The array stores keys in even slots and values in odd slots. Values are looked up with a hashing strategy that uses linear probing to resolve collisions."
{ $terpri }
"There are two special objects: the " { $link ((tombstone)) } " marker and the " { $link ((empty)) } " marker. Neither of these markers can be used as hashtable keys."
{ $terpri }
"The " { $link hash-count } " slot is the number of entries including deleted entries, and " { $link hash-deleted } " is the number of deleted entries."
{ $subsection <hash-array> }
{ $subsection nth-pair }
{ $subsection set-nth-pair }
{ $subsection each-pair }
{ $subsection all-pairs? } ;
ARTICLE: "namespaces" "Variables and namespaces"
"A variable is an entry in a hashtable of bindings, with the hashtable being implicit rather than passed on the stack. These hashtables are termed " { $emphasis "namespaces" } ". Nesting of scopes is implemented with a search order on namespaces, defined by a " { $emphasis "namestack" } ". Since namespaces are just hashtables, any object can be used as a variable, however by convention, variables are keyed by symbols (see " { $link "symbols" } ")."
$terpri
"The " { $snippet "get" } " and " { $snippet "set" } " words read and write variable values. The " { $snippet "get" } " word searches up the chain of nested namespaces, while " { $snippet "set" } " always sets variable values in the current namespace only. Namespaces are dynamically scoped; when a quotation is called from a nested scope, any words called by the quotation also execute in that scope."
{ $subsection get }
{ $subsection set }
"Various utility words abstract away common variable access patterns:"
{ $subsection "namespaces-change" }
{ $subsection "namespaces-combinators" }
{ $subsection "namespaces-utilities" }
"A useful facility for constructing sequences by holding an accumulator sequence in a variable:"
{ $subsection "namespaces-make" }
"Implementation details your code probably does not care about:"
{ $subsection "namespaces-internals" } ;
ARTICLE: "namespaces-combinators" "Namespace combinators"
{ $subsection make-hash }
{ $subsection with-scope }
{ $subsection bind } ;
ARTICLE: "namespaces-change" "Ways to change variable values"
{ $subsection on }
{ $subsection off }
{ $subsection inc }
{ $subsection dec }
{ $subsection change } ;
ARTICLE: "namespaces-utilities" "Namespace utilities"
{ $subsection namespace }
{ $subsection nest }
{ $subsection global }
{ $subsection set-global } ;
ARTICLE: "namespaces-make" "Constructing sequences"
"There is a lexicon of words for constructing sequences without passing the partial sequence being built on the stack. This reduces stack noise."
{ $subsection make }
{ $subsection , }
{ $subsection % }
{ $subsection # } ;
ARTICLE: "namespaces-internals" "Namespace implementation details"
"The namestack holds namespaces."
{ $subsection namestack }
{ $subsection set-namestack }
"A pair of words push and pop namespaces on the namestack."
{ $subsection >n }
{ $subsection n> } ;

View File

@ -1,6 +1,6 @@
USING: help math prettyprint sequences ;
ARTICLE: "math" "Mathematics"
ARTICLE: "math" "Numbers"
"Factor attempts to preserve natural mathematical semantics for numbers. Multiplying two large integers never results in overflow, and dividing two integers yields an exact ratio. Floating point numbers are also supported, along with complex numbers."
$terpri
"Math words are in the " { $snippet "math" } " vocabulary. Implementation details are in the " { $snippet "math-internals" } " vocabulary."
@ -8,7 +8,8 @@ $terpri
{ $subsection "number-types" }
{ $subsection "math-functions" }
{ $subsection "math-constants" }
{ $subsection "math-vectors" } ;
{ $subsection "math-vectors" }
{ $subsection "number-strings" } ;
ARTICLE: "number-types" "Types of numbers"
{ $subsection "integers" }
@ -222,3 +223,22 @@ $terpri
{ $subsection norm }
{ $subsection norm-sq }
{ $subsection normalize } ;
ARTICLE: "number-strings" "Converting between numbers and strings"
"These words only convert between real numbers and strings. Complex numbers are constructed by the parser (" { $link "parser" } ") and printed by the prettyprinter (" { $link "prettyprint" } ")."
$terpri
"Note that only integers can be converted to and from strings using a representation other than base 10. Calling a word such as " { $link >oct } " on a float will give a result in base 10."
$terpri
"Converting numbers to strings:"
{ $subsection number>string }
{ $subsection >bin }
{ $subsection >oct }
{ $subsection >hex }
{ $subsection >base }
"Converting strings to numbers:"
{ $subsection string>number }
{ $subsection bin> }
{ $subsection oct> }
{ $subsection hex> }
{ $subsection base> }
"You can also input literal numbers in a different base (" { $link "syntax-integers" } ")." ;

View File

@ -1,7 +1,7 @@
USING: help io parser words ;
USING: help io parser sequences words ;
ARTICLE: "parser" "The parser"
"This section concerns itself with reflective access and extension of the Factor parser. The parser algorithm and standard syntax is described in " { $link "syntax" } ". Before the parser proper is documented, we draw attention to a set of words for parsing numbers. They are called by the parser, and are useful in their own right."
"This section concerns itself with reflective access and extension of the Factor parser. The parser algorithm and standard syntax is described in " { $link "syntax" } "."
$terpri
"The set of words making up the parser are found in the " { $snippet "parser" } " and " { $snippet "syntax" } " vocabularies."
$terpri
@ -13,6 +13,7 @@ $terpri
{ $subsection eval }
"More sophisticated facilities exist, too."
{ $subsection "parse-stream" }
"The parser can be extended with new parsing word definitions."
{ $subsection "parsing-words" } ;
ARTICLE: "parse-stream" "Parsing from streams"
@ -36,42 +37,45 @@ $terpri
{ $subsection "parsing-word-nest" }
{ $subsection "reading-ahead" }
{ $subsection "defining-words" }
{ $subsection "string-mode" } ;
{ $subsection "string-mode" }
{ $subsection "parser-internals" } ;
ARTICLE: "parsing-word-nest" "Nested structure"
"The first thing to look at is how the parse tree is built. When parsing begins, the empty list is pushed on the data stack; whenever the parser algorithm appends an object to the parse tree, it conses the object onto the quotation at the top of the stack. This builds the quotation in reverse order, so when parsing is done, the quotation is reversed before it is called."
"The first thing to look at is how the parse tree is built. When parsing begins, " { $link f } " is pushed on the data stack; when a new object is parsed, " { $link ?push } " is called to add it to the parse tree. The first call to " { $link ?push } " creates a new one-element vector, and subsequent calls add elements to the end of this vector. When parsing is complete, the vector is converted into a quotation."
$terpri
"Lets look at a simple example; the parsing of " { $snippet "1 2 3" } ":"
$terpri
{ $list
{ "Token: " { $snippet "1" } " - stack: " { $snippet "[ 1 ]" } }
{ "Token: " { $snippet "2" } " - stack: " { $snippet "[ 2 1 ]" } }
{ "Token: " { $snippet "3" } " - stack: " { $snippet "[ 3 2 1 ]" } }
{ "Initial stack after parsing begins:" { $snippet "f" } }
{ "Token: " { $snippet "1" } " - stack top: " { $snippet "V{ 1 }" } }
{ "Token: " { $snippet "2" } " - stack top: " { $snippet "V{ 1 2 }" } }
{ "Token: " { $snippet "3" } " - stack top: " { $snippet "V{ 1 2 3 }" } }
{ "Final stack upon completion:" { $snippet "[ 1 2 3 ]" } }
}
"Once the end of the string has been reached, the quotation is reversed, leaving the following output:"
{ $code "[ 1 2 3 ]" }
"Nested structure is a bit more involved. The basic idea is that parsing words can push an empty list on the stack, then all subsequent tokens are consed onto this list, until another parsing word adds this list to the list underneath."
"Nested structure is a bit more involved. The basic idea is that parsing words can push " { $link f } " on the stack to begin a new level of nesting, then all subsequent objects are pushed onto this sequence, until another parsing word adds this sequence to the vector underneath."
$terpri
"The parsing words that delimit the beginning and the end of a quotation illustrate the idiom:"
{ $subsection POSTPONE: [ }
{ $subsection POSTPONE: ] }
"Let us ponder, then, how one particular string will parse::"
"Let us ponder, then, how one particular string will parse:"
{ $snippet "\"1 [ 2 3 ] 4\"" }
{ $list
{ "Token: " { $snippet "1" } " - stack: " { $snippet "[ 1 ]" } }
{ "Token: " { $snippet "[" } " - stack: " { $snippet "[ ] [ 1 ]" } }
{ "Token: " { $snippet "2" } " - stack: " { $snippet "[ 2 ] [ 1 ]" } }
{ "Token: " { $snippet "3" } " - stack: " { $snippet "[ 3 2 ] [ 1 ]" } }
{ "Token: " { $snippet "]" } " - stack: " { $snippet "[ [ 2 3 ] 1 ]" } }
{ "Token: " { $snippet "4" } " - stack: " { $snippet "[ 4 [ 2 3 ] 1 ]" } }
{ "Initial stack after parsing begins:" { $snippet "f" } }
{ "Token: " { $snippet "1" } " - stack top: " { $snippet "V{ 1 }" } }
{ "Token: " { $snippet "[" } " - stack top: " { $snippet "f V{ 1 }" } }
{ "Token: " { $snippet "2" } " - stack top: " { $snippet "V{ 2 } V{ 1 }" } }
{ "Token: " { $snippet "3" } " - stack top: " { $snippet "V{ 2 3 } V{ 1 }" } }
{ "Token: " { $snippet "]" } " - stack top: " { $snippet "V{ 1 [ 2 3 ] }" } }
{ "Token: " { $snippet "4" } " - stack top: " { $snippet "V{ 1 [ 2 3 ] 4 }" } }
{ "Final stack upon completion:" { $snippet "[ 1 [ 2 3 ] 4 ]" } }
}
"Having done all that, the parser reverses the original quotation, and the expected output is now on the stack:"
{ $code "[ 1 [ 2 3 ] 4 ]" }
"Notice how in the definition of the list parsing words, the final word " { $link POSTPONE: ] } " does all the work. A closely related set of parsing words for reading various other literal types implements another useful idiom."
"Notice how in the definition of the quotation parsing words, the final word " { $link POSTPONE: ] } " does all the work. A closely related set of parsing words for reading various other literal types implements another useful idiom."
$terpri
"The word set in question consists of various start delimiters, such a " { $link POSTPONE: { } " for arrays and " { $link POSTPONE: H{ } " for hashtables, together with one end delimiter " { $link POSTPONE: } } ". The start words push a quotation in addition to an empty list; the end word reverses the empty list, and applies the quotation to the newly-parsed list; the quotation converts it to the appropriate type of literal."
"The word set in question consists of various start delimiters, such a " { $link POSTPONE: { } " for arrays and " { $link POSTPONE: H{ } " for hashtables, together with one end delimiter " { $link POSTPONE: } } ". The start words push a quotation in addition to pushing " { $link f } "; the end word applies the quotation to the newly-parsed vector; the quotation converts it to the appropriate type of literal."
{ $subsection POSTPONE: { }
{ $subsection POSTPONE: H{ }
{ $subsection POSTPONE: V{ }
{ $subsection POSTPONE: W{ }
{ $subsection POSTPONE: T{ }
{ $subsection POSTPONE: } } ;
ARTICLE: "reading-ahead" "Reading ahead"
@ -91,23 +95,29 @@ ARTICLE: "defining-words" "Defining words"
{ $subsection CREATE }
"Colon definitions are defined in a more elaborate way. The definition of " { $link POSTPONE: : } " introduces the next idiom, and that is building a quotation and then adding a definition using " { $link POSTPONE: ; } "."
$terpri
"Recall the colon definition syntax. When the " { $link POSTPONE: : } " word executes, it reads ahead from the input and defines a word. Then, it places a quotation and an empty list on the stack. The parser conses tokens onto the empty list, and the quotation is called by " { $link POSTPONE: ; } "."
"Recall the colon definition syntax. When the " { $link POSTPONE: : } " word executes, it reads ahead from the input and defines a word. Then, it places a quotation and " { $link f } " on the data stack. The parser builds up a parse tree, and the quotation pushed by " { $link POSTPONE: : } " is called by " { $link POSTPONE: ; } "."
{ $subsection POSTPONE: : }
{ $subsection POSTPONE: ; }
"There are additional parsing words whose syntax is delimited by " { $link POSTPONE: ; } ", and they are all implemented in the same way -- first they read some input, then they leave a quotation followed by an empty list on the stack."
{ $subsection POSTPONE: C: }
{ $subsection POSTPONE: G: }
{ $subsection POSTPONE: M: }
{ $subsection POSTPONE: C: } ;
{ $subsection POSTPONE: PREDICATE: }
{ $subsection POSTPONE: TUPLE: }
{ $subsection POSTPONE: UNION: }
{ $subsection POSTPONE: USING: } ;
ARTICLE: "string-mode" "String mode and parser internals"
ARTICLE: "string-mode" "String mode"
"String mode allows custom parsing of tokenized input. For even more esoteric situations, the input text can be accessed directly."
$terpri
"String mode is controlled by a boolean variable in the parser scope:"
{ $subsection string-mode }
"An illustration of this idiom is found in the " { $link POSTPONE: USING: } " parsing word. It reads a list of vocabularies, terminated by " { $link POSTPONE: ; } ". However, the vocabulary names do not name words, except by coincidence; so string mode is used to read them."
{ $subsection POSTPONE: USING: }
"Make note of the quotation that is left in position for " { $link POSTPONE: ; } " to call. It switches off string mode, so that normal parsing can resume, then adds the given vocabularies to the search path."
$terpri
"Some additional variables that encapsulate internal parser state:"
"Make note of the quotation that is left in position for " { $link POSTPONE: ; } " to call. It switches off string mode, so that normal parsing can resume, then adds the given vocabularies to the search path." ;
ARTICLE: "parser-internals" "Parser internals"
"Some variables that encapsulate internal parser state:"
{ $subsection file }
{ $subsection line-number }
{ $subsection line-text }

View File

@ -20,6 +20,7 @@ $terpri
{ $subsection "sequences-sorting" }
{ $subsection "sequences-stacks" }
{ $subsection "sequences-comparing" }
{ $subsection "sequences-assoc" }
"Some implementation details which your code should probably not care about:"
{ $subsection "sequences-unsafe" }
{ $subsection "sequences-growable" }
@ -31,11 +32,13 @@ ARTICLE: "sequence-implementations" "Sequence implementations"
{ $subsection "vectors" }
{ $subsection "strings" }
{ $subsection "sbufs" }
{ $subsection "quotations" }
"Virtual sequences wrap an underlying sequence to present an alternative view of its elements:"
{ $subsection <slice> }
{ $subsection <reversed> }
"Integers support the sequence protocol:"
{ $subsection "sequences-integers" } ;
{ $subsection "sequences-integers" }
"The " { $link f } " object also supports the sequence protocol. It responds with a length of zero, and instead of throwing an out of bounds error, outputs " { $link f } " when an element is accessed. This can simplify code that would like a dummy sequence behaving as if it has arbitrary length." ;
ARTICLE: "sequences-integers" "Integer sequences and counted loops"
"Integers support the sequence protocol in a trivial fashion; a non-negative integer presents its non-negative predecessors as elements. For example, the integer 3, when viewed as a sequence, contains the elements 0, 1, and 2. This is very useful for performing counted loops."
@ -44,7 +47,7 @@ $terpri
{ $example "3 [ . ] each" "0\n1\n2" }
"A common idiom is to iterate over a sequence, while also maintaining a loop counter. This can be done using " { $link 2each } ":"
{ $example "{ \"a\" \"b\" \"c\" } dup length [\n \"Index: \" write . \"Element: \" write .\n] 2each" "Index: 0\nElement: \"a\"\nIndex: 1\nElement: \"b\"\nIndex: 2\nElement: \"c\"" }
"Combinators that produce new sequences, such as " { $snippet map } ", will output an array if the input is an integer." ;
"Combinators that produce new sequences, such as " { $link map } ", will output an array if the input is an integer." ;
ARTICLE: "sequences-utilities" "Basic utilities"
"Some utilities for accessing various common indices:"
@ -104,7 +107,7 @@ ARTICLE: "sequences-slicing" "Slicing and splitting"
{ $subsection (split1) }
{ $subsection split1 }
{ $subsection split }
{ $subsection unpair } ;
{ $subsection unclip } ;
ARTICLE: "sequences-indices" "Order-sensitive operations"
"Searching for the index of an element and or beginning of a subsequence:"
@ -158,6 +161,13 @@ ARTICLE: "sequences-comparing" "Comparing sequences"
"Lexicographic order:"
{ $subsection <=> } ;
ARTICLE: "sequences-assoc" "Association lists"
"An " { $emphasis "association list" } " is a sequence of pairs. Association lists come up from time to time; for example, the " { $link cond } " combinator takes an association list of quotations as input. You can perform lookups and take association lists apart:"
{ $subsection assoc }
{ $subsection rassoc }
{ $subsection unpair }
"An association list is slower to search than a hashtable. The main advantage of an association list is that the elements are ordered; also sometimes it is more convenient to construct an association list with sequence words than to construct a hashtable with hastable words. Most of the time, hashtables are more appropriate. See " { $link "hashtables" } "." ;
ARTICLE: "sequence-protocol" "Sequence protocol"
"All sequences must know their length, and provide a way to access elements:"
{ $subsection length }
@ -211,18 +221,22 @@ $terpri
{ $subsection ch>upper } ;
ARTICLE: "sbufs" "String buffers"
"A string buffer is a resizable mutable sequence of characters. String buffers can be used to construct new strings by accumilating substrings and characters, however usually they are only used indirectly, since the sequence construction words are more convenient to use in most cases (see " { $link "sequences-make" } ")."
"A string buffer is a resizable mutable sequence of characters. String buffers can be used to construct new strings by accumilating substrings and characters, however usually they are only used indirectly, since the sequence construction words are more convenient to use in most cases (see " { $link "namespaces-make" } ")."
$terpri
"String buffer words are found in the " { $snippet "strings" } " vocabulary."
{ $subsection sbuf? }
{ $subsection >sbuf }
{ $subsection <sbuf> } ;
{ $subsection <sbuf> }
"If you don't care about initial capacity, a more elegant way to create a new string buffer is to write:"
{ $code "SBUF\" \" clone" } ;
ARTICLE: "vectors" "Vectors"
"A vector is a resizable mutable sequence of objects. Vector words are found in the " { $snippet "vectors" } " vocabulary."
{ $subsection vector? }
{ $subsection >vector }
{ $subsection <vector> } ;
{ $subsection <vector> }
"If you don't care about initial capacity, a more elegant way to create a new vector is to write:"
{ $code "V{ } clone" } ;
ARTICLE: "sequences-sorting" "Sorting and binary search"
"Sorting and binary search combinators all take comparator quotations with stack effect " { $snippet "( elt1 elt2 -- n )" } " that order the two given elements and output a value whose sign denotes the result:"

View File

@ -116,7 +116,8 @@ $terpri
$terpri
"The following two words perform unit testing; they are usually placed inside test harness files which you run using " { $link run-file } ":"
{ $subsection unit-test }
{ $subsection unit-test-fails } ;
{ $subsection unit-test-fails }
{ $subsection assert-depth } ;
ARTICLE: "timing" "Timing code"
"You can time the execution of a quotation in the listener:"

View File

@ -285,6 +285,7 @@ vectors words ;
"/doc/handbook/collections.facts"
"/doc/handbook/dataflow.facts"
"/doc/handbook/handbook.facts"
"/doc/handbook/hashtables.facts"
"/doc/handbook/math.facts"
"/doc/handbook/objects.facts"
"/doc/handbook/parser.facts"

View File

@ -1,26 +1,6 @@
IN: queues
USING: help ;
ARTICLE: "queues" "Queues"
"Last-in-first-out queues can be found in the " { $snippet "queues" } " vocabulary."
{ $subsection <queue> }
{ $subsection queue-empty? }
{ $subsection deque }
{ $subsection enque }
"An example of usage:"
{ $snippet
"<queue> \"q\" set"
"5 \"q\" get enque"
"3 \"q\" get enque"
"7 \"q\" get enque"
"\"q\" get deque ."
" 5"
"\"q\" get deque ."
" 3"
"\"q\" get deque ."
" 7"
} ;
HELP: <queue> "( -- queue )"
{ $values { "queue" "a new queue" } }
{ $description "Makes a new queue with no elements." } ;

View File

@ -195,7 +195,16 @@ HELP: cond "( assoc -- )"
{ $code "X [ Y ] [ Z [ T ] [ no-cond ] if ] if" }
"Note that the base case is " { $link no-cond } " which throws an error."
}
{ $errors "Throws an error if the first quotation in every pair yields " { $link f } "." } ;
{ $errors "Throws an error if the first quotation in every pair yields " { $link f } "." }
{ $examples
{ $example
"{"
" { [ dup 0 > ] [ \"positive\" ] }"
" { [ dup 0 < ] [ \"negative\" ] }"
" { [ dup zero? ] [ \"zero\" ] }"
"} cond"
}
} ;
HELP: unix? "( -- ? )"
{ $values { "?" "a boolean" } }

View File

@ -6,7 +6,7 @@ HELP: alien-callback "( return parameters quot -- alien )"
{ $description
"Defines a callback from C to Factor which accepts the given set of parameters from the C caller, pushes them on the data stack, calls the quotation, and passes a return value back to the C caller. A return type of " { $snippet "\"void\"" } " indicates that no value is to be returned."
$terpri
"This word only runs when it is called from within a " { $emphasis "compiled" } " word, with all three parameters as literal inputs. See " { $link "compiler" } "."
"This word only runs when it is called from within a " { $emphasis "compiled" } " word, with all three parameters as literal inputs."
$terpri
"When a compiled reference to this word is called, it pushes the callback's alien address on the data stack. This address can be passed to any C function expecting a C function pointer with the correct signature. The callback is actually generated when the word calling " { $link alien-callback } " is compiled."
$terpri

View File

@ -5,7 +5,7 @@ HELP: alien-invoke "( ... return library function parameters -- ... )"
{ $values { "return" "a C return type" } { "library" "a logical library name" } { "function" "a C function name" } { "parameters" "a sequence of C parameter types" } }
{ $description "Calls a C library function with the given name. Input parameters are taken from the data stack, and the return value is pushed on the data stack after the function returns. A return type of " { $snippet "\"void\"" } " indicates that no value is to be expected."
$terpri
"This word only runs when it is called from within a " { $emphasis "compiled" } " word, with all four parameters as literal inputs. See " { $link "compiler" } "." }
"This word only runs when it is called from within a " { $emphasis "compiled" } " word, with all four parameters as literal inputs." }
{ $see-also alien-callback } ;
HELP: define-c-word "( return library function parameters -- )"

View File

@ -15,7 +15,7 @@ $terpri
HELP: <displaced-alien> "( displacement c-ptr -- alien )"
{ $values { "displacement" "an integer" } { "c-ptr" "an alien, byte array, or " { $link f } } { "alien" "a new alien" } }
{ $description "Creates a new alien address object, wrapping a raw memory address. The alien points to a location in memory which is offset by " { $snippet "displacement" } " from the address of " { $link "c-ptr" } "." }
{ $description "Creates a new alien address object, wrapping a raw memory address. The alien points to a location in memory which is offset by " { $snippet "displacement" } " from the address of " { $snippet "c-ptr" } "." }
{ $notes "Passing a value of " { $link f } " for " { $snippet "c-ptr" } " creates an alien with an absolute address; this is how " { $link <alien> } " is implemented."
$terpri
"Passing a zero absolute address does not construct a new alien object, but instead makes the word output " { $link f } "." }

View File

@ -20,7 +20,7 @@ HELP: FUNCTION: "return name ( parameters )"
{ $values { "return" "a C return type" } { "name" "a C function name" "parameters" "a comma-separated sequence of type/name pairs; " { $snippet "type1 arg1, type2 arg2, ..." } } }
{ $description "Defines a new word " { $snippet "name" } " which calls a C library function with the same name, in the logical library given by the most recent " { $link POSTPONE: LIBRARY: } " declaration."
$terpri
"The new word must be compiled before being executed; see " { $link "compiler" } "." }
"The new word must be compiled before being executed." }
{ $examples
"For example, suppose the " { $snippet "foo" } " library exports the following function:"
{ $code

View File

@ -9,7 +9,7 @@ HELP: compiled? "( word -- ? )"
HELP: compile "( word -- )"
{ $values { "word" "a word" } }
{ $description "Compiles a word together with any uncompiled dependencies. Does nothing if the word is already compiled." }
{ $errors "If compilation fails, this word can throw an error. In particular, if the word's stack effect cannot be inferred (see " { $link "inference" } ", this word will throw an error. The related " { $link try-compile } " word logs errors and returns rather than throwing." } ;
{ $errors "If compilation fails, this word can throw an error. In particular, if the word's stack effect cannot be inferred, this word will throw an error. The related " { $link try-compile } " word logs errors and returns rather than throwing." } ;
HELP: compiled f
{ $description "Compiles the most recently defined word." }
@ -34,9 +34,9 @@ HELP: recompile "( word -- )"
HELP: compile-quot "( quot -- word )"
{ $values { "quot" "a quotation" } { "word" "a new, uninterned word" } }
{ $description "Creates a new uninterned word having the given quotation as its definition, and compiles it. The returned word can be passed to " { $link execute } "." }
{ $errors "Throws an error if the stack effect of the quotation cannot be inferred. See " { $link "inference" } "." } ;
{ $errors "Throws an error if the stack effect of the quotation cannot be inferred." } ;
HELP: compile-1 "( quot -- )"
{ $values { "quot" "a quotation" } }
{ $description "Compiles and runs a quotation." }
{ $errors "Throws an error if the stack effect of the quotation cannot be inferred. See " { $link "inference" } "." } ;
{ $errors "Throws an error if the stack effect of the quotation cannot be inferred." } ;

View File

@ -4,4 +4,4 @@ USING: help ;
HELP: infer "( quot -- effect )"
{ $values { "quot" "a quotation" } { "effect" "a pair of integers" } }
{ $description "Attempts to infer the quotation's stack effect, outputting a pair holding the correct of data stack inputs and outputs for the quotation." }
{ $errors "Throws an error if stack effect inference fails. See " { $link "inference" } "." } ;
{ $errors "Throws an error if stack effect inference fails." } ;

View File

@ -28,7 +28,7 @@ HELP: class "( object -- class )"
HELP: tuple-predicate "( class -- )"
{ $values { "class" "a tuple class word" } }
{ $description "Defines a predicate word that tests if the top of the stack is an instance of " { $snippet class } ". This will only work if " { $snippet class } " is a tuple class." }
{ $description "Defines a predicate word that tests if the top of the stack is an instance of " { $snippet "class" } ". This will only work if " { $snippet "class" } " is a tuple class." }
$low-level-note ;
HELP: check-shape "( class slots -- )"

View File

@ -1,7 +1,8 @@
! Copyright (C) 2005, 2006 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
IN: help
USING: arrays hashtables io kernel namespaces strings ;
USING: arrays errors hashtables io kernel namespaces sequences
strings ;
! Markup
GENERIC: print-element
@ -11,13 +12,14 @@ SYMBOL: articles
TUPLE: article title content ;
: article ( name -- article ) articles get hash ;
: article ( name -- article )
dup articles get hash
[ ] [ "No such article: " swap append throw ] ?if ;
: add-article ( name title element -- )
<article> swap articles get set-hash ;
M: string article-title article article-title ;
M: string article-content article article-content ;
! Special case: f help

View File

@ -16,11 +16,8 @@ PREDICATE: array simple-element
dup empty? [ drop t ] [ first word? not ] if ;
M: simple-element print-element [ print-element ] each ;
M: string print-element last-block off format* ;
M: array print-element unclip execute ;
M: word print-element { } swap execute ;
: ($span) ( content style -- )
@ -110,12 +107,13 @@ M: word print-element { } swap execute ;
TUPLE: link name ;
M: link article-title link-name article-title ;
M: link article-content link-name article-content ;
M: link summary "Link to " swap link-name unparse append ;
: >link ( obj -- obj ) dup string? [ <link> ] when ;
GENERIC: >link
M: object >link ;
M: string >link <link> ;
M: f >link <link> ;
: ($subsection) ( quot object -- )
subsection-style [

View File

@ -316,11 +316,11 @@ HELP: exit "( n -- )"
HELP: getenv "( n -- obj )"
{ $values { "n" "a non-negative integer" } { "obj" "an object" } }
{ $values "Reads an object from the Factor runtime's environment table. User code never has to read the environment table directly; instead, use one of the callers of this word." } ;
{ $description "Reads an object from the Factor runtime's environment table. User code never has to read the environment table directly; instead, use one of the callers of this word." } ;
HELP: setenv "( obj n -- )"
{ $values { "n" "a non-negative integer" } { "obj" "an object" } }
{ $values "Writes an object to the Factor runtime's environment table. User code never has to write to the environment table directly; instead, use one of the callers of this word." } ;
{ $description "Writes an object to the Factor runtime's environment table. User code never has to write to the environment table directly; instead, use one of the callers of this word." } ;
HELP: integer-slot "( obj m -- n )"
{ $values { "obj" "an object" } { "m" "a non-negative fixnum" } { "n" "an integer" } }

View File

@ -2,7 +2,7 @@ IN: kernel
USING: arrays help strings vectors ;
HELP: quotation f
{ $description "The class of quotations. See " { $link "syntax-quotations" } " for syntax and " { $link "quotations" } " for general information." } ;
{ $description "The class of quotations. See " { $link "syntax-quots" } " for syntax and " { $link "quotations" } " for general information." } ;
HELP: <quotation> "( n -- quot )"
{ $values { "n" "a non-negative integer" } { "quot" "a new quotation" } }
@ -32,7 +32,7 @@ HELP: unit "( obj -- quot )"
{ $see-also 1array } ;
HELP: wrapper f
{ $description "The class of wrappers. See " { $link "syntax-wrappers" } " for syntax." } ;
{ $description "The class of wrappers. See " { $link "syntax-words" } " for syntax." } ;
HELP: <wrapper> "( obj -- wrapper )"
{ $values { "obj" "an object" } { "wrapper" "a new wrapper" } }

View File

@ -68,6 +68,11 @@ HELP: T{ "class delegate slots... }"
{ $values { "class" "a tuple class word" } { "delegate" "a delegate" } { "slots" "list of objects" } }
{ $description "Marks the beginning of a literal tuple. The class word must always be specified. If an insufficient number of values is given after the class word, the remaining slots of the tuple are set to " { $link f } ". If too many values are given, an error is thrown." } ;
HELP: W{ "object }"
{ $values { "object" "an object" } }
{ $description "Marks the beginning of a literal wrapper." }
{ $see-also POSTPONE: \ <wrapper> literalize } ;
HELP: POSTPONE: "word"
{ $values { "word" "a word" } }
{ $description "Reads the next word from the input string and appends the word to the parse tree, even if it is a parsing word." }

View File

@ -0,0 +1,11 @@
USING: gadgets-panes help io kernel namespaces prettyprint
sequences test threads words ;
[
all-articles [
stdio get pane-clear
dup global [ . flush ] bind
[ dup help ] assert-depth drop
1 sleep
] each
] time