Skip to main content

konjure_lang/catalog/
values.rs

1//! Primitive references reuse doc comments captured at the Rust Value variants.
2use super::{BuiltinDefinition, ExampleSpec};
3
4macro_rules! value_references {
5    ($( $name:literal => $variant:ident, $category:literal, $declaration:literal, $representation:literal,
6        [$($example:expr),+ $(,)?]; )*) => {
7        fn primitive_definitions() -> Vec<BuiltinDefinition> {
8            vec![$(BuiltinDefinition {
9                name: $name, category: $category, kind: "type", declaration: $declaration,
10                docs: crate::value::value_documentation(stringify!($variant)),
11                status: "runtime", members: &[], examples: &[$($example),+],
12                rust_path: concat!("/sdk/rust/konjure_lang/enum.Value.html#variant.", stringify!($variant)),
13                representation: $representation,
14            }),*]
15        }
16    };
17}
18
19value_references! {
20    "Number" => Number, "Values", "Number", "Value::Number(f64); one finite Rust f64 per language value.",
21    [ExampleSpec {title: "Calculate a distance", description: "Change either side length and inspect the hypotenuse.", source: "let x: Number = 3;\nlet y: Number = 4;\nlet squared = ((x * x)? + (y * y)?)?;\nprint(squared.sqrt()?);", output: &["5"], ticks: 0, presentation: "snippet"}];
22    "Bool" => Bool, "Values", "Bool", "Value::Bool(bool); conditions never coerce numbers or strings.",
23    [ExampleSpec {title: "Combine conditions", description: "The right side of and is skipped when ready is false.", source: "let ready: Bool = false;\nprint(ready and ((-1).sqrt()? > 0));\nprint(ready or true);", output: &["false", "true"], ticks: 0, presentation: "snippet"}];
24    "Str" => Text, "Values", "Str", "Value::Text(konjure_sdk::data::Str); shared immutable UTF-8 text.",
25    [ExampleSpec {title: "Join and measure text", description: "The accented character counts as one scalar value even though it uses two UTF-8 bytes.", source: "let name: Str = \"café\";\nprint(\"hello \" + name);\nprint(name.len());", output: &["hello café", "4"], ticks: 0, presentation: "snippet"}];
26    "String" => Text, "Values", "String = Str", "Compatibility spelling of Str; new source uses Str.",
27    [ExampleSpec {title: "Read existing source", description: "The compatibility spelling resolves to the same immutable text type.", source: "let legacy: String = \"text\";\nlet text: Str = legacy;\nprint(text);", output: &["text"], ticks: 0, presentation: "snippet"}];
28    "Bin" => Bin, "Values", "Bin", "Value::Bin(konjure_sdk::data::Bin); shared immutable byte storage.",
29    [ExampleSpec {title: "Keep bytes distinct from text", description: "Encoding is explicit; byte length and Unicode scalar count differ.", source: "let text: Str = \"café\";\nlet data: Bin = text.utf8();\nprint(text.len());\nprint(data.len());\nmatch data.decode() { Ok(value) => print(value), Err(error) => print(error), };", output: &["4", "5", "café"], ticks: 0, presentation: "snippet"}];
30    "Tensor" => Tensor, "Collections", "Tensor[T]", "Value::Tensor(konjure_sdk::data::Tensor); a numeric dtype, shape, strides and shared packed storage.",
31    [ExampleSpec {title: "Slice a matrix", description: "A slice is an immutable view; indexing with one integer per axis returns a typed scalar.", source: "let values: Tensor[i32] = tensor[i32]([1, 2, 3, 4, 5, 6], [2, 3])?;\nlet columns = values[:, 1:]?;\nprint(columns.shape());\nprint(columns.get([1, 0]));", output: &["[2, 2]", "Some(5)"], ticks: 0, presentation: "snippet"}];
32    "List" => List, "Collections", "List[T]", "Value::List(Vec<Value>); static T and runtime validation enforce homogeneous elements.",
33    [ExampleSpec {title: "Append without changing the original", description: "append returns a new list. Change the appended value and compare both lists.", source: "let values: List[Number] = [2, 4];\nlet longer = values.append(6);\nprint(values.len());\nfor value in longer { print(value); }", output: &["2", "2", "4", "6"], ticks: 0, presentation: "snippet"}];
34    "Unit" => Unit, "Values", "Unit", "Value::Unit; a Rust enum variant with no payload.",
35    [ExampleSpec {title: "Return from a procedure", description: "The procedure logs its work; its result is the empty value ().", source: "func notify() -> Unit {\n  print(\"ready\");\n  ret;\n}\nprint(notify());", output: &["ready", "()"], ticks: 0, presentation: "snippet"}];
36    "Entity" => Entity, "Entities", "Entity", "Value::Entity(u64); stable interpreter identity, not a pointer or a Rust SDK Entity struct.",
37    [ExampleSpec {title: "Share an entity identity", description: "Both handles address the same entity, so the update through alias is visible through item.", source: "type Counter { value: Number = 0; }\nlet item: Entity = spawn(Counter {});\nlet alias = item;\nset(alias, Counter { value: 4 });\nprint(get[Counter](item).value);", output: &["4"], ticks: 0, presentation: "snippet"}];
38    "ComponentReference" => ComponentReference, "Entities", "ComponentReference[T]", "Value::ComponentReference(ComponentReference); an entity ID and canonical component type resolved at invocation.",
39    [ExampleSpec {title: "Capture a live component method", description: "Calling advance updates the stored component, rather than a copied receiver.", source: "type Counter {\n  value: Number = 0;\n  func advance() -> Res[Unit, DataError] {\n    self.value = (self.value + 1)?;\n    ret Ok(());\n  }\n}\nlet item = spawn(Counter {});\nlet reference: ComponentReference[Counter] = bind[Counter](item);\nlet advance = reference.advance;\nadvance()?;\nprint(get[Counter](item).value);", output: &["1"], ticks: 0, presentation: "snippet"}];
40}
41
42macro_rules! contextual_references {
43    ($( $(#[doc = $doc:literal])* $constant:ident => $name:literal, $category:literal, $kind:literal, $declaration:literal,
44        $representation:literal, $example:expr; )*) => {
45        $(
46            $(#[doc = $doc])*
47            pub const $constant: BuiltinDefinition = BuiltinDefinition {
48                name: $name, category: $category, kind: $kind, declaration: $declaration,
49                docs: concat!($($doc, "\n",)*), status: "runtime", members: &[], examples: &[$example],
50                rust_path: concat!("/sdk/rust/konjure_lang/catalog/values/constant.", stringify!($constant), ".html"), representation: $representation,
51            };
52        )*
53        fn contextual_definitions() -> Vec<BuiltinDefinition> {
54            vec![$($constant),*]
55        }
56    };
57}
58contextual_references! {
59    /// The mathematical constant pi, available as a Number.
60    ///
61    /// pi is a finite binary64 approximation. Angles passed to sin and cos are
62    /// radians; one full turn is 2 * pi. The name is available in ordinary expressions.
63    PI => "pi", "Math", "constant", "pi: Number",
64    "The Rust interpreter installs std::f64::consts::PI as a Number binding.",
65    ExampleSpec { title: "Measure a circle", description: "The circumference scales linearly with the radius.", source: "let radius = 2;\nprint(((2 * pi)? * radius)?);", output: &["12.566370614359172"], ticks: 0, presentation: "snippet" };
66    /// The current entity handle inside a system lifecycle callback.
67    ///
68    /// entity identifies the entity whose component join is being processed.
69    /// It is immutable and available in init, frame and done, not at module scope.
70    /// Use it to access other components or schedule removal at the callback boundary.
71    ENTITY => "entity", "Entities", "context", "entity: Entity",
72    "Machine supplies a Value::Entity for the currently executing system join.",
73    ExampleSpec {title: "Inspect the current entity", description: "Step once to see the two entities in creation order.", source: "type Marker {}\nspawn(Marker {});\nspawn(Marker {});\nsystem Inspect of Marker {\n  func frame(dt: Number) -> Unit { print(entity); }\n}", output: &["entity(1)", "entity(2)"], ticks: 1, presentation: "console"};
74    /// Accepted simulation time in seconds inside a system lifecycle callback.
75    ///
76    /// time advances with accepted simulation ticks, not wall-clock time or browser
77    /// rendering. The embedding host chooses the fixed cadence. Failed ticks do
78    /// not publish new time; this immutable binding is unavailable at module scope.
79    TIME => "time", "Values", "context", "time: Number",
80    "Machine supplies accepted simulation seconds as Value::Number.",
81    ExampleSpec {title: "Read simulation time", description: "Step once: time is positive after the first accepted tick.", source: "type Clock {}\nspawn(Clock {});\nsystem Observe of Clock {\n  func frame(dt: Number) -> Unit { print(time > 0); }\n}", output: &["true"], ticks: 1, presentation: "console"};
82    /// The accepted simulation tick number inside a system lifecycle callback.
83    ///
84    /// tick is an immutable Number supplied by the runtime. It counts accepted
85    /// simulation updates; browser animation frames and rejected updates do not
86    /// increment it. It is available only inside init, frame and done callbacks.
87    TICK => "tick", "Values", "context", "tick: Number",
88    "Machine exposes its accepted tick counter as Value::Number.",
89    ExampleSpec {title: "Count accepted updates", description: "Step twice to log 1 and 2. Reset starts a fresh run.", source: "type Clock {}\nspawn(Clock {});\nsystem Observe of Clock {\n  func frame(dt: Number) -> Unit { print(tick); }\n}", output: &["1", "2"], ticks: 2, presentation: "console"};
90    /// The standard module automatically available to every supplied source module.
91    ///
92    /// Use builtin. to qualify prelude types, traits and interpreter functions
93    /// explicitly, or refer to those names without an import. Primitive types,
94    /// pi and callback-only entity/time/tick bindings do not use this qualifier.
95    ///
96    /// builtin is reserved. Its definitions ship inside Rust; it does not fetch
97    /// code, resolve package versions, or grant device permissions.
98    BUILTIN => "builtin", "Modules", "module", "builtin",
99    "The compiler loads catalog::PRELUDE as a reserved module and resolves native registrations in Rust.",
100    ExampleSpec {title: "Qualify builtin names", description: "Both qualified operations use the same prelude and interpreter as unqualified names.", source: "let value = builtin.Vec3 { x: 2 };\nbuiltin.print(value.x);", output: &["2"], ticks: 0, presentation: "snippet"};
101}
102
103pub(super) fn definitions() -> Vec<BuiltinDefinition> {
104    primitive_definitions()
105        .into_iter()
106        .chain(contextual_definitions())
107        .collect()
108}