aboutsummaryrefslogtreecommitdiff
path: root/src/compile
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-08-24 18:09:45 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-08-24 18:09:45 -0400
commit222fbcd0027f085c48e93c6e70445699eec79d96 (patch)
tree0c94fe2680b89ad29577be0366ffbb2ab127b25c /src/compile
parent9974ddd86ebe6f986ba6352c183250c99210656b (diff)
Move assignment code.
Diffstat (limited to 'src/compile')
-rw-r--r--src/compile/assignments.c47
-rw-r--r--src/compile/assignments.h1
-rw-r--r--src/compile/statements.c44
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);