forth-riscv

My forth
git clone git://git.electrosoup.com/forth-riscv
Log | Files | Refs

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:
Mforth.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