lib/std/lang/parser/tests.rad 103.7 KiB raw
1
//! Parser tests.
2
3
use std::mem;
4
use std::testing;
5
use std::lang::ast;
6
use std::lang::scanner;
7
use std::lang::strings;
8
9
/// Unified arena size.
10
const ARENA_SIZE: u32 = 2097152;
11
/// Unified arena storage for all AST allocations.
12
static ARENA_STORAGE: [u8; ARENA_SIZE] = undefined;
13
/// String pool.
14
static STRING_POOL: strings::Pool = strings::Pool { table: undefined, count: 0 };
15
16
/// Assert that a node is an identifier with the given name.
17
fn expectIdent(node: *ast::Node, name: *[u8])
18
    throws (testing::TestError)
19
{
20
    let case ast::NodeValue::Ident(n) = node.value
21
        if mem::eq(n, name)
22
        else throw testing::TestError::Failed;
23
}
24
25
/// Assert that a node is a type identifier with the given name.
26
fn expectTypeIdent(node: *ast::Node, name: *[u8])
27
    throws (testing::TestError)
28
{
29
    let case ast::NodeValue::TypeSig(ts) = node.value
30
        else throw testing::TestError::Failed;
31
    let case ast::TypeSig::Nominal(ident) = ts
32
        else throw testing::TestError::Failed;
33
34
    try expectIdent(ident, name);
35
}
36
37
/// Assert that a node is a number literal with the given text.
38
fn expectNumber(node: *ast::Node, text: *[u8])
39
    throws (testing::TestError)
40
{
41
    let case ast::NodeValue::Number(n) = node.value
42
        if mem::eq(n.text, text)
43
        else throw testing::TestError::Failed;
44
}
45
46
/// Assert that a node is a range literal with the given optional bounds.
47
fn expectRangeNumbers(node: *ast::Node, start: ?*[u8], end: ?*[u8])
48
    throws (testing::TestError)
49
{
50
    let case ast::NodeValue::Range(range) = node.value
51
        else throw testing::TestError::Failed;
52
53
    if let text = start {
54
        let startNode = range.start
55
            else throw testing::TestError::Failed;
56
        try expectNumber(startNode, text);
57
    } else {
58
        try testing::expect(range.start == nil);
59
    }
60
    if let text = end {
61
        let endNode = range.end
62
            else throw testing::TestError::Failed;
63
        try expectNumber(endNode, text);
64
    } else {
65
        try testing::expect(range.end == nil);
66
    }
67
}
68
69
/// Parse multiple statements from a string.
70
fn parseStmtsStr(input: *[u8]) -> *ast::Node
71
    throws (testing::TestError)
72
{
73
    let mut arena = ast::nodeArena(&mut ARENA_STORAGE[..]);
74
    let mut parser = super::mkParser(scanner::SourceLoc::String, input, &mut arena, &mut STRING_POOL);
75
    return try super::parseModule(&mut parser) catch {
76
        throw testing::TestError::Failed;
77
    };
78
}
79
80
/// Parse a single type from a string.
81
fn parseTypeStr(input: *[u8]) -> *ast::Node
82
    throws (super::ParseError)
83
{
84
    let mut arena = ast::nodeArena(&mut ARENA_STORAGE[..]);
85
    let mut parser = super::mkParser(scanner::SourceLoc::String, input, &mut arena, &mut STRING_POOL);
86
    super::advance(&mut parser);
87
    let root = try super::parseType(&mut parser);
88
    try super::expect(&mut parser, scanner::TokenKind::Eof, "expected end of type");
89
90
    return root;
91
}
92
93
/// Parse a single expression from a string.
94
pub fn parseExprStr(input: *[u8]) -> *ast::Node
95
    throws (super::ParseError)
96
{
97
    let mut arena = ast::nodeArena(&mut ARENA_STORAGE[..]);
98
    let mut parser = super::mkParser(scanner::SourceLoc::String, input, &mut arena, &mut STRING_POOL);
99
    super::advance(&mut parser);
100
    return try super::parseExpr(&mut parser);
101
}
102
103
/// Parse a single statement from a string.
104
fn parseStmtStr(input: *[u8]) -> *ast::Node
105
    throws (super::ParseError)
106
{
107
    let mut arena = ast::nodeArena(&mut ARENA_STORAGE[..]);
108
    let mut parser = super::mkParser(scanner::SourceLoc::String, input, &mut arena, &mut STRING_POOL);
109
    super::advance(&mut parser);
110
    let root = try super::parseStmt(&mut parser);
111
    while super::consume(&mut parser, scanner::TokenKind::Semicolon) {}
112
    try super::expect(&mut parser, scanner::TokenKind::Eof, "expected end of statement");
113
114
    return root;
115
}
116
117
/// Parse an expression expected to be a number literal and return its payload.
118
fn parseNumberLiteral(text: *[u8]) -> ast::IntLiteral
119
    throws (testing::TestError)
120
{
121
    let mut arena = ast::nodeArena(&mut ARENA_STORAGE[..]);
122
    let mut parser = super::mkParser(scanner::SourceLoc::String, text, &mut arena, &mut STRING_POOL);
123
    super::advance(&mut parser);
124
125
    let node = try! super::parseExpr(&mut parser);
126
127
    if not super::check(&parser, scanner::TokenKind::Eof) {
128
        throw testing::TestError::Failed;
129
    }
130
    let case ast::NodeValue::Number(lit) = node.value
131
        else throw testing::TestError::Failed;
132
133
    return lit;
134
}
135
136
/// Ensure that parsing the supplied literal source fails.
137
fn expectNumberLiteralFail(text: *[u8])
138
    throws (testing::TestError)
139
{
140
    let mut arena = ast::nodeArena(&mut ARENA_STORAGE[..]);
141
    let mut parser = super::mkParser(scanner::SourceLoc::String, text, &mut arena, &mut STRING_POOL);
142
    super::advance(&mut parser);
143
144
    try super::parseExpr(&mut parser) catch {
145
        return;
146
    };
147
    if not super::check(&parser, scanner::TokenKind::Eof) {
148
        return;
149
    }
150
    throw testing::TestError::Failed;
151
}
152
153
/// Assert that a node is a type signature matching the expected type.
154
fn expectType(node: *ast::Node, type: ast::TypeSig)
155
    throws (testing::TestError)
156
{
157
    let case ast::NodeValue::TypeSig(t) = node.value
158
        if (t == type)
159
        else throw testing::TestError::Failed;
160
}
161
162
/// Assert that a node is an integer type with the expected width and sign.
163
fn expectIntType(node: *ast::Node, expectedWidth: u32, expectedSign: ast::Signedness)
164
    throws (testing::TestError)
165
{
166
    let case ast::NodeValue::TypeSig(sig) = node.value
167
        else throw testing::TestError::Failed;
168
169
    let case ast::TypeSig::Integer { width, sign } = sig
170
        else throw testing::TestError::Failed;
171
172
    try testing::expect(width == expectedWidth);
173
    try testing::expect(sign == expectedSign);
174
}
175
176
/// Extract a union variant and verify its name and index.
177
/// Returns the payload's fields slice for further checking with `expectField`.
178
fn expectVariant(varNode: *ast::Node, name: *[u8], index: u32) -> ?*mut [*ast::Node]
179
    throws (testing::TestError)
180
{
181
    let case ast::NodeValue::UnionDeclVariant(v) = varNode.value
182
        else throw testing::TestError::Failed;
183
    try expectIdent(v.name, name);
184
    try testing::expect(v.index == index);
185
    try testing::expect(v.value == nil);
186
187
    let payloadType = v.type else return nil;
188
    let case ast::NodeValue::TypeSig(sig) = payloadType.value
189
        else throw testing::TestError::Failed;
190
    let case ast::TypeSig::Record { fields, .. } = sig
191
        else throw testing::TestError::Failed;
192
193
    return fields;
194
}
195
196
/// Check a record field has the expected name and type signature.
197
fn expectFieldSig(
198
    fields: *mut [*ast::Node], index: u32, name: ?*[u8], sig: ast::TypeSig
199
) throws (testing::TestError) {
200
    let fieldNode = fields[index];
201
    let case ast::NodeValue::RecordField { field, type: fieldType, .. } = fieldNode.value
202
        else throw testing::TestError::Failed;
203
204
    if let expectedName = name {
205
        let actualName = field else throw testing::TestError::Failed;
206
        try expectIdent(actualName, expectedName);
207
    } else {
208
        try testing::expect(field == nil);
209
    }
210
    try expectType(fieldType, sig);
211
}
212
213
/// Assert that a block's first statement is an expression statement with the expected value.
214
fn expectBlockExprStmt(blk: *ast::Node, expected: ast::NodeValue)
215
    throws (testing::TestError)
216
{
217
    let stmt = try getBlockFirstStmt(blk);
218
    let case ast::NodeValue::ExprStmt(expr) = stmt.value
219
        else throw testing::TestError::Failed;
220
221
    if let case ast::NodeValue::Ident(e) = expected {
222
        if let case ast::NodeValue::Ident(a) = expr.value {
223
            if mem::eq(e, a) {
224
                return;
225
            } else {
226
                throw testing::TestError::Failed;
227
            }
228
        }
229
    }
230
    panic "expectBlockExprStmt: comparing values we don't know how to compare";
231
}
232
233
/// Get the first statement from a block node.
234
pub fn getBlockFirstStmt(blk: *ast::Node) -> *ast::Node
235
    throws (testing::TestError)
236
{
237
    let case ast::NodeValue::Block(block) = blk.value
238
        else throw testing::TestError::Failed;
239
240
    if block.statements.len == 0 {
241
        throw testing::TestError::Failed;
242
    }
243
    return block.statements[0];
244
}
245
246
/// Get the last statement from a block node.
247
pub fn getBlockLastStmt(blk: *ast::Node) -> *ast::Node
248
    throws (testing::TestError)
