mirror of
https://github.com/ziglang/zig.git
synced 2026-02-20 08:14:48 +00:00
std.zig.parser can now parse top level test declarations
This commit is contained in:
parent
032fccf615
commit
9df2a6a502
@ -22,6 +22,7 @@ pub const Node = struct {
|
||||
StringLiteral,
|
||||
BuiltinCall,
|
||||
LineComment,
|
||||
TestDecl,
|
||||
};
|
||||
|
||||
pub fn iterate(base: &Node, index: usize) ?&Node {
|
||||
@ -39,6 +40,7 @@ pub const Node = struct {
|
||||
Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).iterate(index),
|
||||
Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).iterate(index),
|
||||
Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).iterate(index),
|
||||
Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).iterate(index),
|
||||
};
|
||||
}
|
||||
|
||||
@ -57,6 +59,7 @@ pub const Node = struct {
|
||||
Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).firstToken(),
|
||||
Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).firstToken(),
|
||||
Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).firstToken(),
|
||||
Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).firstToken(),
|
||||
};
|
||||
}
|
||||
|
||||
@ -75,6 +78,7 @@ pub const Node = struct {
|
||||
Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).lastToken(),
|
||||
Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).lastToken(),
|
||||
Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).lastToken(),
|
||||
Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).lastToken(),
|
||||
};
|
||||
}
|
||||
};
|
||||
@ -476,3 +480,28 @@ pub const NodeLineComment = struct {
|
||||
return self.lines.at(self.lines.len - 1);
|
||||
}
|
||||
};
|
||||
|
||||
pub const NodeTestDecl = struct {
|
||||
base: Node,
|
||||
test_token: Token,
|
||||
name_token: Token,
|
||||
body_node: &Node,
|
||||
|
||||
pub fn iterate(self: &NodeTestDecl, index: usize) ?&Node {
|
||||
var i = index;
|
||||
|
||||
if (i < 1) return self.body_node;
|
||||
i -= 1;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn firstToken(self: &NodeTestDecl) Token {
|
||||
return self.test_token;
|
||||
}
|
||||
|
||||
pub fn lastToken(self: &NodeTestDecl) Token {
|
||||
return self.body_node.lastToken();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -171,6 +171,22 @@ pub const Parser = struct {
|
||||
stack.append(State { .TopLevelExtern = token }) catch unreachable;
|
||||
continue;
|
||||
},
|
||||
Token.Id.Keyword_test => {
|
||||
stack.append(State.TopLevel) catch unreachable;
|
||||
|
||||
const name_token = self.getNextToken();
|
||||
if (name_token.id != Token.Id.StringLiteral)
|
||||
return self.parseError(token, "expected {}, found {}", @tagName(Token.Id.StringLiteral), @tagName(name_token.id));
|
||||
|
||||
const lbrace = self.getNextToken();
|
||||
if (lbrace.id != Token.Id.LBrace)
|
||||
return self.parseError(token, "expected {}, found {}", @tagName(Token.Id.LBrace), @tagName(name_token.id));
|
||||
|
||||
const block = try self.createBlock(arena, token);
|
||||
const test_decl = try self.createAttachTestDecl(arena, &root_node.decls, token, name_token, block);
|
||||
try stack.append(State { .Block = block });
|
||||
continue;
|
||||
},
|
||||
Token.Id.Eof => {
|
||||
root_node.eof_token = token;
|
||||
return Tree {.root_node = root_node, .arena_allocator = arena_allocator};
|
||||
@ -733,6 +749,20 @@ pub const Parser = struct {
|
||||
return node;
|
||||
}
|
||||
|
||||
fn createTestDecl(self: &Parser, arena: &mem.Allocator, test_token: &const Token, name_token: &const Token,
|
||||
block: &ast.NodeBlock) !&ast.NodeTestDecl
|
||||
{
|
||||
const node = try arena.create(ast.NodeTestDecl);
|
||||
|
||||
*node = ast.NodeTestDecl {
|
||||
.base = self.initNode(ast.Node.Id.TestDecl),
|
||||
.test_token = *test_token,
|
||||
.name_token = *name_token,
|
||||
.body_node = &block.base,
|
||||
};
|
||||
return node;
|
||||
}
|
||||
|
||||
fn createFnProto(self: &Parser, arena: &mem.Allocator, fn_token: &const Token, extern_token: &const ?Token,
|
||||
cc_token: &const ?Token, visib_token: &const ?Token, inline_token: &const ?Token) !&ast.NodeFnProto
|
||||
{
|
||||
@ -867,6 +897,14 @@ pub const Parser = struct {
|
||||
return node;
|
||||
}
|
||||
|
||||
fn createAttachTestDecl(self: &Parser, arena: &mem.Allocator, list: &ArrayList(&ast.Node),
|
||||
test_token: &const Token, name_token: &const Token, block: &ast.NodeBlock) !&ast.NodeTestDecl
|
||||
{
|
||||
const node = try self.createTestDecl(arena, test_token, name_token, block);
|
||||
try list.append(&node.base);
|
||||
return node;
|
||||
}
|
||||
|
||||
fn parseError(self: &Parser, token: &const Token, comptime fmt: []const u8, args: ...) (error{ParseError}) {
|
||||
const loc = self.tokenizer.getTokenLocation(token);
|
||||
warn("{}:{}:{}: error: " ++ fmt ++ "\n", self.source_file_name, token.line + 1, token.column + 1, args);
|
||||
@ -1032,7 +1070,11 @@ pub const Parser = struct {
|
||||
ast.Node.Id.VarDecl => {
|
||||
const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", decl);
|
||||
try stack.append(RenderState { .VarDecl = var_decl});
|
||||
|
||||
},
|
||||
ast.Node.Id.TestDecl => {
|
||||
const test_decl = @fieldParentPtr(ast.NodeTestDecl, "base", decl);
|
||||
try stream.print("test {} ", self.tokenizer.getTokenSlice(test_decl.name_token));
|
||||
try stack.append(RenderState { .Expression = test_decl.body_node });
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
@ -1201,6 +1243,7 @@ pub const Parser = struct {
|
||||
|
||||
ast.Node.Id.Root,
|
||||
ast.Node.Id.VarDecl,
|
||||
ast.Node.Id.TestDecl,
|
||||
ast.Node.Id.ParamDecl => unreachable,
|
||||
},
|
||||
RenderState.FnProtoRParen => |fn_proto| {
|
||||
@ -1422,4 +1465,12 @@ test "zig fmt" {
|
||||
\\}
|
||||
\\
|
||||
);
|
||||
|
||||
try testCanonical(
|
||||
\\test "test name" {
|
||||
\\ const a = 1;
|
||||
\\ var b = 1;
|
||||
\\}
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user