starlight-cli 1.0.35 → 1.0.37
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/dist/index.js +28 -1
- package/package.json +1 -1
- package/src/evaluator.js +27 -0
- package/src/lexer.js +1 -1
package/dist/index.js
CHANGED
|
@@ -1467,6 +1467,9 @@ async evaluate(node, env = this.global) {
|
|
|
1467
1467
|
case 'Literal': return node.value;
|
|
1468
1468
|
case 'Identifier': return env.get(node.name);
|
|
1469
1469
|
case 'IfStatement': return await this.evalIf(node, env);
|
|
1470
|
+
case 'ForInStatement':
|
|
1471
|
+
return await this.evalForIn(node, env);
|
|
1472
|
+
|
|
1470
1473
|
case 'WhileStatement': return await this.evalWhile(node, env);
|
|
1471
1474
|
case 'ForStatement': return await this.evalFor(node, env);
|
|
1472
1475
|
case 'BreakStatement': throw new BreakSignal();
|
|
@@ -1536,6 +1539,30 @@ async evalProgram(node, env) {
|
|
|
1536
1539
|
}
|
|
1537
1540
|
return result;
|
|
1538
1541
|
}
|
|
1542
|
+
async evalForIn(node, env) {
|
|
1543
|
+
const iterable = await this.evaluate(node.iterable, env);
|
|
1544
|
+
|
|
1545
|
+
if (!Array.isArray(iterable)) {
|
|
1546
|
+
throw new Error("for-in expects an array");
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
for (const value of iterable) {
|
|
1550
|
+
const local = new Environment(env);
|
|
1551
|
+
|
|
1552
|
+
// loop variable
|
|
1553
|
+
local.define(node.id.name, value);
|
|
1554
|
+
|
|
1555
|
+
try {
|
|
1556
|
+
await this.evaluate(node.body, local);
|
|
1557
|
+
} catch (e) {
|
|
1558
|
+
if (e instanceof BreakSignal) break;
|
|
1559
|
+
if (e instanceof ContinueSignal) continue;
|
|
1560
|
+
throw e;
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
return null;
|
|
1565
|
+
}
|
|
1539
1566
|
|
|
1540
1567
|
async evalImport(node, env) {
|
|
1541
1568
|
const spec = node.path;
|
|
@@ -1992,7 +2019,7 @@ class Lexer {
|
|
|
1992
2019
|
'break', 'continue', 'func', 'return',
|
|
1993
2020
|
'true', 'false', 'null',
|
|
1994
2021
|
'ask', 'define', 'import', 'from', 'as',
|
|
1995
|
-
'async', 'await', 'new'
|
|
2022
|
+
'async', 'await', 'new', 'in'
|
|
1996
2023
|
];
|
|
1997
2024
|
|
|
1998
2025
|
|
package/package.json
CHANGED
package/src/evaluator.js
CHANGED
|
@@ -124,6 +124,9 @@ async evaluate(node, env = this.global) {
|
|
|
124
124
|
case 'Literal': return node.value;
|
|
125
125
|
case 'Identifier': return env.get(node.name);
|
|
126
126
|
case 'IfStatement': return await this.evalIf(node, env);
|
|
127
|
+
case 'ForInStatement':
|
|
128
|
+
return await this.evalForIn(node, env);
|
|
129
|
+
|
|
127
130
|
case 'WhileStatement': return await this.evalWhile(node, env);
|
|
128
131
|
case 'ForStatement': return await this.evalFor(node, env);
|
|
129
132
|
case 'BreakStatement': throw new BreakSignal();
|
|
@@ -193,6 +196,30 @@ async evalProgram(node, env) {
|
|
|
193
196
|
}
|
|
194
197
|
return result;
|
|
195
198
|
}
|
|
199
|
+
async evalForIn(node, env) {
|
|
200
|
+
const iterable = await this.evaluate(node.iterable, env);
|
|
201
|
+
|
|
202
|
+
if (!Array.isArray(iterable)) {
|
|
203
|
+
throw new Error("for-in expects an array");
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
for (const value of iterable) {
|
|
207
|
+
const local = new Environment(env);
|
|
208
|
+
|
|
209
|
+
// loop variable
|
|
210
|
+
local.define(node.id.name, value);
|
|
211
|
+
|
|
212
|
+
try {
|
|
213
|
+
await this.evaluate(node.body, local);
|
|
214
|
+
} catch (e) {
|
|
215
|
+
if (e instanceof BreakSignal) break;
|
|
216
|
+
if (e instanceof ContinueSignal) continue;
|
|
217
|
+
throw e;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
196
223
|
|
|
197
224
|
async evalImport(node, env) {
|
|
198
225
|
const spec = node.path;
|