@rcrsr/rill 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +187 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +69 -0
- package/dist/cli.js.map +1 -0
- package/dist/demo.d.ts +6 -0
- package/dist/demo.d.ts.map +1 -0
- package/dist/demo.js +121 -0
- package/dist/demo.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/lexer/errors.d.ts +9 -0
- package/dist/lexer/errors.d.ts.map +1 -0
- package/dist/lexer/errors.js +12 -0
- package/dist/lexer/errors.js.map +1 -0
- package/dist/lexer/helpers.d.ts +14 -0
- package/dist/lexer/helpers.d.ts.map +1 -0
- package/dist/lexer/helpers.js +30 -0
- package/dist/lexer/helpers.js.map +1 -0
- package/dist/lexer/index.d.ts +8 -0
- package/dist/lexer/index.d.ts.map +1 -0
- package/dist/lexer/index.js +8 -0
- package/dist/lexer/index.js.map +1 -0
- package/dist/lexer/operators.d.ts +11 -0
- package/dist/lexer/operators.d.ts.map +1 -0
- package/dist/lexer/operators.js +58 -0
- package/dist/lexer/operators.js.map +1 -0
- package/dist/lexer/readers.d.ts +12 -0
- package/dist/lexer/readers.d.ts.map +1 -0
- package/dist/lexer/readers.js +144 -0
- package/dist/lexer/readers.js.map +1 -0
- package/dist/lexer/state.d.ts +18 -0
- package/dist/lexer/state.d.ts.map +1 -0
- package/dist/lexer/state.js +37 -0
- package/dist/lexer/state.js.map +1 -0
- package/dist/lexer/tokenizer.d.ts +9 -0
- package/dist/lexer/tokenizer.d.ts.map +1 -0
- package/dist/lexer/tokenizer.js +100 -0
- package/dist/lexer/tokenizer.js.map +1 -0
- package/dist/lexer.d.ts +19 -0
- package/dist/lexer.d.ts.map +1 -0
- package/dist/lexer.js +344 -0
- package/dist/lexer.js.map +1 -0
- package/dist/parser/arithmetic.d.ts +16 -0
- package/dist/parser/arithmetic.d.ts.map +1 -0
- package/dist/parser/arithmetic.js +128 -0
- package/dist/parser/arithmetic.js.map +1 -0
- package/dist/parser/boolean.d.ts +15 -0
- package/dist/parser/boolean.d.ts.map +1 -0
- package/dist/parser/boolean.js +20 -0
- package/dist/parser/boolean.js.map +1 -0
- package/dist/parser/control-flow.d.ts +56 -0
- package/dist/parser/control-flow.d.ts.map +1 -0
- package/dist/parser/control-flow.js +167 -0
- package/dist/parser/control-flow.js.map +1 -0
- package/dist/parser/expressions.d.ts +23 -0
- package/dist/parser/expressions.d.ts.map +1 -0
- package/dist/parser/expressions.js +950 -0
- package/dist/parser/expressions.js.map +1 -0
- package/dist/parser/extraction.d.ts +48 -0
- package/dist/parser/extraction.d.ts.map +1 -0
- package/dist/parser/extraction.js +279 -0
- package/dist/parser/extraction.js.map +1 -0
- package/dist/parser/functions.d.ts +20 -0
- package/dist/parser/functions.d.ts.map +1 -0
- package/dist/parser/functions.js +96 -0
- package/dist/parser/functions.js.map +1 -0
- package/dist/parser/helpers.d.ts +94 -0
- package/dist/parser/helpers.d.ts.map +1 -0
- package/dist/parser/helpers.js +225 -0
- package/dist/parser/helpers.js.map +1 -0
- package/dist/parser/index.d.ts +49 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +73 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/literals.d.ts +37 -0
- package/dist/parser/literals.d.ts.map +1 -0
- package/dist/parser/literals.js +373 -0
- package/dist/parser/literals.js.map +1 -0
- package/dist/parser/parser-collect.d.ts +16 -0
- package/dist/parser/parser-collect.d.ts.map +1 -0
- package/dist/parser/parser-collect.js +125 -0
- package/dist/parser/parser-collect.js.map +1 -0
- package/dist/parser/parser-control.d.ts +20 -0
- package/dist/parser/parser-control.d.ts.map +1 -0
- package/dist/parser/parser-control.js +120 -0
- package/dist/parser/parser-control.js.map +1 -0
- package/dist/parser/parser-expr.d.ts +37 -0
- package/dist/parser/parser-expr.d.ts.map +1 -0
- package/dist/parser/parser-expr.js +639 -0
- package/dist/parser/parser-expr.js.map +1 -0
- package/dist/parser/parser-extract.d.ts +17 -0
- package/dist/parser/parser-extract.d.ts.map +1 -0
- package/dist/parser/parser-extract.js +222 -0
- package/dist/parser/parser-extract.js.map +1 -0
- package/dist/parser/parser-functions.d.ts +21 -0
- package/dist/parser/parser-functions.d.ts.map +1 -0
- package/dist/parser/parser-functions.js +155 -0
- package/dist/parser/parser-functions.js.map +1 -0
- package/dist/parser/parser-literals.d.ts +22 -0
- package/dist/parser/parser-literals.d.ts.map +1 -0
- package/dist/parser/parser-literals.js +288 -0
- package/dist/parser/parser-literals.js.map +1 -0
- package/dist/parser/parser-script.d.ts +21 -0
- package/dist/parser/parser-script.d.ts.map +1 -0
- package/dist/parser/parser-script.js +174 -0
- package/dist/parser/parser-script.js.map +1 -0
- package/dist/parser/parser-variables.d.ts +20 -0
- package/dist/parser/parser-variables.d.ts.map +1 -0
- package/dist/parser/parser-variables.js +146 -0
- package/dist/parser/parser-variables.js.map +1 -0
- package/dist/parser/parser.d.ts +49 -0
- package/dist/parser/parser.d.ts.map +1 -0
- package/dist/parser/parser.js +54 -0
- package/dist/parser/parser.js.map +1 -0
- package/dist/parser/script.d.ts +14 -0
- package/dist/parser/script.d.ts.map +1 -0
- package/dist/parser/script.js +196 -0
- package/dist/parser/script.js.map +1 -0
- package/dist/parser/state.d.ts +40 -0
- package/dist/parser/state.d.ts.map +1 -0
- package/dist/parser/state.js +129 -0
- package/dist/parser/state.js.map +1 -0
- package/dist/parser/variables.d.ts +10 -0
- package/dist/parser/variables.d.ts.map +1 -0
- package/dist/parser/variables.js +215 -0
- package/dist/parser/variables.js.map +1 -0
- package/dist/runtime/ast-equals.d.ts +13 -0
- package/dist/runtime/ast-equals.d.ts.map +1 -0
- package/dist/runtime/ast-equals.js +447 -0
- package/dist/runtime/ast-equals.js.map +1 -0
- package/dist/runtime/builtins.d.ts +13 -0
- package/dist/runtime/builtins.d.ts.map +1 -0
- package/dist/runtime/builtins.js +180 -0
- package/dist/runtime/builtins.js.map +1 -0
- package/dist/runtime/callable.d.ts +88 -0
- package/dist/runtime/callable.d.ts.map +1 -0
- package/dist/runtime/callable.js +98 -0
- package/dist/runtime/callable.js.map +1 -0
- package/dist/runtime/context.d.ts +13 -0
- package/dist/runtime/context.d.ts.map +1 -0
- package/dist/runtime/context.js +73 -0
- package/dist/runtime/context.js.map +1 -0
- package/dist/runtime/core/callable.d.ts +171 -0
- package/dist/runtime/core/callable.d.ts.map +1 -0
- package/dist/runtime/core/callable.js +246 -0
- package/dist/runtime/core/callable.js.map +1 -0
- package/dist/runtime/core/context.d.ts +29 -0
- package/dist/runtime/core/context.d.ts.map +1 -0
- package/dist/runtime/core/context.js +154 -0
- package/dist/runtime/core/context.js.map +1 -0
- package/dist/runtime/core/equals.d.ts +9 -0
- package/dist/runtime/core/equals.d.ts.map +1 -0
- package/dist/runtime/core/equals.js +381 -0
- package/dist/runtime/core/equals.js.map +1 -0
- package/dist/runtime/core/eval/base.d.ts +65 -0
- package/dist/runtime/core/eval/base.d.ts.map +1 -0
- package/dist/runtime/core/eval/base.js +112 -0
- package/dist/runtime/core/eval/base.js.map +1 -0
- package/dist/runtime/core/eval/evaluator.d.ts +47 -0
- package/dist/runtime/core/eval/evaluator.d.ts.map +1 -0
- package/dist/runtime/core/eval/evaluator.js +73 -0
- package/dist/runtime/core/eval/evaluator.js.map +1 -0
- package/dist/runtime/core/eval/index.d.ts +57 -0
- package/dist/runtime/core/eval/index.d.ts.map +1 -0
- package/dist/runtime/core/eval/index.js +95 -0
- package/dist/runtime/core/eval/index.js.map +1 -0
- package/dist/runtime/core/eval/mixins/annotations.d.ts +19 -0
- package/dist/runtime/core/eval/mixins/annotations.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/annotations.js +146 -0
- package/dist/runtime/core/eval/mixins/annotations.js.map +1 -0
- package/dist/runtime/core/eval/mixins/closures.d.ts +49 -0
- package/dist/runtime/core/eval/mixins/closures.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/closures.js +479 -0
- package/dist/runtime/core/eval/mixins/closures.js.map +1 -0
- package/dist/runtime/core/eval/mixins/collections.d.ts +24 -0
- package/dist/runtime/core/eval/mixins/collections.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/collections.js +466 -0
- package/dist/runtime/core/eval/mixins/collections.js.map +1 -0
- package/dist/runtime/core/eval/mixins/control-flow.d.ts +27 -0
- package/dist/runtime/core/eval/mixins/control-flow.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/control-flow.js +369 -0
- package/dist/runtime/core/eval/mixins/control-flow.js.map +1 -0
- package/dist/runtime/core/eval/mixins/core.d.ts +24 -0
- package/dist/runtime/core/eval/mixins/core.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/core.js +335 -0
- package/dist/runtime/core/eval/mixins/core.js.map +1 -0
- package/dist/runtime/core/eval/mixins/expressions.d.ts +19 -0
- package/dist/runtime/core/eval/mixins/expressions.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/expressions.js +202 -0
- package/dist/runtime/core/eval/mixins/expressions.js.map +1 -0
- package/dist/runtime/core/eval/mixins/extraction.d.ts +10 -0
- package/dist/runtime/core/eval/mixins/extraction.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/extraction.js +250 -0
- package/dist/runtime/core/eval/mixins/extraction.js.map +1 -0
- package/dist/runtime/core/eval/mixins/literals.d.ts +23 -0
- package/dist/runtime/core/eval/mixins/literals.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/literals.js +180 -0
- package/dist/runtime/core/eval/mixins/literals.js.map +1 -0
- package/dist/runtime/core/eval/mixins/types.d.ts +20 -0
- package/dist/runtime/core/eval/mixins/types.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/types.js +109 -0
- package/dist/runtime/core/eval/mixins/types.js.map +1 -0
- package/dist/runtime/core/eval/mixins/variables.d.ts +34 -0
- package/dist/runtime/core/eval/mixins/variables.d.ts.map +1 -0
- package/dist/runtime/core/eval/mixins/variables.js +247 -0
- package/dist/runtime/core/eval/mixins/variables.js.map +1 -0
- package/dist/runtime/core/eval/types.d.ts +41 -0
- package/dist/runtime/core/eval/types.d.ts.map +1 -0
- package/dist/runtime/core/eval/types.js +10 -0
- package/dist/runtime/core/eval/types.js.map +1 -0
- package/dist/runtime/core/evaluate.d.ts +42 -0
- package/dist/runtime/core/evaluate.d.ts.map +1 -0
- package/dist/runtime/core/evaluate.debug.js +1251 -0
- package/dist/runtime/core/evaluate.js +1913 -0
- package/dist/runtime/core/evaluate.js.map +1 -0
- package/dist/runtime/core/execute.d.ts +26 -0
- package/dist/runtime/core/execute.d.ts.map +1 -0
- package/dist/runtime/core/execute.js +177 -0
- package/dist/runtime/core/execute.js.map +1 -0
- package/dist/runtime/core/signals.d.ts +19 -0
- package/dist/runtime/core/signals.d.ts.map +1 -0
- package/dist/runtime/core/signals.js +26 -0
- package/dist/runtime/core/signals.js.map +1 -0
- package/dist/runtime/core/types.d.ts +177 -0
- package/dist/runtime/core/types.d.ts.map +1 -0
- package/dist/runtime/core/types.js +50 -0
- package/dist/runtime/core/types.js.map +1 -0
- package/dist/runtime/core/values.d.ts +66 -0
- package/dist/runtime/core/values.d.ts.map +1 -0
- package/dist/runtime/core/values.js +240 -0
- package/dist/runtime/core/values.js.map +1 -0
- package/dist/runtime/evaluate.d.ts +32 -0
- package/dist/runtime/evaluate.d.ts.map +1 -0
- package/dist/runtime/evaluate.js +1111 -0
- package/dist/runtime/evaluate.js.map +1 -0
- package/dist/runtime/execute.d.ts +26 -0
- package/dist/runtime/execute.d.ts.map +1 -0
- package/dist/runtime/execute.js +121 -0
- package/dist/runtime/execute.js.map +1 -0
- package/dist/runtime/ext/builtins.d.ts +16 -0
- package/dist/runtime/ext/builtins.d.ts.map +1 -0
- package/dist/runtime/ext/builtins.js +528 -0
- package/dist/runtime/ext/builtins.js.map +1 -0
- package/dist/runtime/ext/content-parser.d.ts +83 -0
- package/dist/runtime/ext/content-parser.d.ts.map +1 -0
- package/dist/runtime/ext/content-parser.js +536 -0
- package/dist/runtime/ext/content-parser.js.map +1 -0
- package/dist/runtime/index.d.ts +28 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +34 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/signals.d.ts +19 -0
- package/dist/runtime/signals.d.ts.map +1 -0
- package/dist/runtime/signals.js +26 -0
- package/dist/runtime/signals.js.map +1 -0
- package/dist/runtime/types.d.ts +169 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime/types.js +50 -0
- package/dist/runtime/types.js.map +1 -0
- package/dist/runtime/values.d.ts +50 -0
- package/dist/runtime/values.d.ts.map +1 -0
- package/dist/runtime/values.js +209 -0
- package/dist/runtime/values.js.map +1 -0
- package/dist/runtime.d.ts +254 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +2014 -0
- package/dist/runtime.js.map +1 -0
- package/dist/types.d.ts +752 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +189 -0
- package/dist/types.js.map +1 -0
- package/docs/00_INDEX.md +65 -0
- package/docs/01_guide.md +390 -0
- package/docs/02_types.md +399 -0
- package/docs/03_variables.md +314 -0
- package/docs/04_operators.md +551 -0
- package/docs/05_control-flow.md +350 -0
- package/docs/06_closures.md +353 -0
- package/docs/07_collections.md +686 -0
- package/docs/08_iterators.md +330 -0
- package/docs/09_strings.md +205 -0
- package/docs/10_parsing.md +366 -0
- package/docs/11_reference.md +350 -0
- package/docs/12_examples.md +771 -0
- package/docs/13_modules.md +519 -0
- package/docs/14_host-integration.md +826 -0
- package/docs/15_grammar.ebnf +693 -0
- package/docs/16_conventions.md +696 -0
- package/docs/99_llm-reference.txt +300 -0
- package/docs/assets/logo.png +0 -0
- package/package.json +70 -0
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
# rill Operators
|
|
2
|
+
|
|
3
|
+
*Pipe, arithmetic, comparison, logical, spread, and extraction operators*
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
| Category | Operators |
|
|
8
|
+
|----------|-----------|
|
|
9
|
+
| Pipe | `->` |
|
|
10
|
+
| Capture | `:>` |
|
|
11
|
+
| Arithmetic | `+`, `-`, `*`, `/`, `%` |
|
|
12
|
+
| Comparison | `==`, `!=`, `<`, `>`, `<=`, `>=` |
|
|
13
|
+
| Comparison Methods | `.eq`, `.ne`, `.lt`, `.gt`, `.le`, `.ge` |
|
|
14
|
+
| Logical | `!` (unary), `&&`, `||` |
|
|
15
|
+
| Spread | `@` (sequential), `*` (tuple) |
|
|
16
|
+
| Extraction | `*<>` (destructure), `/<>` (slice) |
|
|
17
|
+
| Type | `:type` (assert), `:?type` (check) |
|
|
18
|
+
| Member | `.field`, `[index]` |
|
|
19
|
+
| Default | `?? value` |
|
|
20
|
+
| Existence | `.?field`, `.?field&type` |
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Pipe Operator `->`
|
|
25
|
+
|
|
26
|
+
The pipe operator passes the left-hand value to the right-hand side:
|
|
27
|
+
|
|
28
|
+
```rill
|
|
29
|
+
"hello" -> .upper # "HELLO"
|
|
30
|
+
42 -> ($ + 8) # 50
|
|
31
|
+
[1, 2, 3] -> each { $ * 2 } # [2, 4, 6]
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Piped Value as `$`
|
|
35
|
+
|
|
36
|
+
The piped value is available as `$`:
|
|
37
|
+
|
|
38
|
+
```rill
|
|
39
|
+
"world" -> "hello {$}" # "hello world"
|
|
40
|
+
5 -> ($ * $ + $) # 30
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Method Syntax
|
|
44
|
+
|
|
45
|
+
Method calls are sugar for pipes:
|
|
46
|
+
|
|
47
|
+
```rill
|
|
48
|
+
"hello".upper # equivalent: "hello" -> .upper
|
|
49
|
+
"hello".contains("ell") # equivalent: "hello" -> .contains("ell")
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Implicit `$`
|
|
53
|
+
|
|
54
|
+
Bare `.method()` implies `$` as receiver:
|
|
55
|
+
|
|
56
|
+
```rill
|
|
57
|
+
"hello" -> {
|
|
58
|
+
.upper -> log # $."upper" -> log
|
|
59
|
+
.len # $.len
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Capture Operator `:>`
|
|
66
|
+
|
|
67
|
+
Captures a value into a variable:
|
|
68
|
+
|
|
69
|
+
```rill
|
|
70
|
+
"hello" :> $greeting # store in $greeting
|
|
71
|
+
42 :> $count # store in $count
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Capture and Continue
|
|
75
|
+
|
|
76
|
+
`:>` captures AND continues the chain:
|
|
77
|
+
|
|
78
|
+
```rill
|
|
79
|
+
"hello" :> $a -> .upper :> $b -> .len
|
|
80
|
+
# $a is "hello", $b is "HELLO", result is 5
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
See [Variables](03_variables.md) for detailed scoping rules.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Arithmetic Operators
|
|
88
|
+
|
|
89
|
+
| Operator | Description |
|
|
90
|
+
|----------|-------------|
|
|
91
|
+
| `+` | Addition |
|
|
92
|
+
| `-` | Subtraction |
|
|
93
|
+
| `*` | Multiplication |
|
|
94
|
+
| `/` | Division |
|
|
95
|
+
| `%` | Modulo (remainder) |
|
|
96
|
+
|
|
97
|
+
```rill
|
|
98
|
+
5 + 3 # 8
|
|
99
|
+
10 - 4 # 6
|
|
100
|
+
3 * 4 # 12
|
|
101
|
+
15 / 3 # 5
|
|
102
|
+
17 % 5 # 2
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Precedence
|
|
106
|
+
|
|
107
|
+
Standard mathematical precedence (high to low):
|
|
108
|
+
1. Unary: `-`, `!`
|
|
109
|
+
2. Multiplicative: `*`, `/`, `%`
|
|
110
|
+
3. Additive: `+`, `-`
|
|
111
|
+
|
|
112
|
+
```rill
|
|
113
|
+
2 + 3 * 4 # 14 (multiplication first)
|
|
114
|
+
(2 + 3) * 4 # 20 (parentheses override)
|
|
115
|
+
-5 + 3 # -2
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Type Constraint
|
|
119
|
+
|
|
120
|
+
All operands must be numbers. No implicit conversion:
|
|
121
|
+
|
|
122
|
+
```rill
|
|
123
|
+
5 + 3 # OK: 8
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
```text
|
|
127
|
+
"5" + 1 # ERROR: Arithmetic requires number, got string
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Error Handling
|
|
131
|
+
|
|
132
|
+
```text
|
|
133
|
+
10 / 0 # ERROR: Division by zero
|
|
134
|
+
10 % 0 # ERROR: Modulo by zero
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Comparison Operators
|
|
140
|
+
|
|
141
|
+
| Operator | Description |
|
|
142
|
+
|----------|-------------|
|
|
143
|
+
| `==` | Equal |
|
|
144
|
+
| `!=` | Not equal |
|
|
145
|
+
| `<` | Less than |
|
|
146
|
+
| `>` | Greater than |
|
|
147
|
+
| `<=` | Less or equal |
|
|
148
|
+
| `>=` | Greater or equal |
|
|
149
|
+
|
|
150
|
+
```rill
|
|
151
|
+
5 == 5 # true
|
|
152
|
+
5 != 3 # true
|
|
153
|
+
3 < 5 # true
|
|
154
|
+
5 > 3 # true
|
|
155
|
+
5 <= 5 # true
|
|
156
|
+
5 >= 3 # true
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Value Comparison
|
|
160
|
+
|
|
161
|
+
All comparisons are by value, not reference:
|
|
162
|
+
|
|
163
|
+
```rill
|
|
164
|
+
[1, 2, 3] == [1, 2, 3] # true
|
|
165
|
+
[a: 1] == [a: 1] # true
|
|
166
|
+
"hello" == "hello" # true
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Comparison Methods
|
|
170
|
+
|
|
171
|
+
Methods provide readable alternatives in conditionals:
|
|
172
|
+
|
|
173
|
+
| Method | Equivalent |
|
|
174
|
+
|--------|------------|
|
|
175
|
+
| `.eq(val)` | `== val` |
|
|
176
|
+
| `.ne(val)` | `!= val` |
|
|
177
|
+
| `.lt(val)` | `< val` |
|
|
178
|
+
| `.gt(val)` | `> val` |
|
|
179
|
+
| `.le(val)` | `<= val` |
|
|
180
|
+
| `.ge(val)` | `>= val` |
|
|
181
|
+
|
|
182
|
+
```rill
|
|
183
|
+
"A" :> $v
|
|
184
|
+
$v -> .eq("A") ? "match" ! "no" # "match"
|
|
185
|
+
5 -> .gt(3) ? "big" ! "small" # "big"
|
|
186
|
+
10 -> .le(10) ? "ok" ! "over" # "ok"
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Logical Operators
|
|
192
|
+
|
|
193
|
+
| Operator | Description |
|
|
194
|
+
|----------|-------------|
|
|
195
|
+
| `&&` | Logical AND (short-circuit) |
|
|
196
|
+
| `\|\|` | Logical OR (short-circuit) |
|
|
197
|
+
| `!` | Logical NOT |
|
|
198
|
+
|
|
199
|
+
```rill
|
|
200
|
+
(true && false) # false
|
|
201
|
+
(true || false) # true
|
|
202
|
+
!true # false
|
|
203
|
+
!false # true
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Short-Circuit Evaluation
|
|
207
|
+
|
|
208
|
+
```rill
|
|
209
|
+
(false && undefined_var) # false (right side not evaluated)
|
|
210
|
+
(true || undefined_var) # true (right side not evaluated)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### With Comparisons
|
|
214
|
+
|
|
215
|
+
```rill
|
|
216
|
+
(1 < 2 && 3 > 2) # true
|
|
217
|
+
(5 > 10 || 3 < 5) # true
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Grouping Required
|
|
221
|
+
|
|
222
|
+
Compound expressions require grouping in simple-body contexts:
|
|
223
|
+
|
|
224
|
+
```rill
|
|
225
|
+
true -> ($ && true) ? "both" ! "not both" # "both"
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Negation in Pipes
|
|
229
|
+
|
|
230
|
+
In pipe targets, `!expr` binds tightly and returns a boolean:
|
|
231
|
+
|
|
232
|
+
```rill
|
|
233
|
+
"hello" -> !.empty # true (not empty)
|
|
234
|
+
"" -> !.empty # false (is empty)
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
This works naturally with conditionals and captures:
|
|
238
|
+
|
|
239
|
+
```rill
|
|
240
|
+
"hello" -> !.empty ? "has content" ! "empty" # "has content"
|
|
241
|
+
"hello" -> !.empty :> $not_empty # $not_empty = true
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
No grouping needed — `!.empty` is parsed as a unit before `?` or `:>`.
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## Spread Operators
|
|
249
|
+
|
|
250
|
+
### Sequential Spread `@`
|
|
251
|
+
|
|
252
|
+
Chain closures where each receives the previous result (fold pattern):
|
|
253
|
+
|
|
254
|
+
```rill
|
|
255
|
+
|x|($x + 1) :> $inc
|
|
256
|
+
|x|($x * 2) :> $double
|
|
257
|
+
|x|($x + 10) :> $add10
|
|
258
|
+
|
|
259
|
+
# Chain: (5 + 1) = 6, (6 * 2) = 12, (12 + 10) = 22
|
|
260
|
+
5 -> @[$inc, $double, $add10] # 22
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Single closure:
|
|
264
|
+
|
|
265
|
+
```rill
|
|
266
|
+
|x|($x * 2) :> $dbl
|
|
267
|
+
5 -> @$dbl # 10
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Tuple Spread `*`
|
|
271
|
+
|
|
272
|
+
Create tuples for argument unpacking:
|
|
273
|
+
|
|
274
|
+
```rill
|
|
275
|
+
# From list (positional)
|
|
276
|
+
*[1, 2, 3] :> $args
|
|
277
|
+
|
|
278
|
+
# From dict (named)
|
|
279
|
+
*[x: 1, y: 2] :> $named
|
|
280
|
+
|
|
281
|
+
# Convert list to tuple via pipe
|
|
282
|
+
[1, 2, 3] -> * :> $tuple
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Using tuples at invocation:
|
|
286
|
+
|
|
287
|
+
```rill
|
|
288
|
+
|a, b, c|"{$a}-{$b}-{$c}" :> $fmt
|
|
289
|
+
*[1, 2, 3] -> $fmt() # "1-2-3"
|
|
290
|
+
*[c: 3, a: 1, b: 2] -> $fmt() # "1-2-3" (named, order doesn't matter)
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
See [Types](02_types.md) for full tuple documentation.
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Extraction Operators
|
|
298
|
+
|
|
299
|
+
### Destructure `*<>`
|
|
300
|
+
|
|
301
|
+
Extract elements from lists or dicts into variables. Returns the original value unchanged.
|
|
302
|
+
|
|
303
|
+
**List destructuring** (pattern count must match list length):
|
|
304
|
+
|
|
305
|
+
```rill
|
|
306
|
+
[1, 2, 3] -> *<$a, $b, $c>
|
|
307
|
+
# $a = 1, $b = 2, $c = 3
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
**With type annotations:**
|
|
311
|
+
|
|
312
|
+
```rill
|
|
313
|
+
[0, "ok"] -> *<$code:number, $msg:string>
|
|
314
|
+
# $code = 0, $msg = "ok"
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
**Skip elements with `_`:**
|
|
318
|
+
|
|
319
|
+
```rill
|
|
320
|
+
[1, 2, 3, 4] -> *<$first, _, _, $last>
|
|
321
|
+
# $first = 1, $last = 4
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
**Dict destructuring** (explicit key mapping):
|
|
325
|
+
|
|
326
|
+
```rill
|
|
327
|
+
[name: "test", count: 42] -> *<name: $n, count: $c>
|
|
328
|
+
# $n = "test", $c = 42
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
**Nested destructuring:**
|
|
332
|
+
|
|
333
|
+
```rill
|
|
334
|
+
[[1, 2], 3] -> *<*<$a, $b>, $c>
|
|
335
|
+
# $a = 1, $b = 2, $c = 3
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**Errors:**
|
|
339
|
+
|
|
340
|
+
```text
|
|
341
|
+
[1, 2] -> *<$a, $b, $c> # Error: pattern has 3 elements, list has 2
|
|
342
|
+
[name: "x"] -> *<name: $n, age: $a> # Error: key 'age' not found
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Slice `/<>`
|
|
346
|
+
|
|
347
|
+
Extract a portion using Python-style `start:stop:step`. Works on lists and strings.
|
|
348
|
+
|
|
349
|
+
**Basic slicing:**
|
|
350
|
+
|
|
351
|
+
```rill
|
|
352
|
+
[0, 1, 2, 3, 4] -> /<0:3> # [0, 1, 2]
|
|
353
|
+
[0, 1, 2, 3, 4] -> /<1:4> # [1, 2, 3]
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
**Omitted bounds:**
|
|
357
|
+
|
|
358
|
+
```rill
|
|
359
|
+
[0, 1, 2, 3, 4] -> /<:3> # [0, 1, 2] (first 3)
|
|
360
|
+
[0, 1, 2, 3, 4] -> /<2:> # [2, 3, 4] (from index 2)
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
**Negative indices:**
|
|
364
|
+
|
|
365
|
+
```rill
|
|
366
|
+
[0, 1, 2, 3, 4] -> /<-2:> # [3, 4] (last 2)
|
|
367
|
+
[0, 1, 2, 3, 4] -> /<:-1> # [0, 1, 2, 3] (all but last)
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
**Step:**
|
|
371
|
+
|
|
372
|
+
```rill
|
|
373
|
+
[0, 1, 2, 3, 4] -> /<::2> # [0, 2, 4] (every 2nd)
|
|
374
|
+
[0, 1, 2, 3, 4] -> /<::-1> # [4, 3, 2, 1, 0] (reversed)
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
**String slicing:**
|
|
378
|
+
|
|
379
|
+
```rill
|
|
380
|
+
"hello" -> /<1:4> # "ell"
|
|
381
|
+
"hello" -> /<::-1> # "olleh"
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
**Edge cases:**
|
|
385
|
+
|
|
386
|
+
```rill
|
|
387
|
+
[1, 2, 3] -> /<0:100> # [1, 2, 3] (clamped)
|
|
388
|
+
[1, 2, 3] -> /<2:1> # [] (empty when start >= stop)
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
```text
|
|
392
|
+
[1, 2, 3] -> /<::0> # Error: step cannot be zero
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
## Member Access Operators
|
|
398
|
+
|
|
399
|
+
### Field Access `.field`
|
|
400
|
+
|
|
401
|
+
Access dict fields:
|
|
402
|
+
|
|
403
|
+
```rill
|
|
404
|
+
[name: "alice", age: 30] :> $person
|
|
405
|
+
$person.name # "alice"
|
|
406
|
+
$person.age # 30
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### Index Access `[n]`
|
|
410
|
+
|
|
411
|
+
Access list elements (0-based, negative from end):
|
|
412
|
+
|
|
413
|
+
```rill
|
|
414
|
+
["a", "b", "c"] :> $list
|
|
415
|
+
$list[0] # "a"
|
|
416
|
+
$list[-1] # "c"
|
|
417
|
+
$list[1] # "b"
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Variable Key `.$key`
|
|
421
|
+
|
|
422
|
+
Use a variable as key:
|
|
423
|
+
|
|
424
|
+
```rill
|
|
425
|
+
"name" :> $key
|
|
426
|
+
[name: "alice"] :> $data
|
|
427
|
+
$data.$key # "alice"
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Computed Key `.($expr)`
|
|
431
|
+
|
|
432
|
+
Use an expression as key:
|
|
433
|
+
|
|
434
|
+
```rill
|
|
435
|
+
0 :> $i
|
|
436
|
+
["a", "b", "c"] :> $list
|
|
437
|
+
$list.($i + 1) # "b"
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### Alternative Keys `.(a || b)`
|
|
441
|
+
|
|
442
|
+
Try keys left-to-right:
|
|
443
|
+
|
|
444
|
+
```rill
|
|
445
|
+
[nickname: "Al"] :> $user
|
|
446
|
+
$user.(name || nickname) # "Al"
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
## Default Operator `??`
|
|
452
|
+
|
|
453
|
+
Provide a default value if field is missing:
|
|
454
|
+
|
|
455
|
+
```rill
|
|
456
|
+
[:] :> $empty
|
|
457
|
+
$empty.name ?? "unknown" # "unknown"
|
|
458
|
+
|
|
459
|
+
[name: "alice"] :> $user
|
|
460
|
+
$user.name ?? "unknown" # "alice"
|
|
461
|
+
$user.age ?? 0 # 0
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
---
|
|
465
|
+
|
|
466
|
+
## Existence Operators
|
|
467
|
+
|
|
468
|
+
### Field Existence `.?field`
|
|
469
|
+
|
|
470
|
+
Returns boolean:
|
|
471
|
+
|
|
472
|
+
```rill
|
|
473
|
+
[name: "alice"] :> $user
|
|
474
|
+
$user.?name # true
|
|
475
|
+
$user.?age # false
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
### Existence with Type `.?field&type`
|
|
479
|
+
|
|
480
|
+
Check existence AND type:
|
|
481
|
+
|
|
482
|
+
```rill
|
|
483
|
+
[name: "alice", age: 30] :> $user
|
|
484
|
+
$user.?name&string # true
|
|
485
|
+
$user.?age&number # true
|
|
486
|
+
$user.?age&string # false
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
---
|
|
490
|
+
|
|
491
|
+
## Type Operators
|
|
492
|
+
|
|
493
|
+
### Type Assert `:type`
|
|
494
|
+
|
|
495
|
+
Error if type doesn't match, returns value unchanged:
|
|
496
|
+
|
|
497
|
+
```rill
|
|
498
|
+
42:number # 42
|
|
499
|
+
"hello" -> :string # "hello"
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
```text
|
|
503
|
+
"hello" -> :number # ERROR: expected number, got string
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
### Type Check `:?type`
|
|
507
|
+
|
|
508
|
+
Returns boolean:
|
|
509
|
+
|
|
510
|
+
```rill
|
|
511
|
+
42:?number # true
|
|
512
|
+
"hello":?number # false
|
|
513
|
+
"hello" -> :?string # true
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
See [Types](02_types.md) for detailed type system documentation.
|
|
517
|
+
|
|
518
|
+
---
|
|
519
|
+
|
|
520
|
+
## Operator Precedence
|
|
521
|
+
|
|
522
|
+
From highest to lowest:
|
|
523
|
+
|
|
524
|
+
1. Member access: `.field`, `[index]`
|
|
525
|
+
2. Type operators: `:type`, `:?type`
|
|
526
|
+
3. Unary: `-`, `!`
|
|
527
|
+
4. Multiplicative: `*`, `/`, `%`
|
|
528
|
+
5. Additive: `+`, `-`
|
|
529
|
+
6. Comparison: `==`, `!=`, `<`, `>`, `<=`, `>=`
|
|
530
|
+
7. Logical AND: `&&`
|
|
531
|
+
8. Logical OR: `||`
|
|
532
|
+
9. Default: `??`
|
|
533
|
+
10. Pipe: `->`
|
|
534
|
+
11. Capture: `:>`
|
|
535
|
+
|
|
536
|
+
Use parentheses to override precedence:
|
|
537
|
+
|
|
538
|
+
```rill
|
|
539
|
+
(2 + 3) * 4 # 20
|
|
540
|
+
5 -> ($ > 3) ? "big" ! "small" # "big"
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
---
|
|
544
|
+
|
|
545
|
+
## See Also
|
|
546
|
+
|
|
547
|
+
- [Types](02_types.md) — Type system and assertions
|
|
548
|
+
- [Variables](03_variables.md) — Capture and scope
|
|
549
|
+
- [Control Flow](05_control-flow.md) — Conditionals and loops
|
|
550
|
+
- [Collections](07_collections.md) — Collection operators
|
|
551
|
+
- [Reference](11_reference.md) — Quick reference tables
|