Skip to content

Commit bacaef0

Browse files
committed
Make example work for sub/rsub. Still work in progress.
1 parent 60f2914 commit bacaef0

File tree

2 files changed

+40
-17
lines changed

2 files changed

+40
-17
lines changed

vm/src/obj/objint.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ fn int_sub(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
226226
.ctx
227227
.new_float(i.to_f64().unwrap() - objfloat::get_value(i2)))
228228
} else {
229-
Err(vm.new_type_error(format!("Cannot substract {:?} and {:?}", i, i2)))
229+
Err(vm.new_not_implemented_error(format!("Cannot substract {:?} and {:?}", i, i2)))
230230
}
231231
}
232232

vm/src/vm.rs

+39-16
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ impl VirtualMachine {
7878
self.new_exception(value_error, msg)
7979
}
8080

81+
pub fn new_not_implemented_error(&mut self, msg: String) -> PyObjectRef {
82+
let value_error = self.ctx.exceptions.not_implemented_error.clone();
83+
self.new_exception(value_error, msg)
84+
}
85+
8186
pub fn new_scope(&mut self, parent_scope: Option<PyObjectRef>) -> PyObjectRef {
8287
// let parent_scope = self.current_frame_mut().locals.clone();
8388
self.ctx.new_scope(parent_scope)
@@ -437,32 +442,50 @@ impl VirtualMachine {
437442
}
438443

439444
pub fn _sub(&mut self, a: PyObjectRef, b: PyObjectRef) -> PyResult {
440-
// Try __sub__, next __rsub__, next, give up
445+
// 1. Try __sub__, next __rsub__, next, give up
441446
if let Ok(method) = self.get_method(a.clone(), "__sub__") {
442-
self.invoke(
447+
match self.invoke(
443448
method,
444449
PyFuncArgs {
445-
args: vec![b],
450+
args: vec![b.clone()],
446451
kwargs: vec![],
447452
},
448-
)
449-
} else if let Ok(method) = self.get_method(b.clone(), "__rsub__") {
450-
self.invoke(
453+
) {
454+
Ok(value) => return Ok(value),
455+
Err(err) => {
456+
if !objtype::isinstance(&err, &self.ctx.exceptions.not_implemented_error) {
457+
return Err(err);
458+
}
459+
}
460+
}
461+
}
462+
463+
// 2. try __rsub__
464+
if let Ok(method) = self.get_method(b.clone(), "__rsub__") {
465+
match self.invoke(
451466
method,
452467
PyFuncArgs {
453-
args: vec![a],
468+
args: vec![a.clone()],
454469
kwargs: vec![],
455470
},
456-
)
457-
} else {
458-
// Cannot sub a and b
459-
let a_type_name = objtype::get_type_name(&a.typ());
460-
let b_type_name = objtype::get_type_name(&b.typ());
461-
Err(self.new_type_error(format!(
462-
"Unsupported operand types for '-': '{}' and '{}'",
463-
a_type_name, b_type_name
464-
)))
471+
) {
472+
Ok(value) => return Ok(value),
473+
Err(err) => {
474+
if !objtype::isinstance(&err, &self.ctx.exceptions.not_implemented_error) {
475+
return Err(err);
476+
}
477+
}
478+
}
465479
}
480+
481+
// 3. It all failed :(
482+
// Cannot sub a and b
483+
let a_type_name = objtype::get_type_name(&a.typ());
484+
let b_type_name = objtype::get_type_name(&b.typ());
485+
Err(self.new_type_error(format!(
486+
"Unsupported operand types for '-': '{}' and '{}'",
487+
a_type_name, b_type_name
488+
)))
466489
}
467490

468491
pub fn _add(&mut self, a: PyObjectRef, b: PyObjectRef) -> PyResult {

0 commit comments

Comments
 (0)