Browse Source

Enable obj[key] = value syntax. (#161)

* wip: setting keys in objects

* handle array case when setting objects
pull/183/head
letmutx 5 years ago committed by Jason Williams
parent
commit
0f72bf556e
  1. 48
      src/lib/exec.rs
  2. 2
      src/lib/js/object.rs
  3. 11
      src/lib/js/value.rs

48
src/lib/exec.rs

@ -415,6 +415,13 @@ impl Executor for Interpreter {
let val_obj = self.run(obj)?; let val_obj = self.run(obj)?;
val_obj.borrow().set_field(field.clone(), val.clone()); val_obj.borrow().set_field(field.clone(), val.clone());
} }
ExprDef::GetField(ref obj, ref field) => {
let val_obj = self.run(obj)?;
let val_field = self.run(field)?;
val_obj
.borrow()
.set_field(val_field.to_string(), val.clone());
}
_ => (), _ => (),
} }
Ok(val) Ok(val)
@ -703,4 +710,45 @@ mod tests {
assert_eq!(exec(scenario), pass); assert_eq!(exec(scenario), pass);
} }
#[test]
fn object_field_set() {
let scenario = r#"
let m = {};
m['key'] = 22;
m['key']
"#;
assert_eq!(exec(scenario), String::from("22"));
}
#[test]
fn array_field_set() {
let element_changes = r#"
let m = [1, 2, 3];
m[1] = 5;
m[1]
"#;
assert_eq!(exec(element_changes), String::from("5"));
let length_changes = r#"
let m = [1, 2, 3];
m[10] = 52;
m.length
"#;
assert_eq!(exec(length_changes), String::from("11"));
let negative_index_wont_affect_length = r#"
let m = [1, 2, 3];
m[-11] = 5;
m.length
"#;
assert_eq!(exec(negative_index_wont_affect_length), String::from("3"));
let non_num_key_wont_affect_length = r#"
let m = [1, 2, 3];
m["magic"] = 5;
m.length
"#;
assert_eq!(exec(non_num_key_wont_affect_length), String::from("3"));
}
} }

2
src/lib/js/object.rs

@ -402,7 +402,7 @@ impl Object {
} }
} }
#[derive(Trace, Finalize, Clone, Debug)] #[derive(Trace, Finalize, Clone, Debug, Eq, PartialEq)]
pub enum ObjectKind { pub enum ObjectKind {
Function, Function,
Array, Array,

11
src/lib/js/value.rs

@ -402,6 +402,17 @@ impl ValueData {
pub fn set_field(&self, field: String, val: Value) -> Value { pub fn set_field(&self, field: String, val: Value) -> Value {
match *self { match *self {
ValueData::Object(ref obj) => { ValueData::Object(ref obj) => {
if obj.borrow().kind == ObjectKind::Array {
if let Ok(num) = field.parse::<usize>() {
if num > 0 {
let len: i32 = from_value(self.get_field_slice("length"))
.expect("Could not convert argument to i32");
if len < (num + 1) as i32 {
self.set_field_slice("length", to_value(num + 1));
}
}
}
}
obj.borrow_mut() obj.borrow_mut()
.properties .properties
.insert(field, Property::default().value(val.clone())); .insert(field, Property::default().value(val.clone()));

Loading…
Cancel
Save