diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-01-24 12:45:57 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-01-24 12:45:57 +0900 |
| commit | dec37504377d1d6fb21f762d9da4ff0126ccbfaa (patch) | |
| tree | 3421b9f35b8409481b50a7338d0d4c554db950fc | |
| parent | a5bff442c1f09792ff7291652103048688c3a128 (diff) | |
| download | ducc-dec37504377d1d6fb21f762d9da4ff0126ccbfaa.tar.gz ducc-dec37504377d1d6fb21f762d9da4ff0126ccbfaa.tar.zst ducc-dec37504377d1d6fb21f762d9da4ff0126ccbfaa.zip | |
fix: parsing of unary expressions
| -rw-r--r-- | src/parse.c | 18 | ||||
| -rw-r--r-- | tests/expressions.sh | 18 |
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' |
