Skip to content

Commit

Permalink
working return statement
Browse files Browse the repository at this point in the history
  • Loading branch information
cezaris13 committed Dec 15, 2024
1 parent d763e4e commit f8e029d
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 6 deletions.
24 changes: 21 additions & 3 deletions src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ impl Interpreter {
body,
} => {
let arity = parameters.len();
let body = body.clone();

let closure = move |parent_environment: Rc<RefCell<Environment>>,
arguments: &Vec<LiteralValue>|
Expand All @@ -119,7 +120,17 @@ impl Interpreter {
.define(String::from(&parameters[i].lexeme), argument.clone());
}

closure_interpreter.interpret_statements(body.clone())?;
for i in 0..(body.len()) {
closure_interpreter.interpret_statements(vec![body[i].clone()])?;

if let Statement::Return {
keyword: _,
value: _,
} = &body[i]
{
return closure_interpreter.environment.borrow_mut().get("return");
}
}

Ok(LiteralValue::Nil)
};
Expand All @@ -133,8 +144,15 @@ impl Interpreter {
},
);
}
Statement::Return { keyword, value } => {
todo!()
Statement::Return { keyword: _, value } => {
let response = match value {
Some(val) => val.evaluate(self.environment.clone())?,
_ => LiteralValue::Nil,
};

self.environment
.borrow_mut()
.define(String::from("return"), response);
}
};
}
Expand Down
10 changes: 10 additions & 0 deletions src/tests/cases/fun_empty_return.lox
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
var a=0;

fun printA(a) {
print a;
return;
}

var b = printA(a);

print b;
5 changes: 5 additions & 0 deletions src/tests/cases/funreturn.lox
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fun add(a,b) {
return a+b;
}

print add(2,3);
4 changes: 2 additions & 2 deletions src/tests/expression_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,8 @@ mod tests {
sources
.iter()
.map(|source| {
let closure = move |parent_environment: Rc<RefCell<Environment>>,
arguments: &Vec<LiteralValue>|
let closure = move |_parent_environment: Rc<RefCell<Environment>>,
_arguments: &Vec<LiteralValue>|
-> Result<LiteralValue, String> {
Ok(LiteralValue::IntValue(2))
};
Expand Down
77 changes: 76 additions & 1 deletion src/tests/interpreter_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ mod tests {
}

#[test]
fn expression_with_function_statement__test() {
fn expression_with_function_statement_test() {
let source = "
var a=0;
Expand Down Expand Up @@ -337,4 +337,79 @@ mod tests {
Ok(LiteralValue::Nil)
);
}

#[test]
fn test_function_with_return() {
let source = "
var a=0;
fun addOne(a) {
return a + 1;
}
var b = addOne(a);
";
let mut scanner = Scanner::new(source);
let tokens = scanner.scan_tokens().unwrap();

let mut parser = Parser::new(tokens);
let statements = parser.parse().unwrap();

let mut interpreter: Interpreter = Interpreter::new();
let variable_count = interpreter.environment.borrow().values.len();
let result = interpreter.interpret_statements(statements);

assert!(result.is_ok());

assert_eq!(
interpreter.environment.borrow().values.len(),
variable_count + 3
);
assert_eq!(
interpreter.environment.borrow().get("a"),
Ok(LiteralValue::IntValue(0))
);
assert_eq!(
interpreter.environment.borrow().get("b"),
Ok(LiteralValue::IntValue(1))
);
}

#[test]
fn test_function_with_empty_return() {
let source = "
var a=0;
fun printA(a) {
print a;
return;
}
var b = printA(a);
";
let mut scanner = Scanner::new(source);
let tokens = scanner.scan_tokens().unwrap();

let mut parser = Parser::new(tokens);
let statements = parser.parse().unwrap();

let mut interpreter: Interpreter = Interpreter::new();
let variable_count = interpreter.environment.borrow().values.len();
let result = interpreter.interpret_statements(statements);

assert!(result.is_ok());

assert_eq!(
interpreter.environment.borrow().values.len(),
variable_count + 3
);
assert_eq!(
interpreter.environment.borrow().get("a"),
Ok(LiteralValue::IntValue(0))
);
assert_eq!(
interpreter.environment.borrow().get("b"),
Ok(LiteralValue::Nil)
);
}
}
19 changes: 19 additions & 0 deletions src/tests/main_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,25 @@ mod tests {
assert_eq!(lines[0], "3");
}

#[test]
fn function_with_return() {
let lines = test_file("./src/tests/cases/funreturn.lox");

assert_eq!(lines.len(), 1);

assert_eq!(lines[0], "5");
}

#[test]
fn function_with_empty_return() {
let lines = test_file("./src/tests/cases/fun_empty_return.lox");

assert_eq!(lines.len(), 2);

assert_eq!(lines[0], "0");
assert_eq!(lines[1], "nil");
}

fn test_file(file_path: &str) -> Vec<String> {
let output = Command::new("cargo")
.args(["run", file_path])
Expand Down

0 comments on commit f8e029d

Please sign in to comment.