aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-07-21 06:23:15 +0900
committernsfisis <nsfisis@gmail.com>2025-08-15 10:04:23 +0900
commit4113cec4ecaef37eaa5638592bdc80ad7783d530 (patch)
treed3cf86ee97f9592191981dea4d3fed55c7ba0082
parent8dfdbc9cf84be2d82960784f70a2e00378fca5c5 (diff)
downloadducc-4113cec4ecaef37eaa5638592bdc80ad7783d530.tar.gz
ducc-4113cec4ecaef37eaa5638592bdc80ad7783d530.tar.zst
ducc-4113cec4ecaef37eaa5638592bdc80ad7783d530.zip
feat: implement substraction between pointers
-rw-r--r--main.c11
-rw-r--r--tests/024.sh7
2 files changed, 16 insertions, 2 deletions
diff --git a/main.c b/main.c
index 48f391c..ef19587 100644
--- a/main.c
+++ b/main.c
@@ -1459,8 +1459,15 @@ AstNode* parse_additive_expr(Parser* p) {
next_token(p);
rhs = parse_multiplicative_expr(p);
if (lhs->ty->kind == TypeKind_ptr) {
- lhs = ast_new_binary_expr(
- op, lhs, ast_new_binary_expr(TokenKind_star, rhs, ast_new_int(type_sizeof(lhs->ty->to))));
+ if (rhs->ty->kind == TypeKind_ptr) {
+ // (a - b) / sizeof(a)
+ lhs = ast_new_binary_expr(TokenKind_slash, ast_new_binary_expr(op, lhs, rhs),
+ ast_new_int(type_sizeof(lhs->ty->to)));
+ } else {
+ // a - b*sizeof(a)
+ lhs = ast_new_binary_expr(
+ op, lhs, ast_new_binary_expr(TokenKind_star, rhs, ast_new_int(type_sizeof(lhs->ty->to))));
+ }
} else {
lhs = ast_new_binary_expr(op, lhs, rhs);
}
diff --git a/tests/024.sh b/tests/024.sh
index 99557e1..20453a0 100644
--- a/tests/024.sh
+++ b/tests/024.sh
@@ -1,6 +1,9 @@
set -e
cat <<'EOF' > expected
+3
+3
+3
EOF
bash ../../test_diff.sh <<'EOF'
int printf();
@@ -29,6 +32,10 @@ int main() {
lp1 = &l;
lp2 = &l + 3;
+ printf("%d\n", cp2 - cp1);
+ printf("%d\n", ip2 - ip1);
+ printf("%d\n", lp2 - lp1);
+
return 0;
}
EOF