lib/std/lang/parser.rad 78.5 KiB raw
1
//! Recursive descent parser for the Radiance programming language.
2
@test pub mod tests;
3
4
use std::mem;
5
use std::io;
6
use std::lang::alloc;
7
use std::lang::ast;
8
use std::lang::strings;
9
use std::lang::scanner;
10
11
/// Maximum `u32` value.
12
pub const U32_MAX: u32 = 0xFFFFFFFF;
13
/// Maximum representable `u64` value.
14
pub const U64_MAX: u64 = 0xFFFFFFFFFFFFFFFF;
15
/// Maximum number of fields in a record.
16
pub const MAX_RECORD_FIELDS: u32 = 32;
17
18
/// Maximum number of parser errors before aborting.
19
const MAX_ERRORS: u32 = 8;
20
21
/// Parser error type.
22
pub union ParseError {
23
    /// Encountered a token that was not expected in the current context.
24
    UnexpectedToken,
25
}
26
27
/// Represents a parsed name-type-value triple.
28
///
29
/// Used for record field declarations, variable declarations,
30
/// and record field initializations.
31
record NameTypeValue {
32
    /// The identifier name.
33
    name: *ast::Node,
34
    /// The optional type annotation.
35
    type: ?*ast::Node,
36
    /// The optional initialization value.
37
    value: ?*ast::Node,
38
    /// The optional alignment specifier.
39
    alignment: ?*ast::Node,
40
}
41
42
/// Behavioural differences when parsing record field lists.
43
union RecordFieldMode {
44
    /// Labeled fields, allows for default values.
45
    Labeled,
46
    /// Unlabeled fields.
47
    Unlabeled,
48
}
49
50
/// Parser context differentiates between regular expressions and
51
/// conditional contexts where `{` begins a block.
52
union Context {
53
    /// Normal expression context where `{` may start a record literal
54
    /// and `if` may start a conditional expression.
55
    Normal,
56
    /// Pattern context where `{` may start a record literal
57
    /// but `if` is reserved for guards.
58
    Pattern,
59
    /// Conditional context where `{` always begins a block
60
    /// and `if` is reserved for guards.
61
    Condition,
62
}
63
64
/// A single parser error with location information.
65
pub record Error {
66
    /// Human-readable error message.
67
    message: *[u8],
68
    /// The token where the error occurred.
69
    token: scanner::Token,
70
}
71
72
/// List of parser errors encountered during parsing.
73
record ErrorList {
74
    /// Fixed-size array of error records.
75
    list: [Error; MAX_ERRORS],
76
    /// Number of errors currently in the list.
77
    count: u32,
78
}
79
80
/// Snapshot of parser state for speculative parsing.
81
record SavedState {
82
    parser: Parser,
83
    arena: u32,
84
    nextId: u32,
85
}
86
87
/// Operator metadata for precedence climbing.
88
record OpInfo {
89
    op: ast::BinaryOp,
90
    prec: i32,
91
}
92
93
/// Get operator info for a token kind using match-based dispatch.
94
/// Returns nil if the token is not a binary operator.
95
fn getOpInfo(kind: scanner::TokenKind) -> ?OpInfo {
96
    match kind {
97
        case scanner::TokenKind::Star =>
98
            return { op: ast::BinaryOp::Mul, prec: 7 },
99
        case scanner::TokenKind::Slash =>
100
            return { op: ast::BinaryOp::Div, prec: 7 },
101
        case scanner::TokenKind::Percent =>
102
            return { op: ast::BinaryOp::Mod, prec: 7 },
103
        case scanner::TokenKind::Plus =>
104
            return { op: ast::BinaryOp::Add, prec: 6 },
105
        case scanner::TokenKind::Minus =>
106
            return { op: ast::BinaryOp::Sub, prec: 6 },
107
        case scanner::TokenKind::LtLt =>
108
            return { op: ast::BinaryOp::Shl, prec: 5 },
109
        case scanner::TokenKind::GtGt =>
110
            return { op: ast::BinaryOp::Shr, prec: 5 },
111
        case scanner::TokenKind::Amp =>
112
            return { op: ast::BinaryOp::BitAnd, prec: 4 },
113
        case scanner::TokenKind::Caret =>
114
            return { op: ast::BinaryOp::BitXor, prec: 3 },
115
        case scanner::TokenKind::Pipe =>
116
            return { op: ast::BinaryOp::BitOr, prec: 2 },
117
        case scanner::TokenKind::EqualEqual =>
118
            return { op: ast::BinaryOp::Eq, prec: 1 },
119
        case scanner::TokenKind::BangEqual =>
120
            return { op: ast::BinaryOp::Ne, prec: 1 },
121
        case scanner::TokenKind::Lt =>
122
            return { op: ast::BinaryOp::Lt, prec: 1 },
123
        case scanner::TokenKind::Gt =>
124
            return { op: ast::BinaryOp::Gt, prec: 1 },
125
        case scanner::TokenKind::LtEqual =>
126
            return { op: ast::BinaryOp::Lte, prec: 1 },
127
        case scanner::TokenKind::GtEqual =>
128
            return { op: ast::BinaryOp::Gte, prec: 1 },
129
        case scanner::TokenKind::And =>
130
            return { op: ast::BinaryOp::And, prec: 0 },
131
        case scanner::TokenKind::Or =>
132
            return { op: ast::BinaryOp::Or, prec: 0 },
133
        else =>
134
            return nil,
135
    }
136
}
137
138
/// Parser state.
139
pub record Parser {
140
    /// The scanner that provides tokens.
141
    scanner: scanner::Scanner,
142
    /// The current token being examined.
143
    current: scanner::Token,
144
    /// The most recently consumed token.
145
    previous: scanner::Token,
146
    /// Collection of errors encountered during parsing.
147
    errors: ErrorList,
148
    /// Arena for all node allocations.
149
    arena: *mut ast::NodeArena,
150
    /// Allocator backed by the node arena.
151
    allocator: alloc::Allocator,
152
    /// Current parsing context (normal or conditional).
153
    context: Context,
154
}
155
156
/// Create a new parser initialized with the given source kind, source and node arena.
157
pub fn mkParser(sourceLoc: scanner::SourceLoc, source: *[u8], arena: *mut ast::NodeArena, pool: *mut strings::Pool) -> Parser {
158
    return Parser {
159
        scanner: scanner::scanner(sourceLoc, source, pool),
160
        current: scanner::invalid(0, ""),
161
        previous: scanner::invalid(0, ""),
162
        errors: ErrorList { list: undefined, count: 0 },
163
        arena,
164
        allocator: alloc::arenaAllocator(&mut arena.arena),
165
        context: Context::Normal,
166
    };
167
}
168
169
/// Emit a `true` or `false` literal node.
170
fn nodeBool(p: *mut Parser, value: bool) -> *ast::Node {
171
    return node(p, ast::NodeValue::Bool(value));
172
}
173
174
/// Convert a single ASCII digit into its numeric value for the given radix.
175
pub fn digitFromAscii(ch: u8, radix: u32) -> ?u32 {
176
    assert radix >= 2 and radix <= 36;
177
178
    // Default to an out-of-range value so non-digits fall through to `nil`.
179
    let mut value: u32 = 36;
180
181
    if ch >= '0' and ch <= '9' {
182
        value = (ch - '0') as u32;
183
    } else if radix > 10 {
184
        // Mask to convert ASCII letters to uppercase.
185
        let upper = ch & 0xDF;
186
        if upper >= 'A' and upper <= 'Z' {
187
            value = (upper - 'A') as u32 + 10;
188
        }
189
    }
190
    if value < radix {
191
        return value;
192
    }
193
    return nil;
194
}
195
196
/// Parse an integer literal (binary, decimal, or hexadecimal) including an optional sign.
197
fn parseIntLiteral(p: *mut Parser, text: *[u8]) -> ast::IntLiteral
198
    throws (ParseError)
199
{
200
    if text.len == 0 {
201
        throw failParsing(p, "integer literal is empty");
202
    }
203
    let first = text[0];
204
    let negative = first == '-';
205
    let signed: bool = negative or (first == '+');
206
207
    let mut start: u32 = 0;
208
    let mut radix: u32 = 10;
209
    let mut radixType = ast::Radix::Decimal;
210
211
    if signed {
212
        start = 1;
213
        if start >= text.len {
214
            throw failParsing(p, "integer literal requires digits after sign");
215
        }
216
    }
217
    if start + 1 < text.len and text[start] == '0' {
218
        let prefix = text[start + 1];
219
        if prefix == 'x' or prefix == 'X' {
220
            radix = 16;
221
            radixType = ast::Radix::Hex;
222
            start += 2;
223
        } else if prefix == 'b' or prefix == 'B' {
224
            radix = 2;
225
            radixType = ast::Radix::Binary;
226
            start += 2;
227
        }
228
        if start >= text.len {
229
            throw failParsing(p, "integer literal prefix must be followed by digits");
230
        }
231
    }
232
    let mut value: u64 = 0;
233
    let radix64: u64 = radix as u64;
234
    for i in start..text.len {
235
        let ch = text[i];
236
        let digit = digitFromAscii(ch, radix) else {
237
            throw failParsing(p, "invalid digit in integer literal");
238
        };
239
        if value > (U64_MAX / radix64) {
240
            throw failParsing(p, "integer literal overflow");
241
        }
242
        value *= radix64;
243
244
        if value > U64_MAX - (digit as u64) {
245
            throw failParsing(p, "integer literal overflow");
246
        }
247
        value += (digit as u64);
248
    }
249
    return ast::IntLiteral {
250
        text, magnitude: value, radix: radixType, signed, negative,
251
    };
252
}
253
254
/// Emit an integer type node.
255
fn nodeTypeInt(p: *mut Parser, width: u8, sign: ast::Signedness) -> *ast::Node {
256
    return node(p, ast::NodeValue::TypeSig(
257
        ast::TypeSig::Integer { width, sign }
258
    ));
259
}
260
261
/// Emit a number literal node with the provided literal metadata.
262
fn nodeNumber(p: *mut Parser, literal: ast::IntLiteral) -> *ast::Node {
263
    return node(p, ast::NodeValue::Number(literal));
264
}
265
266
/// Emit a `super` node.
267
fn nodeSuper(p: *mut Parser) -> *ast::Node {
268
    return node(p, ast::NodeValue::Super);
269
}
270
271
/// Process escape sequences in a raw string, writing the result into `dst`.
272
/// Returns the number of bytes written.
273
fn unescapeString(raw: *[u8], dst: *mut [u8]) -> u32 {
274
    let mut i: u32 = 0;
275
    let mut j: u32 = 0;
276
277
    while i < raw.len {
278
        if raw[i] == '\\' and i + 1 < raw.len {
279
            match raw[i + 1] {
280
                case 'n'  => dst[j] = '\n',
281
                case 't'  => dst[j] = '\t',
282
                case 'r'  => dst[j] = '\r',
283
                case '\\' => dst[j] = '\\',
284
                case '"'  => dst[j] = '"',
285
                case '0'  => dst[j] = 0,
286
                else      => dst[j] = raw[i + 1],
287
            }
288
            i += 2;
289
        } else {
290
            dst[j] = raw[i];
291
            i += 1;
292
        }
293
        j += 1;
294
    }
295
    return j;
296
}
297
298
/// Emit a single attribute node.
299
fn nodeAttribute(p: *mut Parser, attr: ast::Attribute) -> *ast::Node {
300
    return node(p, ast::NodeValue::Attribute(attr));
301
}
302
303
/// Emit a unary operator node.
304
fn nodeUnary(p: *mut Parser, op: ast::UnaryOp, value: *ast::Node) -> *ast::Node {
305
    return node(p, ast::NodeValue::UnOp({ op, value }));
306
}
307
308
/// Parse a parenthesized expression without applying postfix operators.
309
fn parseParenthesized(p: *mut Parser) -> *ast::Node
310
    throws (ParseError)
311
{
312
    try expect(p, scanner::TokenKind::LParen, "expected `(`");
313
314
    let saved = p.context;
315
    p.context = Context::Normal;
316
    let expr = try parseExpr(p);
317
    p.context = saved;
318
319
    try expect(p, scanner::TokenKind::RParen, "expected `)`");
320
321
    return expr;
322
}
323
324
/// Parse an array literal: `[a, b, c]` or `[item; count]`.
325
fn parseArrayLiteral(p: *mut Parser) -> *ast::Node
326
    throws (ParseError)
