commit 0658179a0e430c8caeb0fc860f3af353da74cdeb
parent 4d8d2185f886a1f5d3829e0e441a837d5fa4b8fe
Author: Drew DeVault <sir@cmpwn.com>
Date: Wed, 4 Aug 2021 09:45:31 +0200
gen: implement tuple expressions
This will definitely have to be refactored later on, starting from
check, when we merge struct into constants also.
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
2 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/src/gen.c b/src/gen.c
@@ -469,6 +469,28 @@ gen_expr_struct_at(struct gen_context *ctx,
}
}
+static void
+gen_expr_tuple_at(struct gen_context *ctx,
+ const struct expression *expr,
+ struct gen_value out)
+{
+ // TODO: Merge me into constant expressions
+ struct qbe_value base = mkqval(ctx, &out);
+
+ const struct type *type = type_dealias(expr->result);
+ struct gen_value vtemp = mktemp(ctx, &builtin_type_void, "value.%d");
+ const struct expression_tuple *value = &expr->tuple;
+ for (const struct type_tuple *tuple = &type->tuple;
+ tuple; tuple = tuple->next) {
+ struct qbe_value offs = constl(tuple->offset);
+ vtemp.type = value->value->result;
+ struct qbe_value ptr = mklval(ctx, &vtemp);
+ pushi(ctx->current, &ptr, Q_ADD, &base, &offs, NULL);
+ gen_expr_at(ctx, value->value, vtemp);
+ value = value->next;
+ }
+}
+
static struct gen_value
gen_expr_unarithm(struct gen_context *ctx,
const struct expression *expr)
@@ -536,11 +558,11 @@ gen_expr(struct gen_context *ctx, const struct expression *expr)
return gen_expr_return(ctx, expr);
case EXPR_SLICE:
case EXPR_SWITCH:
- case EXPR_TUPLE:
assert(0); // TODO
case EXPR_UNARITHM:
return gen_expr_unarithm(ctx, expr);
case EXPR_STRUCT:
+ case EXPR_TUPLE:
break; // Prefers -at style
}
@@ -570,6 +592,9 @@ gen_expr_at(struct gen_context *ctx,
case EXPR_STRUCT:
gen_expr_struct_at(ctx, expr, out);
return;
+ case EXPR_TUPLE:
+ gen_expr_tuple_at(ctx, expr, out);
+ return;
default:
break; // Prefers non-at style
}
diff --git a/src/qtype.c b/src/qtype.c
@@ -77,9 +77,20 @@ aggregate_lookup(struct gen_context *ctx, const struct type *type)
}
free(tfields);
break;
+ case STORAGE_TUPLE:
+ for (const struct type_tuple *tuple = &type->tuple;
+ tuple; tuple = tuple->next) {
+ field->type = qtype_lookup(ctx, tuple->type, true);
+ field->count = 1;
+
+ if (tuple->next) {
+ field->next = xcalloc(1, sizeof(struct qbe_field));
+ field = field->next;
+ }
+ }
+ break;
case STORAGE_SLICE:
case STORAGE_TAGGED:
- case STORAGE_TUPLE:
assert(0); // TODO
case STORAGE_ENUM:
case STORAGE_ALIAS: