@rcrsr/rill 0.4.5 → 0.5.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 (137) hide show
  1. package/dist/check/config.d.ts.map +1 -1
  2. package/dist/check/config.js +9 -9
  3. package/dist/check/config.js.map +1 -1
  4. package/dist/check/visitor.d.ts.map +1 -1
  5. package/dist/check/visitor.js +1 -0
  6. package/dist/check/visitor.js.map +1 -1
  7. package/dist/cli-check.js +8 -9
  8. package/dist/cli-check.js.map +1 -1
  9. package/dist/cli-eval.js +4 -5
  10. package/dist/cli-eval.js.map +1 -1
  11. package/dist/cli-exec.d.ts.map +1 -1
  12. package/dist/cli-exec.js +2 -3
  13. package/dist/cli-exec.js.map +1 -1
  14. package/dist/cli-shared.d.ts +5 -3
  15. package/dist/cli-shared.d.ts.map +1 -1
  16. package/dist/cli-shared.js +5 -9
  17. package/dist/cli-shared.js.map +1 -1
  18. package/dist/generated/introspection-data.d.ts +2 -0
  19. package/dist/generated/introspection-data.d.ts.map +1 -0
  20. package/dist/generated/introspection-data.js +618 -0
  21. package/dist/generated/introspection-data.js.map +1 -0
  22. package/dist/generated/version-data.d.ts +18 -0
  23. package/dist/generated/version-data.d.ts.map +1 -0
  24. package/dist/generated/version-data.js +16 -0
  25. package/dist/generated/version-data.js.map +1 -0
  26. package/dist/index.d.ts +2 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +5 -1
  29. package/dist/index.js.map +1 -1
  30. package/dist/lexer/errors.d.ts +3 -2
  31. package/dist/lexer/errors.d.ts.map +1 -1
  32. package/dist/lexer/errors.js +19 -4
  33. package/dist/lexer/errors.js.map +1 -1
  34. package/dist/lexer/operators.d.ts.map +1 -1
  35. package/dist/lexer/operators.js +1 -0
  36. package/dist/lexer/operators.js.map +1 -1
  37. package/dist/lexer/readers.d.ts.map +1 -1
  38. package/dist/lexer/readers.js +4 -4
  39. package/dist/lexer/readers.js.map +1 -1
  40. package/dist/lexer/tokenizer.js +1 -1
  41. package/dist/lexer/tokenizer.js.map +1 -1
  42. package/dist/parser/helpers.d.ts.map +1 -1
  43. package/dist/parser/helpers.js +5 -3
  44. package/dist/parser/helpers.js.map +1 -1
  45. package/dist/parser/parser-collect.js +1 -1
  46. package/dist/parser/parser-collect.js.map +1 -1
  47. package/dist/parser/parser-control.js +6 -4
  48. package/dist/parser/parser-control.js.map +1 -1
  49. package/dist/parser/parser-expr.d.ts.map +1 -1
  50. package/dist/parser/parser-expr.js +24 -4
  51. package/dist/parser/parser-expr.js.map +1 -1
  52. package/dist/parser/parser-extract.js +1 -1
  53. package/dist/parser/parser-extract.js.map +1 -1
  54. package/dist/parser/parser-functions.js +2 -1
  55. package/dist/parser/parser-functions.js.map +1 -1
  56. package/dist/parser/parser-literals.js +11 -11
  57. package/dist/parser/parser-literals.js.map +1 -1
  58. package/dist/parser/parser-script.js +2 -0
  59. package/dist/parser/parser-script.js.map +1 -1
  60. package/dist/parser/parser-variables.js +7 -3
  61. package/dist/parser/parser-variables.js.map +1 -1
  62. package/dist/parser/state.js +1 -1
  63. package/dist/parser/state.js.map +1 -1
  64. package/dist/runtime/core/callable.d.ts +8 -0
  65. package/dist/runtime/core/callable.d.ts.map +1 -1
  66. package/dist/runtime/core/callable.js +6 -6
  67. package/dist/runtime/core/callable.js.map +1 -1
  68. package/dist/runtime/core/context.d.ts.map +1 -1
  69. package/dist/runtime/core/context.js +17 -8
  70. package/dist/runtime/core/context.js.map +1 -1
  71. package/dist/runtime/core/equals.d.ts.map +1 -1
  72. package/dist/runtime/core/equals.js +2 -1
  73. package/dist/runtime/core/equals.js.map +1 -1
  74. package/dist/runtime/core/eval/base.js +2 -2
  75. package/dist/runtime/core/eval/base.js.map +1 -1
  76. package/dist/runtime/core/eval/mixins/annotations.js +2 -2
  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 +32 -26
  80. package/dist/runtime/core/eval/mixins/closures.js.map +1 -1
  81. package/dist/runtime/core/eval/mixins/collections.js +13 -13
  82. package/dist/runtime/core/eval/mixins/collections.js.map +1 -1
  83. package/dist/runtime/core/eval/mixins/control-flow.js +1 -1
  84. package/dist/runtime/core/eval/mixins/control-flow.js.map +1 -1
  85. package/dist/runtime/core/eval/mixins/core.d.ts.map +1 -1
  86. package/dist/runtime/core/eval/mixins/core.js +37 -14
  87. package/dist/runtime/core/eval/mixins/core.js.map +1 -1
  88. package/dist/runtime/core/eval/mixins/expressions.d.ts +2 -0
  89. package/dist/runtime/core/eval/mixins/expressions.d.ts.map +1 -1
  90. package/dist/runtime/core/eval/mixins/expressions.js +80 -27
  91. package/dist/runtime/core/eval/mixins/expressions.js.map +1 -1
  92. package/dist/runtime/core/eval/mixins/extraction.js +14 -14
  93. package/dist/runtime/core/eval/mixins/extraction.js.map +1 -1
  94. package/dist/runtime/core/eval/mixins/literals.d.ts +4 -1
  95. package/dist/runtime/core/eval/mixins/literals.d.ts.map +1 -1
  96. package/dist/runtime/core/eval/mixins/literals.js +40 -20
  97. package/dist/runtime/core/eval/mixins/literals.js.map +1 -1
  98. package/dist/runtime/core/eval/mixins/types.js +3 -3
  99. package/dist/runtime/core/eval/mixins/types.js.map +1 -1
  100. package/dist/runtime/core/eval/mixins/variables.js +32 -32
  101. package/dist/runtime/core/eval/mixins/variables.js.map +1 -1
  102. package/dist/runtime/core/execute.js +2 -2
  103. package/dist/runtime/core/execute.js.map +1 -1
  104. package/dist/runtime/core/introspection-data.d.ts +2 -0
  105. package/dist/runtime/core/introspection-data.d.ts.map +1 -0
  106. package/dist/runtime/core/introspection-data.js +618 -0
  107. package/dist/runtime/core/introspection-data.js.map +1 -0
  108. package/dist/runtime/core/introspection.d.ts +59 -0
  109. package/dist/runtime/core/introspection.d.ts.map +1 -0
  110. package/dist/runtime/core/introspection.js +120 -0
  111. package/dist/runtime/core/introspection.js.map +1 -0
  112. package/dist/runtime/core/version-data.d.ts +18 -0
  113. package/dist/runtime/core/version-data.d.ts.map +1 -0
  114. package/dist/runtime/core/version-data.js +16 -0
  115. package/dist/runtime/core/version-data.js.map +1 -0
  116. package/dist/runtime/ext/builtins.js +21 -21
  117. package/dist/runtime/ext/builtins.js.map +1 -1
  118. package/dist/runtime/ext/extensions.js +1 -1
  119. package/dist/runtime/ext/extensions.js.map +1 -1
  120. package/dist/runtime/index.d.ts +4 -0
  121. package/dist/runtime/index.d.ts.map +1 -1
  122. package/dist/runtime/index.js +2 -0
  123. package/dist/runtime/index.js.map +1 -1
  124. package/dist/types.d.ts +116 -6
  125. package/dist/types.d.ts.map +1 -1
  126. package/dist/types.js +457 -11
  127. package/dist/types.js.map +1 -1
  128. package/docs/02_types.md +22 -0
  129. package/docs/04_operators.md +22 -1
  130. package/docs/05_control-flow.md +62 -0
  131. package/docs/11_reference.md +3 -2
  132. package/docs/12_examples.md +4 -4
  133. package/docs/14_host-integration.md +152 -0
  134. package/docs/15_grammar.ebnf +19 -1
  135. package/docs/88_errors.md +902 -0
  136. package/docs/99_llm-reference.txt +13 -0
  137. package/package.json +4 -2
@@ -562,6 +562,67 @@ Error halts the loop immediately:
562
562
 
563
563
  ---
564
564
 
565
+ ## Pass
566
+
567
+ The `pass` keyword returns the current pipe value (`$`) unchanged. Use it for explicit identity pass-through in conditional branches and dict values.
568
+
569
+ ### In Conditionals
570
+
571
+ Use `pass` when one branch should preserve the piped value:
572
+
573
+ ```rill
574
+ "input" -> .contains("in") ? pass ! "fallback"
575
+ # Returns "input" (condition true, pass preserves $)
576
+ ```
577
+
578
+ ```rill
579
+ "data" -> .empty ? { error "Empty input" } ! pass
580
+ # Returns "data" (condition false, pass preserves $)
581
+ ```
582
+
583
+ ### In Dict Values
584
+
585
+ Use `pass` to include the piped value in dict construction:
586
+
587
+ ```rill
588
+ "success" -> { [status: pass, code: 0] }
589
+ # Returns [status: "success", code: 0]
590
+ ```
591
+
592
+ ### In Collection Operators
593
+
594
+ Preserve elements conditionally:
595
+
596
+ ```rill
597
+ [1, -2, 3, -4] -> map { ($ > 0) ? pass ! 0 }
598
+ # Returns [1, 0, 3, 0]
599
+ ```
600
+
601
+ ### Why Use Pass?
602
+
603
+ The `pass` keyword provides clearer intent than bare `$`:
604
+
605
+ ```text
606
+ # Less clear - what does $ mean here?
607
+ $cond ? do_something() ! $
608
+
609
+ # More explicit - reader knows this is intentional no-op
610
+ $cond ? do_something() ! pass
611
+ ```
612
+
613
+ ### Pass Behavior
614
+
615
+ | Pattern | Returns | Context |
616
+ |---------|---------|---------|
617
+ | `cond ? pass ! alt` | `$` if true, `alt` if false | Conditional branch |
618
+ | `cond ? alt ! pass` | `alt` if true, `$` if false | Conditional branch |
619
+ | `[key: pass]` | Dict with `$` as value | Dict construction |
620
+ | `-> { pass }` | `$` | Block body |
621
+
622
+ **Note:** `pass` requires pipe context. Using `pass` without `$` bound throws an error.
623
+
624
+ ---
625
+
565
626
  ## Control Flow Summary
566
627
 
567
628
  | Statement | Scope | Effect |
@@ -570,6 +631,7 @@ Error halts the loop immediately:
570
631
  | `$val -> break` | Loop | Exit loop with value |
571
632
  | `return` | Block/Script | Exit block or script with current `$` |
572
633
  | `$val -> return` | Block/Script | Exit block or script with value |
634
+ | `pass` | Any | Returns current `$` unchanged |
573
635
  | `assert cond` | Any | Halt if condition false, pass through on success |
574
636
  | `assert cond "msg"` | Any | Halt with custom message if condition false |
575
637
  | `error "msg"` | Any | Always halt with error message |
@@ -1,10 +1,10 @@
1
- # rill Core Language Specification v0.4.5
1
+ # rill Core Language Specification v0.5.0
2
2
 
3
3
  *From prompts to workflows*
4
4
 
5
5
  rill is a pipe-based scripting language for orchestrating workflows.
6
6
 
7
- > **Experimental (v0.4.5).** Active development. Breaking changes until v1.0.
7
+ > **Experimental (v0.5.0).** Active development. Breaking changes until v1.0.
8
8
 
9
9
  ## Overview
10
10
 
@@ -60,6 +60,7 @@ See [Operators](04_operators.md) for detailed documentation.
60
60
  | `@ body ? cond` | Do-while |
61
61
  | `break` / `$val -> break` | Exit loop |
62
62
  | `return` / `$val -> return` | Exit block or script |
63
+ | `pass` | Returns current `$` unchanged (use in conditionals, dicts) |
63
64
  | `assert cond` / `assert cond "msg"` | Validate condition, halt on failure |
64
65
  | `error "msg"` / `$val -> error` | Halt execution with error message |
65
66
 
@@ -75,7 +75,7 @@ $verification -> ?(.contains("PASS")) {
75
75
 
76
76
  Works through a checklist until complete.
77
77
 
78
- ```rill
78
+ ```text
79
79
  ---
80
80
  args: plan: string
81
81
  ---
@@ -84,7 +84,7 @@ args: plan: string
84
84
  app::prompt("Read {$plan} and find the first unchecked item (- [ ])") :> $status
85
85
 
86
86
  # Work loop
87
- (!$status -> .contains("ALL COMPLETE")) @ {
87
+ $status -> (!.contains("ALL COMPLETE")) @ {
88
88
  """
89
89
  Based on this status:
90
90
  {$}
@@ -387,7 +387,7 @@ Items {$start} through {$end}
387
387
 
388
388
  Uses explicit signals for workflow control.
389
389
 
390
- ```rill
390
+ ```text
391
391
  ---
392
392
  args: task: string
393
393
  exceptions:
@@ -404,7 +404,7 @@ Rules:
404
404
  - Output :::DONE::: when complete
405
405
  """ -> app::prompt() :> $result
406
406
 
407
- (!$result -> .contains(":::DONE:::")) @ {
407
+ $result -> (!.contains(":::DONE:::")) @ {
408
408
  """
409
409
  Continue working on: {$task}
410
410
 
@@ -593,6 +593,150 @@ interface ExecutionResult {
593
593
  }
594
594
  ```
595
595
 
596
+ ## Introspection
597
+
598
+ Discover available functions, access language documentation, and check runtime version at runtime.
599
+
600
+ ### getFunctions()
601
+
602
+ Enumerate all callable functions registered in the runtime context:
603
+
604
+ ```typescript
605
+ import { createRuntimeContext, getFunctions } from '@rcrsr/rill';
606
+
607
+ const ctx = createRuntimeContext({
608
+ functions: {
609
+ greet: {
610
+ params: [
611
+ { name: 'name', type: 'string', description: 'Person to greet' },
612
+ ],
613
+ description: 'Generate a greeting message',
614
+ fn: (args) => `Hello, ${args[0]}!`,
615
+ },
616
+ },
617
+ });
618
+
619
+ const functions = getFunctions(ctx);
620
+ // [
621
+ // {
622
+ // name: 'greet',
623
+ // description: 'Generate a greeting message',
624
+ // params: [{ name: 'name', type: 'string', description: 'Person to greet', defaultValue: undefined }]
625
+ // },
626
+ // ... built-in functions
627
+ // ]
628
+ ```
629
+
630
+ Returns `FunctionMetadata[]` combining:
631
+ 1. Host functions (with full parameter metadata)
632
+ 2. Built-in functions
633
+ 3. Script closures (reads `^(doc: "...")` annotation for description)
634
+
635
+ ### getLanguageReference()
636
+
637
+ Access the bundled rill language reference for LLM prompt context:
638
+
639
+ ```typescript
640
+ import { getLanguageReference } from '@rcrsr/rill';
641
+
642
+ const reference = getLanguageReference();
643
+ // Returns complete language reference text (syntax, operators, types, etc.)
644
+
645
+ // Use in LLM system prompts:
646
+ const systemPrompt = `You are a rill script assistant.
647
+
648
+ ${reference}
649
+
650
+ Help the user write rill scripts.`;
651
+ ```
652
+
653
+ ### VERSION and VERSION_INFO
654
+
655
+ Access runtime version information for logging, diagnostics, or version checks:
656
+
657
+ ```typescript
658
+ import { VERSION, VERSION_INFO } from '@rcrsr/rill';
659
+
660
+ // VERSION: Semver string for display
661
+ console.log(`Running rill ${VERSION}`); // "Running rill 0.5.0"
662
+
663
+ // VERSION_INFO: Structured components for programmatic comparison
664
+ if (VERSION_INFO.major === 0 && VERSION_INFO.minor < 4) {
665
+ console.warn('Rill version too old, upgrade required');
666
+ }
667
+
668
+ // Log full version info
669
+ console.log('Runtime:', {
670
+ version: VERSION,
671
+ major: VERSION_INFO.major,
672
+ minor: VERSION_INFO.minor,
673
+ patch: VERSION_INFO.patch,
674
+ prerelease: VERSION_INFO.prerelease,
675
+ });
676
+ ```
677
+
678
+ **VERSION Constant:**
679
+ - Type: `string`
680
+ - Format: Semver (e.g., `"0.5.0"`, `"1.0.0-beta.1"`)
681
+ - Use: Display in logs, error messages, diagnostics
682
+
683
+ **VERSION_INFO Constant:**
684
+ - Type: `VersionInfo`
685
+ - Fields:
686
+ - `major: number` - Major version (breaking changes)
687
+ - `minor: number` - Minor version (new features)
688
+ - `patch: number` - Patch version (bug fixes)
689
+ - `prerelease?: string` - Prerelease tag if present
690
+ - Use: Programmatic version comparison, compatibility checks
691
+
692
+ **Version Comparison Example:**
693
+
694
+ ```typescript
695
+ import { VERSION_INFO } from '@rcrsr/rill';
696
+
697
+ function checkCompatibility(): boolean {
698
+ const required = { major: 0, minor: 4, patch: 0 };
699
+
700
+ if (VERSION_INFO.major !== required.major) {
701
+ return false; // Breaking change
702
+ }
703
+
704
+ if (VERSION_INFO.minor < required.minor) {
705
+ return false; // Missing features
706
+ }
707
+
708
+ return true;
709
+ }
710
+
711
+ if (!checkCompatibility()) {
712
+ throw new Error(`Requires rill >= 0.4.0, found ${VERSION}`);
713
+ }
714
+ ```
715
+
716
+ ### Introspection Types
717
+
718
+ ```typescript
719
+ interface FunctionMetadata {
720
+ readonly name: string; // Function name (e.g., "math::add")
721
+ readonly description: string; // Human-readable description
722
+ readonly params: readonly ParamMetadata[];
723
+ }
724
+
725
+ interface ParamMetadata {
726
+ readonly name: string; // Parameter name
727
+ readonly type: string; // Type constraint (e.g., "string")
728
+ readonly description: string; // Parameter description
729
+ readonly defaultValue: RillValue | undefined; // Default if optional
730
+ }
731
+
732
+ interface VersionInfo {
733
+ readonly major: number; // Major version (breaking changes)
734
+ readonly minor: number; // Minor version (new features)
735
+ readonly patch: number; // Patch version (bug fixes)
736
+ readonly prerelease?: string; // Prerelease tag if present
737
+ }
738
+ ```
739
+
596
740
  ## I/O Callbacks
597
741
 
598
742
  Handle script I/O through callbacks:
@@ -813,6 +957,14 @@ export { validateHostFunctionArgs };
813
957
  // Value types
814
958
  export type { RillValue, RillArgs };
815
959
 
960
+ // Introspection
961
+ export { getFunctions, getLanguageReference };
962
+ export type { FunctionMetadata, ParamMetadata };
963
+
964
+ // Version information
965
+ export { VERSION, VERSION_INFO };
966
+ export type { VersionInfo };
967
+
816
968
  // Callbacks
817
969
  export type { RuntimeCallbacks, ObservabilityCallbacks };
818
970
  export type { StepStartEvent, StepEndEvent, FunctionCallEvent, FunctionReturnEvent };
@@ -128,6 +128,10 @@ comparison = additive , [ comparison-op , additive ] ;
128
128
  additive = multiplicative , { ( "+" | "-" ) , multiplicative } ;
129
129
  multiplicative = unary , { ( "*" | "/" | "%" ) , unary } ;
130
130
  unary = [ "-" | "!" ] , postfix-expr ;
131
+ (* Semantic: "!" requires boolean operand. No truthiness coercion.
132
+ !true -> false, !false -> true
133
+ !"string" -> RUNTIME_TYPE_ERROR (Negation requires boolean, got string)
134
+ !0 -> RUNTIME_TYPE_ERROR (Negation requires boolean, got number) *)
131
135
 
132
136
  comparison-op = "==" | "!=" | "<" | ">" | "<=" | ">=" ;
133
137
 
@@ -151,7 +155,21 @@ primary = literal
151
155
  | loop
152
156
  | block
153
157
  | grouped-expr
154
- | spread ; (* *expr - convert list/dict to tuple *)
158
+ | spread (* *expr - convert list/dict to tuple *)
159
+ | pass ;
160
+
161
+ (* Pass: returns current pipe value ($) unchanged.
162
+ Used for explicit identity pass-through in conditionals and dict values.
163
+
164
+ Examples:
165
+ cond ? pass ! "fallback" -- preserve $ when condition true
166
+ cond ? "value" ! pass -- preserve $ when condition false
167
+ [key: pass] -- include $ as dict value
168
+ -> { pass } -- block returns $
169
+
170
+ Semantic: pass requires pipe context. Using pass without $ bound
171
+ throws RUNTIME_UNDEFINED_VARIABLE: Variable '$' not defined *)
172
+ pass = "pass" ;
155
173
 
156
174
  (* implicit-primary: used in contexts where implicit $ is available (body, pipe targets).
157
175
  Includes method-call because .method() expands to $ -> .method().