aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-02-13 13:08:00 -0500
committerBruce Hill <bruce@bruce-hill.com>2024-02-13 13:08:00 -0500
commitcf70dac0be983ef8a395bd017ac9975760d3fe4b (patch)
tree51b3fe6e9219a3dc32792274d13f513d1ede4f95
parentf3b9d577c2a64e8a81f7d1c75c1eb560b1940f62 (diff)
Fix multi-assignment
-rw-r--r--compile.c18
-rw-r--r--util.h1
2 files changed, 13 insertions, 6 deletions
diff --git a/compile.c b/compile.c
index 1f036c25..7b9b6698 100644
--- a/compile.c
+++ b/compile.c
@@ -167,12 +167,18 @@ CORD compile(ast_t *ast)
}
case Assign: {
auto assign = Match(ast, Assign);
- CORD code = CORD_EMPTY;
- for (ast_list_t *target = assign->targets, *value = assign->values; target && value; target = target->next, value = value->next) {
- CORD_sprintf(&code, "%r = %r", compile(target->ast), compile(value->ast));
- if (target->next) code = CORD_cat(code, ", ");
- }
- return CORD_cat(code, ";");
+ // Single assignment:
+ if (assign->targets && !assign->targets->next)
+ return CORD_asprintf("%r = %r", compile(assign->targets->ast), compile(assign->values->ast));
+
+ CORD code = "{ // Assignment\n";
+ int64_t i = 1;
+ for (ast_list_t *value = assign->values; value; value = value->next)
+ CORD_appendf(&code, "__declare(_%ld, %r);\n", i++, compile(value->ast));
+ i = 1;
+ for (ast_list_t *target = assign->targets; target; target = target->next)
+ CORD_appendf(&code, "%r = _%ld;\n", compile(target->ast), i++);
+ return CORD_cat(code, "\n}");
}
case Min: {
return CORD_asprintf("min(%r, %r)", compile(Match(ast, Min)->lhs), compile(Match(ast, Min)->rhs));
diff --git a/util.h b/util.h
index 90ac8b3d..1c098781 100644
--- a/util.h
+++ b/util.h
@@ -25,6 +25,7 @@ char *heap_strn(const char *str, size_t len);
char *heap_str(const char *str);
char *heap_strf(const char *fmt, ...);
CORD CORD_asprintf(const char *fmt, ...);
+#define CORD_appendf(cord, fmt, ...) CORD_sprintf(cord, "%r" fmt, *(cord) __VA_OPT__(,) __VA_ARGS__)
#define REVERSE_LIST(list) do { \
__typeof(list) _prev = NULL; \