98%

Section 0: Full Parser Support

Goal: Complete parser support for entire Ori spec grammar (parsing only — evaluator in Section 23)

SPEC: spec/grammar.ebnf (authoritative), spec/06-source-code.md, spec/07-lexical-elements.md

Status: In Progress — Re-verified 2026-02-14. ~3 parser bugs remain (down from ~24). 23 items previously broken now parse correctly. Remaining gaps: const functions, .match() method syntax. See § 0.8 for full bug list.


OVERVIEW

This section ensures the parser handles every syntactic construct in the Ori specification. It has no dependencies and can be worked on at any time. Other sections may overlap with this work — that’s expected and acceptable.

Why this matters: The formatter, LSP, and other tooling depend on complete parser support. Without it, valid Ori code may fail to parse, blocking downstream work.

Approach:

  1. Audit current parser against each grammar production
  2. Implement missing productions
  3. Add parser tests for each production
  4. Mark items complete as verified

0.1 Lexical Grammar

SPEC: grammar.ebnf § LEXICAL GRAMMAR, spec/07-lexical-elements.md

0.1.1 Comments

  • Audit: Line comments // ... — grammar.ebnf § comment [done] (2026-02-10)

    • Rust Tests: oric/tests/phases/parse/lexer.rs — 14 comment tests (classification, spans, detached warnings)
    • Ori Tests: tests/spec/lexical/comments.ori — 30+ tests
  • Audit: Doc comments with markers — grammar.ebnf § doc_comment [done] (2026-02-10)

    • // (description), // * (param), // ! (warning), // > (example)
    • Rust Tests: oric/tests/phases/parse/lexer.rs — doc comment type tests
    • Ori Tests: tests/spec/lexical/comments.ori — all marker types tested

0.1.2 Identifiers

  • Audit: Standard identifiers letter { letter | digit | "_" } — grammar.ebnf § identifier [done] (2026-02-10)
    • Rust Tests: oric/tests/phases/parse/lexer.rs — identifier tokenization
    • Ori Tests: tests/spec/lexical/identifiers.ori — 40+ tests (letters, digits, underscores, case sensitivity)

0.1.3 Keywords

  • Audit: Reserved keywords — grammar.ebnf § Keywords [done] (2026-02-10)

    • break, continue, def, do, else, extern, false, for, if, impl
    • in, let, loop, match, pub, self, Self, then, trait, true
    • type, unsafe, use, uses, void, where, with, yield
    • Rust Tests: oric/tests/phases/parse/lexer.rs — 45+ keyword recognition tests
    • Ori Tests: tests/spec/lexical/keywords.ori — 50+ tests
  • Audit: Context-sensitive keywords (patterns) — grammar.ebnf § Keywords [done] (2026-02-10)

    • cache, catch, for, match, nursery, parallel, recurse, run, spawn, timeout, try, with
    • Rust Tests: oric/tests/phases/parse/lexer.rs — soft keyword lookahead, contextual flag tests
    • Ori Tests: tests/spec/lexical/keywords.ori — context-sensitive usage verified
  • Audit: Context-sensitive keywords (stdlib methods) — spec/07-lexical-elements.md § Context-Sensitive [done] (2026-02-10)

    • collect, filter, find, fold, map, retry, validate
    • Note: These are stdlib iterator methods, not compiler patterns — listed in spec as context-sensitive
    • Rust Tests: oric/tests/phases/parse/lexer.rs — builtin_names_are_identifiers test
    • Ori Tests: tests/spec/lexical/keywords.orifold tested as identifier; stdlib methods are plain identifiers
  • Audit: Context-sensitive keywords (other) — grammar.ebnf § Keywords [done] (2026-02-10)

    • without (imports only), by (ranges only), max (fixed-capacity only)
    • int, float, str, byte (type conversion call position)
    • Rust Tests: oric/tests/phases/parse/lexer.rs — type keywords always resolved, soft keyword handling
    • Ori Tests: tests/spec/lexical/keywords.ori — type keywords and context-sensitive usage tested

0.1.4 Operators

  • Audit: Arithmetic operators — grammar.ebnf § arith_op [done] (2026-02-10)

    • +, -, *, /, %, divFixed: Added div to parser (was missing)
    • Rust Tests: implicit through tokenization
    • Ori Tests: tests/spec/lexical/operators.ori — 80+ tests including precedence
  • Audit: Comparison operators — grammar.ebnf § comp_op [done] (2026-02-10)

    • ==, !=, <, >, <=, >=
    • Rust Tests: implicit through tokenization
    • Ori Tests: tests/spec/lexical/operators.ori
  • Audit: Logic operators — grammar.ebnf § logic_op [done] (2026-02-10)

    • &&, ||, !
    • Rust Tests: implicit through tokenization
    • Ori Tests: tests/spec/lexical/operators.ori
  • Audit: Bitwise operators — grammar.ebnf § bit_op [done] (2026-02-10)

    • &, |, ^, ~, <<, >>
    • Rust Tests: implicit through tokenization
    • Ori Tests: tests/spec/lexical/operators.ori
  • Audit: Other operators — grammar.ebnf § other_op [done] (2026-02-10)

    • .., ..=, ??, ?, ->, => — Note: ?? parses but evaluator incomplete
    • Rust Tests: implicit through tokenization
    • Ori Tests: tests/spec/lexical/operators.ori

0.1.5 Delimiters

  • Audit: All delimiters — grammar.ebnf § delimiter [done] (2026-02-10)
    • (, ), [, ], {, }, ,, :, ., @, $
    • Rust Tests: implicit through parsing
    • Ori Tests: tests/spec/lexical/delimiters.ori — 70+ tests (all delimiter types in context)

0.1.6 Integer Literals

  • Audit: Decimal integers — grammar.ebnf § decimal_lit [done] (2026-02-10)

    • Basic: 42, with underscores: 1_000_000
    • Rust Tests: oric/tests/phases/parse/lexer.rs — decimal/hex/binary underscore tests
    • Ori Tests: tests/spec/lexical/int_literals.ori — 50+ tests (decimal, hex, binary, underscores, negative, boundary)
  • Audit: Hexadecimal integers — grammar.ebnf § hex_lit [done] (2026-02-10)

    • Basic: 0xFF, with underscores: 0x1A_2B_3C
    • Rust Tests: oric/tests/phases/parse/lexer.rs — hex underscore tests
    • Ori Tests: tests/spec/lexical/int_literals.ori — hex literals with case/underscore variants

0.1.7 Float Literals

  • Audit: Basic floats — grammar.ebnf § float_literal [done] (2026-02-10)
    • Simple: 3.14, with exponent: 2.5e-8, 1.0E+10
    • Rust Tests: oric/tests/phases/parse/lexer.rs — float/scientific notation tests
    • Ori Tests: tests/spec/lexical/float_literals.ori — 50+ tests (basic, exponents, underscores, precision)

0.1.8 String Literals

  • Audit: Basic strings — grammar.ebnf § string_literal [done] (2026-02-10)

    • Simple: "hello", empty: ""
    • Rust Tests: oric/tests/phases/parse/lexer.rs — string escape tests
    • Ori Tests: tests/spec/lexical/string_literals.ori — 60+ tests
  • Audit: Escape sequences — grammar.ebnf § escape [done] (2026-02-10)

    • \\, \", \n, \t, \r, \0
    • Rust Tests: oric/tests/phases/parse/lexer.rs — escape parsing
    • Ori Tests: tests/spec/lexical/string_literals.ori — escapes tested in same file

