duskos

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

commit daf1246ca14dd25b3fdaacde68b0142b6d8fa87e
parent c61cf0798d1a9a26577370697ff80fafb69912a8
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Fri, 30 Sep 2022 07:19:44 -0400

cc: code consolidation

Diffstat:
Mfs/cc/ast.fs | 47++++++++++++++++-------------------------------
Mfs/cc/gen.fs | 4++--
Mfs/cc/type.fs | 46++++++++++++++++++++++++----------------------
Mfs/tests/cc/type.fs | 2+-
4 files changed, 43 insertions(+), 56 deletions(-)

diff --git a/fs/cc/ast.fs b/fs/cc/ast.fs @@ -93,15 +93,15 @@ extends ASTNode struct[ Unit 2 const STORAGE_MEM \ Fixed address in memory extends NamedNode struct[ Declare - sfield type - sfield nbelem + sfield ctype \ for variables and args, "address" is a frame offset sfield address sfield storage - : :new ( type name -- node ) - AST_DECLARE NamedNode :new ( type name node ) - rot ( type ) , 0 ( nbelem ) , 0 ( address ) , STORAGE_SF , tuck :storename ; + : :new ( ctype -- node ) + AST_DECLARE NamedNode :new ( ctype node ) + swap ( ctype ) , 0 ( address ) , STORAGE_SF , + dup ctype CType name over to name ; : :isarg? ( dnode -- f ) storage STORAGE_PS = ; : :isglobal? ( dnode -- f ) storage STORAGE_MEM = ; @@ -109,17 +109,9 @@ extends NamedNode struct[ Declare \ Number of bytes required to hold this variable declaration in memory. : :totsize ( dnode -- size-in-bytes ) dup :isarg? if drop CELLSZ \ always 4b in params - else - dup type ( dnode type ) - typesize swap nbelem ( nbelem ) - 1 max * then ; + else ctype CType :size then ; : :address! ( addr self -- addr+size ) 2dup to address :totsize + ; - : :parseNbelem ( tok self -- ) - over S" [" s= if ( tok self ) - nip nextt parse _assert nextt ']' expectChar ( nbelem ) swap to nbelem - else drop to nexttputback then ; - ]struct \ a node that contains Declare children (among others) @@ -205,8 +197,7 @@ struct+[ ASTNode \ Return the "pointer arithmetic size" of "node". : :*arisz ( self -- n ) dup id AST_IDENT = if ( self ) - Ident :finddecl ?dup _assert dup Declare type ( dnode type ) - swap Declare nbelem if type*lvl+ then *ariunitsz ( n ) else + Ident :finddecl ?dup _assert Declare ctype CType :*arisz else drop 1 then ; ]struct @@ -258,9 +249,7 @@ ASTIDCNT stringlist astidnames ASTIDCNT wordtbl astdatatbl ( node -- node ) :w ( Declare ) _[ - dup Declare type printtype spc> - dup Declare name stype - dup Declare nbelem dup 1 > if _[ .x _] else drop then spc> + dup Declare ctype CType :. spc> dup Declare address .x1 _] ; 'w noop ( Unit ) :w ( function ) _[ @@ -439,9 +428,8 @@ current to parseExpression \ Parse a variable declaration from within a function : parseDeclare ( type parentnode -- dnode ) - swap parseType* ( pnode type tok ) expectIdent ( pnode type name ) - Declare :new ( pnode dnode ) dup rot Node :add ( dnode ) - nextt over Declare :parseNbelem ; + swap parseVariable ( pnode ctype ) + Declare :new ( pnode dnode ) dup rot Node :add ( dnode ) ; : parseDeclareInit ( dnode tok -- ) dup S" =" s= not if to nexttputback drop exit then @@ -527,10 +515,8 @@ current to parseStatements swap parseFuncArgs over Node :add ( unode fnode ) dup rot Node :add ( fnode ) parseStatements ; -\ type and name have already been parsed, parse the rest -: parseGlobalDecl ( unitnode type name tok -- ) - >r Declare :new ( unode dnode ) dup rot Node :add ( dnode ) - r> over Declare :parseNbelem +: parseGlobalDecl ( unitnode ctype -- ) + Declare :new ( unode dnode ) dup rot Node :add ( dnode ) STORAGE_MEM over to Declare storage nextt parseDeclareInit read; ; @@ -540,14 +526,13 @@ current to parseStatements 0 to curstatic dup S" static" s= if drop nextt 1 to curstatic then parseType _assert ( unode type ) - parseType* ( unode type tok ) - dup ';' isChar? if \ Only a type on a line is fine, carry on + nextt dup ';' isChar? if \ Only a type on a line is fine, carry on 2drop drop exit then - expectIdent ( unode type name ) nextt dup S" (" s= if - drop parseFuncDef else parseGlobalDecl then ; + to nexttputback parseVariable ( unode ctype ) nextt dup S" (" s= if + drop dup CType type swap CType name parseFuncDef + else to nexttputback parseGlobalDecl then ; : newparseunit ( -- unit ) AST_UNIT ASTNode :new dup to curunit ; : parseast ( -- ) newparseunit begin ( unode ) nextt? ?dup while over swap parseUnit repeat drop ; - diff --git a/fs/cc/gen.fs b/fs/cc/gen.fs @@ -121,12 +121,12 @@ BOPSCNT wordtbl bopgentblpost ( -- ) \ Sometimes, we get a Function as dnode. In these cases, it's a global \ address and its type is "void" TYPE_VOID to vmop type Function address mem>op exit then - dup Declare type to vmop type ( dnode ) + dup Declare ctype CType type to vmop type ( dnode ) case 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 if vmop :&op then + r@ Declare ctype CType nbelem if vmop :&op then endcase ; ASTIDCNT wordtbl gentbl ( node -- ) diff --git a/fs/cc/type.fs b/fs/cc/type.fs @@ -5,6 +5,10 @@ : _err ( -- ) abort" type error" ; : _assert ( f -- ) not if _err then ; +\ Forward declaration implemented below +alias _err _typesize ( type -- size-in-bytes ) +alias _err _printtype ( type -- ) + \ All information related to a basic type fits in 1b, so that's how "type" is \ passed around. Structure: \ b1:0 = *lvl. Indirection levels, from 0 to 3. @@ -43,11 +47,16 @@ create _ 0 c, 1 c, 2 c, 4 c, : ctype? ( type -- f ) $ff > ; : ctype' ( type -- ctype ) $fffffffc and ; -: printType* ( type -- ) type*lvl begin ?dup while '*' emit 1- repeat ; - -\ Forward declaration implemented below -alias _err _typesize ( type -- size-in-bytes ) -alias _err _printtype ( type -- ) +\ Returns the "pointer arithmetics unit size" for type, that is, the size of +\ a "single element" in pointer arithmetics. This allows, for example, "ptr + 1" +\ to generate "ptr + 4" in native code if "ptr" is a "int*". +\ Pointers to pointers always return 4. Non-pointers always return 1. 1st level +\ pointers return the size of the data they point to. +: *ariunitsz ( type -- n ) dup type*lvl case + 0 of = drop 1 endof + 1 of = type*lvl- _typesize endof + drop 4 + endcase ; struct[ CType sfield nexttype \ a CType is a Linked List @@ -69,17 +78,19 @@ struct[ CType tuck dup type _typesize swap nbelem 1 max * + swap llnext repeat ( res ) ; + : :*arisz ( self -- n ) + dup type swap nbelem if type*lvl+ then *ariunitsz ; + \ Find "name" in CType's LL. Error out if not found. : _ 2dup name s= if nip else llnext ?dup if _ else _err then then ; : :find ( name self -- ctype ) llnext _ ; : :. ( self -- ) >r - r@ flags if - ." struct" r@ name c@ if spc> r@ name stype then ." { " - r@ nexttype ?dup if :. then ." }" - else - r@ type _printtype r@ name c@ if spc> r@ name stype then - r@ nexttype ?dup if ." , " :. then + r@ :struct? if ." struct" else r@ type _printtype then + r@ name c@ if spc> r@ name stype then + r@ nbelem if '[' emit r@ nbelem . ']' emit then + r@ :struct? if ." { " r@ nexttype ?dup if :. then ." }" + else r@ nexttype ?dup if ." , " :. then then rdrop ; ]struct @@ -91,6 +102,8 @@ create typedefs 0 , 0 c, \ this is a dict link : findTypedef ( name -- type-or-0 ) typedefs find dup if @ then ; : cctypes$ 0 typedefs ! ; +: printType* ( type -- ) type*lvl begin ?dup while '*' emit 1- repeat ; + : printtype ( type -- ) dup ctype? if ctype' CType :. else dup typeunsigned? if ." unsigned " then @@ -111,17 +124,6 @@ current to _typesize 4 of = TYPE_INT endof _err endcase ; -\ Returns the "pointer arithmetics unit size" for type, that is, the size of -\ a "single element" in pointer arithmetics. This allows, for example, "ptr + 1" -\ to generate "ptr + 4" in native code if "ptr" is a "int*". -\ Pointers to pointers always return 4. Non-pointers always return 1. 1st level -\ pointers return the size of the data they point to. -: *ariunitsz ( type -- n ) dup type*lvl case - 0 of = drop 1 endof - 1 of = type*lvl- typesize endof - drop 4 - endcase ; - : parseType* ( type -- type tok ) begin nextt dup '*' isChar? while drop type*lvl+ repeat ; diff --git a/fs/tests/cc/type.fs b/fs/tests/cc/type.fs @@ -32,7 +32,7 @@ S" bar" over CType :find \ once defined, parseType will find the struct in typedefs current with-stdin< Struct1 STOP over #eq capture printtype -S" struct Struct1 { unsigned int foo, short* bar, char baz }" #s= +S" struct Struct1 { unsigned int foo, short* bar, char baz[2] }" #s= \ Anonymous structs work too current with-stdin< struct { int foo; } STOP typesize 4 #eq