starlight-cli 1.0.21 → 1.0.23

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/src/parser.js CHANGED
@@ -12,7 +12,10 @@ class Parser {
12
12
 
13
13
  eat(type) {
14
14
  if (this.current.type === type) this.advance();
15
- else throw new Error(`Expected ${type}, got ${this.current.type}`);
15
+ else throw new Error(
16
+ `Expected ${type}, got ${this.current.type} at line ${this.current.line}, column ${this.current.column}`
17
+ );
18
+
16
19
  }
17
20
 
18
21
  peekType(offset = 1) {
@@ -99,52 +102,52 @@ class Parser {
99
102
  const body = this.block();
100
103
  return { type: 'WhileStatement', test, body };
101
104
  }
102
-
103
105
  importStatement() {
104
106
  this.eat('IMPORT');
105
107
 
106
108
  let specifiers = [];
107
109
 
108
110
  if (this.current.type === 'STAR') {
109
- this.eat('STAR');
110
- this.eat('AS');
111
- const name = this.current.value;
112
- this.eat('IDENTIFIER');
113
- specifiers.push({ type: 'NamespaceImport', local: name });
111
+ this.eat('STAR');
112
+ this.eat('AS');
113
+ const name = this.current.value;
114
+ this.eat('IDENTIFIER');
115
+ specifiers.push({ type: 'NamespaceImport', local: name });
114
116
  }
115
117
  else if (this.current.type === 'LBRACE') {
116
- this.eat('LBRACE');
117
- while (this.current.type !== 'RBRACE') {
118
- const importedName = this.current.value;
119
- this.eat('IDENTIFIER');
120
- let localName = importedName;
121
- if (this.current.type === 'AS') {
122
- this.eat('AS');
123
- localName = this.current.value;
124
- this.eat('IDENTIFIER');
118
+ this.eat('LBRACE');
119
+ while (this.current.type !== 'RBRACE') {
120
+ const importedName = this.current.value;
121
+ this.eat('IDENTIFIER');
122
+ let localName = importedName;
123
+ if (this.current.type === 'AS') {
124
+ this.eat('AS');
125
+ localName = this.current.value;
126
+ this.eat('IDENTIFIER');
127
+ }
128
+ specifiers.push({ type: 'NamedImport', imported: importedName, local: localName });
129
+ if (this.current.type === 'COMMA') this.eat('COMMA');
125
130
  }
126
- specifiers.push({ type: 'NamedImport', imported: importedName, local: localName });
127
- if (this.current.type === 'COMMA') this.eat('COMMA');
128
- }
129
- this.eat('RBRACE');
131
+ this.eat('RBRACE');
130
132
  }
131
133
  else if (this.current.type === 'IDENTIFIER') {
132
- const localName = this.current.value;
133
- this.eat('IDENTIFIER');
134
- specifiers.push({ type: 'DefaultImport', local: localName });
134
+ const localName = this.current.value;
135
+ this.eat('IDENTIFIER');
136
+ specifiers.push({ type: 'DefaultImport', local: localName });
135
137
  } else {
136
- throw new Error('Unexpected token in import statement');
138
+ throw new Error(`Unexpected token in import statement at line ${this.current.line}, column ${this.current.column}`);
137
139
  }
138
140
 
139
141
  this.eat('FROM');
140
142
  const pathToken = this.current;
141
- if (pathToken.type !== 'STRING') throw new Error('Expected string literal after from in import');
143
+ if (pathToken.type !== 'STRING') throw new Error(`Expected string literal after from in import at line ${this.current.line}, column ${this.current.column}`);
142
144
  this.eat('STRING');
143
145
 
144
146
  if (this.current.type === 'SEMICOLON') this.eat('SEMICOLON');
145
147
 
146
148
  return { type: 'ImportStatement', path: pathToken.value, specifiers };
147
- }
149
+ }
150
+
148
151
 
149
152
  forStatement() {
150
153
  this.eat('FOR');
@@ -224,23 +227,6 @@ class Parser {
224
227
  if (this.current.type === 'SEMICOLON') this.eat('SEMICOLON');
225
228
  return { type: 'ExpressionStatement', expression: expr };
226
229
  }
227
- parseTemplateLiteral() {
228
- const parts = [];
229
- while (true) {
230
- if (this.current.type === 'TEMPLATE_STRING') {
231
- parts.push({ type: 'Literal', value: this.current.value });
232
- this.eat('TEMPLATE_STRING');
233
- } else if (this.current.type === 'DOLLAR_LBRACE') {
234
- this.eat('DOLLAR_LBRACE');
235
- const expr = this.expression();
236
- parts.push(expr);
237
- this.eat('RBRACE');
238
- } else {
239
- break;
240
- }
241
- }
242
- return { type: 'TemplateLiteral', parts };
243
- }
244
230
 
245
231
  expression() {
246
232
  return this.assignment();
@@ -287,7 +273,7 @@ class Parser {
287
273
 
288
274
  equality() {
289
275
  let node = this.comparison();
290
- while (['EQEQ', 'NOTEQ', 'STRICT_EQ', 'STRICT_NOTEQ'].includes(this.current.type)) {
276
+ while (['EQEQ', 'NOTEQ'].includes(this.current.type)) {
291
277
  const op = this.current.type;
292
278
  this.eat(op);
293
279
  node = { type: 'BinaryExpression', operator: op, left: node, right: this.comparison() };
@@ -297,7 +283,7 @@ class Parser {
297
283
 
298
284
  comparison() {
299
285
  let node = this.term();
300
- while (['LT', 'LTE', 'GT', 'GTE', 'LSHIFT', 'RSHIFT'].includes(this.current.type)) {
286
+ while (['LT', 'LTE', 'GT', 'GTE'].includes(this.current.type)) {
301
287
  const op = this.current.type;
302
288
  this.eat(op);
303
289
  node = { type: 'BinaryExpression', operator: op, left: node, right: this.term() };
@@ -366,7 +352,7 @@ class Parser {
366
352
  }
367
353
  if (this.current.type === 'DOT') {
368
354
  this.eat('DOT');
369
- if (this.current.type !== 'IDENTIFIER') throw new Error('Expected property name after dot');
355
+ if (this.current.type !== 'IDENTIFIER') throw new Error(`Expected property name after dot at line ${this.current.line}, column ${this.current.column}`);
370
356
  const property = this.current.value;
371
357
  this.eat('IDENTIFIER');
372
358
  node = { type: 'MemberExpression', object: node, property };
@@ -388,15 +374,9 @@ class Parser {
388
374
 
389
375
  if (t.type === 'NUMBER') { this.eat('NUMBER'); return { type: 'Literal', value: t.value }; }
390
376
  if (t.type === 'STRING') { this.eat('STRING'); return { type: 'Literal', value: t.value }; }
391
- if (t.type === 'TEMPLATE_STRING') {
392
- return this.parseTemplateLiteral();
393
- }
394
-
395
-
396
377
  if (t.type === 'TRUE') { this.eat('TRUE'); return { type: 'Literal', value: true }; }
397
378
  if (t.type === 'FALSE') { this.eat('FALSE'); return { type: 'Literal', value: false }; }
398
379
  if (t.type === 'NULL') { this.eat('NULL'); return { type: 'Literal', value: null }; }
399
- if (t.type === 'UNDEFINED') { this.eat('UNDEFINED'); return { type: 'Literal', value: undefined }; }
400
380
 
401
381
  if (t.type === 'ASK') {
402
382
  this.eat('ASK');
@@ -447,7 +427,7 @@ class Parser {
447
427
  let key;
448
428
  if (this.current.type === 'STRING') { key = this.current.value; this.eat('STRING'); }
449
429
  else if (this.current.type === 'IDENTIFIER') { key = this.current.value; this.eat('IDENTIFIER'); }
450
- else throw new Error('Invalid object key');
430
+ else throw new Error(`Invalid object key at line ${this.current.line}, column ${this.current.column}`);
451
431
  this.eat('COLON');
452
432
  const value = this.expression();
453
433
  props.push({ key, value });
@@ -457,8 +437,8 @@ class Parser {
457
437
  return { type: 'ObjectExpression', props };
458
438
  }
459
439
 
460
- throw new Error(`Unexpected token in primary: ${t.type}`);
440
+ throw new Error(`Unexpected token in primary: ${t.type} at line ${this.current.line}, column ${this.current.column}`);
461
441
  }
462
442
  }
463
443
 
464
- module.exports = Parser;
444
+ module.exports = Parser;
package/src/starlight.js CHANGED
@@ -9,7 +9,7 @@ const Lexer = require('./lexer');
9
9
  const Parser = require('./parser');
10
10
  const Evaluator = require('./evaluator');
11
11
 
12
- const VERSION = '1.0.21';
12
+ const VERSION = '1.0.23';
13
13
 
14
14
  const COLOR = {
15
15
  reset: '\x1b[0m',