DOCUMENTATION

Documentation

DOCUMENTATION

XCX Compiler Error and Diagnostics System

The XCX compiler incorporates a structured diagnostics pipeline designed to detect, track, and format diagnostic logs for syntax errors, semantic type mismatches, and execution halts.

Data Structures (src/error/)

Core structures categorize error locations, diagnostics severity levels, and print properties.

Spans (span.rs)

Position details are wrapped inside the Span structure:

$ rust
_ ⛶ ×
1pub struct Span {
2 pub line: usize, // 1-based line number in source file
3 pub col: usize, // 0-based column offset in line
4 pub len: usize, // length of token to highlight
5}

Diagnostic Definitions (diagnostic.rs)

Diagnostics map individual report instances via Diagnostic carrying error severity types:

  • Severity (enum): Severity::Error, Severity::Warning, or Severity::Note.
  • Diagnostic (struct): Registers warning/error message strings (message), the target Span, a severity flag, and optional error code slices (code: Option<&'static str>).

Diagnostic and Error Classifications

The compiler maps diagnostics using three distinct series of error codes:

1. Placeholder Code Definitions (E-Series, E101–E304):

Defined in src/error/codes.rs for future compiler and VM VM-level integration, these codes are currently unused placeholders. The primary compiler parser currently raises raw text errors instead of instantiating these variants:

  • Parser & Syntax Checks (100–199): E101 (Unexpected Token), E102 (Missing Semicolon), E103 (Malformed Expression)
  • Semantic Errors (200–299): E201 (Variable already defined), E202 (Variable not found), E203 (Type mismatch), E204 (Function not found)
  • VM / Runtime Errors (300–399): E301 (Stack overflow), E302 (Invalid OpCode), E303 (Table Schema mismatch), E304 (Index out of bounds)

2. Active Semantic Logic Codes (S-Series, S101–S302):

Emitted by the compile-time semantic checking phase (src/sema/error/error_kind.rs). See details in the Semantic Type and Logic Verification section below.

3. Active VM/Runtime Codes (R-Series, R103–R501):

Active diagnostic indicators printed to stderr or triggered as runtime exceptions when logical dynamic assertions fail during script execution. These range from bounds errors to IO exceptions:

  • R103: Input Type Mismatch (e.g. expected type, got float/string at CLI read).
  • R303: Access Index Out of Bounds (Table column indices, String slice offsets, or Array bounds).
  • R304: Missing Column references.
  • R305: Invalid JSON string parsed.
  • R306: Finished Fiber next access / Invalid JSON push.
  • R307: .replace() method empty 'from' search.
  • R401: Database connectivity / missing SQL table exceptions.
  • R403: SQL database query/prepare execution errors.
  • R404: Binding JSON path not found / DB row drop exception.
  • R405–R408: Relational SQL table constraint failures (R405 sync expects a Table, R406 sync failure, R407 wrong argument type, R408 drop failure).
  • R440, R441: Terminal raw mode setup failure / cursor position out of bounds.
  • R501: Unsupported VM instruction/method call index type.

Preprocessor and Lexer Validation Errors

Include File Expansion (src/frontend/parser/expander.rs)

The preprocessor (Expander) resolves include "..." directives before parsing is finalized. If resolved paths fail, it throws formatted errors:

  • File Not Found: If standard paths or include directory trials fail, returns File not found: <filename> (tried: <paths>).
  • Circular Inclusion: Detects nested loop boundaries using call tracking sets, raising Circular dependency detected: <filename>.

C-Style Comment Validation (src/frontend/lexer/lexer.rs)

XCX strictly requires --- for single-line comments and --- ... --- blocks (which are initiated by placing --- alone on a line and terminated by --- on a line of its own). If the lexer scans C-style comment notations (// or /*), it raises a hard compiler abort panic:

$ text
_ ⛶ ×
1[XCX Error] C-style comments (// or /* */) are NOT supported in XCX.
2Use '---' for single-line comments.

VM Execution and Arithmetic Halts (src/vm/)

VM Call and Stack Overflows (src/vm/core/executor.rs)

During bytecode execution, the VM monitors stack limits:

  • Stack Boundaries: If stack_ptr exceeds the execution stack pool limits, the VM outputs ERROR halt: XCX VM Stack Overflow and increments the error_count counter.
  • Recursion Limits: The call hierarchy stack tracks nest levels. If function calls nested frame limits exceed 800 trace frames, execution aborts: ERROR halt: Recursion limit exceeded (800 frames). Since 4.4 the depth counter measures physical (post-inlining) frames, so equivalent programs may recurse deeper than in 4.3.
  • Invalid Method Invocation: Unrecognized method tag kinds yield direct failures: R501: Invalid method kind index: <kind>.

Runtime Cast and Structure Halts (4.4)

  • Failing casts: .toInt() / .toFloat() on a non-numeric string raise halt.error (whitespace-trimmed parse) in both execution modes instead of panicking; the failure increments the error tally, and the process exits with code 1 when the tally is non-zero.
  • JSON push target: push through a JSON path that does not resolve to an array raises halt.error ("push target is not an array") instead of a raw panic.
  • halt.error recovery: a halt.error inside a function with a return type hands the caller the type's proper default value, so execution continues with a well-typed value.
  • Halt parity: halt diagnostics (fatal/error/alert wording) are identical between JIT and interpreter, and fallible JIT fast paths check the same error tally as generic dispatch (see compiler/jit/jit_codegen.md).

Safe FFI Error Reporting

To support safe and consistent exception reporting from JIT-compiled code and FFI modules (such as Array boundary checks R303), the runtime uses a thread-local pointer model:

  • *ACTIVE_VM: Cell<const VM>:** A thread-local cell linking runtime calls back to the executing VM context.
  • ActiveVmGuard: An RAII guard managing ACTIVE_VM registration across VM execution sweeps (run_frame, handle_call_no_jit, and dispatch_jit_call).
  • increment_error_count(): An FFI helper callable from JIT-emitted code or array bounds checks to safely increment runtime error counters, eliminating JIT compile-time execution divergence.

Arithmetic Exception Handlers (src/vm/core/step/arith.rs)

Mathematical divisions evaluate bounds to preempt CPU crashes:

  • Division by Zero: Triggers ERROR halt: division by zero, increments the VM error counter, and issues OpResult::Halt.
  • Modulo by Zero: Triggers ERROR halt: modulo by zero, increments the VM error counter, and issues OpResult::Halt.

Visual Diagnostic Reporter (src/error/reporter.rs)

The Reporter structure frames source buffers to generate colorized, framed terminal diagnostics output.

CLI Formatting Configuration

Using ANSI colors (\x1b[31;1m for Red text, \x1b[33;1m for Yellow highlight, and \x1b[36m for Cyan boundaries), the reporter formats logs:

1. Header Block: Renders the severity level (e.g. ERROR: or WARNING:) followed by compilation messages.

2. Context Framing: Prints target source lines using a centered column line gutter:

$ text
_ ⛶ ×
1 3 | i: val = "hello" + 42;

3. Squiggle Highlights: Creates underline indicators positioned directly offset from the start column:

  • For zero-length error contexts, prints a pointing arrow symbol (^).
  • For non-empty spans, mirrors token lengths using wave squiggles (~).

Semantic Type and Logic Verification (src/sema/error/)

The semantic check module identifies compile-time logic checks:

Error Wrappers (type_error.rs)

Semantic type errors pair type errors payload (TypeErrorKind) with its corresponding ast source Span under the TypeError structure.

Error Catalogs (error_kind.rs)

The TypeErrorKind enum maps precise semantic logic failures:

CodeError CategoryDetails
[S101]Undefined VariableReferencing an undeclared identifier.
[S102]Redefined VariableDeclaring an identical variable in the same block.
[S103]Type MismatchExpected and actual types mismatch.
[S104]Invalid Binary OpAttempting operators between non-matching operand types (e.g. adding INT to STRING).
[S105]Const ReassignmentAttempting to mutate value bound to a const modifier.
[S106]Break Outside LoopIssuing a loop exit break statement outside loop blocks.
[S107]Continue Outside LoopIssuing continue directives outside loop contexts.
[S108]Index Not SupportedAttempting index access on types that do not support indexing.
[S109]Property Not FoundAccessing a property field not defined in structure type mappings.
[S110]Method Not FoundAccessing methods not defined on the target data structure.
[S111]Invalid Argument CountInvoking functions with argument metrics that don't match the signature.
[S208]Yield Outside FiberUtilizing yield syntax outside a fiber body representation.
[S209]Fiber Type MismatchIssuing yield expr; return paths inside empty void fiber blocks.
[S210]Return Mismatch In FiberTyped fibers must use return expr; instead of a blank return;.
[S211]Iterate Over Void FiberPerforming for loop iterations over empty void fibers.
[S212]Run Typed FiberInvoking .run() methods on typed fibers (which require generator iterator loops instead).
[S301]Predicate Name CollisionConflicting naming parameters between local variables and query columns in .where() predicates.
[S302]Table Row Count MismatchInserting row values with item counts that don't match the table columns schema definition.

Two 4.4 additions share the S-series with the entries above: method calls with

more than 16 arguments are rejected at compile time, and .size() called on a

plain string is a compile-time error (the string API exposes .length).