summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkitty <nepeta@canaglie.net>2026-03-28 20:24:50 +1100
committerkitty <nepeta@canaglie.net>2026-03-28 20:24:50 +1100
commitde41cbce8997fa2cba9047db7cc3b5d9d5aaccce (patch)
tree9699ea06009f4903821a0cbf3de9d6b30054c33e
parent2814698c08e02c65793bd9cbc9437ff56dd61fbe (diff)
PNO and some other stuff
-rw-r--r--readme.md63
-rw-r--r--sanctuary.fs23
2 files changed, 80 insertions, 6 deletions
diff --git a/readme.md b/readme.md
index 7b813cd..0b89015 100644
--- a/readme.md
+++ b/readme.md
@@ -10,21 +10,35 @@ documentation and will be obvious or documented in the description.
- `c`: one byte value
- `n`: signed integer
- `u`: unsigned integer
+- `z`: null-terminated string
- `?`: boolean flag
- `xt`: execution token
- `ht`: header token
- `""`: string in input buffer
- `|`: 'or'
-- `,`: used to separate multiple stack effects when multiple are needed
+- `,`: separates multiple stack effects when multiple are needed
## Glossary
the following is a list of words available in this forth.
+certain constants for linux system interaction are not documented;
+they are identical to their C versions.
### `! ( u a -- )`
store the 64 bit value u into the memory address a.
-### `#tib ( -- a )`
+### `# ( u -- u' )`
+add a numeric digit to the numeric output buffer
+by dividing u by `base` and appending the remainder.
+
+### `#> ( u -- a u )`
+drop the remaining digit processing debris from the stack
+and return the numeric output buffer contents as a string.
+
+### `#pad ( -- u )`
+length of the pad buffer.
+
+### `#tib ( -- u )`
variable containing the amount of characters in the input buffer.
### `' ( "word" -- xt )`
@@ -77,7 +91,7 @@ add u2 to u1.
### `+! ( a -- )`
add one to the value at memory address a.
-### `+to ( comp: "name" -- | intr: u "name" -- ) IMMEDIATE`
+### `+to ( comp: "name" -- , intr: u "name" -- ) IMMEDIATE`
compile or execute (depending on `state`) code to add u to the contents
of a `value`. (in compile mode u is whatever was on the stack already.)
@@ -90,7 +104,7 @@ subtract u2 from u1.
### `-! ( a -- )`
subtract one from the value at memory address a.
-### `-to ( comp: "name" -- | intr: u "name" -- ) IMMEDIATE`
+### `-to ( comp: "name" -- , intr: u "name" -- ) IMMEDIATE`
compile or execute (depending on `state`) code to subtract u from the contents
of a `value`. (in compile mode u is whatever was on the stack already.)
@@ -129,9 +143,13 @@ fetch the 64 bit value at memory address a.
### `= ( n1 n2 -- ? )`
return true if n1 and n2 are equal.
+
### `< ( n1 n2 -- ? )`
return true if n1 is less than n2.
+### `<# ( -- )`
+initialise the system for numeric output.
+
### `<= ( n1 n2 -- ? )`
return true if n1 is less than or equal to n2.
@@ -369,6 +387,12 @@ its very specific context (replacing core assembly words
with better versions in forth), so it should be avoided
in favour of `defer` and friends.
+### `hld ( -- a )`
+the address of the beginning of the used section of the pad buffer.
+
+### `hold ( c -- )`
+add the given charater into the numeric output buffer.
+
### `if ( ? -- ) IMMEDIATE COMPILE-ONLY`
if the flag is true, execute the following if statement,
terminated by `else` or `then`.
@@ -416,6 +440,13 @@ perform bitwise OR on u1 and u2.
### `over ( u1 u2 -- u1 u2 u1 )`
copy the second-highest value on the stack and move it to the top of the stack.
+### `pad ( -- a )`
+the address of the start of the pictured numeric output buffer.
+
+### `pad$ ( -- a )`
+the address of the end of the pictured numeric output buffer.
+useful because numeric output uses the buffer high-memory first.
+
### `parse ( "name<c>" c -- a u )`
parse one word from the input buffer,
separated by a newline or the character c,
@@ -444,6 +475,12 @@ and activated with `privatise`.
### `privatise ( -- )`
activate a private section.
+### `r/o ( -- 0 )`
+a constant, meaning 'read only', used for file I/O.
+
+### `r/w ( -- 2 )`
+a constant, meaning 'read and write', used for file I/O.
+
### `r> ( -- u ) ( R: u -- )`
move a value from the return stack to the working stack.
@@ -470,6 +507,9 @@ the string data and length are stored inline in the definition.
compile into user memory a copy of the given regular string
converted to a null-terminated string.
+### `sign ( n -- )`
+add a minus sign to the numeric output buffer if n is less than zero.
+
### `smudge ( -- )`
toggles the smudge bit on the xt in latest.
@@ -495,6 +535,13 @@ push the file descriptor of stdout to the stack.
### `swap ( u1 u2 -- u2 u1 )`
swap the two topmost values on the stack.
+### `sys-close ( fd -- n )`
+perform a `close(2)` system call on the given file descriptor.
+
+### `sys-open ( mode flag z -- n )`
+perform an `open(2)` system call on the file named
+in the null-terminated string z, using the given file mode and flags.
+
### `sys-read ( u a fd -- n )`
perform a `read(2)` system call, reading into the buffer `u a`
from file descriptor `fd`.
@@ -545,7 +592,7 @@ conclude an if statement.
### `tib ( -- a )`
a variable containing the address of the current input buffer.
-### `to ( comp: "name" -- | intr: u "name" -- ) IMMEDIATE`
+### `to ( comp: "name" -- , intr: u "name" -- ) IMMEDIATE`
compile or execute (depending on `state`) code to modify the contents
of a `value`.
@@ -583,6 +630,9 @@ create a value called name, the initial value of which is u.
### `variable ( "name" -- )`
create a variable word, which yields an address that can be written and read.
+### `w/o ( -- 1 )`
+a constant, meaning 'write only', used for file I/O.
+
### `while ( ? -- ) IMMEDIAT COMPILE-ONLYE`
if given flag is true, continue the current begin-while-repeat loop,
otherwise branch to after.
@@ -625,3 +675,6 @@ but it diverges in a few notable places:
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.
+- PNO words (`<# # #>` etc.) work with single cell numbers.
+ this is because this forth has no double number support.
+ (128 bit integer arithmetic does not seem all that useful to me)
diff --git a/sanctuary.fs b/sanctuary.fs
index 15d5a0e..1aab4e2 100644
--- a/sanctuary.fs
+++ b/sanctuary.fs
@@ -111,6 +111,21 @@ decimal
: munmap 11 syscall2 ;
\ }}}
+\ NUMERIC OUTPUT {{{
+\ this buffer is also used as a temporary string buffer.
+255 constant #pad
+create pad 255 cells allot
+: pad$ pad #pad + ;
+variable hld
+
+: <# pad$ hld ! ;
+: hold 1 hld -! ( chr ) hld @ c! ;
+: sign 0< if [ char - ] literal hold then ;
+: # base @ /mod swap 9 over < if 7 + then [ char 0 ] literal + hold ;
+: #s begin # dup 0= until ;
+: #> drop hld @ pad$ over - ;
+\ }}}
+
\ I/O {{{
0 constant stdin
1 constant stdout
@@ -118,9 +133,15 @@ decimal
: sys-write 0 syscall3 ;
: sys-read 1 syscall3 ;
+: sys-open 2 syscall3 ;
+: sys-close 3 syscall1 ;
-: type swap stdout 1 syscall3 drop ;
+: type swap stdout sys-read drop ;
: emit sp 1 type drop ;
+
+0 constant r/o
+1 constant w/o
+2 constant r/w
\ }}}
bye