I posted about
SedaiBasic in this forum (
https://forum.lazarus.freepascal.org/index.php/topic,72593.msg568516.html) some time ago.
Enough has changed since then that a new thread makes more sense than reviving the old one.
What's new, in short: the interpreter is no longer the only execution mode. There is now a full compilation pipeline, lexer -> parser -> AST -> SSA intermediate representation -> optimization passes (GVN, LICM, algebraic simplification, register allocation via backward dataflow liveness) -> register-based bytecode, and two native backends emitting x86-64 directly with no external assembler or linker. AOT compiles the whole program at load; the JIT compiles loop regions. They can be combined.
The code generator uses typed register banks (int/float/string) resolved statically in SSA, so there is no tagging, boxing or runtime type checking in the hot path. Machine registers are allocated over GPR r9-r15 and xmm2-7.
Where that lands, n-body from the Computer Language Benchmarks Game, 1M iterations, on an old i7-3630QM: bytecode interpreter 9.8s, AOT 0.86s, JIT 0.80s, AOT+JIT 0.77s. CPython 3.14 runs the same program in 16.8s. FreeBASIC -O2 is 0.196s for execution alone and 0.466s including its compilation step; compared over the full pipeline, which is the fair comparison since SedaiBasic compiles at load, the gap is currently under 2x.
Language coverage has also moved: roughly 90% compatibility with BASIC v7, 84% with the FreeBASIC dialect. The graphical console now abstracts over SDL2 (including KMSDRM) and there's a clean-room SID emulator verified against VICE-generated reference audio.
Two FPC-specific findings from the recent work, which may be more useful here than the benchmark table:
Managed types in hot recursive functions are brutal. My SSA value record carried three string fields, and the code generation entry point had several dozen locals. FPC's prologue/epilogue zeroing and RTTI finalization came to roughly 24 µs per call against 0.25 µs of actual work in the function body. Two orders of magnitude of pure frame overhead, invisible to any reasoning about the algorithm, found only by bisection profiling. A fast path with no managed locals cut SSA generation from 16.1ms to 5.2ms on a const-heavy module.
On the other side, the strictness of the type system caught a class of IR construction errors at compile time that would have been silent memory corruption elsewhere. Writing a compiler backend in Pascal turned out to be considerably more comfortable than I expected.
Questions welcome on any part of it, particularly the SSA lowering and register allocation, which is where most of the work went.
Released under GNU GPL v3.
Develop branch:
https://github.com/camauri/SedaiBasic2/tree/develop