Shared implementation for optional or. If return value is Ok, the result is assigned to the result reference argument.
| 124 | // If return value is Ok, the result is assigned to the result reference |
| 125 | // argument. |
| 126 | absl::Status EvalOptionalOr(OptionalOrKind kind, const Value& lhs, |
| 127 | const Value& rhs, const AttributeTrail& lhs_attr, |
| 128 | const AttributeTrail& rhs_attr, Value& result, |
| 129 | AttributeTrail& result_attr) { |
| 130 | if (InstanceOf<ErrorValue>(lhs) || InstanceOf<UnknownValue>(lhs)) { |
| 131 | result = lhs; |
| 132 | result_attr = lhs_attr; |
| 133 | return absl::OkStatus(); |
| 134 | } |
| 135 | |
| 136 | auto lhs_optional_value = As<OptionalValue>(lhs); |
| 137 | if (!lhs_optional_value.has_value()) { |
| 138 | result = MakeNoOverloadError(kind); |
| 139 | result_attr = AttributeTrail(); |
| 140 | return absl::OkStatus(); |
| 141 | } |
| 142 | |
| 143 | if (lhs_optional_value->HasValue()) { |
| 144 | if (kind == OptionalOrKind::kOrValue) { |
| 145 | result = lhs_optional_value->Value(); |
| 146 | } else { |
| 147 | result = lhs; |
| 148 | } |
| 149 | result_attr = lhs_attr; |
| 150 | return absl::OkStatus(); |
| 151 | } |
| 152 | |
| 153 | if (kind == OptionalOrKind::kOrOptional && !InstanceOf<ErrorValue>(rhs) && |
| 154 | !InstanceOf<UnknownValue>(rhs) && !InstanceOf<OptionalValue>(rhs)) { |
| 155 | result = MakeNoOverloadError(kind); |
| 156 | result_attr = AttributeTrail(); |
| 157 | return absl::OkStatus(); |
| 158 | } |
| 159 | |
| 160 | result = rhs; |
| 161 | result_attr = rhs_attr; |
| 162 | return absl::OkStatus(); |
| 163 | } |
| 164 | |
| 165 | absl::Status OptionalOrStep::Evaluate(ExecutionFrame* frame) const { |
| 166 | if (!frame->value_stack().HasEnough(2)) { |
no test coverage detected