authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-03-31 17:46:29+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-03-31 17:46:29+02:00
log4793c3397e17169317d2feded9ca6901ff0e99e8
treea5853ece8a1f54c831917f06ca59cf6c1306bbbc
parentcda35093537221abe7c148c57b3a28892046b8b2

std.zig.parser now handles lib name for extern var and fn


2 files changed, 102 insertions(+), 63 deletions(-)

std/zig/ast.zig+1-2
......@@ -624,7 +624,7 @@ pub const NodeLineComment = struct {
624624pub const NodeTestDecl = struct {
625625 base: Node,
626626 test_token: Token,
627 name_token: Token,
627 name: &Node,
628628 body_node: &Node,
629629
630630 pub fn iterate(self: &NodeTestDecl, index: usize) ?&Node {
......@@ -644,4 +644,3 @@ pub const NodeTestDecl = struct {
644644 return self.body_node.lastToken();
645645 }
646646};
647
std/zig/parser.zig+101-61
......@@ -55,6 +55,7 @@ pub const Parser = struct {
5555 const TopLevelDeclCtx = struct {
5656 visib_token: ?Token,
5757 extern_token: ?Token,
58 lib_name: ?&ast.Node,
5859 };
5960
6061 const DestPtr = union(enum) {
......@@ -183,8 +184,9 @@ pub const Parser = struct {
183184 if (lbrace.id != Token.Id.LBrace)
184185 return self.parseError(token, "expected {}, found {}", @tagName(Token.Id.LBrace), @tagName(name_token.id));
185186
187 const name = try self.createStringLiteral(arena, name_token);
186188 const block = try self.createBlock(arena, token);
187 const test_decl = try self.createAttachTestDecl(arena, &root_node.decls, token, name_token, block);
189 const test_decl = try self.createAttachTestDecl(arena, &root_node.decls, token, &name.base, block);
188190 try stack.append(State { .Block = block });
189191 continue;
190192 },
......@@ -202,10 +204,22 @@ pub const Parser = struct {
202204 State.TopLevelExtern => |visib_token| {
203205 const token = self.getNextToken();
204206 if (token.id == Token.Id.Keyword_extern) {
207 const lib_name_token = self.getNextToken();
208 const lib_name = blk: {
209 if (lib_name_token.id == Token.Id.StringLiteral) {
210 const res = try self.createStringLiteral(arena, lib_name_token);
211 break :blk &res.base;
212 } else {
213 self.putBackToken(lib_name_token);
214 break :blk null;
215 }
216 };
217
205218 stack.append(State {
206219 .TopLevelDecl = TopLevelDeclCtx {
207220 .visib_token = visib_token,
208221 .extern_token = token,
222 .lib_name = lib_name,
209223 },
210224 }) catch unreachable;
211225 continue;
......@@ -215,6 +229,7 @@ pub const Parser = struct {
215229 .TopLevelDecl = TopLevelDeclCtx {
216230 .visib_token = visib_token,
217231 .extern_token = null,
232 .lib_name = null,
218233 },
219234 }) catch unreachable;
220235 continue;
......@@ -226,7 +241,7 @@ pub const Parser = struct {
226241 stack.append(State.TopLevel) catch unreachable;
227242 // TODO shouldn't need these casts
228243 const var_decl_node = try self.createAttachVarDecl(arena, &root_node.decls, ctx.visib_token,
229 token, (?Token)(null), ctx.extern_token);
244 token, (?Token)(null), ctx.extern_token, ctx.lib_name);
230245 try stack.append(State { .VarDecl = var_decl_node });
231246 continue;
232247 },
......@@ -234,20 +249,17 @@ pub const Parser = struct {
234249 stack.append(State.TopLevel) catch unreachable;
235250 // TODO shouldn't need these casts
236251 const fn_proto = try self.createAttachFnProto(arena, &root_node.decls, token,
237 ctx.extern_token, (?Token)(null), ctx.visib_token, (?Token)(null));
252 ctx.extern_token, ctx.lib_name, (?Token)(null), ctx.visib_token, (?Token)(null));
238253 try stack.append(State { .FnDef = fn_proto });
239254 try stack.append(State { .FnProto = fn_proto });
240255 continue;
241256 },
242 Token.Id.StringLiteral => {
243 @panic("TODO extern with string literal");
244 },
245257 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
246258 stack.append(State.TopLevel) catch unreachable;
247259 const fn_token = try self.eatToken(Token.Id.Keyword_fn);
248260 // TODO shouldn't need this cast
249261 const fn_proto = try self.createAttachFnProto(arena, &root_node.decls, fn_token,
250 ctx.extern_token, (?Token)(token), (?Token)(null), (?Token)(null));
262 ctx.extern_token, ctx.lib_name, (?Token)(token), (?Token)(null), (?Token)(null));
251263 try stack.append(State { .FnDef = fn_proto });
252264 try stack.append(State { .FnProto = fn_proto });
253265 continue;
......@@ -437,11 +449,7 @@ pub const Parser = struct {
437449 continue;
438450 },
439451 Token.Id.StringLiteral => {
440 const node = try arena.create(ast.NodeStringLiteral);
441 *node = ast.NodeStringLiteral {
442 .base = self.initNode(ast.Node.Id.StringLiteral),
443 .token = token,
444 };
452 const node = try self.createStringLiteral(arena, token);
445453 try stack.append(State {
446454 .Operand = &node.base
447455 });
......@@ -722,7 +730,7 @@ pub const Parser = struct {
722730 if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) {
723731 // TODO shouldn't need these casts
724732 const var_decl = try self.createAttachVarDecl(arena, &block.statements, (?Token)(null),
725 mut_token, (?Token)(comptime_token), (?Token)(null));
733 mut_token, (?Token)(comptime_token), (?Token)(null), null);
726734 try stack.append(State { .VarDecl = var_decl });
727735 continue;
728736 }
......@@ -736,7 +744,7 @@ pub const Parser = struct {
736744 if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) {
737745 // TODO shouldn't need these casts
738746 const var_decl = try self.createAttachVarDecl(arena, &block.statements, (?Token)(null),
739 mut_token, (?Token)(null), (?Token)(null));
747 mut_token, (?Token)(null), (?Token)(null), null);
740748 try stack.append(State { .VarDecl = var_decl });
741749 continue;
742750 }
......@@ -852,7 +860,7 @@ pub const Parser = struct {
852860 }
853861
854862 fn createVarDecl(self: &Parser, arena: &mem.Allocator, visib_token: &const ?Token, mut_token: &const Token,
855 comptime_token: &const ?Token, extern_token: &const ?Token) !&ast.NodeVarDecl
863 comptime_token: &const ?Token, extern_token: &const ?Token, lib_name: ?&ast.Node) !&ast.NodeVarDecl
856864 {
857865 const node = try arena.create(ast.NodeVarDecl);
858866
......@@ -865,7 +873,7 @@ pub const Parser = struct {
865873 .type_node = null,
866874 .align_node = null,
867875 .init_node = null,
868 .lib_name = null,
876 .lib_name = lib_name,
869877 // initialized later
870878 .name_token = undefined,
871879 .eq_token = undefined,
......@@ -874,7 +882,18 @@ pub const Parser = struct {
874882 return node;
875883 }
876884
877 fn createTestDecl(self: &Parser, arena: &mem.Allocator, test_token: &const Token, name_token: &const Token,
885 fn createStringLiteral(self: &Parser, arena: &mem.Allocator, token: &const Token) !&ast.NodeStringLiteral {
886 const node = try arena.create(ast.NodeStringLiteral);
887
888 assert(token.id == Token.Id.StringLiteral);
889 *node = ast.NodeStringLiteral {
890 .base = self.initNode(ast.Node.Id.StringLiteral),
891 .token = *token,
892 };
893 return node;
894 }
895
896 fn createTestDecl(self: &Parser, arena: &mem.Allocator, test_token: &const Token, name: &ast.Node,
878897 block: &ast.NodeBlock) !&ast.NodeTestDecl
879898 {
880899 const node = try arena.create(ast.NodeTestDecl);
......@@ -882,14 +901,14 @@ pub const Parser = struct {
882901 *node = ast.NodeTestDecl {
883902 .base = self.initNode(ast.Node.Id.TestDecl),
884903 .test_token = *test_token,
885 .name_token = *name_token,
904 .name = name,
886905 .body_node = &block.base,
887906 };
888907 return node;
889908 }
890909
891910 fn createFnProto(self: &Parser, arena: &mem.Allocator, fn_token: &const Token, extern_token: &const ?Token,
892 cc_token: &const ?Token, visib_token: &const ?Token, inline_token: &const ?Token) !&ast.NodeFnProto
911 lib_name: ?&ast.Node, cc_token: &const ?Token, visib_token: &const ?Token, inline_token: &const ?Token) !&ast.NodeFnProto
893912 {
894913 const node = try arena.create(ast.NodeFnProto);
895914
......@@ -905,7 +924,7 @@ pub const Parser = struct {
905924 .inline_token = *inline_token,
906925 .cc_token = *cc_token,
907926 .body_node = null,
908 .lib_name = null,
927 .lib_name = lib_name,
909928 .align_expr = null,
910929 };
911930 return node;
......@@ -1015,27 +1034,27 @@ pub const Parser = struct {
10151034 }
10161035
10171036 fn createAttachFnProto(self: &Parser, arena: &mem.Allocator, list: &ArrayList(&ast.Node), fn_token: &const Token,
1018 extern_token: &const ?Token, cc_token: &const ?Token, visib_token: &const ?Token,
1037 extern_token: &const ?Token, lib_name: ?&ast.Node, cc_token: &const ?Token, visib_token: &const ?Token,
10191038 inline_token: &const ?Token) !&ast.NodeFnProto
10201039 {
1021 const node = try self.createFnProto(arena, fn_token, extern_token, cc_token, visib_token, inline_token);
1040 const node = try self.createFnProto(arena, fn_token, extern_token, lib_name, cc_token, visib_token, inline_token);
10221041 try list.append(&node.base);
10231042 return node;
10241043 }
10251044
10261045 fn createAttachVarDecl(self: &Parser, arena: &mem.Allocator, list: &ArrayList(&ast.Node),
10271046 visib_token: &const ?Token, mut_token: &const Token, comptime_token: &const ?Token,
1028 extern_token: &const ?Token) !&ast.NodeVarDecl
1047 extern_token: &const ?Token, lib_name: ?&ast.Node) !&ast.NodeVarDecl
10291048 {
1030 const node = try self.createVarDecl(arena, visib_token, mut_token, comptime_token, extern_token);
1049 const node = try self.createVarDecl(arena, visib_token, mut_token, comptime_token, extern_token, lib_name);
10311050 try list.append(&node.base);
10321051 return node;
10331052 }
10341053
10351054 fn createAttachTestDecl(self: &Parser, arena: &mem.Allocator, list: &ArrayList(&ast.Node),
1036 test_token: &const Token, name_token: &const Token, block: &ast.NodeBlock) !&ast.NodeTestDecl
1055 test_token: &const Token, name: &ast.Node, block: &ast.NodeBlock) !&ast.NodeTestDecl
10371056 {
1038 const node = try self.createTestDecl(arena, test_token, name_token, block);
1057 const node = try self.createTestDecl(arena, test_token, name, block);
10391058 try list.append(&node.base);
10401059 return node;
10411060 }
......@@ -1169,23 +1188,6 @@ pub const Parser = struct {
11691188 switch (decl.id) {
11701189 ast.Node.Id.FnProto => {
11711190 const fn_proto = @fieldParentPtr(ast.NodeFnProto, "base", decl);
1172 if (fn_proto.visib_token) |visib_token| {
1173 switch (visib_token.id) {
1174 Token.Id.Keyword_pub => try stream.print("pub "),
1175 Token.Id.Keyword_export => try stream.print("export "),
1176 else => unreachable,
1177 }
1178 }
1179 if (fn_proto.extern_token) |extern_token| {
1180 try stream.print("{} ", self.tokenizer.getTokenSlice(extern_token));
1181 }
1182 try stream.print("fn");
1183
1184 if (fn_proto.name_token) |name_token| {
1185 try stream.print(" {}", self.tokenizer.getTokenSlice(name_token));
1186 }
1187
1188 try stream.print("(");
11891191
11901192 if (fn_proto.body_node == null) {
11911193 try stack.append(RenderState { .Text = ";" });
......@@ -1201,6 +1203,27 @@ pub const Parser = struct {
12011203 try stack.append(RenderState { .Text = ", " });
12021204 }
12031205 }
1206
1207 try stack.append(RenderState { .Text = "(" });
1208 if (fn_proto.name_token) |name_token| {
1209 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(name_token) });
1210 }
1211
1212 try stack.append(RenderState { .Text = "fn " });
1213 if (fn_proto.lib_name) |lib_name| {
1214 try stack.append(RenderState { .Text = " " });
1215 try stack.append(RenderState { .Expression = lib_name });
1216 }
1217 if (fn_proto.extern_token) |extern_token| {
1218 try stack.append(RenderState { .Text = " " });
1219 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_token) });
1220 }
1221
1222 if (fn_proto.visib_token) |visib_token| {
1223 assert(visib_token.id == Token.Id.Keyword_pub or visib_token.id == Token.Id.Keyword_export);
1224 try stack.append(RenderState { .Text = " " });
1225 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(visib_token) });
1226 }
12041227 },
12051228 ast.Node.Id.VarDecl => {
12061229 const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", decl);
......@@ -1208,29 +1231,16 @@ pub const Parser = struct {
12081231 },
12091232 ast.Node.Id.TestDecl => {
12101233 const test_decl = @fieldParentPtr(ast.NodeTestDecl, "base", decl);
1211 try stream.print("test {} ", self.tokenizer.getTokenSlice(test_decl.name_token));
1234 try stream.print("test ");
12121235 try stack.append(RenderState { .Expression = test_decl.body_node });
1236 try stack.append(RenderState { .Text = " " });
1237 try stack.append(RenderState { .Expression = test_decl.name });
12131238 },
12141239 else => unreachable,
12151240 }
12161241 },
12171242
12181243 RenderState.VarDecl => |var_decl| {
1219 if (var_decl.visib_token) |visib_token| {
1220 try stream.print("{} ", self.tokenizer.getTokenSlice(visib_token));
1221 }
1222 if (var_decl.extern_token) |extern_token| {
1223 try stream.print("{} ", self.tokenizer.getTokenSlice(extern_token));
1224 if (var_decl.lib_name != null) {
1225 @panic("TODO");
1226 }
1227 }
1228 if (var_decl.comptime_token) |comptime_token| {
1229 try stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token));
1230 }
1231 try stream.print("{} ", self.tokenizer.getTokenSlice(var_decl.mut_token));
1232 try stream.print("{}", self.tokenizer.getTokenSlice(var_decl.name_token));
1233
12341244 try stack.append(RenderState { .Text = ";" });
12351245 if (var_decl.init_node) |init_node| {
12361246 try stack.append(RenderState { .Expression = init_node });
......@@ -1242,8 +1252,30 @@ pub const Parser = struct {
12421252 try stack.append(RenderState { .Text = " align(" });
12431253 }
12441254 if (var_decl.type_node) |type_node| {
1245 try stream.print(": ");
12461255 try stack.append(RenderState { .Expression = type_node });
1256 try stack.append(RenderState { .Text = ": " });
1257 }
1258 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(var_decl.name_token) });
1259 try stack.append(RenderState { .Text = " " });
1260 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(var_decl.mut_token) });
1261
1262 if (var_decl.comptime_token) |comptime_token| {
1263 try stack.append(RenderState { .Text = " " });
1264 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(comptime_token) });
1265 }
1266
1267 if (var_decl.extern_token) |extern_token| {
1268 if (var_decl.lib_name != null) {
1269 try stack.append(RenderState { .Text = " " });
1270 try stack.append(RenderState { .Expression = ??var_decl.lib_name });
1271 }
1272 try stack.append(RenderState { .Text = " " });
1273 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_token) });
1274 }
1275
1276 if (var_decl.visib_token) |visib_token| {
1277 try stack.append(RenderState { .Text = " " });
1278 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(visib_token) });
12471279 }
12481280 },
12491281
......@@ -1612,6 +1644,14 @@ test "zig fmt: global declarations" {
16121644 \\pub const a: i32 = b;
16131645 \\var a: i32 = b;
16141646 \\pub var a: i32 = b;
1647 \\extern const a: i32 = b;
1648 \\pub extern const a: i32 = b;
1649 \\extern var a: i32 = b;
1650 \\pub extern var a: i32 = b;
1651 \\extern "a" const a: i32 = b;
1652 \\pub extern "a" const a: i32 = b;
1653 \\extern "a" var a: i32 = b;
1654 \\pub extern "a" var a: i32 = b;
16151655 \\
16161656 );
16171657}
......@@ -2232,7 +2272,7 @@ test "zig fmt: coroutines" {
22322272 \\ x += 1;
22332273 \\ suspend |p| {
22342274 \\ }
2235 \\ const p = async simpleAsyncFn() cache unreachable;
2275 \\ const p = async simpleAsyncFn() catch unreachable;
22362276 \\ await p;
22372277 \\}
22382278 \\