gen.fs (1951B) - raw
1 \ C compiler parse+generate main entry point 2 \ In this unit, we are fed with tokens, we parse it, then we generate native 3 \ code through the HAL. The "cparse" word is the main entry point. 4 require /sys/scratch.fs 5 ?f<< /lib/str.fs 6 ?f<< /lib/wordtbl.fs 7 ?f<< /lib/stack.fs 8 ?f<< /lib/arena.fs 9 ?f<< /comp/c/tok.fs 10 ?f<< /comp/c/ptype.fs 11 ?f<< /comp/c/fgen.fs 12 13 0 value _ccdebug 14 : _err ( -- ) tokdbg abort" gen error" ; 15 : _assert ( f -- ) not if _err then ; 16 : spit ( a u -- ) swap >r for 17 i 40 mod not if nl> then 18 8b to@+ V1 .x1 next rdrop ; 19 20 : parseGlobalDecl ( cdecl -- ) 21 dup addSymbol 22 dup CDecl :static? not if \ not static 23 dup CDecl name NEXTWORD ! create then ( cdecl ) 24 here over to CDecl offset ( cdecl ) 25 '=' readChar? if ( cdecl ) 26 nextt parseExpression case ( cdecl ) 27 ExprOp :isconst? of r@ ExprOp arg , endof 28 ExprOp :isarray? of r@ ExprOp arg over CDecl :typesize writeStack endof 29 _err endcase 30 else to nexttputback dup CDecl :size allot then ( cdecl ) 31 ',' readChar? if 32 CDecl type parseDeclarator parseGlobalDecl 33 else ';' expectChar drop then ; 34 35 \ Begin parsing incoming tokens for a new "element" (a function or a 36 \ declaration) and consume tokens until that element is finished parsing. That 37 \ element is written to memory at "here". 38 : cparse ( tok -- ) 39 typereserve egenreserve 0 to curstatic lockhere 40 dup S" static" s= if drop nextt 1 to curstatic then 41 parseType _assert ( type ) 42 ';' readChar? if \ Only a type on a line is fine, carry on 43 drop unlockhere exit then to nexttputback 44 parseDeclarator ( cdecl ) 45 curstatic if dup CDecl :static! then 46 _ccdebug if ." parsing: " dup printtype nl> then 47 dup CDecl :funcsig? if ( cdecl ) 48 '{' readChar? if dup parseFunctionBody 49 _ccdebug if 50 ." complete: " dup printtype nl> CDecl offset here over - spit nl> 51 else drop then 52 else parseFunctionProto then 53 else alignhere parseGlobalDecl then ( ) unlockhere ;