0.1.9 Template Literals

  • Audit: Template strings — grammar.ebnf § template_literal [done] (2026-02-10)

    • Simple: `hello`, interpolation: `{name}`
    • Rust Tests: oric/tests/phases/parse/lexer.rs — 12 template tests (head/middle/tail tokens, interpolation)
    • Ori Tests: tests/spec/expressions/template_literals.ori — end-to-end template tests
  • Audit: Template escapes — grammar.ebnf § template_escape, template_brace [done] (2026-02-10)

    • Escapes: \`, \\, \n, \t, \r, \0
    • Brace escapes: {{, }}
    • Rust Tests: oric/tests/phases/parse/lexer.rs — template escape/brace tests
  • Audit: Format specifications — grammar.ebnf § format_spec [done] (2026-02-10)

    • Fill/align: {x:<10}, {x:>5}, {x:^8}
    • Sign: {x:+} (always sign), {x:-} (negative only), {x: } (space for positive)
    • Width/precision: {x:10}, {x:.2}, {x:10.2}
    • Format types: {x:b}, {x:x}, {x:X}, {x:o}, {x:e}, {x:E}, {x:f}, {x:%}
    • Rust Tests: oric/tests/phases/parse/lexer.rs — format spec parsing tests (:x, >10.2f)

0.1.10 Character Literals

  • Audit: Character literals — grammar.ebnf § char_literal [done] (2026-02-10)
    • Simple: 'a', escapes: '\n', '\t', '\'', '\\'
    • Rust Tests: oric/tests/phases/parse/lexer.rs — char literal parsing
    • Ori Tests: tests/spec/lexical/char_literals.ori — 60+ tests (letters, digits, punctuation, escapes)

0.1.11 Boolean Literals

  • Audit: Boolean literals — grammar.ebnf § bool_literal [done] (2026-02-10)
    • true, false
    • Rust Tests: implicit through keyword recognition
    • Ori Tests: tests/spec/lexical/bool_literals.ori — 60+ tests (truth tables, De Morgan’s, short-circuit)

0.1.12 Duration Literals

  • Audit: Duration literals — grammar.ebnf § duration_literal [done] (2026-02-10)
    • All units: 100ns, 50us, 10ms, 5s, 2m, 1h
    • Decimal syntax: 0.5s, 1.5m (compile-time sugar) — tested
    • Rust Tests: oric/tests/phases/parse/lexer.rs — 10+ duration tests (units, decimal, many digits)
    • Ori Tests: tests/spec/lexical/duration_literals.ori — 70+ tests (all units, decimal, cross-unit equivalences)

0.1.13 Size Literals

  • Audit: Size literals — grammar.ebnf § size_literal [done] (2026-02-10)
    • All units: 100b, 10kb, 5mb, 1gb, 500tb
    • Decimal syntax: 1.5kb, 2.5mb (compile-time sugar) — tested
    • Rust Tests: oric/tests/phases/parse/lexer.rs — 5+ size tests (units, decimal)
    • Ori Tests: tests/spec/lexical/size_literals.ori — 70+ tests (all units, decimal, SI units verified: 1kb == 1000b)

0.2 Source Structure

SPEC: grammar.ebnf § SOURCE STRUCTURE, spec/06-source-code.md, spec/18-modules.md

0.2.1 Source File

  • Audit: Source file structure — grammar.ebnf § source_file [done] (2026-02-10)

    • [ file_attribute ] { import } { declaration } — imports + types + functions + tests all parse
    • Rust Tests: implicit through full-file parsing
    • Ori Tests: tests/spec/source/file_structure.ori — 6 tests
  • Audit: File-level attributes — grammar.ebnf § file_attribute [done] (2026-02-13)

    • #!target(os: "linux"), #!cfg(debug) — parses correctly, stored in Module.file_attr
    • Rust Tests: oric/tests/phases/parse/file_attr.rs — 16 tests, ori_parse::grammar::attr — 5 tests
    • Ori Tests: tests/spec/source/file_attr_target.ori, file_attr_cfg.ori, file_attributes.ori

0.2.2 Imports

  • Audit: Import statements — grammar.ebnf § import [done] (2026-02-10)

    • Relative: use "./path" { items } — parses correctly
    • Module: use std.math { sqrt } — parses correctly
    • Alias: use std.net.http as http — parses correctly
    • Ori Tests: tests/spec/source/imports.ori — 3 tests
  • Audit: Import items — grammar.ebnf § import_item [done] (2026-02-10)

    • Basic: { name }, aliased: { name as alias } — parses correctly
    • Private: { ::internal } — parses correctly (2026-02-13), constants: { $CONST } — parses correctly (parser + formatter, evaluator pending)
    • Without default impl: { Trait without def } — parses correctly (2026-02-13, trait resolution pending)
    • Rust Tests: oric/tests/phases/parse/imports.rs — 12 tests (all import_item forms)
    • Ori Tests: tests/spec/source/imports.ori, tests/spec/modules/use_imports.ori, tests/spec/modules/_test/use_constants.test.ori

0.2.3 Re-exports

  • Audit: Re-export statements — grammar.ebnf § reexport [done] (2026-02-10)
    • pub use path { items } — parses correctly (verified via ori parse)
    • Ori Tests: tests/spec/modules/reexporter.ori — 1 test

0.2.4 Extensions

  • Audit: Extension definitions — grammar.ebnf § extension_def [done] (2026-02-10)

    • extend Type { methods } — parses correctly (verified via ori parse)
    • extend Type where T: Bound { methods } — parses correctly (2026-02-13), including multiple bounds
    • Ori Tests: tests/spec/source/extensions.ori — 3 tests
  • Audit: Extension imports — grammar.ebnf § extension_import [done] (2026-02-13)

    • extension std.iter.extensions { Iterator.count } — parses correctly (2026-02-13)
    • pub extension path { Type.method } — parses correctly (public re-export)
    • extension "./path" { Type.method } — parses correctly (relative paths)
    • Rust Tests: oric/tests/phases/parse/extensions.rs — 8 extension import tests
    • Formatter: round-trips correctly

0.2.5 FFI

  • Audit: Extern blocks — grammar.ebnf § extern_block [done] (2026-02-13)

    • C: extern "c" from "lib" { ... } — parses correctly (verified via ori parse)
    • JS: extern "js" { ... } — parses correctly
    • pub extern visibility — parses correctly
    • from "path" library clause — parses correctly
    • Empty extern blocks — parses correctly
    • Note: Extern blocks are now proper AST nodes (ExternBlock, ExternItem, ExternParam)
  • Audit: Extern items — grammar.ebnf § extern_item [done] (2026-02-13)

    • @_sin (x: float) -> float as "sin" — parses correctly (as alias)
    • @sin (x: float) -> float — parses correctly (no alias)
    • Mixed alias/no-alias items in same block — parses correctly
  • Audit: C variadics — grammar.ebnf § c_variadic [done] (2026-02-13)

    • @printf (fmt: CPtr, ...) -> c_int — parses correctly
    • (...) -> void — parses correctly (no named params)
  • Rust Tests: oric/tests/phases/parse/extern_def.rs — 20 tests (2026-02-13)

  • Formatter: round-trips correctly (2026-02-13)


0.3 Declarations

SPEC: grammar.ebnf § DECLARATIONS, spec/10-declarations.md

0.3.1 Attributes

  • Audit: Item attributes — grammar.ebnf § attribute [done] (2026-02-10)

    • #derive(Eq, Clone) — parses correctly
    • #skip("reason"), #fail("expected"), #compile_fail("E1234") — parse correctly
    • #target(os: "linux"), #cfg(debug) — parses correctly [done] (2026-02-13)
    • #repr("c") — parses correctly [done] (2026-02-13)
    • Ori Tests: tests/spec/declarations/attributes.ori — 24+ tests
  • Audit: Attribute arguments — grammar.ebnf § attribute_arg [done] (2026-02-10)

    • Expression: #attr(42), named: #attr(key: value) — tested in attributes.ori
    • Array: #attr(["a", "b"]) — tested via #derive(Eq, Clone) syntax
    • Ori Tests: tests/spec/declarations/attributes.ori — covers argument forms

0.3.2 Functions

  • Audit: Function declarations — grammar.ebnf § function [done] (2026-02-10)

    • Basic: @name (x: int) -> int = expr — parses correctly
    • Public: pub @name — parses correctly
    • Rust Tests: oric/tests/phases/parse/function.rs — 8 tests for return type annotations
    • Ori Tests: extensive coverage across all test files (3068 tests use function syntax)
  • Audit: Function generics — grammar.ebnf § generics (partial) [done] (2026-02-10)

    • Type params: @f<T> (x: T) -> T — parses correctly (verified via ori parse)
    • Bounded: @f<T: Eq> (x: T) -> bool — parses correctly
    • Multiple bounds: @f<T: Eq + Clone> (x: T) -> T — parses correctly
    • Const params: @f<$N: int> () -> [int, max $N] — parses correctly [done] (2026-02-13)
    • Default params: @f<T = int> (x: T) -> T — parses correctly
    • Ori Tests: tests/spec/declarations/generics.ori — exists but tests commented out (type checker deps)
  • Audit: Clause parameters — grammar.ebnf § clause_params [done] (2026-02-13)

    • Pattern param: @fib (0: int) -> int = 1 — parses correctly (verified via ori parse)
    • Default value: @greet (name: str = "World") -> str — parses correctly (verified via ori parse)
    • Ori Tests: tests/spec/declarations/clause_params.ori — exists, commented out (blocked by type checker/evaluator)
  • Audit: Guard clauses — grammar.ebnf § guard_clause [done] (2026-02-13)

    • @f (n: int) -> int if n > 0 = n — parses correctly (verified via ori parse)
  • Audit: Uses clause — grammar.ebnf § uses_clause [done] (2026-02-10)

    • @fetch (url: str) -> str uses Http = ... — parses correctly (verified via ori parse)
    • Multiple: @process () -> void uses Http, FileSystem = ... — parses correctly
  • Audit: Where clause — grammar.ebnf § where_clause [done] (2026-02-10)

    • Type constraint: where T: Clone — parses correctly (verified via ori parse)
    • Multiple: where T: Clone, U: Default — parses correctly
    • Const constraint: where N > 0 — parses correctly [done] (2026-02-13)
    • Ori Tests: tests/spec/declarations/where_clause.ori — exists but tests commented out

0.3.3 Const Bound Expressions

  • Audit: Const bound expressions — grammar.ebnf § const_bound_expr [done] (2026-02-13)
    • Comparison: N > 0, N == M, N >= 1 — parses correctly
    • Logical: N > 0 && N < 100, A || B, !C — parses correctly
    • Grouped: (N > 0 && N < 10) || N == 100 — parses correctly
    • Rust Tests: ori_parse/src/grammar/item/generics.rs — 5 where clause tests

0.3.4 Type Definitions

  • Audit: Struct types — grammar.ebnf § struct_body [done] (2026-02-10)

    • type Point = { x: int, y: int } — parses correctly
    • Generic: type Box<T> = { value: T } — parses correctly
    • Ori Tests: tests/spec/declarations/struct_types.ori — 39 active tests (comprehensive)
  • Audit: Sum types — grammar.ebnf § sum_body [done] (2026-02-10)

    • type Option<T> = Some(value: T) | None — parses correctly
    • Unit variants: type Color = Red | Green | Blue — parses correctly
    • Ori Tests: tests/spec/declarations/sum_types.ori — 35+ active tests
  • Audit: Newtype aliases — grammar.ebnf § type_body (type reference) [done] (2026-02-10)

    • type UserId = int — parses correctly (verified via ori parse)
    • Ori Tests: tests/spec/types/newtypes.ori — tests in types/ directory

0.3.5 Traits

  • Audit: Trait definitions — grammar.ebnf § trait_def [done] (2026-02-10)

    • Basic: trait Printable { @to_str (self) -> str } — parses correctly
    • With inheritance: trait Comparable: Eq { ... } — parses correctly
    • With generics: trait Into<T> { @into (self) -> T } — parses correctly
    • Default type params: trait Add<Rhs = Self> { ... } — parses correctly
    • Ori Tests: tests/spec/declarations/traits.ori — 30+ active tests
  • Audit: Method signatures — grammar.ebnf § method_sig [done] (2026-02-10)

    • @method (self) -> T, @method (self, other: Self) -> bool — parse correctly
    • Ori Tests: tests/spec/declarations/traits.ori — method sigs tested within trait tests
  • Audit: Default methods — grammar.ebnf § default_method [done] (2026-02-10)

    • @method (self) -> T = expr — parses correctly
    • Ori Tests: tests/spec/declarations/traits.ori — default methods tested within trait tests
  • Audit: Associated types — grammar.ebnf § assoc_type [done] (2026-02-10)

    • Basic: type Item — parses correctly
    • Bounded: type Item: Eq — parses correctly
    • Default: type Output = Self — parses correctly
    • Ori Tests: tests/spec/traits/associated_types.ori — comprehensive tests
  • Audit: Variadic parameters — grammar.ebnf § variadic_param [done] (2026-02-13)

    • @sum (nums: ...int) -> int — parses correctly (verified via ori parse)

0.3.6 Implementations

  • Audit: Inherent impl — grammar.ebnf § inherent_impl [done] (2026-02-10)

    • impl Point { @distance (self) -> float = ... } — parses correctly
    • Generic: impl<T> Box<T> { ... } — parses correctly (verified via ori parse)
    • Ori Tests: tested across trait/struct test files
  • Audit: Trait impl — grammar.ebnf § trait_impl [done] (2026-02-10)

    • impl Point: Printable { ... } — parses correctly
    • Generic: impl<T: Printable> Box<T>: Printable { ... } — parses correctly
    • Ori Tests: tests/spec/declarations/traits.ori — trait impls tested
  • Audit: Default impl — grammar.ebnf § def_impl [done] (2026-02-10)

    • def impl Printable { @to_str (self) -> str = ... } — parses correctly (verified via ori parse)

0.3.7 Tests

  • Audit: Test declarations — grammar.ebnf § test [done] (2026-02-14)
    • Attached: @t tests @target () -> void = ... — parses correctly (used in 3068 tests)
    • Floating: @t tests _ () -> void = ... — parses correctly [done] (2026-02-14)
    • Multi-target: @t tests @a tests @b () -> void = ... — parses correctly [done] (2026-02-14)
    • Ori Tests: tests/spec/free_floating_test.ori — 3 tests (2 floating with tests _, 1 legacy test_ prefix)
    • Rust Tests: ori_parse::grammar::item::function::tests — 5 tests

0.3.8 Constants

  • Audit: Module-level constants — grammar.ebnf § constant_decl (partial) [done] (2026-02-10)
    • let $PI = 3.14159 — parses correctly (verified via ori parse)
    • Computed: let $X = 2 + 3 — parses correctly
    • Typed: let $MAX_SIZE: int = 1000 — parses correctly [done] (2026-02-14)
    • Ori Tests: tests/spec/declarations/constants.ori — exists but all commented out

0.4 Types

SPEC: grammar.ebnf § TYPES, spec/08-types.md

0.4.1 Type Paths

  • Audit: Simple type paths — grammar.ebnf § type_path [done] (2026-02-10)

    • int, Point, std.math.Complex — parses correctly
    • Rust Tests: ori_ir/tests/ — 16 parsed_type tests (primitive, named, generic, nested, associated, function, list, map, tuple, unit)
  • Audit: Generic type arguments — grammar.ebnf § type_args [done] (2026-02-10)

    • Option<int>, Result<T, E>, Map<str, int> — parses correctly
    • With const: [int, max 10] — parses correctly [done] (2026-02-13)
    • Array<int, $N> — parses correctly [done] (2026-02-13)

0.4.2 Existential Types

  • Audit: impl Trait — grammar.ebnf § impl_trait_type
    • Basic: impl IteratorBROKEN: parser rejects impl in type position
    • Multi-trait: impl Iterator + Clone — blocked by above
    • With where: impl Iterator where Item == int — blocked by above

0.4.3 Compound Types

  • Audit: List types — grammar.ebnf § list_type [done] (2026-02-10)

    • Dynamic: [int], [Option<str>] — parses correctly
  • Audit: Fixed-capacity list types — grammar.ebnf § fixed_list_type [done] (2026-02-13)

    • [int, max 10], [T, max N] — parses correctly (verified via ori parse)
  • Audit: Map types — grammar.ebnf § map_type [done] (2026-02-10)

    • {str: int}, {K: V} — parses correctly
  • Audit: Tuple types — grammar.ebnf § tuple_type [done] (2026-02-10)

    • Unit: (), pairs: (int, str), nested: ((int, int), str) — parses correctly
  • Audit: Function types — grammar.ebnf § function_type [done] (2026-02-10)

    • () -> void, (int) -> int, (int, str) -> bool — parses correctly (verified via typed lambda)

0.4.4 Const Expressions in Types

  • Audit: Const expressions — grammar.ebnf § const_expr [done] (2026-02-13)
    • Literal: 10 in type argument position (e.g., Array<int, 10>) — parses correctly
    • Parameter: $N in type argument position — parses correctly
    • Arithmetic: $N + 1, $N * 2 in type argument position — parses correctly
    • Rust Tests: ori_parse/src/grammar/ty.rs — 4 const expression type arg tests

0.4.5 Trait Objects

SPEC: spec/08-types.md § Trait Objects

  • Audit: Simple trait objects — spec/08-types.md § Trait Objects [done] (2026-02-10)

    • Trait name as type: @display (item: Printable) -> void — parses correctly (verified via ori parse)
    • In collections: [Printable], {str: Printable} — parses correctly [done] (2026-02-13)
    • Ori Tests: tests/spec/types/trait_objects.ori — tests exist
  • Audit: Bounded trait objects — spec/08-types.md § Bounded Trait Objects [done] (2026-02-14)

    • Multiple bounds: Printable + Hashable — parses correctly as TraitBounds variant [done] (2026-02-14)
    • As parameter type: @store (item: Printable + Hashable) -> void — parses correctly [done] (2026-02-14)
    • Grammar: trait_object_bounds already in grammar.ebnf; parser now implements it [done] (2026-02-14)

0.5 Expressions

SPEC: grammar.ebnf § EXPRESSIONS, spec/14-expressions.md

0.5.1 Primary Expressions

Note: Pattern expressions (run, try, match, parallel, nursery, channel, etc.) are valid primary expressions per grammar.ebnf § primary → pattern_expr. See section 0.6 for pattern-specific audit items.

  • Audit: Literals — grammar.ebnf § primary [done] (2026-02-10)

    • All literal types covered in 0.1 — all parse correctly
    • Ori Tests: tests/spec/lexical/ — 690+ tests across all literal types
  • Audit: Identifiers and self — grammar.ebnf § primary [done] (2026-02-10)

    • x, self, Self — parse correctly
    • Ori Tests: tests/spec/lexical/identifiers.ori — 40+ tests
  • Audit: Grouped expressions — grammar.ebnf § primary [done] (2026-02-10)

    • (expr), nested: ((a + b) * c) — parse correctly (verified via ori parse)
  • Audit: Length placeholder — grammar.ebnf § primary [done] (2026-02-13)

    • list[# - 1] (last element) — parses correctly (verified via ori parse)

0.5.2 Unsafe Expression

  • Audit: Unsafe expressions — grammar.ebnf § unsafe_expr [done] (2026-02-10)
    • unsafe(expr) — parsed correctly (verified 2026-02-10; parenthesized form removed by unsafe-semantics-proposal 2026-02-20)
    • unsafe { expr } — block-only form (implemented 2026-02-21)

0.5.3 List Literals

  • Audit: List literals — grammar.ebnf § list_literal [done] (2026-02-10)
    • Empty: [], simple: [1, 2, 3] — parse correctly
    • With spread: [...a, 4, ...b] — parses correctly (verified via ori parse)

0.5.4 Map Literals

  • Audit: Map literals — grammar.ebnf § map_literal [done] (2026-02-10)
    • Empty: {}, simple: {"a": 1, "b": 2} — parse correctly
    • String keys: {"key": value} — parses correctly
    • Computed keys: {[expr]: value} — parses correctly (verified via ori parse)
    • With spread: {...base, extra: 1} — parses correctly (verified via ori parse)

0.5.5 Struct Literals

  • Audit: Struct literals — grammar.ebnf § struct_literal [done] (2026-02-10)
    • Basic: Point { x: 1, y: 2 } — parses correctly
    • Shorthand: Point { x, y } — parses correctly (verified via ori parse)
    • With spread: Point { ...base, x: 10 } — parses correctly (verified via ori parse)
    • Ori Tests: tests/spec/declarations/struct_types.ori — 39 active tests

0.5.6 Postfix Expressions

  • Audit: Field/method access — grammar.ebnf § postfix_op [done] (2026-02-10)

    • Field: point.x — parses correctly
    • Method: list.len() — parses correctly
    • Ori Tests: extensive coverage across all test files
  • Audit: Index access — grammar.ebnf § postfix_op [done] (2026-02-10)

    • list[0], map["key"] — parse correctly
    • list[# - 1] — parses correctly [done] (2026-02-13)
  • Audit: Function calls — grammar.ebnf § call_args [done] (2026-02-10)

    • Named: greet(name: "Alice") — parses correctly
    • Positional (lambda): list.map(x -> x * 2) — parses correctly
    • Spread: sum(...numbers) — parses correctly (verified via ori parse)
    • Ori Tests: tests/spec/declarations/named_arguments.ori — 149 lines
  • Audit: Error propagation — grammar.ebnf § postfix_op [done] (2026-02-10)

    • result? — parses correctly (verified via ori parse)
  • Audit: Type conversion — grammar.ebnf § postfix_op [done] (2026-02-10)

    • Infallible: 42 as float — parses correctly (verified via ori parse)
    • Fallible: "42" as? int — parses correctly (verified via ori parse)

0.5.7 Unary Expressions

  • Audit: Unary operators — grammar.ebnf § unary_expr [done] (2026-02-10)
    • Logical not: !condition — parses correctly
    • Negation: -number — parses correctly
    • Bitwise not: ~bits — parses correctly
    • Ori Tests: tests/spec/lexical/operators.ori — 80+ tests including unary

0.5.8 Binary Expressions

  • Audit: Null coalesce — grammar.ebnf § coalesce_expr [done] (2026-02-10)

    • option ?? default — parses correctly (verified via ori parse)
  • Audit: Logical operators — grammar.ebnf § or_expr, and_expr [done] (2026-02-10)

    • a || b, a && b — parse correctly
    • Ori Tests: tests/spec/lexical/operators.ori, tests/spec/lexical/bool_literals.ori
  • Audit: Bitwise operators — grammar.ebnf § bit_or_expr, bit_xor_expr, bit_and_expr [done] (2026-02-10)

    • a | b, a ^ b, a & b — parse correctly
    • Ori Tests: tests/spec/lexical/operators.ori
  • Audit: Equality operators — grammar.ebnf § eq_expr [done] (2026-02-10)

    • a == b, a != b — parse correctly
    • Ori Tests: tests/spec/lexical/operators.ori
  • Audit: Comparison operators — grammar.ebnf § cmp_expr [done] (2026-02-10)

    • a < b, a > b, a <= b, a >= b — parse correctly
    • Ori Tests: tests/spec/lexical/operators.ori
  • Audit: Range expressions — grammar.ebnf § range_expr [done] (2026-02-10)

    • Exclusive: 0..10, inclusive: 0..=10 — parse correctly
    • With step: 0..10 by 2 — parses correctly
    • Ori Tests: tests/spec/lexical/operators.ori
  • Audit: Shift operators — grammar.ebnf § shift_expr [done] (2026-02-10)

    • a << n, a >> n — parse correctly
    • Ori Tests: tests/spec/lexical/operators.ori
  • Audit: Arithmetic operators — grammar.ebnf § add_expr, mul_expr [done] (2026-02-10)

    • a + b, a - b, a * b, a / b, a % b, a div b — parse correctly
    • Ori Tests: tests/spec/lexical/operators.ori

0.5.9 With Expression

  • Audit: Capability provision — grammar.ebnf § with_expr [done] (2026-02-10)
    • with x = value in expr — parses correctly (verified via ori parse)
    • Capability form: with Http = MockHttp in expr — parses correctly [done] (2026-02-13)

0.5.10 Let Binding

  • Audit: Let expressions — grammar.ebnf § let_expr [done] (2026-02-10)

    • Mutable: let x = 42 — parses correctly
    • Immutable: let $x = 42 — parses correctly
    • Typed: let x: int = 42 — parses correctly
    • Ori Tests: extensive coverage across all test files (3068 tests use let bindings)
  • Audit: Assignment — grammar.ebnf § assignment [done] (2026-02-10)

    • x = new_value — parses correctly

0.5.11 Conditional

  • Audit: If expressions — grammar.ebnf § if_expr [done] (2026-02-10)
    • Simple: if cond then a else b — parses correctly
    • Void: if cond then action — parses correctly
    • Chained: if c1 then a else if c2 then b else c — parses correctly (verified via ori parse)
    • Ori Tests: extensive coverage across test files

0.5.12 For Expression

  • Audit: For loops — grammar.ebnf § for_expr [done] (2026-02-10)
    • Do: for x in items do action — parses correctly
    • Yield: for x in items yield x * 2 — parses correctly (verified via ori parse)
    • Filter: for x in items if x > 0 yield x — parses correctly (verified via ori parse)
    • Labeled: for:outer x in items do ... — parses correctly [done] (2026-02-14)

0.5.13 Loop Expression

  • Audit: Loop expressions — grammar.ebnf § loop_expr [done] (2026-02-14)
    • Basic: loop { body } — parses correctly (verified via ori parse)
    • Labeled: loop:name { body } — parses correctly [done] (2026-02-14)

0.5.14 Labels

  • Audit: Loop labels — grammar.ebnf § label [done] (2026-02-14)
    • :name (no space around colon) — parses correctly (verified via labeled for/loop/break/continue)

0.5.15 Lambda

  • Audit: Simple lambdas — grammar.ebnf § simple_lambda [done] (2026-02-10)

    • Single param: x -> x + 1 — parses correctly
    • Multiple: (a, b) -> a + b — parses correctly
    • No params: () -> 42 — parses correctly
    • Ori Tests: extensive coverage (lambdas used throughout test suite)
  • Audit: Typed lambdas — grammar.ebnf § typed_lambda [done] (2026-02-10)

    • (x: int) -> int = x * 2 — parses correctly (verified via ori parse)

0.5.16 Control Flow

  • Audit: Break expression — grammar.ebnf § break_expr [done] (2026-02-14)

    • Simple: break — parses correctly
    • With value: break result — parses correctly (verified via loop test)
    • Labeled: break:outer, break:outer result — parses correctly [done] (2026-02-14)
  • Audit: Continue expression — grammar.ebnf § continue_expr [done] (2026-02-14)

    • Simple: continue — parses correctly (verified via ori parse)
    • With value: continue replacement — parses correctly [done] (2026-02-13)
    • Labeled: continue:outer — parses correctly [done] (2026-02-14)

0.6 Patterns

SPEC: grammar.ebnf § PATTERNS, spec/15-patterns.md

0.6.1 Sequential Patterns

  • Audit: Block expressions and function contracts — grammar.ebnf § block_expr [done] (2026-02-14)

    • Basic: { let x = a \n result } — parses correctly (verified via ori parse)
    • Pre-contract: pre(cond) on function declaration — parses correctly [done] (2026-02-14)
    • Post-contract: post(r -> cond) on function declaration — parses correctly [done] (2026-02-14)
    • Pre-contract with message: pre(cond | "msg") — parses correctly [done] (2026-02-14)
    • Post-contract with message: post(r -> cond | "msg") — parses correctly [done] (2026-02-14)
    • Multiple pre-contracts: pre(a) pre(b) — parses correctly [done] (2026-02-14)
    • Enforcement: pre/post contracts not yet enforced at runtime
  • Audit: Try pattern — grammar.ebnf § try_expr [done] (2026-02-13)

    • try { let x = f()? \n Ok(x) } — parses correctly (verified via ori parse)
  • Audit: Match pattern — grammar.ebnf § match_expr [done] (2026-02-10)

    • match expr { Some(x) -> x, None -> default } — parses correctly (verified via ori parse)
  • Audit: Guard syntax — grammar.ebnf § guard [done] (2026-02-14)

    • .match(...) syntax — verified (now superseded: guards use if syntax per match-arm-comma-separator-proposal)
  • Audit: For pattern — grammar.ebnf § for_pattern [done] (2026-02-10)

    • Basic form: for(over: items, match: x -> x, default: 0) — parses correctly (verified via ori parse)
  • Audit: Catch pattern — grammar.ebnf § catch_expr [done] (2026-02-10)

    • catch(expr: risky_operation) — parses correctly (verified via ori parse)
  • Audit: Nursery pattern — grammar.ebnf § nursery_expr [done] (2026-02-10)

    • nursery(body: n -> ..., on_error: CancelRemaining) — parses correctly (verified via ori parse)

0.6.2 Function Expression Patterns

  • Audit: Pattern arguments — grammar.ebnf § pattern_arg [done] (2026-02-10)

    • Named argument syntax: identifier ":" expression — parses correctly
    • All function_exp patterns use this form — verified across recurse/parallel/spawn/timeout/cache
    • Ori Tests: Named args verified through pattern tests
  • Audit: Recurse pattern — grammar.ebnf § function_exp [done] (2026-02-10)

    • recurse(condition: n -> n > 0, base: 1, step: n -> n - 1) — parses correctly (verified via ori parse)
    • With memo: recurse(..., memo: true) — parses correctly [done] (2026-02-13)
  • Audit: Parallel pattern — grammar.ebnf § function_exp [done] (2026-02-10)

    • parallel(tasks: [...], max_concurrent: 4) — parses correctly (verified via ori parse)
    • With timeout: parallel(tasks: [...], timeout: 10s) — parses correctly [done] (2026-02-13)
  • Audit: Spawn pattern — grammar.ebnf § function_exp [done] (2026-02-10)

    • spawn(tasks: [...], max_concurrent: 10) — parses correctly (verified via ori parse)
  • Audit: Timeout pattern — grammar.ebnf § function_exp [done] (2026-02-10)

    • timeout(op: expr, after: 5s) — parses correctly (verified via ori parse)
  • Audit: Cache pattern — grammar.ebnf § function_exp [done] (2026-02-10)

    • cache(key: k, op: 42, ttl: 1h) — parses correctly (verified via ori parse)
  • Audit: With pattern (RAII) — grammar.ebnf § function_exp [done] (2026-02-14)

    • with(resource: expr, body: f -> ...) — parses correctly with named args (verified via ori parse)
    • with(acquire: expr, action: f -> ..., release: f -> ...) — parses correctly [done] (2026-02-14). Spec uses action: not use: (because use is a reserved keyword)
    • Note: with keyword disambiguated correctly: with Ident = → capability provision, with( → RAII pattern

0.6.3 Type Conversion Patterns

  • Audit: Type conversion calls — grammar.ebnf § function_val [done] (2026-02-10)
    • int(x), float(x), str(x), byte(x) — all parse correctly (verified via ori parse)
    • Ori Tests: tests/spec/expressions/type_conversion.ori — if exists; verified parsing via temp files

0.6.4 Channel Constructors

  • Audit: Channel creation — grammar.ebnf § channel_expr [done] (2026-02-14)
    • channel<int>(buffer: 10) — FIXED [done] (2026-02-14): Added FunctionExpKind::Channel variants + parse_channel_expr with generic type args
    • channel_in<T>(buffer: 5), channel_out<T>(buffer: 5) — FIXED [done] (2026-02-14)
    • channel_all<T>(buffer: 5) — FIXED [done] (2026-02-14)
    • channel(buffer: 10) — still works (no generics)

0.6.5 Match Patterns

  • Audit: Literal patterns — grammar.ebnf § literal_pattern [done] (2026-02-10)

    • Int: 42, -1 — parses correctly in match arms
    • String: "hello" — parses correctly in match arms
    • Bool: true, false — parses correctly in match arms
    • Char: 'a' — parses and evaluates correctly [done] (2026-02-14)
    • Verified: match 42 { 42 -> 1, _ -> 0 } parses correctly (via ori parse)
  • Audit: Identifier pattern — grammar.ebnf § identifier_pattern [done] (2026-02-10)

    • x (binds value) — parses correctly (verified via ori parse)
  • Audit: Wildcard pattern — grammar.ebnf § wildcard_pattern [done] (2026-02-10)

    • _ — parses correctly in match arms (verified via ori parse)
  • Audit: Variant patterns — grammar.ebnf § variant_pattern [done] (2026-02-10)

    • Red, Green, Blue — unit variants parse correctly in match arms (verified via ori parse)
    • Some(x), Ok(value), Err(e) — parses correctly with named-field sum types [done] (2026-02-13)
  • Audit: Struct patterns — grammar.ebnf § struct_pattern (partial) [done] (2026-02-10)

    • { x, y } — parses correctly in match arms (verified via ori parse)
    • { x: px, y: py } — parses correctly [done] (2026-02-13)
    • With rest: { x, .. } — parses and evaluates correctly [done] (2026-02-14)
  • Audit: Tuple patterns — grammar.ebnf § tuple_pattern [done] (2026-02-10)

    • (a, b), (x, y, z) — parse correctly in match arms (verified via ori parse)
  • Audit: List patterns — grammar.ebnf § list_pattern [done] (2026-02-10)

    • [a, b, c] — parses correctly in match arms (verified via ori parse)
    • [head, ..tail] — parses correctly (verified via ori parse)
    • Rest only: [..], [..rest] — parses correctly [done] (2026-02-13)
  • Audit: Range patterns — grammar.ebnf § range_pattern [done] (2026-02-10)

    • 1..10 — parses correctly in match arms (verified via ori parse)
    • 'a'..='z' — char range patterns parse and evaluate correctly [done] (2026-02-14)
  • Audit: Or patterns — grammar.ebnf § or_pattern [done] (2026-02-10)

    • 1 | 2 — parses correctly in match arms (verified via ori parse)
    • Some(1) | Some(2) — variant or-patterns parse correctly [done] (2026-02-13)
  • Audit: At patterns — grammar.ebnf § at_pattern [done] (2026-02-10)

    • x @ 42 — parses correctly in match arms (verified via ori parse)
    • list @ [_, ..] — parses correctly [done] (2026-02-13)

0.6.6 Binding Patterns

  • Audit: Identifier bindings — grammar.ebnf § binding_pattern [done] (2026-02-14)

    • Mutable: let x = 42 — parses correctly (verified via ori parse)
    • Immutable: let $x = 42 in function body — parses and evaluates correctly [done] (2026-02-14)
    • Wildcard: _ — parses correctly (verified in for loops and match arms)
  • Audit: Struct destructure — grammar.ebnf § binding_pattern [done] (2026-02-14)

    • let { x, y } = Point { ... } — parses correctly (verified via ori parse)
    • let { x: px, y: py } = ... — parses correctly [done] (2026-02-13)
    • Immutable: let { $x, $y } = ... — parses and evaluates correctly [done] (2026-02-14)
  • Audit: Tuple destructure — grammar.ebnf § binding_pattern [done] (2026-02-14)

    • let (a, b) = (1, 2) — parses correctly (verified via ori parse)
    • let ($a, $b) = ... — parses and evaluates correctly [done] (2026-02-14)
  • Audit: List destructure — grammar.ebnf § binding_pattern [done] (2026-02-14)

    • let [head, ..tail] = [1, 2, 3] — parses correctly (verified via ori parse)
    • let [$first, $second, ..rest] = ... — parses and evaluates correctly [done] (2026-02-14)

0.7 Constant Expressions

SPEC: grammar.ebnf § CONSTANT EXPRESSIONS, spec/12-constants.md, spec/24-constant-expressions.md

  • Audit: Literal const expressions — grammar.ebnf § const_expr [done] (2026-02-10)

    • let $A = 42, let $B = true, let $C = "hello" — all parse correctly (verified via ori parse)
  • Audit: Arithmetic const expressions — grammar.ebnf § const_expr [done] (2026-02-14)

    • let $D = $A + 1, let $E = $A * 2 — parses correctly (verified via ori parse)
    • Fix: Replaced parse_literal_expr() with parse_expr() in constant initializer parsing
  • Audit: Comparison const expressions — grammar.ebnf § const_expr [done] (2026-02-14)

    • let $F = $A > 0 — parses correctly (verified via ori parse)
  • Audit: Logical const expressions — grammar.ebnf § const_expr [done] (2026-02-14)

    • let $G = $A && $B — parses correctly (verified via ori parse)
  • Audit: Grouped const expressions — grammar.ebnf § const_expr [done] (2026-02-14)

    • let $H = ($A + 1) * 2 — parses correctly (verified via ori parse)

0.8 Section Completion Checklist

STATUS: In Progress — Re-verified 2026-02-14. 8/10 checklist items complete, 2 blocked. Remaining: 0.4 audit (blocked-by:19, only impl Trait), 0.6 audit (blocked-by:23, only runtime enforcement). All unblocked parser work is complete. 3176 Ori tests pass, 1443 Rust tests pass.

  • All lexical grammar items audited and tested (0.1) [done] (2026-02-10)
  • All source structure items audited and tested (0.2) [done] (2026-02-13) — file attributes, extern as, C variadics all work now
  • All declaration items audited and tested (0.3) [done] (2026-02-14) — 92/92 checkboxes complete; typed constants, const generics, floating tests, clause params, guard clauses, variadic params all work
  • All type items audited and tested (0.4) — 30/34 complete; only impl Trait remains (0.4.2, 4 items)
  • All expression items audited and tested (0.5) [done] (2026-02-14) — length placeholder # now works; labeled break/continue/for/loop NOW WORK [done] (2026-02-14)
  • All pattern items audited and tested (0.6) — 93/94 complete; only runtime contract enforcement remains (0.6.1, 1 item)
  • All constant expression items audited and tested (0.7) [done] (2026-02-14) — computed constants now work (arithmetic, comparison, logical, grouped)
  • Run cargo t -p ori_parse — all parser tests pass [done] (2026-02-14)
  • Run cargo t -p ori_lexer — all lexer tests pass [done] (2026-02-14)
  • Run cargo st tests/ — 3176 passed, 0 failed, 59 skipped [done] (2026-02-14)

Exit Criteria: Every grammar production in grammar.ebnf has verified parser support with tests.

Remaining Parser Bugs (verified 2026-02-13):

  • Const functions ($name (params)) — rejected
  • Computed constants (let $D = $A + 1) — FIXED [done] (2026-02-14)
  • impl Trait in type position — rejected
  • Associated type constraints (where I.Item == int) — == rejected
  • Floating tests (tests _) — FIXED [done] (2026-02-14)
  • Typed constants (let $X: int) — FIXED [done] (2026-02-14)
  • Channel generic syntax (channel<int>) — FIXED [done] (2026-02-14)
  • Struct rest pattern ({ x, .. }) — FIXED [done] (2026-02-14)
  • .match() method syntax — FIXED [done] (2026-02-14) — desugars expr.match { arms } to match expr { arms } at parser level
  • with() RAII pattern (acquire:/action:/release:) — FIXED [done] (2026-02-14) — was doc error: spec uses action: not use: (use is reserved keyword)
  • Function-level contracts (pre()/post()) — FIXED [done] (2026-02-14)
  • Immutable binding in function body (let $x = 42) — FIXED [done] (2026-02-14)
  • Labeled continue (continue:outer) — FIXED [done] (2026-02-14)
  • Char patterns in match ('a', 'a'..='z') — FIXED [done] (2026-02-14)

Fixed since 2026-02-10 (23 items): File attributes, extern as alias, C variadics, pattern params, guard clauses, default params, variadic params, #repr/#target/#cfg attributes, fixed-capacity lists, length placeholder, try ? inside try { }, const generic type args (Array<int, $N>), const expressions in types, const bounds in where clauses (where N > 0), labeled continue (continue:outer), function-level contracts (pre()/post()), computed constants (let $D = $A + 1), struct rest pattern ({ x, .. }), immutable bindings in function bodies (let $x, let ($a, $b), let { $x }, let [$h, ..]), with() RAII pattern (acquire:/action:/release: — was doc error, spec uses action: not use:), .match() method syntax (expr.match { arms } desugars to match expr { arms })


0.9 Parser Bugs (from Comprehensive Tests)

STATUS: Re-verified 2026-02-13. Many items previously marked “STILL BROKEN” now parse correctly.

POLICY: Skipping tests is NOT acceptable. Every test must pass. If a feature is tested, it must work. Fix the code, not the tests.

This section documents parser-only bugs discovered by the comprehensive test suite. Evaluator/type checker bugs are tracked in Section 23: Full Evaluator Support.

0.9.1 Parser/Syntax Bugs — STILL BROKEN (verified 2026-02-13)

These features fail at the parse phase — the parser does not recognize the syntax.

  • Implement: Const generics parser support [done] (2026-02-13)

    • Parser: $N: int in generic parameters — was already working
    • Syntax: Array<int, $N> — const expressions in type arguments (NEW)
    • Syntax: [int, max $N] — const expressions in fixed-list capacity (NEW)
    • Syntax: where N > 0 — const bounds in where clauses (NEW)
  • Implement: Associated type constraints in where clauses

    • Syntax: where I.Item == intBROKEN: parser expects :, finds ==
  • Implement: Const functions

    • Syntax: $add (a: int, b: int) = a + bBROKEN: parser error
  • Implement: Computed constants [done] (2026-02-14)

    • Syntax: let $D = $A + 1 — parses correctly (constant initializer now uses general expression parser)
  • Implement: impl Trait in type position

    • Syntax: @f () -> impl IteratorBROKEN: parser rejects impl in type
  • Implement: Channel generic syntax [done] (2026-02-14)

    • Syntax: channel<int>(buffer: 10) — FIXED: detect channel identifiers in parse_primary, parse_channel_expr with generic type args
  • Implement: Struct rest pattern in match [done] (2026-02-14)

    • Syntax: { x, .. } — parses and evaluates correctly [done] (2026-02-14)
  • Implement: .match() method syntax [done] (2026-02-14)

    • Syntax: 42.match { ... } — method-style match desugars to match 42 { ... } at parse level [done] (2026-02-14)
  • Implement: Immutable bindings in function bodies [done] (2026-02-14)

    • Syntax: let $x = 42 inside function — parses and evaluates correctly [done] (2026-02-14)
    • Syntax: let ($a, $b) = ... — tuple destructuring with $ [done] (2026-02-14)
    • Syntax: let { $x, $y } = ... — struct destructuring with $ [done] (2026-02-14)
    • Syntax: let [$first, ..rest] = ... — list destructuring with $ [done] (2026-02-14)
  • Implement: Floating tests with _ target [done] (2026-02-14)

    • Syntax: @t tests _ () -> void = ... — parses correctly [done] (2026-02-14)
  • Implement: Typed constants [done] (2026-02-14)

    • Syntax: let $MAX_SIZE: int = 1000 — parses correctly [done] (2026-02-14)
  • Implement: Function-level contracts (pre()/post()) [done] (2026-02-14)

    • Syntax: pre(cond) on function declaration — parses correctly [done] (2026-02-14)
    • Syntax: post(r -> cond) on function declaration — parses correctly [done] (2026-02-14)
    • Syntax: pre(c | "msg") post(r -> c | "msg") — parses correctly [done] (2026-02-14)
    • Enforcement: Runtime contract execution tracked in Section 23
  • Implement: with(acquire:, action:, release:) RAII pattern [done] (2026-02-14)

    • Syntax: with(acquire: expr, action: f -> ..., release: f -> ...) — parses correctly. Spec uses action: not use: (use is reserved keyword)
  • Implement: Labeled continue [done] (2026-02-14)

    • Syntax: continue:outer — parses correctly [done] (2026-02-14)
  • Implement: Char patterns in match [done] (2026-02-14)

    • Syntax: 'a' in match arm — parses and evaluates correctly
    • Syntax: 'a'..='z' range — parses and evaluates correctly

0.9.2 Previously Fixed Bugs — VERIFIED WORKING

These features were previously reported as broken but now parse correctly.

  • Fixed: Guard clauses — @f (n: int) -> int if n > 0 = n [done] (2026-02-13)
  • Fixed: Pattern params — @fib (0: int) -> int = 1 [done] (2026-02-13)
  • Fixed: Default params — @greet (name: str = "World") -> str [done] (2026-02-13)
  • Fixed: Variadic parameters — @sum (nums: ...int) [done] (2026-02-13)
  • Fixed: #repr attribute — #repr("c") [done] (2026-02-13)
  • Fixed: #target attribute — #target(os: "linux") [done] (2026-02-13)
  • Fixed: #cfg attribute — #cfg(debug) [done] (2026-02-13)
  • Fixed: Fixed-capacity list type — [int, max 10] [done] (2026-02-13)
  • Fixed: File-level attributes — #!target(os: "linux") [done] (2026-02-13)
  • Fixed: Extern as alias — @_sin (x: float) -> float as "sin" [done] (2026-02-13)
  • Fixed: C variadics — @printf (fmt: CPtr, ...) -> c_int [done] (2026-02-13)
  • Fixed: Try ? inside try — try { let x = f()? \n Ok(x) } [done] (2026-02-13)
  • Fixed: Length placeholder — list[# - 1] [done] (2026-02-13)
  • Fixed: Spread in function calls — sum(...list) [done] (2026-02-10)
  • Fixed: timeout as identifier — let timeout = 5 [done] (2026-02-10)
  • Fixed: List spread syntax — [...result, i] [done] (2026-02-10)
  • Fixed: Map spread syntax — {...base, "c": 3} [done] (2026-02-10)
  • Fixed: Tuple destructuring in for loops — for (k, v) in m do ... — parser dispatch via is_named_arg_at(2) (commit 0aae9265, verified 2026-02-24)
  • Fixed: Multiple derives — #derive(Eq, Clone, Debug) [done] (2026-02-10)
  • Fixed: as/as? type conversion — 42 as float, "42" as? int [done] (2026-02-10)
  • Fixed: Wildcard pattern in for loops — for _ in 0..n do ... [done] (2026-02-10)
  • Fixed: Context-sensitive pattern keywords — let timeout = 5, let cache = 10 [done] (2026-02-10)

NOTE: Type checker and evaluator bugs have been moved to Section 23: Full Evaluator Support.


Completion Summary

Full Audit Completed: 2026-02-10

Systematic ori parse verification of every grammar production against actual parser behavior.

Previously Fixed (verified working):

  1. div operator in match_multiplicative_op()
  2. Spread in function calls (sum(...list))
  3. Context-sensitive keywords (timeout, parallel, cache as identifiers)
  4. List spread ([...a, ...b]), map spread ({...base, key: val})
  5. Tuple destructure in for (for (k, v) in m)
  6. Multiple derives (#derive(Eq, Clone, Debug))
  7. as/as? type conversion operators
  8. Wildcard in for loops (for _ in range)

Verified Parser Bugs — 24 items originally, 19 fixed, ~5 remain:

  1. Guard clauses (if before =) — parser rejects FIXED [done]
  2. List/pattern params (@fib (0: int)) — parser rejects FIXED [done]
  3. Const generics ($ in generics) — parser rejects FIXED [done] (2026-02-13)
  4. Variadic params (...int) — parser rejects FIXED [done]
  5. #repr/#target/#cfg attributes — unknown attribute error
  6. Associated type constraints (where I.Item == int) — == rejected
  7. Const functions ($name (params)) — parser error
  8. Computed constants (let $D = $A + 1) — FIXED [done] (2026-02-14)
  9. Fixed-capacity lists ([T, max N]) — comma rejected in type
  10. impl Trait in type position — parser rejects
  11. Channel generics (channel<int>) — FIXED [done] (2026-02-14)
  12. Struct rest pattern ({ x, .. }) — .. rejected
  13. .match() method syntax — keyword conflict
  14. with() RAII pattern (acquire:/use:/release:) — named arg rejection
  15. File attributes (#!target(...)) — ! rejected
  16. Extern as alias — rejected
  17. C variadics (... in params) — rejected
  18. Floating tests (tests _) — FIXED [done] (2026-02-14)
  19. Typed constants (let $X: int = 1000) — FIXED [done] (2026-02-14)
  20. Try ? inside try() — rejected
  21. Function-level contracts (pre()/post()) — FIXED [done] (2026-02-14)
  22. Length placeholder (#) — attribute marker conflict
  23. Immutable binding in function body (let $x = 42) — FIXED [done] (2026-02-14)
  24. .match() guard method syntax — RESOLVED: guards now use if syntax (match-arm-comma-separator-proposal)

Known Limitations (Parser works, but semantics incomplete — tracked in Section 23):

  • ?? operator: Parses but evaluator support incomplete
  • Primitive trait methods: Parse but evaluator doesn’t resolve
  • Map indexing semantics: Parses but returns wrong type

Notes

  • This section intentionally overlaps with other roadmap sections
  • Other sections add semantics; this section ensures syntax parses
  • Work can proceed in any order within this section
  • Parser tests should verify both success and error cases
  • Error messages should include spans for IDE integration

Grammar Inconsistencies Identified

The following grammar inconsistencies were identified during the audit and require resolution:

1. Extension Generics (grammar.ebnf § extension_def) — RESOLVED

Resolution: Updated grammar.ebnf to support generics and any type in extensions:

extension_def = "extend" [ generics ] type [ where_clause ] "{" { method } "}" .

This allows:

extend<T: Clone> [T] { ... }           // Angle bracket generics
extend [T] where T: Clone { ... }       // List type with where clause
extend Iterator where Self.Item: Add { ... }

2. Bounded Trait Objects (grammar.ebnf § type) — RESOLVED

Resolution: Added trait_object_bounds production to grammar.ebnf:

type = type_path [ type_args ]
     | trait_object_bounds            /* Printable + Hashable */
     | list_type | fixed_list_type | map_type | tuple_type | function_type
     | impl_trait_type .

trait_object_bounds = type_path "+" type_path { "+" type_path } .

Resolution Status: All grammar inconsistencies resolved.


0.10 Block Expression Syntax (PRIORITY)

Proposal: proposals/approved/block-expression-syntax.md Migration script: scripts/migrate_block_syntax.py

This section blocks all other roadmap work. Every feature built on run()/match()/try() syntax creates migration debt. Complete this before continuing.

Overview

Replace parenthesized function_seq syntax with curly-brace block expressions. Remove run() entirely. Move contracts to function-level pre()/post() declarations.

OldNew
run(a, b, c){ a \n b \n c }
match(expr, P -> e)match expr { P -> e }
try(a, b)try { a \n b }
loop(run(a, b))loop { a \n b }
unsafe(run(a, b))unsafe { a \n b }
run(pre_check: c, body, post_check: r -> c)pre(c) post(r -> c) on function decl

Implementation

Phase 1: Parser — Block Expressions

  • Implement: Newline-as-separator tokenization inside { } blocks — N/A: semicolons-only design decision (2026-02-20)
  • Implement: Block expression parsing ({ block_body }) — semicolons as separators (2026-02-20)
    • Rust Tests: ori_parse/src/tests/parser.rstest_parse_block_expr
    • Ori Tests: tests/spec/expressions/block_scope.ori
  • Implement: Block vs map vs struct disambiguation (2-token lookahead) (2026-02-20)
    • Rust Tests: ori_parse/src/tests/parser.rs — block/map disambiguation
    • Ori Tests: tests/spec/expressions/block_scope.ori
  • Implement: Balanced delimiter continuation rules — N/A: only needed for newline separators (2026-02-20)

Phase 2: Parser — Construct Migration

  • Implement: match expr { arms } syntax (scrutinee before block) (2026-02-20)
    • Rust Tests: ori_parse/src/tests/parser.rs — match block syntax
    • Ori Tests: All spec tests migrated to new syntax
  • Implement: try { block_body } syntax (2026-02-20)
    • Ori Tests: All spec tests migrated to new syntax
  • Implement: loop { block_body } syntax (drop parens) (2026-02-20)
    • Ori Tests: All spec tests migrated to new syntax
  • Implement: unsafe { block_body } syntax (block-only form) (2026-02-21)
    • Rust Tests: Parser unit tests for block syntax + rejection of paren form
    • Ori Tests: tests/spec/capabilities/unsafe_block.ori — 6 test cases
  • Implement: for...do { block_body } and for...yield { block_body } (automatic — blocks are expressions) (2026-02-20)
  • Implement: Remove old run()/match()/try() paren forms from parser (2026-02-20)
    • Rust Tests: Old syntax produces helpful error messages
    • Ori Tests: All AOT and spec tests migrated

Phase 3: Parser — Function-Level Contracts

  • Implement: pre(condition) parsing between return type and = (2026-02-21)
    • Rust Tests: ori_parse/src/grammar/item/function/tests.rs — pre contract parsing (4 tests)
    • Ori Tests: tests/spec/declarations/contracts/pre_basic.ori
  • Implement: post(r -> condition) parsing between return type and = (2026-02-21)
    • Rust Tests: ori_parse/src/grammar/item/function/tests.rs — post contract parsing (4 tests)
    • Ori Tests: tests/spec/declarations/contracts/post_basic.ori
  • Implement: Multiple pre()/post() declarations (2026-02-21)
    • Ori Tests: tests/spec/declarations/contracts/multiple_contracts.ori
  • Implement: Message syntax pre(condition | "message") (2026-02-21)
    • Ori Tests: Tests included in pre_basic.ori and post_basic.ori (message variants)
  • Implement: IR changes — PreContract/PostContract structs + pre_contracts/post_contracts fields on Function (2026-02-21)

Phase 4: Migration

  • Run: scripts/migrate_block_syntax.py on all documentation (.md files) (2026-02-20)
  • Manual: Migrate pre_check:/post_check: references to function-level pre()/post() (2026-02-21) — README examples, parser context comment, design doc
  • Run: scripts/migrate_block_syntax.py on all .ori test files (2026-02-20)
  • Update: grammar.ebnf with new block/match/try rules (2026-02-20)
  • Update: .claude/rules/ori-syntax.md with new syntax (2026-02-20)
  • Update: Spec files with new syntax (2026-02-20)
  • Verify: ./test-all.sh passes with new syntax (10,219 tests passing) (2026-02-20)

Phase 5: Formatter

  • Implement: Blank-line-before-result enforcement (2026-02-21)
    • Block and try-block: emit blank line before result when 2+ statements precede it
    • Spec rule: 16-formatting.md:74-85
  • Implement: Match trailing comma on every arm (2026-02-21)
    • Always emit comma after every arm including last (spec: 16-formatting.md:786)
  • Update: Golden tests updated to match new formatting (19 files) (2026-02-21)
  • Implement: Contract formatting (pre/post between signature and =)
    • IR unblocked: Function now has pre_contracts/post_contracts fields (2026-02-21)
    • Still blocked: formatter needs contract emit logic (depends on 15D contract enforcement design)
  • Fix: Formatter double-emits $ for immutable local bindings (2026-02-21)
    • emit_stmt() emits let $ AND emit_binding_pattern() emits $ → produces let $$x
    • Root cause: $ prefix emitted in two independent locations (stacked.rs:211, patterns.rs:135-137)
    • Parser is correct (strips $, sets Immutable); formatter had the bug
    • Fix: Removed $ from emit_stmt in all 3 renderers (stacked, inline, broken); emit_binding_pattern is sole owner

Phase 6: Dead Code Cleanup — FunctionSeq::Run Removal

Completed as part of Block Unification plan (plans/block_unify/), commit 01c43e21. Removed FunctionSeq::Run, SeqBinding, CheckExpr, CheckRange and all downstream consumers across 37 files in 9 crates. FunctionSeq reduced from 4 → 3 variants (Try, Match, ForPattern).

  • Remove: FunctionSeq::Run variant from ori_ir/src/ast/patterns/seq/mod.rs (2026-02-20)
  • Remove: Formatter dead paths (2026-02-20):
    • ori_fmt/src/formatter/stacked.rsemit_function_seq() Run arm + emit_run_with_checks()
    • ori_fmt/src/rules/run_rule.rs — entire module (RunRule, RunContext, is_run())
    • ori_fmt/src/width/mod.rsFunctionSeq::Run arm in width calculation
  • Remove: Type checker dead paths: ori_types/src/infer/expr/sequences.rs, ori_types/src/infer/expr/mod.rs (2026-02-20)
  • Remove: Canon lowering dead paths: ori_canon/src/lower/sequences.rs (2026-02-20)
  • Remove: Incremental copier dead paths: ori_parse/src/incremental/copier.rs (2026-02-20)
  • Remove: Visitor dead paths: ori_ir/src/visitor.rs (2026-02-20)
  • Remove: Test references: ori_fmt/src/width/tests.rs, ori_ir/src/ast/patterns/seq/tests.rs, ori_types/src/infer/expr/tests.rs (2026-02-20)
  • Verify: ./test-all.sh passes after removal (10,215+ tests passing) (2026-02-20)