summary refs log tree commit diff
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2026-05-08 02:31:09 -0700
committerIrene Knapp <ireneista@irenes.space>2026-05-08 02:31:09 -0700
commit5481ec020eabce663b5e7423c5e217005df6ad49 (patch)
treefbf790b1e8c6e752c33f92bffd756baac5c141bf
parent07f2e7911326d2b3b1f826b551c27648e13ae452 (diff)
add a rough draft of a self-hosted "interpret"
Force-Push: yes
Change-Id: I063232ca7d840237f53dc805bc896c7b452cedc8
-rw-r--r--interpret.e59
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