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