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 create 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 { "Property" "Documentation" }
95 { { $snippet "\"parsing\"" } { $link "parsing-words" } }
97 { { { $snippet "\"inline\"" } ", " { $snippet "\"foldable\"" } ", " { $snippet "flushable" } } { $link "declarations" } }
99 { { $snippet "\"loc\"" } { "Location information - " { $link where } } }
101 { { { $snippet "\"methods\"" } ", " { $snippet "\"combination\"" } } { "Set on generic words - " { $link "generic" } } }
103 { { { $snippet "\"reading\"" } ", " { $snippet "\"writing\"" } } { "Set on slot accessor words - " { $link "slots" } } }
105 { { $snippet "\"declared-effect\"" } { $link "effects" } }
107 { { { $snippet "\"help\"" } ", " { $snippet "\"help-loc\"" } ", " { $snippet "\"help-parent\"" } } { "Where word help is stored - " { $link "writing-help" } } }
109 { { $snippet "\"specializer\"" } { $link "hints" } }
111 { { $snippet "\"predicating\"" } " Set on class predicates, stores the corresponding class word" }
113 "Properties which are defined for classes only:"
115 { "Property" "Documentation" }
116 { { $snippet "\"class\"" } { "A boolean indicating whether this word is a class - " { $link "classes" } } }
118 { { $snippet "\"coercer\"" } { "A quotation for converting the top of the stack to an instance of this class" } }
120 { { $snippet "\"constructor\"" } { $link "tuple-constructors" } }
122 { { $snippet "\"type\"" } { $link "builtin-classes" } }
124 { { { $snippet "\"superclass\"" } ", " { $snippet "\"predicate-definition\"" } } { $link "predicates" } }
126 { { $snippet "\"members\"" } { $link "unions" } }
128 { { $snippet "\"slots\"" } { $link "slots" } }
130 { { $snippet "\"predicate\"" } { "A quotation that tests if the top of the stack is an instance of this class - " { $link "class-predicates" } } }
133 ARTICLE: "word.private" "Word implementation details"
134 "The " { $snippet "def" } " slot of a word holds a " { $link quotation } " instance that is called when the word is executed."
136 "A primitive to get the memory range storing the machine code for a word:"
137 { $subsections word-code } ;
139 ARTICLE: "words.introspection" "Word introspection"
140 "Word introspection facilities and implementation details are found in the " { $vocab-link "words" } " vocabulary."
142 "Word objects contain several slots:"
144 { { $snippet "name" } "a word name" }
145 { { $snippet "vocabulary" } "a word vocabulary name" }
146 { { $snippet "def" } "a definition quotation" }
147 { { $snippet "props" } "an assoc of word properties, including documentation and other meta-data" }
149 "Words are instances of a class."
154 "Words implement the definition protocol; see " { $link "definitions" } "."
162 ARTICLE: "words" "Words"
163 "Words are the Factor equivalent of functions or procedures in other languages. Words are essentially named " { $link "quotations" } "."
165 "There are two ways of creating word definitions:"
167 "using parsing words at parse time."
168 "using defining words at run time."
170 "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."
184 "words.introspection"
186 { $see-also "vocabularies" "vocabs.loader" "definitions" "see" } ;
191 { $class-description "The class of deferred words created by " { $link POSTPONE: DEFER: } "." } ;
193 { deferred POSTPONE: DEFER: } related-words
196 { $error-description "This error is thrown in two cases, and the debugger's summary message reflects the cause:"
198 { "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." }
199 { "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." }
204 { $description "The class of primitive words." } ;
207 { $values { "word" word } { "name" "a property name" } { "value" "a property value" } }
208 { $description "Retrieves a word property. Word property names are conventionally strings." } ;
211 { $values { "word" word } { "value" "a property value" } { "name" "a property name" } }
212 { $description "Stores a word property. Word property names are conventionally strings." }
213 { $side-effects "word" } ;
215 HELP: remove-word-prop
216 { $values { "word" word } { "name" "a property name" } }
217 { $description "Removes a word property, so future lookups will output " { $link f } " until it is set again. Word property names are conventionally strings." }
218 { $side-effects "word" } ;
221 { $values { "word" word } { "start" "the word's start address" } { "end" "the word's end address" } }
222 { $description "Outputs the memory range containing the word's machine code." } ;
225 { $values { "word" word } { "def" quotation } }
226 { $description "Defines the word to call a quotation when executed. This is the run time equivalent of " { $link POSTPONE: : } "." }
227 { $notes "This word must be called from inside " { $link with-compilation-unit } "." }
228 { $side-effects "word" } ;
231 { $values { "word" word } { "seq" "a sequence of word property names" } }
232 { $description "Removes all listed word properties from the word." }
233 { $side-effects "word" } ;
236 { $values { "word" word } }
237 { $description "Reset word declarations." }
239 { $side-effects "word" } ;
242 { $values { "word" word } }
243 { $description "Reset word declarations and generic word properties." }
245 { $side-effects "word" } ;
248 { $values { "name" string } { "vocab" string } { "word" word } }
249 { $description "Allocates a word with the specified name and vocabulary. User code should call " { $link <uninterned-word> } " to create uninterned words and " { $link create } " to create interned words, instead of calling this constructor directly." }
250 { $notes "This word must be called from inside " { $link with-compilation-unit } "." } ;
252 HELP: <uninterned-word>
253 { $values { "name" string } { "word" word } }
254 { $description "Creates an uninterned word with the specified name, that is not equal to any other word in the system." }
255 { $notes "Unlike " { $link create } ", this word does not have to be called from inside " { $link with-compilation-unit } "." } ;
258 { $values { "word" word } }
259 { $description "Creates an uninterned word that is not equal to any other word in the system." }
260 { $examples { $example "USING: prettyprint words ;"
265 { $notes "Unlike " { $link create } ", this word does not have to be called from inside " { $link with-compilation-unit } "." } ;
268 { $var-description "Set by the library while bootstrap is in progress. Some parsing words need to behave differently during bootstrap." } ;
271 { $values { "word" word } }
272 { $description "Outputs the most recently defined word." } ;
275 { $class-description "The class of words. One notable subclass is " { $link class } ", the class of class words." } ;
277 { last-word set-last-word save-location } related-words
280 { $values { "word" word } }
281 { $description "Sets the recently defined word." } ;
284 { $values { "name" string } { "vocab" string } { "word" { $maybe word } } }
285 { $description "Looks up a word in the dictionary. If the vocabulary or the word is not defined, outputs " { $link f } "." } ;
288 { $values { "word" word } }
289 { $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 } "." } ;
292 { $values { "name" string } { "vocab" string } }
293 { $description "Throws a " { $link check-create } " error if " { $snippet "name" } " or " { $snippet "vocab" } " is not a string." }
294 { $error-description "Thrown if " { $link create } " is called with invalid parameters." } ;
297 { $values { "name" string } { "vocab" string } { "word" word } }
298 { $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." }
299 { $notes "This word must be called from inside " { $link with-compilation-unit } ". Parsing words should call " { $link create-in } " instead of this word." } ;
301 HELP: constructor-word
302 { $values { "name" string } { "vocab" string } { "word" word } }
303 { $description "Creates a new word, surrounding " { $snippet "name" } " in angle brackets." }
304 { $notes "This word must be called from inside " { $link with-compilation-unit } "." }
305 { $examples { $example "USING: compiler.units prettyprint words ;" "[ \"salmon\" \"scratchpad\" constructor-word ] with-compilation-unit ." "<salmon>" } } ;
307 { POSTPONE: FORGET: forget forget* forget-vocab } related-words
310 { $values { "word" word } { "target" word } }
311 { $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." } ;
314 { $values { "word" word } { "target" word } }
315 { $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." } ;
318 { $values { "object" object } { "?" boolean } }
319 { $description "Tests if an object is a parsing word declared by " { $link POSTPONE: SYNTAX: } "." }
320 { $notes "Outputs " { $link f } " if the object is not a word." } ;
322 HELP: define-declared
323 { $values { "word" word } { "def" quotation } { "effect" effect } }
324 { $description "Defines a word and declares its stack effect." }
325 { $notes "This word must be called from inside " { $link with-compilation-unit } "." }
326 { $side-effects "word" } ;
329 { $values { "quot" quotation } { "effect" effect } { "word" word } }
330 { $description "Creates an uninterned word that will call " { $snippet "quot" } " when executed." }
332 "The following phrases are equivalent:"
333 { $code "[ 2 2 + . ] call" }
334 { $code "[ 2 2 + . ] ( -- ) define-temp execute" }
335 "This word must be called from inside " { $link with-compilation-unit } "."
339 { $values { "obj" object } { "?" boolean } }
340 { $description "Tests if an object is a delimiter word declared by " { $link POSTPONE: delimiter } "." }
341 { $notes "Outputs " { $link f } " if the object is not a word." } ;
344 { $values { "obj" object } { "?" boolean } }
345 { $description "Tests if an object is " { $link POSTPONE: deprecated } "." }
346 { $notes "Outputs " { $link f } " if the object is not a word." } ;
349 { $values { "word" word } { "seq" sequence } }
350 { $description "Lists all specializations for the given word." }
353 "USING: math.functions prettyprint words ;"
355 "{ M\\ object sin M\\ complex sin M\\ real sin M\\ float sin }"
358 { $notes "Outputs " { $link f } " if the word isn't generic." } ;
360 HELP: make-deprecated
361 { $values { "word" word } }
362 { $description "Declares a word as " { $link POSTPONE: deprecated } "." }
363 { $side-effects "word" } ;
366 { $values { "word" word } }
367 { $description "Declares a word as " { $link POSTPONE: flushable } "." }
368 { $side-effects "word" } ;
371 { $values { "word" word } }
372 { $description "Declares a word as " { $link POSTPONE: foldable } "." }
373 { $side-effects "word" } ;
376 { $values { "word" word } }
377 { $description "Declares a word as " { $link POSTPONE: inline } "." }
378 { $side-effects "word" } ;
381 { $values { "word" word } { "def" quotation } { "effect" effect } }
382 { $description "Defines a word and makes it " { $link POSTPONE: inline } "." }
383 { $notes "This word must be called from inside " { $link with-compilation-unit } "." }
384 { $side-effects "word" } ;