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