~vdupras/duskos

4b7527215f84849241e07354fd80c5de090ecef6 — Virgil Dupras 2 days ago 336a34a
cc: make funcmap fields into lib/struct unbounded fields
3 files changed, 29 insertions(+), 12 deletions(-)

M fs/cc/gen.fs
M fs/cc/map.fs
M fs/lib/struct.fs
M fs/cc/gen.fs => fs/cc/gen.fs +1 -1
@@ 140,7 140,7 @@ ASTIDCNT wordtbl gentbl ( node -- )
  ops$
  dup data1 entry
  dup data2 ( astfunc mapfunc )
  here over fmap.address! \ set address
  here over to fmap.address \ set address
  dup fmap.argsize swap fmap.sfsize over - ( argsz locsz ) vmprelude,
  genchildren
  _debug if current here current - spit nl> then ;

M fs/cc/map.fs => fs/cc/map.fs +8 -11
@@ 19,15 19,12 @@
\ 4b link to AST_DECLARE node
newxdict curmap

: fmap.astnode @ ;
: fmap.sfsize 4 + @ ;
\ Return fmap Stack Frame size and then increase it by 4.
: fmap.sfsize+ ( n fmap -- ) 4 + +! ;
: fmap.argsize 8 + @ ;
: fmap.argsize+ ( n fmap -- ) 8 + +! ;
: fmap.address 12 + @ ;
: fmap.address! 12 + ! ;
: fmap.vmap 16 + ;
\ Funcmap. Unbounded fields because the full struct generates more noise in the
\ code.
4  ufield  fmap.sfsize
8  ufield  fmap.argsize
12 ufield  fmap.address
16 'ufield fmap.vmap

struct Varmap
  field vmap.sfoff


@@ 53,7 50,7 @@ struct Varmap
  curmap @ fmap.sfsize , dup , ( dnode )
  dup data2 ( dnode type ) typesize swap data3 ( nbelem )
  1 max * ( sfsize )
  curmap @ fmap.sfsize+ ;
  curmap @ to+ fmap.sfsize ;

: findvarinmap ( name funcentry -- varentry )
  fmap.vmap xfind not if _err then ;


@@ 64,7 61,7 @@ struct Varmap
  dup Function ( astfunc fmap ) over data2! ( astfunc ) begin ( curnode )
    AST_DECLARE nextnodeid dup if ( astdecl )
      dup parentnode nodeid AST_ARGSPECS = if \ inc argssize field
        4 curmap @ fmap.argsize+ then
        4 curmap @ to+ fmap.argsize then
      dup Variable 0 else 1 then
  until ( curnode ) drop  ;


M fs/lib/struct.fs => fs/lib/struct.fs +20 -0
@@ 29,3 29,23 @@

: field doer laststruct to' execute , lastoffset , 4 to+ lastoffset does>
  dup @ @ swap 4 + @ + to? ?dup if execute else @ then ;

\ A 'field returns the address of the field instead of the value. It doesn't
\ follow "to" semantics and does not increase struct size.
: 'field doer laststruct to' execute , lastoffset , does>
  dup @ @ swap 4 + @ + ;

\ Unbounded fields
\ These works a bit like struct fields, but without an associated struct. In
\ some cases, it makes more sense to have them instead of a full struct. Each
\ invocation of them require the struct's address on the top of PS. They also
\ support "to" semantics, but they are a bit awkward. Example:

\ 4 ( offset ) ufield foo
\ $1234 foo ( equivalent to $1238 @ )
\ 42 $1234 to+ foo ( equivalent to 42 $1238 +! )

: ufield ( off -- ) doer , does> ( a 'w )
  @ + to? ?dup if execute else @ then ;

: 'ufield ( off -- ) doer , does> ( a 'w ) @ + ;