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