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.
-( vim: syntax=forth
-)
-
: FIB ( n -- Fn )
0 1 ( n a b )
0 ( n a b i )
: FIB ( n -- Fn )
0 1 ( n a b )
0 ( n a b i )
DUP 4 PICK = UNTIL
DROP SWAP DROP SWAP DROP ; ( a+b )
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 ;
+;; 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'
;; 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'
+\ 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
( Compile the given string into the current word directly. )
: STORE-STRING ( str len -- )
BEGIN
( Read a number from standard input. )
: READ-NUMBER READ-WORD PARSE-NUMBER ;
( Read a number from standard input. )
: READ-NUMBER READ-WORD PARSE-NUMBER ;
+: RESTART S" Ready." TELL NEWLINE ;
+RESTART