yukigo-ast 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 (42) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/globals/generics.d.ts +740 -0
  3. package/dist/globals/generics.js +1128 -0
  4. package/dist/globals/helpers.d.ts +4 -0
  5. package/dist/globals/helpers.js +76 -0
  6. package/dist/globals/operators.d.ts +251 -0
  7. package/dist/globals/operators.js +336 -0
  8. package/dist/globals/patterns.d.ts +170 -0
  9. package/dist/globals/patterns.js +261 -0
  10. package/dist/globals/runtime.d.ts +22 -0
  11. package/dist/globals/runtime.js +6 -0
  12. package/dist/globals/types.d.ts +185 -0
  13. package/dist/globals/types.js +329 -0
  14. package/dist/index.d.ts +12 -0
  15. package/dist/index.js +12 -0
  16. package/dist/paradigms/data.d.ts +246 -0
  17. package/dist/paradigms/data.js +348 -0
  18. package/dist/paradigms/functional.d.ts +59 -0
  19. package/dist/paradigms/functional.js +103 -0
  20. package/dist/paradigms/imperative.d.ts +124 -0
  21. package/dist/paradigms/imperative.js +188 -0
  22. package/dist/paradigms/logic.d.ts +163 -0
  23. package/dist/paradigms/logic.js +240 -0
  24. package/dist/paradigms/object.d.ts +201 -0
  25. package/dist/paradigms/object.js +308 -0
  26. package/dist/visitor.d.ts +254 -0
  27. package/dist/visitor.js +426 -0
  28. package/package.json +25 -0
  29. package/src/globals/generics.ts +1421 -0
  30. package/src/globals/helpers.ts +107 -0
  31. package/src/globals/operators.ts +515 -0
  32. package/src/globals/patterns.ts +321 -0
  33. package/src/globals/runtime.ts +33 -0
  34. package/src/globals/types.ts +375 -0
  35. package/src/index.ts +12 -0
  36. package/src/paradigms/data.ts +393 -0
  37. package/src/paradigms/functional.ts +129 -0
  38. package/src/paradigms/imperative.ts +232 -0
  39. package/src/paradigms/logic.ts +314 -0
  40. package/src/paradigms/object.ts +366 -0
  41. package/src/visitor.ts +692 -0
  42. package/tsconfig.json +22 -0