327
{
328
    try expect(p, scanner::TokenKind::LBracket, "expected `[`");
329
    if consume(p, scanner::TokenKind::RBracket) { // Empty array: `[]`.
330
        let empty: *mut [*ast::Node] = &mut [];
331
        return node(p, ast::NodeValue::ArrayLit(empty));
332
    }
333
    let firstExpr = try parseExpr(p);
334
335
    if consume(p, scanner::TokenKind::Semicolon) {
336
        // Array repeat literal: `[item; count]`.
337
        let count = try parseExpr(p);
338
        try expect(p, scanner::TokenKind::RBracket, "expected `]` after array repeat count");
339
340
        return node(p, ast::NodeValue::ArrayRepeatLit(
341
            ast::ArrayRepeatLit { item: firstExpr, count }
342
        ));
343
    }
344
    // Regular array literal: `[a, b, ...]`.
345
    let mut items = ast::nodeSlice(p.arena, 64).append(firstExpr, p.allocator);
346
347
    while consume(p, scanner::TokenKind::Comma) and not check(p, scanner::TokenKind::RBracket) {
348
        let elem = try parseExpr(p);
349
        items.append(elem, p.allocator);
350
    }
351
    try expect(p, scanner::TokenKind::RBracket, "expected `]` after array elements");
352
353
    return node(p, ast::NodeValue::ArrayLit(items));
354
}
355
356
/// Parse a function call expression.
357
fn parseCall(p: *mut Parser, callee: *ast::Node) -> *ast::Node
358
    throws (ParseError)
359
{
360
    let args = try parseList(
361
        p,
362
        scanner::TokenKind::LParen,
363
        scanner::TokenKind::RParen,
364
        parseExpr
365
    );
366
    return node(p, ast::NodeValue::Call(
367
        ast::Call { callee, args }
368
    ));
369
}
370
371
/// Parse zero or more trailing `as` casts applied to `expr`.
372
fn parseAsCast(p: *mut Parser, expr: *ast::Node) -> *ast::Node
373
    throws (ParseError)
374
{
375
    let mut result = expr;
376
377
    while consume(p, scanner::TokenKind::As) {
378
        let target = try parseType(p);
379
380
        result = node(p, ast::NodeValue::As(
381
            ast::As { value: result, type: target }
382
        ));
383
    }
384
    return result;
385
}
386
387
/// Parse an optional conditional expression suffix.
388
///
389
///   `<thenExpr> if <condition> else <elseExpr>`
390
///
391
/// If no `if` keyword follows, returns the input expression unchanged.
392
fn parseCondExpr(p: *mut Parser, thenExpr: *ast::Node) -> *ast::Node
393
    throws (ParseError)
394
{
395
    // Only parse conditional expressions in normal context.
396
    // In conditional context, `if` is used for guards.
397
    if p.context != Context::Normal {
398
        return thenExpr;
399
    }
400
    if not consume(p, scanner::TokenKind::If) {
401
        return thenExpr;
402
    }
403
    let condition = try parseCond(p);
404
    try expect(p, scanner::TokenKind::Else, "expected `else` in conditional expression");
405
    let elseExpr = try parseExpr(p);
406
407
    return node(p, ast::NodeValue::CondExpr(
408
        ast::CondExpr { condition, thenExpr, elseExpr }
409
    ));
410
}
411
412
/// Parse array subscript or slice expression after `[`.
413
fn parseSubscriptOrSlice(p: *mut Parser, container: *ast::Node) -> *ast::Node
414
    throws (ParseError)
415
{
416
    try expect(p, scanner::TokenKind::LBracket, "expected `[`");
417
418
    let mut index: *ast::Node = undefined;
419
420
    if consume(p, scanner::TokenKind::DotDot) {
421
        // Either `..` or `..end`.
422
        let mut endExpr: ?*ast::Node = nil;
423
        if not check(p, scanner::TokenKind::RBracket) {
424
            endExpr = try parseExpr(p);
425
        }
426
        index = node(p, ast::NodeValue::Range(
427
            ast::Range { start: nil, end: endExpr }
428
        ));
429
    } else {
430
        // Either `n`, `n..` or `n..end`.
431
        let startExpr = try parseExpr(p);
432
433
        if consume(p, scanner::TokenKind::DotDot) {
434
            // Either `n..` or `n..end`.
435
            let mut endExpr: ?*ast::Node = nil;
436
            if not check(p, scanner::TokenKind::RBracket) {
437
                endExpr = try parseExpr(p);
438
            }
439
            index = node(p, ast::NodeValue::Range(
440
                ast::Range { start: startExpr, end: endExpr }
441
            ));
442
        } else {
443
            // Just `n` - regular indexing.
444
            index = startExpr;
445
        }
446
    }
447
    try expect(p, scanner::TokenKind::RBracket, "expected `]` after array index");
448
449
    return node(p, ast::NodeValue::Subscript { container, index });
450
}
451
452
/// Parse postfix operators (eg. field access, function call etc.)
453
fn parsePostfix(p: *mut Parser, expr: *ast::Node) -> *ast::Node
454
    throws (ParseError)
455
{
456
    let mut result = expr;
457
458
    loop {
459
        match p.current.kind {
460
            case scanner::TokenKind::Dot => {
461
                advance(p);
462
463
                let field = try parseIdent(p, "expected field name after `.`");
464
                result = node(p, ast::NodeValue::FieldAccess(
465
                    ast::Access { parent: result, child: field }
466
                ));
467
            }
468
            case scanner::TokenKind::ColonColon => {
469
                advance(p);
470
471
                let ident = try parseIdent(p, "expected identifier after `::`");
472
                result = node(p, ast::NodeValue::ScopeAccess(
473
                    ast::Access { parent: result, child: ident }
474
                ));
475
            }
476
            case scanner::TokenKind::LBracket => {
477
                result = try parseSubscriptOrSlice(p, result);
478
            }
479
            case scanner::TokenKind::LParen => {
480
                result = try parseCall(p, result);
481
            }
482
            case scanner::TokenKind::LBrace if p.context != Context::Condition => {
483
                result = try parseRecordLit(p, result);
484
            }
485
            else => {
486
                break;
487
            }
488
        }
489
    }
490
    return result;
491
}
492
493
/// Parse a conditional expression.
494
pub fn parseCond(p: *mut Parser) -> *ast::Node throws (ParseError) {
495
    let saved = p.context;
496
    p.context = Context::Condition;
497
    let expr = try parseExpr(p);
498
    p.context = saved;
499
500
    return expr;
501
}
502
503
/// Parse unary expression followed by optional `as` cast.
504
/// `as` has higher precedence than binary ops but lower than unary.
505
fn parseUnary(p: *mut Parser) -> *ast::Node throws (ParseError) {
506
    let unary = try parseUnaryExpr(p);
507
    return try parseAsCast(p, unary);
508
}
509
510
/// Parse prefix unary expressions and defer to primary expressions otherwise.
511
fn parseUnaryExpr(p: *mut Parser) -> *ast::Node
512
    throws (ParseError)
513
{
514
    match p.current.kind {
515
        case scanner::TokenKind::Not => {
516
            advance(p);
517
            let value = try parseUnaryExpr(p);
518
            return nodeUnary(p, ast::UnaryOp::Not, value);
519
        }
520
        case scanner::TokenKind::Minus => {
521
            advance(p);
522
            let value = try parseUnaryExpr(p);
523
            return nodeUnary(p, ast::UnaryOp::Neg, value);
524
        }
525
        case scanner::TokenKind::Tilde => {
526
            advance(p);
527
            let value = try parseUnaryExpr(p);
528
            return nodeUnary(p, ast::UnaryOp::BitNot, value);
529
        }
530
        case scanner::TokenKind::Star => {
531
            advance(p);
532
            let value = try parseUnaryExpr(p);
533
            return node(p, ast::NodeValue::Deref(value));
534
        }
535
        case scanner::TokenKind::Amp => {
536
            advance(p);
537
            let mutable = consume(p, scanner::TokenKind::Mut);
538
            let target = try parseUnaryExpr(p);
539
            return node(p, ast::NodeValue::AddressOf({ target: target, mutable: mutable }));
540
        }
541
        else => {
542
            return try parsePrimary(p);
543
        }
544
    }
545
}
546
547
/// Find the operator info for a token if it has precedence greater than the
548
/// given minimum.
549
fn findNextOp(kind: scanner::TokenKind, minPrec: i32) -> ?OpInfo {
550
    if let opInfo = getOpInfo(kind) {
551
        if opInfo.prec > minPrec {
552
            return opInfo;
553
        }
554
    }
555
    return nil;
556
}
557
558
/// Determine whether the current token can terminate a range expression.
559
fn isRangeTerminator(kind: scanner::TokenKind) -> bool {
560
    match kind {
561
        case scanner::TokenKind::Comma,
562
             scanner::TokenKind::Semicolon,
563
             scanner::TokenKind::RParen,
564
             scanner::TokenKind::RBrace,
565
             scanner::TokenKind::RBracket,
566
             scanner::TokenKind::Else,
567
             scanner::TokenKind::In,
568
             scanner::TokenKind::LBrace,
569
             scanner::TokenKind::Eof =>
570
            return true,
571
        else =>
572
            return false,
573
    }
574
}
575
576
/// Build a range expression node with an optional start and end expression.
577
fn parseRangeExpr(p: *mut Parser, start: ?*ast::Node) -> *ast::Node
578
    throws (ParseError)
579
{
580
    let mut endExpr: ?*ast::Node = nil;
581
582
    if not isRangeTerminator(p.current.kind) {
583
        let right = try parseUnary(p);
584
        endExpr = try parseBinary(p, right, -1);
585
    }
586
    return node(p, ast::NodeValue::Range(
587
        ast::Range { start, end: endExpr }
588
    ));
589
}
590
591
/// Parse binary expressions using precedence climbing.
592
fn parseBinary(p: *mut Parser, left: *ast::Node, minPrec: i32) -> *ast::Node
593
    throws (ParseError)
594
{
595
    let mut result = left;
596
597
    loop {
598
        if p.current.kind == scanner::TokenKind::DotDot {
599
            advance(p);
600
            result = try parseRangeExpr(p, result);
601
        } else {
602
            let opInfo = findNextOp(p.current.kind, minPrec) else break;
603
            advance(p);
604
605
            let mut right = try parseUnary(p);
606
607
            while let _ = findNextOp(p.current.kind, opInfo.prec)  {
608
                right = try parseBinary(p, right, opInfo.prec);
609
            }
610
            result = node(p, ast::NodeValue::BinOp(ast::BinOp {
611
                op: opInfo.op, left: result, right,
612
            }));
613
        }
614
    }
615
    return result;
616
}
617
618
/// Check whether an expression may appear on the left side of an assignment.
619
fn isAssignableTarget(node: *ast::Node) -> bool {
620
    match node.value {
621
        case ast::NodeValue::Ident(_) =>
622
            return true,
623
        case ast::NodeValue::FieldAccess(_) =>
624
            return true,
625
        case ast::NodeValue::Subscript { .. } =>
626
            return true,
627
        case ast::NodeValue::Deref(_) =>
628
            return true,
629
        else =>
630
            return false,
631
    }
632
}
633
634
/// Check if a statement requires a semicolon after it.
635
///
636
/// Statements that end with blocks don't require semicolons.
637
/// All other statements do.
638
fn expectsSemicolon(stmt: *ast::Node) -> bool {
639
    match stmt.value {
640
        case ast::NodeValue::If(_),
641
             ast::NodeValue::IfLet(_),
642
             ast::NodeValue::While(_),
643
             ast::NodeValue::WhileLet(_),
644
             ast::NodeValue::For(_),
645
             ast::NodeValue::Loop { .. },
646
             ast::NodeValue::Match(_),
647
             ast::NodeValue::Block(_),
648
             ast::NodeValue::FnDecl(_),
649
             ast::NodeValue::RecordDecl(_),
650
             ast::NodeValue::UnionDecl(_),
651
             ast::NodeValue::TraitDecl { .. },
652
             ast::NodeValue::InstanceDecl { .. },
653
             ast::NodeValue::MethodDecl { .. } => return false,
654
        else => return true,
655
    }
656
}
657
658
/// Parse a primary leaf expression without postfix operators.
659
fn parseLeaf(p: *mut Parser) -> *ast::Node
660
    throws (ParseError)
