@@ -56,25 +56,7 @@ impl fmt::Display for Object {
5656 object. fmt ( f)
5757 }
5858 Object :: Identifier ( identifier) => write ! ( f, "{}" , identifier) ,
59- Object :: Function ( function) => {
60- write ! ( f, "(fn(" ) ?;
61-
62- for ( index, parameter) in function. parameters . iter ( ) . enumerate ( ) {
63- if index > 0 {
64- write ! ( f, ", {}" , parameter) ?;
65- } else {
66- write ! ( f, "{}" , parameter) ?;
67- }
68- }
69-
70- write ! ( f, ") " ) ?;
71-
72- for statement in & function. body {
73- statement. fmt ( f) ?;
74- }
75-
76- write ! ( f, ")" )
77- }
59+ Object :: Function ( _) => write ! ( f, "function" ) ,
7860 Object :: Array ( objects) => {
7961 write ! ( f, "[" ) ?;
8062
@@ -331,6 +313,37 @@ impl Interpreter {
331313
332314 Ok ( Object :: Array ( objects) )
333315 }
316+ Expression :: Access ( expression) => match expression. object {
317+ Expression :: Array ( _) => {
318+ let array = self . eval_expression ( expression. object ) ?;
319+
320+ let index = self . eval_expression ( expression. key ) ?;
321+
322+ match ( array, index) {
323+ ( Object :: Array ( objects) , Object :: Number ( index) ) => {
324+ if index. fract ( ) != 0.0 {
325+ return Err ( format ! ( "expected integer, got {}" , index) ) ;
326+ }
327+
328+ let rounded_index = index. round ( ) as i64 ;
329+
330+ if rounded_index < 0 {
331+ return Ok ( Object :: Null ) ;
332+ }
333+
334+ let value = match objects. get ( rounded_index as usize ) {
335+ Some ( object) => object. clone ( ) ,
336+ None => Object :: Null ,
337+ } ;
338+
339+ Ok ( value)
340+ }
341+ ( Object :: Array ( _) , object) => Err ( format ! ( "expected integer, got {}" , object) ) ,
342+ _ => unreachable ! ( ) ,
343+ }
344+ }
345+ _ => unreachable ! ( ) ,
346+ } ,
334347 }
335348 }
336349
@@ -820,10 +833,7 @@ mod tests {
820833 r#"len("hello", "world")"# ,
821834 "len() expected one argument, got 2" ,
822835 ) ,
823- (
824- "len(fn(x){ x + 2})" ,
825- "len() can't be used on (fn(x) (x + 2))" ,
826- ) ,
836+ ( "len(fn(x){ x + 2})" , "len() can't be used on function" ) ,
827837 ( "len(x)" , "identifier not found: x" ) ,
828838 ] ;
829839
@@ -868,6 +878,27 @@ mod tests {
868878 ) ,
869879 ] ;
870880
881+ for ( input, expected) in test_cases {
882+ let mut parser = Parser :: new ( Lexer :: new ( String :: from ( input) ) . lex ( ) . unwrap ( ) ) ;
883+
884+ let program = parser. parse ( ) ;
885+
886+ let mut interpreter = Interpreter :: new ( ) ;
887+
888+ assert_eq ! ( interpreter. evaluate( program) . unwrap( ) , expected) ;
889+ }
890+ }
891+
892+ #[ test]
893+ fn evaluate_array_access_expression ( ) {
894+ let test_cases: Vec < ( & str , Object ) > = vec ! [
895+ ( "[1, 2, 3][0]" , Object :: Number ( 1.0 ) ) ,
896+ ( "[1, 2, 3][3]" , Object :: Null ) ,
897+ ( "[1, 2, 3][-1]" , Object :: Null ) ,
898+ ( "[1, 2, 3][3]" , Object :: Null ) ,
899+ ( "[1, 2, 3][2]" , Object :: Number ( 3.0 ) ) ,
900+ ] ;
901+
871902 for ( input, expected) in test_cases {
872903 let mut parser = Parser :: new ( Lexer :: new ( String :: from ( input) ) . lex ( ) . unwrap ( ) ) ;
873904
@@ -877,4 +908,23 @@ mod tests {
877908 assert_eq ! ( interpreter. evaluate( program) . unwrap( ) , expected) ;
878909 }
879910 }
911+
912+ #[ test]
913+ fn evaluate_array_access_expression_errors ( ) {
914+ let test_cases: Vec < ( & str , & str ) > = vec ! [
915+ ( "[1, 2, 3][[]]" , "expected integer, got []" ) ,
916+ ( "[1, 2, 3][fn(x){}]" , "expected integer, got function" ) ,
917+ ( r#"[1, 2, 3]["1"]"# , "expected integer, got 1" ) ,
918+ ( "[1, 2, 3][2.5]" , "expected integer, got 2.5" ) ,
919+ ] ;
920+
921+ for ( input, expected) in test_cases {
922+ let mut parser = Parser :: new ( Lexer :: new ( String :: from ( input) ) . lex ( ) . unwrap ( ) ) ;
923+
924+ let program = parser. parse ( ) ;
925+ let mut interpreter = Interpreter :: new ( ) ;
926+
927+ assert_eq ! ( interpreter. evaluate( program) , Err ( String :: from( expected) ) ) ;
928+ }
929+ }
880930}
0 commit comments