forth-riscv

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

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