diff options
| author | nsfisis <nsfisis@gmail.com> | 2025-08-22 00:06:14 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2025-08-22 21:57:20 +0900 |
| commit | 0ac6ac95283735dd70ebf55b26ef78a4c32c31de (patch) | |
| tree | f4aa9c5c855fb31db29b95530454b994b6a78c2c /parse.c | |
| parent | a2da09917886860ed478f4b37c31543e869cbd64 (diff) | |
| download | ducc-0ac6ac95283735dd70ebf55b26ef78a4c32c31de.tar.gz ducc-0ac6ac95283735dd70ebf55b26ef78a4c32c31de.tar.zst ducc-0ac6ac95283735dd70ebf55b26ef78a4c32c31de.zip | |
feat: partially support #if directive
Diffstat (limited to 'parse.c')
| -rw-r--r-- | parse.c | 38 |
1 files changed, 38 insertions, 0 deletions
@@ -697,6 +697,12 @@ AstNode* parse_conditional_expr(Parser* p) { } } +// constant-expression: +// conditional-expression +AstNode* parse_constant_expression(Parser* p) { + return parse_conditional_expr(p); +} + AstNode* parse_assignment_expr(Parser* p) { AstNode* lhs = parse_conditional_expr(p); while (1) { @@ -1364,3 +1370,35 @@ Program* parse(TokenArray* tokens) { prog->str_literals = p->str_literals; return prog; } + +int eval(AstNode* e) { + if (e->kind == AstNodeKind_int_expr) { + return e->node_int_value; + } else if (e->kind == AstNodeKind_unary_expr) { + int v = eval(e->node_operand); + if (e->node_op == TokenKind_not) { + return !v; + } else { + unimplemented(); + } + } else if (e->kind == AstNodeKind_binary_expr || e->kind == AstNodeKind_logical_expr) { + int v1 = eval(e->node_lhs); + int v2 = eval(e->node_rhs); + if (e->node_op == TokenKind_andand) { + return v1 && v2; + } else if (e->node_op == TokenKind_oror) { + return v1 || v2; + } else { + unimplemented(); + } + } else { + unimplemented(); + } +} + +BOOL pp_eval_constant_expression(TokenArray* pp_tokens) { + TokenArray* tokens = tokenize(pp_tokens); + Parser* p = parser_new(tokens); + AstNode* e = parse_constant_expression(p); + return eval(e) != 0; +} |
