@@ -290,7 +290,38 @@ fn builtin_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
290290// builtin_oct
291291// builtin_open
292292// builtin_ord
293- // builtin_pow
293+
294+ fn builtin_pow ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
295+ arg_check ! (
296+ vm,
297+ args,
298+ required = [ ( x, None ) , ( y, None ) ] ,
299+ optional = [ ( mod_value, Some ( vm. ctx. int_type( ) ) ) ]
300+ ) ;
301+ let pow_method_name = "__pow__" . to_string ( ) ;
302+ let result = match vm. get_attribute ( x. clone ( ) , & pow_method_name) {
303+ Ok ( attrib) => vm. invoke ( attrib, PyFuncArgs :: new ( vec ! [ y. clone( ) ] , vec ! [ ] ) ) ,
304+ Err ( ..) => Err ( vm. new_type_error ( "unsupported operand type(s) for pow" . to_string ( ) ) ) ,
305+ } ;
306+ //Check if the 3rd argument is defined and perform modulus on the result
307+ //this should be optimized in the future to perform a "power-mod" algorithm in
308+ //order to improve performance
309+ match mod_value {
310+ Some ( mod_value) => {
311+ let mod_method_name = "__mod__" . to_string ( ) ;
312+ match vm. get_attribute (
313+ result. expect ( "result not defined" ) . clone ( ) ,
314+ & mod_method_name,
315+ ) {
316+ Ok ( value) => vm. invoke ( value, PyFuncArgs :: new ( vec ! [ mod_value. clone( ) ] , vec ! [ ] ) ) ,
317+ Err ( ..) => {
318+ Err ( vm. new_type_error ( "unsupported operand type(s) for mod" . to_string ( ) ) )
319+ }
320+ }
321+ }
322+ None => result,
323+ }
324+ }
294325
295326pub fn builtin_print ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
296327 trace ! ( "print called with {:?}" , args) ;
@@ -386,6 +417,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
386417 dict. insert ( String :: from ( "list" ) , ctx. list_type ( ) ) ;
387418 dict. insert ( String :: from ( "locals" ) , ctx. new_rustfunc ( builtin_locals) ) ;
388419 dict. insert ( String :: from ( "next" ) , ctx. new_rustfunc ( builtin_next) ) ;
420+ dict. insert ( String :: from ( "pow" ) , ctx. new_rustfunc ( builtin_pow) ) ;
389421 dict. insert ( String :: from ( "print" ) , ctx. new_rustfunc ( builtin_print) ) ;
390422 dict. insert ( String :: from ( "range" ) , ctx. new_rustfunc ( builtin_range) ) ;
391423 dict. insert ( String :: from ( "repr" ) , ctx. new_rustfunc ( builtin_repr) ) ;
0 commit comments