version 1.81, 2000/08/25 19:43:40
|
version 1.82, 2000/08/26 13:29:47
|
Line 323 Tokens for Words
|
Line 323 Tokens for Words
|
* Compilation token:: represents compilation semantics |
* Compilation token:: represents compilation semantics |
* Name token:: represents named words |
* Name token:: represents named words |
|
|
|
Compiling words |
|
|
|
* Literals:: Compiling data values |
|
* Macros:: Compiling words |
|
|
The Text Interpreter |
The Text Interpreter |
|
|
* Input Sources:: |
* Input Sources:: |
* Number Conversion:: |
* Number Conversion:: |
* Interpret/Compile states:: |
* Interpret/Compile states:: |
* Literals:: |
|
* Interpreter Directives:: |
* Interpreter Directives:: |
|
|
Word Lists |
Word Lists |
Line 3422 to Modula-2 modules and C++ namespaces.
|
Line 3426 to Modula-2 modules and C++ namespaces.
|
programs in this way has disadvantages for debugging and reuse/factoring |
programs in this way has disadvantages for debugging and reuse/factoring |
that overcome the advantages in my experience (I don't do huge projects, |
that overcome the advantages in my experience (I don't do huge projects, |
though). These disadvantages are not so clear in other |
though). These disadvantages are not so clear in other |
languages/programming environments, because these langauges are not so |
languages/programming environments, because these languages are not so |
strong in debugging and reuse. |
strong in debugging and reuse. |
|
|
@c !! example |
@c !! example |
Line 5207 doc-compare
|
Line 5211 doc-compare
|
doc-search |
doc-search |
doc--trailing |
doc--trailing |
doc-/string |
doc-/string |
|
doc-bounds |
|
|
@comment TODO examples |
@comment TODO examples |
|
|
Line 5267 who also know other languages (and is no
|
Line 5271 who also know other languages (and is no
|
prejudices against Forth in these people). Adding @code{ENDIF} to a |
prejudices against Forth in these people). Adding @code{ENDIF} to a |
system that only supplies @code{THEN} is simple: |
system that only supplies @code{THEN} is simple: |
@example |
@example |
: ENDIF POSTPONE THEN ; immediate |
: ENDIF POSTPONE then ; immediate |
@end example |
@end example |
|
|
[According to @cite{Webster's New Encyclopedic Dictionary}, @dfn{then |
[According to @cite{Webster's New Encyclopedic Dictionary}, @dfn{then |
Line 6453 supply a part of the parameters for a wo
|
Line 6457 supply a part of the parameters for a wo
|
the functional language community). E.g., @code{+} needs two |
the functional language community). E.g., @code{+} needs two |
parameters. Creating versions of @code{+} with one parameter fixed can |
parameters. Creating versions of @code{+} with one parameter fixed can |
be done like this: |
be done like this: |
|
|
@example |
@example |
: curry+ ( n1 -- ) |
: curry+ ( n1 "name" -- ) |
CREATE , |
CREATE , |
DOES> ( n2 -- n1+n2 ) |
DOES> ( n2 -- n1+n2 ) |
@@ + ; |
@@ + ; |
Line 6841 doc-immediate
|
Line 6846 doc-immediate
|
doc-compile-only |
doc-compile-only |
doc-restrict |
doc-restrict |
|
|
|
By convention, words with non-default compilation semantics (e.g., |
|
immediate words) often have names surrounded with brackets (e.g., |
|
@code{[']}, @pxref{Execution token}). |
|
|
Note that ticking (@code{'}) a compile-only word gives an error |
Note that ticking (@code{'}) a compile-only word gives an error |
(``Interpreting a compile-only word''). |
(``Interpreting a compile-only word''). |
Line 6894 opti-foobar} would compile compilation s
|
Line 6902 opti-foobar} would compile compilation s
|
@code{[compile] foobar} would compile interpretation semantics. |
@code{[compile] foobar} would compile interpretation semantics. |
|
|
@cindex state-smart words (are a bad idea) |
@cindex state-smart words (are a bad idea) |
|
@anchor{state-smartness} |
Some people try to use @dfn{state-smart} words to emulate the feature provided |
Some people try to use @dfn{state-smart} words to emulate the feature provided |
by @code{interpret/compile:} (words are state-smart if they check |
by @code{interpret/compile:} (words are state-smart if they check |
@code{STATE} during execution). E.g., they would try to code |
@code{STATE} during execution). E.g., they would try to code |
Line 7047 In ANS Forth the XT is just an abstract
|
Line 7056 In ANS Forth the XT is just an abstract
|
operations that produce or consume it). For old hands: In Gforth, the |
operations that produce or consume it). For old hands: In Gforth, the |
XT is implemented as a code field address (CFA). |
XT is implemented as a code field address (CFA). |
|
|
@c !! discuss "compile," some more (or in Macros). |
|
|
|
doc-execute |
doc-execute |
doc-perform |
doc-perform |
doc-compile, |
|
|
|
@node Compilation token, Name token, Execution token, Tokens for Words |
@node Compilation token, Name token, Execution token, Tokens for Words |
@subsection Compilation token |
@subsection Compilation token |
Line 7107 doc-name>string
|
Line 7113 doc-name>string
|
@cindex macros |
@cindex macros |
|
|
In contrast to most other languages, Forth has no strict boundary |
In contrast to most other languages, Forth has no strict boundary |
between compilation and run-time. |
between compilation and run-time. E.g., you can run arbitrary code |
|
between defining words (or for computing data used by defining words |
|
like @code{constant}). Moreover, @code{Immediate} (@pxref{Interpretation |
|
and Compilation Semantics} and @code{[}...@code{]} (see below) allow |
|
running arbitrary code while compiling a colon definition (exception: |
|
you must not allot dictionary space). |
|
|
doc-postpone |
@menu |
|
* Literals:: Compiling data values |
|
* Macros:: Compiling words |
|
@end menu |
|
|
|
@node Literals, Macros, Compiling words, Compiling words |
|
@subsection Literals |
|
@cindex Literals |
|
|
|
The simplest and most frequent example is to compute a literal during |
|
compilation. E.g., the following definition prints an array of strings, |
|
one string per line: |
|
|
|
@example |
|
: .strings ( addr u -- ) \ gforth |
|
2* cells bounds U+DO |
|
cr i 2@@ type |
|
2 cells +LOOP ; |
|
@end example |
|
|
@comment TODO -- expand glossary text for POSTPONE |
With a simple-minded compiler like Gforth's, this computes @code{2 |
|
cells} on every loop iteration. You can compute this value once and for |
|
all at compile time and compile it into the definition like this: |
|
|
|
@example |
|
: .strings ( addr u -- ) \ gforth |
|
2* cells bounds U+DO |
|
cr i 2@@ type |
|
[ 2 cells ] literal +LOOP ; |
|
@end example |
|
|
|
@code{[} switches the text interpreter to interpret state (you will get |
|
an @code{ok} prompt if you type this example interactively and insert a |
|
newline between @code{[} and @code{]}), so it performs the |
|
interpretation semantics of @code{2 cells}; this computes a number. |
|
@code{]} switches the text interpreter back into compile state. It then |
|
performs @code{Literal}'s compilation semantics, which are to compile |
|
this number into the current word. You can decompile the word with |
|
@code{see .strings} to see the effect on the compiled code. |
|
|
|
You can also optimize the @code{2* cells} into @code{[ 2 cells ] literal |
|
*} in this way. |
|
|
|
doc-[ |
|
doc-] |
doc-literal |
doc-literal |
doc-]L |
doc-]L |
|
|
|
There are also words for compiling other data types than single cells as |
|
literals: |
|
|
doc-2literal |
doc-2literal |
doc-fliteral |
doc-fliteral |
doc-[ |
doc-sliteral |
doc-] |
|
|
@cindex colon-sys, passing data across @code{:} |
|
@cindex @code{:}, passing data across |
|
You might be tempted to pass data from outside a colon definition to the |
|
inside on the data stack. This does not work, because @code{:} puhes a |
|
colon-sys, making stuff below unaccessible. E.g., this does not work: |
|
|
|
@example |
|
5 : foo literal ; \ error: "unstructured" |
|
@end example |
|
|
|
Instead, you have to pass the value in some other way, e.g., through a |
|
variable: |
|
|
|
@example |
|
variable temp |
|
5 temp ! |
|
: foo [ temp @@ ] literal ; |
|
@end example |
|
|
|
|
|
@node Macros, , Literals, Compiling words |
|
@subsection Macros |
|
@cindex Macros |
|
@cindex compiling compilation semantics |
|
|
|
@code{Literal} and friends compile data values into the current |
|
definition. You can also write words that compile other words into the |
|
current definition. E.g., |
|
|
|
@example |
|
: compile-+ ( -- ) \ compiled code: ( n1 n2 -- n ) |
|
POSTPONE + ; |
|
|
|
: foo ( n1 n2 -- n ) |
|
[ compile-+ ] ; |
|
1 2 foo . |
|
@end example |
|
|
|
This is equivalent to @code{: foo + ;} (@code{see foo} to check this). |
|
What happens in this example? @code{Postpone} compiles the compilation |
|
semantics of @code{+} into @code{compile-+}; later the text interpreter |
|
executes @code{compile-+} and thus the compilation semantics of +, which |
|
compile (the execution semantics of) @code{+} into |
|
@code{foo}.@footnote{A recent RFI answer requires that compiling words |
|
should only be executed in compile state, so this example is not |
|
guaranteed to work on all standard systems, but on any decent system it |
|
will work.} |
|
|
|
doc-postpone |
|
doc-[compile] |
|
|
|
Compiling words like @code{compile-+} are usually immediate (or similar) |
|
so you do not have to switch to interpret state to execute them; |
|
mopifying the last example accordingly produces: |
|
|
|
@example |
|
: [compile-+] ( compilation: --; interpretation: -- ) |
|
\ compiled code: ( n1 n2 -- n ) |
|
POSTPONE + ; immediate |
|
|
|
: foo ( n1 n2 -- n ) |
|
[compile-+] ; |
|
1 2 foo . |
|
@end example |
|
|
|
Immediate compiling words are similar to macros in other languages (in |
|
particular, Lisp). The important differences to macros in, e.g., C are: |
|
|
|
@itemize @bullet |
|
|
|
@item |
|
You use the same language for defining and processing macros, not a |
|
separate preprocessing language and processor. |
|
|
|
@item |
|
Consequently, the full power of Forth is available in macro definitions. |
|
E.g., you can perform arbitrarily complex computations, or generate |
|
different code conditionally or in a loop (e.g., @pxref{Advanced macros |
|
Tutorial}). This power is very useful when writing a parser generators |
|
or other code-generating software. |
|
|
|
@item |
|
Macros defined using @code{postpone} etc. deal with the language at a |
|
higher level than strings; name binding happens at macro definition |
|
time, so you can avoid the pitfalls of name collisions that can happen |
|
in C macros. Of course, Forth is a liberal language and also allows to |
|
shoot yourself in the foot with text-interpreted macros like |
|
|
|
@example |
|
: [compile-+] s" +" evaluate ; immediate |
|
@end example |
|
|
|
Apart from binding the name at macro use time, using @code{evaluate} |
|
also makes your definition @code{state}-smart (@pxref{state-smartness}). |
|
@end itemize |
|
|
|
You may want the macro to compile a number into a word. The word to do |
|
it is @code{literal}, but you have to @code{postpone} it, so its |
|
compilation semantics take effect when the macro is executed, not when |
|
it is compiled: |
|
|
|
@example |
|
: [compile-5] ( -- ) \ compiled code: ( -- n ) |
|
5 POSTPONE literal ; immediate |
|
|
|
: foo [compile-5] ; |
|
foo . |
|
@end example |
|
|
|
You may want to pass parameters to a macro, that the macro should |
|
compile into the current definition. If the parameter is a number, then |
|
you can use @code{postpone literal} (similar for other values). |
|
|
|
If you want to pass a word that is to be compiled, the usual way is to |
|
pass an execution token and @code{compile,} it: |
|
|
|
@example |
|
: twice1 ( xt -- ) \ compiled code: ... -- ... |
|
dup compile, compile, ; |
|
|
|
: 2+ ( n1 -- n2 ) |
|
[ ' 1+ twice1 ] ; |
|
@end example |
|
|
|
doc-compile, |
|
|
|
An alternative available in Gforth, that allows you to pass compile-only |
|
words as parameters is to use the compilation token (@pxref{Compilation |
|
token}). The same example in this technique: |
|
|
|
@example |
|
: twice ( ... ct -- ... ) \ compiled code: ... -- ... |
|
2dup 2>r execute 2r> execute ; |
|
|
|
: 2+ ( n1 -- n2 ) |
|
[ comp' 1+ twice ] ; |
|
@end example |
|
|
|
In the example above @code{2>r} and @code{2r>} ensure that @code{twice} |
|
works even if the executed compilation semantics has an effect on the |
|
data stack. |
|
|
|
You can also define complete definitions with these words; this provides |
|
an alternative to using @code{does>} (@pxref{User-defined Defining |
|
Words}). E.g., instead of |
|
|
|
@example |
|
: curry+ ( n1 "name" -- ) |
|
CREATE , |
|
DOES> ( n2 -- n1+n2 ) |
|
@@ + ; |
|
@end example |
|
|
|
you could define |
|
|
|
@example |
|
: curry+ ( n1 "name" -- ) |
|
\ name execution: ( n2 -- n1+n2 ) |
|
>r : r> POSTPONE literal POSTPONE + POSTPONE ; ; |
|
|
|
-3 curry+ 3- |
|
see 3- |
|
@end example |
|
|
|
The sequence @code{>r : r>} is necessary, because @code{:} puts a |
|
colon-sys on the data stack that makes everything below it unaccessible. |
|
|
|
This way of writing defining words is sometimes more, sometimes less |
|
convenient than using @code{does>} (@pxref{Advanced does> usage |
|
example}). One advantage of this method is that it can be optimized |
|
better, because the compiler knows that the value compiled with |
|
@code{literal} is fixed, whereas the data associated with a |
|
@code{create}d word can be changed. |
|
|
@c ---------------------------------------------------------- |
@c ---------------------------------------------------------- |
@node The Text Interpreter, Word Lists, Compiling words, Words |
@node The Text Interpreter, Word Lists, Compiling words, Words |
Line 7324 doc-#tib
|
Line 7550 doc-#tib
|
* Input Sources:: |
* Input Sources:: |
* Number Conversion:: |
* Number Conversion:: |
* Interpret/Compile states:: |
* Interpret/Compile states:: |
* Literals:: |
|
* Interpreter Directives:: |
* Interpreter Directives:: |
@end menu |
@end menu |
|
|
Line 7498 of @code{base}.
|
Line 7723 of @code{base}.
|
You can read numbers into your programs with the words described in |
You can read numbers into your programs with the words described in |
@ref{Input}. |
@ref{Input}. |
|
|
@node Interpret/Compile states, Literals, Number Conversion, The Text Interpreter |
@node Interpret/Compile states, Interpreter Directives, Number Conversion, The Text Interpreter |
@subsection Interpret/Compile states |
@subsection Interpret/Compile states |
@cindex Interpret/Compile states |
@cindex Interpret/Compile states |
|
|
Line 7568 create table ' aa , ' bb , ' cc ,
|
Line 7793 create table ' aa , ' bb , ' cc ,
|
|
|
doc-state |
doc-state |
|
|
@node Literals, Interpreter Directives, Interpret/Compile states, The Text Interpreter |
|
@subsection Literals |
|
@cindex Literals |
|
|
|
Often, you want to use a number within a colon definition. When you do |
|
this, the text interpreter automatically compiles the number as a |
|
@i{literal}. A literal is a number whose run-time effect is to be pushed |
|
onto the stack. If you had to do some maths to generate the number, you |
|
might write it like this: |
|
|
|
@example |
|
: HOUR-TO-SEC ( n1 -- n2 ) |
|
60 * \ to minutes |
|
60 * ; \ to seconds |
|
@end example |
|
|
|
It is very clear what this definition is doing, but it's inefficient |
@node Interpreter Directives, , Interpret/Compile states, The Text Interpreter |
since it is performing 2 multiples at run-time. An alternative would be |
|
to write: |
|
|
|
@example |
|
: HOUR-TO-SEC ( n1 -- n2 ) |
|
3600 * ; \ to seconds |
|
@end example |
|
|
|
Which does the same thing, and has the advantage of using a single |
|
multiply. Ideally, we'd like the efficiency of the second with the |
|
readability of the first. |
|
|
|
@code{Literal} allows us to achieve that. It takes a number from the |
|
stack and lays it down in the current definition just as though the |
|
number had been typed directly into the definition. Our first attempt |
|
might look like this: |
|
|
|
@example |
|
60 \ mins per hour |
|
60 * \ seconds per minute |
|
: HOUR-TO-SEC ( n1 -- n2 ) |
|
Literal * ; \ to seconds |
|
@end example |
|
|
|
But this produces the error message @code{unstructured}. What happened? |
|
The stack notation for @code{:} is (@i{ -- colon-sys}) and the size of |
|
@i{colon-sys} is implementation-defined. In other words, once we start a |
|
colon definition we can't portably access anything that was on the stack |
|
before the definition began@footnote{@cite{Two Problems in ANS Forth}, |
|
by Thomas Worthington; Forth Dimensions 20(2) pages 32--34 describes |
|
some situations where you might want to access stack items above |
|
colon-sys, and provides a solution to the problem.}. The correct way of |
|
solving this problem in this instance is to use @code{[ ]} like this: |
|
|
|
@example |
|
: HOUR-TO-SEC ( n1 -- n2 ) |
|
[ 60 \ minutes per hour |
|
60 * ] \ seconds per minute |
|
LITERAL * ; \ to seconds |
|
@end example |
|
|
|
|
|
|
|
@node Interpreter Directives, , Literals, The Text Interpreter |
|
@subsection Interpreter Directives |
@subsection Interpreter Directives |
@cindex interpreter directives |
@cindex interpreter directives |
@cindex conditional compilation |
@cindex conditional compilation |
Line 8615 doc-s"
|
Line 8781 doc-s"
|
doc-c" |
doc-c" |
doc-char |
doc-char |
doc-[char] |
doc-[char] |
doc-sliteral |
|
|
|
|
|
@noindent |
@noindent |
Line 11788 doc-cputime
|
Line 11953 doc-cputime
|
These section lists the ANS Forth words that are not documented |
These section lists the ANS Forth words that are not documented |
elsewhere in this manual. Ultimately, they all need proper homes. |
elsewhere in this manual. Ultimately, they all need proper homes. |
|
|
doc-[compile] |
|
doc-quit |
doc-quit |
|
|
The following ANS Forth words are not currently supported by Gforth |
The following ANS Forth words are not currently supported by Gforth |