@@ -78,6 +78,11 @@ impl VirtualMachine {
7878self . 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+
8186pub fn new_scope ( & mut self , parent_scope : Option < PyObjectRef > ) ->PyObjectRef {
8287// let parent_scope = self.current_frame_mut().locals.clone();
8388self . ctx . new_scope ( parent_scope)
@@ -437,32 +442,50 @@ impl VirtualMachine {
437442}
438443
439444pub 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
441446if let Ok ( method) =self . get_method ( a. clone ( ) , "__sub__" ) {
442- self . invoke (
447+ match self . invoke (
443448 method,
444449PyFuncArgs {
445- args : vec ! [ b] ,
450+ args : vec ! [ b. clone ( ) ] ,
446451kwargs : 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,
452467PyFuncArgs {
453- args : vec ! [ a] ,
468+ args : vec ! [ a. clone ( ) ] ,
454469kwargs : 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
468491pub fn _add ( & mut self , a : PyObjectRef , b : PyObjectRef ) ->PyResult {