Browse Source

Implement for loop (#374)

* implement for loop execution

* for loop benchmark

* add more for loop tests

* Update boa/src/exec/tests.rs

Co-authored-by: Iban Eguia <razican@protonmail.ch>
pull/370/head
Alexander Kryvomaz 5 years ago committed by GitHub
parent
commit
75cf44a08a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 39
      boa/benches/exec.rs
  2. 18
      boa/src/exec/mod.rs
  3. 45
      boa/src/exec/tests.rs

39
boa/benches/exec.rs

@ -26,30 +26,25 @@ fn symbol_creation(c: &mut Criterion) {
}); });
} }
// TODO: implement for loops. static FOR_LOOP: &str = r#"
// static FOR_LOOP: &str = r#" let a = 10;
// let a = 10; let b = "hello";
// let b = "hello"; for (;a > 100;) {
// for (;;) { a += 5;
// a += 5;
// if (a < 50) { if (a < 50) {
// b += "world"; b += "world";
// } }
}
// if (a > 100) { b
// break; "#;
// }
// }
// let c = a;
// let d = b;
// "#;
// fn for_loop_execution(c: &mut Criterion) { fn for_loop_execution(c: &mut Criterion) {
// c.bench_function("For loop (Execution)", move |b| { c.bench_function("For loop (Execution)", move |b| {
// b.iter(|| exec(black_box(FOR_LOOP))) b.iter(|| exec(black_box(FOR_LOOP)))
// }); });
// } }
static FIBONACCI: &str = r#" static FIBONACCI: &str = r#"
let num = 12; let num = 12;
@ -74,7 +69,7 @@ criterion_group!(
execution, execution,
create_realm, create_realm,
symbol_creation, symbol_creation,
// for_loop_execution, for_loop_execution,
fibonacci fibonacci
); );
criterion_main!(execution); criterion_main!(execution);

18
boa/src/exec/mod.rs

@ -173,6 +173,24 @@ impl Executor for Interpreter {
} }
Ok(result) Ok(result)
} }
Node::ForLoop(ref init, ref cond, ref step, ref body) => {
if let Some(init) = init {
self.run(init)?;
}
while match cond {
Some(cond) => self.run(cond)?.borrow().is_true(),
None => true,
} {
self.run(body)?;
if let Some(step) = step {
self.run(step)?;
}
}
Ok(Gc::new(ValueData::Undefined))
}
Node::If(ref cond, ref expr, None) => Ok(if self.run(cond)?.borrow().is_true() { Node::If(ref cond, ref expr, None) => Ok(if self.run(cond)?.borrow().is_true() {
self.run(expr)? self.run(expr)?
} else { } else {

45
boa/src/exec/tests.rs

@ -304,6 +304,51 @@ fn test_do_while_post_inc() {
assert_eq!(exec(with_post_incrementors), String::from("11")); assert_eq!(exec(with_post_incrementors), String::from("11"));
} }
#[test]
fn test_for_loop() {
let simple = r#"
const a = ['h', 'e', 'l', 'l', 'o'];
let b = '';
for (let i = 0; i < a.length; i = i + 1) {
b = b + a[i];
}
b
"#;
assert_eq!(exec(simple), String::from("hello"));
let without_init_and_inc_step = r#"
let a = 0;
let i = 0;
for (;i < 10;) {
a = a + i;
i = i + 1;
}
a
"#;
assert_eq!(exec(without_init_and_inc_step), String::from("45"));
let body_should_not_execute_on_false_condition = r#"
let a = 0
for (;false;) {
a = a + 1;
}
a
"#;
assert_eq!(
exec(body_should_not_execute_on_false_condition),
String::from("0")
);
let inner_scope = r#"
for (let i = 0;false;) {}
i
"#;
assert_eq!(exec(inner_scope), String::from("undefined"));
}
#[test] #[test]
#[ignore] #[ignore]
fn test_unary_pre() { fn test_unary_pre() {

Loading…
Cancel
Save