harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 92bd3f55a9a6e09da69b59bffeb7ef80a74f616c
parent 6264d353ad68d07c0f675be917e3c59b6cbad23d
Author: Drew DeVault <sir@cmpwn.com>
Date:   Tue, 29 Dec 2020 12:14:50 -0500

parse: implement if expressions

Diffstat:
Minclude/ast.h | 6++++++
Msrc/gen.c | 2+-
Msrc/parse.c | 36++++++++++++++++++++++++++++++++++--
3 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/include/ast.h b/include/ast.h @@ -162,6 +162,11 @@ struct ast_expression_constant { }; }; +struct ast_expression_if { + struct ast_expression *cond; + struct ast_expression *true_branch, *false_branch; +}; + struct ast_expression_list { struct ast_expression *expr; struct ast_expression_list *next; @@ -220,6 +225,7 @@ struct ast_expression { struct ast_expression_binding binding; struct ast_expression_call call; struct ast_expression_constant constant; + struct ast_expression_if _if; struct ast_expression_list list; struct ast_expression_measure measure; struct ast_expression_return _return; diff --git a/src/gen.c b/src/gen.c @@ -446,7 +446,7 @@ gen_expr_call(struct gen_context *ctx, if (type_is_aggregate(carg->value->result)) { alloc_temp(ctx, &arg->value, carg->value->result, "arg.%d"); - qval_address(&arg->value); + qval_deref(&arg->value); } else { gen_temp(ctx, &arg->value, qtype_for_type(ctx, carg->value->result, true), diff --git a/src/parse.c b/src/parse.c @@ -330,6 +330,8 @@ parse_primitive_type(struct parser *par) } static struct ast_expression *parse_simple_expression(struct parser *par); +static struct ast_expression *parse_complex_expression(struct parser *par); +static struct ast_expression *parse_compound_expression(struct parser *par); static struct ast_type * parse_enum_type(struct parser *par) @@ -599,8 +601,6 @@ parse_type(struct parser *par) return type; } -static struct ast_expression *parse_complex_expression(struct parser *par); - static struct ast_expression * parse_access(struct parser *par, struct identifier ident) { @@ -1295,11 +1295,43 @@ parse_simple_expression(struct parser *par) } static struct ast_expression * +parse_if_expression(struct parser *par) +{ + struct ast_expression *exp = xcalloc(1, sizeof(struct ast_expression)); + exp->type = EXPR_IF; + + struct token tok = {0}; + + want(par, T_LPAREN, &tok); + exp->_if.cond = parse_simple_expression(par); + want(par, T_RPAREN, &tok); + + exp->_if.true_branch = parse_compound_expression(par); + + switch (lex(par->lex, &tok)) { + case T_ELSE: + if (lex(par->lex, &tok) == T_IF) { + exp->_if.false_branch = parse_if_expression(par); + } else { + unlex(par->lex, &tok); + exp->_if.false_branch = parse_compound_expression(par); + } + break; + default: + unlex(par->lex, &tok); + break; + } + + return exp; +} + +static struct ast_expression * parse_complex_expression(struct parser *par) { struct token tok; switch (lex(par->lex, &tok)) { case T_IF: + return parse_if_expression(par); case T_FOR: case T_MATCH: case T_SWITCH: