forth-riscv

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

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:
MDockerfile | 1+
Aforth.f | 3+++
Mforth.s | 110++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mriscv32-virt.ld | 4++++
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 = .;