Sigil 0.10.0
Experimental CPS compiler with optimization passes. This release adds a continuation-passing style intermediate representation to the compiler pipeline, sitting between macro expansion and bytecode generation. The CPS path is opt-in and does not change default compiler behavior.
CPS Compiler
Enable with SIGIL_USE_CPS=1. The CPS pipeline converts expanded S-expressions into CPS IR, runs optimization passes, then emits bytecode. All existing tests pass through the CPS path.
New source files:
cps.h-- CPS IR data structures and arena allocatorcps-convert.c-- S-expression to CPS conversioncps-emit.c-- CPS to bytecode emissioncps-opt.c-- optimization pass pipelinecps-dump.c-- CPS IR pretty-printer for debugging
Optimization Passes
Control the optimization level with SIGIL_OPT_LEVEL (0, 1, or 2). Individual passes can be disabled with environment variables.
-O1 (contification + dead code elimination):
- Contification: converts single-call closures in tail position into continuation jumps, eliminating closure allocation. Non-tail contification enabled for pure callees.
- Dead code elimination: removes unreachable continuations via BFS reachability analysis.
-O2 (adds inlining, constant propagation, capture minimization):
- Beta reduction / inlining: inlines small functions (10 or fewer CPS terms, called at most twice) at tail call sites.
- Constant propagation: folds fixnum arithmetic and boolean operations at compile time, eliminates constant branches. Overflow-safe using compiler builtins.
- Capture minimization: removes unused captures from closures after dead code elimination.
Pass ordering: contification, inlining, constant propagation, DCE, capture minimization. At -O2, the pipeline iterates up to 3 times for cascading opportunities.
Debugging
SIGIL_DUMP_CPS=1-- dump CPS IR before optimizationSIGIL_DUMP_CPS_OPT=1-- dump CPS IR after optimization- Individual pass toggles:
SIGIL_CPS_NO_CONTIFY=1,SIGIL_CPS_NO_DCE=1,SIGIL_CPS_NO_INLINE=1,SIGIL_CPS_NO_CONSTPROP=1,SIGIL_CPS_NO_CAPMIN=1
Other Changes
cond-expandimplemented as an expression form in the CPS convertercase-lambdaCPS expansion bypasses hygiene interaction bug in syntax-rules dispatch- Fix
sigil_apply{0,1,2,3}to reserve stack space for locals - Fix module context inheritance for closures created inside
define-librarybody - Fix
make-vectorto use native call instead of primitive opcode makedefault target now builds stdlib (previously requiredmake stdlib)