Commit 1ac28eed83
Changed files (4)
lib
std
src-self-hosted
lib/std/zig/ast.zig
@@ -453,7 +453,7 @@ pub const Node = struct {
Range,
Sub,
SubWrap,
- UnwrapOptional,
+ OrElse,
// SimplePrefixOp
AddressOf,
@@ -582,7 +582,7 @@ pub const Node = struct {
.Range,
.Sub,
.SubWrap,
- .UnwrapOptional,
+ .OrElse,
=> SimpleInfixOp,
.AddressOf,
lib/std/zig/parse.zig
@@ -1486,7 +1486,7 @@ const Parser = struct {
.Range,
.Sub,
.SubWrap,
- .UnwrapOptional,
+ .OrElse,
=> node.cast(Node.SimpleInfixOp).?.lhs = res,
else => unreachable,
@@ -1563,7 +1563,7 @@ const Parser = struct {
.Range,
.Sub,
.SubWrap,
- .UnwrapOptional,
+ .OrElse,
=> node.cast(Node.SimpleInfixOp).?.lhs = res,
else => unreachable,
}
@@ -2425,7 +2425,7 @@ const Parser = struct {
.Ampersand => .BitAnd,
.Caret => .BitXor,
.Pipe => .BitOr,
- .Keyword_orelse => .UnwrapOptional,
+ .Keyword_orelse => .OrElse,
.Keyword_catch => {
const payload = try p.parsePayload();
const node = try p.arena.allocator.create(Node.Catch);
lib/std/zig/render.zig
@@ -503,7 +503,7 @@ fn renderExpression(
.Range,
.Sub,
.SubWrap,
- .UnwrapOptional,
+ .OrElse,
=> {
const infix_op_node = @fieldParentPtr(ast.Node.SimpleInfixOp, "base", base);
@@ -2656,7 +2656,7 @@ fn nodeCausesSliceOpSpace(base: *ast.Node) bool {
.Range,
.Sub,
.SubWrap,
- .UnwrapOptional,
+ .OrElse,
=> true,
else => false,
src-self-hosted/astgen.zig
@@ -88,7 +88,7 @@ fn varDecl(mod: *Module, scope: *Scope, node: *ast.Node.VarDecl) InnerError!Scop
// or an rvalue as a result location. If it is an rvalue, we can use the instruction as
// the variable, no memory location needed.
const init_node = node.getTrailer("init_node").?;
- if (nodeNeedsMemoryLocation(init_node)) {
+ if (nodeMayNeedMemoryLocation(init_node)) {
return mod.failNode(scope, init_node, "TODO implement result locations", .{});
}
const init_inst = try expr(mod, scope, init_node);
@@ -579,120 +579,130 @@ fn getSimplePrimitiveValue(name: []const u8) ?TypedValue {
return null;
}
-fn nodeNeedsMemoryLocation(node: *ast.Node) bool {
- return switch (node.tag) {
- .Root,
- .Use,
- .TestDecl,
- .DocComment,
- .SwitchCase,
- .SwitchElse,
- .Else,
- .Payload,
- .PointerPayload,
- .PointerIndexPayload,
- .ContainerField,
- .ErrorTag,
- .FieldInitializer,
- => unreachable,
-
- .ControlFlowExpression,
- .BitNot,
- .BoolNot,
- .VarDecl,
- .Defer,
- .AddressOf,
- .OptionalType,
- .Negation,
- .NegationWrap,
- .Resume,
- .ArrayType,
- .ArrayTypeSentinel,
- .PtrType,
- .SliceType,
- .Suspend,
- .AnyType,
- .ErrorType,
- .FnProto,
- .AnyFrameType,
- .IntegerLiteral,
- .FloatLiteral,
- .EnumLiteral,
- .StringLiteral,
- .MultilineStringLiteral,
- .CharLiteral,
- .BoolLiteral,
- .NullLiteral,
- .UndefinedLiteral,
- .Unreachable,
- .Identifier,
- .ErrorSetDecl,
- .ContainerDecl,
- .Asm,
- .Add,
- .AddWrap,
- .ArrayCat,
- .ArrayMult,
- .Assign,
- .AssignBitAnd,
- .AssignBitOr,
- .AssignBitShiftLeft,
- .AssignBitShiftRight,
- .AssignBitXor,
- .AssignDiv,
- .AssignSub,
- .AssignSubWrap,
- .AssignMod,
- .AssignAdd,
- .AssignAddWrap,
- .AssignMul,
- .AssignMulWrap,
- .BangEqual,
- .BitAnd,
- .BitOr,
- .BitShiftLeft,
- .BitShiftRight,
- .BitXor,
- .BoolAnd,
- .BoolOr,
- .Div,
- .EqualEqual,
- .ErrorUnion,
- .GreaterOrEqual,
- .GreaterThan,
- .LessOrEqual,
- .LessThan,
- .MergeErrorSets,
- .Mod,
- .Mul,
- .MulWrap,
- .Range,
- .Period,
- .Sub,
- .SubWrap,
- => false,
-
- .ArrayInitializer,
- .ArrayInitializerDot,
- .StructInitializer,
- .StructInitializerDot,
- => true,
-
- .GroupedExpression => nodeNeedsMemoryLocation(node.castTag(.GroupedExpression).?.expr),
-
- .UnwrapOptional => @panic("TODO nodeNeedsMemoryLocation for UnwrapOptional"),
- .Catch => @panic("TODO nodeNeedsMemoryLocation for Catch"),
- .Await => @panic("TODO nodeNeedsMemoryLocation for Await"),
- .Try => @panic("TODO nodeNeedsMemoryLocation for Try"),
- .If => @panic("TODO nodeNeedsMemoryLocation for If"),
- .SuffixOp => @panic("TODO nodeNeedsMemoryLocation for SuffixOp"),
- .Call => @panic("TODO nodeNeedsMemoryLocation for Call"),
- .Switch => @panic("TODO nodeNeedsMemoryLocation for Switch"),
- .While => @panic("TODO nodeNeedsMemoryLocation for While"),
- .For => @panic("TODO nodeNeedsMemoryLocation for For"),
- .BuiltinCall => @panic("TODO nodeNeedsMemoryLocation for BuiltinCall"),
- .Comptime => @panic("TODO nodeNeedsMemoryLocation for Comptime"),
- .Nosuspend => @panic("TODO nodeNeedsMemoryLocation for Nosuspend"),
- .Block => @panic("TODO nodeNeedsMemoryLocation for Block"),
- };
+fn nodeMayNeedMemoryLocation(start_node: *ast.Node) bool {
+ var node = start_node;
+ while (true) {
+ switch (node.tag) {
+ .Root,
+ .Use,
+ .TestDecl,
+ .DocComment,
+ .SwitchCase,
+ .SwitchElse,
+ .Else,
+ .Payload,
+ .PointerPayload,
+ .PointerIndexPayload,
+ .ContainerField,
+ .ErrorTag,
+ .FieldInitializer,
+ => unreachable,
+
+ .ControlFlowExpression,
+ .BitNot,
+ .BoolNot,
+ .VarDecl,
+ .Defer,
+ .AddressOf,
+ .OptionalType,
+ .Negation,
+ .NegationWrap,
+ .Resume,
+ .ArrayType,
+ .ArrayTypeSentinel,
+ .PtrType,
+ .SliceType,
+ .Suspend,
+ .AnyType,
+ .ErrorType,
+ .FnProto,
+ .AnyFrameType,
+ .IntegerLiteral,
+ .FloatLiteral,
+ .EnumLiteral,
+ .StringLiteral,
+ .MultilineStringLiteral,
+ .CharLiteral,
+ .BoolLiteral,
+ .NullLiteral,
+ .UndefinedLiteral,
+ .Unreachable,
+ .Identifier,
+ .ErrorSetDecl,
+ .ContainerDecl,
+ .Asm,
+ .Add,
+ .AddWrap,
+ .ArrayCat,
+ .ArrayMult,
+ .Assign,
+ .AssignBitAnd,
+ .AssignBitOr,
+ .AssignBitShiftLeft,
+ .AssignBitShiftRight,
+ .AssignBitXor,
+ .AssignDiv,
+ .AssignSub,
+ .AssignSubWrap,
+ .AssignMod,
+ .AssignAdd,
+ .AssignAddWrap,
+ .AssignMul,
+ .AssignMulWrap,
+ .BangEqual,
+ .BitAnd,
+ .BitOr,
+ .BitShiftLeft,
+ .BitShiftRight,
+ .BitXor,
+ .BoolAnd,
+ .BoolOr,
+ .Div,
+ .EqualEqual,
+ .ErrorUnion,
+ .GreaterOrEqual,
+ .GreaterThan,
+ .LessOrEqual,
+ .LessThan,
+ .MergeErrorSets,
+ .Mod,
+ .Mul,
+ .MulWrap,
+ .Range,
+ .Period,
+ .Sub,
+ .SubWrap,
+ => return false,
+
+ // Forward the question to a sub-expression.
+ .GroupedExpression => node = node.castTag(.GroupedExpression).?.expr,
+ .Try => node = node.castTag(.Try).?.rhs,
+ .Await => node = node.castTag(.Await).?.rhs,
+ .Catch => node = node.castTag(.Catch).?.rhs,
+ .OrElse => node = node.castTag(.OrElse).?.rhs,
+ .Comptime => node = node.castTag(.Comptime).?.expr,
+ .Nosuspend => node = node.castTag(.Nosuspend).?.expr,
+
+ // True because these are exactly the expressions we need memory locations for.
+ .ArrayInitializer,
+ .ArrayInitializerDot,
+ .StructInitializer,
+ .StructInitializerDot,
+ => return true,
+
+ // True because depending on comptime conditions, sub-expressions
+ // may be the kind that need memory locations.
+ .While,
+ .For,
+ .Switch,
+ .Call,
+ .BuiltinCall, // TODO some of these can return false
+ .SuffixOp, // TODO this should be split up
+ => return true,
+
+ // Depending on AST properties, they may need memory locations.
+ .If => return node.castTag(.If).?.@"else" != null,
+ .Block => return node.castTag(.Block).?.label != null,
+ }
+ }
}