1 USING: classes compiler.units definitions effects help.markup
2 help.syntax kernel parser quotations sequences strings vocabs ;
5 ARTICLE: "interned-words" "Looking up and creating words"
6 "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" } "."
8 "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 look up words dynamically."
10 "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 "word-search" } ")."
17 ARTICLE: "uninterned-words" "Uninterned words"
18 "A word that is not a member of any vocabulary is said to be " { $emphasis "uninterned" } "."
20 "There are several ways of creating an uninterned word:"
28 ARTICLE: "colon-definition" "Colon definitions"
29 "All words have associated definition " { $link "quotations" } ". A word's definition quotation is called when the word is executed. A " { $emphasis "colon definition" } " is a word where this quotation is supplied directly by the user. This is the simplest and most common type of word definition."
31 "Defining words at parse time:"
36 "Defining words at run time:"
42 "Word definitions must declare their stack effect. See " { $link "effects" } "."
44 "All other types of word definitions, such as " { $link "words.symbol" } " and " { $link "generic" } ", are just special cases of the above." ;
46 ARTICLE: "primitives" "Primitives"
47 "Primitives are words defined in the Factor VM. They provide the essential low-level services to the rest of the system."
53 ARTICLE: "deferred" "Deferred words and mutual recursion"
54 "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."
56 "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."
57 { $subsections POSTPONE: DEFER: }
58 "The class of deferred word definitions:"
63 "Deferred words throw an error when called:"
64 { $subsections undefined }
65 "Deferred words are just compound definitions in disguise. The following two lines are equivalent:"
68 ": foo ( -- * ) undefined ;"
71 ARTICLE: "declarations" "Compiler declarations"
72 "Compiler declarations are parsing words that set a word property in the most recently defined word. They appear after the final " { $link POSTPONE: ; } " of a word definition:"
73 { $code ": cubed ( x -- y ) dup dup * * ; foldable" }
74 "Compiler declarations assert that the word follows a certain contract, enabling certain optimizations that are not valid in general."
81 "It is entirely up to the programmer to ensure that the word satisfies the contract of a declaration. Furthermore, if a generic word is declared " { $link POSTPONE: foldable } " or " { $link POSTPONE: flushable } ", all methods must satisfy the contract. Unspecified behavior may result if a word does not follow the contract of one of its declarations."
82 { $see-also "effects" } ;
84 ARTICLE: "word-props" "Word properties"
85 "Each word has a hashtable of properties."
90 "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."
92 "The following are some of the properties used by the library:"
94 { { $strong "Property" } { $strong "Documentation" } }
96 { $snippet "\"declared-effect\"" } { $link "effects" }
100 { $snippet "\"inline\"" } ", "
101 { $snippet "\"foldable\"" } ", "
102 { $snippet "\"flushable\"" } ", "
103 { $snippet "\"recursive\"" }
105 { $link "declarations" }
109 { $snippet "\"help\"" } ", "
110 { $snippet "\"help-loc\"" } ", "
111 { $snippet "\"help-parent\"" }
113 { "Where word help is stored - " { $link "writing-help" } }
116 { $snippet "\"intrinsic\"" }
117 { "Quotation run by the compiler during cfg building to emit the word inline." }
120 { $snippet "\"loc\"" }
121 { "Location information - " { $link where } }
124 { { $snippet "\"methods\"" } ", " { $snippet "\"combination\"" } }
125 { "Set on generic words - " { $link "generic" } }
129 { $snippet "\"outputs\"" } ", "
130 { $snippet "\"input-classes\"" } ", "
131 { $snippet "\"default-output-classes\"" }
133 { "A bunch of metadata used during the value propagation step of the compilation to produce type-optimized code." }
136 { $snippet "\"parsing\"" }
137 { $link "parsing-words" }
140 { $snippet "\"predicating\"" }
141 "Set on class predicates, stores the corresponding class word."
144 { { $snippet "\"reading\"" } ", " { $snippet "\"writing\"" } }
145 { "Set on slot accessor words - " { $link "slots" } }
148 { $snippet "\"specializer\"" }
153 { $snippet "\"dependencies\"" } ", "
156 { "Used by the optimizing compiler when forgetting words for fast dependency lookup. See " { $link "compilation-units" } "." }
159 { $snippet "\"generic-call-sites\"" }
160 { "Set on some generic words." }
163 "Properties which are defined for classes only:"
165 { { $strong "Property" } { $strong "Documentation" } }
166 { { $snippet "\"class\"" } { "A boolean indicating whether this word is a class - " { $link "classes" } } }
168 { { $snippet "\"coercer\"" } { "A quotation for converting the top of the stack to an instance of this class" } }
170 { { $snippet "\"constructor\"" } { $link "tuple-constructors" } }
172 { { $snippet "\"type\"" } { $link "builtin-classes" } }
174 { { { $snippet "\"superclass\"" } ", " { $snippet "\"predicate-definition\"" } } { $link "predicates" } }
176 { { $snippet "\"members\"" } { $link "unions" } { $link "maybes" } }
178 { $snippet "\"instances\"" }
179 { "Lists the instances of the mixin class and where they are defined - " { $link "mixins" } }
182 { $snippet "\"predicate\"" }
183 { "A quotation that tests if the top of the stack is an instance of this class - " { $link "class-predicates" } }
185 { { $snippet "\"slots\"" } { $link "slots" } }
188 { $snippet "\"superclass\"" } ", "
189 { $snippet "\"predicate-definition\"" }
191 { $link "predicates" }
193 { { $snippet "\"type\"" } { $link "builtin-classes" } }
196 ARTICLE: "word.private" "Word implementation details"
197 "The " { $snippet "def" } " slot of a word holds a " { $link quotation } " instance that is called when the word is executed."
199 "A primitive to get the memory range storing the machine code for a word:"
200 { $subsections word-code } ;
202 ARTICLE: "words.introspection" "Word introspection"
203 "Word introspection facilities and implementation details are found in the " { $vocab-link "words" } " vocabulary."
205 "Word objects contain several slots:"
207 { { $snippet "name" } "a word name" }
208 { { $snippet "vocabulary" } "a word vocabulary name" }
209 { { $snippet "def" } "a definition quotation" }
210 { { $snippet "props" } "an assoc of word properties, including documentation and other metadata" }
212 "Words are instances of a class."
217 "Words implement the definition protocol; see " { $link "definitions" } "."
225 ARTICLE: "words" "Words"
226 "Words are the Factor equivalent of functions or procedures in other languages. Words are essentially named " { $link "quotations" } "."
228 "There are two ways of creating word definitions:"
230 "using parsing words at parse time."
231 "using defining words at run time."
233 "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."
247 "words.introspection"
250 { $see-also "vocabularies" "vocabs.loader" "definitions" "see" } ;
255 { $values { "word" word } }
256 { $description "Signals to the compilation unit that the effect of the word has changed. It causes all words that depend on it to be recompiled in response." }
257 { $see-also changed-effects } ;
260 { $class-description "The class of deferred words created by " { $link POSTPONE: DEFER: } "." } ;
262 { deferred POSTPONE: DEFER: } related-words
265 { $error-description "This error is thrown in two cases, and the debugger's summary message reflects the cause:"
267 { "A word was executed before being compiled. For example, this can happen if a macro is defined in the same compilation unit where it was used. See " { $link "compilation-units" } " for a discussion." }
268 { "A word defined with " { $link POSTPONE: DEFER: } " was executed. Since this syntax is usually used for mutually-recursive word definitions, executing a deferred word usually indicates a programmer mistake." }
273 { $class-description "The class of primitive words." } ;
276 { $values { "word" word } { "name" "a property name" } { "value" "a property value" } }
277 { $description "Retrieves a word property. Word property names are conventionally strings." } ;
280 { $values { "word" word } { "value" "a property value" } { "name" "a property name" } }
281 { $description "Stores a word property. Word property names are conventionally strings." }
282 { $side-effects "word" } ;
284 HELP: remove-word-prop
285 { $values { "word" word } { "name" "a property name" } }
286 { $description "Removes a word property, so future lookups will output " { $link f } " until it is set again. Word property names are conventionally strings." }
287 { $side-effects "word" } ;
289 HELP: remove-word-props
290 { $values { "word" word } { "seq" { $sequence "word property names" } } }
291 { $description "Removes all listed word properties from the word." }
292 { $side-effects "word" } ;
295 { $values { "word" word } { "start" "the word's start address" } { "end" "the word's end address" } }
296 { $description "Outputs the memory range containing the word's machine code." } ;
299 { $values { "word" word } { "def" quotation } }
300 { $description "Defines the word to call a quotation when executed. This is the run time equivalent of " { $link POSTPONE: : } "." }
301 { $notes "This word must be called from inside " { $link with-compilation-unit } "." }
302 { $side-effects "word" } ;
305 { $values { "word" word } }
306 { $description "Reset word declarations." }
308 { $side-effects "word" } ;
311 { $values { "word" word } }
312 { $description "Reset word declarations and generic word properties." }
314 { $side-effects "word" } ;
317 { $values { "name" string } { "vocab" string } { "word" word } }
318 { $description "Allocates a word with the specified name and vocabulary. User code should call " { $link <uninterned-word> } " to create uninterned words and " { $link create-word } " to create interned words, instead of calling this constructor directly." }
319 { $notes "This word must be called from inside " { $link with-compilation-unit } "." } ;
321 HELP: <uninterned-word>
322 { $values { "name" string } { "word" word } }
323 { $description "Creates an uninterned word with the specified name, that is not equal to any other word in the system." }
324 { $notes "Unlike " { $link create-word } ", this word does not have to be called from inside " { $link with-compilation-unit } "." } ;
327 { $values { "word" word } }
328 { $description "Creates an uninterned word that is not equal to any other word in the system." }
329 { $examples { $example "USING: prettyprint words ;"
334 { $notes "Unlike " { $link create-word } ", this word does not have to be called from inside " { $link with-compilation-unit } "." } ;
337 { $var-description "Set by the library while bootstrap is in progress. Some parsing words need to behave differently during bootstrap." } ;
340 { $values { "word" word } }
341 { $description "Outputs the most recently defined word." } ;
344 { $class-description "The class of words. One notable subclass is " { $link class } ", the class of class words." } ;
346 { last-word set-last-word save-location } related-words
349 { $values { "word" word } }
350 { $description "Sets the recently defined word." } ;
353 { $values { "name" string } { "vocab" string } { "word" { $maybe word } } }
354 { $description "Looks up a word in the dictionary. If the vocabulary or the word is not defined, outputs " { $link f } "." } ;
357 { $values { "word" word } }
358 { $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-word } "." } ;
361 { $values { "name" string } { "vocab" string } }
362 { $description "Throws a " { $link check-create } " error if " { $snippet "name" } " or " { $snippet "vocab" } " is not a string." }
363 { $error-description "Thrown if " { $link create-word } " is called with invalid parameters." } ;
366 { $values { "name" string } { "vocab" string } { "word" word } }
367 { $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." }
368 { $notes "This word must be called from inside " { $link with-compilation-unit } ". Parsing words should call " { $link create-word-in } " instead of this word." } ;
370 { POSTPONE: FORGET: forget forget* forget-vocab } related-words
373 { $values { "word" word } { "target" word } }
374 { $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." } ;
377 { $values { "word" word } { "target" word } }
378 { $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." } ;
381 { $values { "object" object } { "?" boolean } }
382 { $description "Tests if an object is a parsing word declared by " { $link POSTPONE: SYNTAX: } "." }
383 { $notes "Outputs " { $link f } " if the object is not a word." } ;
385 HELP: define-declared
386 { $values { "word" word } { "def" quotation } { "effect" effect } }
387 { $description "Defines a word and declares its stack effect." }
388 { $notes "This word must be called from inside " { $link with-compilation-unit } "." }
389 { $side-effects "word" } ;
392 { $values { "quot" quotation } { "effect" effect } { "word" word } }
393 { $description "Creates an uninterned word that will call " { $snippet "quot" } " when executed." }
395 "The following phrases are equivalent:"
396 { $code "[ 2 2 + . ] call" }
397 { $code "[ 2 2 + . ] ( -- ) define-temp execute" }
398 "This word must be called from inside " { $link with-compilation-unit } "."
402 { $values { "obj" object } { "?" boolean } }
403 { $description "Tests if an object is a delimiter word declared by " { $link POSTPONE: delimiter } "." }
404 { $notes "Outputs " { $link f } " if the object is not a word." } ;
407 { $values { "obj" object } { "?" boolean } }
408 { $description "Tests if an object is " { $link POSTPONE: deprecated } "." }
409 { $notes "Outputs " { $link f } " if the object is not a word." } ;
412 { $values { "obj" object } { "?" boolean } }
413 { $description "Tests if an object is " { $link POSTPONE: inline } "." }
414 { $notes "Outputs " { $link f } " if the object is not a word." } ;
417 { $values { "word" word } { "seq" sequence } }
418 { $description "Lists all specializations for the given word." }
421 "USING: math.functions prettyprint words ;"
423 "{ M\\ object sin M\\ complex sin M\\ real sin M\\ float sin }"
426 { $notes "Outputs " { $link f } " if the word isn't generic." } ;
428 HELP: make-deprecated
429 { $values { "word" word } }
430 { $description "Declares a word as " { $link POSTPONE: deprecated } "." }
431 { $side-effects "word" } ;
434 { $values { "word" word } }
435 { $description "Declares a word as " { $link POSTPONE: flushable } "." }
436 { $side-effects "word" } ;
439 { $values { "word" word } }
440 { $description "Declares a word as " { $link POSTPONE: foldable } "." }
441 { $side-effects "word" } ;
444 { $values { "word" word } }
445 { $description "Declares a word as " { $link POSTPONE: inline } "." }
446 { $side-effects "word" } ;
449 { $values { "word" word } { "def" quotation } { "effect" effect } }
450 { $description "Defines a word and makes it " { $link POSTPONE: inline } "." }
451 { $notes "This word must be called from inside " { $link with-compilation-unit } "." }
452 { $side-effects "word" } ;