Set comparisons with subset/superset semantics over set/frozenset. */
(&mut self, a: Val, b: Val, op: OpCode)
| 194 | |
| 195 | /* Set comparisons with subset/superset semantics over set/frozenset. */ |
| 196 | pub(crate) fn set_compare_and_push(&mut self, a: Val, b: Val, op: OpCode) -> Result<(), VmErr> { |
| 197 | let (sa, sb) = match (self.clone_set_items(a), self.clone_set_items(b)) { |
| 198 | (Some(x), Some(y)) => (x, y), |
| 199 | _ => return Err(cold_runtime("set_compare on non-set operands")), |
| 200 | }; |
| 201 | // Content-based so distinct-handle equal elements (tuples, long strings) compare correctly. |
| 202 | let eq = eq_set(&sa, &sb, |a, b| eq_vals_with_heap(a, b, &self.heap)); |
| 203 | let subset = |x: &ValSet, y: &ValSet| |
| 204 | x.iter().all(|&v| y.iter().any(|&w| eq_vals_with_heap(v, w, &self.heap))); |
| 205 | let result = match op { |
| 206 | OpCode::Eq => eq, |
| 207 | OpCode::NotEq => !eq, |
| 208 | OpCode::Lt => subset(&sa, &sb) && !eq, |
| 209 | OpCode::LtEq => subset(&sa, &sb), |
| 210 | OpCode::Gt => subset(&sb, &sa) && !eq, |
| 211 | OpCode::GtEq => subset(&sb, &sa), |
| 212 | _ => return Err(cold_runtime("set_compare with non-compare opcode")), |
| 213 | }; |
| 214 | self.push(Val::bool(result)); |
| 215 | Ok(()) |
| 216 | } |
| 217 | |
| 218 | pub fn type_name(&self, v: Val) -> &'static str { |
| 219 | if v.is_bool() { "bool" } |
no test coverage detected