@rcrsr/rill 0.5.0 → 0.6.1
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 +88 -162
- package/dist/generated/introspection-data.d.ts +1 -1
- package/dist/generated/introspection-data.d.ts.map +1 -1
- package/dist/generated/introspection-data.js +107 -186
- package/dist/generated/introspection-data.js.map +1 -1
- package/dist/generated/version-data.d.ts +1 -1
- package/dist/generated/version-data.js +4 -4
- package/dist/generated/version-data.js.map +1 -1
- package/dist/highlight-map.d.ts +4 -0
- package/dist/highlight-map.d.ts.map +1 -0
- package/dist/highlight-map.js +71 -0
- package/dist/highlight-map.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/lexer/errors.d.ts.map +1 -1
- package/dist/lexer/errors.js +9 -3
- package/dist/lexer/errors.js.map +1 -1
- package/dist/lexer/operators.js +1 -1
- package/dist/lexer/tokenizer.d.ts.map +1 -1
- package/dist/lexer/tokenizer.js +0 -14
- package/dist/lexer/tokenizer.js.map +1 -1
- package/dist/parser/helpers.d.ts +8 -0
- package/dist/parser/helpers.d.ts.map +1 -1
- package/dist/parser/helpers.js +4 -4
- package/dist/parser/helpers.js.map +1 -1
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/parser/index.js +1 -1
- package/dist/parser/index.js.map +1 -1
- package/dist/parser/parser-collect.js +1 -1
- package/dist/parser/parser-collect.js.map +1 -1
- package/dist/parser/parser-control.js +4 -4
- package/dist/parser/parser-control.js.map +1 -1
- package/dist/parser/parser-expr.js +32 -10
- package/dist/parser/parser-expr.js.map +1 -1
- package/dist/parser/parser-extract.js +7 -3
- package/dist/parser/parser-extract.js.map +1 -1
- package/dist/parser/parser-functions.d.ts.map +1 -1
- package/dist/parser/parser-functions.js +7 -18
- package/dist/parser/parser-functions.js.map +1 -1
- package/dist/parser/parser-literals.js +15 -15
- package/dist/parser/parser-literals.js.map +1 -1
- package/dist/parser/parser-script.js +3 -3
- package/dist/parser/parser-script.js.map +1 -1
- package/dist/parser/parser-variables.js +4 -4
- package/dist/parser/parser-variables.js.map +1 -1
- package/dist/parser/state.d.ts +1 -1
- package/dist/parser/state.d.ts.map +1 -1
- package/dist/parser/state.js +2 -2
- package/dist/parser/state.js.map +1 -1
- package/dist/runtime/core/callable.d.ts +20 -0
- package/dist/runtime/core/callable.d.ts.map +1 -1
- package/dist/runtime/core/callable.js +30 -7
- package/dist/runtime/core/callable.js.map +1 -1
- package/dist/runtime/core/context.d.ts +21 -0
- package/dist/runtime/core/context.d.ts.map +1 -1
- package/dist/runtime/core/context.js +75 -4
- package/dist/runtime/core/context.js.map +1 -1
- package/dist/runtime/core/eval/base.d.ts.map +1 -1
- package/dist/runtime/core/eval/base.js +3 -3
- package/dist/runtime/core/eval/base.js.map +1 -1
- package/dist/runtime/core/eval/index.d.ts.map +1 -1
- package/dist/runtime/core/eval/index.js +2 -0
- package/dist/runtime/core/eval/index.js.map +1 -1
- package/dist/runtime/core/eval/mixins/annotations.js +3 -3
- package/dist/runtime/core/eval/mixins/annotations.js.map +1 -1
- package/dist/runtime/core/eval/mixins/closures.d.ts.map +1 -1
- package/dist/runtime/core/eval/mixins/closures.js +69 -40
- package/dist/runtime/core/eval/mixins/closures.js.map +1 -1
- package/dist/runtime/core/eval/mixins/collections.js +15 -15
- package/dist/runtime/core/eval/mixins/collections.js.map +1 -1
- package/dist/runtime/core/eval/mixins/control-flow.d.ts.map +1 -1
- package/dist/runtime/core/eval/mixins/control-flow.js +12 -12
- package/dist/runtime/core/eval/mixins/control-flow.js.map +1 -1
- package/dist/runtime/core/eval/mixins/core.d.ts.map +1 -1
- package/dist/runtime/core/eval/mixins/core.js +12 -13
- package/dist/runtime/core/eval/mixins/core.js.map +1 -1
- package/dist/runtime/core/eval/mixins/expressions.js +9 -9
- package/dist/runtime/core/eval/mixins/expressions.js.map +1 -1
- package/dist/runtime/core/eval/mixins/extraction.d.ts.map +1 -1
- package/dist/runtime/core/eval/mixins/extraction.js +15 -15
- package/dist/runtime/core/eval/mixins/extraction.js.map +1 -1
- package/dist/runtime/core/eval/mixins/literals.js +22 -22
- package/dist/runtime/core/eval/mixins/literals.js.map +1 -1
- package/dist/runtime/core/eval/mixins/types.js +4 -4
- package/dist/runtime/core/eval/mixins/types.js.map +1 -1
- package/dist/runtime/core/eval/mixins/variables.js +34 -34
- package/dist/runtime/core/eval/mixins/variables.js.map +1 -1
- package/dist/runtime/core/execute.js +3 -3
- package/dist/runtime/core/execute.js.map +1 -1
- package/dist/runtime/core/introspection.d.ts +30 -1
- package/dist/runtime/core/introspection.d.ts.map +1 -1
- package/dist/runtime/core/introspection.js +47 -1
- package/dist/runtime/core/introspection.js.map +1 -1
- package/dist/runtime/core/types.d.ts +11 -0
- package/dist/runtime/core/types.d.ts.map +1 -1
- package/dist/runtime/core/types.js.map +1 -1
- package/dist/runtime/ext/builtins.js +22 -22
- package/dist/runtime/ext/builtins.js.map +1 -1
- package/dist/runtime/ext/extensions.d.ts +1 -1
- package/dist/runtime/ext/extensions.d.ts.map +1 -1
- package/dist/runtime/ext/extensions.js +4 -5
- package/dist/runtime/ext/extensions.js.map +1 -1
- package/dist/runtime/index.d.ts +6 -4
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +3 -2
- package/dist/runtime/index.js.map +1 -1
- package/dist/types.d.ts +36 -37
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +440 -120
- package/dist/types.js.map +1 -1
- package/package.json +7 -66
- package/dist/check/config.d.ts +0 -20
- package/dist/check/config.d.ts.map +0 -1
- package/dist/check/config.js +0 -151
- package/dist/check/config.js.map +0 -1
- package/dist/check/fixer.d.ts +0 -39
- package/dist/check/fixer.d.ts.map +0 -1
- package/dist/check/fixer.js +0 -119
- package/dist/check/fixer.js.map +0 -1
- package/dist/check/index.d.ts +0 -10
- package/dist/check/index.d.ts.map +0 -1
- package/dist/check/index.js +0 -21
- package/dist/check/index.js.map +0 -1
- package/dist/check/rules/anti-patterns.d.ts +0 -65
- package/dist/check/rules/anti-patterns.d.ts.map +0 -1
- package/dist/check/rules/anti-patterns.js +0 -481
- package/dist/check/rules/anti-patterns.js.map +0 -1
- package/dist/check/rules/closures.d.ts +0 -66
- package/dist/check/rules/closures.d.ts.map +0 -1
- package/dist/check/rules/closures.js +0 -370
- package/dist/check/rules/closures.js.map +0 -1
- package/dist/check/rules/collections.d.ts +0 -90
- package/dist/check/rules/collections.d.ts.map +0 -1
- package/dist/check/rules/collections.js +0 -373
- package/dist/check/rules/collections.js.map +0 -1
- package/dist/check/rules/conditionals.d.ts +0 -41
- package/dist/check/rules/conditionals.d.ts.map +0 -1
- package/dist/check/rules/conditionals.js +0 -134
- package/dist/check/rules/conditionals.js.map +0 -1
- package/dist/check/rules/flow.d.ts +0 -46
- package/dist/check/rules/flow.d.ts.map +0 -1
- package/dist/check/rules/flow.js +0 -206
- package/dist/check/rules/flow.js.map +0 -1
- package/dist/check/rules/formatting.d.ts +0 -133
- package/dist/check/rules/formatting.d.ts.map +0 -1
- package/dist/check/rules/formatting.js +0 -648
- package/dist/check/rules/formatting.js.map +0 -1
- package/dist/check/rules/helpers.d.ts +0 -26
- package/dist/check/rules/helpers.d.ts.map +0 -1
- package/dist/check/rules/helpers.js +0 -66
- package/dist/check/rules/helpers.js.map +0 -1
- package/dist/check/rules/index.d.ts +0 -21
- package/dist/check/rules/index.d.ts.map +0 -1
- package/dist/check/rules/index.js +0 -78
- package/dist/check/rules/index.js.map +0 -1
- package/dist/check/rules/loops.d.ts +0 -77
- package/dist/check/rules/loops.d.ts.map +0 -1
- package/dist/check/rules/loops.js +0 -310
- package/dist/check/rules/loops.js.map +0 -1
- package/dist/check/rules/naming.d.ts +0 -21
- package/dist/check/rules/naming.d.ts.map +0 -1
- package/dist/check/rules/naming.js +0 -174
- package/dist/check/rules/naming.js.map +0 -1
- package/dist/check/rules/strings.d.ts +0 -28
- package/dist/check/rules/strings.d.ts.map +0 -1
- package/dist/check/rules/strings.js +0 -79
- package/dist/check/rules/strings.js.map +0 -1
- package/dist/check/rules/types.d.ts +0 -41
- package/dist/check/rules/types.d.ts.map +0 -1
- package/dist/check/rules/types.js +0 -167
- package/dist/check/rules/types.js.map +0 -1
- package/dist/check/types.d.ts +0 -112
- package/dist/check/types.d.ts.map +0 -1
- package/dist/check/types.js +0 -6
- package/dist/check/types.js.map +0 -1
- package/dist/check/validator.d.ts +0 -18
- package/dist/check/validator.d.ts.map +0 -1
- package/dist/check/validator.js +0 -110
- package/dist/check/validator.js.map +0 -1
- package/dist/check/visitor.d.ts +0 -33
- package/dist/check/visitor.d.ts.map +0 -1
- package/dist/check/visitor.js +0 -259
- package/dist/check/visitor.js.map +0 -1
- package/dist/cli-check.d.ts +0 -43
- package/dist/cli-check.d.ts.map +0 -1
- package/dist/cli-check.js +0 -368
- package/dist/cli-check.js.map +0 -1
- package/dist/cli-eval.d.ts +0 -15
- package/dist/cli-eval.d.ts.map +0 -1
- package/dist/cli-eval.js +0 -116
- package/dist/cli-eval.js.map +0 -1
- package/dist/cli-exec.d.ts +0 -49
- package/dist/cli-exec.d.ts.map +0 -1
- package/dist/cli-exec.js +0 -183
- package/dist/cli-exec.js.map +0 -1
- package/dist/cli-module-loader.d.ts +0 -19
- package/dist/cli-module-loader.d.ts.map +0 -1
- package/dist/cli-module-loader.js +0 -83
- package/dist/cli-module-loader.js.map +0 -1
- package/dist/cli-shared.d.ts +0 -44
- package/dist/cli-shared.d.ts.map +0 -1
- package/dist/cli-shared.js +0 -108
- package/dist/cli-shared.js.map +0 -1
- package/dist/cli.d.ts +0 -13
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -62
- package/dist/cli.js.map +0 -1
- package/dist/runtime/core/introspection-data.d.ts +0 -2
- package/dist/runtime/core/introspection-data.d.ts.map +0 -1
- package/dist/runtime/core/introspection-data.js +0 -618
- package/dist/runtime/core/introspection-data.js.map +0 -1
- package/dist/runtime/core/version-data.d.ts +0 -18
- package/dist/runtime/core/version-data.d.ts.map +0 -1
- package/dist/runtime/core/version-data.js +0 -16
- package/dist/runtime/core/version-data.js.map +0 -1
- package/docs/00_INDEX.md +0 -67
- package/docs/01_guide.md +0 -390
- package/docs/02_types.md +0 -504
- package/docs/03_variables.md +0 -324
- package/docs/04_operators.md +0 -629
- package/docs/05_control-flow.md +0 -692
- package/docs/06_closures.md +0 -787
- package/docs/07_collections.md +0 -688
- package/docs/08_iterators.md +0 -330
- package/docs/09_strings.md +0 -205
- package/docs/10_parsing.md +0 -366
- package/docs/11_reference.md +0 -600
- package/docs/12_examples.md +0 -748
- package/docs/13_modules.md +0 -519
- package/docs/14_host-integration.md +0 -985
- package/docs/15_grammar.ebnf +0 -773
- package/docs/16_conventions.md +0 -695
- package/docs/17_cli-tools.md +0 -184
- package/docs/18_design-principles.md +0 -247
- package/docs/19_cookbook.md +0 -628
- package/docs/88_errors.md +0 -902
- package/docs/99_llm-reference.txt +0 -614
- package/docs/assets/logo.png +0 -0
package/docs/11_reference.md
DELETED
|
@@ -1,600 +0,0 @@
|
|
|
1
|
-
# rill Core Language Specification v0.5.0
|
|
2
|
-
|
|
3
|
-
*From prompts to workflows*
|
|
4
|
-
|
|
5
|
-
rill is a pipe-based scripting language for orchestrating workflows.
|
|
6
|
-
|
|
7
|
-
> **Experimental (v0.5.0).** Active development. Breaking changes until v1.0.
|
|
8
|
-
|
|
9
|
-
## Overview
|
|
10
|
-
|
|
11
|
-
rill is an imperative scripting language that is dynamically typed and type-safe. Types are checked at runtime, but type errors are always caught—there are no implicit conversions. Type annotations are optional, but variables lock their type on first assignment. The language is value-based: no references, all copies are deep, all comparisons are by value. Empty values are valid (empty strings, lists, dicts), but null and undefined do not exist. Control flow is singular: no exceptions, no try/catch. Data flows through pipes (`->`), not assignment.
|
|
12
|
-
|
|
13
|
-
## Design Principles
|
|
14
|
-
|
|
15
|
-
1. **Pipes over assignment** — Data flows via `->`. No `=` operator exists.
|
|
16
|
-
2. **Pattern-driven decisions** — Check response patterns, branch accordingly.
|
|
17
|
-
3. **Singular control flow** — No try/catch. Errors halt execution. Recovery requires explicit conditionals.
|
|
18
|
-
4. **Value-based** — All values compare by content. No references, no object identity.
|
|
19
|
-
5. **No null/undefined** — Empty values are valid, but "no value" cannot be represented.
|
|
20
|
-
6. **No magic** — No truthiness, no automatic type conversions. Explicit behavior only.
|
|
21
|
-
7. **Expressive and consistent** — Small syntax, coherent semantics. Every construct composes predictably.
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Quick Reference Tables
|
|
26
|
-
|
|
27
|
-
### Expression Delimiters
|
|
28
|
-
|
|
29
|
-
| Delimiter | Semantics | Produces |
|
|
30
|
-
|-----------|-----------|----------|
|
|
31
|
-
| `{ body }` | Deferred (closure creation) | `ScriptCallable` |
|
|
32
|
-
| `( expr )` | Eager (immediate evaluation) | Result value |
|
|
33
|
-
|
|
34
|
-
### Operators
|
|
35
|
-
|
|
36
|
-
| Category | Operators |
|
|
37
|
-
|----------|-----------|
|
|
38
|
-
| Arithmetic | `+`, `-`, `*`, `/`, `%` |
|
|
39
|
-
| Comparison | `==`, `!=`, `<`, `>`, `<=`, `>=` |
|
|
40
|
-
| Comparison | `.eq`, `.ne`, `.lt`, `.gt`, `.le`, `.ge` methods |
|
|
41
|
-
| Logical | `!` (unary), `&&`, `\|\|` |
|
|
42
|
-
| Pipe | `->` |
|
|
43
|
-
| Capture | `:>` |
|
|
44
|
-
| Spread | `@` (sequential), `*` (tuple) |
|
|
45
|
-
| Extraction | `*<>` (destructure), `/<>` (slice) |
|
|
46
|
-
| Type | `:type` (assert), `:?type` (check) |
|
|
47
|
-
| Member | `.field`, `[index]` |
|
|
48
|
-
| Default | `?? value` |
|
|
49
|
-
| Existence | `.?field`, `.?$var`, `.?($expr)`, `.?field&type` |
|
|
50
|
-
|
|
51
|
-
See [Operators](04_operators.md) for detailed documentation.
|
|
52
|
-
|
|
53
|
-
### Control Flow
|
|
54
|
-
|
|
55
|
-
| Syntax | Description |
|
|
56
|
-
|--------|-------------|
|
|
57
|
-
| `cond ? then ! else` | Conditional (if-else) |
|
|
58
|
-
| `$val -> ? then ! else` | Piped conditional ($ as condition) |
|
|
59
|
-
| `(cond) @ body` | While loop |
|
|
60
|
-
| `@ body ? cond` | Do-while |
|
|
61
|
-
| `break` / `$val -> break` | Exit loop |
|
|
62
|
-
| `return` / `$val -> return` | Exit block or script |
|
|
63
|
-
| `pass` | Returns current `$` unchanged (use in conditionals, dicts) |
|
|
64
|
-
| `assert cond` / `assert cond "msg"` | Validate condition, halt on failure |
|
|
65
|
-
| `error "msg"` / `$val -> error` | Halt execution with error message |
|
|
66
|
-
|
|
67
|
-
See [Control Flow](05_control-flow.md) for detailed documentation. Script-level exit functions must be host-provided.
|
|
68
|
-
|
|
69
|
-
### Collection Operators
|
|
70
|
-
|
|
71
|
-
| Syntax | Description |
|
|
72
|
-
|--------|-------------|
|
|
73
|
-
| `-> each { body }` | Sequential iteration, all results |
|
|
74
|
-
| `-> each(init) { body }` | Sequential with accumulator (`$@`) |
|
|
75
|
-
| `-> map { body }` | Parallel iteration, all results |
|
|
76
|
-
| `-> filter { cond }` | Parallel filter, matching elements |
|
|
77
|
-
| `-> fold(init) { body }` | Sequential reduction, final result |
|
|
78
|
-
|
|
79
|
-
See [Collections](07_collections.md) for detailed documentation.
|
|
80
|
-
|
|
81
|
-
### Types
|
|
82
|
-
|
|
83
|
-
| Type | Syntax | Example | Produces |
|
|
84
|
-
|------|--------|---------|----------|
|
|
85
|
-
| String | `"text"`, `"""text"""` | `"hello"`, `"""line 1\nline 2"""` | String value |
|
|
86
|
-
| Number | `123`, `0.5` | `42`, `0.9` | Number value |
|
|
87
|
-
| Bool | `true`, `false` | `true` | Boolean value |
|
|
88
|
-
| List | `[a, b]`, `[...$list]` | `["file.ts", 42]`, `[...$a, 3]` | List value |
|
|
89
|
-
| Dict | `[k: v]`, `[$k: v]`, `[($e): v]` | `[output: "text"]`, `[$key: 1]` | Dict value |
|
|
90
|
-
| Tuple | `*[...]` | `*[1, 2]`, `*[x: 1, y: 2]` | Tuple value |
|
|
91
|
-
| Closure | `\|\|{ }` | `\|x\|($x * 2)` | `ScriptCallable` |
|
|
92
|
-
| Block | `{ body }` | `{ $ + 1 }` | `ScriptCallable` |
|
|
93
|
-
|
|
94
|
-
See [Types](02_types.md) for detailed documentation.
|
|
95
|
-
|
|
96
|
-
### Functions
|
|
97
|
-
|
|
98
|
-
| Syntax | Description |
|
|
99
|
-
|--------|-------------|
|
|
100
|
-
| `\|p: type\|{ } :> $fn` | Define and capture function |
|
|
101
|
-
| `\|p = default\|{ }` | Parameter with default |
|
|
102
|
-
| `\|p ^(min: 0)\|{ }` | Parameter with annotation |
|
|
103
|
-
| `$fn(arg)` | Call function directly |
|
|
104
|
-
| `arg -> $fn()` | Call function with pipe value |
|
|
105
|
-
| `arg -> $fn` | Pipe-style invoke |
|
|
106
|
-
|
|
107
|
-
See [Closures](06_closures.md) for detailed documentation.
|
|
108
|
-
|
|
109
|
-
### Special Variables
|
|
110
|
-
|
|
111
|
-
| Variable | Contains | Source |
|
|
112
|
-
|----------|----------|--------|
|
|
113
|
-
| `$` | Piped value (current scope) | Grammar |
|
|
114
|
-
| `$ARGS` | CLI positional args (list) | Runtime |
|
|
115
|
-
| `$ENV.NAME` | Environment variable | Runtime |
|
|
116
|
-
| `$name` | Named variable | Runtime |
|
|
117
|
-
|
|
118
|
-
See [Variables](03_variables.md) for detailed documentation.
|
|
119
|
-
|
|
120
|
-
### `$` Binding by Context
|
|
121
|
-
|
|
122
|
-
| Context | `$` contains |
|
|
123
|
-
|---------|--------------|
|
|
124
|
-
| Inline block `-> { }` | Piped value |
|
|
125
|
-
| Each loop `-> each { }` | Current item |
|
|
126
|
-
| While-loop `(cond) @ { }` | Accumulated value |
|
|
127
|
-
| Do-while `@ { } ? cond` | Accumulated value |
|
|
128
|
-
| Conditional `cond ? { }` | Tested value |
|
|
129
|
-
| Piped conditional `-> ? { }` | Piped value |
|
|
130
|
-
| Stored closure `\|x\|{ }` | N/A — use params |
|
|
131
|
-
| Dict closure `\|\|{ $.x }` | Dict self |
|
|
132
|
-
|
|
133
|
-
### Property Access
|
|
134
|
-
|
|
135
|
-
| Syntax | Description |
|
|
136
|
-
|--------|-------------|
|
|
137
|
-
| `$data.field` | Literal field access |
|
|
138
|
-
| `$data[0]`, `$data[-1]` | Index access |
|
|
139
|
-
| `$data.$key` | Variable as key |
|
|
140
|
-
| `$data.($i + 1)` | Computed key |
|
|
141
|
-
| `$data.(a \|\| b)` | Alternative keys |
|
|
142
|
-
| `$data.field ?? default` | Default if missing |
|
|
143
|
-
| `$data.?field` | Existence check (literal) |
|
|
144
|
-
| `$data.?$key` | Existence check (variable) |
|
|
145
|
-
| `$data.?($expr)` | Existence check (computed) |
|
|
146
|
-
| `$data.?field&type` | Existence + type check |
|
|
147
|
-
| `$data.^key` | Annotation reflection |
|
|
148
|
-
|
|
149
|
-
### Dispatch
|
|
150
|
-
|
|
151
|
-
Pipe a value to a collection (dict or list) to retrieve the corresponding element.
|
|
152
|
-
|
|
153
|
-
**Dict Dispatch:** Match keys and return associated values.
|
|
154
|
-
|
|
155
|
-
| Syntax | Description |
|
|
156
|
-
|--------|-------------|
|
|
157
|
-
| `$val -> [k1: v1, k2: v2]` | Returns value for matching key |
|
|
158
|
-
| `$val -> [k1: v1, k2: v2] ?? default` | Returns matched value or default |
|
|
159
|
-
| `$val -> [["k1", "k2"]: shared]` | Multi-key dispatch (same value) |
|
|
160
|
-
|
|
161
|
-
```text
|
|
162
|
-
$value -> [apple: "fruit", carrot: "vegetable"] # Returns "fruit" if $value is "apple"
|
|
163
|
-
$value -> [apple: "fruit"] ?? "not found" # Returns "not found" if no match
|
|
164
|
-
$method -> [["GET", "HEAD"]: "safe", ["POST", "PUT"]: "unsafe"] # Multi-key dispatch
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
**Type-Aware Dispatch:** Keys match by both value and type.
|
|
168
|
-
|
|
169
|
-
| Input | Dict | Result |
|
|
170
|
-
|-------|------|--------|
|
|
171
|
-
| `1` | `[1: "one", 2: "two"]` | `"one"` |
|
|
172
|
-
| `"1"` | `[1: "one", "1": "string"]` | `"string"` |
|
|
173
|
-
| `true` | `[true: "yes", false: "no"]` | `"yes"` |
|
|
174
|
-
| `"true"` | `[true: "bool", "true": "string"]` | `"string"` |
|
|
175
|
-
| `1` | `[[1, "one"]: "match"]` | `"match"` |
|
|
176
|
-
| `"one"` | `[[1, "one"]: "match"]` | `"match"` |
|
|
177
|
-
|
|
178
|
-
Dict keys can be identifiers, numbers, or booleans. Multi-key syntax `[k1, k2]: value` maps multiple keys to the same value.
|
|
179
|
-
|
|
180
|
-
**Hierarchical Dispatch:** Navigate nested structures using a path list.
|
|
181
|
-
|
|
182
|
-
| Syntax | Description |
|
|
183
|
-
|--------|-------------|
|
|
184
|
-
| `[path] -> $target` | Navigate nested dict/list using path of keys/indexes |
|
|
185
|
-
| `[] -> $target` | Empty path returns target unchanged |
|
|
186
|
-
| `[k1, k2, ...] -> $dict` | Sequential navigation through nested dicts |
|
|
187
|
-
| `[0, 1, ...] -> $list` | Sequential navigation through nested lists |
|
|
188
|
-
| `[k, 0, k2] -> $mixed` | Mixed dict keys and list indexes |
|
|
189
|
-
|
|
190
|
-
Path element types: string keys for dict lookup, number indexes for list access (negative indexes supported). Type mismatch throws `RUNTIME_TYPE_ERROR`.
|
|
191
|
-
|
|
192
|
-
Terminal closures receive `$` bound to the final path key.
|
|
193
|
-
|
|
194
|
-
```text
|
|
195
|
-
["name", "first"] -> [name: [first: "Alice"]] # "Alice" (dict path)
|
|
196
|
-
[0, 1] -> [[1, 2, 3], [4, 5, 6]] # 2 (list path)
|
|
197
|
-
["users", 0, "name"] -> [users: [[name: "Alice"]]] # "Alice" (mixed path)
|
|
198
|
-
["req", "draft"] -> [req: [draft: { "key={$}" }]] # "key=draft" (terminal closure)
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
**List Dispatch:** Index into a list using a number.
|
|
202
|
-
|
|
203
|
-
| Syntax | Description |
|
|
204
|
-
|--------|-------------|
|
|
205
|
-
| `$idx -> [a, b, c]` | Returns element at index (0-based) |
|
|
206
|
-
| `$idx -> [a, b, c] ?? default` | Returns element or default if out of bounds |
|
|
207
|
-
|
|
208
|
-
```text
|
|
209
|
-
0 -> ["first", "second", "third"] # "first"
|
|
210
|
-
1 -> ["first", "second", "third"] # "second"
|
|
211
|
-
-1 -> ["first", "second", "third"] # "third" (last element)
|
|
212
|
-
5 -> ["a", "b"] ?? "not found" # "not found" (out of bounds)
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
**Variable Dispatch:** Use stored collections.
|
|
216
|
-
|
|
217
|
-
```rill
|
|
218
|
-
[apple: "fruit", carrot: "vegetable"] :> $lookup
|
|
219
|
-
"apple" -> $lookup # "fruit"
|
|
220
|
-
|
|
221
|
-
["a", "b", "c"] :> $items
|
|
222
|
-
1 -> $items # "b"
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
**Error Messages:**
|
|
226
|
-
|
|
227
|
-
| Scenario | Error |
|
|
228
|
-
|----------|-------|
|
|
229
|
-
| Dict dispatch key not found | `Dict dispatch: key '{key}' not found` |
|
|
230
|
-
| List dispatch index not found | `List dispatch: index '{index}' not found` |
|
|
231
|
-
| List dispatch with non-number | `List dispatch requires number index, got {type}` |
|
|
232
|
-
| Dispatch to non-collection | `Cannot dispatch to {type}` |
|
|
233
|
-
|
|
234
|
-
### Parsing Functions
|
|
235
|
-
|
|
236
|
-
| Function | Description |
|
|
237
|
-
|----------|-------------|
|
|
238
|
-
| `parse_auto` | Auto-detect and extract structured content |
|
|
239
|
-
| `parse_json` | Parse JSON with error repair |
|
|
240
|
-
| `parse_xml(tag?)` | Extract content between XML tags |
|
|
241
|
-
| `parse_fence(lang?)` | Extract fenced code block content |
|
|
242
|
-
| `parse_fences` | Extract all fenced blocks as list |
|
|
243
|
-
| `parse_frontmatter` | Parse `---` delimited YAML frontmatter |
|
|
244
|
-
| `parse_checklist` | Parse `- [ ]` and `- [x]` items |
|
|
245
|
-
|
|
246
|
-
See [Parsing](10_parsing.md) for detailed documentation.
|
|
247
|
-
|
|
248
|
-
### Core Methods
|
|
249
|
-
|
|
250
|
-
| Method | Input | Output | Description |
|
|
251
|
-
|--------|-------|--------|-------------|
|
|
252
|
-
| `.str` | Any | String | Convert to string |
|
|
253
|
-
| `.num` | Any | Number | Convert to number |
|
|
254
|
-
| `.len` | Any | Number | Length |
|
|
255
|
-
| `.trim` | String | String | Remove whitespace |
|
|
256
|
-
| `.head` | String/List | Any | First element |
|
|
257
|
-
| `.tail` | String/List | Any | Last element |
|
|
258
|
-
| `.at(idx)` | String/List | Any | Element at index |
|
|
259
|
-
| `.split(sep)` | String | List | Split by separator |
|
|
260
|
-
| `.join(sep)` | List | String | Join with separator |
|
|
261
|
-
| `.lines` | String | List | Split on newlines |
|
|
262
|
-
| `.lower` | String | String | Lowercase |
|
|
263
|
-
| `.upper` | String | String | Uppercase |
|
|
264
|
-
| `.replace(pat, repl)` | String | String | Replace first match |
|
|
265
|
-
| `.replace_all(pat, repl)` | String | String | Replace all matches |
|
|
266
|
-
| `.contains(text)` | String | Bool | Contains substring |
|
|
267
|
-
| `.starts_with(pre)` | String | Bool | Starts with prefix |
|
|
268
|
-
| `.ends_with(suf)` | String | Bool | Ends with suffix |
|
|
269
|
-
| `.match(regex)` | String | Dict | First match info |
|
|
270
|
-
| `.is_match(regex)` | String | Bool | Regex matches |
|
|
271
|
-
| `.empty` | Any | Bool | Is empty |
|
|
272
|
-
| `.has(value)` | List | Bool | Check if list contains value (deep equality) |
|
|
273
|
-
| `.has_any([values])` | List | Bool | Check if list contains any value from candidates |
|
|
274
|
-
| `.has_all([values])` | List | Bool | Check if list contains all values from candidates |
|
|
275
|
-
| `.keys` | Dict | List | All keys |
|
|
276
|
-
| `.values` | Dict | List | All values |
|
|
277
|
-
| `.entries` | Dict | List | Key-value pairs |
|
|
278
|
-
| `.params` | Closure | Dict | Parameter metadata (type, __annotations) |
|
|
279
|
-
|
|
280
|
-
See [Strings](09_strings.md) for detailed string method documentation.
|
|
281
|
-
|
|
282
|
-
### Global Functions
|
|
283
|
-
|
|
284
|
-
| Function | Description |
|
|
285
|
-
|----------|-------------|
|
|
286
|
-
| `type` | Returns type name of value |
|
|
287
|
-
| `log` | Print to console, pass through |
|
|
288
|
-
| `json` | Convert to JSON string |
|
|
289
|
-
| `identity` | Returns input unchanged |
|
|
290
|
-
| `range(start, end, step?)` | Generate number sequence |
|
|
291
|
-
| `repeat(value, count)` | Repeat value n times |
|
|
292
|
-
| `enumerate(collection)` | Add index to elements |
|
|
293
|
-
|
|
294
|
-
See [Iterators](08_iterators.md) for `range` and `repeat` documentation.
|
|
295
|
-
|
|
296
|
-
---
|
|
297
|
-
|
|
298
|
-
## Implied `$`
|
|
299
|
-
|
|
300
|
-
When constructs appear without explicit input, `$` is used implicitly:
|
|
301
|
-
|
|
302
|
-
| Written | Equivalent to |
|
|
303
|
-
|---------|---------------|
|
|
304
|
-
| `? { }` | `$ -> ? { }` |
|
|
305
|
-
| `.method()` | `$ -> .method()` |
|
|
306
|
-
| `$fn()` | `$fn($)` (when no args, no default) |
|
|
307
|
-
|
|
308
|
-
---
|
|
309
|
-
|
|
310
|
-
## Extraction Operators
|
|
311
|
-
|
|
312
|
-
### Destructure `*<>`
|
|
313
|
-
|
|
314
|
-
Extract elements from lists or dicts into variables:
|
|
315
|
-
|
|
316
|
-
```rill
|
|
317
|
-
[1, 2, 3] -> *<$a, $b, $c>
|
|
318
|
-
# $a = 1, $b = 2, $c = 3
|
|
319
|
-
|
|
320
|
-
[name: "test", count: 42] -> *<name: $n, count: $c>
|
|
321
|
-
# $n = "test", $c = 42
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
### Slice `/<>`
|
|
325
|
-
|
|
326
|
-
Extract portions using Python-style `start:stop:step`:
|
|
327
|
-
|
|
328
|
-
```rill
|
|
329
|
-
[0, 1, 2, 3, 4] -> /<0:3> # [0, 1, 2]
|
|
330
|
-
[0, 1, 2, 3, 4] -> /<-2:> # [3, 4]
|
|
331
|
-
[0, 1, 2, 3, 4] -> /<::-1> # [4, 3, 2, 1, 0]
|
|
332
|
-
"hello" -> /<1:4> # "ell"
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
See [Operators](04_operators.md) for detailed extraction operator documentation.
|
|
336
|
-
|
|
337
|
-
---
|
|
338
|
-
|
|
339
|
-
## Annotation Reflection
|
|
340
|
-
|
|
341
|
-
Access annotation values on closures using `.^key` syntax.
|
|
342
|
-
|
|
343
|
-
**Type Restriction:** Annotations attach to closures only. Accessing `.^key` on primitives (string, number, boolean, list, dict) throws `RUNTIME_TYPE_ERROR`.
|
|
344
|
-
|
|
345
|
-
```rill
|
|
346
|
-
^(min: 0, max: 100) |x|($x) :> $fn
|
|
347
|
-
|
|
348
|
-
$fn.^min # 0
|
|
349
|
-
$fn.^max # 100
|
|
350
|
-
$fn.^missing # Error: RUNTIME_UNDEFINED_ANNOTATION
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
Annotations are metadata attached to closures during creation. They enable runtime configuration and introspection.
|
|
354
|
-
|
|
355
|
-
### Common Use Cases
|
|
356
|
-
|
|
357
|
-
**Function Metadata:**
|
|
358
|
-
|
|
359
|
-
```rill
|
|
360
|
-
^(doc: "validates user input", version: 2) |input|($input) :> $validate
|
|
361
|
-
|
|
362
|
-
$validate.^doc # "validates user input"
|
|
363
|
-
$validate.^version # 2
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
**Configuration Annotations:**
|
|
367
|
-
|
|
368
|
-
```rill
|
|
369
|
-
^(timeout: 30000, retry: 3) |url|($url) :> $fetch
|
|
370
|
-
|
|
371
|
-
$fetch.^timeout # 30000
|
|
372
|
-
$fetch.^retry # 3
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
**Complex Annotation Values:**
|
|
376
|
-
|
|
377
|
-
```rill
|
|
378
|
-
^(config: [timeout: 30, endpoints: ["a", "b"]]) |x|($x) :> $fn
|
|
379
|
-
|
|
380
|
-
$fn.^config.timeout # 30
|
|
381
|
-
$fn.^config.endpoints[0] # "a"
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
### Error Handling
|
|
385
|
-
|
|
386
|
-
Accessing undefined annotation keys throws `RUNTIME_UNDEFINED_ANNOTATION`:
|
|
387
|
-
|
|
388
|
-
```rill
|
|
389
|
-
|x|($x) :> $fn
|
|
390
|
-
$fn.^missing # Error: Annotation 'missing' not defined
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
Use default value operator for optional annotations:
|
|
394
|
-
|
|
395
|
-
```rill
|
|
396
|
-
|x|($x) :> $fn
|
|
397
|
-
$fn.^timeout ?? 30 # 30 (uses default since annotation missing)
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
Accessing `.^key` on non-closure values throws `RUNTIME_TYPE_ERROR`:
|
|
401
|
-
|
|
402
|
-
```text
|
|
403
|
-
"hello" :> $str
|
|
404
|
-
$str.^key # Error: Cannot access annotation on string
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
### Parameter Annotations
|
|
408
|
-
|
|
409
|
-
Parameters can have their own annotations using `^(key: value)` syntax. These attach metadata to individual parameters.
|
|
410
|
-
|
|
411
|
-
**Syntax:** `|paramName ^(annotation: value)| body`
|
|
412
|
-
|
|
413
|
-
**Order:** Parameter annotations appear after the type annotation (if present) and before the default value (if present).
|
|
414
|
-
|
|
415
|
-
```rill
|
|
416
|
-
|x: number ^(min: 0, max: 100)|($x) :> $validate
|
|
417
|
-
|name: string ^(required: true) = "guest"|($name) :> $greet
|
|
418
|
-
|count ^(cache: true) = 0|($count) :> $process
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
**Access via `.params`:**
|
|
422
|
-
|
|
423
|
-
The `.params` property returns a dict keyed by parameter name. Each entry is a dict containing:
|
|
424
|
-
|
|
425
|
-
- `type` — Type annotation (string) if present
|
|
426
|
-
- `__annotations` — Dict of parameter-level annotations if present
|
|
427
|
-
|
|
428
|
-
```rill
|
|
429
|
-
|x: number ^(min: 0, max: 100), y: string|($x + $y) :> $fn
|
|
430
|
-
|
|
431
|
-
$fn.params
|
|
432
|
-
# Returns:
|
|
433
|
-
# [
|
|
434
|
-
# x: [type: "number", __annotations: [min: 0, max: 100]],
|
|
435
|
-
# y: [type: "string"]
|
|
436
|
-
# ]
|
|
437
|
-
|
|
438
|
-
$fn.params.x.__annotations.min # 0
|
|
439
|
-
$fn.params.y.?__annotations # false (no annotations on y)
|
|
440
|
-
```
|
|
441
|
-
|
|
442
|
-
**Use Cases:**
|
|
443
|
-
|
|
444
|
-
```rill
|
|
445
|
-
# Validation metadata
|
|
446
|
-
|value ^(min: 0, max: 100)|($value) :> $bounded
|
|
447
|
-
|
|
448
|
-
# Caching hints
|
|
449
|
-
|key ^(cache: true)|($key) :> $fetch
|
|
450
|
-
|
|
451
|
-
# Format specifications
|
|
452
|
-
|timestamp ^(format: "ISO8601")|($timestamp) :> $formatDate
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
See [Closures](06_closures.md) for parameter annotation examples and patterns.
|
|
456
|
-
|
|
457
|
-
---
|
|
458
|
-
|
|
459
|
-
## Tuples
|
|
460
|
-
|
|
461
|
-
Tuples package values for argument unpacking:
|
|
462
|
-
|
|
463
|
-
```rill
|
|
464
|
-
|a, b, c|"{$a}-{$b}-{$c}" :> $fmt
|
|
465
|
-
*[1, 2, 3] -> $fmt() # "1-2-3"
|
|
466
|
-
*[c: 3, a: 1, b: 2] -> $fmt() # "1-2-3" (named)
|
|
467
|
-
```
|
|
468
|
-
|
|
469
|
-
See [Types](02_types.md) for detailed tuple documentation.
|
|
470
|
-
|
|
471
|
-
---
|
|
472
|
-
|
|
473
|
-
## Runtime Limits
|
|
474
|
-
|
|
475
|
-
### Iteration Limits
|
|
476
|
-
|
|
477
|
-
Loops have a default maximum of **10,000 iterations**. Override with `^(limit: N)`:
|
|
478
|
-
|
|
479
|
-
```rill
|
|
480
|
-
^(limit: 100) 0 -> ($ < 50) @ { $ + 1 }
|
|
481
|
-
```
|
|
482
|
-
|
|
483
|
-
### Concurrency Limits
|
|
484
|
-
|
|
485
|
-
The `^(limit: N)` annotation also controls parallel concurrency in `map`:
|
|
486
|
-
|
|
487
|
-
```text
|
|
488
|
-
^(limit: 3) $items -> map { slow_process($) }
|
|
489
|
-
```
|
|
490
|
-
|
|
491
|
-
See [Host Integration](14_host-integration.md) for timeout and cancellation configuration.
|
|
492
|
-
|
|
493
|
-
---
|
|
494
|
-
|
|
495
|
-
## Host-Provided Functions
|
|
496
|
-
|
|
497
|
-
rill is a vanilla language. The host application registers domain-specific functions via `RuntimeContext`:
|
|
498
|
-
|
|
499
|
-
```typescript
|
|
500
|
-
const ctx = createRuntimeContext({
|
|
501
|
-
functions: {
|
|
502
|
-
prompt: async (args) => await callLLM(args[0]),
|
|
503
|
-
'io::read': async (args) => fs.readFile(String(args[0]), 'utf-8'),
|
|
504
|
-
},
|
|
505
|
-
variables: {
|
|
506
|
-
config: { apiUrl: 'https://api.example.com' },
|
|
507
|
-
},
|
|
508
|
-
});
|
|
509
|
-
```
|
|
510
|
-
|
|
511
|
-
Scripts call these as `prompt("text")` or `io::read("file.txt")`.
|
|
512
|
-
|
|
513
|
-
See [Host Integration](14_host-integration.md) for complete API documentation.
|
|
514
|
-
|
|
515
|
-
---
|
|
516
|
-
|
|
517
|
-
## Script Frontmatter
|
|
518
|
-
|
|
519
|
-
Optional YAML frontmatter between `---` markers. **Frontmatter is opaque to rill**—the host interprets it:
|
|
520
|
-
|
|
521
|
-
```text
|
|
522
|
-
---
|
|
523
|
-
timeout: 00:10:00
|
|
524
|
-
args: file: string
|
|
525
|
-
---
|
|
526
|
-
|
|
527
|
-
process($file)
|
|
528
|
-
```
|
|
529
|
-
|
|
530
|
-
---
|
|
531
|
-
|
|
532
|
-
## Script Return Values
|
|
533
|
-
|
|
534
|
-
Scripts return their last expression:
|
|
535
|
-
|
|
536
|
-
| Return | Exit Code |
|
|
537
|
-
|--------|-----------|
|
|
538
|
-
| `true` / non-empty string | 0 |
|
|
539
|
-
| `false` / empty string | 1 |
|
|
540
|
-
| `[0, "message"]` | 0 with message |
|
|
541
|
-
| `[1, "message"]` | 1 with message |
|
|
542
|
-
|
|
543
|
-
---
|
|
544
|
-
|
|
545
|
-
## Comments
|
|
546
|
-
|
|
547
|
-
Single-line comments start with `#`:
|
|
548
|
-
|
|
549
|
-
```rill
|
|
550
|
-
# This is a comment
|
|
551
|
-
"hello" # inline comment
|
|
552
|
-
```
|
|
553
|
-
|
|
554
|
-
---
|
|
555
|
-
|
|
556
|
-
## Grammar
|
|
557
|
-
|
|
558
|
-
The complete formal grammar is in [grammar.ebnf](15_grammar.ebnf).
|
|
559
|
-
|
|
560
|
-
---
|
|
561
|
-
|
|
562
|
-
## Error Codes
|
|
563
|
-
|
|
564
|
-
Runtime and parse errors include structured error codes for programmatic handling.
|
|
565
|
-
|
|
566
|
-
| Code | Description |
|
|
567
|
-
|------|-------------|
|
|
568
|
-
| `PARSE_UNEXPECTED_TOKEN` | Unexpected token in source |
|
|
569
|
-
| `PARSE_INVALID_SYNTAX` | Invalid syntax |
|
|
570
|
-
| `PARSE_INVALID_TYPE` | Invalid type annotation |
|
|
571
|
-
| `RUNTIME_UNDEFINED_VARIABLE` | Variable not defined |
|
|
572
|
-
| `RUNTIME_UNDEFINED_FUNCTION` | Function not defined |
|
|
573
|
-
| `RUNTIME_UNDEFINED_METHOD` | Method not defined (built-in only) |
|
|
574
|
-
| `RUNTIME_UNDEFINED_ANNOTATION` | Annotation key not defined |
|
|
575
|
-
| `RUNTIME_TYPE_ERROR` | Type mismatch |
|
|
576
|
-
| `RUNTIME_TIMEOUT` | Operation timed out |
|
|
577
|
-
| `RUNTIME_ABORTED` | Execution cancelled |
|
|
578
|
-
| `RUNTIME_INVALID_PATTERN` | Invalid regex pattern |
|
|
579
|
-
| `RUNTIME_AUTO_EXCEPTION` | Auto-exception triggered |
|
|
580
|
-
| `RUNTIME_ASSERTION_FAILED` | Assertion failed (condition false) |
|
|
581
|
-
| `RUNTIME_ERROR_RAISED` | Error statement executed |
|
|
582
|
-
|
|
583
|
-
See [Host Integration](14_host-integration.md) for error handling details.
|
|
584
|
-
|
|
585
|
-
---
|
|
586
|
-
|
|
587
|
-
## Topic Guides
|
|
588
|
-
|
|
589
|
-
For detailed documentation on specific topics:
|
|
590
|
-
|
|
591
|
-
- [Types](02_types.md) — Type system, type assertions
|
|
592
|
-
- [Variables](03_variables.md) — Declaration, scope, `$` binding
|
|
593
|
-
- [Control Flow](05_control-flow.md) — Conditionals, loops
|
|
594
|
-
- [Operators](04_operators.md) — All operators
|
|
595
|
-
- [Closures](06_closures.md) — Late binding, dict closures
|
|
596
|
-
- [Collections](07_collections.md) — `each`, `map`, `filter`, `fold`
|
|
597
|
-
- [Iterators](08_iterators.md) — `range`, `repeat`, `.first()`
|
|
598
|
-
- [Strings](09_strings.md) — String methods
|
|
599
|
-
- [Parsing](10_parsing.md) — Content parsing
|
|
600
|
-
- [Host Integration](14_host-integration.md) — Embedding API
|