starlight-cli 1.0.37 → 1.0.39

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 CHANGED
@@ -1467,11 +1467,11 @@ 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
-
1473
1470
  case 'WhileStatement': return await this.evalWhile(node, env);
1474
- case 'ForStatement': return await this.evalFor(node, env);
1471
+ case 'ForStatement':
1472
+ case 'ForInStatement':
1473
+ return await this.evalFor(node, env);
1474
+
1475
1475
  case 'BreakStatement': throw new BreakSignal();
1476
1476
  case 'ContinueStatement': throw new ContinueSignal();
1477
1477
  case 'ImportStatement': return await this.evalImport(node, env);
@@ -1487,12 +1487,14 @@ async evaluate(node, env = this.global) {
1487
1487
  return await Promise.all(node.elements.map(el => this.evaluate(el, env)));
1488
1488
  case 'IndexExpression': return await this.evalIndex(node, env);
1489
1489
  case 'ObjectExpression': {
1490
- const out = {};
1491
- for (const p of node.props) {
1492
- out[p.key] = await this.evaluate(p.value, env);
1493
- }
1494
- return out;
1495
- }
1490
+ const out = {};
1491
+ for (const p of node.props) {
1492
+ const key = await this.evaluate(p.key, env);
1493
+ out[key] = await this.evaluate(p.value, env);
1494
+ }
1495
+ return out;
1496
+ }
1497
+
1496
1498
  case 'MemberExpression': return await this.evalMember(node, env);
1497
1499
  case 'UpdateExpression': return await this.evalUpdate(node, env);
1498
1500
  case 'AwaitExpression': {
@@ -1539,30 +1541,7 @@ async evalProgram(node, env) {
1539
1541
  }
1540
1542
  return result;
1541
1543
  }
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
1544
 
1564
- return null;
1565
- }
1566
1545
 
1567
1546
  async evalImport(node, env) {
1568
1547
  const spec = node.path;
@@ -1772,9 +1751,11 @@ async evalWhile(node, env) {
1772
1751
  }
1773
1752
  return null;
1774
1753
  }
