diff options
| author | Irene Knapp <ireneista@irenes.space> | 2026-05-08 02:31:09 -0700 |
|---|---|---|
| committer | Irene Knapp <ireneista@irenes.space> | 2026-05-08 02:31:09 -0700 |
| commit | 5481ec020eabce663b5e7423c5e217005df6ad49 (patch) | |
| tree | fbf790b1e8c6e752c33f92bffd756baac5c141bf | |
| parent | 07f2e7911326d2b3b1f826b551c27648e13ae452 (diff) | |
add a rough draft of a self-hosted "interpret"
Force-Push: yes Change-Id: I063232ca7d840237f53dc805bc896c7b452cedc8
| -rw-r--r-- | interpret.e | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/interpret.e b/interpret.e new file mode 100644 index 0000000..1270429 --- /dev/null +++ b/interpret.e @@ -0,0 +1,59 @@ +~ Now the single most important word... +: funterpret + word + + ~ If no word was returned, exit. + dup 0 = { drop exit } if + + ~ The string is on the top of the stack, so to get a pointer to it we get + ~ the stack address. + ~ (string) + value@ dup emitstring newline find + + ~ Check whether the word was found in the dictionary. + dup 0 != { + ~ If the word is in the dictionary, check what mode we're in, then... + dropstring-with-result + ~ (entry pointer) + interpreter-flags @ 0x01 & { + ~ ... if we're in compile mode, there's still a chance it's an immediate + ~ word, in which case we fall through to interpret mode... + dup entry-flags@ 1 & 0 = + + ~ ... but it's a regular word, so append it to the heap. + { entry-to-execution-token , exit } if + } if + + ~ ... if we're in interpret mode, or the word is immediate, run it. + entry-to-execution-token execute exit + } if + + ~ If it's not in the dictionary, check whether it's a decimal number. + drop + ~ As before, we get the stack address and use it as a string pointer. + ~ (string) + value@ read-integer 0 = { + ~ It's a number. + interpreter-flags @ 0x01 & { + ~ We're in compile mode; append first "lit", then the number, to the + ~ heap. The version of "lit" we use is the one that's current when we + ~ ourselves are compiled, hardcoded; doing a dynamic lookup would + ~ require dealing with what happens if it's not found. + dropstring-with-result + [ ' lit entry-to-execution-token literal ] + , , + exit + } if + + ~ We're in interpret mode; push the number to the stack. Or at least, that's + ~ what the code we're interpreting will see. Really it's already on the + ~ stack, just clean everything else up and leave it there. + dropstring-with-result exit + } if + + ~ If it's neither in the dictionary nor a number, just print an error. + s" No such word: " emitstring value@ emitstring dropstring exit ; + +: funquit { funterpret } forever ; + +funquit 4 5 + . bye |