summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--readme.md26
-rw-r--r--sanctuary.s43
2 files changed, 61 insertions, 8 deletions
diff --git a/readme.md b/readme.md
index 9257664..4613d21 100644
--- a/readme.md
+++ b/readme.md
@@ -23,16 +23,22 @@ store the 64 bit value u into the memory address a.
### `#tib ( -- a )`
variable containing the amount of characters in the input buffer.
-### `(header) ( a u -- xt )`
-create a dictionary header for a word named the provided string.
-this word does not set the code field.
-this word returns an incompleted xt and does not update latest.
-
### `( ( -- ) IMMEDIATE`
start a comment which lasts until the next closed bracket.
if the unclosed bracket in the description above bothers you,
have a closing bracket: ).
+### `(0handler) ( -- )`
+the very early error handler, which simply quits the program.
+
+### `(execute) ( a -- )`
+call the function at the address.
+
+### `(header) ( a u -- xt )`
+create a dictionary header for a word named the provided string.
+this word does not set the code field.
+this word returns an incompleted xt and does not update latest.
+
### `* ( u1 u2 -- u)`
multiply u1 and u2.
@@ -143,6 +149,10 @@ remove the two topmost values from the stack.
### `2dup ( u1 u2 -- u1 u2 u1 u2 )`
duplicate the two topmost values on the stack.
+### `abort ( -- )`
+call the error handler
+(the address of which is in the variable `handler`)
+
### `and ( u1 u2 -- u )`
perform bitwise AND on u1 and u2.
@@ -209,6 +219,9 @@ 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.
+### `execute ( xt -- )`
+call the word xt.
+
### `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
@@ -218,6 +231,9 @@ its xt is returned along with the true flag.
### `grow ( u -- )`
grows, and marks as executable, the user memory space by u bytes.
+### `handler ( -- a )`
+variable containing the address of the current error handler.
+
### `here ( -- a )`
yields the address of the first available byte in user memory.
diff --git a/sanctuary.s b/sanctuary.s
index 0d35337..53749cc 100644
--- a/sanctuary.s
+++ b/sanctuary.s
@@ -1,15 +1,26 @@
; sanctuary
; macros {{{
-; TODO: error handling (once i add that)
+; the error handling feels slow but i dont know a better way
+; todo at some point make these use actual error codes
%macro pspush 1
lea r15, [r15-8]
mov qword [r15], %1
+
+ cmp r15, wstk_b
+ jge %%ok
+ call abort
+ %%ok:
%endmacro
%macro pspop 1
mov %1, qword [r15]
lea r15, [r15+8]
+
+ cmp r15, wstk
+ jle %%ok
+ call abort
+ %%ok:
%endmacro
%define s_latest 0
@@ -58,8 +69,8 @@
%assign init_brk 0x9c400
section .bss
-resq 4091
-wstk: resq 1
+wstk_b: resq 4091
+wstk: resq 1
section .text
global _start
@@ -502,6 +513,16 @@ defcode "char", char, 0
pspush r11
ret
+defcode "(execute)", do_execute, 0
+ pspop r11
+ call r11
+ ret
+
+defcode "execute", execute, 0
+ call to_body
+ call do_execute
+ ret
+
; number {{{
defcode "number", number, 0 ; ( c-addr u -- ?n flag )
pspop r11 ; u
@@ -965,6 +986,21 @@ defcode "?branch", q_branch, 0
mov qword [here], r12
ret
+; error handling {{{
+; default error handler, because we don't have QUIT yet
+; it just Exits with exit code 1
+defcode "(0handler)", do_0handler, 0
+ mov rdi, 1
+ mov rax, __NR_exit
+ syscall
+ ret
+
+defcode "abort", abort, 0
+ mov r11, qword [handler]
+ call r11
+ ret
+; }}}
+
; TEMPORARY WONKY DEBUGGING FUNCTIONS {{{
; .s {{{
defcode ".s", dots, 0
@@ -1024,6 +1060,7 @@ defvar "dp$", dp$, 0, 0
defvar "tib", tib, 0, initfile
defvar "#tib", n_tib, 0, initlen
defvar ">in", to_in, 0, 0
+defvar "handler", handler, 0, do_0handler
defvar "latest", latest, 0, lfa_latest
initfile: incbin "sanctuary.fs"