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