Skip to content

Add the rand module #100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 22, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions .idea/rune.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion crates/rune-modules/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,21 @@ Native modules for Rune, an embeddable dynamic programming language for Rust.
"""

[features]
full = ["time", "http", "json", "toml", "fs", "process", "signal"]
full = ["time", "http", "json", "toml", "fs", "process", "signal", "rand"]
time = ["tokio", "tokio/time"]
fs = ["tokio", "tokio/fs"]
http = ["reqwest"]
json = ["serde_json"]
process = ["tokio/process"]
signal = ["tokio/signal"]
rand = ["nanorand"]

[dependencies]
reqwest = {version = "0.10.7", optional = true, default-features = false, features = ["rustls-tls", "gzip", "json"]}
tokio = {version = "0.2.22", optional = true}
serde_json = {version = "1.0.57", optional = true}
toml = {version = "0.5.6", optional = true}
nanorand = {version = "0.4.0", optional = true}

runestick = {version = "0.6.16", path = "../runestick"}

Expand Down
12 changes: 9 additions & 3 deletions crates/rune-modules/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
//! * [fs]
//! * [process]
//! * [signal]
//! * [rand]
//!
//! ## Features
//!
Expand All @@ -60,9 +61,10 @@
//! * `json` for the [json module][json]
//! * `toml` for the [toml module][toml]
//! * `time` for the [time module][time]
//! * `fs` for the [fs module]][fs]
//! * `process` for the [process module]][process]
//! * `signal` for the [process module]][signal]
//! * `fs` for the [fs module][fs]
//! * `process` for the [process module][process]
//! * `signal` for the [signal module][signal]
//! * `rand` for the [rand module][rand]
//!
//! [http]: https://docs.rs/rune-modules/0/rune_modules/http/
//! [json]: https://docs.rs/rune-modules/0/rune_modules/json/
Expand All @@ -71,6 +73,7 @@
//! [fs]: https://docs.rs/rune-modules/0/rune_modules/fs/
//! [process]: https://docs.rs/rune-modules/0/rune_modules/process/
//! [signal]: https://docs.rs/rune-modules/0/rune_modules/signal/
//! [rand]: https://docs.rs/rune-modules/0/rune_modules/rand/

#[cfg(feature = "http")]
pub mod http;
Expand All @@ -92,3 +95,6 @@ pub mod process;

#[cfg(feature = "signal")]
pub mod signal;

#[cfg(feature = "rand")]
pub mod rand;
131 changes: 131 additions & 0 deletions crates/rune-modules/src/rand.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#![allow(dead_code)]
//! The native `rand` module for the [Rune Language].
//!
//! [Rune Language]: https://rune-rs.github.io
//!
//! ## Usage
//!
//! Add the following to your `Cargo.toml`:
//!
//! ```toml
//! rune-modules = {version = "0.6.16", features = ["rand"]}
//! ```
//!
//! Install it into your context:
//!
//! ```rust
//! # fn main() -> runestick::Result<()> {
//! let mut context = runestick::Context::with_default_modules()?;
//! context.install(&rune_modules::rand::module()?)?;
//! # Ok(())
//! # }
//! ```
//!
//! Use it in Rune:
//!
//! ```rust,ignore
//! fn main() {
//! let rng = rand::WyRand::new();
//! let rand_int = rng.int();
//! println(`Random int: {rand_int}`);
//! let rand_int_range = rng.int_range(-100, 100);
//! println(`Random int between -100 and 100: {rand_int_range}`);
//! }
//! ```

use nanorand::RNG;
use runestick::{Any, ContextError, Module, Value};

/// Construct the `rand` module.
pub fn module() -> Result<Module, ContextError> {
let mut module = Module::new(&["rand"]);

module.ty::<WyRand>()?;
module.function(&["WyRand", "new"], WyRand::new)?;
module.function(&["WyRand", "new_seed"], WyRand::new_seed)?;
module.inst_fn("int", WyRand::int)?;
module.inst_fn("int_range", WyRand::int_range)?;

module.ty::<Pcg64>()?;
module.function(&["Pcg64", "new"], Pcg64::new)?;
module.function(&["Pcg64", "new_seed"], Pcg64::new_seed)?;
module.inst_fn("int", Pcg64::int)?;
module.inst_fn("int_range", Pcg64::int_range)?;

module.function(&["int"], int)?;
module.function(&["int_range"], int_range)?;

Ok(module)
}

#[derive(Any)]
struct WyRand {
inner: nanorand::WyRand,
}

impl WyRand {
/// Create a new RNG instance.
fn new() -> Self {
Self {
inner: nanorand::WyRand::new(),
}
}

/// Create a new RNG instance, using a custom seed.
fn new_seed(seed: i64) -> Self {
Self {
inner: nanorand::WyRand::new_seed(seed as u64),
}
}

/// Generate a random integer
fn int(&mut self) -> Value {
Value::Integer(self.inner.generate::<i64>())
}

/// Generate a random integer within the specified range
fn int_range(&mut self, lower: i64, upper: i64) -> Value {
Value::Integer(self.inner.generate_range::<i64>(lower, upper))
}
}

#[derive(Any)]
struct Pcg64 {
inner: nanorand::Pcg64,
}

impl Pcg64 {
/// Create a new RNG instance.
fn new() -> Self {
Self {
inner: nanorand::Pcg64::new(),
}
}

/// Create a new RNG instance, using a custom seed.
fn new_seed(seed: i64) -> Self {
Self {
inner: nanorand::Pcg64::new_seed(seed as u128),
}
}

/// Generate a random integer
fn int(&mut self) -> Value {
Copy link
Collaborator

@udoprog udoprog Sep 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FTR, these can simply return i64. Conversion is handled by Rune (for any type implementing the ToValue trait). Returning a Value doesn't hurt though!

Value::Integer(self.inner.generate::<i64>())
}

/// Generate a random integer within the specified range
fn int_range(&mut self, lower: i64, upper: i64) -> Value {
Value::Integer(self.inner.generate_range::<i64>(lower, upper))
}
}

fn int() -> runestick::Result<Value> {
Ok(Value::Integer(nanorand::WyRand::new().generate::<i64>()))
}

fn int_range(lower: i64, upper: i64) -> runestick::Result<Value> {
Ok(Value::Integer(
nanorand::WyRand::new().generate_range::<i64>(lower, upper),
))
}
2 changes: 1 addition & 1 deletion crates/rune-wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ js-sys = "0.3.45"

rune = {version = "0.6.16", path = "../rune", features = []}
rune-macros = {version = "0.6.16", path = "../rune-macros"}
rune-modules = {version = "0.6.16", path = "../rune-modules", features = ["json", "toml"]}
rune-modules = {version = "0.6.16", path = "../rune-modules", features = ["json", "toml", "rand"]}
runestick = {version = "0.6.16", path = "../runestick"}

[dependencies.web-sys]
Expand Down
1 change: 1 addition & 0 deletions crates/rune-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ fn setup_context() -> Result<runestick::Context, ContextError> {
context.install(&http::module()?)?;
context.install(&rune_modules::json::module()?)?;
context.install(&rune_modules::toml::module()?)?;
context.install(&rune_modules::rand::module()?)?;
Ok(context)
}

Expand Down
1 change: 1 addition & 0 deletions crates/rune/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ pub fn default_context() -> Result<runestick::Context, runestick::ContextError>
context.install(&rune_modules::process::module()?)?;
context.install(&rune_modules::fs::module()?)?;
context.install(&rune_modules::signal::module()?)?;
context.install(&rune_modules::rand::module()?)?;
}

Ok(context)
Expand Down
15 changes: 15 additions & 0 deletions scripts/rand.rn
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use rand;

fn main() {
let rng = rand::WyRand::new();
let rand_int = rng.int();
println(`Random int: {rand_int}`);
let rand_int_range = rng.int_range(-100, 100);
println(`Random int between -100 and 100: {rand_int_range}`);

let rng = rand::Pcg64::new();
let rand_int = rng.int();
println(`Random int: {rand_int}`);
let rand_int_range = rng.int_range(-100, 100);
println(`Random int between -100 and 100: {rand_int_range}`);
}