diff options
| author | kitty <nepeta@canaglie.net> | 2026-03-29 20:23:28 +1100 |
|---|---|---|
| committer | kitty <nepeta@canaglie.net> | 2026-03-29 20:23:28 +1100 |
| commit | a059eda0ecd73cbb6277da3bf64a550097bc346d (patch) | |
| tree | 535a9219248ab79a8b972d129a995e6eb7439083 | |
| parent | de41cbce8997fa2cba9047db7cc3b5d9d5aaccce (diff) | |
DEFER-ed words in core, file open/read/write/close
| -rw-r--r-- | readme.md | 29 | ||||
| -rw-r--r-- | sanctuary.fs | 12 | ||||
| -rw-r--r-- | sanctuary.s | 29 |
3 files changed, 68 insertions, 2 deletions
@@ -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 |
