stage2 AST: rename OptionalUnwrap to OrElse

preparing to flatten suffix operations AST
This commit is contained in:
Andrew Kelley 2020-07-20 15:52:24 -07:00
parent 1cfe43d563
commit 1ac28eed83
4 changed files with 130 additions and 120 deletions

View File

@ -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,

View File

@ -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);

View File

@ -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,

View File

@ -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,
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,
=> false,
.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,
.ArrayInitializer,
.ArrayInitializerDot,
.StructInitializer,
.StructInitializerDot,
=> true,
// 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,
.GroupedExpression => nodeNeedsMemoryLocation(node.castTag(.GroupedExpression).?.expr),
// True because these are exactly the expressions we need memory locations for.
.ArrayInitializer,
.ArrayInitializerDot,
.StructInitializer,
.StructInitializerDot,
=> return true,
.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"),
};
// 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,
}
}
}