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:
M | fs/cc/ast.fs | | | 104 | +++++++++++++++++++++++++++++++++++++++++-------------------------------------- |
M | fs/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 ;