summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--readme.md18
-rw-r--r--sanctuary.s55
2 files changed, 71 insertions, 2 deletions
diff --git a/readme.md b/readme.md
index 51bad71..9a52103 100644
--- a/readme.md
+++ b/readme.md
@@ -10,7 +10,9 @@ for amd64 linux systems.
- `n`: signed integer
- `u`: unsigned integer
- `?`: boolean flag
+- `xt`: execution token
- `""`: string in input buffer
+- `|`: 'or'
## Glossary
@@ -43,6 +45,12 @@ marks the u bytes starting at address a as executable.
this is used primarily to mark the program break,
which is used as the user memory space.
+### `find ( a u -- a u 0 | xt -1 )`
+look in the dictionary for the word a (of u characters).
+a zero is returned along with the original given string
+if no word was found. if a word was found,
+its xt is returned along with the true flag.
+
### `grow ( u -- )`
grows the user memory space by u bytes.
@@ -90,3 +98,13 @@ note that the string length of one byte limits a word's name to 255 characters.
## reserved registers
the register `r15` is reserved for the parameter stack pointer.
+
+## differences from standard forth
+
+for the most part this forth intends to be in line with standards
+but it diverges in a few notable places:
+
+- the most visally obvious one by far,
+ this forth uses lower case word names for core words.
+- `find` takes `a u` instead of a counted string,
+ and does not return 1 for immediate words.
diff --git a/sanctuary.s b/sanctuary.s
index 2db3bc8..18c6623 100644
--- a/sanctuary.s
+++ b/sanctuary.s
@@ -40,6 +40,13 @@
%endmacro
; }}}
+%assign smudge_mask 0x1
+%assign immediate_mask 0x2
+%assign comp_only_mask 0x4
+
+%assign true 0x0
+%assign false (~0x0)
+
%assign INTERPRET 0x0
%assign COMPILING (~0x0)
@@ -68,8 +75,6 @@ _start:
call type
call bye
-teststr: db "TESTING"
-
defcode "brk@", brk@, 0
xor rdi, rdi
mov rax, __NR_brk
@@ -225,6 +230,52 @@ defcode "type", type, 0
syscall
ret
+; r9: processing temporary value
+; r10: input size
+; r11: input addr
+; r12: pointer into currently processing word
+; r13: same as r12 but kept at xt
+defcode "find", find, 0
+ pspop r10 ; u
+ pspop r11 ; a
+ mov r12, qword [latest]
+ mov r13, r12
+
+.check_smudge:
+ add r12, 8
+ mov r9b, byte [r12]
+ test r9b, smudge_mask
+ jnz .no
+
+ inc r12
+ mov r9b, byte [r12]
+ cmp r9b, r10b
+ jne .no
+
+ mov rsi, r12
+ inc rsi
+ mov rdi, r11
+ mov rcx, r10
+ repe cmpsb
+ jnz .no
+
+ pspush r13
+ mov r13, true
+ pspush r13
+ ret
+
+.no:
+ mov r12, qword [r13]
+ mov r13, r12
+ cmp r12, 0
+ jne .check_smudge
+
+ pspush r11
+ pspush r10
+ mov r13, false
+ pspush r13
+ ret
+
; .s {{{
defcode ".s", dots, 0
push r11