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
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stone Module Resolver
|
|
3
|
+
*
|
|
4
|
+
* Resolution order:
|
|
5
|
+
* 1. Built-in modules (primitives, plots)
|
|
6
|
+
* 2. Standard library (.stn builtins: math, array, stats, etc.)
|
|
7
|
+
* 3. Local stone_modules/ (at project root, where package.son lives)
|
|
8
|
+
* 4. Global ~/.stone/stone_modules/
|
|
9
|
+
* 5. File-based resolution (relative paths, filesSource)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
resolvePath,
|
|
14
|
+
resolveRelative,
|
|
15
|
+
getDirectory,
|
|
16
|
+
} from '../../../utils/filePathResolver.js';
|
|
17
|
+
import { extractCodeSection } from '../../fileFormat/stoneFileParser.js';
|
|
18
|
+
|
|
19
|
+
// Import standard library modules
|
|
20
|
+
import primitives from '../../standard-library/primitives.js';
|
|
21
|
+
|
|
22
|
+
// Embedded .stn standard library content (generated from .stn files)
|
|
23
|
+
// To regenerate: node scripts/build-stn-content.js
|
|
24
|
+
import { STN_BUILTIN_CONTENT } from '../../standard-library/stn-content.generated.js';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Module cache for tracking loaded modules
|
|
28
|
+
*/
|
|
29
|
+
class ModuleCache {
|
|
30
|
+
constructor() {
|
|
31
|
+
this.modules = new Map();
|
|
32
|
+
this.loading = new Set();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
has(modulePath) {
|
|
36
|
+
return this.modules.has(modulePath);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
get(modulePath) {
|
|
40
|
+
return this.modules.get(modulePath);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
set(modulePath, moduleData) {
|
|
44
|
+
this.modules.set(modulePath, moduleData);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
isLoading(modulePath) {
|
|
48
|
+
return this.loading.has(modulePath);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
startLoading(modulePath) {
|
|
52
|
+
this.loading.add(modulePath);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
finishLoading(modulePath) {
|
|
56
|
+
this.loading.delete(modulePath);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
clear() {
|
|
60
|
+
this.modules.clear();
|
|
61
|
+
this.loading.clear();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
entries() {
|
|
65
|
+
return this.modules.entries();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Custom serialization - only export minimal dependency data
|
|
69
|
+
toJSON() {
|
|
70
|
+
const modules = {};
|
|
71
|
+
for (const [key, value] of this.modules) {
|
|
72
|
+
modules[key] = {
|
|
73
|
+
fileId: value.fileId,
|
|
74
|
+
modulePath: value.modulePath,
|
|
75
|
+
isBuiltin: value.isBuiltin
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return { modules, loading: [] };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export class ModuleResolver {
|
|
83
|
+
constructor(options = {}) {
|
|
84
|
+
this.cache = new ModuleCache();
|
|
85
|
+
this.filesSource = options.filesSource || null;
|
|
86
|
+
this.currentFilePath = null;
|
|
87
|
+
this.fileLoader = options.fileLoader || null;
|
|
88
|
+
this.builtinModules = this.createBuiltinModules();
|
|
89
|
+
|
|
90
|
+
// Package system support (optional)
|
|
91
|
+
// PackageContext handles stone_modules resolution
|
|
92
|
+
this.packageContext = options.packageContext || null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Set the package context for stone_modules resolution
|
|
97
|
+
*/
|
|
98
|
+
setPackageContext(context) {
|
|
99
|
+
this.packageContext = context;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Create built-in module exports
|
|
104
|
+
* Imports from standard-library/ modules
|
|
105
|
+
* Note: Most standard library modules are now .stn (in STN_BUILTIN_CONTENT)
|
|
106
|
+
*/
|
|
107
|
+
createBuiltinModules() {
|
|
108
|
+
return {
|
|
109
|
+
// Primitives module (JS) - all primitives with overload wrappers
|
|
110
|
+
'primitives': primitives,
|
|
111
|
+
// Note: stats, math, builtins are now .stn modules (see STN_BUILTIN_CONTENT)
|
|
112
|
+
// Other modules (array, string, linalg, complex, random) being migrated to .stn
|
|
113
|
+
|
|
114
|
+
// Plots module - runtime terminal constructors (actual exports bound by executor)
|
|
115
|
+
// This is a placeholder so the module resolver recognizes 'plots' as valid
|
|
116
|
+
'plots': {
|
|
117
|
+
graph2d: null, // Bound at runtime by executor
|
|
118
|
+
graph3d: null, // Bound at runtime by executor
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
// Note: 'file' module is now a .stn builtin (see STN_BUILTIN_CONTENT)
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Check if a module is a runtime module (needs executor binding)
|
|
127
|
+
*/
|
|
128
|
+
isRuntimeModule(modulePath) {
|
|
129
|
+
return modulePath === 'plots';
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Check if a module is a .stn builtin
|
|
134
|
+
*/
|
|
135
|
+
isStnBuiltinModule(modulePath) {
|
|
136
|
+
return modulePath in STN_BUILTIN_CONTENT;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Get .stn builtin content
|
|
141
|
+
*/
|
|
142
|
+
getStnBuiltinContent(modulePath) {
|
|
143
|
+
return STN_BUILTIN_CONTENT[modulePath];
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
setFilesSource(filesSource) {
|
|
147
|
+
this.filesSource = filesSource;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
setCurrentFilePath(path) {
|
|
151
|
+
this.currentFilePath = path;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
setFileLoader(loader) {
|
|
155
|
+
this.fileLoader = loader;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
getCurrentFilePath() {
|
|
159
|
+
return this.currentFilePath;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
resolveModulePath(modulePath) {
|
|
163
|
+
const currentFilePath = this.currentFilePath;
|
|
164
|
+
|
|
165
|
+
if ((modulePath.startsWith('./') || modulePath.startsWith('../')) && currentFilePath) {
|
|
166
|
+
const currentDir = getDirectory(currentFilePath);
|
|
167
|
+
return resolveRelative(currentDir, modulePath);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return modulePath.replace(/^\.\//, '');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
isBuiltinModule(modulePath) {
|
|
174
|
+
return this.builtinModules.hasOwnProperty(modulePath);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
getBuiltinModule(modulePath) {
|
|
178
|
+
return this.builtinModules[modulePath];
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Check if a file ID corresponds to an actual .stn file (not a folder)
|
|
183
|
+
*/
|
|
184
|
+
isStoneFile(fileId) {
|
|
185
|
+
if (!fileId || !this.filesSource) return false;
|
|
186
|
+
const files = this.filesSource instanceof Map
|
|
187
|
+
? Array.from(this.filesSource.values())
|
|
188
|
+
: Array.isArray(this.filesSource) ? this.filesSource : [];
|
|
189
|
+
const file = files.find(f => (f._id || f.id) === fileId);
|
|
190
|
+
return file && file.name && file.name.endsWith('.stn');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Resolve module path to file ID
|
|
195
|
+
* @param {string} modulePath - The module path to resolve
|
|
196
|
+
* @param {string|null} inferredFilename - Optional filename to append for directory imports
|
|
197
|
+
* (e.g., for "import stats from 'dir'" -> tries "dir/stats.stn")
|
|
198
|
+
* @returns {string|null} The resolved file ID or null if not found
|
|
199
|
+
*/
|
|
200
|
+
resolveToFileId(modulePath, inferredFilename = null) {
|
|
201
|
+
// If no filesSource but we have a fileLoader, use resolveModulePath
|
|
202
|
+
// This supports file-based loading with relative paths
|
|
203
|
+
if (!this.filesSource && this.fileLoader) {
|
|
204
|
+
return this.resolveModulePath(modulePath);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (!this.filesSource) {
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const currentFilePath = this.currentFilePath;
|
|
212
|
+
|
|
213
|
+
// 1. Try exact path first (must be an actual .stn file, not a folder)
|
|
214
|
+
let fileId = resolvePath(modulePath, this.filesSource, currentFilePath);
|
|
215
|
+
if (fileId && this.isStoneFile(fileId)) {
|
|
216
|
+
return fileId;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// 2. Try with inferred filename (directory + inferred filename resolution)
|
|
220
|
+
// This enables: import stats from "core logic/math" -> "core logic/math/stats.stn"
|
|
221
|
+
if (inferredFilename) {
|
|
222
|
+
const inferredPath = `${modulePath}/${inferredFilename}`;
|
|
223
|
+
fileId = resolvePath(inferredPath, this.filesSource, currentFilePath);
|
|
224
|
+
if (fileId && this.isStoneFile(fileId)) {
|
|
225
|
+
return fileId;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// 3. Try index.stn fallback
|
|
230
|
+
fileId = resolvePath(modulePath + '/index.stn', this.filesSource, currentFilePath);
|
|
231
|
+
if (fileId && this.isStoneFile(fileId)) {
|
|
232
|
+
return fileId;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Load a module by path
|
|
240
|
+
* @param {string} modulePath - The module path to load
|
|
241
|
+
* @param {function} parseFunction - Function to parse source code
|
|
242
|
+
* @param {string|null} inferredFilename - Optional filename for directory inference
|
|
243
|
+
*/
|
|
244
|
+
async loadModule(modulePath, parseFunction, inferredFilename = null) {
|
|
245
|
+
// Check JS builtins first (fast path)
|
|
246
|
+
if (this.isBuiltinModule(modulePath)) {
|
|
247
|
+
return {
|
|
248
|
+
isBuiltin: true,
|
|
249
|
+
exports: this.getBuiltinModule(modulePath),
|
|
250
|
+
modulePath,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (this.cache.has(modulePath)) {
|
|
255
|
+
return this.cache.get(modulePath);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Check .stn builtins - these are parsed and executed like regular modules
|
|
259
|
+
if (this.isStnBuiltinModule(modulePath)) {
|
|
260
|
+
|
|
261
|
+
if (this.cache.isLoading(modulePath)) {
|
|
262
|
+
const error = new Error(`Circular dependency detected: ${modulePath}`);
|
|
263
|
+
error.stage = 'module_load';
|
|
264
|
+
error.type = 'module';
|
|
265
|
+
error.module = modulePath;
|
|
266
|
+
throw error;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
this.cache.startLoading(modulePath);
|
|
270
|
+
|
|
271
|
+
try {
|
|
272
|
+
const stnContent = this.getStnBuiltinContent(modulePath);
|
|
273
|
+
const ast = parseFunction(stnContent, { filename: `<builtin:${modulePath}>` });
|
|
274
|
+
|
|
275
|
+
const moduleData = {
|
|
276
|
+
isBuiltin: false, // Treated as regular module for execution
|
|
277
|
+
isStnBuiltin: true, // Mark as .stn builtin for reference
|
|
278
|
+
ast,
|
|
279
|
+
fileId: null,
|
|
280
|
+
modulePath,
|
|
281
|
+
exports: null,
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
this.cache.set(modulePath, moduleData);
|
|
285
|
+
this.cache.finishLoading(modulePath);
|
|
286
|
+
|
|
287
|
+
return moduleData;
|
|
288
|
+
} catch (error) {
|
|
289
|
+
this.cache.finishLoading(modulePath);
|
|
290
|
+
const parseErr = new Error(`Failed to parse .stn builtin '${modulePath}': ${error.message}`);
|
|
291
|
+
parseErr.stage = 'module_load';
|
|
292
|
+
parseErr.type = 'module';
|
|
293
|
+
parseErr.module = modulePath;
|
|
294
|
+
throw parseErr;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (this.cache.isLoading(modulePath)) {
|
|
299
|
+
const error = new Error(`Circular dependency detected: ${modulePath}`);
|
|
300
|
+
error.stage = 'module_load';
|
|
301
|
+
error.type = 'module';
|
|
302
|
+
error.module = modulePath;
|
|
303
|
+
throw error;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Try stone_modules resolution first (if package context is available)
|
|
307
|
+
// This handles: import foo from bar -> stone_modules/bar/main.stn
|
|
308
|
+
if (this.packageContext && !modulePath.startsWith('./') && !modulePath.startsWith('../')) {
|
|
309
|
+
const packagePath = await this.packageContext.resolveModule(
|
|
310
|
+
modulePath,
|
|
311
|
+
this.currentFilePath,
|
|
312
|
+
{ isBuiltin: (m) => this.isBuiltinModule(m) || this.isStnBuiltinModule(m) }
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
if (packagePath) {
|
|
316
|
+
// Load from resolved package path
|
|
317
|
+
return this.loadModuleFromPath(packagePath, modulePath, parseFunction);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Pass inferredFilename for directory + inferred filename resolution
|
|
322
|
+
const fileId = this.resolveToFileId(modulePath, inferredFilename);
|
|
323
|
+
if (!fileId) {
|
|
324
|
+
// Provide helpful error message for inferred paths
|
|
325
|
+
let errorMsg = `Module not found: ${modulePath}`;
|
|
326
|
+
if (inferredFilename) {
|
|
327
|
+
errorMsg += ` (also tried ${modulePath}/${inferredFilename}.stn)`;
|
|
328
|
+
}
|
|
329
|
+
if (this.packageContext) {
|
|
330
|
+
errorMsg += ` (also checked stone_modules)`;
|
|
331
|
+
}
|
|
332
|
+
const error = new Error(errorMsg);
|
|
333
|
+
error.stage = 'module_load';
|
|
334
|
+
error.type = 'module';
|
|
335
|
+
error.module = modulePath;
|
|
336
|
+
throw error;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
this.cache.startLoading(modulePath);
|
|
340
|
+
|
|
341
|
+
try {
|
|
342
|
+
if (!this.fileLoader) {
|
|
343
|
+
const error = new Error('No file loader configured for module resolver');
|
|
344
|
+
error.stage = 'module_load';
|
|
345
|
+
error.type = 'module';
|
|
346
|
+
throw error;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
const fileContent = await this.fileLoader(fileId);
|
|
350
|
+
if (!fileContent) {
|
|
351
|
+
const error = new Error(`Failed to load module content: ${modulePath}`);
|
|
352
|
+
error.stage = 'module_load';
|
|
353
|
+
error.type = 'module';
|
|
354
|
+
error.module = modulePath;
|
|
355
|
+
throw error;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
const rawContent = fileContent.content || fileContent.code || fileContent.data || fileContent;
|
|
359
|
+
const codeOnly = typeof rawContent === 'string' ? extractCodeSection(rawContent) : rawContent;
|
|
360
|
+
const ast = parseFunction(codeOnly, { filename: modulePath });
|
|
361
|
+
|
|
362
|
+
const moduleData = {
|
|
363
|
+
isBuiltin: false,
|
|
364
|
+
ast,
|
|
365
|
+
fileId,
|
|
366
|
+
modulePath,
|
|
367
|
+
exports: null,
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
this.cache.set(modulePath, moduleData);
|
|
371
|
+
this.cache.finishLoading(modulePath);
|
|
372
|
+
|
|
373
|
+
return moduleData;
|
|
374
|
+
} catch (error) {
|
|
375
|
+
this.cache.finishLoading(modulePath);
|
|
376
|
+
throw error;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Load a module from a resolved file path (used by package resolution)
|
|
382
|
+
*/
|
|
383
|
+
async loadModuleFromPath(filePath, modulePath, parseFunction) {
|
|
384
|
+
this.cache.startLoading(modulePath);
|
|
385
|
+
|
|
386
|
+
try {
|
|
387
|
+
// Read file content using package context
|
|
388
|
+
let fileContent = null;
|
|
389
|
+
|
|
390
|
+
if (this.packageContext && this.packageContext.readFile) {
|
|
391
|
+
fileContent = await this.packageContext.readFile(filePath);
|
|
392
|
+
} else if (this.fileLoader) {
|
|
393
|
+
fileContent = await this.fileLoader(filePath);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
if (!fileContent) {
|
|
397
|
+
const error = new Error(`Failed to load module content: ${modulePath} (${filePath})`);
|
|
398
|
+
error.stage = 'module_load';
|
|
399
|
+
error.type = 'module';
|
|
400
|
+
error.module = modulePath;
|
|
401
|
+
throw error;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const rawContent = typeof fileContent === 'string' ? fileContent :
|
|
405
|
+
(fileContent.content || fileContent.code || fileContent.data || fileContent);
|
|
406
|
+
const codeOnly = typeof rawContent === 'string' ? extractCodeSection(rawContent) : rawContent;
|
|
407
|
+
const ast = parseFunction(codeOnly, { filename: filePath });
|
|
408
|
+
|
|
409
|
+
const moduleData = {
|
|
410
|
+
isBuiltin: false,
|
|
411
|
+
isPackageModule: true,
|
|
412
|
+
ast,
|
|
413
|
+
fileId: filePath,
|
|
414
|
+
modulePath,
|
|
415
|
+
exports: null,
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
this.cache.set(modulePath, moduleData);
|
|
419
|
+
this.cache.finishLoading(modulePath);
|
|
420
|
+
|
|
421
|
+
return moduleData;
|
|
422
|
+
} catch (error) {
|
|
423
|
+
this.cache.finishLoading(modulePath);
|
|
424
|
+
throw error;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
getModuleName(modulePath) {
|
|
429
|
+
const segments = modulePath.split('/');
|
|
430
|
+
return segments[segments.length - 1];
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
getExportedNames(ast) {
|
|
434
|
+
if (!ast || !ast.exports) return [];
|
|
435
|
+
|
|
436
|
+
return ast.exports.map(exportStmt => {
|
|
437
|
+
const decl = exportStmt.declaration;
|
|
438
|
+
if (decl.type === 'FunctionDefinition') return decl.name;
|
|
439
|
+
if (decl.type === 'Assignment') return decl.target;
|
|
440
|
+
return null;
|
|
441
|
+
}).filter(Boolean);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
clearCache() {
|
|
445
|
+
this.cache.clear();
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// Custom serialization - exclude filesSource to avoid serializing entire file system
|
|
449
|
+
toJSON() {
|
|
450
|
+
return {
|
|
451
|
+
cache: this.cache,
|
|
452
|
+
// filesSource excluded - runtime context only, not needed for serialization
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
export function createModuleResolver(options = {}) {
|
|
458
|
+
return new ModuleResolver(options);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Create a module resolver with package support for Node.js
|
|
463
|
+
* @param {object} options - Resolver options
|
|
464
|
+
* @returns {Promise<ModuleResolver>} Configured module resolver
|
|
465
|
+
*/
|
|
466
|
+
export async function createPackageAwareResolver(options = {}) {
|
|
467
|
+
const resolver = new ModuleResolver(options);
|
|
468
|
+
|
|
469
|
+
// Try to set up package context
|
|
470
|
+
try {
|
|
471
|
+
const { createNodePackageContext } = await import('../../packages/packageResolver.js');
|
|
472
|
+
const packageContext = await createNodePackageContext();
|
|
473
|
+
resolver.setPackageContext(packageContext);
|
|
474
|
+
} catch (e) {
|
|
475
|
+
// Package support not available, continue without it
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
return resolver;
|
|
479
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "stone-lang",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Stone - A modern programming language for data science and numerical computing",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"stone",
|
|
7
|
+
"programming-language",
|
|
8
|
+
"data-science",
|
|
9
|
+
"numerical-computing",
|
|
10
|
+
"interpreter",
|
|
11
|
+
"cli"
|
|
12
|
+
],
|
|
13
|
+
"author": "Alvei",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/alvei/stone-lang"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://stone-lang.dev",
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/alvei/stone-lang/issues"
|
|
22
|
+
},
|
|
23
|
+
"type": "module",
|
|
24
|
+
"bin": {
|
|
25
|
+
"stone": "./cli/entry.js"
|
|
26
|
+
},
|
|
27
|
+
"main": "./StoneEngine.js",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": "./StoneEngine.js",
|
|
30
|
+
"./engine": "./StoneEngine.js"
|
|
31
|
+
},
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18.0.0"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"commander": "^12.1.0"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"cli/",
|
|
40
|
+
"frontend/",
|
|
41
|
+
"backend/",
|
|
42
|
+
"adapters/",
|
|
43
|
+
"stdlib/",
|
|
44
|
+
"packages/",
|
|
45
|
+
"daemon/",
|
|
46
|
+
"StoneEngine.js",
|
|
47
|
+
"StoneEngineService.js",
|
|
48
|
+
"README.md"
|
|
49
|
+
]
|
|
50
|
+
}
|