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); self.environment_stack.push_back(env);
} }
pub fn pop(&mut self) { pub fn pop(&mut self) -> Option<Environment> {
self.environment_stack.pop_back(); self.environment_stack.pop_back()
} }
pub fn environments(&self) -> impl Iterator<Item = Environment> { 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}, value::{from_value, to_value, ResultValue, Value, ValueData},
}, },
environment::lexical_environment::{ environment::lexical_environment::{
new_declarative_environment, new_function_environment, VariableScope, new_declarative_environment, new_function_environment, EnvironmentType, VariableScope,
}, },
realm::Realm, realm::Realm,
syntax::ast::{ syntax::ast::{
@ -86,7 +86,6 @@ impl Executor for Interpreter {
// early return // early return
if self.is_return { if self.is_return {
obj = val; obj = val;
self.is_return = false;
break; break;
} }
if e == es.last().expect("unable to get last value") { 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) Ok(obj)
} }
ExprDef::Local(ref name) => { ExprDef::Local(ref name) => {
@ -798,4 +806,18 @@ mod tests {
"#; "#;
assert_eq!(exec(boolean_false), String::from("-1")); 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