rm block scope

This commit is contained in:
2026-02-09 10:11:22 -06:00
parent 7469383e66
commit 0503acb7e6
6 changed files with 91 additions and 284 deletions

View File

@@ -500,13 +500,11 @@ static int mach_gen_compound_assign (MachGenState *s, cJSON *node, const char *o
if (strcmp (left_kind, "name") == 0) {
const char *name = cJSON_GetStringValue (cJSON_GetObjectItemCaseSensitive (left, "name"));
const char *sn = cJSON_GetStringValue (cJSON_GetObjectItemCaseSensitive (left, "scope_name"));
const char *ln = sn ? sn : name;
cJSON *level_node = cJSON_GetObjectItemCaseSensitive (left, "level");
int level = level_node ? (int)cJSON_GetNumberValue (level_node) : -1;
int left_slot = mach_gen_alloc_slot (s);
if (level == 0 || level == -1) {
int local = mach_gen_find_var (s, ln);
int local = mach_gen_find_var (s, name);
if (local >= 0) {
mach_gen_emit_2 (s, "move", left_slot, local);
level = 0; /* treat as local for the store below */
@@ -515,7 +513,7 @@ static int mach_gen_compound_assign (MachGenState *s, cJSON *node, const char *o
if (level > 0) {
MachGenState *target = s;
for (int i = 0; i < level; i++) target = target->parent;
int slot = mach_gen_find_var (target, ln);
int slot = mach_gen_find_var (target, name);
mach_gen_emit_3 (s, "get", left_slot, slot, level);
} else if (level == -1) {
cJSON *instr = cJSON_CreateArray ();
@@ -532,12 +530,12 @@ static int mach_gen_compound_assign (MachGenState *s, cJSON *node, const char *o
int dest = mach_gen_alloc_slot (s);
mach_gen_emit_3 (s, op, dest, left_slot, right_slot);
if (level == 0) {
int local = mach_gen_find_var (s, ln);
int local = mach_gen_find_var (s, name);
if (local >= 0) mach_gen_emit_2 (s, "move", local, dest);
} else if (level > 0) {
MachGenState *target = s;
for (int i = 0; i < level; i++) target = target->parent;
int slot = mach_gen_find_var (target, ln);
int slot = mach_gen_find_var (target, name);
mach_gen_emit_3 (s, "put", dest, slot, level);
} else {
cJSON *instr = cJSON_CreateArray ();
@@ -606,12 +604,10 @@ static int mach_gen_assign (MachGenState *s, cJSON *node) {
if (strcmp (left_kind, "name") == 0) {
const char *name = cJSON_GetStringValue (cJSON_GetObjectItemCaseSensitive (left, "name"));
const char *sn = cJSON_GetStringValue (cJSON_GetObjectItemCaseSensitive (left, "scope_name"));
const char *ln = sn ? sn : name;
cJSON *level_node = cJSON_GetObjectItemCaseSensitive (left, "level");
int level = level_node ? (int)cJSON_GetNumberValue (level_node) : -1;
if (level == 0 || level == -1) {
int slot = mach_gen_find_var (s, ln);
int slot = mach_gen_find_var (s, name);
if (slot >= 0) mach_gen_emit_2 (s, "move", slot, val_slot);
else if (level == -1) {
/* No annotation and not local — set global */
@@ -624,7 +620,7 @@ static int mach_gen_assign (MachGenState *s, cJSON *node) {
} else if (level > 0) {
MachGenState *target = s;
for (int i = 0; i < level; i++) target = target->parent;
int slot = mach_gen_find_var (target, ln);
int slot = mach_gen_find_var (target, name);
mach_gen_emit_3 (s, "put", val_slot, slot, level);
} else {
mach_gen_error (s, node, "cannot assign to unbound variable '%s'", name);
@@ -755,18 +751,16 @@ static int mach_gen_expr (MachGenState *s, cJSON *expr, int target) {
/* Variable reference — uses parser-provided level annotation */
if (strcmp (kind, "name") == 0) {
const char *name = cJSON_GetStringValue (cJSON_GetObjectItemCaseSensitive (expr, "name"));
const char *scope_name = cJSON_GetStringValue (cJSON_GetObjectItemCaseSensitive (expr, "scope_name"));
const char *lookup_name = scope_name ? scope_name : name;
cJSON *level_node = cJSON_GetObjectItemCaseSensitive (expr, "level");
int level = level_node ? (int)cJSON_GetNumberValue (level_node) : -1;
if (level == 0 || level == -1) {
/* level 0 = known local; level -1 = no annotation, try local first */
int slot = mach_gen_find_var (s, lookup_name);
int slot = mach_gen_find_var (s, name);
if (slot >= 0) return slot;
} else if (level > 0) {
MachGenState *target = s;
for (int i = 0; i < level; i++) target = target->parent;
int parent_slot = mach_gen_find_var (target, lookup_name);
int parent_slot = mach_gen_find_var (target, name);
int dest = mach_gen_alloc_slot (s);
mach_gen_emit_3 (s, "get", dest, parent_slot, level);
return dest;
@@ -934,19 +928,17 @@ static int mach_gen_expr (MachGenState *s, cJSON *expr, int target) {
if (strcmp (operand_kind, "name") == 0) {
const char *name = cJSON_GetStringValue (cJSON_GetObjectItemCaseSensitive (operand, "name"));
const char *inc_sn = cJSON_GetStringValue (cJSON_GetObjectItemCaseSensitive (operand, "scope_name"));
const char *inc_ln = inc_sn ? inc_sn : name;
cJSON *level_node = cJSON_GetObjectItemCaseSensitive (operand, "level");
int level = level_node ? (int)cJSON_GetNumberValue (level_node) : -1;
int old_slot = mach_gen_alloc_slot (s);
/* Load current value */
if (level == 0) {
int local = mach_gen_find_var (s, inc_ln);
int local = mach_gen_find_var (s, name);
if (local >= 0) mach_gen_emit_2 (s, "move", old_slot, local);
} else if (level > 0) {
MachGenState *target = s;
for (int i = 0; i < level; i++) target = target->parent;
int slot = mach_gen_find_var (target, inc_ln);
int slot = mach_gen_find_var (target, name);
mach_gen_emit_3 (s, "get", old_slot, slot, level);
} else {
cJSON *instr = cJSON_CreateArray ();
@@ -963,12 +955,12 @@ static int mach_gen_expr (MachGenState *s, cJSON *expr, int target) {
mach_gen_emit_3 (s, arith_op, new_slot, old_slot, one_slot);
/* Store new value */
if (level == 0) {
int local = mach_gen_find_var (s, inc_ln);
int local = mach_gen_find_var (s, name);
if (local >= 0) mach_gen_emit_2 (s, "move", local, new_slot);
} else if (level > 0) {
MachGenState *target = s;
for (int i = 0; i < level; i++) target = target->parent;
int slot = mach_gen_find_var (target, inc_ln);
int slot = mach_gen_find_var (target, name);
mach_gen_emit_3 (s, "put", new_slot, slot, level);
}
return postfix ? old_slot : new_slot;
@@ -1135,9 +1127,7 @@ static void mach_gen_statement (MachGenState *s, cJSON *stmt) {
cJSON *left = cJSON_GetObjectItemCaseSensitive (stmt, "left");
cJSON *right = cJSON_GetObjectItemCaseSensitive (stmt, "right");
const char *name = cJSON_GetStringValue (cJSON_GetObjectItemCaseSensitive (left, "name"));
const char *scope_name = cJSON_GetStringValue (cJSON_GetObjectItemCaseSensitive (left, "scope_name"));
const char *lookup_name = scope_name ? scope_name : name;
int local_slot = mach_gen_find_var (s, lookup_name);
int local_slot = mach_gen_find_var (s, name);
/* Pop: var val = arr[] */
cJSON *pop_flag = cJSON_GetObjectItemCaseSensitive (stmt, "pop");
if (pop_flag && cJSON_IsTrue (pop_flag) && right) {