add the anyframe and anyframe->T types
This commit is contained in:
@@ -540,6 +540,7 @@ pub fn autoHash(key: var, comptime rng: *std.rand.Random, comptime HashInt: type
|
||||
.Undefined,
|
||||
.ArgTuple,
|
||||
.Frame,
|
||||
.AnyFrame,
|
||||
=> @compileError("cannot hash this type"),
|
||||
|
||||
.Void,
|
||||
|
||||
@@ -30,6 +30,7 @@ pub fn expectEqual(expected: var, actual: @typeOf(expected)) void {
|
||||
.ArgTuple,
|
||||
.Opaque,
|
||||
.Frame,
|
||||
.AnyFrame,
|
||||
=> @compileError("value of type " ++ @typeName(@typeOf(actual)) ++ " encountered"),
|
||||
|
||||
.Undefined,
|
||||
|
||||
@@ -400,7 +400,7 @@ pub const Node = struct {
|
||||
VarType,
|
||||
ErrorType,
|
||||
FnProto,
|
||||
PromiseType,
|
||||
AnyFrameType,
|
||||
|
||||
// Primary expressions
|
||||
IntegerLiteral,
|
||||
@@ -952,9 +952,9 @@ pub const Node = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub const PromiseType = struct {
|
||||
pub const AnyFrameType = struct {
|
||||
base: Node,
|
||||
promise_token: TokenIndex,
|
||||
anyframe_token: TokenIndex,
|
||||
result: ?Result,
|
||||
|
||||
pub const Result = struct {
|
||||
@@ -962,7 +962,7 @@ pub const Node = struct {
|
||||
return_type: *Node,
|
||||
};
|
||||
|
||||
pub fn iterate(self: *PromiseType, index: usize) ?*Node {
|
||||
pub fn iterate(self: *AnyFrameType, index: usize) ?*Node {
|
||||
var i = index;
|
||||
|
||||
if (self.result) |result| {
|
||||
@@ -973,13 +973,13 @@ pub const Node = struct {
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn firstToken(self: *const PromiseType) TokenIndex {
|
||||
return self.promise_token;
|
||||
pub fn firstToken(self: *const AnyFrameType) TokenIndex {
|
||||
return self.anyframe_token;
|
||||
}
|
||||
|
||||
pub fn lastToken(self: *const PromiseType) TokenIndex {
|
||||
pub fn lastToken(self: *const AnyFrameType) TokenIndex {
|
||||
if (self.result) |result| return result.return_type.lastToken();
|
||||
return self.promise_token;
|
||||
return self.anyframe_token;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1201,7 +1201,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
||||
/// / KEYWORD_error DOT IDENTIFIER
|
||||
/// / KEYWORD_false
|
||||
/// / KEYWORD_null
|
||||
/// / KEYWORD_promise
|
||||
/// / KEYWORD_anyframe
|
||||
/// / KEYWORD_true
|
||||
/// / KEYWORD_undefined
|
||||
/// / KEYWORD_unreachable
|
||||
@@ -1256,11 +1256,11 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
|
||||
}
|
||||
if (eatToken(it, .Keyword_false)) |token| return createLiteral(arena, Node.BoolLiteral, token);
|
||||
if (eatToken(it, .Keyword_null)) |token| return createLiteral(arena, Node.NullLiteral, token);
|
||||
if (eatToken(it, .Keyword_promise)) |token| {
|
||||
const node = try arena.create(Node.PromiseType);
|
||||
node.* = Node.PromiseType{
|
||||
.base = Node{ .id = .PromiseType },
|
||||
.promise_token = token,
|
||||
if (eatToken(it, .Keyword_anyframe)) |token| {
|
||||
const node = try arena.create(Node.AnyFrameType);
|
||||
node.* = Node.AnyFrameType{
|
||||
.base = Node{ .id = .AnyFrameType },
|
||||
.anyframe_token = token,
|
||||
.result = null,
|
||||
};
|
||||
return &node.base;
|
||||
@@ -2194,7 +2194,7 @@ fn parsePrefixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
||||
|
||||
/// PrefixTypeOp
|
||||
/// <- QUESTIONMARK
|
||||
/// / KEYWORD_promise MINUSRARROW
|
||||
/// / KEYWORD_anyframe MINUSRARROW
|
||||
/// / ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
|
||||
/// / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
|
||||
fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
||||
@@ -2209,20 +2209,20 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
|
||||
return &node.base;
|
||||
}
|
||||
|
||||
// TODO: Returning a PromiseType instead of PrefixOp makes casting and setting .rhs or
|
||||
// TODO: Returning a AnyFrameType instead of PrefixOp makes casting and setting .rhs or
|
||||
// .return_type more difficult for the caller (see parsePrefixOpExpr helper).
|
||||
// Consider making the PromiseType a member of PrefixOp and add a
|
||||
// PrefixOp.PromiseType variant?
|
||||
if (eatToken(it, .Keyword_promise)) |token| {
|
||||
// Consider making the AnyFrameType a member of PrefixOp and add a
|
||||
// PrefixOp.AnyFrameType variant?
|
||||
if (eatToken(it, .Keyword_anyframe)) |token| {
|
||||
const arrow = eatToken(it, .Arrow) orelse {
|
||||
putBackToken(it, token);
|
||||
return null;
|
||||
};
|
||||
const node = try arena.create(Node.PromiseType);
|
||||
node.* = Node.PromiseType{
|
||||
.base = Node{ .id = .PromiseType },
|
||||
.promise_token = token,
|
||||
.result = Node.PromiseType.Result{
|
||||
const node = try arena.create(Node.AnyFrameType);
|
||||
node.* = Node.AnyFrameType{
|
||||
.base = Node{ .id = .AnyFrameType },
|
||||
.anyframe_token = token,
|
||||
.result = Node.AnyFrameType.Result{
|
||||
.arrow_token = arrow,
|
||||
.return_type = undefined, // set by caller
|
||||
},
|
||||
@@ -2903,8 +2903,8 @@ fn parsePrefixOpExpr(
|
||||
rightmost_op = rhs;
|
||||
} else break;
|
||||
},
|
||||
.PromiseType => {
|
||||
const prom = rightmost_op.cast(Node.PromiseType).?;
|
||||
.AnyFrameType => {
|
||||
const prom = rightmost_op.cast(Node.AnyFrameType).?;
|
||||
if (try opParseFn(arena, it, tree)) |rhs| {
|
||||
prom.result.?.return_type = rhs;
|
||||
rightmost_op = rhs;
|
||||
@@ -2922,8 +2922,8 @@ fn parsePrefixOpExpr(
|
||||
.InvalidToken = AstError.InvalidToken{ .token = it.index },
|
||||
});
|
||||
},
|
||||
.PromiseType => {
|
||||
const prom = rightmost_op.cast(Node.PromiseType).?;
|
||||
.AnyFrameType => {
|
||||
const prom = rightmost_op.cast(Node.AnyFrameType).?;
|
||||
prom.result.?.return_type = try expectNode(arena, it, tree, childParseFn, AstError{
|
||||
.InvalidToken = AstError.InvalidToken{ .token = it.index },
|
||||
});
|
||||
|
||||
@@ -2111,12 +2111,12 @@ test "zig fmt: coroutines" {
|
||||
\\ suspend;
|
||||
\\ x += 1;
|
||||
\\ suspend;
|
||||
\\ const p: promise->void = async simpleAsyncFn() catch unreachable;
|
||||
\\ const p: anyframe->void = async simpleAsyncFn() catch unreachable;
|
||||
\\ await p;
|
||||
\\}
|
||||
\\
|
||||
\\test "coroutine suspend, resume, cancel" {
|
||||
\\ const p: promise = try async<std.debug.global_allocator> testAsyncSeq();
|
||||
\\ const p: anyframe = try async<std.debug.global_allocator> testAsyncSeq();
|
||||
\\ resume p;
|
||||
\\ cancel p;
|
||||
\\}
|
||||
|
||||
@@ -1205,15 +1205,15 @@ fn renderExpression(
|
||||
}
|
||||
},
|
||||
|
||||
ast.Node.Id.PromiseType => {
|
||||
const promise_type = @fieldParentPtr(ast.Node.PromiseType, "base", base);
|
||||
ast.Node.Id.AnyFrameType => {
|
||||
const anyframe_type = @fieldParentPtr(ast.Node.AnyFrameType, "base", base);
|
||||
|
||||
if (promise_type.result) |result| {
|
||||
try renderToken(tree, stream, promise_type.promise_token, indent, start_col, Space.None); // promise
|
||||
if (anyframe_type.result) |result| {
|
||||
try renderToken(tree, stream, anyframe_type.anyframe_token, indent, start_col, Space.None); // anyframe
|
||||
try renderToken(tree, stream, result.arrow_token, indent, start_col, Space.None); // ->
|
||||
return renderExpression(allocator, stream, tree, indent, start_col, result.return_type, space);
|
||||
} else {
|
||||
return renderToken(tree, stream, promise_type.promise_token, indent, start_col, space); // promise
|
||||
return renderToken(tree, stream, anyframe_type.anyframe_token, indent, start_col, space); // anyframe
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ pub const Token = struct {
|
||||
Keyword{ .bytes = "align", .id = Id.Keyword_align },
|
||||
Keyword{ .bytes = "allowzero", .id = Id.Keyword_allowzero },
|
||||
Keyword{ .bytes = "and", .id = Id.Keyword_and },
|
||||
Keyword{ .bytes = "anyframe", .id = Id.Keyword_anyframe },
|
||||
Keyword{ .bytes = "asm", .id = Id.Keyword_asm },
|
||||
Keyword{ .bytes = "async", .id = Id.Keyword_async },
|
||||
Keyword{ .bytes = "await", .id = Id.Keyword_await },
|
||||
@@ -42,7 +43,6 @@ pub const Token = struct {
|
||||
Keyword{ .bytes = "or", .id = Id.Keyword_or },
|
||||
Keyword{ .bytes = "orelse", .id = Id.Keyword_orelse },
|
||||
Keyword{ .bytes = "packed", .id = Id.Keyword_packed },
|
||||
Keyword{ .bytes = "promise", .id = Id.Keyword_promise },
|
||||
Keyword{ .bytes = "pub", .id = Id.Keyword_pub },
|
||||
Keyword{ .bytes = "resume", .id = Id.Keyword_resume },
|
||||
Keyword{ .bytes = "return", .id = Id.Keyword_return },
|
||||
@@ -174,7 +174,7 @@ pub const Token = struct {
|
||||
Keyword_or,
|
||||
Keyword_orelse,
|
||||
Keyword_packed,
|
||||
Keyword_promise,
|
||||
Keyword_anyframe,
|
||||
Keyword_pub,
|
||||
Keyword_resume,
|
||||
Keyword_return,
|
||||
|
||||
Reference in New Issue
Block a user