commit d140833201f383389c4f802113748baff60ee0d8
parent dd834857099b98fb76fef04441461d1e5ca74ec7
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Sat, 24 Sep 2022 10:59:55 -0400
Make struct fields iterable
Diffstat:
3 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/fs/lib/str.fs b/fs/lib/str.fs
@@ -9,6 +9,9 @@ $100 value STR_MAXSZ
: s) ( str -- a ) c@+ + ;
\ write "str" to here
: s, ( str -- ) dup c@ 1+ move, ;
+\ compare a string to a range
+: s[]= ( str a len -- f )
+ rot dup c@ rot = if ( a str ) c@+ []= else 2drop 0 then ;
\\ append character to end of string
: sappend ( c str -- ) tuck s) c! dup c@ 1+ swap c! ;
diff --git a/fs/tests/kernel.fs b/fs/tests/kernel.fs
@@ -1,4 +1,6 @@
-?f<< tests/harness.fs
+?f<< /tests/harness.fs
+?f<< /lib/meta.fs
+?f<< /lib/str.fs
testbegin
\ Testing native words and boot.fs
@@ -129,4 +131,10 @@ create data3 7 , 9 c, ' mybleh , 999 ,
data3 Bazooka bling 999 #eq
data3 Bazooka baz 9 #eq
+\ we can iterate fields of a struct
+' Bazooka does' Struct lastfield
+S" bling" over wordname[] s[]= #
+does' Field next S" baz" over wordname[] s[]= #
+does' Field next S" bar" over wordname[] s[]= #
+does' Field next 0 #eq
testend
diff --git a/fs/xcomp/bootlo.fs b/fs/xcomp/bootlo.fs
@@ -213,6 +213,7 @@ HERE ivalue here
: structsz' ( struct -- a ) does' 5 + ;
: structsz ( struct -- sz ) structsz' @ ;
: structdict' does' ;
+: structlastfield' structsz' 4 + ;
: _curroot! ( struct -- )
\ Make root word of struct temporarily point to sysdict
@@ -222,7 +223,8 @@ HERE ivalue here
structdict' @ sysdict ! ;
: struct[
- doer immediate 0 , 0 c, _extends dup if structsz' @ then ,
+ doer immediate 0 , 0 c,
+ _extends dup if structsz' CELLSZ 2 * move, else ( 0 ) , 0 , then
sysdict @ dup to _cur to _bkp
_extends ?dup if
_curroot! 0 to@! _extends structdict' sysdict !
@@ -242,28 +244,30 @@ does> ( 'struct )
_bkp sysdict @! _cur e>w structdict' ! ;
: sallot ( n -- ) _cur e>w structsz' +! ;
-: field ( sz off -- ) doer immediate , ,
- does> @+ swap @ swap ( a? sz off )
+: _sfield ( sz -- ) doer immediate
+ current _cur e>w structlastfield' @! ( next ) ,
+ _cur e>w structsz , ( sz ) dup , sallot
+ does> CELLSZ + @+ swap @ swap ( a? sz off )
compiling if ( sz off )
litn compile + 0 toptr @! ( sz toptr )
?dup if swap ?b execute, else ?b compile @ then
else ( a sz off )
rot + 0 toptr @! ( sz a toptr )
?dup not if ['] @ then rot ?b (woff) + execute then ;
-: method ( off -- ) doer , does> @ over + @ execute ;
-: _sfield dup _cur e>w structsz field sallot ;
: sfield CELLSZ _sfield ;
: sfieldw 2 _sfield ;
: sfieldb 1 _sfield ;
-: smethod _cur e>w structsz method CELLSZ sallot ;
+: smethod doer _cur e>w structsz , CELLSZ sallot does> @ over + @ execute ;
struct[ Struct
sfield dict
1 sallot \ 1b that is always zero after dict link. See doc/impl
sfield size
+ sfield lastfield \ pointer to field *word*
]struct
struct[ Field
+ sfield next
sfield offset
sfield size \ 1, 2 or 4
]struct