@rcrsr/rill 0.4.5 → 0.6.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.
Files changed (246) hide show
  1. package/dist/generated/introspection-data.d.ts +2 -0
  2. package/dist/generated/introspection-data.d.ts.map +1 -0
  3. package/dist/generated/introspection-data.js +539 -0
  4. package/dist/generated/introspection-data.js.map +1 -0
  5. package/dist/generated/version-data.d.ts +18 -0
  6. package/dist/generated/version-data.d.ts.map +1 -0
  7. package/dist/generated/version-data.js +16 -0
  8. package/dist/generated/version-data.js.map +1 -0
  9. package/dist/highlight-map.d.ts +4 -0
  10. package/dist/highlight-map.d.ts.map +1 -0
  11. package/dist/highlight-map.js +71 -0
  12. package/dist/highlight-map.js.map +1 -0
  13. package/dist/index.d.ts +3 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +9 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/lexer/errors.d.ts +3 -2
  18. package/dist/lexer/errors.d.ts.map +1 -1
  19. package/dist/lexer/errors.js +25 -4
  20. package/dist/lexer/errors.js.map +1 -1
  21. package/dist/lexer/operators.d.ts.map +1 -1
  22. package/dist/lexer/operators.js +2 -1
  23. package/dist/lexer/operators.js.map +1 -1
  24. package/dist/lexer/readers.d.ts.map +1 -1
  25. package/dist/lexer/readers.js +4 -4
  26. package/dist/lexer/readers.js.map +1 -1
  27. package/dist/lexer/tokenizer.d.ts.map +1 -1
  28. package/dist/lexer/tokenizer.js +1 -15
  29. package/dist/lexer/tokenizer.js.map +1 -1
  30. package/dist/parser/helpers.d.ts +8 -0
  31. package/dist/parser/helpers.d.ts.map +1 -1
  32. package/dist/parser/helpers.js +7 -5
  33. package/dist/parser/helpers.js.map +1 -1
  34. package/dist/parser/index.d.ts.map +1 -1
  35. package/dist/parser/index.js +1 -1
  36. package/dist/parser/index.js.map +1 -1
  37. package/dist/parser/parser-collect.js +1 -1
  38. package/dist/parser/parser-collect.js.map +1 -1
  39. package/dist/parser/parser-control.js +6 -4
  40. package/dist/parser/parser-control.js.map +1 -1
  41. package/dist/parser/parser-expr.d.ts.map +1 -1
  42. package/dist/parser/parser-expr.js +52 -10
  43. package/dist/parser/parser-expr.js.map +1 -1
  44. package/dist/parser/parser-extract.js +7 -3
  45. package/dist/parser/parser-extract.js.map +1 -1
  46. package/dist/parser/parser-functions.d.ts.map +1 -1
  47. package/dist/parser/parser-functions.js +8 -18
  48. package/dist/parser/parser-functions.js.map +1 -1
  49. package/dist/parser/parser-literals.js +15 -15
  50. package/dist/parser/parser-literals.js.map +1 -1
  51. package/dist/parser/parser-script.js +5 -3
  52. package/dist/parser/parser-script.js.map +1 -1
  53. package/dist/parser/parser-variables.js +10 -6
  54. package/dist/parser/parser-variables.js.map +1 -1
  55. package/dist/parser/state.d.ts +1 -1
  56. package/dist/parser/state.d.ts.map +1 -1
  57. package/dist/parser/state.js +2 -2
  58. package/dist/parser/state.js.map +1 -1
  59. package/dist/runtime/core/callable.d.ts +28 -0
  60. package/dist/runtime/core/callable.d.ts.map +1 -1
  61. package/dist/runtime/core/callable.js +30 -7
  62. package/dist/runtime/core/callable.js.map +1 -1
  63. package/dist/runtime/core/context.d.ts +21 -0
  64. package/dist/runtime/core/context.d.ts.map +1 -1
  65. package/dist/runtime/core/context.js +90 -10
  66. package/dist/runtime/core/context.js.map +1 -1
  67. package/dist/runtime/core/equals.d.ts.map +1 -1
  68. package/dist/runtime/core/equals.js +2 -1
  69. package/dist/runtime/core/equals.js.map +1 -1
  70. package/dist/runtime/core/eval/base.d.ts.map +1 -1
  71. package/dist/runtime/core/eval/base.js +3 -3
  72. package/dist/runtime/core/eval/base.js.map +1 -1
  73. package/dist/runtime/core/eval/index.d.ts.map +1 -1
  74. package/dist/runtime/core/eval/index.js +2 -0
  75. package/dist/runtime/core/eval/index.js.map +1 -1
  76. package/dist/runtime/core/eval/mixins/annotations.js +3 -3
  77. package/dist/runtime/core/eval/mixins/annotations.js.map +1 -1
  78. package/dist/runtime/core/eval/mixins/closures.d.ts.map +1 -1
  79. package/dist/runtime/core/eval/mixins/closures.js +75 -40
  80. package/dist/runtime/core/eval/mixins/closures.js.map +1 -1
  81. package/dist/runtime/core/eval/mixins/collections.js +15 -15
  82. package/dist/runtime/core/eval/mixins/collections.js.map +1 -1
  83. package/dist/runtime/core/eval/mixins/control-flow.d.ts.map +1 -1
  84. package/dist/runtime/core/eval/mixins/control-flow.js +12 -12
  85. package/dist/runtime/core/eval/mixins/control-flow.js.map +1 -1
  86. package/dist/runtime/core/eval/mixins/core.d.ts.map +1 -1
  87. package/dist/runtime/core/eval/mixins/core.js +39 -17
  88. package/dist/runtime/core/eval/mixins/core.js.map +1 -1
  89. package/dist/runtime/core/eval/mixins/expressions.d.ts +2 -0
  90. package/dist/runtime/core/eval/mixins/expressions.d.ts.map +1 -1
  91. package/dist/runtime/core/eval/mixins/expressions.js +81 -28
  92. package/dist/runtime/core/eval/mixins/expressions.js.map +1 -1
  93. package/dist/runtime/core/eval/mixins/extraction.d.ts.map +1 -1
  94. package/dist/runtime/core/eval/mixins/extraction.js +15 -15
  95. package/dist/runtime/core/eval/mixins/extraction.js.map +1 -1
  96. package/dist/runtime/core/eval/mixins/literals.d.ts +4 -1
  97. package/dist/runtime/core/eval/mixins/literals.d.ts.map +1 -1
  98. package/dist/runtime/core/eval/mixins/literals.js +45 -25
  99. package/dist/runtime/core/eval/mixins/literals.js.map +1 -1
  100. package/dist/runtime/core/eval/mixins/types.js +4 -4
  101. package/dist/runtime/core/eval/mixins/types.js.map +1 -1
  102. package/dist/runtime/core/eval/mixins/variables.js +34 -34
  103. package/dist/runtime/core/eval/mixins/variables.js.map +1 -1
  104. package/dist/runtime/core/execute.js +3 -3
  105. package/dist/runtime/core/execute.js.map +1 -1
  106. package/dist/runtime/core/introspection.d.ts +88 -0
  107. package/dist/runtime/core/introspection.d.ts.map +1 -0
  108. package/dist/runtime/core/introspection.js +166 -0
  109. package/dist/runtime/core/introspection.js.map +1 -0
  110. package/dist/runtime/core/types.d.ts +11 -0
  111. package/dist/runtime/core/types.d.ts.map +1 -1
  112. package/dist/runtime/core/types.js.map +1 -1
  113. package/dist/runtime/ext/builtins.js +22 -22
  114. package/dist/runtime/ext/builtins.js.map +1 -1
  115. package/dist/runtime/ext/extensions.d.ts +1 -1
  116. package/dist/runtime/ext/extensions.d.ts.map +1 -1
  117. package/dist/runtime/ext/extensions.js +4 -5
  118. package/dist/runtime/ext/extensions.js.map +1 -1
  119. package/dist/runtime/index.d.ts +8 -2
  120. package/dist/runtime/index.d.ts.map +1 -1
  121. package/dist/runtime/index.js +4 -1
  122. package/dist/runtime/index.js.map +1 -1
  123. package/dist/types.d.ts +141 -32
  124. package/dist/types.d.ts.map +1 -1
  125. package/dist/types.js +806 -40
  126. package/dist/types.js.map +1 -1
  127. package/package.json +7 -64
  128. package/README.md +0 -223
  129. package/dist/check/config.d.ts +0 -20
  130. package/dist/check/config.d.ts.map +0 -1
  131. package/dist/check/config.js +0 -151
  132. package/dist/check/config.js.map +0 -1
  133. package/dist/check/fixer.d.ts +0 -39
  134. package/dist/check/fixer.d.ts.map +0 -1
  135. package/dist/check/fixer.js +0 -119
  136. package/dist/check/fixer.js.map +0 -1
  137. package/dist/check/index.d.ts +0 -10
  138. package/dist/check/index.d.ts.map +0 -1
  139. package/dist/check/index.js +0 -21
  140. package/dist/check/index.js.map +0 -1
  141. package/dist/check/rules/anti-patterns.d.ts +0 -65
  142. package/dist/check/rules/anti-patterns.d.ts.map +0 -1
  143. package/dist/check/rules/anti-patterns.js +0 -481
  144. package/dist/check/rules/anti-patterns.js.map +0 -1
  145. package/dist/check/rules/closures.d.ts +0 -66
  146. package/dist/check/rules/closures.d.ts.map +0 -1
  147. package/dist/check/rules/closures.js +0 -370
  148. package/dist/check/rules/closures.js.map +0 -1
  149. package/dist/check/rules/collections.d.ts +0 -90
  150. package/dist/check/rules/collections.d.ts.map +0 -1
  151. package/dist/check/rules/collections.js +0 -373
  152. package/dist/check/rules/collections.js.map +0 -1
  153. package/dist/check/rules/conditionals.d.ts +0 -41
  154. package/dist/check/rules/conditionals.d.ts.map +0 -1
  155. package/dist/check/rules/conditionals.js +0 -134
  156. package/dist/check/rules/conditionals.js.map +0 -1
  157. package/dist/check/rules/flow.d.ts +0 -46
  158. package/dist/check/rules/flow.d.ts.map +0 -1
  159. package/dist/check/rules/flow.js +0 -206
  160. package/dist/check/rules/flow.js.map +0 -1
  161. package/dist/check/rules/formatting.d.ts +0 -133
  162. package/dist/check/rules/formatting.d.ts.map +0 -1
  163. package/dist/check/rules/formatting.js +0 -648
  164. package/dist/check/rules/formatting.js.map +0 -1
  165. package/dist/check/rules/helpers.d.ts +0 -26
  166. package/dist/check/rules/helpers.d.ts.map +0 -1
  167. package/dist/check/rules/helpers.js +0 -66
  168. package/dist/check/rules/helpers.js.map +0 -1
  169. package/dist/check/rules/index.d.ts +0 -21
  170. package/dist/check/rules/index.d.ts.map +0 -1
  171. package/dist/check/rules/index.js +0 -78
  172. package/dist/check/rules/index.js.map +0 -1
  173. package/dist/check/rules/loops.d.ts +0 -77
  174. package/dist/check/rules/loops.d.ts.map +0 -1
  175. package/dist/check/rules/loops.js +0 -310
  176. package/dist/check/rules/loops.js.map +0 -1
  177. package/dist/check/rules/naming.d.ts +0 -21
  178. package/dist/check/rules/naming.d.ts.map +0 -1
  179. package/dist/check/rules/naming.js +0 -174
  180. package/dist/check/rules/naming.js.map +0 -1
  181. package/dist/check/rules/strings.d.ts +0 -28
  182. package/dist/check/rules/strings.d.ts.map +0 -1
  183. package/dist/check/rules/strings.js +0 -79
  184. package/dist/check/rules/strings.js.map +0 -1
  185. package/dist/check/rules/types.d.ts +0 -41
  186. package/dist/check/rules/types.d.ts.map +0 -1
  187. package/dist/check/rules/types.js +0 -167
  188. package/dist/check/rules/types.js.map +0 -1
  189. package/dist/check/types.d.ts +0 -112
  190. package/dist/check/types.d.ts.map +0 -1
  191. package/dist/check/types.js +0 -6
  192. package/dist/check/types.js.map +0 -1
  193. package/dist/check/validator.d.ts +0 -18
  194. package/dist/check/validator.d.ts.map +0 -1
  195. package/dist/check/validator.js +0 -110
  196. package/dist/check/validator.js.map +0 -1
  197. package/dist/check/visitor.d.ts +0 -33
  198. package/dist/check/visitor.d.ts.map +0 -1
  199. package/dist/check/visitor.js +0 -258
  200. package/dist/check/visitor.js.map +0 -1
  201. package/dist/cli-check.d.ts +0 -43
  202. package/dist/cli-check.d.ts.map +0 -1
  203. package/dist/cli-check.js +0 -369
  204. package/dist/cli-check.js.map +0 -1
  205. package/dist/cli-eval.d.ts +0 -15
  206. package/dist/cli-eval.d.ts.map +0 -1
  207. package/dist/cli-eval.js +0 -117
  208. package/dist/cli-eval.js.map +0 -1
  209. package/dist/cli-exec.d.ts +0 -49
  210. package/dist/cli-exec.d.ts.map +0 -1
  211. package/dist/cli-exec.js +0 -184
  212. package/dist/cli-exec.js.map +0 -1
  213. package/dist/cli-module-loader.d.ts +0 -19
  214. package/dist/cli-module-loader.d.ts.map +0 -1
  215. package/dist/cli-module-loader.js +0 -83
  216. package/dist/cli-module-loader.js.map +0 -1
  217. package/dist/cli-shared.d.ts +0 -42
  218. package/dist/cli-shared.d.ts.map +0 -1
  219. package/dist/cli-shared.js +0 -112
  220. package/dist/cli-shared.js.map +0 -1
  221. package/dist/cli.d.ts +0 -13
  222. package/dist/cli.d.ts.map +0 -1
  223. package/dist/cli.js +0 -62
  224. package/dist/cli.js.map +0 -1
  225. package/docs/00_INDEX.md +0 -67
  226. package/docs/01_guide.md +0 -390
  227. package/docs/02_types.md +0 -482
  228. package/docs/03_variables.md +0 -324
  229. package/docs/04_operators.md +0 -608
  230. package/docs/05_control-flow.md +0 -630
  231. package/docs/06_closures.md +0 -787
  232. package/docs/07_collections.md +0 -688
  233. package/docs/08_iterators.md +0 -330
  234. package/docs/09_strings.md +0 -205
  235. package/docs/10_parsing.md +0 -366
  236. package/docs/11_reference.md +0 -599
  237. package/docs/12_examples.md +0 -748
  238. package/docs/13_modules.md +0 -519
  239. package/docs/14_host-integration.md +0 -833
  240. package/docs/15_grammar.ebnf +0 -755
  241. package/docs/16_conventions.md +0 -695
  242. package/docs/17_cli-tools.md +0 -184
  243. package/docs/18_design-principles.md +0 -247
  244. package/docs/19_cookbook.md +0 -628
  245. package/docs/99_llm-reference.txt +0 -601
  246. package/docs/assets/logo.png +0 -0
