commit 17628e5e79de400e908e214454454aaef5834e3b
parent 9d1d4f3a8d66ce1d0df74e528b770586b712074f
Author: Drew DeVault <sir@cmpwn.com>
Date: Mon, 2 Aug 2021 11:39:30 +0200
gen: implement -at variant of gen_expr_list
It would be nice to merge these. Only ever using the _at form for
expression lists risks generating extra storage when not required, for
instance:
let x: []int = ...
let y = x[{
z;
}];
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/src/gen.c b/src/gen.c
@@ -207,6 +207,7 @@ gen_expr_const(struct gen_context *ctx, const struct expression *expr)
abort(); // Invariant
}
+// TODO: Decide how/if gen_expr_list and gen_expr_list_at should be merged
static struct gen_value
gen_expr_list(struct gen_context *ctx, const struct expression *expr)
{
@@ -221,6 +222,21 @@ gen_expr_list(struct gen_context *ctx, const struct expression *expr)
abort(); // Unreachable
}
+static void
+gen_expr_list_at(struct gen_context *ctx,
+ const struct expression *expr,
+ struct gen_value out)
+{
+ // TODO: Set up defer scope
+ for (const struct expressions *exprs = &expr->list.exprs;
+ exprs; exprs = exprs->next) {
+ if (!exprs->next) {
+ gen_expr_at(ctx, exprs->expr, out);
+ }
+ gen_expr(ctx, exprs->expr);
+ }
+}
+
static struct gen_value
gen_expr_return(struct gen_context *ctx, const struct expression *expr)
{
@@ -313,8 +329,7 @@ gen_expr(struct gen_context *ctx, const struct expression *expr)
case EXPR_UNARITHM:
assert(0); // TODO
case EXPR_STRUCT:
- // Prefers _at style
- break;
+ break; // Prefers -at style
}
struct gen_value out = mktemp(ctx, expr->result, "object.%d");
@@ -334,11 +349,14 @@ gen_expr_at(struct gen_context *ctx,
assert(out.kind != GV_CONST);
switch (expr->type) {
+ case EXPR_LIST:
+ gen_expr_list_at(ctx, expr, out);
+ return;
case EXPR_STRUCT:
gen_expr_struct_at(ctx, expr, out);
return;
default:
- break; // Does not have an _at implementation
+ break; // Prefers non-at style
}
gen_store(ctx, out, gen_expr(ctx, expr));