zig fmt: support threadlocal

master
Andrew Kelley 2019-02-09 00:19:06 -05:00
parent d6f2af378a
commit 052800e952
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
5 changed files with 73 additions and 0 deletions

View File

@ -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);

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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,