@@ -1,833 +0,0 @@
1
- # Host Integration Guide
2
-
3
- This guide covers embedding Rill in host applications. Rill is a vanilla language—all domain-specific functionality must be provided by the host.
4
-
5
- ## Quick Start
6
-
7
- ```typescript
8
- import { parse, execute, createRuntimeContext } from '@rcrsr/rill';
9
-
10
- const source = `
11
- "Hello, World!" -> prompt() :> $response
12
- $response
13
- `;
14
-
15
- const ast = parse(source);
16
- const ctx = createRuntimeContext({
17
- functions: {
18
- prompt: {
19
- params: [{ name: 'text', type: 'string' }],
20
- fn: async (args) => {
21
- return await callYourLLM(args[0]);
22
- },
23
- },
24
- },
25
- });
26
-
27
- const result = await execute(ast, ctx);
28
- console.log(result.value);
29
- ```
30
-
31
- ## RuntimeOptions
32
-
33
- The `createRuntimeContext()` function accepts these options:
34
-
35
- | Option | Type | Description |
36
- |--------|------|-------------|
37
- | `variables` | `Record<string, RillValue>` | Initial variables accessible as `$name` |
38
- | `functions` | `Record<string, HostFunctionDefinition>` | Custom functions callable as `name()` |
39
- | `callbacks` | `Partial<RuntimeCallbacks>` | I/O callbacks (e.g., `onLog`) |
40
- | `observability` | `ObservabilityCallbacks` | Execution monitoring hooks |
41
- | `timeout` | `number` | Timeout in ms for async functions |
42
- | `autoExceptions` | `string[]` | Regex patterns that halt execution |
43
- | `signal` | `AbortSignal` | Cancellation signal |
44
-
45
- ## Host Function Contract
46
-
47
- Host functions must follow these rules to ensure correct script behavior:
48
-
49
- ### Immutability
50
-
51
- **Host functions must not mutate input arguments.** rill values are immutable by design—modifying arguments breaks value semantics and causes unpredictable behavior.
52
-
53
- ```typescript
54
- // WRONG: Mutates input array
55
- functions: {
56
- addItem: {
57
- params: [{ name: 'list', type: 'list' }],
58
- fn: (args) => {
59
- const list = args[0] as unknown[];
60
- list.push('new'); // DON'T DO THIS
61
- return list;
62
- },
63
- },
64
- }
65
-
66
- // CORRECT: Return new value
67
- functions: {
68
- addItem: {
69
- params: [{ name: 'list', type: 'list' }],
70
- fn: (args) => {
71
- const list = args[0] as unknown[];
72
- return [...list, 'new']; // Create new array
73
- },
74
- },
75
- }
76
- ```
77
-
78
- ### Defensive Copies
79
-
80
- For maximum safety, consider freezing values passed to host functions:
81
-
82
- ```typescript
83
- import { deepFreeze } from './utils'; // Your utility
84
-
85
- functions: {
86
- process: {
87
- params: [{ name: 'input', type: 'string' }],
88
- fn: (args) => {
89
- const frozen = deepFreeze(args[0]);
90
- return transform(frozen); // Any mutation throws
91
- },
92
- },
93
- }
94
- ```
95
-
96
- ### Return Values
97
-
98
- - Return new values instead of modifying inputs
99
- - Return `RillValue` types (string, number, boolean, array, object, or `RillCallable`)
100
- - Avoid returning `null` or `undefined`—use empty string `''` or empty array `[]` instead
101
-
102
- ## Custom Functions
103
-
104
- Functions are called by name: `functionName(arg1, arg2)`.
105
-
106
- ```typescript
107
- const ctx = createRuntimeContext({
108
- functions: {
109
- // Sync function
110
- add: {
111
- params: [
112
- { name: 'a', type: 'number' },
113
- { name: 'b', type: 'number' },
114
- ],
115
- fn: (args) => args[0] + args[1],
116
- },
117
-
118
- // Async function
119
- fetch: {
120
- params: [{ name: 'url', type: 'string' }],
121
- fn: async (args, ctx, location) => {
122
- const response = await fetch(args[0]);
123
- return await response.text();
124
- },
125
- },
126
-
127
- // Function with context access
128
- getVar: {
129
- params: [{ name: 'name', type: 'string' }],
130
- fn: (args, ctx) => {
131
- return ctx.variables.get(args[0]) ?? null;
132
- },
133
- },
134
-
135
- // Function with location for error reporting
136
- validate: {
137
- params: [{ name: 'value', type: 'string' }],
138
- fn: (args, ctx, location) => {
139
- if (!args[0]) {
140
- throw new Error(`Validation failed at line ${location?.line}`);
141
- }
142
- return args[0];
143
- },
144
- },
145
- },
146
- });
147
- ```
148
-
149
- ### Namespaced Functions
150
-
151
- Use `::` to organize functions into namespaces:
152
-
153
- ```typescript
154
- const ctx = createRuntimeContext({
155
- functions: {
156
- // Namespaced functions use :: separator
157
- 'math::add': {
158
- params: [
159
- { name: 'a', type: 'number' },
160
- { name: 'b', type: 'number' },
161
- ],
162
- fn: (args) => args[0] + args[1],
163
- },
164
- 'math::multiply': {
165
- params: [
166
- { name: 'a', type: 'number' },
167
- { name: 'b', type: 'number' },
168
- ],
169
- fn: (args) => args[0] * args[1],
170
- },
171
- 'str::upper': {
172
- params: [{ name: 'text', type: 'string' }],
173
- fn: (args) => args[0].toUpperCase(),
174
- },
175
- 'str::lower': {
176
- params: [{ name: 'text', type: 'string' }],
177
- fn: (args) => args[0].toLowerCase(),
178
- },
179
-
180
- // Multi-level namespaces
181
- 'io::file::read': {
182
- params: [{ name: 'path', type: 'string' }],
183
- fn: async (args) => fs.readFile(args[0], 'utf-8'),
184
- },
185
- 'io::file::write': {
186
- params: [
187
- { name: 'path', type: 'string' },
188
- { name: 'content', type: 'string' },
189
- ],
190
- fn: async (args) => fs.writeFile(args[0], args[1]),
191
- },
192
- },
193
- });
194
- ```
195
-
196
- Scripts call namespaced functions with the same syntax:
197
-
198
- ```rill
199
- math::add(1, 2) # 3
200
- "hello" -> str::upper # "HELLO"
201
- io::file::read("config.json") -> parse_json
202
- ```
203
-
204
- Namespaces help organize host APIs and avoid name collisions without requiring the `$` variable prefix.
205
- ```
206
-
207
- ### CallableFn Signature
208
-
209
- The `fn` property in `HostFunctionDefinition` uses the `CallableFn` type:
210
-
211
- ```typescript
212
- type CallableFn = (
213
- args: RillValue[],
214
- ctx: RuntimeContext,
215
- location?: SourceLocation
216
- ) => RillValue | Promise<RillValue>;
217
- ```
218
-
219
- | Parameter | Description |
220
- |-----------|-------------|
221
- | `args` | Positional arguments passed to the function (already validated against `params`) |
222
- | `ctx` | Runtime context with variables, pipeValue, etc. |
223
- | `location` | Source location of the call site (for error reporting) |
224
-
225
- ## Host Function Type Declarations
226
-
227
- All host functions must declare parameter types and optional defaults using the `HostFunctionDefinition` interface. The runtime validates arguments before calling your function, eliminating manual type checking.
228
-
229
- ### Parameter Type Declarations
230
-
231
- Declare parameter types in the `params` array:
232
-
233
- ```typescript
234
- const ctx = createRuntimeContext({
235
- functions: {
236
- repeat: {
237
- params: [
238
- { name: 'str', type: 'string' },
239
- { name: 'count', type: 'number', defaultValue: 1 },
240
- ],
241
- fn: (args) => {
242
- // args[0] guaranteed to be string
243
- // args[1] guaranteed to be number (or default)
244
- return args[0].repeat(args[1]);
245
- },
246
- },
247
- },
248
- });
249
- ```
250
-
251
- Scripts call typed functions the same way:
252
-
253
- ```text
254
- repeat("hello", 3) # "hellohellohello"
255
- repeat("hi") # "hi" (uses default count)
256
- ```
257
-
258
- ### Supported Types
259
-
260
- | Type | Rill Value | Validation |
261
- |------|------------|------------|
262
- | `'string'` | String | `typeof value === 'string'` |
263
- | `'number'` | Number | `typeof value === 'number'` |
264
- | `'bool'` | Boolean | `typeof value === 'boolean'` |
265
- | `'list'` | List | `Array.isArray(value)` |
266
- | `'dict'` | Dict | `isDict(value)` |
267
-
268
- ### Default Values
269
-
270
- Parameters with default values are optional. The default applies when the argument is missing:
271
-
272
- ```typescript
273
- functions: {
274
- greet: {
275
- params: [
276
- { name: 'name', type: 'string' },
277
- { name: 'greeting', type: 'string', defaultValue: 'Hello' },
278
- ],
279
- fn: (args) => `${args[1]}, ${args[0]}!`,
280
- },
281
- }
282
- ```
283
-
284
- ```text
285
- greet("Alice") # "Hello, Alice!"
286
- greet("Bob", "Hi") # "Hi, Bob!"
287
- ```
288
-
289
- ### Type Mismatch Errors
290
-
291
- When argument types don't match, the runtime throws `RuntimeError` with code `RUNTIME_TYPE_ERROR`:
292
-
293
- ```typescript
294
- // Script: repeat(42, 3)
295
- // Error: Function 'repeat' expects parameter 'str' (position 0) to be string, got number
296
- ```
297
-
298
- Error details include:
299
-
300
- - Function name
301
- - Parameter name
302
- - Parameter position
303
- - Expected type
304
- - Actual type received
305
-
306
- ### HostFunctionDefinition Interface
307
-
308
- ```typescript
309
- interface HostFunctionDefinition {
310
- params: HostFunctionParam[];
311
- fn: CallableFn;
312
- }
313
-
314
- interface HostFunctionParam {
315
- name: string;
316
- type: 'string' | 'number' | 'bool' | 'list' | 'dict';
317
- defaultValue?: RillValue;
318
- }
319
- ```
320
-
321
- ## Application Callables
322
-
323
- Hosts can create first-class callable values that scripts can store, pass, and invoke.
324
-
325
- ```typescript
326
- import { callable, isCallable, isApplicationCallable } from '@rcrsr/rill';
327
-
328
- // Create a callable
329
- const greet = callable((args) => `Hello, ${args[0]}!`);
330
-
331
- // Use in variables
332
- const ctx = createRuntimeContext({
333
- variables: {
334
- greet: greet,
335
- },
336
- });
337
-
338
- // Script can invoke: $greet("World") -> "Hello, World!"
339
- ```
340
-
341
- ### callable() Function
342
-
343
- ```typescript
344
- function callable(fn: CallableFn, isProperty?: boolean): ApplicationCallable;
345
- ```
346
-
347
- | Parameter | Description |
348
- |-----------|-------------|
349
- | `fn` | The function to wrap |
350
- | `isProperty` | If `true`, auto-invokes when accessed from dict |
351
-
352
- ### Property-Style Callables
353
-
354
- Property-style callables auto-invoke when accessed from a dict, enabling computed properties:
355
-
356
- ```typescript
357
- const ctx = createRuntimeContext({
358
- variables: {
359
- user: {
360
- firstName: 'John',
361
- lastName: 'Doe',
362
- // Auto-invokes on access, receives bound dict
363
- fullName: callable((args) => {
364
- const dict = args[0] as Record<string, RillValue>;
365
- return `${dict.firstName} ${dict.lastName}`;
366
- }, true),
367
- },
368
- },
369
- });
370
-
371
- // Script: $user.fullName -> "John Doe"
372
- ```
373
-
374
- ### Dict Callables
375
-
376
- Callables stored in dicts can be invoked using method syntax:
377
-
378
- ```typescript
379
- const ctx = createRuntimeContext({
380
- variables: {
381
- math: {
382
- add: callable((args) => {
383
- const a = typeof args[0] === 'number' ? args[0] : 0;
384
- const b = typeof args[1] === 'number' ? args[1] : 0;
385
- return a + b;
386
- }),
387
- },
388
- },
389
- });
390
-
391
- // Script: $math.add(1, 2) -> 3
392
- ```
393
-
394
- ### Callable Kinds
395
-
396
- | Kind | Type | Description |
397
- |------|------|-------------|
398
- | `script` | `ScriptCallable` | Closures from Rill source code |
399
- | `runtime` | `RuntimeCallable` | Rill's built-in functions |
400
- | `application` | `ApplicationCallable` | Host-provided callables |
401
-
402
- ### Type Guards
403
-
404
- ```typescript
405
- import {
406
- isCallable,
407
- isScriptCallable,
408
- isRuntimeCallable,
409
- isApplicationCallable,
410
- } from '@rcrsr/rill';
411
-
412
- if (isCallable(value)) {
413
- // value is RillCallable (any callable)
414
- }
415
-
416
- if (isApplicationCallable(value)) {
417
- // value is ApplicationCallable (host-provided)
418
- }
419
-
420
- if (isScriptCallable(value)) {
421
- // value is ScriptCallable (from Rill source)
422
- }
423
- ```
424
-
425
- ## Cancellation
426
-
427
- Use `AbortSignal` to cancel long-running scripts:
428
-
429
- ```typescript
430
- const controller = new AbortController();
431
-
432
- const ctx = createRuntimeContext({
433
- signal: controller.signal,
434
- functions: {
435
- longTask: {
436
- params: [],
437
- fn: async () => {
438
- await new Promise((r) => setTimeout(r, 10000));
439
- return 'done';
440
- },
441
- },
442
- },
443
- });
444
-
445
- // Cancel after 1 second
446
- setTimeout(() => controller.abort(), 1000);
447
-
448
- try {
449
- await execute(ast, ctx);
450
- } catch (err) {
451
- if (err instanceof AbortError) {
452
- console.log('Execution cancelled');
453
- }
454
- }
455
- ```
456
-
457
- ### AbortError
458
-
459
- ```typescript
460
- import { AbortError } from '@rcrsr/rill';
461
-
462
- try {
463
- await execute(ast, ctx);
464
- } catch (err) {
465
- if (err instanceof AbortError) {
466
- console.log(err.code); // 'RUNTIME_ABORTED'
467
- console.log(err.message); // 'Execution aborted'
468
- }
469
- }
470
- ```
471
-
472
- Abort is checked at:
473
- - Before each statement
474
- - Before each function call
475
- - Before each loop iteration
476
- - In the stepper's `step()` method
477
-
478
- ## Observability
479
-
480
- Monitor execution with observability callbacks:
481
-
482
- ```typescript
483
- const ctx = createRuntimeContext({
484
- observability: {
485
- onStepStart: (event) => {
486
- console.log(`Step ${event.index + 1}/${event.total}`);
487
- },
488
- onStepEnd: (event) => {
489
- console.log(`Completed in ${event.durationMs}ms`);
490
- },
491
- onFunctionCall: (event) => {
492
- console.log(`Calling ${event.name}(${event.args.join(', ')})`);
493
- },
494
- onFunctionReturn: (event) => {
495
- console.log(`${event.name} returned: ${event.value}`);
496
- },
497
- onCapture: (event) => {
498
- console.log(`Captured $${event.name} = ${event.value}`);
499
- },
500
- onError: (event) => {
501
- console.error(`Error at step ${event.index}:`, event.error);
502
- },
503
- },
504
- });
505
- ```
506
-
507
- ### Event Types
508
-
509
- ```typescript
510
- interface StepStartEvent {
511
- index: number; // Statement index (0-based)
512
- total: number; // Total statements
513
- pipeValue: RillValue;
514
- }
515
-
516
- interface StepEndEvent {
517
- index: number;
518
- total: number;
519
- value: RillValue;
520
- durationMs: number;
521
- }
522
-
523
- interface FunctionCallEvent {
524
- name: string;
525
- args: RillValue[];
526
- }
527
-
528
- interface FunctionReturnEvent {
529
- name: string;
530
- value: RillValue;
531
- durationMs: number;
532
- }
533
-
534
- interface CaptureEvent {
535
- name: string;
536
- value: RillValue;
537
- }
538
-
539
- interface ErrorEvent {
540
- error: Error;
541
- index?: number;
542
- }
543
- ```
544
-
545
- ## Step-by-Step Execution
546
-
547
- Use the stepper API for controlled execution:
548
-
549
- ```typescript
550
- import { parse, createRuntimeContext, createStepper } from '@rcrsr/rill';
551
-
552
- const ast = parse(source);
553
- const ctx = createRuntimeContext({ ... });
554
- const stepper = createStepper(ast, ctx);
555
-
556
- while (!stepper.done) {
557
- const result = await stepper.step();
558
- console.log(`Step ${result.index + 1}: ${result.value}`);
559
-
560
- if (result.captured) {
561
- console.log(`Captured: $${result.captured.name}`);
562
- }
563
- }
564
-
565
- const final = stepper.getResult();
566
- console.log('Final value:', final.value);
567
- console.log('Variables:', final.variables);
568
- ```
569
-
570
- ### ExecutionStepper Interface
571
-
572
- ```typescript
573
- interface ExecutionStepper {
574
- readonly done: boolean;
575
- readonly index: number;
576
- readonly total: number;
577
- readonly context: RuntimeContext;
578
- step(): Promise<StepResult>;
579
- getResult(): ExecutionResult;
580
- }
581
-
582
- interface StepResult {
583
- value: RillValue;
584
- done: boolean;
585
- index: number;
586
- total: number;
587
- captured?: { name: string; value: RillValue };
588
- }
589
-
590
- interface ExecutionResult {
591
- value: RillValue;
592
- variables: Record<string, RillValue>;
593
- }
594
- ```
595
-
596
- ## I/O Callbacks
597
-
598
- Handle script I/O through callbacks:
599
-
600
- ```typescript
601
- const ctx = createRuntimeContext({
602
- callbacks: {
603
- onLog: (value) => {
604
- // Called when script uses .log method
605
- console.log('[Rill]', value);
606
- },
607
- },
608
- });
609
- ```
610
-
611
- ## Timeouts
612
-
613
- Set a timeout for async operations:
614
-
615
- ```typescript
616
- const ctx = createRuntimeContext({
617
- timeout: 30000, // 30 seconds
618
- functions: {
619
- slowOperation: {
620
- params: [],
621
- fn: async () => {
622
- // Will throw TimeoutError if exceeds 30s
623
- await longRunningTask();
624
- return 'done';
625
- },
626
- },
627
- },
628
- });
629
- ```
630
-
631
- ## Auto-Exceptions
632
-
633
- Halt execution when output matches patterns:
634
-
635
- ```typescript
636
- const ctx = createRuntimeContext({
637
- autoExceptions: [
638
- 'error:.*', // Matches "error: something"
639
- 'FATAL', // Matches "FATAL" anywhere
640
- ],
641
- functions: {
642
- process: {
643
- params: [{ name: 'input', type: 'string' }],
644
- fn: (args) => {
645
- // If this returns "error: invalid input",
646
- // execution halts with AutoExceptionError
647
- return externalProcess(args[0]);
648
- },
649
- },
650
- },
651
- });
652
- ```
653
-
654
- ## Initial Variables
655
-
656
- Provide variables accessible in scripts:
657
-
658
- ```typescript
659
- const ctx = createRuntimeContext({
660
- variables: {
661
- config: {
662
- apiUrl: 'https://api.example.com',
663
- maxRetries: 3,
664
- },
665
- userId: 'user-123',
666
- items: [1, 2, 3],
667
- },
668
- });
669
-
670
- // Script can access: $config.apiUrl, $userId, $items
671
- ```
672
-
673
- ## Error Handling
674
-
675
- All Rill errors extend `RillError` with structured information:
676
-
677
- ```typescript
678
- import { RuntimeError, ParseError, AbortError, TimeoutError } from '@rcrsr/rill';
679
-
680
- try {
681
- const ast = parse(source);
682
- const result = await execute(ast, ctx);
683
- } catch (err) {
684
- if (err instanceof ParseError) {
685
- console.log('Parse error:', err.message);
686
- console.log('Location:', err.location);
687
- } else if (err instanceof RuntimeError) {
688
- console.log('Runtime error:', err.code);
689
- console.log('Message:', err.message);
690
- console.log('Location:', err.location);
691
- console.log('Context:', err.context);
692
- } else if (err instanceof AbortError) {
693
- console.log('Execution cancelled');
694
- } else if (err instanceof TimeoutError) {
695
- console.log('Operation timed out');
696
- }
697
- }
698
- ```
699
-
700
- ### Error Codes
701
-
702
- | Code | Description |
703
- |------|-------------|
704
- | `PARSE_UNEXPECTED_TOKEN` | Unexpected token in source |
705
- | `PARSE_INVALID_SYNTAX` | Invalid syntax |
706
- | `PARSE_INVALID_TYPE` | Invalid type annotation |
707
- | `RUNTIME_UNDEFINED_VARIABLE` | Variable not defined |
708
- | `RUNTIME_UNDEFINED_FUNCTION` | Function not defined |
709
- | `RUNTIME_UNDEFINED_METHOD` | Method not defined (built-in only) |
710
- | `RUNTIME_TYPE_ERROR` | Type mismatch (includes host function parameter validation) |
711
- | `RUNTIME_TIMEOUT` | Operation timed out |
712
- | `RUNTIME_ABORTED` | Execution cancelled |
713
- | `RUNTIME_INVALID_PATTERN` | Invalid regex pattern |
714
- | `RUNTIME_AUTO_EXCEPTION` | Auto-exception triggered |
715
- | `RUNTIME_ASSERTION_FAILED` | Assertion failed (condition false) |
716
- | `RUNTIME_ERROR_RAISED` | Error statement executed |
717
-
718
- ## Complete Example
719
-
720
- ```typescript
721
- import {
722
- parse,
723
- execute,
724
- createRuntimeContext,
725
- callable,
726
- AbortError,
727
- type RillValue,
728
- } from '@rcrsr/rill';
729
-
730
- const script = `
731
- $config.greeting -> prompt() :> $response
732
- $response
733
- `;
734
-
735
- const controller = new AbortController();
736
-
737
- const ctx = createRuntimeContext({
738
- variables: {
739
- config: {
740
- greeting: 'Say hello in French',
741
- },
742
- utils: {
743
- // Property-style callable (computed property)
744
- timestamp: callable(() => Date.now(), true),
745
- // Regular callable
746
- format: callable((args) => {
747
- const [template, ...values] = args;
748
- return String(template).replace(/\{\}/g, () =>
749
- String(values.shift() ?? '')
750
- );
751
- }),
752
- },
753
- },
754
-
755
- functions: {
756
- prompt: {
757
- params: [{ name: 'text', type: 'string' }],
758
- fn: async (args, ctx, location) => {
759
- console.log(`[prompt at line ${location?.line}]`);
760
- return await callLLM(args[0]);
761
- },
762
- },
763
- },
764
-
765
- callbacks: {
766
- onLog: (value) => console.log('[log]', value),
767
- },
768
-
769
- observability: {
770
- onStepStart: (e) => console.log(`Step ${e.index + 1}...`),
771
- onStepEnd: (e) => console.log(`Done (${e.durationMs}ms)`),
772
- },
773
-
774
- timeout: 30000,
775
- signal: controller.signal,
776
- });
777
-
778
- try {
779
- const ast = parse(script);
780
- const result = await execute(ast, ctx);
781
- console.log('Result:', result.value);
782
- console.log('Variables:', result.variables);
783
- } catch (err) {
784
- if (err instanceof AbortError) {
785
- console.log('Cancelled');
786
- } else {
787
- throw err;
788
- }
789
- }
790
- ```
791
-
792
- ## API Reference
793
-
794
- ### Exports
795
-
796
- ```typescript
797
- // Parsing
798
- export { parse, ParseError, tokenize, LexerError };
799
-
800
- // Execution
801
- export { execute, createRuntimeContext, createStepper };
802
- export type { RuntimeContext, RuntimeOptions, ExecutionResult };
803
- export type { ExecutionStepper, StepResult };
804
-
805
- // Callable types
806
- export { callable, isCallable, isScriptCallable, isRuntimeCallable, isApplicationCallable };
807
- export type { RillCallable, ScriptCallable, RuntimeCallable, ApplicationCallable, CallableFn };
808
-
809
- // Host function types
810
- export type { HostFunctionDefinition, HostFunctionParam };
811
- export { validateHostFunctionArgs };
812
-
813
- // Value types
814
- export type { RillValue, RillArgs };
815
-
816
- // Callbacks
817
- export type { RuntimeCallbacks, ObservabilityCallbacks };
818
- export type { StepStartEvent, StepEndEvent, FunctionCallEvent, FunctionReturnEvent };
819
- export type { CaptureEvent, ErrorEvent };
820
-
821
- // Errors
822
- export { RillError, RuntimeError, ParseError, AbortError, TimeoutError, AutoExceptionError };
823
- export { RILL_ERROR_CODES };
824
- export type { RillErrorCode };
825
-
826
- // Utilities
827
- export { isArgs, isDict, isReservedMethod, RESERVED_DICT_METHODS };
828
- export type { SourceLocation, SourceSpan };
829
-
830
- // Control flow (for advanced use)
831
- export { BreakSignal, ReturnSignal };
832
- ```
833
-