1use std::fmt::{Debug, Display};
2use std::cell::RefCell;
3use std::rc::Rc;
4
5use crate::environment::Environment;
6use crate::interpreter::Interpreter;
7use crate::object::{Object, Callable};
8use crate::error::{RuntimeError, ReturnType};
9use crate::stmt::Stmt;
10use crate::token::Token;
11use crate::literal::Literal;
12
13#[derive(Debug, Clone)]
17pub struct Function {
18 pub name: Token,
19 params: Vec<Token>,
20 body: Vec<Stmt>,
21 closure: Rc<RefCell<Environment>>,
22 is_initializer: bool,
23}
24
25impl Function {
26 pub fn new(stmt: Stmt, closure: Rc<RefCell<Environment>>, is_initializer: bool) -> Self {
28 if let Stmt::Function(data) = stmt {
29 Function {
30 name: data.name,
31 params: data.params,
32 body: data.body,
33 closure,
34 is_initializer,
35 }
36 } else {
37 unreachable!("Expected function statement")
38 }
39 }
40
41 pub fn bind(&mut self, instance: Object) -> Self {
44 let mut environment = Environment::new(Some(Rc::clone(&self.closure)));
45 environment.define("this", instance);
46
47 Function {
48 name: self.name.clone(),
49 params: self.params.clone(),
50 body: self.body.clone(),
51 closure: Rc::new(RefCell::new(environment)),
52 is_initializer: self.is_initializer,
53 }
54 }
55}
56
57impl Callable for Function {
58 fn call(&self, interpreter: &mut Interpreter, arguments: Vec<Object>) -> Result<Object, RuntimeError> {
64 let environment = Rc::new(RefCell::new(
65 Environment::new(Some(Rc::clone(&self.closure)))
66 ));
67
68 self.params.iter().zip(arguments.iter()).for_each(|(param, arg)| {
69 environment.borrow_mut().define(¶m.lexeme, arg.to_owned());
70 });
71
72 match interpreter.execute_block(&self.body, environment) {
73 Ok(_) => {
74 if self.is_initializer {
75 return self.closure.borrow().get_at(0, &Token::from("this"));
76 }
77
78 Ok(Object::from(Literal::Null))
79 },
80 Err(err) => {
81 if self.is_initializer {
82 return self.closure.borrow().get_at(0, &Token::from("this"));
83 }
84
85 match err {
86 ReturnType::Return(err) => {
87 return Ok(err.value);
88 },
89 ReturnType::Error(err) => {
90 return Err(err);
91 },
92 ReturnType::Break(_) => {
93 unreachable!("function calls should not return break");
94 }
95 }
96 },
97 }
98 }
99
100 fn arity(&self) -> usize {
101 self.params.len()
102 }
103}
104
105impl Display for Function {
106 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107 write!(f, "<function {}>", self.name.lexeme)
108 }
109}
110
111impl PartialEq for Function {
112 fn eq(&self, other: &Self) -> bool {
113 return self.name == other.name;
114 }
115}
116
117#[derive(Clone)]
131pub struct NativeFunction {
132 pub name: Token,
133 function: fn(&mut Interpreter, Vec<Object>) -> Result<Object, RuntimeError>,
134}
135
136impl Callable for NativeFunction {
137 fn call(&self, interpreter: &mut Interpreter, arguments: Vec<Object>) -> Result<Object, RuntimeError> {
139 (self.function)(interpreter, arguments)
140 }
141
142 fn arity(&self) -> usize {
143 0
144 }
145}
146
147impl NativeFunction {
148 pub fn get_globals() -> Vec<NativeFunction> {
150 vec![
151 NativeFunction {
152 name: Token::from("clock"),
153 function: |_, _| {
154 let now = std::time::SystemTime::now()
155 .duration_since(std::time::UNIX_EPOCH)
156 .unwrap()
157 .as_millis();
158 Ok(Object::from(now as f64))
159 },
160 },
161 NativeFunction {
162 name: Token::from("input"),
163 function: |_, _| {
164 let mut input = String::new();
165 std::io::stdin().read_line(&mut input).unwrap();
166 input.pop(); Ok(Object::from(input))
168 },
169 },
170 ]
171 }
172}
173
174impl Display for NativeFunction {
175 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
176 write!(f, "<native function {}>", self.name.lexeme)
177 }
178}
179
180impl Debug for NativeFunction {
181 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
182 write!(f, "<native function {}>", self.name.lexeme)
183 }
184}
185
186impl PartialEq for NativeFunction {
187 fn eq(&self, other: &Self) -> bool {
188 return self.name == other.name;
189 }
190}