661
{
662
    match p.current.kind {
663
        case scanner::TokenKind::True => {
664
            advance(p);
665
            return nodeBool(p, true);
666
        }
667
        case scanner::TokenKind::False => {
668
            advance(p);
669
            return nodeBool(p, false);
670
        }
671
        case scanner::TokenKind::Ident => {
672
            advance(p);
673
            return node(p, ast::NodeValue::Ident(p.previous.source));
674
        }
675
        case scanner::TokenKind::Super => {
676
            advance(p);
677
            return nodeSuper(p);
678
        }
679
        case scanner::TokenKind::Number => {
680
            advance(p);
681
            let literal = try parseIntLiteral(p, p.previous.source);
682
            return nodeNumber(p, literal);
683
        }
684
        case scanner::TokenKind::LParen => {
685
            return try parseParenthesized(p);
686
        }
687
        case scanner::TokenKind::Try => {
688
            return try parseTryExpr(p);
689
        }
690
        case scanner::TokenKind::Nil => {
691
            advance(p);
692
            return node(p, ast::NodeValue::Nil);
693
        }
694
        case scanner::TokenKind::Undefined => {
695
            advance(p);
696
            return node(p, ast::NodeValue::Undef);
697
        }
698
        case scanner::TokenKind::Char => {
699
            advance(p);
700
            let src = p.previous.source;
701
            let mut ch: u8 = 0;
702
703
            if src[1] == '\\' { // Handle escape sequences.
704
                match src[2] {
705
                    case 'n'  => { ch = '\n'; }
706
                    case 't'  => { ch = '\t'; }
707
                    case 'r'  => { ch = '\r'; }
708
                    case '\'' => { ch = '\''; }
709
                    case '\\' => { ch = '\\'; }
710
                    else      => { ch = src[2]; }
711
                }
712
            } else {
713
                ch = src[1];
714
            }
715
            return node(p, ast::NodeValue::Char(ch));
716
        }
717
        case scanner::TokenKind::String => {
718
            advance(p);
719
            let src = p.previous.source;
720
            let raw = &src[1..src.len - 1]; // Strip quotes.
721
722
            // Process escape sequences into arena buffer.
723
            let buf = alloc::remainingBuf(&mut p.arena.arena);
724
            let len = unescapeString(raw, buf);
725
            alloc::commit(&mut p.arena.arena, len);
726
727
            return node(p, ast::NodeValue::String(&buf[..len]));
728
        }
729
        case scanner::TokenKind::Underscore => {
730
            advance(p);
731
            return node(p, ast::NodeValue::Placeholder);
732
        }
733
        case scanner::TokenKind::LBracket => {
734
            return try parseArrayLiteral(p);
735
        }
736
        case scanner::TokenKind::AtIdent => {
737
            return try parseBuiltin(p);
738
        }
739
        case scanner::TokenKind::DotDot => {
740
            advance(p);
741
            return try parseRangeExpr(p, nil);
742
        }
743
        case scanner::TokenKind::LBrace => {
744
            // Anonymous record literal: { x: 1, y: 2 }.
745
            // Only allowed in normal context, not in conditions.
746
            if p.context != Context::Normal {
747
                throw failParsing(p, "unexpected `{` in this context");
748
            }
749
            return try parseRecordLit(p, nil);
750
        }
751
        else => {
752
            throw failParsing(p, "expected expression");
753
        }
754
    }
755
}
756
757
/// Parse a primary expression (leaf nodes followed by postfix operators).
758
fn parsePrimary(p: *mut Parser) -> *ast::Node
759
    throws (ParseError)
760
{
761
    let leaf = try parseLeaf(p);
762
    return try parsePostfix(p, leaf);
763
}
764
765
/// Parse a builtin function call like `@sizeOf(T)` or `@alignOf(T)`.
766
fn parseBuiltin(p: *mut Parser) -> *ast::Node
767
    throws (ParseError)
768
{
769
    // Skip the '@' to get the name.
770
    let ident = p.current.source;
771
    advance(p);
772
773
    let mut kind: ast::Builtin = undefined;
774
    // TODO: Use `match`.
775
    if ident == "@sizeOf" {
776
        kind = ast::Builtin::SizeOf;
777
    } else if ident == "@alignOf" {
778
        kind = ast::Builtin::AlignOf;
779
    } else if ident == "@sliceOf" {
780
        kind = ast::Builtin::SliceOf;
781
    } else {
782
        throw failParsing(p, "unknown builtin");
783
    }
784
    try expect(p, scanner::TokenKind::LParen, "expected `(` after builtin name");
785
786
    // Parse arguments into a list. Use capacity 4 to handle any valid argument count
787
    // plus some extra for error recovery.
788
    let mut args = ast::nodeSlice(p.arena, 4);
789
790
    if kind == ast::Builtin::SliceOf {
791
        // Parse comma-separated expressions until closing paren.
792
        // Argument count validation is done in semantic analysis.
793
        while not check(p, scanner::TokenKind::RParen) {
794
            args.append(try parseExpr(p), p.allocator);
795
            if not consume(p, scanner::TokenKind::Comma) {
796
                break;
797
            }
798
        }
799
    } else {
800
        args.append(try parseType(p), p.allocator);
801
    }
802
    try expect(p, scanner::TokenKind::RParen, "expected `)` after builtin argument");
803
804
    return node(p, ast::NodeValue::BuiltinCall { kind, args });
805
}
806
807
/// Parse a single expression.
808
///
809
/// Parses unary and binary operators using precedence climbing.
810
/// Conditional expressions (`x if cond else y`) have lowest precedence.
811
pub fn parseExpr(p: *mut Parser) -> *ast::Node
812
    throws (ParseError)
813
{
814
    let left = try parseUnary(p);
815
    let expr = try parseBinary(p, left, -1);
816
    return try parseCondExpr(p, expr);
817
}
818
819
/// Try to consume a compound assignment operator and return its binary op.
820
fn tryCompoundAssignOp(p: *mut Parser) -> ?ast::BinaryOp {
821
    match p.current.kind {
822
        case scanner::TokenKind::PlusEqual =>    { advance(p); return ast::BinaryOp::Add; }
823
        case scanner::TokenKind::MinusEqual =>   { advance(p); return ast::BinaryOp::Sub; }
824
        case scanner::TokenKind::StarEqual =>    { advance(p); return ast::BinaryOp::Mul; }
825
        case scanner::TokenKind::SlashEqual =>   { advance(p); return ast::BinaryOp::Div; }
826
        case scanner::TokenKind::PercentEqual => { advance(p); return ast::BinaryOp::Mod; }
827
        case scanner::TokenKind::AmpEqual =>     { advance(p); return ast::BinaryOp::BitAnd; }
828
        case scanner::TokenKind::PipeEqual =>    { advance(p); return ast::BinaryOp::BitOr; }
829
        case scanner::TokenKind::CaretEqual =>   { advance(p); return ast::BinaryOp::BitXor; }
830
        case scanner::TokenKind::LtLtEqual =>    { advance(p); return ast::BinaryOp::Shl; }
831
        case scanner::TokenKind::GtGtEqual =>    { advance(p); return ast::BinaryOp::Shr; }
832
        else => return nil,
833
    }
834
}
835
836
/// Parse an expression statement.
837
pub fn parseExprStmt(p: *mut Parser) -> *ast::Node
838
    throws (ParseError)
839
{
840
    let expr = try parseExpr(p);
841
842
    if consume(p, scanner::TokenKind::Equal) {
843
        if not isAssignableTarget(expr) {
844
            throw failParsing(p, "invalid assignment target");
845
        }
846
        let value = try parseExpr(p);
847
848
        return node(p, ast::NodeValue::Assign(
849
            ast::Assign { left: expr, right: value }
850
        ));
851
    }
852
    // Compound assignment: desugar `x <op>= y` into `x = x <op> y`.
853
    // The left-hand side node is shared between the assignment target and the
854
    // binary operand. This is safe because the resolver caches results by node
855
    // and returns the same type on repeated visits.
856
    if let op = tryCompoundAssignOp(p) {
857
        if not isAssignableTarget(expr) {
858
            throw failParsing(p, "invalid compound assignment target");
859
        }
860
        let rhs = try parseExpr(p);
861
        let binop = node(p, ast::NodeValue::BinOp(
862
            ast::BinOp { op, left: expr, right: rhs }
863
        ));
864
865
        return node(p, ast::NodeValue::Assign(
866
            ast::Assign { left: expr, right: binop }
867
        ));
868
    }
869
    return node(p, ast::NodeValue::ExprStmt(expr));
870
}
871
872
/// Parse leading attributes attached to the next declaration statement.
873
fn parseAttributes(p: *mut Parser) -> ?ast::Attributes {
874
    let mut attrs = ast::nodeSlice(p.arena, 4);
875
876
    if let attr = tryParseAnnotation(p) {
877
        attrs.append(attr, p.allocator);
878
    }
879
    if consume(p, scanner::TokenKind::Pub) {
880
        let attrNode = nodeAttribute(p, ast::Attribute::Pub);
881
        attrs.append(attrNode, p.allocator);
882
    }
883
    if consume(p, scanner::TokenKind::Extern) {
884
        let attrNode = nodeAttribute(p, ast::Attribute::Extern);
885
        attrs.append(attrNode, p.allocator);
886
    }
887
    if attrs.len > 0 {
888
        return ast::Attributes { list: attrs };
889
    }
890
    return nil;
891
}
892
893
/// Try to parse an annotation like `@default`.
894
///
895
/// Returns `nil` if not a known annotation (e.g. `@sizeOf` or `@alignOf` which are builtins).
896
/// Only consumes tokens if a valid annotation is found.
897
fn tryParseAnnotation(p: *mut Parser) -> ?*ast::Node {
898
    if not check(p, scanner::TokenKind::AtIdent) {
899
        return nil;
900
    }
901
    // Token is @identifier, skip the '@' to get the name.
902
    let ident = &p.current.source[..];
903
    if ident == "@default" {
904
        advance(p); // Consume `@default`.
905
        return nodeAttribute(p, ast::Attribute::Default);
906
    }
907
    if ident == "@test" {
908
        advance(p); // Consume `@test`.
909
        return nodeAttribute(p, ast::Attribute::Test);
910
    }
911
    if ident == "@intrinsic" {
912
        advance(p); // Consume `@intrinsic`.
913
        return nodeAttribute(p, ast::Attribute::Intrinsic);
914
    }
915
    return nil;
916
}
917
918
/// Parse a single statement.
919
///
920
/// Dispatches to the appropriate statement parser based on the current token.
921
pub fn parseStmt(p: *mut Parser) -> *ast::Node
922
    throws (ParseError)
