1- use crate :: ast:: { Expression , Program , Statement } ;
1+ use crate :: ast:: { CallExpression , Expression , Program , Statement } ;
22use crate :: token:: Token ;
33use std:: collections:: HashMap ;
44use std:: fmt;
@@ -234,38 +234,7 @@ impl Interpreter {
234234 Expression :: Call ( expression) => {
235235 self . environment . create_scope ( ) ;
236236
237- let ( parameters, function_body) = match * expression. function {
238- Expression :: Function ( function) => ( function. parameters , function. body ) ,
239- Expression :: Identifier ( identifier) => match self . environment . get_binding ( & identifier) {
240- Some ( Object :: Function ( function) ) => {
241- ( function. parameters . clone ( ) , function. body . clone ( ) )
242- }
243- _ => return Err ( format ! ( "identifier not found: {}" , identifier) ) ,
244- } ,
245- _ => unreachable ! ( ) ,
246- } ;
247-
248- if expression. arguments . len ( ) != parameters. len ( ) {
249- return Err ( format ! (
250- "expected {} arguments, got {}" ,
251- parameters. len( ) ,
252- expression. arguments. len( ) ,
253- ) ) ;
254- }
255-
256- let mut arguments = Vec :: new ( ) ;
257-
258- for argument in expression. arguments {
259- arguments. push ( self . eval_expression ( argument) ?) ;
260- }
261-
262- for ( parameter, argument) in parameters. iter ( ) . zip ( arguments. iter ( ) ) {
263- self
264- . environment
265- . set_binding ( parameter. clone ( ) , argument. clone ( ) ) ?;
266- }
267-
268- let return_value = self . eval_statements ( function_body) ?;
237+ let return_value = self . evaluate_function_call ( expression) ?;
269238
270239 self . environment . destroy_current_scope ( ) ;
271240
@@ -275,6 +244,42 @@ impl Interpreter {
275244 }
276245 }
277246
247+ fn evaluate_function_call (
248+ & mut self ,
249+ expression : CallExpression ,
250+ ) -> Result < Object , InterpreterError > {
251+ let ( parameters, function_body) = match * expression. function {
252+ Expression :: Function ( function) => ( function. parameters , function. body ) ,
253+ Expression :: Identifier ( identifier) => match self . environment . get_binding ( & identifier) {
254+ Some ( Object :: Function ( function) ) => ( function. parameters . clone ( ) , function. body . clone ( ) ) ,
255+ _ => return Err ( format ! ( "identifier not found: {}" , identifier) ) ,
256+ } ,
257+ expression => return Err ( format ! ( "expression is not a function: {}" , expression) ) ,
258+ } ;
259+
260+ if expression. arguments . len ( ) != parameters. len ( ) {
261+ return Err ( format ! (
262+ "expected {} arguments, got {}" ,
263+ parameters. len( ) ,
264+ expression. arguments. len( ) ,
265+ ) ) ;
266+ }
267+
268+ let mut arguments = Vec :: new ( ) ;
269+
270+ for argument in expression. arguments {
271+ arguments. push ( self . eval_expression ( argument) ?) ;
272+ }
273+
274+ for ( parameter, argument) in parameters. iter ( ) . zip ( arguments. iter ( ) ) {
275+ self
276+ . environment
277+ . set_binding ( parameter. clone ( ) , argument. clone ( ) ) ?;
278+ }
279+
280+ Ok ( self . eval_statements ( function_body) ?)
281+ }
282+
278283 fn to_boolean ( & self , object : & Object ) -> Object {
279284 match object {
280285 Object :: Boolean ( boolean) => Object :: Boolean ( * boolean) ,
@@ -467,19 +472,14 @@ mod tests {
467472 ( "false / true" , "unexpected infix expression: false / true" ) ,
468473 ( "true / true" , "unexpected infix expression: true / true" ) ,
469474 ( "true / false" , "unexpected infix expression: true / false" ) ,
470- (
471- "false |> false" ,
472- "unexpected infix expression: false |> false" ,
473- ) ,
474- (
475- "false |> true" ,
476- "unexpected infix expression: false |> true" ,
477- ) ,
478- ( "true |> true" , "unexpected infix expression: true |> true" ) ,
479- (
480- "true |> false" ,
481- "unexpected infix expression: true |> false" ,
482- ) ,
475+ ( "false |> false" , "expression is not a function: false" ) ,
476+ ( "false |> true" , "expression is not a function: true" ) ,
477+ ( "true |> true" , "expression is not a function: true" ) ,
478+ ( "true |> false" , "expression is not a function: false" ) ,
479+ ( "true |> 10" , "expression is not a function: 10" ) ,
480+ ( "true |> 32" , "expression is not a function: 32" ) ,
481+ ( "true |> -1" , "expression is not a function: (- 1)" ) ,
482+ ( "10 |> 0" , "expression is not a function: 0" ) ,
483483 ] ;
484484
485485 for ( input, expected) in test_cases {
@@ -666,6 +666,13 @@ mod tests {
666666 Object :: Number ( 120.0 ) ,
667667 ) ,
668668 ( "fn(x) { x }(3)" , Object :: Number ( 3.0 ) ) ,
669+ (
670+ "
671+ let double = fn(x) { x * 2 }
672+ 2 |> double |> double
673+ " ,
674+ Object :: Number ( 8.0 ) ,
675+ ) ,
669676 ] ;
670677
671678 for ( input, expected) in test_cases {
0 commit comments