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,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
|
+
}
|