Browse Source

Fix early return (#197)

Fix early return
pull/200/head
evomassiny 5 years ago committed by Iovoslav Iovchev
parent
commit
0cbdaefe46
  1. 4
      src/lib/environment/lexical_environment.rs
  2. 28
      src/lib/exec.rs

4
src/lib/environment/lexical_environment.rs

@ -95,8 +95,8 @@ impl LexicalEnvironment {
self.environment_stack.push_back(env);
}
pub fn pop(&mut self) {
self.environment_stack.pop_back();
pub fn pop(&mut self) -> Option<Environment> {
self.environment_stack.pop_back()
}
pub fn environments(&self) -> impl Iterator<Item = Environment> {

28
src/lib/exec.rs

@ -5,7 +5,7 @@ use crate::{
value::{from_value, to_value, ResultValue, Value, ValueData},
},
environment::lexical_environment::{
new_declarative_environment, new_function_environment, VariableScope,
new_declarative_environment, new_function_environment, EnvironmentType, VariableScope,
},
realm::Realm,
syntax::ast::{
@ -86,7 +86,6 @@ impl Executor for Interpreter {
// early return
if self.is_return {
obj = val;
self.is_return = false;
break;
}
if e == es.last().expect("unable to get last value") {
@ -94,7 +93,16 @@ impl Executor for Interpreter {
}
}
self.realm.environment.pop();
// pop the block env
let block_env = self.realm.environment.pop();
// clear the early return flag `self.is_return`
// only when we leave the associated function
if let Some(env) = block_env {
if let EnvironmentType::Function = env.deref().borrow().get_environment_type() {
self.is_return = false;
}
}
Ok(obj)
}
ExprDef::Local(ref name) => {
@ -798,4 +806,18 @@ mod tests {
"#;
assert_eq!(exec(boolean_false), String::from("-1"));
}
#[test]
fn test_early_return() {
let early_return = r#"
function early_return() {
if (true) {
return true;
}
return false;
}
early_return()
"#;
assert_eq!(exec(early_return), String::from("true"));
}
}

Loading…
Cancel
Save