Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/elfrask/cls/llms.txt

Use this file to discover all available pages before exploring further.

CLS is designed around a strict separation of concerns: language logic, execution, and deployment environment are three fully decoupled layers that never reach across each other’s boundaries. cls-core knows only about tokens, ASTs, types, and diagnostics — it has no filesystem access and no opinion about where code comes from. cls-runtime knows how to execute an AST and what a Value is, but it never reads a file or opens a socket directly. The nodes — clx and clxr — are the narrow integration points that wire everything together for a specific environment by injecting resolvers, stdlib modules, and I/O capabilities.

Layer Diagram

┌─────────────┐    ┌──────────────┐    ┌───────────────┐
│   cls-core   │    │  cls-runtime  │    │  clx / clxr   │
│  (compiler)  │───▶│  (executor)   │───▶│   (nodes)     │
│ lexer, parser│    │ interpreter   │    │ CLI, modules, │
│ type checker │    │ stdlib, VFS   │    │ LSP server    │
│ optimizer    │    │ intrinsics    │    │ package mgmt  │
└─────────────┘    └──────────────┘    └───────────────┘
Data flows left to right: source text enters cls-core, becomes an AST, travels to cls-runtime for execution, and the node provides everything the runtime cannot see — which files to read, which network calls to allow, and where to print errors.

cls-core

cls-core is the pure language crate. It accepts source text, produces tokens and an AST, and optionally runs middleware passes. It has zero filesystem or network I/O. Crate layout:
cls-core/src/
├── frontend/     # Lexer, Parser, AST node types, Token definitions
├── middleware/   # TypeChecker, NameResolver, Optimizer
├── config/       # ModuleManifest (cls.json parser), TypesConfig
├── backend/      # JSON AST dump; WASM codegen (planned)
├── error/        # ClsError, Span, Diagnostic, error formatting
└── ansi/         # Centralised ANSI color constants

Frontend

Lexer converts source text to a SpannedToken stream, handling string delimiters, CMX markup, and # comments inline.Parser is a recursive-descent parser that builds typed AST nodes (Module, Statement, Expression) from the token stream.

Middleware

TypeChecker validates type annotations, resolves generics, and reports diagnostics without modifying the AST.NameResolver ensures every identifier is declared before use.Optimizer performs AST-level rewrites (constant folding infrastructure is present, though the folding pass is planned).
Middleware is entirely optional and compile-time only — the tree-walker interpreter operates directly on the raw AST and does not require any middleware pass to have run first.

cls-runtime

cls-runtime is the execution crate. It contains the tree-walker interpreter, the Value enum, the scoped Environment, and the core standard library. Like cls-core, it has no direct I/O — every capability is injected by the node. Crate layout:
cls-runtime/src/
├── interpreter.rs     # Tree-walking AST executor
├── value.rs           # Value enum (Int, Float, String, Bool, Array, Record, …)
├── environment.rs     # Scoped variable store
├── resolver.rs        # ModuleResolver trait (implemented by nodes)
├── error_report.rs    # Error formatting (Plain / Console / Html / Json)
├── stdlib/            # math, json, async, primitive (per-type methods)
├── vfs/               # VFS with res://, app://, user://, tmp:// protocols
├── clslib.rs          # .clslib index
├── modules.rs         # ModuleManager
└── gc.rs              # GC stub
The ModuleResolver trait is the key abstraction: the runtime calls it to resolve import "module" paths, but it never knows whether the resolver reads from a file, a zip archive, an in-memory map, or a registry. That decision belongs entirely to the node.

Nodes: clx and clxr

A node is a binary that configures the runtime for a specific environment. It:
  1. Registers intrinsics (print, input, exit, etc.) in the initial environment.
  2. Configures a ModuleResolver that knows how to locate .clsx source files, .clsapp zips, and standard library modules.
  3. Injects node-local modules (fs, http, Lib) that the runtime and core never reference directly.
  4. Decides where and how to report errors (console, JSON, HTML).

clx — Development CLI

clx is the full development toolchain. Its subcommands:
SubcommandDescription
new <name>Scaffold a new CLS project
run [file]Execute a .clsx file
check [file|dir]Run type checker and name resolver
build [file]Package into a .clsapp zip
maptype [path]Generate .type.json type maps
ast <file> --jsonDump AST as JSON
replInteractive REPL
add / remove / installDependency management
lspStart the LSP server

clxr — Lightweight Runtime

clxr is the production executor. It can run .clsx source files and .clsapp packaged applications, but exposes none of the development tooling. It is the binary you distribute alongside a .clsapp.
clxr app.clsx        # Run source directly
clxr app.clsapp      # Execute a packaged application

Module System Architecture

CLS has two orthogonal module systems that coexist without interfering:

System A — Source Modules

import "mod" loads .clsx source or a stdlib name. Resolved by the pluggable ModuleResolver. During clx build, all resolved module ASTs are serialised into the .clsapp zip and accessible at runtime via the res:// VFS protocol.

System B — Compiled Libraries

Lib.load("./lib.clslib") loads a .clslib zip containing .clbin WASM bytecode (planned). Resolved by a separate ClsLibResolver. A .clslib ships alongside a .clsapp, not inside it — equivalent to a .dll or .so.
The core and runtime never know where a module comes from. The node configures both resolvers and injects them at startup.

Workspace Crate Structure

cls/
├── cls-core/              # Language core (lexer, parser, AST, middleware)
├── cls-runtime/           # Execution engine (interpreter, stdlib, VFS)
│   └── clsi/              # Built-in type interface files
├── nodos/
│   ├── clx/               # Development CLI node
│   │   └── src/
│   │       ├── subcommands/   # run, check, build, maptype, lsp, repl, …
│   │       ├── modules/       # fs, http, Lib (node-local modules)
│   │       ├── lsp.rs         # LSP server implementation
│   │       └── type_defs.rs   # .clsi parser for LSP completions
│   └── clxr/              # Runtime executor node
├── docs/                  # Documentation
├── examples/              # Example scripts
└── .vscode/extensions/ccls-lang/  # VS Code extension
The workspace is a standard Cargo workspace. Build the development CLI with cargo build -p clx and the runtime executor with cargo build -p clxr.

Build docs developers (and LLMs) love