Commitee8d5818Recorded14 Jan 2026Repositorysigil-app
run: Fix stale compile-time modules blocking bytecode execution
Message
When sigil build compiles a module, the compiler registers it with scheme_loaded=true for compile-time imports, but the bytecode is never executed (only generated). When sigil run later tries to import the module, it finds this stale registration and skips loading the bytecode, resulting in "does not export 'main'" errors.
The fix adds clear-module-cache! which removes a module from the VM's registry. The run-entry function now calls this before importing the entry module, forcing a fresh load from bytecode.
Also cleaned up debug output from investigation and removed unused functions collect_internal_define_names and tag_input_bindings from the compiler.
Changed
packages/sigil-cli/src/sigil/cli.sgl | 6 ++++
packages/sigil-lib/include/sigil/sigil.h | 7 +++++
packages/sigil-lib/src/compiler.c | 239 -------------------------------------------------------------------------------------------------------------------------------------------------------
packages/sigil-lib/src/module.c | 44 ++++++++++++++++++++++------
packages/sigil-lib/src/natives.c | 40 ++++++++++++++++++++------
packages/sigil-lib/src/serializer.c | 16 -----------
packages/sigil-lib/src/vm.c | 68 -------------------------------------------
7 files changed, 79 insertions(+), 341 deletions(-)Diff
packages/sigil-cli/src/sigil/cli.sglmodified
@@ -350,6 +350,12 @@
350
(define (run-entry entry args) 351
;; Import the entry module and call main 352
(let ((module-name entry))+353
;; Clear any stale module registration from compile time.+354
;; During `sigil build`, modules get registered with scheme_loaded=true+355
;; but without executing the bytecode (only compiling it). We need to+356
;; remove that registration so the import will properly load and execute+357
;; the bytecode, which defines the actual bindings including 'main'.+358
(clear-module-cache! module-name) 359
(eval `(import ,module-name)) 360
(let* ((mod (find-module module-name)) 361
(main-proc (and mod (module-ref mod 'main))))packages/sigil-lib/include/sigil/sigil.hmodified
@@ -2090,6 +2090,13 @@ Value sigil_module_lookup_exported_macro(SigilVM *vm, SigilModule *module, Value
2090
*/ 2091
bool sigil_vm_register_module(SigilVM *vm, SigilModule *module); 2092
+2093
/**+2094
* Unregister a module from the VM's module registry.+2095
* This is used when a module is compiled to a file - the module was registered+2096
* at compile time, but should be properly loaded when the bytecode is executed.+2097
*/+2098
void sigil_vm_unregister_module(SigilVM *vm, const char *name);+2099
2100
/** 2101
* Look up a module by its canonical name string. 2102
* Returns the module, or NULL if not found.packages/sigil-lib/src/compiler.cmodified
@@ -475,83 +475,6 @@ static int collect_internal_defines(Value body, LocalScope *scope)
475
return count; 476
} 477
−478
/*−479
* Collect internal define names from a body as a list of symbols.−480
* This is used during library compilation to populate vm->library_pending_locals−481
* BEFORE macro expansion, so that syntax-rules can detect these bindings−482
* for capture even when compiled via sigil_eval_expr.−483
*/−484
static Value collect_internal_define_names(SigilVM *vm, Value body)−485
{−486
Value result = SIGIL_EMPTY;−487
body = unwrap_syntax(body);−488
−489
while (syntax_is_pair(body)) {−490
Value expr = unwrap_syntax(syntax_car(body));−491
if (!syntax_is_pair(expr)) break;−492
−493
Value first = unwrap_syntax(syntax_car(expr));−494
if (!syntax_is_symbol(first)) break;−495
−496
const char *name_str = symbol_name(first);−497
−498
/* Handle begin at start of body - splice its contents */−499
if (strcmp(name_str, "begin") == 0) {−500
/* Recursively collect defines from begin body */−501
Value inner = collect_internal_define_names(vm, syntax_cdr(expr));−502
/* Append inner to result */−503
while (sigil_is_pair(inner)) {−504
result = sigil_cons(vm, sigil_car(inner), result);−505
inner = sigil_cdr(inner);−506
}−507
body = syntax_cdr(body);−508
continue;−509
}−510
−511
/* Skip define-syntax */−512
if (strcmp(name_str, "define-syntax") == 0) {−513
body = syntax_cdr(body);−514
continue;−515
}−516
−517
/* Skip %set-docstring! */−518
if (strcmp(name_str, "%set-docstring!") == 0) {−519
body = syntax_cdr(body);−520
continue;−521
}−522
−523
/* Skip expressions that are not defines */−524
if (strcmp(name_str, "%define") != 0 && strcmp(name_str, "define") != 0) {−525
body = syntax_cdr(body);−526
continue;−527
}−528
−529
/* Found a define - extract the name */−530
Value rest = unwrap_syntax(syntax_cdr(expr));−531
if (!syntax_is_pair(rest)) break;−532
−533
Value target = unwrap_syntax(syntax_car(rest));−534
Value def_name;−535
−536
if (syntax_is_symbol(target)) {−537
/* (define x val) */−538
def_name = target;−539
} else if (syntax_is_pair(target)) {−540
/* (define (f args) body) */−541
def_name = unwrap_syntax(syntax_car(target));−542
if (!syntax_is_symbol(def_name)) break;−543
} else {−544
break;−545
}−546
−547
/* Add to result list */−548
result = sigil_cons(vm, def_name, result);−549
−550
body = syntax_cdr(body);−551
}−552
return result;−553
}−554
478
/* 479
* Global Variable Registry 480
*@@ -3242,168 +3165,6 @@ static Value handle_define_syntax_in_expansion(CompileContext *ctx, Value expr)
3165
return expr; /* Return the form so it's also compiled (as a no-op) */ 3166
} 3167
−3245
/*−3246
* Tag input identifiers with binding context for free-identifier=? comparison.−3247
*−3248
* Before passing an expression to a macro transformer, we tag identifiers−3249
* with their binding context so literal comparison can use free-identifier=?−3250
* semantics. An identifier bound locally gets (local-binding . (scope_id . index)),−3251
* allowing the pattern matcher to distinguish between identifiers with the same−3252
* name but different bindings.−3253
*/−3254
static Value tag_input_bindings(CompileContext *ctx, Value expr)−3255
{−3256
/* Handle syntax objects */−3257
if (sigil_is_syntax(expr)) {−3258
SigilSyntax *stx = (SigilSyntax *)sigil_as_ptr(expr);−3259
Value datum = stx->datum;−3260
−3261
/* If datum is a symbol, check if it's locally bound */−3262
if (sigil_is_symbol(datum)) {−3263
/* Use the full syntax object (with marks) for local resolution */−3264
int local_idx = scope_resolve_local(&ctx->locals, expr);−3265
if (local_idx >= 0) {−3266
/* Found a local binding - tag with local-binding metadata */−3267
bool is_module_level = ctx->is_module_body &&−3268
ctx->locals.locals[local_idx].depth == 0;−3269
if (!is_module_level) {−3270
/* Create (local-binding . (scope_id . local_index)) */−3271
Value scope_id_val = sigil_fixnum((int64_t)ctx->scope_id);−3272
Value idx_val = sigil_fixnum((int64_t)local_idx);−3273
sigil__gc_push_temp_root(ctx->vm, scope_id_val);−3274
sigil__gc_push_temp_root(ctx->vm, idx_val);−3275
−3276
Value binding_info = sigil_cons(ctx->vm, scope_id_val, idx_val);−3277
sigil__gc_push_temp_root(ctx->vm, binding_info);−3278
−3279
Value local_binding_sym = sigil_intern_symbol(ctx->vm, "local-binding", 13);−3280
sigil__gc_push_temp_root(ctx->vm, local_binding_sym);−3281
−3282
Value entry = sigil_cons(ctx->vm, local_binding_sym, binding_info);−3283
sigil__gc_push_temp_root(ctx->vm, entry);−3284
−3285
/* Add to existing substs */−3286
Value new_substs = sigil_cons(ctx->vm, entry, stx->substs);−3287
sigil__gc_push_temp_root(ctx->vm, new_substs);−3288
−3289
/* Create new syntax object with updated substs */−3290
SigilSyntax *new_stx = sigil__gc_alloc(ctx->vm, SIGIL_OBJ_SYNTAX, sizeof(SigilSyntax));−3291
new_stx->datum = datum;−3292
new_stx->srcloc = stx->srcloc;−3293
new_stx->doc = stx->doc;−3294
new_stx->marks = stx->marks;−3295
new_stx->substs = new_substs;−3296
−3297
sigil__gc_pop_temp_root(ctx->vm); /* new_substs */−3298
sigil__gc_pop_temp_root(ctx->vm); /* entry */−3299
sigil__gc_pop_temp_root(ctx->vm); /* local_binding_sym */−3300
sigil__gc_pop_temp_root(ctx->vm); /* binding_info */−3301
sigil__gc_pop_temp_root(ctx->vm); /* idx_val */−3302
sigil__gc_pop_temp_root(ctx->vm); /* scope_id_val */−3303
−3304
return sigil_ptr(new_stx);−3305
}−3306
}−3307
/* Not locally bound - return unchanged */−3308
return expr;−3309
}−3310
−3311
/* If datum is a pair, recursively tag children */−3312
if (sigil_is_pair(datum)) {−3313
Value tagged_datum = tag_input_bindings(ctx, datum);−3314
if (tagged_datum == datum) {−3315
return expr; /* No changes */−3316
}−3317
/* Create new syntax with tagged datum */−3318
sigil__gc_push_temp_root(ctx->vm, tagged_datum);−3319
SigilSyntax *new_stx = sigil__gc_alloc(ctx->vm, SIGIL_OBJ_SYNTAX, sizeof(SigilSyntax));−3320
new_stx->datum = tagged_datum;−3321
new_stx->srcloc = stx->srcloc;−3322
new_stx->doc = stx->doc;−3323
new_stx->marks = stx->marks;−3324
new_stx->substs = stx->substs;−3325
sigil__gc_pop_temp_root(ctx->vm);−3326
return sigil_ptr(new_stx);−3327
}−3328
−3329
/* Other datum types - return unchanged */−3330
return expr;−3331
}−3332
−3333
/* Handle bare symbols (not wrapped in syntax) */−3334
if (sigil_is_symbol(expr)) {−3335
int local_idx = scope_resolve_local(&ctx->locals, expr);−3336
if (local_idx >= 0) {−3337
bool is_module_level = ctx->is_module_body &&−3338
ctx->locals.locals[local_idx].depth == 0;−3339
if (!is_module_level) {−3340
/* Wrap in syntax with local-binding metadata */−3341
Value scope_id_val = sigil_fixnum((int64_t)ctx->scope_id);−3342
Value idx_val = sigil_fixnum((int64_t)local_idx);−3343
sigil__gc_push_temp_root(ctx->vm, scope_id_val);−3344
sigil__gc_push_temp_root(ctx->vm, idx_val);−3345
−3346
Value binding_info = sigil_cons(ctx->vm, scope_id_val, idx_val);−3347
sigil__gc_push_temp_root(ctx->vm, binding_info);−3348
−3349
Value local_binding_sym = sigil_intern_symbol(ctx->vm, "local-binding", 13);−3350
sigil__gc_push_temp_root(ctx->vm, local_binding_sym);−3351
−3352
Value entry = sigil_cons(ctx->vm, local_binding_sym, binding_info);−3353
sigil__gc_push_temp_root(ctx->vm, entry);−3354
−3355
Value substs = sigil_cons(ctx->vm, entry, SIGIL_EMPTY);−3356
sigil__gc_push_temp_root(ctx->vm, substs);−3357
−3358
SigilSyntax *new_stx = sigil__gc_alloc(ctx->vm, SIGIL_OBJ_SYNTAX, sizeof(SigilSyntax));−3359
new_stx->datum = expr;−3360
new_stx->srcloc = SIGIL_FALSE;−3361
new_stx->doc = SIGIL_FALSE;−3362
new_stx->marks = SIGIL_EMPTY;−3363
new_stx->substs = substs;−3364
−3365
sigil__gc_pop_temp_root(ctx->vm); /* substs */−3366
sigil__gc_pop_temp_root(ctx->vm); /* entry */−3367
sigil__gc_pop_temp_root(ctx->vm); /* local_binding_sym */−3368
sigil__gc_pop_temp_root(ctx->vm); /* binding_info */−3369
sigil__gc_pop_temp_root(ctx->vm); /* idx_val */−3370
sigil__gc_pop_temp_root(ctx->vm); /* scope_id_val */−3371
−3372
return sigil_ptr(new_stx);−3373
}−3374
}−3375
return expr;−3376
}−3377
−3378
/* Handle pairs - recursively tag car and cdr */−3379
if (sigil_is_pair(expr)) {−3380
Value car = sigil_car(expr);−3381
Value cdr = sigil_cdr(expr);−3382
−3383
sigil__gc_push_temp_root(ctx->vm, cdr);−3384
Value tagged_car = tag_input_bindings(ctx, car);−3385
sigil__gc_pop_temp_root(ctx->vm);−3386
−3387
sigil__gc_push_temp_root(ctx->vm, tagged_car);−3388
Value tagged_cdr = tag_input_bindings(ctx, cdr);−3389
sigil__gc_pop_temp_root(ctx->vm);−3390
−3391
if (tagged_car == car && tagged_cdr == cdr) {−3392
return expr; /* No changes */−3393
}−3394
−3395
sigil__gc_push_temp_root(ctx->vm, tagged_car);−3396
sigil__gc_push_temp_root(ctx->vm, tagged_cdr);−3397
Value result = sigil_cons(ctx->vm, tagged_car, tagged_cdr);−3398
sigil__gc_pop_temp_root(ctx->vm);−3399
sigil__gc_pop_temp_root(ctx->vm);−3400
return result;−3401
}−3402
−3403
/* Other types (vectors, etc.) - return unchanged */−3404
return expr;−3405
}−3406
3168
/* 3169
* Macro Expansion 3170
*packages/sigil-lib/src/module.cmodified
@@ -440,6 +440,33 @@ bool sigil_vm_register_module(SigilVM *vm, SigilModule *module)
440
return true; 441
} 442
+443
/*+444
* Unregister a module from the VM's module registry.+445
* This is used when a module is compiled to a file - the module was registered+446
* at compile time, but should be properly loaded when the bytecode is executed.+447
*/+448
void sigil_vm_unregister_module(SigilVM *vm, const char *name)+449
{+450
if (!vm || !name) return;+451
+452
for (int i = 0; i < vm->module_count; i++) {+453
if (vm->modules[i] && strcmp(vm->modules[i]->name, name) == 0) {+454
if (getenv("SIGIL_DEBUG_LOAD")) {+455
fprintf(stderr, "[unregister-module] Removing: %s (index=%d, count=%d -> %d)\n",+456
name, i, vm->module_count, vm->module_count - 1);+457
fflush(stderr);+458
}+459
/* Shift remaining modules down */+460
for (int j = i; j < vm->module_count - 1; j++) {+461
vm->modules[j] = vm->modules[j + 1];+462
}+463
vm->modules[vm->module_count - 1] = NULL;+464
vm->module_count--;+465
return;+466
}+467
}+468
}+469
470
/* 471
* Look up a module by its canonical name string. 472
*/@@ -609,14 +636,11 @@ static char *find_library_file(SigilVM *vm, Value name_list, LibFileType *file_t
636
} 637
638
/* Debug: show what we're looking for */−612
const char *debug_env = getenv("SIGIL_DEBUG");−613
int debug = debug_env && debug_env[0] == '1';+639
const char *debug_env = getenv("SIGIL_DEBUG_LOAD");+640
int debug = debug_env && debug_env[0] != '\0'; 641
if (debug) {−615
fprintf(stderr, "[DEBUG] find_library_file: looking for '%s'\n", base_path);−616
fprintf(stderr, "[DEBUG] load_path_count = %d\n", vm->load_path_count);−617
for (int i = 0; i < vm->load_path_count; i++) {−618
fprintf(stderr, "[DEBUG] load_path[%d] = '%s'\n", i, vm->load_paths[i]);−619
}+642
fprintf(stderr, "[find-lib] Looking for: %s\n", base_path);+643
fflush(stderr); 644
} 645
646
size_t base_len = strlen(base_path);@@ -642,7 +666,8 @@ static char *find_library_file(SigilVM *vm, Value name_list, LibFileType *file_t
666
/* Check if file exists (handles both filesystem and VFS) */ 667
if (lib_file_exists(full_path)) { 668
if (debug) {−645
fprintf(stderr, "[DEBUG] FOUND: '%s' (type=%d)\n", full_path, types[ext]);+669
fprintf(stderr, "[find-lib] Found: %s\n", full_path);+670
fflush(stderr); 671
} 672
free(base_path); 673
*file_type = types[ext];@@ -653,7 +678,8 @@ static char *find_library_file(SigilVM *vm, Value name_list, LibFileType *file_t
678
} 679
680
if (debug) {−656
fprintf(stderr, "[DEBUG] NOT FOUND: '%s'\n", base_path);+681
fprintf(stderr, "[find-lib] Not found: %s\n", base_path);+682
fflush(stderr); 683
} 684
free(base_path); 685
*file_type = LIB_FILE_NONE;packages/sigil-lib/src/natives.cmodified
@@ -3062,6 +3062,35 @@ static Value native_find_module(SigilVM *vm, int argc, Value *args)
3062
return sigil_ptr(module); 3063
} 3064
+3065
/* (clear-module-cache! name-list) -> void+3066
* Remove a module from the VM's registry, forcing it to be reloaded from+3067
* bytecode the next time it's imported. This is useful after compilation+3068
* when the in-memory module from compile time needs to be replaced with+3069
* a properly loaded version.+3070
*/+3071
static Value native_clear_module_cache(SigilVM *vm, int argc, Value *args)+3072
{+3073
(void)argc; /* Known to be 1 */+3074
Value name_list = args[0];+3075
+3076
if (!sigil_is_list(name_list)) {+3077
sigil__vm_error(vm, SIGIL_ERR_TYPE, "clear-module-cache!: expected list of symbols");+3078
return SIGIL_UNDEFINED;+3079
}+3080
+3081
/* Convert name list to string for lookup */+3082
char *name_str = sigil_module_name_to_string(name_list);+3083
if (!name_str) {+3084
return SIGIL_UNDEFINED;+3085
}+3086
+3087
/* Unregister the module if it exists */+3088
sigil_vm_unregister_module(vm, name_str);+3089
free(name_str);+3090
+3091
return SIGIL_UNDEFINED;+3092
}+3093
3094
/* (module-exports module) -> list of symbols 3095
* Get list of exported symbols from a module 3096
*/@@ -3236,17 +3265,8 @@ static Value native_hygiene_ref(SigilVM *vm, int argc, Value *args)
3265
return SIGIL_UNDEFINED; 3266
} 3267
−3239
if (getenv("SIGIL_DEBUG_HYGIENE")) {−3240
fprintf(stderr, "[DEBUG hygiene-ref] Looking up '%s' in module '%s'\n",−3241
sigil_symbol_name(sym), module->name);−3242
}−3243
3268
/* Look up binding in the module (including imports) */ 3269
Value cell = sigil_module_lookup(module, sym);−3246
if (getenv("SIGIL_DEBUG_HYGIENE")) {−3247
fprintf(stderr, "[DEBUG hygiene-ref] cell result: is_undefined=%d is_upvalue_cell=%d\n",−3248
sigil_is_undefined(cell), sigil_is_upvalue_cell(cell));−3249
} 3270
if (cell != SIGIL_UNDEFINED && sigil_is_upvalue_cell(cell)) { 3271
return ((SigilUpvalueCell *)sigil_as_ptr(cell))->value; 3272
}@@ -5226,6 +5246,8 @@ void sigil__init_natives(SigilVM *vm)
5246
SIGIL_ARITY_RANGE(1, 2), "Disassemble procedure bytecode"); 5247
sigil_register_builtin(vm, "find-module", native_find_module, 5248
SIGIL_ARITY_EXACT(1), "Find loaded module by name list");+5249
sigil_register_builtin(vm, "clear-module-cache!", native_clear_module_cache,+5250
SIGIL_ARITY_EXACT(1), "Clear module from cache to force reload"); 5251
sigil_register_builtin(vm, "load-module", native_load_module, 5252
SIGIL_ARITY_EXACT(1), "Load module by name list"); 5253
sigil_register_builtin(vm, "module-exists?", native_module_exists,packages/sigil-lib/src/serializer.cmodified
@@ -1313,30 +1313,18 @@ bool sigil_load_bytecode_file(SigilVM *vm, const char *path)
1313
* inherit the correct module context from frame->module. */ 1314
SigilModule *target_module = NULL; 1315
−1316
const char *debug_env = getenv("SIGIL_DEBUG");−1317
int debug = debug_env && debug_env[0] == '1';−1318
1316
if (sigil_is_pair(module_name)) { 1317
/* Convert module name to string for lookup */ 1318
char *name_str = sigil_module_name_to_string(module_name); 1319
if (name_str) {−1323
if (debug) {−1324
fprintf(stderr, "[DEBUG] sigil_load_bytecode_file: module_name='%s'\n", name_str);−1325
} 1320
/* Check if module already exists (e.g., native module) */ 1321
target_module = sigil_vm_find_module(vm, name_str);−1328
if (debug) {−1329
fprintf(stderr, "[DEBUG] find_module returned: %p\n", (void*)target_module);−1330
} 1322
if (!target_module) { 1323
/* Create new module - module_name must stay rooted for this call */ 1324
Value module_val = sigil_module_create(vm, module_name); 1325
if (sigil_is_module(module_val)) { 1326
target_module = (SigilModule *)sigil_as_ptr(module_val); 1327
sigil_vm_register_module(vm, target_module);−1337
if (debug) {−1338
fprintf(stderr, "[DEBUG] created and registered new module: %p\n", (void*)target_module);−1339
} 1328
} 1329
} 1330
free(name_str);@@ -1345,10 +1333,6 @@ bool sigil_load_bytecode_file(SigilVM *vm, const char *path)
1333
/* No module name in bytecode - use vm->current_module as fallback. 1334
* This is set by load_scheme_portion before calling us. */ 1335
target_module = vm->current_module;−1348
if (debug) {−1349
fprintf(stderr, "[DEBUG] sigil_load_bytecode_file: no module name, using current_module=%p ('%s')\n",−1350
(void*)target_module, target_module ? target_module->name : "?");−1351
} 1336
} 1337
1338
/* Set the module on the main closure before execution */packages/sigil-lib/src/vm.cmodified
@@ -972,32 +972,6 @@ static Value sigil__vm_run(SigilVM *vm)
972
} 973
if (val == SIGIL_UNDEFINED) { 974
const char *name = sigil_symbol_name(name_sym);−975
const char *debug_env = getenv("SIGIL_DEBUG");−976
if (debug_env && debug_env[0] == '1') {−977
fprintf(stderr, "[DEBUG] UNBOUND '%s': frame->module=%p ('%s'), vm->current_module=%p ('%s')\n",−978
name ? name : "?",−979
(void*)frame->module, frame->module && frame->module->name ? frame->module->name : "?",−980
(void*)vm->current_module, vm->current_module && vm->current_module->name ? vm->current_module->name : "?");−981
if (lookup_module) {−982
fprintf(stderr, "[DEBUG] lookup_module name='%s', binding_count=%d\n",−983
lookup_module->name ? lookup_module->name : "?", lookup_module->binding_count);−984
} else {−985
fprintf(stderr, "[DEBUG] lookup_module=NULL\n");−986
}−987
/* Print current frame's closure info */−988
if (frame->closure) {−989
const char *closure_name = "<anon>";−990
if (frame->closure->code && sigil_is_symbol(frame->closure->code->name)) {−991
closure_name = sigil_symbol_name(frame->closure->code->name);−992
}−993
fprintf(stderr, "[DEBUG] closure: '%s', closure->module=%p",−994
closure_name, (void*)frame->closure->module);−995
if (frame->closure->module) {−996
fprintf(stderr, " ('%s')", frame->closure->module->name ? frame->closure->module->name : "?");−997
}−998
fprintf(stderr, "\n");−999
}−1000
} 975
sigil__vm_error(vm, SIGIL_ERR_UNBOUND, 976
"unbound variable '%s'", name ? name : "?"); 977
return SIGIL_UNDEFINED;@@ -1099,12 +1073,6 @@ static Value sigil__vm_run(SigilVM *vm)
1073
if (vm->current_module) { 1074
SigilModule *mod = vm->current_module; 1075
SigilSymbol *sym = (SigilSymbol *)sigil_as_ptr(name_sym);−1102
const char *debug_env = getenv("SIGIL_DEBUG_MACROS");−1103
if (debug_env && debug_env[0] == '1') {−1104
fprintf(stderr, "[DEBUG] OP_DEFINE_SYNTAX: '%s' in module '%s', export_count=%d\n",−1105
sym->name, mod->name ? mod->name : "?", mod->export_count);−1106
}−1107
bool found_in_exports = false; 1076
for (int i = 0; i < mod->export_count; i++) { 1077
if (mod->exports[i].internal_name != SIGIL_UNDEFINED) { 1078
SigilSymbol *exp = (SigilSymbol *)sigil_as_ptr(mod->exports[i].internal_name);@@ -1112,18 +1080,11 @@ static Value sigil__vm_run(SigilVM *vm)
1080
exp->length == sym->length && 1081
memcmp(exp->name, sym->name, sym->length) == 0) { 1082
/* Macro is in export list - mark as exported */−1115
found_in_exports = true;−1116
if (debug_env && debug_env[0] == '1') {−1117
fprintf(stderr, "[DEBUG] Found '%s' in export list, calling export_macro\n", sym->name);−1118
} 1083
sigil_module_export_macro(mod, name_sym); 1084
break; 1085
} 1086
} 1087
}−1124
if (debug_env && debug_env[0] == '1' && !found_in_exports) {−1125
fprintf(stderr, "[DEBUG] '%s' NOT in export list\n", sym->name);−1126
} 1088
} 1089
1090
/* Macros are stored in the module's macro table via sigil_register_macro above.@@ -1374,25 +1335,6 @@ static Value sigil__vm_run(SigilVM *vm)
1335
frame->closure = closure; 1336
frame->module = closure->module; 1337
frame->ip = callee_code->code;−1377
−1378
/* Debug: trace closure->module when calling pattern-related functions */−1379
{−1380
const char *debug_env = getenv("SIGIL_DEBUG");−1381
if (debug_env && debug_env[0] == '1' && callee_code && sigil_is_symbol(callee_code->name)) {−1382
const char *name = sigil_symbol_name(callee_code->name);−1383
if (name && (strcmp(name, "pattern-variable?") == 0 ||−1384
strcmp(name, "pattern-match") == 0 ||−1385
strcmp(name, "pm-match") == 0 ||−1386
strcmp(name, "make-syntax-rules-transformer") == 0)) {−1387
fprintf(stderr, "[DEBUG] Calling %s: closure=%p, closure->module=%p",−1388
name, (void*)closure, (void*)closure->module);−1389
if (closure->module) {−1390
fprintf(stderr, " ('%s')", closure->module->name ? closure->module->name : "?");−1391
}−1392
fprintf(stderr, "\n");−1393
}−1394
}−1395
} 1338
frame->bp = new_bp; 1339
frame->srcloc = vm->current_srcloc; 1340
@@ -3044,16 +2986,6 @@ static Value sigil__vm_run(SigilVM *vm)
2986
Value external_name = pop(vm); 2987
Value module_val = pop(vm); 2988
−3047
const char *debug_env = getenv("SIGIL_DEBUG_MACROS");−3048
if (debug_env && debug_env[0] == '1' && sigil_is_symbol(external_name) && sigil_is_module(module_val)) {−3049
SigilSymbol *sym = (SigilSymbol *)sigil_as_ptr(external_name);−3050
SigilModule *m = (SigilModule *)sigil_as_ptr(module_val);−3051
if (m->name && strstr(m->name, "request")) {−3052
fprintf(stderr, "[DEBUG] OP_MODULE_EXPORT: '%s' to module '%s'\n",−3053
sym->name, m->name);−3054
}−3055
}−3056
2989
if (!sigil_is_module(module_val)) { 2990
sigil__vm_error(vm, SIGIL_ERR_TYPE, 2991
"module-export: expected module");