harec

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

commit 6ede1609fef95d37d853ae1751ee9ceaeb026912
parent 079d0afa986d1bc50e3ab0630af99e9b2564754e
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Thu, 31 Dec 2020 17:34:01 -0500

parse, check: implement += et al

Diffstat:
Minclude/ast.h | 1+
Minclude/expr.h | 11++++++-----
Msrc/check.c | 1+
Msrc/gen.c | 1+
Msrc/parse.c | 26++++++++++++++++++++++++--
5 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/include/ast.h b/include/ast.h @@ -123,6 +123,7 @@ struct ast_expression_assert { }; struct ast_expression_assign { + enum binarithm_operator op; struct ast_expression *object, *value; bool indirect; }; diff --git a/include/expr.h b/include/expr.h @@ -54,11 +54,6 @@ struct expression_assert { bool is_static; }; -struct expression_assign { - struct expression *object, *value; - bool indirect; -}; - enum binarithm_operator { BIN_BAND, // & BIN_BOR, // | @@ -81,6 +76,12 @@ enum binarithm_operator { BIN_BXOR, // ^ }; +struct expression_assign { + enum binarithm_operator op; + struct expression *object, *value; + bool indirect; +}; + struct expression_binarithm { enum binarithm_operator op; struct expression *lvalue, *rvalue; diff --git a/src/check.c b/src/check.c @@ -134,6 +134,7 @@ check_expr_assign(struct context *ctx, check_expression(ctx, aexpr->assign.object, object); check_expression(ctx, aexpr->assign.value, value); + expr->assign.op = aexpr->assign.op; expr->assign.object = object; expr->assign.value = value; diff --git a/src/gen.c b/src/gen.c @@ -387,6 +387,7 @@ gen_expr_assign(struct gen_context *ctx, const struct qbe_value *out) { assert(out == NULL); // Invariant + assert(expr->assign.op == BIN_LEQUAL); // TODO // TODO: When this grows to support e.g. indexing expressions, we need // to ensure that the side-effects of the lvalue occur before the // side-effects of the rvalue. diff --git a/src/parse.c b/src/parse.c @@ -1556,12 +1556,14 @@ parse_binding_list(struct lexer *lexer) } static struct ast_expression * -parse_assignment(struct lexer *lexer, struct ast_expression *object, bool indirect) +parse_assignment(struct lexer *lexer, struct ast_expression *object, + bool indirect, enum binarithm_operator op) { trenter(TR_PARSE, "assign"); struct ast_expression *value = parse_complex_expression(lexer); struct ast_expression *expr = mkexpr(&lexer->loc); expr->type = EXPR_ASSIGN; + expr->assign.op = op; expr->assign.object = object; expr->assign.value = value; expr->assign.indirect = indirect; @@ -1616,7 +1618,27 @@ parse_scope_expression(struct lexer *lexer) switch (lex(lexer, &tok)) { case T_EQUAL: - return parse_assignment(lexer, value, indirect); + return parse_assignment(lexer, value, indirect, BIN_LEQUAL); + case T_ANDEQ: + return parse_assignment(lexer, value, indirect, BIN_BAND); + case T_DIVEQ: + return parse_assignment(lexer, value, indirect, BIN_DIV); + case T_LSHIFTEQ: + return parse_assignment(lexer, value, indirect, BIN_LSHIFT); + case T_MINUSEQ: + return parse_assignment(lexer, value, indirect, BIN_MINUS); + case T_MODEQ: + return parse_assignment(lexer, value, indirect, BIN_MODULO); + case T_OREQ: + return parse_assignment(lexer, value, indirect, BIN_BOR); + case T_PLUSEQ: + return parse_assignment(lexer, value, indirect, BIN_PLUS); + case T_RSHIFTEQ: + return parse_assignment(lexer, value, indirect, BIN_RSHIFT); + case T_TIMESEQ: + return parse_assignment(lexer, value, indirect, BIN_TIMES); + case T_BXOREQ: + return parse_assignment(lexer, value, indirect, BIN_BXOR); default: unlex(lexer, &tok); value = parse_bin_expression(lexer, value, 0);