authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-12 11:20:38-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-12 11:20:38-04:00
log29e0e4088e7b742190c0fc9d841ef74764020584
treeadfdacbced5d6cab03d75311c2a657ed94500cc1
parent7b2cb7e679b114057f95692a88a666669246131f
parent0d8646d262ebc3db6631421db8fc79228b6622f8

Merge remote-tracking branch 'origin/master' into self-hosted-cli


6 files changed, 461 insertions(+), 301 deletions(-)

deps/lld/ELF/MarkLive.cpp+9
......@@ -301,6 +301,15 @@ template <class ELFT> void elf::markLive() {
301301 // Follow the graph to mark all live sections.
302302 doGcSections<ELFT>();
303303
304 // If all references to a DSO happen to be weak, the DSO is removed from
305 // DT_NEEDED, which creates dangling shared symbols to non-existent DSO.
306 // We'll replace such symbols with undefined ones to fix it.
307 for (Symbol *Sym : Symtab->getSymbols())
308 if (auto *S = dyn_cast<SharedSymbol>(Sym))
309 if (S->isWeak() && !S->getFile<ELFT>().IsNeeded)
310 replaceSymbol<Undefined>(S, nullptr, S->getName(), STB_WEAK, S->StOther,
311 S->Type);
312
304313 // Report garbage-collected sections.
305314 if (Config->PrintGcSections)
306315 for (InputSectionBase *Sec : InputSections)
src/ir.cpp+8-1
......@@ -11804,7 +11804,8 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
1180411804 }
1180511805 }
1180611806
11807 bool comptime_arg = param_decl_node->data.param_decl.is_inline;
11807 bool comptime_arg = param_decl_node->data.param_decl.is_inline ||
11808 casted_arg->value.type->id == TypeTableEntryIdNumLitInt || casted_arg->value.type->id == TypeTableEntryIdNumLitFloat;
1180811809
1180911810 ConstExprValue *arg_val;
1181011811
......@@ -11829,6 +11830,12 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
1182911830 var->shadowable = !comptime_arg;
1183011831
1183111832 *next_proto_i += 1;
11833 } else if (casted_arg->value.type->id == TypeTableEntryIdNumLitInt ||
11834 casted_arg->value.type->id == TypeTableEntryIdNumLitFloat)
11835 {
11836 ir_add_error(ira, casted_arg,
11837 buf_sprintf("compiler bug: integer and float literals in var args function must be casted. https://github.com/zig-lang/zig/issues/557"));
11838 return false;
1183211839 }
1183311840
1183411841 if (!comptime_arg) {
std/zig/ast.zig+13-13
......@@ -214,7 +214,7 @@ pub const NodeVarDecl = struct {
214214 eq_token: Token,
215215 mut_token: Token,
216216 comptime_token: ?Token,
217 extern_token: ?Token,
217 extern_export_token: ?Token,
218218 lib_name: ?&Node,
219219 type_node: ?&Node,
220220 align_node: ?&Node,
......@@ -245,7 +245,7 @@ pub const NodeVarDecl = struct {
245245 pub fn firstToken(self: &NodeVarDecl) Token {
246246 if (self.visib_token) |visib_token| return visib_token;
247247 if (self.comptime_token) |comptime_token| return comptime_token;
248 if (self.extern_token) |extern_token| return extern_token;
248 if (self.extern_export_token) |extern_export_token| return extern_export_token;
249249 assert(self.lib_name == null);
250250 return self.mut_token;
251251 }
......@@ -360,6 +360,7 @@ pub const NodeContainerDecl = struct {
360360
361361pub const NodeStructField = struct {
362362 base: Node,
363 visib_token: ?Token,
363364 name_token: Token,
364365 type_expr: &Node,
365366
......@@ -373,6 +374,7 @@ pub const NodeStructField = struct {
373374 }
374375
375376 pub fn firstToken(self: &NodeStructField) Token {
377 if (self.visib_token) |visib_token| return visib_token;
376378 return self.name_token;
377379 }
378380
......@@ -494,8 +496,7 @@ pub const NodeFnProto = struct {
494496 params: ArrayList(&Node),
495497 return_type: ReturnType,
496498 var_args_token: ?Token,
497 extern_token: ?Token,
498 inline_token: ?Token,
499 extern_export_inline_token: ?Token,
499500 cc_token: ?Token,
500501 async_attr: ?&NodeAsyncAttribute,
501502 body_node: ?&Node,
......@@ -545,9 +546,8 @@ pub const NodeFnProto = struct {
545546
546547 pub fn firstToken(self: &NodeFnProto) Token {
547548 if (self.visib_token) |visib_token| return visib_token;
548 if (self.extern_token) |extern_token| return extern_token;
549 if (self.extern_export_inline_token) |extern_export_inline_token| return extern_export_inline_token;
549550 assert(self.lib_name == null);
550 if (self.inline_token) |inline_token| return inline_token;
551551 if (self.cc_token) |cc_token| return cc_token;
552552 return self.fn_token;
553553 }
......@@ -1606,7 +1606,7 @@ pub const NodeThisLiteral = struct {
16061606pub const NodeAsmOutput = struct {
16071607 base: Node,
16081608 symbolic_name: &NodeIdentifier,
1609 constraint: &NodeStringLiteral,
1609 constraint: &Node,
16101610 kind: Kind,
16111611
16121612 const Kind = union(enum) {
......@@ -1620,7 +1620,7 @@ pub const NodeAsmOutput = struct {
16201620 if (i < 1) return &self.symbolic_name.base;
16211621 i -= 1;
16221622
1623 if (i < 1) return &self.constraint.base;
1623 if (i < 1) return self.constraint;
16241624 i -= 1;
16251625
16261626 switch (self.kind) {
......@@ -1652,7 +1652,7 @@ pub const NodeAsmOutput = struct {
16521652pub const NodeAsmInput = struct {
16531653 base: Node,
16541654 symbolic_name: &NodeIdentifier,
1655 constraint: &NodeStringLiteral,
1655 constraint: &Node,
16561656 expr: &Node,
16571657
16581658 pub fn iterate(self: &NodeAsmInput, index: usize) ?&Node {
......@@ -1661,7 +1661,7 @@ pub const NodeAsmInput = struct {
16611661 if (i < 1) return &self.symbolic_name.base;
16621662 i -= 1;
16631663
1664 if (i < 1) return &self.constraint.base;
1664 if (i < 1) return self.constraint;
16651665 i -= 1;
16661666
16671667 if (i < 1) return self.expr;
......@@ -1683,11 +1683,11 @@ pub const NodeAsm = struct {
16831683 base: Node,
16841684 asm_token: Token,
16851685 is_volatile: bool,
1686 template: Token,
1686 template: &Node,
16871687 //tokens: ArrayList(AsmToken),
16881688 outputs: ArrayList(&NodeAsmOutput),
16891689 inputs: ArrayList(&NodeAsmInput),
1690 cloppers: ArrayList(&NodeStringLiteral),
1690 cloppers: ArrayList(&Node),
16911691 rparen: Token,
16921692
16931693 pub fn iterate(self: &NodeAsm, index: usize) ?&Node {
......@@ -1699,7 +1699,7 @@ pub const NodeAsm = struct {
16991699 if (i < self.inputs.len) return &self.inputs.at(index).base;
17001700 i -= self.inputs.len;
17011701
1702 if (i < self.cloppers.len) return &self.cloppers.at(index).base;
1702 if (i < self.cloppers.len) return self.cloppers.at(index);
17031703 i -= self.cloppers.len;
17041704
17051705 return null;
std/zig/parser.zig+420-286
......@@ -55,7 +55,7 @@ pub const Parser = struct {
5555 const TopLevelDeclCtx = struct {
5656 decls: &ArrayList(&ast.Node),
5757 visib_token: ?Token,
58 extern_token: ?Token,
58 extern_export_inline_token: ?Token,
5959 lib_name: ?&ast.Node,
6060 };
6161
......@@ -142,6 +142,7 @@ pub const Parser = struct {
142142 const State = union(enum) {
143143 TopLevel,
144144 TopLevelExtern: TopLevelDeclCtx,
145 TopLevelLibname: TopLevelDeclCtx,
145146 TopLevelDecl: TopLevelDeclCtx,
146147 ContainerExtern: ContainerExternCtx,
147148 ContainerDecl: &ast.NodeContainerDecl,
......@@ -171,12 +172,14 @@ pub const Parser = struct {
171172 Semicolon: &const &const ast.Node,
172173 AsmOutputItems: &ArrayList(&ast.NodeAsmOutput),
173174 AsmInputItems: &ArrayList(&ast.NodeAsmInput),
174 AsmClopperItems: &ArrayList(&ast.NodeStringLiteral),
175 AsmClopperItems: &ArrayList(&ast.Node),
175176 ExprListItemOrEnd: ExprListCtx,
176177 ExprListCommaOrEnd: ExprListCtx,
177178 FieldInitListItemOrEnd: ListSave(&ast.NodeFieldInitializer),
178179 FieldInitListCommaOrEnd: ListSave(&ast.NodeFieldInitializer),
179180 FieldListCommaOrEnd: &ast.NodeContainerDecl,
181 IdentifierListItemOrEnd: ListSave(&ast.NodeIdentifier),
182 IdentifierListCommaOrEnd: ListSave(&ast.NodeIdentifier),
180183 SwitchCaseOrEnd: ListSave(&ast.NodeSwitchCase),
181184 SuspendBody: &ast.NodeSuspend,
182185 AsyncEnd: AsyncEndCtx,
......@@ -299,7 +302,11 @@ pub const Parser = struct {
299302 Token.Id.Keyword_test => {
300303 stack.append(State.TopLevel) catch unreachable;
301304
302 const name_token = (try self.expectToken(&stack, Token.Id.StringLiteral)) ?? continue;
305 const name_token = self.getNextToken();
306 const name = (try self.parseStringLiteral(arena, name_token)) ?? {
307 try self.parseError(&stack, name_token, "expected string literal, found {}", @tagName(name_token.id));
308 continue;
309 };
303310 const lbrace = (try self.expectToken(&stack, Token.Id.LBrace)) ?? continue;
304311
305312 const block = try self.createNode(arena, ast.NodeBlock,
......@@ -315,7 +322,7 @@ pub const Parser = struct {
315322 ast.NodeTestDecl {
316323 .base = undefined,
317324 .test_token = token,
318 .name = &(try self.createLiteral(arena, ast.NodeStringLiteral, name_token)).base,
325 .name = name,
319326 .body_node = &block.base,
320327 }
321328 );
......@@ -326,13 +333,13 @@ pub const Parser = struct {
326333 root_node.eof_token = token;
327334 return Tree {.root_node = root_node, .arena_allocator = arena_allocator};
328335 },
329 Token.Id.Keyword_pub, Token.Id.Keyword_export => {
336 Token.Id.Keyword_pub => {
330337 stack.append(State.TopLevel) catch unreachable;
331338 try stack.append(State {
332339 .TopLevelExtern = TopLevelDeclCtx {
333340 .decls = &root_node.decls,
334341 .visib_token = token,
335 .extern_token = null,
342 .extern_export_inline_token = null,
336343 .lib_name = null,
337344 }
338345 });
......@@ -357,7 +364,7 @@ pub const Parser = struct {
357364 .TopLevelExtern = TopLevelDeclCtx {
358365 .decls = &root_node.decls,
359366 .visib_token = null,
360 .extern_token = null,
367 .extern_export_inline_token = null,
361368 .lib_name = null,
362369 }
363370 });
......@@ -368,42 +375,24 @@ pub const Parser = struct {
368375 State.TopLevelExtern => |ctx| {
369376 const token = self.getNextToken();
370377 switch (token.id) {
371 Token.Id.Keyword_use => {
372 const node = try self.createAttachNode(arena, ctx.decls, ast.NodeUse,
373 ast.NodeUse {
374 .base = undefined,
375 .visib_token = ctx.visib_token,
376 .expr = undefined,
377 .semicolon_token = undefined,
378 }
379 );
378 Token.Id.Keyword_export, Token.Id.Keyword_inline => {
380379 stack.append(State {
381 .ExpectTokenSave = ExpectTokenSave {
382 .id = Token.Id.Semicolon,
383 .ptr = &node.semicolon_token,
384 }
380 .TopLevelDecl = TopLevelDeclCtx {
381 .decls = ctx.decls,
382 .visib_token = ctx.visib_token,
383 .extern_export_inline_token = token,
384 .lib_name = null,
385 },
385386 }) catch unreachable;
386 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
387387 continue;
388388 },
389389 Token.Id.Keyword_extern => {
390 const lib_name_token = self.getNextToken();
391 const lib_name = blk: {
392 if (lib_name_token.id == Token.Id.StringLiteral) {
393 const res = try self.createLiteral(arena, ast.NodeStringLiteral, lib_name_token);
394 break :blk &res.base;
395 } else {
396 self.putBackToken(lib_name_token);
397 break :blk null;
398 }
399 };
400
401390 stack.append(State {
402 .TopLevelDecl = TopLevelDeclCtx {
391 .TopLevelLibname = TopLevelDeclCtx {
403392 .decls = ctx.decls,
404393 .visib_token = ctx.visib_token,
405 .extern_token = token,
406 .lib_name = lib_name,
394 .extern_export_inline_token = token,
395 .lib_name = null,
407396 },
408397 }) catch unreachable;
409398 continue;
......@@ -415,17 +404,67 @@ pub const Parser = struct {
415404 }
416405 }
417406 },
407
408 State.TopLevelLibname => |ctx| {
409 const lib_name = blk: {
410 const lib_name_token = self.getNextToken();
411 break :blk (try self.parseStringLiteral(arena, lib_name_token)) ?? {
412 self.putBackToken(lib_name_token);
413 break :blk null;
414 };
415 };
416
417 stack.append(State {
418 .TopLevelDecl = TopLevelDeclCtx {
419 .decls = ctx.decls,
420 .visib_token = ctx.visib_token,
421 .extern_export_inline_token = ctx.extern_export_inline_token,
422 .lib_name = lib_name,
423 },
424 }) catch unreachable;
425 },
426
418427 State.TopLevelDecl => |ctx| {
419428 const token = self.getNextToken();
420429 switch (token.id) {
430 Token.Id.Keyword_use => {
431 if (ctx.extern_export_inline_token != null) {
432 try self.parseError(&stack, token, "Invalid token {}", @tagName((??ctx.extern_export_inline_token).id));
433 continue;
434 }
435
436 const node = try self.createAttachNode(arena, ctx.decls, ast.NodeUse,
437 ast.NodeUse {
438 .base = undefined,
439 .visib_token = ctx.visib_token,
440 .expr = undefined,
441 .semicolon_token = undefined,
442 }
443 );
444 stack.append(State {
445 .ExpectTokenSave = ExpectTokenSave {
446 .id = Token.Id.Semicolon,
447 .ptr = &node.semicolon_token,
448 }
449 }) catch unreachable;
450 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
451 continue;
452 },
421453 Token.Id.Keyword_var, Token.Id.Keyword_const => {
454 if (ctx.extern_export_inline_token) |extern_export_inline_token| {
455 if (extern_export_inline_token.id == Token.Id.Keyword_inline) {
456 try self.parseError(&stack, token, "Invalid token {}", @tagName(extern_export_inline_token.id));
457 continue;
458 }
459 }
460
422461 const var_decl_node = try self.createAttachNode(arena, ctx.decls, ast.NodeVarDecl,
423462 ast.NodeVarDecl {
424463 .base = undefined,
425464 .visib_token = ctx.visib_token,
426465 .mut_token = token,
427466 .comptime_token = null,
428 .extern_token = ctx.extern_token,
467 .extern_export_token = ctx.extern_export_inline_token,
429468 .type_node = null,
430469 .align_node = null,
431470 .init_node = null,
......@@ -449,8 +488,7 @@ pub const Parser = struct {
449488 .params = ArrayList(&ast.Node).init(arena),
450489 .return_type = undefined,
451490 .var_args_token = null,
452 .extern_token = ctx.extern_token,
453 .inline_token = null,
491 .extern_export_inline_token = ctx.extern_export_inline_token,
454492 .cc_token = null,
455493 .async_attr = null,
456494 .body_node = null,
......@@ -472,8 +510,7 @@ pub const Parser = struct {
472510 .params = ArrayList(&ast.Node).init(arena),
473511 .return_type = undefined,
474512 .var_args_token = null,
475 .extern_token = ctx.extern_token,
476 .inline_token = null,
513 .extern_export_inline_token = ctx.extern_export_inline_token,
477514 .cc_token = token,
478515 .async_attr = null,
479516 .body_node = null,
......@@ -510,8 +547,7 @@ pub const Parser = struct {
510547 .params = ArrayList(&ast.Node).init(arena),
511548 .return_type = undefined,
512549 .var_args_token = null,
513 .extern_token = ctx.extern_token,
514 .inline_token = null,
550 .extern_export_inline_token = ctx.extern_export_inline_token,
515551 .cc_token = null,
516552 .async_attr = async_node,
517553 .body_node = null,
......@@ -667,6 +703,7 @@ pub const Parser = struct {
667703 const node = try self.createAttachNode(arena, &container_decl.fields_and_decls, ast.NodeStructField,
668704 ast.NodeStructField {
669705 .base = undefined,
706 .visib_token = null,
670707 .name_token = token,
671708 .type_expr = undefined,
672709 }
......@@ -719,13 +756,48 @@ pub const Parser = struct {
719756 },
720757 }
721758 },
722 Token.Id.Keyword_pub, Token.Id.Keyword_export => {
759 Token.Id.Keyword_pub => {
760 if (self.eatToken(Token.Id.Identifier)) |identifier| {
761 switch (container_decl.kind) {
762 ast.NodeContainerDecl.Kind.Struct => {
763 const node = try self.createAttachNode(arena, &container_decl.fields_and_decls, ast.NodeStructField,
764 ast.NodeStructField {
765 .base = undefined,
766 .visib_token = token,
767 .name_token = identifier,
768 .type_expr = undefined,
769 }
770 );
771
772 stack.append(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;
773 try stack.append(State { .Expression = DestPtr { .Field = &node.type_expr } });
774 try stack.append(State { .ExpectToken = Token.Id.Colon });
775 continue;
776 },
777 else => {
778 self.putBackToken(identifier);
779 }
780 }
781 }
782
783 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
784 try stack.append(State {
785 .TopLevelExtern = TopLevelDeclCtx {
786 .decls = &container_decl.fields_and_decls,
787 .visib_token = token,
788 .extern_export_inline_token = null,
789 .lib_name = null,
790 }
791 });
792 continue;
793 },
794 Token.Id.Keyword_export => {
723795 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
724796 try stack.append(State {
725797 .TopLevelExtern = TopLevelDeclCtx {
726798 .decls = &container_decl.fields_and_decls,
727799 .visib_token = token,
728 .extern_token = null,
800 .extern_export_inline_token = null,
729801 .lib_name = null,
730802 }
731803 });
......@@ -742,7 +814,7 @@ pub const Parser = struct {
742814 .TopLevelExtern = TopLevelDeclCtx {
743815 .decls = &container_decl.fields_and_decls,
744816 .visib_token = null,
745 .extern_token = null,
817 .extern_export_inline_token = null,
746818 .lib_name = null,
747819 }
748820 });
......@@ -862,111 +934,11 @@ pub const Parser = struct {
862934 stack.append(State { .Expression = DestPtr { .Field = &node.rhs } }) catch unreachable;
863935 continue;
864936 },
865 Token.Id.Keyword_suspend => {
866 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSuspend,
867 ast.NodeSuspend {
868 .base = undefined,
869 .suspend_token = token,
870 .payload = null,
871 .body = null,
872 }
873 );
874
875 stack.append(State { .SuspendBody = node }) catch unreachable;
876 try stack.append(State { .Payload = &node.payload });
877 continue;
878 },
879 Token.Id.Keyword_if => {
880 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeIf,
881 ast.NodeIf {
882 .base = undefined,
883 .if_token = token,
884 .condition = undefined,
885 .payload = null,
886 .body = undefined,
887 .@"else" = null,
888 }
889 );
890
891 stack.append(State { .Else = &node.@"else" }) catch unreachable;
892 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });
893 try stack.append(State { .PointerPayload = &node.payload });
894 try stack.append(State { .ExpectToken = Token.Id.RParen });
895 try stack.append(State { .Expression = DestPtr { .Field = &node.condition } });
896 try stack.append(State { .ExpectToken = Token.Id.LParen });
897 continue;
898 },
899 Token.Id.Keyword_while => {
900 stack.append(State {
901 .While = LoopCtx {
902 .label = null,
903 .inline_token = null,
904 .loop_token = token,
905 .dest_ptr = dest_ptr,
906 }
907 }) catch unreachable;
908 continue;
909 },
910 Token.Id.Keyword_for => {
911 stack.append(State {
912 .For = LoopCtx {
913 .label = null,
914 .inline_token = null,
915 .loop_token = token,
916 .dest_ptr = dest_ptr,
917 }
918 }) catch unreachable;
919 continue;
920 },
921 Token.Id.Keyword_switch => {
922 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSwitch,
923 ast.NodeSwitch {
924 .base = undefined,
925 .switch_token = token,
926 .expr = undefined,
927 .cases = ArrayList(&ast.NodeSwitchCase).init(arena),
928 .rbrace = undefined,
929 }
930 );
931
932 stack.append(State {
933 .SwitchCaseOrEnd = ListSave(&ast.NodeSwitchCase) {
934 .list = &node.cases,
935 .ptr = &node.rbrace,
936 },
937 }) catch unreachable;
938 try stack.append(State { .ExpectToken = Token.Id.LBrace });
939 try stack.append(State { .ExpectToken = Token.Id.RParen });
940 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
941 try stack.append(State { .ExpectToken = Token.Id.LParen });
942 },
943 Token.Id.Keyword_comptime => {
944 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeComptime,
945 ast.NodeComptime {
946 .base = undefined,
947 .comptime_token = token,
948 .expr = undefined,
949 }
950 );
951 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
952 continue;
953 },
954 Token.Id.LBrace => {
955 const block = try self.createToDestNode(arena, dest_ptr, ast.NodeBlock,
956 ast.NodeBlock {
957 .base = undefined,
958 .label = null,
959 .lbrace = token,
960 .statements = ArrayList(&ast.Node).init(arena),
961 .rbrace = undefined,
962 }
963 );
964 stack.append(State { .Block = block }) catch unreachable;
965 continue;
966 },
967937 else => {
968 self.putBackToken(token);
969 stack.append(State { .UnwrapExpressionBegin = dest_ptr }) catch unreachable;
938 if (!try self.parseBlockExpr(&stack, arena, dest_ptr, token)) {
939 self.putBackToken(token);
940 stack.append(State { .UnwrapExpressionBegin = dest_ptr }) catch unreachable;
941 }
970942 continue;
971943 }
972944 }
......@@ -1405,7 +1377,7 @@ pub const Parser = struct {
14051377 State.PrefixOpExpression => |dest_ptr| {
14061378 const token = self.getNextToken();
14071379 if (tokenIdToPrefixOp(token.id)) |prefix_id| {
1408 const node = try self.createToDestNode(arena, dest_ptr, ast.NodePrefixOp,
1380 var node = try self.createToDestNode(arena, dest_ptr, ast.NodePrefixOp,
14091381 ast.NodePrefixOp {
14101382 .base = undefined,
14111383 .op_token = token,
......@@ -1413,6 +1385,20 @@ pub const Parser = struct {
14131385 .rhs = undefined,
14141386 }
14151387 );
1388
1389 if (token.id == Token.Id.AsteriskAsterisk) {
1390 const child = try self.createNode(arena, ast.NodePrefixOp,
1391 ast.NodePrefixOp {
1392 .base = undefined,
1393 .op_token = token,
1394 .op = prefix_id,
1395 .rhs = undefined,
1396 }
1397 );
1398 node.rhs = &child.base;
1399 node = child;
1400 }
1401
14161402 stack.append(State { .TypeExprBegin = DestPtr { .Field = &node.rhs } }) catch unreachable;
14171403 if (node.op == ast.NodePrefixOp.PrefixOp.AddrOf) {
14181404 try stack.append(State { .AddrOfModifiers = &node.op.AddrOf });
......@@ -1515,17 +1501,23 @@ pub const Parser = struct {
15151501 continue;
15161502 },
15171503 Token.Id.Period => {
1504 const identifier = try self.createLiteral(arena, ast.NodeIdentifier, Token(undefined));
15181505 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
15191506 ast.NodeInfixOp {
15201507 .base = undefined,
15211508 .lhs = dest_ptr.get(),
15221509 .op_token = token,
15231510 .op = ast.NodeInfixOp.InfixOp.Period,
1524 .rhs = undefined,
1511 .rhs = &identifier.base,
15251512 }
15261513 );
15271514 stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable;
1528 try stack.append(State { .SuffixOpExpressionBegin = DestPtr { .Field = &node.rhs }});
1515 try stack.append(State {
1516 .ExpectTokenSave = ExpectTokenSave {
1517 .id = Token.Id.Identifier,
1518 .ptr = &identifier.token
1519 }
1520 });
15291521 continue;
15301522 },
15311523 else => {
......@@ -1546,10 +1538,6 @@ pub const Parser = struct {
15461538 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeFloatLiteral, token)).base);
15471539 continue;
15481540 },
1549 Token.Id.StringLiteral => {
1550 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeStringLiteral, token)).base);
1551 continue;
1552 },
15531541 Token.Id.CharLiteral => {
15541542 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeCharLiteral, token)).base);
15551543 continue;
......@@ -1578,24 +1566,8 @@ pub const Parser = struct {
15781566 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeUnreachable, token)).base);
15791567 continue;
15801568 },
1581 Token.Id.MultilineStringLiteralLine => {
1582 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeMultilineStringLiteral,
1583 ast.NodeMultilineStringLiteral {
1584 .base = undefined,
1585 .tokens = ArrayList(Token).init(arena),
1586 }
1587 );
1588 try node.tokens.append(token);
1589 while (true) {
1590 const multiline_str = self.getNextToken();
1591 if (multiline_str.id != Token.Id.MultilineStringLiteralLine) {
1592 self.putBackToken(multiline_str);
1593 break;
1594 }
1595
1596 try node.tokens.append(multiline_str);
1597 }
1598 continue;
1569 Token.Id.StringLiteral, Token.Id.MultilineStringLiteralLine => {
1570 dest_ptr.store((try self.parseStringLiteral(arena, token)) ?? unreachable);
15991571 },
16001572 Token.Id.LParen => {
16011573 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeGroupedExpression,
......@@ -1677,11 +1649,8 @@ pub const Parser = struct {
16771649
16781650 },
16791651 Token.Id.Keyword_error => {
1680 const next = self.getNextToken();
1681
1682 if (next.id != Token.Id.LBrace) {
1652 if (self.eatToken(Token.Id.LBrace) == null) {
16831653 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeErrorType, token)).base);
1684 self.putBackToken(next);
16851654 continue;
16861655 }
16871656
......@@ -1694,43 +1663,12 @@ pub const Parser = struct {
16941663 }
16951664 );
16961665
1697 while (true) {
1698 const t = self.getNextToken();
1699 switch (t.id) {
1700 Token.Id.RBrace => {
1701 node.rbrace_token = t;
1702 break;
1703 },
1704 Token.Id.Identifier => {
1705 try node.decls.append(
1706 try self.createLiteral(arena, ast.NodeIdentifier, t)
1707 );
1708 },
1709 else => {
1710 try self.parseError(&stack, token, "expected {} or {}, found {}",
1711 @tagName(Token.Id.RBrace),
1712 @tagName(Token.Id.Identifier),
1713 @tagName(token.id));
1714 continue;
1715 }
1716 }
1717
1718 const t2 = self.getNextToken();
1719 switch (t2.id) {
1720 Token.Id.RBrace => {
1721 node.rbrace_token = t;
1722 break;
1723 },
1724 Token.Id.Comma => continue,
1725 else => {
1726 try self.parseError(&stack, token, "expected {} or {}, found {}",
1727 @tagName(Token.Id.RBrace),
1728 @tagName(Token.Id.Comma),
1729 @tagName(token.id));
1730 continue;
1731 }
1666 stack.append(State {
1667 .IdentifierListItemOrEnd = ListSave(&ast.NodeIdentifier) {
1668 .list = &node.decls,
1669 .ptr = &node.rbrace_token,
17321670 }
1733 }
1671 }) catch unreachable;
17341672 continue;
17351673 },
17361674 Token.Id.Keyword_packed => {
......@@ -1754,8 +1692,7 @@ pub const Parser = struct {
17541692 .params = ArrayList(&ast.Node).init(arena),
17551693 .return_type = undefined,
17561694 .var_args_token = null,
1757 .extern_token = token,
1758 .inline_token = null,
1695 .extern_export_inline_token = token,
17591696 .cc_token = null,
17601697 .async_attr = null,
17611698 .body_node = null,
......@@ -1812,8 +1749,7 @@ pub const Parser = struct {
18121749 .params = ArrayList(&ast.Node).init(arena),
18131750 .return_type = undefined,
18141751 .var_args_token = null,
1815 .extern_token = null,
1816 .inline_token = null,
1752 .extern_export_inline_token = null,
18171753 .cc_token = null,
18181754 .async_attr = null,
18191755 .body_node = null,
......@@ -1835,8 +1771,7 @@ pub const Parser = struct {
18351771 .params = ArrayList(&ast.Node).init(arena),
18361772 .return_type = undefined,
18371773 .var_args_token = null,
1838 .extern_token = null,
1839 .inline_token = null,
1774 .extern_export_inline_token = null,
18401775 .cc_token = token,
18411776 .async_attr = null,
18421777 .body_node = null,
......@@ -1857,7 +1792,12 @@ pub const Parser = struct {
18571792 break :blk true;
18581793 };
18591794 _ = (try self.expectToken(&stack, Token.Id.LParen)) ?? continue;
1860 const template = (try self.expectToken(&stack, Token.Id.StringLiteral)) ?? continue;
1795
1796 const template_token = self.getNextToken();
1797 const template = (try self.parseStringLiteral(arena, template_token)) ?? {
1798 try self.parseError(&stack, template_token, "expected string literal, found {}", @tagName(template_token.id));
1799 continue;
1800 };
18611801 // TODO parse template
18621802
18631803 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeAsm,
......@@ -1869,7 +1809,7 @@ pub const Parser = struct {
18691809 //.tokens = ArrayList(ast.NodeAsm.AsmToken).init(arena),
18701810 .outputs = ArrayList(&ast.NodeAsmOutput).init(arena),
18711811 .inputs = ArrayList(&ast.NodeAsmInput).init(arena),
1872 .cloppers = ArrayList(&ast.NodeStringLiteral).init(arena),
1812 .cloppers = ArrayList(&ast.Node).init(arena),
18731813 .rparen = undefined,
18741814 }
18751815 );
......@@ -1897,7 +1837,9 @@ pub const Parser = struct {
18971837 continue;
18981838 },
18991839 else => {
1900 try self.parseError(&stack, token, "expected primary expression, found {}", @tagName(token.id));
1840 if (!try self.parseBlockExpr(&stack, arena, dest_ptr, token)) {
1841 try self.parseError(&stack, token, "expected primary expression, found {}", @tagName(token.id));
1842 }
19011843 continue;
19021844 }
19031845 }
......@@ -1955,7 +1897,12 @@ pub const Parser = struct {
19551897
19561898 const symbolic_name = (try self.expectToken(&stack, Token.Id.Identifier)) ?? continue;
19571899 _ = (try self.expectToken(&stack, Token.Id.RBracket)) ?? continue;
1958 const constraint = (try self.expectToken(&stack, Token.Id.StringLiteral)) ?? continue;
1900
1901 const constraint_token = self.getNextToken();
1902 const constraint = (try self.parseStringLiteral(arena, constraint_token)) ?? {
1903 try self.parseError(&stack, constraint_token, "expected string literal, found {}", @tagName(constraint_token.id));
1904 continue;
1905 };
19591906
19601907 _ = (try self.expectToken(&stack, Token.Id.LParen)) ?? continue;
19611908 try stack.append(State { .ExpectToken = Token.Id.RParen });
......@@ -1964,7 +1911,7 @@ pub const Parser = struct {
19641911 ast.NodeAsmOutput {
19651912 .base = undefined,
19661913 .symbolic_name = try self.createLiteral(arena, ast.NodeIdentifier, symbolic_name),
1967 .constraint = try self.createLiteral(arena, ast.NodeStringLiteral, constraint),
1914 .constraint = constraint,
19681915 .kind = undefined,
19691916 }
19701917 );
......@@ -2000,7 +1947,12 @@ pub const Parser = struct {
20001947
20011948 const symbolic_name = (try self.expectToken(&stack, Token.Id.Identifier)) ?? continue;
20021949 _ = (try self.expectToken(&stack, Token.Id.RBracket)) ?? continue;
2003 const constraint = (try self.expectToken(&stack, Token.Id.StringLiteral)) ?? continue;
1950
1951 const constraint_token = self.getNextToken();
1952 const constraint = (try self.parseStringLiteral(arena, constraint_token)) ?? {
1953 try self.parseError(&stack, constraint_token, "expected string literal, found {}", @tagName(constraint_token.id));
1954 continue;
1955 };
20041956
20051957 _ = (try self.expectToken(&stack, Token.Id.LParen)) ?? continue;
20061958 try stack.append(State { .ExpectToken = Token.Id.RParen });
......@@ -2009,7 +1961,7 @@ pub const Parser = struct {
20091961 ast.NodeAsmInput {
20101962 .base = undefined,
20111963 .symbolic_name = try self.createLiteral(arena, ast.NodeIdentifier, symbolic_name),
2012 .constraint = try self.createLiteral(arena, ast.NodeStringLiteral, constraint),
1964 .constraint = constraint,
20131965 .expr = undefined,
20141966 }
20151967 );
......@@ -2018,13 +1970,13 @@ pub const Parser = struct {
20181970 },
20191971
20201972 State.AsmClopperItems => |items| {
2021 const string = self.getNextToken();
2022 if (string.id != Token.Id.StringLiteral) {
2023 self.putBackToken(string);
1973 const string_token = self.getNextToken();
1974 const string = (try self.parseStringLiteral(arena, string_token)) ?? {
1975 self.putBackToken(string_token);
20241976 continue;
2025 }
1977 };
1978 try items.append(string);
20261979
2027 try items.append(try self.createLiteral(arena, ast.NodeStringLiteral, string));
20281980 stack.append(State { .AsmClopperItems = items }) catch unreachable;
20291981 try stack.append(State { .IfToken = Token.Id.Comma });
20301982 },
......@@ -2076,6 +2028,24 @@ pub const Parser = struct {
20762028 });
20772029 },
20782030
2031 State.IdentifierListItemOrEnd => |list_state| {
2032 if (self.eatToken(Token.Id.RBrace)) |rbrace| {
2033 *list_state.ptr = rbrace;
2034 continue;
2035 }
2036
2037 const node = try self.createLiteral(arena, ast.NodeIdentifier, Token(undefined));
2038 try list_state.list.append(node);
2039
2040 stack.append(State { .IdentifierListCommaOrEnd = list_state }) catch unreachable;
2041 try stack.append(State {
2042 .ExpectTokenSave = ExpectTokenSave {
2043 .id = Token.Id.Identifier,
2044 .ptr = &node.token,
2045 }
2046 });
2047 },
2048
20792049 State.SwitchCaseOrEnd => |list_state| {
20802050 if (self.eatToken(Token.Id.RBrace)) |rbrace| {
20812051 *list_state.ptr = rbrace;
......@@ -2092,7 +2062,7 @@ pub const Parser = struct {
20922062 );
20932063 try list_state.list.append(node);
20942064 stack.append(State { .SwitchCaseCommaOrEnd = list_state }) catch unreachable;
2095 try stack.append(State { .Expression = DestPtr{ .Field = &node.expr } });
2065 try stack.append(State { .AssignmentExpressionBegin = DestPtr{ .Field = &node.expr } });
20962066 try stack.append(State { .PointerPayload = &node.payload });
20972067
20982068 const maybe_else = self.getNextToken();
......@@ -2133,6 +2103,11 @@ pub const Parser = struct {
21332103 continue;
21342104 },
21352105
2106 State.IdentifierListCommaOrEnd => |list_state| {
2107 try self.commaOrEnd(&stack, Token.Id.RBrace, list_state.ptr, State { .IdentifierListItemOrEnd = list_state });
2108 continue;
2109 },
2110
21362111 State.SwitchCaseCommaOrEnd => |list_state| {
21372112 try self.commaOrEnd(&stack, Token.Id.RBrace, list_state.ptr, State { .SwitchCaseOrEnd = list_state });
21382113 continue;
......@@ -2355,12 +2330,14 @@ pub const Parser = struct {
23552330 },
23562331
23572332 State.FnProtoAlign => |fn_proto| {
2333 stack.append(State { .FnProtoReturnType = fn_proto }) catch unreachable;
2334
23582335 if (self.eatToken(Token.Id.Keyword_align)) |align_token| {
2359 @panic("TODO fn proto align");
2336 try stack.append(State { .ExpectToken = Token.Id.RParen });
2337 try stack.append(State { .Expression = DestPtr { .NullableField = &fn_proto.align_expr } });
2338 try stack.append(State { .ExpectToken = Token.Id.LParen });
23602339 }
2361 stack.append(State {
2362 .FnProtoReturnType = fn_proto,
2363 }) catch unreachable;
2340
23642341 continue;
23652342 },
23662343
......@@ -2374,11 +2351,17 @@ pub const Parser = struct {
23742351 }) catch unreachable;
23752352 continue;
23762353 },
2377 Token.Id.Keyword_align => {
2378 @panic("TODO fn proto align");
2379 continue;
2380 },
23812354 else => {
2355 // TODO: this is a special case. Remove this when #760 is fixed
2356 if (token.id == Token.Id.Keyword_error) {
2357 if (self.isPeekToken(Token.Id.LBrace)) {
2358 fn_proto.return_type = ast.NodeFnProto.ReturnType {
2359 .Explicit = &(try self.createLiteral(arena, ast.NodeErrorType, token)).base
2360 };
2361 continue;
2362 }
2363 }
2364
23822365 self.putBackToken(token);
23832366 fn_proto.return_type = ast.NodeFnProto.ReturnType { .Explicit = undefined };
23842367 stack.append(State {
......@@ -2628,7 +2611,7 @@ pub const Parser = struct {
26282611 .visib_token = null,
26292612 .mut_token = mut_token,
26302613 .comptime_token = next,
2631 .extern_token = null,
2614 .extern_export_token = null,
26322615 .type_node = null,
26332616 .align_node = null,
26342617 .init_node = null,
......@@ -2656,7 +2639,7 @@ pub const Parser = struct {
26562639 .visib_token = null,
26572640 .mut_token = next,
26582641 .comptime_token = null,
2659 .extern_token = null,
2642 .extern_export_token = null,
26602643 .type_node = null,
26612644 .align_node = null,
26622645 .init_node = null,
......@@ -2747,7 +2730,7 @@ pub const Parser = struct {
27472730 continue;
27482731 }
27492732
2750 n = while_node.body;
2733 return while_node.body.id != ast.Node.Id.Block;
27512734 },
27522735 ast.Node.Id.For => {
27532736 const for_node = @fieldParentPtr(ast.NodeFor, "base", n);
......@@ -2756,7 +2739,7 @@ pub const Parser = struct {
27562739 continue;
27572740 }
27582741
2759 n = for_node.body;
2742 return for_node.body.id != ast.Node.Id.Block;
27602743 },
27612744 ast.Node.Id.If => {
27622745 const if_node = @fieldParentPtr(ast.NodeIf, "base", n);
......@@ -2765,25 +2748,25 @@ pub const Parser = struct {
27652748 continue;
27662749 }
27672750
2768 n = if_node.body;
2751 return if_node.body.id != ast.Node.Id.Block;
27692752 },
27702753 ast.Node.Id.Else => {
27712754 const else_node = @fieldParentPtr(ast.NodeElse, "base", n);
27722755 n = else_node.body;
2756 continue;
27732757 },
27742758 ast.Node.Id.Defer => {
27752759 const defer_node = @fieldParentPtr(ast.NodeDefer, "base", n);
2776 n = defer_node.expr;
2760 return defer_node.expr.id != ast.Node.Id.Block;
27772761 },
27782762 ast.Node.Id.Comptime => {
27792763 const comptime_node = @fieldParentPtr(ast.NodeComptime, "base", n);
2780 n = comptime_node.expr;
2764 return comptime_node.expr.id != ast.Node.Id.Block;
27812765 },
27822766 ast.Node.Id.Suspend => {
27832767 const suspend_node = @fieldParentPtr(ast.NodeSuspend, "base", n);
27842768 if (suspend_node.body) |body| {
2785 n = body;
2786 continue;
2769 return body.id != ast.Node.Id.Block;
27872770 }
27882771
27892772 return true;
......@@ -2793,6 +2776,148 @@ pub const Parser = struct {
27932776 }
27942777 }
27952778
2779 fn parseStringLiteral(self: &Parser, arena: &mem.Allocator, token: &const Token) !?&ast.Node {
2780 switch (token.id) {
2781 Token.Id.StringLiteral => {
2782 return &(try self.createLiteral(arena, ast.NodeStringLiteral, token)).base;
2783 },
2784 Token.Id.MultilineStringLiteralLine => {
2785 const node = try self.createNode(arena, ast.NodeMultilineStringLiteral,
2786 ast.NodeMultilineStringLiteral {
2787 .base = undefined,
2788 .tokens = ArrayList(Token).init(arena),
2789 }
2790 );
2791 try node.tokens.append(token);
2792 while (true) {
2793 const multiline_str = self.getNextToken();
2794 if (multiline_str.id != Token.Id.MultilineStringLiteralLine) {
2795 self.putBackToken(multiline_str);
2796 break;
2797 }
2798
2799 try node.tokens.append(multiline_str);
2800 }
2801
2802 return &node.base;
2803 },
2804 // TODO: We shouldn't need a cast, but:
2805 // zig: /home/jc/Documents/zig/src/ir.cpp:7962: TypeTableEntry* ir_resolve_peer_types(IrAnalyze*, AstNode*, IrInstruction**, size_t): Assertion `err_set_type != nullptr' failed.
2806 else => return (?&ast.Node)(null),
2807 }
2808 }
2809
2810 fn parseBlockExpr(self: &Parser, stack: &ArrayList(State), arena: &mem.Allocator, dest_ptr: &const DestPtr, token: &const Token) !bool {
2811 switch (token.id) {
2812 Token.Id.Keyword_suspend => {
2813 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSuspend,
2814 ast.NodeSuspend {
2815 .base = undefined,
2816 .suspend_token = *token,
2817 .payload = null,
2818 .body = null,
2819 }
2820 );
2821
2822 stack.append(State { .SuspendBody = node }) catch unreachable;
2823 try stack.append(State { .Payload = &node.payload });
2824 return true;
2825 },
2826 Token.Id.Keyword_if => {
2827 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeIf,
2828 ast.NodeIf {
2829 .base = undefined,
2830 .if_token = *token,
2831 .condition = undefined,
2832 .payload = null,
2833 .body = undefined,
2834 .@"else" = null,
2835 }
2836 );
2837
2838 stack.append(State { .Else = &node.@"else" }) catch unreachable;
2839 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });
2840 try stack.append(State { .PointerPayload = &node.payload });
2841 try stack.append(State { .ExpectToken = Token.Id.RParen });
2842 try stack.append(State { .Expression = DestPtr { .Field = &node.condition } });
2843 try stack.append(State { .ExpectToken = Token.Id.LParen });
2844 return true;
2845 },
2846 Token.Id.Keyword_while => {
2847 stack.append(State {
2848 .While = LoopCtx {
2849 .label = null,
2850 .inline_token = null,
2851 .loop_token = *token,
2852 .dest_ptr = *dest_ptr,
2853 }
2854 }) catch unreachable;
2855 return true;
2856 },
2857 Token.Id.Keyword_for => {
2858 stack.append(State {
2859 .For = LoopCtx {
2860 .label = null,
2861 .inline_token = null,
2862 .loop_token = *token,
2863 .dest_ptr = *dest_ptr,
2864 }
2865 }) catch unreachable;
2866 return true;
2867 },
2868 Token.Id.Keyword_switch => {
2869 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSwitch,
2870 ast.NodeSwitch {
2871 .base = undefined,
2872 .switch_token = *token,
2873 .expr = undefined,
2874 .cases = ArrayList(&ast.NodeSwitchCase).init(arena),
2875 .rbrace = undefined,
2876 }
2877 );
2878
2879 stack.append(State {
2880 .SwitchCaseOrEnd = ListSave(&ast.NodeSwitchCase) {
2881 .list = &node.cases,
2882 .ptr = &node.rbrace,
2883 },
2884 }) catch unreachable;
2885 try stack.append(State { .ExpectToken = Token.Id.LBrace });
2886 try stack.append(State { .ExpectToken = Token.Id.RParen });
2887 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
2888 try stack.append(State { .ExpectToken = Token.Id.LParen });
2889 return true;
2890 },
2891 Token.Id.Keyword_comptime => {
2892 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeComptime,
2893 ast.NodeComptime {
2894 .base = undefined,
2895 .comptime_token = *token,
2896 .expr = undefined,
2897 }
2898 );
2899 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
2900 return true;
2901 },
2902 Token.Id.LBrace => {
2903 const block = try self.createToDestNode(arena, dest_ptr, ast.NodeBlock,
2904 ast.NodeBlock {
2905 .base = undefined,
2906 .label = null,
2907 .lbrace = *token,
2908 .statements = ArrayList(&ast.Node).init(arena),
2909 .rbrace = undefined,
2910 }
2911 );
2912 stack.append(State { .Block = block }) catch unreachable;
2913 return true;
2914 },
2915 else => {
2916 return false;
2917 }
2918 }
2919 }
2920
27962921 fn commaOrEnd(self: &Parser, stack: &ArrayList(State), end: &const Token.Id, maybe_ptr: ?&Token, state_after_comma: &const State) !void {
27972922 var token = self.getNextToken();
27982923 switch (token.id) {
......@@ -2884,7 +3009,7 @@ pub const Parser = struct {
28843009 Token.Id.Tilde => ast.NodePrefixOp.PrefixOp { .BitNot = void{} },
28853010 Token.Id.Minus => ast.NodePrefixOp.PrefixOp { .Negation = void{} },
28863011 Token.Id.MinusPercent => ast.NodePrefixOp.PrefixOp { .NegationWrap = void{} },
2887 Token.Id.Asterisk => ast.NodePrefixOp.PrefixOp { .Deref = void{} },
3012 Token.Id.Asterisk, Token.Id.AsteriskAsterisk => ast.NodePrefixOp.PrefixOp { .Deref = void{} },
28883013 Token.Id.Ampersand => ast.NodePrefixOp.PrefixOp {
28893014 .AddrOf = ast.NodePrefixOp.AddrOfInfo {
28903015 .align_expr = null,
......@@ -2897,6 +3022,7 @@ pub const Parser = struct {
28973022 Token.Id.QuestionMark => ast.NodePrefixOp.PrefixOp { .MaybeType = void{} },
28983023 Token.Id.QuestionMarkQuestionMark => ast.NodePrefixOp.PrefixOp { .UnwrapMaybe = void{} },
28993024 Token.Id.Keyword_await => ast.NodePrefixOp.PrefixOp { .Await = void{} },
3025 Token.Id.Keyword_try => ast.NodePrefixOp.PrefixOp { .Try = void{ } },
29003026 else => null,
29013027 };
29023028 }
......@@ -3051,7 +3177,6 @@ pub const Parser = struct {
30513177
30523178 const RenderState = union(enum) {
30533179 TopLevelDecl: &ast.Node,
3054 FnProtoRParen: &ast.NodeFnProto,
30553180 ParamDecl: &ast.Node,
30563181 Text: []const u8,
30573182 Expression: &ast.Node,
......@@ -3129,6 +3254,9 @@ pub const Parser = struct {
31293254 },
31303255 ast.Node.Id.StructField => {
31313256 const field = @fieldParentPtr(ast.NodeStructField, "base", decl);
3257 if (field.visib_token) |visib_token| {
3258 try stream.print("{} ", self.tokenizer.getTokenSlice(visib_token));
3259 }
31323260 try stream.print("{}: ", self.tokenizer.getTokenSlice(field.name_token));
31333261 try stack.append(RenderState { .Expression = field.type_expr});
31343262 },
......@@ -3190,13 +3318,13 @@ pub const Parser = struct {
31903318 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(comptime_token) });
31913319 }
31923320
3193 if (var_decl.extern_token) |extern_token| {
3321 if (var_decl.extern_export_token) |extern_export_token| {
31943322 if (var_decl.lib_name != null) {
31953323 try stack.append(RenderState { .Text = " " });
31963324 try stack.append(RenderState { .Expression = ??var_decl.lib_name });
31973325 }
31983326 try stack.append(RenderState { .Text = " " });
3199 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_token) });
3327 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_export_token) });
32003328 }
32013329
32023330 if (var_decl.visib_token) |visib_token| {
......@@ -3737,8 +3865,10 @@ pub const Parser = struct {
37373865 },
37383866 }
37393867
3740 if (fn_proto.align_expr != null) {
3741 @panic("TODO");
3868 if (fn_proto.align_expr) |align_expr| {
3869 try stack.append(RenderState { .Text = ") " });
3870 try stack.append(RenderState { .Expression = align_expr});
3871 try stack.append(RenderState { .Text = "align(" });
37423872 }
37433873
37443874 try stack.append(RenderState { .Text = ") " });
......@@ -3774,9 +3904,9 @@ pub const Parser = struct {
37743904 try stack.append(RenderState { .Text = " " });
37753905 try stack.append(RenderState { .Expression = lib_name });
37763906 }
3777 if (fn_proto.extern_token) |extern_token| {
3907 if (fn_proto.extern_export_inline_token) |extern_export_inline_token| {
37783908 try stack.append(RenderState { .Text = " " });
3779 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_token) });
3909 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_export_inline_token) });
37803910 }
37813911
37823912 if (fn_proto.visib_token) |visib_token| {
......@@ -4021,8 +4151,6 @@ pub const Parser = struct {
40214151 try stream.write("volatile ");
40224152 }
40234153
4024 try stream.print("({}", self.tokenizer.getTokenSlice(asm_node.template));
4025
40264154 try stack.append(RenderState { .Indent = indent });
40274155 try stack.append(RenderState { .Text = ")" });
40284156 {
......@@ -4030,7 +4158,7 @@ pub const Parser = struct {
40304158 var i = cloppers.len;
40314159 while (i != 0) {
40324160 i -= 1;
4033 try stack.append(RenderState { .Expression = &cloppers[i].base });
4161 try stack.append(RenderState { .Expression = cloppers[i] });
40344162
40354163 if (i != 0) {
40364164 try stack.append(RenderState { .Text = ", " });
......@@ -4099,6 +4227,8 @@ pub const Parser = struct {
40994227 try stack.append(RenderState.PrintIndent);
41004228 try stack.append(RenderState { .Indent = indent + indent_delta});
41014229 try stack.append(RenderState { .Text = "\n" });
4230 try stack.append(RenderState { .Expression = asm_node.template });
4231 try stack.append(RenderState { .Text = "(" });
41024232 },
41034233 ast.Node.Id.AsmInput => {
41044234 const asm_input = @fieldParentPtr(ast.NodeAsmInput, "base", base);
......@@ -4106,7 +4236,7 @@ pub const Parser = struct {
41064236 try stack.append(RenderState { .Text = ")"});
41074237 try stack.append(RenderState { .Expression = asm_input.expr});
41084238 try stack.append(RenderState { .Text = " ("});
4109 try stack.append(RenderState { .Expression = &asm_input.constraint.base});
4239 try stack.append(RenderState { .Expression = asm_input.constraint });
41104240 try stack.append(RenderState { .Text = "] "});
41114241 try stack.append(RenderState { .Expression = &asm_input.symbolic_name.base});
41124242 try stack.append(RenderState { .Text = "["});
......@@ -4125,7 +4255,7 @@ pub const Parser = struct {
41254255 },
41264256 }
41274257 try stack.append(RenderState { .Text = " ("});
4128 try stack.append(RenderState { .Expression = &asm_output.constraint.base});
4258 try stack.append(RenderState { .Expression = asm_output.constraint });
41294259 try stack.append(RenderState { .Text = "] "});
41304260 try stack.append(RenderState { .Expression = &asm_output.symbolic_name.base});
41314261 try stack.append(RenderState { .Text = "["});
......@@ -4140,26 +4270,6 @@ pub const Parser = struct {
41404270 ast.Node.Id.TestDecl,
41414271 ast.Node.Id.ParamDecl => unreachable,
41424272 },
4143 RenderState.FnProtoRParen => |fn_proto| {
4144 try stream.print(")");
4145 if (fn_proto.align_expr != null) {
4146 @panic("TODO");
4147 }
4148 try stream.print(" ");
4149 if (fn_proto.body_node) |body_node| {
4150 try stack.append(RenderState { .Expression = body_node});
4151 try stack.append(RenderState { .Text = " "});
4152 }
4153 switch (fn_proto.return_type) {
4154 ast.NodeFnProto.ReturnType.Explicit => |node| {
4155 try stack.append(RenderState { .Expression = node});
4156 },
4157 ast.NodeFnProto.ReturnType.InferErrorSet => |node| {
4158 try stream.print("!");
4159 try stack.append(RenderState { .Expression = node});
4160 },
4161 }
4162 },
41634273 RenderState.Statement => |base| {
41644274 if (base.comment) |comment| {
41654275 for (comment.lines.toSliceConst()) |line_token| {
......@@ -4513,10 +4623,20 @@ test "zig fmt: var type" {
45134623 );
45144624}
45154625
4516test "zig fmt: extern function" {
4626test "zig fmt: functions" {
45174627 try testCanonical(
45184628 \\extern fn puts(s: &const u8) c_int;
45194629 \\extern "c" fn puts(s: &const u8) c_int;
4630 \\export fn puts(s: &const u8) c_int;
4631 \\inline fn puts(s: &const u8) c_int;
4632 \\pub extern fn puts(s: &const u8) c_int;
4633 \\pub extern "c" fn puts(s: &const u8) c_int;
4634 \\pub export fn puts(s: &const u8) c_int;
4635 \\pub inline fn puts(s: &const u8) c_int;
4636 \\pub extern fn puts(s: &const u8) align(2 + 2) c_int;
4637 \\pub extern "c" fn puts(s: &const u8) align(2 + 2) c_int;
4638 \\pub export fn puts(s: &const u8) align(2 + 2) c_int;
4639 \\pub inline fn puts(s: &const u8) align(2 + 2) c_int;
45204640 \\
45214641 );
45224642}
......@@ -4576,6 +4696,7 @@ test "zig fmt: struct declaration" {
45764696 \\const S = struct {
45774697 \\ const Self = this;
45784698 \\ f1: u8,
4699 \\ pub f3: u8,
45794700 \\
45804701 \\ fn method(self: &Self) Self {
45814702 \\ return *self;
......@@ -4586,14 +4707,14 @@ test "zig fmt: struct declaration" {
45864707 \\
45874708 \\const Ps = packed struct {
45884709 \\ a: u8,
4589 \\ b: u8,
4710 \\ pub b: u8,
45904711 \\
45914712 \\ c: u8
45924713 \\};
45934714 \\
45944715 \\const Es = extern struct {
45954716 \\ a: u8,
4596 \\ b: u8,
4717 \\ pub b: u8,
45974718 \\
45984719 \\ c: u8
45994720 \\};
......@@ -4753,6 +4874,7 @@ test "zig fmt: switch" {
47534874 \\ const res = switch (0) {
47544875 \\ 0 => 0,
47554876 \\ 1 => 2,
4877 \\ 1 => a = 4,
47564878 \\ else => 4
47574879 \\ };
47584880 \\
......@@ -4898,6 +5020,7 @@ test "zig fmt: if" {
48985020 \\ }
48995021 \\
49005022 \\ const is_world_broken = if (10 < 0) true else false;
5023 \\ const some_number = 1 + if (10 < 0) 2 else 3;
49015024 \\
49025025 \\ const a: ?u8 = 10;
49035026 \\ const b: ?u8 = null;
......@@ -5011,6 +5134,7 @@ test "zig fmt: inline asm" {
50115134test "zig fmt: coroutines" {
50125135 try testCanonical(
50135136 \\async fn simpleAsyncFn() void {
5137 \\ const a = async a.b();
50145138 \\ x += 1;
50155139 \\ suspend;
50165140 \\ x += 1;
......@@ -5058,3 +5182,13 @@ test "zig fmt: string identifier" {
50585182 \\
50595183 );
50605184}
5185
5186test "zig fmt: error return" {
5187 try testCanonical(
5188 \\fn err() error {
5189 \\ call();
5190 \\ return error.InvalidArgs;
5191 \\}
5192 \\
5193 );
5194}
test/cases/fn.zig+10
......@@ -94,3 +94,13 @@ test "inline function call" {
9494}
9595
9696fn add(a: i32, b: i32) i32 { return a + b; }
97
98
99test "number literal as an argument" {
100 numberLiteralArg(3);
101 comptime numberLiteralArg(3);
102}
103
104fn numberLiteralArg(a: var) void {
105 assert(a == 3);
106}
test/compile_errors.zig+1-1
......@@ -1723,7 +1723,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
17231723 \\}
17241724 \\
17251725 \\export fn entry() usize { return @sizeOf(@typeOf(bar)); }
1726 , ".tmp_source.zig:10:16: error: parameter of type '(integer literal)' requires comptime");
1726 , ".tmp_source.zig:10:16: error: compiler bug: integer and float literals in var args function must be casted");
17271727
17281728 cases.add("assign too big number to u16",
17291729 \\export fn foo() void {