diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-02-13 13:08:00 -0500 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-02-13 13:08:00 -0500 |
| commit | cf70dac0be983ef8a395bd017ac9975760d3fe4b (patch) | |
| tree | 51b3fe6e9219a3dc32792274d13f513d1ede4f95 | |
| parent | f3b9d577c2a64e8a81f7d1c75c1eb560b1940f62 (diff) | |
Fix multi-assignment
| -rw-r--r-- | compile.c | 18 | ||||
| -rw-r--r-- | util.h | 1 |
2 files changed, 13 insertions, 6 deletions
@@ -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)); @@ -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; \ |
