commit 23aa533dbca7e55a404a15ebe8598c1ae35650de
parent bd25b5a311d0e9fb99eb88364be986b6b7209baf
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Sat, 1 Apr 2023 21:39:40 -0400
halcc: <goldleader>Almost there...</goldleader>
Diffstat:
5 files changed, 56 insertions(+), 5 deletions(-)
diff --git a/fs/comp/c/egen.fs b/fs/comp/c/egen.fs
@@ -144,7 +144,8 @@ code _callA branchA,
: parsePostfixOp ( res -- res )
nextt case ( )
'[' of isChar?^ \ x[y] is the equivalent of *(x+y)
- nextt parseExpression _+, Result :*
+ nextt parseExpression _+,
+ dup Result cdecl CDecl :structdot? not if Result :* then
nextt ']' expectChar parsePostfixOp endof
'(' of isChar?^ _funcall parsePostfixOp endof
S" ->" of s=
diff --git a/fs/comp/c/expr.fs b/fs/comp/c/expr.fs
@@ -6,6 +6,9 @@
: _err ( -- ) tokdbg abort" expr error" ;
: _assert ( f -- ) not if _err then ;
+: nb) ( halop sz -- halop )
+ case 1 of = 8b) endof 2 of = 16b) endof 4 of = 32b) endof _err endcase ;
+
NULLSTR TYPE_UINT CDecl :new const UintCDecl
struct[ Result
diff --git a/fs/comp/c/type.fs b/fs/comp/c/type.fs
@@ -44,9 +44,6 @@ STORAGE_MEM value curstorage
: cdecl? ( type -- f ) $f > ;
-: nb) ( halop sz -- halop )
- case 1 of = 8b) endof 2 of = 16b) endof 4 of = 32b) endof _err endcase ;
-
\ CDecl flags
\ b0=is a struct? if 1, this is an "empty" CDecl with the name of the struct.
\ First field is nexttype.
diff --git a/fs/tests/comp/c/cc.fs b/fs/tests/comp/c/cc.fs
@@ -108,7 +108,6 @@ opwidth5 42 #eq
opwidth6 1 #eq
$ff 1 opwidth7 $1fe #eq
opwidth8 0 #eq
-testend \s
42 50 ptrari3 46 #eq
41 value myval
to' myval ptrari4 not #
@@ -122,6 +121,7 @@ funcall1 138 #eq
42 funcall2 85 #eq
41 switch1 41 #eq
42 switch1 43 #eq
+testend \s
switch2 42 #eq
\ and what about inline functions?
diff --git a/fs/tests/comp/c/test2.c b/fs/tests/comp/c/test2.c
@@ -483,3 +483,53 @@ int opwidth8() {
globdata.baz[1] = 1;
return x < globdata.baz[0];
}
+// when subtracting 2 pointers, the result is considered a scalar for the
+// remainder of the expression.
+int* ptrari3(int *lo, int *hi) {
+ return lo+((hi-lo)/2);
+}
+int ptrari4(int *a) {
+ return *(a++) == 42;
+}
+struct SixBytes { int foo; short bar; };
+static SixBytes globstructarray[2];
+// Previously, pointer arithmetics adjustments only worked with power of two.
+SixBytes* ptrari5() {
+ globstructarray[1].foo = 42;
+ return globstructarray;
+}
+// unary op, apart from ++ and --, *don't* modify their target.
+int unaryop1(int n) {
+ !n;
+ return n;
+}
+// ... even if it's a pointer!
+int* unaryop2(int *n) {
+ !*n;
+ return n;
+}
+// Function calls with other function calls in arguments used to mess things up
+int funcall1() {
+ return adder(54, retconst() + retconst());
+}
+int funcall2(int x) {
+ return adder(++x, 42);
+}
+// 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.
+int switch1(char *x) {
+ switch (x+1) {
+ case 43: return 43;
+ }
+ return x;
+}
+// The i386 VM used to misallocate EAX because vmop was a VM_*REGISTER=EAX
+int switch2() {
+ char c = 'X';
+ char *p = &c;
+ switch (*p) {
+ case 'X': return 42;
+ }
+ return 0;
+}