commit 51ea8748a32244c57113c6bedef511397cfe76dd
parent 31ebc4bf49bc204657605429ea5a6523482fa3f4
Author: Christian Ermann <christianermann@gmail.com>
Date: Thu, 28 Nov 2024 12:26:08 -0800
Add prefix-based parsing to interpreter
Diffstat:
| M | src/forth.s | | | 138 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------ |
1 file changed, 118 insertions(+), 20 deletions(-)
diff --git a/src/forth.s b/src/forth.s
@@ -1,5 +1,3 @@
-.option norelax
-
.extern uart_put_char
.extern uart_get_char
.extern uart_put_string
@@ -178,6 +176,38 @@ defcode "bye", bye, 0x71F39F63
next
# -----------------------------------------------------------------------------
+# built-in prefixes
+# -----------------------------------------------------------------------------
+
+defvar "#", prefix_decimal, 0x260C9112
+ .int 0x23
+ .int 0
+ .int string_to_decimal
+
+defvar "$", prefix_hex, 0x210C8933
+ .int 0x24
+ .int _prefix_decimal
+ .int string_to_hex
+
+defvar "%", prefix_binary, 0x200C87A0
+ .int 0x25
+ .int _prefix_hex
+ .int string_to_binary
+
+defvar "'", prefix_address, 0x220C8AC6
+ .int 0x27
+ .int _prefix_binary
+ .int string_to_address
+
+defvar "*", prefix_execute, 0x2F0C9F3D
+ .int 0x2A
+ .int _prefix_address
+ .int string_to_execute
+
+defvar "latest-prefix", latest_prefix, 0x86C823C5
+ .int _prefix_execute
+
+# -----------------------------------------------------------------------------
# constants and variables
# -----------------------------------------------------------------------------
@@ -479,6 +509,53 @@ _to_number_done:
mv w, x
next
+defword "string>#", string_to_decimal, 0x75831783
+ la x, _base
+ li y, 10
+ sw y, 0(x)
+ jal to_number
+ bnez w, _string_to_number_fail
+ not w, w
+ exit
+
+defword "string>$", string_to_hex, 0x7A831F62
+ la x, _base
+ li y, 16
+ sw y, 0(x)
+ jal to_number
+ bnez w, _string_to_number_fail
+ not w, w
+ exit
+
+defword "string>%", string_to_binary, 0x7B8320F5
+ la x, _base
+ li y, 2
+ sw y, 0(x)
+ jal to_number
+ bnez w, _string_to_number_fail
+ not w, w
+ exit
+
+_string_to_number_fail:
+ mv w, zero
+ exit
+
+defword "string>address", string_to_address, 0xFDC3CE9A
+ jal find
+ addi x, w, code_offset
+ push x
+ exit
+
+defword "string>execute" string_to_execute, 0xC1A5C011
+ jal string_to_address
+ beqz w, _string_to_execute_done
+ pop w
+ jal execute
+ push w
+ li w, 1
+_string_to_execute_done:
+ exit
+
defcode "word>hash", word_to_hash, 0x50E0A245
load_cell w, hash_offset(w)
next
@@ -525,15 +602,45 @@ defcode "execute", execute, 0xA01E3D98
jr x
# 'next' should be called by the executed word
+defcode "match-prefix", match_prefix, 0x2C1AB495
+ lw x, 0(psp)
+ lb x, 0(x)
+ la y, _latest_prefix
+ lw y, 0(y)
+ push w
+_match_prefix_loop:
+ lb w, 0(y)
+ beq w, x, _match_prefix_done
+ addi y, y, cell
+ lw y, 0(y)
+ bnez y, _match_prefix_loop
+_match_prefix_fail:
+ mv w, zero
+ next
+_match_prefix_done:
+ # decrement string length
+ lw x, 0(psp)
+ addi x, x, -1
+ sw x, 0(psp)
+ # increment string address
+ lw x, cell(psp)
+ addi x, x, 1
+ sw x, cell(psp)
+ # code address
+ addi w, y, 2*cell
+ next
+
defword "interpret", interpret, 0x1F98C57A
_interpret_start:
jal parse_word
beqz w, _interpret_parse_area_empty
- jal two_dup
+ jal match_prefix
+ bnez w, _interpret_execute_prefix
+_interpret_find_word:
+ jal drop
jal find
- beqz w, _interpret_word_not_found
+ beqz w, _interpret_retry
_interpret_word_found:
- addi psp, psp, 2 * cell # nip, nip
addi w, w, code_offset
# compiling?
la x, _state
@@ -554,24 +661,15 @@ _interpret_execute_word:
pop w
jalr x
j _interpret_start
-_interpret_word_not_found:
- pop w
- jal to_number
- bnez w, _interpret_retry
+_interpret_execute_prefix:
+ load_cell x, 0(w)
pop w
- # compiling?
- la x, _state
- load_cell x, 0(x)
- beqz x, _interpret_start
-_interpret_compile_number:
- push w
- la w, lit
- jal jal_to
- jal comma
- jal comma
+ jalr x
+ pop x
+ beqz w, _interpret_retry
+ mv w, x
j _interpret_start
_interpret_retry:
- addi psp, psp, cell
pop w
j _interpret_start
_interpret_parse_area_empty: