Skip to content

Commit 2c9acbf

Browse files
committed
rand works for doubles
1 parent b129bc6 commit 2c9acbf

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

src/environment.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ impl Environment {
7474
let subtract_fn = rust_core::SubtractFn {};
7575
let multiply_fn = rust_core::MultiplyFn {};
7676
let divide_fn = rust_core::DivideFn {};
77+
let rand_fn = rust_core::RandFn {};
7778
let str_fn = rust_core::StrFn {};
7879
let do_fn = rust_core::DoFn {};
7980
let nth_fn = rust_core::NthFn {};
@@ -105,6 +106,7 @@ impl Environment {
105106
environment.insert(Symbol::intern("-"), subtract_fn.to_rc_value());
106107
environment.insert(Symbol::intern("*"), multiply_fn.to_rc_value());
107108
environment.insert(Symbol::intern("_slash_"), divide_fn.to_rc_value());
109+
environment.insert(Symbol::intern("rand"), rand_fn.to_rc_value());
108110
environment.insert(Symbol::intern("let"), let_macro.to_rc_value());
109111
environment.insert(Symbol::intern("str"), str_fn.to_rc_value());
110112
environment.insert(Symbol::intern("quote"), quote_macro.to_rc_value());

src/rust_core.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ pub use self::_divide_::*;
2222
pub(crate) mod _multiply_;
2323
pub use self::_multiply_::*;
2424

25+
pub(crate) mod rand;
26+
pub use self::rand::*;
27+
28+
2529
// string
2630
pub(crate) mod str;
2731
pub use self::str::*;

src/rust_core/rand.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use crate::ifn::IFn;
2+
use crate::value::{Value, ToValue};
3+
use std::rc::Rc;
4+
use rand::{random, thread_rng, Rng};
5+
use crate::error_message;
6+
use std::any::Any;
7+
8+
/// (rand) or (rand n)
9+
///
10+
#[derive(Debug, Clone)]
11+
pub struct RandFn {}
12+
impl ToValue for RandFn {
13+
fn to_value(&self) -> Value {
14+
Value::IFn(Rc::new(self.clone()))
15+
}
16+
}
17+
impl IFn for RandFn {
18+
fn invoke(&self, args: Vec<Rc<Value>>) -> Value {
19+
match args.len() {
20+
0 => Value::F64(thread_rng().gen()),
21+
1 => {
22+
let arg = args.get(0).unwrap().to_value();
23+
match arg {
24+
Value::I32(i_) => Value::F64(thread_rng().gen_range(0.0, i_ as f64)),
25+
Value::F64(f_) => Value::F64(thread_rng().gen_range(0.0, f_)),
26+
_ => Value::Condition(format!( // TODO: what error message should be returned regarding using typetags?
27+
"Type mismatch; Expecting: (i32 | i64 | f32 | f64), Found: {}",
28+
arg.type_tag()
29+
))
30+
}
31+
},
32+
_ => error_message::wrong_varg_count(&[0, 1], args.len())
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)