aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-01-24 12:45:57 +0900
committernsfisis <nsfisis@gmail.com>2026-01-24 12:45:57 +0900
commitdec37504377d1d6fb21f762d9da4ff0126ccbfaa (patch)
tree3421b9f35b8409481b50a7338d0d4c554db950fc
parenta5bff442c1f09792ff7291652103048688c3a128 (diff)
downloadducc-dec37504377d1d6fb21f762d9da4ff0126ccbfaa.tar.gz
ducc-dec37504377d1d6fb21f762d9da4ff0126ccbfaa.tar.zst
ducc-dec37504377d1d6fb21f762d9da4ff0126ccbfaa.zip
fix: parsing of unary expressions
-rw-r--r--src/parse.c18
-rw-r--r--tests/expressions.sh18
2 files changed, 27 insertions, 9 deletions
diff --git a/src/parse.c b/src/parse.c
index c6ad44c..41caa4a 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -352,7 +352,7 @@ static Token* parse_ident(Parser*);
static AstNode* parse_primary_expr(Parser*);
static AstNode* parse_postfix_expr(Parser*);
static AstNode* parse_argument_expr_list(Parser*);
-static AstNode* parse_prefix_expr(Parser*);
+static AstNode* parse_unary_expr(Parser*);
static AstNode* parse_cast_expr(Parser*);
static AstNode* parse_multiplicative_expr(Parser*);
static AstNode* parse_additive_expr(Parser*);
@@ -740,28 +740,28 @@ static AstNode* parse_argument_expr_list(Parser* p) {
// 'sizeof' unary-expr
// 'sizeof' '(' type-name ')'
// TODO 'alignof' '(' type-name ')'
-static AstNode* parse_prefix_expr(Parser* p) {
+static AstNode* parse_unary_expr(Parser* p) {
TokenKind op = peek_token(p)->kind;
if (consume_token_if(p, TokenKind_minus)) {
- AstNode* operand = parse_prefix_expr(p);
+ AstNode* operand = parse_cast_expr(p);
return ast_new_binary_expr(op, ast_new_int(0), operand);
} else if (consume_token_if(p, TokenKind_not)) {
- AstNode* operand = parse_prefix_expr(p);
+ AstNode* operand = parse_cast_expr(p);
return ast_new_unary_expr(op, operand);
} else if (consume_token_if(p, TokenKind_tilde)) {
- AstNode* operand = parse_prefix_expr(p);
+ AstNode* operand = parse_cast_expr(p);
return ast_new_unary_expr(op, operand);
} else if (consume_token_if(p, TokenKind_and)) {
- AstNode* operand = parse_prefix_expr(p);
+ AstNode* operand = parse_cast_expr(p);
return ast_new_ref_expr(operand);
} else if (consume_token_if(p, TokenKind_star)) {
AstNode* operand = parse_cast_expr(p);
return ast_new_deref_expr(operand);
} else if (consume_token_if(p, TokenKind_plusplus)) {
- AstNode* operand = parse_prefix_expr(p);
+ AstNode* operand = parse_unary_expr(p);
return ast_new_assign_add_expr(operand, ast_new_int(1));
} else if (consume_token_if(p, TokenKind_minusminus)) {
- AstNode* operand = parse_prefix_expr(p);
+ AstNode* operand = parse_unary_expr(p);
return ast_new_assign_sub_expr(operand, ast_new_int(1));
} else if (consume_token_if(p, TokenKind_keyword_sizeof)) {
expect(p, TokenKind_paren_l);
@@ -801,7 +801,7 @@ static AstNode* parse_cast_expr(Parser* p) {
AstNode* e = parse_cast_expr(p);
return ast_new_cast_expr(e, ty);
}
- return parse_prefix_expr(p);
+ return parse_unary_expr(p);
}
// multiplicative-expr:
diff --git a/tests/expressions.sh b/tests/expressions.sh
index dadfade..8443774 100644
--- a/tests/expressions.sh
+++ b/tests/expressions.sh
@@ -184,6 +184,24 @@ int main() {
EOF
cat <<'EOF' > expected
+Result: -42
+Result: 0
+EOF
+test_diff <<'EOF'
+int printf(const char*, ...);
+
+typedef int foo;
+
+int main() {
+ int a = 42;
+ int b = -(int)a;
+ int c = !(foo)a;
+ printf("Result: %d\n", b);
+ printf("Result: %d\n", c);
+}
+EOF
+
+cat <<'EOF' > expected
Result: 130
EOF
test_diff <<'EOF'