923
{
924
    // TODO: Why is `parseStmt` checking for attributes?
925
    // We should have a `parseDecl` which is top-level, and `parseStmt` which
926
    // is inside functions.
927
    let attrs = parseAttributes(p);
928
    if attrs != nil {
929
        let allowed: bool =
930
            p.current.kind == scanner::TokenKind::Fn or
931
            p.current.kind == scanner::TokenKind::Union or
932
            p.current.kind == scanner::TokenKind::Record or
933
            p.current.kind == scanner::TokenKind::Mod or
934
            p.current.kind == scanner::TokenKind::Static or
935
            p.current.kind == scanner::TokenKind::Const or
936
            p.current.kind == scanner::TokenKind::Use or
937
            p.current.kind == scanner::TokenKind::Trait;
938
939
        if not allowed {
940
            throw failParsing(p, "attributes are not allowed in this context");
941
        }
942
    }
943
944
    match p.current.kind {
945
        case scanner::TokenKind::If => {
946
            return try parseIf(p);
947
        }
948
        case scanner::TokenKind::LBrace => {
949
            return try parseBlock(p);
950
        }
951
        case scanner::TokenKind::While => {
952
            return try parseWhile(p);
953
        }
954
        case scanner::TokenKind::Loop => {
955
            return try parseLoop(p);
956
        }
957
        case scanner::TokenKind::For => {
958
            return try parseFor(p);
959
        }
960
        case scanner::TokenKind::Return => {
961
            return try parseReturn(p);
962
        }
963
        case scanner::TokenKind::Throw => {
964
            return try parseThrow(p);
965
        }
966
        case scanner::TokenKind::Panic => {
967
            return try parsePanic(p);
968
        }
969
        case scanner::TokenKind::Assert => {
970
            return try parseAssert(p);
971
        }
972
        case scanner::TokenKind::Break => {
973
            advance(p);
974
            return node(p, ast::NodeValue::Break);
975
        }
976
        case scanner::TokenKind::Continue => {
977
            advance(p);
978
            return node(p, ast::NodeValue::Continue);
979
        }
980
        case scanner::TokenKind::Match => {
981
            return try parseMatch(p);
982
        }
983
        case scanner::TokenKind::Let => {
984
            advance(p);
985
            if consume(p, scanner::TokenKind::Case) {
986
                return try parseLetCase(p);
987
            }
988
            if consume(p, scanner::TokenKind::Mut) {
989
                return try parseLet(p, true);
990
            }
991
            return try parseLet(p, false);
992
        }
993
        case scanner::TokenKind::Const => {
994
            return try parseConst(p, attrs);
995
        }
996
        case scanner::TokenKind::Static => {
997
            return try parseStatic(p, attrs);
998
        }
999
        case scanner::TokenKind::Fn => {
1000
            return try parseFnDecl(p, attrs);
1001
        }
1002
        case scanner::TokenKind::Union => {
1003
            return try parseUnionDecl(p, attrs);
1004
        }
1005
        case scanner::TokenKind::Record => {
1006
            return try parseRecordDecl(p, attrs);
1007
        }
1008
        case scanner::TokenKind::Use => {
1009
            return try parseUse(p, attrs);
1010
        }
1011
        case scanner::TokenKind::Mod => {
1012
            return try parseMod(p, attrs);
1013
        }
1014
        case scanner::TokenKind::Trait => {
1015
            return try parseTraitDecl(p, attrs);
1016
        }
1017
        case scanner::TokenKind::Instance => {
1018
            return try parseInstanceDecl(p);
1019
        }
1020
        else => {
1021
            return try parseExprStmt(p);
1022
        }
1023
    }
1024
}
1025
1026
/// Parse statements until the specified ending token is encountered.
1027
///
1028
/// Adds each parsed statement to the given block's statement list.
1029
pub fn parseStmtsUntil(p: *mut Parser, end: scanner::TokenKind, blk: *mut ast::Block)
1030
    throws (ParseError)
1031
{
1032
    while not check(p, end) {
1033
        let stmt = try parseStmt(p);
1034
        blk.statements.append(stmt, p.allocator);
1035
1036
        if check(p, end) or check(p, scanner::TokenKind::Eof) {
1037
            break;
1038
        }
1039
        if not consume(p, scanner::TokenKind::Semicolon) {
1040
            // Only require semicolon if the statement needs one.
1041
            if expectsSemicolon(stmt) {
1042
                throw failParsing(p, "expected `;` after statement");
1043
            }
1044
        }
1045
    }
1046
}
1047
1048
/// Parse a block of statements enclosed in curly braces.
1049
pub fn parseBlock(p: *mut Parser) -> *ast::Node
1050
    throws (ParseError)
1051
{
1052
    let start = p.current;
1053
    let mut blk = mkBlock(p, 64);
1054
1055
    if not consume(p, scanner::TokenKind::LBrace) {
1056
        throw failParsing(p, "expected `{`");
1057
    }
1058
    try parseStmtsUntil(p, scanner::TokenKind::RBrace, &mut blk);
1059
    try expect(p, scanner::TokenKind::RBrace, "expected `}`");
1060
1061
    return node(p, ast::NodeValue::Block(blk));
1062
}
1063
1064
/// Create an empty block with no statements.
1065
fn mkBlock(p: *mut Parser, cap: u32) -> ast::Block {
1066
    return ast::Block { statements: ast::nodeSlice(p.arena, cap) };
1067
}
1068
1069
/// Create a block containing a single statement node.
1070
fn mkBlockWith(p: *mut Parser, node: *ast::Node) -> ast::Block {
1071
    let stmts = ast::nodeSlice(p.arena, 1).append(node, p.allocator);
1072
    return ast::Block { statements: stmts };
1073
}
1074
1075
/// Parse the branch that follows `else` in let-else style constructs.
1076
///
1077
/// Allows either a block, a single statement like `return`,
1078
/// or a standalone expression which is returned directly.
1079
fn parseLetElseBranch(p: *mut Parser) -> *ast::Node
1080
    throws (ParseError)
1081
{
1082
    if check(p, scanner::TokenKind::LBrace) {
1083
        return try parseBlock(p);
1084
    }
1085
    let branch = try parseStmt(p);
1086
1087
    if let case ast::NodeValue::ExprStmt(expr) = branch.value {
1088
        return expr;
1089
    }
1090
    return branch;
1091
}
1092
1093
/// Allocate a new node from the parser's arena.
1094
fn node(p: *mut Parser, value: ast::NodeValue) -> *mut ast::Node {
1095
    let span = ast::Span {
1096
        offset: p.previous.offset,
1097
        length: p.previous.source.len,
1098
    };
1099
    let n = ast::allocNode(p.arena, span, value);
1100
    finishSpan(p, n);
1101
1102
    return n;
1103
}
1104
1105
/// Update the span of `node` using the most recently consumed token.
1106
fn finishSpan(p: *mut Parser, node: *mut ast::Node) {
1107
    let start: u32 = node.span.offset;
1108
    let mut end: u32 = p.previous.offset + p.previous.source.len;
1109
1110
    if end >= start {
1111
        node.span.length = end - start;
1112
    } else {
1113
        node.span.length = 0;
1114
    }
1115
}
1116
1117
/// Save parser state for speculative parsing.
1118
fn saveState(p: *Parser) -> SavedState {
1119
    return SavedState {
1120
        parser: *p,
1121
        arena: alloc::save(&p.arena.arena),
1122
        nextId: p.arena.nextId,
1123
    };
1124
}
1125
1126
/// Restore parser state from a snapshot, fully undoing any
1127
/// side effects of a failed speculative parse.
1128
fn restoreState(p: *mut Parser, s: *SavedState) {
1129
    *p = s.parser;
1130
    alloc::restore(&mut p.arena.arena, s.arena);
1131
    p.arena.nextId = s.nextId;
1132
}
1133
1134
/// Report a parser error.
1135
fn reportError(p: *mut Parser, token: scanner::Token, message: *[u8]) {
1136
    assert message.len > 0;
1137
1138
    // Ignore errors once the error list is full.
1139
    if p.errors.count < p.errors.list.len {
1140
        p.errors.list[p.errors.count] = Error { message, token };
1141
        p.errors.count += 1;
1142
    }
1143
}
1144
1145
/// Fail the parsing process with the given error.
1146
fn failParsing(p: *mut Parser, err: *[u8]) -> ParseError {
1147
    reportError(p, p.current, err);
1148
    return ParseError::UnexpectedToken;
1149
}
1150
1151
/// Print all errors that have been collected during parsing.
1152
pub fn printErrors(p: *Parser) {
1153
    for i in 0..p.errors.count {
1154
        let e = p.errors.list[i];
1155
        if let loc = scanner::getLocation(
1156
            p.scanner.sourceLoc, p.scanner.source, e.token.offset
1157
        ) {
1158
            if let case scanner::SourceLoc::File(path) = loc.source {
1159
                io::print(path);
1160
                io::print(":");
1161
            }
1162
            io::printU32(loc.line as u32);
1163
            io::print(":");
1164
            io::printU32(loc.col as u32);
1165
            io::print(": error: ");
1166
        } else {
1167
            io::print("error: ");
1168
        }
1169
        io::print(e.message);
1170
        if e.token.kind == scanner::TokenKind::Invalid {
1171
            io::print(": ");
1172
            io::print(e.token.source);
1173
        } else {
1174
            io::print(", got `");
1175
            io::print(e.token.source);
1176
            io::print("`");
1177
        }
1178
        io::print("\n");
1179
    }
1180
}
1181
1182
/// Check whether the current token matches the expected kind.
1183
pub fn check(p: *Parser, kind: scanner::TokenKind) -> bool {
1184
    return p.current.kind == kind;
1185
}
1186
1187
/// Advance the parser by one token.
1188
pub fn advance(p: *mut Parser) {
1189
    p.previous = p.current;
1190
    p.current = scanner::next(&mut p.scanner);
1191
}
1192
1193
/// Parse an `if let` pattern matching statement.
1194
///
1195
/// Syntax: `if let binding = scrutinee { ... }`
1196
/// Syntax: `if let mut binding = scrutinee { ... }`
1197
fn parseIfLet(p: *mut Parser) -> *ast::Node throws (ParseError) {
1198
    try expect(p, scanner::TokenKind::Let, "expected `let`");
1199
1200
    // Parse pattern: either `case <pattern>`, `mut <ident>`, or simple `<ident>`.
1201
    let mut pattern: *ast::Node = undefined;
1202
    let mut kind = ast::PatternKind::Binding;
1203
    let mut mutable = false;
1204
1205
    if consume(p, scanner::TokenKind::Case) {
1206
        pattern = try parseMatchPattern(p);
1207
        kind = ast::PatternKind::Case;
1208
    } else {
1209
        mutable = consume(p, scanner::TokenKind::Mut);
1210
        pattern = try parseIdentOrPlaceholder(p, "expected `case`, `mut`, or identifier after `let`");
1211
    }
1212
    try expect(p, scanner::TokenKind::Equal, "expected `=` after pattern");
1213
1214
    let scrutinee = try parseCond(p);
1215
    let mut guard: ?*ast::Node = nil;
1216
1217
    if consume(p, scanner::TokenKind::Semicolon) {
1218
        guard = try parseCond(p);
1219
    }
1220
    let thenBranch = try parseBlock(p);
1221
    let mut elseBranch: ?*ast::Node = nil;
1222
1223
    if consume(p, scanner::TokenKind::Else) {
1224
        if check(p, scanner::TokenKind::If) {
1225
            elseBranch = node(p, ast::NodeValue::Block(
1226
                mkBlockWith(p, try parseIf(p))
1227
            ));
1228
        } else {
1229
            elseBranch = try parseBlock(p);
1230
        }
1231
    }
1232
1233
    return node(p, ast::NodeValue::IfLet(ast::IfLet {
1234
        pattern: ast::PatternMatch { pattern, scrutinee, guard, kind, mutable },
1235
        thenBranch,
1236
        elseBranch,
1237
    }));
1238
}
1239
1240
/// Parse a `while let` statement.
1241
fn parseWhileLet(p: *mut Parser) -> *ast::Node
1242
    throws (ParseError)
1243
{
1244
    try expect(p, scanner::TokenKind::Let, "expected `let`");
1245
1246
    // Parse pattern: either `case <pattern>`, `mut <ident>`, or simple `<ident>`.
1247
    let mut pattern: *ast::Node = undefined;
1248
    let mut kind = ast::PatternKind::Binding;
1249
    let mut mutable = false;
1250
    if consume(p, scanner::TokenKind::Case) {
1251
        pattern = try parseMatchPattern(p);
1252
        kind = ast::PatternKind::Case;
1253
    } else {
1254
        mutable = consume(p, scanner::TokenKind::Mut);
1255
        pattern = try parseIdentOrPlaceholder(p, "expected `case`, `mut`, or identifier after `let`");
1256
    }
1257
    try expect(p, scanner::TokenKind::Equal, "expected `=` after pattern");
1258
1259
    let scrutinee = try parseCond(p);
1260
    let mut guard: ?*ast::Node = nil;
1261
1262
    if consume(p, scanner::TokenKind::Semicolon) {
1263
        guard = try parseCond(p);
1264
    }
1265
    let body = try parseBlock(p);
1266
    let mut elseBranch: ?*ast::Node = nil;
1267
1268
    if consume(p, scanner::TokenKind::Else) {
1269
        elseBranch = try parseBlock(p);
1270
    }
1271
    return node(p, ast::NodeValue::WhileLet(ast::WhileLet {
1272
        pattern: ast::PatternMatch { pattern, scrutinee, guard, kind, mutable },
1273
        body,
1274
        elseBranch,
1275
    }));
1276
}
1277
1278
/// Parse a `while` statement.
1279
fn parseWhile(p: *mut Parser) -> *ast::Node
1280
    throws (ParseError)
