diff --git a/boa/src/exec/mod.rs b/boa/src/exec/mod.rs index c8e928a2b9..fb9cc0ed66 100644 --- a/boa/src/exec/mod.rs +++ b/boa/src/exec/mod.rs @@ -353,9 +353,23 @@ impl Executor for Interpreter { Node::UnaryOp(ref op, ref a) => { let v_r_a = self.run(a)?; let v_a = (*v_r_a).clone(); - Ok(match *op { + Ok(match op { UnaryOp::Minus => to_value(-v_a.to_number()), UnaryOp::Plus => to_value(v_a.to_number()), + UnaryOp::IncrementPost => { + self.set_value(a.deref(), to_value(v_a.to_number() + 1.0))?; + v_r_a + } + UnaryOp::IncrementPre => { + self.set_value(a.deref(), to_value(v_a.to_number() + 1.0))? + } + UnaryOp::DecrementPost => { + self.set_value(a.deref(), to_value(v_a.to_number() - 1.0))?; + v_r_a + } + UnaryOp::DecrementPre => { + self.set_value(a.deref(), to_value(v_a.to_number() - 1.0))? + } UnaryOp::Not => Gc::new(!v_a), UnaryOp::Tilde => { let num_v_a = v_a.to_number(); @@ -839,4 +853,22 @@ impl Interpreter { Err(()) } + + fn set_value(&mut self, node: &Node, value: Value) -> ResultValue { + match node { + Node::Local(ref name) => { + self.realm + .environment + .set_mutable_binding(name, value.clone(), true); + Ok(value) + } + Node::GetConstField(ref obj, ref field) => { + Ok(self.run(obj)?.set_field_slice(field, value)) + } + Node::GetField(ref obj, ref field) => { + Ok(self.run(obj)?.set_field(self.run(field)?, value)) + } + _ => panic!("TypeError: invalid assignment to {}", node), + } + } } diff --git a/boa/src/exec/tests.rs b/boa/src/exec/tests.rs index 1abe951cef..b91bb39de1 100644 --- a/boa/src/exec/tests.rs +++ b/boa/src/exec/tests.rs @@ -295,7 +295,6 @@ fn do_while_loop() { } #[test] -#[ignore] fn do_while_post_inc() { let with_post_incrementors = r#" var i = 0; @@ -309,7 +308,7 @@ 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) { + for (let i = 0; i < a.length; i++) { b = b + a[i]; } b @@ -321,7 +320,7 @@ fn test_for_loop() { let i = 0; for (;i < 10;) { a = a + i; - i = i + 1; + i++; } a @@ -331,7 +330,7 @@ fn test_for_loop() { let body_should_not_execute_on_false_condition = r#" let a = 0 for (;false;) { - a = a + 1; + a++; } a @@ -350,7 +349,6 @@ fn test_for_loop() { } #[test] -#[ignore] fn unary_pre() { let unary_inc = r#" let a = 5; @@ -364,17 +362,36 @@ fn unary_pre() { --a; a; "#; - assert_eq!(exec(unary_dec), String::from("6")); + assert_eq!(exec(unary_dec), String::from("4")); - let execs_before = r#" + let inc_obj_prop = r#" + const a = { b: 5 }; + ++a.b; + a['b']; + "#; + assert_eq!(exec(inc_obj_prop), String::from("6")); + + let inc_obj_field = r#" + const a = { b: 5 }; + ++a['b']; + a.b; + "#; + assert_eq!(exec(inc_obj_field), String::from("6")); + + let execs_before_inc = r#" let a = 5; ++a === 6; "#; - assert_eq!(exec(execs_before), String::from("true")); + assert_eq!(exec(execs_before_inc), String::from("true")); + + let execs_before_dec = r#" + let a = 5; + --a === 4; + "#; + assert_eq!(exec(execs_before_dec), String::from("true")); } #[test] -#[ignore] fn unary_post() { let unary_inc = r#" let a = 5; @@ -388,13 +405,33 @@ fn unary_post() { a--; a; "#; - assert_eq!(exec(unary_dec), String::from("6")); + assert_eq!(exec(unary_dec), String::from("4")); - let execs_after = r#" + let inc_obj_prop = r#" + const a = { b: 5 }; + a.b++; + a['b']; + "#; + assert_eq!(exec(inc_obj_prop), String::from("6")); + + let inc_obj_field = r#" + const a = { b: 5 }; + a['b']++; + a.b; + "#; + assert_eq!(exec(inc_obj_field), String::from("6")); + + let execs_after_inc = r#" let a = 5; a++ === 5; "#; - assert_eq!(exec(execs_after), String::from("true")); + assert_eq!(exec(execs_after_inc), String::from("true")); + + let execs_after_dec = r#" + let a = 5; + a-- === 5; + "#; + assert_eq!(exec(execs_after_dec), String::from("true")); } #[cfg(test)]