Skip to content

Commit

Permalink
Implement builtin methods for Number.
Browse files Browse the repository at this point in the history
  • Loading branch information
huaqiwen committed Jun 28, 2020
1 parent 9a2ccc8 commit 9e252ba
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 5 deletions.
20 changes: 18 additions & 2 deletions src/data_types/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use crate::token::Literals;
impl DoveObject for Rc<RefCell<Vec<Literals>>> {
fn get_property(&mut self, name: &str) -> Result<Literals> {
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)))),
Expand All @@ -19,6 +19,22 @@ impl DoveObject for Rc<RefCell<Vec<Literals>>> {
}
}

fn array_len(array: &Rc<RefCell<Vec<Literals>>>) -> 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<RefCell<Vec<Literals>>>) -> impl DoveCallable {
let array = Rc::clone(array);

BuiltinFunction::new(0, move |_| {
Ok(Literals::Boolean(array.borrow().len() == 0))
})
}

fn array_append(array: &Rc<RefCell<Vec<Literals>>>) -> impl DoveCallable {
let array = Rc::clone(array);

Expand Down
10 changes: 9 additions & 1 deletion src/data_types/dict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::token::{Literals, DictKey};
impl DoveObject for Rc<RefCell<HashMap<DictKey, Literals>>> {
fn get_property(&mut self, name: &str) -> Result<Literals> {
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)))),
Expand All @@ -19,6 +19,14 @@ impl DoveObject for Rc<RefCell<HashMap<DictKey, Literals>>> {
}
}

fn dict_len(dict: &Rc<RefCell<HashMap<DictKey, Literals>>>) -> impl DoveCallable {
let dict = Rc::clone(dict);

BuiltinFunction::new(0, move |_| {
Ok(Literals::Number(dict.borrow().len() as f64))
})
}

fn dict_keys(dict: &Rc<RefCell<HashMap<DictKey, Literals>>>) -> impl DoveCallable {
let dict = Rc::clone(dict);

Expand Down
1 change: 1 addition & 0 deletions src/data_types/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::token::Literals;

pub mod number;
pub mod string;
pub mod array;
pub mod dict;
Expand Down
42 changes: 42 additions & 0 deletions src/data_types/number.rs
Original file line number Diff line number Diff line change
@@ -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<Literals> {
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()))
})
}

11 changes: 9 additions & 2 deletions src/data_types/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,21 @@ use crate::token::Literals;
impl DoveObject for String {
fn get_property(&mut self, name: &str) -> Result<Literals> {
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();

Expand Down
1 change: 1 addition & 0 deletions src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ impl Literals {

pub fn as_object(&self) -> Box<dyn DoveObject> {
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)),
Expand Down

0 comments on commit 9e252ba

Please sign in to comment.