authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-09 00:19:06-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-09 00:19:24-05:00
log052800e9529a3c2b403b7f43ffba4c981935d0a6
tree399a929419b2d853c8d274191685f9a80c5ae31a
parentd6f2af378abe7467657f6fbf8133b995e5f55142
signature Commit is signed but in an unrecognized format.

zig fmt: support threadlocal


5 files changed, 73 insertions(+), 0 deletions(-)

std/zig/ast.zig+6
...@@ -110,6 +110,7 @@ pub const Tree = struct {...@@ -110,6 +110,7 @@ pub const Tree = struct {
110pub const Error = union(enum) {110pub const Error = union(enum) {
111 InvalidToken: InvalidToken,111 InvalidToken: InvalidToken,
112 ExpectedVarDeclOrFn: ExpectedVarDeclOrFn,112 ExpectedVarDeclOrFn: ExpectedVarDeclOrFn,
113 ExpectedVarDecl: ExpectedVarDecl,
113 ExpectedAggregateKw: ExpectedAggregateKw,114 ExpectedAggregateKw: ExpectedAggregateKw,
114 UnattachedDocComment: UnattachedDocComment,115 UnattachedDocComment: UnattachedDocComment,
115 ExpectedEqOrSemi: ExpectedEqOrSemi,116 ExpectedEqOrSemi: ExpectedEqOrSemi,
...@@ -133,6 +134,7 @@ pub const Error = union(enum) {...@@ -133,6 +134,7 @@ pub const Error = union(enum) {
133 // TODO https://github.com/ziglang/zig/issues/683134 // TODO https://github.com/ziglang/zig/issues/683
134 @TagType(Error).InvalidToken => |*x| return x.render(tokens, stream),135 @TagType(Error).InvalidToken => |*x| return x.render(tokens, stream),
135 @TagType(Error).ExpectedVarDeclOrFn => |*x| return x.render(tokens, stream),136 @TagType(Error).ExpectedVarDeclOrFn => |*x| return x.render(tokens, stream),
137 @TagType(Error).ExpectedVarDecl => |*x| return x.render(tokens, stream),
136 @TagType(Error).ExpectedAggregateKw => |*x| return x.render(tokens, stream),138 @TagType(Error).ExpectedAggregateKw => |*x| return x.render(tokens, stream),
137 @TagType(Error).UnattachedDocComment => |*x| return x.render(tokens, stream),139 @TagType(Error).UnattachedDocComment => |*x| return x.render(tokens, stream),
138 @TagType(Error).ExpectedEqOrSemi => |*x| return x.render(tokens, stream),140 @TagType(Error).ExpectedEqOrSemi => |*x| return x.render(tokens, stream),
...@@ -158,6 +160,7 @@ pub const Error = union(enum) {...@@ -158,6 +160,7 @@ pub const Error = union(enum) {
158 // TODO https://github.com/ziglang/zig/issues/683160 // TODO https://github.com/ziglang/zig/issues/683
159 @TagType(Error).InvalidToken => |x| return x.token,161 @TagType(Error).InvalidToken => |x| return x.token,
160 @TagType(Error).ExpectedVarDeclOrFn => |x| return x.token,162 @TagType(Error).ExpectedVarDeclOrFn => |x| return x.token,
163 @TagType(Error).ExpectedVarDecl => |x| return x.token,
161 @TagType(Error).ExpectedAggregateKw => |x| return x.token,164 @TagType(Error).ExpectedAggregateKw => |x| return x.token,
162 @TagType(Error).UnattachedDocComment => |x| return x.token,165 @TagType(Error).UnattachedDocComment => |x| return x.token,
163 @TagType(Error).ExpectedEqOrSemi => |x| return x.token,166 @TagType(Error).ExpectedEqOrSemi => |x| return x.token,
...@@ -180,6 +183,7 @@ pub const Error = union(enum) {...@@ -180,6 +183,7 @@ pub const Error = union(enum) {
180183
181 pub const InvalidToken = SingleTokenError("Invalid token {}");184 pub const InvalidToken = SingleTokenError("Invalid token {}");
182 pub const ExpectedVarDeclOrFn = SingleTokenError("Expected variable declaration or function, found {}");185 pub const ExpectedVarDeclOrFn = SingleTokenError("Expected variable declaration or function, found {}");
186 pub const ExpectedVarDecl = SingleTokenError("Expected variable declaration, found {}");
183 pub const ExpectedAggregateKw = SingleTokenError("Expected " ++ @tagName(Token.Id.Keyword_struct) ++ ", " ++ @tagName(Token.Id.Keyword_union) ++ ", or " ++ @tagName(Token.Id.Keyword_enum) ++ ", found {}");187 pub const ExpectedAggregateKw = SingleTokenError("Expected " ++ @tagName(Token.Id.Keyword_struct) ++ ", " ++ @tagName(Token.Id.Keyword_union) ++ ", or " ++ @tagName(Token.Id.Keyword_enum) ++ ", found {}");
184 pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found {}");188 pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found {}");
185 pub const ExpectedSemiOrLBrace = SingleTokenError("Expected ';' or '{{', found {}");189 pub const ExpectedSemiOrLBrace = SingleTokenError("Expected ';' or '{{', found {}");
...@@ -496,6 +500,7 @@ pub const Node = struct {...@@ -496,6 +500,7 @@ pub const Node = struct {
496 base: Node,500 base: Node,
497 doc_comments: ?*DocComment,501 doc_comments: ?*DocComment,
498 visib_token: ?TokenIndex,502 visib_token: ?TokenIndex,
503 thread_local_token: ?TokenIndex,
499 name_token: TokenIndex,504 name_token: TokenIndex,
500 eq_token: TokenIndex,505 eq_token: TokenIndex,
501 mut_token: TokenIndex,506 mut_token: TokenIndex,
...@@ -536,6 +541,7 @@ pub const Node = struct {...@@ -536,6 +541,7 @@ pub const Node = struct {
536541
537 pub fn firstToken(self: *const VarDecl) TokenIndex {542 pub fn firstToken(self: *const VarDecl) TokenIndex {
538 if (self.visib_token) |visib_token| return visib_token;543 if (self.visib_token) |visib_token| return visib_token;
544 if (self.thread_local_token) |thread_local_token| return thread_local_token;
539 if (self.comptime_token) |comptime_token| return comptime_token;545 if (self.comptime_token) |comptime_token| return comptime_token;
540 if (self.extern_export_token) |extern_export_token| return extern_export_token;546 if (self.extern_export_token) |extern_export_token| return extern_export_token;
541 assert(self.lib_name == null);547 assert(self.lib_name == null);
std/zig/parse.zig+54
...@@ -229,6 +229,32 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -229,6 +229,32 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
229 }) catch unreachable;229 }) catch unreachable;
230 continue;230 continue;
231 },231 },
232 State.ThreadLocal => |ctx| {
233 const token = nextToken(&tok_it, &tree);
234 const token_index = token.index;
235 const token_ptr = token.ptr;
236 switch (token_ptr.id) {
237 Token.Id.Keyword_var, Token.Id.Keyword_const => {
238 try stack.append(State{
239 .VarDecl = VarDeclCtx{
240 .comments = ctx.comments,
241 .visib_token = ctx.visib_token,
242 .thread_local_token = ctx.thread_local_token,
243 .lib_name = ctx.lib_name,
244 .comptime_token = ctx.comptime_token,
245 .extern_export_token = ctx.extern_export_token,
246 .mut_token = token_index,
247 .list = ctx.list,
248 },
249 });
250 continue;
251 },
252 else => {
253 ((try tree.errors.addOne())).* = Error{ .ExpectedVarDecl = Error.ExpectedVarDecl{ .token = token_index } };
254 return tree;
255 },
256 }
257 },
232 State.TopLevelDecl => |ctx| {258 State.TopLevelDecl => |ctx| {
233 const token = nextToken(&tok_it, &tree);259 const token = nextToken(&tok_it, &tree);
234 const token_index = token.index;260 const token_index = token.index;
...@@ -260,6 +286,28 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -260,6 +286,28 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
260 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.expr } });286 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.expr } });
261 continue;287 continue;
262 },288 },
289 Token.Id.Keyword_threadlocal => {
290 if (ctx.extern_export_inline_token) |annotated_token| {
291 if (annotated_token.ptr.id == Token.Id.Keyword_inline) {
292 ((try tree.errors.addOne())).* = Error{ .InvalidToken = Error.InvalidToken{ .token = annotated_token.index } };
293 return tree;
294 }
295 }
296
297 try stack.append(State{
298 .ThreadLocal = VarDeclCtx{
299 .comments = ctx.comments,
300 .visib_token = ctx.visib_token,
301 .thread_local_token = token_index,
302 .lib_name = ctx.lib_name,
303 .comptime_token = null,
304 .extern_export_token = if (ctx.extern_export_inline_token) |at| at.index else null,
305 .mut_token = undefined,
306 .list = ctx.decls,
307 },
308 });
309 continue;
310 },
263 Token.Id.Keyword_var, Token.Id.Keyword_const => {311 Token.Id.Keyword_var, Token.Id.Keyword_const => {
264 if (ctx.extern_export_inline_token) |annotated_token| {312 if (ctx.extern_export_inline_token) |annotated_token| {
265 if (annotated_token.ptr.id == Token.Id.Keyword_inline) {313 if (annotated_token.ptr.id == Token.Id.Keyword_inline) {
...@@ -272,6 +320,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -272,6 +320,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
272 .VarDecl = VarDeclCtx{320 .VarDecl = VarDeclCtx{
273 .comments = ctx.comments,321 .comments = ctx.comments,
274 .visib_token = ctx.visib_token,322 .visib_token = ctx.visib_token,
323 .thread_local_token = null,
275 .lib_name = ctx.lib_name,324 .lib_name = ctx.lib_name,
276 .comptime_token = null,325 .comptime_token = null,
277 .extern_export_token = if (ctx.extern_export_inline_token) |at| at.index else null,326 .extern_export_token = if (ctx.extern_export_inline_token) |at| at.index else null,
...@@ -611,6 +660,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -611,6 +660,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
611 .base = ast.Node{ .id = ast.Node.Id.VarDecl },660 .base = ast.Node{ .id = ast.Node.Id.VarDecl },
612 .doc_comments = ctx.comments,661 .doc_comments = ctx.comments,
613 .visib_token = ctx.visib_token,662 .visib_token = ctx.visib_token,
663 .thread_local_token = ctx.thread_local_token,
614 .mut_token = ctx.mut_token,664 .mut_token = ctx.mut_token,
615 .comptime_token = ctx.comptime_token,665 .comptime_token = ctx.comptime_token,
616 .extern_export_token = ctx.extern_export_token,666 .extern_export_token = ctx.extern_export_token,
...@@ -1094,6 +1144,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1094,6 +1144,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1094 .VarDecl = VarDeclCtx{1144 .VarDecl = VarDeclCtx{
1095 .comments = null,1145 .comments = null,
1096 .visib_token = null,1146 .visib_token = null,
1147 .thread_local_token = null,
1097 .comptime_token = null,1148 .comptime_token = null,
1098 .extern_export_token = null,1149 .extern_export_token = null,
1099 .lib_name = null,1150 .lib_name = null,
...@@ -1150,6 +1201,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1150,6 +1201,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1150 .VarDecl = VarDeclCtx{1201 .VarDecl = VarDeclCtx{
1151 .comments = null,1202 .comments = null,
1152 .visib_token = null,1203 .visib_token = null,
1204 .thread_local_token = null,
1153 .comptime_token = ctx.comptime_token,1205 .comptime_token = ctx.comptime_token,
1154 .extern_export_token = null,1206 .extern_export_token = null,
1155 .lib_name = null,1207 .lib_name = null,
...@@ -2937,6 +2989,7 @@ const TopLevelDeclCtx = struct {...@@ -2937,6 +2989,7 @@ const TopLevelDeclCtx = struct {
2937const VarDeclCtx = struct {2989const VarDeclCtx = struct {
2938 mut_token: TokenIndex,2990 mut_token: TokenIndex,
2939 visib_token: ?TokenIndex,2991 visib_token: ?TokenIndex,
2992 thread_local_token: ?TokenIndex,
2940 comptime_token: ?TokenIndex,2993 comptime_token: ?TokenIndex,
2941 extern_export_token: ?TokenIndex,2994 extern_export_token: ?TokenIndex,
2942 lib_name: ?*ast.Node,2995 lib_name: ?*ast.Node,
...@@ -3081,6 +3134,7 @@ const State = union(enum) {...@@ -3081,6 +3134,7 @@ const State = union(enum) {
3081 ContainerInitArg: *ast.Node.ContainerDecl,3134 ContainerInitArg: *ast.Node.ContainerDecl,
3082 ContainerDecl: *ast.Node.ContainerDecl,3135 ContainerDecl: *ast.Node.ContainerDecl,
30833136
3137 ThreadLocal: VarDeclCtx,
3084 VarDecl: VarDeclCtx,3138 VarDecl: VarDeclCtx,
3085 VarDeclAlign: *ast.Node.VarDecl,3139 VarDeclAlign: *ast.Node.VarDecl,
3086 VarDeclSection: *ast.Node.VarDecl,3140 VarDeclSection: *ast.Node.VarDecl,
std/zig/parser_test.zig+8
...@@ -1,3 +1,10 @@...@@ -1,3 +1,10 @@
1test "zig fmt: threadlocal" {
2 try testCanonical(
3 \\threadlocal var x: i32 = 1234;
4 \\
5 );
6}
7
1test "zig fmt: linksection" {8test "zig fmt: linksection" {
2 try testCanonical(9 try testCanonical(
3 \\export var aoeu: u64 linksection(".text.derp") = 1234;10 \\export var aoeu: u64 linksection(".text.derp") = 1234;
...@@ -5,6 +12,7 @@ test "zig fmt: linksection" {...@@ -5,6 +12,7 @@ test "zig fmt: linksection" {
5 \\12 \\
6 );13 );
7}14}
15
8test "zig fmt: shebang line" {16test "zig fmt: shebang line" {
9 try testCanonical(17 try testCanonical(
10 \\#!/usr/bin/env zig18 \\#!/usr/bin/env zig
std/zig/render.zig+3
...@@ -1706,6 +1706,9 @@ fn renderVarDecl(...@@ -1706,6 +1706,9 @@ fn renderVarDecl(
1706 try renderToken(tree, stream, comptime_token, indent, start_col, Space.Space); // comptime1706 try renderToken(tree, stream, comptime_token, indent, start_col, Space.Space); // comptime
1707 }1707 }
17081708
1709 if (var_decl.thread_local_token) |thread_local_token| {
1710 try renderToken(tree, stream, thread_local_token, indent, start_col, Space.Space); // threadlocal
1711 }
1709 try renderToken(tree, stream, var_decl.mut_token, indent, start_col, Space.Space); // var1712 try renderToken(tree, stream, var_decl.mut_token, indent, start_col, Space.Space); // var
17101713
1711 const name_space = if (var_decl.type_node == null and (var_decl.align_node != null or1714 const name_space = if (var_decl.type_node == null and (var_decl.align_node != null or
std/zig/tokenizer.zig+2
...@@ -53,6 +53,7 @@ pub const Token = struct {...@@ -53,6 +53,7 @@ pub const Token = struct {
53 Keyword{ .bytes = "switch", .id = Id.Keyword_switch },53 Keyword{ .bytes = "switch", .id = Id.Keyword_switch },
54 Keyword{ .bytes = "test", .id = Id.Keyword_test },54 Keyword{ .bytes = "test", .id = Id.Keyword_test },
55 Keyword{ .bytes = "this", .id = Id.Keyword_this },55 Keyword{ .bytes = "this", .id = Id.Keyword_this },
56 Keyword{ .bytes = "threadlocal", .id = Id.Keyword_threadlocal },
56 Keyword{ .bytes = "true", .id = Id.Keyword_true },57 Keyword{ .bytes = "true", .id = Id.Keyword_true },
57 Keyword{ .bytes = "try", .id = Id.Keyword_try },58 Keyword{ .bytes = "try", .id = Id.Keyword_try },
58 Keyword{ .bytes = "undefined", .id = Id.Keyword_undefined },59 Keyword{ .bytes = "undefined", .id = Id.Keyword_undefined },
...@@ -182,6 +183,7 @@ pub const Token = struct {...@@ -182,6 +183,7 @@ pub const Token = struct {
182 Keyword_switch,183 Keyword_switch,
183 Keyword_test,184 Keyword_test,
184 Keyword_this,185 Keyword_this,
186 Keyword_threadlocal,
185 Keyword_true,187 Keyword_true,
186 Keyword_try,188 Keyword_try,
187 Keyword_undefined,189 Keyword_undefined,