1281
{
1282
    try expect(p, scanner::TokenKind::While, "expected `while`");
1283
1284
    // Check for `while let` or `while let case` syntax.
1285
    if check(p, scanner::TokenKind::Let) {
1286
        return try parseWhileLet(p);
1287
    }
1288
    let condition = try parseCond(p);
1289
    let body = try parseBlock(p);
1290
    let mut elseBranch: ?*ast::Node = nil;
1291
1292
    if consume(p, scanner::TokenKind::Else) {
1293
        elseBranch = try parseBlock(p);
1294
    }
1295
    return node(p, ast::NodeValue::While(ast::While {
1296
        condition, body, elseBranch,
1297
    }));
1298
}
1299
1300
/// Parse a `loop` statement.
1301
fn parseLoop(p: *mut Parser) -> *ast::Node
1302
    throws (ParseError)
1303
{
1304
    try expect(p, scanner::TokenKind::Loop, "expected `loop`");
1305
    let body = try parseBlock(p);
1306
1307
    return node(p, ast::NodeValue::Loop { body });
1308
}
1309
1310
/// Parse a `for` statement.
1311
fn parseFor(p: *mut Parser) -> *ast::Node
1312
    throws (ParseError)
1313
{
1314
    try expect(p, scanner::TokenKind::For, "expected `for`");
1315
1316
    let binding = try parseIdentOrPlaceholder(p, "expected identifier or `_`");
1317
    let mut index: ?*ast::Node = nil;
1318
1319
    if consume(p, scanner::TokenKind::Comma) {
1320
        index = try parseIdentOrPlaceholder(p, "expected index identifier or `_` after `,`");
1321
    }
1322
    try expect(p, scanner::TokenKind::In, "expected `in`");
1323
1324
    let iterable = try parseCond(p);
1325
    let body = try parseBlock(p);
1326
    let mut elseBranch: ?*ast::Node = nil;
1327
1328
    if consume(p, scanner::TokenKind::Else) {
1329
        elseBranch = try parseBlock(p);
1330
    }
1331
    return node(p, ast::NodeValue::For(ast::For {
1332
        binding, index, iterable, body, elseBranch,
1333
    }));
1334
}
1335
1336
/// Parse a `return` statement.
1337
fn parseReturn(p: *mut Parser) -> *ast::Node
1338
    throws (ParseError)
1339
{
1340
    try expect(p, scanner::TokenKind::Return, "expected `return`");
1341
1342
    // Speculatively try to parse a return value expression.
1343
    let saved = saveState(p);
1344
    let value: ?*ast::Node = try? parseExpr(p);
1345
    if value == nil {
1346
        restoreState(p, &saved);
1347
    }
1348
    return node(p, ast::NodeValue::Return { value });
1349
}
1350
1351
/// Parse a `throw` statement.
1352
fn parseThrow(p: *mut Parser) -> *ast::Node
1353
    throws (ParseError)
1354
{
1355
    try expect(p, scanner::TokenKind::Throw, "expected `throw`");
1356
    let expr = try parseExpr(p);
1357
1358
    return node(p, ast::NodeValue::Throw { expr });
1359
}
1360
1361
/// Parse a `panic` statement.
1362
fn parsePanic(p: *mut Parser) -> *ast::Node
1363
    throws (ParseError)
1364
{
1365
    try expect(p, scanner::TokenKind::Panic, "expected `panic`");
1366
1367
    // `panic { expr }`.
1368
    if consume(p, scanner::TokenKind::LBrace) {
1369
        let message: ?*ast::Node = try parseExpr(p);
1370
        try expect(p, scanner::TokenKind::RBrace, "expected closing `}` after expression");
1371
        return node(p, ast::NodeValue::Panic { message });
1372
    }
1373
    // `panic` or `panic "message"`.
1374
    let saved = saveState(p);
1375
    let message: ?*ast::Node = try? parseExpr(p);
1376
    if message == nil {
1377
        restoreState(p, &saved);
1378
    }
1379
    return node(p, ast::NodeValue::Panic { message });
1380
}
1381
1382
/// Parse an `assert` statement.
1383
///
1384
/// Forms:
1385
///   `assert <expr>`
1386
///   `assert <expr>, "message"`
1387
///   `assert { <expr> }, "message"`
1388
fn parseAssert(p: *mut Parser) -> *ast::Node
1389
    throws (ParseError)
1390
{
1391
    try expect(p, scanner::TokenKind::Assert, "expected `assert`");
1392
1393
    // `assert { expr }` block form or `assert <expr>`.
1394
    let mut condition: *ast::Node = undefined;
1395
    if consume(p, scanner::TokenKind::LBrace) {
1396
        condition = try parseExpr(p);
1397
        try expect(p, scanner::TokenKind::RBrace, "expected closing `}` after expression");
1398
    } else {
1399
        condition = try parseExpr(p);
1400
    }
1401
    let mut message: ?*ast::Node = nil;
1402
    if consume(p, scanner::TokenKind::Comma) {
1403
        message = try parseExpr(p);
1404
    }
1405
    return node(p, ast::NodeValue::Assert { condition, message });
1406
}
1407
1408
/// Parse a `try` expression with optional `catch` clause(s).
1409
fn parseTryExpr(p: *mut Parser) -> *ast::Node
1410
    throws (ParseError)
1411
{
1412
    try expect(p, scanner::TokenKind::Try, "expected `try`");
1413
1414
    let shouldPanic = consume(p, scanner::TokenKind::Bang);
1415
    let returnsOptional = consume(p, scanner::TokenKind::Question);
1416
    let expr = try parsePrimary(p);
1417
    let mut catches = ast::nodeSlice(p.arena, 4);
1418
1419
    while consume(p, scanner::TokenKind::Catch) {
1420
        let mut binding: ?*ast::Node = nil;
1421
        let mut typeNode: ?*ast::Node = nil;
1422
1423
        // Check for optional error binding: `catch ident { ... }` or
1424
        // `catch ident as Type { ... }`.
1425
        if check(p, scanner::TokenKind::Ident) {
1426
            binding = try parseIdent(p, "expected identifier after `catch`");
1427
            if consume(p, scanner::TokenKind::As) {
1428
                typeNode = try parseType(p);
1429
            }
1430
        }
1431
        if not check(p, scanner::TokenKind::LBrace) {
1432
            throw failParsing(p, "expected `{` after `catch`");
1433
        }
1434
        let body = try parseBlock(p);
1435
        let clause = node(p, ast::NodeValue::CatchClause(
1436
            ast::CatchClause { binding, typeNode, body }
1437
        ));
1438
        catches.append(clause, p.allocator);
1439
    }
1440
    return node(p, ast::NodeValue::Try(
1441
        ast::Try { expr, catches, shouldPanic, returnsOptional }
1442
    ));
1443
}
1444
1445
/// Parse an `if` expression, with optional `else` or `else if` clauses.
1446
///
1447
/// The `else if` construct is handled by creating a recursive structure:
1448
/// 1. When an `else` is followed by an `if`, we create a new block node.
1449
/// 2. We parse the nested `if` statement recursively using `parseIf`.
1450
/// 3. We put this nested `if` statement inside the block node.
1451
/// 4. This block node becomes the `elseBranch` of the parent `if`.
1452
///
1453
/// This approach naturally handles multiple `else if` chains through recursion.
1454
///
1455
/// For example:
1456
///   if x {
1457
///       a
1458
///   } else if y {
1459
///       b
1460
///   } else if z {
1461
///       c
1462
///   } else {
1463
///       d
1464
///   }
1465
///
1466
/// Is represented as a nested structure like:
1467
///
1468
///   if x {
1469
///       a
1470
///   } else {
1471
///       if y {
1472
///           b
1473
///       } else {
1474
///           if z {
1475
///               c
1476
///           } else {
1477
///               d
1478
///           }
1479
///       }
1480
///   }
1481
///
1482
fn parseIf(p: *mut Parser) -> *ast::Node throws (ParseError) {
1483
    try expect(p, scanner::TokenKind::If, "expected `if`");
1484
1485
    // Check for `if let` or `if let case` syntax.
1486
    if check(p, scanner::TokenKind::Let) {
1487
        return try parseIfLet(p);
1488
    }
1489
    // Regular if statement.
1490
    let cond = try parseCond(p);
1491
    let thenBranch = try parseBlock(p);
1492
    let mut elseBranch: ?*ast::Node = nil;
1493
1494
    if consume(p, scanner::TokenKind::Else) {
1495
        // Check for `else if` construct.
1496
        if check(p, scanner::TokenKind::If) {
1497
            // Set the else branch to a block containing the nested if.
1498
            elseBranch = node(p, ast::NodeValue::Block(
1499
                mkBlockWith(p, try parseIf(p))
1500
            ));
1501
        } else {
1502
            // Regular else clause.
1503
            elseBranch = try parseBlock(p);
1504
        }
1505
    }
1506
    return node(p, ast::NodeValue::If(ast::If {
1507
        condition: cond, thenBranch, elseBranch,
1508
    }));
1509
}
1510
1511
/// Parse a `match` statement.
1512
fn parseMatch(p: *mut Parser) -> *ast::Node
1513
    throws (ParseError)
1514
{
1515
    try expect(p, scanner::TokenKind::Match, "expected `match`");
1516
1517
    let subject = try parseCond(p);
1518
    try expect(p, scanner::TokenKind::LBrace, "expected `{` before match prongs");
1519
1520
    let mut prongs = ast::nodeSlice(p.arena, 128);
1521
    while not check(p, scanner::TokenKind::RBrace) and
1522
          not check(p, scanner::TokenKind::Eof) // TODO: We shouldn't have to manually check for EOF.
1523
    {
1524
        let prongNode = try parseMatchProng(p);
1525
        prongs.append(prongNode, p.allocator);
1526
        consume(p, scanner::TokenKind::Comma);
1527
    }
1528
    try expect(p, scanner::TokenKind::RBrace, "expected `}` after match prongs");
1529
1530
    return node(p, ast::NodeValue::Match(
1531
        ast::Match { subject, prongs }
1532
    ));
1533
}
1534
1535
/// Parse a single `match` prong.
1536
fn parseMatchProng(p: *mut Parser) -> *ast::Node
1537
    throws (ParseError)
1538
{
1539
    let mut guard: ?*ast::Node = nil;
1540
1541
    // Case prong: `case <pattern>, ... if <guard> => <body>`.
1542
    if consume(p, scanner::TokenKind::Case) {
1543
        let mut patterns = ast::nodeSlice(p.arena, 16);
1544
        loop {
1545
            let pattern = try parseMatchPattern(p);
1546
            patterns.append(pattern, p.allocator);
1547
1548
            if not consume(p, scanner::TokenKind::Comma) {
1549
                break;
1550
            }
1551
            // After a comma, check for tokens that start a new prong.
1552
            // This catches mistakes like `case A, case B`.
1553
            if check(p, scanner::TokenKind::Case) or check(p, scanner::TokenKind::Else) {
1554
                throw failParsing(p, "unexpected keyword after `,` in case pattern list");
1555
            }
1556
        }
1557
        if consume(p, scanner::TokenKind::If) {
1558
            guard = try parseCond(p);
1559
        }
1560
        try expect(p, scanner::TokenKind::FatArrow, "expected `=>` after case pattern");
1561
        let body = try parseStmt(p);
1562
1563
        return node(p, ast::NodeValue::MatchProng(
1564
            ast::MatchProng { arm: ast::ProngArm::Case(patterns), guard, body }
1565
        ));
1566
    }
1567
    // Else prong: `else if <guard> => <body>`.
1568
    if consume(p, scanner::TokenKind::Else) {
1569
        if consume(p, scanner::TokenKind::If) {
1570
            guard = try parseCond(p);
1571
        }
1572
        try expect(p, scanner::TokenKind::FatArrow, "expected `=>` after else");
1573
        let body = try parseStmt(p);
1574
1575
        return node(p, ast::NodeValue::MatchProng(
1576
            ast::MatchProng { arm: ast::ProngArm::Else, guard, body }
1577
        ));
1578
    }
1579
    // Binding prong: `<ident> if <guard> => <body>` or `_ if <guard> => <body>`.
1580
    let binding = try parseIdentOrPlaceholder(p, "expected `case`, `else`, or identifier");
1581
1582
    if consume(p, scanner::TokenKind::If) {
1583
        guard = try parseCond(p);
1584
    }
1585
    try expect(p, scanner::TokenKind::FatArrow, "expected `=>` after binding");
1586
    let body = try parseStmt(p);
1587
1588
    return node(p, ast::NodeValue::MatchProng(
1589
        ast::MatchProng { arm: ast::ProngArm::Binding(binding), guard, body }
1590
    ));
1591
}
1592
1593
/// Parse a pattern expression used by `case` constructs.
1594
/// Uses `Pattern` context to allow record literals but not conditional expressions.
1595
fn parseMatchPattern(p: *mut Parser) -> *ast::Node
1596
    throws (ParseError)
