summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkitty <nepeta@canaglie.net>2026-03-24 23:23:19 +1100
committerkitty <nepeta@canaglie.net>2026-03-24 23:23:19 +1100
commit839e3510d3ad5bece904001a76d65901664ec4da (patch)
tree635363f9b365205a3a181ad414cd4c2519b5e0c1
parent6819ca743193bb9ae4e32c9c87c98b27d06c0c82 (diff)
zstrings and the worst hack in the universe
-rw-r--r--readme.md24
-rw-r--r--sanctuary.fs13
2 files changed, 36 insertions, 1 deletions
diff --git a/readme.md b/readme.md
index beb2a86..a13df97 100644
--- a/readme.md
+++ b/readme.md
@@ -13,6 +13,7 @@ sanctuary is a 64-bit subroutine threaded forth for amd64 linux systems.
- `ht`: header token
- `""`: string in input buffer
- `|`: 'or'
+- `,`: used to separate multiple stack effects when multiple are needed
## Glossary
@@ -353,6 +354,13 @@ yields the address of the first available byte in user memory.
### `hex ( -- )`
set current base to hexadecimal.
+### `hijacks ( xt "word" -- )`
+'hijack' an existing definition to perform the action of xt.
+this word *will* corrupt the dictionary if used outside
+its very specific context (replacing core assembly words
+with better versions in forth), so it should be avoided
+in favour of `defer` and friends.
+
### `if ( ? -- ) IMMEDIATE COMPILE-ONLY`
if the flag is true, execute the following if statement,
terminated by `else` or `then`.
@@ -428,11 +436,15 @@ yield the address of the return pointer.
note that the address points to the return stack *before*
this word was called.
-### `s" ( "string" -- ) IMMEDIATE COMPILE-ONLY`
+### `s" ( "string" -- , COMPILES: -- a u ) IMMEDIATE COMPILE-ONLY`
compile into the definition code to push the given string,
terminated by a double quote.
the string data and length are stored inline in the definition.
+### `s>z ( a u -- a )`
+compile into user memory a copy of the given regular string
+converted to a null-terminated string.
+
### `smudge ( -- )`
toggles the smudge bit on the xt in latest.
@@ -510,6 +522,16 @@ otherwise branch to after.
### `xor ( u1 u2 -- u )`
perform bitwise XOR on u1 and u2.
+### `z" ( "string" -- , COMPILES: -- a ) IMMEDIATE COMPILE-ONLY`
+compile into the definition code to push the given string,
+terminated by a double quote.
+the string is null terminated and does not store a length;
+this is meant for interfacing with the linux system.
+
+### `zstrlen ( a -- u )`
+the length of a null terminated string in bytes.
+the ending null byte is not counted.
+
## dictionary format
note that the string length of one byte limits a word's name to 255 characters.
diff --git a/sanctuary.fs b/sanctuary.fs
index 2715912..c420890 100644
--- a/sanctuary.fs
+++ b/sanctuary.fs
@@ -61,6 +61,12 @@
branch >mark >r 2dup cmove, nip ( u ) ( R: mark )
r> dup >resolve 4 + ( u a )
postpone literal ( a ) postpone literal ( u ) ; immediate compile-only
+: z" [ char " ] literal parse ( a u )
+ branch >mark >r 2dup cmove, 0 c, nip ( u ) ( R: mark )
+ r> dup >resolve 4 + ( u a )
+ postpone literal ( a ) drop ; immediate compile-only
+: zstrlen dup begin dup c@ 0<> while 1+ repeat swap - ;
+: s>z here -rot cmove, 0 c, ;
1 constant stdout
2 constant stderr
@@ -68,4 +74,11 @@
: type swap stdout 1 syscall3 ;
: emit sp 1 swap stdout 1 syscall3 2drop ;
+hex
+\ really i should just change the builtins to work with defer
+: hijacks ' ( word ) here >r dp ! ( temporarily set dp so we can use , )
+ 49 c, bb c, ( xt ) , \ mov r11, xt
+ 41 c, ff c, e3 c, \ jmp r11
+ r> dp ! ;
+decimal
bye