Commit 3b80e66507
Changed files (2)
std
std/zig/ast.zig
@@ -11,6 +11,7 @@ pub const Node = struct {
pub const Id = enum {
Root,
VarDecl,
+ Use,
ErrorSetDecl,
ContainerDecl,
StructField,
@@ -63,6 +64,7 @@ pub const Node = struct {
return switch (base.id) {
Id.Root => @fieldParentPtr(NodeRoot, "base", base).iterate(index),
Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).iterate(index),
+ Id.Use => @fieldParentPtr(NodeUse, "base", base).iterate(index),
Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).iterate(index),
Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).iterate(index),
Id.StructField => @fieldParentPtr(NodeStructField, "base", base).iterate(index),
@@ -116,6 +118,7 @@ pub const Node = struct {
return switch (base.id) {
Id.Root => @fieldParentPtr(NodeRoot, "base", base).firstToken(),
Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).firstToken(),
+ Id.Use => @fieldParentPtr(NodeUse, "base", base).firstToken(),
Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).firstToken(),
Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).firstToken(),
Id.StructField => @fieldParentPtr(NodeStructField, "base", base).firstToken(),
@@ -169,6 +172,7 @@ pub const Node = struct {
return switch (base.id) {
Id.Root => @fieldParentPtr(NodeRoot, "base", base).lastToken(),
Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).lastToken(),
+ Id.Use => @fieldParentPtr(NodeUse, "base", base).lastToken(),
Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).lastToken(),
Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).lastToken(),
Id.StructField => @fieldParentPtr(NodeStructField, "base", base).lastToken(),
@@ -288,6 +292,31 @@ pub const NodeVarDecl = struct {
}
};
+pub const NodeUse = struct {
+ base: Node,
+ visib_token: ?Token,
+ expr: &Node,
+ semicolon_token: Token,
+
+ pub fn iterate(self: &NodeUse, index: usize) ?&Node {
+ var i = index;
+
+ if (i < 1) return self.expr;
+ i -= 1;
+
+ return null;
+ }
+
+ pub fn firstToken(self: &NodeUse) Token {
+ if (self.visib_token) |visib_token| return visib_token;
+ return self.expr.firstToken();
+ }
+
+ pub fn lastToken(self: &NodeUse) Token {
+ return self.semicolon_token;
+ }
+};
+
pub const NodeErrorSetDecl = struct {
base: Node,
error_token: Token,
std/zig/parser.zig
@@ -348,31 +348,54 @@ pub const Parser = struct {
},
State.TopLevelExtern => |ctx| {
const token = self.getNextToken();
- if (token.id == Token.Id.Keyword_extern) {
- const lib_name_token = self.getNextToken();
- const lib_name = blk: {
- if (lib_name_token.id == Token.Id.StringLiteral) {
- const res = try self.createStringLiteral(arena, lib_name_token);
- break :blk &res.base;
- } else {
- self.putBackToken(lib_name_token);
- break :blk null;
- }
- };
-
- stack.append(State {
- .TopLevelDecl = TopLevelDeclCtx {
- .decls = ctx.decls,
+ switch (token.id) {
+ Token.Id.Keyword_use => {
+ const node = try arena.create(ast.NodeUse);
+ *node = ast.NodeUse {
+ .base = self.initNode(ast.Node.Id.Use),
.visib_token = ctx.visib_token,
- .extern_token = token,
- .lib_name = lib_name,
- },
- }) catch unreachable;
- continue;
+ .expr = undefined,
+ .semicolon_token = undefined,
+ };
+ try ctx.decls.append(&node.base);
+
+ stack.append(State {
+ .ExpectTokenSave = ExpectTokenSave {
+ .id = Token.Id.Semicolon,
+ .ptr = &node.semicolon_token,
+ }
+ }) catch unreachable;
+ try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
+ continue;
+ },
+ Token.Id.Keyword_extern => {
+ const lib_name_token = self.getNextToken();
+ const lib_name = blk: {
+ if (lib_name_token.id == Token.Id.StringLiteral) {
+ const res = try self.createStringLiteral(arena, lib_name_token);
+ break :blk &res.base;
+ } else {
+ self.putBackToken(lib_name_token);
+ break :blk null;
+ }
+ };
+
+ stack.append(State {
+ .TopLevelDecl = TopLevelDeclCtx {
+ .decls = ctx.decls,
+ .visib_token = ctx.visib_token,
+ .extern_token = token,
+ .lib_name = lib_name,
+ },
+ }) catch unreachable;
+ continue;
+ },
+ else => {
+ self.putBackToken(token);
+ stack.append(State { .TopLevelDecl = ctx }) catch unreachable;
+ continue;
+ }
}
- self.putBackToken(token);
- stack.append(State { .TopLevelDecl = ctx }) catch unreachable;
- continue;
},
State.TopLevelDecl => |ctx| {
const token = self.getNextToken();
@@ -3068,6 +3091,15 @@ pub const Parser = struct {
try stack.append(RenderState { .Expression = decl });
},
+ ast.Node.Id.Use => {
+ const use_decl = @fieldParentPtr(ast.NodeUse, "base", decl);
+ if (use_decl.visib_token) |visib_token| {
+ try stream.print("{} ", self.tokenizer.getTokenSlice(visib_token));
+ }
+ try stream.print("use ");
+ try stack.append(RenderState { .Text = ";" });
+ try stack.append(RenderState { .Expression = use_decl.expr });
+ },
ast.Node.Id.VarDecl => {
const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", decl);
try stack.append(RenderState { .VarDecl = var_decl});
@@ -4086,6 +4118,7 @@ pub const Parser = struct {
ast.Node.Id.EnumTag,
ast.Node.Id.Root,
ast.Node.Id.VarDecl,
+ ast.Node.Id.Use,
ast.Node.Id.TestDecl,
ast.Node.Id.ParamDecl => unreachable,
},
@@ -5000,3 +5033,11 @@ test "zig fmt: Block after if" {
\\
);
}
+
+test "zig fmt: use" {
+ try testCanonical(
+ \\use @import("std");
+ \\pub use @import("std");
+ \\
+ );
+}