@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
@@ -0,0 +1,2 @@
1
+ export declare const LANGUAGE_REFERENCE = "RILL LANGUAGE REFERENCE\n=======================\n\nRill is designed to be generated by LLMs and understood by humans. The focus is\non auditable LLM output, not ergonomic human authoring.\n\nESSENTIALS\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 # ERROR\n5. Loops cannot modify outer vars: use fold, each(init), or $ as state dict\n\nSTRENGTHS AND USE CASES\n-----------------------\nStrengths:\n - Unambiguous syntax: $ prefix, explicit operators, no implicit coercion\n - Single-pass parseable: LLMs generate correct code without symbol tables\n - Readable by humans: pipe chains show data flow left-to-right\n - Safe defaults: immutable values, type locking, no null/undefined\n\nUse cases:\n - Workflow orchestration: chain LLM calls, API requests, transformations\n - State machines: (cond) @ { } loops with $ as state dict\n - Data pipelines: each/map/filter/fold process collections declaratively\n - Prompt engineering: parse LLM output with parse_json, parse_xml, parse_fence\n\nState machine pattern ($ carries state through iterations):\n [state: \"init\", data: $input]\n -> ($.state != \"done\") @ {\n $.state -> [\n init: { [state: \"process\", data: transform($.data)] },\n process: { [state: \"done\", data: finalize($.data)] }\n ]\n }\n\nNAMING CONVENTION: snake_case\n-----------------------------\nUse snake_case for all identifiers:\n $user_name, $item_list, $is_valid # variables\n $double_value, $cleanup_text # closures\n [first_name: \"x\", last_name: \"y\"] # dict keys\n\nWHY VARIABLES USE $ PREFIX\n--------------------------\nThe $ prefix enables single-pass parsing without a symbol table:\n\n name() -> 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 host function or stored\nclosure? Is data a variable or key? This would require tracking all declarations.\n\nSPACING RULES\n-------------\nOperators: space both sides 5 + 3, $x -> .upper, \"a\" => $b\nParentheses: no inner space ($x + 1), ($ > 3) ? \"yes\"\nBraces: space inside { $x + 1 }, each { $ * 2 }\nBrackets: no inner space $list[0], $dict.items[1]\nLiterals: space after , and : [1, 2, 3], [name: \"x\", age: 30]\nClosures: space after params |x| ($x * 2), |a, b| { $a + $b }\nMethods: no space before . or ( $str.upper(), $list.join(\", \")\nPipes: space both sides \"x\" -> .upper -> .len\nContinuations: indent 2 spaces $data\n -> .filter { $.active }\n -> map { $.name }\n\nIMPLICIT $ SHORTHAND (always prefer)\n------------------------------------\n$.method() -> .method \"x\" -> .upper (not $.upper())\nfunc($) -> func \"x\" -> log (not log($))\n$fn($) -> $fn 5 -> $double (not $double($))\n\nDon't capture just to continue - use line continuation instead:\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\nCRITICAL DIFFERENCES FROM MAINSTREAM LANGUAGES\n----------------------------------------------\n\n1. NO ASSIGNMENT OPERATOR\n Wrong: x = 5 Mainstream: x = value\n Right: 5 => $x Rill: value => $x\n\n Pipe (->): passes value to next operation\n Capture (=>): stores value AND continues chain\n Example: \"hello\" => $x -> .upper => $y # $x=\"hello\", $y=\"HELLO\"\n\n2. NO NULL/UNDEFINED\n Empty values (\"\", [], [:]) exist. \"No value\" cannot be represented.\n Use ?? for defaults: $dict.field ?? \"default\"\n Use .empty to check: $str -> .empty ? \"was empty\"\n Mainstream: null/undefined Rill: ?? default, .? existence check\n\n3. NO TRUTHINESS\n Conditions MUST be boolean. No implicit coercion.\n Wrong: \"\" ? \"yes\" ! \"no\" Right: \"\" -> .empty ? \"yes\" ! \"no\"\n Wrong: 0 ? \"yes\" ! \"no\" Right: (0 == 0) ? \"yes\" ! \"no\"\n Negation (!) also requires boolean:\n Right: !true # false\n Right: \"hello\" -> .empty -> (!$) # true (negates boolean from .empty)\n Wrong: !\"hello\" # ERROR: Negation requires boolean\n Mainstream: if \"\" / if 0 Rill: .empty, == 0, :?type\n\n4. VARIABLES LOCK TO FIRST TYPE\n \"hello\" => $x\n 42 => $x # ERROR: cannot assign number to string variable\n\n5. NO VARIABLE SHADOWING (CRITICAL FOR LOOPS)\n Child scopes can READ parent variables but cannot WRITE or redeclare them.\n Variables created inside blocks/loops do NOT leak out.\n\n WRONG - outer variable modification (NEVER works):\n 0 => $count\n [1, 2, 3] -> each { $count + 1 => $count } # creates LOCAL $count\n $count # still 0!\n\n WRONG - \"while\" keyword does not exist:\n while ($i < 10) { $i + 1 => $i } # SYNTAX ERROR\n\n RIGHT - use fold for reduction:\n [1, 2, 3] -> fold(0) { $@ + $ } # 6 ($@ is accumulator)\n\n RIGHT - use each(init) for results AND accumulator:\n [1, 2, 3] -> each(0) { $@ + $ } # [1, 3, 6] (running totals)\n\n RIGHT - use (cond) @ { } with $ as state dict for multiple values:\n [iter: 0, max: 3, text: $input, done: false]\n -> (!$.done && $.iter < $.max) @ {\n $.iter + 1 => $i\n process($.text) => $result\n $result.finished ? [iter: $i, max: $.max, text: $.text, done: true]\n ! [iter: $i, max: $.max, text: $result.text, done: false]\n }\n\n Pattern summary:\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 Mainstream: count += 1 in loop Rill: fold(0) { $@ + 1 } or $ accumulator\n\n6. NO EXCEPTIONS\n Errors halt execution. No try/catch. Use conditionals for error handling.\n Built-in: assert (validate condition), error (halt with message).\n Mainstream: try { } catch { } Rill: assert, conditionals, error\n\n7. VALUE SEMANTICS (no references)\n All copies are deep. All comparisons are by value. No object identity.\n [1, 2, 3] == [1, 2, 3] # true (content equality)\n [1, 2] => $a\n $a => $b # $b is an independent deep copy\n Mainstream: a === b (reference) Rill: == always compares by value\n Mainstream: a = b (shared ref) Rill: => always deep-copies\n\nSYNTAX QUICK REFERENCE\n----------------------\n\nVariables: $name (always prefixed with $)\nStrings: \"hello {$var}\" # interpolation with {}\n \"\"\"...\"\"\" # multiline (also interpolates)\nNumbers: 42, 3.14, -7\nBooleans: true, false\nLists: [1, 2, 3]\n [...$list, 4] # spread: inline list elements\nDicts: [name: \"alice\", age: 30] # identifier keys\n [1: \"one\", 2: \"two\"] # number keys (incl. negative: [-1: \"neg\"])\n [true: \"yes\", false: \"no\"] # boolean keys\n [[\"a\", \"b\"]: 1] # multi-key: [a: 1, b: 1]\n [$keyVar: value] # variable key (must eval to string)\n [($expr): value] # computed key (must eval to string)\nTuples: *[1, 2, 3] # for argument unpacking\nClosures: |x|($x + 1) # like lambda/arrow functions\nType annot: \"hi\" => $x:string # lock type on capture\nComments: # single line only\n\nPIPES AND $ BINDING\n-------------------\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 - use parameters |\n\nImplied $: bare .method() means $ -> .method()\nExample: \"hello\" -> .upper # same as \"hello\" -> $.upper()\n\nCONTROL FLOW\n------------\n\nConditional (if-else):\n cond ? then_expr ! else_expr\n cond ? then_expr # else returns \"\"\n\nPiped conditional ($ becomes condition):\n value -> ? then_expr ! else_expr\n\nCondition loop (NO \"while\" keyword - use @ operator):\n init_value -> ($ < 10) @ { $ + 1 } # $ is accumulator\n\nDo-condition loop (body runs at least once):\n init_value -> @ { $ + 1 } ? ($ < 10)\n\nBreak (exits loop, returns collected results before break):\n [1,2,3,4,5] -> each { ($ == 3) ? break; $ } # returns [1, 2]\n\nReturn (exits block or script with value):\n { 5 => $x; ($x > 3) ? (\"big\" -> return); \"small\" } # returns \"big\"\n \"done\" -> return # exits script with \"done\"\n\nAssert (validate condition, halt if false, pass through if true):\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 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 cond ? pass ! \"fallback\" # preserve $ when condition true\n cond ? \"value\" ! pass # preserve $ when condition false\n \"data\" -> { [status: pass] } # include $ in dict: [status: \"data\"]\n [1, -2, 3] -> map { ($ > 0) ? pass ! 0 } # [1, 0, 3]\n Note: pass requires pipe context. Using pass without $ throws error.\n\nCOLLECTION OPERATORS\n--------------------\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 [\"a\", \"b\"] -> map .upper # [\"A\", \"B\"]\n [\"\", \"x\"] -> filter (!.empty) # [\"x\"]\n [\"a\", \"b\"] -> map .pad_start(3, \"0\") # [\"00a\", \"00b\"] (with args)\n [\" HI \"] -> map .trim.lower # [\"hi\"] (chained methods)\n\nBody forms (all operators accept these):\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 # host function\n\nDict iteration ($ contains key and value fields):\n [a: 1, b: 2] -> each { \"{$.key}={$.value}\" } # [\"a=1\", \"b=2\"]\n [a: 1, b: 5] -> filter { $.value > 2 } # entries where value > 2\n\nString iteration (iterates over characters):\n \"abc\" -> each { \"{$}!\" } # [\"a!\", \"b!\", \"c!\"]\n \"hello\" -> filter { $ != \"l\" } # [\"h\", \"e\", \"o\"]\n\nCLOSURES\n--------\n\nBLOCK-CLOSURES vs EXPLICIT CLOSURES:\n\nTwo ways to create closures:\n\n1. Block-closures: { body } in expression position\n { $ + 1 } => $inc # implicit $ parameter\n $inc(5) # 6\n 5 -> $inc # 6 (pipe invocation)\n [x: { $ * 2 }] # dict value is closure\n type({ \"hi\" }) # \"closure\"\n\n2. Explicit closures: |params| body\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\nCRITICAL: { } vs ( ) distinction\n\n| Syntax | Semantics | Example |\n|--------------|------------------------|----------------------------|\n| { body } | Deferred (closure) | { $ + 1 } => $fn # closure |\n| ( expr ) | Eager (immediate eval) | ( 5 + 1 ) => $x # 6 |\n\nWhen to use:\n { body } => $fn # store closure for later use\n ( expr ) => $x # store result value immediately\n\nPIPE TARGET: { } creates closure then immediately invokes it:\n 5 -> { $ + 1 } # 6 (create closure, invoke with 5)\n 5 -> ($ + 1) # 6 (evaluate expression with $=5)\n Same observable result, different mechanism. Error messages differ.\n\nBlock-closure invocation:\n { $ + 1 } => $inc\n $inc(5) # direct call: 6\n 5 -> $inc # pipe call: 6\n [1,2,3] -> map $inc # in collection op\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 [count: 3, double: ||{ $.count * 2 }] => $obj\n $obj.double # 6 ($ is bound to dict)\n\nPROPERTY ACCESS\n---------------\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\nDISPATCH OPERATORS\n------------------\n\nDICT DISPATCH (single key):\nPipe a value to a dict to match keys and return associated values:\n $val -> [apple: \"fruit\", carrot: \"veg\"] # returns \"fruit\" if $val is \"apple\"\n $val -> [apple: \"fruit\"] ?? \"not found\" # default if no match\n $method -> [[\"GET\", \"HEAD\"]: \"safe\", [\"POST\", \"PUT\"]: \"unsafe\"] # multi-key dispatch\n\nType-aware matching (keys matched by value AND type):\n 1 -> [1: \"number\", \"1\": \"string\"] # \"number\" (number key matches)\n \"1\" -> [1: \"number\", \"1\": \"string\"] # \"string\" (string key matches)\n true -> [true: \"bool\", \"true\": \"str\"] # \"bool\" (boolean key matches)\n\nLIST DISPATCH (index):\nPipe a number to a list to get element at index:\n 0 -> [\"first\", \"second\"] # \"first\"\n -1 -> [\"first\", \"second\"] # \"second\" (last)\n 5 -> [\"a\", \"b\"] ?? \"not found\" # default if out of bounds\n\nHIERARCHICAL DISPATCH (path navigation):\nPipe a list of keys/indexes to navigate nested structures:\n [\"name\", \"first\"] -> [name: [first: \"Alice\"]] # \"Alice\" (dict path)\n [0, 1] -> [[1, 2, 3], [4, 5, 6]] # 2 (list path)\n [\"users\", 0, \"name\"] -> [users: [[name: \"Alice\"]]] # \"Alice\" (mixed)\n [] -> [a: 1] # [a: 1] (empty path = unchanged)\n [\"a\", \"missing\"] -> [a: [x: 1]] ?? \"default\" # \"default\" (missing key)\n\nTYPE OPERATIONS\n---------------\n\n:type - assert type (error if wrong): 42:number passes; \"x\":number errors\n:?type - check type (boolean): 42:?number is true; \"x\":?number is false\n\nTypes: string, number, boolean, list, dict, tuple, closure\n\nComparison methods (for readable conditionals):\n .eq(val) == .ne(val) != .lt(val) < .gt(val) > .le(val) <= .ge(val) >=\n Example: $age -> .ge(18) ? \"adult\" ! \"minor\"\n\nOPERATOR PRECEDENCE (highest to lowest)\n---------------------------------------\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\nEXTRACTION OPERATORS\n--------------------\n\nDestructure (*<>):\n [1, 2, 3] -> *<$a, $b, $c> # $a=1, $b=2, $c=3\n [x: 1, y: 2] -> *<x: $a, y: $b> # $a=1, $b=2\n [1, 2, 3] -> *<$first, _, $third> # _ skips element\n\nSlice (/<start:stop:step>):\n [0,1,2,3,4] -> /<1:3> # [1, 2]\n [0,1,2,3,4] -> /<-2:> # [3, 4]\n [0,1,2,3,4] -> /<::-1> # [4,3,2,1,0] (reverse)\n \"hello\" -> /<1:4> # \"ell\"\n\nLIST SPREAD IN LITERALS\n-----------------------\n\nInline list elements into a new list using ... (spread operator):\n [1, 2] => $a\n [...$a, 3] # [1, 2, 3]\n [...$a, ...$b] # concatenate lists\n [...($nums -> map {$ * 2})] # spread expression result\n\nMULTI-KEY DICT LITERALS\n-----------------------\n\nMap multiple keys to the same value using list syntax:\n [[\"a\", \"b\"]: 1] # [a: 1, b: 1]\n [[1, \"1\"]: \"x\"] # [1: \"x\", \"1\": \"x\"] (mixed types)\n [a: 0, [\"b\", \"c\"]: 1] # [a: 0, b: 1, c: 1] (mixed entries)\n\nTUPLES FOR ARGUMENT UNPACKING\n-----------------------------\n\n*[1, 2, 3] -> $fn() # positional: $fn(1, 2, 3)\n*[b: 2, a: 1] -> $fn() # named: $fn(a=1, b=2)\n*[...$list, 3] -> $fn() # spread in tuple: combines elements\n\nCLOSURE CHAIN (@)\n-----------------\n\nChains closures sequentially (each receives previous result):\n 5 -> @[$inc, $double, $add10] # (5+1)*2+10 = 22\n\nSTRING METHODS\n--------------\n\n.len length .empty is empty string\n.trim remove whitespace .upper uppercase\n.lower lowercase .str convert to string\n.num parse to number .head first character\n.tail last character .at(i) character at index\n.split(sep) split into list (default: newline)\n.lines split on newlines .join(sep) join list with separator\n.contains(s) substring check .starts_with(s) prefix check\n.ends_with(s) suffix check .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: \"ab\" -> .repeat(3) # \"ababab\"\n.pad_start(n,f) pad start: \"42\" -> .pad_start(5, \"0\") # \"00042\"\n.pad_end(n,f) pad end: \"42\" -> .pad_end(5, \"0\") # \"42000\"\n\nLIST/DICT METHODS\n-----------------\n\n.len length .empty is empty\n.head first element .tail last element\n.at(i) element at index .keys dict keys as list\n.values dict values as list .entries dict as list of [k, v] tuples\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\nPARSING FUNCTIONS (for LLM output)\n----------------------------------\n\nparse_auto(str) auto-detect format\nparse_json(str) parse JSON (repairs common errors)\nparse_xml(str, tag?) extract XML tag content\nparse_fence(str, lang?) extract fenced code block\nparse_fences(str) all fenced blocks as list\nparse_frontmatter(str) parse --- delimited YAML + body\nparse_checklist(str) parse markdown task lists\n\nGLOBAL FUNCTIONS\n----------------\n\ntype(val) returns type name (string, number, boolean, list, dict, closure, tuple)\nlog(val) print and pass through\njson(val) convert to JSON string\nidentity(val) returns input unchanged\nrange(start, end, step?) number sequence (iterator)\nrepeat(val, count) repeat value n times (iterator)\nenumerate(coll) lists: [index, value]; dicts: [index, key, value]\n\nITERATORS\n---------\n\nLazy sequence generation. Collection operators auto-expand iterators.\n\nBuilt-in iterators:\n range(0, 5) -> each { $ * 2 } # [0, 2, 4, 6, 8]\n repeat(\"x\", 3) -> each { $ } # [\"x\", \"x\", \"x\"]\n\n.first() method (returns iterator for any collection):\n [1, 2, 3] -> .first() # iterator at 1\n \"abc\" -> .first() # iterator at \"a\"\n\nIterator protocol (dict with value, done, next):\n $it.done # bool: is exhausted?\n $it.value # current element\n $it.next() # returns new iterator at next position\n\nITERATION LIMITS\n----------------\n\nDefault: 10,000 iterations max for loops.\nOverride: ^(limit: N) statement\n\n ^(limit: 100) 0 -> ($ < 50) @ { $ + 1 }\n ^(limit: 3) $items -> map { slow_process($) } # concurrency limit\n\nSCRIPT RETURN VALUES\n--------------------\n\ntrue / non-empty string -> exit code 0\nfalse / empty string -> exit code 1\n[0, \"message\"] -> exit code 0 with message\n[1, \"message\"] -> exit code 1 with message\n";
2
+ //# sourceMappingURL=introspection-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"introspection-data.d.ts","sourceRoot":"","sources":["../../src/generated/introspection-data.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,kBAAkB,q+sBAuhB9B,CAAC"}
@@ -0,0 +1,539 @@
1
+ // AUTO-GENERATED - DO NOT EDIT
2
+ // Generated by packages/core/scripts/generate-docs-bundle.ts from docs/ref-llm.txt
3
+ export const LANGUAGE_REFERENCE = `RILL LANGUAGE REFERENCE
4
+ =======================
5
+
6
+ Rill is designed to be generated by LLMs and understood by humans. The focus is
7
+ on auditable LLM output, not ergonomic human authoring.
8
+
9
+ ESSENTIALS
10
+ ----------
11
+ 1. Variables use \$ prefix ALWAYS: 5 => \$x (no assignment operator =)
12
+ 2. Pipe with ->, capture with =>: "hello" => \$x -> .upper => \$y
13
+ 3. No null/undefined, no try/catch, no truthiness (conditions must be boolean)
14
+ 4. Variables lock to first type: "hi" => \$x; 42 => \$x # ERROR
15
+ 5. Loops cannot modify outer vars: use fold, each(init), or \$ as state dict
16
+
17
+ STRENGTHS AND USE CASES
18
+ -----------------------
19
+ Strengths:
20
+ - Unambiguous syntax: \$ prefix, explicit operators, no implicit coercion
21
+ - Single-pass parseable: LLMs generate correct code without symbol tables
22
+ - Readable by humans: pipe chains show data flow left-to-right
23
+ - Safe defaults: immutable values, type locking, no null/undefined
24
+
25
+ Use cases:
26
+ - Workflow orchestration: chain LLM calls, API requests, transformations
27
+ - State machines: (cond) @ { } loops with \$ as state dict
28
+ - Data pipelines: each/map/filter/fold process collections declaratively
29
+ - Prompt engineering: parse LLM output with parse_json, parse_xml, parse_fence
30
+
31
+ State machine pattern (\$ carries state through iterations):
32
+ [state: "init", data: \$input]
33
+ -> (\$.state != "done") @ {
34
+ \$.state -> [
35
+ init: { [state: "process", data: transform(\$.data)] },
36
+ process: { [state: "done", data: finalize(\$.data)] }
37
+ ]
38
+ }
39
+
40
+ NAMING CONVENTION: snake_case
41
+ -----------------------------
42
+ Use snake_case for all identifiers:
43
+ \$user_name, \$item_list, \$is_valid # variables
44
+ \$double_value, \$cleanup_text # closures
45
+ [first_name: "x", last_name: "y"] # dict keys
46
+
47
+ WHY VARIABLES USE \$ PREFIX
48
+ --------------------------
49
+ The \$ prefix enables single-pass parsing without a symbol table:
50
+
51
+ name() -> host function call
52
+ \$name() -> closure invocation
53
+ \$name -> variable reference
54
+ name -> dict key literal
55
+
56
+ Without \$, "process(data)" is ambiguous: is process a host function or stored
57
+ closure? Is data a variable or key? This would require tracking all declarations.
58
+
59
+ SPACING RULES
60
+ -------------
61
+ Operators: space both sides 5 + 3, \$x -> .upper, "a" => \$b
62
+ Parentheses: no inner space (\$x + 1), (\$ > 3) ? "yes"
63
+ Braces: space inside { \$x + 1 }, each { \$ * 2 }
64
+ Brackets: no inner space \$list[0], \$dict.items[1]
65
+ Literals: space after , and : [1, 2, 3], [name: "x", age: 30]
66
+ Closures: space after params |x| (\$x * 2), |a, b| { \$a + \$b }
67
+ Methods: no space before . or ( \$str.upper(), \$list.join(", ")
68
+ Pipes: space both sides "x" -> .upper -> .len
69
+ Continuations: indent 2 spaces \$data
70
+ -> .filter { \$.active }
71
+ -> map { \$.name }
72
+
73
+ IMPLICIT \$ SHORTHAND (always prefer)
74
+ ------------------------------------
75
+ \$.method() -> .method "x" -> .upper (not \$.upper())
76
+ func(\$) -> func "x" -> log (not log(\$))
77
+ \$fn(\$) -> \$fn 5 -> \$double (not \$double(\$))
78
+
79
+ Don't capture just to continue - use line continuation instead:
80
+ # avoid # good
81
+ "x" => \$a "x"
82
+ \$a -> .upper => \$b -> .upper
83
+ \$b -> .len -> .len
84
+
85
+ Only capture when the variable is reused later in the code.
86
+
87
+ CRITICAL DIFFERENCES FROM MAINSTREAM LANGUAGES
88
+ ----------------------------------------------
89
+
90
+ 1. NO ASSIGNMENT OPERATOR
91
+ Wrong: x = 5 Mainstream: x = value
92
+ Right: 5 => \$x Rill: value => \$x
93
+
94
+ Pipe (->): passes value to next operation
95
+ Capture (=>): stores value AND continues chain
96
+ Example: "hello" => \$x -> .upper => \$y # \$x="hello", \$y="HELLO"
97
+
98
+ 2. NO NULL/UNDEFINED
99
+ Empty values ("", [], [:]) exist. "No value" cannot be represented.
100
+ Use ?? for defaults: \$dict.field ?? "default"
101
+ Use .empty to check: \$str -> .empty ? "was empty"
102
+ Mainstream: null/undefined Rill: ?? default, .? existence check
103
+
104
+ 3. NO TRUTHINESS
105
+ Conditions MUST be boolean. No implicit coercion.
106
+ Wrong: "" ? "yes" ! "no" Right: "" -> .empty ? "yes" ! "no"
107
+ Wrong: 0 ? "yes" ! "no" Right: (0 == 0) ? "yes" ! "no"
108
+ Negation (!) also requires boolean:
109
+ Right: !true # false
110
+ Right: "hello" -> .empty -> (!\$) # true (negates boolean from .empty)
111
+ Wrong: !"hello" # ERROR: Negation requires boolean
112
+ Mainstream: if "" / if 0 Rill: .empty, == 0, :?type
113
+
114
+ 4. VARIABLES LOCK TO FIRST TYPE
115
+ "hello" => \$x
116
+ 42 => \$x # ERROR: cannot assign number to string variable
117
+
118
+ 5. NO VARIABLE SHADOWING (CRITICAL FOR LOOPS)
119
+ Child scopes can READ parent variables but cannot WRITE or redeclare them.
120
+ Variables created inside blocks/loops do NOT leak out.
121
+
122
+ WRONG - outer variable modification (NEVER works):
123
+ 0 => \$count
124
+ [1, 2, 3] -> each { \$count + 1 => \$count } # creates LOCAL \$count
125
+ \$count # still 0!
126
+
127
+ WRONG - "while" keyword does not exist:
128
+ while (\$i < 10) { \$i + 1 => \$i } # SYNTAX ERROR
129
+
130
+ RIGHT - use fold for reduction:
131
+ [1, 2, 3] -> fold(0) { \$@ + \$ } # 6 (\$@ is accumulator)
132
+
133
+ RIGHT - use each(init) for results AND accumulator:
134
+ [1, 2, 3] -> each(0) { \$@ + \$ } # [1, 3, 6] (running totals)
135
+
136
+ RIGHT - use (cond) @ { } with \$ as state dict for multiple values:
137
+ [iter: 0, max: 3, text: \$input, done: false]
138
+ -> (!\$.done && \$.iter < \$.max) @ {
139
+ \$.iter + 1 => \$i
140
+ process(\$.text) => \$result
141
+ \$result.finished ? [iter: \$i, max: \$.max, text: \$.text, done: true]
142
+ ! [iter: \$i, max: \$.max, text: \$result.text, done: false]
143
+ }
144
+
145
+ Pattern summary:
146
+ Single value accumulation -> fold(init) { \$@ + \$ }
147
+ Per-item results + running -> each(init) { ... \$@ ... }
148
+ Multiple state values / while -> (cond) @ { } with \$ as state dict
149
+ "while" and "for" keywords -> DO NOT EXIST
150
+ Mainstream: count += 1 in loop Rill: fold(0) { \$@ + 1 } or \$ accumulator
151
+
152
+ 6. NO EXCEPTIONS
153
+ Errors halt execution. No try/catch. Use conditionals for error handling.
154
+ Built-in: assert (validate condition), error (halt with message).
155
+ Mainstream: try { } catch { } Rill: assert, conditionals, error
156
+
157
+ 7. VALUE SEMANTICS (no references)
158
+ All copies are deep. All comparisons are by value. No object identity.
159
+ [1, 2, 3] == [1, 2, 3] # true (content equality)
160
+ [1, 2] => \$a
161
+ \$a => \$b # \$b is an independent deep copy
162
+ Mainstream: a === b (reference) Rill: == always compares by value
163
+ Mainstream: a = b (shared ref) Rill: => always deep-copies
164
+
165
+ SYNTAX QUICK REFERENCE
166
+ ----------------------
167
+
168
+ Variables: \$name (always prefixed with \$)
169
+ Strings: "hello {\$var}" # interpolation with {}
170
+ """...""" # multiline (also interpolates)
171
+ Numbers: 42, 3.14, -7
172
+ Booleans: true, false
173
+ Lists: [1, 2, 3]
174
+ [...\$list, 4] # spread: inline list elements
175
+ Dicts: [name: "alice", age: 30] # identifier keys
176
+ [1: "one", 2: "two"] # number keys (incl. negative: [-1: "neg"])
177
+ [true: "yes", false: "no"] # boolean keys
178
+ [["a", "b"]: 1] # multi-key: [a: 1, b: 1]
179
+ [\$keyVar: value] # variable key (must eval to string)
180
+ [(\$expr): value] # computed key (must eval to string)
181
+ Tuples: *[1, 2, 3] # for argument unpacking
182
+ Closures: |x|(\$x + 1) # like lambda/arrow functions
183
+ Type annot: "hi" => \$x:string # lock type on capture
184
+ Comments: # single line only
185
+
186
+ PIPES AND \$ BINDING
187
+ -------------------
188
+
189
+ \$ is the current piped value. Its meaning depends on context:
190
+
191
+ | Context | \$ contains |
192
+ |----------------------------|-------------------------|
193
+ | -> { body } | piped value |
194
+ | -> each { } | current item |
195
+ | (cond) @ { } | accumulated value |
196
+ | @ { } ? cond | accumulated value |
197
+ | cond ? { } ! { } | tested value |
198
+ | -> ? { } ! { } | piped value |
199
+ | ||{ \$.field } in dict | the containing dict |
200
+ | |x|{ } stored closure | N/A - use parameters |
201
+
202
+ Implied \$: bare .method() means \$ -> .method()
203
+ Example: "hello" -> .upper # same as "hello" -> \$.upper()
204
+
205
+ CONTROL FLOW
206
+ ------------
207
+
208
+ Conditional (if-else):
209
+ cond ? then_expr ! else_expr
210
+ cond ? then_expr # else returns ""
211
+
212
+ Piped conditional (\$ becomes condition):
213
+ value -> ? then_expr ! else_expr
214
+
215
+ Condition loop (NO "while" keyword - use @ operator):
216
+ init_value -> (\$ < 10) @ { \$ + 1 } # \$ is accumulator
217
+
218
+ Do-condition loop (body runs at least once):
219
+ init_value -> @ { \$ + 1 } ? (\$ < 10)
220
+
221
+ Break (exits loop, returns collected results before break):
222
+ [1,2,3,4,5] -> each { (\$ == 3) ? break; \$ } # returns [1, 2]
223
+
224
+ Return (exits block or script with value):
225
+ { 5 => \$x; (\$x > 3) ? ("big" -> return); "small" } # returns "big"
226
+ "done" -> return # exits script with "done"
227
+
228
+ Assert (validate condition, halt if false, pass through if true):
229
+ 5 -> assert (\$ > 0) # returns 5
230
+ -1 -> assert (\$ > 0) # ERROR: Assertion failed
231
+ "" -> assert !.empty "Input required" # ERROR: Input required
232
+ \$val -> assert \$:?list "Expected list" # type validation
233
+
234
+ Error (halt execution immediately with message):
235
+ error "Something went wrong" # halt with message
236
+ "Operation failed" -> error # piped form (must be string)
237
+ error "Status: {\$code}" # interpolation works
238
+
239
+ Pass (returns \$ unchanged, explicit no-op):
240
+ cond ? pass ! "fallback" # preserve \$ when condition true
241
+ cond ? "value" ! pass # preserve \$ when condition false
242
+ "data" -> { [status: pass] } # include \$ in dict: [status: "data"]
243
+ [1, -2, 3] -> map { (\$ > 0) ? pass ! 0 } # [1, 0, 3]
244
+ Note: pass requires pipe context. Using pass without \$ throws error.
245
+
246
+ COLLECTION OPERATORS
247
+ --------------------
248
+
249
+ | Operator | Execution | Returns | Break? |
250
+ |--------------------|------------|----------------------|--------|
251
+ | -> each { } | sequential | all body results | yes |
252
+ | -> each(i) { \$@+\$} | sequential | all with accumulator | yes |
253
+ | -> map { } | parallel | all body results | NO |
254
+ | -> filter { } | parallel | matching elements | NO |
255
+ | -> fold(i) { \$@+\$} | sequential | final result only | yes |
256
+
257
+ \$@ is the accumulator in each(init) and fold(init).
258
+
259
+ Method shorthand in collection operators:
260
+ ["a", "b"] -> map .upper # ["A", "B"]
261
+ ["", "x"] -> filter (!.empty) # ["x"]
262
+ ["a", "b"] -> map .pad_start(3, "0") # ["00a", "00b"] (with args)
263
+ [" HI "] -> map .trim.lower # ["hi"] (chained methods)
264
+
265
+ Body forms (all operators accept these):
266
+ -> each { \$ * 2 } # block (\$ is current element)
267
+ -> each (\$ + 10) # grouped expression
268
+ -> each |x| (\$x * 2) # inline closure
269
+ -> each \$double # variable closure
270
+ -> each .upper # method shorthand
271
+ -> each log # host function
272
+
273
+ Dict iteration (\$ contains key and value fields):
274
+ [a: 1, b: 2] -> each { "{\$.key}={\$.value}" } # ["a=1", "b=2"]
275
+ [a: 1, b: 5] -> filter { \$.value > 2 } # entries where value > 2
276
+
277
+ String iteration (iterates over characters):
278
+ "abc" -> each { "{\$}!" } # ["a!", "b!", "c!"]
279
+ "hello" -> filter { \$ != "l" } # ["h", "e", "o"]
280
+
281
+ CLOSURES
282
+ --------
283
+
284
+ BLOCK-CLOSURES vs EXPLICIT CLOSURES:
285
+
286
+ Two ways to create closures:
287
+
288
+ 1. Block-closures: { body } in expression position
289
+ { \$ + 1 } => \$inc # implicit \$ parameter
290
+ \$inc(5) # 6
291
+ 5 -> \$inc # 6 (pipe invocation)
292
+ [x: { \$ * 2 }] # dict value is closure
293
+ type({ "hi" }) # "closure"
294
+
295
+ 2. Explicit closures: |params| body
296
+ |x|(\$x + 1) => \$inc # named parameter
297
+ |a, b|(\$a + \$b) => \$add # multiple params
298
+ |x = 0|(\$x + 1) => \$inc_or_one # default value
299
+ |x: number|(\$x + 1) => \$typed # type annotation
300
+
301
+ CRITICAL: { } vs ( ) distinction
302
+
303
+ | Syntax | Semantics | Example |
304
+ |--------------|------------------------|----------------------------|
305
+ | { body } | Deferred (closure) | { \$ + 1 } => \$fn # closure |
306
+ | ( expr ) | Eager (immediate eval) | ( 5 + 1 ) => \$x # 6 |
307
+
308
+ When to use:
309
+ { body } => \$fn # store closure for later use
310
+ ( expr ) => \$x # store result value immediately
311
+
312
+ PIPE TARGET: { } creates closure then immediately invokes it:
313
+ 5 -> { \$ + 1 } # 6 (create closure, invoke with 5)
314
+ 5 -> (\$ + 1) # 6 (evaluate expression with \$=5)
315
+ Same observable result, different mechanism. Error messages differ.
316
+
317
+ Block-closure invocation:
318
+ { \$ + 1 } => \$inc
319
+ \$inc(5) # direct call: 6
320
+ 5 -> \$inc # pipe call: 6
321
+ [1,2,3] -> map \$inc # in collection op
322
+
323
+ LATE BINDING: closures capture scope, not values. Variables resolve at call time.
324
+
325
+ \$ vs named params:
326
+ Use \$ in inline pipes and loops: "hello" -> { .upper }
327
+ Use named params in stored closures: |x| (\$x * 2) => \$double
328
+ \$ is undefined when a stored closure is called later — always use params.
329
+
330
+ Zero-param dict closures (methods):
331
+ [count: 3, double: ||{ \$.count * 2 }] => \$obj
332
+ \$obj.double # 6 (\$ is bound to dict)
333
+
334
+ PROPERTY ACCESS
335
+ ---------------
336
+
337
+ \$data.field # dict field
338
+ \$data[0], \$data[-1] # list index (negative from end)
339
+ \$data.\$key # variable as key
340
+ \$data.(\$i + 1) # computed key
341
+ \$data.(a || b) # try keys left-to-right
342
+ \$data.field ?? "default" # default if missing
343
+ \$data.?field # existence check (boolean)
344
+ \$data.?\$keyVar # variable existence check
345
+ \$data.?(\$expr) # computed existence check
346
+ \$data.?field&string # existence AND type check
347
+ \$data.?\$key&number # variable existence + type check
348
+ \$data.?(\$a -> "{\$}_b")&list # computed existence + type check
349
+
350
+ DISPATCH OPERATORS
351
+ ------------------
352
+
353
+ DICT DISPATCH (single key):
354
+ Pipe a value to a dict to match keys and return associated values:
355
+ \$val -> [apple: "fruit", carrot: "veg"] # returns "fruit" if \$val is "apple"
356
+ \$val -> [apple: "fruit"] ?? "not found" # default if no match
357
+ \$method -> [["GET", "HEAD"]: "safe", ["POST", "PUT"]: "unsafe"] # multi-key dispatch
358
+
359
+ Type-aware matching (keys matched by value AND type):
360
+ 1 -> [1: "number", "1": "string"] # "number" (number key matches)
361
+ "1" -> [1: "number", "1": "string"] # "string" (string key matches)
362
+ true -> [true: "bool", "true": "str"] # "bool" (boolean key matches)
363
+
364
+ LIST DISPATCH (index):
365
+ Pipe a number to a list to get element at index:
366
+ 0 -> ["first", "second"] # "first"
367
+ -1 -> ["first", "second"] # "second" (last)
368
+ 5 -> ["a", "b"] ?? "not found" # default if out of bounds
369
+
370
+ HIERARCHICAL DISPATCH (path navigation):
371
+ Pipe a list of keys/indexes to navigate nested structures:
372
+ ["name", "first"] -> [name: [first: "Alice"]] # "Alice" (dict path)
373
+ [0, 1] -> [[1, 2, 3], [4, 5, 6]] # 2 (list path)
374
+ ["users", 0, "name"] -> [users: [[name: "Alice"]]] # "Alice" (mixed)
375
+ [] -> [a: 1] # [a: 1] (empty path = unchanged)
376
+ ["a", "missing"] -> [a: [x: 1]] ?? "default" # "default" (missing key)
377
+
378
+ TYPE OPERATIONS
379
+ ---------------
380
+
381
+ :type - assert type (error if wrong): 42:number passes; "x":number errors
382
+ :?type - check type (boolean): 42:?number is true; "x":?number is false
383
+
384
+ Types: string, number, boolean, list, dict, tuple, closure
385
+
386
+ Comparison methods (for readable conditionals):
387
+ .eq(val) == .ne(val) != .lt(val) < .gt(val) > .le(val) <= .ge(val) >=
388
+ Example: \$age -> .ge(18) ? "adult" ! "minor"
389
+
390
+ OPERATOR PRECEDENCE (highest to lowest)
391
+ ---------------------------------------
392
+
393
+ 1. Member access: .field, [index]
394
+ 2. Type operators: :type, :?type
395
+ 3. Unary: -, !
396
+ 4. Multiplicative: *, /, %
397
+ 5. Additive: +, -
398
+ 6. Comparison: ==, !=, <, >, <=, >=
399
+ 7. Logical AND: &&
400
+ 8. Logical OR: ||
401
+ 9. Default: ??
402
+ 10. Pipe: ->
403
+ 11. Capture: =>
404
+
405
+ Use parentheses to override: (2 + 3) * 4
406
+
407
+ EXTRACTION OPERATORS
408
+ --------------------
409
+
410
+ Destructure (*<>):
411
+ [1, 2, 3] -> *<\$a, \$b, \$c> # \$a=1, \$b=2, \$c=3
412
+ [x: 1, y: 2] -> *<x: \$a, y: \$b> # \$a=1, \$b=2
413
+ [1, 2, 3] -> *<\$first, _, \$third> # _ skips element
414
+
415
+ Slice (/<start:stop:step>):
416
+ [0,1,2,3,4] -> /<1:3> # [1, 2]
417
+ [0,1,2,3,4] -> /<-2:> # [3, 4]
418
+ [0,1,2,3,4] -> /<::-1> # [4,3,2,1,0] (reverse)
419
+ "hello" -> /<1:4> # "ell"
420
+
421
+ LIST SPREAD IN LITERALS
422
+ -----------------------
423
+
424
+ Inline list elements into a new list using ... (spread operator):
425
+ [1, 2] => \$a
426
+ [...\$a, 3] # [1, 2, 3]
427
+ [...\$a, ...\$b] # concatenate lists
428
+ [...(\$nums -> map {\$ * 2})] # spread expression result
429
+
430
+ MULTI-KEY DICT LITERALS
431
+ -----------------------
432
+
433
+ Map multiple keys to the same value using list syntax:
434
+ [["a", "b"]: 1] # [a: 1, b: 1]
435
+ [[1, "1"]: "x"] # [1: "x", "1": "x"] (mixed types)
436
+ [a: 0, ["b", "c"]: 1] # [a: 0, b: 1, c: 1] (mixed entries)
437
+
438
+ TUPLES FOR ARGUMENT UNPACKING
439
+ -----------------------------
440
+
441
+ *[1, 2, 3] -> \$fn() # positional: \$fn(1, 2, 3)
442
+ *[b: 2, a: 1] -> \$fn() # named: \$fn(a=1, b=2)
443
+ *[...\$list, 3] -> \$fn() # spread in tuple: combines elements
444
+
445
+ CLOSURE CHAIN (@)
446
+ -----------------
447
+
448
+ Chains closures sequentially (each receives previous result):
449
+ 5 -> @[\$inc, \$double, \$add10] # (5+1)*2+10 = 22
450
+
451
+ STRING METHODS
452
+ --------------
453
+
454
+ .len length .empty is empty string
455
+ .trim remove whitespace .upper uppercase
456
+ .lower lowercase .str convert to string
457
+ .num parse to number .head first character
458
+ .tail last character .at(i) character at index
459
+ .split(sep) split into list (default: newline)
460
+ .lines split on newlines .join(sep) join list with separator
461
+ .contains(s) substring check .starts_with(s) prefix check
462
+ .ends_with(s) suffix check .index_of(s) first match position (-1 if none)
463
+ .replace(p,r) replace first regex match
464
+ .replace_all(p,r) replace all regex matches
465
+ .match(regex) first match info (dict with matched, index, groups)
466
+ .is_match(regex) boolean regex check
467
+ .repeat(n) repeat n times: "ab" -> .repeat(3) # "ababab"
468
+ .pad_start(n,f) pad start: "42" -> .pad_start(5, "0") # "00042"
469
+ .pad_end(n,f) pad end: "42" -> .pad_end(5, "0") # "42000"
470
+
471
+ LIST/DICT METHODS
472
+ -----------------
473
+
474
+ .len length .empty is empty
475
+ .head first element .tail last element
476
+ .at(i) element at index .keys dict keys as list
477
+ .values dict values as list .entries dict as list of [k, v] tuples
478
+ .has(val) list contains value (deep equality)
479
+ .has_any(list) list contains any value from candidates
480
+ .has_all(list) list contains all values from candidates
481
+
482
+ PARSING FUNCTIONS (for LLM output)
483
+ ----------------------------------
484
+
485
+ parse_auto(str) auto-detect format
486
+ parse_json(str) parse JSON (repairs common errors)
487
+ parse_xml(str, tag?) extract XML tag content
488
+ parse_fence(str, lang?) extract fenced code block
489
+ parse_fences(str) all fenced blocks as list
490
+ parse_frontmatter(str) parse --- delimited YAML + body
491
+ parse_checklist(str) parse markdown task lists
492
+
493
+ GLOBAL FUNCTIONS
494
+ ----------------
495
+
496
+ type(val) returns type name (string, number, boolean, list, dict, closure, tuple)
497
+ log(val) print and pass through
498
+ json(val) convert to JSON string
499
+ identity(val) returns input unchanged
500
+ range(start, end, step?) number sequence (iterator)
501
+ repeat(val, count) repeat value n times (iterator)
502
+ enumerate(coll) lists: [index, value]; dicts: [index, key, value]
503
+
504
+ ITERATORS
505
+ ---------
506
+
507
+ Lazy sequence generation. Collection operators auto-expand iterators.
508
+
509
+ Built-in iterators:
510
+ range(0, 5) -> each { \$ * 2 } # [0, 2, 4, 6, 8]
511
+ repeat("x", 3) -> each { \$ } # ["x", "x", "x"]
512
+
513
+ .first() method (returns iterator for any collection):
514
+ [1, 2, 3] -> .first() # iterator at 1
515
+ "abc" -> .first() # iterator at "a"
516
+
517
+ Iterator protocol (dict with value, done, next):
518
+ \$it.done # bool: is exhausted?
519
+ \$it.value # current element
520
+ \$it.next() # returns new iterator at next position
521
+
522
+ ITERATION LIMITS
523
+ ----------------
524
+
525
+ Default: 10,000 iterations max for loops.
526
+ Override: ^(limit: N) statement
527
+
528
+ ^(limit: 100) 0 -> (\$ < 50) @ { \$ + 1 }
529
+ ^(limit: 3) \$items -> map { slow_process(\$) } # concurrency limit
530
+
531
+ SCRIPT RETURN VALUES
532
+ --------------------
533
+
534
+ true / non-empty string -> exit code 0
535
+ false / empty string -> exit code 1
536
+ [0, "message"] -> exit code 0 with message
537
+ [1, "message"] -> exit code 1 with message
538
+ `;
539
+ //# sourceMappingURL=introspection-data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"introspection-data.js","sourceRoot":"","sources":["../../src/generated/introspection-data.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,mFAAmF;AAEnF,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuhBjC,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Version information structure
3
+ */
4
+ export interface VersionInfo {
5
+ readonly major: number;
6
+ readonly minor: number;
7
+ readonly patch: number;
8
+ readonly prerelease: string | undefined;
9
+ }
10
+ /**
11
+ * Version string from package.json
12
+ */
13
+ export declare const VERSION = "0.6.0";
14
+ /**
15
+ * Parsed version components
16
+ */
17
+ export declare const VERSION_INFO: VersionInfo;
18
+ //# sourceMappingURL=version-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-data.d.ts","sourceRoot":"","sources":["../../src/generated/version-data.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAED;;GAEG;AACH,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,WAK1B,CAAC"}
@@ -0,0 +1,16 @@
1
+ // AUTO-GENERATED - DO NOT EDIT
2
+ // Generated by packages/core/scripts/generate-version.ts from package.json
3
+ /**
4
+ * Version string from package.json
5
+ */
6
+ export const VERSION = '0.6.0';
7
+ /**
8
+ * Parsed version components
9
+ */
10
+ export const VERSION_INFO = {
11
+ major: 0,
12
+ minor: 6,
13
+ patch: 0,
14
+ prerelease: undefined,
15
+ };
16
+ //# sourceMappingURL=version-data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-data.js","sourceRoot":"","sources":["../../src/generated/version-data.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,2EAA2E;AAY3E;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAgB;IACvC,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,CAAC;IACR,UAAU,EAAE,SAAS;CACtB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { TokenType } from './types.js';
2
+ export type HighlightCategory = 'keyword' | 'operator' | 'string' | 'number' | 'bool' | 'comment' | 'variableName' | 'punctuation' | 'bracket' | 'meta';
3
+ export declare const TOKEN_HIGHLIGHT_MAP: ReadonlyMap<TokenType, HighlightCategory>;
4
+ //# sourceMappingURL=highlight-map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"highlight-map.d.ts","sourceRoot":"","sources":["../src/highlight-map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAM5C,MAAM,MAAM,iBAAiB,GACzB,SAAS,GACT,UAAU,GACV,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,SAAS,GACT,cAAc,GACd,aAAa,GACb,SAAS,GACT,MAAM,CAAC;AAMX,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,SAAS,EAAE,iBAAiB,CA2EtE,CAAC"}