From 118520ea080c04a6261265056a172ede66b19e8e Mon Sep 17 00:00:00 2001 From: rich Date: Sat, 8 Sep 2007 15:47:41 +0000 Subject: [PATCH] More documentation. --- jonesforth.S | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/jonesforth.S b/jonesforth.S index 7514f58..2fb8515 100644 --- a/jonesforth.S +++ b/jonesforth.S @@ -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) -- 1.8.3.1