lib/std/lang/ast.rad 26.7 KiB raw
1
//! Radiance AST modules.
2
export mod printer;
3
4
use std::io;
5
use std::fmt;
6
use std::lang::alloc;
7
8
/// Ownership and safety qualifier written in a pointer type.
9
/// Named reference regions are separate `TypeSig::RegionRef` nodes.
10
export union PointerClass: Copy {
11
    /// Owned pointer introduced by `*`.
12
    Owned,
13
    /// Borrowed reference introduced by `&`.
14
    Ref,
15
    /// Raw pointer introduced by `*unsafe`.
16
    Unsafe,
17
}
18
19
/// Maximum number of trait methods.
20
export constant MAX_TRAIT_METHODS: u32 = 8;
21
22
/// Arena for all parser allocations.
23
///
24
/// Uses a bump allocator for both AST nodes and node pointer arrays.
25
export record NodeArena {
26
    /// Bump allocator for all allocations.
27
    arena: alloc::Arena,
28
    /// Next node ID to assign. Incremented on each node allocation.
29
    nextId: u32,
30
}
31
32
/// Initialize a node arena backed by the given byte slice.
33
export fn nodeArena(data: *mut [u8]) -> NodeArena {
34
    return NodeArena {
35
        arena: alloc::new(data),
36
        nextId: 0,
37
    };
38
}
39
40
/// Create an empty `*mut [*Node]` slice with the given capacity.
41
export unsafe fn nodeSlice(arena: &mut NodeArena, capacity: u32) -> *mut [*Node] {
42
    if capacity == 0 {
43
        return &mut [];
44
    }
45
    let ptr = try! alloc::allocSlice(&mut arena.arena, @sizeOf(*Node), @alignOf(*Node), capacity);
46
47
    let nodes = ptr as *mut [*Node];
48
    return &mut nodes[..0];
49
}
50
51
/// Attribute bit set applied to declarations or fields.
52
export union Attribute: Copy {
53
    /// Public visibility attribute.
54
    Export = 0b1,
55
    /// Default implementation attribute.
56
    Default = 0b10,
57
    /// Extern linkage attribute.
58
    Extern = 0b100,
59
    /// Test-only declaration attribute.
60
    Test = 0b1000,
61
    /// Compiler intrinsic attribute.
62
    Intrinsic = 0b10000,
63
    /// Declaration may perform unsafe pointer operations.
64
    Unsafe = 0b100000,
65
}
66
67
/// Ordered collection of attribute nodes applied to a declaration.
68
export record Attributes: Copy {
69
    /// Attribute nodes in declaration order.
70
    list: *[*Node],
71
}
72
73
/// Check if an attributes list contains an attribute.
74
export fn attributesContains(self: &Attributes, attr: Attribute) -> bool {
75
    for node in self.list {
76
        if let case NodeValue::Attribute(a) = node.value; a == attr {
77
            return true;
78
        }
79
    }
80
    return false;
81
}
82
83
/// Check if an attribute set includes the given attribute.
84
export fn hasAttribute(attrs: u32, attr: Attribute) -> bool {
85
    return (attrs & (attr as u32)) <> 0;
86
}
87
88
/// Signedness of an integer type.
89
export union Signedness: Copy {
90
    /// Signed, eg. `i8`.
91
    Signed,
92
    /// Unsigned, eg. `u32`.
93
    Unsigned,
94
}
95
96
/// Binary operator kinds used in numeric expressions.
97
export union BinaryOp: Copy {
98
    /// Addition (`+`).
99
    Add,
100
    /// Subtraction (`-`).
101
    Sub,
102
    /// Multiplication (`*`).
103
    Mul,
104
    /// Division (`/`).
105
    Div,
106
    /// Remainder (`%`).
107
    Mod,
108
    /// Bitwise AND (`&`).
109
    BitAnd,
110
    /// Bitwise OR (`|`).
111
    BitOr,
112
    /// Bitwise XOR (`^`).
113
    BitXor,
114
    /// Left shift (`<<`).
115
    Shl,
116
    /// Right shift (`>>`).
117
    Shr,
118
119
    /// Equality comparison (`==`).
120
    Eq,
121
    /// Inequality comparison (`<>`).
122
    Ne,
123
    /// Less-than comparison (`<`).
124
    Lt,
125
    /// Greater-than comparison (`>`).
126
    Gt,
127
    /// Less-than-or-equal comparison (`<=`).
128
    Lte,
129
    /// Greater-than-or-equal comparison (`>=`).
130
    Gte,
131
132
    /// Logical conjunction (`and`).
133
    And,
134
    /// Logical disjunction (`or`).
135
    Or,
136
    /// Logical exclusive disjunction (`xor`).
137
    Xor,
138
}
139
140
/// Unary operator kinds used in expressions.
141
export union UnaryOp: Copy {
142
    /// Logical negation (`not`).
143
    Not,
144
    /// Arithmetic negation (`-`).
145
    Neg,
146
    /// Bitwise NOT (`~`).
147
    BitNot,
148
}
149
150
/// Builtin function kind.
151
export union Builtin: Copy {
152
    /// Size of type in bytes (`@sizeOf`).
153
    SizeOf,
154
    /// Alignment requirement of type (`@alignOf`).
155
    AlignOf,
156
    /// Construct a slice from pointer, length, and optional capacity (`@sliceOf`).
157
    SliceOf,
158
}
159
160
/// Source extent for a node measured in bytes.
161
export record Span: Copy {
162
    /// Byte offset from the start of the source file.
163
    offset: u32,
164
    /// Length of the node in bytes.
165
    length: u32,
166
}
167
168
/// Type signature node.
169
export union TypeSig: Copy {
170
    /// Absence of type.
171
    Void,
172
    /// A function return type with no possible value.
173
    Never,
174
    /// Opaque type.
175
    Opaque,
176
    /// Boolean type.
177
    Bool,
178
    /// Integer type.
179
    Integer {
180
        /// Size of values, in bytes.
181
        width: u8,
182
        /// Signedness of values.
183
        sign: Signedness,
184
    },
185
    /// Fixed-size array type, eg. `[i32; 16]`.
186
    Array {
187
        /// Array element type.
188
        itemType: *Node,
189
        /// Expression that evaluates to the array length.
190
        length: *Node,
191
    },
192
    /// Slice type, eg. `*[i32]`, `&[i32]`, or `*unsafe [i32]`.
193
    Slice {
194
        /// Ownership and safety class.
195
        class: PointerClass,
196
        /// Slice element type.
197
        itemType: *Node,
198
        /// Whether the slice is mutable.
199
        mutable: bool,
200
    },
201
    /// Pointer type, eg. `*i32`, `&i32`, or `*unsafe i32`.
202
    Pointer {
203
        /// Ownership and safety class.
204
        class: PointerClass,
205
        /// Pointer target type.
206
        valueType: *Node,
207
        /// Whether the pointer is mutable.
208
        mutable: bool,
209
    },
210
    /// Optional, eg. `?i32`.
211
    Optional {
212
        /// Underlying type.
213
        valueType: *Node,
214
    },
215
    /// Shared cell pointer with value access to its payload.
216
    Cell {
217
        /// Storage lifetime and ownership class.
218
        class: PointerClass,
219
        /// Copy payload type.
220
        payload: *Node,
221
    },
222
    /// Nominal type, points to identifier node.
223
    Nominal(*Node),
224
    /// Reference qualified by a lexical region.
225
    RegionRef {
226
        /// Region name node.
227
        region: *Node,
228
        /// Reference type node.
229
        type: *Node,
230
    },
231
    /// Nominal type with invariant region arguments.
232
    Applied {
233
        /// Nominal type path.
234
        name: *Node,
235
        /// Region arguments in declaration order.
236
        regions: *[*Node],
237
    },
238
    /// Inline record type for union variant payloads.
239
    Record {
240
        /// Field declaration nodes.
241
        fields: *[*Node],
242
        /// Whether this record has labeled fields.
243
        labeled: bool,
244
    },
245
    /// Anonymous function type.
246
    Fn {
247
        /// Parameter, return, and error types.
248
        sig: FnSig,
249
        /// Whether a call requires an unsafe function body.
250
        isUnsafe: bool,
251
    },
252
    /// Trait object type, eg. `*opaque Allocator`, `&opaque Allocator`, or
253
    /// `*unsafe opaque Allocator`.
254
    TraitObject {
255
        /// Ownership and safety class.
256
        class: PointerClass,
257
        /// Trait name identifier.
258
        traitName: *Node,
259
        /// Whether the pointer is mutable.
260
        mutable: bool,
261
    },
262
}
263
264
/// Function signature.
265
export record FnSig: Copy {
266
    /// Parameter type nodes in declaration order.
267
    params: *[*Node],
268
    /// Optional return type node.
269
    returnType: ?*Node,
270
    /// Throwable type nodes declared in the signature.
271
    throwList: *[*Node],
272
}
273
274
/// Access provided by an address-of expression.
275
export union AddressKind: Copy {
276
    /// Shared access to an immutable value.
277
    Shared,
278
    /// Exclusive access to a mutable value.
279
    Mutable,
280
    /// Shared access to a mutable Copy payload.
281
    Cell,
282
}
283
284
/// Address-of expression metadata.
285
export record AddressOf: Copy {
286
    /// Target expression being referenced.
287
    target: *Node,
288
    /// Access provided by the resulting pointer.
289
    kind: AddressKind,
290
}
291
292
/// Return whether creating an address requires exclusive source access.
293
export fn isExclusiveAddress(address: AddressOf) -> bool {
294
    return address.kind <> AddressKind::Shared;
295
}
296
297
/// Compound statement block with optional dedicated scope.
298
export record Block: Copy {
299
    /// Statements that belong to this block.
300
    statements: *[*Node],
301
    /// Whether this block permits unsafe operations.
302
    isUnsafe: bool,
303
}
304
305
/// Function call expression.
306
export record Call: Copy {
307
    /// Callee expression.
308
    callee: *Node,
309
    /// Argument expressions in source order.
310
    args: *[*Node],
311
}
312
313
/// Single argument to a function or record literal, optionally labeled.
314
export record Arg: Copy {
315
    /// Optional label applied to the argument.
316
    label: ?*Node,
317
    /// Expression supplying the argument value.
318
    value: *Node,
319
}
320
321
/// Assignment expression connecting a target and value.
322
export record Assign: Copy {
323
    /// Expression representing the assignment target.
324
    left: *Node,
325
    /// Expression providing the value being assigned.
326
    right: *Node,
327
}
328
329
/// While loop with an optional alternate branch.
330
export record While: Copy {
331
    /// Condition evaluated before each iteration.
332
    condition: *Node,
333
    /// Loop body executed while `condition` is true.
334
    body: *Node,
335
    /// Optional branch executed when the condition is false at entry.
336
    elseBranch: ?*Node,
337
}
338
339
/// `while let` loop binding metadata.
340
export record WhileLet: Copy {
341
    /// Pattern matching structure.
342
    pattern: PatternMatch,
343
    /// Loop body executed when the pattern matches.
344
    body: *Node,
345
    /// Optional branch executed when the match fails immediately.
346
    elseBranch: ?*Node,
347
}
348
349
/// Try expression metadata.
350
export record Try: Copy {
351
    /// Expression evaluated with implicit error propagation.
352
    expr: *Node,
353
    /// Catch clauses. Empty for propagation (`try`), `try!`, or `try?`.
354
    catches: *[*Node],
355
    /// Whether the try should panic instead of returning an error.
356
    shouldPanic: bool,
357
    /// Whether the try should return an optional instead of propagating error.
358
    returnsOptional: bool,
359
}
360
361
/// A single catch clause in a `try ... catch` expression.
362
export record CatchClause: Copy {
363
    /// Optional identifier binding for the error value (eg. `e`).
364
    binding: ?*Node,
365
    /// Optional type annotation after `as` (eg. `IoError`).
366
    typeNode: ?*Node,
367
    /// Block body executed when this clause matches.
368
    body: *Node,
369
}
370
371
/// `for` loop metadata.
372
export record For: Copy {
373
    /// Loop variable binding.
374
    binding: *Node,
375
    /// Optional index binding for enumeration loops.
376
    index: ?*Node,
377
    /// Expression producing the iterable value.
378
    iterable: *Node,
379
    /// Body executed for each element.
380
    body: *Node,
381
    /// Optional branch executed when the loop body never runs.
382
    elseBranch: ?*Node,
383
}
384
385
/// Conditional `if` statement metadata.
386
export record If: Copy {
387
    /// Condition controlling the branch.
388
    condition: *Node,
389
    /// Branch executed when `condition` is true.
390
    thenBranch: *Node,
391
    /// Optional branch executed when `condition` is false.
392
    elseBranch: ?*Node,
393
}
394
395
/// Conditional expression (`<true> if <condition> else <false>`).
396
export record CondExpr: Copy {
397
    /// Condition controlling which branch is evaluated.
398
    condition: *Node,
399
    /// Expression evaluated when `condition` is true.
400
    thenExpr: *Node,
401
    /// Expression evaluated when `condition` is false.
402
    elseExpr: *Node,
403
}
404
405
/// Classification of pattern matches (if-let, while-let, let-else).
406
export union PatternKind: Copy {
407
    /// Case pattern match.
408
    Case,
409
    /// Binding pattern match.
410
    Binding,
411
}
412
413
/// Prong arm.
414
export union ProngArm: Copy {
415
    /// Case arm with pattern list.
416
    Case(*[*Node]),
417
    /// Binding arm with single identifier or placeholder.
418
    Binding(*Node),
419
    /// Else arm.
420
    Else,
421
}
422
423
/// Common pattern matching structure used by `if let`, `while let`, and `let-else`.
424
export record PatternMatch: Copy {
425
    /// Pattern or binding to match against.
426
    pattern: *Node,
427
    /// Scrutinee expression to match against.
428
    scrutinee: *Node,
429
    /// Optional guard that must evaluate to `true`.
430
    guard: ?*Node,
431
    /// Whether this is a case pattern or binding.
432
    kind: PatternKind,
433
    /// Whether the binding is mutable.
434
    mutable: bool,
435
}
436
437
/// `if let` conditional binding metadata.
438
export record IfLet: Copy {
439
    /// Pattern matching structure.
440
    pattern: PatternMatch,
441
    /// Branch executed when the pattern matches.
442
    thenBranch: *Node,
443
    /// Optional branch executed when the match fails.
444
    elseBranch: ?*Node,
445
}
446
447
/// `let-else` statement metadata.
448
export record LetElse: Copy {
449
    /// Pattern matching structure.
450
    pattern: PatternMatch,
451
    /// Else branch executed if match fails (must diverge).
452
    elseBranch: *Node,
453
}
454
455
/// `match` statement metadata.
456
export record Match: Copy {
457
    /// Expression whose value controls the match.
458
    subject: *Node,
459
    /// Prong nodes evaluated in order.
460
    prongs: *[*Node],
461
}
462
463
/// `match` prong metadata.
464
export record MatchProng: Copy {
465
    /// Prong arm.
466
    arm: ProngArm,
467
    /// Optional guard that must evaluate to `true`.
468
    guard: ?*Node,
469
    /// Body executed when patterns match and guard passes.
470
    body: *Node,
471
}
472
473
/// `let` binding.
474
export record Let: Copy {
475
    /// Identifier bound by the declaration.
476
    ident: *Node,
477
    /// Declared type annotation.
478
    type: ?*Node,
479
    /// Initializer expression.
480
    value: *Node,
481
    /// Storage alignment.
482
    alignment: ?*Node,
483
    /// Whether the variable is mutable.
484
    mutable: bool,
485
}
486
487
/// Constant declaration.
488
export record ConstDecl: Copy {
489
    /// Identifier bound by the declaration.
490
    ident: *Node,
491
    /// Declared type annotation.
492
    type: *Node,
493
    /// Constant initializer expression.
494
    value: *Node,
495
    /// Optional attribute list applied to the constant.
496
    attrs: ?Attributes,
497
}
498
499
/// Static storage declaration.
500
export record StaticDecl: Copy {
501
    /// Identifier bound by the declaration.
502
    ident: *Node,
503
    /// Declared storage type.
504
    type: *Node,
505
    /// Initialization expression.
506
    value: *Node,
507
    /// Optional attribute list applied to the static.
508
    attrs: ?Attributes,
509
}
510
511
/// Function parameter declaration.
512
export record FnParam: Copy {
513
    /// Parameter identifier.
514
    name: *Node,
515
    /// Parameter type annotation.
516
    type: *Node,
517
}
518
519
/// Record literal expression metadata.
520
export record RecordLit: Copy {
521
    /// Type name associated with the literal.
522
    /// If `nil`, it's an anonymous record literal.
523
    typeName: ?*Node,
524
    /// Field initializer nodes.
525
    fields: *[*Node],
526
    /// When true, remaining fields are discarded (`{ x, .. }`).
527
    ignoreRest: bool,
528
}
529
530
/// Record declaration.
531
export record RecordDecl: Copy {
532
    /// Identifier naming the record.
533
    name: *Node,
534
    /// Field declaration nodes.
535
    fields: *[*Node],
536
    /// Optional attribute list applied to the record.
537
    attrs: ?Attributes,
538
    /// Region parameters in declaration order.
539
    regions: *[*Node],
540
    /// Ownership trait derivations attached to the record.
541
    derives: *[*Node],
542
    /// Whether this record has labeled fields.
543
    labeled: bool,
544
}
545
546
/// Union declarations.
547
export record UnionDecl: Copy {
548
    /// Identifier naming the union.
549
    name: *Node,
550
    /// Variant nodes making up the union.
551
    variants: *[*Node],
552
    /// Optional attribute list applied to the union.
553
    attrs: ?Attributes,
554
    /// Region parameters in declaration order.
555
    regions: *[*Node],
556
    /// Ownership trait derivations attached to the union.
557
    derives: *[*Node],
558
}
559
560
/// Union variant declaration.
561
export record UnionDeclVariant: Copy {
562
    /// Identifier naming the variant.
563
    name: *Node,
564
    /// Variant index.
565
    index: u32,
566
    /// Explicit discriminant value, if provided.
567
    value: ?*Node,
568
    /// Optional payload type.
569
    type: ?*Node,
570
}
571
572
/// Function declaration.
573
export record FnDecl: Copy {
574
    /// Identifier naming the function.
575
    name: *Node,
576
    /// Region parameters in declaration order.
577
    regions: *[*Node],
578
    /// Function type signature.
579
    sig: FnSig,
580
    /// Optional function body (`nil` for extern functions).
581
    body: ?*Node,
582
    /// Optional attribute list applied to the function.
583
    attrs: ?Attributes,
584
}
585
586
/// Method declaration modifiers.
587
export record MethodModifiers: Copy {
588
    /// Region parameters in declaration order.
589
    regions: *[*Node],
590
    /// Optional attribute list.
591
    attrs: ?Attributes,
592
}
593
594
/// Array repeat literal metadata.
595
export record ArrayRepeatLit: Copy {
596
    /// Expression providing the repeated value.
597
    item: *Node,
598
    /// Expression providing the repetition count.
599
    count: *Node,
600
}
601
602
/// Module declaration.
603
export record Mod: Copy {
604
    /// Identifier naming the module.
605
    name: *Node,
606
    /// Optional attribute list applied to the module.
607
    attrs: ?Attributes,
608
}
609
610
/// Use declaration for importing modules.
611
export record Use: Copy {
612
    /// Access node identifying the imported module.
613
    path: *Node,
614
    /// Whether this is a wildcard import (e.g. `use ast::*`).
615
    wildcard: bool,
616
    /// Optional attribute list applied to the use declaration.
617
    attrs: ?Attributes,
618
}
619
620
/// Access expression used for field, scope, and index lookups.
621
export record Access: Copy {
622
    /// Expression providing the container or namespace.
623
    parent: *Node,
624
    /// Expression identifying the member, scope element, or index.
625
    child: *Node,
626
}
627
628
/// `as` cast expression metadata.
629
export record As: Copy {
630
    /// Expression being coerced.
631
    value: *Node,
632
    /// Target type annotation.
633
    type: *Node,
634
}
635
636
/// Range expression metadata.
637
export record Range: Copy {
638
    /// Optional inclusive start expression.
639
    start: ?*Node,
640
    /// Optional exclusive end expression.
641
    end: ?*Node,
642
}
643
644
/// Binary operation expression, eg. `x * y`.
645
export record BinOp: Copy {
646
    /// Operator applied to the operands.
647
    op: BinaryOp,
648
    /// Left-hand operand.
649
    left: *Node,
650
    /// Right-hand operand.
651
    right: *Node,
652
}
653
654
/// Unary operation expression, eg. `-x`.
655
export record UnOp: Copy {
656
    /// Operator applied to the operand.
657
    op: UnaryOp,
658
    /// Operand expression.
659
    value: *Node,
660
}
661
662
/// Tagged union describing every possible AST node payload.
663
export union NodeValue: Copy {
664
    /// Placeholder `_` expression.
665
    Placeholder,
666
    /// Nil literal (`nil`).
667
    Nil,
668
    /// Undefined literal (`undefined`).
669
    Undef,
670
    /// Boolean literal (`true` or `false`).
671
    Bool(bool),
672
    /// Character literal like `'x'`.
673
    Char(u8),
674
    /// String literal like `"Hello World!"`.
675
    String(*[u8]),
676
    /// Identifier expression.
677
    Ident(*[u8]),
678
    /// Lexical region name, including its apostrophe prefix.
679
    Region {
680
        /// Source name.
681
        name: *[u8],
682
        /// Declared parent for a region parameter.
683
        parent: ?*Node,
684
    },
685
    /// Function or nominal constructor applied to explicit region arguments.
686
    RegionApply {
687
        /// Function or constructor expression.
688
        value: *Node,
689
        /// Region argument nodes in declaration order.
690
        regions: *[*Node],
691
    },
692
    /// Named source place for a lexical region binding.
693
    RegionBinding(Arg),
694
    /// Block with explicit storage bindings for a concrete region.
695
    RegionBlock {
696
        /// Region name introduced by this block.
697
        region: *Node,
698
        /// Binding nodes with address expressions as initializers.
699
        bindings: *[*Node],
700
        /// Statements within the region.
701
        body: *Node,
702
        /// Whether a `use` block supplies an allocation interface.
703
        isSession: bool,
704
    },
705
    /// Numeric literal such as `42` or `0xFF`.
706
    Number(fmt::IntLiteral),
707
    /// Range expression such as `0..10` or `..`.
708
    Range(Range),
709
    /// Array literal expression.
710
    ArrayLit(*[*Node]),
711
    /// Array repeat literal expression.
712
    ArrayRepeatLit(ArrayRepeatLit),
713
    /// Array subscript expression.
714
    Subscript {
715
        /// Array or slice.
716
        container: *Node,
717
        /// Index expression.
718
        index: *Node
719
    },
720
    /// Binary operator expression.
721
    BinOp(BinOp),
722
    /// Unary operator expression.
723
    UnOp(UnOp),
724
    /// Builtin function call (e.g. `@sizeOf(T)`).
725
    BuiltinCall {
726
        /// Builtin function kind.
727
        kind: Builtin,
728
        /// Argument list.
729
        args: *[*Node],
730
    },
731
    /// Block expression or statement body.
732
    Block(Block),
733
    /// Call expression, eg. `f(x)`.
734
    Call(Call),
735
    /// Field access expression (e.g. `foo.bar`).
736
    FieldAccess(Access),
737
    /// Scope access expression (e.g. `foo::bar`).
738
    ScopeAccess(Access),
739
    /// Address of expression (e.g. `&mut x`).
740
    AddressOf(AddressOf),
741
    /// Dereference expression (e.g. `*ptr`).
742
    Deref(*Node),
743
    /// Cast expression using `as`.
744
    As(As),
745
    /// While loop statement.
746
    While(While),
747
    /// `while let` loop statement.
748
    WhileLet(WhileLet),
749
    /// `for` loop statement.
750
    For(For),
751
    /// Infinite loop statement.
752
    Loop {
753
        /// Body executed each iteration.
754
        body: *Node,
755
    },
756
    /// Break statement.
757
    Break,
758
    /// Continue statement.
759
    Continue,
760
    /// Return statement.
761
    Return {
762
        /// Expression returned by this statement, if any.
763
        value: ?*Node,
764
    },
765
    /// Throw statement.
766
    Throw {
767
        /// Expression to throw.
768
        expr: *Node,
769
    },
770
    /// Panic statement.
771
    Panic {
772
        /// Optional panic message expression.
773
        message: ?*Node,
774
    },
775
    /// Assert statement.
776
    Assert {
777
        /// Condition expression that must be true.
778
        condition: *Node,
779
        /// Optional assertion failure message.
780
        message: ?*Node,
781
    },
782
    /// Conditional statement.
783
    If(If),
784
    /// Conditional expression.
785
    CondExpr(CondExpr),
786
    /// `if let` conditional binding.
787
    IfLet(IfLet),
788
    /// `let-else` statement.
789
    LetElse(LetElse),
790
    /// Try expression.
791
    Try(Try),
792
    /// Match statement.
793
    Match(Match),
794
    /// Match prong.
795
    MatchProng(MatchProng),
796
    /// Function declaration.
797
    FnDecl(FnDecl),
798
    /// Function parameter declaration.
799
    FnParam(FnParam),
800
    /// `let binding.
801
    Let(Let),
802
    /// Constant declaration.
803
    ConstDecl(ConstDecl),
804
    /// Static storage declaration.
805
    StaticDecl(StaticDecl),
806
    /// Type signature node.
807
    TypeSig(TypeSig),
808
    /// Assignment statement.
809
    Assign(Assign),
810
    /// Expression statement.
811
    ExprStmt(*Node),
812
    /// Module declaration (`mod`).
813
    Mod(Mod),
814
    /// Parent module reference.
815
    Super,
816
    /// Module use declaration.
817
    Use(Use),
818
    /// Union type declaration.
819
    UnionDecl(UnionDecl),
820
    /// Union variant declaration.
821
    UnionDeclVariant(UnionDeclVariant),
822
    /// Attribute node.
823
    Attribute(Attribute),
824
    /// Record type declaration.
825
    RecordDecl(RecordDecl),
826
    /// Record field declaration.
827
    RecordField {
828
        /// Identifier bound by the declaration.
829
        field: ?*Node,
830
        /// Declared type annotation.
831
        type: *Node,
832
        /// Optional initializer expression.
833
        value: ?*Node,
834
    },
835
    /// Record literal expression.
836
    RecordLit(RecordLit),
837
    /// Record literal field initializer.
838
    RecordLitField(Arg),
839
    /// Alignment specifier.
840
    Align {
841
        /// Alignment value.
842
        value: *Node,
843
    },
844
    /// Catch clause within a try expression.
845
    CatchClause(CatchClause),
846
    /// Trait declaration.
847
    TraitDecl {
848
        /// Trait name identifier.
849
        name: *Node,
850
        /// Supertrait name nodes.
851
        supertraits: *[*Node],
852
        /// Method signature nodes ([`TraitMethodSig`]).
853
        methods: *[*Node],
854
        /// Optional attributes.
855
        attrs: ?Attributes,
856
    },
857
    /// Method signature inside a trait declaration.
858
    TraitMethodSig {
859
        /// Method name identifier.
860
        name: *Node,
861
        /// Region parameters and attributes.
862
        modifiers: *MethodModifiers,
863
        /// Receiver type node (eg. `*mut Allocator`).
864
        receiver: *Node,
865
        /// Function signature.
866
        sig: FnSig,
867
    },
868
    /// Instance block.
869
    InstanceDecl {
870
        /// Trait name identifier.
871
        traitName: *Node,
872
        /// Target type identifier.
873
        targetType: *Node,
874
        /// Region parameters in declaration order.
875
        regions: *[*Node],
876
        /// Method definition nodes ([`MethodDecl`]).
877
        methods: *[*Node],
878
    },
879
    /// Method definition with a receiver.
880
    /// Used both inside `instance` blocks and as standalone methods.
881
    MethodDecl {
882
        /// Method name identifier.
883
        name: *Node,
884
        /// Region parameters and attributes.
885
        modifiers: *MethodModifiers,
886
        /// Receiver binding name ([`Ident`] node).
887
        receiverName: *Node,
888
        /// Receiver type node (eg. `*mut Arena`).
889
        receiverType: *Node,
890
        /// Function signature.
891
        sig: FnSig,
892
        /// Method body.
893
        body: *Node,
894
    },
895
}
896
897
/// Full AST node with shared metadata and variant-specific payload.
898
export record Node: Copy {
899
    /// Unique identifier for this node.
900
    id: u32,
901
    /// Source span describing where the node originated.
902
    span: Span,
903
    /// Variant-specific payload for the node.
904
    value: NodeValue,
905
}
906
907
/// Check whether a node is a place expression.
908
///
909
/// Place expressions have persistent storage and can appear on the left side
910
/// of `set` assignments.
911
export fn isPlaceExpr(node: *Node) -> bool {
912
    match node.value {
913
        case NodeValue::Ident(_),
914
             NodeValue::ScopeAccess(_),
915
             NodeValue::FieldAccess(_),
916
             NodeValue::Subscript { .. },
917
             NodeValue::Deref(_) => return true,
918
        else => return false,
919
    }
920
}
921
922
/// Allocate a new AST node from the arena with the given span and value.
923
export unsafe fn allocNode(arena: &mut NodeArena, span: Span, value: NodeValue) -> *mut Node {
924
    let p = try! alloc::alloc(&mut arena.arena, @sizeOf(Node), @alignOf(Node));
925
    let node = p as *mut Node;
926
    let nodeId = arena.nextId;
927
    set arena.nextId = nodeId + 1;
928
929
    set *node = Node { id: nodeId, span, value };
930
931
    return node;
932
}
933
934
/// Allocate a synthetic AST node with a zero-length span.
935
export unsafe fn synthNode(arena: &mut NodeArena, value: NodeValue) -> *mut Node {
936
    return allocNode(arena, Span { offset: 0, length: 0 }, value);
937
}
938
939
/// Synthetic module with a single function in it.
940
record SynthFnMod: Copy {
941
    /// The module block.
942
    modBody: *Node,
943
    /// The function block.
944
    fnBody: *Node
945
}
946
947
/// Synthesize a module with a function in it with the given name and statements.
948
export unsafe fn synthFnModule(
949
    arena: &mut NodeArena, name: *[u8], bodyStmts: *[*Node]
950
) -> SynthFnMod {
951
    let a = alloc::arenaAllocator(&mut arena.arena);
952
    let fnName = synthNode(arena, NodeValue::Ident(name));
953
    let params: *[*Node] = &[];
954
    let throwList: *[*Node] = &[];
955
    let fnSig = FnSig { params, returnType: nil, throwList };
956
    let fnBody: *Node = synthNode(arena, NodeValue::Block(Block { statements: bodyStmts, isUnsafe: false }));
957
    let fnDecl = synthNode(arena, NodeValue::FnDecl(FnDecl {
958
        name: fnName, regions: &[], sig: fnSig, body: fnBody, attrs: nil,
959
    }));
960
    let mut rootStmts: *mut [*Node] = &mut [];
961
    rootStmts.append(fnDecl, a);
962
    let modBody = synthNode(arena, NodeValue::Block(Block { statements: rootStmts, isUnsafe: false }));
963
964
    return SynthFnMod { modBody, fnBody };
965
}
966
967
/// Describe the immutable binding introduced by a lexical region header.
968
export fn borrowBinding(binding: Arg) -> Let {
969
    let ident = binding.label else panic "borrowBinding: missing name";
970
    return Let { ident, type: nil, value: binding.value, alignment: nil, mutable: false };
971
}