commit 7dbd683d96d9451049631fae54e2167d07bcbcad
parent c1cc08c8b24bd89ab982ad8defdc70d213d3231a
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Sat, 7 Jan 2023 14:12:09 -0500
Add "structfind" and "sfield!"
See doc/struct
Diffstat:
5 files changed, 34 insertions(+), 24 deletions(-)
diff --git a/fs/doc/dict.txt b/fs/doc/dict.txt
@@ -276,21 +276,7 @@ current -- w Yield the last word to be added to the system dictionary.
## Structure
-struct[ "x" -- Create new struct "x" and begin defining it.
-]struct -- Exit current struct definition.
-extends "x" -- Find struct "x" in system dictionary and make the next
- defined struct extend it.
-sfield "x" -- Add a new struct 4b field named "x".
-sfieldw "x" -- Add a new struct 2b field named "x".
-sfieldb "x" -- Add a new struct 1b field named "x".
-sconst "x" -- Add a new struct read-only 4b field named "x".
-sfield' sz "x" -- Add a new struct buffer of size sz named "x".
-smethod "x" -- Add a new struct method named "x".
-structbind 'data "x y" --
- Create a new binding named "x" that binds 'data to struct
- named "y".
-rebind 'data 'bind --
- Bind 'data to structbind 'bind.
+See doc/struct.
## I/O
diff --git a/fs/doc/struct.txt b/fs/doc/struct.txt
@@ -170,12 +170,12 @@ intended to be called from the outside (so, not only methods) begin with a ":".
## API
-struct[ <name> -- Create a struct named "name" and enter its definition
+struct[ "name" -- Create a struct named "name" and enter its definition
]struct -- Exit the definition of the current structure
-struct+[ <name> -- Re-open the definition of existing struct "name"
-extends <name> -- Make the next struct definition extend struct "name"
+struct+[ "name" -- Re-open the definition of existing struct "name"
+extends "name" -- Make the next struct definition extend struct "name"
-structbind <struct> <name> ( 'data -- )
+structbind "struct" "name" ( 'data -- )
Create a new struct bind named "name" binding "'data" to the struct "struct".
rebind ( 'data 'bind -- )
Rebind struct binding "'bind" to data "'data".
@@ -187,6 +187,9 @@ structdict' w -- a Address of struct namespace dictionary.
structsz w -- sz Size of the fields and methods in the struct.
structsz' w -- 'sz Address of the size field cell.
structlastfield' w -- a Address of the last field of the struct.
+structfind ( "struct" "name" -- 'word )
+ Find a word named "name" in "struct" and returns its address. Aborts if not
+ found.
Fields words, described above, only work inside struct[ definitions and must be
followed by their name:
@@ -200,7 +203,7 @@ ssmethod
These words (also described above) have a slightly different signature:
-sfield' <name> ( size -- )
+sfield' "name" ( size -- )
sallot ( size -- )
## Inspecting structures
@@ -226,3 +229,11 @@ STRUCTFIELD_REGULAR sfield'
STRUCTFIELD_CONST sconst
STRUCTFIELD_METHOD smethod
STRUCTFIELD_STATICMETHOD ssmethod
+
+Words:
+
+sfield! ( val data 'field -- )
+ Set the 4b value in "data" associated with field "'field" to "val". Useless on
+ regular fields because it's the same as using "to", but can be useful for
+ methods or consts. The result of "structfind" returns a "'field".
+
diff --git a/fs/lib/struct.fs b/fs/lib/struct.fs
@@ -13,3 +13,5 @@ struct[ Field
sfield size \ 1, 2 or 4
sfield type \ STRUCTFIELD_*
]struct
+
+: sfield! ( val data word -- ) does' Field offset + ! ;
diff --git a/fs/tests/lib/struct.fs b/fs/tests/lib/struct.fs
@@ -5,7 +5,7 @@ testbegin
struct[ Foo
sfield bar
sfieldb baz
- smethod :bleh
+ ssmethod :bleh
sfield bling
]struct
@@ -14,8 +14,16 @@ struct[ Foo
S" bling" over wordname[] s[]= #
dup does' Field type STRUCTFIELD_REGULAR #eq
does' Field next S" :bleh" over wordname[] s[]= #
-dup does' Field type STRUCTFIELD_METHOD #eq
+dup does' Field type STRUCTFIELD_STATICMETHOD #eq
does' Field next S" baz" over wordname[] s[]= #
does' Field next S" bar" over wordname[] s[]= #
does' Field next 0 #eq
+
+: bleh1 42 ;
+: bleh2 54 ;
+create data 0 , 0 c, ' bleh1 , 0 ,
+
+data Foo :bleh 42 #eq
+' bleh2 data structfind Foo :bleh sfield!
+data Foo :bleh 54 #eq
testend
diff --git a/fs/xcomp/bootlo.fs b/fs/xcomp/bootlo.fs
@@ -195,6 +195,10 @@ alias noop [then]
: structsz ( struct -- sz ) structsz' @ ;
: structdict' does' ;
: structlastfield' structsz' 4 + ;
+: _structfind ( 'struct "name" -- 'word )
+ @ ( 'dict ) word swap ( str 'dict ) find ( 'word )
+ ?dup not if curword stype abort" not in namespace!" then ;
+: structfind ( "struct" "name" -- 'word ) ' does' _structfind ;
: _curroot! ( struct -- )
\ Make root word of struct temporarily point to sysdict
@@ -214,8 +218,7 @@ alias noop [then]
sysdict @ to _curroot then
word" SZ" code _cur e>w structsz' litn compile @ exit,
does> ( 'struct )
- @ ( 'dict ) word swap ( str 'dict ) find ( 'word )
- ?dup not if curword stype abort" not in namespace!" then
+ _structfind
dup 1- c@ $80 and not compiling and \ compile only if not immediate
if execute, else execute then ;
: ]struct