@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
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* High-level compile API for Elo
|
|
3
|
+
*
|
|
4
|
+
* Compiles Elo expressions to callable JavaScript functions with
|
|
5
|
+
* runtime dependency injection.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Runtime dependencies that can be injected into compiled functions.
|
|
9
|
+
* All dependencies used by the JS compiler should be listed here.
|
|
10
|
+
*/
|
|
11
|
+
export interface EloRuntime {
|
|
12
|
+
DateTime?: unknown;
|
|
13
|
+
Duration?: unknown;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Options for the compile function
|
|
17
|
+
*/
|
|
18
|
+
export interface CompileOptions {
|
|
19
|
+
runtime?: EloRuntime;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Compiles an Elo expression to a callable JavaScript function.
|
|
23
|
+
*
|
|
24
|
+
* The expression should typically be a lambda, e.g.:
|
|
25
|
+
* compile('fn(x ~> x * 2)')
|
|
26
|
+
* compile('fn(x ~> x in SOW ... EOW)')
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* import { compile } from '@enspirit/elo';
|
|
31
|
+
* import { DateTime, Duration } from 'luxon';
|
|
32
|
+
*
|
|
33
|
+
* const double = compile<(x: number) => number>(
|
|
34
|
+
* 'fn(x ~> x * 2)',
|
|
35
|
+
* { runtime: { DateTime, Duration } }
|
|
36
|
+
* );
|
|
37
|
+
* double(21); // => 42
|
|
38
|
+
*
|
|
39
|
+
* const inThisWeek = compile<(x: Date) => boolean>(
|
|
40
|
+
* 'fn(x ~> x in SOW ... EOW)',
|
|
41
|
+
* { runtime: { DateTime, Duration } }
|
|
42
|
+
* );
|
|
43
|
+
* inThisWeek(new Date()); // => true or false
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function compile<T = unknown>(source: string, options?: CompileOptions): T;
|
|
47
|
+
//# sourceMappingURL=compile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/compile.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CAEpB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAQD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,OAAO,CAAC,CAAC,GAAG,OAAO,EACjC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,CAAC,CAgBH"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* High-level compile API for Elo
|
|
4
|
+
*
|
|
5
|
+
* Compiles Elo expressions to callable JavaScript functions with
|
|
6
|
+
* runtime dependency injection.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.compile = compile;
|
|
10
|
+
const parser_1 = require("./parser");
|
|
11
|
+
const javascript_1 = require("./compilers/javascript");
|
|
12
|
+
/**
|
|
13
|
+
* List of runtime dependency names to inject.
|
|
14
|
+
* Must match the keys in EloRuntime.
|
|
15
|
+
*/
|
|
16
|
+
const RUNTIME_DEPS = ['DateTime', 'Duration'];
|
|
17
|
+
/**
|
|
18
|
+
* Compiles an Elo expression to a callable JavaScript function.
|
|
19
|
+
*
|
|
20
|
+
* The expression should typically be a lambda, e.g.:
|
|
21
|
+
* compile('fn(x ~> x * 2)')
|
|
22
|
+
* compile('fn(x ~> x in SOW ... EOW)')
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* import { compile } from '@enspirit/elo';
|
|
27
|
+
* import { DateTime, Duration } from 'luxon';
|
|
28
|
+
*
|
|
29
|
+
* const double = compile<(x: number) => number>(
|
|
30
|
+
* 'fn(x ~> x * 2)',
|
|
31
|
+
* { runtime: { DateTime, Duration } }
|
|
32
|
+
* );
|
|
33
|
+
* double(21); // => 42
|
|
34
|
+
*
|
|
35
|
+
* const inThisWeek = compile<(x: Date) => boolean>(
|
|
36
|
+
* 'fn(x ~> x in SOW ... EOW)',
|
|
37
|
+
* { runtime: { DateTime, Duration } }
|
|
38
|
+
* );
|
|
39
|
+
* inThisWeek(new Date()); // => true or false
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
function compile(source, options) {
|
|
43
|
+
const ast = (0, parser_1.parse)(source);
|
|
44
|
+
const jsCode = (0, javascript_1.compileToJavaScript)(ast);
|
|
45
|
+
// Extract runtime dependencies
|
|
46
|
+
const runtime = options?.runtime ?? {};
|
|
47
|
+
// Build parameter list and argument list for dependency injection
|
|
48
|
+
const paramNames = RUNTIME_DEPS.join(', ');
|
|
49
|
+
const args = RUNTIME_DEPS.map(dep => runtime[dep]);
|
|
50
|
+
// Create a function that injects all dependencies into scope
|
|
51
|
+
// The compiled code is always a function taking _ as input, so call it with null
|
|
52
|
+
const factory = new Function(paramNames, `return (${jsCode})(null);`);
|
|
53
|
+
return factory(...args);
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=compile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/compile.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAqDH,0BAmBC;AAtED,qCAAiC;AACjC,uDAA6D;AAmB7D;;;GAGG;AACH,MAAM,YAAY,GAAG,CAAC,UAAU,EAAE,UAAU,CAAU,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,SAAgB,OAAO,CACrB,MAAc,EACd,OAAwB;IAExB,MAAM,GAAG,GAAG,IAAA,cAAK,EAAC,MAAM,CAAC,CAAC;IAC1B,MAAM,MAAM,GAAG,IAAA,gCAAmB,EAAC,GAAG,CAAC,CAAC;IAExC,+BAA+B;IAC/B,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC;IAEvC,kEAAkE;IAClE,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IAEnD,6DAA6D;IAC7D,iFAAiF;IACjF,MAAM,OAAO,GAAG,IAAI,QAAQ,CAAC,UAAU,EAAE,WAAW,MAAM,UAAU,CAAC,CAAC;IAEtE,OAAO,OAAO,CAAC,GAAG,IAAI,CAAM,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Expr } from '../ast';
|
|
2
|
+
/**
|
|
3
|
+
* JavaScript compilation options
|
|
4
|
+
*/
|
|
5
|
+
export interface JavaScriptCompileOptions {
|
|
6
|
+
/** If true, always wrap output as a function (even if _ is not used) */
|
|
7
|
+
asFunction?: boolean;
|
|
8
|
+
/** If true, immediately execute the function with null as input */
|
|
9
|
+
execute?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Result of JavaScript compilation
|
|
13
|
+
*/
|
|
14
|
+
export interface JavaScriptCompileResult {
|
|
15
|
+
/** The generated JavaScript code */
|
|
16
|
+
code: string;
|
|
17
|
+
/** Whether the code uses the input variable _ */
|
|
18
|
+
usesInput: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Compiles Elo expressions to JavaScript code
|
|
22
|
+
* Uses luxon for temporal operations
|
|
23
|
+
*
|
|
24
|
+
* This compiler works in two phases:
|
|
25
|
+
* 1. Transform AST to typed IR
|
|
26
|
+
* 2. Emit JavaScript from IR (tracking required helpers)
|
|
27
|
+
* 3. Wrap in IIFE with helper definitions if needed
|
|
28
|
+
*
|
|
29
|
+
* If the expression uses `_` (input variable), the output is a function
|
|
30
|
+
* that takes `_` as a parameter instead of an IIFE.
|
|
31
|
+
*/
|
|
32
|
+
export declare function compileToJavaScript(expr: Expr, options?: JavaScriptCompileOptions): string;
|
|
33
|
+
/**
|
|
34
|
+
* Compiles Elo expressions to JavaScript with metadata about input usage.
|
|
35
|
+
* Use this when you need to know if the expression uses input.
|
|
36
|
+
*
|
|
37
|
+
* Every Elo program compiles to a function taking _ as input parameter.
|
|
38
|
+
* The usesInput field indicates whether _ is actually referenced.
|
|
39
|
+
*/
|
|
40
|
+
export declare function compileToJavaScriptWithMeta(expr: Expr, options?: JavaScriptCompileOptions): JavaScriptCompileResult;
|
|
41
|
+
//# sourceMappingURL=javascript.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"javascript.d.ts","sourceRoot":"","sources":["../../../src/compilers/javascript.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAO9B;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,wEAAwE;IACxE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,SAAS,EAAE,OAAO,CAAC;CACpB;AAUD;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,wBAAwB,GAAG,MAAM,CAG1F;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,wBAAwB,GAAG,uBAAuB,CA6BnH"}
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.compileToJavaScript = compileToJavaScript;
|
|
4
|
+
exports.compileToJavaScriptWithMeta = compileToJavaScriptWithMeta;
|
|
5
|
+
const ir_1 = require("../ir");
|
|
6
|
+
const transform_1 = require("../transform");
|
|
7
|
+
const javascript_1 = require("../bindings/javascript");
|
|
8
|
+
const runtime_1 = require("../runtime");
|
|
9
|
+
/**
|
|
10
|
+
* Compiles Elo expressions to JavaScript code
|
|
11
|
+
* Uses luxon for temporal operations
|
|
12
|
+
*
|
|
13
|
+
* This compiler works in two phases:
|
|
14
|
+
* 1. Transform AST to typed IR
|
|
15
|
+
* 2. Emit JavaScript from IR (tracking required helpers)
|
|
16
|
+
* 3. Wrap in IIFE with helper definitions if needed
|
|
17
|
+
*
|
|
18
|
+
* If the expression uses `_` (input variable), the output is a function
|
|
19
|
+
* that takes `_` as a parameter instead of an IIFE.
|
|
20
|
+
*/
|
|
21
|
+
function compileToJavaScript(expr, options) {
|
|
22
|
+
const result = compileToJavaScriptWithMeta(expr, options);
|
|
23
|
+
return result.code;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Compiles Elo expressions to JavaScript with metadata about input usage.
|
|
27
|
+
* Use this when you need to know if the expression uses input.
|
|
28
|
+
*
|
|
29
|
+
* Every Elo program compiles to a function taking _ as input parameter.
|
|
30
|
+
* The usesInput field indicates whether _ is actually referenced.
|
|
31
|
+
*/
|
|
32
|
+
function compileToJavaScriptWithMeta(expr, options) {
|
|
33
|
+
const ir = (0, transform_1.transform)(expr);
|
|
34
|
+
const actuallyUsesInput = (0, ir_1.usesInput)(ir);
|
|
35
|
+
const result = emitJSWithHelpers(ir);
|
|
36
|
+
// Resolve helper dependencies
|
|
37
|
+
const allHelpers = new Set(result.requiredHelpers);
|
|
38
|
+
for (const helper of result.requiredHelpers) {
|
|
39
|
+
const deps = runtime_1.JS_HELPER_DEPS[helper];
|
|
40
|
+
if (deps) {
|
|
41
|
+
for (const dep of deps) {
|
|
42
|
+
allHelpers.add(dep);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Build helper definitions (sorted for deterministic output)
|
|
47
|
+
const helperDefs = Array.from(allHelpers)
|
|
48
|
+
.sort()
|
|
49
|
+
.map(name => runtime_1.JS_HELPERS[name].replace(/\n\s*/g, ' '))
|
|
50
|
+
.join(' ');
|
|
51
|
+
// Always wrap as a function taking _ as input parameter
|
|
52
|
+
// When execute is true, add (null) to call the function and ; to make it a statement
|
|
53
|
+
const suffix = options?.execute ? '(null);' : '';
|
|
54
|
+
if (result.requiredHelpers.size === 0) {
|
|
55
|
+
return { code: `(function(_) { return ${result.code}; })${suffix}`, usesInput: actuallyUsesInput };
|
|
56
|
+
}
|
|
57
|
+
return { code: `(function(_) { ${helperDefs} return ${result.code}; })${suffix}`, usesInput: actuallyUsesInput };
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Emit JavaScript with helper tracking
|
|
61
|
+
*/
|
|
62
|
+
function emitJSWithHelpers(ir) {
|
|
63
|
+
const requiredHelpers = new Set();
|
|
64
|
+
const code = emitJS(ir, requiredHelpers);
|
|
65
|
+
return { code, requiredHelpers };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* JavaScript operator precedence (higher = binds tighter)
|
|
69
|
+
*/
|
|
70
|
+
const JS_PRECEDENCE = {
|
|
71
|
+
'||': 1,
|
|
72
|
+
'&&': 2,
|
|
73
|
+
'==': 3, '!=': 3,
|
|
74
|
+
'<': 4, '>': 4, '<=': 4, '>=': 4,
|
|
75
|
+
'+': 5, '-': 5,
|
|
76
|
+
'*': 6, '/': 6, '%': 6,
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Map IR function names to JS operators for precedence checking
|
|
80
|
+
*/
|
|
81
|
+
const OP_MAP = {
|
|
82
|
+
'add': '+', 'sub': '-', 'mul': '*', 'div': '/', 'mod': '%',
|
|
83
|
+
'lt': '<', 'gt': '>', 'lte': '<=', 'gte': '>=',
|
|
84
|
+
'eq': '==', 'neq': '!=', 'and': '&&', 'or': '||',
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Check if an IR expression needs parentheses when used as child of a binary op
|
|
88
|
+
*/
|
|
89
|
+
function needsParens(child, parentOp, side) {
|
|
90
|
+
if (!(0, javascript_1.isNativeBinaryOp)(child))
|
|
91
|
+
return false;
|
|
92
|
+
const call = child;
|
|
93
|
+
const childOp = OP_MAP[call.fn];
|
|
94
|
+
if (!childOp)
|
|
95
|
+
return false;
|
|
96
|
+
const parentPrec = JS_PRECEDENCE[parentOp] || 0;
|
|
97
|
+
const childPrec = JS_PRECEDENCE[childOp] || 0;
|
|
98
|
+
if (childPrec < parentPrec)
|
|
99
|
+
return true;
|
|
100
|
+
if (childPrec === parentPrec && side === 'right')
|
|
101
|
+
return true;
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
// Create the JavaScript standard library binding
|
|
105
|
+
const jsLib = (0, javascript_1.createJavaScriptBinding)();
|
|
106
|
+
/**
|
|
107
|
+
* Emit JavaScript code from IR
|
|
108
|
+
*/
|
|
109
|
+
function emitJS(ir, requiredHelpers) {
|
|
110
|
+
const ctx = {
|
|
111
|
+
emit: (child) => emitJS(child, requiredHelpers),
|
|
112
|
+
emitWithParens: (child, parentOp, side) => {
|
|
113
|
+
const emitted = emitJS(child, requiredHelpers);
|
|
114
|
+
if (needsParens(child, parentOp, side)) {
|
|
115
|
+
return `(${emitted})`;
|
|
116
|
+
}
|
|
117
|
+
return emitted;
|
|
118
|
+
},
|
|
119
|
+
requireHelper: requiredHelpers ? (name) => requiredHelpers.add(name) : undefined,
|
|
120
|
+
};
|
|
121
|
+
switch (ir.type) {
|
|
122
|
+
case 'int_literal':
|
|
123
|
+
case 'float_literal':
|
|
124
|
+
return ir.value.toString();
|
|
125
|
+
case 'bool_literal':
|
|
126
|
+
return ir.value.toString();
|
|
127
|
+
case 'null_literal':
|
|
128
|
+
return 'null';
|
|
129
|
+
case 'string_literal':
|
|
130
|
+
return JSON.stringify(ir.value);
|
|
131
|
+
case 'date_literal':
|
|
132
|
+
return `DateTime.fromISO('${ir.value}')`;
|
|
133
|
+
case 'datetime_literal':
|
|
134
|
+
return `DateTime.fromISO('${ir.value}')`;
|
|
135
|
+
case 'duration_literal':
|
|
136
|
+
return `Duration.fromISO('${ir.value}')`;
|
|
137
|
+
case 'object_literal': {
|
|
138
|
+
const props = ir.properties.map(p => `${p.key}: ${ctx.emit(p.value)}`).join(', ');
|
|
139
|
+
// Wrap in parens to avoid parsing ambiguity with blocks
|
|
140
|
+
return `({${props}})`;
|
|
141
|
+
}
|
|
142
|
+
case 'array_literal': {
|
|
143
|
+
const elements = ir.elements.map(e => ctx.emit(e)).join(', ');
|
|
144
|
+
return `[${elements}]`;
|
|
145
|
+
}
|
|
146
|
+
case 'variable':
|
|
147
|
+
return ir.name;
|
|
148
|
+
case 'member_access': {
|
|
149
|
+
const object = ctx.emit(ir.object);
|
|
150
|
+
const needsParensForMember = ir.object.type === 'call';
|
|
151
|
+
const objectExpr = needsParensForMember ? `(${object})` : object;
|
|
152
|
+
return `${objectExpr}.${ir.property}`;
|
|
153
|
+
}
|
|
154
|
+
case 'let': {
|
|
155
|
+
// Collect consecutive let bindings, but stop if we encounter shadowing
|
|
156
|
+
const allBindings = [];
|
|
157
|
+
const seenNames = new Set();
|
|
158
|
+
let current = ir;
|
|
159
|
+
while (current.type === 'let') {
|
|
160
|
+
let hasShadowing = false;
|
|
161
|
+
for (const b of current.bindings) {
|
|
162
|
+
if (seenNames.has(b.name)) {
|
|
163
|
+
hasShadowing = true;
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (hasShadowing) {
|
|
168
|
+
// Stop flattening - emit nested IIFE for proper scoping
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
for (const b of current.bindings) {
|
|
172
|
+
seenNames.add(b.name);
|
|
173
|
+
allBindings.push({ name: b.name, value: ctx.emit(b.value) });
|
|
174
|
+
}
|
|
175
|
+
current = current.body;
|
|
176
|
+
}
|
|
177
|
+
const declarations = allBindings.map(b => `const ${b.name} = ${b.value};`).join(' ');
|
|
178
|
+
const body = ctx.emit(current);
|
|
179
|
+
return `(() => { ${declarations} return ${body}; })()`;
|
|
180
|
+
}
|
|
181
|
+
case 'call':
|
|
182
|
+
return jsLib.emit(ir.fn, ir.args, ir.argTypes, ctx);
|
|
183
|
+
case 'if': {
|
|
184
|
+
const cond = ctx.emit(ir.condition);
|
|
185
|
+
const thenBranch = ctx.emit(ir.then);
|
|
186
|
+
const elseBranch = ctx.emit(ir.else);
|
|
187
|
+
return `(${cond}) ? (${thenBranch}) : (${elseBranch})`;
|
|
188
|
+
}
|
|
189
|
+
case 'lambda': {
|
|
190
|
+
const params = ir.params.map(p => p.name).join(', ');
|
|
191
|
+
const body = ctx.emit(ir.body);
|
|
192
|
+
return `(${params}) => ${body}`;
|
|
193
|
+
}
|
|
194
|
+
case 'apply': {
|
|
195
|
+
const fn = ctx.emit(ir.fn);
|
|
196
|
+
const args = ir.args.map(a => ctx.emit(a)).join(', ');
|
|
197
|
+
// Wrap function in parens if it's a lambda expression
|
|
198
|
+
const needsParens = ir.fn.type === 'lambda';
|
|
199
|
+
const fnExpr = needsParens ? `(${fn})` : fn;
|
|
200
|
+
return `${fnExpr}(${args})`;
|
|
201
|
+
}
|
|
202
|
+
case 'alternative': {
|
|
203
|
+
// Compile to nullish coalescing chain: a ?? b ?? c
|
|
204
|
+
const alts = ir.alternatives.map(alt => {
|
|
205
|
+
const code = ctx.emit(alt);
|
|
206
|
+
// Wrap in parens if it's a complex expression
|
|
207
|
+
return alt.type === 'call' || alt.type === 'alternative' ? `(${code})` : code;
|
|
208
|
+
});
|
|
209
|
+
return alts.join(' ?? ');
|
|
210
|
+
}
|
|
211
|
+
case 'datapath': {
|
|
212
|
+
// Compile datapath as an array of segments
|
|
213
|
+
const segments = ir.segments.map(s => typeof s === 'string' ? JSON.stringify(s) : s.toString());
|
|
214
|
+
return `[${segments.join(', ')}]`;
|
|
215
|
+
}
|
|
216
|
+
case 'typedef': {
|
|
217
|
+
// Generate parser function for the type and bind it
|
|
218
|
+
// Wrap it so calling TypeName(value) auto-unwraps the result
|
|
219
|
+
const parserCode = emitTypeExprParser(ir.typeExpr, ctx);
|
|
220
|
+
ctx.requireHelper?.('pUnwrap');
|
|
221
|
+
const body = ctx.emit(ir.body);
|
|
222
|
+
// The type name becomes a function that calls the parser and unwraps
|
|
223
|
+
return `(() => { const _p_${ir.name} = ${parserCode}; const ${ir.name} = (v) => pUnwrap(_p_${ir.name}(v, '')); return ${body}; })()`;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Emit a parser function for a type expression
|
|
229
|
+
*/
|
|
230
|
+
function emitTypeExprParser(typeExpr, ctx) {
|
|
231
|
+
switch (typeExpr.kind) {
|
|
232
|
+
case 'type_ref': {
|
|
233
|
+
// Map type name to parser helper
|
|
234
|
+
const parserMap = {
|
|
235
|
+
'Any': 'pAny',
|
|
236
|
+
'String': 'pString',
|
|
237
|
+
'Int': 'pInt',
|
|
238
|
+
'Float': 'pFloat',
|
|
239
|
+
'Bool': 'pBool',
|
|
240
|
+
'Boolean': 'pBool',
|
|
241
|
+
'Datetime': 'pDatetime',
|
|
242
|
+
};
|
|
243
|
+
const parserName = parserMap[typeExpr.name];
|
|
244
|
+
if (parserName) {
|
|
245
|
+
ctx.requireHelper?.(parserName);
|
|
246
|
+
return parserName;
|
|
247
|
+
}
|
|
248
|
+
// Check if it's a user-defined type (uppercase identifier not in built-ins)
|
|
249
|
+
// User-defined types are referenced as _p_TypeName
|
|
250
|
+
const firstChar = typeExpr.name.charAt(0);
|
|
251
|
+
if (firstChar === firstChar.toUpperCase() && firstChar !== firstChar.toLowerCase()) {
|
|
252
|
+
return `_p_${typeExpr.name}`;
|
|
253
|
+
}
|
|
254
|
+
throw new Error(`Unknown type in type definition: ${typeExpr.name}`);
|
|
255
|
+
}
|
|
256
|
+
case 'type_schema': {
|
|
257
|
+
// Object schema: generate inline parser
|
|
258
|
+
ctx.requireHelper?.('pOk');
|
|
259
|
+
ctx.requireHelper?.('pFail');
|
|
260
|
+
const propParsers = typeExpr.properties.map(prop => {
|
|
261
|
+
const propParser = emitTypeExprParser(prop.typeExpr, ctx);
|
|
262
|
+
return { key: prop.key, parser: propParser, optional: prop.optional };
|
|
263
|
+
});
|
|
264
|
+
const knownKeys = typeExpr.properties.map(p => p.key);
|
|
265
|
+
// Generate object parser - wrap parser in parens to handle inline functions
|
|
266
|
+
const propChecks = propParsers.map(({ key, parser, optional }) => {
|
|
267
|
+
if (optional) {
|
|
268
|
+
// Optional: if value is null/undefined, skip attribute; otherwise parse
|
|
269
|
+
return `if (v.${key} != null) { const _r_${key} = (${parser})(v.${key}, p + '.${key}'); if (!_r_${key}.success) return pFail(p, null, [_r_${key}]); _o.${key} = _r_${key}.value; }`;
|
|
270
|
+
}
|
|
271
|
+
// Required: parse and fail if not successful
|
|
272
|
+
return `const _r_${key} = (${parser})(v.${key}, p + '.${key}'); if (!_r_${key}.success) return pFail(p, null, [_r_${key}]); _o.${key} = _r_${key}.value;`;
|
|
273
|
+
}).join(' ');
|
|
274
|
+
// Handle extras based on the extras mode
|
|
275
|
+
let extrasCheck;
|
|
276
|
+
if (typeExpr.extras === undefined || typeExpr.extras === 'closed') {
|
|
277
|
+
// Closed: fail if any extra keys exist
|
|
278
|
+
const knownKeysSet = JSON.stringify(knownKeys);
|
|
279
|
+
extrasCheck = `const _ks = ${knownKeysSet}; for (const _k in v) { if (!_ks.includes(_k)) return pFail(p + '.' + _k, 'unexpected attribute'); }`;
|
|
280
|
+
}
|
|
281
|
+
else if (typeExpr.extras === 'ignored') {
|
|
282
|
+
// Ignored: no check, extras are silently ignored
|
|
283
|
+
extrasCheck = '';
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
// Typed extras: parse each extra key with the given type
|
|
287
|
+
const extrasParser = emitTypeExprParser(typeExpr.extras, ctx);
|
|
288
|
+
const knownKeysSet = JSON.stringify(knownKeys);
|
|
289
|
+
extrasCheck = `const _ks = ${knownKeysSet}; const _ep = ${extrasParser}; for (const _k in v) { if (!_ks.includes(_k)) { const _re = _ep(v[_k], p + '.' + _k); if (!_re.success) return pFail(p, null, [_re]); _o[_k] = _re.value; } }`;
|
|
290
|
+
}
|
|
291
|
+
return `(v, p) => { if (typeof v !== 'object' || v === null) return pFail(p, 'expected object, got ' + (v === null ? 'Null' : typeof v)); const _o = {}; ${propChecks} ${extrasCheck} return pOk(_o, p); }`;
|
|
292
|
+
}
|
|
293
|
+
case 'subtype_constraint': {
|
|
294
|
+
// Subtype constraint: Int(i | i > 0)
|
|
295
|
+
// First parse with base type, then check constraint
|
|
296
|
+
ctx.requireHelper?.('pOk');
|
|
297
|
+
ctx.requireHelper?.('pFail');
|
|
298
|
+
const baseParser = emitTypeExprParser(typeExpr.baseType, ctx);
|
|
299
|
+
const constraintCode = ctx.emit(typeExpr.constraint);
|
|
300
|
+
const varName = typeExpr.variable;
|
|
301
|
+
return `(v, p) => { const _r = ${baseParser}(v, p); if (!_r.success) return _r; const ${varName} = _r.value; if (!(${constraintCode})) return pFail(p, 'constraint violated'); return _r; }`;
|
|
302
|
+
}
|
|
303
|
+
case 'array_type': {
|
|
304
|
+
// Array type: [Int]
|
|
305
|
+
// Parse each element with the element type
|
|
306
|
+
ctx.requireHelper?.('pOk');
|
|
307
|
+
ctx.requireHelper?.('pFail');
|
|
308
|
+
const elemParser = emitTypeExprParser(typeExpr.elementType, ctx);
|
|
309
|
+
// Store element parser in variable to handle inline functions (like object schemas)
|
|
310
|
+
return `(v, p) => { if (!Array.isArray(v)) return pFail(p, 'expected array, got ' + (v === null ? 'Null' : typeof v)); const _el = ${elemParser}; const _a = []; for (let _i = 0; _i < v.length; _i++) { const _r = _el(v[_i], p + '.' + _i); if (!_r.success) return pFail(p, null, [_r]); _a.push(_r.value); } return pOk(_a, p); }`;
|
|
311
|
+
}
|
|
312
|
+
case 'union_type': {
|
|
313
|
+
// Union type: Int|String
|
|
314
|
+
// Try each type in order, return first successful parse (PEG-style)
|
|
315
|
+
ctx.requireHelper?.('pFail');
|
|
316
|
+
const parsers = typeExpr.types.map(t => emitTypeExprParser(t, ctx));
|
|
317
|
+
// Generate tries: call each parser directly in order
|
|
318
|
+
const tries = parsers.map(p => `_r = (${p})(v, p); if (_r.success) return _r; _causes.push(_r);`).join(' ');
|
|
319
|
+
return `(v, p) => { let _r; const _causes = []; ${tries} return pFail(p, 'no union alternative matched', _causes); }`;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
//# sourceMappingURL=javascript.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"javascript.js","sourceRoot":"","sources":["../../../src/compilers/javascript.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Expr } from '../ast';
|
|
2
|
+
/**
|
|
3
|
+
* Ruby compilation options
|
|
4
|
+
*/
|
|
5
|
+
export interface RubyCompileOptions {
|
|
6
|
+
/** If true, always wrap output as a lambda (even if _ is not used) */
|
|
7
|
+
asFunction?: boolean;
|
|
8
|
+
/** If true, immediately execute the lambda with nil as input */
|
|
9
|
+
execute?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Result of Ruby compilation
|
|
13
|
+
*/
|
|
14
|
+
export interface RubyCompileResult {
|
|
15
|
+
/** The generated Ruby code */
|
|
16
|
+
code: string;
|
|
17
|
+
/** Whether the code uses the input variable _ */
|
|
18
|
+
usesInput: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Compiles Elo expressions to Ruby code
|
|
22
|
+
*
|
|
23
|
+
* This compiler works in two phases:
|
|
24
|
+
* 1. Transform AST to typed IR
|
|
25
|
+
* 2. Emit Ruby from IR (tracking required helpers)
|
|
26
|
+
* 3. Wrap with helper definitions if needed
|
|
27
|
+
*
|
|
28
|
+
* If the expression uses `_` (input variable), the output is a lambda
|
|
29
|
+
* that takes `_` as a parameter.
|
|
30
|
+
*/
|
|
31
|
+
export declare function compileToRuby(expr: Expr, options?: RubyCompileOptions): string;
|
|
32
|
+
/**
|
|
33
|
+
* Compiles Elo expressions to Ruby with metadata about input usage.
|
|
34
|
+
* Use this when you need to know if the expression uses input.
|
|
35
|
+
*
|
|
36
|
+
* Every Elo program compiles to a lambda taking _ as input parameter.
|
|
37
|
+
* The usesInput field indicates whether _ is actually referenced.
|
|
38
|
+
*/
|
|
39
|
+
export declare function compileToRubyWithMeta(expr: Expr, options?: RubyCompileOptions): RubyCompileResult;
|
|
40
|
+
//# sourceMappingURL=ruby.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruby.d.ts","sourceRoot":"","sources":["../../../src/compilers/ruby.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAO9B;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,sEAAsE;IACtE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gEAAgE;IAChE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,SAAS,EAAE,OAAO,CAAC;CACpB;AAoDD;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAG9E;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,iBAAiB,CA6BjG"}
|