Merge branch 'newsyn' into mcode2

This commit is contained in:
2026-02-06 03:55:56 -06:00
8 changed files with 1752 additions and 3425 deletions

View File

@@ -552,27 +552,14 @@ int cell_init(int argc, char **argv)
return 1;
}
char *mcode_json = JS_Mcode(ctx, ast_json);
/* --mcode now uses the new compiler and dumps bytecode (same as --mach) */
JS_DumpMach(ctx, ast_json, JS_NULL);
free(ast_json);
if (mcode_json) {
if (print_json_errors(mcode_json)) {
free(mcode_json);
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
free(allocated_script);
return 1;
}
printf("%s\n", mcode_json);
free(mcode_json);
} else {
printf("Failed to generate MCODE\n");
}
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
free(allocated_script);
return mcode_json ? 0 : 1;
return 0;
}
/* Check for --run-mcode flag to execute via MCODE interpreter */

File diff suppressed because it is too large Load Diff

View File

@@ -1226,9 +1226,9 @@ char *JS_AST (JSContext *ctx, const char *source, size_t len, const char *filena
Returns malloc'd JSON string (caller must free), or NULL on error. */
char *JS_Tokenize (JSContext *ctx, const char *source, size_t len, const char *filename);
/* Generate MCODE (JSON IR) from AST JSON.
Returns malloc'd JSON string (caller must free), or NULL on error. */
char *JS_Mcode (JSContext *ctx, const char *ast_json);
/* Compile AST JSON directly to register bytecode.
Returns JSCodeRegister* (caller should not free — managed by context), or NULL on error. */
struct JSCodeRegister *JS_CompileMach(JSContext *ctx, const char *ast_json, JSValue env);
/* Dump MACH bytecode to stdout for debugging. Takes AST JSON.
Internally generates MCODE and links to binary bytecode. */

View File

@@ -2388,102 +2388,26 @@ TEST(ast_sem_nested_function_scope) {
}
/* ============================================================================
CODEGEN/SEMANTIC ERROR TESTS
CODEGEN TESTS (updated for new direct AST-to-bytecode compiler)
============================================================================ */
TEST(mach_assign_to_const) {
const char *src = "def x = 1; x = 2";
char *ast_json = JS_AST(ctx, src, strlen(src), "<test>");
ASSERT_MSG(ast_json != NULL, "JS_AST returned NULL");
char *mach_json = JS_Mcode(ctx, ast_json);
free(ast_json);
ASSERT_MSG(mach_json != NULL, "JS_Mcode returned NULL");
ASSERT_ERROR_MSG_CONTAINS(mach_json, "cannot assign to constant");
free(mach_json);
return 1;
}
TEST(mach_assign_to_arg) {
const char *src = "function f(x) { x = 5 }";
char *ast_json = JS_AST(ctx, src, strlen(src), "<test>");
ASSERT_MSG(ast_json != NULL, "JS_AST returned NULL");
char *mach_json = JS_Mcode(ctx, ast_json);
free(ast_json);
ASSERT_MSG(mach_json != NULL, "JS_Mcode returned NULL");
ASSERT_ERROR_MSG_CONTAINS(mach_json, "cannot assign to function argument");
free(mach_json);
return 1;
}
TEST(mach_redeclare_const) {
const char *src = "def x = 1; def x = 2";
char *ast_json = JS_AST(ctx, src, strlen(src), "<test>");
ASSERT_MSG(ast_json != NULL, "JS_AST returned NULL");
char *mach_json = JS_Mcode(ctx, ast_json);
free(ast_json);
ASSERT_MSG(mach_json != NULL, "JS_Mcode returned NULL");
ASSERT_ERROR_MSG_CONTAINS(mach_json, "cannot redeclare constant");
free(mach_json);
return 1;
}
TEST(mach_break_outside_loop) {
const char *src = "break";
char *ast_json = JS_AST(ctx, src, strlen(src), "<test>");
ASSERT_MSG(ast_json != NULL, "JS_AST returned NULL");
char *mach_json = JS_Mcode(ctx, ast_json);
free(ast_json);
ASSERT_MSG(mach_json != NULL, "JS_Mcode returned NULL");
ASSERT_ERROR_MSG_CONTAINS(mach_json, "outside of loop");
free(mach_json);
return 1;
}
TEST(mach_continue_outside_loop) {
const char *src = "continue";
char *ast_json = JS_AST(ctx, src, strlen(src), "<test>");
ASSERT_MSG(ast_json != NULL, "JS_AST returned NULL");
char *mach_json = JS_Mcode(ctx, ast_json);
free(ast_json);
ASSERT_MSG(mach_json != NULL, "JS_Mcode returned NULL");
ASSERT_ERROR_MSG_CONTAINS(mach_json, "outside of loop");
free(mach_json);
return 1;
}
TEST(mach_assign_unbound_var) {
const char *src = "x = 42";
char *ast_json = JS_AST(ctx, src, strlen(src), "<test>");
ASSERT_MSG(ast_json != NULL, "JS_AST returned NULL");
char *mach_json = JS_Mcode(ctx, ast_json);
free(ast_json);
ASSERT_MSG(mach_json != NULL, "JS_Mcode returned NULL");
ASSERT_ERROR_MSG_CONTAINS(mach_json, "not declared");
free(mach_json);
return 1;
}
TEST(mach_shadow_is_ok) {
const char *src = "var array = []; array";
char *ast_json = JS_AST(ctx, src, strlen(src), "<test>");
ASSERT_MSG(ast_json != NULL, "JS_AST returned NULL");
char *mach_json = JS_Mcode(ctx, ast_json);
free(ast_json);
ASSERT_MSG(mach_json != NULL, "JS_Mcode returned NULL");
ASSERT_NO_ERRORS(mach_json);
free(mach_json);
return 1;
}
TEST(mach_valid_no_errors) {
TEST(mach_compile_basic) {
const char *src = "var x = 1; x = x + 1";
char *ast_json = JS_AST(ctx, src, strlen(src), "<test>");
ASSERT_MSG(ast_json != NULL, "JS_AST returned NULL");
char *mach_json = JS_Mcode(ctx, ast_json);
struct JSCodeRegister *code = JS_CompileMach(ctx, ast_json, JS_NULL);
free(ast_json);
ASSERT_MSG(mach_json != NULL, "JS_Mcode returned NULL");
ASSERT_NO_ERRORS(mach_json);
free(mach_json);
ASSERT_MSG(code != NULL, "JS_CompileMach returned NULL");
return 1;
}
TEST(mach_compile_function) {
const char *src = "function f(x) { return x + 1 }";
char *ast_json = JS_AST(ctx, src, strlen(src), "<test>");
ASSERT_MSG(ast_json != NULL, "JS_AST returned NULL");
struct JSCodeRegister *code = JS_CompileMach(ctx, ast_json, JS_NULL);
free(ast_json);
ASSERT_MSG(code != NULL, "JS_CompileMach returned NULL");
return 1;
}
@@ -2730,15 +2654,9 @@ int run_c_test_suite(JSContext *ctx)
RUN_TEST(ast_sem_var_assign_ok);
RUN_TEST(ast_sem_nested_function_scope);
printf("\nCodegen Errors:\n");
RUN_TEST(mach_assign_to_const);
RUN_TEST(mach_assign_to_arg);
RUN_TEST(mach_redeclare_const);
RUN_TEST(mach_break_outside_loop);
RUN_TEST(mach_continue_outside_loop);
RUN_TEST(mach_assign_unbound_var);
RUN_TEST(mach_shadow_is_ok);
RUN_TEST(mach_valid_no_errors);
printf("\nCodegen:\n");
RUN_TEST(mach_compile_basic);
RUN_TEST(mach_compile_function);
printf("\n=================================\n");
printf("Results: %d passed, %d failed\n", tests_passed, tests_failed);

View File

@@ -1 +0,0 @@
var x = 0; outer: { x = 1; break outer; x = 2 }; x

View File

@@ -1 +0,0 @@
typeof 5

View File

@@ -1 +0,0 @@
var r; switch(2) { case 1: r = 1; break; case 2: r = 2; break }; r

View File

@@ -252,22 +252,6 @@ loop: for (var m = 0; m < 3; m++) {
}
}
// --- switch/case/default ---
var sw
switch (2) {
case 1:
sw = "one"
break
case 2:
sw = "two"
break
case 3:
sw = "three"
break
default:
sw = "other"
}
// --- try/catch/finally ---
var tc
try {