| ... | @@ -1012,8 +1012,9 @@ pub const Parser = struct { | ... | @@ -1012,8 +1012,9 @@ pub const Parser = struct { |
| 1012 | }); | 1012 | }); |
| 1013 | }, | 1013 | }, |
| 1014 | State.ParamDeclComma => |fn_proto| { | 1014 | State.ParamDeclComma => |fn_proto| { |
| 1015 | var discard_end: Token = undefined; | 1015 | if ((try self.expectCommaOrEnd(Token.Id.RParen)) == null) { |
| 1016 | try self.commaOrEnd(&stack, Token.Id.RParen, &discard_end, State { .ParamDecl = fn_proto }); | 1016 | stack.append(State { .ParamDecl = fn_proto }) catch unreachable; |
| | 1017 | } |
| 1017 | continue; | 1018 | continue; |
| 1018 | }, | 1019 | }, |
| 1019 | | 1020 | |
| ... | @@ -1394,7 +1395,11 @@ pub const Parser = struct { | ... | @@ -1394,7 +1395,11 @@ pub const Parser = struct { |
| 1394 | try stack.append(State { .Expression = OptionalCtx { .Required = try list_state.list.addOne() } }); | 1395 | try stack.append(State { .Expression = OptionalCtx { .Required = try list_state.list.addOne() } }); |
| 1395 | }, | 1396 | }, |
| 1396 | State.ExprListCommaOrEnd => |list_state| { | 1397 | State.ExprListCommaOrEnd => |list_state| { |
| 1397 | try self.commaOrEnd(&stack, list_state.end, list_state.ptr, State { .ExprListItemOrEnd = list_state }); | 1398 | if (try self.expectCommaOrEnd(list_state.end)) |end| { |
| | 1399 | *list_state.ptr = end; |
| | 1400 | } else { |
| | 1401 | stack.append(State { .ExprListItemOrEnd = list_state }) catch unreachable; |
| | 1402 | } |
| 1398 | continue; | 1403 | continue; |
| 1399 | }, | 1404 | }, |
| 1400 | State.FieldInitListItemOrEnd => |list_state| { | 1405 | State.FieldInitListItemOrEnd => |list_state| { |
| ... | @@ -1430,12 +1435,19 @@ pub const Parser = struct { | ... | @@ -1430,12 +1435,19 @@ pub const Parser = struct { |
| 1430 | }); | 1435 | }); |
| 1431 | }, | 1436 | }, |
| 1432 | State.FieldInitListCommaOrEnd => |list_state| { | 1437 | State.FieldInitListCommaOrEnd => |list_state| { |
| 1433 | try self.commaOrEnd(&stack, Token.Id.RBrace, list_state.ptr, State { .FieldInitListItemOrEnd = list_state }); | 1438 | if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| { |
| | 1439 | *list_state.ptr = end; |
| | 1440 | } else { |
| | 1441 | stack.append(State { .FieldInitListItemOrEnd = list_state }) catch unreachable; |
| | 1442 | } |
| 1434 | continue; | 1443 | continue; |
| 1435 | }, | 1444 | }, |
| 1436 | State.FieldListCommaOrEnd => |container_decl| { | 1445 | State.FieldListCommaOrEnd => |container_decl| { |
| 1437 | try self.commaOrEnd(&stack, Token.Id.RBrace, &container_decl.rbrace_token, | 1446 | if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| { |
| 1438 | State { .ContainerDecl = container_decl }); | 1447 | container_decl.rbrace_token = end; |
| | 1448 | } else { |
| | 1449 | stack.append(State { .ContainerDecl = container_decl }) catch unreachable; |
| | 1450 | } |
| 1439 | continue; | 1451 | continue; |
| 1440 | }, | 1452 | }, |
| 1441 | State.IdentifierListItemOrEnd => |list_state| { | 1453 | State.IdentifierListItemOrEnd => |list_state| { |
| ... | @@ -1448,7 +1460,11 @@ pub const Parser = struct { | ... | @@ -1448,7 +1460,11 @@ pub const Parser = struct { |
| 1448 | try stack.append(State { .Identifier = OptionalCtx { .Required = try list_state.list.addOne() } }); | 1460 | try stack.append(State { .Identifier = OptionalCtx { .Required = try list_state.list.addOne() } }); |
| 1449 | }, | 1461 | }, |
| 1450 | State.IdentifierListCommaOrEnd => |list_state| { | 1462 | State.IdentifierListCommaOrEnd => |list_state| { |
| 1451 | try self.commaOrEnd(&stack, Token.Id.RBrace, list_state.ptr, State { .IdentifierListItemOrEnd = list_state }); | 1463 | if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| { |
| | 1464 | *list_state.ptr = end; |
| | 1465 | } else { |
| | 1466 | stack.append(State { .IdentifierListItemOrEnd = list_state }) catch unreachable; |
| | 1467 | } |
| 1452 | continue; | 1468 | continue; |
| 1453 | }, | 1469 | }, |
| 1454 | State.SwitchCaseOrEnd => |list_state| { | 1470 | State.SwitchCaseOrEnd => |list_state| { |
| ... | @@ -1473,7 +1489,11 @@ pub const Parser = struct { | ... | @@ -1473,7 +1489,11 @@ pub const Parser = struct { |
| 1473 | | 1489 | |
| 1474 | }, | 1490 | }, |
| 1475 | State.SwitchCaseCommaOrEnd => |list_state| { | 1491 | State.SwitchCaseCommaOrEnd => |list_state| { |
| 1476 | try self.commaOrEnd(&stack, Token.Id.RBrace, list_state.ptr, State { .SwitchCaseOrEnd = list_state }); | 1492 | if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| { |
| | 1493 | *list_state.ptr = end; |
| | 1494 | } else { |
| | 1495 | stack.append(State { .SwitchCaseOrEnd = list_state }) catch unreachable; |
| | 1496 | } |
| 1477 | continue; | 1497 | continue; |
| 1478 | }, | 1498 | }, |
| 1479 | State.SwitchCaseFirstItem => |case_items| { | 1499 | State.SwitchCaseFirstItem => |case_items| { |
| ... | @@ -1498,7 +1518,9 @@ pub const Parser = struct { | ... | @@ -1498,7 +1518,9 @@ pub const Parser = struct { |
| 1498 | try stack.append(State { .RangeExpressionBegin = OptionalCtx { .Required = try case_items.addOne() } }); | 1518 | try stack.append(State { .RangeExpressionBegin = OptionalCtx { .Required = try case_items.addOne() } }); |
| 1499 | }, | 1519 | }, |
| 1500 | State.SwitchCaseItemCommaOrEnd => |case_items| { | 1520 | State.SwitchCaseItemCommaOrEnd => |case_items| { |
| 1501 | try self.commaOrEnd(&stack, Token.Id.EqualAngleBracketRight, null, State { .SwitchCaseItem = case_items }); | 1521 | if ((try self.expectCommaOrEnd(Token.Id.EqualAngleBracketRight)) == null) { |
| | 1522 | stack.append(State { .SwitchCaseItem = case_items }) catch unreachable; |
| | 1523 | } |
| 1502 | continue; | 1524 | continue; |
| 1503 | }, | 1525 | }, |
| 1504 | | 1526 | |
| ... | @@ -2986,22 +3008,16 @@ pub const Parser = struct { | ... | @@ -2986,22 +3008,16 @@ pub const Parser = struct { |
| 2986 | } | 3008 | } |
| 2987 | } | 3009 | } |
| 2988 | | 3010 | |
| 2989 | fn commaOrEnd(self: &Parser, stack: &ArrayList(State), end: &const Token.Id, maybe_ptr: ?&Token, state_after_comma: &const State) !void { | 3011 | fn expectCommaOrEnd(self: &Parser, end: @TagType(Token.Id)) !?Token { |
| 2990 | var token = self.getNextToken(); | 3012 | var token = self.getNextToken(); |
| 2991 | switch (token.id) { | 3013 | switch (token.id) { |
| 2992 | Token.Id.Comma => { | 3014 | Token.Id.Comma => return null, |
| 2993 | stack.append(state_after_comma) catch unreachable; | | |
| 2994 | }, | | |
| 2995 | else => { | 3015 | else => { |
| 2996 | const IdTag = @TagType(Token.Id); | 3016 | if (end == token.id) { |
| 2997 | if (IdTag(*end) == token.id) { | 3017 | return token; |
| 2998 | if (maybe_ptr) |ptr| { | | |
| 2999 | *ptr = token; | | |
| 3000 | } | | |
| 3001 | return; | | |
| 3002 | } | 3018 | } |
| 3003 | | 3019 | |
| 3004 | return self.parseError(token, "expected ',' or {}, found {}", @tagName(*end), @tagName(token.id)); | 3020 | return self.parseError(token, "expected ',' or {}, found {}", @tagName(end), @tagName(token.id)); |
| 3005 | }, | 3021 | }, |
| 3006 | } | 3022 | } |
| 3007 | } | 3023 | } |