| ... | ... | @@ -493,6 +493,33 @@ static AstNode *ast_parse_root(ParseContext *pc) { |
| 493 | 493 | return node; |
| 494 | 494 | } |
| 495 | 495 | |
| 496 | static Token *ast_parse_multiline_string_literal(ParseContext *pc, Buf *buf) { |
| 497 | Token *first_str_token = nullptr; |
| 498 | Token *str_token = nullptr; |
| 499 | while ((str_token = eat_token_if(pc, TokenIdMultilineStringLiteral))) { |
| 500 | if (first_str_token == nullptr) { |
| 501 | first_str_token = str_token; |
| 502 | } |
| 503 | if (buf->list.length == 0) { |
| 504 | buf_resize(buf, 0); |
| 505 | } |
| 506 | buf_append_buf(buf, token_buf(str_token)); |
| 507 | |
| 508 | // Ignore inline comments |
| 509 | size_t cur_token = pc->current_token; |
| 510 | while (eat_token_if(pc, TokenIdDocComment)); |
| 511 | |
| 512 | // Lookahead to see if there's another multilne string literal, |
| 513 | // if not, we have to revert back to before the doc comment |
| 514 | if (peek_token(pc)->id != TokenIdMultilineStringLiteral) { |
| 515 | pc->current_token = cur_token; |
| 516 | } else { |
| 517 | buf_append_char(buf, '\n'); // Add a newline between comments |
| 518 | } |
| 519 | } |
| 520 | return first_str_token; |
| 521 | } |
| 522 | |
| 496 | 523 | static Token *ast_parse_doc_comments(ParseContext *pc, Buf *buf) { |
| 497 | 524 | Token *first_doc_token = nullptr; |
| 498 | 525 | Token *doc_token = nullptr; |
| ... | ... | @@ -605,7 +632,7 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) { |
| 605 | 632 | case ContainerFieldStateSeen: |
| 606 | 633 | break; |
| 607 | 634 | case ContainerFieldStateEnd: |
| 608 | | ast_error(pc, first_token, "declarations are not allowed between container fields"); |
| 635 | ast_error(pc, first_token, "declarations are not allowed between container fields"); |
| 609 | 636 | } |
| 610 | 637 | |
| 611 | 638 | assert(container_field->type == NodeTypeStructField); |
| ... | ... | @@ -1754,12 +1781,21 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) { |
| 1754 | 1781 | if (unreachable != nullptr) |
| 1755 | 1782 | return ast_create_node(pc, NodeTypeUnreachable, unreachable); |
| 1756 | 1783 | |
| 1784 | |
| 1785 | Buf *string_buf; |
| 1757 | 1786 | Token *string_lit = eat_token_if(pc, TokenIdStringLiteral); |
| 1758 | | if (string_lit == nullptr) |
| 1759 | | string_lit = eat_token_if(pc, TokenIdMultilineStringLiteral); |
| 1787 | if (string_lit != nullptr) { |
| 1788 | string_buf = token_buf(string_lit); |
| 1789 | } else { |
| 1790 | Buf multiline_string_buf = BUF_INIT; |
| 1791 | string_lit = ast_parse_multiline_string_literal(pc, &multiline_string_buf); |
| 1792 | if (string_lit != nullptr) { |
| 1793 | string_buf = buf_create_from_buf(&multiline_string_buf); |
| 1794 | } |
| 1795 | } |
| 1760 | 1796 | if (string_lit != nullptr) { |
| 1761 | 1797 | AstNode *res = ast_create_node(pc, NodeTypeStringLiteral, string_lit); |
| 1762 | | res->data.string_literal.buf = token_buf(string_lit); |
| 1798 | res->data.string_literal.buf = string_buf; |
| 1763 | 1799 | return res; |
| 1764 | 1800 | } |
| 1765 | 1801 | |