Browse Source

Implement unary increment and decrement (#380)

pull/382/head
Alexander Kryvomaz 5 years ago committed by GitHub
parent
commit
f6e0fdb197
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 34
      boa/src/exec/mod.rs
  2. 61
      boa/src/exec/tests.rs

34
boa/src/exec/mod.rs

@ -353,9 +353,23 @@ impl Executor for Interpreter {
Node::UnaryOp(ref op, ref a) => { Node::UnaryOp(ref op, ref a) => {
let v_r_a = self.run(a)?; let v_r_a = self.run(a)?;
let v_a = (*v_r_a).clone(); let v_a = (*v_r_a).clone();
Ok(match *op { Ok(match op {
UnaryOp::Minus => to_value(-v_a.to_number()), UnaryOp::Minus => to_value(-v_a.to_number()),
UnaryOp::Plus => 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::Not => Gc::new(!v_a),
UnaryOp::Tilde => { UnaryOp::Tilde => {
let num_v_a = v_a.to_number(); let num_v_a = v_a.to_number();
@ -839,4 +853,22 @@ impl Interpreter {
Err(()) 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),
}
}
} }

61
boa/src/exec/tests.rs

@ -295,7 +295,6 @@ fn do_while_loop() {
} }
#[test] #[test]
#[ignore]
fn do_while_post_inc() { fn do_while_post_inc() {
let with_post_incrementors = r#" let with_post_incrementors = r#"
var i = 0; var i = 0;
@ -309,7 +308,7 @@ fn test_for_loop() {
let simple = r#" let simple = r#"
const a = ['h', 'e', 'l', 'l', 'o']; const a = ['h', 'e', 'l', 'l', 'o'];
let b = ''; 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 = b + a[i];
} }
b b
@ -321,7 +320,7 @@ fn test_for_loop() {
let i = 0; let i = 0;
for (;i < 10;) { for (;i < 10;) {
a = a + i; a = a + i;
i = i + 1; i++;
} }
a a
@ -331,7 +330,7 @@ fn test_for_loop() {
let body_should_not_execute_on_false_condition = r#" let body_should_not_execute_on_false_condition = r#"
let a = 0 let a = 0
for (;false;) { for (;false;) {
a = a + 1; a++;
} }
a a
@ -350,7 +349,6 @@ fn test_for_loop() {
} }
#[test] #[test]
#[ignore]
fn unary_pre() { fn unary_pre() {
let unary_inc = r#" let unary_inc = r#"
let a = 5; let a = 5;
@ -364,17 +362,36 @@ fn unary_pre() {
--a; --a;
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; let a = 5;
++a === 6; ++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] #[test]
#[ignore]
fn unary_post() { fn unary_post() {
let unary_inc = r#" let unary_inc = r#"
let a = 5; let a = 5;
@ -388,13 +405,33 @@ fn unary_post() {
a--; a--;
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; let a = 5;
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)] #[cfg(test)]

Loading…
Cancel
Save