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
@@ -0,0 +1,703 @@
1
+ /**
2
+ * Stone Language AST Node Type Definitions
3
+ *
4
+ * These represent the structure of Stone programs as abstract syntax trees.
5
+ * Each node type corresponds to a Stone language construct.
6
+ */
7
+
8
+ /**
9
+ * Base class for all AST nodes
10
+ */
11
+ export class ASTNode {
12
+ constructor(type, location) {
13
+ this.type = type;
14
+ this.location = location; // { line, column, file }
15
+ }
16
+ }
17
+
18
+ // ============================================================================
19
+ // LITERALS & IDENTIFIERS
20
+ // ============================================================================
21
+
22
+ /**
23
+ * Literal values: numbers, strings, booleans, complex numbers
24
+ * @example 42, 3.14, "hello", true, false, none, 2+3i
25
+ */
26
+ export class Literal extends ASTNode {
27
+ constructor(value, literalType, location) {
28
+ super("Literal", location);
29
+ this.value = value;
30
+ this.literalType = literalType; // 'number' | 'complex' | 'string' | 'bool' | 'none'
31
+ }
32
+ }
33
+
34
+ /**
35
+ * Variable/identifier reference
36
+ * @example x, user_name, count
37
+ */
38
+ export class Identifier extends ASTNode {
39
+ constructor(name, location) {
40
+ super("Identifier", location);
41
+ this.name = name;
42
+ }
43
+ }
44
+
45
+ // ============================================================================
46
+ // EXPRESSIONS
47
+ // ============================================================================
48
+
49
+ /**
50
+ * Binary operations: +, -, *, /, <, >, ==, &&, ||, etc.
51
+ * @example a + b, x < 5, count == 0, a && b
52
+ */
53
+ export class BinaryOp extends ASTNode {
54
+ constructor(operator, left, right, location) {
55
+ super("BinaryOp", location);
56
+ this.operator = operator;
57
+ this.left = left;
58
+ this.right = right;
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Unary operations: -, !, not
64
+ * @example -x, !flag
65
+ */
66
+ export class UnaryOp extends ASTNode {
67
+ constructor(operator, operand, location) {
68
+ super("UnaryOp", location);
69
+ this.operator = operator;
70
+ this.operand = operand;
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Function call expression
76
+ * @example add(5, 3), process(user, options), Math.sqrt(4)
77
+ */
78
+ export class FunctionCall extends ASTNode {
79
+ constructor(funcName, args, location, callee = null) {
80
+ super("FunctionCall", location);
81
+ this.funcName = funcName; // null for method calls
82
+ this.args = args;
83
+ this.callee = callee; // MemberAccess for method calls like obj.method(args)
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Array literal
89
+ * @example [1, 2, 3], ["a", "b", "c"]
90
+ */
91
+ export class ArrayLiteral extends ASTNode {
92
+ constructor(elements, location) {
93
+ super("ArrayLiteral", location);
94
+ this.elements = elements;
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Object literal (record)
100
+ * @example {name: "Alice", age: 30}
101
+ */
102
+ export class ObjectLiteral extends ASTNode {
103
+ constructor(properties, location) {
104
+ super("ObjectLiteral", location);
105
+ this.properties = properties; // Array<{key: string, value: ASTNode}>
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Block expression - a block of statements that evaluates to the returned value
111
+ * @example { x = 5; y = x * 2; return y }
112
+ * @deprecated Use BindingStructure instead for unified braces model
113
+ */
114
+ export class BlockExpression extends ASTNode {
115
+ constructor(body, location) {
116
+ super("BlockExpression", location);
117
+ this.body = body; // Array<ASTNode> - statements in the block
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Binding structure - unified representation for all {} constructs
123
+ *
124
+ * In Stone, {} is always a structure of bindings:
125
+ * - Ends with bindings → evaluates to object of those bindings
126
+ * - Ends with bare expression → evaluates to that value (sugar for return)
127
+ * - Used for: objects, blocks, loop state, loop body
128
+ *
129
+ * @example { x = 10, y = 20 } // object
130
+ * @example { x = 10, x + 1 } // block returning x + 1
131
+ * @example { sum = 0 } for (x in xs) {...} // loop state
132
+ */
133
+ export class BindingStructure extends ASTNode {
134
+ constructor(bindings, trailingExpr, location) {
135
+ super("BindingStructure", location);
136
+ this.bindings = bindings; // Array<{name: string, typeAnnotation: TypeAnnotation|null, value: ASTNode}>
137
+ this.trailingExpr = trailingExpr; // ASTNode|null - bare expression at end (sugar for return)
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Single binding within a BindingStructure
143
+ * @example sum = 0
144
+ * @example sum: num = 0
145
+ * @example sum' = sum + x (prime binding for loop state transitions)
146
+ * @example name: string (type descriptor - no value, required field in schema)
147
+ * @example name: string = 'default' (type descriptor with default value)
148
+ */
149
+ export class Binding {
150
+ constructor(name, value, typeAnnotation = null, isTypeDescriptor = false) {
151
+ this.name = name; // string - may end with ' for state transitions
152
+ this.value = value; // ASTNode - null for type descriptors without defaults
153
+ this.typeAnnotation = typeAnnotation; // TypeAnnotation|null
154
+ this.isTypeDescriptor = isTypeDescriptor; // true if this is a type descriptor (name: type) binding
155
+ }
156
+
157
+ get isPrime() {
158
+ return this.name.endsWith("'");
159
+ }
160
+
161
+ get baseName() {
162
+ return this.isPrime ? this.name.slice(0, -1) : this.name;
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Member access: object.field or array[index]
168
+ * @example user.name, items[0]
169
+ */
170
+ export class MemberAccess extends ASTNode {
171
+ constructor(object, property, computed, location) {
172
+ super("MemberAccess", location);
173
+ this.object = object;
174
+ this.property = property;
175
+ this.computed = computed; // true for [], false for .
176
+ }
177
+ }
178
+
179
+ /**
180
+ * String interpolation
181
+ * @example f"Hello {name}, you are {age} years old"
182
+ */
183
+ export class StringInterpolation extends ASTNode {
184
+ constructor(parts, expressions, location) {
185
+ super("StringInterpolation", location);
186
+ this.parts = parts;
187
+ this.expressions = expressions;
188
+ }
189
+ }
190
+
191
+ // ============================================================================
192
+ // STATEMENTS
193
+ // ============================================================================
194
+
195
+ /**
196
+ * Variable binding/assignment
197
+ * @example x = 5, name = "Alice"
198
+ */
199
+ export class Assignment extends ASTNode {
200
+ constructor(target, value, typeAnnotation, location) {
201
+ super("Assignment", location);
202
+ this.target = target; // string (variable name)
203
+ this.value = value;
204
+ this.typeAnnotation = typeAnnotation;
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Destructuring assignment - extracts properties from an object into variables
210
+ * @example x, y := point
211
+ * @example name, age as years := person
212
+ */
213
+ export class DestructuringAssignment extends ASTNode {
214
+ constructor(targets, value, location) {
215
+ super("DestructuringAssignment", location);
216
+ this.targets = targets; // Array<{name: string, alias: string|null}> - properties to extract
217
+ this.value = value; // ASTNode - expression that evaluates to an object
218
+ }
219
+ }
220
+
221
+ /**
222
+ * Type alias declaration
223
+ * @example type Person = {name: string, age: num}
224
+ * @example type ScoreMap = {[string]: num}
225
+ */
226
+ export class TypeAlias extends ASTNode {
227
+ constructor(name, typeAnnotation, location) {
228
+ super("TypeAlias", location);
229
+ this.name = name; // string (alias name)
230
+ this.typeAnnotation = typeAnnotation; // TypeAnnotation AST node
231
+ }
232
+ }
233
+
234
+ /**
235
+ * Indexed mapping assignment (parallel transformation)
236
+ * @example doubled[i] = xs[i] * 2
237
+ * @example matrix[i][j] = a[i][j] + b[i][j]
238
+ */
239
+ export class IndexedAssignment extends ASTNode {
240
+ constructor(target, indices, value, location) {
241
+ super("IndexedAssignment", location);
242
+ this.target = target; // string (result array name)
243
+ this.indices = indices; // Array<string> (index variable names like ['i'] or ['i', 'j'])
244
+ this.value = value; // ASTNode (expression to compute each element)
245
+ }
246
+ }
247
+
248
+ /**
249
+ * Return statement
250
+ * @example return x + y
251
+ */
252
+ export class ReturnStatement extends ASTNode {
253
+ constructor(value, location) {
254
+ super("ReturnStatement", location);
255
+ this.value = value;
256
+ }
257
+ }
258
+
259
+ /**
260
+ * Break statement
261
+ * @example break
262
+ */
263
+ export class BreakStatement extends ASTNode {
264
+ constructor(location) {
265
+ super("BreakStatement", location);
266
+ }
267
+ }
268
+
269
+ /**
270
+ * Continue statement
271
+ * @example continue
272
+ */
273
+ export class ContinueStatement extends ASTNode {
274
+ constructor(location) {
275
+ super("ContinueStatement", location);
276
+ }
277
+ }
278
+
279
+ // ============================================================================
280
+ // CONTROL FLOW
281
+ // ============================================================================
282
+
283
+ /**
284
+ * Branch/conditional expression (if/elif/else)
285
+ * @example if (condition) { value1 } else { value2 }
286
+ */
287
+ export class BranchExpression extends ASTNode {
288
+ constructor(paths, location) {
289
+ super("BranchExpression", location);
290
+ this.paths = paths;
291
+ }
292
+ }
293
+
294
+ /**
295
+ * Single path in a branch (if, elif, or else)
296
+ */
297
+ export class BranchPath {
298
+ constructor(type, condition, body) {
299
+ this.type = type; // 'if' | 'elif' | 'else'
300
+ this.condition = condition; // ASTNode | null (null for else)
301
+ this.body = body; // Array<ASTNode>
302
+ }
303
+ }
304
+
305
+
306
+ // ============================================================================
307
+ // LOOPS
308
+ // ============================================================================
309
+
310
+ /**
311
+ * Loop expression - state machine with drivers
312
+ *
313
+ * New syntax: { state } driver { body }
314
+ * @example { sum = 0 } for (x in xs) { sum' = sum + x }
315
+ * @example { x = 1 } while (x < 100) { x' = x * 2 }
316
+ *
317
+ * The state block defines initial bindings. The driver iterates.
318
+ * The body contains prime bindings (state transitions) like sum' = sum + x.
319
+ */
320
+ export class LoopExpression extends ASTNode {
321
+ constructor(variables, drivers, body, destructuring, location) {
322
+ super("LoopExpression", location);
323
+ this.variables = variables; // Array<LoopVariable> - state variables from state block
324
+ this.drivers = drivers; // Array<LoopDriver> - for/while drivers
325
+ this.body = body; // Array<ASTNode> - body statements (includes prime bindings)
326
+ this.destructuring = destructuring; // Array<{name: string, alias: string|null}>
327
+ this.isDestructured = false; // true if using := operator
328
+ }
329
+ }
330
+
331
+ /**
332
+ * Loop variable (state variable)
333
+ * @param {string} name - Variable name
334
+ * @param {ASTNode|null} initialValue - Initial value expression
335
+ * @param {TypeAnnotation|null} typeAnnotation - Optional type annotation
336
+ */
337
+ export class LoopVariable {
338
+ constructor(name, initialValue, typeAnnotation) {
339
+ this.name = name;
340
+ this.initialValue = initialValue;
341
+ this.typeAnnotation = typeAnnotation;
342
+ }
343
+ }
344
+
345
+ /**
346
+ * Loop variable update within loop body
347
+ * @example sum = sum + i, count += 1, counter++
348
+ */
349
+ export class VariableUpdate extends ASTNode {
350
+ constructor(variableName, operator, value, location) {
351
+ super("VariableUpdate", location);
352
+ this.variableName = variableName;
353
+ this.operator = operator; // '=' | '+=' | '-=' | '*=' | '/=' | '++' | '--'
354
+ this.value = value; // ASTNode | null (null for ++ and --)
355
+ }
356
+ }
357
+
358
+ // ============================================================================
359
+ // LOOP DRIVERS
360
+ // ============================================================================
361
+
362
+ /**
363
+ * Base class for loop drivers
364
+ */
365
+ export class LoopDriver {
366
+ constructor(type, location) {
367
+ this.type = type;
368
+ this.location = location;
369
+ }
370
+ }
371
+
372
+ /**
373
+ * For driver: ~for(pattern in iterable)
374
+ * @example ~for(i in 1..=10), ~for(item in items)
375
+ */
376
+ export class ForDriver extends LoopDriver {
377
+ constructor(pattern, iterable, step, location) {
378
+ super("for", location);
379
+ this.pattern = pattern;
380
+ this.iterable = iterable;
381
+ this.step = step;
382
+ }
383
+ }
384
+
385
+ /**
386
+ * While driver: ~while(condition)
387
+ * @example ~while(sum < 100), ~while(count > 0)
388
+ */
389
+ export class WhileDriver extends LoopDriver {
390
+ constructor(condition, location) {
391
+ super("while", location);
392
+ this.condition = condition;
393
+ }
394
+ }
395
+
396
+ // ============================================================================
397
+ // FUNCTIONS
398
+ // ============================================================================
399
+
400
+ /**
401
+ * Function definition
402
+ * @example fn add(x, y) = x + y
403
+ * @example fn abs(x) { if (x >= 0) { return x } else { return -x } }
404
+ * @example extend fn T(self: array) = transpose(self)
405
+ */
406
+ export class FunctionDefinition extends ASTNode {
407
+ constructor(name, parameters, returnType, body, isExpression, location) {
408
+ super("FunctionDefinition", location);
409
+ this.name = name;
410
+ this.parameters = parameters; // Array<Parameter>
411
+ this.returnType = returnType; // TypeAnnotation | null
412
+ this.body = body; // ASTNode (expression) or Array<ASTNode> (block)
413
+ this.isExpression = isExpression; // true for `= expr`, false for `{ ... }`
414
+ this.isExtension = false; // true for `extend fn` - enables method call syntax
415
+ this.selfType = null; // TypeAnnotation for extension's self parameter
416
+ }
417
+ }
418
+
419
+ /**
420
+ * Function parameter
421
+ */
422
+ export class Parameter {
423
+ constructor(name, typeAnnotation, defaultValue) {
424
+ this.name = name;
425
+ this.typeAnnotation = typeAnnotation;
426
+ this.defaultValue = defaultValue;
427
+ }
428
+ }
429
+
430
+ // ============================================================================
431
+ // TYPES
432
+ // ============================================================================
433
+
434
+ /**
435
+ * Type annotation - represents parsed type syntax
436
+ *
437
+ * Kinds:
438
+ * - 'simple': Int, Float, Bool, String, Unit
439
+ * - 'generic': Array<Float, 2>, List<Int>
440
+ * - 'function': (Int, Int) -> Float
441
+ * - 'record': { x: Int, y: Float }
442
+ * - 'union': Int | String
443
+ *
444
+ * @example Int, String?, Array<Float, 2>, List<Int>, (Int) -> Bool
445
+ */
446
+ export class TypeAnnotation {
447
+ constructor(kind, details, location = null) {
448
+ this.kind = kind; // 'simple' | 'generic' | 'function' | 'record' | 'union'
449
+ this.details = details; // type-specific details
450
+ this.location = location;
451
+ this.isOptional = false; // set separately when ? is present
452
+ }
453
+
454
+ // Convenience getters for backward compatibility
455
+ get baseType() {
456
+ if (this.kind === "simple") {
457
+ return this.details.name;
458
+ }
459
+ if (this.kind === "generic") {
460
+ return this.details.name;
461
+ }
462
+ return null;
463
+ }
464
+
465
+ get genericParams() {
466
+ if (this.kind === "generic") {
467
+ return this.details.params;
468
+ }
469
+ return null;
470
+ }
471
+
472
+ toString() {
473
+ let str;
474
+ switch (this.kind) {
475
+ case "simple":
476
+ str = this.details.name;
477
+ break;
478
+ case "generic":
479
+ const params = this.details.params
480
+ .map((p) => (p instanceof TypeAnnotation ? p.toString() : String(p)))
481
+ .join(", ");
482
+ str = `${this.details.name}<${params}>`;
483
+ break;
484
+ case "function":
485
+ const paramTypes = this.details.paramTypes
486
+ .map((t) => t.toString())
487
+ .join(", ");
488
+ str = `(${paramTypes}) -> ${this.details.returnType.toString()}`;
489
+ break;
490
+ case "record":
491
+ const fields = this.details.fields
492
+ .map((f) => `${f.name}: ${f.type.toString()}`)
493
+ .join(", ");
494
+ const suffix = this.details.open ? ", .." : "";
495
+ str = `{ ${fields}${suffix} }`;
496
+ break;
497
+ case "union":
498
+ str = this.details.types.map((t) => t.toString()).join(" | ");
499
+ break;
500
+ case "promoted":
501
+ str = `${this.details.targetType.toString()} | ${this.details.converterFunc}(${this.details.paramRef})`;
502
+ break;
503
+ default:
504
+ str = "unknown";
505
+ }
506
+ return this.isOptional ? `${str}?` : str;
507
+ }
508
+ }
509
+
510
+ /**
511
+ * Helper to create a simple type annotation
512
+ */
513
+ export function simpleType(name, location = null) {
514
+ return new TypeAnnotation("simple", { name }, location);
515
+ }
516
+
517
+ /**
518
+ * Helper to create a generic type annotation
519
+ */
520
+ export function genericType(name, params, location = null) {
521
+ return new TypeAnnotation("generic", { name, params }, location);
522
+ }
523
+
524
+ /**
525
+ * Helper to create a function type annotation
526
+ */
527
+ export function functionType(paramTypes, returnType, location = null) {
528
+ return new TypeAnnotation("function", { paramTypes, returnType }, location);
529
+ }
530
+
531
+ /**
532
+ * Helper to create a record type annotation
533
+ */
534
+ export function recordType(fields, open = false, location = null) {
535
+ return new TypeAnnotation("record", { fields, open }, location);
536
+ }
537
+
538
+ // ============================================================================
539
+ // RANGES
540
+ // ============================================================================
541
+
542
+ /**
543
+ * Range expression
544
+ * @example 1..10, 1..<10, 0..100 by 2
545
+ */
546
+ export class Range extends ASTNode {
547
+ constructor(start, end, inclusive, step, location) {
548
+ super("Range", location);
549
+ this.start = start;
550
+ this.end = end;
551
+ this.inclusive = inclusive; // true for ..=, false for ..<
552
+ this.step = step;
553
+ }
554
+ }
555
+
556
+ // ============================================================================
557
+ // MODULES (IMPORTS & EXPORTS)
558
+ // ============================================================================
559
+
560
+ /**
561
+ * Import statement - selective import
562
+ * @example import calcVelocity, calcAcceleration from physics/mechanics/SpeedCalcUtility
563
+ * @example import calcVelocity as vel from physics/mechanics/SpeedCalcUtility
564
+ * @example import stats from "core logic/math" (quoted path with inferred filename)
565
+ */
566
+ export class ImportStatement extends ASTNode {
567
+ constructor(specifiers, modulePath, location, isQuotedPath = false, inferredFilename = null) {
568
+ super("ImportStatement", location);
569
+ this.specifiers = specifiers; // Array<ImportSpecifier>
570
+ this.modulePath = modulePath; // string - module path like "physics/mechanics/SpeedCalcUtility"
571
+ this.isNamespaceImport = false;
572
+ this.isQuotedPath = isQuotedPath; // boolean - true if path was a string literal
573
+ this.inferredFilename = inferredFilename; // string | null - filename to append for directory imports
574
+ }
575
+ }
576
+
577
+ /**
578
+ * Namespace import statement
579
+ * @example import physics/mechanics/SpeedCalcUtility as Speed
580
+ * @example import physics/mechanics/SpeedCalcUtility (auto-binds as SpeedCalcUtility)
581
+ * @example import "core logic/math/stats" as stats (quoted path)
582
+ */
583
+ export class NamespaceImportStatement extends ASTNode {
584
+ constructor(modulePath, alias, location, isQuotedPath = false) {
585
+ super("NamespaceImportStatement", location);
586
+ this.modulePath = modulePath; // string - module path
587
+ this.alias = alias; // string | null - if null, use last segment of path
588
+ this.isNamespaceImport = true;
589
+ this.isQuotedPath = isQuotedPath; // boolean - true if path was a string literal
590
+ }
591
+ }
592
+
593
+ /**
594
+ * Import specifier (for selective imports)
595
+ * @example name1 as local1
596
+ */
597
+ export class ImportSpecifier {
598
+ constructor(importedName, localName, location = null) {
599
+ this.importedName = importedName; // Original exported name
600
+ this.localName = localName || importedName; // Local binding name (alias)
601
+ this.location = location; // Source location for error reporting
602
+ }
603
+ }
604
+
605
+ /**
606
+ * Export statement - marks a binding as exported
607
+ * @example export fn calcVelocity(d, t) = d / t
608
+ * @example export constant = 42
609
+ */
610
+ export class ExportStatement extends ASTNode {
611
+ constructor(declaration, location) {
612
+ super("ExportStatement", location);
613
+ this.declaration = declaration; // The exported declaration (FunctionDefinition, Assignment, etc.)
614
+ }
615
+ }
616
+
617
+ /**
618
+ * Selective re-export - re-exports specific names from another module
619
+ * @example export add, sub from ./math
620
+ * @example export add as plus, sub as minus from ./math
621
+ */
622
+ export class SelectiveReExportStatement extends ASTNode {
623
+ constructor(specifiers, modulePath, location) {
624
+ super("SelectiveReExportStatement", location);
625
+ this.specifiers = specifiers; // Array of { name, alias } objects
626
+ this.modulePath = modulePath; // The module to re-export from
627
+ }
628
+ }
629
+
630
+ /**
631
+ * Namespace re-export - re-exports an entire module as a namespace
632
+ * @example export ./math as math
633
+ * @example export ./physics/mechanics/SpeedCalcUtility
634
+ */
635
+ export class NamespaceReExportStatement extends ASTNode {
636
+ constructor(modulePath, alias, location) {
637
+ super("NamespaceReExportStatement", location);
638
+ this.modulePath = modulePath; // The module path to re-export
639
+ this.alias = alias; // Optional alias name (if null, uses last path segment)
640
+ }
641
+ }
642
+
643
+ // ============================================================================
644
+ // PROGRAM ROOT
645
+ // ============================================================================
646
+
647
+ /**
648
+ * Top-level program/module
649
+ */
650
+ export class Program extends ASTNode {
651
+ constructor(statements, location) {
652
+ super("Program", location);
653
+ this.statements = statements;
654
+ this.imports = []; // Will be populated by parser
655
+ this.exports = []; // Will be populated by parser
656
+ }
657
+ }
658
+
659
+ // ============================================================================
660
+ // HELPER FUNCTIONS
661
+ // ============================================================================
662
+
663
+ export function createLocation(line, column, file = null) {
664
+ return { line, column, file };
665
+ }
666
+
667
+ export function isExpression(node) {
668
+ return (
669
+ node instanceof Literal ||
670
+ node instanceof Identifier ||
671
+ node instanceof BinaryOp ||
672
+ node instanceof UnaryOp ||
673
+ node instanceof FunctionCall ||
674
+ node instanceof ArrayLiteral ||
675
+ node instanceof ObjectLiteral ||
676
+ node instanceof BlockExpression ||
677
+ node instanceof BindingStructure ||
678
+ node instanceof MemberAccess ||
679
+ node instanceof StringInterpolation ||
680
+ node instanceof BranchExpression ||
681
+ node instanceof LoopExpression ||
682
+ node instanceof Range
683
+ );
684
+ }
685
+
686
+ export function isStatement(node) {
687
+ return (
688
+ node instanceof Assignment ||
689
+ node instanceof IndexedAssignment ||
690
+ node instanceof ReturnStatement ||
691
+ node instanceof BreakStatement ||
692
+ node instanceof ContinueStatement ||
693
+ node instanceof VariableUpdate ||
694
+ node instanceof FunctionDefinition ||
695
+ node instanceof ImportStatement ||
696
+ node instanceof NamespaceImportStatement ||
697
+ node instanceof ExportStatement
698
+ );
699
+ }
700
+
701
+ export function hasDrivers(loopExpr) {
702
+ return loopExpr.drivers && loopExpr.drivers.length > 0;
703
+ }