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