aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-01-24 13:19:48 +0900
committernsfisis <nsfisis@gmail.com>2026-01-24 13:24:37 +0900
commit6f1e639ff0092c56fb1b8ce8fe298cc5ffc32bfb (patch)
tree3a45657e1081121d350d5bf563c1bcab49b4e2be
parent8e0de5b89ecfdd0aa9a7c01b9ef1652b4107ad4c (diff)
downloadducc-6f1e639ff0092c56fb1b8ce8fe298cc5ffc32bfb.tar.gz
ducc-6f1e639ff0092c56fb1b8ce8fe298cc5ffc32bfb.tar.zst
ducc-6f1e639ff0092c56fb1b8ce8fe298cc5ffc32bfb.zip
feat: implement parsing of "sizeof expr"
-rw-r--r--src/parse.c27
-rw-r--r--tests/operators.c23
2 files changed, 31 insertions, 19 deletions
diff --git a/src/parse.c b/src/parse.c
index 12e8815..80007ed 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -766,26 +766,15 @@ static AstNode* parse_unary_expr(Parser* 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);
- Token* next_tok = peek_token(p);
- Type* ty = NULL;
- if (next_tok->kind == TokenKind_ident) {
- int lvar_idx = find_lvar(p, next_tok->value.string);
- if (lvar_idx != -1) {
- next_token(p);
- ty = p->lvars.data[lvar_idx].ty;
- }
- int gvar_idx = find_gvar(p, next_tok->value.string);
- if (gvar_idx != -1) {
- next_token(p);
- ty = p->gvars.data[gvar_idx].ty;
- }
- }
- if (!ty) {
- ty = parse_type_name(p);
+ if (peek_token(p)->kind == TokenKind_paren_l && is_type_token(p, peek_token2(p))) {
+ next_token(p);
+ Type* ty = parse_type_name(p);
+ expect(p, TokenKind_paren_r);
+ return ast_new_int(type_sizeof(ty));
+ } else {
+ AstNode* expr = parse_unary_expr(p);
+ return ast_new_int(type_sizeof(expr->ty));
}
- expect(p, TokenKind_paren_r);
- return ast_new_int(type_sizeof(ty));
}
return parse_postfix_expr(p);
}
diff --git a/tests/operators.c b/tests/operators.c
index 9e9ba08..e089477 100644
--- a/tests/operators.c
+++ b/tests/operators.c
@@ -119,4 +119,27 @@ int main() {
// ternary operator
ASSERT_EQ(2, 1 ? 2 : 3);
ASSERT_EQ(5, 0 ? 4 : 5);
+
+ // sizeof operator
+ // sizeof '(' type-name ')'
+ ASSERT_EQ(4, sizeof(int));
+ ASSERT_EQ(1, sizeof(char));
+
+ // sizeof unary-expr (with parenthesized expressions)
+ ASSERT_EQ(4, sizeof(+123));
+ ASSERT_EQ(4, sizeof(-1));
+ ASSERT_EQ(4, sizeof(1 + 2));
+ ASSERT_EQ(4, sizeof(~0));
+ ASSERT_EQ(4, sizeof(!0));
+
+ // sizeof unary-expr (variable)
+ int sz_var = 42;
+ ASSERT_EQ(4, sizeof(sz_var));
+ ASSERT_EQ(4, sizeof sz_var);
+
+ // sizeof with more complex expressions
+ char sz_c = 'a';
+ ASSERT_EQ(1, sizeof sz_c);
+ ASSERT_EQ(1, sizeof(sz_c));
+ ASSERT_EQ(4, sizeof(sz_c + 1));
}