1use std::cell::RefCell;
2use std::cell::RefMut;
3use std::collections::HashMap;
4use std::ops::Deref;
5use std::rc::Rc;
6
7use crate::{ast::*, builtin::*, env::Env, object::Object, token::TokenType};
8
9pub struct Evaluator {
10 env: Rc<RefCell<Env>>,
11}
12
13impl Evaluator {
14 pub fn new(env: Rc<RefCell<Env>>) -> Self {
15 Evaluator { env }
16 }
17
18 pub fn builtin(&mut self) {
19 let builtins = make_builtin();
20 self.env = Rc::new(RefCell::new(Env::from(builtins)));
21
22 println!("22 {:?}", self.env);
23 }
24
25 pub fn eval_program(&mut self, program: AstNode) -> Option<Object> {
26 println!("{:?}", program);
27
28 match program {
29 AstNode::Program(statements) => {
30 let mut value = Some(Object::Null);
31
32 for statement in statements {
33 value = self.eval_statement(statement);
34 }
35
36 value
37 }
38 }
39 }
40
41 pub fn get_env(&self) -> RefMut<Env> {
42 self.env.borrow_mut()
43 }
44
45 fn eval_statement(&mut self, statement: Statement) -> Option<Object> {
46 match statement {
47 Statement::Let(identifier, expr) => self.eval_let_statement(identifier, expr),
48 Statement::Return(expr) => self.eval_return_statement(expr),
49 Statement::Expr(expr) => self.eval_expression(expr),
50 Statement::BlockStatement(statements) => self.eval_block_statements(statements),
51 }
52 }
53
54 fn eval_let_statement(&mut self, identifier: Box<Expression>, expr: Box<Expression>) -> Option<Object> {
55 match *identifier {
56 Expression::Identifier(ident) => match self.eval_expression(expr) {
57 Some(value) => {
58 self.env.deref().borrow_mut().set(ident, value);
59 None
60 }
61 None => None,
62 },
63 _ => None,
64 }
65 }
66
67 fn eval_return_statement(&mut self, expr: Box<Expression>) -> Option<Object> {
68 self.eval_expression(expr)
69 }
70
71 fn eval_block_statement(&mut self, block_stmt: Statement) -> Option<Object> {
72 match block_stmt {
73 Statement::BlockStatement(stmts) => self.eval_block_statements(stmts),
74 _ => Some(Object::Null),
75 }
76 }
77
78 fn eval_block_statements(&mut self, block_stmts: Vec<Statement>) -> Option<Object> {
79 let mut value = Some(Object::Null);
80
81 for stmt in block_stmts {
82 value = self.eval_statement(stmt);
83 }
84
85 value
86 }
87
88 fn eval_expression(&mut self, expr: Box<Expression>) -> Option<Object> {
89 match *expr {
90 Expression::String(string) => self.eval_string(string),
91 Expression::Integer(int) => self.eval_integer(int),
92 Expression::Boolean(bl) => self.eval_boolean(bl),
93 Expression::Identifier(identifer) => self.eval_identifier(identifer),
94 Expression::Array(exprs) => self.eval_array_expression(exprs),
95 Expression::Hash(hashes) => self.eval_hash_expression(hashes),
96 Expression::Prefix(operator, expr) => self.eval_prefix_expression(operator, expr),
97 Expression::Infix(left, operator, right) => self.eval_infix_expression(left, operator, right),
98 Expression::If(condition, statement, else_statement) => {
99 self.eval_if_expression(condition, statement, else_statement)
100 }
101 Expression::While(condition, block_statement) => self.eval_while_expression(condition, block_statement),
102 Expression::Break => Some(Object::Break),
103 Expression::Fn(fn_name, fn_parameter, fn_body) => self.eval_fn_expression(*fn_name, fn_parameter, fn_body),
104 Expression::FnCall(fn_name, fn_parameter) => self.eval_fn_call_expression(fn_name, fn_parameter),
105 _ => Some(Object::Null),
106 }
107 }
108
109 fn eval_prefix_expression(&mut self, operator: TokenType, expr: Box<Expression>) -> Option<Object> {
110 match operator {
111 TokenType::BANG => {
112 let value = self.eval_expression(expr).unwrap();
113
114 if value.is_truthy() {
115 Some(Object::Boolean(false))
116 } else {
117 Some(Object::Boolean(true))
118 }
119 }
120 _ => Some(Object::Null),
121 }
122 }
123
124 fn get_integer_val(&mut self, object: Object) -> usize {
125 match object {
126 Object::Integer(i) => i,
127 _ => 0,
128 }
129 }
130
131 fn get_infix_objects(&mut self, left: &InfixExpression, right: &InfixExpression) -> (Object, Object) {
132 let left = self.eval_expression(left.clone()).unwrap();
133 let right = self.eval_expression(right.clone()).unwrap();
134
135 (left, right)
136 }
137
138 fn eval_infix_expression(
139 &mut self,
140 left: InfixExpression,
141 operator: TokenType,
142 right: InfixExpression,
143 ) -> Option<Object> {
144 let value = Some(Object::Null);
145
146 match operator {
147 TokenType::ADD => {
148 let (left_obj, right_obj) = self.get_infix_objects(&left, &right);
149 let left_val = self.get_integer_val(left_obj);
150 let right_val = self.get_integer_val(right_obj);
151
152 Some(Object::Integer(left_val + right_val))
153 }
154 TokenType::MINUS => {
155 let (left_obj, right_obj) = self.get_infix_objects(&left, &right);
156 let left_val = self.get_integer_val(left_obj);
157 let right_val = self.get_integer_val(right_obj);
158
159 Some(Object::Integer(left_val - right_val))
160 }
161 TokenType::MULTIPLY => {
162 let (left_obj, right_obj) = self.get_infix_objects(&left, &right);
163 let left_val = self.get_integer_val(left_obj);
164 let right_val = self.get_integer_val(right_obj);
165
166 Some(Object::Integer(left_val * right_val))
167 }
168 TokenType::DIVIDE => {
169 let (left_obj, right_obj) = self.get_infix_objects(&left, &right);
170 let left_val = self.get_integer_val(left_obj);
171 let right_val = self.get_integer_val(right_obj);
172
173 Some(Object::Integer(left_val / right_val))
174 }
175 _ => value,
176 }
177 }
178
179 fn eval_identifier(&mut self, identifier: String) -> Option<Object> {
180 match self.env.deref().borrow_mut().get(identifier.clone()) {
181 Some(value) => Some(value),
182 None => Some(Object::Error(format!("no identifier found: {}", identifier))),
183 }
184 }
185
186 fn eval_integer(&mut self, int: usize) -> Option<Object> {
187 Some(Object::Integer(int))
188 }
189
190 fn eval_string(&mut self, string: String) -> Option<Object> {
191 Some(Object::String(string))
192 }
193
194 fn eval_boolean(&mut self, bl: bool) -> Option<Object> {
195 Some(Object::Boolean(bl))
196 }
197
198 fn eval_array_expression(&mut self, exprs: Vec<Expression>) -> Option<Object> {
199 Some(Object::Array(
200 exprs
201 .into_iter()
202 .map(|expr| self.eval_expression(Box::new(expr)).unwrap_or(Object::Null))
203 .collect::<Vec<_>>(),
204 ))
205 }
206
207 fn eval_hash_expression(&mut self, hashes: Vec<(Expression, Expression)>) -> Option<Object> {
208 let mut hash_object = HashMap::<Object, Object>::new();
209
210 hashes.into_iter().for_each(|(k, v)| {
211 hash_object.insert(
212 self.eval_expression(Box::new(k)).unwrap_or(Object::Null),
213 self.eval_expression(Box::new(v)).unwrap_or(Object::Null),
214 );
215 });
216
217 Some(Object::Hash(hash_object))
218 }
219
220 fn eval_if_expression(
221 &mut self,
222 if_condition: IfCondition,
223 statements: Statement,
224 else_statements: Option<Statement>,
225 ) -> Option<Object> {
226 let condition = self.eval_expression(if_condition);
227
228 if let Some(condition_val) = condition {
229 if condition_val.is_truthy() {
230 self.eval_block_statement(statements)
231 } else if let Some(else_stmts) = else_statements {
232 self.eval_block_statement(else_stmts)
233 } else {
234 None
235 }
236 } else {
237 None
238 }
239 }
240
241 fn eval_while_expression(&mut self, while_condition: WhileCondition, block_stmt: Statement) -> Option<Object> {
242 let condition = self.eval_expression(while_condition).unwrap();
243
244 while condition.is_truthy() {
245 match block_stmt {
246 Statement::BlockStatement(ref stmts) => {
247 for stmt in stmts {
248 let mut _value = Some(Object::Null);
249
250 _value = self.eval_statement(stmt.clone());
251
252 if _value.eq(&Some(Object::Break)) {
253 break;
254 }
255 }
256 }
257 _ => {
258 break;
259 }
260 }
261 }
262
263 None
264 }
265
266 fn eval_fn_expression(
267 &mut self,
268 fn_name_expr: Expression,
269 fn_parameter: FnParameter,
270 fn_body: FnBody,
271 ) -> Option<Object> {
272 let fn_name = match fn_name_expr {
273 Expression::Identifier(str) => str,
274 _ => "".to_string(),
275 };
276
277 let fn_object = Object::Function(fn_parameter, fn_body, Rc::clone(&self.env));
278
279 if fn_name.is_empty() {
280 Some(fn_object)
282 } else {
283 self.env.borrow_mut().set(fn_name, fn_object);
285 None
286 }
287 }
288
289 fn enclose_fn_env(
290 &mut self,
291 arg_pair_vec: Vec<(&Expression, &Object)>,
292 outer_env: Rc<RefCell<Env>>,
293 ) -> Rc<RefCell<Env>> {
294 let mut enclosed_env = Env::enclosed_outer_env(Rc::clone(&outer_env));
295
296 for (key, value) in arg_pair_vec {
297 let name = match key {
298 Expression::Identifier(str) => str,
299 _ => "",
300 };
301
302 if !name.is_empty() {
303 enclosed_env.set(name.to_string(), value.clone());
304 }
305 }
306
307 Rc::new(RefCell::new(enclosed_env))
308 }
309
310 fn eval_fn_call_expression(&mut self, fn_name: FnName, fn_parameter: FnParameter) -> Option<Object> {
311 let arguments = fn_parameter
312 .iter()
313 .map(|expr| self.eval_expression(Box::new(expr.clone())).unwrap_or(Object::Null))
314 .collect::<Vec<Object>>();
315
316 let (parameters, stmt, outer_env) = match self.eval_expression(fn_name).unwrap() {
317 Object::Function(args, stmt, outer_env) => (args, stmt, outer_env),
318 Object::Builtin(func) => {
319 return Some(func(arguments));
321 }
322 _ => {
323 return None;
324 }
325 };
326
327 let original_env = Rc::clone(&self.env);
328
329 let para_arg_pair = parameters.iter().zip(arguments.iter());
331
332 self.env = self.enclose_fn_env(para_arg_pair.collect::<Vec<(&Expression, &Object)>>(), outer_env);
334
335 let fn_call_value = self.eval_block_statement(stmt);
336
337 self.env = original_env;
339
340 fn_call_value
341 }
342}
343
344#[cfg(test)]
345mod unit_test {
346 use crate::env::Env;
347 use crate::evaluator::Evaluator;
348 use crate::object::Object;
349 use crate::parser::Parser;
350 use std::cell::RefCell;
351 use std::rc::Rc;
352
353 fn get_eval_val(input: &str) -> Option<Object> {
354 let program = Parser::get(input).parse_program();
355
356 let mut evaluator = Evaluator::new(Rc::new(RefCell::new(Env::new())));
357
358 evaluator.builtin();
359
360 evaluator.eval_program(program)
361 }
362
363 #[test]
364 fn eval_integer() {
365 let evaluated = get_eval_val("12");
366 let expected = Some(Object::Integer(12));
367
368 assert_eq!(format!("{:?}", evaluated), format!("{:?}", expected));
369 }
370
371 #[test]
372 fn eval_boolean() {
373 assert_eq!(
374 format!("{:?}", get_eval_val("true")),
375 format!("{:?}", Some(Object::Boolean(true)))
376 );
377 assert_eq!(
378 format!("{:?}", get_eval_val("false")),
379 format!("{:?}", Some(Object::Boolean(false)))
380 );
381 }
382
383 #[test]
384 fn eval_string() {
385 assert_eq!(
386 format!("{:?}", get_eval_val(r#""foo_bar_123""#)),
387 format!("{:?}", Some(Object::String(String::from("foo_bar_123"))))
388 );
389 }
390
391 #[test]
392 fn eval_hash_expression() {
393 let hash_value = get_eval_val(
394 r#"
395 {
396 "foo": "bar",
397 1: 2,
398 2: [1234, true, "Lynx programming language"],
399 "abc": true
400 };
401 "#,
402 )
403 .unwrap();
404
405 match hash_value {
406 Object::Hash(hashes) => {
407 assert_eq!(
408 hashes.get(&Object::String(String::from("abc"))),
409 Some(&Object::Boolean(true))
410 );
411
412 assert_eq!(hashes.get(&Object::Integer(1)), Some(&Object::Integer(2)));
413
414 assert_eq!(
415 hashes.get(&Object::String(String::from("foo"))),
416 Some(&Object::String(String::from("bar")))
417 );
418
419 assert_eq!(
420 hashes.get(&Object::Integer(2)),
421 Some(&Object::Array(vec![
422 Object::Integer(1234),
423 Object::Boolean(true),
424 Object::String(String::from("Lynx programming language"))
425 ]))
426 );
427 }
428 _ => (),
429 }
430 }
431
432 #[test]
433 fn eval_array_expression() {
434 assert_eq!(
435 format!(
436 "{:?}",
437 get_eval_val(
438 r#"[1234, true, "Lynx programming language", [1234, true, "Lynx programming language"]];"#
439 )
440 ),
441 format!(
442 "{:?}",
443 Some(Object::Array(vec![
444 Object::Integer(1234),
445 Object::Boolean(true),
446 Object::String(String::from("Lynx programming language")),
447 Object::Array(vec![
448 Object::Integer(1234),
449 Object::Boolean(true),
450 Object::String(String::from("Lynx programming language"))
451 ])
452 ]))
453 )
454 );
455 }
456
457 #[test]
458 fn eval_identifier() {
459 assert_eq!(
460 format!(
461 "{:?}",
462 get_eval_val(
463 r#"
464 foo;
465 "#
466 )
467 ),
468 format!("{:?}", Some(Object::Error(String::from("no identifier found: foo"))))
469 );
470 }
471
472 #[test]
473 fn eval_let_statement() {
474 assert_eq!(
475 format!(
476 "{:?}",
477 get_eval_val(
478 r#"
479 let foo = 123 + 4;
480 foo;
481 "#
482 )
483 ),
484 format!("{:?}", Some(Object::Integer(127)))
485 );
486 }
487
488 #[test]
489 fn eval_return_statement() {
490 assert_eq!(
491 format!("{:?}", get_eval_val(r#"return !false;"#)),
492 format!("{:?}", Some(Object::Boolean(true)))
493 );
494
495 assert_eq!(
496 format!("{:?}", get_eval_val(r#"return 123;"#)),
497 format!("{:?}", Some(Object::Integer(123)))
498 );
499
500 assert_eq!(
501 format!(
502 "{:?}",
503 get_eval_val(
504 r#"
505 let foo = 123;
506 return foo;
507 "#
508 )
509 ),
510 format!("{:?}", Some(Object::Integer(123)))
511 );
512 }
513
514 #[test]
515 fn eval_prefix_expression() {
516 assert_eq!(
517 format!("{:?}", get_eval_val(r#"!false"#)),
518 format!("{:?}", Some(Object::Boolean(true)))
519 );
520
521 assert_eq!(
522 format!("{:?}", get_eval_val(r#"!true"#)),
523 format!("{:?}", Some(Object::Boolean(false)))
524 );
525 }
526
527 #[test]
528 fn eval_infix_expression() {
529 assert_eq!(
530 format!("{:?}", get_eval_val(r#"1 + 2 + 3 + 4 / 2 * 3"#)),
531 format!("{:?}", Some(Object::Integer(12)))
532 );
533 }
534
535 #[test]
536 fn eval_grouped_expression() {
537 assert_eq!(
538 format!("{:?}", get_eval_val(r#"(7 + 2) / 3"#)),
539 format!("{:?}", Some(Object::Integer(3)))
540 );
541
542 assert_eq!(
543 format!("{:?}", get_eval_val(r#"9 / (1 + 2)"#)),
544 format!("{:?}", Some(Object::Integer(3)))
545 );
546 }
547
548 #[test]
549 fn eval_if_expression() {
550 assert_eq!(
551 format!(
552 "{:?}",
553 get_eval_val(
554 r#"
555 if (false) {
556 false;
557 } else {
558 true;
559 }
560 "#
561 )
562 ),
563 format!("{:?}", Some(Object::Boolean(true)))
564 );
565
566 assert_eq!(
567 format!(
568 "{:?}",
569 get_eval_val(
570 r#"
571 let foo = 123;
572 if (foo) {
573 let bar = "stuff";
574 return bar;
575 } else {
576 return 5;
577 }
578 "#
579 )
580 ),
581 format!("{:?}", Some(Object::String(String::from("stuff"))))
582 );
583 }
584
585 #[test]
586 fn eval_while_expression() {
587 assert_eq!(1, 1);
603 }
604
605 #[test]
606 fn eval_fn_expression() {
607 let input = r#"
608 fn bar(foo, stuff) {
609 let another_bar = stuff;
610 return another_bar + foo;
611 }
612 "#;
613 let program = Parser::get(input).parse_program();
614 let mut evaluator = Evaluator::new(Rc::new(RefCell::new(Env::new())));
615 evaluator.eval_program(program);
616 let env_stored = evaluator.get_env().get("bar".to_string());
617
618 assert!(env_stored.is_some());
619 }
620
621 #[test]
622 fn eval_let_fn_expression() {
623 let input = r#"
624 let foo = fn(bar, stuff) {
625 let another_bar = stuff;
626 return another_bar + bar;
627 }
628 "#;
629 let program = Parser::get(input).parse_program();
630 let mut evaluator = Evaluator::new(Rc::new(RefCell::new(Env::new())));
631 evaluator.eval_program(program);
632
633 let env_stored = evaluator.get_env().get("foo".to_string());
634
635 assert!(env_stored.is_some());
636 }
637
638 #[test]
639 fn eval_fn_call_expression() {
640 let value = format!(
641 "{:?}",
642 get_eval_val(
643 r#"
644 fn bar(foo, stuff, var) {
645 let another_bar = stuff;
646 return another_bar + foo + var;
647 }
648 let value = bar(1, 2, 3);
649 value;
650 "#
651 )
652 );
653
654 println!("{:?}", value);
655
656 assert_eq!(value, format!("{:?}", Some(Object::Integer(6))));
657 }
658
659 #[test]
660 fn eval_let_fn_call_expression() {
661 let value = format!(
662 "{:?}",
663 get_eval_val(
664 r#"
665 let bar = fn(foo, stuff, var) {
666 let another_bar = stuff;
667 return another_bar + foo + var;
668 }
669 let value = bar(1, 2, 3);
670 value;
671 "#
672 )
673 );
674
675 println!("{:?}", value);
676
677 assert_eq!(value, format!("{:?}", Some(Object::Integer(6))));
678 }
679
680 #[test]
681 fn eval_fibonacci_fn() {
682 let value = format!(
684 "{:?}",
685 get_eval_val(
686 r#"
687 fn fibonacci(x) {
688 if (x == 0) {
689 return 0;
690 } else {
691 return 1;
692 }
693 }
694 let foo = 123;
695 let fib_val = fibonacci(foo);
696 fib_val;
697 "#
698 )
699 );
700
701 println!("{:?}", value);
702
703 assert_eq!(value, format!("{:?}", Some(Object::Integer(1))));
704 }
705
706 #[test]
707 fn eval_build_ins() {
708 assert_eq!(
709 format!("{:?}", get_eval_val(r#"first([1, 2, 3]);"#)),
710 format!("{:?}", Some(Object::Integer(1)))
711 );
712
713 assert_eq!(
714 format!(
715 "{:?}",
716 get_eval_val(
717 r#"
718 last([1, 2, 3]);
719 "#
720 )
721 ),
722 format!("{:?}", Some(Object::Integer(3)))
723 );
724
725 assert_eq!(
726 format!("{:?}", get_eval_val(r#"rest([1, 2, 3]);"#)),
727 format!(
728 "{:?}",
729 Some(Object::Array(vec![Object::Integer(2), Object::Integer(3)]))
730 )
731 );
732
733 assert_eq!(
734 format!("{:?}", get_eval_val(r#"len([1, 2, 3]);"#)),
735 format!("{:?}", Some(Object::Integer(3)))
736 );
737
738 assert_eq!(
739 format!("{:?}", get_eval_val(r#"push([1, 2, 3], 4);"#)),
740 format!(
741 "{:?}",
742 Some(Object::Array(vec![
743 Object::Integer(1),
744 Object::Integer(2),
745 Object::Integer(3),
746 Object::Integer(4)
747 ]))
748 )
749 );
750
751 assert_eq!(
752 format!("{:?}", get_eval_val(r#"unshift([1, 2, 3], 4);"#)),
753 format!(
754 "{:?}",
755 Some(Object::Array(vec![
756 Object::Integer(4),
757 Object::Integer(1),
758 Object::Integer(2),
759 Object::Integer(3)
760 ]))
761 )
762 );
763
764 }
769}