249
{
250
    let case ast::NodeValue::Block(block) = blk.value
251
        else throw testing::TestError::Failed;
252
253
    if block.statements.len == 0 {
254
        throw testing::TestError::Failed;
255
    }
256
    return block.statements[block.statements.len - 1];
257
}
258
259
/// Test parsing boolean literals (`true` and `false`).
260
@test fn testParseBool() throws (testing::TestError) {
261
    let r1 = try! parseExprStr("true");
262
    let case ast::NodeValue::Bool(v1) = r1.value if v1
263
        else throw testing::TestError::Failed;
264
265
    let r2 = try! parseExprStr("false");
266
    let case ast::NodeValue::Bool(v2) = r2.value if not v2
267
        else throw testing::TestError::Failed;
268
}
269
270
/// Test parsing number literals.
271
@test fn testParseNumber() throws (testing::TestError) {
272
    let r1 = try! parseExprStr("4519");
273
    try expectNumber(r1, "4519");
274
}
275
276
/// Verify that decimal literals record magnitude and base metadata.
277
@test fn testParseDecimalLiteralMetadata() throws (testing::TestError) {
278
    let lit = try parseNumberLiteral("1234");
279
    try testing::expect(lit.magnitude == 1234);
280
    try testing::expect(lit.radix == ast::Radix::Decimal);
281
}
282
283
/// Verify that hexadecimal literals record metadata without marking them signed.
284
@test fn testParseNumberMetadata() throws (testing::TestError) {
285
    let lit = try parseNumberLiteral("0xFF");
286
    try testing::expect(lit.magnitude == 0xFF);
287
    try testing::expect(lit.radix == ast::Radix::Hex);
288
    try testing::expect(not lit.signed);
289
    try testing::expect(not lit.negative);
290
}
291
292
/// Verify that binary literals capture their radix.
293
@test fn testParseBinaryLiteralMetadata() throws (testing::TestError) {
294
    let lit = try parseNumberLiteral("0b1010");
295
    try testing::expect(lit.magnitude == 0b1010);
296
    try testing::expect(lit.radix == ast::Radix::Binary);
297
}
298
299
/// Signed literals produced by the scanner keep sign details in metadata.
300
@test fn testParseSignedLiteralMetadata() throws (testing::TestError) {
301
    let literal = try parseNumberLiteral("42");
302
    try testing::expect(not literal.signed);
303
    try testing::expect(not literal.negative);
304
    try testing::expect(literal.magnitude == 42);
305
306
    let neg = try parseNumberLiteral("-99");
307
    try testing::expect(neg.signed);
308
    try testing::expect(neg.negative);
309
    try testing::expect(neg.magnitude == 99);
310
}
311
312
/// Literals with prefixes still parse correctly when explicitly signed.
313
@test fn testParseSignedPrefixedLiteral() throws (testing::TestError) {
314
    let hex = try parseNumberLiteral("+0x2A");
315
    try testing::expect(hex.signed);
316
    try testing::expect(not hex.negative);
317
    try testing::expect(hex.radix == ast::Radix::Hex);
318
    try testing::expect(hex.magnitude == 0x2A);
319
320
    let neg = try parseNumberLiteral("-0x2A");
321
    try testing::expect(neg.signed);
322
    try testing::expect(neg.negative);
323
    try testing::expect(neg.radix == ast::Radix::Hex);
324
    try testing::expect(neg.magnitude == 0x2A);
325
326
    let bin = try parseNumberLiteral("-0b11");
327
    try testing::expect(bin.signed);
328
    try testing::expect(bin.negative);
329
    try testing::expect(bin.radix == ast::Radix::Binary);
330
    try testing::expect(bin.magnitude == 0b11);
331
}
332
333
/// Range expressions parse with explicit start and end bounds.
334
@test fn testParseRangeExpr() throws (testing::TestError) {
335
    let node = try! parseExprStr("0..5");
336
    try expectRangeNumbers(node, "0", "5");
337
}
338
339
/// Range expressions allow a missing end bound.
340
@test fn testParseRangeExprNoEnd() throws (testing::TestError) {
341
    let node = try! parseExprStr("0..");
342
    try expectRangeNumbers(node, "0", nil);
343
}
344
345
/// Range expressions allow a missing start bound.
346
@test fn testParseRangeExprNoStart() throws (testing::TestError) {
347
    let node = try! parseExprStr("..5");
348
    try expectRangeNumbers(node, nil, "5");
349
}
350
351
/// Literals with out-of-range digits for their base are rejected.
352
@test fn testParseInvalidIntLiteral() throws (testing::TestError) {
353
    // 2^64 overflows u64.
354
    try expectNumberLiteralFail("18446744073709551616");
355
    try expectNumberLiteralFail("0x10000000000000000");
356
    try expectNumberLiteralFail("0x1G");
357
    try expectNumberLiteralFail("0b102");
358
    try expectNumberLiteralFail("+0x1G");
359
}
360
361
/// Ensure digit-to-value conversion covers decimal and hex ranges.
362
@test fn testDigitFromAscii() throws (testing::TestError) {
363
    let zero = super::digitFromAscii('0', 10) else throw testing::TestError::Failed;
364
    try testing::expect(zero == 0);
365
366
    let nine = super::digitFromAscii('9', 10) else throw testing::TestError::Failed;
367
    try testing::expect(nine == 9);
368
369
    let lower = super::digitFromAscii('a', 16) else throw testing::TestError::Failed;
370
    try testing::expect(lower == 10);
371
372
    let lowerF = super::digitFromAscii('f', 16) else throw testing::TestError::Failed;
373
    try testing::expect(lowerF == 15);
374
375
    let upper = super::digitFromAscii('A', 16) else throw testing::TestError::Failed;
376
    try testing::expect(upper == 10);
377
378
    let upperF = super::digitFromAscii('F', 16) else throw testing::TestError::Failed;
379
    try testing::expect(upperF == 15);
380
381
    try testing::expect(super::digitFromAscii('g', 16) == nil);
382
    try testing::expect(super::digitFromAscii('_', 10) == nil);
383
}
384
385
/// Test parsing nil literal.
386
@test fn testParseNil() throws (testing::TestError) {
387
    let r1 = try! parseExprStr("nil");
388
    let case ast::NodeValue::Nil = r1.value
389
        else throw testing::TestError::Failed;
390
}
391
392
/// Test parsing undefined literal.
393
@test fn testParseUndefined() throws (testing::TestError) {
394
    let r1 = try! parseExprStr("undefined");
395
    let case ast::NodeValue::Undef = r1.value
396
        else throw testing::TestError::Failed;
397
}
398
399
/// Test parsing character literals.
400
@test fn testParseChar() throws (testing::TestError) {
401
    let r1 = try! parseExprStr("'a'");
402
    let case ast::NodeValue::Char(c1) = r1.value if c1 == 'a'
403
        else throw testing::TestError::Failed;
404
405
    let r2 = try! parseExprStr("'\\n'");
406
    let case ast::NodeValue::Char(c2) = r2.value if c2 == '\n'
407
        else throw testing::TestError::Failed;
408
409
    let r3 = try! parseExprStr("'\\t'");
410
    let case ast::NodeValue::Char(c3) = r3.value if c3 == '\t'
411
        else throw testing::TestError::Failed;
412
}
413
414
/// Test parsing string literals.
415
@test fn testParseString() throws (testing::TestError) {
416
    let r1 = try! parseExprStr("\"hello\"");
417
    let case ast::NodeValue::String(s1) = r1.value if mem::eq(s1, "hello")
418
        else throw testing::TestError::Failed;
419
420
    let r2 = try! parseExprStr("\"\"");
421
    let case ast::NodeValue::String(s2) = r2.value if s2.len == 0
422
        else throw testing::TestError::Failed;
423
}
424
425
/// Test string escape sequence processing.
426
@test fn testParseStringEscape() throws (testing::TestError) {
427
    // Tab and newline.
428
    let r1 = try! parseExprStr("\"hello\\tworld\\n\"");
429
    let case ast::NodeValue::String(s1) = r1.value if s1.len == 12
430
        else throw testing::TestError::Failed;
431
    if s1[5] != '\t' {
432
        throw testing::TestError::Failed;
433
    }
434
    if s1[11] != '\n' {
435
        throw testing::TestError::Failed;
436
    }
437
438
    // Escaped quote.
439
    let r2 = try! parseExprStr("\"\\\"\"");
440
    let case ast::NodeValue::String(s2) = r2.value if s2.len == 1
441
        else throw testing::TestError::Failed;
442
    if s2[0] != '"' {
443
        throw testing::TestError::Failed;
444
    }
445
446
    // Escaped backslash.
447
    let r3 = try! parseExprStr("\"\\\\\"");
448
    let case ast::NodeValue::String(s3) = r3.value if s3.len == 1
449
        else throw testing::TestError::Failed;
450
    if s3[0] != '\\' {
451
        throw testing::TestError::Failed;
452
    }
453
454
    // Mixed escapes.
455
    let r4 = try! parseExprStr("\"a\\nb\\tc\"");
456
    let case ast::NodeValue::String(s4) = r4.value if s4.len == 5
457
        else throw testing::TestError::Failed;
458
    if s4[0] != 'a' {
459
        throw testing::TestError::Failed;
460
    }
461
    if s4[1] != '\n' {
462
        throw testing::TestError::Failed;
463
    }
464
    if s4[2] != 'b' {
465
        throw testing::TestError::Failed;
466
    }
467
    if s4[3] != '\t' {
468
        throw testing::TestError::Failed;
469
    }
470
    if s4[4] != 'c' {
471
        throw testing::TestError::Failed;
472
    }
473
}
474
475
/// Test parsing placeholder/underscore.
476
@test fn testParsePlaceholder() throws (testing::TestError) {
477
    let r1 = try! parseExprStr("_");
478
    let case ast::NodeValue::Placeholder = r1.value
479
        else throw testing::TestError::Failed;
480
}
481
482
/// Test parsing array literals.
483
@test fn testParseArrayLiteral() throws (testing::TestError) {
484
    let r1 = try! parseExprStr("[]");
485
    let case ast::NodeValue::ArrayLit(items1) = r1.value if items1.len == 0
486
        else throw testing::TestError::Failed;
487
488
    let r2 = try! parseExprStr("[1]");
489
    let case ast::NodeValue::ArrayLit(items2) = r2.value if items2.len == 1
490
        else throw testing::TestError::Failed;
491
492
    let r3 = try! parseExprStr("[1, 2, 3]");
493
    let case ast::NodeValue::ArrayLit(items3) = r3.value if items3.len == 3
494
        else throw testing::TestError::Failed;
495
}
496
497
/// Test parsing array repeat literals.
498
@test fn testParseArrayRepeatLiteral() throws (testing::TestError) {
499
    let r1 = try! parseExprStr("[42; 10]");
500
    let case ast::NodeValue::ArrayRepeatLit(a) = r1.value
501
        else throw testing::TestError::Failed;
502
503
    try expectNumber(a.item, "42");
504
    try expectNumber(a.count, "10");
505
}
506
507
/// Test parsing a simple `if` statement without an `else` clause.
508
@test fn testParseIf() throws (testing::TestError) {
509
    let r1 = try parseStmtStr("if condition { body; }") catch {
510
        throw testing::TestError::Failed;
511
    };
512
    let case ast::NodeValue::If(n) = r1.value
513
        else throw testing::TestError::Failed;
514
515
    try expectIdent(n.condition, "condition");
516
    try expectBlockExprStmt(n.thenBranch, ast::NodeValue::Ident("body"));
517
    try testing::expect(n.elseBranch == nil);
518
}
519
520
/// Test parsing an `if-else` statement.
521
@test fn testParseIfElse() throws (testing::TestError) {
522
    let r1 = try! parseStmtStr("if condition { left; } else { right; }") catch {
523
        throw testing::TestError::Failed;
524
    };
525
    let case ast::NodeValue::If(n) = r1.value
526
        else throw testing::TestError::Failed;
527
528
    try expectIdent(n.condition, "condition");
529
    try expectBlockExprStmt(n.thenBranch, ast::NodeValue::Ident("left"));
530
531
    let elseBranch = n.elseBranch
532
        else throw testing::TestError::Failed;
533
534
    try expectBlockExprStmt(elseBranch, ast::NodeValue::Ident("right"));
535
}
536
537
/// Test parsing an `if-else if-else` chain.
538
@test fn testParseIfElseIf() throws (testing::TestError) {
539
    let root = try! parseStmtStr("if x { a; } else if y { b; } else { c; }") catch {
540
        throw testing::TestError::Failed;
541
    };
542
    let case ast::NodeValue::If(top) = root.value
543
        else throw testing::TestError::Failed;
544
545
    try expectIdent(top.condition, "x");
546
    try expectBlockExprStmt(top.thenBranch, ast::NodeValue::Ident("a"));
547
548
    let topElse = top.elseBranch
549
        else throw testing::TestError::Failed;
550
    let nested = try getBlockFirstStmt(topElse);
551
    let case ast::NodeValue::If(inner) = nested.value
552
        else throw testing::TestError::Failed;
553
554
    try expectIdent(inner.condition, "y");
555
    try expectBlockExprStmt(inner.thenBranch, ast::NodeValue::Ident("b"));
556
557
    let innerElse = inner.elseBranch
558
        else throw testing::TestError::Failed;
559
    try expectBlockExprStmt(innerElse, ast::NodeValue::Ident("c"));
560
}
561
562
/// Test parsing a block with multiple statements where the last lacks a semicolon.
563
@test fn testParseBlockMultiStmt() throws (testing::TestError) {
564
    let root = try! parseStmtStr("{ first; second; third }");
565
    let case ast::NodeValue::Block(body) = root.value
566
        else throw testing::TestError::Failed;
567
    try testing::expect(body.statements.len == 3);
568
569
    let firstStmt = body.statements[0];
570
    let case ast::NodeValue::ExprStmt(firstExpr) = firstStmt.value
571
        else throw testing::TestError::Failed;
572
    try expectIdent(firstExpr, "first");
573
574
    let secondStmt = body.statements[1];
575
    let case ast::NodeValue::ExprStmt(secondExpr) = secondStmt.value
576
        else throw testing::TestError::Failed;
577
    try expectIdent(secondExpr, "second");
578
579
    let thirdStmt = body.statements[2];
580
    let case ast::NodeValue::ExprStmt(thirdExpr) = thirdStmt.value
581
        else throw testing::TestError::Failed;
582
    try expectIdent(thirdExpr, "third");
583
}
584
585
/// Test parsing a block that keeps a trailing `;` delimiter.
586
@test fn testParseBlockTrailingSemicolon() throws (testing::TestError) {
587
    let root = try! parseStmtStr("if cond { only; }") catch {
588
        throw testing::TestError::Failed;
589
    };
590
    let case ast::NodeValue::If(node) = root.value
591
        else throw testing::TestError::Failed;
592
593
    let case ast::NodeValue::Block(body) = node.thenBranch.value
594
        else throw testing::TestError::Failed;
595
    try testing::expect(body.statements.len == 1);
596
597
    let stmt = body.statements[0];
598
    let case ast::NodeValue::ExprStmt(expr) = stmt.value
599
        else throw testing::TestError::Failed;
600
    try expectIdent(expr, "only");
601
}
602
603
/// Test that missing delimiters between block statements produce an error.
604
@test fn testParseBlockMissingDelimiter() throws (testing::TestError) {
605
    let parsed: ?*ast::Node =
606
        try? parseStmtStr("if cond { first second }");
607
    try testing::expect(parsed == nil);
608
}
609
610
/// Test parsing a `let` binding without a type annotation.
611
@test fn testParseLet() throws (testing::TestError) {
612
    let r1 = try! parseStmtStr("let x = y;") catch {
613
        throw testing::TestError::Failed;
614
    };
615
    let case ast::NodeValue::Let(n) = r1.value
616
        else throw testing::TestError::Failed;
617
618
    try expectIdent(n.ident, "x");
619
    try expectIdent(n.value, "y");
620
    try testing::expect(not n.mutable);
621
    try testing::expect(n.type == nil);
622
}
623
624
/// Test parsing a `let` binding with a type annotation.
625
@test fn testParseLetTyped() throws (testing::TestError) {
626
    let r1 = try! parseStmtStr("let x: i32 = y;");
627
    let case ast::NodeValue::Let(n) = r1.value
628
        else throw testing::TestError::Failed;
629
630
    try expectIdent(n.ident, "x");
631
    try expectIdent(n.value, "y");
632
    try testing::expect(not n.mutable);
633
634
    let type = n.type
635
        else throw testing::TestError::Failed;
636
    try expectType(type, ast::TypeSig::Integer {
637
        width: 4, sign: ast::Signedness::Signed
638
    });
639
}
640
641
/// Test parsing a `let` binding with alignment modifier.
642
@test fn testParseLetAlign() throws (testing::TestError) {
643
    let r1 = try! parseStmtStr("let x: i32 align(16) = 13;");
644
    let case ast::NodeValue::Let(n) = r1.value
645
        else throw testing::TestError::Failed;
646
647
    try expectIdent(n.ident, "x");
648
    try expectNumber(n.value, "13");
649
    try testing::expect(not n.mutable);
650
651
    let type = n.type
652
        else throw testing::TestError::Failed;
653
    try expectType(type, ast::TypeSig::Integer {
654
        width: 4, sign: ast::Signedness::Signed
655
    });
656
657
    let alignment = n.alignment
658
        else throw testing::TestError::Failed;
659
    let case ast::NodeValue::Align(a) = alignment.value
660
        else throw testing::TestError::Failed;
661
    try expectNumber(a, "16");
662
}
663
664
/// Test parsing let-else statement.
665
@test fn testParseLetElse() throws (testing::TestError) {
666
    let root = try! parseStmtStr("let x = opt else { return };");
667
    let case ast::NodeValue::LetElse(letElse) = root.value
668
        else throw testing::TestError::Failed;
669
670
    try expectIdent(letElse.pattern.pattern, "x");
671
672
    let case ast::NodeValue::Block(elseBlock) = letElse.elseBranch.value
673
        else throw testing::TestError::Failed;
674
    try testing::expect(elseBlock.statements.len == 1);
675
}
676
677
/// Test parsing let-else with single statement.
678
@test fn testParseLetElseSingleStmt() throws (testing::TestError) {
679
    let root = try! parseStmtStr("let y = val else return;");
680
    let case ast::NodeValue::LetElse(letElse) = root.value
681
        else throw testing::TestError::Failed;
682
683
    try expectIdent(letElse.pattern.pattern, "y");
684
685
    let case ast::NodeValue::Return(_) = letElse.elseBranch.value
686
        else throw testing::TestError::Failed;
687
}
688
689
/// Test parsing let-else with expression branch.
690
@test fn testParseLetElseExpr() throws (testing::TestError) {
691
    let root = try! parseStmtStr("let z = opt else y;");
692
    let case ast::NodeValue::LetElse(letElse) = root.value
693
        else throw testing::TestError::Failed;
694
695
    try expectIdent(letElse.pattern.pattern, "z");
696
    try expectIdent(letElse.elseBranch, "y");
697
}
698
699
/// Test parsing let-case-else statement.
700
@test fn testParseLetCaseElse() throws (testing::TestError) {
701
    let root = try! parseStmtStr("let case Variant(x) = opt else { return };");
702
    let case ast::NodeValue::LetElse(letElse) = root.value
703
        else throw testing::TestError::Failed;
704
705
    try testing::expect(letElse.pattern.guard == nil);
706
}
707
708
/// Test parsing let-case-else with guard.
709
@test fn testParseLetCaseElseWithGuard() throws (testing::TestError) {
710
    let root = try! parseStmtStr("let case Variant(x) = opt if x > 0 else { return };");
711
    let case ast::NodeValue::LetElse(letElse) = root.value
712
        else throw testing::TestError::Failed;
713
714
    try testing::expect(letElse.pattern.guard != nil);
715
716
    let guardNode = letElse.pattern.guard else throw testing::TestError::Failed;
717
    let case ast::NodeValue::BinOp(cmp) = guardNode.value
718
        else throw testing::TestError::Failed;
719
    try testing::expect(cmp.op == ast::BinaryOp::Gt);
720
}
721
722
/// Test parsing a `let mut` declaration.
723
@test fn testParseMut() throws (testing::TestError) {
724
    let r1 = try! parseStmtStr("let mut x = 42;");
725
    let case ast::NodeValue::Let(n) = r1.value
726
        else throw testing::TestError::Failed;
727
728
    try expectIdent(n.ident, "x");
729
    try expectNumber(n.value, "42");
730
    try testing::expect(n.mutable);
731
    try testing::expect(n.type == nil);
732
}
733
734
/// Test parsing a `let mut` declaration with type annotation.
735
@test fn testParseMutTyped() throws (testing::TestError) {
736
    let r1 = try! parseStmtStr("let mut x: i32 = 42;");
737
    let case ast::NodeValue::Let(n) = r1.value
738
        else throw testing::TestError::Failed;
739
740
    try expectIdent(n.ident, "x");
741
    try expectNumber(n.value, "42");
742
    try testing::expect(n.mutable);
743
744
    let type = n.type
745
        else throw testing::TestError::Failed;
746
    try expectType(type, ast::TypeSig::Integer {
747
        width: 4, sign: ast::Signedness::Signed
748
    });
749
}
750
751
/// Test parsing a `const` declaration.
752
@test fn testParseConst() throws (testing::TestError) {
753
    let node = try! parseStmtStr("const ANSWER: i32 = 42;");
754
    let case ast::NodeValue::ConstDecl(decl) = node.value
755
        else throw testing::TestError::Failed;
756
757
    try expectIdent(decl.ident, "ANSWER");
758
    try expectType(decl.type, ast::TypeSig::Integer {
759
        width: 4, sign: ast::Signedness::Signed
760
    });
761
    try expectNumber(decl.value, "42");
762
}
763
764
/// Test parsing a `static` declaration.
765
@test fn testParseStatic() throws (testing::TestError) {
766
    let node = try! parseStmtStr("static COUNTER: i32 = 0;");
767
    let case ast::NodeValue::StaticDecl(decl) = node.value
768
        else throw testing::TestError::Failed;
769
770
    try expectIdent(decl.ident, "COUNTER");
771
    try expectType(decl.type, ast::TypeSig::Integer {
772
        width: 4, sign: ast::Signedness::Signed
773
    });
774
    try expectNumber(decl.value, "0");
775
}
776
777
/// Test parsing a `use` declaration.
778
@test fn testParseUse() throws (testing::TestError) {
779
    let node = try! parseStmtStr("use module::item;");
780
    let case ast::NodeValue::Use(decl) = node.value
781
        else throw testing::TestError::Failed;
782
783
    let case ast::NodeValue::ScopeAccess(scope) = decl.path.value
784
        else throw testing::TestError::Failed;
785
786
    try expectIdent(scope.parent, "module");
787
    try expectIdent(scope.child, "item");
788
}
789
790
/// Test parsing a `mod` declaration.
791
@test fn testParseMod() throws (testing::TestError) {
792
    let node = try! parseStmtStr("mod io;");
793
    let case ast::NodeValue::Mod(decl) = node.value
794
        else throw testing::TestError::Failed;
795
796
    try expectIdent(decl.name, "io");
797
    try testing::expect(decl.attrs == nil);
798
}
799
800
/// Test parsing a module declaration with attributes.
801
@test fn testParseModAttributes() throws (testing::TestError) {
802
    let node = try! parseStmtStr("pub mod io;");
803
    let case ast::NodeValue::Mod(decl) = node.value
804
        else throw testing::TestError::Failed;
805
806
    try expectIdent(decl.name, "io");
807
    let attrs = decl.attrs
808
        else throw testing::TestError::Failed;
809
810
    try testing::expect(attrs.list.len == 1);
811
812
    let case ast::NodeValue::Attribute(attr) = attrs.list[0].value
813
        else throw testing::TestError::Failed;
814
815
    try testing::expect(attr == ast::Attribute::Pub);
816
    try testing::expect(ast::attributesContains(&attrs, ast::Attribute::Pub));
817
}
818
819
/// Test parsing an optional type.
820
@test fn testParseTypeOptional() throws (testing::TestError) {
821
    let node = try! parseTypeStr("?i32");
822
    let case ast::NodeValue::TypeSig(optional) = node.value
823
        else throw testing::TestError::Failed;
824
    let case ast::TypeSig::Optional(opt) = optional
825
        else throw testing::TestError::Failed;
826
827
    try expectIntType(opt, 4, ast::Signedness::Signed);
828
}
829
830
/// Test parsing a pointer type, including `mut`.
831
@test fn testParseTypePointer() throws (testing::TestError) {
832
    let node = try! parseTypeStr("*mut i32");
833
    let case ast::NodeValue::TypeSig(sig) = node.value
834
        else throw testing::TestError::Failed;
835
    let case ast::TypeSig::Pointer { valueType, mutable } = sig
836
        else throw testing::TestError::Failed;
837
838
    try expectIntType(valueType, 4, ast::Signedness::Signed);
839
    try testing::expect(mutable);
840
}
841
842
/// Test parsing an immutable pointer type.
843
@test fn testParseTypePointerImmutable() throws (testing::TestError) {
844
    let node = try! parseTypeStr("*i32");
845
    let case ast::NodeValue::TypeSig(sig) = node.value
846
        else throw testing::TestError::Failed;
847
    let case ast::TypeSig::Pointer { valueType, mutable } = sig
848
        else throw testing::TestError::Failed;
849
850
    try expectIntType(valueType, 4, ast::Signedness::Signed);
851
    try testing::expect(not mutable);
852
}
853
854
/// Test parsing a slice type.
855
@test fn testParseTypeSlice() throws (testing::TestError) {
856
    let node = try! parseTypeStr("*[u8]");
857
    let case ast::NodeValue::TypeSig(sig) = node.value
858
        else throw testing::TestError::Failed;
859
    let case ast::TypeSig::Slice { itemType, mutable } = sig
860
        else throw testing::TestError::Failed;
861
862
    try expectIntType(itemType, 1, ast::Signedness::Unsigned);
863
    try testing::expect(not mutable);
864
}
865
866
/// Test parsing a mutable slice type.
867
@test fn testParseTypeSliceMutable() throws (testing::TestError) {
868
    let node = try! parseTypeStr("*mut [u8]");
869
    let case ast::NodeValue::TypeSig(sig) = node.value
870
        else throw testing::TestError::Failed;
871
    let case ast::TypeSig::Slice { itemType, mutable } = sig
872
        else throw testing::TestError::Failed;
873
874
    try expectIntType(itemType, 1, ast::Signedness::Unsigned);
875
    try testing::expect(mutable);
876
}
877
878
/// Test parsing an array type.
879
@test fn testParseTypeArray() throws (testing::TestError) {
880
    let node = try! parseTypeStr("[i32; 4]");
881
    let case ast::NodeValue::TypeSig(sig) = node.value
882
        else throw testing::TestError::Failed;
883
    let case ast::TypeSig::Array { itemType, length } = sig
884
        else throw testing::TestError::Failed;
885
886
    try expectIntType(itemType, 4, ast::Signedness::Signed);
887
    try expectNumber(length, "4");
888
}
889
890
/// Test parsing a named record declaration without derives.
891
@test fn testParseRecordDecl() throws (testing::TestError) {
892
    let node = try! parseStmtStr("record R { x: bool, y: i32 }");
893
    let case ast::NodeValue::RecordDecl(decl) = node.value
894
        else throw testing::TestError::Failed;
895
896
    try expectIdent(decl.name, "R");
897
    try testing::expect(decl.derives.len == 0);
898
    try testing::expect(decl.fields.len == 2);
899
900
    try expectFieldSig(decl.fields, 0, "x", ast::TypeSig::Bool);
901
    try expectFieldSig(decl.fields, 1, "y", ast::TypeSig::Integer {
902
        width: 4,
903
        sign: ast::Signedness::Signed,
904
    });
905
}
906
907
/// Test parsing a record declaration with derives.
908
@test fn testParseRecordDeclDerives() throws (testing::TestError) {
909
    let node = try! parseStmtStr("record R: Eq + Debug { field: i32 }");
910
    let case ast::NodeValue::RecordDecl(decl) = node.value
911
        else throw testing::TestError::Failed;
912
913
    try expectIdent(decl.name, "R");
914
    try testing::expect(decl.derives.len == 2);
915
    try expectIdent(decl.derives[0], "Eq");
916
    try expectIdent(decl.derives[1], "Debug");
917
}
918
919
/// Test parsing a record declaration with field initializers.
920
@test fn testParseRecordDeclFieldDefaults() throws (testing::TestError) {
921
    let node = try! parseStmtStr("record Config { size: opaque = 42, flag: bool = true }");
922
    let case ast::NodeValue::RecordDecl(decl) = node.value
923
        else throw testing::TestError::Failed;
924
925
    try expectIdent(decl.name, "Config");
926
    try testing::expect(decl.derives.len == 0);
927
    try testing::expect(decl.fields.len == 2);
928
929
    try expectFieldSig(decl.fields, 0, "size", ast::TypeSig::Opaque);
930
    try expectFieldSig(decl.fields, 1, "flag", ast::TypeSig::Bool);
931
932
    // Check default values.
933
    let case ast::NodeValue::RecordField { value: val0, .. } = decl.fields[0].value
934
        else throw testing::TestError::Failed;
935
    let v0 = val0 else throw testing::TestError::Failed;
936
    try expectNumber(v0, "42");
937
938
    let case ast::NodeValue::RecordField { value: val1, .. } = decl.fields[1].value
939
        else throw testing::TestError::Failed;
940
    let v1 = val1 else throw testing::TestError::Failed;
941
    let case ast::NodeValue::Bool(flagValue) = v1.value
942
        else throw testing::TestError::Failed;
943
    try testing::expect(flagValue);
944
}
945
946
/// Test parsing an unlabeled record declaration.
947
@test fn testParseTupleRecordDecl() throws (testing::TestError) {
948
    let node = try! parseStmtStr("record Pair(bool, i32);");
949
    let case ast::NodeValue::RecordDecl(decl) = node.value
950
        else throw testing::TestError::Failed;
951
952
    try expectIdent(decl.name, "Pair");
953
    try testing::expect(not decl.labeled);
954
    try testing::expect(decl.derives.len == 0);
955
    try testing::expect(decl.fields.len == 2);
956
957
    try expectFieldSig(decl.fields, 0, nil, ast::TypeSig::Bool);
958
    try expectFieldSig(decl.fields, 1, nil, ast::TypeSig::Integer {
959
        width: 4,
960
        sign: ast::Signedness::Signed,
961
    });
962
}
963
964
/// Test parsing a single-field unlabeled record.
965
@test fn testParseTupleRecordSingleField() throws (testing::TestError) {
966
    let node = try! parseStmtStr("record R(bool);");
967
    let case ast::NodeValue::RecordDecl(decl) = node.value
968
        else throw testing::TestError::Failed;
969
970
    try expectIdent(decl.name, "R");
971
    try testing::expect(not decl.labeled);
972
    try testing::expect(decl.fields.len == 1);
973
974
    try expectFieldSig(decl.fields, 0, nil, ast::TypeSig::Bool);
975
}
976
977
/// Test parsing empty record literals.
978
@test fn testParseEmptyRecordLiteral() throws (testing::TestError) {
979
    let r1 = try! parseExprStr("{}");
980
    let case ast::NodeValue::RecordLit(lit) = r1.value
981
        else throw testing::TestError::Failed;
982
983
    try testing::expect(lit.typeName == nil);
984
    try testing::expect(lit.fields.len == 0);
985
986
    let r2 = try! parseExprStr("Point {}");
987
    let case ast::NodeValue::RecordLit(lit2) = r2.value
988
        else throw testing::TestError::Failed;
989
990
    let typeName = lit2.typeName else throw testing::TestError::Failed;
991
    try expectIdent(typeName, "Point");
992
    try testing::expect(lit2.fields.len == 0);
993
}
994
995
/// Test parsing a function type with parameters and return type.
996
@test fn testParseTypeFn() throws (testing::TestError) {
997
    let node = try! parseTypeStr("fn (i32, *u8) -> bool");
998
    let case ast::NodeValue::TypeSig(sigValue) = node.value
999
        else throw testing::TestError::Failed;
1000
    let case ast::TypeSig::Fn(sig) = sigValue
1001
        else throw testing::TestError::Failed;
1002
1003
    try testing::expect(sig.params.len == 2);
1004
1005
    let param0 = sig.params[0];
1006
    try expectIntType(param0, 4, ast::Signedness::Signed);
1007
1008
    let param1 = sig.params[1];
1009
    let case ast::NodeValue::TypeSig(p1) = param1.value
1010
        else throw testing::TestError::Failed;
1011
    let case ast::TypeSig::Pointer { valueType: ptrTarget, mutable: _ } = p1
1012
        else throw testing::TestError::Failed;
1013
    try expectIntType(ptrTarget, 1, ast::Signedness::Unsigned);
1014
1015
    try testing::expect(sig.returnType != nil);
1016
}
1017
1018
/// Test parsing a function type with a throws clause.
1019
@test fn testParseTypeFnThrows() throws (testing::TestError) {
1020
    let node = try! parseTypeStr("fn (i32) -> bool throws (Error, Other)");
1021
    let case ast::NodeValue::TypeSig(sigValue) = node.value
1022
        else throw testing::TestError::Failed;
1023
    let case ast::TypeSig::Fn(sig) = sigValue
1024
        else throw testing::TestError::Failed;
1025
1026
    try testing::expect(sig.params.len == 1);
1027
    try expectIntType(sig.params[0], 4, ast::Signedness::Signed);
1028
1029
    try testing::expect(sig.throwList.len == 2);
1030
    try expectTypeIdent(sig.throwList[0], "Error");
1031
    try expectTypeIdent(sig.throwList[1], "Other");
1032
1033
    let returnType = sig.returnType
1034
        else throw testing::TestError::Failed;
1035
    try expectType(returnType, ast::TypeSig::Bool);
1036
}
1037
1038
/// Test parsing a function declaration without parameters.
1039
@test fn testParseFnDeclEmpty() throws (testing::TestError) {
1040
    let node = try! parseStmtStr("fn main() {}");
1041
    let case ast::NodeValue::FnDecl(decl) = node.value
1042
        else throw testing::TestError::Failed;
1043
1044
    try expectIdent(decl.name, "main");
1045
    try testing::expect(decl.sig.params.len == 0);
1046
    try testing::expect(decl.sig.returnType == nil);
1047
    try testing::expect(decl.attrs == nil);
1048
1049
    let body = decl.body else throw testing::TestError::Failed;
1050
    let case ast::NodeValue::Block(_) = body.value
1051
        else throw testing::TestError::Failed;
1052
}
1053
1054
/// Test parsing a function declaration with parameters and return type.
1055
@test fn testParseFnDeclParams() throws (testing::TestError) {
1056
    let node = try! parseStmtStr("fn add(x: i32, y: *u8) -> bool {}");
1057
    let case ast::NodeValue::FnDecl(decl) = node.value
1058
        else throw testing::TestError::Failed;
1059
1060
    try expectIdent(decl.name, "add");
1061
    try testing::expect(decl.sig.params.len == 2);
1062
1063
    {
1064
        let param0 = decl.sig.params[0];
1065
        let case ast::NodeValue::FnParam(p0) = param0.value
1066
            else throw testing::TestError::Failed;
1067
        try expectIdent(p0.name, "x");
1068
        try expectIntType(p0.type, 4, ast::Signedness::Signed);
1069
    }
1070
    {
1071
        let param1 = decl.sig.params[1];
1072
        let case ast::NodeValue::FnParam(p1) = param1.value
1073
            else throw testing::TestError::Failed;
1074
        try expectIdent(p1.name, "y");
1075
        let case ast::NodeValue::TypeSig(sig1) = p1.type.value
1076
            else throw testing::TestError::Failed;
1077
        let case ast::TypeSig::Pointer { valueType, .. } = sig1
1078
            else throw testing::TestError::Failed;
1079
        try expectIntType(valueType, 1, ast::Signedness::Unsigned);
1080
    }
1081
    {
1082
        let returnType = decl.sig.returnType
1083
            else throw testing::TestError::Failed;
1084
        try expectType(returnType, ast::TypeSig::Bool);
1085
1086
        let body = decl.body else throw testing::TestError::Failed;
1087
        let case ast::NodeValue::Block(_) = body.value
1088
            else throw testing::TestError::Failed;
1089
    }
1090
}
1091
1092
/// Test parsing a function declaration with a throws clause.
1093
@test fn testParseFnDeclThrows() throws (testing::TestError) {
1094
    let node = try! parseStmtStr("fn handle() throws (Error, Crash) {}");
1095
    let case ast::NodeValue::FnDecl(decl) = node.value
1096
        else throw testing::TestError::Failed;
1097
1098
    try expectIdent(decl.name, "handle");
1099
    try testing::expect(decl.sig.returnType == nil);
1100
1101
    try testing::expect(decl.sig.throwList.len == 2);
1102
    try expectTypeIdent(decl.sig.throwList[0], "Error");
1103
    try expectTypeIdent(decl.sig.throwList[1], "Crash");
1104
1105
    let body = decl.body else throw testing::TestError::Failed;
1106
    let case ast::NodeValue::Block(_) = body.value
1107
        else throw testing::TestError::Failed;
1108
}
1109
1110
/// Test scanning source-level `void` produces an identifier, not a type keyword.
1111
@test fn testParseTypeVoidRejected() throws (testing::TestError) {
1112
    let mut arena = ast::nodeArena(&mut ARENA_STORAGE[..]);
1113
    let mut parser = super::mkParser(scanner::SourceLoc::String, "void", &mut arena, &mut STRING_POOL);
1114
    super::advance(&mut parser);
1115
    try testing::expect(super::check(&parser, scanner::TokenKind::Ident));
1116
}
1117
1118
/// Test parsing a function declaration with attributes.
1119
@test fn testParseFnDeclAttributes() throws (testing::TestError) {
1120
    let node = try! parseStmtStr("pub extern fn run();");
1121
    let case ast::NodeValue::FnDecl(decl) = node.value
1122
        else throw testing::TestError::Failed;
1123
1124
    try expectIdent(decl.name, "run");
1125
1126
    let attrs = decl.attrs
1127
        else throw testing::TestError::Failed;
1128
1129
    try testing::expect(attrs.list.len == 2);
1130
1131
    let case ast::NodeValue::Attribute(attr0) = attrs.list[0].value
1132
        else throw testing::TestError::Failed;
1133
    try testing::expect(attr0 == ast::Attribute::Pub);
1134
1135
    let case ast::NodeValue::Attribute(attr1) = attrs.list[1].value
1136
        else throw testing::TestError::Failed;
1137
    try testing::expect(attr1 == ast::Attribute::Extern);
1138
1139
    try testing::expect(ast::attributesContains(&attrs, ast::Attribute::Pub));
1140
    try testing::expect(ast::attributesContains(&attrs, ast::Attribute::Extern));
1141
    try testing::expect(decl.body == nil);
1142
}
1143
1144
/// Test parsing a scoped identifier type.
1145
@test fn testParseTypeScopedIdent() throws (testing::TestError) {
1146
    let node = try! parseTypeStr("module::Type");
1147
    let case ast::NodeValue::TypeSig(ts) = node.value
1148
        else throw testing::TestError::Failed;
1149
    let case ast::TypeSig::Nominal(name) = ts
1150
        else throw testing::TestError::Failed;
1151
    let case ast::NodeValue::ScopeAccess(access) = name.value
1152
        else throw testing::TestError::Failed;
1153
1154
    try expectIdent(access.parent, "module");
1155
    try expectIdent(access.child, "Type");
1156
}
1157
1158
/// Test parsing the `bool` type.
1159
@test fn testParseTypeBool() throws (testing::TestError) {
1160
    let node = try! parseTypeStr("bool");
1161
    try expectType(node, ast::TypeSig::Bool);
1162
}
1163
1164
1165
/// Test parsing an unsigned integer type.
1166
@test fn testParseTypeUnsigned() throws (testing::TestError) {
1167
    let node = try! parseTypeStr("u8");
1168
    try expectType(node, ast::TypeSig::Integer {
1169
        width: 1,
1170
        sign: ast::Signedness::Unsigned,
1171
    });
1172
}
1173
1174
/// Test parsing a simple `if let` statement without guard or else.
1175
@test fn testParseIfLet() throws (testing::TestError) {
1176
    let root = try! parseStmtStr("if let value = opt { body; }");
1177
    let case ast::NodeValue::IfLet(node) = root.value
1178
        else throw testing::TestError::Failed;
1179
1180
    try expectIdent(node.pattern.pattern, "value");
1181
    try expectIdent(node.pattern.scrutinee, "opt");
1182
1183
    try testing::expect(node.pattern.guard == nil);
1184
    try expectBlockExprStmt(node.thenBranch, ast::NodeValue::Ident("body"));
1185
    try testing::expect(node.elseBranch == nil);
1186
}
1187
1188
/// Test parsing an `if let` statement with guard and else branches.
1189
@test fn testParseIfLetGuardElse() throws (testing::TestError) {
1190
    let root = try! parseStmtStr(
1191
        "if let value = opt; guard { body; } else { alt; }"
1192
    );
1193
    let case ast::NodeValue::IfLet(node) = root.value
1194
        else throw testing::TestError::Failed;
1195
1196
    try expectIdent(node.pattern.pattern, "value");
1197
    try expectIdent(node.pattern.scrutinee, "opt");
1198
1199
    let guard = node.pattern.guard
1200
        else throw testing::TestError::Failed;
1201
    try expectIdent(guard, "guard");
1202
1203
    try expectBlockExprStmt(node.thenBranch, ast::NodeValue::Ident("body"));
1204
1205
    let elseBranch = node.elseBranch
1206
        else throw testing::TestError::Failed;
1207
    try expectBlockExprStmt(elseBranch, ast::NodeValue::Ident("alt"));
1208
}
1209
1210
/// Test parsing an `if let` statement with an `else if` chain.
1211
@test fn testParseIfLetElseIf() throws (testing::TestError) {
1212
    let root = try! parseStmtStr(
1213
        "if let value = opt { body; } else if cond { alt; }"
1214
    );
1215
    let case ast::NodeValue::IfLet(node) = root.value
1216
        else throw testing::TestError::Failed;
1217
1218
    try expectIdent(node.pattern.pattern, "value");
1219
1220
    let elseBranch = node.elseBranch
1221
        else throw testing::TestError::Failed;
1222
1223
    let nested = try getBlockFirstStmt(elseBranch);
1224
    let case ast::NodeValue::If(inner) = nested.value
1225
        else throw testing::TestError::Failed;
1226
1227
    try expectIdent(inner.condition, "cond");
1228
    try expectBlockExprStmt(inner.thenBranch, ast::NodeValue::Ident("alt"));
1229
    try testing::expect(inner.elseBranch == nil);
1230
}
1231
1232
/// Test parsing `if let mut` binding.
1233
@test fn testParseIfLetMut() throws (testing::TestError) {
1234
    let root = try! parseStmtStr("if let mut value = opt { body; }");
1235
    let case ast::NodeValue::IfLet(node) = root.value
1236
        else throw testing::TestError::Failed;
1237
1238
    try expectIdent(node.pattern.pattern, "value");
1239
    try expectIdent(node.pattern.scrutinee, "opt");
1240
    try testing::expect(node.pattern.mutable);
1241
    try testing::expect(node.pattern.guard == nil);
1242
    try expectBlockExprStmt(node.thenBranch, ast::NodeValue::Ident("body"));
1243
    try testing::expect(node.elseBranch == nil);
1244
}
1245
1246
/// Test parsing `let mut ... else` binding.
1247
@test fn testParseLetMutElse() throws (testing::TestError) {
1248
    let root = try! parseStmtStr("let mut x = opt else { return };");
1249
    let case ast::NodeValue::LetElse(letElse) = root.value
1250
        else throw testing::TestError::Failed;
1251
1252
    try expectIdent(letElse.pattern.pattern, "x");
1253
    try testing::expect(letElse.pattern.mutable);
1254
}
1255
1256
/// Test that `if let` without `mut` is not mutable.
1257
@test fn testParseIfLetNotMutable() throws (testing::TestError) {
1258
    let root = try! parseStmtStr("if let value = opt { body; }");
1259
    let case ast::NodeValue::IfLet(node) = root.value
1260
        else throw testing::TestError::Failed;
1261
1262
    try testing::expect(not node.pattern.mutable);
1263
}
1264
1265
/// Test that `let ... else` without `mut` is not mutable.
1266
@test fn testParseLetElseNotMutable() throws (testing::TestError) {
1267
    let root = try! parseStmtStr("let x = opt else { return };");
1268
    let case ast::NodeValue::LetElse(letElse) = root.value
1269
        else throw testing::TestError::Failed;
1270
1271
    try testing::expect(not letElse.pattern.mutable);
1272
}
1273
1274
/// Test parsing a simple `if let case` statement.
1275
@test fn testParseIfCase() throws (testing::TestError) {
1276
    let root = try! parseStmtStr("if let case pat = value { body; }");
1277
    let case ast::NodeValue::IfLet(node) = root.value
1278
        else throw testing::TestError::Failed;
1279
1280
    try expectIdent(node.pattern.pattern, "pat");
1281
    try expectIdent(node.pattern.scrutinee, "value");
1282
    try testing::expect(node.pattern.guard == nil);
1283
    try expectBlockExprStmt(node.thenBranch, ast::NodeValue::Ident("body"));
1284
    try testing::expect(node.elseBranch == nil);
1285
}
1286
1287
/// Test parsing an `if let case` statement with guard and else branches.
1288
@test fn testParseIfCaseGuardElse() throws (testing::TestError) {
1289
    let root = try! parseStmtStr(
1290
        "if let case pat = value; guard { body; } else { alt; }"
1291
    );
1292
    let case ast::NodeValue::IfLet(node) = root.value
1293
        else throw testing::TestError::Failed;
1294
1295
    try expectIdent(node.pattern.pattern, "pat");
1296
    try expectIdent(node.pattern.scrutinee, "value");
1297
1298
    let guard = node.pattern.guard
1299
        else throw testing::TestError::Failed;
1300
    try expectIdent(guard, "guard");
1301
1302
    try expectBlockExprStmt(node.thenBranch, ast::NodeValue::Ident("body"));
1303
1304
    let elseBranch = node.elseBranch
1305
        else throw testing::TestError::Failed;
1306
    try expectBlockExprStmt(elseBranch, ast::NodeValue::Ident("alt"));
1307
}
1308
1309
/// Test parsing an `if let case` statement with an `else if` chain.
1310
@test fn testParseIfCaseElseIf() throws (testing::TestError) {
1311
    let root = try! parseStmtStr(
1312
        "if let case pat = value { body; } else if cond { alt; }"
1313
    );
1314
    let case ast::NodeValue::IfLet(node) = root.value
1315
        else throw testing::TestError::Failed;
1316
1317
    let elseBranch = node.elseBranch
1318
        else throw testing::TestError::Failed;
1319
1320
    let nested = try getBlockFirstStmt(elseBranch);
1321
    let case ast::NodeValue::If(inner) = nested.value
1322
        else throw testing::TestError::Failed;
1323
1324
    try expectIdent(inner.condition, "cond");
1325
    try expectBlockExprStmt(inner.thenBranch, ast::NodeValue::Ident("alt"));
1326
    try testing::expect(inner.elseBranch == nil);
1327
}
1328
1329
/// Test parsing a simple `while` loop without an `else` branch.
1330
@test fn testParseWhile() throws (testing::TestError) {
1331
    let root = try! parseStmtStr("while cond { body; }");
1332
    let case ast::NodeValue::While(loopNode) = root.value
1333
        else throw testing::TestError::Failed;
1334
1335
    try expectIdent(loopNode.condition, "cond");
1336
    try expectBlockExprStmt(loopNode.body, ast::NodeValue::Ident("body"));
1337
    try testing::expect(loopNode.elseBranch == nil);
1338
}
1339
1340
/// Test parsing a `while` loop with an `else` branch.
1341
@test fn testParseWhileElse() throws (testing::TestError) {
1342
    let root = try! parseStmtStr("while cond { body; } else { alt; }");
1343
    let case ast::NodeValue::While(loopNode) = root.value
1344
        else throw testing::TestError::Failed;
1345
1346
    try expectIdent(loopNode.condition, "cond");
1347
    try expectBlockExprStmt(loopNode.body, ast::NodeValue::Ident("body"));
1348
1349
    let elseBranch = loopNode.elseBranch
1350
        else throw testing::TestError::Failed;
1351
    try expectBlockExprStmt(elseBranch, ast::NodeValue::Ident("alt"));
1352
}
1353
1354
/// Test parsing a simple `while let case` loop.
1355
@test fn testParseWhileCase() throws (testing::TestError) {
1356
    let root = try! parseStmtStr("while let case pat = value { body; }");
1357
    let case ast::NodeValue::WhileLet(node) = root.value
1358
        else throw testing::TestError::Failed;
1359
1360
    try expectIdent(node.pattern.pattern, "pat");
1361
    try expectIdent(node.pattern.scrutinee, "value");
1362
    try testing::expect(node.pattern.guard == nil);
1363
    try expectBlockExprStmt(node.body, ast::NodeValue::Ident("body"));
1364
    try testing::expect(node.elseBranch == nil);
1365
}
1366
1367
/// Test parsing a `while let case` loop with guard and else branches.
1368
@test fn testParseWhileCaseGuardElse() throws (testing::TestError) {
1369
    let root = try! parseStmtStr(
1370
        "while let case pat = value; guard { body; } else { alt; }"
1371
    );
1372
    let case ast::NodeValue::WhileLet(node) = root.value
1373
        else throw testing::TestError::Failed;
1374
1375
    let guard = node.pattern.guard
1376
        else throw testing::TestError::Failed;
1377
    try expectIdent(guard, "guard");
1378
1379
    try expectBlockExprStmt(node.body, ast::NodeValue::Ident("body"));
1380
1381
    let elseBranch = node.elseBranch
1382
        else throw testing::TestError::Failed;
1383
    try expectBlockExprStmt(elseBranch, ast::NodeValue::Ident("alt"));
1384
}
1385
1386
/// Test parsing a simple `try` expression without catch.
1387
@test fn testParseTry() throws (testing::TestError) {
1388
    let root = try! parseExprStr("try value");
1389
    let case ast::NodeValue::Try(node) = root.value
1390
        else throw testing::TestError::Failed;
1391
1392
    try expectIdent(node.expr, "value");
1393
    try testing::expect(node.catches.len == 0);
1394
    try testing::expect(not node.shouldPanic);
1395
}
1396
1397
/// Test parsing a `try!` expression that panics on error.
1398
@test fn testParseTryBang() throws (testing::TestError) {
1399
    let root = try! parseExprStr("try! value");
1400
    let case ast::NodeValue::Try(node) = root.value
1401
        else throw testing::TestError::Failed;
1402
1403
    try expectIdent(node.expr, "value");
1404
    try testing::expect(node.catches.len == 0);
1405
    try testing::expect(node.shouldPanic);
1406
}
1407
1408
/// Test parsing a `try` expression with a `catch` block.
1409
@test fn testParseTryCatchBlock() throws (testing::TestError) {
1410
    let root = try! parseExprStr("try value catch { alt; }");
1411
    let case ast::NodeValue::Try(node) = root.value
1412
        else throw testing::TestError::Failed;
1413
1414
    try expectIdent(node.expr, "value");
1415
    try testing::expect(node.catches.len == 1);
1416
1417
    let case ast::NodeValue::CatchClause(clause) = node.catches[0].value
1418
        else throw testing::TestError::Failed;
1419
    try testing::expect(clause.binding == nil);
1420
    try testing::expect(clause.typeNode == nil);
1421
    try expectBlockExprStmt(clause.body, ast::NodeValue::Ident("alt"));
1422
}
1423
1424
/// Test that `catch` without a block is rejected.
1425
@test fn testParseTryCatchExprRejected() throws (testing::TestError) {
1426
    let parsed: ?*ast::Node = try? parseExprStr("try value catch alternate");
1427
    try testing::expect(parsed == nil);
1428
}
1429
1430
/// Test parsing a `break` statement.
1431
@test fn testParseBreak() throws (testing::TestError) {
1432
    let root = try! parseStmtStr("break");
1433
    let case ast::NodeValue::Break= root.value
1434
        else throw testing::TestError::Failed;
1435
}
1436
1437
/// Test parsing a `continue` statement.
1438
@test fn testParseContinue() throws (testing::TestError) {
1439
    let root = try! parseStmtStr("continue");
1440
    let case ast::NodeValue::Continue= root.value
1441
        else throw testing::TestError::Failed;
1442
}
1443
1444
/// Test parsing a `return` statement without value.
1445
@test fn testParseReturnVoid() throws (testing::TestError) {
1446
    let root = try! parseStmtStr("return");
1447
    let case ast::NodeValue::Return(retValue) = root.value
1448
        else throw testing::TestError::Failed;
1449
1450
    try testing::expect(retValue == nil);
1451
}
1452
1453
/// Test parsing a `return` statement with a value.
1454
@test fn testParseReturnValue() throws (testing::TestError) {
1455
    let root = try! parseStmtStr("return result");
1456
    let case ast::NodeValue::Return(retValue) = root.value
1457
        else throw testing::TestError::Failed;
1458
1459
    let value = retValue
1460
        else throw testing::TestError::Failed;
1461
    try expectIdent(value, "result");
1462
}
1463
1464
/// Test parsing a `throw` statement.
1465
@test fn testParseThrow() throws (testing::TestError) {
1466
    let root = try! parseStmtStr("throw error");
1467
    let case ast::NodeValue::Throw(throwExpr) = root.value
1468
        else throw testing::TestError::Failed;
1469
1470
    try expectIdent(throwExpr, "error");
1471
}
1472
1473
/// Test parsing a `panic` statement without a message.
1474
@test fn testParsePanicEmpty() throws (testing::TestError) {
1475
    let root = try! parseStmtStr("panic");
1476
    let case ast::NodeValue::Panic(panicMsg) = root.value
1477
        else throw testing::TestError::Failed;
1478
1479
    try testing::expect(panicMsg == nil);
1480
}
1481
1482
/// Test parsing a `panic` statement with a message.
1483
@test fn testParsePanicMessage() throws (testing::TestError) {
1484
    let root = try! parseStmtStr("panic \"something went wrong\"");
1485
    let case ast::NodeValue::Panic(panicMsg) = root.value
1486
        else throw testing::TestError::Failed;
1487
1488
    let message = panicMsg
1489
        else throw testing::TestError::Failed;
1490
    let case ast::NodeValue::String(msgStr) = message.value if mem::eq(msgStr, "something went wrong")
1491
        else throw testing::TestError::Failed;
1492
}
1493
1494
/// Test parsing a `panic` statement with braces.
1495
@test fn testParsePanicBraces() throws (testing::TestError) {
1496
    let root = try! parseStmtStr("panic { \"error\" }");
1497
    let case ast::NodeValue::Panic(panicMsg) = root.value
1498
        else throw testing::TestError::Failed;
1499
1500
    let message = panicMsg
1501
        else throw testing::TestError::Failed;
1502
    let case ast::NodeValue::String(msgStr) = message.value if mem::eq(msgStr, "error")
1503
        else throw testing::TestError::Failed;
1504
}
1505
1506
/// Test parsing a simple `match` statement with one case.
1507
@test fn testParseMatchSingle() throws (testing::TestError) {
1508
    let root = try! parseStmtStr("match subject { case pattern => body }");
1509
    let case ast::NodeValue::Match(sw) = root.value
1510
        else throw testing::TestError::Failed;
1511
1512
    try expectIdent(sw.subject, "subject");
1513
    try testing::expect(sw.prongs.len == 1);
1514
1515
    let caseNode = sw.prongs[0];
1516
    let case ast::NodeValue::MatchProng(prong) = caseNode.value
1517
        else throw testing::TestError::Failed;
1518
1519
    let case ast::ProngArm::Case(patterns) = prong.arm
1520
        else throw testing::TestError::Failed;
1521
    try testing::expect(patterns.len == 1);
1522
    try expectIdent(patterns[0], "pattern");
1523
    try testing::expect(prong.guard == nil);
1524
1525
    let case ast::NodeValue::ExprStmt(bodyStmt) = prong.body.value
1526
        else throw testing::TestError::Failed;
1527
    let case ast::NodeValue::Ident(name) = bodyStmt.value
1528
        if mem::eq(name, "body")
1529
        else throw testing::TestError::Failed;
1530
}
1531
1532
/// Test parsing a `match` case with guard and multiple patterns.
1533
@test fn testParseMatchGuard() throws (testing::TestError) {
1534
    let root = try! parseStmtStr(
1535
        "match subject { case left, right if cond => handle }"
1536
    );
1537
    let case ast::NodeValue::Match(sw) = root.value
1538
        else throw testing::TestError::Failed;
1539
1540
    try testing::expect(sw.prongs.len == 1);
1541
    let case ast::NodeValue::MatchProng(prong) = sw.prongs[0].value
1542
        else throw testing::TestError::Failed;
1543
1544
    let case ast::ProngArm::Case(patterns) = prong.arm
1545
        else throw testing::TestError::Failed;
1546
    try testing::expect(patterns.len == 2);
1547
    try expectIdent(patterns[0], "left");
1548
    try expectIdent(patterns[1], "right");
1549
1550
    let guard = prong.guard
1551
        else throw testing::TestError::Failed;
1552
    try expectIdent(guard, "cond");
1553
}
1554
1555
/// Test parsing `match` prongs whose bodies omit trailing semicolons.
1556
@test fn testParseMatchReturnNoSemicolon() throws (testing::TestError) {
1557
    let root = try! parseStmtStr(
1558
        "match subject { case First => return, case Second => return }"
1559
    );
1560
    let case ast::NodeValue::Match(sw) = root.value
1561
        else throw testing::TestError::Failed;
1562
1563
    try testing::expect(sw.prongs.len == 2);
1564
1565
    let firstCaseNode = sw.prongs[0];
1566
    let case ast::NodeValue::MatchProng(firstProng) = firstCaseNode.value
1567
        else throw testing::TestError::Failed;
1568
    let case ast::NodeValue::Return(firstRetVal) = firstProng.body.value
1569
        else throw testing::TestError::Failed;
1570
    try testing::expect(firstRetVal == nil);
1571
1572
    let secondCaseNode = sw.prongs[1];
1573
    let case ast::NodeValue::MatchProng(secondProng) = secondCaseNode.value
1574
        else throw testing::TestError::Failed;
1575
    let case ast::NodeValue::Return(secondRetVal) = secondProng.body.value
1576
        else throw testing::TestError::Failed;
1577
    try testing::expect(secondRetVal == nil);
1578
}
1579
1580
/// Test parsing a `match` statement with multiple branches.
1581
@test fn testParseMatchMultipleCases() throws (testing::TestError) {
1582
    let root = try! parseStmtStr(
1583
        "match subject { case First => first, case Second => second }"
1584
    );
1585
    let case ast::NodeValue::Match(sw) = root.value
1586
        else throw testing::TestError::Failed;
1587
1588
    try testing::expect(sw.prongs.len == 2);
1589
    {
1590
        let case ast::NodeValue::MatchProng(prong) = sw.prongs[0].value
1591
            else throw testing::TestError::Failed;
1592
        let case ast::ProngArm::Case(patterns) = prong.arm
1593
            else throw testing::TestError::Failed;
1594
        try testing::expect(patterns.len == 1);
1595
        try expectIdent(patterns[0], "First");
1596
        let case ast::NodeValue::ExprStmt(stmt) = prong.body.value
1597
            else throw testing::TestError::Failed;
1598
        let case ast::NodeValue::Ident(val) = stmt.value
1599
            if mem::eq(val, "first")
1600
            else throw testing::TestError::Failed;
1601
    } {
1602
        let case ast::NodeValue::MatchProng(prong) = sw.prongs[1].value
1603
            else throw testing::TestError::Failed;
1604
        let case ast::ProngArm::Case(pats) = prong.arm
1605
            else throw testing::TestError::Failed;
1606
1607
        try testing::expect(pats.len == 1);
1608
        try expectIdent(pats[0], "Second");
1609
1610
        let case ast::NodeValue::ExprStmt(stmt) = prong.body.value
1611
            else throw testing::TestError::Failed;
1612
        let case ast::NodeValue::Ident(val) = stmt.value
1613
            if mem::eq(val, "second")
1614
            else throw testing::TestError::Failed;
1615
    }
1616
}
1617
1618
/// Test parsing a `match` case whose body is a block.
1619
@test fn testParseMatchProngBlock() throws (testing::TestError) {
1620
    let root = try! parseStmtStr("match subject { case Pattern => { body; } }");
1621
    let case ast::NodeValue::Match(sw) = root.value
1622
        else throw testing::TestError::Failed;
1623
1624
    try testing::expect(sw.prongs.len == 1);
1625
    let case ast::NodeValue::MatchProng(prong) = sw.prongs[0].value
1626
        else throw testing::TestError::Failed;
1627
    try expectBlockExprStmt(prong.body, ast::NodeValue::Ident("body"));
1628
}
1629
1630
/// Test parsing a `match` statement with an `else` case.
1631
@test fn testParseMatchElse() throws (testing::TestError) {
1632
    let root = try! parseStmtStr("match subject { else => body }");
1633
    let case ast::NodeValue::Match(sw) = root.value
1634
        else throw testing::TestError::Failed;
1635
1636
    try testing::expect(sw.prongs.len == 1);
1637
    let case ast::NodeValue::MatchProng(prong) = sw.prongs[0].value
1638
        else throw testing::TestError::Failed;
1639
    // Else prong has no pattern.
1640
    let case ast::ProngArm::Else = prong.arm
1641
        else throw testing::TestError::Failed;
1642
    try testing::expect(prong.guard == nil);
1643
1644
    let case ast::NodeValue::ExprStmt(bodyStmt) = prong.body.value
1645
        else throw testing::TestError::Failed;
1646
    let case ast::NodeValue::Ident(name) = bodyStmt.value
1647
        if mem::eq(name, "body")
1648
        else throw testing::TestError::Failed;
1649
}
1650
1651
/// Test parsing a `match` statement with a binding prong.
1652
@test fn testParseMatchBinding() throws (testing::TestError) {
1653
    let root = try! parseStmtStr("match subject { x => body }");
1654
    let case ast::NodeValue::Match(sw) = root.value
1655
        else throw testing::TestError::Failed;
1656
1657
    try testing::expect(sw.prongs.len == 1);
1658
    let case ast::NodeValue::MatchProng(prong) = sw.prongs[0].value
1659
        else throw testing::TestError::Failed;
1660
    // Binding prong has single identifier pattern.
1661
    let case ast::ProngArm::Binding(pat) = prong.arm
1662
        else throw testing::TestError::Failed;
1663
    try expectIdent(pat, "x");
1664
    try testing::expect(prong.guard == nil);
1665
1666
    let case ast::NodeValue::ExprStmt(bodyStmt) = prong.body.value
1667
        else throw testing::TestError::Failed;
1668
    try expectIdent(bodyStmt, "body");
1669
}
1670
1671
/// Test parsing a `match` statement with a guarded binding prong.
1672
@test fn testParseMatchBindingGuard() throws (testing::TestError) {
1673
    let root = try! parseStmtStr("match subject { x if x > 0 => body }");
1674
    let case ast::NodeValue::Match(sw) = root.value
1675
        else throw testing::TestError::Failed;
1676
1677
    try testing::expect(sw.prongs.len == 1);
1678
    let case ast::NodeValue::MatchProng(prong) = sw.prongs[0].value
1679
        else throw testing::TestError::Failed;
1680
    // Binding prong has single identifier pattern.
1681
    let case ast::ProngArm::Binding(pat) = prong.arm
1682
        else throw testing::TestError::Failed;
1683
    try expectIdent(pat, "x");
1684
1685
    let guard = prong.guard else throw testing::TestError::Failed;
1686
    let case ast::NodeValue::BinOp(binop) = guard.value
1687
        else throw testing::TestError::Failed;
1688
    try testing::expect(binop.op == ast::BinaryOp::Gt);
1689
}
1690
1691
/// Test parsing a `match` statement with a `_` wildcard.
1692
@test fn testParseMatchWildcard() throws (testing::TestError) {
1693
    let root = try! parseStmtStr("match subject { _ => body }");
1694
    let case ast::NodeValue::Match(sw) = root.value
1695
        else throw testing::TestError::Failed;
1696
1697
    try testing::expect(sw.prongs.len == 1);
1698
    let case ast::NodeValue::MatchProng(prong) = sw.prongs[0].value
1699
        else throw testing::TestError::Failed;
1700
    // Wildcard binding prong has single placeholder pattern.
1701
    let case ast::ProngArm::Binding(pat) = prong.arm
1702
        else throw testing::TestError::Failed;
1703
    let case ast::NodeValue::Placeholder = pat.value
1704
        else throw testing::TestError::Failed;
1705
    try testing::expect(prong.guard == nil);
1706
1707
    let case ast::NodeValue::ExprStmt(bodyStmt) = prong.body.value
1708
        else throw testing::TestError::Failed;
1709
    try expectIdent(bodyStmt, "body");
1710
}
1711
1712
/// Test parsing a `match` statement with a guarded `_` wildcard.
1713
@test fn testParseMatchWildcardGuard() throws (testing::TestError) {
1714
    let root = try! parseStmtStr("match subject { _ if cond => body }");
1715
    let case ast::NodeValue::Match(sw) = root.value
1716
        else throw testing::TestError::Failed;
1717
1718
    try testing::expect(sw.prongs.len == 1);
1719
    let case ast::NodeValue::MatchProng(prong) = sw.prongs[0].value
1720
        else throw testing::TestError::Failed;
1721
    // Guarded wildcard binding prong has single placeholder pattern.
1722
    let case ast::ProngArm::Binding(pat) = prong.arm
1723
        else throw testing::TestError::Failed;
1724
    let case ast::NodeValue::Placeholder = pat.value
1725
        else throw testing::TestError::Failed;
1726
1727
    let guard = prong.guard else throw testing::TestError::Failed;
1728
    try expectIdent(guard, "cond");
1729
    let case ast::NodeValue::ExprStmt(bodyStmt) = prong.body.value
1730
        else throw testing::TestError::Failed;
1731
    try expectIdent(bodyStmt, "body");
1732
}
1733
1734
/// Test parsing a `while let` loop with guard and else branches.
1735
@test fn testParseWhileLet() throws (testing::TestError) {
1736
    let root = try! parseStmtStr(
1737
        "while let value = opt; guard { body; } else { alt; }"
1738
    );
1739
    let case ast::NodeValue::WhileLet(loopNode) = root.value
1740
        else throw testing::TestError::Failed;
1741
1742
    try expectIdent(loopNode.pattern.pattern, "value");
1743
    try expectIdent(loopNode.pattern.scrutinee, "opt");
1744
1745
    let guard = loopNode.pattern.guard
1746
        else throw testing::TestError::Failed;
1747
    try expectIdent(guard, "guard");
1748
1749
    try expectBlockExprStmt(loopNode.body, ast::NodeValue::Ident("body"));
1750
1751
    let elseBranch = loopNode.elseBranch
1752
        else throw testing::TestError::Failed;
1753
    try expectBlockExprStmt(elseBranch, ast::NodeValue::Ident("alt"));
1754
}
1755
1756
/// Test parsing a simple `loop` statement.
1757
@test fn testParseLoop() throws (testing::TestError) {
1758
    let root = try! parseStmtStr("loop { body; }");
1759
    let case ast::NodeValue::Loop(loopBody) = root.value
1760
        else throw testing::TestError::Failed;
1761
1762
    try expectBlockExprStmt(loopBody, ast::NodeValue::Ident("body"));
1763
}
1764
1765
/// Test parsing a `for` loop without index or else branches.
1766
@test fn testParseFor() throws (testing::TestError) {
1767
    let root = try! parseStmtStr("for item in items { body; }");
1768
    let case ast::NodeValue::For(loopNode) = root.value
1769
        else throw testing::TestError::Failed;
1770
1771
    try expectIdent(loopNode.binding, "item");
1772
    try testing::expect(loopNode.index == nil);
1773
1774
    try expectIdent(loopNode.iterable, "items");
1775
    try expectBlockExprStmt(loopNode.body, ast::NodeValue::Ident("body"));
1776
    try testing::expect(loopNode.elseBranch == nil);
1777
}
1778
1779
/// Test parsing a `for` loop over a range expression.
1780
@test fn testParseForRangeIterable() throws (testing::TestError) {
1781
    let root = try! parseStmtStr("for item in 0..5 {}");
1782
    let case ast::NodeValue::For(loopNode) = root.value
1783
        else throw testing::TestError::Failed;
1784
1785
    try expectIdent(loopNode.binding, "item");
1786
    try testing::expect(loopNode.index == nil);
1787
    try expectRangeNumbers(loopNode.iterable, "0", "5");
1788
1789
    let case ast::NodeValue::Block(body) = loopNode.body.value
1790
        else throw testing::TestError::Failed;
1791
    try testing::expect(body.statements.len == 0);
1792
    try testing::expect(loopNode.elseBranch == nil);
1793
}
1794
1795
/// Test parsing a `for` loop with index and else branches.
1796
@test fn testParseForIndexElse() throws (testing::TestError) {
1797
    let root = try! parseStmtStr(
1798
        "for value, idx in items { body; } else { alt; }"
1799
    );
1800
    let case ast::NodeValue::For(loopNode) = root.value
1801
        else throw testing::TestError::Failed;
1802
1803
    try expectIdent(loopNode.binding, "value");
1804
1805
    let index = loopNode.index
1806
        else throw testing::TestError::Failed;
1807
    try expectIdent(index, "idx");
1808
1809
    try expectIdent(loopNode.iterable, "items");
1810
    try expectBlockExprStmt(loopNode.body, ast::NodeValue::Ident("body"));
1811
1812
    let elseBranch = loopNode.elseBranch
1813
        else throw testing::TestError::Failed;
1814
    try expectBlockExprStmt(elseBranch, ast::NodeValue::Ident("alt"));
1815
}
1816
1817
/// Test parsing field access expression.
1818
@test fn testParseFieldAccess() throws (testing::TestError) {
1819
    let root = try! parseExprStr("obj.field");
1820
    let case ast::NodeValue::FieldAccess(access) = root.value
1821
        else throw testing::TestError::Failed;
1822
1823
    try expectIdent(access.parent, "obj");
1824
    try expectIdent(access.child, "field");
1825
}
1826
1827
/// Test parsing scope access expression.
1828
@test fn testParseScopeAccess() throws (testing::TestError) {
1829
    let root = try! parseExprStr("module::item");
1830
    let case ast::NodeValue::ScopeAccess(access) = root.value
1831
        else throw testing::TestError::Failed;
1832
1833
    try expectIdent(access.parent, "module");
1834
    try expectIdent(access.child, "item");
1835
}
1836
1837
/// Test parsing array subscript expression.
1838
@test fn testParseArraySubscript() throws (testing::TestError) {
1839
    let root = try! parseExprStr("array[index]");
1840
    let case ast::NodeValue::Subscript { container, index } = root.value
1841
        else throw testing::TestError::Failed;
1842
1843
    try expectIdent(container, "array");
1844
    try expectIdent(index, "index");
1845
}
1846
1847
/// Test parsing array slicing expressions.
1848
@test fn testParseArraySlicing() throws (testing::TestError) {
1849
    // Test `array[start..end]`.
1850
    {
1851
        let expr = try! parseExprStr("array[1..10]");
1852
        let case ast::NodeValue::Subscript { container: subContainer, index: subIndex } = expr.value
1853
            else throw testing::TestError::Failed;
1854
        try expectIdent(subContainer, "array");
1855
1856
        let case ast::NodeValue::Range(range) = subIndex.value
1857
            else throw testing::TestError::Failed;
1858
        let start = range.start
1859
            else throw testing::TestError::Failed;
1860
        let end = range.end
1861
            else throw testing::TestError::Failed;
1862
        try expectNumber(start, "1");
1863
        try expectNumber(end, "10");
1864
    }
1865
    // Test `array[start..]`.
1866
    {
1867
        let expr = try! parseExprStr("array[5..]");
1868
        let case ast::NodeValue::Subscript { container: subContainer, index: subIndex } = expr.value
1869
            else throw testing::TestError::Failed;
1870
        try expectIdent(subContainer, "array");
1871
1872
        let case ast::NodeValue::Range(range) = subIndex.value
1873
            else throw testing::TestError::Failed;
1874
        let start = range.start
1875
            else throw testing::TestError::Failed;
1876
        try expectNumber(start, "5");
1877
        try testing::expect(range.end == nil);
1878
    }
1879
    // Test `array[..end]`.
1880
    {
1881
        let expr = try! parseExprStr("array[..10]");
1882
        let case ast::NodeValue::Subscript { container: subContainer, index: subIndex } = expr.value
1883
            else throw testing::TestError::Failed;
1884
        try expectIdent(subContainer, "array");
1885
1886
        let case ast::NodeValue::Range(range) = subIndex.value
1887
            else throw testing::TestError::Failed;
1888
        try testing::expect(range.start == nil);
1889
        let end = range.end
1890
            else throw testing::TestError::Failed;
1891
        try expectNumber(end, "10");
1892
    }
1893
    // Test `array[..]`.
1894
    {
1895
        let expr = try! parseExprStr("array[..]");
1896
        let case ast::NodeValue::Subscript { container: subContainer, index: subIndex } = expr.value
1897
            else throw testing::TestError::Failed;
1898
        try expectIdent(subContainer, "array");
1899
1900
        let case ast::NodeValue::Range(range) = subIndex.value
1901
            else throw testing::TestError::Failed;
1902
        try testing::expect(range.start == nil);
1903
        try testing::expect(range.end == nil);
1904
    }
1905
}
1906
1907
/// Test parsing function call expression.
1908
@test fn testParseFunctionCall() throws (testing::TestError) {
1909
    let root = try! parseExprStr("func(x, y)");
1910
    let case ast::NodeValue::Call(call) = root.value
1911
        else throw testing::TestError::Failed;
1912
1913
    try expectIdent(call.callee, "func");
1914
    try testing::expect(call.args.len == 2);
1915
    try expectIdent(call.args[0], "x");
1916
    try expectIdent(call.args[1], "y");
1917
}
1918
1919
/// Test parsing chained postfix operators.
1920
@test fn testParseChainedPostfix() throws (testing::TestError) {
1921
    let root = try! parseExprStr("obj.method(arg)[0]");
1922
    let case ast::NodeValue::Subscript { container: subContainer, index: subIndex } = root.value
1923
        else throw testing::TestError::Failed;
1924
1925
    let case ast::NodeValue::Call(call) = subContainer.value
1926
        else throw testing::TestError::Failed;
1927
1928
    let case ast::NodeValue::FieldAccess(fieldAccess) = call.callee.value
1929
        else throw testing::TestError::Failed;
1930
1931
    try expectIdent(fieldAccess.parent, "obj");
1932
    try expectIdent(fieldAccess.child, "method");
1933
    try testing::expect(call.args.len == 1);
1934
    try expectIdent(call.args[0], "arg");
1935
}
1936
1937
/// Test parsing a literal cast using `as`.
1938
@test fn testParseAsCastLiteral() throws (testing::TestError) {
1939
    let root = try! parseExprStr("1 as i32");
1940
    let case ast::NodeValue::As(asExpr) = root.value
1941
        else throw testing::TestError::Failed;
1942
1943
    let case ast::NodeValue::Number(_) = asExpr.value.value
1944
        else throw testing::TestError::Failed;
1945
1946
    try expectIntType(asExpr.type, 4, ast::Signedness::Signed);
1947
}
1948
1949
/// Test parsing a cast following chained postfix expressions.
1950
@test fn testParseAsCastWithPostfix() throws (testing::TestError) {
1951
    let root = try! parseExprStr("value.method(arg) as u32");
1952
    let case ast::NodeValue::As(asExpr) = root.value
1953
        else throw testing::TestError::Failed;
1954
1955
    let case ast::NodeValue::Call(call) = asExpr.value.value
1956
        else throw testing::TestError::Failed;
1957
1958
    let case ast::NodeValue::FieldAccess(access) = call.callee.value
1959
        else throw testing::TestError::Failed;
1960
1961
    try expectIdent(access.parent, "value");
1962
    try expectIdent(access.child, "method");
1963
    try testing::expect(call.args.len == 1);
1964
    try expectIdent(call.args[0], "arg");
1965
    try expectIntType(asExpr.type, 4, ast::Signedness::Unsigned);
1966
}
1967
1968
/// Test parsing @sizeOf builtin.
1969
@test fn testParseBuiltinSizeOf() throws (testing::TestError) {
1970
    let expr = try! parseExprStr("@sizeOf(i32)");
1971
    let case ast::NodeValue::BuiltinCall { kind: builtinKind, args: builtinArgs } = expr.value
1972
        else throw testing::TestError::Failed;
1973
1974
    try testing::expect(builtinKind == ast::Builtin::SizeOf);
1975
    try testing::expect(builtinArgs.len == 1);
1976
    try expectType(builtinArgs[0], ast::TypeSig::Integer {
1977
        width: 4,
1978
        sign: ast::Signedness::Signed,
1979
    });
1980
}
1981
1982
/// Test parsing @alignOf builtin.
1983
@test fn testParseBuiltinAlignOf() throws (testing::TestError) {
1984
    let expr = try! parseExprStr("@alignOf(i32)");
1985
    let case ast::NodeValue::BuiltinCall { kind: builtinKind, args: builtinArgs } = expr.value
1986
        else throw testing::TestError::Failed;
1987
1988
    try testing::expect(builtinKind == ast::Builtin::AlignOf);
1989
    try testing::expect(builtinArgs.len == 1);
1990
    try expectType(builtinArgs[0], ast::TypeSig::Integer {
1991
        width: 4,
1992
        sign: ast::Signedness::Signed,
1993
    });
1994
}
1995
1996
/// Test parsing @sliceOf with varying argument counts.
1997
@test fn testParseBuiltinSliceOf() throws (testing::TestError) {
1998
    // Two arguments.
1999
    {
2000
        let expr = try! parseExprStr("@sliceOf(ptr, len)");
2001
        let case ast::NodeValue::BuiltinCall { kind: builtinKind, args: builtinArgs } = expr.value
2002
            else throw testing::TestError::Failed;
2003
        try testing::expect(builtinKind == ast::Builtin::SliceOf);
2004
        try testing::expect(builtinArgs.len == 2);
2005
    }
2006
    // One argument.
2007
    {
2008
        let expr = try! parseExprStr("@sliceOf(ptr)");
2009
        let case ast::NodeValue::BuiltinCall { kind: builtinKind, args: builtinArgs } = expr.value
2010
            else throw testing::TestError::Failed;
2011
        try testing::expect(builtinKind == ast::Builtin::SliceOf);
2012
        try testing::expect(builtinArgs.len == 1);
2013
    }
2014
    // Three arguments.
2015
    {
2016
        let expr = try! parseExprStr("@sliceOf(ptr, len, extra)");
2017
        let case ast::NodeValue::BuiltinCall { kind: builtinKind, args: builtinArgs } = expr.value
2018
            else throw testing::TestError::Failed;
2019
        try testing::expect(builtinKind == ast::Builtin::SliceOf);
2020
        try testing::expect(builtinArgs.len == 3);
2021
    }
2022
}
2023
2024
/// Test parsing prefix unary operators.
2025
@test fn testParseUnaryOperators() throws (testing::TestError) {
2026
    {
2027
        let notExpr = try! parseExprStr("not flag");
2028
        let case ast::NodeValue::UnOp(notNode) = notExpr.value
2029
            else throw testing::TestError::Failed;
2030
        try testing::expect(notNode.op == ast::UnaryOp::Not);
2031
        try expectIdent(notNode.value, "flag");
2032
    }
2033
    {
2034
        let negExpr = try! parseExprStr("-value");
2035
        let case ast::NodeValue::UnOp(negNode) = negExpr.value
2036
            else throw testing::TestError::Failed;
2037
        try testing::expect(negNode.op == ast::UnaryOp::Neg);
2038
        try expectIdent(negNode.value, "value");
2039
    }
2040
    {
2041
        let bitNotExpr = try! parseExprStr("~mask");
2042
        let case ast::NodeValue::UnOp(bitNotNode) = bitNotExpr.value
2043
            else throw testing::TestError::Failed;
2044
        try testing::expect(bitNotNode.op == ast::UnaryOp::BitNot);
2045
        try expectIdent(bitNotNode.value, "mask");
2046
    }
2047
}
2048
2049
/// Test parsing dereference expressions.
2050
@test fn testParseDereference() throws (testing::TestError) {
2051
    {
2052
        let derefExpr = try! parseExprStr("*ptr");
2053
        let case ast::NodeValue::Deref(target) = derefExpr.value
2054
            else throw testing::TestError::Failed;
2055
        try expectIdent(target, "ptr");
2056
    }
2057
    {
2058
        let derefField = try! parseExprStr("*ptr.field");
2059
        let case ast::NodeValue::Deref(target) = derefField.value
2060
            else throw testing::TestError::Failed;
2061
        let case ast::NodeValue::FieldAccess(access) = target.value
2062
            else throw testing::TestError::Failed;
2063
        try expectIdent(access.parent, "ptr");
2064
        try expectIdent(access.child, "field");
2065
    }
2066
}
2067
2068
/// Test parsing reference (address-of) expressions.
2069
@test fn testParseReferences() throws (testing::TestError) {
2070
    {
2071
        let refExpr = try! parseExprStr("&foo");
2072
        let case ast::NodeValue::AddressOf(refNode) = refExpr.value
2073
            else throw testing::TestError::Failed;
2074
        try testing::expect(refNode.mutable == false);
2075
        try expectIdent(refNode.target, "foo");
2076
    }
2077
    {
2078
        let mutRefExpr = try! parseExprStr("&mut bar");
2079
        let case ast::NodeValue::AddressOf(mutRefNode) = mutRefExpr.value
2080
            else throw testing::TestError::Failed;
2081
        try testing::expect(mutRefNode.mutable == true);
2082
        try expectIdent(mutRefNode.target, "bar");
2083
    }
2084
    {
2085
        let refFieldExpr = try! parseExprStr("&obj.field");
2086
        let case ast::NodeValue::AddressOf(refFieldNode) = refFieldExpr.value
2087
            else throw testing::TestError::Failed;
2088
        try testing::expect(refFieldNode.mutable == false);
2089
        let case ast::NodeValue::FieldAccess(access) = refFieldNode.target.value
2090
            else throw testing::TestError::Failed;
2091
        try expectIdent(access.parent, "obj");
2092
        try expectIdent(access.child, "field");
2093
    }
2094
    {
2095
        let mutRefFieldExpr = try! parseExprStr("&mut obj.field");
2096
        let case ast::NodeValue::AddressOf(mutRefFieldNode) = mutRefFieldExpr.value
2097
            else throw testing::TestError::Failed;
2098
        try testing::expect(mutRefFieldNode.mutable == true);
2099
        let case ast::NodeValue::FieldAccess(access) = mutRefFieldNode.target.value
2100
            else throw testing::TestError::Failed;
2101
        try expectIdent(access.parent, "obj");
2102
        try expectIdent(access.child, "field");
2103
    }
2104
}
2105
2106
/// Test unary operator precedence relative to binary and postfix expressions.
2107
@test fn testParseUnaryPrecedence() throws (testing::TestError) {
2108
    {
2109
        let expr = try! parseExprStr("not a and b");
2110
        let case ast::NodeValue::BinOp(bin) = expr.value
2111
            else throw testing::TestError::Failed;
2112
        try testing::expect(bin.op == ast::BinaryOp::And);
2113
        let case ast::NodeValue::UnOp(leftUnary) = bin.left.value
2114
            else throw testing::TestError::Failed;
2115
        try testing::expect(leftUnary.op == ast::UnaryOp::Not);
2116
        try expectIdent(leftUnary.value, "a");
2117
        try expectIdent(bin.right, "b");
2118
    }
2119
    {
2120
        let mulExpr = try! parseExprStr("-x * y");
2121
        let case ast::NodeValue::BinOp(mul) = mulExpr.value
2122
            else throw testing::TestError::Failed;
2123
        try testing::expect(mul.op == ast::BinaryOp::Mul);
2124
        let case ast::NodeValue::UnOp(leftNeg) = mul.left.value
2125
            else throw testing::TestError::Failed;
2126
        try testing::expect(leftNeg.op == ast::UnaryOp::Neg);
2127
        try expectIdent(leftNeg.value, "x");
2128
        try expectIdent(mul.right, "y");
2129
    }
2130
    {
2131
        let callExpr = try! parseExprStr("not func()");
2132
        let case ast::NodeValue::UnOp(callNot) = callExpr.value
2133
            else throw testing::TestError::Failed;
2134
        try testing::expect(callNot.op == ast::UnaryOp::Not);
2135
        let case ast::NodeValue::Call(call) = callNot.value.value
2136
            else throw testing::TestError::Failed;
2137
        try expectIdent(call.callee, "func");
2138
    }
2139
}
2140
2141
/// Test parsing assignment expressions.
2142
@test fn testParseAssignment() throws (testing::TestError) {
2143
    {
2144
        let assign = try! parseStmtStr("x = 1;");
2145
        let case ast::NodeValue::Assign(node) = assign.value
2146
            else throw testing::TestError::Failed;
2147
        try expectIdent(node.left, "x");
2148
        let case ast::NodeValue::Number(_) = node.right.value
2149
            else throw testing::TestError::Failed;
2150
    }
2151
    {
2152
        let assign = try! parseStmtStr("obj.field = value;");
2153
        let case ast::NodeValue::Assign(node) = assign.value
2154
            else throw testing::TestError::Failed;
2155
        let case ast::NodeValue::FieldAccess(access) = node.left.value
2156
            else throw testing::TestError::Failed;
2157
        try expectIdent(access.parent, "obj");
2158
        try expectIdent(access.child, "field");
2159
        try expectIdent(node.right, "value");
2160
    }
2161
    {
2162
        let assign = try! parseStmtStr("*ptr = rhs;");
2163
        let case ast::NodeValue::Assign(node) = assign.value
2164
            else throw testing::TestError::Failed;
2165
        let case ast::NodeValue::Deref(target) = node.left.value
2166
            else throw testing::TestError::Failed;
2167
        try expectIdent(target, "ptr");
2168
        try expectIdent(node.right, "rhs");
2169
    }
2170
    {
2171
        let assign = try! parseStmtStr("x = 1 + 2;");
2172
        let case ast::NodeValue::Assign(node) = assign.value
2173
            else throw testing::TestError::Failed;
2174
        let case ast::NodeValue::BinOp(bin) = node.right.value
2175
            else throw testing::TestError::Failed;
2176
        try testing::expect(bin.op == ast::BinaryOp::Add);
2177
    }
2178
}
2179
2180
/// Test parsing basic arithmetic binary operators (+, -, *, /, %).
2181
@test fn testParseBinOpArithmetic() throws (testing::TestError) {
2182
    let add = try! parseExprStr("a + b");
2183
    let case ast::NodeValue::BinOp(op1) = add.value
2184
        else throw testing::TestError::Failed;
2185
    try testing::expect(op1.op == ast::BinaryOp::Add);
2186
    try expectIdent(op1.left, "a");
2187
    try expectIdent(op1.right, "b");
2188
2189
    let sub = try! parseExprStr("x - y");
2190
    let case ast::NodeValue::BinOp(op2) = sub.value
2191
        else throw testing::TestError::Failed;
2192
    try testing::expect(op2.op == ast::BinaryOp::Sub);
2193
2194
    let mul = try! parseExprStr("a * b");
2195
    let case ast::NodeValue::BinOp(op3) = mul.value
2196
        else throw testing::TestError::Failed;
2197
    try testing::expect(op3.op == ast::BinaryOp::Mul);
2198
2199
    let div = try! parseExprStr("x / y");
2200
    let case ast::NodeValue::BinOp(op4) = div.value
2201
        else throw testing::TestError::Failed;
2202
    try testing::expect(op4.op == ast::BinaryOp::Div);
2203
2204
    let modOp = try! parseExprStr("a % b");
2205
    let case ast::NodeValue::BinOp(op5) = modOp.value
2206
        else throw testing::TestError::Failed;
2207
    try testing::expect(op5.op == ast::BinaryOp::Mod);
2208
}
2209
2210
/// Test parsing comparison binary operators (==, !=).
2211
@test fn testParseBinOpEq() throws (testing::TestError) {
2212
    let eq = try! parseExprStr("a == b");
2213
    let case ast::NodeValue::BinOp(op1) = eq.value
2214
        else throw testing::TestError::Failed;
2215
    try testing::expect(op1.op == ast::BinaryOp::Eq);
2216
2217
    let ne = try! parseExprStr("x != y");
2218
    let case ast::NodeValue::BinOp(op2) = ne.value
2219
        else throw testing::TestError::Failed;
2220
    try testing::expect(op2.op == ast::BinaryOp::Ne);
2221
}
2222
2223
/// Test parsing comparison binary operators.
2224
@test fn testParseBinOpGtLt() throws (testing::TestError) {
2225
    let lt = try! parseExprStr("a < b");
2226
    let case ast::NodeValue::BinOp(op1) = lt.value
2227
        else throw testing::TestError::Failed;
2228
    try testing::expect(op1.op == ast::BinaryOp::Lt);
2229
2230
    let gt = try! parseExprStr("x > y");
2231
    let case ast::NodeValue::BinOp(op2) = gt.value
2232
        else throw testing::TestError::Failed;
2233
    try testing::expect(op2.op == ast::BinaryOp::Gt);
2234
2235
    let lte = try! parseExprStr("a <= b");
2236
    let case ast::NodeValue::BinOp(op3) = lte.value
2237
        else throw testing::TestError::Failed;
2238
    try testing::expect(op3.op == ast::BinaryOp::Lte);
2239
2240
    let gte = try! parseExprStr("x >= y");
2241
    let case ast::NodeValue::BinOp(op4) = gte.value
2242
        else throw testing::TestError::Failed;
2243
    try testing::expect(op4.op == ast::BinaryOp::Gte);
2244
}
2245
2246
/// Test parsing bitwise binary operators (&, |, ^, <<, >>).
2247
@test fn testParseBinOpBitwise() throws (testing::TestError) {
2248
    let bitAnd = try! parseExprStr("a & b");
2249
    let case ast::NodeValue::BinOp(op1) = bitAnd.value
2250
        else throw testing::TestError::Failed;
2251
    try testing::expect(op1.op == ast::BinaryOp::BitAnd);
2252
2253
    let bitOr = try! parseExprStr("x | y");
2254
    let case ast::NodeValue::BinOp(op2) = bitOr.value
2255
        else throw testing::TestError::Failed;
2256
    try testing::expect(op2.op == ast::BinaryOp::BitOr);
2257
2258
    let bitXor = try! parseExprStr("a ^ b");
2259
    let case ast::NodeValue::BinOp(op3) = bitXor.value
2260
        else throw testing::TestError::Failed;
2261
    try testing::expect(op3.op == ast::BinaryOp::BitXor);
2262
2263
    let shl = try! parseExprStr("x << y");
2264
    let case ast::NodeValue::BinOp(op4) = shl.value
2265
        else throw testing::TestError::Failed;
2266
    try testing::expect(op4.op == ast::BinaryOp::Shl);
2267
2268
    let shr = try! parseExprStr("a >> b");
2269
    let case ast::NodeValue::BinOp(op5) = shr.value
2270
        else throw testing::TestError::Failed;
2271
    try testing::expect(op5.op == ast::BinaryOp::Shr);
2272
}
2273
2274
/// Test parsing logical binary operators (and, or).
2275
@test fn testParseBinOpLogical() throws (testing::TestError) {
2276
    let andOp = try! parseExprStr("a and b");
2277
    let case ast::NodeValue::BinOp(op1) = andOp.value
2278
        else throw testing::TestError::Failed;
2279
    try testing::expect(op1.op == ast::BinaryOp::And);
2280
    try expectIdent(op1.left, "a");
2281
    try expectIdent(op1.right, "b");
2282
2283
    let orOp = try! parseExprStr("x or y");
2284
    let case ast::NodeValue::BinOp(op2) = orOp.value
2285
        else throw testing::TestError::Failed;
2286
    try testing::expect(op2.op == ast::BinaryOp::Or);
2287
    try expectIdent(op2.left, "x");
2288
    try expectIdent(op2.right, "y");
2289
}
2290
2291
/// Test operator precedence: multiplication before addition.
2292
@test fn testParseBinOpPrecedenceMulAdd() throws (testing::TestError) {
2293
    let root = try! parseExprStr("a + b * c");
2294
    let case ast::NodeValue::BinOp(add) = root.value
2295
        else throw testing::TestError::Failed;
2296
2297
    try testing::expect(add.op == ast::BinaryOp::Add);
2298
    try expectIdent(add.left, "a");
2299
2300
    let case ast::NodeValue::BinOp(mul) = add.right.value
2301
        else throw testing::TestError::Failed;
2302
2303
    try testing::expect(mul.op == ast::BinaryOp::Mul);
2304
    try expectIdent(mul.left, "b");
2305
    try expectIdent(mul.right, "c");
2306
}
2307
2308
/// Test operator precedence: shifts before bitwise operations.
2309
@test fn testParseBinOpPrecedenceShiftBitwise() throws (testing::TestError) {
2310
    let root = try! parseExprStr("a & b << c");
2311
    let case ast::NodeValue::BinOp(bitAnd) = root.value
2312
        else throw testing::TestError::Failed;
2313
2314
    try testing::expect(bitAnd.op == ast::BinaryOp::BitAnd);
2315
    try expectIdent(bitAnd.left, "a");
2316
2317
    let case ast::NodeValue::BinOp(shl) = bitAnd.right.value
2318
        else throw testing::TestError::Failed;
2319
2320
    try testing::expect(shl.op == ast::BinaryOp::Shl);
2321
    try expectIdent(shl.left, "b");
2322
    try expectIdent(shl.right, "c");
2323
}
2324
2325
/// Test operator precedence: comparison before logical AND.
2326
@test fn testParseBinOpPrecedenceCompareLogical() throws (testing::TestError) {
2327
    let root = try! parseExprStr("a < b and c > d");
2328
    let case ast::NodeValue::BinOp(andOp) = root.value
2329
        else throw testing::TestError::Failed;
2330
2331
    try testing::expect(andOp.op == ast::BinaryOp::And);
2332
2333
    let case ast::NodeValue::BinOp(lt) = andOp.left.value
2334
        else throw testing::TestError::Failed;
2335
    try testing::expect(lt.op == ast::BinaryOp::Lt);
2336
    try expectIdent(lt.left, "a");
2337
    try expectIdent(lt.right, "b");
2338
2339
    let case ast::NodeValue::BinOp(gt) = andOp.right.value
2340
        else throw testing::TestError::Failed;
2341
    try testing::expect(gt.op == ast::BinaryOp::Gt);
2342
    try expectIdent(gt.left, "c");
2343
    try expectIdent(gt.right, "d");
2344
}
2345
2346
/// Test left associativity of addition.
2347
@test fn testParseBinOpAssociativityAdd() throws (testing::TestError) {
2348
    let root = try! parseExprStr("a + b + c");
2349
    let case ast::NodeValue::BinOp(add2) = root.value
2350
        else throw testing::TestError::Failed;
2351
2352
    try testing::expect(add2.op == ast::BinaryOp::Add);
2353
    try expectIdent(add2.right, "c");
2354
2355
    let case ast::NodeValue::BinOp(add1) = add2.left.value
2356
        else throw testing::TestError::Failed;
2357
    try testing::expect(add1.op == ast::BinaryOp::Add);
2358
    try expectIdent(add1.left, "a");
2359
    try expectIdent(add1.right, "b");
2360
}
2361
2362
/// Test complex expression with multiple operators and precedence.
2363
@test fn testParseBinOpComplex() throws (testing::TestError) {
2364
    let root = try! parseExprStr("a + b * c - d / e");
2365
    let case ast::NodeValue::BinOp(sub) = root.value
2366
        else throw testing::TestError::Failed;
2367
2368
    try testing::expect(sub.op == ast::BinaryOp::Sub);
2369
2370
    let case ast::NodeValue::BinOp(add) = sub.left.value
2371
        else throw testing::TestError::Failed;
2372
    try testing::expect(add.op == ast::BinaryOp::Add);
2373
    try expectIdent(add.left, "a");
2374
2375
    let case ast::NodeValue::BinOp(mul) = add.right.value
2376
        else throw testing::TestError::Failed;
2377
    try testing::expect(mul.op == ast::BinaryOp::Mul);
2378
2379
    let case ast::NodeValue::BinOp(div) = sub.right.value
2380
        else throw testing::TestError::Failed;
2381
    try testing::expect(div.op == ast::BinaryOp::Div);
2382
}
2383
2384
/// Test binary operators with parentheses override precedence.
2385
@test fn testParseBinOpParentheses() throws (testing::TestError) {
2386
    let root = try! parseExprStr("(a + b) * c");
2387
    let case ast::NodeValue::BinOp(mul) = root.value
2388
        else throw testing::TestError::Failed;
2389
2390
    try testing::expect(mul.op == ast::BinaryOp::Mul);
2391
    try expectIdent(mul.right, "c");
2392
2393
    let case ast::NodeValue::BinOp(add) = mul.left.value
2394
        else throw testing::TestError::Failed;
2395
    try testing::expect(add.op == ast::BinaryOp::Add);
2396
    try expectIdent(add.left, "a");
2397
    try expectIdent(add.right, "b");
2398
}
2399
2400
/// Test parsing a simple union without payloads.
2401
@test fn testParseEnumSimple() throws (testing::TestError) {
2402
    let node = try! parseStmtStr("union Color { Red, Green, Blue }");
2403
    let case ast::NodeValue::UnionDecl(decl) = node.value
2404
        else throw testing::TestError::Failed;
2405
2406
    try expectIdent(decl.name, "Color");
2407
    try testing::expect(decl.derives.len == 0);
2408
2409
    let variants = decl.variants;
2410
    try testing::expect(variants.len == 3);
2411
2412
    let v0 = variants[0];
2413
    let case ast::NodeValue::UnionDeclVariant(var0) = v0.value
2414
        else throw testing::TestError::Failed;
2415
    try expectIdent(var0.name, "Red");
2416
    try testing::expect(var0.index == 0);
2417
    try testing::expect(var0.type == nil);
2418
    try testing::expect(var0.value == nil);
2419
2420
    let v1 = variants[1];
2421
    let case ast::NodeValue::UnionDeclVariant(var1) = v1.value
2422
        else throw testing::TestError::Failed;
2423
    try expectIdent(var1.name, "Green");
2424
    try testing::expect(var1.index == 1);
2425
    try testing::expect(var1.type == nil);
2426
    try testing::expect(var1.value == nil);
2427
2428
    let v2 = variants[2];
2429
    let case ast::NodeValue::UnionDeclVariant(var2) = v2.value
2430
        else throw testing::TestError::Failed;
2431
    try expectIdent(var2.name, "Blue");
2432
    try testing::expect(var2.index == 2);
2433
    try testing::expect(var2.type == nil);
2434
    try testing::expect(var2.value == nil);
2435
}
2436
2437
/// Test parsing a union with trailing comma.
2438
@test fn testParseEnumTrailingComma() throws (testing::TestError) {
2439
    let node = try! parseStmtStr("union Letter { A, B, C, }");
2440
    let case ast::NodeValue::UnionDecl(decl) = node.value
2441
        else throw testing::TestError::Failed;
2442
2443
    try expectIdent(decl.name, "Letter");
2444
    try testing::expect(decl.variants.len == 3);
2445
}
2446
2447
/// Test parsing a union with explicit values.
2448
@test fn testParseEnumExplicitValues() throws (testing::TestError) {
2449
    let node = try! parseStmtStr("union Status { Ok = 0, Error = 1, Pending = 5 }");
2450
    let case ast::NodeValue::UnionDecl(decl) = node.value
2451
        else throw testing::TestError::Failed;
2452
2453
    try expectIdent(decl.name, "Status");
2454
2455
    let variants = decl.variants;
2456
    try testing::expect(variants.len == 3);
2457
2458
    let v0 = variants[0];
2459
    let case ast::NodeValue::UnionDeclVariant(var0) = v0.value
2460
        else throw testing::TestError::Failed;
2461
    try expectIdent(var0.name, "Ok");
2462
    try testing::expect(var0.index == 0);
2463
    try testing::expect(var0.type == nil);
2464
    try testing::expect(var0.value != nil);
2465
2466
    let v1 = variants[1];
2467
    let case ast::NodeValue::UnionDeclVariant(var1) = v1.value
2468
        else throw testing::TestError::Failed;
2469
    try expectIdent(var1.name, "Error");
2470
    try testing::expect(var1.index == 1);
2471
    try testing::expect(var1.value != nil);
2472
2473
    let v2 = variants[2];
2474
    let case ast::NodeValue::UnionDeclVariant(var2) = v2.value
2475
        else throw testing::TestError::Failed;
2476
    try expectIdent(var2.name, "Pending");
2477
    try testing::expect(var2.index == 2);
2478
    try testing::expect(var2.value != nil);
2479
}
2480
2481
/// Test parsing a union with payload and tag-only variants.
2482
@test fn testParseEnumWithPayloads() throws (testing::TestError) {
2483
    let node = try! parseStmtStr("union Result { Ok(bool), Error }");
2484
    let case ast::NodeValue::UnionDecl(decl) = node.value
2485
        else throw testing::TestError::Failed;
2486
2487
    try expectIdent(decl.name, "Result");
2488
    try testing::expect(decl.variants.len == 2);
2489
2490
    let okFields = try expectVariant(decl.variants[0], "Ok", 0)
2491
        else throw testing::TestError::Failed;
2492
    try testing::expect(okFields.len == 1);
2493
    try expectFieldSig(okFields, 0, nil, ast::TypeSig::Bool);
2494
2495
    let errFields = try expectVariant(decl.variants[1], "Error", 1);
2496
    try testing::expect(errFields == nil);
2497
}
2498
2499
/// Test parsing a union with derives.
2500
@test fn testParseEnumWithDerives() throws (testing::TestError) {
2501
    let node = try! parseStmtStr("union Option: Debug + Eq { None, Some(i32) }");
2502
    let case ast::NodeValue::UnionDecl(decl) = node.value
2503
        else throw testing::TestError::Failed;
2504
2505
    try expectIdent(decl.name, "Option");
2506
    try testing::expect(decl.derives.len == 2);
2507
    try expectIdent(decl.derives[0], "Debug");
2508
    try expectIdent(decl.derives[1], "Eq");
2509
2510
    let variants = decl.variants;
2511
    try testing::expect(variants.len == 2);
2512
2513
    let v0 = variants[0];
2514
    let case ast::NodeValue::UnionDeclVariant(var0) = v0.value
2515
        else throw testing::TestError::Failed;
2516
    try expectIdent(var0.name, "None");
2517
    try testing::expect(var0.type == nil);
2518
2519
    let v1 = variants[1];
2520
    let case ast::NodeValue::UnionDeclVariant(var1) = v1.value
2521
        else throw testing::TestError::Failed;
2522
    try expectIdent(var1.name, "Some");
2523
    try testing::expect(var1.type != nil);
2524
}
2525
2526
/// Test parsing named record literals with named fields.
2527
@test fn testParseNamedRecordLiteralNamed() throws (testing::TestError) {
2528
    let r1 = try! parseExprStr("Point { x: 5, y: 10 }");
2529
    let case ast::NodeValue::RecordLit(lit) = r1.value
2530
        else throw testing::TestError::Failed;
2531
2532
    let typeName = lit.typeName else throw testing::TestError::Failed;
2533
    try expectIdent(typeName, "Point");
2534
    try testing::expect(lit.fields.len == 2);
2535
2536
    let field0 = lit.fields[0];
2537
    let case ast::NodeValue::RecordLitField(arg0) = field0.value
2538
        else throw testing::TestError::Failed;
2539
    let label0 = arg0.label else throw testing::TestError::Failed;
2540
    try expectIdent(label0, "x");
2541
    try expectNumber(arg0.value, "5");
2542
}
2543
2544
/// Test parsing anonymous record literals with named fields.
2545
@test fn testParseAnonymousRecordLiteralNamed() throws (testing::TestError) {
2546
    let r1 = try! parseExprStr("{ x: 10, y: 20 }");
2547
    let case ast::NodeValue::RecordLit(lit) = r1.value
2548
        else throw testing::TestError::Failed;
2549
2550
    try testing::expect(lit.typeName == nil);
2551
    try testing::expect(lit.fields.len == 2);
2552
2553
    let field0 = lit.fields[0];
2554
    let case ast::NodeValue::RecordLitField(arg0) = field0.value
2555
        else throw testing::TestError::Failed;
2556
    let label0 = arg0.label else throw testing::TestError::Failed;
2557
    try expectIdent(label0, "x");
2558
    try expectNumber(arg0.value, "10");
2559
2560
    let field1 = lit.fields[1];
2561
    let case ast::NodeValue::RecordLitField(arg1) = field1.value
2562
        else throw testing::TestError::Failed;
2563
    let label1 = arg1.label else throw testing::TestError::Failed;
2564
    try expectIdent(label1, "y");
2565
    try expectNumber(arg1.value, "20");
2566
}
2567
2568
/// Test parsing record literals with shorthand field syntax.
2569
/// `{ x, y }` is equivalent to `{ x: x, y: y }`.
2570
@test fn testParseRecordLiteralShorthand() throws (testing::TestError) {
2571
    let r1 = try! parseExprStr("Point { x, y }");
2572
    let case ast::NodeValue::RecordLit(lit) = r1.value
2573
        else throw testing::TestError::Failed;
2574
2575
    let typeName = lit.typeName else throw testing::TestError::Failed;
2576
    try expectIdent(typeName, "Point");
2577
    try testing::expect(lit.fields.len == 2);
2578
2579
    // First field: shorthand `x`.
2580
    let field0 = lit.fields[0];
2581
    let case ast::NodeValue::RecordLitField(arg0) = field0.value
2582
        else throw testing::TestError::Failed;
2583
    let label0 = arg0.label else throw testing::TestError::Failed;
2584
    try expectIdent(label0, "x");
2585
    try expectIdent(arg0.value, "x");
2586
    // Label and value should point to the same node.
2587
    try testing::expect(label0 == arg0.value);
2588
2589
    // Second field: shorthand `y`.
2590
    let field1 = lit.fields[1];
2591
    let case ast::NodeValue::RecordLitField(arg1) = field1.value
2592
        else throw testing::TestError::Failed;
2593
    let label1 = arg1.label else throw testing::TestError::Failed;
2594
    try expectIdent(label1, "y");
2595
    try expectIdent(arg1.value, "y");
2596
    try testing::expect(label1 == arg1.value);
2597
}
2598
2599
/// Test parsing record literals with mixed shorthand and explicit fields.
2600
@test fn testParseRecordLiteralMixedShorthand() throws (testing::TestError) {
2601
    let r1 = try! parseExprStr("Point { x, y: 10 }");
2602
    let case ast::NodeValue::RecordLit(lit) = r1.value
2603
        else throw testing::TestError::Failed;
2604
2605
    try testing::expect(lit.fields.len == 2);
2606
2607
    // First field: shorthand `x`.
2608
    let field0 = lit.fields[0];
2609
    let case ast::NodeValue::RecordLitField(arg0) = field0.value
2610
        else throw testing::TestError::Failed;
2611
    let label0 = arg0.label else throw testing::TestError::Failed;
2612
    try expectIdent(label0, "x");
2613
    try expectIdent(arg0.value, "x");
2614
2615
    // Second field: explicit `y: 10`.
2616
    let field1 = lit.fields[1];
2617
    let case ast::NodeValue::RecordLitField(arg1) = field1.value
2618
        else throw testing::TestError::Failed;
2619
    let label1 = arg1.label else throw testing::TestError::Failed;
2620
    try expectIdent(label1, "y");
2621
    try expectNumber(arg1.value, "10");
2622
}
2623
2624
/// Test that positional brace initializers are rejected: `{ 1, 2 }`.
2625
@test fn testParsePositionalBraceInitializerAnonymous() throws (testing::TestError) {
2626
    let parsed: ?*ast::Node = try? parseExprStr("{ 1, 2 }");
2627
    try testing::expect(parsed == nil);
2628
}
2629
2630
/// Test that positional brace initializers are rejected: `Point { 1, 2 }`.
2631
@test fn testParsePositionalBraceInitializerNamed() throws (testing::TestError) {
2632
    let parsed: ?*ast::Node = try? parseExprStr("Point { 1, 2 }");
2633
    try testing::expect(parsed == nil);
2634
}
2635
2636
/// Test that mixed labeled/positional brace initializers are rejected: `Pt { x: 1, 2 }`.
2637
@test fn testParseMixedBraceInitializer() throws (testing::TestError) {
2638
    let parsed: ?*ast::Node = try? parseExprStr("Pt { x: 1, 2 }");
2639
    try testing::expect(parsed == nil);
2640
}
2641
2642
@test fn testParseModule() throws (testing::TestError) {
2643
    let r = try! parseStmtsStr("fn f() {} fn g() {}");
2644
2645
    let case ast::NodeValue::Block(module) = r.value
2646
        else throw testing::TestError::Failed;
2647
    try testing::expect(module.statements.len == 2);
2648
2649
    let first = module.statements[0];
2650
    let case ast::NodeValue::FnDecl(fDecl) = first.value
2651
        else throw testing::TestError::Failed;
2652
    try expectIdent(fDecl.name, "f");
2653
2654
    let second = module.statements[1];
2655
    let case ast::NodeValue::FnDecl(gDecl) = second.value
2656
        else throw testing::TestError::Failed;
2657
    try expectIdent(gDecl.name, "g");
2658
}
2659
2660
/// Test parsing a simple conditional expression.
2661
@test fn testParseCondExpr() throws (testing::TestError) {
2662
    let r = try! parseExprStr("a if cond else b") catch {
2663
        throw testing::TestError::Failed;
2664
    };
2665
    let case ast::NodeValue::CondExpr(cond) = r.value
2666
        else throw testing::TestError::Failed;
2667
2668
    try expectIdent(cond.thenExpr, "a");
2669
    try expectIdent(cond.condition, "cond");
2670
    try expectIdent(cond.elseExpr, "b");
2671
}
2672
2673
/// Test parsing a conditional expression with `as` casts.
2674
@test fn testParseCondExprWithAsCast() throws (testing::TestError) {
2675
    let r = try! parseExprStr("x as i32 if cond else y as i32") catch {
2676
        throw testing::TestError::Failed;
2677
    };
2678
    let case ast::NodeValue::CondExpr(cond) = r.value
2679
        else throw testing::TestError::Failed;
2680
2681
    // Check thenExpr is an `as` cast.
2682
    let case ast::NodeValue::As(thenAs) = cond.thenExpr.value
2683
        else throw testing::TestError::Failed;
2684
    try expectIdent(thenAs.value, "x");
2685
    try expectIntType(thenAs.type, 4, ast::Signedness::Signed);
2686
2687
    // Check condition.
2688
    try expectIdent(cond.condition, "cond");
2689
2690
    // Check elseExpr is an `as` cast.
2691
    let case ast::NodeValue::As(elseAs) = cond.elseExpr.value
2692
        else throw testing::TestError::Failed;
2693
    try expectIdent(elseAs.value, "y");
2694
    try expectIntType(elseAs.type, 4, ast::Signedness::Signed);
2695
}
2696
2697
/// Test parsing a nested conditional expression (right-associative).
2698
@test fn testParseCondExprNested() throws (testing::TestError) {
2699
    let r = try! parseExprStr("a if x else b if y else c") catch {
2700
        throw testing::TestError::Failed;
2701
    };
2702
    let case ast::NodeValue::CondExpr(outer) = r.value
2703
        else throw testing::TestError::Failed;
2704
2705
    try expectIdent(outer.thenExpr, "a");
2706
    try expectIdent(outer.condition, "x");
2707
2708
    // The else branch should be another conditional expression.
2709
    let case ast::NodeValue::CondExpr(inner) = outer.elseExpr.value
2710
        else throw testing::TestError::Failed;
2711
2712
    try expectIdent(inner.thenExpr, "b");
2713
    try expectIdent(inner.condition, "y");
2714
    try expectIdent(inner.elseExpr, "c");
2715
}
2716
2717
/// Test that trailing commas are allowed in all comma-separated lists.
2718
@test fn testTrailingCommas() throws (testing::TestError) {
2719
    // Function call arguments.
2720
    let call = try! parseExprStr("f(1, 2, 3,)");
2721
    let case ast::NodeValue::Call(c) = call.value else throw testing::TestError::Failed;
2722
    try testing::expect(c.args.len == 3);
2723
2724
    // Function parameters.
2725
    let fnNode = try! parseStmtStr("fn add(x: i32, y: i32,) {}");
2726
    let case ast::NodeValue::FnDecl(fnDecl) = fnNode.value else throw testing::TestError::Failed;
2727
    try testing::expect(fnDecl.sig.params.len == 2);
2728
2729
    // Record declarations.
2730
    let recNode = try! parseStmtStr("record R { x: i32, y: bool, }");
2731
    let case ast::NodeValue::RecordDecl(recDecl) = recNode.value else throw testing::TestError::Failed;
2732
    try testing::expect(recDecl.fields.len == 2);
2733
2734
    // Tuple record declarations.
2735
    let tupNode = try! parseStmtStr("record R(i32, bool,);");
2736
    let case ast::NodeValue::RecordDecl(tupDecl) = tupNode.value else throw testing::TestError::Failed;
2737
    try testing::expect(tupDecl.fields.len == 2);
2738
2739
    // Record literals.
2740
    let litNode = try! parseExprStr("Point { x: 1, y: 2, }");
2741
    let case ast::NodeValue::RecordLit(lit) = litNode.value else throw testing::TestError::Failed;
2742
    try testing::expect(lit.fields.len == 2);
2743
2744
    // Union declarations.
2745
    let unionNode = try! parseStmtStr("union Color { Red, Green, Blue, }");
2746
    let case ast::NodeValue::UnionDecl(unionDecl) = unionNode.value else throw testing::TestError::Failed;
2747
    try testing::expect(unionDecl.variants.len == 3);
2748
2749
    // Array literals.
2750
    let arrNode = try! parseExprStr("[1, 2, 3,]");
2751
    let case ast::NodeValue::ArrayLit(items) = arrNode.value else throw testing::TestError::Failed;
2752
    try testing::expect(items.len == 3);
2753
2754
    // Function type parameters.
2755
    let fnType = try! parseTypeStr("fn (i32, bool,)");
2756
    let case ast::NodeValue::TypeSig(sigValue) = fnType.value else throw testing::TestError::Failed;
2757
    let case ast::TypeSig::Fn(sig) = sigValue else throw testing::TestError::Failed;
2758
    try testing::expect(sig.params.len == 2);
2759
    try testing::expect(sig.returnType == nil);
2760
2761
    // Throws lists.
2762
    let throwsNode = try! parseStmtStr("fn handle() throws (Error, Other,) {}");
2763
    let case ast::NodeValue::FnDecl(throwsDecl) = throwsNode.value else throw testing::TestError::Failed;
2764
    try testing::expect(throwsDecl.sig.throwList.len == 2);
2765
}