1597
{
1598
    let saved = p.context;
1599
    p.context = Context::Pattern;
1600
    let pattern = try parseExpr(p);
1601
    p.context = saved;
1602
1603
    return pattern;
1604
}
1605
1606
/// Parse an identifier.
1607
fn parseIdent(p: *mut Parser, err: *[u8]) -> *ast::Node
1608
    throws (ParseError)
1609
{
1610
    let source = try expect(p, scanner::TokenKind::Ident, err);
1611
    return node(p, ast::NodeValue::Ident(source));
1612
}
1613
1614
/// Parse either an identifier or a placeholder (`_`).
1615
fn parseIdentOrPlaceholder(p: *mut Parser, err: *[u8]) -> *ast::Node
1616
    throws (ParseError)
1617
{
1618
    if consume(p, scanner::TokenKind::Underscore) {
1619
        return node(p, ast::NodeValue::Placeholder);
1620
    }
1621
    return try parseIdent(p, err);
1622
}
1623
1624
/// Parse an alignment specifier.
1625
///
1626
/// Syntax: `align(N)` where N is a power of 2.
1627
fn parseAlign(p: *mut Parser) -> *ast::Node
1628
    throws (ParseError)
1629
{
1630
    try expect(p, scanner::TokenKind::Align, "expected `align`");
1631
    let value = try parseParenthesized(p);
1632
    return node(p, ast::NodeValue::Align { value });
1633
}
1634
1635
/// Parse a comma-separated list of record fields.
1636
/// The opening delimiter should already be consumed.
1637
/// For labeled fields: `{ name: T, ... }`.
1638
/// For unlabeled fields: `(T, T, ...)`.
1639
fn parseRecordFields(
1640
    p: *mut Parser,
1641
    mode: RecordFieldMode
1642
) -> *mut [*ast::Node]
1643
    throws (ParseError)
1644
{
1645
    let terminator = scanner::TokenKind::RBrace if mode == RecordFieldMode::Labeled
1646
        else scanner::TokenKind::RParen;
1647
    let mut fields = ast::nodeSlice(p.arena, MAX_RECORD_FIELDS);
1648
    while not check(p, terminator) {
1649
        let mut recordField: ast::NodeValue = undefined;
1650
        match mode {
1651
            case RecordFieldMode::Labeled => {
1652
                // Allow optional `let` keyword before field name.
1653
                consume(p, scanner::TokenKind::Let);
1654
1655
                let field = try parseNameTypeValue(p);
1656
                let type = field.type else {
1657
                    throw failParsing(p, "expected type annotation in record field");
1658
                };
1659
                if field.alignment != nil {
1660
                    throw failParsing(p, "record fields cannot specify alignment");
1661
                }
1662
                if field.value != nil and mode != RecordFieldMode::Labeled {
1663
                    throw failParsing(p, "record fields cannot have initializers");
1664
                }
1665
                recordField = ast::NodeValue::RecordField {
1666
                    field: field.name, type, value: field.value,
1667
                };
1668
            }
1669
            case RecordFieldMode::Unlabeled => {
1670
                let type = try parseType(p);
1671
                recordField = ast::NodeValue::RecordField {
1672
                    field: nil, type, value: nil,
1673
                };
1674
            }
1675
        }
1676
        fields.append(node(p, recordField), p.allocator);
1677
1678
        if not consume(p, scanner::TokenKind::Comma) {
1679
            break;
1680
        }
1681
    }
1682
    try expect(p, terminator, "expected closing delimiter after record fields");
1683
1684
    return fields;
1685
}
1686
1687
/// Parse an optional derives list (`: Trait + Trait`).
1688
fn parseDerives(p: *mut Parser) -> *mut [*ast::Node] throws (ParseError) {
1689
    let mut derives = ast::nodeSlice(p.arena, 4);
1690
1691
    if not consume(p, scanner::TokenKind::Colon) {
1692
        return derives;
1693
    }
1694
    loop {
1695
        let t = try parseIdent(p, "expected trait name in derive list");
1696
        derives.append(t, p.allocator);
1697
1698
        if not consume(p, scanner::TokenKind::Plus) {
1699
            break;
1700
        }
1701
    }
1702
    return derives;
1703
}
1704
1705
/// Parse a single record literal field.
1706
/// Can be either labeled, or shorthand.
1707
fn parseRecordLitField(p: *mut Parser) -> *ast::Node
1708
    throws (ParseError)
1709
{
1710
    let name = try parseIdent(p, "expected field name");
1711
    if consume(p, scanner::TokenKind::Colon) {
1712
        // Labeled field: `name: value`.
1713
        let value = try parseExpr(p);
1714
        return node(p, ast::NodeValue::RecordLitField(
1715
            ast::Arg { label: name, value }
1716
        ));
1717
    }
1718
    // Shorthand syntax: `{ x }` is equivalent to `{ x: x }`.
1719
    return node(p, ast::NodeValue::RecordLitField(
1720
        ast::Arg { label: name, value: name }
1721
    ));
1722
}
1723
1724
/// Parse a record literal body.
1725
/// Eg. `{ x: 1, y: 2 }`
1726
/// Eg. `{ x: 1, .. }`
1727
fn parseRecordLit(p: *mut Parser, typeName: ?*ast::Node) -> *ast::Node
1728
    throws (ParseError)
1729
{
1730
    let mut fields = ast::nodeSlice(p.arena, MAX_RECORD_FIELDS);
1731
    let mut ignoreRest = false;
1732
    try expect(p, scanner::TokenKind::LBrace, "expected `{` to begin record literal");
1733
1734
    while not check(p, scanner::TokenKind::RBrace) {
1735
        // Check for `..` to ignore remaining fields.
1736
        if consume(p, scanner::TokenKind::DotDot) {
1737
            ignoreRest = true;
1738
            break;
1739
        }
1740
        let field = try parseRecordLitField(p);
1741
        fields.append(field, p.allocator);
1742
1743
        if not consume(p, scanner::TokenKind::Comma) {
1744
            break;
1745
        }
1746
    }
1747
    try expect(p, scanner::TokenKind::RBrace, "expected `}` to end record literal");
1748
1749
    return node(p, ast::NodeValue::RecordLit(
1750
        ast::RecordLit { typeName, fields, ignoreRest }
1751
    ));
1752
}
1753
1754
/// Parse a named record declaration.
1755
/// `record Point { x: i32, y: i32 }`, or `record Pair(i32, i32);`
1756
fn parseRecordDecl(p: *mut Parser, attrs: ?ast::Attributes) -> *ast::Node
1757
    throws (ParseError)
1758
{
1759
    try expect(p, scanner::TokenKind::Record, "expected `record`");
1760
1761
    let name = try parseIdent(p, "expected record name");
1762
    let derives = try parseDerives(p);
1763
1764
    if consume(p, scanner::TokenKind::LParen) {
1765
        let fields = try parseRecordFields(p, RecordFieldMode::Unlabeled);
1766
        try expect(p, scanner::TokenKind::Semicolon, "expected `;` after record");
1767
        return node(p, ast::NodeValue::RecordDecl(
1768
            ast::RecordDecl { name, fields, attrs, derives, labeled: false }
1769
        ));
1770
    } else {
1771
        try expect(p, scanner::TokenKind::LBrace, "expected `{` before record body");
1772
        let fields = try parseRecordFields(p, RecordFieldMode::Labeled);
1773
        return node(p, ast::NodeValue::RecordDecl(
1774
            ast::RecordDecl { name, fields, attrs, derives, labeled: true }
1775
        ));
1776
    }
1777
}
1778
1779
/// Parse a union declaration.
1780
/// Example: `union Color { Red, Green, Blue = 5 }`
1781
fn parseUnionDecl(p: *mut Parser, attrs: ?ast::Attributes) -> *ast::Node
1782
    throws (ParseError)
1783
{
1784
    try expect(p, scanner::TokenKind::Union, "expected `union`");
1785
1786
    let name = try parseIdent(p, "expected union name");
1787
    let derives = try parseDerives(p);
1788
1789
    try expect(p, scanner::TokenKind::LBrace, "expected `{` before union body");
1790
1791
    let mut variants = ast::nodeSlice(p.arena, 128);
1792
    while not check(p, scanner::TokenKind::RBrace) {
1793
        // Allow optional `case` keyword before variant name.
1794
        consume(p, scanner::TokenKind::Case);
1795
1796
        let variantName = try parseIdent(p, "expected variant name");
1797
        let mut payloadType: ?*ast::Node = nil;
1798
        let mut explicitValue: ?*ast::Node = nil;
1799
1800
        if consume(p, scanner::TokenKind::LParen) { // `Variant(T, U)`.
1801
            let fields = try parseRecordFields(p, RecordFieldMode::Unlabeled);
1802
            payloadType = node(p, ast::NodeValue::TypeSig(
1803
                ast::TypeSig::Record { fields, labeled: false }
1804
            ));
1805
        } else if consume(p, scanner::TokenKind::LBrace) { // `Variant { x: T, y: T }`.
1806
            let fields = try parseRecordFields(p, RecordFieldMode::Labeled);
1807
            payloadType = node(p, ast::NodeValue::TypeSig(
1808
                ast::TypeSig::Record { fields, labeled: true }
1809
            ));
1810
        } else if consume(p, scanner::TokenKind::Equal) {
1811
            // TODO: Support constant expressions.
1812
            try expect(p, scanner::TokenKind::Number, "expected integer literal after `=`");
1813
            let literal = try parseIntLiteral(p, p.previous.source);
1814
            explicitValue = nodeNumber(p, literal);
1815
        }
1816
1817
        let variant = node(p, ast::NodeValue::UnionDeclVariant(
1818
            ast::UnionDeclVariant {
1819
                name: variantName, index: variants.len as u32, value: explicitValue, type: payloadType,
1820
            }
1821
        ));
1822
        variants.append(variant, p.allocator);
1823
1824
        if not consume(p, scanner::TokenKind::Comma) {
1825
            break;
1826
        }
1827
    }
1828
    try expect(p, scanner::TokenKind::RBrace, "expected `}`");
1829
1830
    return node(p, ast::NodeValue::UnionDecl(
1831
        ast::UnionDecl { name, variants, attrs, derives }
1832
    ));
1833
}
1834
1835
/// Parse a function parameter.
1836
fn parseFnParam(p: *mut Parser) -> *ast::Node
1837
    throws (ParseError)
1838
{
1839
    let ntv = try parseNameTypeValue(p);
1840
    let type = ntv.type
1841
        else throw failParsing(p, "missing type in function parameter");
1842
1843
    return node(p, ast::NodeValue::FnParam(
1844
        ast::FnParam { name: ntv.name, type }
1845
    ));
1846
}
1847
1848
/// Parse an optional `throws` clause and return the collected type list.
1849
fn parseThrowList(p: *mut Parser) -> *mut [*ast::Node]
1850
    throws (ParseError)
