Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Experimental REPL

x2c repl evaluates a supported subset of x2c in a persistent session. It uses the compiler’s typed syntax and compile-time Lisp evaluator. It does not compile each submission to a native executable.

x2c repl
x2c repl --help
x2c repl --dump --stats

No source file or checkout is needed when using an installed development build. The command reads standard input and accepts no file operands.

Try a session

Enter these submissions in order:

x2c> int total = 10;
ok
x2c> int plus(int x) { return total + x; }
defined plus
x2c> plus(3);
=> 13
x2c> total = 20;
ok
x2c> plus(3);
=> 23

The function calls display => 13 and => 23: later calls read the current value of total. Definitions display defined NAME; initializations and statements display ok. A final expression displays its value using Var.repr, so character and unsigned values retain their printed tags.

Submit one declaration or function at a time. Executable input may contain several statements. Semicolons are required. Incomplete input continues at the ... prompt until it forms a complete submission. Put a multiline if/else in a block when necessary: a complete if can execute before the next line supplies an else.

Inspect and control the session

CommandMeaning
:helpShow session commands.
:symbolsList successfully defined names and their kinds.
:ast plusShow plus’s typed x2c AST.
:lowered plusShow the Lisp forms used to execute plus.
:cancelDiscard incomplete input.
:quitExit, discarding incomplete input.

For the example above, :symbols prints the list template %((function "plus") (value "total")). Typed AST output begins with typed: %(; lowered Lisp is separately labeled lowered:. Inspection does not execute the function, and earlier functions remain inspectable after later submissions. Values have symbol entries but no function AST.

Help and inspection commands preserve incomplete input, including when a command reports an error. Colon commands are recognized on separate lines even inside an incomplete string or comment. Missing names, extra arguments, and unknown commands report errors.

--dump prints each available typed AST and lowered Lisp form to standard error. --stats prints Lisp calls, word-machine entries, and machine errors at exit. The options can be combined.

Supported subset

The current subset includes initialized simple variables, function definitions, integer arithmetic and narrowing, assignment, conditionals, for loops, self recursion, and calls to earlier functions. String values and length, List literals and indexing, and Array construction, mutation, and indexing are exercised by the focused checks.

Redefinition is disabled; assign to an existing variable to change its value. Function replacement and mutually recursive forward declarations are not supported. Names beginning __repl_ are reserved.

Native pointer and ABI operations, arbitrary C libraries, aggregate and type definitions, imports, protocols, user macro/meta definitions, preprocessor directives, and direct Lisp input are outside this subset. Variables need initializers; declarator modifiers, const, and volatile are rejected. Function-local static, extern, and threaded storage are also rejected: the evaluator cannot provide their native lifetime or linkage semantics. Other constructs depend on the existing lowering and may be declined. Full native execution and reference/lifecycle parity are not established; for example, the evaluator loses the distinction between Var void and an empty List. A void function currently displays the lowering’s zero sentinel.

Failure and lifetime

Rejected submissions leave earlier definitions usable. A declaration publishes its names only after all initializers succeed. If a later initializer fails, none of that declaration’s names become available, including through inspection. Effects already made on existing values remain, both for failed initialization and failed statements.

Session storage lives until exit. Submission scratch is reclaimed, but canonical syntax, compiler caches, and evaluator allocations can accumulate. Long sessions do not have a bounded-memory guarantee. A one-million-step Lisp call budget interrupts runaway interpreted evaluation; native callbacks are not a preemptible sandbox.

EOF exits successfully unless input is incomplete, which exits with status

  1. With piped input, any submission or command error makes the final status 1, while later input still runs. In an interactive session, recovered errors do not change a normal exit’s status from 0. Ctrl-C terminates the process; use :cancel to discard pending input and keep working.