duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

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:
Mfs/doc/dict.txt | 16+---------------
Mfs/doc/struct.txt | 21++++++++++++++++-----
Mfs/lib/struct.fs | 2++
Mfs/tests/lib/struct.fs | 12++++++++++--
Mfs/xcomp/bootlo.fs | 7+++++--
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