|
- Collapse OS usage guide
-
- This document is not meant to be an introduction to Forth, but to instruct the
- user about the peculiarities of this Forth implemenation. Be sure to refer to
- dictionary.txt for a word reference.
-
- *** DOES>
-
- Used inside a colon definition that itself uses CREATE, DOES> transforms that
- newly created word into a "does cell", that is, a regular cell ( when called,
- puts the cell's addr on PS), but right after that, it executes words that appear
- after the DOES>.
-
- "does cells" always allocate 4 bytes (2 for the cell, 2 for the DOES> link) and
- there is no need for ALLOT in colon definition.
-
- At compile time, colon definition stops processing words when reaching the
- DOES>.
-
- Example: ": CONSTANT CREATE HERE @ ! DOES> @ ;"
-
- *** Compilation vs meta-compilation
-
- Compilation vs meta-compilation. When you compile a word with "[COMPILE] foo",
- its straightforward: It writes down to HERE wither the address of the word or
- a number literal.
-
- When you *meta* compile, it's a bit more mind blowing. It fetches the address
- of the word specified by the caller, then writes that number as a literal,
- followed by a reference to ",".
-
- Example: ": foo [COMPILE] bar;" is the equivalent of ": foo bar ;" if bar is
- not an immediate. However, ": foo COMPILE bar ;" is the equivalent of
- ": foo ['] bar , ;". Got it?
-
- Meta-compile only works with real words, not number literals.
-
- *** I/O
-
- A little word about inputs. There are two kind of inputs: direct and buffered.
- As a general rule, we read line in a buffer, then feed words in it to the
- interpreter. That's what "WORD" does. If it's at the End Of Line, it blocks and
- wait until another line is entered.
-
- KEY input, however, is direct. Regardless of the input buffer's state, KEY will
- return the next typed key.
-
- PARSING AND BOOTSTRAP: Parsing number literal is a very "core" activity of
- Forth, and therefore generally seen as having to be implemented in native code.
- However, Collapse OS' Forth supports many kinds of literals: decimal, hex, char,
- binary. This incurs a significant complexity penalty.
-
- What if we could implement those parsing routines in Forth? "But it's a core
- routine!" you say. Yes, but here's the deal: at its native core, only decimal
- parsing is supported. It lives in the "(parsed)" word. The interpreter's main
- loop is initially set to simply call that word.
-
- However, in core.fs, "(parsex)", "(parsec)" and "(parseb)" are implemented, in
- Forth, then "(parse)", which goes through them all is defined. Then, "(parsef)",
- which is the variable in which the interpreter's word pointer is set, is
- updated to that new "(parse)" word.
-
- This way, we have a full-featured (and extensible) parsing with a tiny native
- core.
-
- *** Chained comparisons
-
- The unit "cmp.fs" contains words to facilitate chained comparisons with a single
- reference number. This allows, for example, to easily express "a == b or a == c"
- or "a > b and a < c".
-
- The way those chained comparison words work is that, unlike single comparison
- operators, they don't have a "n1 n2 -- f" signature, but rather a "n1 f n2 -- n1
- f" signature. That is, each operator "carries over" the reference number in
- addition to the latest flag.
-
- You open a chain with "<>{" and you close a chain with "<>}". Then, in between
- those words, you can chain operators. For example, to check whether A == B or A
- == C, you would write:
-
- A <>{ B &= C |= <>}
-
- The first operator must be of the "&" type because the chain starts with its
- flag to true. For example, "<>{ <>}" yields true.
-
- To check whether A is in between B and C inclusively, you would write:
-
- A <>{ B 1 - &> C 1 + &< <>}
|