duskos

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

commit 808d2da630e13ff60b4eee260d601eb50789844f
parent 710a8632f153d002f4e04d4e75135f0b784f456d
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Fri, 17 Jun 2022 13:30:08 -0400

cc: allow array declaration and allocate them properly in the SF

Diffstat:
Mfs/cc/ast.fs | 17+++++++++++------
Mfs/cc/map.fs | 13+++++++++----
Mfs/cc/type.fs | 5+++--
Mfs/tests/cc/test.c | 5+++++
4 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/fs/cc/ast.fs b/fs/cc/ast.fs @@ -1,5 +1,5 @@ \ C compiler Abstract Syntax Tree -\ requires cc/tok.fs, cc/tree.fs and cc/ops.fs +\ requires cc/tok cc/tree cc/type \ An abstract syntax tree, AST, is a hierarchical structure of nodes \ representing the nodes found in a C source file. See tree.fs for structure. @@ -35,7 +35,7 @@ create bopsprectbl 1 c, 1 c, 0 c, 0 c, 2 c, 2 c, 2 c, 2 c, \ AST node types 15 const ASTIDCNT -0 const AST_DECLARE \ data1=name data2=type +0 const AST_DECLARE \ data1=name data2=type data3=nbelem 1 const AST_UNIT 2 const AST_FUNCTION \ data1=name data2=MAP_FUNCTION data3=type 3 const AST_RETURN @@ -68,7 +68,8 @@ ASTIDCNT stringlist astidnames ASTIDCNT wordtbl astdatatbl ( node -- node ) :w ( Declare ) _[ dup data2 printtype spc> - dup data1 stype _] ; + dup data1 stype + dup data3 dup 1 > if _[ .x _] else drop then _] ; 'w noop ( Unit ) :w ( function ) _[ dup data3 printtype spc> @@ -186,13 +187,17 @@ alias noop parseExpression ( tok -- node ) \ forward declaration current to parseExpression : parseDeclare ( type parentnode -- dnode ) + AST_DECLARE newnode ( type dnode ) swap begin ( pnode type ) nextt dup S" *" s= if drop type*lvl+ 0 else 1 then until ( pnode type tok ) - expectIdent rot ( type name pnode ) - AST_DECLARE newnode ( type name dnode ) rot> , , ( dnode ) ; + expectIdent ( dnode type name ) , , ( dnode ) + nextt dup S" [" s= if ( dnode tok ) + drop nextt parse _assert nextt ']' expectChar ( nbelem ) else + to nexttputback 1 ( nbelem ) then , ; : parseDeclarationList ( type stmtsnode -- ) - parseDeclare nextt '=' expectChar dup data1 ( dnode name ) + parseDeclare nextt dup S" =" s= not if ';' expectChar drop exit then + drop ( dnode ) dup data1 ( dnode name ) swap parentnode AST_BINARYOP newnode ( name anode ) 12 ( = ) , AST_LVALUE newnode ( name lvnode ) swap , parentnode ( anode ) nextt parseExpression read; ( anode expr ) swap addnode ; diff --git a/fs/cc/map.fs b/fs/cc/map.fs @@ -16,19 +16,20 @@ \ Then, each entry in the variable declaration xdict is: \ 4b SF offset +\ 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+ ( fmap -- sfoff ) - dup fmap.sfsize swap 4 + ( sz a ) 4 swap +! ( sz ) ; +: fmap.sfsize+ ( n fmap -- ) 4 + +! ; : fmap.argsize 8 + @ ; : fmap.argsize+ ( n fmap -- ) 8 + +! ; : fmap.address 12 + @ ; : fmap.address! 12 + ! ; : fmap.vmap 16 + ; : vmap.sfoff @ ; +: vmap.decl 4 + @ ; : _err ( -- ) abort" mapping error" ; \ print curmap in reverse order of parsing @@ -45,7 +46,11 @@ newxdict curmap dup data1 ( name ) curmap xentry ( astnode ) here swap , 16 allot0 ( entry ) ; -: Variable ( offset name -- ) curmap @ fmap.vmap xentry , ; +: Variable ( dnode -- ) + dup data1 curmap @ fmap.vmap xentry ( dnode ) + curmap @ fmap.sfsize , dup , ( dnode ) + dup data2 ( dnode type ) typesize swap data3 ( nbelem ) * ( sfsize ) + curmap @ fmap.sfsize+ ; : findvarinmap ( name funcentry -- varentry ) fmap.vmap xfind not if _err then ; @@ -57,7 +62,7 @@ newxdict curmap AST_DECLARE nextnodeid dup if ( astdecl ) dup parentnode nodeid AST_ARGSPECS = if \ inc argssize field 4 curmap @ fmap.argsize+ then - dup data1 curmap @ fmap.sfsize+ swap Variable 0 else 1 then + dup Variable 0 else 1 then until ( curnode ) drop ; \ create a new map from "astunit" diff --git a/fs/cc/type.fs b/fs/cc/type.fs @@ -8,12 +8,13 @@ \ b6:4 = *lvl. Indirection levels, from 0 to 7. 4 stringlist typenames "void" "char" "short" "int" -create _ 0 c, 8 c, 16 c, 32 c, : typesigned? ( type -- flags ) 2 rshift 1 and ; : type*lvl ( type -- lvl ) 3 rshift 3 and ; : type*lvl! ( lvl type -- type ) $f and swap 3 lshift or ; : type*lvl+ ( type -- type ) dup type*lvl 1+ swap type*lvl! ; -: typesize ( type -- size-in-bytes ) dup type*lvl if 4 else 3 and _ + c@ then ; +create _ 0 c, 1 c, 2 c, 4 c, +: typesize ( type -- size-in-bytes ) + dup type*lvl if drop 4 else 3 and _ + c@ then ; \ Unlike ANSI C, "signed" doesn't exist and "unsigned" needs to be before the \ type name. '*' are not parsed because they are sometimes attached to the diff --git a/fs/tests/cc/test.c b/fs/tests/cc/test.c @@ -59,3 +59,8 @@ int exprparens() { return (1 + 2) * 3; } void cnoop() {return;} +int array() { + int a[3]; + *a = 42; + return *a; +}