starlight-cli 1.0.12 → 1.0.13

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
@@ -2449,12 +2449,14 @@ const fs = __nccwpck_require__(896);
2449
2449
  const path = __nccwpck_require__(928);
2450
2450
  const os = __nccwpck_require__(857);
2451
2451
  const { exec } = __nccwpck_require__(317);
2452
+ const readline = __nccwpck_require__(785);
2453
+ const readlineSync = __nccwpck_require__(552);
2452
2454
 
2453
2455
  const Lexer = __nccwpck_require__(211);
2454
2456
  const Parser = __nccwpck_require__(222);
2455
2457
  const Evaluator = __nccwpck_require__(112);
2456
2458
 
2457
- const VERSION = '1.0.12';
2459
+ const VERSION = '1.0.13';
2458
2460
 
2459
2461
  const COLOR = {
2460
2462
  reset: '\x1b[0m',
@@ -2464,30 +2466,38 @@ const COLOR = {
2464
2466
  blue: '\x1b[34m',
2465
2467
  cyan: '\x1b[36m',
2466
2468
  gray: '\x1b[90m',
2467
- green: '\x1b[32m'
2469
+ green: '\x1b[32m',
2470
+ magenta: '\x1b[35m'
2468
2471
  };
2469
2472
 
2473
+
2470
2474
  function waitAndExit(code = 0) {
2475
+ try { process.stdin.setRawMode(true); } catch {}
2471
2476
  console.error(COLOR.gray + '\nPress any key to exit...' + COLOR.reset);
2472
- process.stdin.setRawMode(true);
2473
2477
  process.stdin.resume();
2474
2478
  process.stdin.once('data', () => process.exit(code));
2475
2479
  }
2476
2480
 
2477
2481
  function fatal(msg) {
2478
2482
  console.error(COLOR.red + msg + COLOR.reset);
2479
- return waitAndExit(1);
2483
+ waitAndExit(1);
2480
2484
  }
2481
2485
 
2482
- function printSourceContext(code, line, column) {
2483
- const lines = code.split('\n');
2484
- const srcLine = lines[line - 1];
2485
- if (!srcLine) return;
2486
2486
 
2487
- console.error(COLOR.gray + `\n ${line} | ` + COLOR.reset + srcLine);
2488
- console.error(COLOR.gray + ' | ' + COLOR.red + ' '.repeat(Math.max(0, column - 1)) + '^' + COLOR.reset);
2487
+ function highlightCode(line) {
2488
+ return line
2489
+ // strings
2490
+ .replace(/"(?:\\.|[^"])*"/g, m => COLOR.yellow + m + COLOR.reset)
2491
+ // numbers
2492
+ .replace(/\b\d+(\.\d+)?\b/g, m => COLOR.magenta + m + COLOR.reset)
2493
+ // keywords
2494
+ .replace(
2495
+ /\b(sldeploy|import|from|const|let|var|if|else|for|while|func|return|break|continue|define|ask)\b/g,
2496
+ m => COLOR.blue + m + COLOR.reset
2497
+ );
2489
2498
  }
2490
2499
 
2500
+
2491
2501
  const args = process.argv.slice(2);
2492
2502
 
2493
2503
  if (args.length === 0) {
@@ -2495,12 +2505,11 @@ if (args.length === 0) {
2495
2505
  Starlight Programming Language
2496
2506
 
2497
2507
  Usage:
2498
- starlight <file.sl> Run a Starlight program
2499
- starlight -v Show version
2500
- starlight --help Show help
2501
- starlight --learn Open learning guide
2502
- starlight --writedirectly Write and run temporary code
2503
- starlight --viewfilelist View SL files in a folder
2508
+ starlight <file.sl>
2509
+ starlight -v
2510
+ starlight --help
2511
+ starlight --learn
2512
+ starlight --writedirectly
2504
2513
  `);
2505
2514
  process.exit(0);
2506
2515
  }
@@ -2512,154 +2521,104 @@ if (args[0] === '-v' || args[0] === '--version') {
2512
2521
 
2513
2522
  if (args[0] === '--help') {
2514
2523
  console.log(`
2515
- Starlight CLI Help
2516
-
2517
- Commands:
2518
- starlight file.sl Run a Starlight program
2519
- starlight -v Show version
2520
- starlight --learn Open learning guide
2521
- starlight --writedirectly Write & run temporary code
2522
- starlight --viewfilelist View SL files in a folder
2524
+ starlight <file.sl> Run file
2525
+ starlight --writedirectly Interactive editor
2526
+ starlight --learn Learning guide
2523
2527
  `);
2524
2528
  process.exit(0);
2525
2529
  }
2526
2530
 
2527
2531
  if (args[0] === '--learn') {
2528
- console.log(COLOR.cyan + 'Opening Starlight Learning Guide...' + COLOR.reset);
2529
2532
  exec('start https://programming-lang.pages.dev/learning-guide');
2530
2533
  process.exit(0);
2531
2534
  }
2532
2535
 
2533
- if (args[0] === '--viewfilelist') {
2534
- const readlineSync = __nccwpck_require__(552);
2535
- const folderPath = readlineSync.question(COLOR.cyan + 'Paste folder path to search .sl files: ' + COLOR.reset).trim();
2536
- if (!folderPath) return waitAndExit(0);
2537
- if (!fs.existsSync(folderPath) || !fs.lstatSync(folderPath).isDirectory()) return fatal('Invalid folder path.');
2538
- const files = fs.readdirSync(folderPath).filter(f => f.endsWith('.sl'));
2539
- if (files.length === 0) console.log(COLOR.yellow + 'No .sl files found in folder.' + COLOR.reset);
2540
- else {
2541
- console.log(COLOR.green + `Found ${files.length} .sl files:` + COLOR.reset);
2542
- files.forEach(f => console.log(' ' + f));
2543
- }
2544
- return waitAndExit(0);
2545
- }
2546
2536
 
2547
2537
  if (args[0] === '--writedirectly') {
2548
- const readline = __nccwpck_require__(785);
2549
- const tempFile = path.join(os.tmpdir(), `starlight-temp-${Date.now()}.sl`);
2538
+ const tempFile = path.join(os.tmpdir(), `starlight-${Date.now()}.sl`);
2539
+ const lines = [];
2550
2540
 
2551
2541
  console.log(COLOR.green + 'Interactive Starlight Editor' + COLOR.reset);
2552
- console.log(COLOR.gray + 'Type your code. Enter ":run" on a new line to execute.\n' + COLOR.reset);
2542
+ console.log(COLOR.gray + 'Type code. Use :run to execute.\n' + COLOR.reset);
2553
2543
 
2554
2544
  const rl = readline.createInterface({
2555
2545
  input: process.stdin,
2556
2546
  output: process.stdout,
2557
- prompt: COLOR.cyan + '> ' + COLOR.reset
2547
+ terminal: false
2558
2548
  });
2559
2549
 
2560
- let lines = [];
2561
-
2562
- function highlightCode(line) {
2563
- // Strings first
2564
- line = line.replace(/"(.*?)"/g, COLOR.yellow + '"$1"' + COLOR.reset);
2565
- // Keywords
2566
- line = line.replace(/\b(sldeploy|import|from|const|let|var|if|else|for|while|func|return|break|continue|define|ask)\b/g, COLOR.blue + '$1' + COLOR.reset);
2567
- return line;
2568
- }
2550
+ process.stdout.write(COLOR.cyan + '> ' + COLOR.reset);
2569
2551
 
2570
- rl.prompt();
2571
2552
  rl.on('line', (line) => {
2572
2553
  if (line.trim() === ':run') {
2573
2554
  rl.close();
2574
2555
  fs.writeFileSync(tempFile, lines.join('\n'), 'utf8');
2575
- runFile(tempFile, true, () => saveTempFilePrompt(lines));
2556
+ runFile(tempFile, true, () => savePrompt(lines));
2576
2557
  return;
2577
2558
  }
2578
2559
 
2579
2560
  lines.push(line);
2580
- console.log(COLOR.cyan + '> ' + COLOR.reset + highlightCode(line));
2581
- rl.prompt();
2561
+ process.stdout.write(
2562
+ COLOR.cyan + '> ' + COLOR.reset + highlightCode(line) + '\n'
2563
+ );
2582
2564
  });
2583
2565
 
2584
2566
  return;
2585
2567
  }
2586
2568
 
2587
- function saveTempFilePrompt(lines) {
2588
- const readlineSync = __nccwpck_require__(552);
2589
- const saveChoice = readlineSync.question(COLOR.cyan + 'Do you want to save this code? (y/n): ' + COLOR.reset).trim().toLowerCase();
2590
- if (saveChoice !== 'y') return waitAndExit(0);
2591
2569
 
2592
- let folderPath = readlineSync.question(COLOR.cyan + 'Paste folder path to save (C:/ or D:/...): ' + COLOR.reset).trim();
2593
- if (!folderPath || !fs.existsSync(folderPath) || !fs.lstatSync(folderPath).isDirectory()) {
2594
- console.log(COLOR.yellow + 'Skipping save.' + COLOR.reset);
2570
+ function savePrompt(lines) {
2571
+ try { process.stdin.setRawMode(false); } catch {}
2572
+
2573
+ const save = readlineSync
2574
+ .question(COLOR.cyan + 'Do you want to save this code? (y/n): ' + COLOR.reset)
2575
+ .trim()
2576
+ .toLowerCase();
2577
+
2578
+ if (save !== 'y') return waitAndExit(0);
2579
+
2580
+ const dir = readlineSync.question(
2581
+ COLOR.cyan + 'Folder path: ' + COLOR.reset
2582
+ ).trim();
2583
+
2584
+ if (!fs.existsSync(dir)) {
2585
+ console.log(COLOR.yellow + 'Invalid folder.' + COLOR.reset);
2595
2586
  return waitAndExit(0);
2596
2587
  }
2597
2588
 
2598
- let fileName = readlineSync.question(COLOR.cyan + 'Enter file name (without extension): ' + COLOR.reset).trim();
2599
- if (!fileName) return console.log(COLOR.yellow + 'Skipping save.' + COLOR.reset);
2589
+ const name = readlineSync.question(
2590
+ COLOR.cyan + 'File name: ' + COLOR.reset
2591
+ ).trim();
2600
2592
 
2601
- let fullPath = path.join(folderPath, fileName.endsWith('.sl') ? fileName : fileName + '.sl');
2602
- while (fs.existsSync(fullPath)) {
2603
- fileName = readlineSync.question(COLOR.red + 'File exists! Enter a new name (or leave blank to cancel): ' + COLOR.reset).trim();
2604
- if (!fileName) {
2605
- console.log(COLOR.yellow + 'Skipping save.' + COLOR.reset);
2606
- return waitAndExit(0);
2607
- }
2608
- fullPath = path.join(folderPath, fileName.endsWith('.sl') ? fileName : fileName + '.sl');
2609
- }
2593
+ if (!name) return waitAndExit(0);
2610
2594
 
2611
- fs.writeFileSync(fullPath, lines.join('\n'), 'utf8');
2612
- console.log(COLOR.green + `Saved to ${fullPath}` + COLOR.reset);
2595
+ const file = path.join(dir, name.endsWith('.sl') ? name : name + '.sl');
2596
+ fs.writeFileSync(file, lines.join('\n'), 'utf8');
2597
+
2598
+ console.log(COLOR.green + `Saved to ${file}` + COLOR.reset);
2613
2599
  waitAndExit(0);
2614
2600
  }
2615
2601
 
2616
- function runFile(filePath, isTemp = false, callback = null) {
2617
- if (!fs.existsSync(filePath)) return fatal(`File not found: ${filePath}`);
2618
-
2619
- let code;
2620
- try { code = fs.readFileSync(filePath, 'utf-8'); }
2621
- catch (err) { return fatal(`Failed to read file: ${err.message}`); }
2602
+ function runFile(filePath, isTemp = false, callback) {
2603
+ const code = fs.readFileSync(filePath, 'utf8');
2622
2604
 
2623
- let tokens;
2624
2605
  try {
2625
2606
  const lexer = new Lexer(code);
2626
- tokens = lexer.getTokens();
2627
- } catch (err) {
2628
- console.error(COLOR.red + COLOR.bold + 'Starlight Lexer Error' + COLOR.reset);
2629
- console.error(COLOR.cyan + `File: ${filePath}` + COLOR.reset);
2630
- console.error(COLOR.yellow + `Message: ${err.message}` + COLOR.reset);
2631
- if (err.line && err.column) printSourceContext(code, err.line, err.column);
2632
- return waitAndExit(1);
2633
- }
2634
-
2635
- let ast;
2636
- try {
2637
- const parser = new Parser(tokens);
2638
- ast = parser.parse();
2639
- } catch (err) {
2640
- console.error(COLOR.red + COLOR.bold + 'Starlight Parser Error' + COLOR.reset);
2641
- console.error(COLOR.cyan + `File: ${filePath}` + COLOR.reset);
2642
- console.error(COLOR.yellow + `Message: ${err.message}` + COLOR.reset);
2643
- if (err.token && err.token.line && err.token.column) printSourceContext(code, err.token.line, err.token.column);
2644
- return waitAndExit(1);
2645
- }
2646
-
2647
- try {
2648
- const evaluator = new Evaluator();
2649
- evaluator.evaluate(ast);
2650
- } catch (err) {
2651
- console.error(COLOR.red + COLOR.bold + 'Starlight Runtime Error' + COLOR.reset);
2652
- console.error(COLOR.cyan + `File: ${filePath}` + COLOR.reset);
2653
- console.error(COLOR.yellow + `Message: ${err.message}` + COLOR.reset);
2654
- if (err.line && err.column) printSourceContext(code, err.line, err.column);
2607
+ const parser = new Parser(lexer.getTokens());
2608
+ const ast = parser.parse();
2609
+ new Evaluator().evaluate(ast);
2610
+ } catch (e) {
2611
+ console.error(COLOR.red + e.message + COLOR.reset);
2655
2612
  return waitAndExit(1);
2656
2613
  }
2657
2614
 
2658
2615
  console.log(COLOR.green + '\nProgram finished successfully.' + COLOR.reset);
2616
+
2659
2617
  if (callback) callback();
2660
- if (isTemp) { try { fs.unlinkSync(filePath); } catch {} }
2618
+ if (isTemp) try { fs.unlinkSync(filePath); } catch {}
2661
2619
  }
2662
- if (!['--writedirectly', '--viewfilelist', '--learn', '--help', '-v', '--version'].includes(args[0])) {
2620
+
2621
+ if (!args[0].startsWith('--')) {
2663
2622
  runFile(path.resolve(args[0]));
2664
2623
  }
2665
2624
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starlight-cli",
3
- "version": "1.0.12",
3
+ "version": "1.0.13",
4
4
  "description": "Starlight Programming Language CLI",
5
5
  "bin": {
6
6
  "starlight": "index.js"
package/src/starlight.js CHANGED
@@ -2,12 +2,14 @@ const fs = require('fs');
2
2
  const path = require('path');
3
3
  const os = require('os');
4
4
  const { exec } = require('child_process');
5
+ const readline = require('readline');
6
+ const readlineSync = require('readline-sync');
5
7
 
6
8
  const Lexer = require('./lexer');
7
9
  const Parser = require('./parser');
8
10
  const Evaluator = require('./evaluator');
9
11
 
10
- const VERSION = '1.0.12';
12
+ const VERSION = '1.0.13';
11
13
 
12
14
  const COLOR = {
13
15
  reset: '\x1b[0m',
@@ -17,30 +19,38 @@ const COLOR = {
17
19
  blue: '\x1b[34m',
18
20
  cyan: '\x1b[36m',
19
21
  gray: '\x1b[90m',
20
- green: '\x1b[32m'
22
+ green: '\x1b[32m',
23
+ magenta: '\x1b[35m'
21
24
  };
22
25
 
26
+
23
27
  function waitAndExit(code = 0) {
28
+ try { process.stdin.setRawMode(true); } catch {}
24
29
  console.error(COLOR.gray + '\nPress any key to exit...' + COLOR.reset);
25
- process.stdin.setRawMode(true);
26
30
  process.stdin.resume();
27
31
  process.stdin.once('data', () => process.exit(code));
28
32
  }
29
33
 
30
34
  function fatal(msg) {
31
35
  console.error(COLOR.red + msg + COLOR.reset);
32
- return waitAndExit(1);
36
+ waitAndExit(1);
33
37
  }
34
38
 
35
- function printSourceContext(code, line, column) {
36
- const lines = code.split('\n');
37
- const srcLine = lines[line - 1];
38
- if (!srcLine) return;
39
39
 
40
- console.error(COLOR.gray + `\n ${line} | ` + COLOR.reset + srcLine);
41
- console.error(COLOR.gray + ' | ' + COLOR.red + ' '.repeat(Math.max(0, column - 1)) + '^' + COLOR.reset);
40
+ function highlightCode(line) {
41
+ return line
42
+ // strings
43
+ .replace(/"(?:\\.|[^"])*"/g, m => COLOR.yellow + m + COLOR.reset)
44
+ // numbers
45
+ .replace(/\b\d+(\.\d+)?\b/g, m => COLOR.magenta + m + COLOR.reset)
46
+ // keywords
47
+ .replace(
48
+ /\b(sldeploy|import|from|const|let|var|if|else|for|while|func|return|break|continue|define|ask)\b/g,
49
+ m => COLOR.blue + m + COLOR.reset
50
+ );
42
51
  }
43
52
 
53
+
44
54
  const args = process.argv.slice(2);
45
55
 
46
56
  if (args.length === 0) {
@@ -48,12 +58,11 @@ if (args.length === 0) {
48
58
  Starlight Programming Language
49
59
 
50
60
  Usage:
51
- starlight <file.sl> Run a Starlight program
52
- starlight -v Show version
53
- starlight --help Show help
54
- starlight --learn Open learning guide
55
- starlight --writedirectly Write and run temporary code
56
- starlight --viewfilelist View SL files in a folder
61
+ starlight <file.sl>
62
+ starlight -v
63
+ starlight --help
64
+ starlight --learn
65
+ starlight --writedirectly
57
66
  `);
58
67
  process.exit(0);
59
68
  }
@@ -65,153 +74,103 @@ if (args[0] === '-v' || args[0] === '--version') {
65
74
 
66
75
  if (args[0] === '--help') {
67
76
  console.log(`
68
- Starlight CLI Help
69
-
70
- Commands:
71
- starlight file.sl Run a Starlight program
72
- starlight -v Show version
73
- starlight --learn Open learning guide
74
- starlight --writedirectly Write & run temporary code
75
- starlight --viewfilelist View SL files in a folder
77
+ starlight <file.sl> Run file
78
+ starlight --writedirectly Interactive editor
79
+ starlight --learn Learning guide
76
80
  `);
77
81
  process.exit(0);
78
82
  }
79
83
 
80
84
  if (args[0] === '--learn') {
81
- console.log(COLOR.cyan + 'Opening Starlight Learning Guide...' + COLOR.reset);
82
85
  exec('start https://programming-lang.pages.dev/learning-guide');
83
86
  process.exit(0);
84
87
  }
85
88
 
86
- if (args[0] === '--viewfilelist') {
87
- const readlineSync = require('readline-sync');
88
- const folderPath = readlineSync.question(COLOR.cyan + 'Paste folder path to search .sl files: ' + COLOR.reset).trim();
89
- if (!folderPath) return waitAndExit(0);
90
- if (!fs.existsSync(folderPath) || !fs.lstatSync(folderPath).isDirectory()) return fatal('Invalid folder path.');
91
- const files = fs.readdirSync(folderPath).filter(f => f.endsWith('.sl'));
92
- if (files.length === 0) console.log(COLOR.yellow + 'No .sl files found in folder.' + COLOR.reset);
93
- else {
94
- console.log(COLOR.green + `Found ${files.length} .sl files:` + COLOR.reset);
95
- files.forEach(f => console.log(' ' + f));
96
- }
97
- return waitAndExit(0);
98
- }
99
89
 
100
90
  if (args[0] === '--writedirectly') {
101
- const readline = require('readline');
102
- const tempFile = path.join(os.tmpdir(), `starlight-temp-${Date.now()}.sl`);
91
+ const tempFile = path.join(os.tmpdir(), `starlight-${Date.now()}.sl`);
92
+ const lines = [];
103
93
 
104
94
  console.log(COLOR.green + 'Interactive Starlight Editor' + COLOR.reset);
105
- console.log(COLOR.gray + 'Type your code. Enter ":run" on a new line to execute.\n' + COLOR.reset);
95
+ console.log(COLOR.gray + 'Type code. Use :run to execute.\n' + COLOR.reset);
106
96
 
107
97
  const rl = readline.createInterface({
108
98
  input: process.stdin,
109
99
  output: process.stdout,
110
- prompt: COLOR.cyan + '> ' + COLOR.reset
100
+ terminal: false
111
101
  });
112
102
 
113
- let lines = [];
114
-
115
- function highlightCode(line) {
116
- // Strings first
117
- line = line.replace(/"(.*?)"/g, COLOR.yellow + '"$1"' + COLOR.reset);
118
- // Keywords
119
- line = line.replace(/\b(sldeploy|import|from|const|let|var|if|else|for|while|func|return|break|continue|define|ask)\b/g, COLOR.blue + '$1' + COLOR.reset);
120
- return line;
121
- }
103
+ process.stdout.write(COLOR.cyan + '> ' + COLOR.reset);
122
104
 
123
- rl.prompt();
124
105
  rl.on('line', (line) => {
125
106
  if (line.trim() === ':run') {
126
107
  rl.close();
127
108
  fs.writeFileSync(tempFile, lines.join('\n'), 'utf8');
128
- runFile(tempFile, true, () => saveTempFilePrompt(lines));
109
+ runFile(tempFile, true, () => savePrompt(lines));
129
110
  return;
130
111
  }
131
112
 
132
113
  lines.push(line);
133
- console.log(COLOR.cyan + '> ' + COLOR.reset + highlightCode(line));
134
- rl.prompt();
114
+ process.stdout.write(
115
+ COLOR.cyan + '> ' + COLOR.reset + highlightCode(line) + '\n'
116
+ );
135
117
  });
136
118
 
137
119
  return;
138
120
  }
139
121
 
140
- function saveTempFilePrompt(lines) {
141
- const readlineSync = require('readline-sync');
142
- const saveChoice = readlineSync.question(COLOR.cyan + 'Do you want to save this code? (y/n): ' + COLOR.reset).trim().toLowerCase();
143
- if (saveChoice !== 'y') return waitAndExit(0);
144
122
 
145
- let folderPath = readlineSync.question(COLOR.cyan + 'Paste folder path to save (C:/ or D:/...): ' + COLOR.reset).trim();
146
- if (!folderPath || !fs.existsSync(folderPath) || !fs.lstatSync(folderPath).isDirectory()) {
147
- console.log(COLOR.yellow + 'Skipping save.' + COLOR.reset);
123
+ function savePrompt(lines) {
124
+ try { process.stdin.setRawMode(false); } catch {}
125
+
126
+ const save = readlineSync
127
+ .question(COLOR.cyan + 'Do you want to save this code? (y/n): ' + COLOR.reset)
128
+ .trim()
129
+ .toLowerCase();
130
+
131
+ if (save !== 'y') return waitAndExit(0);
132
+
133
+ const dir = readlineSync.question(
134
+ COLOR.cyan + 'Folder path: ' + COLOR.reset
135
+ ).trim();
136
+
137
+ if (!fs.existsSync(dir)) {
138
+ console.log(COLOR.yellow + 'Invalid folder.' + COLOR.reset);
148
139
  return waitAndExit(0);
149
140
  }
150
141
 
151
- let fileName = readlineSync.question(COLOR.cyan + 'Enter file name (without extension): ' + COLOR.reset).trim();
152
- if (!fileName) return console.log(COLOR.yellow + 'Skipping save.' + COLOR.reset);
142
+ const name = readlineSync.question(
143
+ COLOR.cyan + 'File name: ' + COLOR.reset
144
+ ).trim();
153
145
 
154
- let fullPath = path.join(folderPath, fileName.endsWith('.sl') ? fileName : fileName + '.sl');
155
- while (fs.existsSync(fullPath)) {
156
- fileName = readlineSync.question(COLOR.red + 'File exists! Enter a new name (or leave blank to cancel): ' + COLOR.reset).trim();
157
- if (!fileName) {
158
- console.log(COLOR.yellow + 'Skipping save.' + COLOR.reset);
159
- return waitAndExit(0);
160
- }
161
- fullPath = path.join(folderPath, fileName.endsWith('.sl') ? fileName : fileName + '.sl');
162
- }
146
+ if (!name) return waitAndExit(0);
163
147
 
164
- fs.writeFileSync(fullPath, lines.join('\n'), 'utf8');
165
- console.log(COLOR.green + `Saved to ${fullPath}` + COLOR.reset);
148
+ const file = path.join(dir, name.endsWith('.sl') ? name : name + '.sl');
149
+ fs.writeFileSync(file, lines.join('\n'), 'utf8');
150
+
151
+ console.log(COLOR.green + `Saved to ${file}` + COLOR.reset);
166
152
  waitAndExit(0);
167
153
  }
168
154
 
169
- function runFile(filePath, isTemp = false, callback = null) {
170
- if (!fs.existsSync(filePath)) return fatal(`File not found: ${filePath}`);
171
-
172
- let code;
173
- try { code = fs.readFileSync(filePath, 'utf-8'); }
174
- catch (err) { return fatal(`Failed to read file: ${err.message}`); }
155
+ function runFile(filePath, isTemp = false, callback) {
156
+ const code = fs.readFileSync(filePath, 'utf8');
175
157
 
176
- let tokens;
177
158
  try {
178
159
  const lexer = new Lexer(code);
179
- tokens = lexer.getTokens();
180
- } catch (err) {
181
- console.error(COLOR.red + COLOR.bold + 'Starlight Lexer Error' + COLOR.reset);
182
- console.error(COLOR.cyan + `File: ${filePath}` + COLOR.reset);
183
- console.error(COLOR.yellow + `Message: ${err.message}` + COLOR.reset);
184
- if (err.line && err.column) printSourceContext(code, err.line, err.column);
185
- return waitAndExit(1);
186
- }
187
-
188
- let ast;
189
- try {
190
- const parser = new Parser(tokens);
191
- ast = parser.parse();
192
- } catch (err) {
193
- console.error(COLOR.red + COLOR.bold + 'Starlight Parser Error' + COLOR.reset);
194
- console.error(COLOR.cyan + `File: ${filePath}` + COLOR.reset);
195
- console.error(COLOR.yellow + `Message: ${err.message}` + COLOR.reset);
196
- if (err.token && err.token.line && err.token.column) printSourceContext(code, err.token.line, err.token.column);
197
- return waitAndExit(1);
198
- }
199
-
200
- try {
201
- const evaluator = new Evaluator();
202
- evaluator.evaluate(ast);
203
- } catch (err) {
204
- console.error(COLOR.red + COLOR.bold + 'Starlight Runtime Error' + COLOR.reset);
205
- console.error(COLOR.cyan + `File: ${filePath}` + COLOR.reset);
206
- console.error(COLOR.yellow + `Message: ${err.message}` + COLOR.reset);
207
- if (err.line && err.column) printSourceContext(code, err.line, err.column);
160
+ const parser = new Parser(lexer.getTokens());
161
+ const ast = parser.parse();
162
+ new Evaluator().evaluate(ast);
163
+ } catch (e) {
164
+ console.error(COLOR.red + e.message + COLOR.reset);
208
165
  return waitAndExit(1);
209
166
  }
210
167
 
211
168
  console.log(COLOR.green + '\nProgram finished successfully.' + COLOR.reset);
169
+
212
170
  if (callback) callback();
213
- if (isTemp) { try { fs.unlinkSync(filePath); } catch {} }
171
+ if (isTemp) try { fs.unlinkSync(filePath); } catch {}
214
172
  }
215
- if (!['--writedirectly', '--viewfilelist', '--learn', '--help', '-v', '--version'].includes(args[0])) {
173
+
174
+ if (!args[0].startsWith('--')) {
216
175
  runFile(path.resolve(args[0]));
217
176
  }