duskos

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

commit 93ff71f54c74b8d5e26f93085b0fd9d3e5a311fd
parent bddaff23856a30010f977dc1d47707ee3899e89a
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Fri, 10 Jun 2022 08:21:11 -0400

wip

Diffstat:
Mfs/cc/ast.fs | 128+++++++++++++++++++++++++++++++++++++++++++------------------------------------
1 file changed, 70 insertions(+), 58 deletions(-)

diff --git a/fs/cc/ast.fs b/fs/cc/ast.fs @@ -52,15 +52,15 @@ create bopsprectbl 1 c, 1 c, 0 c, 0 c, 2 c, 2 c, 2 c, 2 c, \ 9 = unused 10 value AST_BINARYOP \ data1=bopid 11 value AST_ASSIGN \ data1=name -12 value AST_DECLLIST +\ 12 = unused 13 value AST_VARIABLE \ data1=name 14 value AST_FUNCALL \ data1=name data2=MAP_FUNCTION create astidnames 7 c, ," declare" 4 c, ," unit" 8 c, ," function" 6 c, ," return" 8 c, ," constant" 5 c, ," stmts" 4 c, ," args" 4 c, ," expr" 7 c, ," unaryop" - 6 c, ," factor" 5 c, ," binop" 6 c, ," assign" - 8 c, ," decllist" 3 c, ," var" 4 c, ," call" + 1 c, ," _" 5 c, ," binop" 6 c, ," assign" + 1 c, ," _" 3 c, ," var" 4 c, ," call" 0 c, 0 value curunit \ points to current Unit, the beginning of the AST @@ -74,8 +74,6 @@ create astidnames 7 c, ," declare" 4 c, ," unit" 8 c, ," function" activenode ?dup not if abort" can't go beyond root!" then 0 over cslots! begin parentnode dup nodeclosed? not until to activenode ; -: closeuntil ( astid -- ) - begin seqclose activenode astid over = until drop ; : _[ '[' emit ; @@ -93,10 +91,10 @@ ASTIDCNT wordtbl astdatatbl ( node -- node ) 'w noop ( ArgSpecs ) 'w noop ( Expression ) :w ( UnaryOp ) _[ dup data1 uopchar emit _] ; -'w noop ( Factor ) +'w noop ( Unused ) :w ( BinaryOp ) _[ dup data1 boptoken stype _] ; 'w _s ( Assign ) -'w noop ( DeclarationList ) +'w noop ( Unused ) 'w _s ( Variable ) 'w _s ( FunCall ) @@ -113,22 +111,25 @@ ASTIDCNT wordtbl astdatatbl ( node -- node ) : newnode createnode dup activenode addnode ( node ) dup nodeclosed? not if to activenode else drop then ; +: newnode2 ( parent cslots astid -- newnode ) + createnode ( parent node ) dup rot addnode ( node ) ; \ AST nodes -: Declare ( name -- ) -1 AST_DECLARE newnode , ; -: Unit ( -- ) -1 AST_UNIT createnode dup to curunit to activenode ; -: Function ( name -- ) 2 AST_FUNCTION newnode , 0 , ; +: Declare ( parent name -- node ) + swap -1 AST_DECLARE newnode2 swap , ; +: Unit ( -- node ) -1 AST_UNIT createnode dup to curunit dup to activenode ; +: Function ( unitnode name -- node ) + swap 2 AST_FUNCTION newnode2 swap , 0 , ; : Return ( -- ) 1 AST_RETURN newnode ; -: Constant ( n -- ) 0 AST_CONSTANT newnode , ; -: Statements ( -- ) -1 AST_STATEMENTS newnode ; -: ArgSpecs ( -- ) -1 AST_ARGSPECS newnode ; +: Constant ( parent n -- ) swap 0 AST_CONSTANT newnode2 drop , ; +: Statements ( funcnode -- node ) -1 AST_STATEMENTS newnode2 ; +: ArgSpecs ( funcnode -- node ) -1 AST_ARGSPECS newnode2 ; : Expression ( -- ) -1 AST_EXPRESSION newnode ; -: UnaryOp ( opid -- ) 1 AST_UNARYOP newnode , ; +: UnaryOp ( parentnode opid -- ) swap 1 AST_UNARYOP newnode2 swap , ; : BinaryOp ( opid -- node ) 2 AST_BINARYOP newnode , ; : Assign ( name -- ) 1 AST_ASSIGN newnode , ; -: DeclarationList ( -- ) -1 AST_DECLLIST newnode ; -: Variable ( name -- ) 0 AST_VARIABLE newnode , ; -: FunCall ( name -- ) 0 AST_FUNCALL newnode , ; +: Variable ( parentnode name -- ) swap 0 AST_VARIABLE newnode2 drop , ; +: FunCall ( parentnode name -- ) swap 0 AST_FUNCALL newnode2 drop , ; : _err ( tok -- ) stype spc> @@ -149,6 +150,21 @@ ASTIDCNT wordtbl astdatatbl ( node -- node ) : expectChar ( tok c -- ) over 1+ c@ = _assert dup c@ 1 = _assert drop ; +\ Parse words + +\ parse a constant, variable or function call +: parseFactor ( parentnode tok -- nexttok ) + dup isIdent? if \ Variable or FunCall + _nextt ( pn prevtok newtok ) dup S" (" s= if \ FunCall + drop FunCall _nextt ')' expectChar _nextt + else \ Variable + rot> Variable ( nexttok ) then + else \ Constant + expectConst Constant _nextt then ; + +: parseUnaryOp ( parentnode uopid -- nexttok ) + UnaryOp _nextt parseFactor ; + \ The binopswap operation is funky. It happens when we want to add a binop that \ "eats up" the preceding node. There are 3 scenarios. \ 1. the preceding sibling (let's call it the target node) is not a binop. @@ -166,59 +182,55 @@ ASTIDCNT wordtbl astdatatbl ( node -- node ) swap removenode to activenode ( bopid tgt ) swap BinaryOp ( tgt ) activenode addnode ; -\ Parse words - -\ parse a constant, variable or function call -: parseFactor ( tok -- nexttok ) - dup isIdent? if \ Variable or FunCall - _nextt ( prevtok newtok ) dup S" (" s= if \ FunCall - drop FunCall _nextt ')' expectChar _nextt - else \ Variable - swap Variable ( nexttok ) then - else \ Constant - expectConst Constant _nextt then ; - -: parseExpression ( tok -- ) - dup S" ;" s= if drop AST_STATEMENTS closeuntil exit then - activeempty? if dup uopid if - UnaryOp drop _nextt parseFactor parseExpression exit then then - dup bopid if ( tok binopid ) - swap activeempty? if _err then \ can't start an expression with a binop - ( bopid tok ) drop - activenode lastchild ( bopid prev ) dup astid AST_BINARYOP = if - ( bopid tgt ) 2dup data1 bopprec swap bopprec > if ( bopid tgt ) +: parseBinaryOp ( parentnode bopid -- nexttok ) + over lastchild ( pn bopid prev ) dup astid AST_BINARYOP = if + ( pn bopid tgt ) 2dup data1 bopprec swap bopprec > if ( pn bopid tgt ) \ new binop has a higher precedence, steal right operand! firstchild nextsibling then then - binopswap _nextt parseFactor parseExpression exit then - parseFactor parseExpression ; + binopswap lastchild _nextt parseFactor ; + +: parseExpression ( parent tok -- ) + swap to activenode begin ( tok ) + dup S" ;" s= if drop seqclose exit then + dup uopid activeempty? and if \ unaryop + nip activenode swap parseUnaryOp + else \ not unaryop + dup bopid if ( tok binopid ) + swap activeempty? if _err then \ can't start an expression with a binop + ( bopid tok ) drop activenode swap parseBinaryOp + else \ not binop + activenode swap parseFactor then then + again ; : parseDeclare ( tok -- ) - '=' expectChar activenode data1 Assign Expression _nextt parseExpression ; + '=' expectChar activenode data1 Assign Expression activenode _nextt parseExpression ; -: parseDeclarationList ( tok -- ) expectIdent Declare _nextt parseDeclare ; +: parseDeclarationList ( stmtsnode -- ) + _nextt expectIdent Declare to activenode _nextt parseDeclare ; -: parseArgSpecs ( tok -- ) - dup S" )" s= if drop seqclose exit then - begin ( tok ) - expectType drop _nextt expectIdent Declare seqclose - _nextt dup S" )" s= if drop seqclose exit then +: parseArgSpecs ( funcnode -- ) + _nextt '(' expectChar ArgSpecs _nextt ( argsnode tok ) + dup S" )" s= if 2drop exit then + begin ( argsnode tok ) + expectType drop dup _nextt expectIdent Declare drop + _nextt dup S" )" s= if 2drop exit then ',' expectChar _nextt again ; -: parseStatements ( tok -- ) +: parseStatements ( funcnode -- ) + _nextt '{' expectChar Statements to activenode _nextt begin ( tok ) - dup S" }" s= if drop seqclose exit then + dup S" }" s= if drop exit then dup S" return" s= if - drop Return Expression _nextt parseExpression else - expectType drop _nextt parseDeclarationList then + drop Return Expression activenode _nextt parseExpression else + expectType drop activenode parseDeclarationList then _nextt again ; -: parseFunction ( tok -- ) - '(' expectChar ArgSpecs _nextt parseArgSpecs _nextt - '{' expectChar Statements _nextt parseStatements ; +: parseFunction ( unitnode tok -- ) + Function ( funcnode ) dup parseArgSpecs parseStatements ; : parseUnit ( -- ) - nextt ?dup not if exit then begin ( tok ) - isType? _assert _nextt expectIdent Function _nextt parseFunction - nextt ?dup not until ; + Unit nextt ?dup not if exit then begin ( unitnode tok ) + isType? _assert _nextt expectIdent over swap parseFunction ( unitnode ) + nextt ?dup not until ( unitnode ) drop ; -: parseast ( -- ) Unit parseUnit ; +: parseast ( -- ) parseUnit ;