forth-riscv

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

commit fd2034c2bb35c5a237c1b9ac1763daa9b8a89363
parent c66ecfa37d879c0570763964d6ea54b0b0b99f6f
Author: Christian Ermann <christianermann@gmail.com>
Date:   Thu, 31 Oct 2024 15:32:09 -0700

Add '>number' and update 'interpret'

Diffstat:
Mforth.s | 90++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 82 insertions(+), 8 deletions(-)

diff --git a/forth.s b/forth.s @@ -290,7 +290,62 @@ defcode "parse-word", 10, 0, 0xB218226F, parse_word, fib push x # word len next -defcode "word>hash", 9, 0, 0x50E0A245, word_to_hash, parse_word +defcode ">number", 7, 0, 0x2F770E4C, to_number, parse_word + pop x # word len + pop w # word addr + mv y, zero # initial value + mv s3, zero # sign flag + la s4, _base + load_cell s4, 0(s4) + + beqz x, _to_number_empty_string + + lb t0, 0(w) + addi w, w, 1 + addi x, x, -1 + li t1, 0x2D # '-' + bne t0, t1, _to_number_digit_value + addi s3, s3, -1 + bnez x, _to_number_loop + +_to_number_empty_string: + addi x, x, -1 + j _to_number_done + +_to_number_invalid: + addi x, x, 1 + j _to_number_sign + +_to_number_loop: + mul y, y, s4 + lb t0, 0(w) + addi w, w, 1 + addi x, x, -1 + +_to_number_digit_value: + addi t0, t0, -48 + bltz t0, _to_number_invalid + addi t1, t0, -10 + bltz t1, _to_number_base + addi t0, t0, -7 + addi t1, t0, -10 + bltz t1, _to_number_invalid + +_to_number_base: + bgt t0, s4, _to_number_invalid + add y, y, t0 + bnez x, _to_number_loop + +_to_number_sign: + beqz s3, _to_number_done + neg y, y + +_to_number_done: + push y + push x + next + +defcode "word>hash", 9, 0, 0x50E0A245, word_to_hash, to_number pop w # word address load_cell w, hash_offset(w) push w # word hash @@ -324,9 +379,10 @@ defcode "execute", 7, 0, 0xA01E3D98, execute, to_cfa defword "interpret", 9, 0, 0x1F98C57A, interpret, execute _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 parse_word, q_dup, q_branch, _interpret_parse_area_empty + .int two_dup + .int find, q_dup, q_branch, _interpret_word_not_found + .int nip, nip, to_cfa .int compiling_q, q_branch, _interpret_execute_word .int dup .int immediate_q, zero_equal, q_branch, _interpret_execute_word @@ -334,10 +390,15 @@ _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 to_number, zero_equal, q_branch, _interpret_retry + .int compiling_q, q_branch, _interpret_start +_interpret_compile_number: + .int lit, lit, comma, comma, branch, _interpret_start +_interpret_retry: .int drop, branch, _interpret_start +_interpret_parse_area_empty: + .int drop, exit defword "evaluate", 8, 0, 0xACE4360A, evaluate, interpret .int lit, 1, source_id, store @@ -473,7 +534,14 @@ defcode "dup", 3, 0, 0xD330F226, dup, align push w next -defcode "swap", 4, 0, 0x64ED874E, swap, dup +defcode "?dup", 4, 0, 0xFD2928D3, q_dup, dup + load_cell w, 0(psp) + beqz w, _q_dup_done + push w +_q_dup_done: + next + +defcode "swap", 4, 0, 0x64ED874E, swap, q_dup pop w pop x push w @@ -484,7 +552,12 @@ defcode "drop", 4, 0, 0xA9A58D8C, drop, swap pop zero next -defcode "2dup", 3, 0, 0xD330F226, two_dup, drop +defcode "nip", 3, 0, 0x21A41868, nip, drop + pop w + store_cell w, 0(psp) + next + +defcode "2dup", 3, 0, 0xD330F226, two_dup, nip load_cell w, 0(psp) load_cell x, cell(psp) push x @@ -655,6 +728,7 @@ _here: .int __here_start _meta: .int __meta_start _state: .int state_immediate +_base: .int 10 _bootstrap: .int __file_start _bootstrap_len: .int __file_len