| ... | ... | @@ -87,6 +87,7 @@ pub const Parser = struct { |
| 87 | 87 | ExpectToken: @TagType(Token.Id), |
| 88 | 88 | FnProto: &ast.NodeFnProto, |
| 89 | 89 | FnProtoAlign: &ast.NodeFnProto, |
| 90 | FnProtoReturnType: &ast.NodeFnProto, |
| 90 | 91 | ParamDecl: &ast.NodeFnProto, |
| 91 | 92 | ParamDeclComma, |
| 92 | 93 | FnDef: &ast.NodeFnProto, |
| ... | ... | @@ -178,7 +179,7 @@ pub const Parser = struct { |
| 178 | 179 | stack.append(State.TopLevel) catch unreachable; |
| 179 | 180 | // TODO shouldn't need these casts |
| 180 | 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 | 183 | try stack.append(State { .FnDef = fn_proto }); |
| 183 | 184 | try stack.append(State { .FnProto = fn_proto }); |
| 184 | 185 | continue; |
| ... | ... | @@ -466,11 +467,37 @@ pub const Parser = struct { |
| 466 | 467 | } |
| 467 | 468 | self.putBackToken(token); |
| 468 | 469 | stack.append(State { |
| 469 | | .TypeExpr = DestPtr {.Field = &fn_proto.return_type}, |
| 470 | .FnProtoReturnType = fn_proto, |
| 470 | 471 | }) catch unreachable; |
| 471 | 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 | 501 | State.ParamDecl => |fn_proto| { |
| 475 | 502 | var token = self.getNextToken(); |
| 476 | 503 | if (token.id == Token.Id.RParen) { |
| ... | ... | @@ -977,19 +1004,23 @@ pub const Parser = struct { |
| 977 | 1004 | }, |
| 978 | 1005 | ast.Node.Id.Block => { |
| 979 | 1006 | const block = @fieldParentPtr(ast.NodeBlock, "base", base); |
| 980 | | try stream.write("{"); |
| 981 | | try stack.append(RenderState { .Text = "}"}); |
| 982 | | try stack.append(RenderState.PrintIndent); |
| 983 | | try stack.append(RenderState { .Indent = indent}); |
| 984 | | try stack.append(RenderState { .Text = "\n"}); |
| 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}); |
| 1007 | if (block.statements.len == 0) { |
| 1008 | try stream.write("{}"); |
| 1009 | } else { |
| 1010 | try stream.write("{"); |
| 1011 | try stack.append(RenderState { .Text = "}"}); |
| 990 | 1012 | try stack.append(RenderState.PrintIndent); |
| 991 | | try stack.append(RenderState { .Indent = indent + indent_delta}); |
| 992 | | try stack.append(RenderState { .Text = "\n" }); |
| 1013 | try stack.append(RenderState { .Indent = indent}); |
| 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 | 1026 | ast.Node.Id.InfixOp => { |
| ... | ... | @@ -1071,7 +1102,18 @@ pub const Parser = struct { |
| 1071 | 1102 | try stack.append(RenderState { .Expression = body_node}); |
| 1072 | 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 | 1118 | RenderState.Statement => |base| { |
| 1077 | 1119 | switch (base.id) { |
| ... | ... | @@ -1169,6 +1211,13 @@ fn testCanonical(source: []const u8) !void { |
| 1169 | 1211 | } |
| 1170 | 1212 | |
| 1171 | 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 | 1221 | try testCanonical( |
| 1173 | 1222 | \\const std = @import("std"); |
| 1174 | 1223 | \\const std = @import(); |