blob: 1088aed585c05587f6768254b5efc8e2842a2045 [file] [log] [blame]
use std::prelude::v1::*;
use std::any::Any;
use std::cell::RefCell;
use object::Object;
use value::{Value, ValueContext};
use executor::ExecutorImpl;
use errors::{VMError, FieldNotFoundError};
pub struct Array {
pub elements: RefCell<Vec<Value>>
}
impl Array {
pub fn new() -> Array {
Array {
elements: RefCell::new(Vec::new())
}
}
}
impl Object for Array {
fn get_children(&self) -> Vec<usize> {
self.elements.borrow().iter().filter(|v| v.is_object()).map(|v| v.as_object_id()).collect()
}
fn as_any(&self) -> &Any {
self as &Any
}
fn as_any_mut(&mut self) -> &mut Any {
self as &mut Any
}
fn call_field(&self, name: &str, executor: &mut ExecutorImpl) -> Value {
match name {
"__get__" | "get" => {
let index = executor.get_current_frame().must_get_argument(0);
let index = ValueContext::new(
&index,
executor.get_object_pool()
).to_i64() as usize;
let elements = self.elements.borrow();
if index >= elements.len() {
panic!(VMError::from("Array index out of bound"))
}
elements[index]
},
"__set__" | "set" => {
let index = executor.get_current_frame().must_get_argument(0);
let val = executor.get_current_frame().must_get_argument(1);
let index = ValueContext::new(
&index,
executor.get_object_pool()
).to_i64() as usize;
let mut elements = self.elements.borrow_mut();
if index >= elements.len() {
panic!(VMError::from("Array index out of bound"))
}
(*elements)[index] = val;
Value::Null
},
"push" => {
let val = executor.get_current_frame().must_get_argument(0);
self.elements.borrow_mut().push(val);
Value::Null
},
"pop" => {
self.elements.borrow_mut().pop().unwrap_or_else(|| panic!(VMError::from("No elements")))
},
"__len__" | "len" | "size" => {
Value::Int(self.elements.borrow().len() as i64)
},
_ => panic!(VMError::from(FieldNotFoundError::from_field_name(name)))
}
}
}