stage2 parser: document undefined and clean up

This commit is contained in:
xackus 2020-01-10 22:48:51 +01:00
parent f81529fab1
commit 5880eb3a75
3 changed files with 30 additions and 26 deletions

View File

@ -10,6 +10,7 @@ pub const TokenIndex = usize;
pub const Tree = struct {
source: []const u8,
tokens: TokenList,
/// undefined on parse error (errors not empty)
root_node: *Node.Root,
arena_allocator: std.heap.ArenaAllocator,
errors: ErrorList,
@ -612,7 +613,7 @@ pub const Node = struct {
visib_token: ?TokenIndex,
thread_local_token: ?TokenIndex,
name_token: TokenIndex,
eq_token: TokenIndex,
eq_token: ?TokenIndex,
mut_token: TokenIndex,
comptime_token: ?TokenIndex,
extern_export_token: ?TokenIndex,

View File

@ -13,7 +13,7 @@ pub const Error = error{ParseError} || Allocator.Error;
/// Result should be freed with tree.deinit() when there are
/// no more references to any of the tokens or nodes.
pub fn parse(allocator: *Allocator, source: []const u8) !*Tree {
pub fn parse(allocator: *Allocator, source: []const u8) Allocator.Error!*Tree {
const tree = blk: {
// This block looks unnecessary, but is a "foot-shield" to prevent the SegmentedLists
// from being initialized with a pointer to this `arena`, which is created on
@ -48,29 +48,32 @@ pub fn parse(allocator: *Allocator, source: []const u8) !*Tree {
while (it.peek().?.id == .LineComment) _ = it.next();
tree.root_node = try parseRoot(arena, &it, tree);
tree.root_node = parseRoot(arena, &it, tree) catch |err| blk: {
switch (err) {
error.ParseError => {
assert(tree.errors.len != 0);
break :blk undefined;
},
error.OutOfMemory => {
return error.OutOfMemory;
},
}
};
return tree;
}
/// Root <- skip ContainerMembers eof
fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error!*Node.Root {
fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!*Node.Root {
const node = try arena.create(Node.Root);
node.* = Node.Root{
.decls = undefined,
.eof_token = undefined,
};
node.decls = parseContainerMembers(arena, it, tree) catch |err| {
// TODO: Switch on the error type
// https://github.com/ziglang/zig/issues/2473
if (err == error.ParseError) return node;
assert(err == Allocator.Error.OutOfMemory);
return Allocator.Error.OutOfMemory;
};
node.eof_token = eatToken(it, .Eof) orelse {
try tree.errors.push(AstError{
.ExpectedContainerMembers = AstError.ExpectedContainerMembers{ .token = it.index },
});
return node;
.decls = try parseContainerMembers(arena, it, tree),
.eof_token = eatToken(it, .Eof) orelse {
try tree.errors.push(AstError{
.ExpectedContainerMembers = .{ .token = it.index },
});
return error.ParseError;
},
};
return node;
}
@ -400,7 +403,7 @@ fn parseVarDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
.visib_token = null,
.thread_local_token = null,
.name_token = name_token,
.eq_token = eq_token orelse undefined,
.eq_token = eq_token,
.mut_token = mut_token,
.comptime_token = null,
.extern_export_token = null,
@ -2187,7 +2190,7 @@ fn parsePrefixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
node.* = Node.PrefixOp{
.op_token = token.index,
.op = op,
.rhs = undefined,
.rhs = undefined, // set by caller
};
return &node.base;
}
@ -2829,8 +2832,8 @@ fn parseUse(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
.doc_comments = null,
.visib_token = null,
.use_token = token,
.expr = undefined,
.semicolon_token = undefined,
.expr = undefined, // set by caller
.semicolon_token = undefined, // set by caller
};
return &node.base;
}
@ -2989,9 +2992,9 @@ fn createInfixOp(arena: *Allocator, index: TokenIndex, op: Node.InfixOp.Op) !*No
const node = try arena.create(Node.InfixOp);
node.* = Node.InfixOp{
.op_token = index,
.lhs = undefined,
.lhs = undefined, // set by caller
.op = op,
.rhs = undefined,
.rhs = undefined, // set by caller
};
return &node.base;
}

View File

@ -2020,7 +2020,7 @@ fn renderVarDecl(
if (var_decl.init_node) |init_node| {
const s = if (init_node.id == .MultilineStringLiteral) Space.None else Space.Space;
try renderToken(tree, stream, var_decl.eq_token, indent, start_col, s); // =
try renderToken(tree, stream, var_decl.eq_token.?, indent, start_col, s); // =
try renderExpression(allocator, stream, tree, indent, start_col, init_node, Space.None);
}