commit 1a74ad03c8760e54a6d25735a10444beeccb36be
parent c0fec2a510ce08c3a9d6888931b97d1bc18f59f7
Author: Christian Ermann <christianermann@gmail.com>
Date: Sun, 27 Oct 2024 19:08:34 -0700
Add 'hash' and 'create' to create new headers at runtime
Diffstat:
2 files changed, 68 insertions(+), 4 deletions(-)
diff --git a/forth.s b/forth.s
@@ -174,7 +174,7 @@ find_impl:
# x = word name length
push_ret ra
jal hash_impl # w = word hash
- la s3, latest
+ la s3, _latest
load_cell s3, 0(s3)
_check_word_hidden:
lb t0, flag_offset(s3)
@@ -223,6 +223,66 @@ defword "quit", 4, 0, 0x47878736, quit, branch
.int branch
.int -dcell
+defcode "create", 6, 0, 0x26BB595D, create, quit
+ pop x # name length
+ pop w # name address
+ jal create_impl
+ next
+
+create_impl:
+ push_ret ra
+ jal hash_impl
+ pop_ret ra
+
+ la t0, here
+ load_cell t1, 0(t0)
+
+ la t2, _latest
+ load_cell t3, 0(t2)
+
+ store_cell t1, 0(t2) # update 'latest' to point 'here'
+ store_cell t3, 0(t1) # add link to last word
+ addi t1, t1, cell
+
+ # store hash
+ store_cell w, 0(t1)
+ addi t1, t1, cell
+
+ # store meta address
+ # TODO: store info about word at address
+ store_cell zero, 0(t1)
+ addi t1, t1, cell
+
+ # store flags
+ sb zero, 0(t1)
+ addi t1, t1, 1
+
+ # align to cell boundary
+ addi t1, t1, 3
+ andi t1, t1, 0xFFFFFFFC
+ store_cell t1, 0(t0)
+ ret
+
+defcode "hash", 4, 0, 0xEDBF0FE3, hash, create
+ pop x # string length
+ pop w # string address
+ jal hash_impl
+ push w # string hash
+ next
+
+hash_impl: # 32-bit fnv1a
+ li t0, 2166136261 # hash
+ li t1, 16777619 # prime
+_hash_char:
+ lb t2, 0(w)
+ addi w, w, 1
+ addi x, x, -1
+ xor t0, t0, t2
+ mul t0, t0, t1
+ bgtz x, _hash_char
+ mv w, t0
+ ret
+
.section ".rodata"
program:
.int type
@@ -233,7 +293,9 @@ version_string:
version_string_len = (. - version_string)
word_buffer: .space 255
-latest: .int name_find
+_latest: .int name_hash
+here: .int __here_start
+meta: .int __meta_start
.section ".text.boot"
start:
diff --git a/riscv32-virt.ld b/riscv32-virt.ld
@@ -4,7 +4,7 @@ OUTPUT_ARCH(riscv)
ENTRY(start)
MEMORY {
- RAM (rwx) : ORIGIN = 0x80000000, LENGTH = 0x8000000
+ RAM (rwx) : ORIGIN = 0x80000000, LENGTH = 128M
}
SECTIONS {
@@ -14,6 +14,8 @@ SECTIONS {
. = ORIGIN(RAM);
.text : { *(.text.boot); *(.text); *(.text.*) } >RAM
- .rodata : { *(.rodata); } >RAM
+ .rodata : { *(.rodata) } >RAM
+ __here_start = .;
+ __meta_start = __here_start + 0x7000000;
}