stone-lang 0.1.0
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/README.md +52 -0
- package/StoneEngine.js +879 -0
- package/StoneEngineService.js +1727 -0
- package/adapters/FileSystemAdapter.js +230 -0
- package/adapters/OutputAdapter.js +208 -0
- package/adapters/index.js +6 -0
- package/cli/CLIOutputAdapter.js +196 -0
- package/cli/DaemonClient.js +349 -0
- package/cli/JSONOutputAdapter.js +135 -0
- package/cli/ReplSession.js +567 -0
- package/cli/ViewerServer.js +590 -0
- package/cli/commands/check.js +84 -0
- package/cli/commands/daemon.js +189 -0
- package/cli/commands/kill.js +66 -0
- package/cli/commands/package.js +713 -0
- package/cli/commands/ps.js +65 -0
- package/cli/commands/run.js +537 -0
- package/cli/entry.js +169 -0
- package/cli/index.js +14 -0
- package/cli/stonec.js +358 -0
- package/cli/test-compiler.js +181 -0
- package/cli/viewer/index.html +495 -0
- package/daemon/IPCServer.js +455 -0
- package/daemon/ProcessManager.js +327 -0
- package/daemon/ProcessRunner.js +307 -0
- package/daemon/daemon.js +398 -0
- package/daemon/index.js +16 -0
- package/frontend/analysis/index.js +5 -0
- package/frontend/analysis/livenessAnalyzer.js +568 -0
- package/frontend/analysis/treeShaker.js +265 -0
- package/frontend/index.js +20 -0
- package/frontend/parsing/astBuilder.js +2196 -0
- package/frontend/parsing/index.js +7 -0
- package/frontend/parsing/sonParser.js +592 -0
- package/frontend/parsing/stoneAstTypes.js +703 -0
- package/frontend/parsing/terminal-registry.js +435 -0
- package/frontend/parsing/tokenizer.js +692 -0
- package/frontend/type-checker/OverloadedFunctionType.js +43 -0
- package/frontend/type-checker/TypeEnvironment.js +165 -0
- package/frontend/type-checker/bidirectionalInference.js +149 -0
- package/frontend/type-checker/index.js +10 -0
- package/frontend/type-checker/moduleAnalysis.js +248 -0
- package/frontend/type-checker/operatorMappings.js +35 -0
- package/frontend/type-checker/overloadResolution.js +605 -0
- package/frontend/type-checker/typeChecker.js +452 -0
- package/frontend/type-checker/typeCompatibility.js +389 -0
- package/frontend/type-checker/visitors/controlFlow.js +483 -0
- package/frontend/type-checker/visitors/functions.js +604 -0
- package/frontend/type-checker/visitors/index.js +38 -0
- package/frontend/type-checker/visitors/literals.js +341 -0
- package/frontend/type-checker/visitors/modules.js +159 -0
- package/frontend/type-checker/visitors/operators.js +109 -0
- package/frontend/type-checker/visitors/statements.js +768 -0
- package/frontend/types/index.js +5 -0
- package/frontend/types/operatorMap.js +134 -0
- package/frontend/types/types.js +2046 -0
- package/frontend/utils/errorCollector.js +244 -0
- package/frontend/utils/index.js +5 -0
- package/frontend/utils/moduleResolver.js +479 -0
- package/package.json +50 -0
- package/packages/browserCache.js +359 -0
- package/packages/fetcher.js +236 -0
- package/packages/index.js +130 -0
- package/packages/lockfile.js +271 -0
- package/packages/manifest.js +291 -0
- package/packages/packageResolver.js +356 -0
- package/packages/resolver.js +310 -0
- package/packages/semver.js +635 -0
package/cli/entry.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Stone CLI - Command-line interface for Stone language
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* stone run <file.stn> Execute a Stone script
|
|
8
|
+
* stone check <file.stn> Type-check without executing
|
|
9
|
+
* stone ps List running processes
|
|
10
|
+
* stone kill <id> Kill a running process
|
|
11
|
+
* stone daemon <action> Manage the daemon
|
|
12
|
+
*
|
|
13
|
+
* Package management:
|
|
14
|
+
* stone init Create a new package.son
|
|
15
|
+
* stone install Install dependencies from package.son
|
|
16
|
+
* stone install <pkg> --source Add and install a package
|
|
17
|
+
* stone install -g <pkg> Install package globally
|
|
18
|
+
* stone remove <pkg> Remove a package
|
|
19
|
+
* stone update Update dependencies
|
|
20
|
+
* stone list List installed packages
|
|
21
|
+
*
|
|
22
|
+
* Run `stone --help` for full usage information.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { Command } from 'commander';
|
|
26
|
+
import { runCommand } from './commands/run.js';
|
|
27
|
+
import { checkCommand } from './commands/check.js';
|
|
28
|
+
import { psCommand } from './commands/ps.js';
|
|
29
|
+
import { killCommand } from './commands/kill.js';
|
|
30
|
+
import { daemonCommand } from './commands/daemon.js';
|
|
31
|
+
import {
|
|
32
|
+
initCommand,
|
|
33
|
+
installCommand,
|
|
34
|
+
removeCommand,
|
|
35
|
+
updateCommand,
|
|
36
|
+
listCommand,
|
|
37
|
+
} from './commands/package.js';
|
|
38
|
+
|
|
39
|
+
const VERSION = '0.1.0';
|
|
40
|
+
|
|
41
|
+
const program = new Command();
|
|
42
|
+
|
|
43
|
+
program
|
|
44
|
+
.name('stone')
|
|
45
|
+
.description('Stone language command-line interface')
|
|
46
|
+
.version(VERSION, '-v, --version', 'Show version number');
|
|
47
|
+
|
|
48
|
+
// run command
|
|
49
|
+
program
|
|
50
|
+
.command('run <file>')
|
|
51
|
+
.description('Execute a Stone script')
|
|
52
|
+
.option('--json', 'Output JSON Lines for IDE integration')
|
|
53
|
+
.option('--headless', 'No browser for graphs, export to files')
|
|
54
|
+
.option('--no-serve', 'Exit immediately after execution (don\'t keep server running)')
|
|
55
|
+
.option('--verbose', 'Show detailed execution info')
|
|
56
|
+
.option('-q, --quiet', 'Suppress non-essential output')
|
|
57
|
+
.option('--ast', 'Print AST and exit')
|
|
58
|
+
.option('--bytecode', 'Print bytecode and exit')
|
|
59
|
+
.option('--no-daemon', 'Skip daemon, use direct execution')
|
|
60
|
+
.action((file, options) => {
|
|
61
|
+
runCommand(file, options);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// check command
|
|
65
|
+
program
|
|
66
|
+
.command('check <file>')
|
|
67
|
+
.description('Type-check a Stone script without executing')
|
|
68
|
+
.option('--json', 'Output JSON')
|
|
69
|
+
.option('--verbose', 'Show detailed info')
|
|
70
|
+
.action((file, options) => {
|
|
71
|
+
checkCommand(file, options);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// ps command
|
|
75
|
+
program
|
|
76
|
+
.command('ps')
|
|
77
|
+
.description('List running Stone processes')
|
|
78
|
+
.option('--mine', 'Only show my processes')
|
|
79
|
+
.option('--status <status>', 'Filter by status (running, completed, failed)')
|
|
80
|
+
.option('--json', 'Output JSON')
|
|
81
|
+
.action((options) => {
|
|
82
|
+
psCommand(options);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// kill command
|
|
86
|
+
program
|
|
87
|
+
.command('kill <processId>')
|
|
88
|
+
.description('Kill a running Stone process')
|
|
89
|
+
.option('--json', 'Output JSON')
|
|
90
|
+
.action((processId, options) => {
|
|
91
|
+
killCommand(processId, options);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// daemon command
|
|
95
|
+
program
|
|
96
|
+
.command('daemon <action>')
|
|
97
|
+
.description('Manage the Stone daemon (status|start|stop)')
|
|
98
|
+
.option('--json', 'Output JSON')
|
|
99
|
+
.option('--force', 'Force action (e.g., stop when others connected)')
|
|
100
|
+
.action((action, options) => {
|
|
101
|
+
daemonCommand(action, options);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Package management commands
|
|
105
|
+
|
|
106
|
+
// init command
|
|
107
|
+
program
|
|
108
|
+
.command('init')
|
|
109
|
+
.description('Create a new package.son')
|
|
110
|
+
.option('--json', 'Output JSON')
|
|
111
|
+
.option('--force', 'Overwrite existing package.son')
|
|
112
|
+
.action((options) => {
|
|
113
|
+
initCommand(options);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// install command
|
|
117
|
+
program
|
|
118
|
+
.command('install [package]')
|
|
119
|
+
.alias('i')
|
|
120
|
+
.description('Install dependencies or a specific package')
|
|
121
|
+
.option('--json', 'Output JSON')
|
|
122
|
+
.option('-g, --global', 'Install globally to ~/.stone/stone_modules')
|
|
123
|
+
.option('--source <url>', 'Package source URL')
|
|
124
|
+
.option('--no-save', 'Do not update package.son')
|
|
125
|
+
.action((pkg, options) => {
|
|
126
|
+
installCommand(pkg, options);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// remove command
|
|
130
|
+
program
|
|
131
|
+
.command('remove <package>')
|
|
132
|
+
.alias('rm')
|
|
133
|
+
.description('Remove a package')
|
|
134
|
+
.option('--json', 'Output JSON')
|
|
135
|
+
.option('-g, --global', 'Remove from global packages')
|
|
136
|
+
.action((pkg, options) => {
|
|
137
|
+
removeCommand(pkg, options);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// update command
|
|
141
|
+
program
|
|
142
|
+
.command('update [package]')
|
|
143
|
+
.alias('up')
|
|
144
|
+
.description('Update dependencies')
|
|
145
|
+
.option('--json', 'Output JSON')
|
|
146
|
+
.action((pkg, options) => {
|
|
147
|
+
updateCommand(pkg, options);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// list command
|
|
151
|
+
program
|
|
152
|
+
.command('list')
|
|
153
|
+
.alias('ls')
|
|
154
|
+
.description('List installed packages')
|
|
155
|
+
.option('--json', 'Output JSON')
|
|
156
|
+
.option('-g, --global', 'List global packages')
|
|
157
|
+
.action((options) => {
|
|
158
|
+
listCommand(options);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// Parse arguments - but check for no-args first to start REPL
|
|
162
|
+
if (!process.argv.slice(2).length) {
|
|
163
|
+
// No arguments - start interactive REPL
|
|
164
|
+
const { ReplSession } = await import('./ReplSession.js');
|
|
165
|
+
const repl = new ReplSession({ version: VERSION });
|
|
166
|
+
await repl.start();
|
|
167
|
+
} else {
|
|
168
|
+
program.parse(process.argv);
|
|
169
|
+
}
|
package/cli/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stone CLI - Exports for CLI module
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export { CLIOutputAdapter } from './CLIOutputAdapter.js';
|
|
6
|
+
export { JSONOutputAdapter } from './JSONOutputAdapter.js';
|
|
7
|
+
export { DaemonClient } from './DaemonClient.js';
|
|
8
|
+
|
|
9
|
+
// Commands
|
|
10
|
+
export { runCommand } from './commands/run.js';
|
|
11
|
+
export { checkCommand } from './commands/check.js';
|
|
12
|
+
export { psCommand } from './commands/ps.js';
|
|
13
|
+
export { killCommand } from './commands/kill.js';
|
|
14
|
+
export { daemonCommand } from './commands/daemon.js';
|
package/cli/stonec.js
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Stone Compiler CLI
|
|
5
|
+
*
|
|
6
|
+
* Command-line interface for Stone compilation to multiple targets.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* stonec input.stn # Compile to JS VM (default)
|
|
10
|
+
* stonec input.stn --target=wasm # Compile to WebAssembly
|
|
11
|
+
* stonec input.stn --target=c # Compile to C source
|
|
12
|
+
* stonec input.stn -o output # Specify output file
|
|
13
|
+
* stonec input.stn -O2 # Optimization level
|
|
14
|
+
* stonec input.stn --emit-hir # Output HIR (debugging)
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import fs from 'fs';
|
|
18
|
+
import path from 'path';
|
|
19
|
+
import { fileURLToPath } from 'url';
|
|
20
|
+
import {
|
|
21
|
+
StoneCompiler,
|
|
22
|
+
StoneCompilerOptions,
|
|
23
|
+
CompilationTarget,
|
|
24
|
+
} from '../compiler.js';
|
|
25
|
+
import { OptimizationLevel } from '../optimization/optimization-manager.js';
|
|
26
|
+
|
|
27
|
+
// ============================================================================
|
|
28
|
+
// CLI ARGUMENT PARSING
|
|
29
|
+
// ============================================================================
|
|
30
|
+
|
|
31
|
+
function parseArgs(argv) {
|
|
32
|
+
const args = {
|
|
33
|
+
input: null,
|
|
34
|
+
output: null,
|
|
35
|
+
target: 'js-vm',
|
|
36
|
+
optimizationLevel: OptimizationLevel.STANDARD,
|
|
37
|
+
emitHir: false,
|
|
38
|
+
emitSourceMap: false,
|
|
39
|
+
debug: false,
|
|
40
|
+
verbose: false,
|
|
41
|
+
help: false,
|
|
42
|
+
version: false,
|
|
43
|
+
printTimings: false,
|
|
44
|
+
printAnalysis: false,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
for (let i = 2; i < argv.length; i++) {
|
|
48
|
+
const arg = argv[i];
|
|
49
|
+
|
|
50
|
+
if (arg === '-h' || arg === '--help') {
|
|
51
|
+
args.help = true;
|
|
52
|
+
} else if (arg === '-v' || arg === '--version') {
|
|
53
|
+
args.version = true;
|
|
54
|
+
} else if (arg === '--verbose') {
|
|
55
|
+
args.verbose = true;
|
|
56
|
+
} else if (arg === '--debug') {
|
|
57
|
+
args.debug = true;
|
|
58
|
+
} else if (arg === '--emit-hir') {
|
|
59
|
+
args.emitHir = true;
|
|
60
|
+
} else if (arg === '--emit-source-map') {
|
|
61
|
+
args.emitSourceMap = true;
|
|
62
|
+
} else if (arg === '--timings') {
|
|
63
|
+
args.printTimings = true;
|
|
64
|
+
} else if (arg === '--analysis') {
|
|
65
|
+
args.printAnalysis = true;
|
|
66
|
+
}
|
|
67
|
+
// Target
|
|
68
|
+
else if (arg.startsWith('--target=')) {
|
|
69
|
+
args.target = arg.slice('--target='.length);
|
|
70
|
+
} else if (arg === '-t' && i + 1 < argv.length) {
|
|
71
|
+
args.target = argv[++i];
|
|
72
|
+
}
|
|
73
|
+
// Output
|
|
74
|
+
else if (arg.startsWith('-o')) {
|
|
75
|
+
if (arg === '-o' && i + 1 < argv.length) {
|
|
76
|
+
args.output = argv[++i];
|
|
77
|
+
} else if (arg.length > 2) {
|
|
78
|
+
args.output = arg.slice(2);
|
|
79
|
+
}
|
|
80
|
+
} else if (arg.startsWith('--output=')) {
|
|
81
|
+
args.output = arg.slice('--output='.length);
|
|
82
|
+
}
|
|
83
|
+
// Optimization level
|
|
84
|
+
else if (arg === '-O0') {
|
|
85
|
+
args.optimizationLevel = OptimizationLevel.NONE;
|
|
86
|
+
} else if (arg === '-O1') {
|
|
87
|
+
args.optimizationLevel = OptimizationLevel.BASIC;
|
|
88
|
+
} else if (arg === '-O2') {
|
|
89
|
+
args.optimizationLevel = OptimizationLevel.STANDARD;
|
|
90
|
+
} else if (arg === '-O3') {
|
|
91
|
+
args.optimizationLevel = OptimizationLevel.AGGRESSIVE;
|
|
92
|
+
}
|
|
93
|
+
// Input file
|
|
94
|
+
else if (!arg.startsWith('-')) {
|
|
95
|
+
args.input = arg;
|
|
96
|
+
}
|
|
97
|
+
// Unknown flag
|
|
98
|
+
else {
|
|
99
|
+
console.error(`Unknown option: ${arg}`);
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return args;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ============================================================================
|
|
108
|
+
// HELP AND VERSION
|
|
109
|
+
// ============================================================================
|
|
110
|
+
|
|
111
|
+
function printHelp() {
|
|
112
|
+
console.log(`
|
|
113
|
+
Stone Compiler (stonec)
|
|
114
|
+
|
|
115
|
+
USAGE:
|
|
116
|
+
stonec <input.stn> [options]
|
|
117
|
+
|
|
118
|
+
OPTIONS:
|
|
119
|
+
-o <file> Output file (default: derived from input)
|
|
120
|
+
--output=<file> Same as -o
|
|
121
|
+
|
|
122
|
+
-t <target> Compilation target
|
|
123
|
+
--target=<target> Targets: js-vm (default), wasm, c, hir
|
|
124
|
+
|
|
125
|
+
-O0 No optimization
|
|
126
|
+
-O1 Basic optimizations
|
|
127
|
+
-O2 Standard optimizations (default)
|
|
128
|
+
-O3 Aggressive optimizations
|
|
129
|
+
|
|
130
|
+
--emit-hir Output HIR intermediate representation
|
|
131
|
+
--emit-source-map Generate source map
|
|
132
|
+
--debug Include debug information
|
|
133
|
+
--verbose Verbose output
|
|
134
|
+
--timings Print compilation timings
|
|
135
|
+
--analysis Print analysis results
|
|
136
|
+
|
|
137
|
+
-h, --help Show this help message
|
|
138
|
+
-v, --version Show version
|
|
139
|
+
|
|
140
|
+
EXAMPLES:
|
|
141
|
+
stonec program.stn # Compile to JS VM
|
|
142
|
+
stonec program.stn -t wasm -o out.wasm # Compile to WASM
|
|
143
|
+
stonec program.stn -t c -o out.c # Compile to C
|
|
144
|
+
stonec program.stn -O3 # Maximum optimization
|
|
145
|
+
stonec program.stn --emit-hir # Debug: show HIR
|
|
146
|
+
|
|
147
|
+
TARGETS:
|
|
148
|
+
js-vm JavaScript bytecode for Stone VM (default)
|
|
149
|
+
wasm WebAssembly binary
|
|
150
|
+
c C source code with Makefile
|
|
151
|
+
hir HIR output for debugging
|
|
152
|
+
`);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function printVersion() {
|
|
156
|
+
console.log('Stone Compiler (stonec) v1.0.0');
|
|
157
|
+
console.log('Part of the Stone Language Project');
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// ============================================================================
|
|
161
|
+
// OUTPUT HANDLING
|
|
162
|
+
// ============================================================================
|
|
163
|
+
|
|
164
|
+
function getDefaultOutputPath(inputPath, target) {
|
|
165
|
+
const dir = path.dirname(inputPath);
|
|
166
|
+
const base = path.basename(inputPath, '.stn');
|
|
167
|
+
|
|
168
|
+
switch (target) {
|
|
169
|
+
case 'wasm':
|
|
170
|
+
return path.join(dir, `${base}.wasm`);
|
|
171
|
+
case 'c':
|
|
172
|
+
return path.join(dir, base); // Will create base.c, base.h, Makefile
|
|
173
|
+
case 'hir':
|
|
174
|
+
return path.join(dir, `${base}.hir`);
|
|
175
|
+
case 'js-vm':
|
|
176
|
+
default:
|
|
177
|
+
return path.join(dir, `${base}.stb`); // Stone bytecode
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function writeOutput(result, outputPath, target, args) {
|
|
182
|
+
const dir = path.dirname(outputPath);
|
|
183
|
+
|
|
184
|
+
// Ensure directory exists
|
|
185
|
+
if (!fs.existsSync(dir)) {
|
|
186
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
switch (target) {
|
|
190
|
+
case 'wasm':
|
|
191
|
+
// Write WASM binary
|
|
192
|
+
fs.writeFileSync(outputPath, result.binary);
|
|
193
|
+
if (args.verbose) {
|
|
194
|
+
console.log(`Wrote WASM binary: ${outputPath} (${result.binary.length} bytes)`);
|
|
195
|
+
}
|
|
196
|
+
break;
|
|
197
|
+
|
|
198
|
+
case 'c':
|
|
199
|
+
// Write C source files
|
|
200
|
+
const base = path.basename(outputPath);
|
|
201
|
+
const cFile = path.join(dir, `${base}.c`);
|
|
202
|
+
const hFile = path.join(dir, `${base}.h`);
|
|
203
|
+
const makeFile = path.join(dir, 'Makefile');
|
|
204
|
+
|
|
205
|
+
fs.writeFileSync(cFile, result.source);
|
|
206
|
+
if (args.verbose) {
|
|
207
|
+
console.log(`Wrote C source: ${cFile}`);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (result.header) {
|
|
211
|
+
fs.writeFileSync(hFile, result.header);
|
|
212
|
+
if (args.verbose) {
|
|
213
|
+
console.log(`Wrote C header: ${hFile}`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (result.makefile) {
|
|
218
|
+
fs.writeFileSync(makeFile, result.makefile);
|
|
219
|
+
if (args.verbose) {
|
|
220
|
+
console.log(`Wrote Makefile: ${makeFile}`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
break;
|
|
224
|
+
|
|
225
|
+
case 'hir':
|
|
226
|
+
// Write HIR text
|
|
227
|
+
fs.writeFileSync(outputPath, result.text);
|
|
228
|
+
if (args.verbose) {
|
|
229
|
+
console.log(`Wrote HIR: ${outputPath}`);
|
|
230
|
+
}
|
|
231
|
+
break;
|
|
232
|
+
|
|
233
|
+
case 'js-vm':
|
|
234
|
+
default:
|
|
235
|
+
// Write JSON representation (for now)
|
|
236
|
+
fs.writeFileSync(outputPath, JSON.stringify(result, null, 2));
|
|
237
|
+
if (args.verbose) {
|
|
238
|
+
console.log(`Wrote bytecode: ${outputPath}`);
|
|
239
|
+
}
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// ============================================================================
|
|
245
|
+
// MAIN
|
|
246
|
+
// ============================================================================
|
|
247
|
+
|
|
248
|
+
async function main() {
|
|
249
|
+
const args = parseArgs(process.argv);
|
|
250
|
+
|
|
251
|
+
// Handle help and version
|
|
252
|
+
if (args.help) {
|
|
253
|
+
printHelp();
|
|
254
|
+
process.exit(0);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (args.version) {
|
|
258
|
+
printVersion();
|
|
259
|
+
process.exit(0);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Validate input
|
|
263
|
+
if (!args.input) {
|
|
264
|
+
console.error('Error: No input file specified');
|
|
265
|
+
console.error('Usage: stonec <input.stn> [options]');
|
|
266
|
+
console.error('Run `stonec --help` for more information');
|
|
267
|
+
process.exit(1);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Check input file exists
|
|
271
|
+
if (!fs.existsSync(args.input)) {
|
|
272
|
+
console.error(`Error: Input file not found: ${args.input}`);
|
|
273
|
+
process.exit(1);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Map target string to CompilationTarget
|
|
277
|
+
const targetMap = {
|
|
278
|
+
'js-vm': CompilationTarget.JS_VM,
|
|
279
|
+
'wasm': CompilationTarget.WASM,
|
|
280
|
+
'c': CompilationTarget.C,
|
|
281
|
+
'hir': CompilationTarget.HIR,
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
const target = targetMap[args.target];
|
|
285
|
+
if (!target) {
|
|
286
|
+
console.error(`Error: Unknown target: ${args.target}`);
|
|
287
|
+
console.error('Valid targets: js-vm, wasm, c, hir');
|
|
288
|
+
process.exit(1);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Determine output path
|
|
292
|
+
const outputPath = args.output || getDefaultOutputPath(args.input, args.target);
|
|
293
|
+
|
|
294
|
+
// Read input
|
|
295
|
+
const source = fs.readFileSync(args.input, 'utf-8');
|
|
296
|
+
|
|
297
|
+
if (args.verbose) {
|
|
298
|
+
console.log(`Compiling: ${args.input}`);
|
|
299
|
+
console.log(`Target: ${args.target}`);
|
|
300
|
+
console.log(`Output: ${outputPath}`);
|
|
301
|
+
console.log(`Optimization: O${args.optimizationLevel}`);
|
|
302
|
+
console.log('');
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// Create compiler options
|
|
306
|
+
const options = new StoneCompilerOptions({
|
|
307
|
+
target,
|
|
308
|
+
optimizationLevel: args.optimizationLevel,
|
|
309
|
+
sourceFile: args.input,
|
|
310
|
+
outputFile: outputPath,
|
|
311
|
+
emitSourceMap: args.emitSourceMap,
|
|
312
|
+
emitDebugInfo: args.debug,
|
|
313
|
+
printHIR: args.emitHir,
|
|
314
|
+
printAnalysis: args.printAnalysis,
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// Compile
|
|
318
|
+
const compiler = new StoneCompiler(options);
|
|
319
|
+
const result = compiler.compile(source);
|
|
320
|
+
|
|
321
|
+
// Handle errors
|
|
322
|
+
if (!result.success) {
|
|
323
|
+
console.error(`\nCompilation failed at stage: ${result.error.stage}`);
|
|
324
|
+
console.error(`Error: ${result.error.message}`);
|
|
325
|
+
if (args.debug) {
|
|
326
|
+
console.error('\nStack trace:');
|
|
327
|
+
console.error(result.error.stack);
|
|
328
|
+
}
|
|
329
|
+
process.exit(1);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Print timings if requested
|
|
333
|
+
if (args.printTimings || args.verbose) {
|
|
334
|
+
console.log('\nCompilation timings:');
|
|
335
|
+
for (const [stage, time] of Object.entries(result.metadata.timings)) {
|
|
336
|
+
console.log(` ${stage}: ${time}ms`);
|
|
337
|
+
}
|
|
338
|
+
console.log(` total: ${result.metadata.totalTime}ms`);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Write output
|
|
342
|
+
writeOutput(result.output, outputPath, args.target, args);
|
|
343
|
+
|
|
344
|
+
// Success message
|
|
345
|
+
if (!args.verbose) {
|
|
346
|
+
console.log(`Compiled ${args.input} -> ${outputPath}`);
|
|
347
|
+
} else {
|
|
348
|
+
console.log('\nCompilation successful!');
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
process.exit(0);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Run main
|
|
355
|
+
main().catch((error) => {
|
|
356
|
+
console.error('Fatal error:', error.message);
|
|
357
|
+
process.exit(1);
|
|
358
|
+
});
|