@@ -215,7 +215,7 @@ static AstNode *ast_parse_block_or_expression(ParseContext *pc, size_t *token_in
215
215
static AstNode *ast_parse_block_expr_or_expression (ParseContext *pc, size_t *token_index, bool mandatory);
216
216
static AstNode *ast_parse_expression (ParseContext *pc, size_t *token_index, bool mandatory);
217
217
static AstNode *ast_parse_block (ParseContext *pc, size_t *token_index, bool mandatory);
218
- static AstNode *ast_parse_if_expr (ParseContext *pc, size_t *token_index, bool mandatory);
218
+ static AstNode *ast_parse_if_try_test_expr (ParseContext *pc, size_t *token_index, bool mandatory);
219
219
static AstNode *ast_parse_block_expr (ParseContext *pc, size_t *token_index, bool mandatory);
220
220
static AstNode *ast_parse_unwrap_expr (ParseContext *pc, size_t *token_index, bool mandatory);
221
221
static AstNode *ast_parse_prefix_op_expr (ParseContext *pc, size_t *token_index, bool mandatory);
@@ -639,110 +639,6 @@ static AstNode *ast_parse_comptime_expr(ParseContext *pc, size_t *token_index, b
639
639
return node;
640
640
}
641
641
642
- /*
643
- TryExpression(body) = "try" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" option("|" Symbol "|") BlockExpression(body))
644
- */
645
- static AstNode *ast_parse_try_expr (ParseContext *pc, size_t *token_index, bool mandatory) {
646
- Token *try_token = &pc->tokens ->at (*token_index);
647
- if (try_token->id == TokenIdKeywordTry) {
648
- *token_index += 1 ;
649
- } else if (mandatory) {
650
- ast_expect_token (pc, try_token, TokenIdKeywordTry);
651
- zig_unreachable ();
652
- } else {
653
- return nullptr ;
654
- }
655
-
656
- AstNode *node = ast_create_node (pc, NodeTypeTryExpr, try_token);
657
-
658
- ast_eat_token (pc, token_index, TokenIdLParen);
659
- node->data .try_expr .target_node = ast_parse_expression (pc, token_index, true );
660
- ast_eat_token (pc, token_index, TokenIdRParen);
661
-
662
- Token *open_bar_tok = &pc->tokens ->at (*token_index);
663
- if (open_bar_tok->id == TokenIdBinOr) {
664
- *token_index += 1 ;
665
-
666
- Token *star_tok = &pc->tokens ->at (*token_index);
667
- if (star_tok->id == TokenIdStar) {
668
- *token_index += 1 ;
669
- node->data .try_expr .var_is_ptr = true ;
670
- }
671
-
672
- Token *var_name_tok = ast_eat_token (pc, token_index, TokenIdSymbol);
673
- node->data .try_expr .var_symbol = token_buf (var_name_tok);
674
-
675
- ast_eat_token (pc, token_index, TokenIdBinOr);
676
- }
677
-
678
- node->data .try_expr .then_node = ast_parse_block_or_expression (pc, token_index, true );
679
-
680
- Token *else_token = &pc->tokens ->at (*token_index);
681
- if (else_token->id == TokenIdKeywordElse) {
682
- *token_index += 1 ;
683
- Token *open_bar_tok = &pc->tokens ->at (*token_index);
684
- if (open_bar_tok->id == TokenIdBinOr) {
685
- *token_index += 1 ;
686
-
687
- Token *err_name_tok = ast_eat_token (pc, token_index, TokenIdSymbol);
688
- node->data .try_expr .err_symbol = token_buf (err_name_tok);
689
-
690
- ast_eat_token (pc, token_index, TokenIdBinOr);
691
- }
692
-
693
- node->data .try_expr .else_node = ast_parse_block_expr_or_expression (pc, token_index, true );
694
- }
695
-
696
- return node;
697
- }
698
-
699
- /*
700
- TestExpression(body) = "test" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" BlockExpression(body))
701
- */
702
- static AstNode *ast_parse_test_expr (ParseContext *pc, size_t *token_index, bool mandatory) {
703
- Token *test_token = &pc->tokens ->at (*token_index);
704
- if (test_token->id == TokenIdKeywordTest) {
705
- *token_index += 1 ;
706
- } else if (mandatory) {
707
- ast_expect_token (pc, test_token, TokenIdKeywordTest);
708
- zig_unreachable ();
709
- } else {
710
- return nullptr ;
711
- }
712
-
713
- AstNode *node = ast_create_node (pc, NodeTypeTestExpr, test_token);
714
-
715
- ast_eat_token (pc, token_index, TokenIdLParen);
716
- node->data .test_expr .target_node = ast_parse_expression (pc, token_index, true );
717
- ast_eat_token (pc, token_index, TokenIdRParen);
718
-
719
- Token *open_bar_tok = &pc->tokens ->at (*token_index);
720
- if (open_bar_tok->id == TokenIdBinOr) {
721
- *token_index += 1 ;
722
-
723
- Token *star_tok = &pc->tokens ->at (*token_index);
724
- if (star_tok->id == TokenIdStar) {
725
- *token_index += 1 ;
726
- node->data .test_expr .var_is_ptr = true ;
727
- }
728
-
729
- Token *var_name_tok = ast_eat_token (pc, token_index, TokenIdSymbol);
730
- node->data .test_expr .var_symbol = token_buf (var_name_tok);
731
-
732
- ast_eat_token (pc, token_index, TokenIdBinOr);
733
- }
734
-
735
- node->data .test_expr .then_node = ast_parse_block_or_expression (pc, token_index, true );
736
-
737
- Token *else_token = &pc->tokens ->at (*token_index);
738
- if (else_token->id == TokenIdKeywordElse) {
739
- *token_index += 1 ;
740
- node->data .test_expr .else_node = ast_parse_block_expr_or_expression (pc, token_index, true );
741
- }
742
-
743
- return node;
744
- }
745
-
746
642
/*
747
643
PrimaryExpression = Number | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl
748
644
KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "this" | "unreachable"
@@ -1434,8 +1330,10 @@ static AstNode *ast_parse_bool_and_expr(ParseContext *pc, size_t *token_index, b
1434
1330
1435
1331
/*
1436
1332
IfExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body))
1333
+ TryExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body "else" "|" Symbol "|" BlockExpression(body)
1334
+ TestExpression(body) = "if" "(" Expression ")" "|" option("*") Symbol "|" body option("else" BlockExpression(body))
1437
1335
*/
1438
- static AstNode *ast_parse_if_expr (ParseContext *pc, size_t *token_index, bool mandatory) {
1336
+ static AstNode *ast_parse_if_try_test_expr (ParseContext *pc, size_t *token_index, bool mandatory) {
1439
1337
Token *if_token = &pc->tokens ->at (*token_index);
1440
1338
1441
1339
if (if_token->id == TokenIdKeywordIf) {
@@ -1448,19 +1346,72 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, size_t *token_index, bool ma
1448
1346
}
1449
1347
1450
1348
ast_eat_token (pc, token_index, TokenIdLParen);
1451
-
1452
- AstNode *node = ast_create_node (pc, NodeTypeIfBoolExpr, if_token);
1453
- node->data .if_bool_expr .condition = ast_parse_expression (pc, token_index, true );
1349
+ AstNode *condition = ast_parse_expression (pc, token_index, true );
1454
1350
ast_eat_token (pc, token_index, TokenIdRParen);
1455
- node->data .if_bool_expr .then_block = ast_parse_block_or_expression (pc, token_index, true );
1456
1351
1457
- Token *else_token = &pc->tokens ->at (*token_index);
1458
- if (else_token->id == TokenIdKeywordElse) {
1352
+ Token *open_bar_tok = &pc->tokens ->at (*token_index);
1353
+ Token *var_name_tok = nullptr ;
1354
+ bool var_is_ptr = false ;
1355
+ if (open_bar_tok->id == TokenIdBinOr) {
1356
+ *token_index += 1 ;
1357
+
1358
+ Token *star_tok = &pc->tokens ->at (*token_index);
1359
+ if (star_tok->id == TokenIdStar) {
1360
+ *token_index += 1 ;
1361
+ var_is_ptr = true ;
1362
+ }
1363
+
1364
+ var_name_tok = ast_eat_token (pc, token_index, TokenIdSymbol);
1365
+
1366
+ ast_eat_token (pc, token_index, TokenIdBinOr);
1367
+ }
1368
+
1369
+ AstNode *body_node = ast_parse_block_or_expression (pc, token_index, true );
1370
+
1371
+ Token *else_tok = &pc->tokens ->at (*token_index);
1372
+ AstNode *else_node = nullptr ;
1373
+ Token *err_name_tok = nullptr ;
1374
+ if (else_tok->id == TokenIdKeywordElse) {
1459
1375
*token_index += 1 ;
1460
- node->data .if_bool_expr .else_node = ast_parse_block_expr_or_expression (pc, token_index, true );
1376
+
1377
+ Token *else_bar_tok = &pc->tokens ->at (*token_index);
1378
+ if (else_bar_tok->id == TokenIdBinOr) {
1379
+ *token_index += 1 ;
1380
+
1381
+ err_name_tok = ast_eat_token (pc, token_index, TokenIdSymbol);
1382
+
1383
+ ast_eat_token (pc, token_index, TokenIdBinOr);
1384
+ }
1385
+
1386
+ else_node = ast_parse_block_expr_or_expression (pc, token_index, true );
1461
1387
}
1462
1388
1463
- return node;
1389
+ if (err_name_tok != nullptr ) {
1390
+ AstNode *node = ast_create_node (pc, NodeTypeTryExpr, if_token);
1391
+ node->data .try_expr .target_node = condition;
1392
+ node->data .try_expr .var_is_ptr = var_is_ptr;
1393
+ if (var_name_tok != nullptr ) {
1394
+ node->data .try_expr .var_symbol = token_buf (var_name_tok);
1395
+ }
1396
+ node->data .try_expr .then_node = body_node;
1397
+ node->data .try_expr .err_symbol = token_buf (err_name_tok);
1398
+ node->data .try_expr .else_node = else_node;
1399
+ return node;
1400
+ } else if (var_name_tok != nullptr ) {
1401
+ AstNode *node = ast_create_node (pc, NodeTypeTestExpr, if_token);
1402
+ node->data .test_expr .target_node = condition;
1403
+ node->data .test_expr .var_is_ptr = var_is_ptr;
1404
+ node->data .test_expr .var_symbol = token_buf (var_name_tok);
1405
+ node->data .test_expr .then_node = body_node;
1406
+ node->data .test_expr .else_node = else_node;
1407
+ return node;
1408
+ } else {
1409
+ AstNode *node = ast_create_node (pc, NodeTypeIfBoolExpr, if_token);
1410
+ node->data .if_bool_expr .condition = condition;
1411
+ node->data .if_bool_expr .then_block = body_node;
1412
+ node->data .if_bool_expr .else_node = else_node;
1413
+ return node;
1414
+ }
1464
1415
}
1465
1416
1466
1417
/*
@@ -1848,7 +1799,7 @@ BlockExpression(body) = Block | IfExpression(body) | TryExpression(body) | TestE
1848
1799
static AstNode *ast_parse_block_expr (ParseContext *pc, size_t *token_index, bool mandatory) {
1849
1800
Token *token = &pc->tokens ->at (*token_index);
1850
1801
1851
- AstNode *if_expr = ast_parse_if_expr (pc, token_index, false );
1802
+ AstNode *if_expr = ast_parse_if_try_test_expr (pc, token_index, false );
1852
1803
if (if_expr)
1853
1804
return if_expr;
1854
1805
@@ -1872,14 +1823,6 @@ static AstNode *ast_parse_block_expr(ParseContext *pc, size_t *token_index, bool
1872
1823
if (comptime_node)
1873
1824
return comptime_node;
1874
1825
1875
- AstNode *try_node = ast_parse_try_expr (pc, token_index, false );
1876
- if (try_node)
1877
- return try_node;
1878
-
1879
- AstNode *test_node = ast_parse_test_expr (pc, token_index, false );
1880
- if (test_node)
1881
- return test_node;
1882
-
1883
1826
if (mandatory)
1884
1827
ast_invalid_token_error (pc, token);
1885
1828
0 commit comments