duskos

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

commit c1d807791d62e60fb37ac44355ba30431146d5c0
parent 5d96fd4248507486fa78b0eac5b9c6fd53d96648
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Fri, 24 Mar 2023 15:49:49 -0400

halcc: funcsig()

Diffstat:
Mfs/comp/c/egen.fs | 5+++--
Mfs/comp/c/expr.fs | 12++++++------
Mfs/comp/c/ptype.fs | 7+++++--
Mfs/comp/c/type.fs | 3++-
Mfs/tests/comp/c/cc.fs | 2+-
Mfs/tests/comp/c/test2.c | 7+++++++
6 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/fs/comp/c/egen.fs b/fs/comp/c/egen.fs @@ -108,14 +108,15 @@ BOPSCNT wordtbl boptbl ( left right -- res ) \ the expected psoff. If it's higher, we need to readjust. After the call, we \ need to restore psoff to its initial level *without actually adjusting* \ because it's the callee's responsibility to free its arguments. +code _callA branchA, : _funcall ( res -- res ) psoff dup >r >r \ V1=psinitlvl V2=pslvl dup Result :iscdecl? _assert ')' readChar? not if begin ( funcres tok ) parseExpression Result :?>W psoff V2 - ?dup if dup ps+, neg to+ psoff then CELLSZ to+ V2 ',' readChar? while nextt repeat ')' expectChar then ( funcres ) - dup Result :cdecl# dup CDecl :funcsig? if + dup Result :cdecl# dup CDecl :funcsig? if ( funcres cdecl ) nip dup CDecl offset execute, - else abort" TODO: dynamic calls" then ( cdecl ) + else swap Result :hal# A>) @, ['] _callA execute, then ( cdecl ) rdrop r> ( psinitlvl ) to psoff Result currentW ?dup if PS- Result :release then \ TODO: arilvl of fun rettype isn't properly preserved here diff --git a/fs/comp/c/expr.fs b/fs/comp/c/expr.fs @@ -65,13 +65,13 @@ struct[ Result swap CDecl nbelem if dup :& -1 over to+ blvl then ; : :cdecl# dup :iscdecl? _assert arg ; - : :opsz ( halop self -- halop ) dup :. - bi+ lvl | blvl = if 'B' emit + : :opsz ( halop self -- halop ) + bi+ lvl | blvl = if basesz case 1 of = 8b) endof 2 of = 16b) endof endcase else drop then ; : :hal# ( self -- halop ) dup type case ( self ) CONST of = arg i) endof - CDECL of = 'C' emit + CDECL of = bi+ arg CDecl :halop | lvl case ( self halop ) 0 of = endof -1 of = A>) lea, A*) endof @@ -81,7 +81,7 @@ struct[ Result PS of = arg PSP+) endof abort" :hal# error" endcase ; : :>W ( self -- ) - dup :isW? if drop else 'W' emit + dup :isW? if drop else :Wfree# dup :hal# @, 0 over to@! lvl neg over to+ blvl dup to currentW W swap to type then ; @@ -95,8 +95,8 @@ struct[ Result \ Free up W by sending it to A if needed. : :?>A ( self -- halop ) dup :isW? if :release W>A, A*) else :hal# then ; - : :* ( self -- ) '*' emit - 1 over to+ lvl dup :isW? if '!' emit W) swap :opsz @, else drop then 'X' emit ; + : :* ( self -- ) + 1 over to+ lvl dup :isW? if W) swap :opsz @, else drop then ; : :<<n ( n self -- ) dup :isconst? if dup arg rot lshift swap to arg else :?>W i) <<, then ; diff --git a/fs/comp/c/ptype.fs b/fs/comp/c/ptype.fs @@ -45,10 +45,13 @@ alias _err parseDeclarator ( type -- cdecl ) \ forward declaration 0 begin ( type lvl ) '*' readChar? while ( type lvl tok ) 1+ repeat ( type lvl tok ) dup '(' isChar? if ( type lvl tok ) - abort" TODO: declarator recursion" + drop swap _parseDeclarator read) ( lvl cdecl ) + \ type recursion in C is "inside out". The cdecl we have now is the result. + \ We need to apply indirection levels we've already parsed to it. + tuck to+ CDecl lvl else ( type lvl tok ) dup isIdent? not if to nexttputback NULLSTR then ( type lvl name ) - rot CDecl :new ( lvl cdecl ) tuck to CDecl lvl _post then ; + rot CDecl :new ( lvl cdecl ) tuck to CDecl lvl then _post ; current ' parseDeclarator realias : _parseStruct ( -- cdecl ) diff --git a/fs/comp/c/type.fs b/fs/comp/c/type.fs @@ -87,7 +87,8 @@ struct[ CDecl : :halop ( self -- operand ) dup bi offset | storage case ( self offset ) STORAGE_SF of = RSP) swap +) endof STORAGE_PS of = PSP+) endof - STORAGE_MEM of = m) endof _err endcase ( self operand ) + STORAGE_MEM of = over :funcsig? if i) else m) then endof + _err endcase ( self operand ) swap type _typesize case 1 of = 8b) endof 2 of = 16b) endof endcase ; \ Combined size of all fields in the LL. diff --git a/fs/tests/comp/c/cc.fs b/fs/tests/comp/c/cc.fs @@ -39,8 +39,8 @@ global 1234 #eq globalinc 1236 #eq globalinc 1238 #eq 1 globalshort 2 #eq -testend \s 42 142 funcsig 184 #eq +testend \s capture helloworld S" Hello World!" #s= create expected ," Null terminated\0" nullstr expected 16 []= # diff --git a/fs/tests/comp/c/test2.c b/fs/tests/comp/c/test2.c @@ -156,3 +156,10 @@ static short shortarray[3] = {1, 2, 3}; short globalshort(int idx) { return shortarray[idx]; } + +typedef unsigned int (*AdderSig)(unsigned int, unsigned int); +int funcsig(int a, int b) { + AdderSig fn = adder; + int foo = fn(a, b); + return fn(a, b); +}