diff --git a/src/data_types/array.rs b/src/data_types/array.rs index 39d8ae4..f50bb6e 100644 --- a/src/data_types/array.rs +++ b/src/data_types/array.rs @@ -9,8 +9,8 @@ use crate::token::Literals; impl DoveObject for Rc>> { fn get_property(&mut self, name: &str) -> Result { match name { - "length" => Ok(Literals::Number(self.borrow().len() as f64)), - "empty" => Ok(Literals::Boolean(self.borrow().len() == 0)), + "len" => Ok(Literals::Function(Rc::new(array_len(self)))), + "is_empty" => Ok(Literals::Function(Rc::new(array_is_empty(self)))), "push" => Ok(Literals::Function(Rc::new(array_append(self)))), "pop" => Ok(Literals::Function(Rc::new(array_pop(self)))), "remove" => Ok(Literals::Function(Rc::new(array_remove(self)))), @@ -19,6 +19,22 @@ impl DoveObject for Rc>> { } } +fn array_len(array: &Rc>>) -> impl DoveCallable { + let array = Rc::clone(array); + + BuiltinFunction::new(0, move |_| { + Ok(Literals::Number(array.borrow().len() as f64)) + }) +} + +fn array_is_empty(array: &Rc>>) -> impl DoveCallable { + let array = Rc::clone(array); + + BuiltinFunction::new(0, move |_| { + Ok(Literals::Boolean(array.borrow().len() == 0)) + }) +} + fn array_append(array: &Rc>>) -> impl DoveCallable { let array = Rc::clone(array); diff --git a/src/data_types/dict.rs b/src/data_types/dict.rs index 0bff91f..1912463 100644 --- a/src/data_types/dict.rs +++ b/src/data_types/dict.rs @@ -10,7 +10,7 @@ use crate::token::{Literals, DictKey}; impl DoveObject for Rc>> { fn get_property(&mut self, name: &str) -> Result { match name { - "length" => Ok(Literals::Number(self.borrow().len() as f64)), + "len" => Ok(Literals::Function(Rc::new(dict_len(self)))), "keys" => Ok(Literals::Function(Rc::new(dict_keys(self)))), "values" => Ok(Literals::Function(Rc::new(dict_values(self)))), "remove" => Ok(Literals::Function(Rc::new(dict_remove(self)))), @@ -19,6 +19,14 @@ impl DoveObject for Rc>> { } } +fn dict_len(dict: &Rc>>) -> impl DoveCallable { + let dict = Rc::clone(dict); + + BuiltinFunction::new(0, move |_| { + Ok(Literals::Number(dict.borrow().len() as f64)) + }) +} + fn dict_keys(dict: &Rc>>) -> impl DoveCallable { let dict = Rc::clone(dict); diff --git a/src/data_types/mod.rs b/src/data_types/mod.rs index 5baf9bd..c793a2f 100644 --- a/src/data_types/mod.rs +++ b/src/data_types/mod.rs @@ -1,5 +1,6 @@ use crate::token::Literals; +pub mod number; pub mod string; pub mod array; pub mod dict; diff --git a/src/data_types/number.rs b/src/data_types/number.rs new file mode 100644 index 0000000..7fbcd80 --- /dev/null +++ b/src/data_types/number.rs @@ -0,0 +1,42 @@ +use std::rc::Rc; + +use crate::data_types::*; +use crate::dove_callable::{DoveCallable, BuiltinFunction}; +use crate::token::Literals; + +impl DoveObject for f64 { + fn get_property(&mut self, name: &str) -> Result { + match name { + "fract" => Ok(Literals::Function(Rc::new(number_fract(*self)))), + "abs" => Ok(Literals::Function(Rc::new(number_abs(*self)))), + "floor" => Ok(Literals::Function(Rc::new(number_floor(*self)))), + "ceil" => Ok(Literals::Function(Rc::new(number_ceil(*self)))), + _ => Err(Error::CannotGetProperty), + } + } +} + +fn number_fract(number: f64) -> impl DoveCallable { + BuiltinFunction::new(0, move |_| { + Ok(Literals::Number(number.fract())) + }) +} + +fn number_abs(number: f64) -> impl DoveCallable { + BuiltinFunction::new(0, move |_| { + Ok(Literals::Number(number.abs())) + }) +} + +fn number_floor(number: f64) -> impl DoveCallable { + BuiltinFunction::new(0, move |_| { + Ok(Literals::Number(number.floor())) + }) +} + +fn number_ceil(number: f64) -> impl DoveCallable { + BuiltinFunction::new(0, move |_| { + Ok(Literals::Number(number.ceil())) + }) +} + diff --git a/src/data_types/string.rs b/src/data_types/string.rs index a8059bf..4f817ab 100644 --- a/src/data_types/string.rs +++ b/src/data_types/string.rs @@ -8,14 +8,21 @@ use crate::token::Literals; impl DoveObject for String { fn get_property(&mut self, name: &str) -> Result { match name { - "length" => Ok(Literals::Number(self.len() as f64)), - // "chars" => Ok(Literals::Function(Rc::new(StringChars { string: self.clone() }))), + "len" => Ok(Literals::Function(Rc::new(string_len(self)))), "chars" => Ok(Literals::Function(Rc::new(string_chars(self)))), _ => Err(Error::CannotGetProperty), } } } +fn string_len(string: &str) -> impl DoveCallable { + let string = string.to_string(); + + BuiltinFunction::new(0, move |_| { + Ok(Literals::Number(string.len() as f64)) + }) +} + fn string_chars(string: &str) -> impl DoveCallable { let string = string.to_string(); diff --git a/src/token.rs b/src/token.rs index d2aa0ad..e6d9108 100644 --- a/src/token.rs +++ b/src/token.rs @@ -124,6 +124,7 @@ impl Literals { pub fn as_object(&self) -> Box { match self { + Literals::Number(number) => Box::new(*number), Literals::String(string) => Box::new(string.clone()), Literals::Instance(instance) => Box::new(Rc::clone(instance)), Literals::Array(array) => Box::new(Rc::clone(array)),