| author | |
| committer | |
| log | 8e2c441b2eae7af27fe311c4539f6932a7f47cea |
| tree | 9bb0bd70760ab320431ada61169520689a65a4c1 |
| parent | 86171afb9b7d7f1c1d5444f894e273ca40e87147 |
| signature |
8 files changed, 133 insertions(+), 17 deletions(-)
doc/langref.html.in+1-1| ... | ... | @@ -10097,7 +10097,7 @@ TopLevelComptime <- KEYWORD_comptime BlockExpr |
| 10097 | 10097 | TopLevelDecl |
| 10098 | 10098 | <- (KEYWORD_export / KEYWORD_extern STRINGLITERAL? / KEYWORD_inline)? FnProto (SEMICOLON / Block) |
| 10099 | 10099 | / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? KEYWORD_threadlocal? VarDecl |
| 10100 | / KEYWORD_use Expr SEMICOLON | |
| 10100 | / KEYWORD_usingnamespace Expr SEMICOLON | |
| 10101 | 10101 | |
| 10102 | 10102 | FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr) |
| 10103 | 10103 |
src/all_types.hpp+25-9| ... | ... | @@ -589,6 +589,7 @@ enum NodeType { |
| 589 | 589 | NodeTypeIfErrorExpr, |
| 590 | 590 | NodeTypeIfOptional, |
| 591 | 591 | NodeTypeErrorSetDecl, |
| 592 | NodeTypeErrorSetField, | |
| 592 | 593 | NodeTypeResume, |
| 593 | 594 | NodeTypeAwaitExpr, |
| 594 | 595 | NodeTypeSuspend, |
| ... | ... | @@ -612,16 +613,10 @@ enum FnInline { |
| 612 | 613 | }; |
| 613 | 614 | |
| 614 | 615 | struct AstNodeFnProto { |
| 615 | VisibMod visib_mod; | |
| 616 | 616 | Buf *name; |
| 617 | 617 | ZigList<AstNode *> params; |
| 618 | 618 | AstNode *return_type; |
| 619 | 619 | Token *return_var_token; |
| 620 | bool is_var_args; | |
| 621 | bool is_extern; | |
| 622 | bool is_export; | |
| 623 | FnInline fn_inline; | |
| 624 | CallingConvention cc; | |
| 625 | 620 | AstNode *fn_def_node; |
| 626 | 621 | // populated if this is an extern declaration |
| 627 | 622 | Buf *lib_name; |
| ... | ... | @@ -629,8 +624,16 @@ struct AstNodeFnProto { |
| 629 | 624 | AstNode *align_expr; |
| 630 | 625 | // populated if the "section(S)" is present |
| 631 | 626 | AstNode *section_expr; |
| 627 | Buf doc_comments; | |
| 632 | 628 | |
| 629 | FnInline fn_inline; | |
| 630 | CallingConvention cc; | |
| 631 | ||
| 632 | VisibMod visib_mod; | |
| 633 | 633 | bool auto_err_set; |
| 634 | bool is_var_args; | |
| 635 | bool is_extern; | |
| 636 | bool is_export; | |
| 634 | 637 | }; |
| 635 | 638 | |
| 636 | 639 | struct AstNodeFnDef { |
| ... | ... | @@ -642,6 +645,7 @@ struct AstNodeParamDecl { |
| 642 | 645 | Buf *name; |
| 643 | 646 | AstNode *type; |
| 644 | 647 | Token *var_token; |
| 648 | Buf doc_comments; | |
| 645 | 649 | bool is_noalias; |
| 646 | 650 | bool is_comptime; |
| 647 | 651 | bool is_var_args; |
| ... | ... | @@ -684,6 +688,7 @@ struct AstNodeVariableDeclaration { |
| 684 | 688 | // populated if the "section(S)" is present |
| 685 | 689 | AstNode *section_expr; |
| 686 | 690 | Token *threadlocal_tok; |
| 691 | Buf doc_comments; | |
| 687 | 692 | |
| 688 | 693 | VisibMod visib_mod; |
| 689 | 694 | bool is_const; |
| ... | ... | @@ -957,25 +962,35 @@ enum ContainerLayout { |
| 957 | 962 | }; |
| 958 | 963 | |
| 959 | 964 | struct AstNodeContainerDecl { |
| 960 | ContainerKind kind; | |
| 965 | AstNode *init_arg_expr; // enum(T), struct(endianness), or union(T), or union(enum(T)) | |
| 961 | 966 | ZigList<AstNode *> fields; |
| 962 | 967 | ZigList<AstNode *> decls; |
| 968 | ||
| 969 | ContainerKind kind; | |
| 963 | 970 | ContainerLayout layout; |
| 964 | AstNode *init_arg_expr; // enum(T), struct(endianness), or union(T), or union(enum(T)) | |
| 971 | ||
| 965 | 972 | bool auto_enum, is_root; // union(enum) |
| 966 | 973 | }; |
| 967 | 974 | |
| 975 | struct AstNodeErrorSetField { | |
| 976 | Buf doc_comments; | |
| 977 | AstNode *field_name; | |
| 978 | }; | |
| 979 | ||
| 968 | 980 | struct AstNodeErrorSetDecl { |
| 981 | // Each AstNode could be AstNodeErrorSetField or just AstNodeSymbolExpr to save memory | |
| 969 | 982 | ZigList<AstNode *> decls; |
| 970 | 983 | }; |
| 971 | 984 | |
| 972 | 985 | struct AstNodeStructField { |
| 973 | VisibMod visib_mod; | |
| 974 | 986 | Buf *name; |
| 975 | 987 | AstNode *type; |
| 976 | 988 | AstNode *value; |
| 977 | 989 | // populated if the "align(A)" is present |
| 978 | 990 | AstNode *align_expr; |
| 991 | Buf doc_comments; | |
| 992 | ||
| 993 | VisibMod visib_mod; | |
| 979 | 994 | }; |
| 980 | 995 | |
| 981 | 996 | struct AstNodeStringLiteral { |
| ... | ... | @@ -1126,6 +1141,7 @@ struct AstNode { |
| 1126 | 1141 | AstNodeInferredArrayType inferred_array_type; |
| 1127 | 1142 | AstNodeErrorType error_type; |
| 1128 | 1143 | AstNodeErrorSetDecl err_set_decl; |
| 1144 | AstNodeErrorSetField err_set_field; | |
| 1129 | 1145 | AstNodeResumeExpr resume_expr; |
| 1130 | 1146 | AstNodeAwaitExpr await_expr; |
| 1131 | 1147 | AstNodeSuspend suspend; |
src/analyze.cpp+1| ... | ... | @@ -3572,6 +3572,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { |
| 3572 | 3572 | case NodeTypeSuspend: |
| 3573 | 3573 | case NodeTypeEnumLiteral: |
| 3574 | 3574 | case NodeTypeAnyFrameType: |
| 3575 | case NodeTypeErrorSetField: | |
| 3575 | 3576 | zig_unreachable(); |
| 3576 | 3577 | } |
| 3577 | 3578 | } |
src/ast_render.cpp+3| ... | ... | @@ -266,6 +266,8 @@ static const char *node_type_str(NodeType node_type) { |
| 266 | 266 | return "AnyFrameType"; |
| 267 | 267 | case NodeTypeEnumLiteral: |
| 268 | 268 | return "EnumLiteral"; |
| 269 | case NodeTypeErrorSetField: | |
| 270 | return "ErrorSetField"; | |
| 269 | 271 | } |
| 270 | 272 | zig_unreachable(); |
| 271 | 273 | } |
| ... | ... | @@ -1177,6 +1179,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { |
| 1177 | 1179 | case NodeTypeTestDecl: |
| 1178 | 1180 | case NodeTypeStructField: |
| 1179 | 1181 | case NodeTypeUsingNamespace: |
| 1182 | case NodeTypeErrorSetField: | |
| 1180 | 1183 | zig_panic("TODO more ast rendering"); |
| 1181 | 1184 | } |
| 1182 | 1185 | } |
src/ir.cpp+10-1| ... | ... | @@ -7945,7 +7945,15 @@ static IrInstruction *ir_gen_err_set_decl(IrBuilder *irb, Scope *parent_scope, A |
| 7945 | 7945 | ErrorTableEntry **errors = allocate<ErrorTableEntry *>(irb->codegen->errors_by_index.length + err_count); |
| 7946 | 7946 | |
| 7947 | 7947 | for (uint32_t i = 0; i < err_count; i += 1) { |
| 7948 | AstNode *symbol_node = node->data.err_set_decl.decls.at(i); | |
| 7948 | AstNode *field_node = node->data.err_set_decl.decls.at(i); | |
| 7949 | AstNode *symbol_node; | |
| 7950 | if (field_node->type == NodeTypeSymbol) { | |
| 7951 | symbol_node = field_node; | |
| 7952 | } else if (field_node->type == NodeTypeErrorSetField) { | |
| 7953 | symbol_node = field_node->data.err_set_field.field_name; | |
| 7954 | } else { | |
| 7955 | zig_unreachable(); | |
| 7956 | } | |
| 7949 | 7957 | assert(symbol_node->type == NodeTypeSymbol); |
| 7950 | 7958 | Buf *err_name = symbol_node->data.symbol_expr.symbol; |
| 7951 | 7959 | ErrorTableEntry *err = allocate<ErrorTableEntry>(1); |
| ... | ... | @@ -8116,6 +8124,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 8116 | 8124 | case NodeTypeSwitchProng: |
| 8117 | 8125 | case NodeTypeSwitchRange: |
| 8118 | 8126 | case NodeTypeStructField: |
| 8127 | case NodeTypeErrorSetField: | |
| 8119 | 8128 | case NodeTypeFnDef: |
| 8120 | 8129 | case NodeTypeTestDecl: |
| 8121 | 8130 | zig_unreachable(); |
src/parser.cpp+41-4| ... | ... | @@ -37,7 +37,7 @@ static AstNode *ast_parse_root(ParseContext *pc); |
| 37 | 37 | static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc); |
| 38 | 38 | static AstNode *ast_parse_test_decl(ParseContext *pc); |
| 39 | 39 | static AstNode *ast_parse_top_level_comptime(ParseContext *pc); |
| 40 | static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod); | |
| 40 | static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, Buf *doc_comments); | |
| 41 | 41 | static AstNode *ast_parse_fn_proto(ParseContext *pc); |
| 42 | 42 | static AstNode *ast_parse_var_decl(ParseContext *pc); |
| 43 | 43 | static AstNode *ast_parse_container_field(ParseContext *pc); |
| ... | ... | @@ -497,6 +497,19 @@ static AstNode *ast_parse_root(ParseContext *pc) { |
| 497 | 497 | return node; |
| 498 | 498 | } |
| 499 | 499 | |
| 500 | static Token *ast_parse_doc_comments(ParseContext *pc, Buf *buf) { | |
| 501 | Token *doc_token = nullptr; | |
| 502 | while ((doc_token = eat_token_if(pc, TokenIdDocComment))) { | |
| 503 | if (buf->list.length == 0) { | |
| 504 | buf_resize(buf, 0); | |
| 505 | } | |
| 506 | // chops off '///' and '\n' | |
| 507 | buf_append_mem(buf, buf_ptr(pc->buf) + doc_token->start_pos + 3, | |
| 508 | doc_token->end_pos - doc_token->start_pos - 4); | |
| 509 | } | |
| 510 | return doc_token; | |
| 511 | } | |
| 512 | ||
| 500 | 513 | // ContainerMembers |
| 501 | 514 | // <- TestDecl ContainerMembers |
| 502 | 515 | // / TopLevelComptime ContainerMembers |
| ... | ... | @@ -519,10 +532,13 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) { |
| 519 | 532 | continue; |
| 520 | 533 | } |
| 521 | 534 | |
| 535 | Buf doc_comment_buf = BUF_INIT; | |
| 536 | ast_parse_doc_comments(pc, &doc_comment_buf); | |
| 537 | ||
| 522 | 538 | Token *visib_token = eat_token_if(pc, TokenIdKeywordPub); |
| 523 | 539 | VisibMod visib_mod = visib_token != nullptr ? VisibModPub : VisibModPrivate; |
| 524 | 540 | |
| 525 | AstNode *top_level_decl = ast_parse_top_level_decl(pc, visib_mod); | |
| 541 | AstNode *top_level_decl = ast_parse_top_level_decl(pc, visib_mod, &doc_comment_buf); | |
| 526 | 542 | if (top_level_decl != nullptr) { |
| 527 | 543 | res.decls.append(top_level_decl); |
| 528 | 544 | continue; |
| ... | ... | @@ -532,6 +548,7 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) { |
| 532 | 548 | if (container_field != nullptr) { |
| 533 | 549 | assert(container_field->type == NodeTypeStructField); |
| 534 | 550 | container_field->data.struct_field.visib_mod = visib_mod; |
| 551 | container_field->data.struct_field.doc_comments = doc_comment_buf; | |
| 535 | 552 | res.fields.append(container_field); |
| 536 | 553 | if (eat_token_if(pc, TokenIdComma) != nullptr) { |
| 537 | 554 | continue; |
| ... | ... | @@ -581,7 +598,7 @@ static AstNode *ast_parse_top_level_comptime(ParseContext *pc) { |
| 581 | 598 | // <- (KEYWORD_export / KEYWORD_extern STRINGLITERAL? / (KEYWORD_inline / KEYWORD_noinline))? FnProto (SEMICOLON / Block) |
| 582 | 599 | // / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? KEYWORD_threadlocal? VarDecl |
| 583 | 600 | // / KEYWORD_use Expr SEMICOLON |
| 584 | static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) { | |
| 601 | static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, Buf *doc_comments) { | |
| 585 | 602 | Token *first = eat_token_if(pc, TokenIdKeywordExport); |
| 586 | 603 | if (first == nullptr) |
| 587 | 604 | first = eat_token_if(pc, TokenIdKeywordExtern); |
| ... | ... | @@ -603,6 +620,7 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) { |
| 603 | 620 | var_decl->column = first->start_column; |
| 604 | 621 | var_decl->data.variable_declaration.threadlocal_tok = thread_local_kw; |
| 605 | 622 | var_decl->data.variable_declaration.visib_mod = visib_mod; |
| 623 | var_decl->data.variable_declaration.doc_comments = *doc_comments; | |
| 606 | 624 | var_decl->data.variable_declaration.is_extern = first->id == TokenIdKeywordExtern; |
| 607 | 625 | var_decl->data.variable_declaration.is_export = first->id == TokenIdKeywordExport; |
| 608 | 626 | var_decl->data.variable_declaration.lib_name = token_buf(lib_name); |
| ... | ... | @@ -623,6 +641,7 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) { |
| 623 | 641 | fn_proto->line = first->start_line; |
| 624 | 642 | fn_proto->column = first->start_column; |
| 625 | 643 | fn_proto->data.fn_proto.visib_mod = visib_mod; |
| 644 | fn_proto->data.fn_proto.doc_comments = *doc_comments; | |
| 626 | 645 | fn_proto->data.fn_proto.is_extern = first->id == TokenIdKeywordExtern; |
| 627 | 646 | fn_proto->data.fn_proto.is_export = first->id == TokenIdKeywordExport; |
| 628 | 647 | switch (first->id) { |
| ... | ... | @@ -657,6 +676,7 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) { |
| 657 | 676 | if (var_decl != nullptr) { |
| 658 | 677 | assert(var_decl->type == NodeTypeVariableDeclaration); |
| 659 | 678 | var_decl->data.variable_declaration.visib_mod = visib_mod; |
| 679 | var_decl->data.variable_declaration.doc_comments = *doc_comments; | |
| 660 | 680 | var_decl->data.variable_declaration.threadlocal_tok = thread_local_kw; |
| 661 | 681 | return var_decl; |
| 662 | 682 | } |
| ... | ... | @@ -672,6 +692,7 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) { |
| 672 | 692 | |
| 673 | 693 | assert(fn_proto->type == NodeTypeFnProto); |
| 674 | 694 | fn_proto->data.fn_proto.visib_mod = visib_mod; |
| 695 | fn_proto->data.fn_proto.doc_comments = *doc_comments; | |
| 675 | 696 | AstNode *res = fn_proto; |
| 676 | 697 | if (body != nullptr) { |
| 677 | 698 | res = ast_create_node_copy_line_info(pc, NodeTypeFnDef, fn_proto); |
| ... | ... | @@ -1719,11 +1740,20 @@ static AstNode *ast_parse_error_set_decl(ParseContext *pc) { |
| 1719 | 1740 | } |
| 1720 | 1741 | |
| 1721 | 1742 | ZigList<AstNode *> decls = ast_parse_list<AstNode>(pc, TokenIdComma, [](ParseContext *context) { |
| 1743 | Buf doc_comment_buf = BUF_INIT; | |
| 1744 | Token *doc_token = ast_parse_doc_comments(context, &doc_comment_buf); | |
| 1722 | 1745 | Token *ident = eat_token_if(context, TokenIdSymbol); |
| 1723 | 1746 | if (ident == nullptr) |
| 1724 | 1747 | return (AstNode*)nullptr; |
| 1725 | 1748 | |
| 1726 | return token_symbol(context, ident); | |
| 1749 | AstNode *symbol_node = token_symbol(context, ident); | |
| 1750 | if (doc_token == nullptr) | |
| 1751 | return symbol_node; | |
| 1752 | ||
| 1753 | AstNode *field_node = ast_create_node(context, NodeTypeErrorSetField, doc_token); | |
| 1754 | field_node->data.err_set_field.field_name = symbol_node; | |
| 1755 | field_node->data.err_set_field.doc_comments = doc_comment_buf; | |
| 1756 | return field_node; | |
| 1727 | 1757 | }); |
| 1728 | 1758 | expect_token(pc, TokenIdRBrace); |
| 1729 | 1759 | |
| ... | ... | @@ -2057,6 +2087,9 @@ static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc) { |
| 2057 | 2087 | |
| 2058 | 2088 | // ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType |
| 2059 | 2089 | static AstNode *ast_parse_param_decl(ParseContext *pc) { |
| 2090 | Buf doc_comments = BUF_INIT; | |
| 2091 | ast_parse_doc_comments(pc, &doc_comments); | |
| 2092 | ||
| 2060 | 2093 | Token *first = eat_token_if(pc, TokenIdKeywordNoAlias); |
| 2061 | 2094 | if (first == nullptr) |
| 2062 | 2095 | first = eat_token_if(pc, TokenIdKeywordCompTime); |
| ... | ... | @@ -2089,6 +2122,7 @@ static AstNode *ast_parse_param_decl(ParseContext *pc) { |
| 2089 | 2122 | res->line = first->start_line; |
| 2090 | 2123 | res->column = first->start_column; |
| 2091 | 2124 | res->data.param_decl.name = token_buf(name); |
| 2125 | res->data.param_decl.doc_comments = doc_comments; | |
| 2092 | 2126 | res->data.param_decl.is_noalias = first->id == TokenIdKeywordNoAlias; |
| 2093 | 2127 | res->data.param_decl.is_comptime = first->id == TokenIdKeywordCompTime; |
| 2094 | 2128 | return res; |
| ... | ... | @@ -3029,6 +3063,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont |
| 3029 | 3063 | case NodeTypeErrorSetDecl: |
| 3030 | 3064 | visit_node_list(&node->data.err_set_decl.decls, visit, context); |
| 3031 | 3065 | break; |
| 3066 | case NodeTypeErrorSetField: | |
| 3067 | visit_field(&node->data.err_set_field.field_name, visit, context); | |
| 3068 | break; | |
| 3032 | 3069 | case NodeTypeResume: |
| 3033 | 3070 | visit_field(&node->data.resume_expr.expr, visit, context); |
| 3034 | 3071 | break; |
src/tokenizer.cpp+51-2| ... | ... | @@ -196,6 +196,8 @@ enum TokenizeState { |
| 196 | 196 | TokenizeStateSawStar, |
| 197 | 197 | TokenizeStateSawStarPercent, |
| 198 | 198 | TokenizeStateSawSlash, |
| 199 | TokenizeStateSawSlash2, | |
| 200 | TokenizeStateSawSlash3, | |
| 199 | 201 | TokenizeStateSawBackslash, |
| 200 | 202 | TokenizeStateSawPercent, |
| 201 | 203 | TokenizeStateSawPlus, |
| ... | ... | @@ -206,6 +208,7 @@ enum TokenizeState { |
| 206 | 208 | TokenizeStateSawCaret, |
| 207 | 209 | TokenizeStateSawBar, |
| 208 | 210 | TokenizeStateSawBarBar, |
| 211 | TokenizeStateDocComment, | |
| 209 | 212 | TokenizeStateLineComment, |
| 210 | 213 | TokenizeStateLineString, |
| 211 | 214 | TokenizeStateLineStringEnd, |
| ... | ... | @@ -910,8 +913,7 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 910 | 913 | case TokenizeStateSawSlash: |
| 911 | 914 | switch (c) { |
| 912 | 915 | case '/': |
| 913 | cancel_token(&t); | |
| 914 | t.state = TokenizeStateLineComment; | |
| 916 | t.state = TokenizeStateSawSlash2; | |
| 915 | 917 | break; |
| 916 | 918 | case '=': |
| 917 | 919 | set_token_id(&t, t.cur_tok, TokenIdDivEq); |
| ... | ... | @@ -925,6 +927,38 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 925 | 927 | continue; |
| 926 | 928 | } |
| 927 | 929 | break; |
| 930 | case TokenizeStateSawSlash2: | |
| 931 | switch (c) { | |
| 932 | case '/': | |
| 933 | t.state = TokenizeStateSawSlash3; | |
| 934 | break; | |
| 935 | case '\n': | |
| 936 | cancel_token(&t); | |
| 937 | t.state = TokenizeStateStart; | |
| 938 | break; | |
| 939 | default: | |
| 940 | cancel_token(&t); | |
| 941 | t.state = TokenizeStateLineComment; | |
| 942 | break; | |
| 943 | } | |
| 944 | break; | |
| 945 | case TokenizeStateSawSlash3: | |
| 946 | switch (c) { | |
| 947 | case '/': | |
| 948 | cancel_token(&t); | |
| 949 | t.state = TokenizeStateLineComment; | |
| 950 | break; | |
| 951 | case '\n': | |
| 952 | set_token_id(&t, t.cur_tok, TokenIdDocComment); | |
| 953 | end_token(&t); | |
| 954 | t.state = TokenizeStateStart; | |
| 955 | break; | |
| 956 | default: | |
| 957 | set_token_id(&t, t.cur_tok, TokenIdDocComment); | |
| 958 | t.state = TokenizeStateDocComment; | |
| 959 | break; | |
| 960 | } | |
| 961 | break; | |
| 928 | 962 | case TokenizeStateSawBackslash: |
| 929 | 963 | switch (c) { |
| 930 | 964 | case '\\': |
| ... | ... | @@ -1004,6 +1038,17 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 1004 | 1038 | break; |
| 1005 | 1039 | } |
| 1006 | 1040 | break; |
| 1041 | case TokenizeStateDocComment: | |
| 1042 | switch (c) { | |
| 1043 | case '\n': | |
| 1044 | end_token(&t); | |
| 1045 | t.state = TokenizeStateStart; | |
| 1046 | break; | |
| 1047 | default: | |
| 1048 | // do nothing | |
| 1049 | break; | |
| 1050 | } | |
| 1051 | break; | |
| 1007 | 1052 | case TokenizeStateSymbolFirstC: |
| 1008 | 1053 | switch (c) { |
| 1009 | 1054 | case '"': |
| ... | ... | @@ -1466,6 +1511,7 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 1466 | 1511 | case TokenizeStateLineStringEnd: |
| 1467 | 1512 | case TokenizeStateSawBarBar: |
| 1468 | 1513 | case TokenizeStateLBracket: |
| 1514 | case TokenizeStateDocComment: | |
| 1469 | 1515 | end_token(&t); |
| 1470 | 1516 | break; |
| 1471 | 1517 | case TokenizeStateSawDotDot: |
| ... | ... | @@ -1478,6 +1524,8 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 1478 | 1524 | tokenize_error(&t, "unexpected EOF"); |
| 1479 | 1525 | break; |
| 1480 | 1526 | case TokenizeStateLineComment: |
| 1527 | case TokenizeStateSawSlash2: | |
| 1528 | case TokenizeStateSawSlash3: | |
| 1481 | 1529 | break; |
| 1482 | 1530 | } |
| 1483 | 1531 | if (t.state != TokenizeStateError) { |
| ... | ... | @@ -1524,6 +1572,7 @@ const char * token_name(TokenId id) { |
| 1524 | 1572 | case TokenIdComma: return ","; |
| 1525 | 1573 | case TokenIdDash: return "-"; |
| 1526 | 1574 | case TokenIdDivEq: return "/="; |
| 1575 | case TokenIdDocComment: return "DocComment"; | |
| 1527 | 1576 | case TokenIdDot: return "."; |
| 1528 | 1577 | case TokenIdEllipsis2: return ".."; |
| 1529 | 1578 | case TokenIdEllipsis3: return "..."; |
src/tokenizer.hpp+1| ... | ... | @@ -42,6 +42,7 @@ enum TokenId { |
| 42 | 42 | TokenIdComma, |
| 43 | 43 | TokenIdDash, |
| 44 | 44 | TokenIdDivEq, |
| 45 | TokenIdDocComment, | |
| 45 | 46 | TokenIdDot, |
| 46 | 47 | TokenIdEllipsis2, |
| 47 | 48 | TokenIdEllipsis3, |