feat(tazjin/rlox): Implement early return from functions

In the book this is implemented via exceptions as control flow, and
I'm sticking somewhat closely to that by doing it via an error
variant.

Change-Id: I9c7b84d6bb28265ab94021ea681df84f16a53da2
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2395
Reviewed-by: tazjin <mail@tazj.in>
Tested-by: BuildkiteCI
This commit is contained in:
Vincent Ambo 2021-01-14 22:49:07 +03:00 committed by tazjin
parent 20a6cfeee2
commit 39439d59e8
3 changed files with 47 additions and 1 deletions

View file

@ -40,7 +40,18 @@ impl Callable {
fn_env.define(param, value)?;
}
lox.interpret_block(Rc::new(RwLock::new(fn_env)), &func.body)
let result = lox.interpret_block(Rc::new(RwLock::new(fn_env)), &func.body);
match result {
// extract returned values if applicable
Err(Error {
kind: ErrorKind::FunctionReturn(value),
..
}) => Ok(value),
// otherwise just return the result itself
_ => result,
}
}
}
}
@ -221,6 +232,12 @@ impl Interpreter {
Statement::If(if_stmt) => return self.interpret_if(if_stmt),
Statement::While(while_stmt) => return self.interpret_while(while_stmt),
Statement::Function(func) => return self.interpret_function(func.clone()),
Statement::Return(ret) => {
return Err(Error {
line: 0,
kind: ErrorKind::FunctionReturn(self.eval(&ret.value)?),
})
}
};
Ok(value)