@@ -0,0 +1,1128 @@
1
+ /**
2
+ * @hidden
3
+ */
4
+ export class ASTNode {
5
+ /** @hidden */
6
+ loc;
7
+ /** @hidden */
8
+ metadata = new Map();
9
+ constructor(loc, metadata) {
10
+ this.loc = loc;
11
+ this.metadata = metadata ?? new Map();
12
+ }
13
+ setMetadata(key, value) {
14
+ this.metadata.set(key, value);
15
+ }
16
+ getMetadata(key) {
17
+ return this.metadata.get(key);
18
+ }
19
+ hasMetadata(key) {
20
+ return this.metadata.has(key);
21
+ }
22
+ }
23
+ /**
24
+ * Generic number primitive
25
+ * @category Literals
26
+ */
27
+ export class NumberPrimitive extends ASTNode {
28
+ /** @hidden */
29
+ value;
30
+ constructor(value, loc) {
31
+ super(loc);
32
+ this.value = value;
33
+ }
34
+ accept(visitor) {
35
+ return visitor.visitNumberPrimitive?.(this);
36
+ }
37
+ /**
38
+ * Compares the primitive to other Primitive passed by argument
39
+ * @param other Another Primitive to compare to.
40
+ * @returns True if both primitive have the same value
41
+ */
42
+ equals(other) {
43
+ if (!(other instanceof NumberPrimitive))
44
+ return false;
45
+ return this.value === other.value;
46
+ }
47
+ toJSON() {
48
+ return {
49
+ type: "YuNumber",
50
+ value: this.value,
51
+ };
52
+ }
53
+ }
54
+ /**
55
+ * Generic boolean primitive
56
+ * @category Literals
57
+ */
58
+ export class BooleanPrimitive extends ASTNode {
59
+ /** @hidden */
60
+ value;
61
+ constructor(value, loc) {
62
+ super(loc);
63
+ this.value = value;
64
+ }
65
+ accept(visitor) {
66
+ return visitor.visitBooleanPrimitive?.(this);
67
+ }
68
+ /**
69
+ * Compares the primitive to other Primitive passed by argument
70
+ * @param other Another Primitive to compare to.
71
+ * @returns True if both primitive have the same value
72
+ */
73
+ equals(other) {
74
+ if (!(other instanceof BooleanPrimitive))
75
+ return false;
76
+ return this.value === other.value;
77
+ }
78
+ toJSON() {
79
+ return {
80
+ type: "YuBoolean",
81
+ value: this.value,
82
+ };
83
+ }
84
+ }
85
+ /**
86
+ * Represent lists - generic uniform variable-size collection of elements. Lists typically map to arrays, lists or sequence-like structures.
87
+ * @category Literals
88
+ */
89
+ export class ListPrimitive extends ASTNode {
90
+ /** @hidden */
91
+ elements;
92
+ constructor(elements, loc) {
93
+ super(loc);
94
+ this.elements = elements;
95
+ }
96
+ accept(visitor) {
97
+ return visitor.visitListPrimitive?.(this);
98
+ }
99
+ /**
100
+ * Compares the primitive to other Primitive passed by argument
101
+ * @param other Another Primitive to compare to.
102
+ * @returns True if both primitive have the same value
103
+ */
104
+ equals(other) {
105
+ if (!(other instanceof ListPrimitive))
106
+ return false;
107
+ return this.elements.every((elem, i) => elem === other.elements[i]);
108
+ }
109
+ toJSON() {
110
+ return {
111
+ type: "YuList",
112
+ value: this.elements,
113
+ };
114
+ }
115
+ }
116
+ /**
117
+ * Generic char primitive
118
+ * @category Literals
119
+ */
120
+ export class CharPrimitive extends ASTNode {
121
+ /** @hidden */
122
+ value;
123
+ constructor(value, loc) {
124
+ super(loc);
125
+ this.value = value;
126
+ }
127
+ accept(visitor) {
128
+ return visitor.visitCharPrimitive?.(this);
129
+ }
130
+ /**
131
+ * Compares the primitive to other Primitive passed by argument
132
+ * @param other Another Primitive to compare to.
133
+ * @returns True if both primitive have the same value
134
+ */
135
+ equals(other) {
136
+ if (!(other instanceof CharPrimitive))
137
+ return false;
138
+ return this.value === other.value;
139
+ }
140
+ toJSON() {
141
+ return {
142
+ type: "YuChar",
143
+ value: this.value,
144
+ };
145
+ }
146
+ }
147
+ /**
148
+ * Generic string primitive
149
+ * @category Literals
150
+ */
151
+ export class StringPrimitive extends ASTNode {
152
+ /** @hidden */
153
+ value;
154
+ constructor(value, loc) {
155
+ super(loc);
156
+ this.value = value;
157
+ }
158
+ accept(visitor) {
159
+ return visitor.visitStringPrimitive?.(this);
160
+ }
161
+ /**
162
+ * Compares the primitive to other Primitive passed by argument
163
+ * @param other Another Primitive to compare to.
164
+ * @returns True if both primitive have the same value
165
+ */
166
+ equals(other) {
167
+ if (!(other instanceof StringPrimitive))
168
+ return false;
169
+ return this.value === other.value;
170
+ }
171
+ toJSON() {
172
+ return {
173
+ type: "YuString",
174
+ value: this.value,
175
+ };
176
+ }
177
+ }
178
+ /**
179
+ * Generic null/undefined primitive
180
+ * @category Literals
181
+ */
182
+ export class NilPrimitive extends ASTNode {
183
+ /** @hidden */
184
+ value;
185
+ constructor(value, loc) {
186
+ super(loc);
187
+ this.value = value;
188
+ }
189
+ accept(visitor) {
190
+ return visitor.visitNilPrimitive?.(this);
191
+ }
192
+ /**
193
+ * Compares the primitive to other Primitive passed by argument
194
+ * @param other Another Primitive to compare to.
195
+ * @returns True if both primitive have the same value
196
+ */
197
+ equals(other) {
198
+ if (!(other instanceof NilPrimitive))
199
+ return false;
200
+ return this.value === other.value;
201
+ }
202
+ toJSON() {
203
+ return {
204
+ type: "YuNil",
205
+ value: this.value,
206
+ };
207
+ }
208
+ }
209
+ /**
210
+ * Generic symbol primitive
211
+ * @category Literals
212
+ */
213
+ export class SymbolPrimitive extends ASTNode {
214
+ /** @hidden */
215
+ value;
216
+ constructor(value, loc) {
217
+ super(loc);
218
+ this.value = value;
219
+ }
220
+ accept(visitor) {
221
+ return visitor.visitSymbolPrimitive?.(this);
222
+ }
223
+ /**
224
+ * Compares the primitive to other Primitive passed by argument
225
+ * @param other Another Primitive to compare to.
226
+ * @returns True if both primitive have the same value
227
+ */
228
+ equals(other) {
229
+ if (!(other instanceof SymbolPrimitive))
230
+ return false;
231
+ return this.value === other.value;
232
+ }
233
+ toJSON() {
234
+ return {
235
+ type: "YuSymbol",
236
+ value: this.value,
237
+ };
238
+ }
239
+ }
240
+ /**
241
+ * Source location information
242
+ */
243
+ export class SourceLocation {
244
+ line;
245
+ column;
246
+ constructor(line, column) {
247
+ this.line = line;
248
+ this.column = column;
249
+ }
250
+ toJSON() {
251
+ return {
252
+ type: "SourceLocation",
253
+ line: this.line,
254
+ column: this.column,
255
+ };
256
+ }
257
+ }
258
+ // Expressions
259
+ /**
260
+ * Represent tuples - generic non-uniform fixed-size collection of elements
261
+ *
262
+ * @example
263
+ * (1, "Hello", true)
264
+ * @category Expressions
265
+ */
266
+ export class TupleExpression extends ASTNode {
267
+ /** @hidden */
268
+ elements;
269
+ constructor(elements, loc) {
270
+ super(loc);
271
+ this.elements = elements;
272
+ }
273
+ accept(visitor) {
274
+ return visitor.visitTupleExpr?.(this);
275
+ }
276
+ toJSON() {
277
+ return {
278
+ type: "TupleExpression",
279
+ elements: this.elements.map((expr) => expr.toJSON()),
280
+ };
281
+ }
282
+ }
283
+ /**
284
+ * Fields of a data expression representations
285
+ * @category Expressions
286
+ */
287
+ export class FieldExpression extends ASTNode {
288
+ /** @hidden */
289
+ expression;
290
+ /** @hidden */
291
+ name;
292
+ constructor(name, expression, loc) {
293
+ super(loc);
294
+ this.name = name;
295
+ this.expression = expression;
296
+ }
297
+ accept(visitor) {
298
+ return visitor.visitFieldExpr?.(this);
299
+ }
300
+ toJSON() {
301
+ return {
302
+ type: "FieldExpression",
303
+ name: this.name.toJSON(),
304
+ expression: this.expression.toJSON(),
305
+ };
306
+ }
307
+ }
308
+ /**
309
+ * Data expression, used to construct Records
310
+ * @example
311
+ * f = DataName { fieldName = 2 }
312
+ * @category Expressions
313
+ */
314
+ export class DataExpression extends ASTNode {
315
+ /** @hidden */
316
+ contents;
317
+ /** @hidden */
318
+ name;
319
+ constructor(name, contents, loc) {
320
+ super(loc);
321
+ this.name = name;
322
+ this.contents = contents;
323
+ }
324
+ accept(visitor) {
325
+ return visitor.visitDataExpr?.(this);
326
+ }
327
+ toJSON() {
328
+ return {
329
+ type: "DataExpression",
330
+ name: this.name.toJSON(),
331
+ contents: this.contents.map((expr) => expr.toJSON()),
332
+ };
333
+ }
334
+ }
335
+ /**
336
+ * Cons expression, represent a concatenation of a head and a tail
337
+ * @example
338
+ * f = x : xs
339
+ * @category Expressions
340
+ */
341
+ export class ConsExpression extends ASTNode {
342
+ /** @hidden */
343
+ tail;
344
+ /** @hidden */
345
+ head;
346
+ constructor(head, tail, loc) {
347
+ super(loc);
348
+ this.head = head;
349
+ this.tail = tail;
350
+ }
351
+ accept(visitor) {
352
+ return visitor.visitConsExpr?.(this);
353
+ }
354
+ toJSON() {
355
+ return {
356
+ type: "ConsExpression",
357
+ head: this.head.toJSON(),
358
+ tail: this.tail.toJSON(),
359
+ };
360
+ }
361
+ }
362
+ /**
363
+ * Represent let...in expressions normally used in Haskell
364
+ * @example
365
+ * f = let x = 2 in x * 4
366
+ * @category Expressions
367
+ */
368
+ export class LetInExpression extends ASTNode {
369
+ /** @hidden */
370
+ expression;
371
+ /** @hidden */
372
+ declarations;
373
+ constructor(declarations, expression, loc) {
374
+ super(loc);
375
+ this.declarations = declarations;
376
+ this.expression = expression;
377
+ }
378
+ accept(visitor) {
379
+ return visitor.visitLetInExpr?.(this);
380
+ }
381
+ toJSON() {
382
+ return {
383
+ type: "LetInExpression",
384
+ declarations: this.declarations.toJSON(),
385
+ expression: this.expression.toJSON(),
386
+ };
387
+ }
388
+ }
389
+ /**
390
+ * Otherwise used as the default case in GuardBody
391
+ * @example
392
+ * f x
393
+ * | x == 2 = 16
394
+ * | otherwise = x * 8
395
+ * @category Declarations
396
+ */
397
+ export class Otherwise extends ASTNode {
398
+ accept(visitor) {
399
+ return visitor.visitOtherwise?.(this);
400
+ }
401
+ toJSON() {
402
+ return {
403
+ type: "Otherwise",
404
+ };
405
+ }
406
+ }
407
+ /**
408
+ * ListComprehension when the for expression is a yield.
409
+ * Scala's for comprehensions, Erlang's and Haskell's list comprehensions
410
+ * @example
411
+ * m = [ f x | x <- [1, 2, 3, 4] ]
412
+ * @category Expressions
413
+ */
414
+ export class ListComprehension extends ASTNode {
415
+ /** @hidden */
416
+ generators;
417
+ /** @hidden */
418
+ projection;
419
+ constructor(projection, generators, loc) {
420
+ super(loc);
421
+ this.projection = projection;
422
+ this.generators = generators;
423
+ }
424
+ accept(visitor) {
425
+ return visitor.visitListComprehension?.(this);
426
+ }
427
+ toJSON() {
428
+ return {
429
+ type: "ListComprehension",
430
+ projection: this.projection.toJSON(),
431
+ generators: this.generators.map((gen) => gen.toJSON()),
432
+ };
433
+ }
434
+ }
435
+ /**
436
+ * Generator represents patterns like "Just m <- ms" or "x <- [1,2,3]"
437
+ * @example
438
+ * x <- [1, 2, 3, 4]
439
+ * @category Declarations
440
+ */
441
+ export class Generator extends ASTNode {
442
+ /** @hidden */
443
+ expression;
444
+ /** @hidden */
445
+ variable;
446
+ constructor(variable, expression, loc) {
447
+ super(loc);
448
+ this.variable = variable;
449
+ this.expression = expression;
450
+ }
451
+ accept(visitor) {
452
+ return visitor.visitGenerator?.(this);
453
+ }
454
+ toJSON() {
455
+ return {
456
+ type: "Generator",
457
+ variable: this.variable.toJSON(),
458
+ expression: this.expression.toJSON(),
459
+ };
460
+ }
461
+ }
462
+ /**
463
+ * RangeExpression represents when a list is given by comprehension in a defined range
464
+ * @example
465
+ * (1..10)
466
+ * @example
467
+ * (1, 2..10)
468
+ * @example
469
+ * (1..)
470
+ * @category Expressions
471
+ */
472
+ export class RangeExpression extends ASTNode {
473
+ /** @hidden */
474
+ step;
475
+ /** @hidden */
476
+ end;
477
+ /** @hidden */
478
+ start;
479
+ constructor(start, end, // undefined for infinite ranges like [0..]
480
+ step, // for [start, second .. end] syntax
481
+ loc) {
482
+ super(loc);
483
+ this.start = start;
484
+ this.end = end;
485
+ this.step = step;
486
+ }
487
+ accept(visitor) {
488
+ return visitor.visitRangeExpression?.(this);
489
+ }
490
+ toJSON() {
491
+ return {
492
+ type: "RangeExpression",
493
+ start: this.start.toJSON(),
494
+ end: this.end?.toJSON(),
495
+ step: this.step?.toJSON(),
496
+ };
497
+ }
498
+ }
499
+ //export type Expression = {
500
+ // type: "Expression";
501
+ // body: BodyExpression;
502
+ //};
503
+ // Statements
504
+ /**
505
+ * Generic conditional If statements.
506
+ * Nested `else if` need to be desugared into `else { if ... }`
507
+ * @example
508
+ * if (condition) { ... } else { ... }
509
+ * @category Expressions
510
+ */
511
+ export class If extends ASTNode {
512
+ /** @hidden */
513
+ elseExpr;
514
+ /** @hidden */
515
+ then;
516
+ /** @hidden */
517
+ condition;
518
+ constructor(condition, then, elseExpr, loc) {
519
+ super(loc);
520
+ this.condition = condition;
521
+ this.then = then;
522
+ this.elseExpr = elseExpr;
523
+ }
524
+ accept(visitor) {
525
+ return visitor.visitIf?.(this);
526
+ }
527
+ toJSON() {
528
+ return {
529
+ type: "If",
530
+ condition: this.condition.toJSON(),
531
+ then: this.then.toJSON(),
532
+ else: this.elseExpr.toJSON(),
533
+ };
534
+ }
535
+ }
536
+ /**
537
+ * Generic return statement.
538
+ * @example
539
+ * // In Haskell
540
+ * f x = x * 2
541
+ * // The parser takes the body and uses it as a Return
542
+ * @example
543
+ * function f(x) {
544
+ * return x * 2 // The node holds this expression
545
+ * }
546
+ * @category Statements
547
+ */
548
+ export class Return extends ASTNode {
549
+ /** @hidden */
550
+ body;
551
+ constructor(body = new NilPrimitive(null), loc) {
552
+ super(loc);
553
+ this.body = body;
554
+ }
555
+ accept(visitor) {
556
+ return visitor.visitReturn?.(this);
557
+ }
558
+ toJSON() {
559
+ return {
560
+ type: "Return",
561
+ body: this.body.toJSON(),
562
+ };
563
+ }
564
+ }
565
+ /**
566
+ * Generic field in a Record statement.
567
+ * The name can be undefined to support positional-only Records
568
+ * @example
569
+ * ... { name :: String }
570
+ * @category Declarations
571
+ */
572
+ export class Field extends ASTNode {
573
+ /** @hidden */
574
+ value;
575
+ /** @hidden */
576
+ name;
577
+ constructor(name, value, loc) {
578
+ super(loc);
579
+ this.name = name;
580
+ this.value = value;
581
+ }
582
+ accept(visitor) {
583
+ return visitor.visitField?.(this);
584
+ }
585
+ toJSON() {
586
+ return {
587
+ type: "Field",
588
+ name: this.name.toJSON(),
589
+ value: this.value.toJSON(),
590
+ };
591
+ }
592
+ }
593
+ /**
594
+ * Generic constructor node.
595
+ * Holds an array of Field nodes.
596
+ * @example
597
+ * data Record = Constructor { field :: String }
598
+ * @category Declarations
599
+ */
600
+ export class Constructor extends ASTNode {
601
+ /** @hidden */
602
+ fields;
603
+ /** @hidden */
604
+ name;
605
+ constructor(name, fields, loc) {
606
+ super(loc);
607
+ this.name = name;
608
+ this.fields = fields;
609
+ }
610
+ accept(visitor) {
611
+ return visitor.visitConstructor?.(this);
612
+ }
613
+ toJSON() {
614
+ return {
615
+ type: "Constructor",
616
+ name: this.name.toJSON(),
617
+ fields: this.fields.map((f) => f.toJSON()),
618
+ };
619
+ }
620
+ }
621
+ /**
622
+ * Generic Record statement node.
623
+ * @example
624
+ * data Record = Constructor { field :: String }
625
+ * data PositionalRecord = Constructor String String
626
+ * @category Declarations
627
+ */
628
+ export class Record extends ASTNode {
629
+ /** @hidden */
630
+ deriving;
631
+ /** @hidden */
632
+ contents;
633
+ /** @hidden */
634
+ name;
635
+ constructor(name, contents, deriving, loc) {
636
+ super(loc);
637
+ this.name = name;
638
+ this.contents = contents;
639
+ this.deriving = deriving;
640
+ }
641
+ accept(visitor) {
642
+ return visitor.visitRecord?.(this);
643
+ }
644
+ toJSON() {
645
+ return {
646
+ type: "Record",
647
+ name: this.name.toJSON(),
648
+ contents: this.contents.map((constructor) => constructor.toJSON()),
649
+ deriving: this.deriving?.map((d) => d.toJSON()),
650
+ };
651
+ }
652
+ }
653
+ /**
654
+ * Represents the body of an Equation that does not have guards.
655
+ * Most languages match the body of its equations to it.
656
+ * @example
657
+ * f x = x + 2
658
+ * // The body is the `x + 2` part
659
+ * @example
660
+ * function f(x) {
661
+ * return x + 2;
662
+ * }
663
+ * @category Declarations
664
+ */
665
+ export class UnguardedBody extends ASTNode {
666
+ /** @hidden */
667
+ sequence;
668
+ constructor(sequence, loc) {
669
+ super(loc);
670
+ this.sequence = sequence;
671
+ }
672
+ accept(visitor) {
673
+ return visitor.visitUnguardedBody?.(this);
674
+ }
675
+ toJSON() {
676
+ return {
677
+ type: "UnguardedBody",
678
+ sequence: this.sequence.toJSON(),
679
+ };
680
+ }
681
+ }
682
+ /**
683
+ * Represents the body of an Equation that does have guards.
684
+ * For example, Haskell's guards
685
+ * @example
686
+ * f x
687
+ * | x > 2 = x * 2
688
+ * | otherwise = x / 2
689
+ * @category Declarations
690
+ */
691
+ export class GuardedBody extends ASTNode {
692
+ /** @hidden */
693
+ body;
694
+ /** @hidden */
695
+ condition;
696
+ constructor(condition, body, loc) {
697
+ super(loc);
698
+ this.condition = condition;
699
+ this.body = body;
700
+ }
701
+ accept(visitor) {
702
+ return visitor.visitGuardedBody?.(this);
703
+ }
704
+ toJSON() {
705
+ return {
706
+ type: "GuardedBody",
707
+ condition: this.condition.toJSON(),
708
+ body: this.body.toJSON(),
709
+ };
710
+ }
711
+ }
712
+ /**
713
+ * Represents one Equation with its arguments and body. Allows for overloading and pattern matching.
714
+ * You may define the return statement to access it more easily.
715
+ *
716
+ * @example
717
+ * add 0 y = y
718
+ * add x y = x + y
719
+ * @category Declarations
720
+ */
721
+ export class Equation extends ASTNode {
722
+ /** @hidden */
723
+ patterns;
724
+ /** @hidden */
725
+ body;
726
+ /** @hidden */
727
+ returnExpr;
728
+ constructor(patterns, body, returnExpr, loc) {
729
+ super(loc);
730
+ this.patterns = patterns;
731
+ this.body = body;
732
+ this.returnExpr = returnExpr;
733
+ }
734
+ /** @hidden */
735
+ accept(visitor) {
736
+ return visitor.visitEquation?.(this);
737
+ }
738
+ /** @hidden */
739
+ toJSON() {
740
+ return {
741
+ type: "Equation",
742
+ patterns: this.patterns.map((pattern) => pattern.toJSON),
743
+ body: Array.isArray(this.body)
744
+ ? this.body.map((guard) => guard.toJSON())
745
+ : this.body.toJSON(),
746
+ return: this.returnExpr.toJSON(),
747
+ };
748
+ }
749
+ }
750
+ /**
751
+ * Functional / Imperative programming function declaration.
752
+ * It is is composed by an identifier and one or more equations
753
+ * @example
754
+ * int foo (int bar) {
755
+ * return bar;
756
+ * }
757
+ * @example
758
+ * def foo(bar):
759
+ * return bar
760
+ * @category Declarations
761
+ */
762
+ export class Function extends ASTNode {
763
+ /** @hidden */
764
+ equations;
765
+ /** @hidden */
766
+ identifier;
767
+ constructor(identifier, equations, loc) {
768
+ super(loc);
769
+ this.identifier = identifier;
770
+ this.equations = equations;
771
+ }
772
+ accept(visitor) {
773
+ return visitor.visitFunction?.(this);
774
+ }
775
+ toJSON() {
776
+ return {
777
+ type: "Function",
778
+ identifier: this.identifier.toJSON(),
779
+ equations: this.equations.map((eq) => eq.toJSON()),
780
+ };
781
+ }
782
+ }
783
+ /**
784
+ * Represents a case expression, selecting a branch based on pattern matching against a value.
785
+ *
786
+ * @example
787
+ * case x of
788
+ * [] -> 0
789
+ * (x:xs) -> 1 + length xs
790
+ * @category Expressions
791
+ */
792
+ export class Case extends ASTNode {
793
+ /** @hidden */
794
+ body;
795
+ /** @hidden */
796
+ condition;
797
+ constructor(condition, body, loc) {
798
+ super(loc);
799
+ this.condition = condition;
800
+ this.body = body;
801
+ }
802
+ accept(visitor) {
803
+ return visitor.visitCase?.(this);
804
+ }
805
+ toJSON() {
806
+ return {
807
+ type: "Case",
808
+ condition: this.condition.toJSON(),
809
+ body: this.body.toJSON(),
810
+ };
811
+ }
812
+ }
813
+ /**
814
+ * Represents a switch statement, selecting execution paths based on value equality.
815
+ * @category Expressions
816
+ */
817
+ export class Switch extends ASTNode {
818
+ /** @hidden */
819
+ defaultExpr;
820
+ /** @hidden */
821
+ cases;
822
+ /** @hidden */
823
+ value;
824
+ constructor(value, cases, defaultExpr, loc) {
825
+ super(loc);
826
+ this.value = value;
827
+ this.cases = cases;
828
+ this.defaultExpr = defaultExpr;
829
+ }
830
+ accept(visitor) {
831
+ return visitor.visitSwitch?.(this);
832
+ }
833
+ toJSON() {
834
+ return {
835
+ type: "Switch",
836
+ value: this.value.toJSON(),
837
+ cases: this.cases.map((caseVal) => ({
838
+ condition: caseVal.condition.toJSON(),
839
+ body: caseVal.body.toJSON(),
840
+ })),
841
+ default: this.defaultExpr.toJSON(),
842
+ };
843
+ }
844
+ }
845
+ /**
846
+ * Represents a catch block for handling exceptions thrown in a try block.
847
+ * @category Statements
848
+ */
849
+ export class Catch extends ASTNode {
850
+ /** @hidden */
851
+ body;
852
+ /** @hidden */
853
+ patterns;
854
+ constructor(patterns, body, loc) {
855
+ super(loc);
856
+ this.patterns = patterns;
857
+ this.body = body;
858
+ }
859
+ accept(visitor) {
860
+ return visitor.visitCatch?.(this);
861
+ }
862
+ toJSON() {
863
+ return {
864
+ type: "Catch",
865
+ patterns: this.patterns.map((pat) => pat.toJSON()),
866
+ body: this.body.toJSON(),
867
+ };
868
+ }
869
+ }
870
+ /**
871
+ * Represents a try block, wrapping code that might throw exceptions.
872
+ *
873
+ * @example
874
+ * try { ... } catch e : DomainException { ... }
875
+ * @category Statements
876
+ */
877
+ export class Try extends ASTNode {
878
+ /** @hidden */
879
+ finallyExpr;
880
+ /** @hidden */
881
+ catchExpr;
882
+ /** @hidden */
883
+ body;
884
+ constructor(body, catchExpr, finallyExpr, loc) {
885
+ super(loc);
886
+ this.body = body;
887
+ this.catchExpr = catchExpr;
888
+ this.finallyExpr = finallyExpr;
889
+ }
890
+ accept(visitor) {
891
+ return visitor.visitTry?.(this);
892
+ }
893
+ toJSON() {
894
+ return {
895
+ type: "Try",
896
+ body: this.body.toJSON(),
897
+ catch: this.catchExpr.map(({ patterns, body }) => ({
898
+ condition: patterns.map((pattern) => pattern.toJSON()),
899
+ body: body.toJSON(),
900
+ })),
901
+ finally: this.finallyExpr.toJSON(),
902
+ };
903
+ }
904
+ }
905
+ /**
906
+ * Represents an explicit raising or throwing of an exception or error.
907
+ * @category Statements
908
+ */
909
+ export class Raise extends ASTNode {
910
+ /** @hidden */
911
+ body;
912
+ constructor(body, loc) {
913
+ super(loc);
914
+ this.body = body;
915
+ }
916
+ accept(visitor) {
917
+ return visitor.visitRaise?.(this);
918
+ }
919
+ toJSON() {
920
+ return {
921
+ type: "Raise",
922
+ body: this.body.toJSON(),
923
+ };
924
+ }
925
+ }
926
+ /**
927
+ * Represents a command to output data to the standard output.
928
+ * @category Statements
929
+ */
930
+ export class Print extends ASTNode {
931
+ /** @hidden */
932
+ expression;
933
+ constructor(expression, loc) {
934
+ super(loc);
935
+ this.expression = expression;
936
+ }
937
+ accept(visitor) {
938
+ return visitor.visitPrint?.(this);
939
+ }
940
+ toJSON() {
941
+ return {
942
+ type: "Print",
943
+ expression: this.expression.toJSON(),
944
+ };
945
+ }
946
+ }
947
+ /**
948
+ * Represents a command to read input from the user or standard input.
949
+ * @category Statements
950
+ */
951
+ export class Input extends ASTNode {
952
+ /** @hidden */
953
+ variable;
954
+ /** @hidden */
955
+ message;
956
+ constructor(message, variable, loc) {
957
+ super(loc);
958
+ this.message = message;
959
+ this.variable = variable;
960
+ }
961
+ accept(visitor) {
962
+ return visitor.visitInput?.(this);
963
+ }
964
+ toJSON() {
965
+ return {
966
+ type: "Input",
967
+ message: this.message.toJSON(),
968
+ variable: this.variable.toJSON(),
969
+ };
970
+ }
971
+ }
972
+ /**
973
+ * Represents a for-loop control structure for iterating over a sequence or range.
974
+ * @category Statements
975
+ */
976
+ export class For extends ASTNode {
977
+ /** @hidden */
978
+ statements;
979
+ /** @hidden */
980
+ body;
981
+ constructor(body, statements, loc) {
982
+ super(loc);
983
+ this.body = body;
984
+ this.statements = statements;
985
+ }
986
+ accept(visitor) {
987
+ return visitor.visitFor?.(this);
988
+ }
989
+ toJSON() {
990
+ return {
991
+ type: "For",
992
+ body: this.body.toJSON(),
993
+ statements: this.statements.map((stmt) => stmt.toJSON()),
994
+ };
995
+ }
996
+ }
997
+ /**
998
+ * Represents a control flow statement to exit the current loop immediately.
999
+ * @category Statements
1000
+ */
1001
+ export class Break extends ASTNode {
1002
+ /** @hidden */
1003
+ body;
1004
+ constructor(body = new NilPrimitive(null), loc) {
1005
+ super(loc);
1006
+ this.body = body;
1007
+ }
1008
+ accept(visitor) {
1009
+ return visitor.visitBreak?.(this);
1010
+ }
1011
+ toJSON() {
1012
+ return {
1013
+ type: "Break",
1014
+ body: this.body.toJSON(),
1015
+ };
1016
+ }
1017
+ }
1018
+ /**
1019
+ * Represents a control flow statement to skip the rest of the current loop iteration.
1020
+ * @category Statements
1021
+ */
1022
+ export class Continue extends ASTNode {
1023
+ /** @hidden */
1024
+ body;
1025
+ constructor(body = new NilPrimitive(null), loc) {
1026
+ super(loc);
1027
+ this.body = body;
1028
+ }
1029
+ accept(visitor) {
1030
+ return visitor.visitContinue?.(this);
1031
+ }
1032
+ toJSON() {
1033
+ return {
1034
+ type: "Continue",
1035
+ body: this.body.toJSON(),
1036
+ };
1037
+ }
1038
+ }
1039
+ /**
1040
+ * Represents a variable usage or reference in an expression.
1041
+ * @category Expressions
1042
+ */
1043
+ export class Variable extends ASTNode {
1044
+ /** @hidden */
1045
+ variableType;
1046
+ /** @hidden */
1047
+ expression;
1048
+ /** @hidden */
1049
+ identifier;
1050
+ constructor(identifier, expression, variableType, loc) {
1051
+ super(loc);
1052
+ this.identifier = identifier;
1053
+ this.expression = expression;
1054
+ this.variableType = variableType;
1055
+ }
1056
+ accept(visitor) {
1057
+ return visitor.visitVariable?.(this);
1058
+ }
1059
+ toJSON() {
1060
+ return {
1061
+ type: "Variable",
1062
+ identifier: this.identifier.toJSON(),
1063
+ expression: this.expression.toJSON(),
1064
+ variableType: this.variableType.toJSON(),
1065
+ };
1066
+ }
1067
+ }
1068
+ /**
1069
+ * Represents an assignment operation, binding a value to a variable.
1070
+ *
1071
+ * @example
1072
+ * count = count + 1
1073
+ * @category Statements
1074
+ */
1075
+ export class Assignment extends ASTNode {
1076
+ /** @hidden */
1077
+ expression;
1078
+ /** @hidden */
1079
+ identifier;
1080
+ constructor(identifier, expression, loc) {
1081
+ super(loc);
1082
+ this.identifier = identifier;
1083
+ this.expression = expression;
1084
+ }
1085
+ accept(visitor) {
1086
+ return visitor.visitAssignment?.(this);
1087
+ }
1088
+ toJSON() {
1089
+ return {
1090
+ type: "Assignment",
1091
+ identifier: this.identifier.toJSON(),
1092
+ expression: this.expression.toJSON(),
1093
+ };
1094
+ }
1095
+ }
1096
+ /**
1097
+ * Represents a sequence of statements executed in order.
1098
+ * @category Statements
1099
+ */
1100
+ export class Sequence extends ASTNode {
1101
+ /** @hidden */
1102
+ statements;
1103
+ constructor(statements, loc) {
1104
+ super(loc);
1105
+ this.statements = statements;
1106
+ }
1107
+ accept(visitor) {
1108
+ return visitor.visitSequence?.(this);
1109
+ }
1110
+ toJSON() {
1111
+ return {
1112
+ type: "Sequence",
1113
+ statements: this.statements.map((stmt) => stmt.toJSON()),
1114
+ };
1115
+ }
1116
+ }
1117
+ /* export interface Match {
1118
+ type: "Match";
1119
+ condition: Expression;
1120
+ body: Equation[];
1121
+ }
1122
+
1123
+ export interface Arrow {
1124
+ type: "Arrow";
1125
+ expression1: Expression[];
1126
+ expression2: Expression[];
1127
+ }
1128
+ */