]> gitweb.factorcode.org Git - factor.git/blob - core/syntax/syntax-docs.factor
c2eb411f0a727657098acff3f4861cb8d3ad61c9
[factor.git] / core / syntax / syntax-docs.factor
1 USING: generic help.syntax help.markup kernel math parser words
2 effects classes generic.standard classes.tuple generic.math
3 generic.standard arrays io.files vocabs.loader io sequences
4 assocs ;
5 IN: syntax
6
7 ARTICLE: "parser-algorithm" "Parser algorithm"
8 "At the most abstract level, Factor syntax consists of whitespace-separated tokens. The parser tokenizes the input on whitespace boundaries.  The parser is case-sensitive and whitespace between tokens is significant, so the following three expressions tokenize differently:"
9 { $code "2X+\n2 X +\n2 x +" }
10 "As the parser reads tokens it makes a distinction between numbers, ordinary words, and parsing words. Tokens are appended to the parse tree, the top level of which is a quotation returned by the original parser invocation. Nested levels of the parse tree are created by parsing words."
11 $nl
12 "The parser iterates through the input text, checking each character in turn. Here is the parser algorithm in more detail -- some of the concepts therein will be defined shortly:"
13 { $list
14     { "If the current character is a double-quote (\"), the " { $link POSTPONE: " } " parsing word is executed, causing a string to be read." }
15     {
16         "Otherwise, the next token is taken from the input. The parser searches for a word named by the token in the currently used set of vocabularies. If the word is found, one of the following two actions is taken:"
17         { $list
18             "If the word is an ordinary word, it is appended to the parse tree."
19             "If the word is a parsing word, it is executed."
20         }
21     }
22     "Otherwise if the token does not represent a known word, the parser attempts to parse it as a number. If the token is a number, the number object is added to the parse tree. Otherwise, an error is raised and parsing halts."
23 }
24 "Parsing words play a key role in parsing; while ordinary words and numbers are simply added to the parse tree, parsing words execute in the context of the parser, and can do their own parsing and create nested data structures in the parse tree. Parsing words are also able to define new words."
25 $nl
26 "While parsing words supporting arbitrary syntax can be defined, the default set is found in the " { $vocab-link "syntax" } " vocabulary and provides the basis for all further syntactic interaction with Factor." ;
27
28 ARTICLE: "syntax-comments" "Comments"
29 { $subsection POSTPONE: ! }
30 { $subsection POSTPONE: #! } ;
31
32 ARTICLE: "syntax-immediate" "Parse time evaluation"
33 "Code can be evaluated at parse time. This is a rarely-used feature; one use-case is " { $link "loading-libs" } ", where you want to execute some code before the words in a source file are compiled."
34 { $subsection POSTPONE: << }
35 { $subsection POSTPONE: >> } ;
36
37 ARTICLE: "syntax-integers" "Integer syntax"
38 "The printed representation of an integer consists of a sequence of digits, optionally prefixed by a sign."
39 { $code
40     "123456"
41     "-10"
42     "2432902008176640000"
43 }
44 "Integers are entered in base 10 unless prefixed with a base change parsing word."
45 { $subsection POSTPONE: BIN: }
46 { $subsection POSTPONE: OCT: }
47 { $subsection POSTPONE: HEX: }
48 "More information on integers can be found in " { $link "integers" } "." ;
49
50 ARTICLE: "syntax-ratios" "Ratio syntax"
51 "The printed representation of a ratio is a pair of integers separated by a slash (/), prefixed by an optional whole number part followed by a plus (+). No intermediate whitespace is permitted. Here are some examples:"
52 { $code
53     "75/33"
54     "1/10"
55     "-5/-6"
56     "1+1/3"
57     "-10+1/7"
58 }
59 "More information on ratios can be found in " { $link "rationals" } ;
60
61 ARTICLE: "syntax-floats" "Float syntax"
62 "Floating point literals must contain a decimal point, and may contain an exponent:"
63 { $code
64     "10.5"
65     "-3.1456"
66     "7.e13"
67     "1.0e-5"
68 }
69 "More information on floats can be found in " { $link "floats" } "." ;
70
71 ARTICLE: "syntax-complex-numbers" "Complex number syntax"
72 "A complex number is given by two components, a ``real'' part and ''imaginary'' part. The components must either be integers, ratios or floats."
73 { $code
74     "C{ 1/2 1/3 }   ! the complex number 1/2+1/3i"
75     "C{ 0 1 }       ! the imaginary unit"
76 }
77 { $subsection POSTPONE: C{ }
78 "More information on complex numbers can be found in " { $link "complex-numbers" } "." ;
79
80 ARTICLE: "syntax-numbers" "Number syntax"
81 "If a vocabulary lookup of a token fails, the parser attempts to parse it as a number."
82 { $subsection "syntax-integers" }
83 { $subsection "syntax-ratios" }
84 { $subsection "syntax-floats" }
85 { $subsection "syntax-complex-numbers" } ;
86
87 ARTICLE: "syntax-words" "Word syntax"
88 "A word occurring inside a quotation is executed when the quotation is called. Sometimes a word needs to be pushed on the data stack instead. The canonical use-case for this is passing the word to the " { $link execute } " combinator, or alternatively, reflectively accessing word properties (" { $link "word-props" } ")."
89 { $subsection POSTPONE: \ }
90 { $subsection POSTPONE: POSTPONE: }
91 "The implementation of the " { $link POSTPONE: \ } " word is discussed in detail in " { $link "reading-ahead" } ". Words are documented in " { $link "words" } "." ;
92
93 ARTICLE: "escape" "Character escape codes"
94 { $table
95     { "Escape code" "Meaning" }
96     { { $snippet "\\\\" } { $snippet "\\" } }
97     { { $snippet "\\s" } "a space" }
98     { { $snippet "\\t" } "a tab" }
99     { { $snippet "\\n" } "a newline" }
100     { { $snippet "\\r" } "a carriage return" }
101     { { $snippet "\\0" } "a null byte (ASCII 0)" }
102     { { $snippet "\\e" } "escape (ASCII 27)" }
103     { { $snippet "\\\"" } { $snippet "\"" } }
104     { { $snippet "\\u" { $emphasis "xxxxxx" } } { "The Unicode code point with hexadecimal number " { $snippet { $emphasis "xxxxxx" } } } }
105     { { $snippet "\\u{" { $emphasis "name" } "}" } { "The Unicode code point named " { $snippet { $emphasis "name" } } } }
106 } ;
107
108 ARTICLE: "syntax-strings" "Character and string syntax"
109 "Factor has no distinct character type, however Unicode character value integers can be read by specifying a literal character, or an escaped representation thereof."
110 { $subsection POSTPONE: CHAR: }
111 { $subsection POSTPONE: " }
112 { $subsection "escape" }
113 "Strings are documented in " { $link "strings" } "." ;
114
115 ARTICLE: "syntax-sbufs" "String buffer syntax"
116 { $subsection POSTPONE: SBUF" }
117 "String buffers are documented in " { $link "sbufs" } "." ;
118
119 ARTICLE: "syntax-arrays" "Array syntax"
120 { $subsection POSTPONE: { }
121 { $subsection POSTPONE: } }
122 "Arrays are documented in " { $link "arrays" } "." ;
123
124 ARTICLE: "syntax-vectors" "Vector syntax"
125 { $subsection POSTPONE: V{ }
126 "Vectors are documented in " { $link "vectors" } "." ;
127
128 ARTICLE: "syntax-hashtables" "Hashtable syntax"
129 { $subsection POSTPONE: H{ }
130 "Hashtables are documented in " { $link "hashtables" } "." ;
131
132 ARTICLE: "syntax-tuples" "Tuple syntax"
133 { $subsection POSTPONE: T{ }
134 "Tuples are documented in " { $link "tuples" } "."  ;
135
136 ARTICLE: "syntax-quots" "Quotation syntax"
137 { $subsection POSTPONE: [ }
138 { $subsection POSTPONE: ] }
139 "Quotations are documented in " { $link "quotations" } "." ;
140
141 ARTICLE: "syntax-bit-arrays" "Bit array syntax"
142 { $subsection POSTPONE: ?{ }
143 "Bit arrays are documented in " { $link "bit-arrays" } "." ;
144
145 ARTICLE: "syntax-float-arrays" "Float array syntax"
146 { $subsection POSTPONE: F{ }
147 "Float arrays are documented in " { $link "float-arrays" } "." ;
148
149 ARTICLE: "syntax-byte-arrays" "Byte array syntax"
150 { $subsection POSTPONE: B{ }
151 "Byte arrays are documented in " { $link "byte-arrays" } "." ;
152
153 ARTICLE: "syntax-bit-vectors" "Bit vector syntax"
154 { $subsection POSTPONE: ?V{ }
155 "Bit vectors are documented in " { $link "bit-vectors" } "." ;
156
157 ARTICLE: "syntax-float-vectors" "Float vector syntax"
158 { $subsection POSTPONE: FV{ }
159 "Float vectors are documented in " { $link "float-vectors" } "." ;
160
161 ARTICLE: "syntax-byte-vectors" "Byte vector syntax"
162 { $subsection POSTPONE: BV{ }
163 "Byte vectors are documented in " { $link "byte-vectors" } "." ;
164
165 ARTICLE: "syntax-pathnames" "Pathname syntax"
166 { $subsection POSTPONE: P" }
167 "Pathnames are documented in " { $link "pathnames" } "." ;
168
169 ARTICLE: "syntax-literals" "Literals"
170 "Many different types of objects can be constructed at parse time via literal syntax. Numbers are a special case since support for reading them is built-in to the parser. All other literals are constructed via parsing words."
171 $nl
172 "If a quotation contains a literal object, the same literal object instance is used each time the quotation executes; that is, literals are ``live''."
173 $nl
174 "Using mutable object literals in word definitions requires care, since if those objects are mutated, the actual word definition will be changed, which is in most cases not what you would expect. Literals should be " { $link clone } "d before being passed to word which may potentially mutate them."
175 { $subsection "syntax-numbers" }
176 { $subsection "syntax-words" }
177 { $subsection "syntax-quots" }
178 { $subsection "syntax-arrays" }
179 { $subsection "syntax-strings" }
180 { $subsection "syntax-bit-arrays" }
181 { $subsection "syntax-byte-arrays" }
182 { $subsection "syntax-float-arrays" }
183 { $subsection "syntax-vectors" }
184 { $subsection "syntax-sbufs" }
185 { $subsection "syntax-bit-vectors" }
186 { $subsection "syntax-byte-vectors" }
187 { $subsection "syntax-float-vectors" }
188 { $subsection "syntax-hashtables" }
189 { $subsection "syntax-tuples" }
190 { $subsection "syntax-pathnames" } ;
191
192 ARTICLE: "syntax" "Syntax"
193 "Factor has two main forms of syntax: " { $emphasis "definition" } " syntax and " { $emphasis "literal" } " syntax. Code is data, so the syntax for code is a special case of object literal syntax. This section documents literal syntax. Definition syntax is covered in " { $link "words" } ". Extending the parser is the main topic of " { $link "parser" } "."
194 { $subsection "parser-algorithm" }
195 { $subsection "syntax-comments" }
196 { $subsection "syntax-literals" }
197 { $subsection "syntax-immediate" } ;
198
199 ABOUT: "syntax"
200
201 HELP: delimiter
202 { $syntax ": foo ... ; delimiter" }
203 { $description "Declares the most recently defined word as a delimiter. Delimiters are words which are only ever valid as the end of a nested block to be read by " { $link parse-until } ". An unpaired occurrence of a delimiter is a parse error." } ;
204
205 HELP: parsing
206 { $syntax ": foo ... ; parsing" }
207 { $description "Declares the most recently defined word as a parsing word." }
208 { $examples "In the below example, the " { $snippet "world" } " word is never called, however its body references a parsing word which executes immediately:" { $example "USE: io" "<< : hello \"Hello parser!\" print ; parsing >>\n: world hello ;" "Hello parser!" } } ;
209
210 HELP: inline
211 { $syntax ": foo ... ; inline" }
212 { $description
213     "Declares the most recently defined word as an inline word. The optimizing compiler copies definitions of inline words when compiling calls to them."
214     $nl
215     "Combinators must be inlined in order to compile with the optimizing compiler - see " { $link "inference-combinators" } ". For any other word, inlining is merely an optimization."
216     $nl
217     "The non-optimizing quotation compiler ignores inlining declarations."
218 } ;
219
220 HELP: foldable
221 { $syntax ": foo ... ; foldable" }
222 { $description
223     "Declares that the most recently defined word may be evaluated at compile-time if all inputs are literal. Foldable words must satisfy a very strong contract:"
224     { $list
225         "foldable words must not have any observable side effects,"
226         "foldable words must halt - for example, a word computing a series until it coverges should not be foldable, since compilation will not halt in the event the series does not converge."
227         "both inputs and outputs of foldable words must be immutable."
228     }
229     "The last restriction ensures that words such as " { $link clone } " do not satisfy the foldable word contract. Indeed, " { $link clone } " will output a mutable object if its input is mutable, and so it is undesirable to evaluate it at compile-time, since doing so would give incorrect semantics for code that clones mutable objects and proceeds to mutate them."
230 }
231 { $notes
232     "Folding optimizations are not applied if the call site of a word is in the same source file as the word. This is a side-effect of the compilation unit system; see " { $link "compilation-units" } "."
233 }
234 { $examples "Most operations on numbers are foldable. For example, " { $snippet "2 2 +" } " compiles to a literal 4, since " { $link + } " is declared foldable." } ;
235
236 HELP: flushable
237 { $syntax ": foo ... ; flushable" }
238 { $description
239     "Declares that the most recently defined word has no side effects, and thus calls to this word may be pruned by the compiler if the outputs are not used."
240     $nl
241     "Note that many words are flushable but not foldable, for example " { $link clone } " and " { $link <array> } "."
242 } ;
243
244 HELP: t
245 { $syntax "t" }
246 { $values { "t" "the canonical truth value" } }
247 { $class-description "The canonical truth value, which is an instance of itself." } ;
248
249 HELP: f
250 { $syntax "f" }
251 { $values { "f" "the singleton false value" } }
252 { $description "The " { $link f } " parsing word adds the " { $link f } " object to the parse tree, and is also the class whose sole instance is the " { $link f } " object. The " { $link f } " object is the singleton false value, the only object that is not true. The " { $link f } " object is not equal to the " { $link f } " class word, which can be pushed on the stack using word wrapper syntax:"
253 { $code "f    ! the singleton f object denoting falsity\n\\ f  ! the f class word" } } ;
254
255 HELP: [
256 { $syntax "[ elements... ]" }
257 { $description "Marks the beginning of a literal quotation." }
258 { $examples { $code "[ 1 2 3 ]" } } ;
259
260 { POSTPONE: [ POSTPONE: ] } related-words
261
262 HELP: ]
263 { $syntax "]" }
264 { $description "Marks the end of a literal quotation."
265 $nl
266 "Parsing words can use this word as a generic end delimiter." } ;
267
268 HELP: }
269 { $syntax "}" }
270 { $description "Marks the end of an array, vector, hashtable, complex number, tuple, or wrapper."
271 $nl
272 "Parsing words can use this word as a generic end delimiter." } ;
273
274 { POSTPONE: { POSTPONE: V{ POSTPONE: H{ POSTPONE: C{ POSTPONE: T{ POSTPONE: W{ POSTPONE: } } related-words
275
276 HELP: {
277 { $syntax "{ elements... }" }
278 { $values { "elements" "a list of objects" } }
279 { $description "Marks the beginning of a literal array. Literal arrays are terminated by " { $link POSTPONE: } } "." } 
280 { $examples { $code "{ 1 2 3 }" } } ;
281
282 HELP: V{
283 { $syntax "V{ elements... }" }
284 { $values { "elements" "a list of objects" } }
285 { $description "Marks the beginning of a literal vector. Literal vectors are terminated by " { $link POSTPONE: } } "." } 
286 { $examples { $code "V{ 1 2 3 }" } } ;
287
288 HELP: B{
289 { $syntax "B{ elements... }" }
290 { $values { "elements" "a list of integers" } }
291 { $description "Marks the beginning of a literal byte array. Literal byte arrays are terminated by " { $link POSTPONE: } } "." } 
292 { $examples { $code "B{ 1 2 3 }" } } ;
293
294 HELP: BV{
295 { $syntax "BV{ elements... }" }
296 { $values { "elements" "a list of bytes" } }
297 { $description "Marks the beginning of a literal byte vector. Literal byte vectors are terminated by " { $link POSTPONE: } } "." } 
298 { $examples { $code "BV{ 1 2 3 12 }" } } ;
299
300 HELP: ?{
301 { $syntax "?{ elements... }" }
302 { $values { "elements" "a list of booleans" } }
303 { $description "Marks the beginning of a literal bit array. Literal bit arrays are terminated by " { $link POSTPONE: } } "." } 
304 { $examples { $code "?{ t f t }" } } ;
305
306 HELP: ?V{
307 { $syntax "?V{ elements... }" }
308 { $values { "elements" "a list of booleans" } }
309 { $description "Marks the beginning of a literal bit vector. Literal bit vectors are terminated by " { $link POSTPONE: } } "." } 
310 { $examples { $code "?V{ t f t }" } } ;
311
312 HELP: FV{
313 { $syntax "FV{ elements... }" }
314 { $values { "elements" "a list of real numbers" } }
315 { $description "Marks the beginning of a literal float vector. Literal float vectors are terminated by " { $link POSTPONE: } } "." } 
316 { $examples { $code "FV{ 1.0 2.0 3.0 }" } } ;
317
318 HELP: F{
319 { $syntax "F{ elements... }" }
320 { $values { "elements" "a list of real numbers" } }
321 { $description "Marks the beginning of a literal float array. Literal float arrays are terminated by " { $link POSTPONE: } } "." } 
322 { $examples { $code "F{ 1.0 2.0 3.0 }" } } ;
323
324 HELP: H{
325 { $syntax "H{ { key value }... }" }
326 { $values { "key" "an object" } { "value" "an object" } }
327 { $description "Marks the beginning of a literal hashtable, given as a list of two-element arrays holding key/value pairs. Literal hashtables are terminated by " { $link POSTPONE: } } "." } 
328 { $examples { $code "H{ { \"tuna\" \"fish\" } { \"jalapeno\" \"vegetable\" } }" } } ;
329
330 HELP: C{
331 { $syntax "C{ real-part imaginary-part }" }
332 { $values { "real-part" "a real number" } { "imaginary-part" "a real number" } }
333 { $description "Parses a complex number given in rectangular form as a pair of real numbers. Literal complex numbers are terminated by " { $link POSTPONE: } } "." }  ;
334
335 HELP: T{
336 { $syntax "T{ class slots... }" }
337 { $values { "class" "a tuple class word" } { "slots" "list of objects" } }
338 { $description "Marks the beginning of a literal tuple. Literal tuples are terminated by " { $link POSTPONE: } } "."
339 $nl
340 "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, they are ignored." } ;
341
342 HELP: W{
343 { $syntax "W{ object }" }
344 { $values { "object" "an object" } }
345 { $description "Marks the beginning of a literal wrapper. Literal wrappers are terminated by " { $link POSTPONE: } } "." }  ;
346
347 HELP: POSTPONE:
348 { $syntax "POSTPONE: word" }
349 { $values { "word" "a word" } }
350 { $description "Reads the next word from the input string and appends the word to the parse tree, even if it is a parsing word." }
351 { $examples "For an ordinary word " { $snippet "foo" } ", " { $snippet "foo" } " and " { $snippet "POSTPONE: foo" } " are equivalent; however, if " { $snippet "foo" } " is a parsing word, the former will execute it at parse time, while the latter will execute it at runtime." }
352 { $notes "This word is used inside parsing words to delegate further action to another parsing word, and to refer to parsing words literally from literal arrays and such." } ;
353
354 HELP: :
355 { $syntax ": word definition... ;" }
356 { $values { "word" "a new word to define" } { "definition" "a word definition" } }
357 { $description "Defines a word in the current vocabulary." }
358 { $examples { $code ": ask-name ( -- name )\n    \"What is your name? \" write readln ;\n: greet ( name -- )\n    \"Greetings, \" write print ;\n: friend ( -- )\n    ask-name greet ;" } } ;
359
360 { POSTPONE: : POSTPONE: ; define } related-words
361
362 HELP: ;
363 { $syntax ";" }
364 { $description
365     "Marks the end of a definition."
366     $nl
367     "Parsing words can use this word as a generic end delimiter."
368 } ;
369
370 HELP: SYMBOL:
371 { $syntax "SYMBOL: word" }
372 { $values { "word" "a new word to define" } }
373 { $description "Defines a new symbol word in the current vocabulary. Symbols push themselves on the stack when executed, and are used to identify variables (see " { $link "namespaces" } ") as well as for storing crufties in word properties (see " { $link "word-props" } ")." }
374 { $examples { $example "USE: prettyprint" "SYMBOL: foo\nfoo ." "foo" } } ;
375
376 { define-symbol POSTPONE: SYMBOL: } related-words
377
378 HELP: \
379 { $syntax "\\ word" }
380 { $values { "word" "a word" } }
381 { $description "Reads the next word from the input and appends a wrapper holding the word to the parse tree. When the evaluator encounters a wrapper, it pushes the wrapped word literally on the data stack." }
382 { $examples "The following two lines are equivalent:" { $code "0 \\ <vector> execute\n0 <vector>" } } ;
383
384 HELP: DEFER:
385 { $syntax "DEFER: word" }
386 { $values { "word" "a new word to define" } }
387 { $description "Create a word in the current vocabulary that simply raises an error when executed. Usually, the word will be replaced with a real definition later." }
388 { $notes "Due to the way the parser works, words cannot be referenced before they are defined; that is, source files must order definitions in a strictly bottom-up fashion. Mutually-recursive pairs of words can be implemented by " { $emphasis "deferring" } " one of the words in the pair allowing the second word in the pair to parse, then by defining the first word." }
389 { $examples { $code "DEFER: foe\n: fie ... foe ... ;\n: foe ... fie ... ;" } } ;
390
391 HELP: FORGET:
392 { $syntax "FORGET: word" }
393 { $values { "word" "a word" } }
394 { $description "Removes the word from its vocabulary, or does nothing if no such word exists. Existing definitions that reference forgotten words will continue to work, but new occurrences of the word will not parse." } ;
395
396 HELP: USE:
397 { $syntax "USE: vocabulary" }
398 { $values { "vocabulary" "a vocabulary name" } }
399 { $description "Adds a new vocabulary at the front of the search path. Subsequent word lookups by the parser will search this vocabulary first." }
400 { $errors "Throws an error if the vocabulary does not exist." } ;
401
402 HELP: USING:
403 { $syntax "USING: vocabularies... ;" }
404 { $values { "vocabularies" "a list of vocabulary names" } }
405 { $description "Adds a list of vocabularies to the front of the search path, with later vocabularies taking precedence." }
406 { $errors "Throws an error if one of the vocabularies does not exist." } ;
407
408 HELP: IN:
409 { $syntax "IN: vocabulary" }
410 { $values { "vocabulary" "a new vocabulary name" } }
411 { $description "Sets the current vocabulary where new words will be defined, creating the vocabulary first if it does not exist. After the vocabulary has been created, it can be listed in " { $link POSTPONE: USE: } " and " { $link POSTPONE: USING: } " declarations." } ;
412
413 HELP: CHAR:
414 { $syntax "CHAR: token" }
415 { $values { "token" "a literal character, escape code, or Unicode character name" } }
416 { $description "Adds a Unicode code point to the parse tree." }
417 { $examples
418     { $code
419         "CHAR: x"
420         "CHAR: \\u000032"
421         "CHAR: \\u{exclamation-mark}"
422         "CHAR: exclamation-mark"
423         "CHAR: ugaritic-letter-samka"
424     }
425 } ;
426
427 HELP: "
428 { $syntax "\"string...\"" }
429 { $values { "string" "literal and escaped characters" } }
430 { $description "Reads from the input string until the next occurrence of " { $link POSTPONE: " } ", and appends the resulting string to the parse tree. String literals cannot span multiple lines. Strings containing the " { $link POSTPONE: " } " character and various other special characters can be read by inserting escape sequences." }
431 { $examples { $example "USE: io" "\"Hello\\nworld\" print" "Hello\nworld" } } ;
432
433 HELP: SBUF"
434 { $syntax "SBUF\" string... \"" }
435 { $values { "string" "literal and escaped characters" } }
436 { $description "Reads from the input string until the next occurrence of " { $link POSTPONE: " } ", converts the string to a string buffer, and appends it to the parse tree." }
437 { $examples { $example "USING: io strings ;" "SBUF\" Hello world\" >string print" "Hello world" } } ;
438
439 HELP: P"
440 { $syntax "P\" pathname\"" }
441 { $values { "pathname" "a pathname string" } }
442 { $description "Reads from the input string until the next occurrence of " { $link POSTPONE: " } ", creates a new " { $link pathname } ", and appends it to the parse tree." }
443 { $examples { $example "USING: io io.files ;" "P\" foo.txt\" pathname-string print" "foo.txt" } } ;
444
445 HELP: (
446 { $syntax "( inputs -- outputs )" }
447 { $values { "inputs" "a list of tokens" } { "outputs" "a list of tokens" } }
448 { $description "Declares the stack effect of the most recently defined word, storing a new " { $link effect } " instance in the " { $snippet "\"declared-effect\"" } " word property." }
449 { $notes "Recursive words must have a declared stack effect to compile. See " { $link "effect-declaration" } " for details." } ;
450
451 HELP: !
452 { $syntax "! comment..." }
453 { $values { "comment" "characters" } }
454 { $description "Discards all input until the end of the line." } ;
455
456 { POSTPONE: ! POSTPONE: #! } related-words
457
458 HELP: #!
459 { $syntax "#! comment..." }
460 { $values { "comment" "characters" } }
461 { $description "Discards all input until the end of the line." } ;
462
463 HELP: HEX:
464 { $syntax "HEX: integer" }
465 { $values { "integer" "hexadecimal digits (0-9, a-f, A-F)" } }
466 { $description "Adds an integer read from a hexadecimal literal to the parse tree." }
467 { $examples { $example "USE: prettyprint" "HEX: ff ." "255" } } ;
468
469 HELP: OCT:
470 { $syntax "OCT: integer" }
471 { $values { "integer" "octal digits (0-7)" } }
472 { $description "Adds an integer read from an octal literal to the parse tree." }
473 { $examples { $example "USE: prettyprint" "OCT: 31337 ." "13023" } } ;
474
475 HELP: BIN:
476 { $syntax "BIN: integer" }
477 { $values { "integer" "binary digits (0 and 1)" } }
478 { $description "Adds an integer read from an binary literal to the parse tree." }
479 { $examples { $example "USE: prettyprint" "BIN: 100 ." "4" } } ;
480
481 HELP: GENERIC:
482 { $syntax "GENERIC: word" }
483 { $values { "word" "a new word to define" } }
484 { $description "Defines a new generic word in the current vocabulary. Initially, it contains no methods, and thus will throw a " { $link no-method } " error when called." } ;
485
486 HELP: GENERIC#
487 { $syntax "GENERIC# word n" }
488 { $values { "word" "a new word to define" } { "n" "the stack position to dispatch on, either 0, 1 or 2" } }
489 { $description "Defines a new generic word which dispatches on the " { $snippet "n" } "th most element from the top of the stack in the current vocabulary. Initially, it contains no methods, and thus will throw a " { $link no-method } " error when called." }
490 { $notes
491     "The following two definitions are equivalent:"
492     { $code "GENERIC: foo" }
493     { $code "GENERIC# foo 0" }
494 } ;
495
496 HELP: MATH:
497 { $syntax "MATH: word" }
498 { $values { "word" "a new word to define" } }
499 { $description "Defines a new generic word which uses the " { $link math-combination } " method combination." } ;
500
501 HELP: HOOK:
502 { $syntax "HOOK: word variable" }
503 { $values { "word" "a new word to define" } { "variable" word } }
504 { $description "Defines a new hook word in the current vocabulary. Hook words are generic words which dispatch on the value of a variable, so methods are defined with " { $link POSTPONE: M: } ". Hook words differ from other generic words in that the dispatch value is removed from the stack before the chosen method is called." }
505 { $examples
506     { $example
507         "USING: io namespaces ;"
508         "SYMBOL: transport"
509         "TUPLE: land-transport ;"
510         "TUPLE: air-transport ;"
511         "HOOK: deliver transport ( destination -- )"
512         "M: land-transport deliver \"Land delivery to \" write print ;"
513         "M: air-transport deliver \"Air delivery to \"  write print ;"
514         "T{ air-transport } transport set"
515         "\"New York City\" deliver"
516         "Air delivery to New York City"
517     }
518 }
519 { $notes
520     "Hook words are really just generic words with a custom method combination (see " { $link "method-combination" } ")."
521 } ;
522
523 HELP: M:
524 { $syntax "M: class generic definition... ;" }
525 { $values { "class" "a class word" } { "generic" "a generic word" } { "definition" "a method definition" } }
526 { $description "Defines a method, that is, a behavior for the generic word specialized on instances of the class." } ;
527
528 HELP: UNION:
529 { $syntax "UNION: class members... ;" }
530 { $values { "class" "a new class word to define" } { "members" "a list of class words separated by whitespace" } }
531 { $description "Defines a union class. An object is an instance of a union class if it is an instance of one of its members." }
532 { $notes "Union classes are used to associate the same method with several different classes, as well as to conveniently define predicates." } ;
533
534 HELP: MIXIN:
535 { $syntax "MIXIN: class" }
536 { $values { "class" "a new class word to define" } }
537 { $description "Defines a mixin class. A mixin is similar to a union class, except it has no members initially, and new members can be added with the " { $link POSTPONE: INSTANCE: } " word." }
538 { $notes "Mixins classes are used to mark implementations of a protocol and define default methods." }
539 { $examples "The " { $link sequence } " and " { $link assoc } " mixin classes." } ;
540
541 HELP: INSTANCE:
542 { $syntax "INSTANCE: instance mixin" }
543 { $values { "instance" "a class word" } { "instance" "a class word" } }
544 { $description "Makes " { $snippet "instance" } " an instance of " { $snippet "mixin" } "." } ;
545
546 HELP: PREDICATE:
547 { $syntax "PREDICATE: class < superclass predicate... ;" }
548 { $values { "class" "a new class word to define" } { "superclass" "an existing class word" } { "predicate" "membership test with stack effect " { $snippet "( superclass -- ? )" } } }
549 { $description
550     "Defines a predicate class deriving from " { $snippet "superclass" } "."
551     $nl
552     "An object is an instance of a predicate class if two conditions hold:"
553     { $list
554         "it is an instance of the predicate's superclass,"
555         "it satisfies the predicate"
556     }
557     "Each predicate must be defined as a subclass of some other class. This ensures that predicates inheriting from disjoint classes do not need to be exhaustively tested during method dispatch."
558 } ;
559
560 HELP: TUPLE:
561 { $syntax "TUPLE: class slots... ;" "TUPLE: class < superclass slots ... ;" }
562 { $values { "class" "a new tuple class to define" } { "slots" "a list of slot names" } }
563 { $description "Defines a new tuple class. The superclass is optional; if left unspecified, it defaults to " { $link tuple } "." } ;
564
565 HELP: ERROR:
566 { $syntax "ERROR: class slots... ;" }
567 { $values { "class" "a new tuple class to define" } { "slots" "a list of slot names" } }
568 { $description "Defines a new tuple class whose class word throws a new instance of the error." }
569 { $notes
570     "The following two snippets are equivalent:"
571     { $code
572         "ERROR: invalid-values x y ;"
573         ""
574         "TUPLE: invalid-values x y ;"
575         ": invalid-values ( x y -- * )"
576         "    \\ invalid-values boa throw ;"
577     }
578 } ;
579
580 HELP: C:
581 { $syntax "C: constructor class" }
582 { $values { "constructor" "a new word to define" } { "class" tuple-class } }
583 { $description "Define a constructor word for a tuple class which simply performs BOA (by order of arguments) construction using " { $link boa } "." }
584 { $examples
585     "Suppose the following tuple has been defined:"
586     { $code "TUPLE: color red green blue ;" }
587     "The following two lines are equivalent:"
588     { $code
589         "C: <color> color"
590         ": <color> color boa ;"
591     }
592     "In both cases, a word " { $snippet "<color>" } " is defined, which reads three values from the stack and creates a " { $snippet "color" } " instance having these values in the " { $snippet "red" } ", " { $snippet "green" } " and " { $snippet "blue" } " slots, respectively."
593 } ;
594
595 HELP: MAIN:
596 { $syntax "MAIN: word" }
597 { $values { "word" word } }
598 { $description "Defines the main entry point for the current vocabulary. This word will be executed when this vocabulary is passed to " { $link run } "." } ;
599
600 HELP: <PRIVATE
601 { $syntax "<PRIVATE ... PRIVATE>" }
602 { $description "Marks the start of a block of private word definitions. Private word definitions are placed in a vocabulary named by suffixing the current vocabulary with " { $snippet ".private" } "." }
603 { $notes
604     "The following is an example of usage:"
605     { $code
606         "IN: factorial"
607         ""
608         "<PRIVATE"
609         ""
610         ": (fac) ( accum n -- n! )"
611         "    dup 1 <= [ drop ] [ [ * ] keep 1- (fac) ] if ;"
612         ""
613         "PRIVATE>"
614         ""
615         ": fac ( n -- n! ) 1 swap (fac) ;"
616     }
617     "The above is equivalent to:"
618     { $code
619         "IN: factorial.private"
620         ""
621         ": (fac) ( accum n -- n! )"
622         "    dup 1 <= [ drop ] [ [ * ] keep 1- (fac) ] if ;"
623         ""
624         "IN: factorial"
625         ""
626         ": fac ( n -- n! ) 1 swap (fac) ;"
627     }
628 } ;
629
630 HELP: PRIVATE>
631 { $syntax "<PRIVATE ... PRIVATE>" }
632 { $description "Marks the end of a block of private word definitions." } ;
633
634 { POSTPONE: <PRIVATE POSTPONE: PRIVATE> } related-words
635
636 HELP: <<
637 { $syntax "<< ... >>" }
638 { $description "Evaluates some code at parse time." }
639 { $notes "Calling words defined in the same source file at parse time is prohibited; see compilation unit as where it was defined; see " { $link "compilation-units" } "." } ;
640
641 HELP: >>
642 { $syntax ">>" }
643 { $description "Marks the end of a parse time code block." } ;
644
645 HELP: call-next-method
646 { $description "Calls the next applicable method. Only valid inside a method definition. The values at the top of the stack are passed on to the next method, and they must be compatible with that method's class specializer." }
647 { $notes "This is syntax sugar around " { $link (call-next-method) } ". The following two lines are equivalent:"
648     { $code
649         "M: my-class my-generic ... call-next-method ... ;"
650         "M: my-class my-generic ... \\ my-class \\ my-generic (call-next-method) ... ;"
651     }
652 "In most cases, this word should be called with the original input values on the stack. Calling it with other values is usually a sign of poor design." }
653 { $errors
654     "Throws a " { $link no-next-method } " error if this is the least specific method, and throws an " { $link inconsistent-next-method } " error if the values at the top of the stack are not compatible with the current method's specializer."
655 } ;
656
657 { POSTPONE: call-next-method (call-next-method) next-method } related-words
658
659 { POSTPONE: << POSTPONE: >> } related-words