commit 9dd1577a009cdc97fe318d0e96bc62731736d68c
parent e1249db39d27511761e07e0a74b37ebdd8ca3cff
Author: Christian Ermann <christianermann@gmail.com>
Date: Wed, 30 Oct 2024 12:17:45 -0700
Add 'evaluate' to interpret file in memory
Diffstat:
4 files changed, 109 insertions(+), 9 deletions(-)
diff --git a/Dockerfile b/Dockerfile
@@ -40,6 +40,7 @@ FROM build-tools as build
ENV PATH="$PATH:/opt/riscv/bin"
COPY ns16550a.s .
COPY forth.s .
+COPY forth.f .
COPY riscv32-virt.ld .
RUN riscv64-unknown-elf-gcc -ggdb -static -nostdlib -nostdinc -nostartfiles -x assembler-with-cpp -march=rv32i -mabi=ilp32 -T riscv32-virt.ld -o forth.elf ns16550a.s forth.s
diff --git a/forth.f b/forth.f
@@ -0,0 +1,3 @@
+
+: test type ;
+
diff --git a/forth.s b/forth.s
@@ -147,6 +147,20 @@ 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
@@ -155,7 +169,11 @@ accept_impl:
li s6, 0x0A # '\n'
li s7, 0x0D # '\r'
1:
- jal uart_get_char
+ la t0, _input_get_char
+ load_cell t0, 0(t0)
+ push x
+ jalr t0
+ pop x
beq w, s6, 2f
beq w, s7, 2f
sb w, 0(x)
@@ -167,17 +185,24 @@ accept_impl:
pop_ret ra
ret
-defword "refill-tib", 10, 0, 0xC8155C0B, refill_tib, accept
- .int tib, accept, dup, q_branch, _refill_tib_failed
+defword "refill-buffer", 13, 0, 0x4B9E9FEE, refill_buffer, accept
+ # ( addr max-len -- recv'd-len )
+ .int two_dup, accept, dup, q_branch, _refill_buffer_failed
.int source_len, store
- .int tib, drop, source_addr, store
+ .int drop, source_addr, store
.int lit, 0, source_offset, store
.int lit, -1
-_refill_tib_failed:
.int exit
+_refill_buffer_failed:
+ .int swap, drop, swap, drop, exit
-defword "refill", 6, 0, 0x238BAA91, refill, refill_tib
- .int refill_tib
+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
.int exit
defcode "source", 6, 0, 0x238BAA91, source, refill
@@ -204,6 +229,11 @@ defcode "source-offset", 13, 0, 0x7F8C1674, source_offset, source_len
push w
next
+defcode "source-id", 9, 0, 0x965ED1E2, source_id, source_offset
+ la w, _source_id
+ push w
+ next
+
defcode "tib", 3, 0, 0xC90B0194, tib, source_len
# ( -- addr len )
la w, _tib
@@ -213,6 +243,15 @@ defcode "tib", 3, 0, 0xC90B0194, tib, source_len
push w
next
+defcode "fib", 3, 0, 0xBCE49236, fib, tib
+ # ( -- addr len )
+ la w, _fib
+ push w
+ la w, _fib_len
+ load_cell w, 0(w)
+ push w
+ next
+
defcode "parse-word", 10, 0, 0xB218226F, parse_word, source
la w, _source
load_cell w, 0(w) # buff addr
@@ -299,9 +338,21 @@ _interpret_execute_word:
_interpret_parse_area_empty:
.int drop, drop, exit
_interpret_word_not_found:
- .int branch, _interpret_start
+ .int drop, branch, _interpret_start
-defcode "branch", 6, 0, 0xB6873945, branch, interpret
+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
load_cell w, 0(ip)
mv ip, w
next
@@ -409,6 +460,13 @@ defcode "drop", 4, 0, 0xA9A58D8C, drop, swap
pop zero
next
+defcode "2dup", 3, 0, 0xD330F226, two_dup, lit
+ load_cell w, 0(psp)
+ load_cell x, cell(psp)
+ push x
+ push w
+ next
+
defword "allot", 5, 0, 0xADB1A69F, allot, drop
.int dp, add_store
.int exit
@@ -522,6 +580,32 @@ defcode "immediate?", 10, 0, 0x89F23E9F, immediate_q, execute
push w
next
+.section ".text"
+file_get_char:
+ la w, _bootstrap
+ load_cell w, 0(w)
+ la x, _bootstrap_len
+ load_cell x, 0(x)
+ sub x, x, w
+ la y, _bootstrap_offset
+ load_cell y, 0(y)
+ add w, w, y
+ sub x, x, y
+ beqz x, _file_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
+ ret
+
.section ".rodata"
program:
.int type
@@ -539,14 +623,22 @@ _meta: .int __meta_start
_state: .int state_immediate
+_bootstrap: .int __file_start
+_bootstrap_len: .int __file_len
+_bootstrap_offset: .int 0
+
_source: .int _tib
_source_len: .int 0
+_source_id: .int 0
_input_offset: .int 0
_tib: .space 255
_tib_len: .int 255
+_fib: .space 255
+_fib_len: .int 255
+
.section ".text.boot"
start:
la psp, __stacktop
diff --git a/riscv32-virt.ld b/riscv32-virt.ld
@@ -1,4 +1,7 @@
+TARGET(binary)
+INPUT("forth.f")
+
OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
OUTPUT_ARCH(riscv)
ENTRY(start)
@@ -14,6 +17,7 @@ SECTIONS {
. = ORIGIN(RAM);
.text : { *(.text.boot); *(.text); *(.text.*) } >RAM
+ .text : { __file_start = .; "forth.f" ; __file_len = . - __file_start; } >RAM
.rodata : { *(.rodata) } >RAM
. = ALIGN(4);
__here_start = .;