harec

[hare] Hare compiler, written in C11 for POSIX OSs
Log | Files | Refs | README | LICENSE

commit 633f10d43ff4bcaf6720e5905f71d1392aecb136
parent d8c5440debe5b15d4c58b0864fb17b17c33bd986
Author: Sebastian <sebastian@sebsite.pw>
Date:   Sun,  5 Feb 2023 00:35:26 -0500

Remove indirect field from assign expression

Assign expressions allow any arbitary expression for the object being
assigned to, including a dereference expression. Removing the indirect
field and instead just using a dereference expression here removes some
code duplication.

This field originally existed because it's used within parse, but it's
easy to just have parse construct a pointer dereference AST expression
rather than passing an "indirect" parameter everywhere.

Signed-off-by: Sebastian <sebastian@sebsite.pw>

Diffstat:
Minclude/ast.h | 1-
Minclude/expr.h | 1-
Msrc/check.c | 64+++++++++++++++++-----------------------------------------------
Msrc/gen.c | 16+++++++++++-----
Msrc/parse.c | 46+++++++++++++++++++++++-----------------------
5 files changed, 51 insertions(+), 77 deletions(-)

diff --git a/include/ast.h b/include/ast.h @@ -151,7 +151,6 @@ struct ast_expression_assert { struct ast_expression_assign { enum binarithm_operator op; struct ast_expression *object, *value; - bool indirect; }; struct ast_expression_binarithm { diff --git a/include/expr.h b/include/expr.h @@ -127,7 +127,6 @@ enum binarithm_operator { struct expression_assign { enum binarithm_operator op; struct expression *object, *value; - bool indirect; }; struct expression_binarithm { diff --git a/src/check.c b/src/check.c @@ -710,7 +710,6 @@ check_expr_assign(struct context *ctx, { expr->type = EXPR_ASSIGN; expr->result = &builtin_type_void; - expr->assign.indirect = aexpr->assign.indirect; struct expression *object = xcalloc(1, sizeof(struct expression)); struct expression *value = xcalloc(1, sizeof(struct expression)); @@ -718,55 +717,26 @@ check_expr_assign(struct context *ctx, expr->assign.op = aexpr->assign.op; - if (aexpr->assign.indirect) { - const struct type *otype = type_dealias(object->result); - if (otype->storage != STORAGE_POINTER) { - error(ctx, aexpr->loc, expr, - "Cannot dereference non-pointer type for assignment"); - return; - } - if (otype->pointer.flags & PTR_NULLABLE) { - error(ctx, aexpr->loc, expr, - "Cannot dereference nullable pointer type"); - return; - } - check_expression(ctx, aexpr->assign.value, value, otype->pointer.referent); - if (!type_is_assignable(otype->pointer.referent, - value->result)) { - error(ctx, aexpr->loc, expr, - "Value type is not assignable to pointer type"); - return; - } - value = lower_implicit_cast(otype->pointer.referent, value); - } else { - check_expression(ctx, aexpr->assign.value, value, object->result); - assert(object->type == EXPR_CONSTANT // If error - || object->type == EXPR_ACCESS - || object->type == EXPR_SLICE); // Invariant - if (object->type == EXPR_SLICE) { - if (expr->assign.op != BIN_LEQUAL) { - error(ctx, aexpr->assign.object->loc, expr, - "Slice assignments may not have a binop"); - return; - } - } - if (object->result->flags & TYPE_CONST) { - error(ctx, aexpr->loc, expr, - "Cannot assign to const object"); - return; - } - if (!type_is_assignable(object->result, value->result)) { - char *valtypename = gen_typename(value->result); - char *objtypename = gen_typename(object->result); - error(ctx, aexpr->loc, expr, - "rvalue type (%s) is not assignable to lvalue (%s)", - valtypename, objtypename); - free(valtypename); - free(objtypename); + check_expression(ctx, aexpr->assign.value, value, object->result); + + if (object->type == EXPR_SLICE) { + if (expr->assign.op != BIN_LEQUAL) { + error(ctx, aexpr->assign.object->loc, expr, + "Slice assignments may not have a binop"); return; } - value = lower_implicit_cast(object->result, value); } + if (!type_is_assignable(object->result, value->result)) { + char *valtypename = gen_typename(value->result); + char *objtypename = gen_typename(object->result); + error(ctx, aexpr->loc, expr, + "rvalue type (%s) is not assignable to lvalue (%s)", + valtypename, objtypename); + free(valtypename); + free(objtypename); + return; + } + value = lower_implicit_cast(object->result, value); expr->assign.object = object; expr->assign.value = value; diff --git a/src/gen.c b/src/gen.c @@ -902,14 +902,20 @@ gen_expr_assign(struct gen_context *ctx, const struct expression *expr) if (object->type == EXPR_SLICE) { return gen_expr_assign_slice(ctx, expr); } - assert(object->type == EXPR_ACCESS || expr->assign.indirect); // Invariant struct gen_value obj; - if (expr->assign.indirect) { - obj = gen_expr(ctx, object); - obj.type = type_dealias(object->result)->pointer.referent; - } else { + switch (object->type) { + case EXPR_ACCESS: obj = gen_expr_access_addr(ctx, object); + break; + case EXPR_UNARITHM: + assert(object->unarithm.op == UN_DEREF); // Invariant + obj = gen_expr(ctx, object->unarithm.operand); + assert(type_dealias(obj.type)->storage == STORAGE_POINTER); + obj.type = type_dealias(obj.type)->pointer.referent; + break; + default: + abort(); // Invariant } if (expr->assign.op == BIN_LEQUAL) { gen_expr_at(ctx, value, obj); diff --git a/src/parse.c b/src/parse.c @@ -2138,7 +2138,7 @@ parse_binding_list(struct lexer *lexer, bool is_static) static struct ast_expression * parse_assignment(struct lexer *lexer, struct ast_expression *object, - bool indirect, enum binarithm_operator op) + enum binarithm_operator op) { struct ast_expression *value = parse_expression(lexer); struct ast_expression *expr = mkexpr(&lexer->loc); @@ -2146,7 +2146,6 @@ parse_assignment(struct lexer *lexer, struct ast_expression *object, expr->assign.op = op; expr->assign.object = object; expr->assign.value = value; - expr->assign.indirect = indirect; return expr; } @@ -2365,44 +2364,45 @@ parse_expression(struct lexer *lexer) break; } + if (indirect) { + struct ast_expression *deref = mkexpr(&value->loc); + deref->type = EXPR_UNARITHM; + deref->unarithm.op = UN_DEREF; + deref->unarithm.operand = value; + value = deref; + } + switch (lex(lexer, &tok)) { case T_EQUAL: - return parse_assignment(lexer, value, indirect, BIN_LEQUAL); + return parse_assignment(lexer, value, BIN_LEQUAL); case T_BANDEQ: - return parse_assignment(lexer, value, indirect, BIN_BAND); + return parse_assignment(lexer, value, BIN_BAND); case T_LANDEQ: - return parse_assignment(lexer, value, indirect, BIN_LAND); + return parse_assignment(lexer, value, BIN_LAND); case T_DIVEQ: - return parse_assignment(lexer, value, indirect, BIN_DIV); + return parse_assignment(lexer, value, BIN_DIV); case T_LSHIFTEQ: - return parse_assignment(lexer, value, indirect, BIN_LSHIFT); + return parse_assignment(lexer, value, BIN_LSHIFT); case T_MINUSEQ: - return parse_assignment(lexer, value, indirect, BIN_MINUS); + return parse_assignment(lexer, value, BIN_MINUS); case T_MODEQ: - return parse_assignment(lexer, value, indirect, BIN_MODULO); + return parse_assignment(lexer, value, BIN_MODULO); case T_BOREQ: - return parse_assignment(lexer, value, indirect, BIN_BOR); + return parse_assignment(lexer, value, BIN_BOR); case T_LOREQ: - return parse_assignment(lexer, value, indirect, BIN_LOR); + return parse_assignment(lexer, value, BIN_LOR); case T_PLUSEQ: - return parse_assignment(lexer, value, indirect, BIN_PLUS); + return parse_assignment(lexer, value, BIN_PLUS); case T_RSHIFTEQ: - return parse_assignment(lexer, value, indirect, BIN_RSHIFT); + return parse_assignment(lexer, value, BIN_RSHIFT); case T_TIMESEQ: - return parse_assignment(lexer, value, indirect, BIN_TIMES); + return parse_assignment(lexer, value, BIN_TIMES); case T_BXOREQ: - return parse_assignment(lexer, value, indirect, BIN_BXOR); + return parse_assignment(lexer, value, BIN_BXOR); case T_LXOREQ: - return parse_assignment(lexer, value, indirect, BIN_LXOR); + return parse_assignment(lexer, value, BIN_LXOR); default: unlex(lexer, &tok); - if (indirect) { - struct ast_expression *deref = mkexpr(&value->loc); - deref->type = EXPR_UNARITHM; - deref->unarithm.op = UN_DEREF; - deref->unarithm.operand = value; - value = deref; - } value = parse_cast_expression(lexer, value); value = parse_bin_expression(lexer, value, 0); return value;