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 +72 -113
- package/package.json +1 -1
- package/src/starlight.js +72 -113
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.
|
|
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
|
-
|
|
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
|
-
|
|
2488
|
-
|
|
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>
|
|
2499
|
-
starlight -v
|
|
2500
|
-
starlight --help
|
|
2501
|
-
starlight --learn
|
|
2502
|
-
starlight --writedirectly
|
|
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
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
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
|
|
2549
|
-
const
|
|
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
|
|
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
|
-
|
|
2547
|
+
terminal: false
|
|
2558
2548
|
});
|
|
2559
2549
|
|
|
2560
|
-
|
|
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, () =>
|
|
2556
|
+
runFile(tempFile, true, () => savePrompt(lines));
|
|
2576
2557
|
return;
|
|
2577
2558
|
}
|
|
2578
2559
|
|
|
2579
2560
|
lines.push(line);
|
|
2580
|
-
|
|
2581
|
-
|
|
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
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
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
|
-
|
|
2599
|
-
|
|
2589
|
+
const name = readlineSync.question(
|
|
2590
|
+
COLOR.cyan + 'File name: ' + COLOR.reset
|
|
2591
|
+
).trim();
|
|
2600
2592
|
|
|
2601
|
-
|
|
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
|
-
|
|
2612
|
-
|
|
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
|
|
2617
|
-
|
|
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
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
console.error(COLOR.
|
|
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)
|
|
2618
|
+
if (isTemp) try { fs.unlinkSync(filePath); } catch {}
|
|
2661
2619
|
}
|
|
2662
|
-
|
|
2620
|
+
|
|
2621
|
+
if (!args[0].startsWith('--')) {
|
|
2663
2622
|
runFile(path.resolve(args[0]));
|
|
2664
2623
|
}
|
|
2665
2624
|
|
package/package.json
CHANGED
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
|
+
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
|
-
|
|
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
|
-
|
|
41
|
-
|
|
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>
|
|
52
|
-
starlight -v
|
|
53
|
-
starlight --help
|
|
54
|
-
starlight --learn
|
|
55
|
-
starlight --writedirectly
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
|
102
|
-
const
|
|
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
|
|
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
|
-
|
|
100
|
+
terminal: false
|
|
111
101
|
});
|
|
112
102
|
|
|
113
|
-
|
|
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, () =>
|
|
109
|
+
runFile(tempFile, true, () => savePrompt(lines));
|
|
129
110
|
return;
|
|
130
111
|
}
|
|
131
112
|
|
|
132
113
|
lines.push(line);
|
|
133
|
-
|
|
134
|
-
|
|
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
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
-
|
|
152
|
-
|
|
142
|
+
const name = readlineSync.question(
|
|
143
|
+
COLOR.cyan + 'File name: ' + COLOR.reset
|
|
144
|
+
).trim();
|
|
153
145
|
|
|
154
|
-
|
|
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
|
-
|
|
165
|
-
|
|
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
|
|
170
|
-
|
|
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
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
console.error(COLOR.
|
|
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)
|
|
171
|
+
if (isTemp) try { fs.unlinkSync(filePath); } catch {}
|
|
214
172
|
}
|
|
215
|
-
|
|
173
|
+
|
|
174
|
+
if (!args[0].startsWith('--')) {
|
|
216
175
|
runFile(path.resolve(args[0]));
|
|
217
176
|
}
|