From 2d8f282611455356b241e37126fa7fa607fe39b1 Mon Sep 17 00:00:00 2001 From: Jesse McDonald Date: Mon, 21 Sep 2020 16:56:50 -0500 Subject: [PATCH] revise startup code with comments and new definitions --- startup.4th | 89 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 13 deletions(-) diff --git a/startup.4th b/startup.4th index edc2ad3..3c36b0c 100644 --- a/startup.4th +++ b/startup.4th @@ -1,30 +1,93 @@ +\ Read the next word and return the first character +( "name" -- c ) : CHAR WORD DROP C@ ; -: TAB 9 EMIT ; -: LF 10 EMIT ; -: SPACE 32 EMIT ; +\ Some common non-word characters +: HT 9 ; \ Horizontal Tab +: LF 10 ; \ Line Feed (newline) +: CR 13 ; \ Carriage Return +: BL 32 ; \ BLank (space) -: BANNER "JumpForth version " .S VERSION . ", by Jesse McDonald" .S LF ; +\ Emit an implementation-dependent End-of-Line sequence +: .EOL LF EMIT ; +\ Switch from compiling to interpreting, or vice-versa : [ FALSE STATE ! ; IMMEDIATE : ] TRUE STATE ! ; IMMEDIATE -: POSTPONE WORD FINDERR , ; IMMEDIATE - +\ COMPILE, appends the effect of the execution token on the top of the stack +\ to the current definition. In this implementation it's equivalent to , since +\ definitions are just arrays of execution tokens. : COMPILE, , ; -: ['] [ ' LIT , ' LIT , ] , ' , ; IMMEDIATE +\ Read a word and append it to the current definition, ignoring the IMMED flag. +\ This is used to "call" an immediate word as a normal function. +\ POSTPONE has no effect (as a modifier) if the IMMED flag is not set. +: POSTPONE WORD FINDERR COMPILE, ; IMMEDIATE -: LITERAL ['] LIT , , ; IMMEDIATE +\ Append the LIT xt and the topmost word on the stack to the current definition. +\ If [COMPILE] were already defined then this could simply be written as: +\ +\ : LITERAL [COMPILE] LIT , ; IMMEDIATE +\ +\ ... but since it isn't we must manually insert the LIT sequence to obtain the +\ address of LIT as a literal to be compiled into the current definition. +: LITERAL [ ' LIT COMPILE, ' LIT , ] COMPILE, , ; IMMEDIATE -: IF ['] 0BRANCH , HERE 0 , ; IMMEDIATE +\ Like CHAR, but generates a literal at compile-time. +: [CHAR] CHAR POSTPONE LITERAL ; IMMEDIATE + +\ Like ', but generates a literal at compile-time. +: ['] ' POSTPONE LITERAL ; IMMEDIATE + +\ "[COMPILE] " is equivalent to "['] COMPILE,". +\ Definition has been manually expanded (vs. [COMPILE] COMPILE,) to avoid recursion. +: [COMPILE] POSTPONE ['] ['] COMPILE, COMPILE, ; IMMEDIATE + +\ Our first control-flow primitive: IF {ELSE } THEN +\ IF consumes and executes if was non-zero or else +\ if was zero. In either case execution continues after THEN. +\ IF and ELSE leave the address of the latest branch "hole" on the data stack. +\ ELSE and THEN fill in the previous "hole" with the relative branch offset. +\ The {ELSE } clause is optional. +: IF [COMPILE] 0BRANCH HERE 0 , ; IMMEDIATE : THEN HERE OVER - SWAP ! ; IMMEDIATE -: ELSE POSTPONE THEN ['] BRANCH , HERE 0 , ; IMMEDIATE +: ELSE [COMPILE] BRANCH HERE 0 , SWAP POSTPONE THEN ; IMMEDIATE +\ Unbounded loop: BEGIN AGAIN +\ BEGIN places the offset of the start of on the stack. +\ AGAIN creates a relative branch back to the start of . : BEGIN HERE ; IMMEDIATE -: AGAIN ['] BRANCH , HERE - , ; IMMEDIATE +: AGAIN [COMPILE] BRANCH HERE - , ; IMMEDIATE -CREATE VAR 123 , DOES> @ ; -: VAR! [ ' VAR >BODY ] LITERAL ! ; +\ Define a named constant. +\ Execution: ( value "name" -- ) +\ name Execution: ( -- value ) +: CONSTANT : POSTPONE LITERAL POSTPONE ; ; + +\ Define a single-cell named variable which returns its data address when executed. +\ The initial value is formally undefined. This implementation sets it to zero. +\ Execution: ( "name" -- ) +\ name Execution: ( -- a-addr ) +: VARIABLE CREATE 0 , ; + +\ Define a single-cell named value which returns its data (not address) when executed. +\ Named values defined with VALUE can be modified with TO. +\ Execution: ( x "name" -- ) +\ name execution: ( -- value ) +: VALUE CREATE , POSTPONE DOES> [COMPILE] @ POSTPONE ; ; + +\ When compiling, append code to store to the data field area of the named value. +\ When interpreting, store to the data field directly. +\ An ambiguous condition exists if the name was not created with VALUE. +( x "name" -- ) +: TO ' >BODY STATE @ IF POSTPONE LITERAL [COMPILE] ! ELSE ! THEN ; IMMEDIATE + +: / /MOD NIP ; +: MOD /MOD DROP ; + +: DEPTH SP@ S0 SWAP - CELL / ; + +: BANNER "JumpForth version " .S VERSION . ", by Jesse McDonald" .S .EOL ; BANNER