commit 000a268c4c1e348e613dec9545bb52cb64c9ab67
parent bcca07ce73c29891b482e8206f9792f92557727c
Author: Drew DeVault <sir@cmpwn.com>
Date: Wed, 20 Jan 2021 09:27:11 -0500
parse: implement defer expressions
Diffstat:
6 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/include/ast.h b/include/ast.h
@@ -209,6 +209,10 @@ struct ast_expression_control {
char *label;
};
+struct ast_expression_defer {
+ struct ast_expression *expression;
+};
+
struct ast_expression_for {
char *label;
struct location label_loc;
@@ -302,6 +306,7 @@ struct ast_expression {
struct ast_expression_cast cast;
struct ast_expression_constant constant;
struct ast_expression_control control;
+ struct ast_expression_defer defer;
struct ast_expression_for _for;
struct ast_expression_if _if;
struct ast_expression_list list;
diff --git a/include/expr.h b/include/expr.h
@@ -18,6 +18,7 @@ enum expr_type {
EXPR_CAST,
EXPR_CONSTANT,
EXPR_CONTINUE,
+ EXPR_DEFER,
EXPR_FOR,
EXPR_IF,
EXPR_LIST,
diff --git a/src/check.c b/src/check.c
@@ -1122,6 +1122,8 @@ check_expression(struct context *ctx,
case EXPR_CONSTANT:
check_expr_constant(ctx, aexpr, expr, hint);
break;
+ case EXPR_DEFER:
+ assert(0);
case EXPR_FOR:
check_expr_for(ctx, aexpr, expr, hint);
break;
diff --git a/src/eval.c b/src/eval.c
@@ -103,6 +103,7 @@ eval_expr(struct context *ctx, struct expression *in, struct expression *out)
case EXPR_BINDING:
case EXPR_BREAK:
case EXPR_CALL:
+ case EXPR_DEFER:
case EXPR_FOR:
case EXPR_IF:
case EXPR_LIST:
diff --git a/src/gen.c b/src/gen.c
@@ -1563,6 +1563,8 @@ gen_expression(struct gen_context *ctx,
case EXPR_CONSTANT:
gen_expr_constant(ctx, expr, out);
break;
+ case EXPR_DEFER:
+ assert(0); // TODO
case EXPR_FOR:
gen_expr_for(ctx, expr, out);
break;
diff --git a/src/parse.c b/src/parse.c
@@ -1040,6 +1040,16 @@ parse_measurement_expression(struct lexer *lexer)
}
static struct ast_expression *
+parse_defer_expression(struct lexer *lexer)
+{
+ struct ast_expression *exp = mkexpr(&lexer->loc);
+ want(lexer, T_DEFER, NULL);
+ exp->type = EXPR_DEFER;
+ exp->defer.expression = parse_scope_expression(lexer);
+ return exp;
+}
+
+static struct ast_expression *
parse_call_expression(struct lexer *lexer, struct ast_expression *lvalue)
{
trenter(TR_PARSE, "call");
@@ -1244,6 +1254,9 @@ parse_postfix_expression(struct lexer *lexer, struct ast_expression *lvalue)
case T_OFFSET:
unlex(lexer, &tok);
return parse_measurement_expression(lexer);
+ case T_DEFER:
+ unlex(lexer, &tok);
+ return parse_defer_expression(lexer);
default:
unlex(lexer, &tok);
break;