1851
{
1852
    if not consume(p, scanner::TokenKind::Throws) {
1853
        return ast::nodeSlice(p.arena, 0);
1854
    }
1855
    return try parseList(
1856
        p,
1857
        scanner::TokenKind::LParen,
1858
        scanner::TokenKind::RParen,
1859
        parseType
1860
    );
1861
}
1862
1863
/// Parse a function type signature.
1864
fn parseFnType(p: *mut Parser) -> *ast::Node
1865
    throws (ParseError)
1866
{
1867
    try expect(p, scanner::TokenKind::Fn, "expected `fn`");
1868
    let params = try parseList(
1869
        p,
1870
        scanner::TokenKind::LParen,
1871
        scanner::TokenKind::RParen,
1872
        parseType
1873
    );
1874
    let mut returnType: ?*ast::Node = nil;
1875
1876
    if consume(p, scanner::TokenKind::Arrow) {
1877
        returnType = try parseType(p);
1878
    }
1879
    let throwList = try parseThrowList(p);
1880
    let sig = ast::FnSig { params, returnType, throwList };
1881
    return node(p, ast::NodeValue::TypeSig(
1882
        ast::TypeSig::Fn(sig)
1883
    ));
1884
}
1885
1886
/// Parse a function signature following the function name.
1887
fn parseFnTypeSig(p: *mut Parser) -> ast::FnSig
1888
    throws (ParseError)
1889
{
1890
    try expect(p, scanner::TokenKind::LParen, "expected `(` after function name");
1891
    let mut params = ast::nodeSlice(p.arena, 8);
1892
1893
    while not check(p, scanner::TokenKind::RParen) {
1894
        let param = try parseFnParam(p);
1895
        params.append(param, p.allocator);
1896
1897
        if not consume(p, scanner::TokenKind::Comma) {
1898
            break;
1899
        }
1900
    }
1901
    try expect(p, scanner::TokenKind::RParen, "expected `)` after function parameters");
1902
1903
    let mut returnType: ?*ast::Node = nil;
1904
    if consume(p, scanner::TokenKind::Arrow) {
1905
        returnType = try parseType(p);
1906
    }
1907
    let throwList = try parseThrowList(p);
1908
1909
    return ast::FnSig { params, returnType, throwList };
1910
}
1911
1912
/// Parse a function declaration.
1913
fn parseFnDecl(p: *mut Parser, attrs: ?ast::Attributes) -> *ast::Node
1914
    throws (ParseError)
1915
{
1916
    try expect(p, scanner::TokenKind::Fn, "expected `fn`");
1917
1918
    // Method syntax: `fn (recv: *Type) name(params) { body }`.
1919
    if check(p, scanner::TokenKind::LParen) {
1920
        return try parseMethodDecl(p, attrs);
1921
    }
1922
    let name = try parseIdent(p, "expected function name");
1923
    let sig = try parseFnTypeSig(p);
1924
    let mut body: ?*ast::Node = nil;
1925
1926
    if let a = attrs; ast::attributesContains(&a, ast::Attribute::Extern) {
1927
        try expect(p, scanner::TokenKind::Semicolon, "expected `;` after extern function declaration");
1928
    } else {
1929
        body = try parseBlock(p);
1930
    }
1931
    return node(p, ast::NodeValue::FnDecl(
1932
        ast::FnDecl { name, sig, body, attrs }
1933
    ));
1934
}
1935
1936
/// Parse a pointer or slice type.
1937
fn parsePointerType(p: *mut Parser) -> *ast::Node
1938
    throws (ParseError)
1939
{
1940
    try expect(p, scanner::TokenKind::Star, "expected `*`");
1941
    let mutable = consume(p, scanner::TokenKind::Mut);
1942
1943
    if consume(p, scanner::TokenKind::LBracket) {
1944
        let itemType = try parseType(p);
1945
        try expect(p, scanner::TokenKind::RBracket, "expected `]` after slice element type");
1946
1947
        return node(p, ast::NodeValue::TypeSig(
1948
            ast::TypeSig::Slice { itemType, mutable }
1949
        ));
1950
    }
1951
    // Check for `*opaque Trait` or `*mut opaque Trait`.
1952
    if consume(p, scanner::TokenKind::Opaque) {
1953
        if check(p, scanner::TokenKind::Ident) or check(p, scanner::TokenKind::Super) {
1954
            let traitName = try parseTypePath(p);
1955
            return node(p, ast::NodeValue::TypeSig(
1956
                ast::TypeSig::TraitObject { traitName, mutable }
1957
            ));
1958
        }
1959
        // Plain `*opaque`.
1960
        return node(p, ast::NodeValue::TypeSig(
1961
            ast::TypeSig::Pointer {
1962
                valueType: node(p, ast::NodeValue::TypeSig(ast::TypeSig::Opaque)),
1963
                mutable,
1964
            }
1965
        ));
1966
    }
1967
    let valueType = try parseType(p);
1968
1969
    return node(p, ast::NodeValue::TypeSig(
1970
        ast::TypeSig::Pointer { valueType, mutable }
1971
    ));
1972
}
1973
1974
/// Parse an array type.
1975
fn parseArrayType(p: *mut Parser) -> *ast::Node
1976
    throws (ParseError)
1977
{
1978
    try expect(p, scanner::TokenKind::LBracket, "expected `[`");
1979
    let itemType = try parseType(p);
1980
1981
    try expect(p, scanner::TokenKind::Semicolon, "expected `;` in array type");
1982
    let length = try parseExpr(p);
1983
1984
    try expect(p, scanner::TokenKind::RBracket, "expected `]` after array length");
1985
    return node(p, ast::NodeValue::TypeSig(
1986
        ast::TypeSig::Array { itemType, length }
1987
    ));
1988
}
1989
1990
/// Parse a type path: an identifier optionally followed by `::` scope access.
1991
/// Returns an identifier node or a scope access chain.
1992
fn parseTypePath(p: *mut Parser) -> *ast::Node
1993
    throws (ParseError)
1994
{
1995
    let mut path: *ast::Node = undefined;
1996
    if p.current.kind == scanner::TokenKind::Super {
1997
        advance(p);
1998
        path = nodeSuper(p);
1999
    } else {
2000
        path = try parseIdent(p, "expected type identifier");
2001
    }
2002
    while consume(p, scanner::TokenKind::ColonColon) {
2003
        let part = try parseIdent(p, "expected identifier after `::`");
2004
        path = node(p, ast::NodeValue::ScopeAccess(
2005
            ast::Access { parent: path, child: part }
2006
        ));
2007
    }
2008
    return path;
2009
}
2010
2011
/// Parse a type annotation.
2012
pub fn parseType(p: *mut Parser) -> *ast::Node
2013
    throws (ParseError)
2014
{
2015
    match p.current.kind {
2016
        case scanner::TokenKind::Question => {
2017
            advance(p);
2018
            let valueType = try parseType(p);
2019
2020
            return node(p, ast::NodeValue::TypeSig(
2021
                ast::TypeSig::Optional { valueType }
2022
            ));
2023
        }
2024
        case scanner::TokenKind::Star => {
2025
            return try parsePointerType(p);
2026
        }
2027
        case scanner::TokenKind::LBracket => {
2028
            return try parseArrayType(p);
2029
        }
2030
        case scanner::TokenKind::Super, scanner::TokenKind::Ident => {
2031
            let path = try parseTypePath(p);
2032
2033
            return node(p, ast::NodeValue::TypeSig(
2034
                ast::TypeSig::Nominal(path)
2035
            ));
2036
        }
2037
        case scanner::TokenKind::U8 => {
2038
            advance(p);
2039
            return nodeTypeInt(p, 1, ast::Signedness::Unsigned);
2040
        }
2041
        case scanner::TokenKind::U16 => {
2042
            advance(p);
2043
            return nodeTypeInt(p, 2, ast::Signedness::Unsigned);
2044
        }
2045
        case scanner::TokenKind::U32 => {
2046
            advance(p);
2047
            return nodeTypeInt(p, 4, ast::Signedness::Unsigned);
2048
        }
2049
        case scanner::TokenKind::U64 => {
2050
            advance(p);
2051
            return nodeTypeInt(p, 8, ast::Signedness::Unsigned);
2052
        }
2053
        case scanner::TokenKind::I8 => {
2054
            advance(p);
2055
            return nodeTypeInt(p, 1, ast::Signedness::Signed);
2056
        }
2057
        case scanner::TokenKind::I16 => {
2058
            advance(p);
2059
            return nodeTypeInt(p, 2, ast::Signedness::Signed);
2060
        }
2061
        case scanner::TokenKind::I32 => {
2062
            advance(p);
2063
            return nodeTypeInt(p, 4, ast::Signedness::Signed);
2064
        }
2065
        case scanner::TokenKind::I64 => {
2066
            advance(p);
2067
            return nodeTypeInt(p, 8, ast::Signedness::Signed);
2068
        }
2069
        case scanner::TokenKind::Bool => {
2070
            advance(p);
2071
            return node(p, ast::NodeValue::TypeSig(ast::TypeSig::Bool));
2072
        }
2073
        case scanner::TokenKind::Opaque => {
2074
            advance(p);
2075
            return node(p, ast::NodeValue::TypeSig(ast::TypeSig::Opaque));
2076
        }
2077
        case scanner::TokenKind::Fn => {
2078
            return try parseFnType(p);
2079
        }
2080
        else => {
2081
            throw failParsing(p, "expected type");
2082
        }
2083
    }
2084
}
2085
2086
/// Parse a name, optional type, and optional value.
2087
///
2088
/// Used for record field declarations, variable declarations,
2089
/// and record field initializations.
2090
fn parseNameTypeValue(p: *mut Parser) -> NameTypeValue
2091
    throws (ParseError)
2092
{
2093
    let name = try parseIdentOrPlaceholder(p, "expected identifier or `_`");
2094
    let mut type: ?*ast::Node = nil;
2095
    let mut alignment: ?*ast::Node = nil;
2096
    let mut value: ?*ast::Node = nil;
2097
2098
    if consume(p, scanner::TokenKind::Colon) {
2099
        type = try parseType(p);
2100
2101
        if check(p, scanner::TokenKind::Align) {
2102
            alignment = try parseAlign(p);
2103
        }
2104
    }
2105
    if consume(p, scanner::TokenKind::Equal) {
2106
        value = try parseExpr(p);
2107
    }
2108
    return NameTypeValue { name, type, value, alignment };
2109
}
2110
2111
/// Parse a constant declaration.
2112
fn parseConst(p: *mut Parser, attrs: ?ast::Attributes) -> *ast::Node
2113
    throws (ParseError)
2114
{
2115
    try expect(p, scanner::TokenKind::Const, "expected `const`");
2116
2117
    let ident = try parseIdent(p, "expected identifier in const declaration");
2118
    try expect(p, scanner::TokenKind::Colon, "expected `:` after identifier");
2119
2120
    let type = try parseType(p);
2121
    try expect(p, scanner::TokenKind::Equal, "expected `=` in const declaration");
2122
2123
    let value = try parseExpr(p);
2124
2125
    return node(p, ast::NodeValue::ConstDecl(
2126
        ast::ConstDecl { ident, type, value, attrs }
2127
    ));
2128
}
2129
2130
/// Parse a static declaration.
2131
fn parseStatic(p: *mut Parser, attrs: ?ast::Attributes) -> *ast::Node
2132
    throws (ParseError)
2133
{
2134
    try expect(p, scanner::TokenKind::Static, "expected `static`");
2135
2136
    let ident = try parseIdent(p, "expected identifier in static declaration");
2137
    try expect(p, scanner::TokenKind::Colon, "expected `:` after identifier");
2138
2139
    let type = try parseType(p);
2140
    try expect(p, scanner::TokenKind::Equal, "expected `=` in static declaration");
2141
2142
    let value = try parseExpr(p);
2143
2144
    return node(p, ast::NodeValue::StaticDecl(
2145
        ast::StaticDecl { ident, type, value, attrs }
2146
    ));
2147
}
2148
2149
/// Parse a `use` declaration.
2150
fn parseUse(p: *mut Parser, attrs: ?ast::Attributes) -> *ast::Node
2151
    throws (ParseError)
