DEV Community

COMMENTERTHE9
COMMENTERTHE9

Posted on • Originally published at cx-lang.com

Cx Dev Log — 2026-03-19

Semantic Interference Complete: Cx Runtime Hits Major Milestone

The verification matrix now shows a perfect 47/47, indicating that every test passes with the runtime executing fully through SemanticProgram. This marks the end of raw AST interpretation for all supported constructs. Semantic interpreter Phase 2 just landed with two significant commits on submain, marking a major milestone on the path to version 0.1.

What Landed

Two pivotal commits took the verification matrix from incomplete to flawless.

The first major commit (369a2e9) involved 693 net insertions across 9 files, fundamentally altering the runtime. The execution now primarily uses run_semantic_stmt and eval_semantic_expr in runtime.rs, which process SemanticStmt and SemanticExpr instead of raw AST nodes. We've introduced a semantic_funcs registry that holds SemanticFunction objects for correct dispatch. Handle operations like HandleNew, HandleVal, and HandleDrop have realized true arena semantics. Method calls, struct instantiation, enum matching, and all forms of control flow are now processed through the semantic pathway.

On the analyzer side, semantic.rs gained awareness of generic parameters and solved the age-old ambiguity between TypeParam and Struct for bare identifiers—always parsing them as Type::Struct and resolving to TypeParam in generic contexts. The jumble around duplicate StructDef handling was sorted this time, and new IR nodes (IfElse, WhileIn, SemanticWhileInChain) were established as essential semantic types.

Additionally, main.rs was revamped so run_with_interpreter could take SemanticProgram directly. There’s a new pre-pass that registers structs, functions, and impl blocks from semantic IR, bridging function registration between semantic and legacy registries amid ongoing migration.

That commit shot the matrix up to 44/47. Three complex failures lingered in deeper stubs.

The second commit (c730bd7) was smaller but packed a punch with 69 net insertions over 4 files:

  • Introduced recursive array element coercion in types_compatible.
  • TypedAssign finally uses current_type_params, ensuring generic variable declarations resolve correctly.
  • A new function, substitute_type_params, resolves generic return types at the call site—making sure fnc identity(x: T): T called with an i64 returns SemanticType::I64.
  • SemanticType::Array(usize, Box) now exists, giving array types a complete path—declaration, assignment, function return, and type compatibility.
  • Handle operations in the runtime were upgraded from stubs to live implementations with stale detection through RuntimeError::StaleHandle.
  • A parsing order fix positioned handle_drop and handle_val before method_call, addressing a precedence issue where handle syntax was mistakenly consumed as method calls.

Key Decisions

Arrays as First-Class Citizens. Previously, arrays were basically a wild card with SemanticType::Unknown, raising havoc with type checking. With the new Array type, they flow through the semantic process transparently.

Generic Return Type Substitution. This happens at call sites, not definitions, preventing broken downstream type checks when dealing with generic function results.

Real Handle Operations. The runtime now effectively manages handles with actual arena operations, closing the gap between IR and runtime behavior.

Parser Ordering and Handle Syntax. Initially, the parser was greedily munching handle syntax as method calls. The fix addressed the priority to handle this correctly.

Current State

The submain branch remains unmerged with main. It's two commits ahead, along with previous work from structure sprints, operators, generics v1, and semantic parity Phase 1. The merge looms larger and more hazardous the longer it's delayed, with 1578 insertions and 1959 deletions across 35 files to consider.

While the old AST interpretation code persists, it's no longer in use and its removal is the final check under the Semantic/Interpreter Parity on the frontend roadmap.

What's Next

Immediate tasks are clear-cut. Merging submain into main will enable CI to run against our true language state. Once the dormant AST interpreter path is axed, semantic parity will be officially closed. Following this, the path to 0.1 is wide open: multi-file imports, generics v2 finalization, and backend Phase 6 (focusing on function call lowering) can advance on a stable semantic ground. The backend work, in particular, stands to gain tremendously from a firm semantic layer, allowing confident consumption of the semantic IR.


Follow the Cx language project:

Originally published at https://cx-lang.com/blog/2026-03-19

Top comments (0)