@rcrsr/rill 0.15.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -21
- package/dist/ast-nodes.d.ts +2 -13
- package/dist/ast-nodes.js +0 -1
- package/dist/ast-unions.d.ts +0 -1
- package/dist/ast-unions.js +0 -1
- package/dist/constants.d.ts +0 -1
- package/dist/constants.js +0 -1
- package/dist/error-classes.d.ts +0 -1
- package/dist/error-classes.js +0 -1
- package/dist/error-formatter.d.ts +0 -1
- package/dist/error-formatter.js +0 -1
- package/dist/error-registry.d.ts +0 -1
- package/dist/error-registry.js +32 -1
- package/dist/ext/crypto/index.d.ts +3 -4
- package/dist/ext/crypto/index.js +66 -64
- package/dist/ext/exec/index.d.ts +3 -4
- package/dist/ext/exec/index.js +17 -12
- package/dist/ext/exec/runner.d.ts +0 -1
- package/dist/ext/exec/runner.js +0 -1
- package/dist/ext/fetch/index.d.ts +3 -4
- package/dist/ext/fetch/index.js +23 -49
- package/dist/ext/fetch/request.d.ts +0 -1
- package/dist/ext/fetch/request.js +0 -1
- package/dist/ext/fs/index.d.ts +3 -4
- package/dist/ext/fs/index.js +268 -266
- package/dist/ext/fs/sandbox.d.ts +0 -1
- package/dist/ext/fs/sandbox.js +0 -1
- package/dist/ext/kv/index.d.ts +3 -4
- package/dist/ext/kv/index.js +216 -215
- package/dist/ext/kv/store.d.ts +0 -1
- package/dist/ext/kv/store.js +2 -2
- package/dist/ext-parse-bridge.d.ts +10 -0
- package/dist/ext-parse-bridge.js +10 -0
- package/dist/generated/introspection-data.d.ts +1 -2
- package/dist/generated/introspection-data.js +385 -297
- package/dist/generated/version-data.d.ts +1 -2
- package/dist/generated/version-data.js +2 -3
- package/dist/highlight-map.d.ts +0 -1
- package/dist/highlight-map.js +0 -1
- package/dist/index.d.ts +15 -5
- package/dist/index.js +14 -6
- package/dist/lexer/errors.d.ts +0 -1
- package/dist/lexer/errors.js +0 -1
- package/dist/lexer/helpers.d.ts +0 -1
- package/dist/lexer/helpers.js +0 -1
- package/dist/lexer/index.d.ts +0 -1
- package/dist/lexer/index.js +0 -1
- package/dist/lexer/operators.d.ts +0 -1
- package/dist/lexer/operators.js +0 -1
- package/dist/lexer/readers.d.ts +0 -1
- package/dist/lexer/readers.js +0 -1
- package/dist/lexer/state.d.ts +0 -1
- package/dist/lexer/state.js +0 -1
- package/dist/lexer/tokenizer.d.ts +0 -1
- package/dist/lexer/tokenizer.js +0 -1
- package/dist/parser/helpers.d.ts +0 -1
- package/dist/parser/helpers.js +0 -1
- package/dist/parser/index.d.ts +0 -1
- package/dist/parser/index.js +0 -1
- package/dist/parser/parser-collect.d.ts +0 -1
- package/dist/parser/parser-collect.js +0 -1
- package/dist/parser/parser-control.d.ts +0 -1
- package/dist/parser/parser-control.js +0 -1
- package/dist/parser/parser-expr.d.ts +0 -1
- package/dist/parser/parser-expr.js +0 -1
- package/dist/parser/parser-extract.d.ts +0 -1
- package/dist/parser/parser-extract.js +0 -1
- package/dist/parser/parser-functions.d.ts +0 -1
- package/dist/parser/parser-functions.js +0 -1
- package/dist/parser/parser-literals.d.ts +0 -1
- package/dist/parser/parser-literals.js +4 -2
- package/dist/parser/parser-script.d.ts +0 -1
- package/dist/parser/parser-script.js +0 -1
- package/dist/parser/parser-shape.d.ts +2 -3
- package/dist/parser/parser-shape.js +8 -52
- package/dist/parser/parser-types.d.ts +28 -2
- package/dist/parser/parser-types.js +76 -13
- package/dist/parser/parser-use.d.ts +0 -1
- package/dist/parser/parser-use.js +7 -2
- package/dist/parser/parser-variables.d.ts +0 -1
- package/dist/parser/parser-variables.js +0 -1
- package/dist/parser/parser.d.ts +0 -1
- package/dist/parser/parser.js +0 -1
- package/dist/parser/state.d.ts +0 -1
- package/dist/parser/state.js +0 -1
- package/dist/runtime/core/callable.d.ts +59 -20
- package/dist/runtime/core/callable.js +188 -39
- package/dist/runtime/core/context.d.ts +0 -12
- package/dist/runtime/core/context.js +77 -77
- package/dist/runtime/core/equals.d.ts +0 -1
- package/dist/runtime/core/equals.js +35 -3
- package/dist/runtime/core/eval/base.d.ts +0 -1
- package/dist/runtime/core/eval/base.js +0 -1
- package/dist/runtime/core/eval/evaluator.d.ts +0 -1
- package/dist/runtime/core/eval/evaluator.js +0 -1
- package/dist/runtime/core/eval/index.d.ts +2 -3
- package/dist/runtime/core/eval/index.js +11 -1
- package/dist/runtime/core/eval/mixins/annotations.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/annotations.js +0 -1
- package/dist/runtime/core/eval/mixins/closures.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/closures.js +92 -70
- package/dist/runtime/core/eval/mixins/collections.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/collections.js +9 -4
- package/dist/runtime/core/eval/mixins/control-flow.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/control-flow.js +0 -1
- package/dist/runtime/core/eval/mixins/conversion.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/conversion.js +196 -188
- package/dist/runtime/core/eval/mixins/core.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/core.js +2 -3
- package/dist/runtime/core/eval/mixins/expressions.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/expressions.js +35 -28
- package/dist/runtime/core/eval/mixins/extraction.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/extraction.js +8 -9
- package/dist/runtime/core/eval/mixins/list-dispatch.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/list-dispatch.js +0 -1
- package/dist/runtime/core/eval/mixins/literals.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/literals.js +6 -10
- package/dist/runtime/core/eval/mixins/types.d.ts +2 -1
- package/dist/runtime/core/eval/mixins/types.js +231 -261
- package/dist/runtime/core/eval/mixins/use.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/use.js +0 -1
- package/dist/runtime/core/eval/mixins/variables.d.ts +0 -1
- package/dist/runtime/core/eval/mixins/variables.js +16 -15
- package/dist/runtime/core/eval/types.d.ts +0 -1
- package/dist/runtime/core/eval/types.js +0 -1
- package/dist/runtime/core/execute.d.ts +0 -1
- package/dist/runtime/core/execute.js +0 -1
- package/dist/runtime/core/field-descriptor.d.ts +4 -5
- package/dist/runtime/core/field-descriptor.js +2 -2
- package/dist/runtime/core/introspection.d.ts +0 -1
- package/dist/runtime/core/introspection.js +6 -7
- package/dist/runtime/core/markers.d.ts +12 -0
- package/dist/runtime/core/markers.js +7 -0
- package/dist/runtime/core/resolvers.d.ts +0 -1
- package/dist/runtime/core/resolvers.js +0 -1
- package/dist/runtime/core/signals.d.ts +0 -1
- package/dist/runtime/core/signals.js +0 -1
- package/dist/runtime/core/type-registrations.d.ts +136 -0
- package/dist/runtime/core/type-registrations.js +749 -0
- package/dist/runtime/core/type-structures.d.ts +128 -0
- package/dist/runtime/core/type-structures.js +12 -0
- package/dist/runtime/core/types.d.ts +15 -4
- package/dist/runtime/core/types.js +0 -1
- package/dist/runtime/core/values.d.ts +88 -146
- package/dist/runtime/core/values.js +466 -470
- package/dist/runtime/ext/builtins.d.ts +0 -1
- package/dist/runtime/ext/builtins.js +125 -80
- package/dist/runtime/ext/extensions.d.ts +30 -125
- package/dist/runtime/ext/extensions.js +0 -94
- package/dist/runtime/ext/test-context.d.ts +28 -0
- package/dist/runtime/ext/test-context.js +154 -0
- package/dist/runtime/index.d.ts +22 -9
- package/dist/runtime/index.js +18 -5
- package/dist/signature-parser.d.ts +2 -3
- package/dist/signature-parser.js +19 -17
- package/dist/source-location.d.ts +0 -1
- package/dist/source-location.js +0 -1
- package/dist/token-types.d.ts +0 -1
- package/dist/token-types.js +0 -1
- package/dist/types.d.ts +0 -1
- package/dist/types.js +0 -1
- package/dist/value-types.d.ts +15 -12
- package/dist/value-types.js +0 -1
- package/package.json +2 -1
- package/dist/ast-nodes.d.ts.map +0 -1
- package/dist/ast-nodes.js.map +0 -1
- package/dist/ast-unions.d.ts.map +0 -1
- package/dist/ast-unions.js.map +0 -1
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js.map +0 -1
- package/dist/error-classes.d.ts.map +0 -1
- package/dist/error-classes.js.map +0 -1
- package/dist/error-formatter.d.ts.map +0 -1
- package/dist/error-formatter.js.map +0 -1
- package/dist/error-registry.d.ts.map +0 -1
- package/dist/error-registry.js.map +0 -1
- package/dist/ext/crypto/index.d.ts.map +0 -1
- package/dist/ext/crypto/index.js.map +0 -1
- package/dist/ext/exec/index.d.ts.map +0 -1
- package/dist/ext/exec/index.js.map +0 -1
- package/dist/ext/exec/runner.d.ts.map +0 -1
- package/dist/ext/exec/runner.js.map +0 -1
- package/dist/ext/fetch/index.d.ts.map +0 -1
- package/dist/ext/fetch/index.js.map +0 -1
- package/dist/ext/fetch/request.d.ts.map +0 -1
- package/dist/ext/fetch/request.js.map +0 -1
- package/dist/ext/fs/index.d.ts.map +0 -1
- package/dist/ext/fs/index.js.map +0 -1
- package/dist/ext/fs/sandbox.d.ts.map +0 -1
- package/dist/ext/fs/sandbox.js.map +0 -1
- package/dist/ext/kv/index.d.ts.map +0 -1
- package/dist/ext/kv/index.js.map +0 -1
- package/dist/ext/kv/store.d.ts.map +0 -1
- package/dist/ext/kv/store.js.map +0 -1
- package/dist/generated/introspection-data.d.ts.map +0 -1
- package/dist/generated/introspection-data.js.map +0 -1
- package/dist/generated/version-data.d.ts.map +0 -1
- package/dist/generated/version-data.js.map +0 -1
- package/dist/highlight-map.d.ts.map +0 -1
- package/dist/highlight-map.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lexer/errors.d.ts.map +0 -1
- package/dist/lexer/errors.js.map +0 -1
- package/dist/lexer/helpers.d.ts.map +0 -1
- package/dist/lexer/helpers.js.map +0 -1
- package/dist/lexer/index.d.ts.map +0 -1
- package/dist/lexer/index.js.map +0 -1
- package/dist/lexer/operators.d.ts.map +0 -1
- package/dist/lexer/operators.js.map +0 -1
- package/dist/lexer/readers.d.ts.map +0 -1
- package/dist/lexer/readers.js.map +0 -1
- package/dist/lexer/state.d.ts.map +0 -1
- package/dist/lexer/state.js.map +0 -1
- package/dist/lexer/tokenizer.d.ts.map +0 -1
- package/dist/lexer/tokenizer.js.map +0 -1
- package/dist/parser/helpers.d.ts.map +0 -1
- package/dist/parser/helpers.js.map +0 -1
- package/dist/parser/index.d.ts.map +0 -1
- package/dist/parser/index.js.map +0 -1
- package/dist/parser/parser-collect.d.ts.map +0 -1
- package/dist/parser/parser-collect.js.map +0 -1
- package/dist/parser/parser-control.d.ts.map +0 -1
- package/dist/parser/parser-control.js.map +0 -1
- package/dist/parser/parser-expr.d.ts.map +0 -1
- package/dist/parser/parser-expr.js.map +0 -1
- package/dist/parser/parser-extract.d.ts.map +0 -1
- package/dist/parser/parser-extract.js.map +0 -1
- package/dist/parser/parser-functions.d.ts.map +0 -1
- package/dist/parser/parser-functions.js.map +0 -1
- package/dist/parser/parser-literals.d.ts.map +0 -1
- package/dist/parser/parser-literals.js.map +0 -1
- package/dist/parser/parser-script.d.ts.map +0 -1
- package/dist/parser/parser-script.js.map +0 -1
- package/dist/parser/parser-shape.d.ts.map +0 -1
- package/dist/parser/parser-shape.js.map +0 -1
- package/dist/parser/parser-types.d.ts.map +0 -1
- package/dist/parser/parser-types.js.map +0 -1
- package/dist/parser/parser-use.d.ts.map +0 -1
- package/dist/parser/parser-use.js.map +0 -1
- package/dist/parser/parser-variables.d.ts.map +0 -1
- package/dist/parser/parser-variables.js.map +0 -1
- package/dist/parser/parser.d.ts.map +0 -1
- package/dist/parser/parser.js.map +0 -1
- package/dist/parser/state.d.ts.map +0 -1
- package/dist/parser/state.js.map +0 -1
- package/dist/runtime/core/callable.d.ts.map +0 -1
- package/dist/runtime/core/callable.js.map +0 -1
- package/dist/runtime/core/context.d.ts.map +0 -1
- package/dist/runtime/core/context.js.map +0 -1
- package/dist/runtime/core/equals.d.ts.map +0 -1
- package/dist/runtime/core/equals.js.map +0 -1
- package/dist/runtime/core/eval/base.d.ts.map +0 -1
- package/dist/runtime/core/eval/base.js.map +0 -1
- package/dist/runtime/core/eval/evaluator.d.ts.map +0 -1
- package/dist/runtime/core/eval/evaluator.js.map +0 -1
- package/dist/runtime/core/eval/index.d.ts.map +0 -1
- package/dist/runtime/core/eval/index.js.map +0 -1
- package/dist/runtime/core/eval/mixins/annotations.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/annotations.js.map +0 -1
- package/dist/runtime/core/eval/mixins/closures.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/closures.js.map +0 -1
- package/dist/runtime/core/eval/mixins/collections.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/collections.js.map +0 -1
- package/dist/runtime/core/eval/mixins/control-flow.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/control-flow.js.map +0 -1
- package/dist/runtime/core/eval/mixins/conversion.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/conversion.js.map +0 -1
- package/dist/runtime/core/eval/mixins/core.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/core.js.map +0 -1
- package/dist/runtime/core/eval/mixins/expressions.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/expressions.js.map +0 -1
- package/dist/runtime/core/eval/mixins/extraction.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/extraction.js.map +0 -1
- package/dist/runtime/core/eval/mixins/list-dispatch.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/list-dispatch.js.map +0 -1
- package/dist/runtime/core/eval/mixins/literals.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/literals.js.map +0 -1
- package/dist/runtime/core/eval/mixins/types.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/types.js.map +0 -1
- package/dist/runtime/core/eval/mixins/use.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/use.js.map +0 -1
- package/dist/runtime/core/eval/mixins/variables.d.ts.map +0 -1
- package/dist/runtime/core/eval/mixins/variables.js.map +0 -1
- package/dist/runtime/core/eval/types.d.ts.map +0 -1
- package/dist/runtime/core/eval/types.js.map +0 -1
- package/dist/runtime/core/execute.d.ts.map +0 -1
- package/dist/runtime/core/execute.js.map +0 -1
- package/dist/runtime/core/field-descriptor.d.ts.map +0 -1
- package/dist/runtime/core/field-descriptor.js.map +0 -1
- package/dist/runtime/core/introspection.d.ts.map +0 -1
- package/dist/runtime/core/introspection.js.map +0 -1
- package/dist/runtime/core/resolvers.d.ts.map +0 -1
- package/dist/runtime/core/resolvers.js.map +0 -1
- package/dist/runtime/core/signals.d.ts.map +0 -1
- package/dist/runtime/core/signals.js.map +0 -1
- package/dist/runtime/core/types.d.ts.map +0 -1
- package/dist/runtime/core/types.js.map +0 -1
- package/dist/runtime/core/values.d.ts.map +0 -1
- package/dist/runtime/core/values.js.map +0 -1
- package/dist/runtime/ext/builtins.d.ts.map +0 -1
- package/dist/runtime/ext/builtins.js.map +0 -1
- package/dist/runtime/ext/extensions.d.ts.map +0 -1
- package/dist/runtime/ext/extensions.js.map +0 -1
- package/dist/runtime/index.d.ts.map +0 -1
- package/dist/runtime/index.js.map +0 -1
- package/dist/signature-parser.d.ts.map +0 -1
- package/dist/signature-parser.js.map +0 -1
- package/dist/source-location.d.ts.map +0 -1
- package/dist/source-location.js.map +0 -1
- package/dist/token-types.d.ts.map +0 -1
- package/dist/token-types.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/value-types.d.ts.map +0 -1
- package/dist/value-types.js.map +0 -1
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export declare const LANGUAGE_REFERENCE = "# rill\n\n> Scripting language designed for machine-generated code. LLMs generate rill scripts; humans review and debug. Data flows through pipes (`->`), not assignment. Variables use `$` prefix. No null, no exceptions, no truthiness.\n\n## Essentials\n\n1. Variables use `$` prefix ALWAYS: `5 => $x` (no assignment operator `=`)\n2. Pipe with `->`, capture with `=>`: `\"hello\" => $x -> .upper => $y`\n3. No null/undefined, no try/catch, no truthiness (conditions must be boolean)\n4. Variables lock to first type: `\"hi\" => $x; 42 => $x` is an ERROR\n5. Loops cannot modify outer vars: use `fold`, `each(init)`, or `$` as state dict\n\n## Critical Differences from Mainstream Languages\n\n### 1. No Assignment Operator\n\n Wrong: x = 5 Mainstream: x = value\n Right: 5 => $x rill: value => $x\n\nPipe (`->`): passes value to next operation.\nCapture (`=>`): stores value AND continues chain.\nExample: `\"hello\" => $x -> .upper => $y` \u2014 `$x=\"hello\"`, `$y=\"HELLO\"`.\n\n### 2. No Null/Undefined\n\nEmpty values (`\"\"`, `list[]`, `dict[]`) exist. \"No value\" cannot be represented.\nUse `??` for defaults: `$dict.field ?? \"default\"`.\nUse `.empty` to check: `$str -> .empty ? \"was empty\"`.\n\n### 3. No Truthiness\n\nConditions MUST be boolean. No implicit coercion.\n\n Wrong: \"\" ? \"yes\" ! \"no\" Right: \"\" -> .empty ? \"yes\" ! \"no\"\n Wrong: 0 ? \"yes\" ! \"no\" Right: (0 == 0) ? \"yes\" ! \"no\"\n\nNegation (`!`) also requires boolean:\n\n !true # false\n \"hello\" -> .empty -> (!$) # true (negates boolean from .empty)\n !\"hello\" # ERROR: Negation requires boolean\n\n### 4. Variables Lock to First Type\n\n \"hello\" => $x\n 42 => $x # ERROR: cannot assign number to string variable\n\n### 5. No Variable Shadowing (Critical for Loops)\n\nChild scopes can READ parent variables but cannot WRITE or redeclare them.\nVariables created inside blocks/loops do NOT leak out.\n\nWRONG \u2014 outer variable modification (runtime error):\n\n 0 => $count\n list[1, 2, 3] -> each { $count + 1 => $count } # ERROR: Cannot reassign outer variable\n\nRIGHT \u2014 use `fold` for reduction:\n\n list[1, 2, 3] -> fold(0) { $@ + $ } # 6 ($@ is accumulator)\n\nRIGHT \u2014 use `each(init)` for results AND accumulator:\n\n list[1, 2, 3] -> each(0) { $@ + $ } # list[1, 3, 6] (running totals)\n\nRIGHT \u2014 use `(cond) @ { }` with `$` as state dict for multiple values:\n\n dict[iter: 0, max: 3, text: $input, done: false]\n -> (!$.done && $.iter < $.max) @ {\n $.iter + 1 => $i\n process($.text) => $result\n $result.finished ? dict[iter: $i, max: $.max, text: $.text, done: true]\n ! dict[iter: $i, max: $.max, text: $result.text, done: false]\n }\n\nPattern summary:\n\n Single value accumulation -> fold(init) { $@ + $ }\n Per-item results + running -> each(init) { ... $@ ... }\n Multiple state values / while -> (cond) @ { } with $ as state dict\n \"while\" and \"for\" keywords -> DO NOT EXIST\n\n### 6. No Exceptions\n\nErrors halt execution. No try/catch. Use conditionals for error handling.\nBuilt-in: `assert` (validate condition), `error` (halt with message).\n\n### 7. Value Semantics (No References)\n\nAll copies are deep. All comparisons are by value. No object identity.\n\n list[1, 2, 3] == list[1, 2, 3] # true (content equality)\n list[1, 2] => $a\n $a => $b # $b is an independent deep copy\n\n## Grammar Patterns\n\nrill uses two bracket forms as grammar constructs (not function calls):\n\n**`keyword[...]`** \u2014 collection literals. Keyword and `[` must be adjacent (no space):\n\n list[1, 2, 3] # list\n dict[name: \"alice\", age: 30] # dict (key: value pairs)\n tuple[1, 2, 3] # positional argument unpacking\n ordered[a: 1, b: 2] # named argument unpacking\n\n list [1, 2] # ERROR: RILL-P007 (space before bracket)\n\n**`keyword<...>`** \u2014 extraction operators. Custom grammar with `,` or `:` separators:\n\n list[1, 2, 3] -> destruct<$a, $b, $c> # destructure into variables\n list[0,1,2,3] -> slice<1:3> # slice with start:stop:step\n\nThese are NOT function calls. They are parsed as special syntax by the compiler.\n\n## Callable Types\n\nrill has three callable types:\n\n| Type | Source | Examples |\n|------|--------|---------|\n| Closure | Script-defined | `\\|x\\| { $x * 2 }`, `{ $ + 1 }` |\n| Built-in function | Shipped with runtime | `log`, `json`, `range`, `chain`, `error` |\n| Host function | Registered by host app | `app::fetch()`, `app::prompt()` |\n\nThe `$` prefix disambiguates callables from variables and keys:\n\n name() -> built-in or host function call\n $name() -> closure invocation\n $name -> variable reference\n name -> dict key literal\n\nWithout `$`, `process(data)` is ambiguous: is `process` a function or stored closure? Is `data` a variable or key? This would require tracking all declarations.\n\n## Syntax Quick Reference\n\n Variables: $name (always prefixed with $)\n Strings: \"hello {$var}\" # interpolation with {}\n \"\"\"...\"\"\" # multiline (also interpolates)\n Numbers: 42, 3.14, -7\n Booleans: true, false\n Lists: list[1, 2, 3]\n list[...$list, 4] # spread: inline list elements\n Dicts: dict[name: \"alice\", age: 30] # identifier keys\n dict[1: \"one\", 2: \"two\"] # number keys (incl. negative: dict[-1: \"neg\"])\n dict[true: \"yes\", false: \"no\"] # boolean keys\n dict[list[\"a\", \"b\"]: 1] # multi-key: dict[a: 1, b: 1]\n dict[$keyVar: value] # variable key (must eval to string)\n dict[(\"{$a}{$b}\"): value] # computed key (must eval to string)\n Tuples: tuple[1, 2, 3] # positional argument unpacking\n Ordered: ordered[a: 1, b: 2] # named argument unpacking (preserves order)\n Closures: |x|($x + 1) # like lambda/arrow functions\n Type annot: \"hi\" => $x:string # lock type on capture\n Comments: # single line only\n\n## Pipes and $ Binding\n\n`$` is the current piped value. Its meaning depends on context:\n\n| Context | `$` contains |\n|---|---|\n| `-> { body }` | piped value |\n| `-> each { }` | current item |\n| `(cond) @ { }` | accumulated value |\n| `@ { } ? cond` | accumulated value |\n| `cond ? { } ! { }` | tested value |\n| `-> ? { } ! { }` | piped value |\n| `\\|\\|{ $.field }` in dict | the containing dict |\n| `\\|x\\|{ }` stored closure | N/A \u2014 use parameters |\n\nImplied `$`: bare `.method()` means `$ -> .method()`.\nExample: `\"hello\" -> .upper` is the same as `\"hello\" -> $.upper()`.\n\n## Control Flow\n\nConditional (if-else):\n\n cond ? then_expr ! else_expr\n cond ? then_expr # else returns null\n\nPiped conditional (`$` becomes condition):\n\n value -> ? then_expr ! else_expr\n\nMulti-line conditionals (`?` and `!` work as line continuations):\n\n condition\n ? \"yes\"\n ! \"no\"\n value -> is_valid\n ? \"ok\"\n ! \"error\"\n $val -> .eq(\"A\") ? \"a\"\n ! .eq(\"B\") ? \"b\"\n ! \"c\"\n\nCondition loop (NO `while` keyword \u2014 use `@` operator):\n\n init_value -> ($ < 10) @ { $ + 1 } # $ is accumulator\n\nDo-condition loop (body runs at least once):\n\n init_value -> @ { $ + 1 } ? ($ < 10)\n\nBreak (exits loop, returns collected results before break):\n\n list[1,2,3,4,5] -> each {\n ($ == 3) ? break\n $\n } # returns list[1, 2]\n\nReturn (exits block or script with value):\n\n 5 => $x\n ($x > 3) ? (\"big\" -> return)\n \"small\" # returns \"big\"\n \"done\" -> return # exits script with \"done\"\n\nAssert (validate condition, halt if false, pass through if true):\n\n 5 -> assert ($ > 0) # returns 5\n -1 -> assert ($ > 0) # ERROR: Assertion failed\n \"\" -> assert !.empty \"Input required\" # ERROR: Input required\n $val -> assert $:?list \"Expected list\" # type validation\n\nError (halt execution immediately with message):\n\n error \"Something went wrong\" # halt with message\n \"Operation failed\" -> error # piped form (must be string)\n error \"Status: {$code}\" # interpolation works\n\nPass (returns `$` unchanged, explicit no-op):\n\n cond ? pass ! \"fallback\" # preserve $ when condition true\n cond ? \"value\" ! pass # preserve $ when condition false\n \"data\" -> { dict[status: pass] } # include $ in dict: dict[status: \"data\"]\n list[1, -2, 3] -> map { ($ > 0) ? pass ! 0 } # list[1, 0, 3]\n\nNote: `pass` requires pipe context. Using `pass` without `$` throws error.\n\n## Collection Operators\n\n| Operator | Execution | Returns | Break? |\n|---|---|---|---|\n| `-> each { }` | sequential | all body results | yes |\n| `-> each(i) { $@ + $ }` | sequential | all with accumulator | yes |\n| `-> map { }` | parallel | all body results | NO |\n| `-> filter { }` | parallel | matching elements | NO |\n| `-> fold(i) { $@ + $ }` | sequential | final result only | yes |\n\n`$@` is the accumulator in `each(init)` and `fold(init)`.\n\nMethod shorthand in collection operators:\n\n list[\"a\", \"b\"] -> map .upper # list[\"A\", \"B\"]\n list[\"\", \"x\"] -> filter (!.empty) # list[\"x\"]\n list[\"a\", \"b\"] -> map .pad_start(3, \"0\") # list[\"00a\", \"00b\"] (with args)\n list[\" HI \"] -> map .trim.lower # list[\"hi\"] (chained methods)\n\nBody forms (all operators accept these):\n\n -> each { $ * 2 } # block ($ is current element)\n -> each ($ + 10) # grouped expression\n -> each |x| ($x * 2) # inline closure\n -> each $double # variable closure\n -> each .upper # method shorthand\n -> each log # built-in function\n\nDict iteration (`$` contains `key` and `value` fields):\n\n dict[a: 1, b: 2] -> each { \"{$.key}={$.value}\" } # list[\"a=1\", \"b=2\"]\n dict[a: 1, b: 5] -> filter { $.value > 2 } # entries where value > 2\n\nString iteration (iterates over characters):\n\n \"abc\" -> each { \"{$}!\" } # list[\"a!\", \"b!\", \"c!\"]\n \"hello\" -> filter { $ != \"l\" } # list[\"h\", \"e\", \"o\"]\n\n## Closures\n\nTwo ways to create closures:\n\n**Block-closures:** `{ body }` in expression position\n\n { $ + 1 } => $inc # implicit $ parameter\n $inc(5) # 6\n 5 -> $inc # 6 (pipe invocation)\n dict[x: { $ * 2 }] # dict value is closure\n { \"hi\" }:?closure # true\n\n**Explicit closures:** `|params| body`\n\n |x|($x + 1) => $inc # named parameter\n |a, b|($a + $b) => $add # multiple params\n |x = 0|($x + 1) => $inc_or_one # default value\n |x: number|($x + 1) => $typed # type annotation\n\n**Anonymous typed closures:** `|type|{ body }` \u2014 reserved type keyword as param, `$` is type-checked piped input\n\n \"hello\" -> |string|{ $ -> .upper } # $ is string, checked at call\n 5 -> |number|{ $ * 2 } # 10\n |number|{ $ * 2 }:number => $double # stored with return type assertion\n 5 -> $double # 10\n \"hi\" -> $double # RILL-R001: expected number, got string\n\nAll 11 type names valid: string, number, bool, list, dict, ordered, tuple, closure, vector, any, type\nParameterized: |list(number)|{ $ -> each { $ * 2 } }\n\n**Return type assertions** (enforced at runtime \u2014 RILL-R004 on mismatch):\n\n |x: number| { \"{$x}\" }:string => $fn # asserts string return type\n $fn(42) # \"42\" (passes assertion)\n\n |x: number| { $x * 2 }:string => $fn # mismatch halts with RILL-R004\n $fn(5) # RILL-R004: expected string, got number\n\nValid return type targets: any type name (string, number, bool, closure, list, dict, tuple,\nordered, vector, any, type), or a parameterized type constructor (list(string),\ndict(a: number, b: string)).\nDeclared return type accessible via $fn.^output annotation.\n\n**Description shorthand** (bare string in `^(...)` expands to `description: <string>`):\n\n ^(\"Get weather for city\") |city: string|($city) => $weather\n $weather.^description # \"Get weather for city\"\n\n ^(\"Fetch profile\", cache: true) |id|($id) => $get_user\n $get_user.^description # \"Fetch profile\"\n $get_user.^cache # true\n\n`{ body }` vs `( expr )` distinction:\n\n| Syntax | Semantics | Example |\n|---|---|---|\n| `{ body }` | Deferred (closure) | `{ $ + 1 } => $fn` |\n| `( expr )` | Eager (immediate eval) | `( 5 + 1 ) => $x` gives 6 |\n\nLATE BINDING: closures capture scope, not values. Variables resolve at call time.\n\n`$` vs named params:\n- Use `$` in inline pipes and loops: `\"hello\" -> { .upper }`\n- Use named params in stored closures: `|x| ($x * 2) => $double`\n- `$` is undefined when a stored closure is called later \u2014 always use params.\n\nZero-param dict closures (methods):\n\n dict[count: 3, double: ||{ $.count * 2 }] => $obj\n $obj.double # 6 ($ is bound to dict)\n\n## Property Access\n\n $data.field # dict field\n $data[0], $data[-1] # list index (negative from end)\n $data.$key # variable as key\n $data.($i + 1) # computed key\n $data.(a || b) # try keys left-to-right\n $data.field ?? \"default\" # default if missing\n $data.?field # existence check (boolean)\n $data.?$keyVar # variable existence check\n $data.?($expr) # computed existence check\n $data.?field&string # existence AND type check\n $data.?$key&number # variable existence + type check\n $data.?($a -> \"{$}_b\")&list # computed existence + type check\n\n## Dispatch Operators\n\n**Dict dispatch** (single key) \u2014 pipe a value to a dict to match keys:\n\n $val -> dict[apple: \"fruit\", carrot: \"veg\"] # \"fruit\" if $val is \"apple\"\n $val -> dict[apple: \"fruit\"] ?? \"not found\" # default if no match\n $method -> dict[list[\"GET\", \"HEAD\"]: \"safe\", list[\"POST\", \"PUT\"]: \"unsafe\"] # multi-key\n\nType-aware matching (keys matched by value AND type):\n\n 1 -> dict[1: \"number\", \"1\": \"string\"] # \"number\"\n \"1\" -> dict[1: \"number\", \"1\": \"string\"] # \"string\"\n true -> dict[true: \"bool\", \"true\": \"str\"] # \"bool\"\n\n**List dispatch** (index) \u2014 pipe a number to a list:\n\n 0 -> list[\"first\", \"second\"] # \"first\"\n -1 -> list[\"first\", \"second\"] # \"second\" (last)\n 5 -> list[\"a\", \"b\"] ?? \"not found\" # default if out of bounds\n\n**Hierarchical dispatch** (path navigation) \u2014 pipe a list of keys/indexes:\n\n list[\"name\", \"first\"] -> dict[name: dict[first: \"Alice\"]] # \"Alice\"\n list[0, 1] -> list[list[1, 2, 3], list[4, 5, 6]] # 2\n list[] -> dict[a: 1] # dict[a: 1] (empty path = unchanged)\n list[\"a\", \"missing\"] -> dict[a: dict[x: 1]] ?? \"default\" # \"default\"\n\nNote: lists require same-type elements. For mixed paths (strings and numbers), use property access:\n\n dict[users: list[dict[name: \"Alice\"]]] => $d\n $d.users[0].name # \"Alice\"\n\n## Types and Type Expressions\n\n**Type names:**\n\n string number bool list dict ordered\n tuple closure vector any type\n\n**Type names are first-class values** \u2014 assign to variables, use in dynamic expressions:\n\n number => $t # store a type value\n 42 -> :$t # dynamic assertion (same as :number)\n 42 -> :?$t # dynamic check: true\n 42 -> :>$t # dynamic conversion (same as :>number)\n $val.^type == $t # compare against stored type\n\n**Parameterized type constructors** (structural types):\n\n list(string) # list of strings\n dict(name: string, age: number) # dict with named fields\n tuple(number, string) # positional tuple\n ordered(x: number, y: number) # named ordered args\n |x: number, y: string| :any # closure signature type\n\nClosure signatures include parameter names \u2014 `|x: number|` and `|y: number|` are different types.\n\n**Type assertion** `:type` \u2014 errors if value does not match:\n\n 42:number # passes\n \"x\":number # RILL-R002: expected number, got string\n $val:list(string) # assert parameterized type\n\n**Enforcing dict shapes** with `dict(field: type, ...)`:\n\n $data -> :dict(name: string, age: number) # assert exact fields and types\n $data:?dict(name: string, age: number) # check without error\n $data:dict(name: string) -> .name # assert then access\n\nUse in closure params to validate input structure:\n\n |d: dict(name: string, age: number)| {\n \"{$d.name} is {$d.age}\"\n } => $format_person\n\n**Type check** `:?type` \u2014 returns boolean, never errors:\n\n 42:?number # true\n \"x\":?number # false\n $val:?list(string) # structural check\n\nBoth forms work as pipe targets:\n\n $val -> :number # assert in pipe\n $val -> :?number # check in pipe\n\n**`^type` operator** \u2014 returns a type value for inspection:\n\n 42.^type # type value for number\n 42.^type.name # \"number\"\n list[1, 2].^type.name # \"list\"\n list[1, 2].^type.signature # \"list(number)\"\n\n**Type value equality:**\n\n $val.^type == list(number) # true if $val is list(number)\n $val.^type == $other.^type # compare structural types\n\n**Type conversion** `:>type` \u2014 explicit conversion between compatible types:\n\n 42 -> :>string # \"42\"\n \"3.14\" -> :>number # 3.14\n list[1, 2] -> :>tuple # tuple[1, 2]\n tuple[1, 2] -> :>list # list[1, 2]\n ordered[a: 1] -> :>dict # dict[a: 1]\n dict[x: 1, y: 2] -> :>ordered(x: number, y: number) # structural\n\nCompatibility matrix (error = halts with RILL-R036, no-op = same-type identity):\n\n Source | :>list | :>dict | :>tuple | :>ordered(sig) | :>number | :>string | :>bool\n ---------|---------|---------|---------|----------------|----------|----------|-------\n list | no-op | error | valid | error | error | valid\u00B9 | error\n dict | error | no-op | error | valid | error | valid\u00B9 | error\n tuple | valid | error | no-op | error | error | valid\u00B9 | error\n ordered | error | valid | error | no-op | error | valid\u00B9 | error\n string | error | error | error | error | valid\u00B2 | no-op | valid\u00B3\n number | error | error | error | error | no-op | valid\u00B9 | valid\u2075\n bool | error | error | error | error | valid\u2074 | valid\u00B9 | no-op\n\n \u00B9 Uses formatValue semantics for formatted output\n \u00B2 Parseable strings only; halts with RILL-R038 on failure\n \u00B3 Accepts only \"true\" and \"false\"; halts with RILL-R036 otherwise\n \u2074 true maps to 1, false maps to 0\n \u2075 0 maps to false, 1 maps to true; all other values halt with RILL-R036\n\n## Comparison Methods\n\n .eq(val) == .ne(val) != .lt(val) < .gt(val) > .le(val) <= .ge(val) >=\n Example: $age -> .ge(18) ? \"adult\" ! \"minor\"\n\n## Operator Precedence (Highest to Lowest)\n\n1. Member access: `.field`, `[index]`\n2. Type operators: `:type`, `:?type`\n3. Unary: `-`, `!`\n4. Multiplicative: `*`, `/`, `%`\n5. Additive: `+`, `-`\n6. Comparison: `==`, `!=`, `<`, `>`, `<=`, `>=`\n7. Logical AND: `&&`\n8. Logical OR: `||`\n9. Default: `??`\n10. Pipe: `->`\n11. Capture: `=>`\n\nUse parentheses to override: `(2 + 3) * 4`\n\n## Extraction Operators\n\nDestructure (`destruct<>`):\n\n list[1, 2, 3] -> destruct<$a, $b, $c> # $a=1, $b=2, $c=3\n dict[x: 1, y: 2] -> destruct<x: $a, y: $b> # $a=1, $b=2\n list[1, 2, 3] -> destruct<$first, _, $third> # _ skips element\n\nSlice (`slice<start:stop:step>`):\n\n list[0,1,2,3,4] -> slice<1:3> # list[1, 2]\n list[0,1,2,3,4] -> slice<-2:> # list[3, 4]\n list[0,1,2,3,4] -> slice<::-1> # list[4,3,2,1,0] (reverse)\n \"hello\" -> slice<1:4> # \"ell\"\n\n## List Spread in Literals\n\n list[1, 2] => $a\n list[...$a, 3] # list[1, 2, 3]\n list[...$a, ...$b] # concatenate lists\n list[...($nums -> map {$ * 2})] # spread expression result\n\n## Tuples and Ordered for Argument Unpacking\n\n tuple[1, 2, 3] -> $fn(...) # positional spread: $fn(1, 2, 3)\n ordered[a: 10, b: 2] -> $fn(...) # named spread: keys must match parameter order\n tuple[...$list, 3] -> $fn(...) # spread in tuple then spread into call\n tuple[1, 2, 3] => $args\n $args -> $fn(...) # spread stored tuple\n ordered[a: 1, b: 2] => $named\n $named -> $fn(...) # spread stored ordered\n\n## String Methods\n\n| Method | Description |\n|---|---|\n| `.len` | length |\n| `.empty` | is empty string |\n| `.trim` | remove whitespace |\n| `.upper` | uppercase |\n| `.lower` | lowercase |\n| `.head` | first character |\n| `.tail` | last character |\n| `.at(i)` | character at index |\n| `.split(sep)` | split into list (default: newline) |\n| `.lines` | split on newlines |\n| `.join(sep)` | join list with separator |\n| `.contains(s)` | substring check |\n| `.starts_with(s)` | prefix check |\n| `.ends_with(s)` | suffix check |\n| `.index_of(s)` | first match position (-1 if none) |\n| `.replace(p, r)` | replace first regex match |\n| `.replace_all(p, r)` | replace all regex matches |\n| `.match(regex)` | first match info (dict with matched, index, groups) |\n| `.is_match(regex)` | boolean regex check |\n| `.repeat(n)` | repeat n times |\n| `.pad_start(n, f)` | pad start |\n| `.pad_end(n, f)` | pad end |\n\n## List/Dict Methods\n\n| Method | Description |\n|---|---|\n| `.len` | length |\n| `.empty` | is empty |\n| `.head` | first element |\n| `.tail` | last element |\n| `.at(i)` | element at index |\n| `.keys` | dict keys as list |\n| `.values` | dict values as list |\n| `.entries` | dict as list of `tuple[k, v]` pairs |\n| `.has(val)` | list contains value (deep equality) |\n| `.has_any(list)` | list contains any value from candidates |\n| `.has_all(list)` | list contains all values from candidates |\n\n## Built-in Functions\n\n| Function | Description |\n|---|---|\n| `log(val)` | print and pass through |\n| `json(val)` | convert to JSON string |\n| `identity(val)` | returns input unchanged |\n| `range(start, end, step?)` | number sequence (iterator) |\n| `repeat(val, count)` | repeat value n times (iterator) |\n| `enumerate(coll)` | lists: `tuple[index, value]`; dicts: `tuple[index, key, value]` |\n| `chain($fn)` | apply single closure; chain(val, list[$f, $g]) applies in sequence |\n\n## Iterators\n\nLazy sequence generation. Collection operators auto-expand iterators.\n\n range(0, 5) -> each { $ * 2 } # list[0, 2, 4, 6, 8]\n repeat(\"x\", 3) -> each { $ } # list[\"x\", \"x\", \"x\"]\n\n`.first()` method (returns iterator for any collection):\n\n list[1, 2, 3] -> .first() # iterator at 1\n \"abc\" -> .first() # iterator at \"a\"\n\nIterator protocol (dict with `value`, `done`, `next`):\n\n $it.done # bool: is exhausted?\n $it.value # current element\n $it.next() # returns new iterator at next position\n\n## Iteration Limits\n\nDefault: 10,000 iterations max for loops.\nOverride: `^(limit: N)` at operator level (between operator name and body).\n\n 0 -> ($ < 50) @ ^(limit: 100) { $ + 1 } # while loop\n $items -> each ^(limit: 1000) { process($) } # each operator\n $items -> map ^(limit: 3) { slow_process($) } # concurrency limit\n\nInvalid annotation keys produce a runtime error.\n\n## Script Return Values\n\n| Return value | Exit code |\n|---|---|\n| `true` / non-empty string | 0 |\n| `false` / empty string | 1 |\n| `list[0, \"message\"]` | 0 with message |\n| `list[1, \"message\"]` | 1 with message |\n\n## Style\n\n### Naming: snake_case\n\n $user_name, $item_list, $is_valid # variables\n $double_value, $cleanup_text # closures\n dict[first_name: \"x\", last_name: \"y\"] # dict keys\n\n### Spacing\n\n Operators: space both sides 5 + 3, $x -> .upper, \"a\" => $b\n Parentheses: no inner space ($x + 1), ($ > 3) ? \"yes\"\n Braces: space inside { $x + 1 }, each { $ * 2 }\n Brackets: no inner space $list[0], $dict.items[1]\n Literals: space after , and : list[1, 2, 3], dict[name: \"x\", age: 30]\n Keyword+[ NO space between list[1, 2] (not list [1, 2] \u2014 RILL-P007)\n Closures: space after params |x| ($x * 2), |a, b| { $a + $b }\n Methods: no space before . or ( $str.upper(), $list.join(\", \")\n Pipes: space both sides \"x\" -> .upper -> .len\n Continuations: indent 2 spaces $data\n -> .filter { $.active }\n -> map { $.name }\n\n### Implicit $ Shorthand (Always Prefer)\n\n $.method() -> .method \"x\" -> .upper (not $.upper())\n func($) -> func \"x\" -> log (not log($))\n $fn($) -> $fn 5 -> $double (not $double($))\n\nDon't capture just to continue \u2014 use line continuation instead:\n\n # avoid # good\n \"x\" => $a \"x\"\n $a -> .upper => $b -> .upper\n $b -> .len -> .len\n\nOnly capture when the variable is reused later in the code.\n";
|
|
2
|
-
//# sourceMappingURL=introspection-data.d.ts.map
|
|
1
|
+
export declare const LANGUAGE_REFERENCE = "# rill\n\n> Scripting language designed for machine-generated code. LLMs generate rill scripts; humans review and debug. Data flows through pipes (`->`), not assignment. Variables use `$` prefix. No null, no exceptions, no truthiness.\n\n## Essentials\n\n1. Variables use `$` prefix ALWAYS: `5 => $x` (no assignment operator `=`)\n2. Pipe with `->`, capture with `=>`: `\"hello\" => $x -> .upper => $y`\n3. No null/undefined, no try/catch, no truthiness (conditions must be boolean)\n4. Variables lock to first type: `\"hi\" => $x; 42 => $x` is an ERROR\n5. Loops cannot modify outer vars: use `fold`, `each(init)`, or `$` as state dict\n\n## Critical Differences from Mainstream Languages\n\n### 1. No Assignment Operator\n\n Wrong: x = 5 Mainstream: x = value\n Right: 5 => $x rill: value => $x\n\nPipe (`->`): passes value to next operation.\nCapture (`=>`): stores value AND continues chain.\nExample: `\"hello\" => $x -> .upper => $y` \u2014 `$x=\"hello\"`, `$y=\"HELLO\"`.\n\n### 2. No Null/Undefined\n\nEmpty values (`\"\"`, `list[]`, `dict[]`) exist. \"No value\" cannot be represented.\nUse `??` for defaults: `$dict.field ?? \"default\"`.\nUse `.empty` to check: `$str -> .empty ? \"was empty\"`.\n\n### 3. No Truthiness\n\nConditions MUST be boolean. No implicit coercion.\n\n Wrong: \"\" ? \"yes\" ! \"no\" Right: \"\" -> .empty ? \"yes\" ! \"no\"\n Wrong: 0 ? \"yes\" ! \"no\" Right: (0 == 0) ? \"yes\" ! \"no\"\n\nNegation (`!`) also requires boolean:\n\n !true # false\n \"hello\" -> .empty -> (!$) # true (negates boolean from .empty)\n !\"hello\" # ERROR: Negation requires boolean\n\n### 4. Variables Lock to First Type\n\n \"hello\" => $x\n 42 => $x # ERROR: cannot assign number to string variable\n\n### 5. No Variable Shadowing (Critical for Loops)\n\nChild scopes can READ parent variables but cannot WRITE or redeclare them.\nVariables created inside blocks/loops do NOT leak out.\n\nWRONG \u2014 outer variable modification (runtime error):\n\n 0 => $count\n list[1, 2, 3] -> each { $count + 1 => $count } # ERROR: Cannot reassign outer variable\n\nRIGHT \u2014 use `fold` for reduction:\n\n list[1, 2, 3] -> fold(0) { $@ + $ } # 6 ($@ is accumulator)\n\nRIGHT \u2014 use `each(init)` for results AND accumulator:\n\n list[1, 2, 3] -> each(0) { $@ + $ } # list[1, 3, 6] (running totals)\n\nRIGHT \u2014 use `(cond) @ { }` with `$` as state dict for multiple values:\n\n dict[iter: 0, max: 3, text: $input, done: false]\n -> (!$.done && $.iter < $.max) @ {\n $.iter + 1 => $i\n process($.text) => $result\n $result.finished ? dict[iter: $i, max: $.max, text: $.text, done: true]\n ! dict[iter: $i, max: $.max, text: $result.text, done: false]\n }\n\nPattern summary:\n\n Single value accumulation -> fold(init) { $@ + $ }\n Per-item results + running -> each(init) { ... $@ ... }\n Multiple state values / while -> (cond) @ { } with $ as state dict\n \"while\" and \"for\" keywords -> DO NOT EXIST\n\n### 6. No Exceptions\n\nErrors halt execution. No try/catch. Use conditionals for error handling.\nKeywords: `assert` (validate condition), `error` (halt with message).\n\n### 7. Value Semantics (No References)\n\nAll copies are deep. All comparisons are by value. No object identity.\n\n list[1, 2, 3] == list[1, 2, 3] # true (content equality)\n list[1, 2] => $a\n $a => $b # $b is an independent deep copy\n\n## Syntax Quick Reference\n\n Variables: $name (always prefixed with $)\n Strings: \"hello {$var}\" # interpolation with {}\n \"\"\"...\"\"\" # multiline (also interpolates)\n Numbers: 42, 3.14, -7\n Booleans: true, false\n Lists: list[1, 2, 3]\n list[...$list, 4] # spread: inline list elements\n Dicts: dict[name: \"alice\", age: 30] # identifier keys\n dict[1: \"one\", 2: \"two\"] # number keys (incl. negative: dict[-1: \"neg\"])\n dict[true: \"yes\", false: \"no\"] # boolean keys\n dict[list[\"a\", \"b\"]: 1] # multi-key: dict[a: 1, b: 1]\n dict[$keyVar: value] # variable key (must eval to string)\n dict[(\"{$a}{$b}\"): value] # computed key (must eval to string)\n Tuples: tuple[1, 2, 3] # positional argument unpacking\n Ordered: ordered[a: 1, b: 2] # named argument unpacking (preserves order)\n Closures: |x|($x + 1) # like lambda/arrow functions\n Type annot: \"hi\" => $x:string # lock type on capture\n Modules: use<module:greetings> => $g # host-provided imports\n Comments: # single line only\n\nCRITICAL: `keyword[` must have NO space before `[`. `list [1]` is ERROR (RILL-P007).\n\n## Callable Types\n\nrill has three callable types:\n\n| Type | Source | Examples |\n|------|--------|---------|\n| Closure | Script-defined | `\\|x\\| { $x * 2 }`, `{ $ + 1 }` |\n| Built-in function | Shipped with runtime | `log`, `json`, `range`, `repeat`, `chain` |\n| Host function | Registered by host app | `app::fetch()`, `app::prompt()` |\n\nThe `$` prefix disambiguates callables from variables and keys:\n\n name() -> built-in or host function call\n $name() -> closure invocation\n $name -> variable reference\n name -> dict key literal\n\n## Pipes and $ Binding\n\n`$` is the current piped value. Its meaning depends on context:\n\n| Context | `$` contains |\n|---|---|\n| `-> { body }` | piped value |\n| `-> each { }` | current item |\n| `(cond) @ { }` | accumulated value |\n| `@ { } ? cond` | accumulated value |\n| `cond ? { } ! { }` | tested value |\n| `-> ? { } ! { }` | piped value |\n| `\\|\\|{ $.field }` in dict | the containing dict |\n| `\\|x\\|{ }` stored closure | N/A \u2014 use parameters |\n\nImplied `$`: bare `.method()` means `$ -> .method()`.\nExample: `\"hello\" -> .upper` is the same as `\"hello\" -> $.upper()`.\n\nAlways prefer implicit `$` shorthand:\n\n $.method() -> .method \"x\" -> .upper (not $.upper())\n func($) -> func \"x\" -> log (not log($))\n $fn($) -> $fn 5 -> $double (not $double($))\n\nDon't capture just to continue \u2014 use line continuation instead:\n\n # avoid # good\n \"x\" => $a \"x\"\n $a -> .upper => $b -> .upper\n $b -> .len -> .len\n\nOnly capture when the variable is reused later in the code.\n\n## Control Flow\n\nConditional (if-else):\n\n cond ? then_expr ! else_expr\n cond ? then_expr # else returns empty string\n\nPiped conditional (`$` becomes condition):\n\n value -> ? then_expr ! else_expr\n\nMulti-line conditionals (`?` and `!` work as line continuations):\n\n condition\n ? \"yes\"\n ! \"no\"\n value -> is_valid\n ? \"ok\"\n ! \"error\"\n $val -> .eq(\"A\") ? \"a\"\n ! .eq(\"B\") ? \"b\"\n ! \"c\"\n\nCondition loop (NO `while` keyword \u2014 use `@` operator):\n\n init_value -> ($ < 10) @ { $ + 1 } # $ is accumulator\n\nDo-condition loop (body runs at least once):\n\n init_value -> @ { $ + 1 } ? ($ < 10)\n\nBreak (exits loop, returns collected results before break):\n\n list[1,2,3,4,5] -> each {\n ($ == 3) ? break\n $\n } # returns list[1, 2]\n\nReturn (exits block or script with value):\n\n 5 => $x\n ($x > 3) ? (\"big\" -> return)\n \"small\" # returns \"big\"\n \"done\" -> return # exits script with \"done\"\n\nAssert (validate condition, halt if false, pass through if true):\n\n 5 -> assert ($ > 0) # returns 5\n -1 -> assert ($ > 0) # ERROR: Assertion failed\n \"\" -> assert !.empty \"Input required\" # ERROR: Input required\n $val -> assert $:?list \"Expected list\" # type validation\n\nError (halt execution immediately with message):\n\n error \"Something went wrong\" # halt with message\n \"Operation failed\" -> error # piped form (must be string)\n error \"Status: {$code}\" # interpolation works\n\nPass (returns `$` unchanged, explicit no-op):\n\n cond ? pass ! \"fallback\" # preserve $ when condition true\n cond ? \"value\" ! pass # preserve $ when condition false\n \"data\" -> { dict[status: pass] } # include $ in dict: dict[status: \"data\"]\n list[1, -2, 3] -> map { ($ > 0) ? pass ! 0 } # list[1, 0, 3]\n\nNote: `pass` requires pipe context. Using `pass` without `$` throws error.\n\n## Closures\n\n**Block-closures:** `{ body }` in expression position\n\n { $ + 1 } => $inc # implicit $ parameter\n $inc(5) # 6\n 5 -> $inc # 6 (pipe invocation)\n dict[x: { $ * 2 }] # dict value is closure\n\n**Explicit closures:** `|params| body`\n\n |x|($x + 1) => $inc # named parameter\n |a, b|($a + $b) => $add # multiple params\n |x = 0|($x + 1) => $inc_or_one # default value\n |x: number|($x + 1) => $typed # type annotation\n\n`{ body }` vs `( expr )` distinction:\n\n| Syntax | Semantics | Example |\n|---|---|---|\n| `{ body }` | Deferred (closure) | `{ $ + 1 } => $fn` |\n| `( expr )` | Eager (immediate eval) | `( 5 + 1 ) => $x` gives 6 |\n\nLATE BINDING: closures capture scope, not values. Variables resolve at call time.\n\n`$` vs named params:\n- Use `$` in inline pipes and loops: `\"hello\" -> { .upper }`\n- Use named params in stored closures: `|x| ($x * 2) => $double`\n- `$` is undefined when a stored closure is called later \u2014 always use params.\n\nZero-param dict closures (methods):\n\n dict[count: 3, double: ||{ $.count * 2 }] => $obj\n $obj.double # 6 ($ is bound to dict)\n\n## Collection Operators\n\nChoose the right operator:\n\n Transform each item? -> map { }\n Side effects per item? -> each { }\n Single result from list? -> fold(init) { $@ + $ }\n Filter items? -> filter { }\n Results + running total? -> each(init) { ... $@ ... }\n Loop with state? -> (cond) @ { } (see Control Flow)\n\n| Operator | Execution | Returns | Break? |\n|---|---|---|---|\n| `-> each { }` | sequential | all body results | yes |\n| `-> each(i) { $@ + $ }` | sequential | all with accumulator | yes |\n| `-> map { }` | parallel | all body results | NO |\n| `-> filter { }` | parallel | matching elements | NO |\n| `-> fold(i) { $@ + $ }` | sequential | final result only | yes |\n\n`$@` is the accumulator in `each(init)` and `fold(init)`.\n\nMethod shorthand in collection operators:\n\n list[\"a\", \"b\"] -> map .upper # list[\"A\", \"B\"]\n list[\"\", \"x\"] -> filter (!.empty) # list[\"x\"]\n list[\"a\", \"b\"] -> map .pad_start(3, \"0\") # list[\"00a\", \"00b\"] (with args)\n list[\" HI \"] -> map .trim.lower # list[\"hi\"] (chained methods)\n\nBody forms (all operators accept these):\n\n -> each { $ * 2 } # block ($ is current element)\n -> each ($ + 10) # grouped expression\n -> each |x| ($x * 2) # inline closure\n -> each $double # variable closure\n -> each .upper # method shorthand\n -> each log # built-in function\n\nDict iteration (`$` contains `key` and `value` fields):\n\n dict[a: 1, b: 2] -> each { \"{$.key}={$.value}\" } # list[\"a=1\", \"b=2\"]\n dict[a: 1, b: 5] -> filter { $.value > 2 } # entries where value > 2\n\nString iteration (iterates over characters):\n\n \"abc\" -> each { \"{$}!\" } # list[\"a!\", \"b!\", \"c!\"]\n \"hello\" -> filter { $ != \"l\" } # list[\"h\", \"e\", \"o\"]\n\n## Property Access\n\n $data.field # dict field\n $data[0], $data[-1] # list index (negative from end)\n $data.$key # variable as key\n $data.($i + 1) # computed key\n $data.(a || b) # try keys left-to-right\n $data.field ?? \"default\" # default if missing\n $data.?field # existence check (boolean)\n $data.?$keyVar # variable existence check\n $data.?($expr) # computed existence check\n $data.?field&string # existence AND type check\n $data.?$key&number # variable existence + type check\n $data.?($a -> \"{$}_b\")&list # computed existence + type check\n\nDict keys take priority over built-in methods. A dict with key `len` returns that key's value, not the built-in `.len` method.\n\n## Types and Assertions\n\n**Type names:**\n\n string number bool list dict ordered\n tuple closure vector iterator any type\n\n**Type assertion** `:type` \u2014 errors if value does not match:\n\n 42:number # passes\n \"x\":number # RILL-R002: expected number, got string\n $val:list(string) # assert parameterized type\n\n**Type check** `:?type` \u2014 returns boolean, never errors:\n\n 42:?number # true\n \"x\":?number # false\n\nBoth forms work as pipe targets:\n\n $val -> :number # assert in pipe\n $val -> :?number # check in pipe\n\n**Union types** (`T1|T2`) \u2014 match any member type:\n\n 42 -> :string|number # passes (number matches)\n 42:?string|number # true\n \"hello\" => $x:string|number # capture with union type\n\n**Enforcing dict shapes** with `dict(field: type, ...)`:\n\n $data -> :dict(name: string, age: number) # assert exact fields and types\n $data:?dict(name: string, age: number) # check without error\n\nUse in closure params to validate input structure:\n\n |d: dict(name: string, age: number)| {\n \"{$d.name} is {$d.age}\"\n } => $format_person\n\n**Parameterized type constructors** (structural types):\n\n list(string) # list of strings\n dict(name: string, age: number) # dict with named fields\n tuple(number, string) # positional tuple\n ordered(x: number, y: number) # named ordered args\n\n**Type conversion** `:>type` \u2014 explicit conversion between compatible types:\n\n 42 -> :>string # \"42\"\n \"3.14\" -> :>number # 3.14\n list[1, 2] -> :>tuple # tuple[1, 2]\n tuple[1, 2] -> :>list # list[1, 2]\n ordered[a: 1] -> :>dict # dict[a: 1]\n\n## Common Patterns\n\n**Process an API response:**\n\n app::fetch(\"https://api.example.com/users\") => $response\n $response.data\n -> filter { $.active }\n -> map { dict[name: $.name, email: $.email] }\n -> each {\n \"Processing {$.name}\" -> log\n app::send_welcome($.email)\n }\n\n**Build a result from a list:**\n\n list[\"alice\", \"bob\", \"charlie\"]\n -> map { dict[name: $, greeting: \"Hello, {$}!\"] }\n -> fold(dict[]) {\n dict[...$@, $.name: $.greeting]\n }\n # dict[alice: \"Hello, alice!\", bob: \"Hello, bob!\", charlie: \"Hello, charlie!\"]\n\n**Validate and transform input:**\n\n $input -> assert $:?string \"Expected string input\"\n $input\n -> .trim\n -> assert !.empty \"Input cannot be empty\"\n -> .split(\",\")\n -> map .trim\n -> filter (!.empty)\n\n**Stateful retry loop:**\n\n dict[attempts: 0, max: 3, result: \"\", done: false]\n -> (!$.done && $.attempts < $.max) @ {\n $.attempts + 1 => $try\n app::fetch($url) => $res\n $res.?status&number\n ? ($res.status == 200)\n ? dict[attempts: $try, max: $.max, result: $res.body, done: true]\n ! dict[attempts: $try, max: $.max, result: \"\", done: false]\n ! dict[attempts: $try, max: $.max, result: \"\", done: false]\n }\n -> $.done ? $.result ! error \"Failed after {$.max} attempts\"\n\n**Reduce with running state:**\n\n list[10, 25, 5, 40, 15]\n -> each(dict[sum: 0, max: 0]) {\n $.sum + $@ => $new_sum\n ($ > $@.max) ? $ ! $@.max => $new_max\n dict[sum: $new_sum, max: $new_max]\n }\n # each item produces the running state; last element is final\n\n## Method Reference\n\n### String Methods\n\n| Method | Description |\n|---|---|\n| `.len` | length |\n| `.empty` | is empty string |\n| `.trim` | remove whitespace |\n| `.upper` | uppercase |\n| `.lower` | lowercase |\n| `.head` | first character |\n| `.tail` | last character |\n| `.at(i)` | character at index |\n| `.first` | iterator at first character |\n| `.split(sep)` | split into list (default: newline) |\n| `.lines` | split on newlines |\n| `.contains(s)` | substring check |\n| `.starts_with(s)` | prefix check |\n| `.ends_with(s)` | suffix check |\n| `.index_of(s)` | first match position (-1 if none) |\n| `.replace(p, r)` | replace first regex match |\n| `.replace_all(p, r)` | replace all regex matches |\n| `.match(regex)` | first match info (dict with matched, index, groups) |\n| `.is_match(regex)` | boolean regex check |\n| `.repeat(n)` | repeat n times |\n| `.pad_start(n, f)` | pad start |\n| `.pad_end(n, f)` | pad end |\n\n### List Methods\n\n| Method | Description |\n|---|---|\n| `.len` | length |\n| `.empty` | is empty |\n| `.head` | first element |\n| `.tail` | last element |\n| `.first` | iterator at first element |\n| `.at(i)` | element at index |\n| `.join(sep)` | join elements with separator |\n| `.has(val)` | contains value (deep equality) |\n| `.has_any(list)` | contains any value from candidates |\n| `.has_all(list)` | contains all values from candidates |\n\n### Dict Methods\n\n| Method | Description |\n|---|---|\n| `.len` | number of entries |\n| `.empty` | is empty |\n| `.first` | iterator at first entry |\n| `.keys` | keys as list |\n| `.values` | values as list |\n| `.entries` | list of `tuple[k, v]` pairs |\n\n### Comparison Methods\n\n .eq(val) == .ne(val) != .lt(val) < .gt(val) > .le(val) <= .ge(val) >=\n Example: $age -> .ge(18) ? \"adult\" ! \"minor\"\n\n### Built-in Functions\n\n| Function | Description |\n|---|---|\n| `log(val)` | print and pass through |\n| `json(val)` | convert to JSON string |\n| `identity(val)` | returns input unchanged |\n| `range(start, end, step?)` | number sequence (iterator) |\n| `repeat(val, count)` | repeat value n times (iterator) |\n| `enumerate(coll)` | lists: `tuple[index, value]`; dicts: `tuple[index, key, value]` |\n| `chain($fn)` | apply single closure; chain(val, list[$f, $g]) applies in sequence |\n\n## Style\n\n### Naming: snake_case\n\n $user_name, $item_list, $is_valid # variables\n $double_value, $cleanup_text # closures\n dict[first_name: \"x\", last_name: \"y\"] # dict keys\n\n### Spacing\n\n Operators: space both sides 5 + 3, $x -> .upper, \"a\" => $b\n Parentheses: no inner space ($x + 1), ($ > 3) ? \"yes\"\n Braces: space inside { $x + 1 }, each { $ * 2 }\n Brackets: no inner space $list[0], $dict.items[1]\n Literals: space after , and : list[1, 2, 3], dict[name: \"x\", age: 30]\n Keyword+[ NO space between list[1, 2] (not list [1, 2] \u2014 RILL-P007)\n Closures: space after params |x| ($x * 2), |a, b| { $a + $b }\n Methods: no space before . or ( $str.upper(), $list.join(\", \")\n Pipes: space both sides \"x\" -> .upper -> .len\n Continuations: indent 2 spaces $data\n -> .filter { $.active }\n -> map { $.name }\n\n## Extended Reference\n\n### Typed Closures\n\n**Anonymous typed closures:** `|type|{ body }` \u2014 reserved type keyword as param, `$` is type-checked piped input\n\n \"hello\" -> |string|{ $ -> .upper } # $ is string, checked at call\n 5 -> |number|{ $ * 2 } # 10\n |number|{ $ * 2 }:number => $double # stored with return type assertion\n 5 -> $double # 10\n \"hi\" -> $double # RILL-R001: expected number, got string\n\nAll 12 type names valid: string, number, bool, list, dict, ordered, tuple, closure, vector, iterator, any, type\nParameterized: |list(number)|{ $ -> each { $ * 2 } }\n\n**Return type assertions** (enforced at runtime \u2014 RILL-R004 on mismatch):\n\n |x: number| { \"{$x}\" }:string => $fn # asserts string return type\n $fn(42) # \"42\" (passes assertion)\n\n |x: number| { $x * 2 }:string => $fn # mismatch halts with RILL-R004\n $fn(5) # RILL-R004: expected string, got number\n\n### Callable Reflection\n\n`.^input` and `.^output` work on ALL callable types:\n\n |x: number, y: string|($x) => $fn\n $fn.^input # ordered(x: number, y: string)\n $fn.^output # any (no return type declared)\n\n |x: number|{ $x * 2 }:number => $fn2\n $fn2.^output # number\n\n`.^input` returns an ordered dict mapping parameter names to type values.\n`.^output` returns the declared return type (`any` if undeclared).\nBoth work on script closures, built-in functions, and host functions.\n\n**Description shorthand** (bare string in `^(...)` expands to `description: <string>`):\n\n ^(\"Get weather for city\") |city: string|($city) => $weather\n $weather.^description # \"Get weather for city\"\n\n ^(\"Fetch profile\", cache: true) |id|($id) => $get_user\n $get_user.^description # \"Fetch profile\"\n $get_user.^cache # true\n\n### Dispatch Operators\n\n**Dict dispatch** (single key) \u2014 pipe a value to a dict to match keys:\n\n $val -> dict[apple: \"fruit\", carrot: \"veg\"] # \"fruit\" if $val is \"apple\"\n $val -> dict[apple: \"fruit\"] ?? \"not found\" # default if no match\n $method -> dict[list[\"GET\", \"HEAD\"]: \"safe\", list[\"POST\", \"PUT\"]: \"unsafe\"] # multi-key\n\nType-aware matching (keys matched by value AND type):\n\n 1 -> dict[1: \"number\", \"1\": \"string\"] # \"number\"\n \"1\" -> dict[1: \"number\", \"1\": \"string\"] # \"string\"\n true -> dict[true: \"bool\", \"true\": \"str\"] # \"bool\"\n\n**List dispatch** (index) \u2014 pipe a number to a list:\n\n 0 -> list[\"first\", \"second\"] # \"first\"\n -1 -> list[\"first\", \"second\"] # \"second\" (last)\n 5 -> list[\"a\", \"b\"] ?? \"not found\" # default if out of bounds\n\n**Hierarchical dispatch** (path navigation) \u2014 pipe a list of keys/indexes:\n\n list[\"name\", \"first\"] -> dict[name: dict[first: \"Alice\"]] # \"Alice\"\n list[0, 1] -> list[list[1, 2, 3], list[4, 5, 6]] # 2\n list[] -> dict[a: 1] # dict[a: 1] (empty path = unchanged)\n list[\"a\", \"missing\"] -> dict[a: dict[x: 1]] ?? \"default\" # \"default\"\n\nNote: lists require same-type elements. For mixed paths (strings and numbers), use property access:\n\n dict[users: list[dict[name: \"Alice\"]]] => $d\n $d.users[0].name # \"Alice\"\n\n### Extraction Operators\n\nDestructure (`destruct<>`):\n\n list[1, 2, 3] -> destruct<$a, $b, $c> # $a=1, $b=2, $c=3\n dict[x: 1, y: 2] -> destruct<x: $a, y: $b> # $a=1, $b=2\n list[1, 2, 3] -> destruct<$first, _, $third> # _ skips element\n\nSlice (`slice<start:stop:step>`):\n\n list[0,1,2,3,4] -> slice<1:3> # list[1, 2]\n list[0,1,2,3,4] -> slice<-2:> # list[3, 4]\n list[0,1,2,3,4] -> slice<::-1> # list[4,3,2,1,0] (reverse)\n \"hello\" -> slice<1:4> # \"ell\"\n\n### List Spread\n\n list[1, 2] => $a\n list[...$a, 3] # list[1, 2, 3]\n list[...$a, ...$b] # concatenate lists\n list[...($nums -> map {$ * 2})] # spread expression result\n\n### Argument Unpacking\n\n tuple[1, 2, 3] -> $fn(...) # positional spread: $fn(1, 2, 3)\n ordered[a: 10, b: 2] -> $fn(...) # named spread: keys must match parameter order\n tuple[...$list, 3] -> $fn(...) # spread in tuple then spread into call\n tuple[1, 2, 3] => $args\n $args -> $fn(...) # spread stored tuple\n ordered[a: 1, b: 2] => $named\n $named -> $fn(...) # spread stored ordered\n\n### Type Conversion Matrix\n\n`:>type` compatibility (error = halts with RILL-R036, no-op = same-type identity):\n\n Source | :>list | :>dict | :>tuple | :>ordered(sig) | :>number | :>string | :>bool\n ---------|---------|---------|---------|----------------|----------|----------|-------\n list | no-op | error | valid | error | error | valid\u00B9 | error\n dict | error | no-op | error | valid | error | valid\u00B9 | error\n tuple | valid | error | no-op | error | error | valid\u00B9 | error\n ordered | error | valid | error | no-op | error | valid\u00B9 | error\n string | error | error | error | error | valid\u00B2 | no-op | valid\u00B3\n number | error | error | error | error | no-op | valid\u00B9 | valid\u2075\n bool | error | error | error | error | valid\u2074 | valid\u00B9 | no-op\n\n \u00B9 Uses formatValue semantics for formatted output\n \u00B2 Parseable strings only; halts with RILL-R038 on failure\n \u00B3 Accepts only \"true\" and \"false\"; halts with RILL-R036 otherwise\n \u2074 true maps to 1, false maps to 0\n \u2075 0 maps to false, 1 maps to true; all other values halt with RILL-R036\n\n**Default values in type constructors** (used with `:>` conversion):\n\n dict(a: string, b: string = \"x\") # field b defaults to \"x\"\n ordered(x: number, y: number = 0) # field y defaults to 0\n tuple(string, number = 0) # trailing element defaults to 0\n\n dict[b: \"b\"] -> :>dict(b: string, a: string = \"a\") # dict[a: \"a\", b: \"b\"]\n\nOnly `:>` conversion fills defaults. `:` assertion does NOT hydrate defaults.\n`:>dict(...)` and `:>ordered(...)` fill missing fields from type constructor defaults.\nNested fields are recursively hydrated.\n\n### Type Inspection\n\n**`^type` operator** \u2014 returns a type value for inspection:\n\n 42.^type # type value for number\n 42.^type.name # \"number\"\n list[1, 2].^type.name # \"list\"\n list[1, 2].^type.signature # \"list(number)\"\n\n**Type value equality:**\n\n $val.^type == list(number) # true if $val is list(number)\n $val.^type == $other.^type # compare structural types\n\n### Modules\n\n`use<scheme:resource>` resolves a named resource through a host-registered scheme resolver:\n\n use<module:greetings> => $g # load module, capture as $g\n $g.hello(\"World\") # call module member\n use<ext:qdrant.search> # load extension member\n\n`use<>` returns the resolved value (dict, closure, or any rill type). The host registers resolvers for each scheme. Scripts cannot define resolvers.\n\n### Iterators\n\nLazy sequence generation. Collection operators auto-expand iterators.\n\n range(0, 5) -> each { $ * 2 } # list[0, 2, 4, 6, 8]\n repeat(\"x\", 3) -> each { $ } # list[\"x\", \"x\", \"x\"]\n\n`.first()` method (returns iterator for any collection):\n\n list[1, 2, 3] -> .first() # iterator at 1\n \"abc\" -> .first() # iterator at \"a\"\n\nIterator protocol (dict with `value`, `done`, `next`):\n\n $it.done # bool: is exhausted?\n $it.value # current element\n $it.next() # returns new iterator at next position\n\n### Iteration Limits\n\nDefault: 10,000 iterations max for loops.\nOverride: `^(limit: N)` at operator level (between operator name and body).\n\n 0 -> ($ < 50) @ ^(limit: 100) { $ + 1 } # while loop\n $items -> each ^(limit: 1000) { process($) } # each operator\n $items -> map ^(limit: 3) { slow_process($) } # concurrency limit\n\nInvalid annotation keys produce a runtime error.\n\n### Operator Precedence (Highest to Lowest)\n\n1. Member access: `.field`, `[index]`\n2. Type operators: `:type`, `:?type`\n3. Unary: `-`, `!`\n4. Multiplicative: `*`, `/`, `%`\n5. Additive: `+`, `-`\n6. Comparison: `==`, `!=`, `<`, `>`, `<=`, `>=`\n7. Logical AND: `&&`\n8. Logical OR: `||`\n9. Default: `??`\n10. Pipe: `->`\n11. Capture: `=>`\n\nUse parentheses to override: `(2 + 3) * 4`\n\n### Script Return Values\n\n| Return value | Exit code |\n|---|---|\n| `true` / non-empty string | 0 |\n| `false` / empty string | 1 |\n| `list[0, \"message\"]` | 0 with message |\n| `list[1, \"message\"]` | 1 with message |\n";
|