llmlang is a token-optimized programming language designed for LLMs. This guide explains how to use the compiler output to create executable binaries.
llmlang provides a wrapper script llm-clang that integrates directly with the Clang driver. This allows you to compile and link .llm files as if they were .c files.
./llm-clang my_program.llm -o my_program
./my_program# 1. Create source
echo ": main + 40 2" > test.llm
# 2. Build to binary
./llm-clang test.llm -o test_bin
# 3. Run
./test_bin
echo $?
# Output: 42llmlang supports external configuration via command-line flags or a JSON configuration file.
| Flag | Description | Default |
|---|---|---|
-o <path> |
Set output binary/object path. | a.out |
-S, --emit-ir |
Emit LLVM IR instead of binary. | false |
-c, --config <file> |
Load a JSON config file. | None |
--parallel <n> |
Complexity threshold for auto-parallelism. | 50 |
--threads <n> |
Number of worker threads in the pool. | 8 |
--queue <n> |
Work-stealing queue size. | 64 |
You can also use a JSON file for configuration. Flags provided on the CLI will override values in the file.
{
"parallel_threshold": 100,
"max_threads": 4,
"queue_size": 32
}llmlang uses a high-precision temporal model inspired by D.J. Bernstein's libtai. It distinguishes between TAI64 labels (atomic time) and Calendar Time.
- Atomic Now (
tn): Returns the current TAI64 label as ani64. - Get Component (
tg T i): Decomposes a label into human-readable parts (0=Y, 1=M, 2=D, 3=H, 4=m, 5=S). - Set Label (
ts Y M D H m S): Composes a TAI64 label from calendar parts.
Example:
: main
L now tn
L year tg $ now 0
) 1 sc "Current Year: " str > year
llmlang supports modular programming via structural signature files with the .llmi (LLM Interface) extension.
When you compile a module with an output path, llmlang automatically generates a .llmi file. This file contains the signatures of all exported symbols (X) and shape definitions.
- Define Library (
math.llm):X : add x y + $ x $ y - Compile Library:
./llm-clang -c math.llm -o math.o # Generates math.o and math.llmi - Import in Client (
main.llm):I math add : main @2 add 10 20 - Link and Run:
./llm-clang math.o main.llm -o main ./main
llm-clang handles linking multiple .llm and .o files automatically.
For common math functions (sin, cos, abs, etc.), see the llmlang-math implementation. It serves as a reference for creating and importing portable modules.
| Operation | Syntax | Description |
|---|---|---|
| Export | X ... |
Mark a definition for external consumption. |
| Apply | @<n> func args |
Call a function with <n> arguments (defaults to 1). |
| Branch | ? cond t f |
Conditional branch (phi-merge). |
| Move | > ^index |
Consume a variable (Linear Ownership). |
| Borrow | $ ^index |
Read a variable without consuming. |
| De Bruijn | ^0, ^1 |
Reference variables by scope depth. |
| Shape | # Name i64 ... |
Define a Struct of Arrays memory layout. |
| New | N Name count |
Allocate a new SoA instance. |
| Get | G instance f idx |
Load value from SoA column. |
| Set | S instance f idx v |
Store value to SoA column. |
| Let | L name val body |
Create a local binding. |
| Import | I mod symbol |
Import external symbol. |
| Compare | =, lt, gt |
Compare two values (returns 0 or 1). < can also be used for lt. |
| Bitwise | &, |, xor |
Bitwise AND, OR, XOR. |
| String | "text" |
String literal. |
| Len | sl str |
Get string length. |
| Concat | sc s1 s2 |
Concatenate two strings. |
| Sub | ss s start len |
Extract substring. |
| Loc | sf s pat |
Find index of pattern in string. |
| Regex | sr s regex |
Match string against regex. |
| System | ( h, ) h s |
Read/Write to/from file handles. |
| Stringify | str i64 |
Convert integer to string. |
| Split | sp s d idx |
Extract segment by delimiter. |
| JSON | jp inst, ju json "Shape" |
Serialize to/Deserialize from JSON. |
| Map | map inst "f" func |
Map function over SoA column. |
| Filter | flt inst func |
Filter SoA instance by predicate. |
| Money | %+, %-, %*, %/ |
Fixed-point precision math. |
| MoneyStr | %str money |
Format money value to string. |
| Panic | ! message |
Abort execution with error message (also maps to `). |
| Trap | ^ try fall |
Catch panic and run fallback (when not a De Bruijn index). |
| Time | tn, tg, ts |
TAI64 and Calendar primitives. |
| TimeNano | tns |
High-resolution monotonic time (nanoseconds). |
| TimeZone | tz |
Get local timezone name. |
| Env | env key |
Access system environment variables. |
| HTTP Client | http method url body |
Make an HTTP request. |
| HTTP Server | srv op arg |
HTTP server socket manager operations. |
| Metadata | M tag val target |
Attach key-value metadata to a definition. |
| OtelEmit | oe type a1 a2 a3 |
Push telemetry payload to async MPSC queue. |
| Sequence | . e1 e2 |
Evaluate e1 then e2, returning e2. |
# Invoice id amount
: process_tax inv
%* $ inv %1.15 // 15% Tax
: main
L i N Invoice 1
. S $ i id 0 101
. S $ i amount 0 %1000.00
L taxed map > i "amount" process_tax
L total G $ taxed amount 0
L msg sc "Total with Tax: " %str > total
. ) 1 > msg
0
llmlang includes a self-hosted test suite for behavioral verification.
# Run all tests (Rust + llmlang)
cargo test && ./llm-testThe ./llm-test script compiles and runs all test programs in tests/lang/*.llm. You can also run specific tests:
./llm-test tests/lang/math.llmTests are written next to production code as functions tagged with the M "test"
metadata operator — no new keywords. Tagged functions are isolated into a test
execution tree and stripped from the production compilation target.
: add a b
+ $ a $ b
M "test" "addition works" : test_add_ok
? = @2 add 2 3 5
0
! "math broken"
A test passes if it runs to completion and fails if it panics (!); the
runner wraps each execution in a trap (^) and records the panic message. Each
test runs in a fresh process with a re-initialized environment, so no state
leaks between tests. Inside a trap fallback, the last panic message is
available via env "LLM_PANIC_MSG".
# Run a file (or a directory, scanned recursively)
llmlang test tests/harness/pass_suite.llm
# External mock data: injected as TEST_DATA_DIR (default ./tests/data)
llmlang test suite.llm --test-data-dir ./mocks
# Machine-readable output
llmlang test suite.llm --format=jsonTest data is never inlined in the AST — tests load it at runtime with the
existing fo/( (read) and ju (JSON unpack) operators from
env "TEST_DATA_DIR". Exit code is 0 on total success (including "0 tests
found") and 1 on any failure. The same engine backs the run_symbol_tests
MCP tool, which maps failures to AST fingerprints for diagnostic loops (see
MCP_GUIDE.md).
The harness's own validation suite lives at tests/harness/run_harness_tests.sh.
If the compiler outputs a code like E005 or W001, refer to DIAGNOSTICS.md for the human-readable mapping. These codes are optimized to save LLM tokens.
llmlang provides native OTEL span instrumentation with zero boilerplate. Tag a function definition with M "otel" "span_name" and the compiler auto-wraps the body with span entry/exit, timing, and trace context propagation.
M "otel" "handle_request" : handle_request req
+ $ req 1
The compiler generates equivalent logic to:
- Record start time (
llm_get_time_ns) - Enter span (
llm_otel_enter_span) - Execute function body
- Record end time, emit span JSON, exit span
Nested auto-instrumented functions automatically propagate trace context via thread-local storage:
M "otel" "inner" : inner x
+ $ x 1
M "otel" "outer" : outer x
L result @ inner $ x
+ > result 10
| Environment Variable | Behavior |
|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT (unset) |
Spans written to stdout as JSON lines. |
OTEL_EXPORTER_OTLP_ENDPOINT=http://... |
Spans sent via HTTP POST to the endpoint. |
The oe operator pushes payloads directly to the async MPSC queue:
// oe type arg1 arg2 arg3
// type 2 = stdout, type 3 = HTTP POST
oe 2 > payload "" ""
The standard library lib/otel.llm provides the OtelLog shape and emit_span wrapper for structured manual telemetry.