@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/dist/src/elo.js
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const parser_1 = require("./parser");
|
|
6
|
+
const javascript_1 = require("./compilers/javascript");
|
|
7
|
+
const luxon_1 = require("luxon");
|
|
8
|
+
function parseArgs(args) {
|
|
9
|
+
const options = {};
|
|
10
|
+
for (let i = 0; i < args.length; i++) {
|
|
11
|
+
const arg = args[i];
|
|
12
|
+
switch (arg) {
|
|
13
|
+
case '-e':
|
|
14
|
+
case '--expression':
|
|
15
|
+
options.expression = args[++i];
|
|
16
|
+
break;
|
|
17
|
+
case '-d':
|
|
18
|
+
case '--data':
|
|
19
|
+
options.inputData = args[++i];
|
|
20
|
+
break;
|
|
21
|
+
case '--stdin':
|
|
22
|
+
options.stdinData = true;
|
|
23
|
+
break;
|
|
24
|
+
case '-h':
|
|
25
|
+
case '--help':
|
|
26
|
+
printHelp();
|
|
27
|
+
process.exit(0);
|
|
28
|
+
break;
|
|
29
|
+
case '-':
|
|
30
|
+
// Read expression from stdin
|
|
31
|
+
options.inputFile = '-';
|
|
32
|
+
break;
|
|
33
|
+
default:
|
|
34
|
+
// If it doesn't start with -, treat it as input file
|
|
35
|
+
if (!arg.startsWith('-') && !options.inputFile && !options.expression) {
|
|
36
|
+
options.inputFile = arg;
|
|
37
|
+
}
|
|
38
|
+
else if (!arg.startsWith('-')) {
|
|
39
|
+
console.error(`Unknown argument: ${arg}`);
|
|
40
|
+
printHelp();
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return options;
|
|
46
|
+
}
|
|
47
|
+
function printHelp() {
|
|
48
|
+
console.log(`
|
|
49
|
+
Elo Evaluator (elo) - Evaluate Elo expressions
|
|
50
|
+
|
|
51
|
+
Usage:
|
|
52
|
+
elo [options] [input-file]
|
|
53
|
+
|
|
54
|
+
Options:
|
|
55
|
+
-e, --expression <expr> Expression to evaluate (like ruby -e)
|
|
56
|
+
-d, --data <json> JSON input data for _ variable (or @file to read from file)
|
|
57
|
+
--stdin Read input data as JSON from stdin
|
|
58
|
+
-h, --help Show this help message
|
|
59
|
+
|
|
60
|
+
Examples:
|
|
61
|
+
# Evaluate a simple expression
|
|
62
|
+
elo -e "2 + 3 * 4"
|
|
63
|
+
|
|
64
|
+
# Evaluate with input data
|
|
65
|
+
elo -e "_.x + _.y" -d '{"x": 1, "y": 2}'
|
|
66
|
+
|
|
67
|
+
# Evaluate with input data from file
|
|
68
|
+
elo -e "_.name" -d @data.json
|
|
69
|
+
|
|
70
|
+
# Evaluate from .elo file
|
|
71
|
+
elo expressions.elo
|
|
72
|
+
|
|
73
|
+
# Pipe data through stdin
|
|
74
|
+
echo '{"x": 10}' | elo -e "_.x * 2" --stdin
|
|
75
|
+
|
|
76
|
+
# Read expression from stdin
|
|
77
|
+
echo "2 + 3" | elo -
|
|
78
|
+
`);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Parse input data from CLI option (JSON string or @file path)
|
|
82
|
+
*/
|
|
83
|
+
function parseInputData(inputData) {
|
|
84
|
+
let jsonString = inputData;
|
|
85
|
+
// If starts with @, read from file
|
|
86
|
+
if (inputData.startsWith('@')) {
|
|
87
|
+
const filePath = inputData.slice(1);
|
|
88
|
+
try {
|
|
89
|
+
jsonString = (0, fs_1.readFileSync)(filePath, 'utf-8');
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
console.error(`Error reading input file ${filePath}: ${error}`);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
return JSON.parse(jsonString);
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
console.error(`Error parsing input JSON: ${error}`);
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Compile and evaluate a single Elo expression
|
|
106
|
+
*/
|
|
107
|
+
function evaluate(source, inputValue) {
|
|
108
|
+
const ast = (0, parser_1.parse)(source);
|
|
109
|
+
const result = (0, javascript_1.compileToJavaScriptWithMeta)(ast);
|
|
110
|
+
// Create function with luxon DateTime and Duration in scope
|
|
111
|
+
// The compiled code is always a function that takes _ as input
|
|
112
|
+
const execFn = new Function('DateTime', 'Duration', `return ${result.code}`);
|
|
113
|
+
const fn = execFn(luxon_1.DateTime, luxon_1.Duration);
|
|
114
|
+
return fn(inputValue);
|
|
115
|
+
}
|
|
116
|
+
function main() {
|
|
117
|
+
const args = process.argv.slice(2);
|
|
118
|
+
if (args.length === 0) {
|
|
119
|
+
printHelp();
|
|
120
|
+
process.exit(0);
|
|
121
|
+
}
|
|
122
|
+
const options = parseArgs(args);
|
|
123
|
+
// Get the source expression(s)
|
|
124
|
+
let sources;
|
|
125
|
+
if (options.expression) {
|
|
126
|
+
sources = [options.expression];
|
|
127
|
+
}
|
|
128
|
+
else if (options.inputFile) {
|
|
129
|
+
try {
|
|
130
|
+
// Use file descriptor 0 for stdin when input is '-'
|
|
131
|
+
const content = options.inputFile === '-'
|
|
132
|
+
? (0, fs_1.readFileSync)(0, 'utf-8')
|
|
133
|
+
: (0, fs_1.readFileSync)(options.inputFile, 'utf-8');
|
|
134
|
+
// Split into lines - keep all lines but mark empty/comment lines as null
|
|
135
|
+
sources = content.split('\n').map(line => {
|
|
136
|
+
const trimmed = line.trim();
|
|
137
|
+
return (trimmed === '' || trimmed.startsWith('#')) ? '' : line;
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
console.error(`Error reading ${options.inputFile === '-' ? 'stdin' : `file ${options.inputFile}`}: ${error}`);
|
|
142
|
+
process.exit(1);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
console.error('Error: Must provide either -e <expression>, an input file, or - for stdin');
|
|
147
|
+
printHelp();
|
|
148
|
+
process.exit(1);
|
|
149
|
+
}
|
|
150
|
+
// Get input data
|
|
151
|
+
let inputValue = null;
|
|
152
|
+
if (options.stdinData) {
|
|
153
|
+
try {
|
|
154
|
+
const stdinContent = (0, fs_1.readFileSync)(0, 'utf-8');
|
|
155
|
+
inputValue = JSON.parse(stdinContent);
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
console.error(`Error reading/parsing stdin: ${error}`);
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else if (options.inputData) {
|
|
163
|
+
inputValue = parseInputData(options.inputData);
|
|
164
|
+
}
|
|
165
|
+
// Evaluate each expression
|
|
166
|
+
const outputs = [];
|
|
167
|
+
for (let i = 0; i < sources.length; i++) {
|
|
168
|
+
const source = sources[i];
|
|
169
|
+
const trimmed = source.trim();
|
|
170
|
+
// Skip empty lines and comments
|
|
171
|
+
if (trimmed === '' || trimmed.startsWith('#')) {
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
try {
|
|
175
|
+
const result = evaluate(trimmed, inputValue);
|
|
176
|
+
outputs.push(JSON.stringify(result));
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
console.error(`Error on line ${i + 1}: ${error}`);
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// Output results
|
|
184
|
+
console.log(outputs.join('\n'));
|
|
185
|
+
}
|
|
186
|
+
main();
|
|
187
|
+
//# sourceMappingURL=elo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elo.js","sourceRoot":"","sources":["../../src/elo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eloc.d.ts","sourceRoot":"","sources":["../../src/eloc.ts"],"names":[],"mappings":""}
|
package/dist/src/eloc.js
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const parser_1 = require("./parser");
|
|
6
|
+
const ruby_1 = require("./compilers/ruby");
|
|
7
|
+
const javascript_1 = require("./compilers/javascript");
|
|
8
|
+
const sql_1 = require("./compilers/sql");
|
|
9
|
+
const preludes_1 = require("./preludes");
|
|
10
|
+
// Map CLI target names to prelude target names
|
|
11
|
+
function toPreludeTarget(target) {
|
|
12
|
+
return target === 'js' ? 'javascript' : target;
|
|
13
|
+
}
|
|
14
|
+
function parseArgs(args) {
|
|
15
|
+
const options = {
|
|
16
|
+
target: 'js' // default target
|
|
17
|
+
};
|
|
18
|
+
for (let i = 0; i < args.length; i++) {
|
|
19
|
+
const arg = args[i];
|
|
20
|
+
switch (arg) {
|
|
21
|
+
case '-e':
|
|
22
|
+
case '--expression':
|
|
23
|
+
options.expression = args[++i];
|
|
24
|
+
break;
|
|
25
|
+
case '-f':
|
|
26
|
+
case '--file':
|
|
27
|
+
options.outputFile = args[++i];
|
|
28
|
+
break;
|
|
29
|
+
case '-t':
|
|
30
|
+
case '--target':
|
|
31
|
+
const target = args[++i];
|
|
32
|
+
if (target !== 'ruby' && target !== 'js' && target !== 'sql') {
|
|
33
|
+
console.error(`Invalid target: ${target}. Must be one of: ruby, js, sql`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
options.target = target;
|
|
37
|
+
break;
|
|
38
|
+
case '-p':
|
|
39
|
+
case '--prelude':
|
|
40
|
+
options.prelude = true;
|
|
41
|
+
break;
|
|
42
|
+
case '--prelude-only':
|
|
43
|
+
options.preludeOnly = true;
|
|
44
|
+
break;
|
|
45
|
+
case '-x':
|
|
46
|
+
case '--execute':
|
|
47
|
+
options.execute = true;
|
|
48
|
+
break;
|
|
49
|
+
case '-h':
|
|
50
|
+
case '--help':
|
|
51
|
+
printHelp();
|
|
52
|
+
process.exit(0);
|
|
53
|
+
break;
|
|
54
|
+
case '-':
|
|
55
|
+
// Read from stdin
|
|
56
|
+
options.inputFile = '-';
|
|
57
|
+
break;
|
|
58
|
+
default:
|
|
59
|
+
// If it doesn't start with -, treat it as input file
|
|
60
|
+
if (!arg.startsWith('-') && !options.inputFile && !options.expression) {
|
|
61
|
+
options.inputFile = arg;
|
|
62
|
+
}
|
|
63
|
+
else if (!arg.startsWith('-')) {
|
|
64
|
+
console.error(`Unknown argument: ${arg}`);
|
|
65
|
+
printHelp();
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return options;
|
|
71
|
+
}
|
|
72
|
+
function printHelp() {
|
|
73
|
+
console.log(`
|
|
74
|
+
Elo Compiler (eloc) - Compile Elo expressions to Ruby, JavaScript, or SQL
|
|
75
|
+
|
|
76
|
+
Usage:
|
|
77
|
+
eloc [options] [input-file]
|
|
78
|
+
|
|
79
|
+
Options:
|
|
80
|
+
-e, --expression <expr> Expression to compile (like ruby -e)
|
|
81
|
+
-t, --target <lang> Target language: ruby, js (default), sql
|
|
82
|
+
-x, --execute Output self-executing code (calls function with null/nil)
|
|
83
|
+
-p, --prelude Include necessary library imports/requires
|
|
84
|
+
--prelude-only Output only the prelude (no expression needed)
|
|
85
|
+
-f, --file <path> Output to file instead of stdout
|
|
86
|
+
-h, --help Show this help message
|
|
87
|
+
|
|
88
|
+
Examples:
|
|
89
|
+
# Compile expression to JavaScript (default)
|
|
90
|
+
eloc -e "2 + 3 * 4"
|
|
91
|
+
|
|
92
|
+
# Compile expression to Ruby
|
|
93
|
+
eloc -e "2 + 3 * 4" -t ruby
|
|
94
|
+
|
|
95
|
+
# Compile expression to SQL
|
|
96
|
+
eloc -e "2 + 3 * 4" -t sql
|
|
97
|
+
|
|
98
|
+
# Compile with prelude (includes required libraries)
|
|
99
|
+
eloc -e "NOW + PT2H" -t ruby -p
|
|
100
|
+
|
|
101
|
+
# Compile from file
|
|
102
|
+
eloc input.elo -t ruby
|
|
103
|
+
|
|
104
|
+
# Compile to file
|
|
105
|
+
eloc -e "2 + 3" -t ruby -f output.rb
|
|
106
|
+
|
|
107
|
+
# Compile file to file
|
|
108
|
+
eloc input.elo -t js -f output.js
|
|
109
|
+
|
|
110
|
+
# Compile from stdin
|
|
111
|
+
echo "2 + 3 * 4" | eloc -
|
|
112
|
+
cat input.elo | eloc - -t ruby
|
|
113
|
+
|
|
114
|
+
For evaluating expressions, use the 'elo' command instead.
|
|
115
|
+
`);
|
|
116
|
+
}
|
|
117
|
+
function compile(source, target, options = {}) {
|
|
118
|
+
const ast = (0, parser_1.parse)(source);
|
|
119
|
+
const { includePrelude = false, execute = false } = options;
|
|
120
|
+
let code;
|
|
121
|
+
switch (target) {
|
|
122
|
+
case 'ruby': {
|
|
123
|
+
const result = (0, ruby_1.compileToRubyWithMeta)(ast, { execute });
|
|
124
|
+
code = result.code;
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
case 'js': {
|
|
128
|
+
const result = (0, javascript_1.compileToJavaScriptWithMeta)(ast, { execute });
|
|
129
|
+
code = result.code;
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
case 'sql': {
|
|
133
|
+
// SQL doesn't support execute option (no function wrapping)
|
|
134
|
+
const result = (0, sql_1.compileToSQLWithMeta)(ast);
|
|
135
|
+
code = result.code;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (includePrelude) {
|
|
140
|
+
const preludeContent = (0, preludes_1.getPrelude)(toPreludeTarget(target));
|
|
141
|
+
if (preludeContent) {
|
|
142
|
+
code = `${preludeContent}\n\n${code}`;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return code;
|
|
146
|
+
}
|
|
147
|
+
function main() {
|
|
148
|
+
const args = process.argv.slice(2);
|
|
149
|
+
if (args.length === 0) {
|
|
150
|
+
printHelp();
|
|
151
|
+
process.exit(0);
|
|
152
|
+
}
|
|
153
|
+
const options = parseArgs(args);
|
|
154
|
+
// Handle --prelude-only: just output the prelude and exit
|
|
155
|
+
if (options.preludeOnly) {
|
|
156
|
+
const prelude = (0, preludes_1.getPrelude)(toPreludeTarget(options.target));
|
|
157
|
+
console.log(prelude);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
// Get the source expression(s)
|
|
161
|
+
let sources;
|
|
162
|
+
if (options.expression) {
|
|
163
|
+
sources = [options.expression];
|
|
164
|
+
}
|
|
165
|
+
else if (options.inputFile) {
|
|
166
|
+
try {
|
|
167
|
+
// Use file descriptor 0 for stdin when input is '-'
|
|
168
|
+
const content = options.inputFile === '-'
|
|
169
|
+
? (0, fs_1.readFileSync)(0, 'utf-8')
|
|
170
|
+
: (0, fs_1.readFileSync)(options.inputFile, 'utf-8');
|
|
171
|
+
// Split into lines - keep all lines but mark empty/comment lines as null
|
|
172
|
+
// so we can output empty lines for them to preserve line numbers
|
|
173
|
+
sources = content.split('\n').map(line => {
|
|
174
|
+
const trimmed = line.trim();
|
|
175
|
+
return (trimmed === '' || trimmed.startsWith('#')) ? '' : line;
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
console.error(`Error reading ${options.inputFile === '-' ? 'stdin' : `file ${options.inputFile}`}: ${error}`);
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
console.error('Error: Must provide either -e <expression>, an input file, or - for stdin');
|
|
185
|
+
printHelp();
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|
|
188
|
+
// Compile each expression
|
|
189
|
+
let results;
|
|
190
|
+
try {
|
|
191
|
+
results = sources.map((source, index) => {
|
|
192
|
+
try {
|
|
193
|
+
const trimmed = source.trim();
|
|
194
|
+
// Skip empty lines and comment lines - return empty result
|
|
195
|
+
if (trimmed === '' || trimmed.startsWith('#')) {
|
|
196
|
+
return '';
|
|
197
|
+
}
|
|
198
|
+
return compile(trimmed, options.target, {
|
|
199
|
+
includePrelude: index === 0 && options.prelude,
|
|
200
|
+
execute: options.execute
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
throw new Error(`Line ${index + 1}: ${error}`);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
console.error(`Compilation error: ${error}`);
|
|
210
|
+
process.exit(1);
|
|
211
|
+
}
|
|
212
|
+
// Join lines with newlines
|
|
213
|
+
const output = results.join('\n');
|
|
214
|
+
// Output the result
|
|
215
|
+
if (options.outputFile) {
|
|
216
|
+
try {
|
|
217
|
+
// Only add trailing newline if output doesn't already end with one
|
|
218
|
+
const finalOutput = output.endsWith('\n') ? output : output + '\n';
|
|
219
|
+
(0, fs_1.writeFileSync)(options.outputFile, finalOutput, 'utf-8');
|
|
220
|
+
console.error(`Compiled to ${options.outputFile}`);
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
console.error(`Error writing file ${options.outputFile}: ${error}`);
|
|
224
|
+
process.exit(1);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
console.log(output);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
main();
|
|
232
|
+
//# sourceMappingURL=eloc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eloc.js","sourceRoot":"","sources":["../../src/eloc.ts"],"names":[],"mappings":";;;AAEA,2BAAiD;AACjD,qCAAiC;AACjC,2CAAyD;AACzD,uDAAqE;AACrE,yCAAuD;AACvD,yCAAiE;AAIjE,+CAA+C;AAC/C,SAAS,eAAe,CAAC,MAAc;IACrC,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC;AACjD,CAAC;AAaD,SAAS,SAAS,CAAC,IAAc;IAC/B,MAAM,OAAO,GAAY;QACvB,MAAM,EAAE,IAAI,CAAQ,iBAAiB;KACtC,CAAC;IAEF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpB,QAAQ,GAAG,EAAE,CAAC;YACZ,KAAK,IAAI,CAAC;YACV,KAAK,cAAc;gBACjB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC/B,MAAM;YAER,KAAK,IAAI,CAAC;YACV,KAAK,QAAQ;gBACX,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC/B,MAAM;YAER,KAAK,IAAI,CAAC;YACV,KAAK,UAAU;gBACb,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACzB,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;oBAC7D,OAAO,CAAC,KAAK,CAAC,mBAAmB,MAAM,iCAAiC,CAAC,CAAC;oBAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC;gBACD,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC;gBACxB,MAAM;YAER,KAAK,IAAI,CAAC;YACV,KAAK,WAAW;gBACd,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;gBACvB,MAAM;YAER,KAAK,gBAAgB;gBACnB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;gBAC3B,MAAM;YAER,KAAK,IAAI,CAAC;YACV,KAAK,WAAW;gBACd,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;gBACvB,MAAM;YAER,KAAK,IAAI,CAAC;YACV,KAAK,QAAQ;gBACX,SAAS,EAAE,CAAC;gBACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAChB,MAAM;YAER,KAAK,GAAG;gBACN,kBAAkB;gBAClB,OAAO,CAAC,SAAS,GAAG,GAAG,CAAC;gBACxB,MAAM;YAER;gBACE,qDAAqD;gBACrD,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;oBACtE,OAAO,CAAC,SAAS,GAAG,GAAG,CAAC;gBAC1B,CAAC;qBAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBAChC,OAAO,CAAC,KAAK,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;oBAC1C,SAAS,EAAE,CAAC;oBACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0Cb,CAAC,CAAC;AACH,CAAC;AAOD,SAAS,OAAO,CAAC,MAAc,EAAE,MAAc,EAAE,UAA0B,EAAE;IAC3E,MAAM,GAAG,GAAG,IAAA,cAAK,EAAC,MAAM,CAAC,CAAC;IAC1B,MAAM,EAAE,cAAc,GAAG,KAAK,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAE5D,IAAI,IAAY,CAAC;IACjB,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,MAAM,GAAG,IAAA,4BAAqB,EAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;YACvD,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YACnB,MAAM;QACR,CAAC;QACD,KAAK,IAAI,CAAC,CAAC,CAAC;YACV,MAAM,MAAM,GAAG,IAAA,wCAA2B,EAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;YAC7D,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YACnB,MAAM;QACR,CAAC;QACD,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,4DAA4D;YAC5D,MAAM,MAAM,GAAG,IAAA,0BAAoB,EAAC,GAAG,CAAC,CAAC;YACzC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YACnB,MAAM;QACR,CAAC;IACH,CAAC;IAED,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,cAAc,GAAG,IAAA,qBAAU,EAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3D,IAAI,cAAc,EAAE,CAAC;YACnB,IAAI,GAAG,GAAG,cAAc,OAAO,IAAI,EAAE,CAAC;QACxC,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,IAAI;IACX,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,SAAS,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAEhC,0DAA0D;IAC1D,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,IAAA,qBAAU,EAAC,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QAC5D,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,+BAA+B;IAC/B,IAAI,OAAiB,CAAC;IACtB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACjC,CAAC;SAAM,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,oDAAoD;YACpD,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,KAAK,GAAG;gBACvC,CAAC,CAAC,IAAA,iBAAY,EAAC,CAAC,EAAE,OAAO,CAAC;gBAC1B,CAAC,CAAC,IAAA,iBAAY,EAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC7C,yEAAyE;YACzE,iEAAiE;YACjE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;gBACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC5B,OAAO,CAAC,OAAO,KAAK,EAAE,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YACjE,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,iBAAiB,OAAO,CAAC,SAAS,KAAK,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,OAAO,CAAC,SAAS,EAAE,KAAK,KAAK,EAAE,CAAC,CAAC;YAC9G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,2EAA2E,CAAC,CAAC;QAC3F,SAAS,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,0BAA0B;IAC1B,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;YACtC,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;gBAC9B,2DAA2D;gBAC3D,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC9C,OAAO,EAAE,CAAC;gBACZ,CAAC;gBACD,OAAO,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE;oBACtC,cAAc,EAAE,KAAK,KAAK,CAAC,IAAI,OAAO,CAAC,OAAO;oBAC9C,OAAO,EAAE,OAAO,CAAC,OAAO;iBACzB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;YACjD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,sBAAsB,KAAK,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,2BAA2B;IAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAElC,oBAAoB;IACpB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,mEAAmE;YACnE,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC;YACnE,IAAA,kBAAa,EAAC,OAAO,CAAC,UAAU,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;YACxD,OAAO,CAAC,KAAK,CAAC,eAAe,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,sBAAsB,OAAO,CAAC,UAAU,KAAK,KAAK,EAAE,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval.d.ts","sourceRoot":"","sources":["../../src/eval.ts"],"names":[],"mappings":""}
|
package/dist/src/eval.js
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const fs_1 = require("fs");
|
|
8
|
+
const parser_1 = require("./parser");
|
|
9
|
+
const javascript_1 = require("./compilers/javascript");
|
|
10
|
+
const dayjs_1 = __importDefault(require("dayjs"));
|
|
11
|
+
const duration_1 = __importDefault(require("dayjs/plugin/duration"));
|
|
12
|
+
const isoWeek_1 = __importDefault(require("dayjs/plugin/isoWeek"));
|
|
13
|
+
const quarterOfYear_1 = __importDefault(require("dayjs/plugin/quarterOfYear"));
|
|
14
|
+
dayjs_1.default.extend(duration_1.default);
|
|
15
|
+
dayjs_1.default.extend(isoWeek_1.default);
|
|
16
|
+
dayjs_1.default.extend(quarterOfYear_1.default);
|
|
17
|
+
function parseArgs(args) {
|
|
18
|
+
const options = {};
|
|
19
|
+
for (let i = 0; i < args.length; i++) {
|
|
20
|
+
const arg = args[i];
|
|
21
|
+
switch (arg) {
|
|
22
|
+
case '-e':
|
|
23
|
+
case '--expression':
|
|
24
|
+
options.expression = args[++i];
|
|
25
|
+
break;
|
|
26
|
+
case '-d':
|
|
27
|
+
case '--data':
|
|
28
|
+
options.inputData = args[++i];
|
|
29
|
+
break;
|
|
30
|
+
case '--stdin':
|
|
31
|
+
options.stdinData = true;
|
|
32
|
+
break;
|
|
33
|
+
case '-h':
|
|
34
|
+
case '--help':
|
|
35
|
+
printHelp();
|
|
36
|
+
process.exit(0);
|
|
37
|
+
break;
|
|
38
|
+
case '-':
|
|
39
|
+
// Read expression from stdin
|
|
40
|
+
options.inputFile = '-';
|
|
41
|
+
break;
|
|
42
|
+
default:
|
|
43
|
+
// If it doesn't start with -, treat it as input file
|
|
44
|
+
if (!arg.startsWith('-') && !options.inputFile && !options.expression) {
|
|
45
|
+
options.inputFile = arg;
|
|
46
|
+
}
|
|
47
|
+
else if (!arg.startsWith('-')) {
|
|
48
|
+
console.error(`Unknown argument: ${arg}`);
|
|
49
|
+
printHelp();
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return options;
|
|
55
|
+
}
|
|
56
|
+
function printHelp() {
|
|
57
|
+
console.log(`
|
|
58
|
+
Elo Evaluator (elo) - Evaluate Elo expressions
|
|
59
|
+
|
|
60
|
+
Usage:
|
|
61
|
+
elo [options] [input-file]
|
|
62
|
+
|
|
63
|
+
Options:
|
|
64
|
+
-e, --expression <expr> Expression to evaluate (like ruby -e)
|
|
65
|
+
-d, --data <json> JSON input data for _ variable (or @file to read from file)
|
|
66
|
+
--stdin Read input data as JSON from stdin
|
|
67
|
+
-h, --help Show this help message
|
|
68
|
+
|
|
69
|
+
Examples:
|
|
70
|
+
# Evaluate a simple expression
|
|
71
|
+
elo -e "2 + 3 * 4"
|
|
72
|
+
|
|
73
|
+
# Evaluate with input data
|
|
74
|
+
elo -e "_.x + _.y" -d '{"x": 1, "y": 2}'
|
|
75
|
+
|
|
76
|
+
# Evaluate with input data from file
|
|
77
|
+
elo -e "_.name" -d @data.json
|
|
78
|
+
|
|
79
|
+
# Evaluate from .elo file
|
|
80
|
+
elo expressions.elo
|
|
81
|
+
|
|
82
|
+
# Pipe data through stdin
|
|
83
|
+
echo '{"x": 10}' | elo -e "_.x * 2" --stdin
|
|
84
|
+
|
|
85
|
+
# Read expression from stdin
|
|
86
|
+
echo "2 + 3" | elo -
|
|
87
|
+
`);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Parse input data from CLI option (JSON string or @file path)
|
|
91
|
+
*/
|
|
92
|
+
function parseInputData(inputData) {
|
|
93
|
+
let jsonString = inputData;
|
|
94
|
+
// If starts with @, read from file
|
|
95
|
+
if (inputData.startsWith('@')) {
|
|
96
|
+
const filePath = inputData.slice(1);
|
|
97
|
+
try {
|
|
98
|
+
jsonString = (0, fs_1.readFileSync)(filePath, 'utf-8');
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
console.error(`Error reading input file ${filePath}: ${error}`);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
return JSON.parse(jsonString);
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
console.error(`Error parsing input JSON: ${error}`);
|
|
110
|
+
process.exit(1);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Compile and evaluate a single Elo expression
|
|
115
|
+
*/
|
|
116
|
+
function evaluate(source, inputValue) {
|
|
117
|
+
const ast = (0, parser_1.parse)(source);
|
|
118
|
+
const result = (0, javascript_1.compileToJavaScriptWithMeta)(ast);
|
|
119
|
+
// Create function with dayjs in scope
|
|
120
|
+
// The compiled code is always a function that takes _ as input
|
|
121
|
+
const execFn = new Function('dayjs', `return ${result.code}`);
|
|
122
|
+
const fn = execFn(dayjs_1.default);
|
|
123
|
+
return fn(inputValue);
|
|
124
|
+
}
|
|
125
|
+
function main() {
|
|
126
|
+
const args = process.argv.slice(2);
|
|
127
|
+
if (args.length === 0) {
|
|
128
|
+
printHelp();
|
|
129
|
+
process.exit(0);
|
|
130
|
+
}
|
|
131
|
+
const options = parseArgs(args);
|
|
132
|
+
// Get the source expression(s)
|
|
133
|
+
let sources;
|
|
134
|
+
if (options.expression) {
|
|
135
|
+
sources = [options.expression];
|
|
136
|
+
}
|
|
137
|
+
else if (options.inputFile) {
|
|
138
|
+
try {
|
|
139
|
+
// Use file descriptor 0 for stdin when input is '-'
|
|
140
|
+
const content = options.inputFile === '-'
|
|
141
|
+
? (0, fs_1.readFileSync)(0, 'utf-8')
|
|
142
|
+
: (0, fs_1.readFileSync)(options.inputFile, 'utf-8');
|
|
143
|
+
// Split into lines - keep all lines but mark empty/comment lines as null
|
|
144
|
+
sources = content.split('\n').map(line => {
|
|
145
|
+
const trimmed = line.trim();
|
|
146
|
+
return (trimmed === '' || trimmed.startsWith('#')) ? '' : line;
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
console.error(`Error reading ${options.inputFile === '-' ? 'stdin' : `file ${options.inputFile}`}: ${error}`);
|
|
151
|
+
process.exit(1);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
console.error('Error: Must provide either -e <expression>, an input file, or - for stdin');
|
|
156
|
+
printHelp();
|
|
157
|
+
process.exit(1);
|
|
158
|
+
}
|
|
159
|
+
// Get input data
|
|
160
|
+
let inputValue = null;
|
|
161
|
+
if (options.stdinData) {
|
|
162
|
+
try {
|
|
163
|
+
const stdinContent = (0, fs_1.readFileSync)(0, 'utf-8');
|
|
164
|
+
inputValue = JSON.parse(stdinContent);
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
console.error(`Error reading/parsing stdin: ${error}`);
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else if (options.inputData) {
|
|
172
|
+
inputValue = parseInputData(options.inputData);
|
|
173
|
+
}
|
|
174
|
+
// Evaluate each expression
|
|
175
|
+
const outputs = [];
|
|
176
|
+
for (let i = 0; i < sources.length; i++) {
|
|
177
|
+
const source = sources[i];
|
|
178
|
+
const trimmed = source.trim();
|
|
179
|
+
// Skip empty lines and comments
|
|
180
|
+
if (trimmed === '' || trimmed.startsWith('#')) {
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
try {
|
|
184
|
+
const result = evaluate(trimmed, inputValue);
|
|
185
|
+
outputs.push(JSON.stringify(result));
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
console.error(`Error on line ${i + 1}: ${error}`);
|
|
189
|
+
process.exit(1);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// Output results
|
|
193
|
+
console.log(outputs.join('\n'));
|
|
194
|
+
}
|
|
195
|
+
main();
|
|
196
|
+
//# sourceMappingURL=eval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval.js","sourceRoot":"","sources":["../../src/eval.ts"],"names":[],"mappings":"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"}
|