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.

Every value that exists at runtime in CLS is a variant of the Value enum defined in cls-runtime/src/value.rs. There are no implicit boxing, wrapper types, or hidden allocations — the interpreter pattern-matches directly on Value for every operation. This single-enum design means the type of any runtime value is always fully known, and every branch of the tree-walking interpreter is exhaustive.

The Value Enum

The complete set of variants, with their Rust inner types:
VariantRust inner typeNotes
Int(i64)64-bit signed integerArithmetic, bitwise ops
Float(f64)64-bit IEEE 754 floatArithmetic
String(String)Owned UTF-8 stringImmutable in method calls
Bool(bool)Rust boolUsed in conditions
Char(char)Rust char (Unicode scalar)Single character
NullExplicit absence of value
VoidReturn value of non-returning functions
Array(Vec<Value>)Dynamic arrayMutable; write-back on mutation
Tuple(Vec<Value>)Immutable arrayNo push/pop/index assignment
Record(HashMap<String, Value>)String-keyed mapStructural type
Fun(FunValue)CallableNative or user-defined
Struct(Box<StructInstance>)Boxed struct instancePositional flat fields
Promise(Promise)Async coroutine handleResolved via poll
Class(Box<ClassDef>)Boxed class definitionCallable: produces Object
Object(Box<ClassInstance>)Boxed class instanceNamed fields + methods
EnumDef(Box<EnumDef>)Boxed enum definitionNamed variants
Enum(Box<EnumValue>)Boxed enum variantHas index for native compilation
Cmx(Box<CmxValue>)Boxed CMX nodeNative JSX-like tree node
UnknownPlaceholder / unresolved type
/// Valores runtime de CLS
#[derive(Debug, Clone, PartialEq)]
pub enum Value {
    // Primitivos
    Int(i64),
    Float(f64),
    String(String),
    Bool(bool),
    Char(char),
    Null,
    Void,

    // Complejos
    Array(Vec<Value>),
    Tuple(Vec<Value>),
    Record(HashMap<String, Value>),
    Fun(FunValue),
    Struct(Box<StructInstance>),
    Promise(Promise),
    Class(Box<ClassDef>),
    Object(Box<ClassInstance>),
    EnumDef(Box<EnumDef>),
    Enum(Box<EnumValue>),

    // Tipos especiales
    Unknown,

    // CMX
    Cmx(Box<CmxValue>),
}

Value Categories

Primitives — by value, no boxing

Int, Float, String, Bool, Char, Null, and Void are carried directly inside the enum variant. Cloning them copies the data. String is an owned String (heap-allocated content, but the Value::String variant itself is not additionally boxed).
let n = 42;        // Value::Int(42)
let f = 3.14;      // Value::Float(3.14)
let s = "hello";   // Value::String("hello")
let b = true;      // Value::Bool(true)
let c = 'A';       // Value::Char('A')
let x = null;      // Value::Null

Collections — primitive-style dispatch

Array, Tuple, and Record are containers but their methods live in static dispatch tables (see Primitive Methods), not on the value itself.
  • Array(Vec<Value>) — ordered, mutable, heterogeneous. Mutating methods (push, pop, etc.) return a new Array value and the interpreter writes it back to the originating variable automatically.
  • Tuple(Vec<Value>) — ordered, immutable. Index assignment (t[0] = x) is a runtime error. Think of it as a fixed-arity record with positional access.
  • Record(HashMap<String, Value>) — unordered, string-keyed map. Structural: two records with the same fields and values are equal.
let arr = [1, 2, 3];       // Value::Array
let tup = (10, 20, 30);    // Value::Tuple
let rec = { name: "Ada" }; // Value::Record

Entities — objects and callable values

Object, Struct, Class, Promise, Fun, EnumDef, and Cmx all carry heap-boxed internal state. They are cloned on assignment like everything else, but identity semantics vary (see Clone Semantics below).

FunValue — Functions and Closures

FunValue is the runtime representation of any callable value. It has a name, an is_async flag, and a FunKind:
pub struct FunValue {
    pub name: String,
    pub kind: FunKind,
    pub is_async: bool,
}

pub enum FunKind {
    /// Native Rust closure
    Native {
        params: Vec<String>,
        func: Arc<dyn Fn(&[Value]) -> ClsResult<Value>>,
    },
    /// User-defined CLS function (AST body + captured environment)
    User {
        params: Vec<Parameter>,
        body: Block,
        closure: Option<Arc<Mutex<Environment>>>,
    },
}
  • FunKind::Native — a Rust closure wrapped in Arc. Used for all built-in functions and primitive method adapters. Cannot be inspected from CLS.
  • FunKind::User — a CLS function parsed from source. The closure field captures the lexical environment at definition time (for closures). When closure is None, the function executes in the current global environment.
// User function — FunKind::User
fn add(a, b) {
    return a + b;
}

// Closure — FunKind::User with captured environment
fn makeCounter() {
    let count = 0;
    return fn() {
        count = count + 1;
        return count;
    };
}

StructInstance — Flat Positional Structs

Struct instances store fields in a Vec<Value> indexed by position, matching the field order of the struct definition. This is analogous to a C struct — no name lookup at runtime, just index access.
pub struct StructInstance {
    pub def_name: String,
    pub fields: Vec<Value>,
}
The def_name is used for display (e.g., Point(1, 2)) and type checking. Field access is resolved by the interpreter using the struct definition stored separately.
struct Point { x, y }
let p = Point(10, 20); // StructInstance { def_name: "Point", fields: [Int(10), Int(20)] }

Promise — Async Coroutines

Promise wraps a Pollable trait object inside an Arc<Mutex<PromiseInner>>. The Arc ensures that cloning a Promise value shares the same underlying coroutine state — exactly like JavaScript Promises.
pub trait Pollable {
    fn poll(&mut self, interp: &mut Interpreter) -> PollState;
}

