Skip to content

Commit

Permalink
Implement unary void, delete operators (#388)
Browse files Browse the repository at this point in the history
  • Loading branch information
akryvomaz authored May 10, 2020
1 parent 143434f commit 9cd9a39
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 2 deletions.
6 changes: 4 additions & 2 deletions boa/src/builtins/value/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,11 +334,13 @@ impl ValueData {
/// Removes a property from a Value object.
///
/// It will return a boolean based on if the value was removed, if there was no value to remove false is returned
pub fn remove_property(&self, field: &str) {
match *self {
pub fn remove_property(&self, field: &str) -> bool {
let removed = match *self {
Self::Object(ref obj) => obj.borrow_mut().deref_mut().properties.remove(field),
_ => None,
};

removed.is_some()
}

/// Resolve the property in the object.
Expand Down
21 changes: 21 additions & 0 deletions boa/src/exec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,27 @@ impl Executor for Interpreter {
!(num_v_a as i32)
})
}
UnaryOp::Void => Value::undefined(),
UnaryOp::Delete => match a.deref() {
Node::GetConstField(ref obj, ref field) => {
Value::boolean(self.run(obj)?.remove_property(field))
}
Node::GetField(ref obj, ref field) => Value::boolean(
self.run(obj)?
.remove_property(&self.run(field)?.to_string()),
),
Node::Local(_) => Value::boolean(false),
Node::ArrayDecl(_)
| Node::Block(_)
| Node::Const(_)
| Node::FunctionDecl(_, _, _)
| Node::FunctionExpr(_, _, _)
| Node::New(_)
| Node::Object(_)
| Node::TypeOf(_)
| Node::UnaryOp(_, _) => Value::boolean(true),
_ => panic!("SyntaxError: wrong delete argument {}", node),
},
_ => unimplemented!(),
})
}
Expand Down
69 changes: 69 additions & 0 deletions boa/src/exec/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,75 @@ fn unary_post() {
assert_eq!(&exec(execs_after_dec), "true");
}

#[test]
fn unary_void() {
let void_should_return_undefined = r#"
const a = 0;
void a;
"#;
assert_eq!(&exec(void_should_return_undefined), "undefined");

let void_invocation = r#"
let a = 0;
const test = () => a = 42;
const b = void test() + '';
a + b
"#;
assert_eq!(&exec(void_invocation), "42undefined");
}

#[test]
fn unary_delete() {
let delete_var = r#"
let a = 5;
const b = delete a + '';
a + b
"#;
assert_eq!(&exec(delete_var), "5false");

let delete_prop = r#"
const a = { b: 5 };
const c = delete a.b + '';
a.b + c
"#;
assert_eq!(&exec(delete_prop), "undefinedtrue");

let delete_not_existing_prop = r#"
const a = { b: 5 };
const c = delete a.c + '';
a.b + c
"#;
assert_eq!(&exec(delete_not_existing_prop), "5false");

let delete_field = r#"
const a = { b: 5 };
const c = delete a['b'] + '';
a.b + c
"#;
assert_eq!(&exec(delete_field), "undefinedtrue");

let delete_object = r#"
const a = { b: 5 };
delete a
"#;
assert_eq!(&exec(delete_object), "false");

let delete_array = r#"
delete [];
"#;
assert_eq!(&exec(delete_array), "true");

let delete_func = r#"
delete function() {};
"#;
assert_eq!(&exec(delete_func), "true");

let delete_recursive = r#"
delete delete delete 1;
"#;
assert_eq!(&exec(delete_recursive), "true");
}

#[cfg(test)]
mod in_operator {
use super::*;
Expand Down

0 comments on commit 9cd9a39

Please sign in to comment.