duskos

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

commit f61de143ca02eda5c3594a88b2c91389d1755770
parent 0718c73159dd8ed2ec316879887c2d604a973f69
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Sun,  4 Sep 2022 10:02:14 -0400

cc: struct-ify the AST some more

Diffstat:
Mfs/cc/ast.fs | 104+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Mfs/cc/gen.fs | 22+++++++++++-----------
2 files changed, 65 insertions(+), 61 deletions(-)

diff --git a/fs/cc/ast.fs b/fs/cc/ast.fs @@ -72,6 +72,30 @@ extends DeclOrFunc struct[ Declare sfield nbelem \ for variables and args, "address" is a frame offset sfield address + + \ Number of bytes required to hold this variable declaration in memory. + : :totsize ( dnode -- size-in-bytes ) + dup type ( dnode type ) + typesize swap nbelem ( nbelem ) + 1 max * ; + + : :isarg? ( dnode -- f ) Node parent Node id AST_ARGSPECS = ; + + : :isglobal? ( dnode -- f ) Node parent Node id AST_UNIT = ; +]struct + +extends Node struct[ ArgSpecs + : :totsize ( fnode -- size-in-bytes ) + Node firstchild ( node ) 0 begin ( node r ) + over while ( node r ) + over Node id AST_DECLARE = _assert + over Declare :totsize + + swap Node nextsibling swap repeat ( node r ) nip ; +]struct + +extends Node struct[ Statements + \ is snode a function body? + : :funcbody? ( snode -- f ) Node parent Node id AST_FUNCTION = ; ]struct extends DeclOrFunc struct[ Function @@ -80,6 +104,25 @@ extends DeclOrFunc struct[ Function sfield address sfield cursf \ last SF offset computed sfield flags + +: _ ( name args-or-stmts -- dnode-or-0 ) + Node firstchild begin ( name node ) + ?dup while ( name node ) + dup Node id AST_DECLARE = if + over over Declare name s= if ( name node ) + nip exit then then + Node nextsibling repeat ( name ) drop 0 ; + +: :finddecl ( name fnode -- dnode-or-0 ) + Node firstchild ( args ) 2dup _ ?dup if + nip nip else Node nextsibling ( stmts ) _ then ; + +: :args ( fnode -- anode ) + Node firstchild dup Node id AST_ARGSPECS = _assert ; + +: :locsize ( fnode -- size-in-bytes ) + dup sfsize swap :args ArgSpecs :totsize - ; + ]struct extends Node struct[ Constant @@ -100,60 +143,24 @@ extends Node struct[ StrLit Node SZ &+ value ]struct +0 value curunit \ points to current Unit, the beginning of the AST +extends Node struct[ Unit + : :find ( name -- fnode-or-0 ) + curunit Node firstchild begin ( name node ) + ?dup while ( name node ) + over over DeclOrFunc name s= if ( name node ) + nip exit then + Node nextsibling repeat ( name ) drop 0 ; +]struct + ASTIDCNT stringlist astidnames "declare" "unit" "function" "return" "constant" "stmts" "args" "ident" "unaryop" "postop" "binop" "list" "if" "str" "call" "for" "push" "pop" -0 value curunit \ points to current Unit, the beginning of the AST 0 value curextern \ is current definition "extern"? : idname ( id -- str ) astidnames slistiter ; -: ast.unit.find ( name -- fnode-or-0 ) - curunit Node firstchild begin ( name node ) - ?dup while ( name node ) - over over DeclOrFunc name s= if ( name node ) - nip exit then - Node nextsibling repeat ( name ) drop 0 ; - -\ Number of bytes required to hold this variable declaration in memory. -: ast.decl.totsize ( dnode -- size-in-bytes ) - dup Declare type ( dnode type ) - typesize swap Declare nbelem ( nbelem ) - 1 max * ; - -: ast.decl.isarg? ( dnode -- f ) Node parent Node id AST_ARGSPECS = ; - -: ast.decl.isglobal? ( dnode -- f ) Node parent Node id AST_UNIT = ; - -: _ ( name args-or-stmts -- dnode-or-0 ) - Node firstchild begin ( name node ) - ?dup while ( name node ) - dup Node id AST_DECLARE = if - over over Declare name s= if ( name node ) - nip exit then then - Node nextsibling repeat ( name ) drop 0 ; - -: ast.func.finddecl ( name fnode -- dnode-or-0 ) - Node firstchild ( args ) 2dup _ ?dup if - nip nip else Node nextsibling ( stmts ) _ then ; - -: ast.func.args ( fnode -- anode ) - Node firstchild dup Node id AST_ARGSPECS = _assert ; - -: ast.args.totsize ( fnode -- size-in-bytes ) - Node firstchild ( node ) 0 begin ( node r ) - over while ( node r ) - over Node id AST_DECLARE = _assert - over ast.decl.totsize + - swap Node nextsibling swap repeat ( node r ) nip ; - -: ast.func.locsize ( fnode -- size-in-bytes ) - dup Function sfsize swap ast.func.args ast.args.totsize - ; - -\ is snode a function body? -: ast.stmts.funcbody? ( snode -- f ) Node parent Node id AST_FUNCTION = ; - : _[ '[' emit ; : _] ']' emit ; @@ -196,9 +203,6 @@ ASTIDCNT wordtbl astdatatbl ( node -- node ) : newnode ( parent nodeid -- newnode ) Node :new ( parent node ) dup rot Node :add ( node ) ; -: _err ( -- ) abort" ast error" ; -: _assert ( f -- ) not if _err then ; - \ Takes a token and returns the corresponding typedef (not AST type). \ For now, we always return 1 on "int". : isType? ( tok -- f ) S" int" s= ; @@ -359,7 +363,7 @@ current to parseExpression expectIdent ( dnode type name ) , , ( dnode ) nextt parseNbelem , ( dnode ) AST_FUNCTION over Node :findparent ?dup _assert ( dnode fnode ) - 0 , over ast.decl.totsize swap to+ Function sfsize ; + 0 , over Declare :totsize swap to+ Function sfsize ; : parseDeclareInit ( dnode tok -- ) dup S" =" s= not if to nexttputback drop exit then diff --git a/fs/cc/gen.fs b/fs/cc/gen.fs @@ -63,8 +63,8 @@ alias noop gennode ( node -- ) \ forward declaration : spit ( a u -- ) swap >r >r begin 8b to@+ V1 .x1 next rdrop ; : identfind ( inode -- dnode-or-fnode-or-0 ) dup Ident name dup rot AST_FUNCTION swap Node :findparent - ( name name fnode ) ast.func.finddecl ?dup not if ( name ) - ast.unit.find else nip then dup to lastidentfound ; + ( name name fnode ) Function :finddecl ?dup not if ( name ) + Unit :find else nip then dup to lastidentfound ; \ Multiply the value of "node" by a factor of "n" \ TODO: support lvalues and expressions @@ -156,16 +156,16 @@ BOPSCNT wordtbl bopgentblpost ( -- ) 'w vm>>=, : decl>op ( dnode -- ) case - of ast.decl.isglobal? r@ Declare address mem>op endof - of ast.decl.isarg? r@ Declare address ps+>op endof + of Declare :isglobal? r@ Declare address mem>op endof + of Declare :isarg? r@ Declare address ps+>op endof r@ Declare address sf+>op r@ Declare nbelem ( nbelem ) 1 > if &op>op then endcase ; ASTIDCNT wordtbl gentbl ( node -- ) -:w ( Declare ) dup ast.decl.isglobal? if +:w ( Declare ) dup Declare :isglobal? if here over to Declare address - dup ast.decl.totsize allot + dup Declare :totsize allot dup Node firstchild Node id case ( dnode ) AST_CONSTANT of = dup Node firstchild Constant value @@ -174,7 +174,7 @@ ASTIDCNT wordtbl gentbl ( node -- ) endcase drop else ( node ) >r AST_FUNCTION r@ Node :findparent dup Function cursf ( fnode cursf ) - r@ ast.decl.totsize - ( fnode cursf ) + r@ Declare :totsize - ( fnode cursf ) dup rot to Function cursf ( cursf ) r@ to Declare address ( ) r@ Node firstchild ?dup if ( node ) @@ -189,7 +189,7 @@ ASTIDCNT wordtbl gentbl ( node -- ) dup Function flags 1 and ( extern? ) if sysdict over Function name entry then ( fnode ) here over to Function address - dup ast.func.args ast.args.totsize over ast.func.locsize ( argsz locsz ) + dup Function :args ArgSpecs :totsize over Function :locsize ( argsz locsz ) vmprelude, dup genchildren Function cursf not _assert \ all decl nodes have been "processed" _debug if current here current - spit nl> then ; @@ -199,15 +199,15 @@ ASTIDCNT wordtbl gentbl ( node -- ) \ we run ops$ between each statement to discard any unused Result dup Node firstchild begin ?dup while dup gennode ops$ Node nextsibling repeat ( snode ) - dup ast.stmts.funcbody? if + dup Statements :funcbody? if \ emit implicit vmret, if needed Node :lastchild ?dup if Node id AST_RETURN = not if vmret, then else vmret, then else drop then ; :w ( ArgSpecs ) - dup ast.args.totsize over Node parent to Function cursf + dup ArgSpecs :totsize over Node parent to Function cursf dup genchildren - Node parent dup ast.func.locsize swap to Function cursf ; + Node parent dup Function :locsize swap to Function cursf ; :w ( Ident ) dup identfind ?dup if ( inode dnode ) nip decl>op else ( inode ) Ident name sysdict @ find ?dup _assert mem>op then ;