~sircmpwn/hare-dev

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
2 2

[PATCH harec v2] Remove indirect field from assign expression

Details
Message ID
<20230205053526.2594-1-sebastian@sebsite.pw>
DKIM signature
pass
Download raw message
Patch: +51 -77
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>
---
Since v1: added commit message body

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

diff --git a/include/ast.h b/include/ast.h
index 88b2db5..3cfc949 100644
--- 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
index 8be7508..accf95a 100644
--- 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
index 8ca4778..61eada7 100644
--- 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
index 9a0cd3e..ae064d6 100644
--- 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
index baf3070..c6e2c84 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -2151,7 +2151,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);
@@ -2159,7 +2159,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;
}

@@ -2370,44 +2369,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;
-- 
2.38.1

[harec/patches] build success

builds.sr.ht <builds@sr.ht>
Details
Message ID
<CQADV60AWH99.25JUO7NFOLFF7@cirno2>
In-Reply-To
<20230205053526.2594-1-sebastian@sebsite.pw> (view parent)
DKIM signature
missing
Download raw message
harec/patches: SUCCESS in 1m9s

[Remove indirect field from assign expression][0] v2 from [Sebastian][1]

[0]: https://lists.sr.ht/~sircmpwn/hare-dev/patches/38754
[1]: sebastian@sebsite.pw

✓ #934756 SUCCESS harec/patches/freebsd.yml https://builds.sr.ht/~sircmpwn/job/934756
✓ #934757 SUCCESS harec/patches/netbsd.yml  https://builds.sr.ht/~sircmpwn/job/934757
✓ #934755 SUCCESS harec/patches/alpine.yml  https://builds.sr.ht/~sircmpwn/job/934755
Details
Message ID
<CQAOJWAM7M9M.1PDQM6ORNHPPD@attila>
In-Reply-To
<20230205053526.2594-1-sebastian@sebsite.pw> (view parent)
DKIM signature
pass
Download raw message
Thanks!

To git@git.sr.ht:~sircmpwn/harec
   d8c5440..633f10d  master -> master
Reply to thread Export thread (mbox)