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