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