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 { argument, .. }) => {
40 let val = eval_expression(argument, env)?;
41 return Ok(Rc::new(Object::ReturnValue(val)));
42 }
43 Statement::Let(Let { identifier: id, expr, .. }) => {
44 let val = eval_expression(expr, &Rc::clone(env))?;
45 let obj: Rc<Object> = Rc::clone(&val);
46 if let TokenKind::IDENTIFIER { name } = &id.kind {
47 env.borrow_mut().set(name.clone(), obj);
48 }
49 return Ok(Rc::new(Object::Null));
50 }
51 }
52}
53
54fn is_truthy(obj: &Object) -> bool {
55 match obj {
56 Object::Null => return false,
57 Object::Boolean(false) => return false,
58 _ => true,
59 }
60}
61
62fn eval_expression(expression: &Expression, env: &Env) -> Result<Rc<Object>, EvalError> {
63 match expression {
64 Expression::LITERAL(literal) => eval_literal(literal, env),
65 Expression::PREFIX(UnaryExpression { op, operand: expr, .. }) => {
66 let right = eval_expression(expr, &Rc::clone(env))?;
67 return eval_prefix(op, &right);
68 }
69 Expression::INFIX(BinaryExpression { op, left, right, .. }) => {
70 let left = eval_expression(left, &Rc::clone(env))?;
71 let right = eval_expression(right, &Rc::clone(env))?;
72 return eval_infix(op, &left, &right);
73 }
74 Expression::IF(IF { condition, consequent, alternate, .. }) => {
75 let condition = eval_expression(condition, &Rc::clone(env))?;
76 if is_truthy(&condition) {
77 eval_block_statements(&(consequent.body), env)
78 } else {
79 match alternate {
80 Some(alt) => eval_block_statements(&(alt.body), env),
81 None => Ok(Rc::new(Object::Null)),
82 }
83 }
84 }
85 Expression::IDENTIFIER(IDENTIFIER { name: id, .. }) => eval_identifier(&id, env),
86 Expression::FUNCTION(FunctionDeclaration { params, body, .. }) => {
87 return Ok(Rc::new(Object::Function(params.clone(), body.clone(), Rc::clone(env))));
88 }
89 Expression::FunctionCall(FunctionCall { callee, arguments, .. }) => {
90 let func = eval_expression(callee, &Rc::clone(env))?;
91 let args = eval_expressions(arguments, env)?;
92 apply_function(&func, &args)
93 }
94 Expression::Index(Index { object: left, index, .. }) => {
95 let literal = eval_expression(left, &Rc::clone(env))?;
96 let index = eval_expression(index, env)?;
97 eval_index_expression(&literal, &index)
98 }
99 }
100}
101
102fn eval_index_expression(left: &Rc<Object>, index: &Rc<Object>) -> Result<Rc<Object>, EvalError> {
103 match (&**left, &**index) {
104 (Object::Array(arr), Object::Integer(idx)) => match arr.get(*idx as usize) {
105 Some(obj) => return Ok(Rc::clone(obj)),
106 None => return Ok(Rc::new(Object::Null)),
107 },
108 (Object::Hash(map), key) => {
109 if !(key.is_hashable()) {
110 return Err(format!("not a valid hash key"));
111 }
112
113 match map.get(key) {
114 Some(obj) => return Ok(Rc::clone(obj)),
115 None => return Ok(Rc::new(Object::Null)),
116 }
117 }
118 _ => return Err(format!("index operator not supported for {}", left)),
119 }
120}
121
122fn apply_function(function: &Rc<Object>, args: &Vec<Rc<Object>>) -> Result<Rc<Object>, EvalError> {
123 match &**function {
124 Object::Function(params, body, env) => {
125 let mut env = Environment::new_enclosed_environment(&env);
126
127 params.iter().enumerate().for_each(|(i, param)| {
128 env.set(param.name.clone(), args[i].clone());
129 });
130
131 let evaluated = eval_block_statements(&body.body, &Rc::new(RefCell::new(env)))?;
132 return unwrap_return(evaluated);
133 }
134 Object::Builtin(b) => Ok(b(args.to_vec())),
135 f => Err(format!("expected {} to be a function", f)),
136 }
137}
138
139fn unwrap_return(obj: Rc<Object>) -> Result<Rc<Object>, EvalError> {
140 if let Object::ReturnValue(val) = &*obj {
141 Ok(Rc::clone(&val))
142 } else {
143 Ok(obj)
144 }
145}
146
147fn eval_expressions(exprs: &Vec<Expression>, env: &Env) -> Result<Vec<Rc<Object>>, EvalError> {
148 let mut list = Vec::new();
149 for expr in exprs {
150 let val = eval_expression(expr, &Rc::clone(env))?;
151 list.push(val);
152 }
153
154 Ok(list)
155}
156
157fn eval_identifier(identifier: &str, env: &Env) -> Result<Rc<Object>, EvalError> {
158 match env.borrow().get(identifier) {
159 Some(obj) => Ok(obj.clone()),
160 None => match BuiltIns.iter().find(|&&b| b.0 == identifier) {
161 Some(obj) => Ok(Rc::new(Object::Builtin(obj.1))),
162 None => Err(format!("unknown identifier {}", identifier)),
163 },
164 }
165}
166
167fn eval_prefix(op: &Token, right: &Object) -> Result<Rc<Object>, EvalError> {
168 match op.kind {
169 TokenKind::BANG => eval_prefix_bang(right),
170 TokenKind::MINUS => eval_prefix_minus(right),
171 _ => Err(format!("unknown prefix operator: {}", op)),
172 }
173}
174
175fn eval_prefix_bang(expr: &Object) -> Result<Rc<Object>, EvalError> {
176 match *expr {
177 Object::Null => Ok(Rc::new(Object::Boolean(true))),
178 Object::Boolean(b) => Ok(Rc::new(Object::Boolean(!b))),
179 _ => Ok(Rc::new(Object::Boolean(false))),
180 }
181}
182
183fn eval_prefix_minus(expr: &Object) -> Result<Rc<Object>, EvalError> {
184 match *expr {
185 Object::Integer(i) => Ok(Rc::from(Object::Integer(-i))),
186 _ => Err(format!("can't apply prefix minus operator: {}", expr)),
187 }
188}
189
190fn eval_infix(op: &Token, left: &Object, right: &Object) -> Result<Rc<Object>, EvalError> {
191 match (left, right) {
192 (Object::Integer(left), Object::Integer(right)) => {
193 return eval_integer_infix(op, *left, *right);
194 }
195 (Object::Boolean(left), Object::Boolean(right)) => {
196 return eval_boolean_infix(op, *left, *right);
197 }
198 (Object::String(left), Object::String(right)) => {
199 return eval_string_infix(op, left.to_string(), right.to_string());
200 }
201 _ => Err(format!("eval infix error for op: {}, left: {}, right: {}", op, left, right)),
202 }
203}
204
205fn eval_integer_infix(op: &Token, left: i64, right: i64) -> Result<Rc<Object>, EvalError> {
206 let result = match &op.kind {
207 TokenKind::PLUS => Object::Integer(left + right),
208 TokenKind::MINUS => Object::Integer(left - right),
209 TokenKind::ASTERISK => Object::Integer(left * right),
210 TokenKind::SLASH => Object::Integer(left / right),
211 TokenKind::LT => Object::Boolean(left < right),
212 TokenKind::GT => Object::Boolean(left > right),
213 TokenKind::EQ => Object::Boolean(left == right),
214 TokenKind::NotEq => Object::Boolean(left != right),
215 op => return Err(format!("Invalid infix operator {} for int", op)),
216 };
217
218 Ok(Rc::from(result))
219}
220
221fn eval_boolean_infix(op: &Token, left: bool, right: bool) -> Result<Rc<Object>, EvalError> {
222 let result = match &op.kind {
223 TokenKind::EQ => Object::Boolean(left == right),
224 TokenKind::NotEq => Object::Boolean(left != right),
225 op => return Err(format!("Invalid infix operator for int: {}", op)),
226 };
227
228 Ok(Rc::from(result))
229}
230
231fn eval_string_infix(op: &Token, left: String, right: String) -> Result<Rc<Object>, EvalError> {
232 let result = match &op.kind {
233 TokenKind::EQ => Object::Boolean(left == right),
234 TokenKind::NotEq => Object::Boolean(left != right),
235 TokenKind::PLUS => Object::String(format!("{}{}", left, right)),
236 op => return Err(format!("Invalid infix {} operator for string", op)),
237 };
238
239 Ok(Rc::from(result))
240}
241
242fn eval_literal(literal: &Literal, env: &Env) -> Result<Rc<Object>, EvalError> {
243 match literal {
244 Literal::Integer(Integer { raw: i, .. }) => Ok(Rc::from(Object::Integer(*i))),
245 Literal::Boolean(Boolean { raw: b, .. }) => Ok(Rc::from(Object::Boolean(*b))),
246 Literal::String(StringType { raw: s, .. }) => Ok(Rc::from(Object::String(s.clone()))),
247 Literal::Array(Array { elements, .. }) => {
248 let list = eval_expressions(elements, env)?;
249 return Ok(Rc::from(Object::Array(list)));
250 }
251 Literal::Hash(Hash { elements: map, .. }) => {
252 let mut hash_map = HashMap::new();
253
254 for (k, v) in map {
255 let key = eval_expression(k, env)?;
256 if !key.is_hashable() {
257 return Err(format!("key {} is not hashable", key));
258 }
259 let value = eval_expression(v, env)?;
260 hash_map.insert(key, value);
261 }
262
263 return Ok(Rc::new(Object::Hash(hash_map)));
264 } }
266}