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