1use std::cell::RefCell;
2use std::collections::HashMap;
3use std::rc::Rc;
4
5use object::builtins::*;
6use object::environment::*;
7use object::{EvalError, Object};
8use parser::ast::*;
9use parser::lexer::token::{Token, TokenKind};
10
11mod interpreter_test;
12
13pub fn eval(node: Node, env: &Env) -> Result<Rc<Object>, EvalError> {
14 match node {
15 Node::Program(p) => eval_block_statements(&p.body, env),
16 Node::Statement(statements) => eval_statement(&statements, env),
17 Node::Expression(expression) => eval_expression(&expression, env),
18 }
19}
20
21fn eval_block_statements(statements: &Vec<Statement>, env: &Env) -> Result<Rc<Object>, EvalError> {
22 let mut result = Rc::new(Object::Null);
23 for statement in statements {
24 let val = eval_statement(statement, &Rc::clone(env))?;
25 match *val {
26 Object::ReturnValue(_) => return Ok(val),
27 _ => {
28 result = val;
29 }
30 }
31 }
32
33 return Ok(result);
34}
35
36fn eval_statement(statement: &Statement, env: &Env) -> Result<Rc<Object>, EvalError> {
37 match statement {
38 Statement::Expr(expr) => eval_expression(expr, env),
39 Statement::Return(ReturnStatement {
40 argument,
41 ..
42 }) => {
43 let val = eval_expression(argument, env)?;
44 return Ok(Rc::new(Object::ReturnValue(val)));
45 }
46 Statement::Let(Let {
47 identifier: id,
48 expr,
49 ..
50 }) => {
51 let val = eval_expression(expr, &Rc::clone(env))?;
52 let obj: Rc<Object> = Rc::clone(&val);
53 if let TokenKind::IDENTIFIER {
54 name,
55 } = &id.kind
56 {
57 env.borrow_mut().set(name.clone(), obj);
58 }
59 return Ok(Rc::new(Object::Null));
60 }
61 }
62}
63
64fn is_truthy(obj: &Object) -> bool {
65 match obj {
66 Object::Null => return false,
67 Object::Boolean(false) => return false,
68 _ => true,
69 }
70}
71
72fn eval_expression(expression: &Expression, env: &Env) -> Result<Rc<Object>, EvalError> {
73 match expression {
74 Expression::LITERAL(literal) => eval_literal(literal, env),
75 Expression::PREFIX(UnaryExpression {
76 op,
77 operand: expr,
78 ..
79 }) => {
80 let right = eval_expression(expr, &Rc::clone(env))?;
81 return eval_prefix(op, &right);
82 }
83 Expression::INFIX(BinaryExpression {
84 op,
85 left,
86 right,
87 ..
88 }) => {
89 let left = eval_expression(left, &Rc::clone(env))?;
90 let right = eval_expression(right, &Rc::clone(env))?;
91 return eval_infix(op, &left, &right);
92 }
93 Expression::IF(IF {
94 condition,
95 consequent,
96 alternate,
97 ..
98 }) => {
99 let condition = eval_expression(condition, &Rc::clone(env))?;
100 if is_truthy(&condition) {
101 eval_block_statements(&(consequent.body), env)
102 } else {
103 match alternate {
104 Some(alt) => eval_block_statements(&(alt.body), env),
105 None => Ok(Rc::new(Object::Null)),
106 }
107 }
108 }
109 Expression::IDENTIFIER(IDENTIFIER {
110 name: id,
111 ..
112 }) => eval_identifier(&id, env),
113 Expression::FUNCTION(FunctionDeclaration {
114 params,
115 body,
116 ..
117 }) => {
118 return Ok(Rc::new(Object::Function(params.clone(), body.clone(), Rc::clone(env))));
119 }
120 Expression::FunctionCall(FunctionCall {
121 callee,
122 arguments,
123 ..
124 }) => {
125 let func = eval_expression(callee, &Rc::clone(env))?;
126 let args = eval_expressions(arguments, env)?;
127 apply_function(&func, &args)
128 }
129 Expression::Index(Index {
130 object: left,
131 index,
132 ..
133 }) => {
134 let literal = eval_expression(left, &Rc::clone(env))?;
135 let index = eval_expression(index, env)?;
136 eval_index_expression(&literal, &index)
137 }
138 }
139}
140
141fn eval_index_expression(left: &Rc<Object>, index: &Rc<Object>) -> Result<Rc<Object>, EvalError> {
142 match (&**left, &**index) {
143 (Object::Array(arr), Object::Integer(idx)) => match arr.get(*idx as usize) {
144 Some(obj) => return Ok(Rc::clone(obj)),
145 None => return Ok(Rc::new(Object::Null)),
146 },
147 (Object::Hash(map), key) => {
148 if !(key.is_hashable()) {
149 return Err(format!("not a valid hash key"));
150 }
151
152 match map.get(key) {
153 Some(obj) => return Ok(Rc::clone(obj)),
154 None => return Ok(Rc::new(Object::Null)),
155 }
156 }
157 _ => return Err(format!("index operator not supported for {}", left)),
158 }
159}
160
161fn apply_function(function: &Rc<Object>, args: &Vec<Rc<Object>>) -> Result<Rc<Object>, EvalError> {
162 match &**function {
163 Object::Function(params, body, env) => {
164 let mut env = Environment::new_enclosed_environment(&env);
165
166 params.iter().enumerate().for_each(|(i, param)| {
167 env.set(param.name.clone(), args[i].clone());
168 });
169
170 let evaluated = eval_block_statements(&body.body, &Rc::new(RefCell::new(env)))?;
171 return unwrap_return(evaluated);
172 }
173 Object::Builtin(b) => Ok(b(args.to_vec())),
174 f => Err(format!("expected {} to be a function", f)),
175 }
176}
177
178fn unwrap_return(obj: Rc<Object>) -> Result<Rc<Object>, EvalError> {
179 if let Object::ReturnValue(val) = &*obj {
180 Ok(Rc::clone(&val))
181 } else {
182 Ok(obj)
183 }
184}
185
186fn eval_expressions(exprs: &Vec<Expression>, env: &Env) -> Result<Vec<Rc<Object>>, EvalError> {
187 let mut list = Vec::new();
188 for expr in exprs {
189 let val = eval_expression(expr, &Rc::clone(env))?;
190 list.push(val);
191 }
192
193 Ok(list)
194}
195
196fn eval_identifier(identifier: &str, env: &Env) -> Result<Rc<Object>, EvalError> {
197 match env.borrow().get(identifier) {
198 Some(obj) => Ok(obj.clone()),
199 None => match BuiltIns.iter().find(|&&b| b.0 == identifier) {
200 Some(obj) => Ok(Rc::new(Object::Builtin(obj.1))),
201 None => Err(format!("unknown identifier {}", identifier)),
202 },
203 }
204}
205
206fn eval_prefix(op: &Token, right: &Object) -> Result<Rc<Object>, EvalError> {
207 match op.kind {
208 TokenKind::BANG => eval_prefix_bang(right),
209 TokenKind::MINUS => eval_prefix_minus(right),
210 _ => Err(format!("unknown prefix operator: {}", op)),
211 }
212}
213
214fn eval_prefix_bang(expr: &Object) -> Result<Rc<Object>, EvalError> {
215 match *expr {
216 Object::Null => Ok(Rc::new(Object::Boolean(true))),
217 Object::Boolean(b) => Ok(Rc::new(Object::Boolean(!b))),
218 _ => Ok(Rc::new(Object::Boolean(false))),
219 }
220}
221
222fn eval_prefix_minus(expr: &Object) -> Result<Rc<Object>, EvalError> {
223 match *expr {
224 Object::Integer(i) => Ok(Rc::from(Object::Integer(-i))),
225 _ => Err(format!("can't apply prefix minus operator: {}", expr)),
226 }
227}
228
229fn eval_infix(op: &Token, left: &Object, right: &Object) -> Result<Rc<Object>, EvalError> {
230 match (left, right) {
231 (Object::Integer(left), Object::Integer(right)) => {
232 return eval_integer_infix(op, *left, *right);
233 }
234 (Object::Boolean(left), Object::Boolean(right)) => {
235 return eval_boolean_infix(op, *left, *right);
236 }
237 (Object::String(left), Object::String(right)) => {
238 return eval_string_infix(op, left.to_string(), right.to_string());
239 }
240 _ => Err(format!("eval infix error for op: {}, left: {}, right: {}", op, left, right)),
241 }
242}
243
244fn eval_integer_infix(op: &Token, left: i64, right: i64) -> Result<Rc<Object>, EvalError> {
245 let result = match &op.kind {
246 TokenKind::PLUS => Object::Integer(left + right),
247 TokenKind::MINUS => Object::Integer(left - right),
248 TokenKind::ASTERISK => Object::Integer(left * right),
249 TokenKind::SLASH => Object::Integer(left / right),
250 TokenKind::LT => Object::Boolean(left < right),
251 TokenKind::GT => Object::Boolean(left > right),
252 TokenKind::EQ => Object::Boolean(left == right),
253 TokenKind::NotEq => Object::Boolean(left != right),
254 op => return Err(format!("Invalid infix operator {} for int", op)),
255 };
256
257 Ok(Rc::from(result))
258}
259
260fn eval_boolean_infix(op: &Token, left: bool, right: bool) -> Result<Rc<Object>, EvalError> {
261 let result = match &op.kind {
262 TokenKind::EQ => Object::Boolean(left == right),
263 TokenKind::NotEq => Object::Boolean(left != right),
264 op => return Err(format!("Invalid infix operator for boolean: {}", op)),
265 };
266
267 Ok(Rc::from(result))
268}
269
270fn eval_string_infix(op: &Token, left: String, right: String) -> Result<Rc<Object>, EvalError> {
271 let result = match &op.kind {
272 TokenKind::EQ => Object::Boolean(left == right),
273 TokenKind::NotEq => Object::Boolean(left != right),
274 TokenKind::PLUS => Object::String(format!("{}{}", left, right)),
275 op => return Err(format!("Invalid infix {} operator for string", op)),
276 };
277
278 Ok(Rc::from(result))
279}
280
281fn eval_literal(literal: &Literal, env: &Env) -> Result<Rc<Object>, EvalError> {
282 match literal {
283 Literal::Integer(Integer {
284 raw: i,
285 ..
286 }) => Ok(Rc::from(Object::Integer(*i))),
287 Literal::Boolean(Boolean {
288 raw: b,
289 ..
290 }) => Ok(Rc::from(Object::Boolean(*b))),
291 Literal::String(StringType {
292 raw: s,
293 ..
294 }) => Ok(Rc::from(Object::String(s.clone()))),
295 Literal::Array(Array {
296 elements,
297 ..
298 }) => {
299 let list = eval_expressions(elements, env)?;
300 return Ok(Rc::from(Object::Array(list)));
301 }
302 Literal::Hash(Hash {
303 elements: map,
304 ..
305 }) => {
306 let mut hash_map = HashMap::new();
307
308 for (k, v) in map {
309 let key = eval_expression(k, env)?;
310 if !key.is_hashable() {
311 return Err(format!("key {} is not hashable", key));
312 }
313 let value = eval_expression(v, env)?;
314 hash_map.insert(key, value);
315 }
316
317 return Ok(Rc::new(Object::Hash(hash_map)));
318 } }
320}