| author | |
| committer | |
| log | 052800e9529a3c2b403b7f43ffba4c981935d0a6 |
| tree | 399a929419b2d853c8d274191685f9a80c5ae31a |
| parent | d6f2af378abe7467657f6fbf8133b995e5f55142 |
| signature |
5 files changed, 73 insertions(+), 0 deletions(-)
std/zig/ast.zig+6| ... | ... | @@ -110,6 +110,7 @@ pub const Tree = struct { |
| 110 | 110 | pub const Error = union(enum) { |
| 111 | 111 | InvalidToken: InvalidToken, |
| 112 | 112 | ExpectedVarDeclOrFn: ExpectedVarDeclOrFn, |
| 113 | ExpectedVarDecl: ExpectedVarDecl, | |
| 113 | 114 | ExpectedAggregateKw: ExpectedAggregateKw, |
| 114 | 115 | UnattachedDocComment: UnattachedDocComment, |
| 115 | 116 | ExpectedEqOrSemi: ExpectedEqOrSemi, |
| ... | ... | @@ -133,6 +134,7 @@ pub const Error = union(enum) { |
| 133 | 134 | // TODO https://github.com/ziglang/zig/issues/683 |
| 134 | 135 | @TagType(Error).InvalidToken => |*x| return x.render(tokens, stream), |
| 135 | 136 | @TagType(Error).ExpectedVarDeclOrFn => |*x| return x.render(tokens, stream), |
| 137 | @TagType(Error).ExpectedVarDecl => |*x| return x.render(tokens, stream), | |
| 136 | 138 | @TagType(Error).ExpectedAggregateKw => |*x| return x.render(tokens, stream), |
| 137 | 139 | @TagType(Error).UnattachedDocComment => |*x| return x.render(tokens, stream), |
| 138 | 140 | @TagType(Error).ExpectedEqOrSemi => |*x| return x.render(tokens, stream), |
| ... | ... | @@ -158,6 +160,7 @@ pub const Error = union(enum) { |
| 158 | 160 | // TODO https://github.com/ziglang/zig/issues/683 |
| 159 | 161 | @TagType(Error).InvalidToken => |x| return x.token, |
| 160 | 162 | @TagType(Error).ExpectedVarDeclOrFn => |x| return x.token, |
| 163 | @TagType(Error).ExpectedVarDecl => |x| return x.token, | |
| 161 | 164 | @TagType(Error).ExpectedAggregateKw => |x| return x.token, |
| 162 | 165 | @TagType(Error).UnattachedDocComment => |x| return x.token, |
| 163 | 166 | @TagType(Error).ExpectedEqOrSemi => |x| return x.token, |
| ... | ... | @@ -180,6 +183,7 @@ pub const Error = union(enum) { |
| 180 | 183 | |
| 181 | 184 | pub const InvalidToken = SingleTokenError("Invalid token {}"); |
| 182 | 185 | pub const ExpectedVarDeclOrFn = SingleTokenError("Expected variable declaration or function, found {}"); |
| 186 | pub const ExpectedVarDecl = SingleTokenError("Expected variable declaration, found {}"); | |
| 183 | 187 | pub const ExpectedAggregateKw = SingleTokenError("Expected " ++ @tagName(Token.Id.Keyword_struct) ++ ", " ++ @tagName(Token.Id.Keyword_union) ++ ", or " ++ @tagName(Token.Id.Keyword_enum) ++ ", found {}"); |
| 184 | 188 | pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found {}"); |
| 185 | 189 | pub const ExpectedSemiOrLBrace = SingleTokenError("Expected ';' or '{{', found {}"); |
| ... | ... | @@ -496,6 +500,7 @@ pub const Node = struct { |
| 496 | 500 | base: Node, |
| 497 | 501 | doc_comments: ?*DocComment, |
| 498 | 502 | visib_token: ?TokenIndex, |
| 503 | thread_local_token: ?TokenIndex, | |
| 499 | 504 | name_token: TokenIndex, |
| 500 | 505 | eq_token: TokenIndex, |
| 501 | 506 | mut_token: TokenIndex, |
| ... | ... | @@ -536,6 +541,7 @@ pub const Node = struct { |
| 536 | 541 | |
| 537 | 542 | pub fn firstToken(self: *const VarDecl) TokenIndex { |
| 538 | 543 | if (self.visib_token) |visib_token| return visib_token; |
| 544 | if (self.thread_local_token) |thread_local_token| return thread_local_token; | |
| 539 | 545 | if (self.comptime_token) |comptime_token| return comptime_token; |
| 540 | 546 | if (self.extern_export_token) |extern_export_token| return extern_export_token; |
| 541 | 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 | 229 | }) catch unreachable; |
| 230 | 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 | 258 | State.TopLevelDecl => |ctx| { |
| 233 | 259 | const token = nextToken(&tok_it, &tree); |
| 234 | 260 | const token_index = token.index; |
| ... | ... | @@ -260,6 +286,28 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree { |
| 260 | 286 | try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.expr } }); |
| 261 | 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 | 311 | Token.Id.Keyword_var, Token.Id.Keyword_const => { |
| 264 | 312 | if (ctx.extern_export_inline_token) |annotated_token| { |
| 265 | 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 | 320 | .VarDecl = VarDeclCtx{ |
| 273 | 321 | .comments = ctx.comments, |
| 274 | 322 | .visib_token = ctx.visib_token, |
| 323 | .thread_local_token = null, | |
| 275 | 324 | .lib_name = ctx.lib_name, |
| 276 | 325 | .comptime_token = null, |
| 277 | 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 | 660 | .base = ast.Node{ .id = ast.Node.Id.VarDecl }, |
| 612 | 661 | .doc_comments = ctx.comments, |
| 613 | 662 | .visib_token = ctx.visib_token, |
| 663 | .thread_local_token = ctx.thread_local_token, | |
| 614 | 664 | .mut_token = ctx.mut_token, |
| 615 | 665 | .comptime_token = ctx.comptime_token, |
| 616 | 666 | .extern_export_token = ctx.extern_export_token, |
| ... | ... | @@ -1094,6 +1144,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree { |
| 1094 | 1144 | .VarDecl = VarDeclCtx{ |
| 1095 | 1145 | .comments = null, |
| 1096 | 1146 | .visib_token = null, |
| 1147 | .thread_local_token = null, | |
| 1097 | 1148 | .comptime_token = null, |
| 1098 | 1149 | .extern_export_token = null, |
| 1099 | 1150 | .lib_name = null, |
| ... | ... | @@ -1150,6 +1201,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree { |
| 1150 | 1201 | .VarDecl = VarDeclCtx{ |
| 1151 | 1202 | .comments = null, |
| 1152 | 1203 | .visib_token = null, |
| 1204 | .thread_local_token = null, | |
| 1153 | 1205 | .comptime_token = ctx.comptime_token, |
| 1154 | 1206 | .extern_export_token = null, |
| 1155 | 1207 | .lib_name = null, |
| ... | ... | @@ -2937,6 +2989,7 @@ const TopLevelDeclCtx = struct { |
| 2937 | 2989 | const VarDeclCtx = struct { |
| 2938 | 2990 | mut_token: TokenIndex, |
| 2939 | 2991 | visib_token: ?TokenIndex, |
| 2992 | thread_local_token: ?TokenIndex, | |
| 2940 | 2993 | comptime_token: ?TokenIndex, |
| 2941 | 2994 | extern_export_token: ?TokenIndex, |
| 2942 | 2995 | lib_name: ?*ast.Node, |
| ... | ... | @@ -3081,6 +3134,7 @@ const State = union(enum) { |
| 3081 | 3134 | ContainerInitArg: *ast.Node.ContainerDecl, |
| 3082 | 3135 | ContainerDecl: *ast.Node.ContainerDecl, |
| 3083 | 3136 | |
| 3137 | ThreadLocal: VarDeclCtx, | |
| 3084 | 3138 | VarDecl: VarDeclCtx, |
| 3085 | 3139 | VarDeclAlign: *ast.Node.VarDecl, |
| 3086 | 3140 | VarDeclSection: *ast.Node.VarDecl, |
std/zig/parser_test.zig+8| ... | ... | @@ -1,3 +1,10 @@ |
| 1 | test "zig fmt: threadlocal" { | |
| 2 | try testCanonical( | |
| 3 | \\threadlocal var x: i32 = 1234; | |
| 4 | \\ | |
| 5 | ); | |
| 6 | } | |
| 7 | ||
| 1 | 8 | test "zig fmt: linksection" { |
| 2 | 9 | try testCanonical( |
| 3 | 10 | \\export var aoeu: u64 linksection(".text.derp") = 1234; |
| ... | ... | @@ -5,6 +12,7 @@ test "zig fmt: linksection" { |
| 5 | 12 | \\ |
| 6 | 13 | ); |
| 7 | 14 | } |
| 15 | ||
| 8 | 16 | test "zig fmt: shebang line" { |
| 9 | 17 | try testCanonical( |
| 10 | 18 | \\#!/usr/bin/env zig |
std/zig/render.zig+3| ... | ... | @@ -1706,6 +1706,9 @@ fn renderVarDecl( |
| 1706 | 1706 | try renderToken(tree, stream, comptime_token, indent, start_col, Space.Space); // comptime |
| 1707 | 1707 | } |
| 1708 | 1708 | |
| 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 | 1712 | try renderToken(tree, stream, var_decl.mut_token, indent, start_col, Space.Space); // var |
| 1710 | 1713 | |
| 1711 | 1714 | 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 | 53 | Keyword{ .bytes = "switch", .id = Id.Keyword_switch }, |
| 54 | 54 | Keyword{ .bytes = "test", .id = Id.Keyword_test }, |
| 55 | 55 | Keyword{ .bytes = "this", .id = Id.Keyword_this }, |
| 56 | Keyword{ .bytes = "threadlocal", .id = Id.Keyword_threadlocal }, | |
| 56 | 57 | Keyword{ .bytes = "true", .id = Id.Keyword_true }, |
| 57 | 58 | Keyword{ .bytes = "try", .id = Id.Keyword_try }, |
| 58 | 59 | Keyword{ .bytes = "undefined", .id = Id.Keyword_undefined }, |
| ... | ... | @@ -182,6 +183,7 @@ pub const Token = struct { |
| 182 | 183 | Keyword_switch, |
| 183 | 184 | Keyword_test, |
| 184 | 185 | Keyword_this, |
| 186 | Keyword_threadlocal, | |
| 185 | 187 | Keyword_true, |
| 186 | 188 | Keyword_try, |
| 187 | 189 | Keyword_undefined, |