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.
Files changed (68) hide show
  1. package/README.md +52 -0
  2. package/StoneEngine.js +879 -0
  3. package/StoneEngineService.js +1727 -0
  4. package/adapters/FileSystemAdapter.js +230 -0
  5. package/adapters/OutputAdapter.js +208 -0
  6. package/adapters/index.js +6 -0
  7. package/cli/CLIOutputAdapter.js +196 -0
  8. package/cli/DaemonClient.js +349 -0
  9. package/cli/JSONOutputAdapter.js +135 -0
  10. package/cli/ReplSession.js +567 -0
  11. package/cli/ViewerServer.js +590 -0
  12. package/cli/commands/check.js +84 -0
  13. package/cli/commands/daemon.js +189 -0
  14. package/cli/commands/kill.js +66 -0
  15. package/cli/commands/package.js +713 -0
  16. package/cli/commands/ps.js +65 -0
  17. package/cli/commands/run.js +537 -0
  18. package/cli/entry.js +169 -0
  19. package/cli/index.js +14 -0
  20. package/cli/stonec.js +358 -0
  21. package/cli/test-compiler.js +181 -0
  22. package/cli/viewer/index.html +495 -0
  23. package/daemon/IPCServer.js +455 -0
  24. package/daemon/ProcessManager.js +327 -0
  25. package/daemon/ProcessRunner.js +307 -0
  26. package/daemon/daemon.js +398 -0
  27. package/daemon/index.js +16 -0
  28. package/frontend/analysis/index.js +5 -0
  29. package/frontend/analysis/livenessAnalyzer.js +568 -0
  30. package/frontend/analysis/treeShaker.js +265 -0
  31. package/frontend/index.js +20 -0
  32. package/frontend/parsing/astBuilder.js +2196 -0
  33. package/frontend/parsing/index.js +7 -0
  34. package/frontend/parsing/sonParser.js +592 -0
  35. package/frontend/parsing/stoneAstTypes.js +703 -0
  36. package/frontend/parsing/terminal-registry.js +435 -0
  37. package/frontend/parsing/tokenizer.js +692 -0
  38. package/frontend/type-checker/OverloadedFunctionType.js +43 -0
  39. package/frontend/type-checker/TypeEnvironment.js +165 -0
  40. package/frontend/type-checker/bidirectionalInference.js +149 -0
  41. package/frontend/type-checker/index.js +10 -0
  42. package/frontend/type-checker/moduleAnalysis.js +248 -0
  43. package/frontend/type-checker/operatorMappings.js +35 -0
  44. package/frontend/type-checker/overloadResolution.js +605 -0
  45. package/frontend/type-checker/typeChecker.js +452 -0
  46. package/frontend/type-checker/typeCompatibility.js +389 -0
  47. package/frontend/type-checker/visitors/controlFlow.js +483 -0
  48. package/frontend/type-checker/visitors/functions.js +604 -0
  49. package/frontend/type-checker/visitors/index.js +38 -0
  50. package/frontend/type-checker/visitors/literals.js +341 -0
  51. package/frontend/type-checker/visitors/modules.js +159 -0
  52. package/frontend/type-checker/visitors/operators.js +109 -0
  53. package/frontend/type-checker/visitors/statements.js +768 -0
  54. package/frontend/types/index.js +5 -0
  55. package/frontend/types/operatorMap.js +134 -0
  56. package/frontend/types/types.js +2046 -0
  57. package/frontend/utils/errorCollector.js +244 -0
  58. package/frontend/utils/index.js +5 -0
  59. package/frontend/utils/moduleResolver.js +479 -0
  60. package/package.json +50 -0
  61. package/packages/browserCache.js +359 -0
  62. package/packages/fetcher.js +236 -0
  63. package/packages/index.js +130 -0
  64. package/packages/lockfile.js +271 -0
  65. package/packages/manifest.js +291 -0
  66. package/packages/packageResolver.js +356 -0
  67. package/packages/resolver.js +310 -0
  68. 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
+ });