Section 23: Full Evaluator Support
Goal: Complete evaluator support for entire Ori spec semantics (parsing assumed working — see Section 0)
SPEC:
spec/grammar.ebnf(authoritative),spec/08-types.md,spec/14-expressions.md,spec/09-properties-of-types.md
Status: In Progress — Most features work! 1983 tests pass, 31 skipped. Only a few actual bugs remain (verified 2026-02-04).
OVERVIEW
This section ensures the evaluator (interpreter) correctly implements all Ori language semantics. It assumes the parser works correctly (Section 0). The evaluator is in compiler/ori_eval/.
Why this matters: The evaluator is the reference implementation for Ori semantics. It must correctly implement every language feature before LLVM codegen can be validated against it.
Approach:
- Audit current evaluator against spec semantics
- Implement missing features
- Fix incorrect behaviors
- Validate with spec tests
23.1 Operators
SPEC:
spec/14-expressions.md§ Operators
23.1.1 Null Coalesce Operator (??)
Test Status:
STATUS: Lexer [OK], Parser [OK], Evaluator [PARTIAL]intests/spec/expressions/coalesce.oriProgress: 26/31 tests pass. Remaining 5 failures: 3 chaining tests (need type info), 2 map tests (separate bug).
- Implement:
??operator evaluation — 26/31 tests pass- Location:
ori_eval/src/interpreter/mod.rs— added short-circuit logic ineval_binary - Semantics:
Option<T> ?? T -> T— return inner value if Some, else right operand - Semantics:
Result<T, E> ?? T -> T— return inner value if Ok, else right operand - Short-circuit: Right operand is NOT evaluated if left is Some/Ok
- Known Limitation: Chaining (
a ?? b ?? c) with Option variables fails without type info- Workaround: Use explicit
.unwrap_or()or.or()methods for chaining
- Workaround: Use explicit
- Depends On: Map lookup returning
Option<V>(Section 23.3.1) for map tests to pass - Ori Tests:
tests/spec/expressions/coalesce.ori
- Location:
23.1.2 Comparison Operators for Option/Result
- Implement:
<,<=,>,>=for Option types- Spec:
None < Some(x)for all x — Works correctly - Verified:
let a: Option<int> = None; let b = Some(1); assert(eq: a < b)passes - Ori Tests:
tests/spec/expressions/operators_comparison.ori
- Spec:
23.1.3 Struct Equality with #derive(Eq)
- Fix: Equality operators for derived structs
- Verified:
#derive(Eq) type Point = { x: int, y: int }withp1 == p2works - Ori Tests:
tests/spec/expressions/operators_comparison.ori
- Verified:
23.1.4 Shift Overflow Behavior
- Fix: Left shift overflow should panic
- Spec:
1 << 63should panic due to overflow - Error: Evaluator succeeds silently instead of panicking
- Ori Tests:
tests/spec/expressions/operators_bitwise.ori
- Spec:
23.2 Primitive Trait Methods
SPEC:
spec/09-properties-of-types.md§ Built-in Traits STATUS: ALL IMPLEMENTED (verified 2026-02-04)
Primitives (int, str, bool, float, etc.) implement standard trait methods.
23.2.1 Printable Trait (.to_str())
- Implement:
.to_str()on primitive types-
int.to_str()— Works:42.to_str() == "42" -
str.to_str()— Works -
bool.to_str()— Works:true.to_str() == "true" -
float.to_str()— Works - Ori Tests:
tests/spec/declarations/traits.ori,tests/spec/types/existential.ori
-
23.2.2 Clone Trait (.clone())
- Implement:
.clone()on primitive types-
int.clone()— Works:let y = x.clone() -
str.clone()— Works - All primitives are cloneable
- Ori Tests:
tests/spec/declarations/traits.ori,tests/spec/types/existential.ori
-
23.2.3 Hashable Trait (.hash())
- Implement:
.hash()on primitive types-
int.hash()— Works -
str.hash()— Works - Ori Tests:
tests/spec/declarations/traits.ori
-
23.3 Type Coercion and Indexing
SPEC:
spec/14-expressions.md§ Index Access STATUS: Mostly complete (verified 2026-02-04)
23.3.1 Map Index Return Type
- Fix: Map lookup works for existing keys
- Verified:
let m = {"a": 1}; let val = m["a"]; assert(eq: val == 1)works - Pending: Missing key behavior needs verification — spec says should return
Option<V> - Ori Tests:
tests/spec/expressions/index_access.ori,tests/spec/expressions/literals.ori
- Verified:
23.3.2 Map Non-String Keys
- Fix: Allow non-string map keys
- Spec:
{int: str}maps should work - Error: “map keys must be strings”
- Required: Support any Hashable type as key
- Ori Tests:
tests/spec/expressions/literals.ori
- Spec:
23.3.3 String Index Return Type
- Fix: String indexing works
- Verified:
let s = "hello"; let c = s[0]compiles and runs - Pending: Verify return type matches spec (str vs char)
- Ori Tests:
tests/spec/expressions/index_access.ori
- Verified:
23.3.4 List Index Assignment
- Implement:
list[i] = valuesyntax- Verified:
let list = [1, 2, 3]; list[0] = 99; assert(eq: list[0] == 99)works - Ori Tests:
tests/spec/expressions/index_access.ori
- Verified:
23.4 Control Flow
SPEC:
spec/14-expressions.md§ Control Flow
23.4.1 Break with Value in Nested Loops
- Fix:
break valueinside for loop inside loop- Error: Returns 0 instead of break value
- Cause: Break value not propagating through nested constructs
- Ori Tests:
tests/spec/expressions/loops.ori
23.4.2 Function Field Calls
- Implement: Calling function stored in struct field
- Syntax:
handler.callback(42)wherecallback: (int) -> str - Error: Compiler crash (index out of bounds in type_interner.rs:226)
- Required: Recognize field as callable, invoke it
- Ori Tests:
tests/spec/types/function_types.ori - Note: This causes a compiler panic, not just a type error (verified 2026-02-04)
- Syntax:
23.5 Derived Traits
SPEC:
spec/10-declarations.md§ Attributes STATUS: ALL IMPLEMENTED (verified 2026-02-04)
23.5.1 #derive(Eq) Implementation
- Fix: Generated equality for structs
- Compares all fields correctly
- Works with
==and!=operators - Verified:
#derive(Eq) type Point = {...}; assert(eq: p1 == p2)works - Ori Tests:
tests/spec/expressions/operators_comparison.ori
23.5.2 #derive(Clone) Implementation
- Fix: Generated clone for structs
- Clones all fields correctly
- Verified:
#derive(Clone) type Point = {...}; let p2 = p1.clone()works - Ori Tests:
tests/spec/declarations/attributes.ori
23.5.3 #derive(Hashable) Implementation
- Fix: Generated hash for structs
- Combines hashes of all fields
- Verified:
#derive(Hashable) type Point = {...}; let h = p.hash()works - Ori Tests:
tests/spec/declarations/attributes.ori
23.6 Stdlib Types and Methods
SPEC: Various stdlib specs
23.6.1 Queue Type
- Implement: Queue data structure — 6 tests skipped
-
Queue.enqueue(value:) -
Queue.dequeue()->Option<T> -
Queue.peek()->Option<T> -
Queue.len()->int -
Queue.is_empty()->bool -
Queue.clear() - Location:
library/std/or evaluator built-ins
-
23.6.2 Stack Type
- Implement: Stack data structure — 6 tests skipped
-
Stack.push(value:) -
Stack.pop()->Option<T> -
Stack.peek()->Option<T> -
Stack.len()->int -
Stack.is_empty()->bool -
Stack.clear() - Location:
library/std/or evaluator built-ins
-
23.6.3 String Slice
- Implement: String slicing — 2 tests skipped
-
str.slice(start:, end:)method -
str[start..end]syntax - Location: Evaluator string operations
-
23.6.4 Stdlib Utilities
- Implement: retry/validate — 5 tests skipped
-
retry(attempts:, delay:, op:) -
validate(value:, rules:) - Location:
library/std/
-
23.6.5 Async/Future Support
- Implement: Future handling — 1 test skipped
- Async/await or Future handling
- Location: Evaluator async support
23.8 Parser Feature Support (Type Checker/Evaluator)
SPEC:
spec/10-declarations.md§ Functions,spec/14-expressions.md§ Calls
These features have working parser support (Section 0.9.1 complete), but need type checker and/or evaluator implementation.
23.8.1 Guard Clauses
Parser Status: Parses correctly (
@f (n: int) -> int if n > 0 = n) Test File:tests/spec/declarations/clause_params.ori
- Type Checker: Verify guard expression returns
bool- Location:
ori_types/src/infer/— check guard expression type - Constraint: Guard must be
bool-typed
- Location:
- Evaluator: Select matching clause based on guard evaluation
- Location:
ori_eval/src/interpreter/— function call resolution - Semantics: Clauses matched top-to-bottom; guard evaluated after pattern match
- Semantics: If guard is false, try next clause
- Location:
23.8.2 List Patterns in Function Parameters
Parser Status: Parses correctly (
@len ([]: [T]) -> int = 0) Test File:tests/spec/declarations/clause_params.ori
- Type Checker: Extract bindings from list patterns
- Location:
ori_types/src/infer/— pattern binding extraction - Bindings:
[x, ..tail]createsx: Tandtail: [T] - Empty:
[]pattern matches empty list only
- Location:
- Evaluator: Destructure list into pattern bindings
- Location:
ori_eval/src/interpreter/— parameter binding - Semantics: Match list structure, bind named elements
- Failure: If pattern doesn’t match, try next clause
- Location:
23.8.3 Const Generics
Parser Status: Parses correctly (
@f<$N: int>,@f<$N: int = 10>) Test File:tests/spec/declarations/generics.ori
- Type Checker: Make const generic params available in scope
- Location:
ori_types/src/infer/— generic parameter handling - Binding:
$Navailable as compile-time constant in function body - Type: Const param has the declared type (
int,bool, etc.)
- Location:
- Type Checker: Evaluate const generic default values
- Constraint: Default must be const-evaluable
- Type Checker: Support const generic constraints in
whereclauses- Syntax:
where N > 0,where N > 0 && N <= 100 - Evaluation: Constraints checked at monomorphization time
- Syntax:
- Evaluator: Substitute const values at call sites
- Location:
ori_eval/src/interpreter/— generic instantiation
- Location:
23.8.4 Variadic Parameters
Parser Status: Parses correctly (
@sum (nums: ...int)) Test File:tests/spec/declarations/variadic_params.ori(needs creation)
- Type Checker: Handle variadic parameter types
- Location:
ori_types/src/infer/— function signature handling - Semantics:
...Tin parameter position → receives as[T] - Constraint: Only one variadic param allowed per function
- Constraint: Variadic must be last parameter
- Location:
- Evaluator: Collect variadic arguments into list
- Location:
ori_eval/src/interpreter/— call argument handling - Semantics: All remaining args collected into
[T] - Semantics: Zero args → empty list
[]
- Location:
23.8.5 Function-Level Contract Enforcement (pre()/post())
Parser Status: Parses correctly (
pre(cond | "msg"),post(r -> cond | "msg")) [done] (2026-02-14) IR:CheckExprstruct,CheckRange, stored on function definition node Test File:tests/spec/patterns/run.ori(commented-out tests at lines 140-288)
- Type Checker: Verify
pre()condition isbool-typed- Location:
ori_types/src/infer/expr.rs— function contract handling - Semantics:
pre(expr)— expr must bebool - Semantics:
pre(expr | "msg")— msg must bestr
- Location:
- Type Checker: Verify
post()lambda returnsbool- Semantics:
post(r -> expr)— lambda(T) -> boolwhere T is result type - Semantics:
post((a, b) -> expr)— tuple destructuring in lambda
- Semantics:
- Evaluator: Execute
pre()contracts before function body- Location:
ori_eval/src/interpreter/— function call evaluation - Semantics: Evaluate condition; if false, panic with message (or default)
- Semantics: Multiple
pre()contracts evaluated in order; first failure panics
- Location:
- Evaluator: Execute
post()contracts after function body- Semantics: Evaluate lambda with result value; if returns false, panic
- Semantics: Multiple
post()contracts evaluated in order; first failure panics
23.8.6 Spread in Function Calls
Parser Status: Parses correctly (
sum(...list)) Test File:tests/spec/expressions/function_calls.ori
- Type Checker: Verify spread arg matches variadic param type
- Location:
ori_types/src/infer/— call type checking - Constraint: Spread only valid for variadic parameters
- Constraint:
...exprwhereexpr: [T]spreads into...Tparam
- Location:
- Evaluator: Expand spread arguments at call site
- Location:
ori_eval/src/interpreter/— call argument evaluation - Semantics:
...listexpands to individual elements - Semantics: Multiple spreads allowed:
fn(...a, ...b)
- Location:
23.7 Section Completion Checklist
STATUS: MOSTLY COMPLETE — 1983 passed, 0 failed, 31 skipped (verified 2026-02-04)
- All operator evaluations implemented (23.1) —
??, comparisons, equality work - All primitive trait methods registered (23.2) —
.to_str(),.clone(),.hash()work - Most indexing behaviors correct per spec (23.3) — list/map/string indexing work
- Control flow semantics (23.4) — break value propagation, function field calls still broken
- All derived traits working (23.5) —
#derive(Eq, Clone, Hashable)work - Stdlib types (23.6) — Queue/Stack not implemented
- Run
cargo st tests/— 1983 passed, 31 skipped (skips are mostly LLVM/capability issues)
Exit Criteria: Every Ori spec semantic is correctly implemented in the evaluator. All spec tests must pass — no skipped tests allowed.
Remaining Issues (verified 2026-02-04):
- Function field calls crash compiler (type_interner.rs:226 index out of bounds)
- Break value propagation in nested loops
- Map missing key behavior (needs Option
) - Queue/Stack types not implemented
Test Status Comments
Each failing test file has a status comment documenting the issue:
// STATUS: Lexer [OK], Parser [OK], Evaluator [BROKEN] - <specific issue>
Files with evaluator bugs:
tests/spec/expressions/coalesce.ori—??operatortests/spec/expressions/index_access.ori— map/string indexingtests/spec/expressions/operators_comparison.ori— Option order, struct eqtests/spec/expressions/operators_bitwise.ori— shift overflowtests/spec/expressions/loops.ori— break value propagationtests/spec/declarations/traits.ori— primitive trait methodstests/spec/types/existential.ori— primitive trait methodstests/spec/types/function_types.ori— function field callstests/spec/expressions/literals.ori— map issuestests/spec/expressions/field_access.ori—??operator
Notes
- This section can be worked on in parallel with Section 0 (parser)
- Evaluator is the reference implementation; LLVM codegen validates against it
- Some evaluator work overlaps with type checker (Section 1, 2, 3)
- Stdlib types may be implemented in Ori itself once evaluator is complete