pub enum PollState {
    Pending,
    Ready(Value),
    Rejected(String),
}
  • Promise::new(pollable) — wraps a coroutine.
  • Promise::resolved(value) — creates an already-settled promise.
  • Promise::rejected(msg) — creates an already-rejected promise.
  • promise.poll(interp) — drives the coroutine one step; caches the result once settled.
Two Promise values compare equal (PartialEq) only if they point to the same Arc — pointer equality, not structural equality. This matches JavaScript semantics.
async fn fetchData() {
    // returns a Promise
}

let p = fetchData();
await p;

EnumDef and EnumValue

Enums are two separate value kinds: the definition and a variant instance.
pub struct EnumDef {
    pub name: String,
    pub variants: Vec<String>,
}

pub struct EnumValue {
    pub def_name: String,
    pub variant: String,
    pub index: u16,  // compiles to 1–2 bytes in native output
}
EnumDef is the callable class-like value you reference by name. Accessing a variant produces an EnumValue. The index field is the ordinal position of the variant in the definition — when CLS compiles to native code, this becomes a u16 tag with no heap allocation.
enum Color { Red, Green, Blue }

let c = Color.Red;   // EnumValue { def_name: "Color", variant: "Red", index: 0 }
let d = Color.Blue;  // EnumValue { def_name: "Color", variant: "Blue", index: 2 }

// Equality compares def_name + variant + index
c == Color.Red;  // true
c == d;          // false
Two EnumValues are only equal if they share the same def_name, variant, and index. An EnumValue from one enum definition will never equal one from another, even if the variant names happen to match.

CmxValue — Native JSX Nodes

CmxValue is the runtime representation of a CMX element (CLS’s native JSX-like syntax):
pub struct CmxValue {
    pub tag: Value,
    pub props: HashMap<String, Value>,
    pub children: Vec<Value>,
}
  • tag is a Value::String for lowercase tags (<div>) or any other Value (a reference to a variable, function, or class) for uppercase component tags (<MyComponent>).
  • props is a flat string-keyed map of attribute values.
  • children is an ordered list of child nodes (which may themselves be CmxValue or any other Value).
let el = <div class="box">
    <span>Hello</span>
</div>;
// CmxValue { tag: String("div"), props: { "class": "box" }, children: [...] }

Value Methods

Every Value exposes three instance methods used throughout the interpreter:
MethodReturn typeDescription
type_name()&'static strThe type name string: "Int", "String", "Array", etc. Both EnumDef and Enum return "Enum".
is_truthy()boolFalsy/truthy evaluation for conditionals
to_string()StringHuman-readable representation
Value also derives PartialEq, enabling == comparisons throughout the interpreter.

Truthiness Rules

CLS has explicit falsy values. Everything else is truthy.
ValueTruthy?Notes
Bool(false)❌ Falsy
Bool(true)✅ Truthy
Int(0)❌ Falsy
Int(n) where n ≠ 0✅ Truthy
Float(0.0)❌ Falsy
Float(f) where f ≠ 0.0✅ Truthy
String("")❌ FalsyEmpty string
String(s) non-empty✅ Truthy
Null❌ Falsy
Void❌ Falsy
Array([])❌ FalsyEmpty array
Array([...]) non-empty✅ Truthy
Tuple(())❌ FalsyEmpty tuple
Tuple((..)) non-empty✅ Truthy
Record({})❌ FalsyEmpty record
Record({..}) non-empty✅ Truthy
Object, Struct, Class✅ Always truthy
Promise, Fun✅ Always truthy
EnumDef, Enum✅ Always truthy
Cmx✅ Always truthy
if (0)        { }  // not entered — falsy
if ("")       { }  // not entered — falsy
if ([])       { }  // not entered — falsy
if ("hello")  { }  // entered    — truthy
if (42)       { }  // entered    — truthy

to_string() Output

The to_string() method produces consistent human-readable output across all variants:
ValueOutput example
Int(42)"42"
Float(3.14)"3.14"
String("hello")"hello"
Bool(true)"true"
Char('A')"A"
Null"null"
Void"void"
Array([1, 2])"[1, 2]"
Tuple((10, 20))"(10, 20)"
Record({a: 1})"{a: 1}"
Fun("add")"<function add>"
Struct Point(1, 2)"Point(1, 2)"
Promise"<promise>"
Class("Dog")"<class Dog>"
Object Dog {name: Rex}"<Dog {name: Rex}>"
Enum Color::Red"Red" (variant name only)
EnumDef Color"<enum Color>"
Enum variants display only their variant name (e.g., "Red"), not the full qualified name ("Color.Red"). Use type_name() to get "Enum" when you need the type, or access def_name on the inner EnumValue.

Clone Semantics and Write-Back

All Value instances derive Clone. Every assignment in CLS clones the value:
let a = [1, 2, 3];
let b = a;          // b is a clone — a separate Vec<Value>
b.push(4);          // modifies b; a is unchanged
Array mutating methods (push, pop, shift, unshift, reverse) return the mutated array as a new Value::Array. The interpreter’s evaluate_call performs write-back: when the receiver of a mutating call is an identifier, the returned array is automatically stored back into that variable. You never need to write a = a.push(4).
Objects (ClassInstance) and their fields are also cloned on assignment. Since CLS uses value semantics throughout, there is no reference aliasing between separately-assigned variables — each variable holds its own copy of the data.
class Dog {
    name = "Rex";
}

let d1 = new Dog();
let d2 = d1;          // d2 is a clone of d1
d2.name = "Buddy";    // does NOT affect d1.name

Build docs developers (and LLMs) love