HGPPascal keeps the language model backend-independent, but each backend has a different standard shape. Debugging, profiling, and SECD support must respect that shape.
HGPFunction, HGPSSTDFrame, and thread-local frame depth.HGPComputeUnary and HGPComputeBinary runtime
helpers, linked into C and native executable output.HGPHeapObject headers, HGPHeapAlloc,
HGPHeapFree, live-count metadata, and pointer-backed aggregate storage.The C backend should stay portable. Debug and profiling features are emitted as plain C structures, comments, or optional generated hooks rather than requiring a non-standard runtime library.
native-m3 for Apple M3/arm64 and native-x86_64 for x86_64.-lm by default.-arch arm64 or -arch x86_64; other
platforms use GCC-oriented defaults such as -march=armv8-a or -m64.The native backends intentionally do not duplicate the C generator. They make the executable build step explicit and preserve the generated C source so users can inspect, debug, profile, or recompile it with their preferred GCC-compatible toolchain.
.class files, currently via Java source lowering.HGPRuntime.LineNumberTable and LocalVariableTable.FunctionValue, SSTDFrame, and SSTD_DUMP.computeUnary and computeBinary
helpers inside HGPRuntime.HEAP table, HeapObject, heap IDs on Ref<T>,
and heap-backed allocate, dispose, and dereference checks.The JVM backend should follow JVM expectations: strongly typed generated Java, clear runtime metadata, and a path toward standard class-file debug tables.
OPT_PASS PEEPHOLE.MAKE_CLOSURE, CAPTURE, APPLY, SSTD_ENTER, SSTD_LEAVE.NUMERIC tags and RUNTIME_BLOCK hgppascal_runtime.HEAP_ALLOC, HEAP_FREE, HEAP_LOAD, HEAP_STORE, and the
HEAP runtime engine entry in RUNTIME_BLOCK hgppascal_runtime.The P-Code backend is the research backend. It can expose compiler-internal concepts directly as uppercase tags, as long as extensions remain explicit and stable.
The shared runtime contract has three linked engines:
SECD: Stack, Environment, Control, and Dump state.SSTD: Stack, Store/Environment, Call, and Dump-style callable invocation.NUMERIC: arithmetic and mathematical compute engine.HEAP: handle-based allocation table for scalar values, records, objects,
arrays, and future aggregate descriptors.Procedure and lambda calls enter a fresh callee frame. The callee stack is empty except for the actual call parameters. When the callable returns, the caller frame is restored from the dump and the return value is pushed onto the caller stack. One-argument application is represented separately so higher-order values can be curried until their arity is satisfied.
C and JVM artifacts link this runtime directly into the generated program.
Native executable targets compile that generated C runtime into the executable.
P-Code artifacts attach the runtime contract through RUNTIME_BLOCK hgppascal_runtime so an executable host can discover and call the runtime
block.
Heap references are represented as runtime handles. A heap object stores its kind, type, value or fields, metadata, and live/free state. Record and object allocations therefore remain visible to profiling, debugging, and future garbage-collection experiments instead of being anonymous host allocations.
Backend optimization is opt-in. Existing compile output remains unchanged until
:backend-optimizations or --backend-optimizations is supplied.
The pass order is fixed:
register-allocationinstruction-schedulingpeepholeThe order is intentionally strict. Register allocation establishes virtual register, local slot, or stack slot pressure before scheduling. Instruction scheduling can then respect calls, I/O, environment switching, and SECD/SSTD barriers. Peephole optimization runs last so it can simplify target artifacts created by both earlier passes.
Callers may enable the whole triple or a subset:
(hgppascal.compiler/compile-source source :pcode {:backend-optimizations true})
(hgppascal.compiler/compile-source source :c {:backend-optimizations {:passes [:register-allocation :peephole]}})
Even when a subset is requested, selected passes are reordered into the
canonical sequence. The public API exposes this through
hgppascal.interface/backend-optimization-order and
backend-optimization-plan.
All backends consume the same resolved AST and descriptor model:
The public API exposes this through hgppascal.interface/backend-capabilities,
backend-standards, backend-optimization-plan, language-profile, and
analyze-source.