Interpreter - Call implementation

This commit is contained in:
Emmanuel BENOîT 2023-01-02 17:45:56 +01:00
parent 8ab144f3c5
commit d47adab0f8

View file

@ -122,6 +122,7 @@ impl ast::StmtNode {
Value::Boolean(false) => String::from("false"), Value::Boolean(false) => String::from("false"),
Value::Number(n) => n.to_string(), Value::Number(n) => n.to_string(),
Value::String(s) => s, Value::String(s) => s,
Value::Callable(c) => c.borrow().to_string(),
}; };
println!("{}", output); println!("{}", output);
Ok(InterpreterFlowControl::default()) Ok(InterpreterFlowControl::default())
@ -243,6 +244,11 @@ impl Interpretable for ast::ExprNode {
ast::ExprNode::Grouping { expression } => expression.interprete(environment), ast::ExprNode::Grouping { expression } => expression.interprete(environment),
ast::ExprNode::Litteral { value } => self.on_litteral(value), ast::ExprNode::Litteral { value } => self.on_litteral(value),
ast::ExprNode::Variable { name } => Ok(environment.borrow().get(name)?.into()), ast::ExprNode::Variable { name } => Ok(environment.borrow().get(name)?.into()),
ast::ExprNode::Call {
callee,
right_paren,
arguments,
} => self.on_call(environment, callee, right_paren, arguments),
} }
} }
} }
@ -375,4 +381,30 @@ impl ast::ExprNode {
}; };
Ok(out_value.into()) Ok(out_value.into())
} }
/// Evaluate a function call.
fn on_call(
&self,
environment: &EnvironmentRef,
callee: &ast::ExprNode,
right_paren: &Token,
arguments: &Vec<ast::ExprNode>,
) -> InterpreterResult {
let callee = callee.interprete(environment)?.result();
let arg_values = {
let mut v = Vec::with_capacity(arguments.len());
for argument in arguments.iter() {
v.push(argument.interprete(environment)?.result());
}
v
};
if let Value::Callable(callable) = &callee {
Ok(callable.borrow().call(environment, arg_values)?.into())
} else {
Err(InterpreterError::new(
right_paren,
"can only call functions and classes",
))
}
}
} }