commit 08e09ae899f75ca75e4fd0da59fddb1a1ddc336f
parent e8db2623c4f71c55abadfcfe69eaaef09b226201
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Tue, 8 Nov 2022 12:10:40 -0500
cc: improve pointer arithmetics
Diffstat:
3 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/fs/cc/ast.fs b/fs/cc/ast.fs
@@ -144,12 +144,16 @@ extends ASTNode struct[ Arrow
]struct
struct+[ ASTNode
- \ Multiply the value of "node" by a factor of "n"
- : :*=n ( n self -- ) >r ( n )
- Constant :new ( cnode )
- 2 ( * ) AST_BINARYOP Op :new dup r@ Node :replace ( cnode bnode )
+ : _ ( opid n self -- ) >r ( opid n )
+ Constant :new ( opid cnode )
+ swap AST_BINARYOP Op :new dup r@ Node :replace ( cnode bnode )
r> over Node :add ( cnode bnode ) Node :add ;
+ \ Multiply the value of "node" by a factor of "n"
+ : :*=n ( n self -- ) 2 ( * ) rot> _ ;
+ \ Divide the value of "node" by a factor of "n"
+ : :/=n ( n self -- ) 3 ( / ) rot> _ ;
+
: :type dup id case ( self )
AST_IDENT of =
Ident :finddecl ?dup _assert CType :type endof
@@ -167,6 +171,7 @@ struct+[ ASTNode
\ Return the "pointer arithmetic size" of "node".
: :*arisz ( self -- n ) :type *ariunitsz ;
+ : :ptr? :type type*lvl bool ;
]struct
extends Op struct[ UnaryOp
@@ -189,11 +194,14 @@ extends Op struct[ BinaryOp
\ multiply the "not a pointer" one by the pointer's "arithmetic size".
: :*ari ( self -- )
dup opid ptrbop? not if drop exit then
- firstchild ?dup _assert dup nextsibling ?dup _assert ( n1 n2 )
- 2dup :*arisz swap :*arisz 2dup = if \ same *arisz, nothing to do
- 2drop 2drop else \ different *arisz, adjust
- ( n1 n2 sz2 sz1 ) < if swap then ( node-to-adjust pointer-node )
- :*arisz swap :*=n then ;
+ dup firstchild ?dup _assert dup nextsibling ?dup _assert ( self n1 n2 )
+ over :ptr? if \ n1 is a pointer
+ swap :*arisz over :ptr? if ( self n2 sz ) \ both are pointers
+ nip swap :/=n else ( self n2 sz ) \ only n1 is a pointer
+ swap :*=n drop then ( )
+ else ( self n1 n2 ) \ n1 is not a pointer
+ dup :ptr? if ( self n1 n2 ) \ only n2 is a pointer
+ :*arisz swap :*=n else 2drop then ( self ) drop then ;
]struct
extends ASTNode struct[ StrLit
diff --git a/fs/tests/cc/cc.fs b/fs/tests/cc/cc.fs
@@ -31,6 +31,7 @@ ptrset 54 #eq
exprparens 9 #eq
cnoop ( no result! ) scnt 0 #eq
42 ptrari 46 #eq
+42 50 ptrari2 2 #eq
array 52 #eq
global 1234 #eq
globalinc 1236 #eq
diff --git a/fs/tests/cc/test.c b/fs/tests/cc/test.c
@@ -122,6 +122,10 @@ int* ptrari(int *x) {
cnoop(); // this doesn't mess up PS
return x + 1;
}
+// subtracting two pointers yield a number divided by the type size.
+int ptrari2(int *lo, int *hi) {
+ return hi-lo;
+}
int array() {
int a[3] = {42, 12, 2};
return *a + a[1] - *(a+2);