Added closure test, accept ints in variable names

This commit is contained in:
Ishan Jain 2024-05-18 08:46:19 +05:30
parent 4ca2e61654
commit c92f4e9e82
Signed by: ishan
GPG Key ID: 0506DB2A1CC75C27
4 changed files with 43 additions and 3 deletions

4
readme.md Normal file
View File

@ -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.

View File

@ -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);
}
}

View File

@ -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<Object>) -> Option<Object> {
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")));
}

View File

@ -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