Commit 5880eb3a75

xackus <14938807+xackus@users.noreply.github.com>
2020-01-10 22:48:51
stage2 parser: document undefined and clean up
1 parent f81529f
Changed files (3)
lib/std/zig/ast.zig
@@ -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,
lib/std/zig/parse.zig
@@ -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;
 }
lib/std/zig/render.zig
@@ -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);
     }