lib/std/lang/parser/tests.rad 103.4 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 throw testing::TestError::Failed;
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: void, y: bool }");
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::Void);
901
    try expectFieldSig(decl.fields, 1, "y", ast::TypeSig::Bool);
902
}
903
904
/// Test parsing a record declaration with derives.
905
@test fn testParseRecordDeclDerives() throws (testing::TestError) {
906
    let node = try! parseStmtStr("record R: Eq + Debug { field: i32 }");
907
    let case ast::NodeValue::RecordDecl(decl) = node.value
908
        else throw testing::TestError::Failed;
909
910
    try expectIdent(decl.name, "R");
911
    try testing::expect(decl.derives.len == 2);
912
    try expectIdent(decl.derives[0], "Eq");
913
    try expectIdent(decl.derives[1], "Debug");
914
}
915
916
/// Test parsing a record declaration with field initializers.
917
@test fn testParseRecordDeclFieldDefaults() throws (testing::TestError) {
918
    let node = try! parseStmtStr("record Config { size: opaque = 42, flag: bool = true }");
919
    let case ast::NodeValue::RecordDecl(decl) = node.value
920
        else throw testing::TestError::Failed;
921
922
    try expectIdent(decl.name, "Config");
923
    try testing::expect(decl.derives.len == 0);
924
    try testing::expect(decl.fields.len == 2);
925
926
    try expectFieldSig(decl.fields, 0, "size", ast::TypeSig::Opaque);
927
    try expectFieldSig(decl.fields, 1, "flag", ast::TypeSig::Bool);
928
929
    // Check default values.
930
    let case ast::NodeValue::RecordField { value: val0, .. } = decl.fields[0].value
931
        else throw testing::TestError::Failed;
932
    let v0 = val0 else throw testing::TestError::Failed;
933
    try expectNumber(v0, "42");
934
935
    let case ast::NodeValue::RecordField { value: val1, .. } = decl.fields[1].value
936
        else throw testing::TestError::Failed;
937
    let v1 = val1 else throw testing::TestError::Failed;
938
    let case ast::NodeValue::Bool(flagValue) = v1.value
939
        else throw testing::TestError::Failed;
940
    try testing::expect(flagValue);
941
}
942
943
/// Test parsing an unlabeled record declaration.
944
@test fn testParseTupleRecordDecl() throws (testing::TestError) {
945
    let node = try! parseStmtStr("record Pair(void, bool);");
946
    let case ast::NodeValue::RecordDecl(decl) = node.value
947
        else throw testing::TestError::Failed;
948
949
    try expectIdent(decl.name, "Pair");
950
    try testing::expect(not decl.labeled);
951
    try testing::expect(decl.derives.len == 0);
952
    try testing::expect(decl.fields.len == 2);
953
954
    try expectFieldSig(decl.fields, 0, nil, ast::TypeSig::Void);
955
    try expectFieldSig(decl.fields, 1, nil, ast::TypeSig::Bool);
956
}
957
958
/// Test parsing a single-field unlabeled record.
959
@test fn testParseTupleRecordSingleField() throws (testing::TestError) {
960
    let node = try! parseStmtStr("record R(bool);");
961
    let case ast::NodeValue::RecordDecl(decl) = node.value
962
        else throw testing::TestError::Failed;
963
964
    try expectIdent(decl.name, "R");
965
    try testing::expect(not decl.labeled);
966
    try testing::expect(decl.fields.len == 1);
967
968
    try expectFieldSig(decl.fields, 0, nil, ast::TypeSig::Bool);
969
}
970
971
/// Test parsing empty record literals.
972
@test fn testParseEmptyRecordLiteral() throws (testing::TestError) {
973
    let r1 = try! parseExprStr("{}");
974
    let case ast::NodeValue::RecordLit(lit) = r1.value
975
        else throw testing::TestError::Failed;
976
977
    try testing::expect(lit.typeName == nil);
978
    try testing::expect(lit.fields.len == 0);
979
980
    let r2 = try! parseExprStr("Point {}");
981
    let case ast::NodeValue::RecordLit(lit2) = r2.value
982
        else throw testing::TestError::Failed;
983
984
    let typeName = lit2.typeName else throw testing::TestError::Failed;
985
    try expectIdent(typeName, "Point");
986
    try testing::expect(lit2.fields.len == 0);
987
}
988
989
/// Test parsing a function type with parameters and return type.
990
@test fn testParseTypeFn() throws (testing::TestError) {
991
    let node = try! parseTypeStr("fn (i32, *u8) -> bool");
992
    let case ast::NodeValue::TypeSig(sigValue) = node.value
993
        else throw testing::TestError::Failed;
994
    let case ast::TypeSig::Fn(sig) = sigValue
995
        else throw testing::TestError::Failed;
996
997
    try testing::expect(sig.params.len == 2);
998
999
    let param0 = sig.params[0];
1000
    try expectIntType(param0, 4, ast::Signedness::Signed);
1001
1002
    let param1 = sig.params[1];
1003
    let case ast::NodeValue::TypeSig(p1) = param1.value
1004
        else throw testing::TestError::Failed;
1005
    let case ast::TypeSig::Pointer { valueType: ptrTarget, mutable: _ } = p1
1006
        else throw testing::TestError::Failed;
1007
    try expectIntType(ptrTarget, 1, ast::Signedness::Unsigned);
1008
1009
    try testing::expect(sig.returnType != nil);
1010
}
1011
1012
/// Test parsing a function type with a throws clause.
1013
@test fn testParseTypeFnThrows() throws (testing::TestError) {
1014
    let node = try! parseTypeStr("fn (i32) -> bool throws (Error, Other)");
1015
    let case ast::NodeValue::TypeSig(sigValue) = node.value
1016
        else throw testing::TestError::Failed;
1017
    let case ast::TypeSig::Fn(sig) = sigValue
1018
        else throw testing::TestError::Failed;
1019
1020
    try testing::expect(sig.params.len == 1);
1021
    try expectIntType(sig.params[0], 4, ast::Signedness::Signed);
1022
1023
    try testing::expect(sig.throwList.len == 2);
1024
    try expectTypeIdent(sig.throwList[0], "Error");
1025
    try expectTypeIdent(sig.throwList[1], "Other");
1026
1027
    let returnType = sig.returnType
1028
        else throw testing::TestError::Failed;
1029
    try expectType(returnType, ast::TypeSig::Bool);
1030
}
1031
1032
/// Test parsing a function declaration without parameters.
1033
@test fn testParseFnDeclEmpty() throws (testing::TestError) {
1034
    let node = try! parseStmtStr("fn main() {}");
1035
    let case ast::NodeValue::FnDecl(decl) = node.value
1036
        else throw testing::TestError::Failed;
1037
1038
    try expectIdent(decl.name, "main");
1039
    try testing::expect(decl.sig.params.len == 0);
1040
    try testing::expect(decl.sig.returnType == nil);
1041
    try testing::expect(decl.attrs == nil);
1042
1043
    let body = decl.body else throw testing::TestError::Failed;
1044
    let case ast::NodeValue::Block(_) = body.value
1045
        else throw testing::TestError::Failed;
1046
}
1047
1048
/// Test parsing a function declaration with parameters and return type.
1049
@test fn testParseFnDeclParams() throws (testing::TestError) {
1050
    let node = try! parseStmtStr("fn add(x: i32, y: *u8) -> bool {}");
1051
    let case ast::NodeValue::FnDecl(decl) = node.value
1052
        else throw testing::TestError::Failed;
1053
1054
    try expectIdent(decl.name, "add");
1055
    try testing::expect(decl.sig.params.len == 2);
1056
1057
    {
1058
        let param0 = decl.sig.params[0];
1059
        let case ast::NodeValue::FnParam(p0) = param0.value
1060
            else throw testing::TestError::Failed;
1061
        try expectIdent(p0.name, "x");
1062
        try expectIntType(p0.type, 4, ast::Signedness::Signed);
1063
    }
1064
    {
1065
        let param1 = decl.sig.params[1];
1066
        let case ast::NodeValue::FnParam(p1) = param1.value
1067
            else throw testing::TestError::Failed;
1068
        try expectIdent(p1.name, "y");
1069
        let case ast::NodeValue::TypeSig(sig1) = p1.type.value
1070
            else throw testing::TestError::Failed;
1071
        let case ast::TypeSig::Pointer { valueType, .. } = sig1
1072
            else throw testing::TestError::Failed;
1073
        try expectIntType(valueType, 1, ast::Signedness::Unsigned);
1074
    }
1075
    {
1076
        let returnType = decl.sig.returnType
1077
            else throw testing::TestError::Failed;
1078
        try expectType(returnType, ast::TypeSig::Bool);
1079
1080
        let body = decl.body else throw testing::TestError::Failed;
1081
        let case ast::NodeValue::Block(_) = body.value
1082
            else throw testing::TestError::Failed;
1083
    }
1084
}
1085
1086
/// Test parsing a function declaration with a throws clause.
1087
@test fn testParseFnDeclThrows() throws (testing::TestError) {
1088
    let node = try! parseStmtStr("fn handle() -> void throws (Error, Crash) {}");
1089
    let case ast::NodeValue::FnDecl(decl) = node.value
1090
        else throw testing::TestError::Failed;
1091
1092
    try expectIdent(decl.name, "handle");
1093
1094
    let returnType = decl.sig.returnType
1095
        else throw testing::TestError::Failed;
1096
    try expectType(returnType, ast::TypeSig::Void);
1097
1098
    try testing::expect(decl.sig.throwList.len == 2);
1099
    try expectTypeIdent(decl.sig.throwList[0], "Error");
1100
    try expectTypeIdent(decl.sig.throwList[1], "Crash");
1101
1102
    let body = decl.body else throw testing::TestError::Failed;
1103
    let case ast::NodeValue::Block(_) = body.value
1104
        else throw testing::TestError::Failed;
1105
}
1106
1107
/// Test parsing a function declaration with attributes.
1108
@test fn testParseFnDeclAttributes() throws (testing::TestError) {
1109
    let node = try! parseStmtStr("pub extern fn run();");
1110
    let case ast::NodeValue::FnDecl(decl) = node.value
1111
        else throw testing::TestError::Failed;
1112
1113
    try expectIdent(decl.name, "run");
1114
1115
    let attrs = decl.attrs
1116
        else throw testing::TestError::Failed;
1117
1118
    try testing::expect(attrs.list.len == 2);
1119
1120
    let case ast::NodeValue::Attribute(attr0) = attrs.list[0].value
1121
        else throw testing::TestError::Failed;
1122
    try testing::expect(attr0 == ast::Attribute::Pub);
1123
1124
    let case ast::NodeValue::Attribute(attr1) = attrs.list[1].value
1125
        else throw testing::TestError::Failed;
1126
    try testing::expect(attr1 == ast::Attribute::Extern);
1127
1128
    try testing::expect(ast::attributesContains(&attrs, ast::Attribute::Pub));
1129
    try testing::expect(ast::attributesContains(&attrs, ast::Attribute::Extern));
1130
    try testing::expect(decl.body == nil);
1131
}
1132
1133
/// Test parsing a scoped identifier type.
1134
@test fn testParseTypeScopedIdent() throws (testing::TestError) {
1135
    let node = try! parseTypeStr("module::Type");
1136
    let case ast::NodeValue::TypeSig(ts) = node.value
1137
        else throw testing::TestError::Failed;
1138
    let case ast::TypeSig::Nominal(name) = ts
1139
        else throw testing::TestError::Failed;
1140
    let case ast::NodeValue::ScopeAccess(access) = name.value
1141
        else throw testing::TestError::Failed;
1142
1143
    try expectIdent(access.parent, "module");
1144
    try expectIdent(access.child, "Type");
1145
}
1146
1147
/// Test parsing the `bool` type.
1148
@test fn testParseTypeBool() throws (testing::TestError) {
1149
    let node = try! parseTypeStr("bool");
1150
    try expectType(node, ast::TypeSig::Bool);
1151
}
1152
1153
/// Test parsing the `void` type.
1154
@test fn testParseTypeVoid() throws (testing::TestError) {
1155
    let node = try! parseTypeStr("void");
1156
    try expectType(node, ast::TypeSig::Void);
1157
}
1158
1159
/// Test parsing an unsigned integer type.
1160
@test fn testParseTypeUnsigned() throws (testing::TestError) {
1161
    let node = try! parseTypeStr("u8");
1162
    try expectType(node, ast::TypeSig::Integer {
1163
        width: 1,
1164
        sign: ast::Signedness::Unsigned,
1165
    });
1166
}
1167
1168
/// Test parsing a simple `if let` statement without guard or else.
1169
@test fn testParseIfLet() throws (testing::TestError) {
1170
    let root = try! parseStmtStr("if let value = opt { body; }");
1171
    let case ast::NodeValue::IfLet(node) = root.value
1172
        else throw testing::TestError::Failed;
1173
1174
    try expectIdent(node.pattern.pattern, "value");
1175
    try expectIdent(node.pattern.scrutinee, "opt");
1176
1177
    try testing::expect(node.pattern.guard == nil);
1178
    try expectBlockExprStmt(node.thenBranch, ast::NodeValue::Ident("body"));
1179
    try testing::expect(node.elseBranch == nil);
1180
}
1181
1182
/// Test parsing an `if let` statement with guard and else branches.
1183
@test fn testParseIfLetGuardElse() throws (testing::TestError) {
1184
    let root = try! parseStmtStr(
1185
        "if let value = opt; guard { body; } else { alt; }"
1186
    );
1187
    let case ast::NodeValue::IfLet(node) = root.value
1188
        else throw testing::TestError::Failed;
1189
1190
    try expectIdent(node.pattern.pattern, "value");
1191
    try expectIdent(node.pattern.scrutinee, "opt");
1192
1193
    let guard = node.pattern.guard
1194
        else throw testing::TestError::Failed;
1195
    try expectIdent(guard, "guard");
1196
1197
    try expectBlockExprStmt(node.thenBranch, ast::NodeValue::Ident("body"));
1198
1199
    let elseBranch = node.elseBranch
1200
        else throw testing::TestError::Failed;
1201
    try expectBlockExprStmt(elseBranch, ast::NodeValue::Ident("alt"));
1202
}
1203
1204
/// Test parsing an `if let` statement with an `else if` chain.
1205
@test fn testParseIfLetElseIf() throws (testing::TestError) {
1206
    let root = try! parseStmtStr(
1207
        "if let value = opt { body; } else if cond { alt; }"
1208
    );
1209
    let case ast::NodeValue::IfLet(node) = root.value
1210
        else throw testing::TestError::Failed;
1211
1212
    try expectIdent(node.pattern.pattern, "value");
1213
1214
    let elseBranch = node.elseBranch
1215
        else throw testing::TestError::Failed;
1216
1217
    let nested = try getBlockFirstStmt(elseBranch);
1218
    let case ast::NodeValue::If(inner) = nested.value
1219
        else throw testing::TestError::Failed;
1220
1221
    try expectIdent(inner.condition, "cond");
1222
    try expectBlockExprStmt(inner.thenBranch, ast::NodeValue::Ident("alt"));
1223
    try testing::expect(inner.elseBranch == nil);
1224
}
1225
1226
/// Test parsing `if let mut` binding.
1227
@test fn testParseIfLetMut() throws (testing::TestError) {
1228
    let root = try! parseStmtStr("if let mut value = opt { body; }");
1229
    let case ast::NodeValue::IfLet(node) = root.value
1230
        else throw testing::TestError::Failed;
1231
1232
    try expectIdent(node.pattern.pattern, "value");
1233
    try expectIdent(node.pattern.scrutinee, "opt");
1234
    try testing::expect(node.pattern.mutable);
1235
    try testing::expect(node.pattern.guard == nil);
1236
    try expectBlockExprStmt(node.thenBranch, ast::NodeValue::Ident("body"));
1237
    try testing::expect(node.elseBranch == nil);
1238
}
1239
1240
/// Test parsing `let mut ... else` binding.
1241
@test fn testParseLetMutElse() throws (testing::TestError) {
1242
    let root = try! parseStmtStr("let mut x = opt else { return };");
1243
    let case ast::NodeValue::LetElse(letElse) = root.value
1244
        else throw testing::TestError::Failed;
1245
1246
    try expectIdent(letElse.pattern.pattern, "x");
1247
    try testing::expect(letElse.pattern.mutable);
1248
}
1249
1250
/// Test that `if let` without `mut` is not mutable.
1251
@test fn testParseIfLetNotMutable() throws (testing::TestError) {
1252
    let root = try! parseStmtStr("if let value = opt { body; }");
1253
    let case ast::NodeValue::IfLet(node) = root.value
1254
        else throw testing::TestError::Failed;
1255
1256
    try testing::expect(not node.pattern.mutable);
1257
}
1258
1259
/// Test that `let ... else` without `mut` is not mutable.
1260
@test fn testParseLetElseNotMutable() throws (testing::TestError) {
1261
    let root = try! parseStmtStr("let x = opt else { return };");
1262
    let case ast::NodeValue::LetElse(letElse) = root.value
1263
        else throw testing::TestError::Failed;
1264
1265
    try testing::expect(not letElse.pattern.mutable);
1266
}
1267
1268
/// Test parsing a simple `if let case` statement.
1269
@test fn testParseIfCase() throws (testing::TestError) {
1270
    let root = try! parseStmtStr("if let case pat = value { body; }");
1271
    let case ast::NodeValue::IfLet(node) = root.value
1272
        else throw testing::TestError::Failed;
1273
1274
    try expectIdent(node.pattern.pattern, "pat");
1275
    try expectIdent(node.pattern.scrutinee, "value");
1276
    try testing::expect(node.pattern.guard == nil);
1277
    try expectBlockExprStmt(node.thenBranch, ast::NodeValue::Ident("body"));
1278
    try testing::expect(node.elseBranch == nil);
1279
}
1280
1281
/// Test parsing an `if let case` statement with guard and else branches.
1282
@test fn testParseIfCaseGuardElse() throws (testing::TestError) {
1283
    let root = try! parseStmtStr(
1284
        "if let case pat = value; guard { body; } else { alt; }"
1285
    );
1286
    let case ast::NodeValue::IfLet(node) = root.value
1287
        else throw testing::TestError::Failed;
1288
1289
    try expectIdent(node.pattern.pattern, "pat");
1290
    try expectIdent(node.pattern.scrutinee, "value");
1291
1292
    let guard = node.pattern.guard
1293
        else throw testing::TestError::Failed;
1294
    try expectIdent(guard, "guard");
1295
1296
    try expectBlockExprStmt(node.thenBranch, ast::NodeValue::Ident("body"));
1297
1298
    let elseBranch = node.elseBranch
1299
        else throw testing::TestError::Failed;
1300
    try expectBlockExprStmt(elseBranch, ast::NodeValue::Ident("alt"));
1301
}
1302
1303
/// Test parsing an `if let case` statement with an `else if` chain.
1304
@test fn testParseIfCaseElseIf() throws (testing::TestError) {
1305
    let root = try! parseStmtStr(
1306
        "if let case pat = value { body; } else if cond { alt; }"
1307
    );
1308
    let case ast::NodeValue::IfLet(node) = root.value
1309
        else throw testing::TestError::Failed;
1310
1311
    let elseBranch = node.elseBranch
1312
        else throw testing::TestError::Failed;
1313
1314
    let nested = try getBlockFirstStmt(elseBranch);
1315
    let case ast::NodeValue::If(inner) = nested.value
1316
        else throw testing::TestError::Failed;
1317
1318
    try expectIdent(inner.condition, "cond");
1319
    try expectBlockExprStmt(inner.thenBranch, ast::NodeValue::Ident("alt"));
1320
    try testing::expect(inner.elseBranch == nil);
1321
}
1322
1323
/// Test parsing a simple `while` loop without an `else` branch.
1324
@test fn testParseWhile() throws (testing::TestError) {
1325
    let root = try! parseStmtStr("while cond { body; }");
1326
    let case ast::NodeValue::While(loopNode) = root.value
1327
        else throw testing::TestError::Failed;
1328
1329
    try expectIdent(loopNode.condition, "cond");
1330
    try expectBlockExprStmt(loopNode.body, ast::NodeValue::Ident("body"));
1331
    try testing::expect(loopNode.elseBranch == nil);
1332
}
1333
1334
/// Test parsing a `while` loop with an `else` branch.
1335
@test fn testParseWhileElse() throws (testing::TestError) {
1336
    let root = try! parseStmtStr("while cond { body; } else { alt; }");
1337
    let case ast::NodeValue::While(loopNode) = root.value
1338
        else throw testing::TestError::Failed;
1339
1340
    try expectIdent(loopNode.condition, "cond");
1341
    try expectBlockExprStmt(loopNode.body, ast::NodeValue::Ident("body"));
1342
1343
    let elseBranch = loopNode.elseBranch
1344
        else throw testing::TestError::Failed;
1345
    try expectBlockExprStmt(elseBranch, ast::NodeValue::Ident("alt"));
1346
}
1347
1348
/// Test parsing a simple `while let case` loop.
1349
@test fn testParseWhileCase() throws (testing::TestError) {
1350
    let root = try! parseStmtStr("while let case pat = value { body; }");
1351
    let case ast::NodeValue::WhileLet(node) = root.value
1352
        else throw testing::TestError::Failed;
1353
1354
    try expectIdent(node.pattern.pattern, "pat");
1355
    try expectIdent(node.pattern.scrutinee, "value");
1356
    try testing::expect(node.pattern.guard == nil);
1357
    try expectBlockExprStmt(node.body, ast::NodeValue::Ident("body"));
1358
    try testing::expect(node.elseBranch == nil);
1359
}
1360
1361
/// Test parsing a `while let case` loop with guard and else branches.
1362
@test fn testParseWhileCaseGuardElse() throws (testing::TestError) {
1363
    let root = try! parseStmtStr(
1364
        "while let case pat = value; guard { body; } else { alt; }"
1365
    );
1366
    let case ast::NodeValue::WhileLet(node) = root.value
1367
        else throw testing::TestError::Failed;
1368
1369
    let guard = node.pattern.guard
1370
        else throw testing::TestError::Failed;
1371
    try expectIdent(guard, "guard");
1372
1373
    try expectBlockExprStmt(node.body, ast::NodeValue::Ident("body"));
1374
1375
    let elseBranch = node.elseBranch
1376
        else throw testing::TestError::Failed;
1377
    try expectBlockExprStmt(elseBranch, ast::NodeValue::Ident("alt"));
1378
}
1379
1380
/// Test parsing a simple `try` expression without catch.
1381
@test fn testParseTry() throws (testing::TestError) {
1382
    let root = try! parseExprStr("try value");
1383
    let case ast::NodeValue::Try(node) = root.value
1384
        else throw testing::TestError::Failed;
1385
1386
    try expectIdent(node.expr, "value");
1387
    try testing::expect(node.catches.len == 0);
1388
    try testing::expect(not node.shouldPanic);
1389
}
1390
1391
/// Test parsing a `try!` expression that panics on error.
1392
@test fn testParseTryBang() throws (testing::TestError) {
1393
    let root = try! parseExprStr("try! value");
1394
    let case ast::NodeValue::Try(node) = root.value
1395
        else throw testing::TestError::Failed;
1396
1397
    try expectIdent(node.expr, "value");
1398
    try testing::expect(node.catches.len == 0);
1399
    try testing::expect(node.shouldPanic);
1400
}
1401
1402
/// Test parsing a `try` expression with a `catch` block.
1403
@test fn testParseTryCatchBlock() throws (testing::TestError) {
1404
    let root = try! parseExprStr("try value catch { alt; }");
1405
    let case ast::NodeValue::Try(node) = root.value
1406
        else throw testing::TestError::Failed;
1407
1408
    try expectIdent(node.expr, "value");
1409
    try testing::expect(node.catches.len == 1);
1410
1411
    let case ast::NodeValue::CatchClause(clause) = node.catches[0].value
1412
        else throw testing::TestError::Failed;
1413
    try testing::expect(clause.binding == nil);
1414
    try testing::expect(clause.typeNode == nil);
1415
    try expectBlockExprStmt(clause.body, ast::NodeValue::Ident("alt"));
1416
}
1417
1418
/// Test that `catch` without a block is rejected.
1419
@test fn testParseTryCatchExprRejected() throws (testing::TestError) {
1420
    let parsed: ?*ast::Node = try? parseExprStr("try value catch alternate");
1421
    try testing::expect(parsed == nil);
1422
}
1423
1424
/// Test parsing a `break` statement.
1425
@test fn testParseBreak() throws (testing::TestError) {
1426
    let root = try! parseStmtStr("break");
1427
    let case ast::NodeValue::Break= root.value
1428
        else throw testing::TestError::Failed;
1429
}
1430
1431
/// Test parsing a `continue` statement.
1432
@test fn testParseContinue() throws (testing::TestError) {
1433
    let root = try! parseStmtStr("continue");
1434
    let case ast::NodeValue::Continue= root.value
1435
        else throw testing::TestError::Failed;
1436
}
1437
1438
/// Test parsing a `return` statement without value.
1439
@test fn testParseReturnVoid() throws (testing::TestError) {
1440
    let root = try! parseStmtStr("return");
1441
    let case ast::NodeValue::Return(retValue) = root.value
1442
        else throw testing::TestError::Failed;
1443
1444
    try testing::expect(retValue == nil);
1445
}
1446
1447
/// Test parsing a `return` statement with a value.
1448
@test fn testParseReturnValue() throws (testing::TestError) {
1449
    let root = try! parseStmtStr("return result");
1450
    let case ast::NodeValue::Return(retValue) = root.value
1451
        else throw testing::TestError::Failed;
1452
1453
    let value = retValue
1454
        else throw testing::TestError::Failed;
1455
    try expectIdent(value, "result");
1456
}
1457
1458
/// Test parsing a `throw` statement.
1459
@test fn testParseThrow() throws (testing::TestError) {
1460
    let root = try! parseStmtStr("throw error");
1461
    let case ast::NodeValue::Throw(throwExpr) = root.value
1462
        else throw testing::TestError::Failed;
1463
1464
    try expectIdent(throwExpr, "error");
1465
}
1466
1467
/// Test parsing a `panic` statement without a message.
1468
@test fn testParsePanicEmpty() throws (testing::TestError) {
1469
    let root = try! parseStmtStr("panic");
1470
    let case ast::NodeValue::Panic(panicMsg) = root.value
1471
        else throw testing::TestError::Failed;
1472
1473
    try testing::expect(panicMsg == nil);
1474
}
1475
1476
/// Test parsing a `panic` statement with a message.
1477
@test fn testParsePanicMessage() throws (testing::TestError) {
1478
    let root = try! parseStmtStr("panic \"something went wrong\"");
1479
    let case ast::NodeValue::Panic(panicMsg) = root.value
1480
        else throw testing::TestError::Failed;
1481
1482
    let message = panicMsg
1483
        else throw testing::TestError::Failed;
1484
    let case ast::NodeValue::String(msgStr) = message.value if mem::eq(msgStr, "something went wrong")
1485
        else throw testing::TestError::Failed;
1486
}
1487
1488
/// Test parsing a `panic` statement with braces.
1489
@test fn testParsePanicBraces() throws (testing::TestError) {
1490
    let root = try! parseStmtStr("panic { \"error\" }");
1491
    let case ast::NodeValue::Panic(panicMsg) = root.value
1492
        else throw testing::TestError::Failed;
1493
1494
    let message = panicMsg
1495
        else throw testing::TestError::Failed;
1496
    let case ast::NodeValue::String(msgStr) = message.value if mem::eq(msgStr, "error")
1497
        else throw testing::TestError::Failed;
1498
}
1499
1500
/// Test parsing a simple `match` statement with one case.
1501
@test fn testParseMatchSingle() throws (testing::TestError) {
1502
    let root = try! parseStmtStr("match subject { case pattern => body }");
1503
    let case ast::NodeValue::Match(sw) = root.value
1504
        else throw testing::TestError::Failed;
1505
1506
    try expectIdent(sw.subject, "subject");
1507
    try testing::expect(sw.prongs.len == 1);
1508
1509
    let caseNode = sw.prongs[0];
1510
    let case ast::NodeValue::MatchProng(prong) = caseNode.value
1511
        else throw testing::TestError::Failed;
1512
1513
    let case ast::ProngArm::Case(patterns) = prong.arm
1514
        else throw testing::TestError::Failed;
1515
    try testing::expect(patterns.len == 1);
1516
    try expectIdent(patterns[0], "pattern");
1517
    try testing::expect(prong.guard == nil);
1518
1519
    let case ast::NodeValue::ExprStmt(bodyStmt) = prong.body.value
1520
        else throw testing::TestError::Failed;
1521
    let case ast::NodeValue::Ident(name) = bodyStmt.value
1522
        if mem::eq(name, "body")
1523
        else throw testing::TestError::Failed;
1524
}
1525
1526
/// Test parsing a `match` case with guard and multiple patterns.
1527
@test fn testParseMatchGuard() throws (testing::TestError) {
1528
    let root = try! parseStmtStr(
1529
        "match subject { case left, right if cond => handle }"
1530
    );
1531
    let case ast::NodeValue::Match(sw) = root.value
1532
        else throw testing::TestError::Failed;
1533
1534
    try testing::expect(sw.prongs.len == 1);
1535
    let case ast::NodeValue::MatchProng(prong) = sw.prongs[0].value
1536
        else throw testing::TestError::Failed;
1537
1538
    let case ast::ProngArm::Case(patterns) = prong.arm
1539
        else throw testing::TestError::Failed;
1540
    try testing::expect(patterns.len == 2);
1541
    try expectIdent(patterns[0], "left");
1542
    try expectIdent(patterns[1], "right");
1543
1544
    let guard = prong.guard
1545
        else throw testing::TestError::Failed;
1546
    try expectIdent(guard, "cond");
1547
}
1548
1549
/// Test parsing `match` prongs whose bodies omit trailing semicolons.
1550
@test fn testParseMatchReturnNoSemicolon() throws (testing::TestError) {
1551
    let root = try! parseStmtStr(
1552
        "match subject { case First => return, case Second => return }"
1553
    );
1554
    let case ast::NodeValue::Match(sw) = root.value
1555
        else throw testing::TestError::Failed;
1556
1557
    try testing::expect(sw.prongs.len == 2);
1558
1559
    let firstCaseNode = sw.prongs[0];
1560
    let case ast::NodeValue::MatchProng(firstProng) = firstCaseNode.value
1561
        else throw testing::TestError::Failed;
1562
    let case ast::NodeValue::Return(firstRetVal) = firstProng.body.value
1563
        else throw testing::TestError::Failed;
1564
    try testing::expect(firstRetVal == nil);
1565
1566
    let secondCaseNode = sw.prongs[1];
1567
    let case ast::NodeValue::MatchProng(secondProng) = secondCaseNode.value
1568
        else throw testing::TestError::Failed;
1569
    let case ast::NodeValue::Return(secondRetVal) = secondProng.body.value
1570
        else throw testing::TestError::Failed;
1571
    try testing::expect(secondRetVal == nil);
1572
}
1573
1574
/// Test parsing a `match` statement with multiple branches.
1575
@test fn testParseMatchMultipleCases() throws (testing::TestError) {
1576
    let root = try! parseStmtStr(
1577
        "match subject { case First => first, case Second => second }"
1578
    );
1579
    let case ast::NodeValue::Match(sw) = root.value
1580
        else throw testing::TestError::Failed;
1581
1582
    try testing::expect(sw.prongs.len == 2);
1583
    {
1584
        let case ast::NodeValue::MatchProng(prong) = sw.prongs[0].value
1585
            else throw testing::TestError::Failed;
1586
        let case ast::ProngArm::Case(patterns) = prong.arm
1587
            else throw testing::TestError::Failed;
1588
        try testing::expect(patterns.len == 1);
1589
        try expectIdent(patterns[0], "First");
1590
        let case ast::NodeValue::ExprStmt(stmt) = prong.body.value
1591
            else throw testing::TestError::Failed;
1592
        let case ast::NodeValue::Ident(val) = stmt.value
1593
            if mem::eq(val, "first")
1594
            else throw testing::TestError::Failed;
1595
    } {
1596
        let case ast::NodeValue::MatchProng(prong) = sw.prongs[1].value
1597
            else throw testing::TestError::Failed;
1598
        let case ast::ProngArm::Case(pats) = prong.arm
1599
            else throw testing::TestError::Failed;
1600
1601
        try testing::expect(pats.len == 1);
1602
        try expectIdent(pats[0], "Second");
1603
1604
        let case ast::NodeValue::ExprStmt(stmt) = prong.body.value
1605
            else throw testing::TestError::Failed;
1606
        let case ast::NodeValue::Ident(val) = stmt.value
1607
            if mem::eq(val, "second")
1608
            else throw testing::TestError::Failed;
1609
    }
1610
}
1611
1612
/// Test parsing a `match` case whose body is a block.
1613
@test fn testParseMatchProngBlock() throws (testing::TestError) {
1614
    let root = try! parseStmtStr("match subject { case Pattern => { body; } }");
1615
    let case ast::NodeValue::Match(sw) = root.value
1616
        else throw testing::TestError::Failed;
1617
1618
    try testing::expect(sw.prongs.len == 1);
1619
    let case ast::NodeValue::MatchProng(prong) = sw.prongs[0].value
1620
        else throw testing::TestError::Failed;
1621
    try expectBlockExprStmt(prong.body, ast::NodeValue::Ident("body"));
1622
}
1623
1624
/// Test parsing a `match` statement with an `else` case.
1625
@test fn testParseMatchElse() throws (testing::TestError) {
1626
    let root = try! parseStmtStr("match subject { else => body }");
1627
    let case ast::NodeValue::Match(sw) = root.value
1628
        else throw testing::TestError::Failed;
1629
1630
    try testing::expect(sw.prongs.len == 1);
1631
    let case ast::NodeValue::MatchProng(prong) = sw.prongs[0].value
1632
        else throw testing::TestError::Failed;
1633
    // Else prong has no pattern.
1634
    let case ast::ProngArm::Else = prong.arm
1635
        else throw testing::TestError::Failed;
1636
    try testing::expect(prong.guard == nil);
1637
1638
    let case ast::NodeValue::ExprStmt(bodyStmt) = prong.body.value
1639
        else throw testing::TestError::Failed;
1640
    let case ast::NodeValue::Ident(name) = bodyStmt.value
1641
        if mem::eq(name, "body")
1642
        else throw testing::TestError::Failed;
1643
}
1644
1645
/// Test parsing a `match` statement with a binding prong.
1646
@test fn testParseMatchBinding() throws (testing::TestError) {
1647
    let root = try! parseStmtStr("match subject { x => body }");
1648
    let case ast::NodeValue::Match(sw) = root.value
1649
        else throw testing::TestError::Failed;
1650
1651
    try testing::expect(sw.prongs.len == 1);
1652
    let case ast::NodeValue::MatchProng(prong) = sw.prongs[0].value
1653
        else throw testing::TestError::Failed;
1654
    // Binding prong has single identifier pattern.
1655
    let case ast::ProngArm::Binding(pat) = prong.arm
1656
        else throw testing::TestError::Failed;
1657
    try expectIdent(pat, "x");
1658
    try testing::expect(prong.guard == nil);
1659
1660
    let case ast::NodeValue::ExprStmt(bodyStmt) = prong.body.value
1661
        else throw testing::TestError::Failed;
1662
    try expectIdent(bodyStmt, "body");
1663
}
1664
1665
/// Test parsing a `match` statement with a guarded binding prong.
1666
@test fn testParseMatchBindingGuard() throws (testing::TestError) {
1667
    let root = try! parseStmtStr("match subject { x if x > 0 => body }");
1668
    let case ast::NodeValue::Match(sw) = root.value
1669
        else throw testing::TestError::Failed;
1670
1671
    try testing::expect(sw.prongs.len == 1);
1672
    let case ast::NodeValue::MatchProng(prong) = sw.prongs[0].value
1673
        else throw testing::TestError::Failed;
1674
    // Binding prong has single identifier pattern.
1675
    let case ast::ProngArm::Binding(pat) = prong.arm
1676
        else throw testing::TestError::Failed;
1677
    try expectIdent(pat, "x");
1678
1679
    let guard = prong.guard else throw testing::TestError::Failed;
1680
    let case ast::NodeValue::BinOp(binop) = guard.value
1681
        else throw testing::TestError::Failed;
1682
    try testing::expect(binop.op == ast::BinaryOp::Gt);
1683
}
1684
1685
/// Test parsing a `match` statement with a `_` wildcard.
1686
@test fn testParseMatchWildcard() throws (testing::TestError) {
1687
    let root = try! parseStmtStr("match subject { _ => body }");
1688
    let case ast::NodeValue::Match(sw) = root.value
1689
        else throw testing::TestError::Failed;
1690
1691
    try testing::expect(sw.prongs.len == 1);
1692
    let case ast::NodeValue::MatchProng(prong) = sw.prongs[0].value
1693
        else throw testing::TestError::Failed;
1694
    // Wildcard binding prong has single placeholder pattern.
1695
    let case ast::ProngArm::Binding(pat) = prong.arm
1696
        else throw testing::TestError::Failed;
1697
    let case ast::NodeValue::Placeholder = pat.value
1698
        else throw testing::TestError::Failed;
1699
    try testing::expect(prong.guard == nil);
1700
1701
    let case ast::NodeValue::ExprStmt(bodyStmt) = prong.body.value
1702
        else throw testing::TestError::Failed;
1703
    try expectIdent(bodyStmt, "body");
1704
}
1705
1706
/// Test parsing a `match` statement with a guarded `_` wildcard.
1707
@test fn testParseMatchWildcardGuard() throws (testing::TestError) {
1708
    let root = try! parseStmtStr("match subject { _ if cond => body }");
1709
    let case ast::NodeValue::Match(sw) = root.value
1710
        else throw testing::TestError::Failed;
1711
1712
    try testing::expect(sw.prongs.len == 1);
1713
    let case ast::NodeValue::MatchProng(prong) = sw.prongs[0].value
1714
        else throw testing::TestError::Failed;
1715
    // Guarded wildcard binding prong has single placeholder pattern.
1716
    let case ast::ProngArm::Binding(pat) = prong.arm
1717
        else throw testing::TestError::Failed;
1718
    let case ast::NodeValue::Placeholder = pat.value
1719
        else throw testing::TestError::Failed;
1720
1721
    let guard = prong.guard else throw testing::TestError::Failed;
1722
    try expectIdent(guard, "cond");
1723
    let case ast::NodeValue::ExprStmt(bodyStmt) = prong.body.value
1724
        else throw testing::TestError::Failed;
1725
    try expectIdent(bodyStmt, "body");
1726
}
1727
1728
/// Test parsing a `while let` loop with guard and else branches.
1729
@test fn testParseWhileLet() throws (testing::TestError) {
1730
    let root = try! parseStmtStr(
1731
        "while let value = opt; guard { body; } else { alt; }"
1732
    );
1733
    let case ast::NodeValue::WhileLet(loopNode) = root.value
1734
        else throw testing::TestError::Failed;
1735
1736
    try expectIdent(loopNode.pattern.pattern, "value");
1737
    try expectIdent(loopNode.pattern.scrutinee, "opt");
1738
1739
    let guard = loopNode.pattern.guard
1740
        else throw testing::TestError::Failed;
1741
    try expectIdent(guard, "guard");
1742
1743
    try expectBlockExprStmt(loopNode.body, ast::NodeValue::Ident("body"));
1744
1745
    let elseBranch = loopNode.elseBranch
1746
        else throw testing::TestError::Failed;
1747
    try expectBlockExprStmt(elseBranch, ast::NodeValue::Ident("alt"));
1748
}
1749
1750
/// Test parsing a simple `loop` statement.
1751
@test fn testParseLoop() throws (testing::TestError) {
1752
    let root = try! parseStmtStr("loop { body; }");
1753
    let case ast::NodeValue::Loop(loopBody) = root.value
1754
        else throw testing::TestError::Failed;
1755
1756
    try expectBlockExprStmt(loopBody, ast::NodeValue::Ident("body"));
1757
}
1758
1759
/// Test parsing a `for` loop without index or else branches.
1760
@test fn testParseFor() throws (testing::TestError) {
1761
    let root = try! parseStmtStr("for item in items { body; }");
1762
    let case ast::NodeValue::For(loopNode) = root.value
1763
        else throw testing::TestError::Failed;
1764
1765
    try expectIdent(loopNode.binding, "item");
1766
    try testing::expect(loopNode.index == nil);
1767
1768
    try expectIdent(loopNode.iterable, "items");
1769
    try expectBlockExprStmt(loopNode.body, ast::NodeValue::Ident("body"));
1770
    try testing::expect(loopNode.elseBranch == nil);
1771
}
1772
1773
/// Test parsing a `for` loop over a range expression.
1774
@test fn testParseForRangeIterable() throws (testing::TestError) {
1775
    let root = try! parseStmtStr("for item in 0..5 {}");
1776
    let case ast::NodeValue::For(loopNode) = root.value
1777
        else throw testing::TestError::Failed;
1778
1779
    try expectIdent(loopNode.binding, "item");
1780
    try testing::expect(loopNode.index == nil);
1781
    try expectRangeNumbers(loopNode.iterable, "0", "5");
1782
1783
    let case ast::NodeValue::Block(body) = loopNode.body.value
1784
        else throw testing::TestError::Failed;
1785
    try testing::expect(body.statements.len == 0);
1786
    try testing::expect(loopNode.elseBranch == nil);
1787
}
1788
1789
/// Test parsing a `for` loop with index and else branches.
1790
@test fn testParseForIndexElse() throws (testing::TestError) {
1791
    let root = try! parseStmtStr(
1792
        "for value, idx in items { body; } else { alt; }"
1793
    );
1794
    let case ast::NodeValue::For(loopNode) = root.value
1795
        else throw testing::TestError::Failed;
1796
1797
    try expectIdent(loopNode.binding, "value");
1798
1799
    let index = loopNode.index
1800
        else throw testing::TestError::Failed;
1801
    try expectIdent(index, "idx");
1802
1803
    try expectIdent(loopNode.iterable, "items");
1804
    try expectBlockExprStmt(loopNode.body, ast::NodeValue::Ident("body"));
1805
1806
    let elseBranch = loopNode.elseBranch
1807
        else throw testing::TestError::Failed;
1808
    try expectBlockExprStmt(elseBranch, ast::NodeValue::Ident("alt"));
1809
}
1810
1811
/// Test parsing field access expression.
1812
@test fn testParseFieldAccess() throws (testing::TestError) {
1813
    let root = try! parseExprStr("obj.field");
1814
    let case ast::NodeValue::FieldAccess(access) = root.value
1815
        else throw testing::TestError::Failed;
1816
1817
    try expectIdent(access.parent, "obj");
1818
    try expectIdent(access.child, "field");
1819
}
1820
1821
/// Test parsing scope access expression.
1822
@test fn testParseScopeAccess() throws (testing::TestError) {
1823
    let root = try! parseExprStr("module::item");
1824
    let case ast::NodeValue::ScopeAccess(access) = root.value
1825
        else throw testing::TestError::Failed;
1826
1827
    try expectIdent(access.parent, "module");
1828
    try expectIdent(access.child, "item");
1829
}
1830
1831
/// Test parsing array subscript expression.
1832
@test fn testParseArraySubscript() throws (testing::TestError) {
1833
    let root = try! parseExprStr("array[index]");
1834
    let case ast::NodeValue::Subscript { container, index } = root.value
1835
        else throw testing::TestError::Failed;
1836
1837
    try expectIdent(container, "array");
1838
    try expectIdent(index, "index");
1839
}
1840
1841
/// Test parsing array slicing expressions.
1842
@test fn testParseArraySlicing() throws (testing::TestError) {
1843
    // Test `array[start..end]`.
1844
    {
1845
        let expr = try! parseExprStr("array[1..10]");
1846
        let case ast::NodeValue::Subscript { container: subContainer, index: subIndex } = expr.value
1847
            else throw testing::TestError::Failed;
1848
        try expectIdent(subContainer, "array");
1849
1850
        let case ast::NodeValue::Range(range) = subIndex.value
1851
            else throw testing::TestError::Failed;
1852
        let start = range.start
1853
            else throw testing::TestError::Failed;
1854
        let end = range.end
1855
            else throw testing::TestError::Failed;
1856
        try expectNumber(start, "1");
1857
        try expectNumber(end, "10");
1858
    }
1859
    // Test `array[start..]`.
1860
    {
1861
        let expr = try! parseExprStr("array[5..]");
1862
        let case ast::NodeValue::Subscript { container: subContainer, index: subIndex } = expr.value
1863
            else throw testing::TestError::Failed;
1864
        try expectIdent(subContainer, "array");
1865
1866
        let case ast::NodeValue::Range(range) = subIndex.value
1867
            else throw testing::TestError::Failed;
1868
        let start = range.start
1869
            else throw testing::TestError::Failed;
1870
        try expectNumber(start, "5");
1871
        try testing::expect(range.end == nil);
1872
    }
1873
    // Test `array[..end]`.
1874
    {
1875
        let expr = try! parseExprStr("array[..10]");
1876
        let case ast::NodeValue::Subscript { container: subContainer, index: subIndex } = expr.value
1877
            else throw testing::TestError::Failed;
1878
        try expectIdent(subContainer, "array");
1879
1880
        let case ast::NodeValue::Range(range) = subIndex.value
1881
            else throw testing::TestError::Failed;
1882
        try testing::expect(range.start == nil);
1883
        let end = range.end
1884
            else throw testing::TestError::Failed;
1885
        try expectNumber(end, "10");
1886
    }
1887
    // Test `array[..]`.
1888
    {
1889
        let expr = try! parseExprStr("array[..]");
1890
        let case ast::NodeValue::Subscript { container: subContainer, index: subIndex } = expr.value
1891
            else throw testing::TestError::Failed;
1892
        try expectIdent(subContainer, "array");
1893
1894
        let case ast::NodeValue::Range(range) = subIndex.value
1895
            else throw testing::TestError::Failed;
1896
        try testing::expect(range.start == nil);
1897
        try testing::expect(range.end == nil);
1898
    }
1899
}
1900
1901
/// Test parsing function call expression.
1902
@test fn testParseFunctionCall() throws (testing::TestError) {
1903
    let root = try! parseExprStr("func(x, y)");
1904
    let case ast::NodeValue::Call(call) = root.value
1905
        else throw testing::TestError::Failed;
1906
1907
    try expectIdent(call.callee, "func");
1908
    try testing::expect(call.args.len == 2);
1909
    try expectIdent(call.args[0], "x");
1910
    try expectIdent(call.args[1], "y");
1911
}
1912
1913
/// Test parsing chained postfix operators.
1914
@test fn testParseChainedPostfix() throws (testing::TestError) {
1915
    let root = try! parseExprStr("obj.method(arg)[0]");
1916
    let case ast::NodeValue::Subscript { container: subContainer, index: subIndex } = root.value
1917
        else throw testing::TestError::Failed;
1918
1919
    let case ast::NodeValue::Call(call) = subContainer.value
1920
        else throw testing::TestError::Failed;
1921
1922
    let case ast::NodeValue::FieldAccess(fieldAccess) = call.callee.value
1923
        else throw testing::TestError::Failed;
1924
1925
    try expectIdent(fieldAccess.parent, "obj");
1926
    try expectIdent(fieldAccess.child, "method");
1927
    try testing::expect(call.args.len == 1);
1928
    try expectIdent(call.args[0], "arg");
1929
}
1930
1931
/// Test parsing a literal cast using `as`.
1932
@test fn testParseAsCastLiteral() throws (testing::TestError) {
1933
    let root = try! parseExprStr("1 as i32");
1934
    let case ast::NodeValue::As(asExpr) = root.value
1935
        else throw testing::TestError::Failed;
1936
1937
    let case ast::NodeValue::Number(_) = asExpr.value.value
1938
        else throw testing::TestError::Failed;
1939
1940
    try expectIntType(asExpr.type, 4, ast::Signedness::Signed);
1941
}
1942
1943
/// Test parsing a cast following chained postfix expressions.
1944
@test fn testParseAsCastWithPostfix() throws (testing::TestError) {
1945
    let root = try! parseExprStr("value.method(arg) as u32");
1946
    let case ast::NodeValue::As(asExpr) = root.value
1947
        else throw testing::TestError::Failed;
1948
1949
    let case ast::NodeValue::Call(call) = asExpr.value.value
1950
        else throw testing::TestError::Failed;
1951
1952
    let case ast::NodeValue::FieldAccess(access) = call.callee.value
1953
        else throw testing::TestError::Failed;
1954
1955
    try expectIdent(access.parent, "value");
1956
    try expectIdent(access.child, "method");
1957
    try testing::expect(call.args.len == 1);
1958
    try expectIdent(call.args[0], "arg");
1959
    try expectIntType(asExpr.type, 4, ast::Signedness::Unsigned);
1960
}
1961
1962
/// Test parsing @sizeOf builtin.
1963
@test fn testParseBuiltinSizeOf() throws (testing::TestError) {
1964
    let expr = try! parseExprStr("@sizeOf(i32)");
1965
    let case ast::NodeValue::BuiltinCall { kind: builtinKind, args: builtinArgs } = expr.value
1966
        else throw testing::TestError::Failed;
1967
1968
    try testing::expect(builtinKind == ast::Builtin::SizeOf);
1969
    try testing::expect(builtinArgs.len == 1);
1970
    try expectType(builtinArgs[0], ast::TypeSig::Integer {
1971
        width: 4,
1972
        sign: ast::Signedness::Signed,
1973
    });
1974
}
1975
1976
/// Test parsing @alignOf builtin.
1977
@test fn testParseBuiltinAlignOf() throws (testing::TestError) {
1978
    let expr = try! parseExprStr("@alignOf(i32)");
1979
    let case ast::NodeValue::BuiltinCall { kind: builtinKind, args: builtinArgs } = expr.value
1980
        else throw testing::TestError::Failed;
1981
1982
    try testing::expect(builtinKind == ast::Builtin::AlignOf);
1983
    try testing::expect(builtinArgs.len == 1);
1984
    try expectType(builtinArgs[0], ast::TypeSig::Integer {
1985
        width: 4,
1986
        sign: ast::Signedness::Signed,
1987
    });
1988
}
1989
1990
/// Test parsing @sliceOf with varying argument counts.
1991
@test fn testParseBuiltinSliceOf() throws (testing::TestError) {
1992
    // Two arguments.
1993
    {
1994
        let expr = try! parseExprStr("@sliceOf(ptr, len)");
1995
        let case ast::NodeValue::BuiltinCall { kind: builtinKind, args: builtinArgs } = expr.value
1996
            else throw testing::TestError::Failed;
1997
        try testing::expect(builtinKind == ast::Builtin::SliceOf);
1998
        try testing::expect(builtinArgs.len == 2);
1999
    }
2000
    // One argument.
2001
    {
2002
        let expr = try! parseExprStr("@sliceOf(ptr)");
2003
        let case ast::NodeValue::BuiltinCall { kind: builtinKind, args: builtinArgs } = expr.value
2004
            else throw testing::TestError::Failed;
2005
        try testing::expect(builtinKind == ast::Builtin::SliceOf);
2006
        try testing::expect(builtinArgs.len == 1);
2007
    }
2008
    // Three arguments.
2009
    {
2010
        let expr = try! parseExprStr("@sliceOf(ptr, len, extra)");
2011
        let case ast::NodeValue::BuiltinCall { kind: builtinKind, args: builtinArgs } = expr.value
2012
            else throw testing::TestError::Failed;
2013
        try testing::expect(builtinKind == ast::Builtin::SliceOf);
2014
        try testing::expect(builtinArgs.len == 3);
2015
    }
2016
}
2017
2018
/// Test parsing prefix unary operators.
2019
@test fn testParseUnaryOperators() throws (testing::TestError) {
2020
    {
2021
        let notExpr = try! parseExprStr("not flag");
2022
        let case ast::NodeValue::UnOp(notNode) = notExpr.value
2023
            else throw testing::TestError::Failed;
2024
        try testing::expect(notNode.op == ast::UnaryOp::Not);
2025
        try expectIdent(notNode.value, "flag");
2026
    }
2027
    {
2028
        let negExpr = try! parseExprStr("-value");
2029
        let case ast::NodeValue::UnOp(negNode) = negExpr.value
2030
            else throw testing::TestError::Failed;
2031
        try testing::expect(negNode.op == ast::UnaryOp::Neg);
2032
        try expectIdent(negNode.value, "value");
2033
    }
2034
    {
2035
        let bitNotExpr = try! parseExprStr("~mask");
2036
        let case ast::NodeValue::UnOp(bitNotNode) = bitNotExpr.value
2037
            else throw testing::TestError::Failed;
2038
        try testing::expect(bitNotNode.op == ast::UnaryOp::BitNot);
2039
        try expectIdent(bitNotNode.value, "mask");
2040
    }
2041
}
2042
2043
/// Test parsing dereference expressions.
2044
@test fn testParseDereference() throws (testing::TestError) {
2045
    {
2046
        let derefExpr = try! parseExprStr("*ptr");
2047
        let case ast::NodeValue::Deref(target) = derefExpr.value
2048
            else throw testing::TestError::Failed;
2049
        try expectIdent(target, "ptr");
2050
    }
2051
    {
2052
        let derefField = try! parseExprStr("*ptr.field");
2053
        let case ast::NodeValue::Deref(target) = derefField.value
2054
            else throw testing::TestError::Failed;
2055
        let case ast::NodeValue::FieldAccess(access) = target.value
2056
            else throw testing::TestError::Failed;
2057
        try expectIdent(access.parent, "ptr");
2058
        try expectIdent(access.child, "field");
2059
    }
2060
}
2061
2062
/// Test parsing reference (address-of) expressions.
2063
@test fn testParseReferences() throws (testing::TestError) {
2064
    {
2065
        let refExpr = try! parseExprStr("&foo");
2066
        let case ast::NodeValue::AddressOf(refNode) = refExpr.value
2067
            else throw testing::TestError::Failed;
2068
        try testing::expect(refNode.mutable == false);
2069
        try expectIdent(refNode.target, "foo");
2070
    }
2071
    {
2072
        let mutRefExpr = try! parseExprStr("&mut bar");
2073
        let case ast::NodeValue::AddressOf(mutRefNode) = mutRefExpr.value
2074
            else throw testing::TestError::Failed;
2075
        try testing::expect(mutRefNode.mutable == true);
2076
        try expectIdent(mutRefNode.target, "bar");
2077
    }
2078
    {
2079
        let refFieldExpr = try! parseExprStr("&obj.field");
2080
        let case ast::NodeValue::AddressOf(refFieldNode) = refFieldExpr.value
2081
            else throw testing::TestError::Failed;
2082
        try testing::expect(refFieldNode.mutable == false);
2083
        let case ast::NodeValue::FieldAccess(access) = refFieldNode.target.value
2084
            else throw testing::TestError::Failed;
2085
        try expectIdent(access.parent, "obj");
2086
        try expectIdent(access.child, "field");
2087
    }
2088
    {
2089
        let mutRefFieldExpr = try! parseExprStr("&mut obj.field");
2090
        let case ast::NodeValue::AddressOf(mutRefFieldNode) = mutRefFieldExpr.value
2091
            else throw testing::TestError::Failed;
2092
        try testing::expect(mutRefFieldNode.mutable == true);
2093
        let case ast::NodeValue::FieldAccess(access) = mutRefFieldNode.target.value
2094
            else throw testing::TestError::Failed;
2095
        try expectIdent(access.parent, "obj");
2096
        try expectIdent(access.child, "field");
2097
    }
2098
}
2099
2100
/// Test unary operator precedence relative to binary and postfix expressions.
2101
@test fn testParseUnaryPrecedence() throws (testing::TestError) {
2102
    {
2103
        let expr = try! parseExprStr("not a and b");
2104
        let case ast::NodeValue::BinOp(bin) = expr.value
2105
            else throw testing::TestError::Failed;
2106
        try testing::expect(bin.op == ast::BinaryOp::And);
2107
        let case ast::NodeValue::UnOp(leftUnary) = bin.left.value
2108
            else throw testing::TestError::Failed;
2109
        try testing::expect(leftUnary.op == ast::UnaryOp::Not);
2110
        try expectIdent(leftUnary.value, "a");
2111
        try expectIdent(bin.right, "b");
2112
    }
2113
    {
2114
        let mulExpr = try! parseExprStr("-x * y");
2115
        let case ast::NodeValue::BinOp(mul) = mulExpr.value
2116
            else throw testing::TestError::Failed;
2117
        try testing::expect(mul.op == ast::BinaryOp::Mul);
2118
        let case ast::NodeValue::UnOp(leftNeg) = mul.left.value
2119
            else throw testing::TestError::Failed;
2120
        try testing::expect(leftNeg.op == ast::UnaryOp::Neg);
2121
        try expectIdent(leftNeg.value, "x");
2122
        try expectIdent(mul.right, "y");
2123
    }
2124
    {
2125
        let callExpr = try! parseExprStr("not func()");
2126
        let case ast::NodeValue::UnOp(callNot) = callExpr.value
2127
            else throw testing::TestError::Failed;
2128
        try testing::expect(callNot.op == ast::UnaryOp::Not);
2129
        let case ast::NodeValue::Call(call) = callNot.value.value
2130
            else throw testing::TestError::Failed;
2131
        try expectIdent(call.callee, "func");
2132
    }
2133
}
2134
2135
/// Test parsing assignment expressions.
2136
@test fn testParseAssignment() throws (testing::TestError) {
2137
    {
2138
        let assign = try! parseStmtStr("x = 1;");
2139
        let case ast::NodeValue::Assign(node) = assign.value
2140
            else throw testing::TestError::Failed;
2141
        try expectIdent(node.left, "x");
2142
        let case ast::NodeValue::Number(_) = node.right.value
2143
            else throw testing::TestError::Failed;
2144
    }
2145
    {
2146
        let assign = try! parseStmtStr("obj.field = value;");
2147
        let case ast::NodeValue::Assign(node) = assign.value
2148
            else throw testing::TestError::Failed;
2149
        let case ast::NodeValue::FieldAccess(access) = node.left.value
2150
            else throw testing::TestError::Failed;
2151
        try expectIdent(access.parent, "obj");
2152
        try expectIdent(access.child, "field");
2153
        try expectIdent(node.right, "value");
2154
    }
2155
    {
2156
        let assign = try! parseStmtStr("*ptr = rhs;");
2157
        let case ast::NodeValue::Assign(node) = assign.value
2158
            else throw testing::TestError::Failed;
2159
        let case ast::NodeValue::Deref(target) = node.left.value
2160
            else throw testing::TestError::Failed;
2161
        try expectIdent(target, "ptr");
2162
        try expectIdent(node.right, "rhs");
2163
    }
2164
    {
2165
        let assign = try! parseStmtStr("x = 1 + 2;");
2166
        let case ast::NodeValue::Assign(node) = assign.value
2167
            else throw testing::TestError::Failed;
2168
        let case ast::NodeValue::BinOp(bin) = node.right.value
2169
            else throw testing::TestError::Failed;
2170
        try testing::expect(bin.op == ast::BinaryOp::Add);
2171
    }
2172
}
2173
2174
/// Test parsing basic arithmetic binary operators (+, -, *, /, %).
2175
@test fn testParseBinOpArithmetic() throws (testing::TestError) {
2176
    let add = try! parseExprStr("a + b");
2177
    let case ast::NodeValue::BinOp(op1) = add.value
2178
        else throw testing::TestError::Failed;
2179
    try testing::expect(op1.op == ast::BinaryOp::Add);
2180
    try expectIdent(op1.left, "a");
2181
    try expectIdent(op1.right, "b");
2182
2183
    let sub = try! parseExprStr("x - y");
2184
    let case ast::NodeValue::BinOp(op2) = sub.value
2185
        else throw testing::TestError::Failed;
2186
    try testing::expect(op2.op == ast::BinaryOp::Sub);
2187
2188
    let mul = try! parseExprStr("a * b");
2189
    let case ast::NodeValue::BinOp(op3) = mul.value
2190
        else throw testing::TestError::Failed;
2191
    try testing::expect(op3.op == ast::BinaryOp::Mul);
2192
2193
    let div = try! parseExprStr("x / y");
2194
    let case ast::NodeValue::BinOp(op4) = div.value
2195
        else throw testing::TestError::Failed;
2196
    try testing::expect(op4.op == ast::BinaryOp::Div);
2197
2198
    let modOp = try! parseExprStr("a % b");
2199
    let case ast::NodeValue::BinOp(op5) = modOp.value
2200
        else throw testing::TestError::Failed;
2201
    try testing::expect(op5.op == ast::BinaryOp::Mod);
2202
}
2203
2204
/// Test parsing comparison binary operators (==, !=).
2205
@test fn testParseBinOpEq() throws (testing::TestError) {
2206
    let eq = try! parseExprStr("a == b");
2207
    let case ast::NodeValue::BinOp(op1) = eq.value
2208
        else throw testing::TestError::Failed;
2209
    try testing::expect(op1.op == ast::BinaryOp::Eq);
2210
2211
    let ne = try! parseExprStr("x != y");
2212
    let case ast::NodeValue::BinOp(op2) = ne.value
2213
        else throw testing::TestError::Failed;
2214
    try testing::expect(op2.op == ast::BinaryOp::Ne);
2215
}
2216
2217
/// Test parsing comparison binary operators.
2218
@test fn testParseBinOpGtLt() throws (testing::TestError) {
2219
    let lt = try! parseExprStr("a < b");
2220
    let case ast::NodeValue::BinOp(op1) = lt.value
2221
        else throw testing::TestError::Failed;
2222
    try testing::expect(op1.op == ast::BinaryOp::Lt);
2223
2224
    let gt = try! parseExprStr("x > y");
2225
    let case ast::NodeValue::BinOp(op2) = gt.value
2226
        else throw testing::TestError::Failed;
2227
    try testing::expect(op2.op == ast::BinaryOp::Gt);
2228
2229
    let lte = try! parseExprStr("a <= b");
2230
    let case ast::NodeValue::BinOp(op3) = lte.value
2231
        else throw testing::TestError::Failed;
2232
    try testing::expect(op3.op == ast::BinaryOp::Lte);
2233
2234
    let gte = try! parseExprStr("x >= y");
2235
    let case ast::NodeValue::BinOp(op4) = gte.value
2236
        else throw testing::TestError::Failed;
2237
    try testing::expect(op4.op == ast::BinaryOp::Gte);
2238
}
2239
2240
/// Test parsing bitwise binary operators (&, |, ^, <<, >>).
2241
@test fn testParseBinOpBitwise() throws (testing::TestError) {
2242
    let bitAnd = try! parseExprStr("a & b");
2243
    let case ast::NodeValue::BinOp(op1) = bitAnd.value
2244
        else throw testing::TestError::Failed;
2245
    try testing::expect(op1.op == ast::BinaryOp::BitAnd);
2246
2247
    let bitOr = try! parseExprStr("x | y");
2248
    let case ast::NodeValue::BinOp(op2) = bitOr.value
2249
        else throw testing::TestError::Failed;
2250
    try testing::expect(op2.op == ast::BinaryOp::BitOr);
2251
2252
    let bitXor = try! parseExprStr("a ^ b");
2253
    let case ast::NodeValue::BinOp(op3) = bitXor.value
2254
        else throw testing::TestError::Failed;
2255
    try testing::expect(op3.op == ast::BinaryOp::BitXor);
2256
2257
    let shl = try! parseExprStr("x << y");
2258
    let case ast::NodeValue::BinOp(op4) = shl.value
2259
        else throw testing::TestError::Failed;
2260
    try testing::expect(op4.op == ast::BinaryOp::Shl);
2261
2262
    let shr = try! parseExprStr("a >> b");
2263
    let case ast::NodeValue::BinOp(op5) = shr.value
2264
        else throw testing::TestError::Failed;
2265
    try testing::expect(op5.op == ast::BinaryOp::Shr);
2266
}
2267
2268
/// Test parsing logical binary operators (and, or).
2269
@test fn testParseBinOpLogical() throws (testing::TestError) {
2270
    let andOp = try! parseExprStr("a and b");
2271
    let case ast::NodeValue::BinOp(op1) = andOp.value
2272
        else throw testing::TestError::Failed;
2273
    try testing::expect(op1.op == ast::BinaryOp::And);
2274
    try expectIdent(op1.left, "a");
2275
    try expectIdent(op1.right, "b");
2276
2277
    let orOp = try! parseExprStr("x or y");
2278
    let case ast::NodeValue::BinOp(op2) = orOp.value
2279
        else throw testing::TestError::Failed;
2280
    try testing::expect(op2.op == ast::BinaryOp::Or);
2281
    try expectIdent(op2.left, "x");
2282
    try expectIdent(op2.right, "y");
2283
}
2284
2285
/// Test operator precedence: multiplication before addition.
2286
@test fn testParseBinOpPrecedenceMulAdd() throws (testing::TestError) {
2287
    let root = try! parseExprStr("a + b * c");
2288
    let case ast::NodeValue::BinOp(add) = root.value
2289
        else throw testing::TestError::Failed;
2290
2291
    try testing::expect(add.op == ast::BinaryOp::Add);
2292
    try expectIdent(add.left, "a");
2293
2294
    let case ast::NodeValue::BinOp(mul) = add.right.value
2295
        else throw testing::TestError::Failed;
2296
2297
    try testing::expect(mul.op == ast::BinaryOp::Mul);
2298
    try expectIdent(mul.left, "b");
2299
    try expectIdent(mul.right, "c");
2300
}
2301
2302
/// Test operator precedence: shifts before bitwise operations.
2303
@test fn testParseBinOpPrecedenceShiftBitwise() throws (testing::TestError) {
2304
    let root = try! parseExprStr("a & b << c");
2305
    let case ast::NodeValue::BinOp(bitAnd) = root.value
2306
        else throw testing::TestError::Failed;
2307
2308
    try testing::expect(bitAnd.op == ast::BinaryOp::BitAnd);
2309
    try expectIdent(bitAnd.left, "a");
2310
2311
    let case ast::NodeValue::BinOp(shl) = bitAnd.right.value
2312
        else throw testing::TestError::Failed;
2313
2314
    try testing::expect(shl.op == ast::BinaryOp::Shl);
2315
    try expectIdent(shl.left, "b");
2316
    try expectIdent(shl.right, "c");
2317
}
2318
2319
/// Test operator precedence: comparison before logical AND.
2320
@test fn testParseBinOpPrecedenceCompareLogical() throws (testing::TestError) {
2321
    let root = try! parseExprStr("a < b and c > d");
2322
    let case ast::NodeValue::BinOp(andOp) = root.value
2323
        else throw testing::TestError::Failed;
2324
2325
    try testing::expect(andOp.op == ast::BinaryOp::And);
2326
2327
    let case ast::NodeValue::BinOp(lt) = andOp.left.value
2328
        else throw testing::TestError::Failed;
2329
    try testing::expect(lt.op == ast::BinaryOp::Lt);
2330
    try expectIdent(lt.left, "a");
2331
    try expectIdent(lt.right, "b");
2332
2333
    let case ast::NodeValue::BinOp(gt) = andOp.right.value
2334
        else throw testing::TestError::Failed;
2335
    try testing::expect(gt.op == ast::BinaryOp::Gt);
2336
    try expectIdent(gt.left, "c");
2337
    try expectIdent(gt.right, "d");
2338
}
2339
2340
/// Test left associativity of addition.
2341
@test fn testParseBinOpAssociativityAdd() throws (testing::TestError) {
2342
    let root = try! parseExprStr("a + b + c");
2343
    let case ast::NodeValue::BinOp(add2) = root.value
2344
        else throw testing::TestError::Failed;
2345
2346
    try testing::expect(add2.op == ast::BinaryOp::Add);
2347
    try expectIdent(add2.right, "c");
2348
2349
    let case ast::NodeValue::BinOp(add1) = add2.left.value
2350
        else throw testing::TestError::Failed;
2351
    try testing::expect(add1.op == ast::BinaryOp::Add);
2352
    try expectIdent(add1.left, "a");
2353
    try expectIdent(add1.right, "b");
2354
}
2355
2356
/// Test complex expression with multiple operators and precedence.
2357
@test fn testParseBinOpComplex() throws (testing::TestError) {
2358
    let root = try! parseExprStr("a + b * c - d / e");
2359
    let case ast::NodeValue::BinOp(sub) = root.value
2360
        else throw testing::TestError::Failed;
2361
2362
    try testing::expect(sub.op == ast::BinaryOp::Sub);
2363
2364
    let case ast::NodeValue::BinOp(add) = sub.left.value
2365
        else throw testing::TestError::Failed;
2366
    try testing::expect(add.op == ast::BinaryOp::Add);
2367
    try expectIdent(add.left, "a");
2368
2369
    let case ast::NodeValue::BinOp(mul) = add.right.value
2370
        else throw testing::TestError::Failed;
2371
    try testing::expect(mul.op == ast::BinaryOp::Mul);
2372
2373
    let case ast::NodeValue::BinOp(div) = sub.right.value
2374
        else throw testing::TestError::Failed;
2375
    try testing::expect(div.op == ast::BinaryOp::Div);
2376
}
2377
2378
/// Test binary operators with parentheses override precedence.
2379
@test fn testParseBinOpParentheses() throws (testing::TestError) {
2380
    let root = try! parseExprStr("(a + b) * c");
2381
    let case ast::NodeValue::BinOp(mul) = root.value
2382
        else throw testing::TestError::Failed;
2383
2384
    try testing::expect(mul.op == ast::BinaryOp::Mul);
2385
    try expectIdent(mul.right, "c");
2386
2387
    let case ast::NodeValue::BinOp(add) = mul.left.value
2388
        else throw testing::TestError::Failed;
2389
    try testing::expect(add.op == ast::BinaryOp::Add);
2390
    try expectIdent(add.left, "a");
2391
    try expectIdent(add.right, "b");
2392
}
2393
2394
/// Test parsing a simple union without payloads.
2395
@test fn testParseEnumSimple() throws (testing::TestError) {
2396
    let node = try! parseStmtStr("union Color { Red, Green, Blue }");
2397
    let case ast::NodeValue::UnionDecl(decl) = node.value
2398
        else throw testing::TestError::Failed;
2399
2400
    try expectIdent(decl.name, "Color");
2401
    try testing::expect(decl.derives.len == 0);
2402
2403
    let variants = decl.variants;
2404
    try testing::expect(variants.len == 3);
2405
2406
    let v0 = variants[0];
2407
    let case ast::NodeValue::UnionDeclVariant(var0) = v0.value
2408
        else throw testing::TestError::Failed;
2409
    try expectIdent(var0.name, "Red");
2410
    try testing::expect(var0.index == 0);
2411
    try testing::expect(var0.type == nil);
2412
    try testing::expect(var0.value == nil);
2413
2414
    let v1 = variants[1];
2415
    let case ast::NodeValue::UnionDeclVariant(var1) = v1.value
2416
        else throw testing::TestError::Failed;
2417
    try expectIdent(var1.name, "Green");
2418
    try testing::expect(var1.index == 1);
2419
    try testing::expect(var1.type == nil);
2420
    try testing::expect(var1.value == nil);
2421
2422
    let v2 = variants[2];
2423
    let case ast::NodeValue::UnionDeclVariant(var2) = v2.value
2424
        else throw testing::TestError::Failed;
2425
    try expectIdent(var2.name, "Blue");
2426
    try testing::expect(var2.index == 2);
2427
    try testing::expect(var2.type == nil);
2428
    try testing::expect(var2.value == nil);
2429
}
2430
2431
/// Test parsing a union with trailing comma.
2432
@test fn testParseEnumTrailingComma() throws (testing::TestError) {
2433
    let node = try! parseStmtStr("union Letter { A, B, C, }");
2434
    let case ast::NodeValue::UnionDecl(decl) = node.value
2435
        else throw testing::TestError::Failed;
2436
2437
    try expectIdent(decl.name, "Letter");
2438
    try testing::expect(decl.variants.len == 3);
2439
}
2440
2441
/// Test parsing a union with explicit values.
2442
@test fn testParseEnumExplicitValues() throws (testing::TestError) {
2443
    let node = try! parseStmtStr("union Status { Ok = 0, Error = 1, Pending = 5 }");
2444
    let case ast::NodeValue::UnionDecl(decl) = node.value
2445
        else throw testing::TestError::Failed;
2446
2447
    try expectIdent(decl.name, "Status");
2448
2449
    let variants = decl.variants;
2450
    try testing::expect(variants.len == 3);
2451
2452
    let v0 = variants[0];
2453
    let case ast::NodeValue::UnionDeclVariant(var0) = v0.value
2454
        else throw testing::TestError::Failed;
2455
    try expectIdent(var0.name, "Ok");
2456
    try testing::expect(var0.index == 0);
2457
    try testing::expect(var0.type == nil);
2458
    try testing::expect(var0.value != nil);
2459
2460
    let v1 = variants[1];
2461
    let case ast::NodeValue::UnionDeclVariant(var1) = v1.value
2462
        else throw testing::TestError::Failed;
2463
    try expectIdent(var1.name, "Error");
2464
    try testing::expect(var1.index == 1);
2465
    try testing::expect(var1.value != nil);
2466
2467
    let v2 = variants[2];
2468
    let case ast::NodeValue::UnionDeclVariant(var2) = v2.value
2469
        else throw testing::TestError::Failed;
2470
    try expectIdent(var2.name, "Pending");
2471
    try testing::expect(var2.index == 2);
2472
    try testing::expect(var2.value != nil);
2473
}
2474
2475
/// Test parsing a union with payload types.
2476
@test fn testParseEnumWithPayloads() throws (testing::TestError) {
2477
    let node = try! parseStmtStr("union Result { Ok(bool), Error(void) }");
2478
    let case ast::NodeValue::UnionDecl(decl) = node.value
2479
        else throw testing::TestError::Failed;
2480
2481
    try expectIdent(decl.name, "Result");
2482
    try testing::expect(decl.variants.len == 2);
2483
2484
    let okFields = try expectVariant(decl.variants[0], "Ok", 0);
2485
    try testing::expect(okFields.len == 1);
2486
    try expectFieldSig(okFields, 0, nil, ast::TypeSig::Bool);
2487
2488
    let errFields = try expectVariant(decl.variants[1], "Error", 1);
2489
    try testing::expect(errFields.len == 1);
2490
    try expectFieldSig(errFields, 0, nil, ast::TypeSig::Void);
2491
}
2492
2493
/// Test parsing a union with derives.
2494
@test fn testParseEnumWithDerives() throws (testing::TestError) {
2495
    let node = try! parseStmtStr("union Option: Debug + Eq { None, Some(i32) }");
2496
    let case ast::NodeValue::UnionDecl(decl) = node.value
2497
        else throw testing::TestError::Failed;
2498
2499
    try expectIdent(decl.name, "Option");
2500
    try testing::expect(decl.derives.len == 2);
2501
    try expectIdent(decl.derives[0], "Debug");
2502
    try expectIdent(decl.derives[1], "Eq");
2503
2504
    let variants = decl.variants;
2505
    try testing::expect(variants.len == 2);
2506
2507
    let v0 = variants[0];
2508
    let case ast::NodeValue::UnionDeclVariant(var0) = v0.value
2509
        else throw testing::TestError::Failed;
2510
    try expectIdent(var0.name, "None");
2511
    try testing::expect(var0.type == nil);
2512
2513
    let v1 = variants[1];
2514
    let case ast::NodeValue::UnionDeclVariant(var1) = v1.value
2515
        else throw testing::TestError::Failed;
2516
    try expectIdent(var1.name, "Some");
2517
    try testing::expect(var1.type != nil);
2518
}
2519
2520
/// Test parsing named record literals with named fields.
2521
@test fn testParseNamedRecordLiteralNamed() throws (testing::TestError) {
2522
    let r1 = try! parseExprStr("Point { x: 5, y: 10 }");
2523
    let case ast::NodeValue::RecordLit(lit) = r1.value
2524
        else throw testing::TestError::Failed;
2525
2526
    let typeName = lit.typeName else throw testing::TestError::Failed;
2527
    try expectIdent(typeName, "Point");
2528
    try testing::expect(lit.fields.len == 2);
2529
2530
    let field0 = lit.fields[0];
2531
    let case ast::NodeValue::RecordLitField(arg0) = field0.value
2532
        else throw testing::TestError::Failed;
2533
    let label0 = arg0.label else throw testing::TestError::Failed;
2534
    try expectIdent(label0, "x");
2535
    try expectNumber(arg0.value, "5");
2536
}
2537
2538
/// Test parsing anonymous record literals with named fields.
2539
@test fn testParseAnonymousRecordLiteralNamed() throws (testing::TestError) {
2540
    let r1 = try! parseExprStr("{ x: 10, y: 20 }");
2541
    let case ast::NodeValue::RecordLit(lit) = r1.value
2542
        else throw testing::TestError::Failed;
2543
2544
    try testing::expect(lit.typeName == nil);
2545
    try testing::expect(lit.fields.len == 2);
2546
2547
    let field0 = lit.fields[0];
2548
    let case ast::NodeValue::RecordLitField(arg0) = field0.value
2549
        else throw testing::TestError::Failed;
2550
    let label0 = arg0.label else throw testing::TestError::Failed;
2551
    try expectIdent(label0, "x");
2552
    try expectNumber(arg0.value, "10");
2553
2554
    let field1 = lit.fields[1];
2555
    let case ast::NodeValue::RecordLitField(arg1) = field1.value
2556
        else throw testing::TestError::Failed;
2557
    let label1 = arg1.label else throw testing::TestError::Failed;
2558
    try expectIdent(label1, "y");
2559
    try expectNumber(arg1.value, "20");
2560
}
2561
2562
/// Test parsing record literals with shorthand field syntax.
2563
/// `{ x, y }` is equivalent to `{ x: x, y: y }`.
2564
@test fn testParseRecordLiteralShorthand() throws (testing::TestError) {
2565
    let r1 = try! parseExprStr("Point { x, y }");
2566
    let case ast::NodeValue::RecordLit(lit) = r1.value
2567
        else throw testing::TestError::Failed;
2568
2569
    let typeName = lit.typeName else throw testing::TestError::Failed;
2570
    try expectIdent(typeName, "Point");
2571
    try testing::expect(lit.fields.len == 2);
2572
2573
    // First field: shorthand `x`.
2574
    let field0 = lit.fields[0];
2575
    let case ast::NodeValue::RecordLitField(arg0) = field0.value
2576
        else throw testing::TestError::Failed;
2577
    let label0 = arg0.label else throw testing::TestError::Failed;
2578
    try expectIdent(label0, "x");
2579
    try expectIdent(arg0.value, "x");
2580
    // Label and value should point to the same node.
2581
    try testing::expect(label0 == arg0.value);
2582
2583
    // Second field: shorthand `y`.
2584
    let field1 = lit.fields[1];
2585
    let case ast::NodeValue::RecordLitField(arg1) = field1.value
2586
        else throw testing::TestError::Failed;
2587
    let label1 = arg1.label else throw testing::TestError::Failed;
2588
    try expectIdent(label1, "y");
2589
    try expectIdent(arg1.value, "y");
2590
    try testing::expect(label1 == arg1.value);
2591
}
2592
2593
/// Test parsing record literals with mixed shorthand and explicit fields.
2594
@test fn testParseRecordLiteralMixedShorthand() throws (testing::TestError) {
2595
    let r1 = try! parseExprStr("Point { x, y: 10 }");
2596
    let case ast::NodeValue::RecordLit(lit) = r1.value
2597
        else throw testing::TestError::Failed;
2598
2599
    try testing::expect(lit.fields.len == 2);
2600
2601
    // First field: shorthand `x`.
2602
    let field0 = lit.fields[0];
2603
    let case ast::NodeValue::RecordLitField(arg0) = field0.value
2604
        else throw testing::TestError::Failed;
2605
    let label0 = arg0.label else throw testing::TestError::Failed;
2606
    try expectIdent(label0, "x");
2607
    try expectIdent(arg0.value, "x");
2608
2609
    // Second field: explicit `y: 10`.
2610
    let field1 = lit.fields[1];
2611
    let case ast::NodeValue::RecordLitField(arg1) = field1.value
2612
        else throw testing::TestError::Failed;
2613
    let label1 = arg1.label else throw testing::TestError::Failed;
2614
    try expectIdent(label1, "y");
2615
    try expectNumber(arg1.value, "10");
2616
}
2617
2618
/// Test that positional brace initializers are rejected: `{ 1, 2 }`.
2619
@test fn testParsePositionalBraceInitializerAnonymous() throws (testing::TestError) {
2620
    let parsed: ?*ast::Node = try? parseExprStr("{ 1, 2 }");
2621
    try testing::expect(parsed == nil);
2622
}
2623
2624
/// Test that positional brace initializers are rejected: `Point { 1, 2 }`.
2625
@test fn testParsePositionalBraceInitializerNamed() throws (testing::TestError) {
2626
    let parsed: ?*ast::Node = try? parseExprStr("Point { 1, 2 }");
2627
    try testing::expect(parsed == nil);
2628
}
2629
2630
/// Test that mixed labeled/positional brace initializers are rejected: `Pt { x: 1, 2 }`.
2631
@test fn testParseMixedBraceInitializer() throws (testing::TestError) {
2632
    let parsed: ?*ast::Node = try? parseExprStr("Pt { x: 1, 2 }");
2633
    try testing::expect(parsed == nil);
2634
}
2635
2636
@test fn testParseModule() throws (testing::TestError) {
2637
    let r = try! parseStmtsStr("fn f() {} fn g() {}");
2638
2639
    let case ast::NodeValue::Block(module) = r.value
2640
        else throw testing::TestError::Failed;
2641
    try testing::expect(module.statements.len == 2);
2642
2643
    let first = module.statements[0];
2644
    let case ast::NodeValue::FnDecl(fDecl) = first.value
2645
        else throw testing::TestError::Failed;
2646
    try expectIdent(fDecl.name, "f");
2647
2648
    let second = module.statements[1];
2649
    let case ast::NodeValue::FnDecl(gDecl) = second.value
2650
        else throw testing::TestError::Failed;
2651
    try expectIdent(gDecl.name, "g");
2652
}
2653
2654
/// Test parsing a simple conditional expression.
2655
@test fn testParseCondExpr() throws (testing::TestError) {
2656
    let r = try! parseExprStr("a if cond else b") catch {
2657
        throw testing::TestError::Failed;
2658
    };
2659
    let case ast::NodeValue::CondExpr(cond) = r.value
2660
        else throw testing::TestError::Failed;
2661
2662
    try expectIdent(cond.thenExpr, "a");
2663
    try expectIdent(cond.condition, "cond");
2664
    try expectIdent(cond.elseExpr, "b");
2665
}
2666
2667
/// Test parsing a conditional expression with `as` casts.
2668
@test fn testParseCondExprWithAsCast() throws (testing::TestError) {
2669
    let r = try! parseExprStr("x as i32 if cond else y as i32") catch {
2670
        throw testing::TestError::Failed;
2671
    };
2672
    let case ast::NodeValue::CondExpr(cond) = r.value
2673
        else throw testing::TestError::Failed;
2674
2675
    // Check thenExpr is an `as` cast.
2676
    let case ast::NodeValue::As(thenAs) = cond.thenExpr.value
2677
        else throw testing::TestError::Failed;
2678
    try expectIdent(thenAs.value, "x");
2679
    try expectIntType(thenAs.type, 4, ast::Signedness::Signed);
2680
2681
    // Check condition.
2682
    try expectIdent(cond.condition, "cond");
2683
2684
    // Check elseExpr is an `as` cast.
2685
    let case ast::NodeValue::As(elseAs) = cond.elseExpr.value
2686
        else throw testing::TestError::Failed;
2687
    try expectIdent(elseAs.value, "y");
2688
    try expectIntType(elseAs.type, 4, ast::Signedness::Signed);
2689
}
2690
2691
/// Test parsing a nested conditional expression (right-associative).
2692
@test fn testParseCondExprNested() throws (testing::TestError) {
2693
    let r = try! parseExprStr("a if x else b if y else c") catch {
2694
        throw testing::TestError::Failed;
2695
    };
2696
    let case ast::NodeValue::CondExpr(outer) = r.value
2697
        else throw testing::TestError::Failed;
2698
2699
    try expectIdent(outer.thenExpr, "a");
2700
    try expectIdent(outer.condition, "x");
2701
2702
    // The else branch should be another conditional expression.
2703
    let case ast::NodeValue::CondExpr(inner) = outer.elseExpr.value
2704
        else throw testing::TestError::Failed;
2705
2706
    try expectIdent(inner.thenExpr, "b");
2707
    try expectIdent(inner.condition, "y");
2708
    try expectIdent(inner.elseExpr, "c");
2709
}
2710
2711
/// Test that trailing commas are allowed in all comma-separated lists.
2712
@test fn testTrailingCommas() throws (testing::TestError) {
2713
    // Function call arguments.
2714
    let call = try! parseExprStr("f(1, 2, 3,)");
2715
    let case ast::NodeValue::Call(c) = call.value else throw testing::TestError::Failed;
2716
    try testing::expect(c.args.len == 3);
2717
2718
    // Function parameters.
2719
    let fnNode = try! parseStmtStr("fn add(x: i32, y: i32,) {}");
2720
    let case ast::NodeValue::FnDecl(fnDecl) = fnNode.value else throw testing::TestError::Failed;
2721
    try testing::expect(fnDecl.sig.params.len == 2);
2722
2723
    // Record declarations.
2724
    let recNode = try! parseStmtStr("record R { x: i32, y: bool, }");
2725
    let case ast::NodeValue::RecordDecl(recDecl) = recNode.value else throw testing::TestError::Failed;
2726
    try testing::expect(recDecl.fields.len == 2);
2727
2728
    // Tuple record declarations.
2729
    let tupNode = try! parseStmtStr("record R(i32, bool,);");
2730
    let case ast::NodeValue::RecordDecl(tupDecl) = tupNode.value else throw testing::TestError::Failed;
2731
    try testing::expect(tupDecl.fields.len == 2);
2732
2733
    // Record literals.
2734
    let litNode = try! parseExprStr("Point { x: 1, y: 2, }");
2735
    let case ast::NodeValue::RecordLit(lit) = litNode.value else throw testing::TestError::Failed;
2736
    try testing::expect(lit.fields.len == 2);
2737
2738
    // Union declarations.
2739
    let unionNode = try! parseStmtStr("union Color { Red, Green, Blue, }");
2740
    let case ast::NodeValue::UnionDecl(unionDecl) = unionNode.value else throw testing::TestError::Failed;
2741
    try testing::expect(unionDecl.variants.len == 3);
2742
2743
    // Array literals.
2744
    let arrNode = try! parseExprStr("[1, 2, 3,]");
2745
    let case ast::NodeValue::ArrayLit(items) = arrNode.value else throw testing::TestError::Failed;
2746
    try testing::expect(items.len == 3);
2747
2748
    // Function type parameters.
2749
    let fnType = try! parseTypeStr("fn (i32, bool,) -> void");
2750
    let case ast::NodeValue::TypeSig(sigValue) = fnType.value else throw testing::TestError::Failed;
2751
    let case ast::TypeSig::Fn(sig) = sigValue else throw testing::TestError::Failed;
2752
    try testing::expect(sig.params.len == 2);
2753
2754
    // Throws lists.
2755
    let throwsNode = try! parseStmtStr("fn handle() throws (Error, Other,) {}");
2756
    let case ast::NodeValue::FnDecl(throwsDecl) = throwsNode.value else throw testing::TestError::Failed;
2757
    try testing::expect(throwsDecl.sig.throwList.len == 2);
2758
}