commit e11ef33d6165c2d53ea49a3bb89bda06e5b37cdf
parent 8707083bcef2775d8963780e5f847ab74d6ab0d0
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Mon, 20 Mar 2023 19:42:36 -0400
halcc: plusone() adder() subber()
Diffstat:
3 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/fs/comp/c/egen.fs b/fs/comp/c/egen.fs
@@ -33,10 +33,22 @@ UOPSCNT wordtbl _tbl ( res -- res )
'w _neg, 'w _not, 'w _err 'w _err 'w _err 'w _err 'w _err
\ we gave to call "res" after having parsed its arguments. "(" is parsed.
-: _funcall ( res -- res ) read)
+\ Arguments construction: basically, we can place arguments on PS in the order
+\ in which we parse them. Convenient. However, parseExpression can "leak" to
+\ psoff, which means that while we construct our list, we need to keep track of
+\ 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.
+: _funcall ( res -- res ) psoff dup >r >r \ V1=psinitlvl V2=pslvl
+ dup Result :isctype? _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 :ctype# dup CType :funcsig? if
nip dup CType offset execute,
- else swap Result :?>W$ compile execute then ( ctype )
+ else abort" TODO: dynamic calls" then ( ctype )
+ rdrop r> ( psinitlvl ) to psoff
+ Result currentW ?dup if PS- Result :release then
CType type if PS+ Result :W else Result :none then ;
\ parses, if possible, a postfix operator. If none, this is a noop.
diff --git a/fs/tests/comp/c/cc.fs b/fs/tests/comp/c/cc.fs
@@ -22,9 +22,9 @@ assignops 83 #eq
boolops 0 #eq
funcall 42 #eq
42 pushpop 42 #eq
-testend \s
-3 2 subber 1 #eq
42 plusone 43 #eq
+3 2 subber 1 #eq
+testend \s
ptrget 42 #eq
ptrset 54 #eq
12 condif 13 #eq
diff --git a/fs/tests/comp/c/test2.c b/fs/tests/comp/c/test2.c
@@ -73,3 +73,18 @@ int funcall() {
void pushpop() {
pspush(pspop());
}
+
+// let's try function prototyping support
+static int adder(int a, int b);
+// are arguments, both constants and lvalues, properly passed?
+// do we support expressions as arguments?
+int plusone(int x) {
+ return adder(1, x+x-x);
+}
+// implements the above prototype
+static int adder(int a, int b) {
+ return a + b;
+}
+int subber(int a, int b) {
+ return a - b;
+}