commit c47a3e50ff83f7d4a0f98f456d7f2a67c1f0ab90
parent e71693d96a90fdd0850f1b5459ac95dfb19a43b5
Author: Christian Ermann <christianermann@gmail.com>
Date: Mon, 4 Nov 2024 16:21:37 -0800
Add 'read-line' to replace 'accept' for files
Diffstat:
| M | forth.s | | | 172 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------- |
1 file changed, 117 insertions(+), 55 deletions(-)
diff --git a/forth.s b/forth.s
@@ -158,20 +158,6 @@ defcode "accept", 6, 0, 0x08247E29, accept, key
push w # recv'd len
next
-_input_get_char: .int uart_get_char
-
-defcode "accept-uart", 11, 0, 0xEA73CDE0, accept_uart, accept
- la w, _input_get_char
- la x, uart_get_char
- store_cell x, 0(w)
- next
-
-defcode "accept-file", 11, 0, 0xD269E17A, accept_file, accept_uart
- la w, _input_get_char
- la x, file_get_char
- store_cell x, 0(w)
- next
-
accept_impl:
push_ret ra
mv s4, w
@@ -180,10 +166,8 @@ accept_impl:
li s6, 0x0A # '\n'
li s7, 0x0D # '\r'
1:
- la t0, _input_get_char
- load_cell t0, 0(t0)
push x
- jalr t0
+ jal uart_get_char
pop x
beq w, s6, 2f
beq w, s7, 2f
@@ -196,24 +180,22 @@ accept_impl:
pop_ret ra
ret
-defword "refill-buffer", 13, 0, 0x4B9E9FEE, refill_buffer, accept_file
- # ( addr max-len -- recv'd-len )
- .int two_dup, accept, dup, q_branch, _refill_buffer_failed
+defword "refill", 6, 0, 0x238BAA91, refill, accept
+ .int source_id, fetch, q_branch, _refill_tib
+_refill_fib:
+ .int fib, read_line, q_branch, _refill_failed
+ .int fib, drop, branch, _refill_success
+_refill_tib:
+ .int tib, accept, dup, q_branch, _refill_failed
+ .int tib, drop
+_refill_success:
+ .int source_addr, store
.int source_len, store
- .int drop, source_addr, store
.int lit, 0, source_offset, store
.int lit, -1
.int exit
-_refill_buffer_failed:
- .int swap, drop, swap, drop, exit
-
-defword "refill", 6, 0, 0x238BAA91, refill, refill_buffer
- .int source_id, fetch, q_branch, _refill_tib
-_refill_fib:
- .int fib, refill_buffer
- .int exit
-_refill_tib:
- .int tib, refill_buffer
+_refill_failed:
+ .int drop, lit, 0
.int exit
defcode "source", 6, 0, 0x238BAA91, source, refill
@@ -413,14 +395,12 @@ _interpret_parse_area_empty:
defword "evaluate", 8, 0, 0xACE4360A, evaluate, interpret
.int lit, 1, source_id, store
- .int accept_file
_evaluate_loop:
.int refill, q_branch, _evaluate_done
.int interpret
.int branch, _evaluate_loop
_evaluate_done:
.int lit, 0, source_id, store
- .int accept_uart
.int exit
defcode "branch", 6, 0, 0xB6873945, branch, evaluate
@@ -576,12 +556,17 @@ defcode "drop", 4, 0, 0xA9A58D8C, drop, swap
pop zero
next
-defcode "nip", 3, 0, 0x21A41868, nip, drop
- pop w
- store_cell w, 0(psp)
- next
+defcode "over", 4, 0, 0x31F6520F, over, drop
+ load_cell w, cell(psp)
+ push w
+ next
+
+defcode "nip", 3, 0, 0x21A41868, nip, over
+ pop w
+ store_cell w, 0(psp)
+ next
-defcode "2dup", 3, 0, 0xD330F226, two_dup, nip
+defcode "2dup", 3, 0, 0x5E46F4D6, two_dup, nip
load_cell w, 0(psp)
load_cell x, cell(psp)
push x
@@ -599,11 +584,19 @@ defcode "+", 1, 0, 0xC4ADC675, plus, two_dup
push w
next
-defcode "or", 2, 0, 0x5D342984, or_, plus
- pop w
- pop x
- or w, w, x
- push w
+defcode "-", 1, 0, 0x280C9438, minus, plus
+ pop x
+ pop w
+ sub w, w, x
+ push w
+ next
+
+defcode "or", 2, 0, 0x5D342984, or_, minus
+ pop w
+ pop x
+ or w, w, x
+ push w
+ next
defcode "aligned", 7, 0, 0xC73174DF, aligned, or_
pop w
@@ -628,18 +621,48 @@ _zero_done:
defcode "=", 1, 0, 0x380CAD68, equal, zero_equal
pop w
pop x
- bne w, x, _equal_not
+ beq w, x, _equal
+ push zero
+ next
+_equal:
+ push_imm -1
+ next
+
+defcode "<>", 2, 0, 0x93F7201F, not_equal, equal
+ pop w
+ pop x
+ bne w, x, _not_equal
+ push zero
+ next
+_not_equal:
push_imm -1
next
-_equal_not:
+
+defcode ">", 1, 0, 0x3B0CB221, greater_than, not_equal
+ pop w
+ pop x
+ bgt x, w, _greater_than
+ push zero
+ next
+_greater_than:
+ push_imm -1
+ next
+
+defcode "<", 1, 0, 0x390CAEFB, less_than, greater_than
+ pop w
+ pop x
+ blt x, w, _less_than
push zero
next
+_less_than:
+ push_imm -1
+ next
# -----------------------------------------------------------------------------
# compiler
# -----------------------------------------------------------------------------
-defword "create", 6, 0, 0x26BB595D, create, equal
+defword "create", 6, 0, 0x26BB595D, create, less_than
.int latest, fetch, comma # link
.int hash, comma # hash
.int lit, 0, comma # meta
@@ -745,8 +768,12 @@ defword "constant", 8, 0, 0x0691EA25, constant, variable
.int comma # initialize to value on stack
.int exit
-.section ".text"
-file_get_char:
+defcode "read-char", 10, 0, 0xF07E2044, read_char, variable
+ jal _read_char_impl
+ push w
+ next
+
+_read_char_impl:
la w, _bootstrap
load_cell w, 0(w)
la x, _bootstrap_len
@@ -756,21 +783,56 @@ file_get_char:
load_cell y, 0(y)
add w, w, y
sub x, x, y
- beqz x, _file_eof
+ beqz x, _read_char_eof
lb w, 0(w)
- li t0, 0x0A # '\n'
- bne w, t0, _file_got_char
- li w, 0x20
-_file_got_char:
addi y, y, 1
la x, _bootstrap_offset
store_cell y, 0(x)
ret
-_file_eof:
- li w, 0x0A
+_read_char_eof:
+ mv w, zero
ret
+defword "buffer-open", 11, 0, 0x79AAD9CA, buffer_open, read_char
+ # ( addr len -- addr end-addr cur-addr )
+ .int over, plus, over
+ .int exit
+
+defword "buffer-close", 12, 0, 0x42B7429E, buffer_close, buffer_open
+ # ( open-buffer -- len )
+ .int nip, swap, minus
+ .int exit
+
+defword "buffer-emit", 11, 0, 0xEA240555, buffer_emit, buffer_close
+ # ( open-buffer char -- open-buffer )
+ .int over, store, lit, 1, plus
+ .int exit
+
+defword "buffer-full?", 12, 0, 0x070A2E6C, buffer_full_q, buffer_emit
+ # ( open-buffer -- flag )
+ .int two_dup, greater_than # TODO: >=
+ .int exit
+
+defword "read-line", 10, 0, 0xAF1308A2, read_line, buffer_full_q
+ .int buffer_open
+_read_line_loop:
+ .int read_char
+ .int dup, lit, 0x0A, not_equal, q_branch, _read_line_newline
+ .int dup, lit, 0x00, not_equal, q_branch, _read_line_eof
+ .int buffer_emit
+ .int buffer_full_q, q_branch, _read_line_buffer_full
+ .int branch, _read_line_loop
+_read_line_newline:
+ .int drop, buffer_close, lit, -1, exit
+_read_line_eof:
+ .int drop, buffer_close, dup, q_branch, _read_line_eof_fail
+ .int lit, -1, exit
+_read_line_eof_fail:
+ .int lit, 0, exit
+_read_line_buffer_full:
+ .int buffer_close, lit, 0, exit
+
.section ".rodata"
program:
.int type