diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-08-24 18:09:45 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-08-24 18:09:45 -0400 |
| commit | 222fbcd0027f085c48e93c6e70445699eec79d96 (patch) | |
| tree | 0c94fe2680b89ad29577be0366ffbb2ab127b25c /src | |
| parent | 9974ddd86ebe6f986ba6352c183250c99210656b (diff) | |
Move assignment code.
Diffstat (limited to 'src')
| -rw-r--r-- | src/compile/assignments.c | 47 | ||||
| -rw-r--r-- | src/compile/assignments.h | 1 | ||||
| -rw-r--r-- | src/compile/statements.c | 44 |
3 files changed, 48 insertions, 44 deletions
diff --git a/src/compile/assignments.c b/src/compile/assignments.c index e0bbc9fe..ba24ecf0 100644 --- a/src/compile/assignments.c +++ b/src/compile/assignments.c @@ -1,13 +1,13 @@ // This file defines how to compile assignments #include "assignments.h" #include "../ast.h" -#include "expressions.h" #include "../environment.h" #include "../stdlib/datatypes.h" #include "../stdlib/text.h" #include "../stdlib/util.h" #include "../typecheck.h" #include "declarations.h" +#include "expressions.h" #include "integers.h" #include "pointers.h" #include "promotions.h" @@ -91,6 +91,51 @@ Text_t compile_assignment(env_t *env, ast_t *target, Text_t value) { } public +Text_t compile_assignment_statement(env_t *env, ast_t *ast) { + DeclareMatch(assign, ast, Assign); + // Single assignment, no temp vars needed: + if (assign->targets && !assign->targets->next) { + type_t *lhs_t = get_type(env, assign->targets->ast); + if (assign->targets->ast->tag == Index && lhs_t->tag == OptionalType + && value_type(get_type(env, Match(assign->targets->ast, Index)->indexed))->tag == TableType) + lhs_t = Match(lhs_t, OptionalType)->type; + if (has_stack_memory(lhs_t)) + code_err(ast, "Stack references cannot be assigned to " + "variables because the " + "variable's scope may outlive the scope of the " + "stack memory."); + env_t *val_env = with_enum_scope(env, lhs_t); + Text_t val = compile_to_type(val_env, assign->values->ast, lhs_t); + return Texts(compile_assignment(env, assign->targets->ast, val), ";\n"); + } + + Text_t code = Text("{ // Assignment\n"); + int64_t i = 1; + for (ast_list_t *value = assign->values, *target = assign->targets; value && target; + value = value->next, target = target->next) { + type_t *lhs_t = get_type(env, target->ast); + if (target->ast->tag == Index && lhs_t->tag == OptionalType + && value_type(get_type(env, Match(target->ast, Index)->indexed))->tag == TableType) + lhs_t = Match(lhs_t, OptionalType)->type; + if (has_stack_memory(lhs_t)) + code_err(ast, "Stack references cannot be assigned to " + "variables because the " + "variable's scope may outlive the scope of the " + "stack memory."); + env_t *val_env = with_enum_scope(env, lhs_t); + Text_t val = compile_to_type(val_env, value->ast, lhs_t); + code = Texts(code, compile_type(lhs_t), " $", String(i), " = ", val, ";\n"); + i += 1; + } + i = 1; + for (ast_list_t *target = assign->targets; target; target = target->next) { + code = Texts(code, compile_assignment(env, target->ast, Texts("$", String(i))), ";\n"); + i += 1; + } + return Texts(code, "\n}"); +} + +public Text_t compile_lvalue(env_t *env, ast_t *ast) { if (!can_be_mutated(env, ast)) { if (ast->tag == Index) { diff --git a/src/compile/assignments.h b/src/compile/assignments.h index 6ee18342..94de05e3 100644 --- a/src/compile/assignments.h +++ b/src/compile/assignments.h @@ -7,4 +7,5 @@ Text_t compile_update_assignment(env_t *env, ast_t *ast); Text_t compile_assignment(env_t *env, ast_t *target, Text_t value); +Text_t compile_assignment_statement(env_t *env, ast_t *ast); Text_t compile_lvalue(env_t *env, ast_t *ast); diff --git a/src/compile/statements.c b/src/compile/statements.c index da6ad465..642b900d 100644 --- a/src/compile/statements.c +++ b/src/compile/statements.c @@ -354,49 +354,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) { return Texts(compile_declaration(t, Texts("_$", name)), " = ", val_code, ";"); } } - case Assign: { - DeclareMatch(assign, ast, Assign); - // Single assignment, no temp vars needed: - if (assign->targets && !assign->targets->next) { - type_t *lhs_t = get_type(env, assign->targets->ast); - if (assign->targets->ast->tag == Index && lhs_t->tag == OptionalType - && value_type(get_type(env, Match(assign->targets->ast, Index)->indexed))->tag == TableType) - lhs_t = Match(lhs_t, OptionalType)->type; - if (has_stack_memory(lhs_t)) - code_err(ast, "Stack references cannot be assigned to " - "variables because the " - "variable's scope may outlive the scope of the " - "stack memory."); - env_t *val_env = with_enum_scope(env, lhs_t); - Text_t val = compile_to_type(val_env, assign->values->ast, lhs_t); - return Texts(compile_assignment(env, assign->targets->ast, val), ";\n"); - } - - Text_t code = Text("{ // Assignment\n"); - int64_t i = 1; - for (ast_list_t *value = assign->values, *target = assign->targets; value && target; - value = value->next, target = target->next) { - type_t *lhs_t = get_type(env, target->ast); - if (target->ast->tag == Index && lhs_t->tag == OptionalType - && value_type(get_type(env, Match(target->ast, Index)->indexed))->tag == TableType) - lhs_t = Match(lhs_t, OptionalType)->type; - if (has_stack_memory(lhs_t)) - code_err(ast, "Stack references cannot be assigned to " - "variables because the " - "variable's scope may outlive the scope of the " - "stack memory."); - env_t *val_env = with_enum_scope(env, lhs_t); - Text_t val = compile_to_type(val_env, value->ast, lhs_t); - code = Texts(code, compile_type(lhs_t), " $", String(i), " = ", val, ";\n"); - i += 1; - } - i = 1; - for (ast_list_t *target = assign->targets; target; target = target->next) { - code = Texts(code, compile_assignment(env, target->ast, Texts("$", String(i))), ";\n"); - i += 1; - } - return Texts(code, "\n}"); - } + case Assign: return compile_assignment_statement(env, ast); case PlusUpdate: { DeclareMatch(update, ast, PlusUpdate); type_t *lhs_t = get_type(env, update->lhs); |
