diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..a555d29 --- /dev/null +++ b/readme.md @@ -0,0 +1,4 @@ +# Monkey Interpreter + +This project is my attempt at writing an interpreter while working through the book, [Writing an Interpreter in Go](https://interpreterbook.com/). +It supports all the features from the book. diff --git a/src/evaluator/mod.rs b/src/evaluator/mod.rs index 7774a33..2054912 100644 --- a/src/evaluator/mod.rs +++ b/src/evaluator/mod.rs @@ -346,4 +346,38 @@ mod tests { run_test_cases(&test_cases); } + + #[test] + fn test_closure() { + let test_cases = [( + "let newAdder = fn(x) { + fn(y) { x + y ; } ; + }; + let adder5 = newAdder(5); + adder5(10); + ", + Some(Object::Integer(15)), + )]; + + run_test_cases(&test_cases); + } + + #[test] + fn memory_test() { + let test_cases = [( + "let counter = fn(x) { + if (x > 100 ) { + return true; + } else { + let foobar = 9999; + counter(x+1); + } + }; + counter(0); + ", + Some(Object::Integer(15)), + )]; + + run_test_cases(&test_cases); + } } diff --git a/src/evaluator/tree_walker/mod.rs b/src/evaluator/tree_walker/mod.rs index 1039621..29e3381 100644 --- a/src/evaluator/tree_walker/mod.rs +++ b/src/evaluator/tree_walker/mod.rs @@ -84,7 +84,6 @@ impl Evaluator for TreeWalker { Some(NULL) } } - _ => None, }, } } @@ -239,13 +238,16 @@ impl TreeWalker { fn apply_function(&self, function: Object, args: Vec) -> Option { let function = match function { Object::Function(f) => f, + Object::Error(e) => { + return Some(Object::Error(format!("not a function: {}", e.to_string()))); + } v => return Some(Object::Error(format!("not a function: {}", v.to_string()))), }; + println!("{:?}", function.env); let mut enclosed_env = Environment::new_enclosed(function.env); for (i, parameter) in function.parameters.iter().enumerate() { if args.len() <= i { - println!("{:?} {}", args, i); return Some(Object::Error(format!("incorrect number of arguments"))); } diff --git a/src/lexer/mod.rs b/src/lexer/mod.rs index d23f618..9640ec4 100644 --- a/src/lexer/mod.rs +++ b/src/lexer/mod.rs @@ -158,7 +158,7 @@ impl<'a> Lexer<'a> { fn read_identifier(&mut self, first: char) -> String { let mut ident = String::new(); ident.push(first); - while self.peek_is_letter() { + while self.peek_is_letter() || self.peek_is_ascii_digit() { ident.push(self.read_char().unwrap()); } ident