Spec (snapshot)
What DEXA actually supports right now
This is a living snapshot of the currently implemented language surface. Future features (tensors, actors, contracts, DX-VM, GPU) are intentionally omitted here until they exist in the compiler.
Types
Primitive types implemented in the typechecker and interpreter:
int— 64-bit signed integer.float— 64-bit floating point.bool—true/false.string— immutable UTF-8 string (interpreter-level only).unit— no value / void, implicit when a function doesn’t declare a return type.
Functions
Declared with fn:
fn add(a: int, b: int) -> int {
return a + b;
}
- Parameters must have explicit types.
- Return type can be omitted; defaults to
unit. - Calls are type-checked for arity and parameter types.
Variables & mutability
fn main() -> int {
let x: int = 1; // immutable
let mut y: int = 2; // mutable
// x = 3; // ❌ compile-time error
y = y + 1; // ✅
return y;
}
letcreates an immutable binding.let mutcreates a mutable binding.- Assignments are checked: you can’t write to non-
mutvariables. - Explicit type annotations are required for now (type inference will be a later feature).
Expressions & operators
Currently implemented expression forms:
- Literals: ints, floats, strings, bools.
- Identifiers referring to local variables or parameters.
- Binary arithmetic:
+ - * /(type-checked numeric operands). - Comparisons:
<, <=, >, >=, ==, !=→bool. - Logical:
&&,||onbool. - Function calls with positional arguments.
fn main() -> bool {
let x: int = 10;
let y: int = 20;
let bigger: int = max(x, y);
return bigger > 15 && bigger < 30;
}
Control flow
Implemented constructs
if/elsewith a boolean condition.- Nested blocks with scoped variables and shadowing.
returnwith or without value.while <cond> { ... }— pre-conditioned loops.loop { ... }— infinite loops controlled withbreak.break— exits the innermostwhile/loop.continue— jumps to the next iteration of the innermost loop.
fn classify(x: int) -> bool {
if x >= 0 && x < 10 {
return true;
} else {
return false;
}
}
fn countdown(start: int) {
let mut x: int = start;
while x > 0 {
x = x - 1;
if x == 2 {
continue;
}
if x == 1 {
break;
}
}
return;
}
Builtins / special forms
The only special-cased function at the typechecker level right now is require:
fn main() {
let x: int = 5;
require(x > 0); // condition must be bool
require(x > 0, "x > 0"); // extra args allowed, unchecked for now
}
- First argument must be
bool, enforced by the typechecker. - Additional arguments are currently ignored by the type system (treated as “any”).
- Semantics are handled by the interpreter runtime (panic / abort).
Execution model (current prototype)
The reference compiler currently targets a simple interpreted IR. Every DEXA program goes through:
- Parse to an AST (functions, blocks,
let/let mut,if/else, expressions). - Typecheck with a small, explicit environment of locals and function signatures.
- Lower to a tiny IR with locals, blocks,
Let,Store,If, andReturn. - Interpret the IR to produce a result (
int,float,bool, orunit).
There is no optimizer, no GPU backend, and no VM yet. This is intentionally minimal — the IR is a place to prove semantics before wiring in more serious backends.
This page tracks the implemented core only. Anything mentioned on the homepage but not listed here (tensors, GPU, actors, contracts, DX-VM) is still in design / prototype.