use new parser info
This commit is contained in:
237
source/quickjs.c
237
source/quickjs.c
@@ -30727,7 +30727,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;
|
||||
|
||||
/* ---- Compiler state ---- */
|
||||
@@ -30871,6 +30872,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 */
|
||||
@@ -32466,13 +32468,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) {
|
||||
@@ -32493,6 +32529,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 */
|
||||
@@ -32545,6 +32582,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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32745,11 +32784,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);
|
||||
@@ -32758,11 +32797,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);
|
||||
@@ -32771,19 +32810,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);
|
||||
@@ -32815,7 +32854,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) {
|
||||
@@ -32837,10 +32876,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);
|
||||
@@ -32848,11 +32887,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);
|
||||
@@ -32879,7 +32918,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) {
|
||||
@@ -32900,13 +32939,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;
|
||||
@@ -32914,36 +32953,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;
|
||||
}
|
||||
@@ -32967,7 +33006,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"));
|
||||
@@ -32981,7 +33022,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;
|
||||
@@ -32991,8 +33032,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;
|
||||
@@ -33005,7 +33046,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"));
|
||||
@@ -33013,10 +33054,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);
|
||||
@@ -33026,28 +33067,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 */
|
||||
@@ -33095,7 +33136,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);
|
||||
@@ -33105,8 +33146,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);
|
||||
@@ -33124,7 +33165,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));
|
||||
@@ -33134,8 +33175,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);
|
||||
@@ -33150,14 +33191,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);
|
||||
@@ -33172,7 +33213,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);
|
||||
@@ -33202,7 +33243,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"));
|
||||
@@ -33211,7 +33252,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);
|
||||
}
|
||||
}
|
||||
@@ -33261,8 +33302,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);
|
||||
@@ -33283,7 +33324,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); }
|
||||
@@ -33308,7 +33349,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); }
|
||||
@@ -33335,7 +33376,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;
|
||||
@@ -33363,17 +33404,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;
|
||||
@@ -33387,7 +33428,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");
|
||||
@@ -33405,17 +33446,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);
|
||||
@@ -33424,7 +33465,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;
|
||||
}
|
||||
@@ -33444,7 +33485,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;
|
||||
@@ -33457,7 +33498,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);
|
||||
@@ -33541,11 +33582,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) {
|
||||
@@ -33600,12 +33641,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) {
|
||||
@@ -33664,12 +33734,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;
|
||||
@@ -33679,7 +33778,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);
|
||||
@@ -33692,7 +33791,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);
|
||||
|
||||
Reference in New Issue
Block a user