2152
{
2153
    try expect(p, scanner::TokenKind::Use, "expected `use`");
2154
2155
    // Allow `super` or identifier as the first part of the path.
2156
    let mut path: *ast::Node = undefined;
2157
    if consume(p, scanner::TokenKind::Super) {
2158
        path = nodeSuper(p);
2159
    } else {
2160
        path = try parseIdent(p, "expected module name or `super` after `use`");
2161
    }
2162
    while consume(p, scanner::TokenKind::ColonColon) {
2163
        // Check for wildcard import (e.g., `use parser::*`)
2164
        if consume(p, scanner::TokenKind::Star) {
2165
            return node(p, ast::NodeValue::Use(
2166
                ast::Use { path, wildcard: true, attrs }
2167
            ));
2168
        }
2169
        let part = try parseIdent(p, "expected identifier or `*` after `::`");
2170
        path = node(p, ast::NodeValue::ScopeAccess(
2171
            ast::Access { parent: path, child: part }
2172
        ));
2173
    }
2174
    return node(p, ast::NodeValue::Use(
2175
        ast::Use { path, wildcard: false, attrs }
2176
    ));
2177
}
2178
2179
/// Parse a `mod` declaration.
2180
fn parseMod(p: *mut Parser, attrs: ?ast::Attributes) -> *ast::Node
2181
    throws (ParseError)
2182
{
2183
    try expect(p, scanner::TokenKind::Mod, "expected `mod`");
2184
    let name = try parseIdent(p, "expected module name after `mod`");
2185
2186
    return node(p, ast::NodeValue::Mod(
2187
        ast::Mod { name, attrs }
2188
    ));
2189
}
2190
2191
/// Parse a `let case` guard statement.
2192
///
2193
/// Eg. `let case <pattern> = <expr> else { ... };`
2194
/// Eg. `let case <pattern> = <expr> if <guard> else { ... };`
2195
///
2196
/// Expects `let case` tokens to have already been consumed.
2197
fn parseLetCase(p: *mut Parser) -> *ast::Node throws (ParseError) {
2198
    let pattern = try parseMatchPattern(p);
2199
2200
    try expect(p, scanner::TokenKind::Equal, "expected `=` after pattern");
2201
    let expr = try parseCond(p);
2202
2203
    let mut guard: ?*ast::Node = nil;
2204
    if consume(p, scanner::TokenKind::If) {
2205
        guard = try parseCond(p);
2206
    }
2207
2208
    try expect(p, scanner::TokenKind::Else, "expected `else` after pattern");
2209
    let elseBranch = try parseLetElseBranch(p);
2210
2211
    return node(p, ast::NodeValue::LetElse(ast::LetElse {
2212
        pattern: ast::PatternMatch { pattern, scrutinee: expr, guard, kind: ast::PatternKind::Case, mutable: false },
2213
        elseBranch,
2214
    }));
2215
}
2216
2217
/// Parse a `let` binding statement.
2218
///
2219
/// Eg. `let <ident> = <expr>;`
2220
/// Eg. `let <ident> = <expr> else { ... };`
2221
/// Eg. `let mut <ident> = <expr> else { ... };`
2222
/// Eg. `let <ident> = <expr> if <guard> else { ... };`
2223
/// Eg. `mut <ident> = <expr>;`
2224
///
2225
/// Expects `let` or `mut` token to have already been consumed.
2226
fn parseLet(p: *mut Parser, mutable: bool) -> *ast::Node throws (ParseError) {
2227
    let binding = try parseNameTypeValue(p);
2228
    let value = binding.value
2229
        else throw failParsing(p, "expected value initializer");
2230
2231
    // Check for optional `else` clause (let-else).
2232
    if consume(p, scanner::TokenKind::Else) {
2233
        let elseBranch = try parseLetElseBranch(p);
2234
2235
        return node(p, ast::NodeValue::LetElse(ast::LetElse {
2236
            pattern: ast::PatternMatch { pattern: binding.name, scrutinee: value, guard: nil, kind: ast::PatternKind::Binding, mutable },
2237
            elseBranch,
2238
        }));
2239
    }
2240
    return node(p, ast::NodeValue::Let(ast::Let {
2241
        ident: binding.name, type: binding.type, value, alignment: binding.alignment, mutable,
2242
    }));
2243
}
2244
2245
/// Parse a module from source text using the provided arena for node storage.
2246
pub fn parse(sourceLoc: scanner::SourceLoc, input: *[u8], arena: *mut ast::NodeArena, pool: *mut strings::Pool) -> *mut ast::Node
2247
    throws (ParseError)
2248
{
2249
    let mut p = mkParser(sourceLoc, input, arena, pool);
2250
    return try parseModule(&mut p) catch {
2251
        printErrors(&p);
2252
        throw ParseError::UnexpectedToken;
2253
    };
2254
}
2255
2256
/// Parse a complete module into a block of top-level statements.
2257
///
2258
/// This is the main entry point for parsing an entire Radiance source file.
2259
/// The parser must already be initialized with source code.
2260
pub fn parseModule(p: *mut Parser) -> *mut ast::Node
2261
    throws (ParseError)
2262
{
2263
    advance(p); // Set the parser up with a first token.
2264
2265
    let mut blk = mkBlock(p, 512);
2266
    try parseStmtsUntil(p, scanner::TokenKind::Eof, &mut blk);
2267
    consume(p, scanner::TokenKind::Eof);
2268
2269
    return node(p, ast::NodeValue::Block(blk));
2270
}
2271
2272
/// Consume a token of the given kind if present.
2273
pub fn consume(p: *mut Parser, kind: scanner::TokenKind) -> bool {
2274
    if check(p, kind) {
2275
        advance(p);
2276
        return true;
2277
    }
2278
    return false;
2279
}
2280
2281
/// Expect a token of the given kind or report an error.
2282
pub fn expect(p: *mut Parser, kind: scanner::TokenKind, message: *[u8]) -> *[u8]
2283
    throws (ParseError)
2284
{
2285
    if not consume(p, kind) {
2286
        reportError(p, p.current, message);
2287
        throw ParseError::UnexpectedToken;
2288
    }
2289
    return p.previous.source;
2290
}
2291
2292
/// Return a generic expectation message for a delimiter token.
2293
fn listExpectMessage(kind: scanner::TokenKind) -> *[u8] {
2294
    match kind {
2295
        case scanner::TokenKind::LParen => return "expected `(`",
2296
        case scanner::TokenKind::RParen => return "expected `)`",
2297
        case scanner::TokenKind::LBracket => return "expected `[`",
2298
        case scanner::TokenKind::RBracket => return "expected `]`",
2299
        case scanner::TokenKind::LBrace => return "expected `{`",
2300
        case scanner::TokenKind::RBrace => return "expected `}`",
2301
        else => return "expected delimiter",
2302
    }
2303
}
2304
2305
/// Parse a trait declaration.
2306
/// Syntax: `trait Name { fn (*Trait) method(...) -> T; ... }`
2307
fn parseTraitDecl(p: *mut Parser, attrs: ?ast::Attributes) -> *ast::Node
2308
    throws (ParseError)
2309
{
2310
    try expect(p, scanner::TokenKind::Trait, "expected `trait`");
2311
    let name = try parseIdent(p, "expected trait name");
2312
    let supertraits = try parseDerives(p);
2313
    try expect(p, scanner::TokenKind::LBrace, "expected `{` after trait name");
2314
2315
    let mut methods = ast::nodeSlice(p.arena, ast::MAX_TRAIT_METHODS);
2316
    while not check(p, scanner::TokenKind::RBrace) and
2317
          not check(p, scanner::TokenKind::Eof)
2318
    {
2319
        let method = try parseTraitMethodSig(p);
2320
        methods.append(method, p.allocator);
2321
    }
2322
    try expect(p, scanner::TokenKind::RBrace, "expected `}` after trait methods");
2323
2324
    return node(p, ast::NodeValue::TraitDecl { name, supertraits, methods, attrs });
2325
}
2326
2327
/// Parse a trait method signature.
2328
/// Syntax: `fn (*Trait) fnord(<params>) -> ReturnType;`
2329
fn parseTraitMethodSig(p: *mut Parser) -> *ast::Node
2330
    throws (ParseError)
2331
{
2332
    try expect(p, scanner::TokenKind::Fn, "expected `fn`");
2333
    try expect(p, scanner::TokenKind::LParen, "expected `(` before receiver");
2334
2335
    let receiver = try parseType(p);
2336
2337
    try expect(p, scanner::TokenKind::RParen, "expected `)` after receiver");
2338
2339
    let name = try parseIdent(p, "expected method name");
2340
    let sig = try parseFnTypeSig(p);
2341
    try expect(p, scanner::TokenKind::Semicolon, "expected `;` after method signature");
2342
2343
    return node(p, ast::NodeValue::TraitMethodSig { name, receiver, sig });
2344
}
2345
2346
/// Parse an instance block.
2347
/// Syntax: `instance Trait for Type { fn (t: *mut Type) fnord(..) {..} }`
2348
///
2349
/// Instance declarations do not accept attributes (e.g. `pub`).
2350
/// Visibility is determined by the trait declaration itself.
2351
fn parseInstanceDecl(p: *mut Parser) -> *ast::Node
2352
    throws (ParseError)
2353
{
2354
    try expect(p, scanner::TokenKind::Instance, "expected `instance`");
2355
    let traitName = try parseTypePath(p);
2356
    try expect(p, scanner::TokenKind::For, "expected `for` after trait name");
2357
    let targetType = try parseTypePath(p);
2358
    try expect(p, scanner::TokenKind::LBrace, "expected `{` after target type");
2359
2360
    let mut methods = ast::nodeSlice(p.arena, ast::MAX_TRAIT_METHODS);
2361
    while not check(p, scanner::TokenKind::RBrace) and
2362
          not check(p, scanner::TokenKind::Eof)
2363
    {
2364
        try expect(p, scanner::TokenKind::Fn, "expected `fn`");
2365
        let method = try parseMethodDecl(p, nil);
2366
2367
        methods.append(method, p.allocator);
2368
    }
2369
    try expect(p, scanner::TokenKind::RBrace, "expected `}` after instance methods");
2370
2371
    return node(p, ast::NodeValue::InstanceDecl { traitName, targetType, methods });
2372
}
2373
2374
/// Parse a method declaration with a receiver.
2375
/// Syntax: `fn (t: *mut Type) fnord(<params>) -> ReturnType { body }`
2376
///
2377
/// Used both inside `instance` blocks and as standalone methods at the top level.
2378
/// Expects the `fn` token to have already been consumed.
2379
fn parseMethodDecl(p: *mut Parser, attrs: ?ast::Attributes) -> *ast::Node
2380
    throws (ParseError)
2381
{
2382
    try expect(p, scanner::TokenKind::LParen, "expected `(` before receiver");
2383
2384
    let receiverName = try parseIdent(p, "expected receiver name");
2385
    try expect(p, scanner::TokenKind::Colon, "expected `:` after receiver name");
2386
    let receiverType = try parseType(p);
2387
2388
    try expect(p, scanner::TokenKind::RParen, "expected `)` after receiver type");
2389
2390
    let name = try parseIdent(p, "expected method name");
2391
    let sig = try parseFnTypeSig(p);
2392
    let body = try parseBlock(p);
2393
2394
    return node(p, ast::NodeValue::MethodDecl {
2395
        name, receiverName, receiverType, sig, body, attrs,
2396
    });
2397
}
2398
2399
/// Parse a comma-separated list enclosed by the given delimiters.
2400
fn parseList(
2401
    p: *mut Parser,
2402
    open: scanner::TokenKind,
2403
    close: scanner::TokenKind,
2404
    parseItem: fn (*mut Parser) -> *ast::Node throws (ParseError)
2405
) -> *mut [*ast::Node] throws (ParseError) {
2406
    try expect(p, open, listExpectMessage(open));
2407
    let mut items = ast::nodeSlice(p.arena, 8);
2408
2409
    while not check(p, close) {
2410
        let item = try parseItem(p);
2411
        items.append(item, p.allocator);
2412
2413
        if not consume(p, scanner::TokenKind::Comma) {
2414
            break;
2415
        }
2416
    }
2417
    try expect(p, close, listExpectMessage(close));
2418
2419
    return items;
2420
}