158 lines
7.9 KiB
Plaintext
158 lines
7.9 KiB
Plaintext
USING: help kernel parser words ;
|
|
|
|
GLOSSARY: "defining word" "a word that adds definitions to the dictionary" ;
|
|
|
|
GLOSSARY: "dictionary" "the collection of vocabularies making up the code in the Factor image" ;
|
|
|
|
ARTICLE: "words" "Words"
|
|
"Words are the fundamental unit of code in Factor, analogous to functions or procedures in other languages. Words are also objects, and this concept forms the basis for Factor's meta-programming facilities. A word consists of several parts:"
|
|
{ $list
|
|
"a word name,"
|
|
"a vocabulary name,"
|
|
"a definition, specifying the behavior of the word when executed,"
|
|
"a set of word properties, including documentation strings and other meta-data."
|
|
}
|
|
"Words for working with words are in the " { $snippet "words" } " vocabulary, and words form a class of objects."
|
|
{ $subsection word }
|
|
{ $subsection word? }
|
|
{ $subsection word-name }
|
|
{ $subsection word-vocabulary }
|
|
{ $subsection word-sort }
|
|
{ $subsection "vocabularies" }
|
|
{ $subsection "word-definition" }
|
|
{ $subsection "word-crossref" }
|
|
{ $subsection "word-internals" } ;
|
|
|
|
GLOSSARY: "interned word" "a word that is a member of the vocabulary named by its vocabulary slot. Interned words are created by calls to " { $link create } ;
|
|
|
|
GLOSSARY: "uninterned word" "a word whose vocabulary slot is either set to " { $link f } ", or that does not belong to the vocabulary named by its vocabulary slot. Uninterned words are created by calls to " { $link gensym } ", and interned words can become uninterned via calls to " { $link forget } ;
|
|
|
|
ARTICLE: "vocabularies" "Vocabularies"
|
|
"Words are organized into named vocabularies, stored in a global variable."
|
|
{ $subsection vocabularies }
|
|
"A word is said to be " { $emphasis "interned" } " if it is a member of the vocabulary named by its vocabulary slot. Otherwise, the word is " { $emphasis "uninterned" } "."
|
|
$terpri
|
|
"Words whose names are known at parse time -- that is, most words making up your program -- can be referenced in source code by stating their name. However, the parser itself, and sometimes code you write, will need to create look up words dynamically."
|
|
$terpri
|
|
"Parsing words add definitions to the current vocabulary. When a source file is being parsed, the current vocabulary is initially set to " { $snippet "scratchpad" } ". The current vocabulary may be changed with the " { $link POSTPONE: IN: } " parsing word (see " { $link "vocabulary-search" } ")."
|
|
{ $subsection create }
|
|
{ $subsection create-in }
|
|
{ $subsection gensym }
|
|
{ $subsection lookup } ;
|
|
|
|
ARTICLE: "word-definition" "Defining words"
|
|
"There are two approaches to creating word definitions:"
|
|
{ $list
|
|
"using parsing words at parse time,"
|
|
"using defining words at run-time."
|
|
}
|
|
"The latter is a more dynamic feature that can be used to implement code generation and such, and in fact parse-time defining words are implemented in terms of run-time defining words."
|
|
{ $subsection "colon-definition" }
|
|
{ $subsection "symbols" }
|
|
{ $subsection "primitives" }
|
|
{ $subsection "deferred" }
|
|
{ $subsection "undefining" }
|
|
{ $subsection "declarations" } ;
|
|
|
|
GLOSSARY: "compound definition" "a word that calls a quotation when executed" ;
|
|
|
|
GLOSSARY: "colon definition" "see compound definition" ;
|
|
|
|
ARTICLE: "colon-definition" "Compound definitions"
|
|
"A compound definition associates a word name with a quotation that is called when the word is executed."
|
|
{ $subsection POSTPONE: : }
|
|
{ $subsection define-compound }
|
|
{ $subsection compound? }
|
|
{ $subsection compound } ;
|
|
|
|
GLOSSARY: "symbol" "a word defined to push itself on the stack when executed, created by the " { $link POSTPONE: SYMBOL: } " parsing word" ;
|
|
|
|
ARTICLE: "symbols" "Symbols"
|
|
{ $subsection POSTPONE: SYMBOL: }
|
|
{ $subsection define-symbol }
|
|
{ $subsection symbol? }
|
|
{ $subsection symbol } ;
|
|
|
|
ARTICLE: "primitives" "Primitives"
|
|
"Executing a primitive invokes native code in the Factor runtime. Primitives cannot be defined through Factor code. Compiled definitions behave similarly to primitives in that the interpreter jumps to native code upon encountering them."
|
|
{ $subsection primitive? }
|
|
{ $subsection primitive } ;
|
|
|
|
ARTICLE: "deferred" "Deferred words and mutual recursion"
|
|
{ $subsection POSTPONE: DEFER: }
|
|
{ $subsection undefined? }
|
|
{ $subsection undefined } ;
|
|
|
|
ARTICLE: "undefining" "Undefining words"
|
|
{ $subsection POSTPONE: FORGET: }
|
|
{ $subsection forget }
|
|
{ $subsection interned? } ;
|
|
|
|
GLOSSARY: "inline word" "calls to inline words are replaced with the inline word's body by the compiler. Inline words are declared via the " { $link POSTPONE: inline } " parsing word" ;
|
|
|
|
GLOSSARY: "flushable word" "calls to flushable words may be removed from compiled code if their outputs are subsequently discarded by calls to " { $link drop } ". Flushable words are declared via the " { $link POSTPONE: flushable } " parsing word" ;
|
|
|
|
GLOSSARY: "foldable word" "calls to foldable words may be evaluated at compile time if all inputs are literal. Foldable words are declared via the " { $link POSTPONE: foldable } " parsing word" ;
|
|
|
|
ARTICLE: "declarations" "Declarations"
|
|
"Declarations give special behavior to a word. Declarations are parsing words that set a word property in the most recently defined word."
|
|
$terpri
|
|
"The first declaration specifies the time when a word runs. It affects both interpreted and compiled definitions."
|
|
{ $subsection POSTPONE: parsing }
|
|
"The remaining declarations only affect compiled definitions. They do not change evaluation semantics of a word, but instead declare that the word follows a certain contract, and thus may be compiled differently."
|
|
$terpri
|
|
{ $warning "If a generic word is defined as " { $link POSTPONE: flushable } " or " { $link POSTPONE: foldable } ", all methods must satisfy the contract, otherwise unpredicable behavior will occur." }
|
|
{ $subsection POSTPONE: inline }
|
|
{ $subsection POSTPONE: flushable }
|
|
{ $subsection POSTPONE: foldable } ;
|
|
|
|
GLOSSARY: "word property" "a name/value pair stored in the word properties of a word" ;
|
|
|
|
GLOSSARY: "word properties" "a hashtable associated with each word storing various sundry properties" ;
|
|
|
|
ARTICLE: "word-props" "Word properties"
|
|
"Each word has a hashtable of properties."
|
|
{ $subsection word-prop }
|
|
{ $subsection set-word-prop }
|
|
{ $subsection word-props }
|
|
{ $subsection set-word-props }
|
|
"The stack effect of the above two words is designed so that it is most convenient when " { $snippet "name" } " is a literal pushed on the stack right before executing this word."
|
|
$terpri
|
|
"The following properties are set by the library:"
|
|
{ $list
|
|
{ { $snippet "\"parsing\"" } ", " { $snippet "\"inline\"" } ", " { $snippet "\"flushable\"" } ", " { $snippet "\"fondable\"" } " - declarations (see " { $link "declarations" } ")" }
|
|
{ { $snippet "\"methods\"" } ", " { $snippet "\"combination\"" } " - only defined on generic words (see " { $link "generic" } ")" }
|
|
{ { $snippet "\"file\"" } " - the source file storing the word definition" }
|
|
{ { $snippet "\"line\"" } " - the line number in the source file storing the word definition" }
|
|
} ;
|
|
|
|
ARTICLE: "word-crossref" "Cross-referencing"
|
|
"The cross-reference database is updated every time a word is redefined."
|
|
{ $subsection crossref }
|
|
"You can find all words called by a given word:"
|
|
{ $subsection uses }
|
|
"As well as all words calling a given word:"
|
|
{ $subsection usage }
|
|
{ $subsection usages }
|
|
"In most cases the cross-reference database is maintained automatically, but if you do something unusual you might need to update it manually."
|
|
{ $subsection recrossref } ;
|
|
|
|
ARTICLE: "word-internals" "Word implementation details"
|
|
"The behavior of a word when executed depends on the values of two slots:"
|
|
{ $list
|
|
"the primitive number"
|
|
"the primitive parameter"
|
|
}
|
|
"The primitive number is an index into an array of native functions in the Factor runtime."
|
|
$terpri
|
|
"Primitive number accessors:"
|
|
{ $subsection word-primitive }
|
|
{ $subsection set-word-primitive }
|
|
"Primitive parameter accessors:"
|
|
{ $subsection word-def }
|
|
{ $subsection set-word-def }
|
|
"A lower-level facility for inspecting the machine code address of a word:"
|
|
{ $subsection word-xt }
|
|
{ $subsection set-word-xt }
|
|
{ $subsection update-xt } ;
|