| ... | @@ -87,6 +87,7 @@ pub const Parser = struct { | ... | @@ -87,6 +87,7 @@ pub const Parser = struct { |
| 87 | ExpectToken: @TagType(Token.Id), | 87 | ExpectToken: @TagType(Token.Id), |
| 88 | FnProto: &ast.NodeFnProto, | 88 | FnProto: &ast.NodeFnProto, |
| 89 | FnProtoAlign: &ast.NodeFnProto, | 89 | FnProtoAlign: &ast.NodeFnProto, |
| | 90 | FnProtoReturnType: &ast.NodeFnProto, |
| 90 | ParamDecl: &ast.NodeFnProto, | 91 | ParamDecl: &ast.NodeFnProto, |
| 91 | ParamDeclComma, | 92 | ParamDeclComma, |
| 92 | FnDef: &ast.NodeFnProto, | 93 | FnDef: &ast.NodeFnProto, |
| ... | @@ -178,7 +179,7 @@ pub const Parser = struct { | ... | @@ -178,7 +179,7 @@ pub const Parser = struct { |
| 178 | stack.append(State.TopLevel) catch unreachable; | 179 | stack.append(State.TopLevel) catch unreachable; |
| 179 | // TODO shouldn't need these casts | 180 | // TODO shouldn't need these casts |
| 180 | const fn_proto = try self.createAttachFnProto(arena, &root_node.decls, token, | 181 | const fn_proto = try self.createAttachFnProto(arena, &root_node.decls, token, |
| 181 | ctx.extern_token, (?Token)(null), (?Token)(null), (?Token)(null)); | 182 | ctx.extern_token, (?Token)(null), ctx.visib_token, (?Token)(null)); |
| 182 | try stack.append(State { .FnDef = fn_proto }); | 183 | try stack.append(State { .FnDef = fn_proto }); |
| 183 | try stack.append(State { .FnProto = fn_proto }); | 184 | try stack.append(State { .FnProto = fn_proto }); |
| 184 | continue; | 185 | continue; |
| ... | @@ -466,11 +467,37 @@ pub const Parser = struct { | ... | @@ -466,11 +467,37 @@ pub const Parser = struct { |
| 466 | } | 467 | } |
| 467 | self.putBackToken(token); | 468 | self.putBackToken(token); |
| 468 | stack.append(State { | 469 | stack.append(State { |
| 469 | .TypeExpr = DestPtr {.Field = &fn_proto.return_type}, | 470 | .FnProtoReturnType = fn_proto, |
| 470 | }) catch unreachable; | 471 | }) catch unreachable; |
| 471 | continue; | 472 | continue; |
| 472 | }, | 473 | }, |
| 473 | | 474 | |
| | 475 | State.FnProtoReturnType => |fn_proto| { |
| | 476 | const token = self.getNextToken(); |
| | 477 | switch (token.id) { |
| | 478 | Token.Id.Keyword_var => { |
| | 479 | fn_proto.return_type = ast.NodeFnProto.ReturnType.Infer; |
| | 480 | }, |
| | 481 | Token.Id.Bang => { |
| | 482 | fn_proto.return_type = ast.NodeFnProto.ReturnType { .InferErrorSet = undefined }; |
| | 483 | stack.append(State { |
| | 484 | .TypeExpr = DestPtr {.Field = &fn_proto.return_type.InferErrorSet}, |
| | 485 | }) catch unreachable; |
| | 486 | }, |
| | 487 | else => { |
| | 488 | self.putBackToken(token); |
| | 489 | fn_proto.return_type = ast.NodeFnProto.ReturnType { .Explicit = undefined }; |
| | 490 | stack.append(State { |
| | 491 | .TypeExpr = DestPtr {.Field = &fn_proto.return_type.Explicit}, |
| | 492 | }) catch unreachable; |
| | 493 | }, |
| | 494 | } |
| | 495 | if (token.id == Token.Id.Keyword_align) { |
| | 496 | @panic("TODO fn proto align"); |
| | 497 | } |
| | 498 | continue; |
| | 499 | }, |
| | 500 | |
| 474 | State.ParamDecl => |fn_proto| { | 501 | State.ParamDecl => |fn_proto| { |
| 475 | var token = self.getNextToken(); | 502 | var token = self.getNextToken(); |
| 476 | if (token.id == Token.Id.RParen) { | 503 | if (token.id == Token.Id.RParen) { |
| ... | @@ -977,19 +1004,23 @@ pub const Parser = struct { | ... | @@ -977,19 +1004,23 @@ pub const Parser = struct { |
| 977 | }, | 1004 | }, |
| 978 | ast.Node.Id.Block => { | 1005 | ast.Node.Id.Block => { |
| 979 | const block = @fieldParentPtr(ast.NodeBlock, "base", base); | 1006 | const block = @fieldParentPtr(ast.NodeBlock, "base", base); |
| 980 | try stream.write("{"); | 1007 | if (block.statements.len == 0) { |
| 981 | try stack.append(RenderState { .Text = "}"}); | 1008 | try stream.write("{}"); |
| 982 | try stack.append(RenderState.PrintIndent); | 1009 | } else { |
| 983 | try stack.append(RenderState { .Indent = indent}); | 1010 | try stream.write("{"); |
| 984 | try stack.append(RenderState { .Text = "\n"}); | 1011 | try stack.append(RenderState { .Text = "}"}); |
| 985 | var i = block.statements.len; | | |
| 986 | while (i != 0) { | | |
| 987 | i -= 1; | | |
| 988 | const statement_node = block.statements.items[i]; | | |
| 989 | try stack.append(RenderState { .Statement = statement_node}); | | |
| 990 | try stack.append(RenderState.PrintIndent); | 1012 | try stack.append(RenderState.PrintIndent); |
| 991 | try stack.append(RenderState { .Indent = indent + indent_delta}); | 1013 | try stack.append(RenderState { .Indent = indent}); |
| 992 | try stack.append(RenderState { .Text = "\n" }); | 1014 | try stack.append(RenderState { .Text = "\n"}); |
| | 1015 | var i = block.statements.len; |
| | 1016 | while (i != 0) { |
| | 1017 | i -= 1; |
| | 1018 | const statement_node = block.statements.items[i]; |
| | 1019 | try stack.append(RenderState { .Statement = statement_node}); |
| | 1020 | try stack.append(RenderState.PrintIndent); |
| | 1021 | try stack.append(RenderState { .Indent = indent + indent_delta}); |
| | 1022 | try stack.append(RenderState { .Text = "\n" }); |
| | 1023 | } |
| 993 | } | 1024 | } |
| 994 | }, | 1025 | }, |
| 995 | ast.Node.Id.InfixOp => { | 1026 | ast.Node.Id.InfixOp => { |
| ... | @@ -1071,7 +1102,18 @@ pub const Parser = struct { | ... | @@ -1071,7 +1102,18 @@ pub const Parser = struct { |
| 1071 | try stack.append(RenderState { .Expression = body_node}); | 1102 | try stack.append(RenderState { .Expression = body_node}); |
| 1072 | try stack.append(RenderState { .Text = " "}); | 1103 | try stack.append(RenderState { .Text = " "}); |
| 1073 | } | 1104 | } |
| 1074 | try stack.append(RenderState { .Expression = fn_proto.return_type}); | 1105 | switch (fn_proto.return_type) { |
| | 1106 | ast.NodeFnProto.ReturnType.Explicit => |node| { |
| | 1107 | try stack.append(RenderState { .Expression = node}); |
| | 1108 | }, |
| | 1109 | ast.NodeFnProto.ReturnType.Infer => { |
| | 1110 | try stream.print("var"); |
| | 1111 | }, |
| | 1112 | ast.NodeFnProto.ReturnType.InferErrorSet => |node| { |
| | 1113 | try stream.print("!"); |
| | 1114 | try stack.append(RenderState { .Expression = node}); |
| | 1115 | }, |
| | 1116 | } |
| 1075 | }, | 1117 | }, |
| 1076 | RenderState.Statement => |base| { | 1118 | RenderState.Statement => |base| { |
| 1077 | switch (base.id) { | 1119 | switch (base.id) { |
| ... | @@ -1169,6 +1211,13 @@ fn testCanonical(source: []const u8) !void { | ... | @@ -1169,6 +1211,13 @@ fn testCanonical(source: []const u8) !void { |
| 1169 | } | 1211 | } |
| 1170 | | 1212 | |
| 1171 | test "zig fmt" { | 1213 | test "zig fmt" { |
| | 1214 | try testCanonical( |
| | 1215 | \\pub fn main() !void {} |
| | 1216 | \\pub fn main() var {} |
| | 1217 | \\pub fn main() i32 {} |
| | 1218 | \\ |
| | 1219 | ); |
| | 1220 | |
| 1172 | try testCanonical( | 1221 | try testCanonical( |
| 1173 | \\const std = @import("std"); | 1222 | \\const std = @import("std"); |
| 1174 | \\const std = @import(); | 1223 | \\const std = @import(); |