From 052800e9529a3c2b403b7f43ffba4c981935d0a6 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 9 Feb 2019 00:19:06 -0500 Subject: [PATCH] zig fmt: support threadlocal --- std/zig/ast.zig | 6 +++++ std/zig/parse.zig | 54 +++++++++++++++++++++++++++++++++++++++++ std/zig/parser_test.zig | 8 ++++++ std/zig/render.zig | 3 +++ std/zig/tokenizer.zig | 2 ++ 5 files changed, 73 insertions(+) diff --git a/std/zig/ast.zig b/std/zig/ast.zig index f6ac4ed98..ea3263456 100644 --- a/std/zig/ast.zig +++ b/std/zig/ast.zig @@ -110,6 +110,7 @@ pub const Tree = struct { pub const Error = union(enum) { InvalidToken: InvalidToken, ExpectedVarDeclOrFn: ExpectedVarDeclOrFn, + ExpectedVarDecl: ExpectedVarDecl, ExpectedAggregateKw: ExpectedAggregateKw, UnattachedDocComment: UnattachedDocComment, ExpectedEqOrSemi: ExpectedEqOrSemi, @@ -133,6 +134,7 @@ pub const Error = union(enum) { // TODO https://github.com/ziglang/zig/issues/683 @TagType(Error).InvalidToken => |*x| return x.render(tokens, stream), @TagType(Error).ExpectedVarDeclOrFn => |*x| return x.render(tokens, stream), + @TagType(Error).ExpectedVarDecl => |*x| return x.render(tokens, stream), @TagType(Error).ExpectedAggregateKw => |*x| return x.render(tokens, stream), @TagType(Error).UnattachedDocComment => |*x| return x.render(tokens, stream), @TagType(Error).ExpectedEqOrSemi => |*x| return x.render(tokens, stream), @@ -158,6 +160,7 @@ pub const Error = union(enum) { // TODO https://github.com/ziglang/zig/issues/683 @TagType(Error).InvalidToken => |x| return x.token, @TagType(Error).ExpectedVarDeclOrFn => |x| return x.token, + @TagType(Error).ExpectedVarDecl => |x| return x.token, @TagType(Error).ExpectedAggregateKw => |x| return x.token, @TagType(Error).UnattachedDocComment => |x| return x.token, @TagType(Error).ExpectedEqOrSemi => |x| return x.token, @@ -180,6 +183,7 @@ pub const Error = union(enum) { pub const InvalidToken = SingleTokenError("Invalid token {}"); pub const ExpectedVarDeclOrFn = SingleTokenError("Expected variable declaration or function, found {}"); + pub const ExpectedVarDecl = SingleTokenError("Expected variable declaration, found {}"); pub const ExpectedAggregateKw = SingleTokenError("Expected " ++ @tagName(Token.Id.Keyword_struct) ++ ", " ++ @tagName(Token.Id.Keyword_union) ++ ", or " ++ @tagName(Token.Id.Keyword_enum) ++ ", found {}"); pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found {}"); pub const ExpectedSemiOrLBrace = SingleTokenError("Expected ';' or '{{', found {}"); @@ -496,6 +500,7 @@ pub const Node = struct { base: Node, doc_comments: ?*DocComment, visib_token: ?TokenIndex, + thread_local_token: ?TokenIndex, name_token: TokenIndex, eq_token: TokenIndex, mut_token: TokenIndex, @@ -536,6 +541,7 @@ pub const Node = struct { pub fn firstToken(self: *const VarDecl) TokenIndex { if (self.visib_token) |visib_token| return visib_token; + if (self.thread_local_token) |thread_local_token| return thread_local_token; if (self.comptime_token) |comptime_token| return comptime_token; if (self.extern_export_token) |extern_export_token| return extern_export_token; assert(self.lib_name == null); diff --git a/std/zig/parse.zig b/std/zig/parse.zig index 783464c62..ae3e00eb4 100644 --- a/std/zig/parse.zig +++ b/std/zig/parse.zig @@ -229,6 +229,32 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree { }) catch unreachable; continue; }, + State.ThreadLocal => |ctx| { + const token = nextToken(&tok_it, &tree); + const token_index = token.index; + const token_ptr = token.ptr; + switch (token_ptr.id) { + Token.Id.Keyword_var, Token.Id.Keyword_const => { + try stack.append(State{ + .VarDecl = VarDeclCtx{ + .comments = ctx.comments, + .visib_token = ctx.visib_token, + .thread_local_token = ctx.thread_local_token, + .lib_name = ctx.lib_name, + .comptime_token = ctx.comptime_token, + .extern_export_token = ctx.extern_export_token, + .mut_token = token_index, + .list = ctx.list, + }, + }); + continue; + }, + else => { + ((try tree.errors.addOne())).* = Error{ .ExpectedVarDecl = Error.ExpectedVarDecl{ .token = token_index } }; + return tree; + }, + } + }, State.TopLevelDecl => |ctx| { const token = nextToken(&tok_it, &tree); const token_index = token.index; @@ -260,6 +286,28 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree { try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.expr } }); continue; }, + Token.Id.Keyword_threadlocal => { + if (ctx.extern_export_inline_token) |annotated_token| { + if (annotated_token.ptr.id == Token.Id.Keyword_inline) { + ((try tree.errors.addOne())).* = Error{ .InvalidToken = Error.InvalidToken{ .token = annotated_token.index } }; + return tree; + } + } + + try stack.append(State{ + .ThreadLocal = VarDeclCtx{ + .comments = ctx.comments, + .visib_token = ctx.visib_token, + .thread_local_token = token_index, + .lib_name = ctx.lib_name, + .comptime_token = null, + .extern_export_token = if (ctx.extern_export_inline_token) |at| at.index else null, + .mut_token = undefined, + .list = ctx.decls, + }, + }); + continue; + }, Token.Id.Keyword_var, Token.Id.Keyword_const => { if (ctx.extern_export_inline_token) |annotated_token| { if (annotated_token.ptr.id == Token.Id.Keyword_inline) { @@ -272,6 +320,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree { .VarDecl = VarDeclCtx{ .comments = ctx.comments, .visib_token = ctx.visib_token, + .thread_local_token = null, .lib_name = ctx.lib_name, .comptime_token = null, .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 { .base = ast.Node{ .id = ast.Node.Id.VarDecl }, .doc_comments = ctx.comments, .visib_token = ctx.visib_token, + .thread_local_token = ctx.thread_local_token, .mut_token = ctx.mut_token, .comptime_token = ctx.comptime_token, .extern_export_token = ctx.extern_export_token, @@ -1094,6 +1144,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree { .VarDecl = VarDeclCtx{ .comments = null, .visib_token = null, + .thread_local_token = null, .comptime_token = null, .extern_export_token = null, .lib_name = null, @@ -1150,6 +1201,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree { .VarDecl = VarDeclCtx{ .comments = null, .visib_token = null, + .thread_local_token = null, .comptime_token = ctx.comptime_token, .extern_export_token = null, .lib_name = null, @@ -2937,6 +2989,7 @@ const TopLevelDeclCtx = struct { const VarDeclCtx = struct { mut_token: TokenIndex, visib_token: ?TokenIndex, + thread_local_token: ?TokenIndex, comptime_token: ?TokenIndex, extern_export_token: ?TokenIndex, lib_name: ?*ast.Node, @@ -3081,6 +3134,7 @@ const State = union(enum) { ContainerInitArg: *ast.Node.ContainerDecl, ContainerDecl: *ast.Node.ContainerDecl, + ThreadLocal: VarDeclCtx, VarDecl: VarDeclCtx, VarDeclAlign: *ast.Node.VarDecl, VarDeclSection: *ast.Node.VarDecl, diff --git a/std/zig/parser_test.zig b/std/zig/parser_test.zig index 7ad842e4b..93d5ce343 100644 --- a/std/zig/parser_test.zig +++ b/std/zig/parser_test.zig @@ -1,3 +1,10 @@ +test "zig fmt: threadlocal" { + try testCanonical( + \\threadlocal var x: i32 = 1234; + \\ + ); +} + test "zig fmt: linksection" { try testCanonical( \\export var aoeu: u64 linksection(".text.derp") = 1234; @@ -5,6 +12,7 @@ test "zig fmt: linksection" { \\ ); } + test "zig fmt: shebang line" { try testCanonical( \\#!/usr/bin/env zig diff --git a/std/zig/render.zig b/std/zig/render.zig index e55a0beb9..66aba75e1 100644 --- a/std/zig/render.zig +++ b/std/zig/render.zig @@ -1706,6 +1706,9 @@ fn renderVarDecl( try renderToken(tree, stream, comptime_token, indent, start_col, Space.Space); // comptime } + if (var_decl.thread_local_token) |thread_local_token| { + try renderToken(tree, stream, thread_local_token, indent, start_col, Space.Space); // threadlocal + } try renderToken(tree, stream, var_decl.mut_token, indent, start_col, Space.Space); // var const name_space = if (var_decl.type_node == null and (var_decl.align_node != null or diff --git a/std/zig/tokenizer.zig b/std/zig/tokenizer.zig index e71babe4e..08ffa28fc 100644 --- a/std/zig/tokenizer.zig +++ b/std/zig/tokenizer.zig @@ -53,6 +53,7 @@ pub const Token = struct { Keyword{ .bytes = "switch", .id = Id.Keyword_switch }, Keyword{ .bytes = "test", .id = Id.Keyword_test }, Keyword{ .bytes = "this", .id = Id.Keyword_this }, + Keyword{ .bytes = "threadlocal", .id = Id.Keyword_threadlocal }, Keyword{ .bytes = "true", .id = Id.Keyword_true }, Keyword{ .bytes = "try", .id = Id.Keyword_try }, Keyword{ .bytes = "undefined", .id = Id.Keyword_undefined }, @@ -182,6 +183,7 @@ pub const Token = struct { Keyword_switch, Keyword_test, Keyword_this, + Keyword_threadlocal, Keyword_true, Keyword_try, Keyword_undefined,