More documentation.
authorrich <rich>
Sat, 8 Sep 2007 15:47:41 +0000 (15:47 +0000)
committerrich <rich>
Sat, 8 Sep 2007 15:47:41 +0000 (15:47 +0000)
jonesforth.S

index 7514f58c9dad6ceb38df75e32071f5fec5c18074..2fb8515edcee0ccc0631115a554c705582b2328d 100644 (file)
@@ -1608,6 +1608,46 @@ _HIDDEN:
        pushl %eax              // Push it on the stack.
        NEXT
 
+/*
+       BRANCHING ----------------------------------------------------------------------
+
+       It turns out that all you need in order to define looping constructs, IF-statements, etc.
+       are two primitives.
+
+       BRANCH is an unconditional branch. 0BRANCH is a conditional branch (it only branches if the
+       top of stack is zero).
+
+       This is how BRANCH works.  When BRANCH executes, %esi starts by pointing to the offset:
+
+       +---------------------+-------+---- - - ---+------------+------------+---- - - - ----+------------+
+       | (Dictionary header) | DOCOL |            | BRANCH     | offset     | (skipped)     | word       |
+       +---------------------+-------+---- - - ---+------------+-----|------+---- - - - ----+------------+
+                                                                  ^  |                       ^
+                                                                  |  |                       |
+                                                                  |  +-----------------------+
+                                                                 %esi added to offset
+
+       The offset is added to %esi to make the new %esi, and the result is that when NEXT runs, execution
+       continues at the branch target.  Negative offsets work as expected.
+
+       0BRANCH is the same except the branch happens conditionally.
+
+       Now standard FORTH words such as IF, THEN, ELSE, WHILE, REPEAT, etc. are implemented entirely
+       in FORTH.  They are IMMEDIATE words which append various combinations of BRANCH or 0BRANCH
+       into the word currently being compiled.
+
+       As an example, code written like this:
+
+               condition-code IF true-part THEN rest-code
+
+       compiles to:
+
+               condition-code 0BRANCH OFFSET true-part rest-code
+                                         |             ^
+                                         |             |
+                                         +-------------+
+*/
+
        defcode "BRANCH",6,,BRANCH
        add (%esi),%esi         // add the offset to the instruction pointer
        NEXT
@@ -1619,6 +1659,11 @@ _HIDDEN:
        lodsl                   // otherwise we need to skip the offset
        NEXT
 
+/*
+       LITSTRING and EMITSTRING are primitives used to implement the ." operator (which is
+       written in FORTH).  See the definition of that operator below.
+*/
+
        defcode "LITSTRING",9,,LITSTRING
        lodsl                   // get the length of the string
        push %eax               // push it on the stack
@@ -1638,6 +1683,8 @@ _HIDDEN:
 
        NEXT
 
+
+
        // COLD must not return (ie. must not call EXIT).
        defword "COLD",4,,COLD
        .int INTERPRETER        // call the interpreter loop (never returns)