1 USING: definitions help.markup help.syntax kernel parser
2 kernel.private words.private vocabs classes quotations
3 strings effects compiler.units ;
6 ARTICLE: "interned-words" "Looking up and creating words"
7 "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" } "."
9 "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."
11 "Parsing words add definitions to the current vocabulary. When a source file is being parsed, the current vocabulary is initially set to " { $vocab-link "scratchpad" } ". The current vocabulary may be changed with the " { $link POSTPONE: IN: } " parsing word (see " { $link "vocabulary-search" } ")."
12 { $subsection create }
13 { $subsection create-in }
14 { $subsection lookup } ;
16 ARTICLE: "uninterned-words" "Uninterned words"
17 "A word that is not a member of any vocabulary is said to be " { $emphasis "uninterned" } "."
19 "There are several ways of creating an uninterned word:"
20 { $subsection <word> }
21 { $subsection gensym }
22 { $subsection define-temp } ;
24 ARTICLE: "colon-definition" "Word definitions"
25 "Every word has an associated quotation definition that is called when the word is executed."
27 "Defining words at parse time:"
28 { $subsection POSTPONE: : }
29 { $subsection POSTPONE: ; }
30 "Defining words at run time:"
31 { $subsection define }
32 { $subsection define-declared }
33 { $subsection define-inline }
34 "Word definitions should declare their stack effect, unless the definition is completely trivial. See " { $link "effect-declaration" } "."
36 "All other types of word definitions, such as " { $link "symbols" } " and " { $link "generic" } ", are just special cases of the above." ;
38 ARTICLE: "primitives" "Primitives"
39 "Primitives are words defined in the Factor VM. They provide the essential low-level services to the rest of the system."
40 { $subsection primitive }
41 { $subsection primitive? } ;
43 ARTICLE: "deferred" "Deferred words and mutual recursion"
44 "Words cannot be referenced before they are defined; that is, source files must order definitions in a strictly bottom-up fashion. This is done to simplify the implementation, facilitate better parse time checking and remove some odd corner cases; it also encourages better coding style."
46 "Sometimes this restriction gets in the way, for example when defining mutually-recursive words; one way to get around this limitation is to make a forward definition."
47 { $subsection POSTPONE: DEFER: }
48 "The class of deferred word definitions:"
49 { $subsection deferred }
50 { $subsection deferred? }
51 "Deferred words throw an error when called:"
52 { $subsection undefined }
53 "Deferred words are just compound definitions in disguise. The following two lines are equivalent:"
59 ARTICLE: "declarations" "Declarations"
60 "Declarations give special behavior to a word. Declarations are parsing words that set a word property in the most recently defined word."
62 "The first declaration specifies the time when a word runs. It affects both the non-optimizing and optimizing compilers:"
63 { $subsection POSTPONE: parsing }
64 "The remaining declarations only affect definitions compiled with the optimizing compiler. 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."
65 { $warning "If a generic word is declared " { $link POSTPONE: foldable } " or " { $link POSTPONE: flushable } ", all methods must satisfy the contract, otherwise unpredicable behavior will occur." }
66 { $subsection POSTPONE: inline }
67 { $subsection POSTPONE: foldable }
68 { $subsection POSTPONE: flushable }
69 { $subsection POSTPONE: recursive }
70 "Stack effect declarations are documented in " { $link "effect-declaration" } "." ;
72 ARTICLE: "word-definition" "Defining words"
73 "There are two approaches to creating word definitions:"
75 "using parsing words at parse time,"
76 "using defining words at run time."
78 "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."
79 { $subsection "colon-definition" }
80 { $subsection "words.symbol" }
81 { $subsection "words.alias" }
82 { $subsection "primitives" }
83 { $subsection "deferred" }
84 { $subsection "declarations" }
85 "Words implement the definition protocol; see " { $link "definitions" } "." ;
87 ARTICLE: "word-props" "Word properties"
88 "Each word has a hashtable of properties."
89 { $subsection word-prop }
90 { $subsection set-word-prop }
91 "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."
93 "The following are some of the properties used by the library:"
95 { "Property" "Documentation" }
96 { { $snippet "\"parsing\"" } { $link "parsing-words" } }
98 { { { $snippet "\"inline\"" } ", " { $snippet "\"foldable\"" } ", " { $snippet "flushable" } } { $link "declarations" } }
100 { { $snippet "\"loc\"" } { "Location information - " { $link where } } }
102 { { { $snippet "\"methods\"" } ", " { $snippet "\"combination\"" } } { "Set on generic words - " { $link "generic" } } }
104 { { { $snippet "\"reading\"" } ", " { $snippet "\"writing\"" } } { "Set on slot accessor words - " { $link "slots" } } }
106 { { $snippet "\"declared-effect\"" } { $link "effect-declaration" } }
108 { { { $snippet "\"help\"" } ", " { $snippet "\"help-loc\"" } ", " { $snippet "\"help-parent\"" } } { "Where word help is stored - " { $link "writing-help" } } }
110 { { $snippet "\"infer\"" } { $link "compiler-transforms" } }
112 { { { $snippet "\"inferred-effect\"" } } { $link "inference" } }
114 { { $snippet "\"specializer\"" } { $link "hints" } }
116 { { $snippet "\"predicating\"" } " Set on class predicates, stores the corresponding class word" }
118 "Properties which are defined for classes only:"
120 { "Property" "Documentation" }
121 { { $snippet "\"class\"" } { "A boolean indicating whether this word is a class - " { $link "classes" } } }
123 { { $snippet "\"coercer\"" } { "A quotation for converting the top of the stack to an instance of this class" } }
125 { { $snippet "\"constructor\"" } { $link "tuple-constructors" } }
127 { { $snippet "\"type\"" } { $link "builtin-classes" } }
129 { { { $snippet "\"superclass\"" } ", " { $snippet "\"predicate-definition\"" } } { $link "predicates" } }
131 { { $snippet "\"members\"" } { $link "unions" } }
133 { { $snippet "\"slots\"" } { $link "slots" } }
135 { { $snippet "\"predicate\"" } { "A quotation that tests if the top of the stack is an instance of this class - " { $link "class-predicates" } } }
138 ARTICLE: "word.private" "Word implementation details"
139 "The " { $snippet "def" } " slot of a word holds a " { $link quotation } " instance that is called when the word is executed."
141 "An " { $emphasis "XT" } " (execution token) is the machine code address of a word:"
142 { $subsection word-xt } ;
144 ARTICLE: "words" "Words"
145 "Words are the Factor equivalent of functions or procedures; a word is essentially a named quotation."
147 "Word introspection facilities and implementation details are found in the " { $vocab-link "words" } " vocabulary."
149 "Word objects contain several slots:"
151 { { $snippet "name" } "a word name" }
152 { { $snippet "vocabulary" } "a word vocabulary name" }
153 { { $snippet "def" } "a definition quotation" }
154 { { $snippet "props" } "an assoc of word properties, including documentation and other meta-data" }
156 "Words are instances of a class."
158 { $subsection word? }
159 { $subsection "interned-words" }
160 { $subsection "uninterned-words" }
161 { $subsection "word-definition" }
162 { $subsection "word-props" }
163 { $subsection "word.private" }
164 { $see-also "vocabularies" "vocabs.loader" "definitions" } ;
168 HELP: execute ( word -- )
169 { $values { "word" word } }
170 { $description "Executes a word." }
172 { $example "USING: kernel io words ;" "IN: scratchpad" ": twice dup execute execute ;\n: hello \"Hello\" print ;\n\\ hello twice" "Hello\nHello" }
176 { $class-description "The class of deferred words created by " { $link POSTPONE: DEFER: } "." } ;
178 { deferred POSTPONE: DEFER: } related-words
181 { $description "The class of primitive words." } ;
184 { $values { "word" word } { "name" "a property name" } { "value" "a property value" } }
185 { $description "Retrieves a word property. Word property names are conventionally strings." } ;
188 { $values { "word" word } { "value" "a property value" } { "name" "a property name" } }
189 { $description "Stores a word property. Word property names are conventionally strings." }
190 { $side-effects "word" } ;
192 HELP: remove-word-prop
193 { $values { "word" word } { "name" "a property name" } }
194 { $description "Removes a word property, so future lookups will output " { $link f } " until it is set again. Word property names are conventionally strings." }
195 { $side-effects "word" } ;
197 HELP: word-xt ( word -- start end )
198 { $values { "word" word } { "start" "the word's start address" } { "end" "the word's end address" } }
199 { $description "Outputs the machine code address of the word's definition." } ;
202 { $values { "word" word } { "def" quotation } }
203 { $description "Defines the word to call a quotation when executed. This is the run time equivalent of " { $link POSTPONE: : } "." }
204 { $notes "This word must be called from inside " { $link with-compilation-unit } "." }
205 { $side-effects "word" } ;
208 { $values { "word" word } { "seq" "a sequence of word property names" } }
209 { $description "Removes all listed word properties from the word." }
210 { $side-effects "word" } ;
213 { $values { "word" word } }
214 { $description "Reset word declarations." }
216 { $side-effects "word" } ;
219 { $values { "word" word } }
220 { $description "Reset word declarations and generic word properties." }
222 { $side-effects "word" } ;
224 HELP: <word> ( name vocab -- word )
225 { $values { "name" string } { "vocab" string } { "word" word } }
226 { $description "Allocates an uninterned word with the specified name and vocabulary, and a blank word property hashtable. User code should call " { $link gensym } " to create uninterned words and " { $link create } " to create interned words." } ;
229 { $values { "word" word } }
230 { $description "Creates an uninterned word that is not equal to any other word in the system." }
231 { $examples { $unchecked-example "gensym ." "G:260561" } }
232 { $notes "Gensyms are often used as placeholder values that have no meaning of their own but must be unique. For example, the compiler uses gensyms to label sections of code." } ;
235 { $var-description "Set by the library while bootstrap is in progress. Some parsing words need to behave differently during bootstrap." } ;
238 { $values { "word" word } }
239 { $description "Outputs the most recently defined word." }
240 { $class-description "The class of words. One notable subclass is " { $link class } ", the class of class words." } ;
242 { word set-word save-location } related-words
245 { $values { "word" word } }
246 { $description "Sets the recently defined word." } ;
249 { $values { "name" string } { "vocab" string } { "word" "a word or " { $link f } } }
250 { $description "Looks up a word in the dictionary. If the vocabulary or the word is not defined, outputs " { $link f } "." } ;
253 { $values { "word" word } }
254 { $description "Adds a newly-created word to the dictionary. Usually this word does not need to be called directly, and is only called as part of " { $link create } "." } ;
257 { $values { "name" string } { "vocab" string } }
258 { $description "Throws a " { $link check-create } " error if " { $snippet "name" } " or " { $snippet "vocab" } " is not a string." }
259 { $error-description "Thrown if " { $link create } " is called with invalid parameters." } ;
262 { $values { "name" string } { "vocab" string } { "word" word } }
263 { $description "Creates a new word. If the vocabulary already contains a word with the requested name, outputs the existing word. The vocabulary must exist already; if it does not, you must call " { $link create-vocab } " first." } ;
265 HELP: constructor-word
266 { $values { "name" string } { "vocab" string } { "word" word } }
267 { $description "Creates a new word, surrounding " { $snippet "name" } " in angle brackets." }
268 { $examples { $example "USING: prettyprint words ;" "\"salmon\" \"scratchpad\" constructor-word ." "<salmon>" } } ;
270 { POSTPONE: FORGET: forget forget* forget-vocab } related-words
273 { $values { "word" word } { "target" word } }
274 { $description "Looks up a word with the same name and vocabulary as the given word. Used during bootstrap to transfer host words to the target dictionary." } ;
277 { $values { "word" word } { "target" word } }
278 { $description "Looks up a word with the same name and vocabulary as the given word, performing a transformation to handle parsing words in the target dictionary. Used during bootstrap to transfer host words to the target dictionary." } ;
280 HELP: parsing-word? ( obj -- ? )
281 { $values { "obj" object } { "?" "a boolean" } }
282 { $description "Tests if an object is a parsing word declared by " { $link POSTPONE: parsing } "." }
283 { $notes "Outputs " { $link f } " if the object is not a word." } ;
285 HELP: define-declared
286 { $values { "word" word } { "def" quotation } { "effect" effect } }
287 { $description "Defines a word and declares its stack effect." }
288 { $side-effects "word" } ;
291 { $values { "quot" quotation } { "word" word } }
292 { $description "Creates an uninterned word that will call " { $snippet "quot" } " when executed." }
294 "The following phrases are equivalent:"
295 { $code "[ 2 2 + . ] call" }
296 { $code "[ 2 2 + . ] define-temp execute" }
297 "This word must be called from inside " { $link with-compilation-unit } "."
301 { $values { "quot" quotation } { "assoc" "an assoc with words as keys" } }
302 { $description "Outputs a set of words referenced by the quotation and any quotations it contains." } ;
305 { $values { "obj" object } { "?" "a boolean" } }
306 { $description "Tests if an object is a delimiter word declared by " { $link POSTPONE: delimiter } "." }
307 { $notes "Outputs " { $link f } " if the object is not a word." } ;
310 { $values { "word" word } }
311 { $description "Declares a word as " { $link POSTPONE: flushable } "." }
312 { $side-effects "word" } ;
315 { $values { "word" word } }
316 { $description "Declares a word as " { $link POSTPONE: foldable } "." }
317 { $side-effects "word" } ;
320 { $values { "word" word } }
321 { $description "Declares a word as " { $link POSTPONE: inline } "." }
322 { $side-effects "word" } ;
325 { $values { "word" word } { "def" quotation } { "effect" effect } }
326 { $description "Defines a word and makes it " { $link POSTPONE: inline } "." }
327 { $side-effects "word" } ;