An object-oriented language with a hand-written compiler and a bytecode VM.
Khudra expands on OOP in three directions:
- Full OOP -- classes, fields, methods, constructors, vtable dispatch.
- Memory management chosen through an object -- a class picks garbage
collection or manual allocation with a
MemoryAllocationTypeObjectfield, and an allocation site can override it. - Procedures -- a named block in a class body that runs the moment an instance is loaded into memory, instead of waiting to be called.
bring khu::stdlib;
public class Session {
public MemoryAllocationTypeObject type = MemoryAllocationTypeObject.setStandard();
public int32 id = 0;
// Runs during materialization, before the constructor body and before the
// allocation site resumes.
private Procedures(int32 handle) {
io.print("session ");
io.print(handle);
io.printLine(" loaded");
}
public Session(int32 handle) {
this.id = handle;
}
func main() {
Session s = Session(7);
io.printLine(s.id);
}
}
cmake -S . -B build
cmake --build build
ctest --test-dir build
Add -DKHU_SANITIZE=ON to build the whole tree under AddressSanitizer and
UndefinedBehaviorSanitizer.
khudra check file.khu parse and typecheck
khudra run file.khu compile in memory and execute
khudra compile file.khu write a .kbc bytecode image
khudra disasm file.khu print a bytecode listing
khudra run file.kbc execute a compiled image
--dump-tokens and --dump-ast print the intermediate forms.
The same program can run without an interpreter at all. --native compiles the
image to native code and runs it against raw memory; build writes a
standalone executable that needs neither khudra nor a VM to run.
khudra run --native file.khu compile to native code and run it in process
khudra build file.khu -o prog write a standalone native executable
khudra build file.kbc a compiled image works too
khudra build file.khu --keep-c keep the intermediate C beside the binary
Both need a host C compiler. run --native falls back to the bytecode VM with
a printed notice when there is none; build reports it, since producing a
native binary is the whole request.
Output does not depend on which path you take: stdout, stderr and exit codes are
byte-identical across the VM and both native modes, and ctest checks that for
every program in examples/ and tests/integration/. See
docs/native.md.
| Path | What is there |
|---|---|
src/lib/ |
the compiler: diagnostics, lexer, parser, sema, codegen, bytecode |
src/vm/ |
the VM: interpreter, object model, collector, manual arenas |
src/native/ |
the native backend: the C emitter and the host it runs against |
utils/ |
the C runtime: the Procedure engine, manual allocation, bool support |
lib/ |
the standard library, written in Khudra and embedded in the binary |
examples/ |
sample programs |
tests/ |
unit tests and golden-file integration tests |
docs/ |
the specification, memory model, Procedures and bytecode formats |
KHU-PLAN.md-- the design decisions and the implementation plandocs/spec.md-- the languagedocs/memory-model.md-- strategies, pinning, the collectordocs/procedures.md-- the materialization pipelinedocs/bytecode.md-- the instruction set and the.kbcformatdocs/native.md-- the native backend:--native,build, safepoints
