2 Commits

Author SHA1 Message Date
John Alanbrook
8cf98d8a9e Merge branch 'mcode2' into mach 2026-02-06 15:14:40 -06:00
John Alanbrook
af2d296f40 use new parser info 2026-02-06 12:45:25 -06:00

View File

@@ -30728,7 +30728,8 @@ typedef enum MachVarResolution {
typedef struct MachVarInfo {
char *name;
int slot;
int is_const; /* 1 for def, function args; 0 for var */
int is_const; /* 1 for def, function args; 0 for var */
int is_closure; /* 1 if captured by a nested function */
} MachVarInfo;
/* ---- Compile-time constant pool entry ---- */
@@ -30922,6 +30923,7 @@ static void mach_add_var(MachCompState *cs, const char *name, int slot, int is_c
strcpy(v->name, name);
v->slot = slot;
v->is_const = is_const;
v->is_closure = 0;
}
/* Find a variable in the current scope */
@@ -32562,13 +32564,47 @@ typedef struct MachGenState {
int function_nr;
cJSON *scopes;
/* Intrinsic (global) name cache */
struct { const char *name; int slot; } intrinsic_cache[64];
int intrinsic_count;
/* Error tracking */
cJSON *errors;
int has_error;
} MachGenState;
static int mach_gen_expr (MachGenState *s, cJSON *expr);
static int mach_gen_expr (MachGenState *s, cJSON *expr, int target);
static void mach_gen_statement (MachGenState *s, cJSON *stmt);
static int mach_gen_alloc_slot (MachGenState *s);
/* Look up an intrinsic in the cache, return slot or -1 */
static int mach_gen_find_intrinsic (MachGenState *s, const char *name) {
for (int i = 0; i < s->intrinsic_count; i++) {
if (strcmp (s->intrinsic_cache[i].name, name) == 0)
return s->intrinsic_cache[i].slot;
}
return -1;
}
/* Pre-load intrinsics from the AST intrinsics array */
static void mach_gen_load_intrinsics (MachGenState *s, cJSON *intrinsics) {
if (!intrinsics) return;
cJSON *item;
cJSON_ArrayForEach (item, intrinsics) {
const char *name = cJSON_GetStringValue (item);
if (!name || s->intrinsic_count >= 64) continue;
if (mach_gen_find_intrinsic (s, name) >= 0) continue;
int slot = mach_gen_alloc_slot (s);
cJSON *instr = cJSON_CreateArray ();
cJSON_AddItemToArray (instr, cJSON_CreateString ("cap_name"));
cJSON_AddItemToArray (instr, cJSON_CreateNumber (slot));
cJSON_AddItemToArray (instr, cJSON_CreateString (name));
cJSON_AddItemToArray (s->instructions, instr);
s->intrinsic_cache[s->intrinsic_count].name = name;
s->intrinsic_cache[s->intrinsic_count].slot = slot;
s->intrinsic_count++;
}
}
/* Allocate a temporary slot */
static int mach_gen_alloc_slot (MachGenState *s) {
@@ -32589,6 +32625,7 @@ static void mach_gen_add_var (MachGenState *s, const char *name, int slot, int i
strcpy (v->name, name);
v->slot = slot;
v->is_const = is_const;
v->is_closure = 0;
}
/* Find a variable in the current scope only */
@@ -32641,6 +32678,8 @@ static void mach_gen_scan_scope (MachGenState *s) {
int is_const = (strcmp (make, "def") == 0 || strcmp (make, "function") == 0);
int slot = 1 + s->nr_args + s->nr_local_slots++;
mach_gen_add_var (s, name, slot, is_const);
cJSON *closure_flag = cJSON_GetObjectItem (v, "closure");
s->vars[s->var_count - 1].is_closure = (closure_flag && cJSON_IsTrue (closure_flag));
}
}
}
@@ -32841,11 +32880,11 @@ static int mach_gen_binary (MachGenState *s, cJSON *node) {
if (strcmp (kind, "&&") == 0) {
char *end_label = mach_gen_label (s, "and_end");
int left_slot = mach_gen_expr (s, left);
int left_slot = mach_gen_expr (s, left, -1);
int dest = mach_gen_alloc_slot (s);
mach_gen_emit_2 (s, "move", dest, left_slot);
mach_gen_emit_jump_cond (s, "jump_false", dest, end_label);
int right_slot = mach_gen_expr (s, right);
int right_slot = mach_gen_expr (s, right, -1);
mach_gen_emit_2 (s, "move", dest, right_slot);
mach_gen_emit_label (s, end_label);
sys_free (end_label);
@@ -32854,11 +32893,11 @@ static int mach_gen_binary (MachGenState *s, cJSON *node) {
if (strcmp (kind, "||") == 0) {
char *end_label = mach_gen_label (s, "or_end");
int left_slot = mach_gen_expr (s, left);
int left_slot = mach_gen_expr (s, left, -1);
int dest = mach_gen_alloc_slot (s);
mach_gen_emit_2 (s, "move", dest, left_slot);
mach_gen_emit_jump_cond (s, "jump_true", dest, end_label);
int right_slot = mach_gen_expr (s, right);
int right_slot = mach_gen_expr (s, right, -1);
mach_gen_emit_2 (s, "move", dest, right_slot);
mach_gen_emit_label (s, end_label);
sys_free (end_label);
@@ -32867,19 +32906,19 @@ static int mach_gen_binary (MachGenState *s, cJSON *node) {
if (strcmp (kind, "??") == 0) {
char *end_label = mach_gen_label (s, "nullish_end");
int left_slot = mach_gen_expr (s, left);
int left_slot = mach_gen_expr (s, left, -1);
int dest = mach_gen_alloc_slot (s);
mach_gen_emit_2 (s, "move", dest, left_slot);
mach_gen_emit_jump_cond (s, "jump_not_null", dest, end_label);
int right_slot = mach_gen_expr (s, right);
int right_slot = mach_gen_expr (s, right, -1);
mach_gen_emit_2 (s, "move", dest, right_slot);
mach_gen_emit_label (s, end_label);
sys_free (end_label);
return dest;
}
int left_slot = mach_gen_expr (s, left);
int right_slot = mach_gen_expr (s, right);
int left_slot = mach_gen_expr (s, left, -1);
int right_slot = mach_gen_expr (s, right, -1);
int dest = mach_gen_alloc_slot (s);
const char *op = mach_gen_binop_to_string (kind);
mach_gen_emit_3 (s, op, dest, left_slot, right_slot);
@@ -32911,7 +32950,7 @@ static int mach_gen_compound_assign (MachGenState *s, cJSON *node, const char *o
cJSON_AddItemToArray (instr, cJSON_CreateString (name));
cJSON_AddItemToArray (s->instructions, instr);
}
int right_slot = mach_gen_expr (s, right);
int right_slot = mach_gen_expr (s, right, -1);
int dest = mach_gen_alloc_slot (s);
mach_gen_emit_3 (s, op, dest, left_slot, right_slot);
if (level == 0) {
@@ -32933,10 +32972,10 @@ static int mach_gen_compound_assign (MachGenState *s, cJSON *node, const char *o
} else if (strcmp (left_kind, ".") == 0) {
cJSON *obj = cJSON_GetObjectItem (left, "left");
const char *prop = cJSON_GetStringValue (cJSON_GetObjectItem (left, "right"));
int obj_slot = mach_gen_expr (s, obj);
int obj_slot = mach_gen_expr (s, obj, -1);
int old_val = mach_gen_alloc_slot (s);
mach_gen_emit_get_prop (s, old_val, obj_slot, prop);
int right_slot = mach_gen_expr (s, right);
int right_slot = mach_gen_expr (s, right, -1);
int dest = mach_gen_alloc_slot (s);
mach_gen_emit_3 (s, op, dest, old_val, right_slot);
mach_gen_emit_set_prop (s, obj_slot, prop, dest);
@@ -32944,11 +32983,11 @@ static int mach_gen_compound_assign (MachGenState *s, cJSON *node, const char *o
} else if (strcmp (left_kind, "[") == 0) {
cJSON *obj = cJSON_GetObjectItem (left, "left");
cJSON *idx_expr = cJSON_GetObjectItem (left, "right");
int obj_slot = mach_gen_expr (s, obj);
int idx_slot = mach_gen_expr (s, idx_expr);
int obj_slot = mach_gen_expr (s, obj, -1);
int idx_slot = mach_gen_expr (s, idx_expr, -1);
int old_val = mach_gen_alloc_slot (s);
mach_gen_emit_get_elem (s, old_val, obj_slot, idx_slot);
int right_slot = mach_gen_expr (s, right);
int right_slot = mach_gen_expr (s, right, -1);
int dest = mach_gen_alloc_slot (s);
mach_gen_emit_3 (s, op, dest, old_val, right_slot);
mach_gen_emit_set_elem (s, obj_slot, idx_slot, dest);
@@ -32975,7 +33014,7 @@ static int mach_gen_assign (MachGenState *s, cJSON *node) {
if (strcmp (kind, ">>=") == 0) return mach_gen_compound_assign (s, node, "shr");
if (strcmp (kind, ">>>=") == 0) return mach_gen_compound_assign (s, node, "ushr");
int val_slot = mach_gen_expr (s, right);
int val_slot = mach_gen_expr (s, right, -1);
const char *left_kind = cJSON_GetStringValue (cJSON_GetObjectItem (left, "kind"));
if (strcmp (left_kind, "name") == 0) {
@@ -32996,13 +33035,13 @@ static int mach_gen_assign (MachGenState *s, cJSON *node) {
} else if (strcmp (left_kind, ".") == 0) {
cJSON *obj = cJSON_GetObjectItem (left, "left");
const char *prop = cJSON_GetStringValue (cJSON_GetObjectItem (left, "right"));
int obj_slot = mach_gen_expr (s, obj);
int obj_slot = mach_gen_expr (s, obj, -1);
mach_gen_emit_set_prop (s, obj_slot, prop, val_slot);
} else if (strcmp (left_kind, "[") == 0) {
cJSON *obj = cJSON_GetObjectItem (left, "left");
cJSON *idx_expr = cJSON_GetObjectItem (left, "right");
int obj_slot = mach_gen_expr (s, obj);
int idx_slot = mach_gen_expr (s, idx_expr);
int obj_slot = mach_gen_expr (s, obj, -1);
int idx_slot = mach_gen_expr (s, idx_expr, -1);
mach_gen_emit_set_elem (s, obj_slot, idx_slot, val_slot);
}
return val_slot;
@@ -33010,36 +33049,36 @@ static int mach_gen_assign (MachGenState *s, cJSON *node) {
static cJSON *mach_gen_function (MachGenState *parent, cJSON *func_node);
static int mach_gen_expr (MachGenState *s, cJSON *expr) {
static int mach_gen_expr (MachGenState *s, cJSON *expr, int target) {
if (!expr) return -1;
const char *kind = cJSON_GetStringValue (cJSON_GetObjectItem (expr, "kind"));
if (!kind) return -1;
/* Literals */
/* Literals — use target slot if provided */
if (strcmp (kind, "number") == 0) {
int slot = mach_gen_alloc_slot (s);
int slot = target >= 0 ? target : mach_gen_alloc_slot (s);
double val = cJSON_GetNumberValue (cJSON_GetObjectItem (expr, "number"));
mach_gen_emit_const_num (s, slot, val);
return slot;
}
if (strcmp (kind, "text") == 0) {
int slot = mach_gen_alloc_slot (s);
int slot = target >= 0 ? target : mach_gen_alloc_slot (s);
const char *val = cJSON_GetStringValue (cJSON_GetObjectItem (expr, "value"));
mach_gen_emit_const_str (s, slot, val ? val : "");
return slot;
}
if (strcmp (kind, "true") == 0) {
int slot = mach_gen_alloc_slot (s);
int slot = target >= 0 ? target : mach_gen_alloc_slot (s);
mach_gen_emit_const_bool (s, slot, 1);
return slot;
}
if (strcmp (kind, "false") == 0) {
int slot = mach_gen_alloc_slot (s);
int slot = target >= 0 ? target : mach_gen_alloc_slot (s);
mach_gen_emit_const_bool (s, slot, 0);
return slot;
}
if (strcmp (kind, "null") == 0) {
int slot = mach_gen_alloc_slot (s);
int slot = target >= 0 ? target : mach_gen_alloc_slot (s);
mach_gen_emit_const_null (s, slot);
return slot;
}
@@ -33063,7 +33102,9 @@ static int mach_gen_expr (MachGenState *s, cJSON *expr) {
mach_gen_emit_3 (s, "get", dest, parent_slot, level);
return dest;
}
/* Unbound — emit cap_name */
/* Unbound — check intrinsic cache first, then emit cap_name */
int cached = mach_gen_find_intrinsic (s, name);
if (cached >= 0) return cached;
int dest = mach_gen_alloc_slot (s);
cJSON *instr = cJSON_CreateArray ();
cJSON_AddItemToArray (instr, cJSON_CreateString ("cap_name"));
@@ -33077,7 +33118,7 @@ static int mach_gen_expr (MachGenState *s, cJSON *expr) {
if (strcmp (kind, ".") == 0) {
cJSON *obj = cJSON_GetObjectItem (expr, "left");
const char *prop = cJSON_GetStringValue (cJSON_GetObjectItem (expr, "right"));
int obj_slot = mach_gen_expr (s, obj);
int obj_slot = mach_gen_expr (s, obj, -1);
int slot = mach_gen_alloc_slot (s);
mach_gen_emit_get_prop (s, slot, obj_slot, prop);
return slot;
@@ -33087,8 +33128,8 @@ static int mach_gen_expr (MachGenState *s, cJSON *expr) {
if (strcmp (kind, "[") == 0) {
cJSON *obj = cJSON_GetObjectItem (expr, "left");
cJSON *idx = cJSON_GetObjectItem (expr, "right");
int obj_slot = mach_gen_expr (s, obj);
int idx_slot = mach_gen_expr (s, idx);
int obj_slot = mach_gen_expr (s, obj, -1);
int idx_slot = mach_gen_expr (s, idx, -1);
int slot = mach_gen_alloc_slot (s);
mach_gen_emit_get_elem (s, slot, obj_slot, idx_slot);
return slot;
@@ -33101,7 +33142,7 @@ static int mach_gen_expr (MachGenState *s, cJSON *expr) {
cJSON *arg_slots = cJSON_CreateArray ();
cJSON *arg;
cJSON_ArrayForEach (arg, args_list) {
int arg_slot = mach_gen_expr (s, arg);
int arg_slot = mach_gen_expr (s, arg, -1);
cJSON_AddItemToArray (arg_slots, cJSON_CreateNumber (arg_slot));
}
const char *callee_kind = cJSON_GetStringValue (cJSON_GetObjectItem (callee, "kind"));
@@ -33109,10 +33150,10 @@ static int mach_gen_expr (MachGenState *s, cJSON *expr) {
if (strcmp (callee_kind, ".") == 0) {
cJSON *obj = cJSON_GetObjectItem (callee, "left");
const char *prop = cJSON_GetStringValue (cJSON_GetObjectItem (callee, "right"));
int obj_slot = mach_gen_expr (s, obj);
int obj_slot = mach_gen_expr (s, obj, -1);
mach_gen_emit_call_method (s, dest, obj_slot, prop, arg_slots);
} else {
int func_slot = mach_gen_expr (s, callee);
int func_slot = mach_gen_expr (s, callee, -1);
mach_gen_emit_call (s, dest, func_slot, arg_slots);
}
cJSON_Delete (arg_slots);
@@ -33122,28 +33163,28 @@ static int mach_gen_expr (MachGenState *s, cJSON *expr) {
/* Unary operators */
if (strcmp (kind, "!") == 0) {
cJSON *operand = cJSON_GetObjectItem (expr, "expression");
int operand_slot = mach_gen_expr (s, operand);
int operand_slot = mach_gen_expr (s, operand, -1);
int slot = mach_gen_alloc_slot (s);
mach_gen_emit_2 (s, "not", slot, operand_slot);
return slot;
}
if (strcmp (kind, "~") == 0) {
cJSON *operand = cJSON_GetObjectItem (expr, "expression");
int operand_slot = mach_gen_expr (s, operand);
int operand_slot = mach_gen_expr (s, operand, -1);
int slot = mach_gen_alloc_slot (s);
mach_gen_emit_2 (s, "bitnot", slot, operand_slot);
return slot;
}
if (strcmp (kind, "-unary") == 0) {
cJSON *operand = cJSON_GetObjectItem (expr, "expression");
int operand_slot = mach_gen_expr (s, operand);
int operand_slot = mach_gen_expr (s, operand, -1);
int slot = mach_gen_alloc_slot (s);
mach_gen_emit_2 (s, "neg", slot, operand_slot);
return slot;
}
if (strcmp (kind, "+unary") == 0) {
cJSON *operand = cJSON_GetObjectItem (expr, "expression");
return mach_gen_expr (s, operand);
return mach_gen_expr (s, operand, -1);
}
/* Increment/Decrement */
@@ -33191,7 +33232,7 @@ static int mach_gen_expr (MachGenState *s, cJSON *expr) {
} else if (strcmp (operand_kind, ".") == 0) {
cJSON *obj = cJSON_GetObjectItem (operand, "left");
const char *prop = cJSON_GetStringValue (cJSON_GetObjectItem (operand, "right"));
int obj_slot = mach_gen_expr (s, obj);
int obj_slot = mach_gen_expr (s, obj, -1);
int old_slot = mach_gen_alloc_slot (s);
mach_gen_emit_get_prop (s, old_slot, obj_slot, prop);
int new_slot = mach_gen_alloc_slot (s);
@@ -33201,8 +33242,8 @@ static int mach_gen_expr (MachGenState *s, cJSON *expr) {
} else if (strcmp (operand_kind, "[") == 0) {
cJSON *obj = cJSON_GetObjectItem (operand, "left");
cJSON *idx_expr = cJSON_GetObjectItem (operand, "right");
int obj_slot = mach_gen_expr (s, obj);
int idx_slot = mach_gen_expr (s, idx_expr);
int obj_slot = mach_gen_expr (s, obj, -1);
int idx_slot = mach_gen_expr (s, idx_expr, -1);
int old_slot = mach_gen_alloc_slot (s);
mach_gen_emit_get_elem (s, old_slot, obj_slot, idx_slot);
int new_slot = mach_gen_alloc_slot (s);
@@ -33220,7 +33261,7 @@ static int mach_gen_expr (MachGenState *s, cJSON *expr) {
if (strcmp (operand_kind, ".") == 0) {
cJSON *obj = cJSON_GetObjectItem (operand, "left");
const char *prop = cJSON_GetStringValue (cJSON_GetObjectItem (operand, "right"));
int obj_slot = mach_gen_expr (s, obj);
int obj_slot = mach_gen_expr (s, obj, -1);
cJSON *instr = cJSON_CreateArray ();
cJSON_AddItemToArray (instr, cJSON_CreateString ("delete_prop"));
cJSON_AddItemToArray (instr, cJSON_CreateNumber (slot));
@@ -33230,8 +33271,8 @@ static int mach_gen_expr (MachGenState *s, cJSON *expr) {
} else if (strcmp (operand_kind, "[") == 0) {
cJSON *obj = cJSON_GetObjectItem (operand, "left");
cJSON *idx = cJSON_GetObjectItem (operand, "right");
int obj_slot = mach_gen_expr (s, obj);
int idx_slot = mach_gen_expr (s, idx);
int obj_slot = mach_gen_expr (s, obj, -1);
int idx_slot = mach_gen_expr (s, idx, -1);
mach_gen_emit_3 (s, "delete_idx", slot, obj_slot, idx_slot);
} else {
mach_gen_emit_const_bool (s, slot, 1);
@@ -33246,14 +33287,14 @@ static int mach_gen_expr (MachGenState *s, cJSON *expr) {
cJSON *else_expr = cJSON_GetObjectItem (expr, "else");
char *else_label = mach_gen_label (s, "tern_else");
char *end_label = mach_gen_label (s, "tern_end");
int cond_slot = mach_gen_expr (s, cond);
int cond_slot = mach_gen_expr (s, cond, -1);
mach_gen_emit_jump_cond (s, "jump_false", cond_slot, else_label);
int dest = mach_gen_alloc_slot (s);
int then_slot = mach_gen_expr (s, then_expr);
int then_slot = mach_gen_expr (s, then_expr, -1);
mach_gen_emit_2 (s, "move", dest, then_slot);
mach_gen_emit_jump (s, end_label);
mach_gen_emit_label (s, else_label);
int else_slot = mach_gen_expr (s, else_expr);
int else_slot = mach_gen_expr (s, else_expr, -1);
mach_gen_emit_2 (s, "move", dest, else_slot);
mach_gen_emit_label (s, end_label);
sys_free (else_label);
@@ -33268,7 +33309,7 @@ static int mach_gen_expr (MachGenState *s, cJSON *expr) {
cJSON *elem_slots = cJSON_CreateArray ();
cJSON *elem;
cJSON_ArrayForEach (elem, list) {
int slot = mach_gen_expr (s, elem);
int slot = mach_gen_expr (s, elem, -1);
cJSON_AddItemToArray (elem_slots, cJSON_CreateNumber (slot));
}
int dest = mach_gen_alloc_slot (s);
@@ -33298,7 +33339,7 @@ static int mach_gen_expr (MachGenState *s, cJSON *expr) {
cJSON_ArrayForEach (pair, list) {
cJSON *key = cJSON_GetObjectItem (pair, "left");
cJSON *val = cJSON_GetObjectItem (pair, "right");
int val_slot = mach_gen_expr (s, val);
int val_slot = mach_gen_expr (s, val, -1);
const char *key_kind = cJSON_GetStringValue (cJSON_GetObjectItem (key, "kind"));
if (key_kind && strcmp (key_kind, "name") == 0) {
const char *name = cJSON_GetStringValue (cJSON_GetObjectItem (key, "name"));
@@ -33307,7 +33348,7 @@ static int mach_gen_expr (MachGenState *s, cJSON *expr) {
const char *name = cJSON_GetStringValue (cJSON_GetObjectItem (key, "value"));
mach_gen_emit_set_prop (s, dest, name ? name : "", val_slot);
} else {
int key_slot = mach_gen_expr (s, key);
int key_slot = mach_gen_expr (s, key, -1);
mach_gen_emit_set_elem (s, dest, key_slot, val_slot);
}
}
@@ -33357,8 +33398,8 @@ static void mach_gen_statement (MachGenState *s, cJSON *stmt) {
const char *name = cJSON_GetStringValue (cJSON_GetObjectItem (left, "name"));
int local_slot = mach_gen_find_var (s, name);
if (right) {
int val_slot = mach_gen_expr (s, right);
if (local_slot >= 0)
int val_slot = mach_gen_expr (s, right, local_slot);
if (local_slot >= 0 && val_slot != local_slot)
mach_gen_emit_2 (s, "move", local_slot, val_slot);
} else if (local_slot >= 0) {
mach_gen_emit_const_null (s, local_slot);
@@ -33379,7 +33420,7 @@ static void mach_gen_statement (MachGenState *s, cJSON *stmt) {
cJSON *else_stmts = cJSON_GetObjectItem (stmt, "else");
char *else_label = mach_gen_label (s, "if_else");
char *end_label = mach_gen_label (s, "if_end");
int cond_slot = mach_gen_expr (s, cond);
int cond_slot = mach_gen_expr (s, cond, -1);
mach_gen_emit_jump_cond (s, "jump_false", cond_slot, else_label);
cJSON *child;
cJSON_ArrayForEach (child, then_stmts) { mach_gen_statement (s, child); }
@@ -33404,7 +33445,7 @@ static void mach_gen_statement (MachGenState *s, cJSON *stmt) {
s->loop_break = end_label;
s->loop_continue = start_label;
mach_gen_emit_label (s, start_label);
int cond_slot = mach_gen_expr (s, cond);
int cond_slot = mach_gen_expr (s, cond, -1);
mach_gen_emit_jump_cond (s, "jump_false", cond_slot, end_label);
cJSON *child;
cJSON_ArrayForEach (child, stmts) { mach_gen_statement (s, child); }
@@ -33431,7 +33472,7 @@ static void mach_gen_statement (MachGenState *s, cJSON *stmt) {
cJSON *child;
cJSON_ArrayForEach (child, stmts) { mach_gen_statement (s, child); }
mach_gen_emit_label (s, cond_label);
int cond_slot = mach_gen_expr (s, cond);
int cond_slot = mach_gen_expr (s, cond, -1);
mach_gen_emit_jump_cond (s, "jump_true", cond_slot, start_label);
mach_gen_emit_label (s, end_label);
s->loop_break = old_break;
@@ -33459,17 +33500,17 @@ static void mach_gen_statement (MachGenState *s, cJSON *stmt) {
if (init_kind && (strcmp (init_kind, "var") == 0 || strcmp (init_kind, "def") == 0))
mach_gen_statement (s, init);
else
mach_gen_expr (s, init);
mach_gen_expr (s, init, -1);
}
mach_gen_emit_label (s, start_label);
if (test) {
int test_slot = mach_gen_expr (s, test);
int test_slot = mach_gen_expr (s, test, -1);
mach_gen_emit_jump_cond (s, "jump_false", test_slot, end_label);
}
cJSON *child;
cJSON_ArrayForEach (child, stmts) { mach_gen_statement (s, child); }
mach_gen_emit_label (s, update_label);
if (update) mach_gen_expr (s, update);
if (update) mach_gen_expr (s, update, -1);
mach_gen_emit_jump (s, start_label);
mach_gen_emit_label (s, end_label);
s->loop_break = old_break;
@@ -33483,7 +33524,7 @@ static void mach_gen_statement (MachGenState *s, cJSON *stmt) {
if (strcmp (kind, "return") == 0) {
cJSON *expr = cJSON_GetObjectItem (stmt, "expression");
if (expr) {
int slot = mach_gen_expr (s, expr);
int slot = mach_gen_expr (s, expr, -1);
mach_gen_emit_1 (s, "return", slot);
} else {
mach_gen_emit_0 (s, "return_undef");
@@ -33501,17 +33542,17 @@ static void mach_gen_statement (MachGenState *s, cJSON *stmt) {
cJSON *arg_slots = cJSON_CreateArray ();
cJSON *arg;
cJSON_ArrayForEach (arg, args_list) {
int arg_slot = mach_gen_expr (s, arg);
int arg_slot = mach_gen_expr (s, arg, -1);
cJSON_AddItemToArray (arg_slots, cJSON_CreateNumber (arg_slot));
}
const char *callee_kind = cJSON_GetStringValue (cJSON_GetObjectItem (callee, "kind"));
if (callee_kind && strcmp (callee_kind, ".") == 0) {
cJSON *obj_node = cJSON_GetObjectItem (callee, "left");
const char *prop = cJSON_GetStringValue (cJSON_GetObjectItem (callee, "right"));
int obj_slot = mach_gen_expr (s, obj_node);
int obj_slot = mach_gen_expr (s, obj_node, -1);
mach_gen_emit_go_call_method (s, obj_slot, prop, arg_slots);
} else {
int func_slot = mach_gen_expr (s, callee);
int func_slot = mach_gen_expr (s, callee, -1);
mach_gen_emit_go_call (s, func_slot, arg_slots);
}
cJSON_Delete (arg_slots);
@@ -33520,7 +33561,7 @@ static void mach_gen_statement (MachGenState *s, cJSON *stmt) {
if (strcmp (kind, "throw") == 0) {
cJSON *expr = cJSON_GetObjectItem (stmt, "expression");
int slot = mach_gen_expr (s, expr);
int slot = mach_gen_expr (s, expr, -1);
mach_gen_emit_1 (s, "throw", slot);
return;
}
@@ -33540,7 +33581,7 @@ static void mach_gen_statement (MachGenState *s, cJSON *stmt) {
if (strcmp (kind, "switch") == 0) {
cJSON *expr = cJSON_GetObjectItem (stmt, "expression");
cJSON *cases = cJSON_GetObjectItem (stmt, "cases");
int switch_val = mach_gen_expr (s, expr);
int switch_val = mach_gen_expr (s, expr, -1);
char *end_label = mach_gen_label (s, "switch_end");
char *default_label = NULL;
const char *old_break = s->loop_break;
@@ -33553,7 +33594,7 @@ static void mach_gen_statement (MachGenState *s, cJSON *stmt) {
} else {
char *case_label = mach_gen_label (s, "switch_case");
cJSON *case_expr = cJSON_GetObjectItem (case_node, "expression");
int case_val = mach_gen_expr (s, case_expr);
int case_val = mach_gen_expr (s, case_expr, -1);
int cmp_slot = mach_gen_alloc_slot (s);
mach_gen_emit_3 (s, "eq", cmp_slot, switch_val, case_val);
mach_gen_emit_jump_cond (s, "jump_true", cmp_slot, case_label);
@@ -33637,11 +33678,11 @@ static void mach_gen_statement (MachGenState *s, cJSON *stmt) {
if (strcmp (kind, "call") == 0) {
cJSON *expr = cJSON_GetObjectItem (stmt, "expression");
mach_gen_expr (s, expr);
mach_gen_expr (s, expr, -1);
return;
}
mach_gen_expr (s, stmt);
mach_gen_expr (s, stmt, -1);
}
static cJSON *mach_gen_function (MachGenState *parent, cJSON *func_node) {
@@ -33695,12 +33736,41 @@ static cJSON *mach_gen_function (MachGenState *parent, cJSON *func_node) {
cJSON_AddNumberToObject (result, "nr_args", s.nr_args);
/* Use nr_slots from AST to pre-allocate var capacity */
cJSON *ns = cJSON_GetObjectItem (func_node, "nr_slots");
int ast_nr_slots = ns ? (int)cJSON_GetNumberValue (ns) : 0;
if (ast_nr_slots > 0) {
s.var_capacity = ast_nr_slots;
s.vars = sys_malloc (s.var_capacity * sizeof(MachVarInfo));
}
/* Scan scope record for variable declarations */
mach_gen_scan_scope (&s);
s.next_temp_slot = 1 + s.nr_args + s.nr_local_slots;
if (s.next_temp_slot > s.max_slot) s.max_slot = s.next_temp_slot;
/* Pre-load intrinsics (global names) */
mach_gen_load_intrinsics (&s, cJSON_GetObjectItem (func_node, "intrinsics"));
/* Compile hoisted function declarations from func_node["functions"] */
cJSON *hoisted = cJSON_GetObjectItem (func_node, "functions");
if (hoisted) {
cJSON *fn;
cJSON_ArrayForEach (fn, hoisted) {
const char *fname = cJSON_GetStringValue (cJSON_GetObjectItem (fn, "name"));
if (fname) {
int func_id = s.func_counter++;
cJSON *compiled = mach_gen_function (&s, fn);
cJSON_AddItemToArray (s.functions, compiled);
int local_slot = mach_gen_find_var (&s, fname);
int dest = mach_gen_alloc_slot (&s);
mach_gen_emit_2 (&s, "mkfunc", dest, func_id);
if (local_slot >= 0) mach_gen_emit_2 (&s, "move", local_slot, dest);
}
}
}
/* Compile body */
cJSON *stmts = cJSON_GetObjectItem (func_node, "statements");
if (!stmts) {
@@ -33759,12 +33829,41 @@ static cJSON *mach_gen_program (MachGenState *s, cJSON *ast) {
s->next_temp_slot = 1;
s->max_slot = 1;
/* Use nr_slots from AST to pre-allocate var capacity */
cJSON *ns = cJSON_GetObjectItem (ast, "nr_slots");
int ast_nr_slots = ns ? (int)cJSON_GetNumberValue (ns) : 0;
if (ast_nr_slots > 0) {
s->var_capacity = ast_nr_slots;
s->vars = sys_malloc (s->var_capacity * sizeof(MachVarInfo));
}
/* Scan scope record for variable declarations */
mach_gen_scan_scope (s);
s->next_temp_slot = 1 + s->nr_local_slots;
if (s->next_temp_slot > s->max_slot) s->max_slot = s->next_temp_slot;
/* Pre-load intrinsics (global names) */
mach_gen_load_intrinsics (s, cJSON_GetObjectItem (ast, "intrinsics"));
/* Compile hoisted function declarations from ast["functions"] */
cJSON *hoisted = cJSON_GetObjectItem (ast, "functions");
if (hoisted) {
cJSON *fn;
cJSON_ArrayForEach (fn, hoisted) {
const char *name = cJSON_GetStringValue (cJSON_GetObjectItem (fn, "name"));
if (name) {
int func_id = s->func_counter++;
cJSON *compiled = mach_gen_function (s, fn);
cJSON_AddItemToArray (s->functions, compiled);
int local_slot = mach_gen_find_var (s, name);
int dest = mach_gen_alloc_slot (s);
mach_gen_emit_2 (s, "mkfunc", dest, func_id);
if (local_slot >= 0) mach_gen_emit_2 (s, "move", local_slot, dest);
}
}
}
/* Generate main code */
cJSON *statements = cJSON_GetObjectItem (ast, "statements");
int last_expr_slot = -1;
@@ -33774,7 +33873,7 @@ static cJSON *mach_gen_program (MachGenState *s, cJSON *ast) {
if (kind) {
if (strcmp (kind, "call") == 0) {
cJSON *expr = cJSON_GetObjectItem (stmt, "expression");
last_expr_slot = mach_gen_expr (s, expr);
last_expr_slot = mach_gen_expr (s, expr, -1);
} else if (strcmp (kind, "return") == 0 || strcmp (kind, "throw") == 0 ||
strcmp (kind, "break") == 0 || strcmp (kind, "continue") == 0) {
mach_gen_statement (s, stmt);
@@ -33787,7 +33886,7 @@ static cJSON *mach_gen_program (MachGenState *s, cJSON *ast) {
mach_gen_statement (s, stmt);
last_expr_slot = -1;
} else {
last_expr_slot = mach_gen_expr (s, stmt);
last_expr_slot = mach_gen_expr (s, stmt, -1);
}
} else {
mach_gen_statement (s, stmt);