Commit 37d3ef2835

Andrew Kelley <superjoe30@gmail.com>
2018-04-30 22:16:58
zig fmt: support promise->T
1 parent 47680cc
std/zig/ast.zig
@@ -36,6 +36,7 @@ pub const Node = struct {
         VarType,
         ErrorType,
         FnProto,
+        PromiseType,
 
         // Primary expressions
         IntegerLiteral,
@@ -495,6 +496,37 @@ pub const Node = struct {
         }
     };
 
+    pub const PromiseType = struct {
+        base: Node,
+        promise_token: Token,
+        result: ?Result,
+
+        pub const Result = struct {
+            arrow_token: Token,
+            return_type: &Node,
+        };
+
+        pub fn iterate(self: &PromiseType, index: usize) ?&Node {
+            var i = index;
+
+            if (self.result) |result| {
+                if (i < 1) return result.return_type;
+                i -= 1;
+            }
+
+            return null;
+        }
+
+        pub fn firstToken(self: &PromiseType) Token {
+            return self.promise_token;
+        }
+
+        pub fn lastToken(self: &PromiseType) Token {
+            if (self.result) |result| return result.return_type.lastToken();
+            return self.promise_token;
+        }
+    };
+
     pub const ParamDecl = struct {
         base: Node,
         comptime_token: ?Token,
std/zig/parser.zig
@@ -2550,6 +2550,30 @@ pub const Parser = struct {
                             _ = try self.createToCtxLiteral(arena, opt_ctx, ast.Node.Unreachable, token);
                             continue;
                         },
+                        Token.Id.Keyword_promise => {
+                            const node = try arena.construct(ast.Node.PromiseType {
+                                .base = ast.Node {
+                                    .id = ast.Node.Id.PromiseType,
+                                    .doc_comments = null,
+                                    .same_line_comment = null,
+                                },
+                                .promise_token = token,
+                                .result = null,
+                            });
+                            opt_ctx.store(&node.base);
+                            const next_token = self.getNextToken();
+                            if (next_token.id != Token.Id.Arrow) {
+                                self.putBackToken(next_token);
+                                continue;
+                            }
+                            node.result = ast.Node.PromiseType.Result {
+                                .arrow_token = next_token,
+                                .return_type = undefined,
+                            };
+                            const return_type_ptr = &((??node.result).return_type);
+                            try stack.append(State { .Expression = OptionalCtx { .Required = return_type_ptr, } });
+                            continue;
+                        },
                         Token.Id.StringLiteral, Token.Id.MultilineStringLiteralLine => {
                             opt_ctx.store((try self.parseStringLiteral(arena, token)) ?? unreachable);
                             continue;
@@ -4147,6 +4171,14 @@ pub const Parser = struct {
                             try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(visib_token) });
                         }
                     },
+                    ast.Node.Id.PromiseType => {
+                        const promise_type = @fieldParentPtr(ast.Node.PromiseType, "base", base);
+                        try stream.write(self.tokenizer.getTokenSlice(promise_type.promise_token));
+                        if (promise_type.result) |result| {
+                            try stream.write(self.tokenizer.getTokenSlice(result.arrow_token));
+                            try stack.append(RenderState { .Expression = result.return_type});
+                        }
+                    },
                     ast.Node.Id.LineComment => {
                         const line_comment_node = @fieldParentPtr(ast.Node.LineComment, "base", base);
                         try stream.write(self.tokenizer.getTokenSlice(line_comment_node.token));
std/zig/parser_test.zig
@@ -948,12 +948,12 @@ test "zig fmt: coroutines" {
         \\    suspend;
         \\    x += 1;
         \\    suspend |p| {}
-        \\    const p = async simpleAsyncFn() catch unreachable;
+        \\    const p: promise->void = async simpleAsyncFn() catch unreachable;
         \\    await p;
         \\}
         \\
         \\test "coroutine suspend, resume, cancel" {
-        \\    const p = try async<std.debug.global_allocator> testAsyncSeq();
+        \\    const p: promise = try async<std.debug.global_allocator> testAsyncSeq();
         \\    resume p;
         \\    cancel p;
         \\}
std/zig/tokenizer.zig
@@ -40,6 +40,7 @@ pub const Token = struct {
         KeywordId{.bytes="null", .id = Id.Keyword_null},
         KeywordId{.bytes="or", .id = Id.Keyword_or},
         KeywordId{.bytes="packed", .id = Id.Keyword_packed},
+        KeywordId{.bytes="promise", .id = Id.Keyword_promise},
         KeywordId{.bytes="pub", .id = Id.Keyword_pub},
         KeywordId{.bytes="resume", .id = Id.Keyword_resume},
         KeywordId{.bytes="return", .id = Id.Keyword_return},
@@ -166,6 +167,7 @@ pub const Token = struct {
         Keyword_null,
         Keyword_or,
         Keyword_packed,
+        Keyword_promise,
         Keyword_pub,
         Keyword_resume,
         Keyword_return,