summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--readme.md29
-rw-r--r--sanctuary.fs12
-rw-r--r--sanctuary.s29
3 files changed, 68 insertions, 2 deletions
diff --git a/readme.md b/readme.md
index 0b89015..73af8a2 100644
--- a/readme.md
+++ b/readme.md
@@ -8,6 +8,7 @@ documentation and will be obvious or documented in the description.
- `a`: memory address
- `c`: one byte value
+- `e`: error code
- `n`: signed integer
- `u`: unsigned integer
- `z`: null-terminated string
@@ -63,6 +64,11 @@ which simply pushes the address following the definition to the stack.
this messes with the return stack and is not meant to be called
outside of its specific context.
+### `(defer) ( -- )`
+activate a deferred word from the address following this word's call.
+this messes with the return stack and is not meant to be called
+outside of its specific context.
+
### `(does>) ( -- )`
run non-default behaviour of a `create`d word.
pushes the data location onto the stack and calls the word
@@ -171,6 +177,13 @@ return true if n1 is greater than or equal to n2.
### `>body ( ht -- xt )`
yield the code field of header token.
+### `>errno ( u -- val err )`
+transform the result of a system call into a value/error pair.
+if no error occured, err is zero and val is the result,
+if an error has occurred, val is zero and
+err is a negative integer
+(the exact value depends on the error)
+
### `>in ( -- a )`
variable containing the index of the first unparsed character
in the input buffer.
@@ -283,6 +296,9 @@ transform an amount of cells into an amount of bytes.
### `char ( "c" -- c )`
yield the value of the first character of the next word in the input stream.
+### `close-file ( fd -- e )`
+close the file at fd.
+
### `cmove ( a1 a2 u -- )`
copy u bytes of memory from a1 to a2.
bytes are copied in low memory to high memory order.
@@ -434,6 +450,11 @@ and no number is provided.
### `octal ( -- )`
set current base to octal.
+### `open-file ( z mode -- fd e )`
+open the given file with the given mode (probably r/w, r/o or w/o)
+and yield the resulting file descriptor
+note that this word uses the pad.
+
### `or ( u1 u2 -- u )`
perform bitwise OR on u1 and u2.
@@ -487,6 +508,10 @@ move a value from the return stack to the working stack.
### `rdrop ( R: u -- )`
remove the value at the top of the return stack.
+### `read-file ( a u fd -- u' e )`
+read u bytes from fd into memory location a.
+u' is the number of bytes read.
+
### `repeat ( -- ) IMMEDIATE COMPILE-ONLY`
in a begin-while-repeat loop, loop back to the condition.
@@ -637,6 +662,10 @@ a constant, meaning 'write only', used for file I/O.
if given flag is true, continue the current begin-while-repeat loop,
otherwise branch to after.
+### `write-file ( a u fd -- u' e )`
+write u bytes from a into fd.
+u' is the number of bytes written.
+
### `xor ( u1 u2 -- u )`
perform bitwise XOR on u1 and u2.
diff --git a/sanctuary.fs b/sanctuary.fs
index 1aab4e2..e198710 100644
--- a/sanctuary.fs
+++ b/sanctuary.fs
@@ -74,6 +74,7 @@ decimal
r> dup >resolve 4 + ( u a )
postpone literal ( a ) drop ; immediate compile-only
: zstrlen dup begin dup c@ 0<> while 1+ repeat swap - ;
+\ todo s>z becomes s>z, s>z writes to pad (will then need to be moved below pno)
: s>z here -rot cmove, 0 c, ;
\ PRIVATISATION AND HIDING {{{
@@ -126,6 +127,12 @@ variable hld
: #> drop hld @ pad$ over - ;
\ }}}
+\ ERRNO {{{
+\ transform syscall result into [RESULT] IOR output,
+\ where IOR is zero on no error and negative on an error (RESULT then being 0)
+: >errno dup 0< if 0 swap else 0 then ;
+\ }}}
+
\ I/O {{{
0 constant stdin
1 constant stdout
@@ -142,6 +149,11 @@ variable hld
0 constant r/o
1 constant w/o
2 constant r/w
+
+: open-file swap >r 0 r> sys-open >errno ;
+: close-file sys-close ;
+: read-file >r swap r> sys-read >errno ;
+: write-file >r swap r> sys-write >errno ;
\ }}}
bye
diff --git a/sanctuary.s b/sanctuary.s
index d37ca5a..02fb961 100644
--- a/sanctuary.s
+++ b/sanctuary.s
@@ -40,6 +40,14 @@
%2:
%endmacro
+%macro defdefer 3
+ defcode %1, %2, %3
+ mov r11, dodefer
+ call r11
+ dq do_%2
+ do_%2:
+%endmacro
+
; this is just taken from jewelforth, and does not correspond
; to how user variables are planned to work in sanctuary
; so todo make better later? i don't know if it really matters
@@ -50,6 +58,17 @@
pspush qword %2
ret
%endmacro
+
+%macro defdefervar 4
+ %2: dq %4
+ defdict %1, %2, %3
+ mov r11, dodefer
+ call r11
+ dq do_%2
+ do_%2:
+ pspush qword %2
+ ret
+%endmacro
; }}}
%assign smudge_mask 0x1
@@ -258,7 +277,7 @@ defcode "parse", parse, 0
; r11: input addr
; r12: pointer into currently processing word
; r13: same as r12 but kept at xt
-defcode "find", find, 0
+defdefer "find", find, 0
pspop r10 ; u
pspop r11 ; a
mov r12, qword [latest]
@@ -1124,6 +1143,12 @@ defcode "(does>)", dodoes, 0
jmp r12
; no RET
+defcode "(defer)", dodefer, 0
+ pop r11
+ mov r12, [r11]
+ jmp r12
+ ; also no RET
+
; TEMPORARY WONKY DEBUGGING FUNCTIONS {{{
; .s {{{
defcode ".s", dots, 0
@@ -1184,7 +1209,7 @@ 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
+defdefervar "latest", latest, 0, lfa_latest
initfile: incbin "sanctuary.fs"
initlen equ $ - initfile