The last E4 item: a comptime call-frame dump. - New nullary `interp_print_frames` IR op (inst/print). The interpreter maintains a `call_chain` side-stack (push/pop a FuncId around each sx-bodied `call`, freed in deinit) and `printInterpFrames` appends the chain to its output — most-recent-last, with the dump frame itself skipped. emit_llvm makes the op a no-op: compiled code has no interpreter stack, and the only caller is `process.exit`'s dead `is_comptime()` branch. - Lowered from a name-recognized `__interp_print_frames()` builtin (tryLowerReflectionCall + inferExprType → void). - `trace.print_interpreter_frames()` wraps the builtin; wired into `process.exit`'s comptime branch (process.sx now imports trace.sx). - Frame source locations await IR-offset resolution (the comptime analog of DWARF), so only function names print today. examples/252-interp-frames.sx (top-level `#run` drives the dump; exit 0). Phase E4 (entry-point + stdlib error story) is now 100% complete.
24 lines
769 B
Plaintext
24 lines
769 B
Plaintext
// `trace.print_interpreter_frames()` (ERR step E4.1). At comptime (`#run`) it
|
|
// dumps the interpreter's active sx call-frame chain (most recent call last) to
|
|
// the build output; in compiled code it folds to nothing (no interpreter stack
|
|
// — the only real caller is `process.exit`'s dead `is_comptime()` branch). The
|
|
// dump frame itself is omitted; frame source locations await IR-offset
|
|
// resolution, so only names print today. Expected exit: 0.
|
|
|
|
#import "modules/std.sx";
|
|
trace :: #import "modules/trace.sx";
|
|
|
|
probe :: () {
|
|
trace.print_interpreter_frames(); // dumps the chain: __run_0 → inner → probe
|
|
}
|
|
|
|
inner :: () {
|
|
probe();
|
|
}
|
|
|
|
#run inner(); // top-level #run drives the chain
|
|
|
|
main :: () -> s32 {
|
|
return 0;
|
|
}
|