(&mut self, op: u16, is_min: bool, chunk: &crate::modules::parser::SSAChunk, slots: &mut [Val])
| 253 | pub fn call_max(&mut self, op: u16, chunk: &crate::modules::parser::SSAChunk, slots: &mut [Val]) -> Result<(), VmErr> { self.call_minmax(op, false, chunk, slots) } |
| 254 | |
| 255 | fn call_minmax(&mut self, op: u16, is_min: bool, chunk: &crate::modules::parser::SSAChunk, slots: &mut [Val]) -> Result<(), VmErr> { |
| 256 | let (positional, kw_flat, _np, _nk) = self.parse_call_args(op)?; |
| 257 | // Optional `default=` (returned when a single iterable is empty) and `key=` (compare by key(x)). |
| 258 | let mut default: Option<Val> = None; |
| 259 | let mut key: Option<Val> = None; |
| 260 | for pair in kw_flat.chunks_exact(2) { |
| 261 | match self.kw_name(pair[0]) { |
| 262 | Some("default") => default = Some(pair[1]), |
| 263 | Some("key") => { if !pair[1].is_none() { key = Some(pair[1]); } } |
| 264 | _ => return Err(cold_type("min()/max() got an unexpected keyword argument")), |
| 265 | } |
| 266 | } |
| 267 | // One arg iterable; many args are values. |
| 268 | let items = if positional.len() == 1 { self.iter_to_vec_general(positional[0])? } else { positional }; |
| 269 | let label = if is_min { "min() arg is an empty sequence" } else { "max() arg is an empty sequence" }; |
| 270 | if items.is_empty() { |
| 271 | return match default { Some(d) => { self.push(d); Ok(()) }, None => Err(cold_value(label)) }; |
| 272 | } |
| 273 | // Without a key, compare elements directly; with one, compare key(x) but return the winning element. |
| 274 | let keys: Vec<Val> = match key { |
| 275 | None => items.clone(), |
| 276 | Some(k) => { |
| 277 | let mut ks = Vec::with_capacity(items.len()); |
| 278 | for &x in &items { self.push(k); self.push(x); self.exec_call(1, chunk, slots)?; ks.push(self.pop()?); } |
| 279 | ks |
| 280 | } |
| 281 | }; |
| 282 | let mut best = 0; |
| 283 | for i in 1..items.len() { |
| 284 | let (l, r) = if is_min { (keys[i], keys[best]) } else { (keys[best], keys[i]) }; |
| 285 | if self.lt_vals(l, r)? { best = i; } |
| 286 | } |
| 287 | self.push(items[best]); Ok(()) |
| 288 | } |
| 289 | |
| 290 | pub fn call_sum(&mut self, op: u16) -> Result<(), VmErr> { |
| 291 | let args = self.pop_n(op as usize)?; |
no test coverage detected