commit 92bd3f55a9a6e09da69b59bffeb7ef80a74f616c
parent 6264d353ad68d07c0f675be917e3c59b6cbad23d
Author: Drew DeVault <sir@cmpwn.com>
Date: Tue, 29 Dec 2020 12:14:50 -0500
parse: implement if expressions
Diffstat:
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: