From afb6afb35d212499a691c0168ad3f1e479792e18 Mon Sep 17 00:00:00 2001 From: Jonas Hvid Date: Sun, 4 Oct 2020 01:06:21 +0200 Subject: [PATCH] Make S" work inside compiled words The approach we're using here is kinda silly and cause by the fact that I wasn't/still aren't very familiar with Forth outside of trying to implement it myself. From doing a bit of reading, it sounds like S" is primarily intended to be used inside definitions -- not at runtime. So now we use the old, weird S" (that has a single static buffer and only works at runtime) to bootstrap the system, then replace it with a more sensible S" that only works at compile time. --- example.f | 21 +++++++-------------- main.asm | 11 +++++++++++ sys.f | 20 +++++++++++++++++--- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/example.f b/example.f index 41993d7..38cd6e4 100644 --- a/example.f +++ b/example.f @@ -1,6 +1,3 @@ -( vim: syntax=forth -) - : FIB ( n -- Fn ) 0 1 ( n a b ) 0 ( n a b i ) @@ -13,16 +10,12 @@ DUP 4 PICK = UNTIL DROP SWAP DROP SWAP DROP ; ( a+b ) -S" HELLO-ADDR" CREATE -S" Hello!" DUP ROT -STORE-STRING -: HELLO - ' HELLO-ADDR LIT, TELL NEWLINE ; - -HELLO +: HELLO S" Hello!" TELL NEWLINE ; -S" 10 FIB = " TELL -10 FIB .U -SPACE S" (Expected: 59)" TELL NEWLINE +: TEST-FIB + S" 10 FIB = " TELL + 10 FIB .U + SPACE S" (Expected: 59)" TELL NEWLINE ; -TERMINATE +HELLO +TEST-FIB diff --git a/main.asm b/main.asm index 537d0e8..43eef7a 100644 --- a/main.asm +++ b/main.asm @@ -160,6 +160,17 @@ forth_asm LIT, 'LIT' push rax next +;; When LITSTRING is encountered while executing a word, it instead reads a +;; string from the definition of that word, and places that string on the stack +;; as (buffer, length). +forth_asm LITSTRING, 'LITSTRING' + lodsb + push rsi ; Buffer + movzx rax, al + push rax ; Length + add rsi, rax ; Skip over string before resuming execution + next + ;; Given a string (a pointer following by a size), return the location of the ;; dictionary entry for that word. If no such word exists, return 0. forth_asm FIND, 'FIND' diff --git a/sys.f b/sys.f index 38708d1..6e7c853 100644 --- a/sys.f +++ b/sys.f @@ -75,6 +75,21 @@ EXIT [ KEY 10 = UNTIL ; +\ So far, S" has only worked in immediate mode, which is backwards -- actually, +\ the main use-case of this is as a compile-time word. Let's fix that. +: S" IMMEDIATE + ' LITSTRING , + HERE @ 0 C, \ We will put the length here + 0 + BEGIN + 1 + + KEY DUP C, + 34 = UNTIL + \ Remove final " + HERE @ 1 - HERE ! + 1 - + SWAP C! ; + ( Compile the given string into the current word directly. ) : STORE-STRING ( str len -- ) BEGIN @@ -89,7 +104,6 @@ EXIT [ ( Read a number from standard input. ) : READ-NUMBER READ-WORD PARSE-NUMBER ; -S" Ready." TELL NEWLINE +: RESTART S" Ready." TELL NEWLINE ; +RESTART -( vim: syntax=forth -) -- 2.39.2