commit b02ede06c26c1f58b0c95016109969f161d80207
parent 5c4325e5be52464ae22613fe540e6fd5202de959
Author: Christian Ermann <christianermann@gmail.com>
Date: Tue, 29 Oct 2024 15:02:36 -0700
Replace 'word' with 'parse-word'
Diffstat:
| M | forth.s | | | 144 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------ |
1 file changed, 112 insertions(+), 32 deletions(-)
diff --git a/forth.s b/forth.s
@@ -4,6 +4,7 @@
#define w a0
#define x a1
+#define y a2
#define ip s1
#define psp sp
#define rsp s2
@@ -139,32 +140,97 @@ defcode "key", 3, 0, 0x6815C86C, key, emit
push a0
next
-defcode "word", 4, 0, 0x6A98E9FD, word, key
- li s3, 0x20 # space
- li s4, 0x0A # new line
- li s5, 0x0D # carriage return
-_skip_whitespace:
+defcode "accept", 6, 0, 0x08247E29, accept, key
+ pop w # max len
+ pop x # address
+ jal accept_impl
+ push w # recv'd len
+ next
+
+accept_impl:
+ push_ret ra
+ mv s4, w
+ mv s5, w
+ beqz s5, 2f
+ li s6, 0x0A # '\n'
+ li s7, 0x0D # '\r'
+1:
jal uart_get_char
- beq w, s3, _skip_whitespace
- beq w, s4, _skip_whitespace
- beq w, s5, _skip_whitespace
- la x, word_buffer
-_store_char:
+ beq w, s6, 2f
+ beq w, s7, 2f
sb w, 0(x)
addi x, x, 1
-_next_char:
- jal uart_get_char
- beq w, s3, _word_end
- beq w, s4, _word_end
- bne w, s5, _store_char
-_word_end:
- la w, word_buffer
- sub x, x, w
+ addi s5, s5, -1
+ bnez s5, 1b
+2:
+ sub w, s4, s5
+ pop_ret ra
+ ret
+
+defcode "refill", 6, 0, 0x238BAA91, refill, accept
+ # fill input buffer from the user input device
+ la x, tib
+ la w, tib_len
+ load_cell w, 0(w)
+ jal accept_impl
+ # set source to terminal input buffer
+ la y, _source_len
+ store_cell w, 0(y)
+ # set input offset to 0
+ la y, _input_offset
+ store_cell zero, 0(y)
+ # return true
+ push_imm -1
+ next
+
+defcode "source", 6, 0, 0x238BAA91, source, refill
+ la w, _source
+ load_cell w, 0(w)
+ la x, _source_len
+ load_cell x, 0(x)
push w
push x
next
-defcode "find", 4, 0, 0xBDF0855A, find, word
+defcode "parse-word", 10, 0, 0xB218226F, parse_word, source
+ la w, _source
+ load_cell w, 0(w) # buff addr
+ la x, _source_len
+ load_cell x, 0(x) # buff len
+ # apply input offset
+ la y, _input_offset
+ load_cell y, 0(y)
+ add w, w, y
+ sub x, x, y
+
+ li s3, 0x20 # space
+ mv s4, w
+1: # find start of word
+ beqz x, 3f # out of chars? -> stop!
+ lb t0, 0(w) # next char!
+ addi w, w, 1 # inc. addr
+ addi y, y, 1 # inc. offset
+ addi x, x, -1 # dec. len
+ beq t0, s3, 1b # space? -> skip!
+
+ addi s4, w, -1 # addr of word
+2: # find end of word
+ beqz x, 3f
+ lb t0, 0(w) # next char!
+ addi y, y, 1 # inc. offset
+ beq t0, s3, 3f # space? -> stop!
+ addi w, w, 1 # inc. addr
+ addi x, x, -1 # dec. len
+ j 2b
+3: # done
+ la t0, _input_offset
+ store_cell y, 0(t0)
+ sub x, w, s4
+ push s4 # word addr
+ push x # word len
+ next
+
+defcode "find", 4, 0, 0xBDF0855A, find, parse_word
pop x # length
pop w # address
jal hash_impl
@@ -198,20 +264,25 @@ defcode "execute", 7, 0, 0xA01E3D98, execute, to_cfa
# 'next' should be called by the executed word
defword "interpret", 9, 0, 0x1F98C57A, interpret, execute
- .int word, find, dup, q_branch, _not_found
+_interpret_start:
+ .int parse_word, dup, q_branch, _interpret_parse_area_empty
+ .int find, dup, q_branch, _interpret_word_not_found
.int to_cfa
- .int compiling_q, q_branch, _execute_word
+ .int compiling_q, q_branch, _interpret_execute_word
.int dup
- .int immediate_q, zero_equal, q_branch, _execute_word
- .int comma, exit
-_execute_word:
- .int execute, exit
-_not_found:
- .int drop, exit
+ .int immediate_q, zero_equal, q_branch, _interpret_execute_word
+_interpret_compile_word:
+ .int comma, branch, _interpret_start
+_interpret_execute_word:
+ .int execute, branch, _interpret_start
+_interpret_parse_area_empty:
+ .int drop, drop, exit
+_interpret_word_not_found:
+ .int branch, _interpret_start
defcode "branch", 6, 0, 0xB6873945, branch, interpret
- load_cell t0, 0(ip)
- add ip, ip, t0
+ load_cell w, 0(ip)
+ mv ip, w
next
defcode "?branch", 7, 0, 0x6AF3C1DE, q_branch, branch
@@ -234,9 +305,10 @@ _zero_done:
next
defword "quit", 4, 0, 0x47878736, quit, zero_equal
+_quit_top:
+ .int refill, drop # TODO: What should happen when 'refill' fails?
.int interpret
- .int branch
- .int -dcell
+ .int branch, _quit_top
defcode "!", 1, 0, 0x240C8DEC, store, quit
pop w # address
@@ -402,7 +474,7 @@ defcode "hidden", 6, 0, 0xF618F139, hidden, r_bracket
next
defword ":", 1, 0, 0x3F0CB86D, colon, hidden
- .int word, create # create header
+ .int parse_word, create # create header
.int lit, docol, comma # append 'docol'
.int latest, fetch, hidden # hide word
.int r_bracket # enter 'compile' mode
@@ -446,6 +518,14 @@ _meta: .int __meta_start
_state: .int state_immediate
+_source: .int tib
+_source_len: .int 0
+
+_input_offset: .int 0
+
+tib: .space 255
+tib_len: .int 255
+
.section ".text.boot"
start:
la psp, __stacktop