Dispatches call: print/range opcodes; imported natives (shadow builtins); builtins table; else LoadName+Call. */
(&mut self, name: String)
| 354 | |
| 355 | /* Dispatches call: print/range opcodes; imported natives (shadow builtins); builtins table; else LoadName+Call. */ |
| 356 | pub(super) fn call(&mut self, name: String) -> bool { |
| 357 | let call_pos = self.last_end as u32; |
| 358 | if name == "print" { |
| 359 | let (pos, kw) = self.parse_args(); |
| 360 | // Same packed layout as Call so the VM can split sep/end kwargs from positionals. |
| 361 | self.chunk.emit(OpCode::CallPrint, super::pack_call(pos, kw)); |
| 362 | self.chunk.record_call_pos(call_pos); |
| 363 | return false; |
| 364 | } |
| 365 | |
| 366 | if name == "range" { |
| 367 | self.call_range(); |
| 368 | return true; |
| 369 | } |
| 370 | |
| 371 | // Imported natives shadow builtins, matching Python `from x import *` rebinding. |
| 372 | if let Some(&extern_idx) = self.chunk.extern_index.get(&name) { |
| 373 | let (pos, kw) = self.parse_args(); |
| 374 | // Operand packs extern_idx<<8 | kw<<4 | pos, same layout as Call. |
| 375 | let encoded = (extern_idx << 8) | ((kw & 0xF) << 4) | (pos & 0xF); |
| 376 | self.chunk.emit(OpCode::CallExtern, encoded); |
| 377 | self.chunk.record_call_pos(call_pos); |
| 378 | return true; |
| 379 | } |
| 380 | |
| 381 | // dict() needs positional and keyword counts distinct. |
| 382 | if name == "dict" { |
| 383 | let (pos, kw) = self.parse_args(); |
| 384 | self.chunk.emit(OpCode::CallDict, super::pack_call(pos, kw)); |
| 385 | self.chunk.record_call_pos(call_pos); |
| 386 | return true; |
| 387 | } |
| 388 | |
| 389 | // min()/max() (`default=`/`key=`) and enumerate() (`start=`) take keywords, so keep positional and keyword counts distinct. |
| 390 | if name == "min" || name == "max" || name == "enumerate" { |
| 391 | let op = match name.as_str() { "min" => OpCode::CallMin, "max" => OpCode::CallMax, _ => OpCode::CallEnumerate }; |
| 392 | let (pos, kw) = self.parse_args(); |
| 393 | self.chunk.emit(op, super::pack_call(pos, kw)); |
| 394 | self.chunk.record_call_pos(call_pos); |
| 395 | return true; |
| 396 | } |
| 397 | |
| 398 | if let Some((op, leaves_value)) = builtin(name.as_str()) { |
| 399 | let (pos, kw) = self.parse_args(); |
| 400 | self.chunk.emit(op, pos + kw); |
| 401 | self.chunk.record_call_pos(call_pos); |
| 402 | return leaves_value; |
| 403 | } |
| 404 | |
| 405 | let i = self.push_ssa_name(&name, self.current_version(&name)); |
| 406 | self.chunk.emit(OpCode::LoadName, i); |
| 407 | let (pos, kw) = self.parse_args(); |
| 408 | self.chunk.emit(OpCode::Call, super::pack_call(pos, kw)); |
| 409 | self.chunk.record_call_pos(call_pos); |
| 410 | true |
| 411 | } |
| 412 | |
| 413 | pub(super) fn call_range(&mut self) { |
no test coverage detected