fix errors with mcode
This commit is contained in:
@@ -296,7 +296,7 @@ static void print_usage(const char *prog)
|
||||
printf(" --ast <code|file> Output AST as JSON\n");
|
||||
printf(" --tokenize <code|file> Output token array as JSON\n");
|
||||
printf(" --mcode <script> [args] Run through mcode compilation pipeline\n");
|
||||
printf(" --run-mcode <code|file> Compile and run through MCODE interpreter\n");
|
||||
printf(" --mcode-print <code|file> Compile to MCODE JSON and print it\n");
|
||||
printf(" --mach <code|file> Output MACH bytecode\n");
|
||||
printf(" --mach-run <code|file> Compile and run through MACH VM\n");
|
||||
printf(" --test [heap_size] Run C test suite\n");
|
||||
@@ -420,70 +420,69 @@ int cell_init(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for --run-mcode flag to execute via MCODE interpreter */
|
||||
if (argc >= 3 && strcmp(argv[1], "--run-mcode") == 0) {
|
||||
const char *filename = argv[2];
|
||||
if (!find_cell_shop()) return 1;
|
||||
/* Check for --mcode-print flag to compile a script to MCODE JSON and print it */
|
||||
if (argc >= 3 && strcmp(argv[1], "--mcode-print") == 0) {
|
||||
const char *script_or_file = argv[2];
|
||||
char *script = NULL;
|
||||
char *allocated_script = NULL;
|
||||
const char *filename = "<eval>";
|
||||
|
||||
size_t boot_size;
|
||||
char *boot_data = load_core_file("internal/bootstrap.cm", &boot_size);
|
||||
if (!boot_data) {
|
||||
printf("ERROR: Could not load internal/bootstrap.cm from %s\n", core_path);
|
||||
struct stat st;
|
||||
if (stat(script_or_file, &st) == 0 && S_ISREG(st.st_mode)) {
|
||||
FILE *f = fopen(script_or_file, "r");
|
||||
if (!f) {
|
||||
printf("Failed to open file: %s\n", script_or_file);
|
||||
return 1;
|
||||
}
|
||||
allocated_script = malloc(st.st_size + 1);
|
||||
if (!allocated_script) {
|
||||
fclose(f);
|
||||
printf("Failed to allocate memory for script\n");
|
||||
return 1;
|
||||
}
|
||||
size_t read_size = fread(allocated_script, 1, st.st_size, f);
|
||||
fclose(f);
|
||||
allocated_script[read_size] = '\0';
|
||||
script = allocated_script;
|
||||
filename = script_or_file;
|
||||
} else {
|
||||
script = (char *)script_or_file;
|
||||
}
|
||||
|
||||
cJSON *ast = JS_ASTTree(script, strlen(script), filename);
|
||||
if (!ast) {
|
||||
printf("Failed to parse AST\n");
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
cJSON *boot_ast = JS_ASTTree(boot_data, boot_size, "internal/bootstrap.cm");
|
||||
free(boot_data);
|
||||
if (!boot_ast) {
|
||||
printf("Failed to parse internal/bootstrap.cm\n");
|
||||
if (print_tree_errors(ast)) {
|
||||
cJSON_Delete(ast);
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (print_tree_errors(boot_ast)) {
|
||||
cJSON_Delete(boot_ast);
|
||||
return 1;
|
||||
}
|
||||
|
||||
cJSON *mcode = JS_McodeTree(boot_ast);
|
||||
cJSON_Delete(boot_ast);
|
||||
cJSON *mcode = JS_McodeTree(ast);
|
||||
cJSON_Delete(ast);
|
||||
|
||||
if (!mcode) {
|
||||
printf("Failed to generate MCODE\n");
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (print_tree_errors(mcode)) {
|
||||
cJSON_Delete(mcode);
|
||||
free(allocated_script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
JSRuntime *rt = JS_NewRuntime();
|
||||
if (!rt) { printf("Failed to create JS runtime\n"); cJSON_Delete(mcode); return 1; }
|
||||
JSContext *ctx = JS_NewContextWithHeapSize(rt, 256 * 1024);
|
||||
if (!ctx) { printf("Failed to create execution context\n"); cJSON_Delete(mcode); JS_FreeRuntime(rt); return 1; }
|
||||
|
||||
JS_FreeValue(ctx, js_blob_use(ctx));
|
||||
|
||||
JSValue hidden_env = JS_NewObject(ctx);
|
||||
JS_SetPropertyStr(ctx, hidden_env, "os", js_os_use(ctx));
|
||||
JS_SetPropertyStr(ctx, hidden_env, "program", JS_NewString(ctx, filename));
|
||||
hidden_env = JS_Stone(ctx, hidden_env);
|
||||
|
||||
JSValue result = JS_CallMcodeTreeEnv(ctx, mcode, hidden_env);
|
||||
|
||||
int exit_code = 0;
|
||||
if (JS_IsException(result)) {
|
||||
/* Error already printed to stderr by JS_Throw* */
|
||||
JS_GetException(ctx);
|
||||
exit_code = 1;
|
||||
} else if (!JS_IsNull(result)) {
|
||||
const char *str = JS_ToCString(ctx, result);
|
||||
if (str) { printf("%s\n", str); JS_FreeCString(ctx, str); }
|
||||
}
|
||||
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
return exit_code;
|
||||
char *pretty = cJSON_Print(mcode);
|
||||
cJSON_Delete(mcode);
|
||||
printf("%s\n", pretty);
|
||||
free(pretty);
|
||||
free(allocated_script);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check for --mach flag to dump MACH bytecode */
|
||||
|
||||
@@ -10505,7 +10505,7 @@ static JSValue js_mcode_run (JSContext *ctx, JSValue this_val, int argc, JSValue
|
||||
|
||||
JSValue env = (argc >= 3 && JS_IsObject (argv[2])) ? argv[2] : JS_NULL;
|
||||
JSValue result = JS_CallMcodeTreeEnv (ctx, mcode, env);
|
||||
cJSON_Delete (mcode);
|
||||
/* mcode tree ownership transferred to JS_CallMcodeTreeEnv — do not free */
|
||||
JS_FreeCString (ctx, name);
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user