Syntax Reference
Complete reference for Calor syntax. Calor uses Lisp-style expressions for all operations.
Why this syntax? Calor's notation is optimized for AI agents, not human aesthetics. You don't need to learn this syntax—AI coding agents write Calor, not humans. This reference exists to help you understand what the AI generates and verify that contracts match your intent. Each design choice serves verification: unique IDs enable precise references, matched tags eliminate scope ambiguity, and Lisp-style expressions allow direct AST manipulation.
Quick Reference Table
| Element | Syntax | Example |
|---|---|---|
| Module | §M{name} | §M{Calculator} |
| Function | §F{name:visibility} | §F{Add:pub} |
| Async Function | §AF{name:visibility} | §AF{FetchAsync:pub} |
| Method | §MT{name:visibility} | §MT{Process:pub} |
| Async Method | §AMT{name:visibility} | §AMT{ProcessAsync:pub} |
| Await | §AWAIT expr | §AWAIT §C{GetAsync} §/C |
| Lambda (inline) | (params) → expr | (x) → (* x 2) |
| Lambda (block) | §LAM{params} (indented body) | §LAM{x:i32} |
| Delegate | §DEL{name} (indented signature) | §DEL{Handler} |
| Event | §EVT{name:vis:type} | §EVT{Click:pub:EventHandler} |
| Subscribe | §SUB event handler | §SUB btn.Click OnClick |
| Unsubscribe | §UNSUB event handler | §UNSUB btn.Click OnClick |
| Input | §I{type:name} | §I{i32:x} |
| Output | §O{type} | §O{i32} |
| Effects | §E{codes} | §E{cw,fs:r,net:rw} |
| Requires | §Q expr | §Q (>= x 0) |
| Ensures | §S expr | §S (>= result 0) |
| For Loop | §L{var:from:to:step} | §L{i:1:100:1} |
| While Loop | §WH condition | §WH (> i 0) |
| Do-While Loop | §DO (body indented) | §DO then §WHILE cond |
| If/ElseIf/Else | §IF cond then §EI / §EL at same column | §IF (> x 0) |
| Call | §C{target}...§/C | §C{Math.Max} §A 1 §A 2 §/C |
| C# Attribute | [@Name] or [@Name(args)] | [@HttpPost], [@Route("api")] |
§P expr | §P "Hello" | |
| Return | §R expr | §R (+ a b) |
| Binding | §B{name} expr | §B{x} (+ 1 2) |
| Operations | (op args...) | (+ a b), (== x 0) |
| Block end | dedent (Python-style) | (no §/X needed) |
| List | §LIST{id:type} | §LIST{nums:i32} |
| Dictionary | §DICT{id:kType:vType} | §DICT{ages:str:i32} |
| HashSet | §HSET{id:type} | §HSET{tags:str} |
| Key-Value | §KV key value | §KV "alice" 30 |
| Push | §PUSH{coll} value | §PUSH{nums} 5 |
| Put | §PUT{dict} key value | §PUT{ages} "bob" 25 |
| Set Index | §SETIDX{list} idx val | §SETIDX{nums} 0 10 |
| Contains | §HAS{coll} value | §HAS{nums} 5 |
| Count | §CNT{coll} | §CNT{nums} |
| Dict Foreach | §EACHKV{id:k:v} dict | §EACHKV{e1:k:v} ages |
| Switch | §W{id} expr | §W{sw1} score |
| Case | §K pattern → result | §K 200 → "OK" |
| Wildcard | §K _ | §K _ → "default" |
| Relational | §PREL{op} value | §PREL{gte} 90 |
| Var Pattern | §VAR{name} | §VAR{n} |
| Guard | §WHEN condition | §WHEN (> n 0) |
Types
| Type | Description | C# Equivalent |
|---|---|---|
i32 | 32-bit integer | int |
i64 | 64-bit integer | long |
f32 | 32-bit float | float |
f64 | 64-bit float | double |
str | String | string |
bool | Boolean | bool |
void | No return value | void |
?T | Optional T | T? (nullable) |
T!E | Result (T or error E) | Result\<T, E\> |
Operators
| Category | Operators |
|---|---|
| Arithmetic | +, -, *, /, % |
| Comparison | ==, !=, <, <=, >, >= |
| Logical | &&, ||, ! |
All operators use Lisp-style prefix notation: (+ a b), (&& x y)
Effect Codes
| Code | Effect | Description |
|---|---|---|
cw | Console write | Console.WriteLine |
cr | Console read | Console.ReadLine |
fs:w | Filesystem write | File system writes |
fs:r | Filesystem read | File system reads |
fs:rw | Filesystem read/write | File system read and write |
net:r | Network read | HTTP GET, etc. |
net:w | Network write | HTTP POST, etc. |
net:rw | Network read/write | HTTP, sockets, etc. |
db:r | Database read | Database queries |
db:w | Database write | Database mutations |
db:rw | Database read/write | Database operations |
ID Conventions
Stable IDs are optional on structural openers and are auto-assigned
by the parser when omitted. Provide an explicit ID only when you want
to reference the element from external tooling (e.g. calor navigate).
| Element | Auto-assigned form | Explicit form |
|---|---|---|
| Modules | §M{Calculator} | §M{m001:Calculator} |
| Functions | §F{Add:pub} | §F{f001:Add:pub} |
| Loops | §L{i:1:10:1} | §L{for1:i:1:10:1} |
| Conditionals | §IF cond | §IF{if1} cond |
Complete Example
§M{FizzBuzz}
§F{Main:pub}
§O{void}
§E{cw}
§L{i:1:100:1}
§IF (== (% i 15) 0) → §P "FizzBuzz"
§EI (== (% i 3) 0) → §P "Fizz"
§EI (== (% i 5) 0) → §P "Buzz"
§EL → §P iBlocks are delimited by indentation (default 2 spaces per nesting
level). Legacy §/X closers are still accepted for transition
compatibility but should not be used in new code — see
Structure Tags for details.
Detailed Reference
- Structure Tags - Modules, functions, block structure
- Types - Type system, Option, Result
- Bindings -
§Blocal bindings and inference - Calls -
§Ccalls and implicit close - Expressions - Lisp-style operators
- Control Flow - Loops, conditionals
- Contracts - Requires, ensures
- Effects - Effect declarations