starlight-cli 1.0.38 → 1.0.40

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
@@ -1468,7 +1468,12 @@ async evaluate(node, env = this.global) {
1468
1468
  case 'Identifier': return env.get(node.name);
1469
1469
  case 'IfStatement': return await this.evalIf(node, env);
1470
1470
  case 'WhileStatement': return await this.evalWhile(node, env);
1471
- case 'ForStatement': return await this.evalFor(node, env);
1471
+ case 'ForStatement':
1472
+ case 'ForInStatement':
1473
+ return await this.evalFor(node, env);
1474
+ case 'DoTrackStatement':
1475
+ return await this.evalDoTrack(node, env);
1476
+
1472
1477
  case 'BreakStatement': throw new BreakSignal();
1473
1478
  case 'ContinueStatement': throw new ContinueSignal();
1474
1479
  case 'ImportStatement': return await this.evalImport(node, env);
@@ -1484,12 +1489,14 @@ async evaluate(node, env = this.global) {
1484
1489
  return await Promise.all(node.elements.map(el => this.evaluate(el, env)));
1485
1490
  case 'IndexExpression': return await this.evalIndex(node, env);
1486
1491
  case 'ObjectExpression': {
1487
- const out = {};
1488
- for (const p of node.props) {
1489
- out[p.key] = await this.evaluate(p.value, env);
1490
- }
1491
- return out;
1492
- }
1492
+ const out = {};
1493
+ for (const p of node.props) {
1494
+ const key = await this.evaluate(p.key, env);
1495
+ out[key] = await this.evaluate(p.value, env);
1496
+ }
1497
+ return out;
1498
+ }
1499
+
1493
1500
  case 'MemberExpression': return await this.evalMember(node, env);
1494
1501
  case 'UpdateExpression': return await this.evalUpdate(node, env);
1495
1502
  case 'AwaitExpression': {
@@ -1537,6 +1544,18 @@ async evalProgram(node, env) {
1537
1544
  return result;
1538
1545
  }
1539
1546
 
1547
+ async evalDoTrack(node, env) {
1548
+ try {
1549
+ return await this.evaluate(node.body, env);
1550
+ } catch (err) {
1551
+ if (!node.handler) throw err;
1552
+
1553
+ const trackEnv = new Environment(env);
1554
+ trackEnv.define('error', err);
1555
+
1556
+ return await this.evaluate(node.handler, trackEnv);
1557
+ }
1558
+ }
1540
1559
 
1541
1560
  async evalImport(node, env) {
1542
1561
  const spec = node.path;
@@ -2002,7 +2021,7 @@ class Lexer {
2002
2021
  'break', 'continue', 'func', 'return',
2003
2022
  'true', 'false', 'null',
2004
2023
  'ask', 'define', 'import', 'from', 'as',
2005
- 'async', 'await', 'new', 'in'
2024
+ 'async', 'await', 'new', 'in', 'do', 'track'
2006
2025
  ];
2007
2026
 
2008
2027
 
@@ -2156,6 +2175,7 @@ class Parser {
2156
2175
  case 'IF': return this.ifStatement();
2157
2176
  case 'WHILE': return this.whileStatement();
2158
2177
  case 'FOR': return this.forStatement();
2178
+ case 'DO': return this.doTrackStatement();
2159
2179
  case 'BREAK': return this.breakStatement();
2160
2180
  case 'CONTINUE': return this.continueStatement();
2161
2181
  case 'FUNC': return this.funcDeclaration();
@@ -2190,6 +2210,23 @@ sldeployStatement() {
2190
2210
  if (this.current.type === 'SEMICOLON') this.eat('SEMICOLON');
2191
2211
  return { type: 'SldeployStatement', expr };
2192
2212
  }
2213
+ doTrackStatement() {
2214
+ this.eat('DO');
2215
+
2216
+ const body = this.block();
2217
+
2218
+ let handler = null;
2219
+ if (this.current.type === 'TRACK') {
2220
+ this.eat('TRACK');
2221
+ handler = this.block();
2222
+ }
2223
+
2224
+ return {
2225
+ type: 'DoTrackStatement',
2226
+ body,
2227
+ handler
2228
+ };
2229
+ }
2193
2230
 
2194
2231
  defineStatement() {
2195
2232
  this.eat('DEFINE');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starlight-cli",
3
- "version": "1.0.38",
3
+ "version": "1.0.40",
4
4
  "description": "Starlight Programming Language CLI",
5
5
  "bin": {
6
6
  "starlight": "index.js"
package/src/evaluator.js CHANGED
@@ -125,7 +125,12 @@ async evaluate(node, env = this.global) {
125
125
  case 'Identifier': return env.get(node.name);
126
126
  case 'IfStatement': return await this.evalIf(node, env);
127
127
  case 'WhileStatement': return await this.evalWhile(node, env);
128
- case 'ForStatement': return await this.evalFor(node, env);
128
+ case 'ForStatement':
129
+ case 'ForInStatement':
130
+ return await this.evalFor(node, env);
131
+ case 'DoTrackStatement':
132
+ return await this.evalDoTrack(node, env);
133
+
129
134
  case 'BreakStatement': throw new BreakSignal();
130
135
  case 'ContinueStatement': throw new ContinueSignal();
131
136
  case 'ImportStatement': return await this.evalImport(node, env);
@@ -141,12 +146,14 @@ async evaluate(node, env = this.global) {
141
146
  return await Promise.all(node.elements.map(el => this.evaluate(el, env)));
142
147
  case 'IndexExpression': return await this.evalIndex(node, env);
143
148
  case 'ObjectExpression': {
144
- const out = {};
145
- for (const p of node.props) {
146
- out[p.key] = await this.evaluate(p.value, env);
147
- }
148
- return out;
149
- }
149
+ const out = {};
150
+ for (const p of node.props) {
151
+ const key = await this.evaluate(p.key, env);
152
+ out[key] = await this.evaluate(p.value, env);
153
+ }
154
+ return out;
155
+ }
156
+
150
157
  case 'MemberExpression': return await this.evalMember(node, env);
151
158
  case 'UpdateExpression': return await this.evalUpdate(node, env);
152
159
  case 'AwaitExpression': {
@@ -194,6 +201,18 @@ async evalProgram(node, env) {
194
201
  return result;
195
202
  }
196
203
 
204
+ async evalDoTrack(node, env) {
205
+ try {
206
+ return await this.evaluate(node.body, env);
207
+ } catch (err) {
208
+ if (!node.handler) throw err;
209
+
210
+ const trackEnv = new Environment(env);
211
+ trackEnv.define('error', err);
212
+
213
+ return await this.evaluate(node.handler, trackEnv);
214
+ }
215
+ }
197
216
 
198
217
  async evalImport(node, env) {
199
218
  const spec = node.path;
package/src/lexer.js CHANGED
@@ -83,7 +83,7 @@ class Lexer {
83
83
  'break', 'continue', 'func', 'return',
84
84
  'true', 'false', 'null',
85
85
  'ask', 'define', 'import', 'from', 'as',
86
- 'async', 'await', 'new', 'in'
86
+ 'async', 'await', 'new', 'in', 'do', 'track'
87
87
  ];
88
88
 
89
89
 
package/src/parser.js CHANGED
@@ -43,6 +43,7 @@ class Parser {
43
43
  case 'IF': return this.ifStatement();
44
44
  case 'WHILE': return this.whileStatement();
45
45
  case 'FOR': return this.forStatement();
46
+ case 'DO': return this.doTrackStatement();
46
47
  case 'BREAK': return this.breakStatement();
47
48
  case 'CONTINUE': return this.continueStatement();
48
49
  case 'FUNC': return this.funcDeclaration();
@@ -77,6 +78,23 @@ sldeployStatement() {
77
78
  if (this.current.type === 'SEMICOLON') this.eat('SEMICOLON');
78
79
  return { type: 'SldeployStatement', expr };
79
80
  }
81
+ doTrackStatement() {
82
+ this.eat('DO');
83
+
84
+ const body = this.block();
85
+
86
+ let handler = null;
87
+ if (this.current.type === 'TRACK') {
88
+ this.eat('TRACK');
89
+ handler = this.block();
90
+ }
91
+
92
+ return {
93
+ type: 'DoTrackStatement',
94
+ body,
95
+ handler
96
+ };
97
+ }
80
98
 
81
99
  defineStatement() {
82
100
  this.eat('DEFINE');