@@ -142,6 +142,7 @@ impl VirtualMachine {
142142 //TODO: move this into the __builtin__ module when we have a module type
143143 let mut locals = callargs;
144144 locals. insert ( "print" . to_string ( ) , NativeType :: NativeFunction ( builtins:: print) ) ;
145+ locals. insert ( "len" . to_string ( ) , NativeType :: NativeFunction ( builtins:: len) ) ;
145146 Frame {
146147 code : code,
147148 stack : vec ! [ ] ,
@@ -233,7 +234,12 @@ impl VirtualMachine {
233234 ( "LOAD_NAME" , Some ( namei) ) => {
234235 // println!("Loading const at index: {}", consti);
235236 let curr_frame = self . curr_frame ( ) ;
236- curr_frame. stack . push ( curr_frame. locals . get :: < str > ( & curr_frame. code . co_names [ namei] ) . unwrap ( ) . clone ( ) ) ;
237+ if let Some ( code) = curr_frame. locals . get :: < str > ( & curr_frame. code . co_names [ namei] ) {
238+ curr_frame. stack . push ( code. clone ( ) ) ;
239+ }
240+ else {
241+ panic ! ( "Can't find symbol {:?} in the current frame" , & curr_frame. code. co_names[ namei] ) ;
242+ }
237243 None
238244 } ,
239245 ( "LOAD_GLOBAL" , Some ( namei) ) => {
@@ -503,14 +509,10 @@ impl VirtualMachine {
503509 let curr_frame = self . curr_frame ( ) ;
504510 let tos = curr_frame. stack . pop ( ) . unwrap ( ) ;
505511 let tos1 = curr_frame. stack . pop ( ) . unwrap ( ) ;
506- if let ( NativeType :: List ( v) , NativeType :: Int ( idx) ) = ( tos1, tos) {
507- if idx as usize >= v. len ( ) {
508- // TODO: change this to a exception
509- panic ! ( "IndexError: list index out of range" ) ;
510- }
511- curr_frame. stack . push ( v[ idx as usize ] . clone ( ) ) ;
512- } else {
513- panic ! ( "TypeError in BINARY_SUBSTRACT" ) ;
512+ match ( & tos1, & tos) {
513+ ( & NativeType :: List ( ref l) , & NativeType :: Int ( ref index) ) => curr_frame. stack . push ( l[ * index as usize ] . clone ( ) ) ,
514+ ( & NativeType :: Tuple ( ref t) , & NativeType :: Int ( ref index) ) => curr_frame. stack . push ( t[ * index as usize ] . clone ( ) ) ,
515+ _ => panic ! ( "TypeError: indexing type {:?} with index {:?} is not supported" , tos1, tos)
514516 } ;
515517 None
516518 } ,
@@ -608,7 +610,8 @@ impl VirtualMachine {
608610 } ,
609611 NativeType :: NativeFunction ( func) => {
610612 pos_args. reverse ( ) ;
611- func ( pos_args) ;
613+ let return_value = func ( pos_args) ;
614+ self . curr_frame ( ) . stack . push ( return_value) ;
612615 } ,
613616 _ => panic ! ( "The item on the stack should be a code object" )
614617 }
@@ -743,13 +746,17 @@ fn main() {
743746 let mut s = String :: new ( ) ;
744747 f. read_to_string ( & mut s) . unwrap ( ) ;
745748 // println!("Read string");
746- let code: PyCodeObject = serde_json:: from_str ( & s) . unwrap ( ) ;
749+ let code: PyCodeObject = match serde_json:: from_str ( & s) {
750+ Ok ( c) => c,
751+ Err ( _) => panic ! ( "Fail to parse the bytecode" )
752+ } ;
747753
748754 let mut vm = VirtualMachine :: new ( ) ;
749755 vm. run_code ( code) ;
750756 // println!("Done");
751757}
752758
759+ /*
753760#[test]
754761fn test_parse_native_type() {
755762
@@ -853,3 +860,10 @@ let input = "{\"co_consts\":[{\"Int\":1},\"NoneType\",{\"Int\":2}],\"co_names\":
853860 let deserialized: PyCodeObject = serde_json::from_str(&input).unwrap();
854861 assert_eq!(expected, deserialized)
855862}
863+ */
864+
865+ #[ test]
866+ fn test_tuple_serialization ( ) {
867+ let tuple = NativeType :: Tuple ( vec ! [ NativeType :: Int ( 1 ) , NativeType :: Int ( 2 ) ] ) ;
868+ println ! ( "{}" , serde_json:: to_string( & tuple) . unwrap( ) ) ;
869+ }
0 commit comments