~vdupras/duskos

f513fb21947f001c52a1ff283e2e7c4038d1158f — Virgil Dupras a month ago 778f643
halcc: fix funcsig/rettype mixup
5 files changed, 16 insertions(+), 3 deletions(-)

M fs/comp/c/egen.fs
M fs/comp/c/ptype.fs
M fs/comp/c/type.fs
M fs/tests/comp/c/cc.fs
M fs/tests/comp/c/test.c
M fs/comp/c/egen.fs => fs/comp/c/egen.fs +1 -1
@@ 131,7 131,7 @@ code _callA branchA,
  rdrop r> ( psinitlvl ) to psoff
  Result currentW ?dup if PS- Result :release then
  \ TODO: arilvl of fun rettype isn't properly preserved here
  CDecl type if PS+ Result :W else Result :none then ;
  CDecl :rettype if PS+ Result :W else Result :none then ;

: _incdec, ( res incsz -- res )
  Result :?freeCurrentW over Result :*arisz *

M fs/comp/c/ptype.fs => fs/comp/c/ptype.fs +3 -1
@@ 44,7 44,9 @@ alias _err parseDeclarator ( type -- cdecl ) \ forward declaration
  endcase again ;

: _parseDeclarator ( type -- cdecl )
  0 begin ( type lvl )
  0 over cdecl? if over CDecl :funcptr? if
    dip bi CDecl type | CDecl lvl | + then then ( type lvl )
  begin ( type lvl )
    '*' readChar? while ( type lvl tok ) 1+ repeat ( type lvl tok )
  dup '(' isChar? if ( type lvl tok )
    \ Complex type parsing is messed up. Example "int (*foo)[42]", a pointer to

M fs/comp/c/type.fs => fs/comp/c/type.fs +3 -1
@@ 82,8 82,10 @@ struct[ CDecl
    dup lvl if drop 0 else _ then ;
  : :structarrow? ( self -- f ) \ is an indirect Struct reference?
    dup lvl 1 = if _ else drop 0 then ;
  : :funcptr? ( self -- f ) bi lvl 1 = | type :funcsig? and ;
  : :funcptr? ( self -- f ) bi lvl 1 = | type bi cdecl? | :funcsig? and and ;
  : :constfuncsig? ( self -- f ) bi :funcsig? | :isglobal? and ;
  : :rettype
    dup :funcptr? if type :rettype else dup :funcsig? _assert type then ;

  \ Arrays, function signatures and struct ident "naturally" yield references.
  : :reference? bi+ nbelem bool | :funcsig? or swap :structdot? or ;

M fs/tests/comp/c/cc.fs => fs/tests/comp/c/cc.fs +1 -0
@@ 122,6 122,7 @@ ptrari5 6 + @ 42 #eq
$1234 2 ptrari7 $1238 #eq
funcall1 138 #eq
42 funcall2 85 #eq
funcall3 scnt not # \ no PS leak/underflow
41 switch1 41 #eq
42 switch1 43 #eq
switch2 42 #eq

M fs/tests/comp/c/test.c => fs/tests/comp/c/test.c +8 -0
@@ 524,6 524,14 @@ int funcall1() {
int funcall2(int x) {
    return adder(++x, 42);
}

// Function signature type is correctly recognised in typedefs
typedef void (*Voider)();
int funcall3() {
	Voider x = cnoop;
	void (*y)() = cnoop;
	x(); y(); // no PS leak/underflow
}
// There used to be a bug in the forth VM where an expression (something that
// isn't a simple reference, but the result of a computation) with an arg on PS
// would mess PS up.