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