starlight-cli 1.0.51 → 1.1.1

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
@@ -1388,13 +1388,25 @@ class Environment {
1388
1388
  return false;
1389
1389
  }
1390
1390
 
1391
- get(name, node, source) {
1391
+ get(name, node, source) {
1392
1392
  if (name in this.store) return this.store[name];
1393
1393
  if (this.parent) return this.parent.get(name, node, source);
1394
- throw new RuntimeError(`Undefined variable: ${name}`, node, source);
1394
+
1395
+ // Only suggest for top-level variable/function names
1396
+ let suggestion = null;
1397
+ if (node && source) {
1398
+ suggestion = this.suggest?.(name, this) || null;
1399
+ }
1400
+
1401
+ const message = suggestion
1402
+ ? `Undefined variable: "${name}". Did you mean "${suggestion}"?`
1403
+ : `Undefined variable: "${name}"`;
1404
+
1405
+ throw new RuntimeError(message, node, source);
1395
1406
  }
1396
1407
 
1397
1408
 
1409
+
1398
1410
  set(name, value) {
1399
1411
  if (name in this.store) { this.store[name] = value; return value; }
1400
1412
  if (this.parent && this.parent.has(name)) { return this.parent.set(name, value); }
@@ -1414,6 +1426,35 @@ class Evaluator {
1414
1426
  this.global = new Environment();
1415
1427
  this.setupBuiltins();
1416
1428
  }
1429
+ suggest(name, env) {
1430
+ // Collect all variable/function names from the environment chain
1431
+ const names = new Set();
1432
+ let current = env;
1433
+ while (current) {
1434
+ for (const key of Object.keys(current.store)) {
1435
+ names.add(key);
1436
+ }
1437
+ current = current.parent;
1438
+ }
1439
+
1440
+ let best = null;
1441
+ let bestScore = Infinity;
1442
+
1443
+ for (const item of names) {
1444
+ // simple edit distance approximation
1445
+ const dist = Math.abs(item.length - name.length) +
1446
+ [...name].filter((c, i) => c !== item[i]).length;
1447
+
1448
+ if (dist < bestScore && dist <= 2) { // max distance 2
1449
+ bestScore = dist;
1450
+ best = item;
1451
+ }
1452
+ }
1453
+
1454
+ return best;
1455
+ }
1456
+
1457
+
1417
1458
  formatValue(value, seen = new Set()) {
1418
1459
  // Circular reference handling
1419
1460
  if (typeof value === 'object' && value !== null) {
@@ -2187,6 +2228,13 @@ class Lexer {
2187
2228
  this.currentChar = input[0] || null;
2188
2229
  this.line = 1;
2189
2230
  this.column = 1;
2231
+ this.keywords = [
2232
+ 'let', 'sldeploy', 'if', 'else', 'while', 'for',
2233
+ 'break', 'continue', 'func', 'return',
2234
+ 'true', 'false', 'null',
2235
+ 'ask', 'define', 'import', 'from', 'as',
2236
+ 'async', 'await', 'new', 'in', 'do', 'track'
2237
+ ];
2190
2238
  }
2191
2239
 
2192
2240
 
@@ -2267,20 +2315,13 @@ class Lexer {
2267
2315
  this.advance();
2268
2316
  }
2269
2317
 
2270
- const keywords = [
2271
- 'let', 'sldeploy', 'if', 'else', 'while', 'for',
2272
- 'break', 'continue', 'func', 'return',
2273
- 'true', 'false', 'null',
2274
- 'ask', 'define', 'import', 'from', 'as',
2275
- 'async', 'await', 'new', 'in', 'do', 'track'
2276
- ];
2318
+ if (this.keywords.includes(result)) {
2319
+ return { type: result.toUpperCase(), value: result, line: startLine, column: startCol };
2320
+ }
2277
2321
 
2322
+ return { type: 'IDENTIFIER', value: result, line: startLine, column: startCol };
2278
2323
 
2279
- if (keywords.includes(result)) {
2280
- return { type: result.toUpperCase(), value: result, line: startLine, column: startCol };
2281
- }
2282
2324
 
2283
- return { type: 'IDENTIFIER', value: result, line: startLine, column: startCol };
2284
2325
  }
2285
2326
 
2286
2327
  string() {
@@ -2373,8 +2414,7 @@ if (char === '-' && next === '>') {
2373
2414
  }
2374
2415
  }
2375
2416
 
2376
- module.exports = Lexer;
2377
-
2417
+ module.exports = Lexer;
2378
2418
 
2379
2419
  /***/ }),
2380
2420
 
@@ -3319,7 +3359,7 @@ const Lexer = __nccwpck_require__(211);
3319
3359
  const Parser = __nccwpck_require__(222);
3320
3360
  const Evaluator = __nccwpck_require__(112);
3321
3361
 
3322
- const VERSION = '1.0.51';
3362
+ const VERSION = '1.1.1';
3323
3363
 
3324
3364
  const COLOR = {
3325
3365
  reset: '\x1b[0m',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starlight-cli",
3
- "version": "1.0.51",
3
+ "version": "1.1.1",
4
4
  "description": "Starlight Programming Language CLI",
5
5
  "bin": {
6
6
  "starlight": "index.js"
package/src/evaluator.js CHANGED
@@ -45,13 +45,25 @@ class Environment {
45
45
  return false;
46
46
  }
47
47
 
48
- get(name, node, source) {
48
+ get(name, node, source) {
49
49
  if (name in this.store) return this.store[name];
50
50
  if (this.parent) return this.parent.get(name, node, source);
51
- throw new RuntimeError(`Undefined variable: ${name}`, node, source);
51
+
52
+ // Only suggest for top-level variable/function names
53
+ let suggestion = null;
54
+ if (node && source) {
55
+ suggestion = this.suggest?.(name, this) || null;
56
+ }
57
+
58
+ const message = suggestion
59
+ ? `Undefined variable: "${name}". Did you mean "${suggestion}"?`
60
+ : `Undefined variable: "${name}"`;
61
+
62
+ throw new RuntimeError(message, node, source);
52
63
  }
53
64
 
54
65
 
66
+
55
67
  set(name, value) {
56
68
  if (name in this.store) { this.store[name] = value; return value; }
57
69
  if (this.parent && this.parent.has(name)) { return this.parent.set(name, value); }
@@ -71,6 +83,35 @@ class Evaluator {
71
83
  this.global = new Environment();
72
84
  this.setupBuiltins();
73
85
  }
86
+ suggest(name, env) {
87
+ // Collect all variable/function names from the environment chain
88
+ const names = new Set();
89
+ let current = env;
90
+ while (current) {
91
+ for (const key of Object.keys(current.store)) {
92
+ names.add(key);
93
+ }
94
+ current = current.parent;
95
+ }
96
+
97
+ let best = null;
98
+ let bestScore = Infinity;
99
+
100
+ for (const item of names) {
101
+ // simple edit distance approximation
102
+ const dist = Math.abs(item.length - name.length) +
103
+ [...name].filter((c, i) => c !== item[i]).length;
104
+
105
+ if (dist < bestScore && dist <= 2) { // max distance 2
106
+ bestScore = dist;
107
+ best = item;
108
+ }
109
+ }
110
+
111
+ return best;
112
+ }
113
+
114
+
74
115
  formatValue(value, seen = new Set()) {
75
116
  // Circular reference handling
76
117
  if (typeof value === 'object' && value !== null) {
package/src/lexer.js CHANGED
@@ -23,6 +23,13 @@ class Lexer {
23
23
  this.currentChar = input[0] || null;
24
24
  this.line = 1;
25
25
  this.column = 1;
26
+ this.keywords = [
27
+ 'let', 'sldeploy', 'if', 'else', 'while', 'for',
28
+ 'break', 'continue', 'func', 'return',
29
+ 'true', 'false', 'null',
30
+ 'ask', 'define', 'import', 'from', 'as',
31
+ 'async', 'await', 'new', 'in', 'do', 'track'
32
+ ];
26
33
  }
27
34
 
28
35
 
@@ -103,20 +110,13 @@ class Lexer {
103
110
  this.advance();
104
111
  }
105
112
 
106
- const keywords = [
107
- 'let', 'sldeploy', 'if', 'else', 'while', 'for',
108
- 'break', 'continue', 'func', 'return',
109
- 'true', 'false', 'null',
110
- 'ask', 'define', 'import', 'from', 'as',
111
- 'async', 'await', 'new', 'in', 'do', 'track'
112
- ];
113
+ if (this.keywords.includes(result)) {
114
+ return { type: result.toUpperCase(), value: result, line: startLine, column: startCol };
115
+ }
113
116
 
117
+ return { type: 'IDENTIFIER', value: result, line: startLine, column: startCol };
114
118
 
115
- if (keywords.includes(result)) {
116
- return { type: result.toUpperCase(), value: result, line: startLine, column: startCol };
117
- }
118
119
 
119
- return { type: 'IDENTIFIER', value: result, line: startLine, column: startCol };
120
120
  }
121
121
 
122
122
  string() {
@@ -209,4 +209,4 @@ if (char === '-' && next === '>') {
209
209
  }
210
210
  }
211
211
 
212
- module.exports = Lexer;
212
+ module.exports = Lexer;
package/src/program.sl ADDED
@@ -0,0 +1,2 @@
1
+ import color from "starlight-color"
2
+ sldeploy color.red("Hello")
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.51';
12
+ const VERSION = '1.1.1';
13
13
 
14
14
  const COLOR = {
15
15
  reset: '\x1b[0m',