1775
-
1776
1754
  async evalFor(node, env) {
1777
- // --- Python-style for x in iterable ---
1755
+
1756
+ // -------------------------------
1757
+ // Python-style: for x in iterable
1758
+ // -------------------------------
1778
1759
  if (node.type === 'ForInStatement') {
1779
1760
  const iterable = await this.evaluate(node.iterable, env);
1780
1761
 
@@ -1782,11 +1763,13 @@ async evalFor(node, env) {
1782
1763
  throw new Error('Cannot iterate over non-iterable');
1783
1764
  }
1784
1765
 
1785
- // Handle arrays
1766
+ const loopVar = node.variable; // STRING from parser
1767
+
1768
+ // Arrays
1786
1769
  if (Array.isArray(iterable)) {
1787
- for (let i = 0; i < iterable.length; i++) {
1770
+ for (const value of iterable) {
1788
1771
  const loopEnv = new Environment(env);
1789
- loopEnv.define(node.variable, iterable[i]);
1772
+ loopEnv.define(loopVar, value);
1790
1773
 
1791
1774
  try {
1792
1775
  await this.evaluate(node.body, loopEnv);
@@ -1796,11 +1779,12 @@ async evalFor(node, env) {
1796
1779
  throw e;
1797
1780
  }
1798
1781
  }
1799
- } else {
1800
- // Handle objects: iterate over keys
1782
+ }
1783
+ // Objects (keys)
1784
+ else {
1801
1785
  for (const key of Object.keys(iterable)) {
1802
1786
  const loopEnv = new Environment(env);
1803
- loopEnv.define(node.variable, key);
1787
+ loopEnv.define(loopVar, key);
1804
1788
 
1805
1789
  try {
1806
1790
  await this.evaluate(node.body, loopEnv);
@@ -1815,7 +1799,11 @@ async evalFor(node, env) {
1815
1799
  return null;
1816
1800
  }
1817
1801
 
1802
+ // -------------------------------
1803
+ // C-style for loop
1804
+ // -------------------------------
1818
1805
  const local = new Environment(env);
1806
+
1819
1807
  if (node.init) await this.evaluate(node.init, local);
1820
1808
 
1821
1809
  while (!node.test || await this.evaluate(node.test, local)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starlight-cli",
3
- "version": "1.0.37",
3
+ "version": "1.0.39",
4
4
  "description": "Starlight Programming Language CLI",
5
5
  "bin": {
6
6
  "starlight": "index.js"
package/src/evaluator.js CHANGED
@@ -124,11 +124,11 @@ 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
-
130
127
  case 'WhileStatement': return await this.evalWhile(node, env);
131
- case 'ForStatement': return await this.evalFor(node, env);
128
+ case 'ForStatement':
129
+ case 'ForInStatement':
130
+ return await this.evalFor(node, env);
131
+
132
132
  case 'BreakStatement': throw new BreakSignal();
133
133
  case 'ContinueStatement': throw new ContinueSignal();
134
134
  case 'ImportStatement': return await this.evalImport(node, env);
@@ -144,12 +144,14 @@ async evaluate(node, env = this.global) {
144
144
  return await Promise.all(node.elements.map(el => this.evaluate(el, env)));
145
145
  case 'IndexExpression': return await this.evalIndex(node, env);
146
146
  case 'ObjectExpression': {
147
- const out = {};
148
- for (const p of node.props) {
149
- out[p.key] = await this.evaluate(p.value, env);
150
- }
151
- return out;
152
- }
147
+ const out = {};
148
+ for (const p of node.props) {
149
+ const key = await this.evaluate(p.key, env);
150
+ out[key] = await this.evaluate(p.value, env);
151
+ }
152
+ return out;
153
+ }
154
+
153
155
  case 'MemberExpression': return await this.evalMember(node, env);
154
156
  case 'UpdateExpression': return await this.evalUpdate(node, env);
155
157
  case 'AwaitExpression': {
@@ -196,30 +198,7 @@ async evalProgram(node, env) {
196
198
  }
197
199
  return result;
198
200
  }
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
201
 
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
- }
223
202
 
224
203
  async evalImport(node, env) {
225
204
  const spec = node.path;
@@ -429,9 +408,11 @@ async evalWhile(node, env) {
429
408
  }
430
409
  return null;
431
410
  }
432
-
433
411
  async evalFor(node, env) {
434
- // --- Python-style for x in iterable ---
412
+
413
+ // -------------------------------
414
+ // Python-style: for x in iterable
415
+ // -------------------------------
435
416
  if (node.type === 'ForInStatement') {
436
417
  const iterable = await this.evaluate(node.iterable, env);
437
418
 
@@ -439,11 +420,13 @@ async evalFor(node, env) {
439
420
  throw new Error('Cannot iterate over non-iterable');
440
421
  }
441
422
 
442
- // Handle arrays
423
+ const loopVar = node.variable; // STRING from parser
424
+
425
+ // Arrays
443
426
  if (Array.isArray(iterable)) {
444
- for (let i = 0; i < iterable.length; i++) {
427
+ for (const value of iterable) {
445
428
  const loopEnv = new Environment(env);
446
- loopEnv.define(node.variable, iterable[i]);
429
+ loopEnv.define(loopVar, value);
447
430
 
448
431
  try {
449
432
  await this.evaluate(node.body, loopEnv);
@@ -453,11 +436,12 @@ async evalFor(node, env) {
453
436
  throw e;
454
437
  }
455
438
  }
456
- } else {
457
- // Handle objects: iterate over keys
439
+ }
440
+ // Objects (keys)
441
+ else {
458
442
  for (const key of Object.keys(iterable)) {
459
443
  const loopEnv = new Environment(env);
460
- loopEnv.define(node.variable, key);
444
+ loopEnv.define(loopVar, key);
461
445
 
462
446
  try {
463
447
  await this.evaluate(node.body, loopEnv);
@@ -472,7 +456,11 @@ async evalFor(node, env) {
472
456
  return null;
473
457
  }
474
458
 
459
+ // -------------------------------
460
+ // C-style for loop
461
+ // -------------------------------
475
462
  const local = new Environment(env);
463
+
476
464
  if (node.init) await this.evaluate(node.init, local);
477
465
 
478
466
  while (!node.test || await this.evaluate(node.test, local)) {