From: rich <rich>
Date: Sat, 8 Sep 2007 15:47:41 +0000 (+0000)
Subject: More documentation.
X-Git-Url: https://git.rrq.au/?a=commitdiff_plain;h=118520ea080c04a6261265056a172ede66b19e8e;p=rrq%2Fjonesforth.git

More documentation.
---

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)