Implement INTERPRET-STRING
[rrq/jonasforth.git] / main.asm
index 538039b5ab29b0cd402d26105e3df89d3c5f2424..7443c48aac209a0d46f08d1cddeb710766655ee9 100644 (file)
--- a/main.asm
+++ b/main.asm
@@ -207,6 +207,25 @@ forth_asm READ_WORD, 'READ-WORD'
   mov rsi, [.rsi]
   next
 
+;; Read a word from a buffer. Expects (buffer buffer-length) on the stack.
+;; Updates buffer and buffer-length, such that the word has been removed from
+;; the buffer. Appends (word-buffer word-buffer-length) to the stack.
+forth_asm POP_WORD, 'POP-WORD'
+  pushr rsi
+
+  pop rcx ; Length
+  pop rsi ; Buffer
+
+  call pop_word
+
+  push rsi ; Updated buffer
+  push rcx ; Length of updated buffer
+  push rdi ; Word buffer
+  push rdx ; Length of word buffer
+
+  popr rsi
+  next
+
 ;; Takes a string on the stack and replaces it with the decimal number that the
 ;; string represents.
 forth_asm PARSE_NUMBER, 'PARSE-NUMBER'
@@ -389,7 +408,10 @@ forth_asm TIMESMOD, '/MOD'
 
 ;; Read user input until next " character is found. Push a string containing the
 ;; input on the stack as (buffer length). Note that the buffer is only valid
-;; until the next call to S" and that no more than 255 character can be read.
+;; until the next call to S" and that no more than 255 characters can be read.
+;;
+;; [TODO] We want to be able to use this when reading from buffers (e.g. in
+;; INTERPRET-STRING) too!
 forth_asm READ_STRING, 'S"'
   push rsi
 
@@ -487,6 +509,8 @@ forth_asm EQL, '='
   next
 
 forth MAIN, 'MAIN'
+  dq SYSCODE
+  dq INTERPRET_STRING
   dq INTERPRET
   dq BRANCH, -8 * 2
   dq TERMINATE
@@ -505,6 +529,19 @@ forth HERE, 'HERE'
   dq LIT, here
   dq EXIT
 
+forth SYSCODE, 'SYSCODE'
+  dq LIT, sysf
+  dq LIT, sysf.len
+  dq EXIT
+
+forth INPUT_BUFFER, 'INPUT-BUFFER'
+  dq LIT, input_buffer
+  dq EXIT
+
+forth INPUT_LENGTH, 'INPUT-LENGTH'
+  dq LIT, input_buffer_length
+  dq EXIT
+
 segment readable writable
 
 ;; The LATEST variable holds a pointer to the word that was last added to the
@@ -535,6 +572,21 @@ DOTU.printed_length dq ?
 here dq here_top
 here_top rq $4000
 
+;; Pointer to input buffer and its length. Used as local variable in
+;; INTERPRET-STRING (see bootstrap.asm). [TODO] The code organization is a bit
+;; awkward here.
+input_buffer dq ?
+input_buffer_length dq ?
+
 ;; Return stack
 rq $2000
 return_stack_top:
+
+segment readable
+
+;; We store some Forth code in sys.f that defined common words that the user
+;; would expect to have available at startup. To execute these words, we just
+;; include the file directly in the binary, and then interpret it at startup.
+sysf file 'sys.f'
+sysf.len = $ - sysf
+