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