@enspirit/elo 0.9.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 +322 -0
- package/bin/elo +2 -0
- package/bin/eloc +2 -0
- package/dist/src/ast.d.ts +309 -0
- package/dist/src/ast.d.ts.map +1 -0
- package/dist/src/ast.js +173 -0
- package/dist/src/ast.js.map +1 -0
- package/dist/src/bindings/javascript.d.ts +17 -0
- package/dist/src/bindings/javascript.d.ts.map +1 -0
- package/dist/src/bindings/javascript.js +350 -0
- package/dist/src/bindings/javascript.js.map +1 -0
- package/dist/src/bindings/ruby.d.ts +20 -0
- package/dist/src/bindings/ruby.d.ts.map +1 -0
- package/dist/src/bindings/ruby.js +365 -0
- package/dist/src/bindings/ruby.js.map +1 -0
- package/dist/src/bindings/sql.d.ts +20 -0
- package/dist/src/bindings/sql.d.ts.map +1 -0
- package/dist/src/bindings/sql.js +319 -0
- package/dist/src/bindings/sql.js.map +1 -0
- package/dist/src/cli.d.ts +3 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +225 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/compile.d.ts +47 -0
- package/dist/src/compile.d.ts.map +1 -0
- package/dist/src/compile.js +55 -0
- package/dist/src/compile.js.map +1 -0
- package/dist/src/compilers/javascript.d.ts +41 -0
- package/dist/src/compilers/javascript.d.ts.map +1 -0
- package/dist/src/compilers/javascript.js +323 -0
- package/dist/src/compilers/javascript.js.map +1 -0
- package/dist/src/compilers/ruby.d.ts +40 -0
- package/dist/src/compilers/ruby.d.ts.map +1 -0
- package/dist/src/compilers/ruby.js +326 -0
- package/dist/src/compilers/ruby.js.map +1 -0
- package/dist/src/compilers/sql.d.ts +37 -0
- package/dist/src/compilers/sql.d.ts.map +1 -0
- package/dist/src/compilers/sql.js +164 -0
- package/dist/src/compilers/sql.js.map +1 -0
- package/dist/src/elo.d.ts +3 -0
- package/dist/src/elo.d.ts.map +1 -0
- package/dist/src/elo.js +187 -0
- package/dist/src/elo.js.map +1 -0
- package/dist/src/eloc.d.ts +3 -0
- package/dist/src/eloc.d.ts.map +1 -0
- package/dist/src/eloc.js +232 -0
- package/dist/src/eloc.js.map +1 -0
- package/dist/src/eval.d.ts +3 -0
- package/dist/src/eval.d.ts.map +1 -0
- package/dist/src/eval.js +196 -0
- package/dist/src/eval.js.map +1 -0
- package/dist/src/index.d.ts +17 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +36 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/ir.d.ts +295 -0
- package/dist/src/ir.d.ts.map +1 -0
- package/dist/src/ir.js +224 -0
- package/dist/src/ir.js.map +1 -0
- package/dist/src/parser.d.ts +137 -0
- package/dist/src/parser.d.ts.map +1 -0
- package/dist/src/parser.js +1266 -0
- package/dist/src/parser.js.map +1 -0
- package/dist/src/preludes/index.d.ts +14 -0
- package/dist/src/preludes/index.d.ts.map +1 -0
- package/dist/src/preludes/index.js +27 -0
- package/dist/src/preludes/index.js.map +1 -0
- package/dist/src/runtime.d.ts +23 -0
- package/dist/src/runtime.d.ts.map +1 -0
- package/dist/src/runtime.js +326 -0
- package/dist/src/runtime.js.map +1 -0
- package/dist/src/stdlib.d.ts +121 -0
- package/dist/src/stdlib.d.ts.map +1 -0
- package/dist/src/stdlib.js +237 -0
- package/dist/src/stdlib.js.map +1 -0
- package/dist/src/transform.d.ts +38 -0
- package/dist/src/transform.d.ts.map +1 -0
- package/dist/src/transform.js +322 -0
- package/dist/src/transform.js.map +1 -0
- package/dist/src/typedefs.d.ts +50 -0
- package/dist/src/typedefs.d.ts.map +1 -0
- package/dist/src/typedefs.js +294 -0
- package/dist/src/typedefs.js.map +1 -0
- package/dist/src/types.d.ts +54 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +62 -0
- package/dist/src/types.js.map +1 -0
- package/package.json +66 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Bernard Lambeau
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# What is Elo ?
|
|
2
|
+
|
|
3
|
+
[](https://github.com/enspirit/elo/actions/workflows/ci.yml)
|
|
4
|
+
|
|
5
|
+
A simple, well-designed, portable and safe data expression language that
|
|
6
|
+
compiles to Ruby, Javascript and PostgreSQL.
|
|
7
|
+
|
|
8
|
+
**[Try Elo online](https://elo-lang.org/)** - Interactive playground and documentation
|
|
9
|
+
|
|
10
|
+
## Why ?
|
|
11
|
+
|
|
12
|
+
No-Code tools like Klaro Cards generally require an expression language for user
|
|
13
|
+
to manipulate data easily. This language must be :
|
|
14
|
+
|
|
15
|
+
- simple, because No-Code tools are used by non-tech people
|
|
16
|
+
- portable, because they are implemented in various frontend/backend/db technologies
|
|
17
|
+
- safe, because end-users writing code yield serious security issues
|
|
18
|
+
- well-designed, because there are too many ill-designed programming languages already
|
|
19
|
+
|
|
20
|
+
See also the Related work section below.
|
|
21
|
+
|
|
22
|
+
## Current Features
|
|
23
|
+
|
|
24
|
+
- **Arithmetic expressions** with scalars and variables
|
|
25
|
+
- **Boolean expressions** with comparison and logical operators
|
|
26
|
+
- **Temporal types** with dates, datetimes, and ISO8601 durations
|
|
27
|
+
- **Infix notation** (standard mathematical notation)
|
|
28
|
+
- **Arithmetic operators**: `+`, `-`, `*`, `/`, `%`, `^` (power, plus string repeat and array concat)
|
|
29
|
+
- **Comparison operators**: `<`, `>`, `<=`, `>=`, `==`, `!=`
|
|
30
|
+
- **Logical operators**: `&&`, `||`, `!`
|
|
31
|
+
- **Unary operators**: `-`, `+`, `!`
|
|
32
|
+
- **Pipe operator**: `|>` for function chaining (Elixir-style), parentheses optional
|
|
33
|
+
- **Alternative operator**: `|` for fallback chains (returns first defined value)
|
|
34
|
+
- **Type selectors**: `Int()`, `Float()`, `Bool()`, `Date()`, `Datetime()`, `Duration()`, `Data()` for parsing strings to typed values
|
|
35
|
+
- **Type definitions**: Finitio-like schema validation with `let Person = { name: String, age: Int } in data |> Person`
|
|
36
|
+
- **Lambdas**: `fn(x ~> x * 2)` or `x ~> x * 2` (sugar) for anonymous functions
|
|
37
|
+
- **Input variable**: `_` for accessing external data passed to expressions
|
|
38
|
+
- **Array iteration**: `map`, `filter`, `reduce`, `any`, `all` (JS/Ruby only)
|
|
39
|
+
- **List functions**: `reverse`, `join(list, separator)`, `split(string, separator)`
|
|
40
|
+
- **Literals**:
|
|
41
|
+
- Numbers: `42`, `3.14`
|
|
42
|
+
- Booleans: `true`, `false`
|
|
43
|
+
- Strings: `'hello'`
|
|
44
|
+
- Null: `null`
|
|
45
|
+
- Dates: `D2024-01-15`
|
|
46
|
+
- DateTimes: `D2024-01-15T10:30:00Z`
|
|
47
|
+
- Durations: `P1D`, `PT1H30M`, `P1Y2M3D` (ISO8601)
|
|
48
|
+
- Objects: `{name: 'Alice', age: 30}`
|
|
49
|
+
- Arrays: `[1, 2, 3]`, `['a', 'b']`, `[1, 'mixed', true, null]`
|
|
50
|
+
- DataPaths: `.x.y.z`, `.items.0.name` (for navigating data structures)
|
|
51
|
+
- **Data functions**: `fetch(data, .path)` for safe access with null handling, `patch(data, .path, value)` for immutable updates, `merge(a, b)` and `deepMerge(a, b)` for merging objects
|
|
52
|
+
- **Parentheses** for grouping
|
|
53
|
+
- **Multi-target compilation**:
|
|
54
|
+
- Ruby (using `**` for power, `&&`/`||`/`!` for boolean logic, `Date.parse()`, `DateTime.parse()`, `ActiveSupport::Duration.parse()`)
|
|
55
|
+
- JavaScript (using `Math.pow()` for power, `&&`/`||`/`!` for boolean logic, `new Date()`, `Duration.parse()`)
|
|
56
|
+
- PostgreSQL (using `POWER()` for power, `AND`/`OR`/`NOT` for boolean logic, `DATE`, `TIMESTAMP`, `INTERVAL` for temporals)
|
|
57
|
+
|
|
58
|
+
## Installation
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm install
|
|
62
|
+
npm run build
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Testing
|
|
66
|
+
|
|
67
|
+
Elo uses a comprehensive test suite that verifies:
|
|
68
|
+
- **Unit tests**: Parser, AST, and compiler components
|
|
69
|
+
- **Integration tests**: End-to-end compilation output
|
|
70
|
+
- **Acceptance tests**: Compiled code execution in real runtimes (Ruby, Node.js, PostgreSQL)
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm run test:unit
|
|
74
|
+
npm run test:integration
|
|
75
|
+
npm run test:acceptance
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Command Line Interface
|
|
79
|
+
|
|
80
|
+
Elo provides two CLI tools:
|
|
81
|
+
- `eloc` - The compiler (for developers integrating Elo into their products)
|
|
82
|
+
- `elo` - The evaluator (for quickly running Elo expressions)
|
|
83
|
+
|
|
84
|
+
### Compiler (eloc)
|
|
85
|
+
|
|
86
|
+
The compiler translates Elo expressions to Ruby, JavaScript, or SQL:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Compile expression to JavaScript (default)
|
|
90
|
+
./bin/eloc -e "2 + 3 * 4"
|
|
91
|
+
|
|
92
|
+
# Compile expression to Ruby
|
|
93
|
+
./bin/eloc -e "2 + 3 * 4" -t ruby
|
|
94
|
+
|
|
95
|
+
# Compile expression to SQL
|
|
96
|
+
./bin/eloc -e "2 + 3 * 4" -t sql
|
|
97
|
+
|
|
98
|
+
# Compile with prelude (includes required runtime libraries)
|
|
99
|
+
./bin/eloc -e "NOW + PT2H" -t ruby -p
|
|
100
|
+
|
|
101
|
+
# Output only the prelude (useful for bundling)
|
|
102
|
+
./bin/eloc --prelude-only -t js
|
|
103
|
+
|
|
104
|
+
# Compile from file (each line is compiled separately)
|
|
105
|
+
./bin/eloc input.elo -t ruby
|
|
106
|
+
|
|
107
|
+
# Compile to file
|
|
108
|
+
./bin/eloc -e "2 + 3" -t ruby -f output.rb
|
|
109
|
+
|
|
110
|
+
# Compile from stdin
|
|
111
|
+
echo "2 + 3 * 4" | ./bin/eloc -
|
|
112
|
+
cat input.elo | ./bin/eloc - -t ruby
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Options:
|
|
116
|
+
- `-e, --expression <expr>` - Expression to compile
|
|
117
|
+
- `-t, --target <lang>` - Target language: `ruby`, `js` (default), `sql`
|
|
118
|
+
- `-p, --prelude` - Include necessary library imports/requires
|
|
119
|
+
- `--prelude-only` - Output only the prelude (no expression needed)
|
|
120
|
+
- `-f, --file <path>` - Output to file instead of stdout
|
|
121
|
+
- `-h, --help` - Show help message
|
|
122
|
+
|
|
123
|
+
### Evaluator (elo)
|
|
124
|
+
|
|
125
|
+
The evaluator compiles to JavaScript and immediately evaluates the expression:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# Evaluate a simple expression
|
|
129
|
+
./bin/elo -e "2 + 3 * 4"
|
|
130
|
+
# Outputs: 14
|
|
131
|
+
|
|
132
|
+
# Evaluate with input data
|
|
133
|
+
./bin/elo -e "_.x + _.y" -d '{"x": 1, "y": 2}'
|
|
134
|
+
# Outputs: 3
|
|
135
|
+
|
|
136
|
+
# Evaluate with data from file
|
|
137
|
+
./bin/elo -e "_.name" -d @data.json
|
|
138
|
+
|
|
139
|
+
# Evaluate from .elo file
|
|
140
|
+
./bin/elo expressions.elo
|
|
141
|
+
|
|
142
|
+
# Pipe data through stdin
|
|
143
|
+
echo '{"x": 10}' | ./bin/elo -e "_.x * 2" --stdin
|
|
144
|
+
# Outputs: 20
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Options:
|
|
148
|
+
- `-e, --expression <expr>` - Expression to evaluate
|
|
149
|
+
- `-d, --data <json>` - JSON input data for `_` variable (or `@file` to read from file)
|
|
150
|
+
- `--stdin` - Read input data as JSON from stdin
|
|
151
|
+
- `-h, --help` - Show help message
|
|
152
|
+
|
|
153
|
+
## Using Elo in JavaScript/TypeScript
|
|
154
|
+
|
|
155
|
+
The simplest way to use Elo is with the `compile()` function, which creates a callable JavaScript function from an Elo lambda expression:
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
import { compile } from '@enspirit/elo';
|
|
159
|
+
import { DateTime, Duration } from 'luxon';
|
|
160
|
+
|
|
161
|
+
// Compile a lambda to a callable function
|
|
162
|
+
const double = compile<(x: number) => number>(
|
|
163
|
+
'fn(x ~> x * 2)',
|
|
164
|
+
{ runtime: { DateTime, Duration } }
|
|
165
|
+
);
|
|
166
|
+
double(21); // => 42
|
|
167
|
+
|
|
168
|
+
// Temporal expressions work too
|
|
169
|
+
const inThisWeek = compile<(d: unknown) => boolean>(
|
|
170
|
+
'fn(d ~> d in SOW ... EOW)',
|
|
171
|
+
{ runtime: { DateTime, Duration } }
|
|
172
|
+
);
|
|
173
|
+
inThisWeek(DateTime.now()); // => true or false
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
The `runtime` option injects dependencies (like `DateTime` and `Duration` from luxon) into the compiled function. This avoids global variables and keeps the compiled code portable.
|
|
177
|
+
|
|
178
|
+
## Lower-Level API
|
|
179
|
+
|
|
180
|
+
For more control, you can use the lower-level parsing and compilation functions:
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
import { parse, compileToRuby, compileToJavaScript, compileToSQL } from '@enspirit/elo';
|
|
184
|
+
|
|
185
|
+
// Parse an expression
|
|
186
|
+
const ast = parse(`
|
|
187
|
+
let
|
|
188
|
+
x = TODAY,
|
|
189
|
+
y = 3
|
|
190
|
+
in
|
|
191
|
+
assert(x + y * P1D == TODAY + P3D)
|
|
192
|
+
`);
|
|
193
|
+
|
|
194
|
+
// Compile to different targets
|
|
195
|
+
console.log(compileToRuby(ast));
|
|
196
|
+
console.log(compileToJavaScript(ast));
|
|
197
|
+
console.log(compileToSQL(ast));
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Programmatic AST Construction
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
import { binary, variable, literal } from './src';
|
|
204
|
+
|
|
205
|
+
// Build: (price * quantity) - discount
|
|
206
|
+
const ast = binary(
|
|
207
|
+
'-',
|
|
208
|
+
binary('*', variable('price'), variable('quantity')),
|
|
209
|
+
variable('discount')
|
|
210
|
+
);
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Examples
|
|
214
|
+
|
|
215
|
+
Run the examples:
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
npm run build
|
|
219
|
+
node dist/examples/basic.js # Arithmetic expressions
|
|
220
|
+
node dist/examples/boolean.js # Boolean expressions
|
|
221
|
+
node dist/examples/temporal.js # Temporal expressions (dates, durations)
|
|
222
|
+
node dist/examples/demo.js # Quick demo
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Project Structure
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
elo/
|
|
229
|
+
├── src/ # Compiler source code
|
|
230
|
+
│ ├── parser.ts # Lexer and parser
|
|
231
|
+
│ ├── ast.ts # AST definitions
|
|
232
|
+
│ ├── types.ts # Type system
|
|
233
|
+
│ ├── ir.ts # Intermediate representation
|
|
234
|
+
│ ├── transform.ts # AST → IR transformation with type inference
|
|
235
|
+
│ ├── stdlib.ts # Standard library abstraction
|
|
236
|
+
│ ├── compilers/ # Code generators (Ruby, JavaScript, SQL)
|
|
237
|
+
│ └── preludes/ # Runtime support libraries
|
|
238
|
+
├── test/ # Test suite
|
|
239
|
+
│ ├── fixtures/ # Test cases
|
|
240
|
+
│ ├── unit/ # Component tests
|
|
241
|
+
│ ├── integration/ # Compilation tests
|
|
242
|
+
│ └── acceptance/ # Runtime execution tests
|
|
243
|
+
├── examples/ # Usage examples
|
|
244
|
+
├── bin/eloc # Compiler CLI
|
|
245
|
+
├── bin/elo # Evaluator CLI
|
|
246
|
+
└── CLAUDE.md # Developer guide
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
For detailed architecture documentation, see [CLAUDE.md](CLAUDE.md).
|
|
250
|
+
|
|
251
|
+
## Related work
|
|
252
|
+
|
|
253
|
+
Enspirit's previous research work includes a lot of places where such expressions
|
|
254
|
+
are used, calling for a shared solution for the future.
|
|
255
|
+
|
|
256
|
+
In many cases, observe that we require compiling expressions that amount to a
|
|
257
|
+
single function evaluating on a context object, sometimes a scalar (Finitio),
|
|
258
|
+
sometimes a current Tuple (Bmg), sometimes json data received from an API
|
|
259
|
+
(Webspicy), or a current Card (Klaro Cards, similar to Bmg's Tuple).
|
|
260
|
+
|
|
261
|
+
See https://elo-lang.org for more documentation.
|
|
262
|
+
|
|
263
|
+
### Finitio
|
|
264
|
+
|
|
265
|
+
The Finitio data validation language supports subtypes by constraints such as:
|
|
266
|
+
|
|
267
|
+
```finitio
|
|
268
|
+
PositiveInt = Int( i | i > 0 )
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Currently, the constraint expression is written in the host language (js or ruby)
|
|
272
|
+
and would require a portable expression language to go further.
|
|
273
|
+
|
|
274
|
+
See https://finitio.io, https://github.com/enspirit/finitio-rb, https://github.com/enspirit/finitio.js
|
|
275
|
+
|
|
276
|
+
### Bmg
|
|
277
|
+
|
|
278
|
+
The Bmg relational algebra requires expressions for the `restrict` and `extend`
|
|
279
|
+
operators inspired by **Tutorial D**. We currently rely on ruby code in some cases,
|
|
280
|
+
but that prevents compiling relational expressions to SQL :
|
|
281
|
+
|
|
282
|
+
```ruby
|
|
283
|
+
r.restrict(->(t){ t[:budget] >= 120 })
|
|
284
|
+
r.extend(:upcased => ->(t) { t[:name].upcase })
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
See https://www.relational-algebra.dev/, https://github.com/enspirit/bmg
|
|
288
|
+
|
|
289
|
+
### Webspicy
|
|
290
|
+
|
|
291
|
+
The Webspicy test framework requires a better expression language for data assertions.
|
|
292
|
+
We currently rely on an hardcoded expression language that is very limited:
|
|
293
|
+
|
|
294
|
+
```
|
|
295
|
+
assert:
|
|
296
|
+
- isEmpty
|
|
297
|
+
- size(10)
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
See https://github.com/enspirit/webspicy
|
|
301
|
+
|
|
302
|
+
### Klaro Cards
|
|
303
|
+
|
|
304
|
+
The Klaro Cards No-Code tool uses various data expressions here and there :
|
|
305
|
+
|
|
306
|
+
- Date ranges for Date/time dimensions : `SOW ... SOW+P1W`
|
|
307
|
+
- Computed dimensions : `_.budget * 1.21`
|
|
308
|
+
- Summary functions : `min(_.budget)`
|
|
309
|
+
|
|
310
|
+
See https://klaro.cards
|
|
311
|
+
|
|
312
|
+
## Contributing
|
|
313
|
+
|
|
314
|
+
Elo follows a strict test-driven development methodology to ensure semantic equivalence across all three target languages (Ruby, JavaScript, SQL).
|
|
315
|
+
|
|
316
|
+
**For developers and AI assistants**: See [CLAUDE.md](CLAUDE.md) for:
|
|
317
|
+
- Test-driven development workflow
|
|
318
|
+
- Three-stage test methodology (unit → integration → acceptance)
|
|
319
|
+
- How to add new features and operators
|
|
320
|
+
- Architecture documentation
|
|
321
|
+
- Troubleshooting guide
|
|
322
|
+
|
package/bin/elo
ADDED
package/bin/eloc
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AST node types for Elo expressions
|
|
3
|
+
*/
|
|
4
|
+
export type Expr = Literal | NullLiteral | StringLiteral | Variable | BinaryOp | UnaryOp | DateLiteral | DateTimeLiteral | DurationLiteral | TemporalKeyword | FunctionCall | MemberAccess | LetExpr | IfExpr | Lambda | ObjectLiteral | ArrayLiteral | Alternative | Apply | DataPath | TypeDef;
|
|
5
|
+
/**
|
|
6
|
+
* Literal value (number or boolean)
|
|
7
|
+
*/
|
|
8
|
+
export interface Literal {
|
|
9
|
+
type: 'literal';
|
|
10
|
+
value: number | boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Null literal
|
|
14
|
+
*/
|
|
15
|
+
export interface NullLiteral {
|
|
16
|
+
type: 'null';
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* String literal (single-quoted)
|
|
20
|
+
*/
|
|
21
|
+
export interface StringLiteral {
|
|
22
|
+
type: 'string';
|
|
23
|
+
value: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Date literal (ISO8601 date string)
|
|
27
|
+
*/
|
|
28
|
+
export interface DateLiteral {
|
|
29
|
+
type: 'date';
|
|
30
|
+
value: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* DateTime literal (ISO8601 datetime string)
|
|
34
|
+
*/
|
|
35
|
+
export interface DateTimeLiteral {
|
|
36
|
+
type: 'datetime';
|
|
37
|
+
value: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Duration literal (ISO8601 duration)
|
|
41
|
+
*/
|
|
42
|
+
export interface DurationLiteral {
|
|
43
|
+
type: 'duration';
|
|
44
|
+
value: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Temporal keyword (NOW, TODAY, TOMORROW, YESTERDAY, and period boundaries)
|
|
48
|
+
*/
|
|
49
|
+
export interface TemporalKeyword {
|
|
50
|
+
type: 'temporal_keyword';
|
|
51
|
+
keyword: 'NOW' | 'TODAY' | 'TOMORROW' | 'YESTERDAY' | 'SOD' | 'EOD' | 'SOW' | 'EOW' | 'SOM' | 'EOM' | 'SOQ' | 'EOQ' | 'SOY' | 'EOY' | 'BOT' | 'EOT';
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Variable reference
|
|
55
|
+
*/
|
|
56
|
+
export interface Variable {
|
|
57
|
+
type: 'variable';
|
|
58
|
+
name: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Binary operation
|
|
62
|
+
*/
|
|
63
|
+
export interface BinaryOp {
|
|
64
|
+
type: 'binary';
|
|
65
|
+
operator: '+' | '-' | '*' | '/' | '%' | '^' | '<' | '>' | '<=' | '>=' | '==' | '!=' | '&&' | '||';
|
|
66
|
+
left: Expr;
|
|
67
|
+
right: Expr;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Unary operation
|
|
71
|
+
*/
|
|
72
|
+
export interface UnaryOp {
|
|
73
|
+
type: 'unary';
|
|
74
|
+
operator: '-' | '+' | '!';
|
|
75
|
+
operand: Expr;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Function call
|
|
79
|
+
*/
|
|
80
|
+
export interface FunctionCall {
|
|
81
|
+
type: 'function_call';
|
|
82
|
+
name: string;
|
|
83
|
+
args: Expr[];
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Function application (calling an expression that evaluates to a function)
|
|
87
|
+
*/
|
|
88
|
+
export interface Apply {
|
|
89
|
+
type: 'apply';
|
|
90
|
+
fn: Expr;
|
|
91
|
+
args: Expr[];
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Member access (dot notation)
|
|
95
|
+
*/
|
|
96
|
+
export interface MemberAccess {
|
|
97
|
+
type: 'member_access';
|
|
98
|
+
object: Expr;
|
|
99
|
+
property: string;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Variable binding in a let expression
|
|
103
|
+
*/
|
|
104
|
+
export interface LetBinding {
|
|
105
|
+
name: string;
|
|
106
|
+
value: Expr;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Let expression: let x = 1, y = 2 in body
|
|
110
|
+
*/
|
|
111
|
+
export interface LetExpr {
|
|
112
|
+
type: 'let';
|
|
113
|
+
bindings: LetBinding[];
|
|
114
|
+
body: Expr;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* If expression: if condition then consequent else alternative
|
|
118
|
+
*/
|
|
119
|
+
export interface IfExpr {
|
|
120
|
+
type: 'if';
|
|
121
|
+
condition: Expr;
|
|
122
|
+
then: Expr;
|
|
123
|
+
else: Expr;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Lambda expression: fn( params ~> body )
|
|
127
|
+
*/
|
|
128
|
+
export interface Lambda {
|
|
129
|
+
type: 'lambda';
|
|
130
|
+
params: string[];
|
|
131
|
+
body: Expr;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Helper functions to create AST nodes
|
|
135
|
+
*/
|
|
136
|
+
export declare function literal(value: number | boolean): Literal;
|
|
137
|
+
export declare function nullLiteral(): NullLiteral;
|
|
138
|
+
export declare function stringLiteral(value: string): StringLiteral;
|
|
139
|
+
export declare function dateLiteral(value: string): DateLiteral;
|
|
140
|
+
export declare function dateTimeLiteral(value: string): DateTimeLiteral;
|
|
141
|
+
export declare function durationLiteral(value: string): DurationLiteral;
|
|
142
|
+
export declare function variable(name: string): Variable;
|
|
143
|
+
export declare function binary(operator: BinaryOp['operator'], left: Expr, right: Expr): BinaryOp;
|
|
144
|
+
export declare function unary(operator: UnaryOp['operator'], operand: Expr): UnaryOp;
|
|
145
|
+
export declare function temporalKeyword(keyword: TemporalKeyword['keyword']): TemporalKeyword;
|
|
146
|
+
export declare function functionCall(name: string, args: Expr[]): FunctionCall;
|
|
147
|
+
export declare function apply(fn: Expr, args: Expr[]): Apply;
|
|
148
|
+
export declare function memberAccess(object: Expr, property: string): MemberAccess;
|
|
149
|
+
/**
|
|
150
|
+
* Creates a let expression, desugaring multiple bindings into nested let expressions.
|
|
151
|
+
* `let a = 1, b = 2 in body` becomes `let a = 1 in let b = 2 in body`
|
|
152
|
+
* This ensures that later bindings can reference earlier ones.
|
|
153
|
+
*/
|
|
154
|
+
export declare function letExpr(bindings: LetBinding[], body: Expr): LetExpr;
|
|
155
|
+
/**
|
|
156
|
+
* Creates an if expression: if condition then consequent else alternative
|
|
157
|
+
*/
|
|
158
|
+
export declare function ifExpr(condition: Expr, thenBranch: Expr, elseBranch: Expr): IfExpr;
|
|
159
|
+
/**
|
|
160
|
+
* Creates a lambda expression: fn( params ~> body )
|
|
161
|
+
*/
|
|
162
|
+
export declare function lambda(params: string[], body: Expr): Lambda;
|
|
163
|
+
/**
|
|
164
|
+
* Object property (key-value pair)
|
|
165
|
+
*/
|
|
166
|
+
export interface ObjectProperty {
|
|
167
|
+
key: string;
|
|
168
|
+
value: Expr;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Object literal: {key: value, ...}
|
|
172
|
+
*/
|
|
173
|
+
export interface ObjectLiteral {
|
|
174
|
+
type: 'object';
|
|
175
|
+
properties: ObjectProperty[];
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Creates an object literal: {key: value, ...}
|
|
179
|
+
*/
|
|
180
|
+
export declare function objectLiteral(properties: ObjectProperty[]): ObjectLiteral;
|
|
181
|
+
/**
|
|
182
|
+
* Array literal: [expr, expr, ...]
|
|
183
|
+
*/
|
|
184
|
+
export interface ArrayLiteral {
|
|
185
|
+
type: 'array';
|
|
186
|
+
elements: Expr[];
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Creates an array literal: [expr, expr, ...]
|
|
190
|
+
*/
|
|
191
|
+
export declare function arrayLiteral(elements: Expr[]): ArrayLiteral;
|
|
192
|
+
/**
|
|
193
|
+
* Alternative expression: a | b | c
|
|
194
|
+
* Evaluates alternatives left-to-right, returns first non-null value.
|
|
195
|
+
*/
|
|
196
|
+
export interface Alternative {
|
|
197
|
+
type: 'alternative';
|
|
198
|
+
alternatives: Expr[];
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Creates an alternative expression: a | b | c
|
|
202
|
+
*/
|
|
203
|
+
export declare function alternative(alternatives: Expr[]): Alternative;
|
|
204
|
+
/**
|
|
205
|
+
* DataPath literal: .x.y.z or .items.0.name
|
|
206
|
+
* A path for navigating data structures, inspired by JSONPath.
|
|
207
|
+
* Segments can be property names (strings) or array indices (numbers).
|
|
208
|
+
*/
|
|
209
|
+
export interface DataPath {
|
|
210
|
+
type: 'datapath';
|
|
211
|
+
segments: (string | number)[];
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Creates a datapath literal: .x.y.z
|
|
215
|
+
*/
|
|
216
|
+
export declare function dataPath(segments: (string | number)[]): DataPath;
|
|
217
|
+
/**
|
|
218
|
+
* Type expression for type definitions
|
|
219
|
+
* Used in `let Person = { name: String, age: Int }` style declarations
|
|
220
|
+
*/
|
|
221
|
+
export type TypeExpr = TypeRef | TypeSchema | SubtypeConstraint | ArrayType | UnionType;
|
|
222
|
+
/**
|
|
223
|
+
* Reference to a base type: String, Int, Bool, Datetime, Any
|
|
224
|
+
*/
|
|
225
|
+
export interface TypeRef {
|
|
226
|
+
kind: 'type_ref';
|
|
227
|
+
name: string;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Object type schema: { name: String, age: Int }
|
|
231
|
+
* extras controls handling of extra attributes:
|
|
232
|
+
* - undefined/'closed': extra attributes are not allowed (default)
|
|
233
|
+
* - 'ignored': extra attributes are allowed but not included in output
|
|
234
|
+
* - TypeExpr: extra attributes are allowed and must match this type
|
|
235
|
+
*/
|
|
236
|
+
export interface TypeSchema {
|
|
237
|
+
kind: 'type_schema';
|
|
238
|
+
properties: TypeSchemaProperty[];
|
|
239
|
+
extras?: 'closed' | 'ignored' | TypeExpr;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Subtype constraint: Int(i | i > 0)
|
|
243
|
+
* A base type with a predicate constraint
|
|
244
|
+
*/
|
|
245
|
+
export interface SubtypeConstraint {
|
|
246
|
+
kind: 'subtype_constraint';
|
|
247
|
+
baseType: TypeExpr;
|
|
248
|
+
variable: string;
|
|
249
|
+
constraint: Expr;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Array type: [Int], [String], [{ name: String }]
|
|
253
|
+
*/
|
|
254
|
+
export interface ArrayType {
|
|
255
|
+
kind: 'array_type';
|
|
256
|
+
elementType: TypeExpr;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Union type: Int|String, String|Int|Bool
|
|
260
|
+
* Tries each type in order, returns first successful parse
|
|
261
|
+
*/
|
|
262
|
+
export interface UnionType {
|
|
263
|
+
kind: 'union_type';
|
|
264
|
+
types: TypeExpr[];
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Property in a type schema
|
|
268
|
+
*/
|
|
269
|
+
export interface TypeSchemaProperty {
|
|
270
|
+
key: string;
|
|
271
|
+
typeExpr: TypeExpr;
|
|
272
|
+
optional?: boolean;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Type definition: let Person = { name: String, age: Int }
|
|
276
|
+
* Binds a type name (uppercase) to a type expression.
|
|
277
|
+
* The body can use the type via pipe: data |> Person
|
|
278
|
+
*/
|
|
279
|
+
export interface TypeDef {
|
|
280
|
+
type: 'typedef';
|
|
281
|
+
name: string;
|
|
282
|
+
typeExpr: TypeExpr;
|
|
283
|
+
body: Expr;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Creates a type reference: String, Int, etc.
|
|
287
|
+
*/
|
|
288
|
+
export declare function typeRef(name: string): TypeRef;
|
|
289
|
+
/**
|
|
290
|
+
* Creates a type schema: { name: String, age: Int }
|
|
291
|
+
*/
|
|
292
|
+
export declare function typeSchema(properties: TypeSchemaProperty[], extras?: 'closed' | 'ignored' | TypeExpr): TypeSchema;
|
|
293
|
+
/**
|
|
294
|
+
* Creates a type definition expression
|
|
295
|
+
*/
|
|
296
|
+
export declare function typeDef(name: string, typeExpr: TypeExpr, body: Expr): TypeDef;
|
|
297
|
+
/**
|
|
298
|
+
* Creates a subtype constraint: Int(i | i > 0)
|
|
299
|
+
*/
|
|
300
|
+
export declare function subtypeConstraint(baseType: TypeExpr, variable: string, constraint: Expr): SubtypeConstraint;
|
|
301
|
+
/**
|
|
302
|
+
* Creates an array type: [Int]
|
|
303
|
+
*/
|
|
304
|
+
export declare function arrayType(elementType: TypeExpr): ArrayType;
|
|
305
|
+
/**
|
|
306
|
+
* Creates a union type: Int|String
|
|
307
|
+
*/
|
|
308
|
+
export declare function unionType(types: TypeExpr[]): UnionType;
|
|
309
|
+
//# sourceMappingURL=ast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":"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"}
|