Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Forth (programming language)
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
===Structure of the compiler=== The compiler itself is not a monolithic program. It consists of Forth words visible to the system, and usable by a programmer. This allows a programmer to change the compiler's words for special purposes. Compilation in traditional Forth systems is straightforward and does not involve building and optimizing an abstract representation of the code. (Some newer Forth compilers use more elaborate compilation methods, as common in other languages.) The "compile time" flag in the name field is set for words with "compile time" behavior. Most simple words execute the same code whether they are typed on a command line, or embedded in code. When compiling these, the compiler simply places code or a threaded pointer to the word.<ref name="compiler" /> The classic examples of compile-time words are the [[control structure]]s such as <code>IF</code> and <code>WHILE</code>. Almost all of Forth's control structures and almost all of its compiler are implemented as compile-time words. Apart from some rarely used [[control flow]] words only found in a few implementations, such as the conditional return word {{PreCode|?EXIT}} used in Ulrich Hoffmann's preForth,<ref name="preForth slides">[http://www.euroforth.org/ef18/papers/hoffmann-slides.pdf Ulrich Hoffmann's preForth slides]</ref><ref name="preForth">[http://www.euroforth.org/ef18/papers/hoffmann.pdf Ulrich Hoffmann's preForth]</ref> all of Forth's [[control flow]] words are executed during compilation to compile various combinations of primitive words along with their branch addresses. For instance, <code>IF</code> and <code>WHILE</code>, and the words that match with those, set up <code>BRANCH</code> (unconditional branch) and {{PreCode|?BRANCH}} (pop a value off the stack, and branch if it is false). Counted loop [[control flow]] words work similarly but set up combinations of primitive words that work with a counter, and so on. During compilation, the data stack is used to support control structure balancing, nesting, and back-patching of branch addresses. The snippet: <syntaxhighlight lang="forth"> ... DUP 6 < IF DROP 5 ELSE 1 - THEN ... </syntaxhighlight> would often be compiled to the following sequence inside a definition: <syntaxhighlight lang="forth"> ... DUP LIT 6 < ?BRANCH 5 DROP LIT 5 BRANCH 3 LIT 1 - ... </syntaxhighlight> The numbers after <code>BRANCH</code> represent relative jump addresses. <code>LIT</code> is the primitive word for pushing a "literal" number onto the data stack. (Faster, shorter code would be compiled using pointers to constants instead of <code>LIT</code> and embedded data, if any of the numbers involved have been separately defined as constants. There would be similar changes if yet other words were used instead of constants, and so on.) ==== Compilation state and interpretation state ==== The word <code>:</code> (colon) parses a name as a parameter, creates a dictionary entry (a ''colon definition'') and enters compilation state. The interpreter continues to read space-delimited words from the user input device. If a word is found, the interpreter executes the ''compilation semantics'' associated with the word, instead of the ''interpretation semantics''. The default compilation semantics of a word are to append its interpretation semantics to the current definition.<ref name="compiler" /> The word <code>;</code> (semi-colon) finishes the current definition and returns to interpretation state. It is an example of a word whose compilation semantics differ from the default. The interpretation semantics of <code>;</code> (semi-colon), most control flow words, and several other words are undefined in {{Not a typo|ANS}} <!-- not a misspelling --> Forth, meaning that they must only be used inside of definitions and not on the interactive command line.<ref name="compiler" /> The interpreter state can be changed manually with the words <code><nowiki>[</nowiki></code> (left-bracket) and <code><nowiki>]</nowiki></code> (right-bracket) which enter interpretation state or compilation state, respectively. These words can be used with the word <code>LITERAL</code> to calculate a value during a compilation and to insert the calculated value into the current colon definition. <code>LITERAL</code> has the compilation semantics to take an object from the data stack and to append semantics to the current colon definition to place that object on the data stack. In {{Not a typo|ANS}} <!-- not a misspelling --> Forth, the current state of the interpreter can be read from the [[flag (programming)|flag]] <code>STATE</code> which contains the value true when in compilation state and false otherwise. This allows the implementation of so-called ''state-smart words'' with behavior that changes according to the current state of the interpreter. ==== Immediate words ==== The word <code>IMMEDIATE</code> marks the most recent colon definition as an ''immediate word'', effectively replacing its compilation semantics with its interpretation semantics.<ref name="odMGJ">{{harvnb|Brodie|1987|p=273}}</ref> Immediate words are normally executed during compilation, not compiled, but this can be overridden by the programmer in either state. <code>;</code> is an example of an immediate word. In {{Not a typo|ANS}} <!-- not a misspelling --> Forth, the word <code>POSTPONE</code> takes a name as a parameter and appends the compilation semantics of the named word to the current definition even if the word was marked immediate. Forth-83 defined separate words <code>COMPILE</code> and <code>[COMPILE]</code> to force the compilation of non-immediate and immediate words, respectively. Instead of reserving space for an Immediate flag in every definition, some implementations of Forth use an Immediates Dictionary which is checked first when in compile mode. ==== Unnamed words and execution tokens ==== In {{Not a typo|ANS}} <!-- not a misspelling --> Forth, unnamed words can be defined with the word <code>:NONAME</code> which compiles the following words up to the next <code>;</code> (semi-colon) and leaves an ''execution token'' on the data stack. The execution token provides an opaque handle for the compiled semantics, similar to the [[function pointer]]s of the [[C (programming language)|C programming language]]. Execution tokens can be stored in variables. The word <code>EXECUTE</code> takes an execution token from the data stack and performs the associated semantics. The word <code>COMPILE,</code> (compile-comma) takes an execution token from the data stack and appends the associated semantics to the current definition. The word <code><nowiki>'</nowiki></code> (tick) takes the name of a word as a parameter and returns the execution token associated with that word on the data stack. In interpretation state, <code>' RANDOM-WORD EXECUTE</code> is equivalent to <code>RANDOM-WORD</code>.<ref name="iUYBX">{{harvnb|Brodie|1987|p=199}}</ref> ==== Parsing words and comments ==== The words <code>:</code> (colon), <code>POSTPONE</code>, <code><nowiki>'</nowiki></code> (tick) are examples of ''parsing words'' that take their arguments from the user input device instead of the data stack. Another example is the word <code>(</code> (paren) which reads and ignores the following words up to and including the next right parenthesis and is used to place comments in a colon definition. Similarly, the word <code>\</code> (backslash) is used for comments that continue to the end of the current line. To be parsed correctly, <code>(</code> (paren) and <code>\</code> (backslash) must be separated by whitespace from the following comment text. <!-- TO DO: Explain PARSE and FIND. -->
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)