diff options
Diffstat (limited to 'crates/sloth_vm/src/sloth_std')
| -rw-r--r-- | crates/sloth_vm/src/sloth_std/mod.rs | 24 | ||||
| -rw-r--r-- | crates/sloth_vm/src/sloth_std/rand.rs | 39 | ||||
| -rw-r--r-- | crates/sloth_vm/src/sloth_std/stdio.rs | 51 |
3 files changed, 114 insertions, 0 deletions
diff --git a/crates/sloth_vm/src/sloth_std/mod.rs b/crates/sloth_vm/src/sloth_std/mod.rs new file mode 100644 index 0000000..86611d7 --- /dev/null +++ b/crates/sloth_vm/src/sloth_std/mod.rs @@ -0,0 +1,24 @@ +use std::collections::HashMap; + +use once_cell::sync::Lazy; + +use crate::native::NativeFunction; + +pub mod rand; +pub mod stdio; + +pub static NATIVE_LIBRARY: Lazy<HashMap<&'static str, NativeFunction>> = Lazy::new(|| { + let mut map = HashMap::new(); + + // rand + map.insert("rand$gen", rand::GEN_FUNCTION); + map.insert("rand$gen_range", rand::GEN_RANGE_FUNCTION); + + // stdio + map.insert("write", stdio::WRITE_FUNCTION); + map.insert("read", stdio::READ_FUNCTION); + + // filesystem + + map +}); diff --git a/crates/sloth_vm/src/sloth_std/rand.rs b/crates/sloth_vm/src/sloth_std/rand.rs new file mode 100644 index 0000000..bae0606 --- /dev/null +++ b/crates/sloth_vm/src/sloth_std/rand.rs @@ -0,0 +1,39 @@ +use rand::Rng; + +use crate::native::{self, NativeFunction, NativeFunctionResult}; +use crate::value::Primitive; +use crate::value::Primitive::{Float, Integer}; +use crate::VM; + +fn gen(_vm: &mut VM, _args: &[Primitive]) -> NativeFunctionResult { + let value = rand::thread_rng().gen_range(0.0..1.0); + + Ok(Float(value)) +} + +pub const GEN_FUNCTION: NativeFunction = NativeFunction { + name: "rand$gen", + function: gen, + arity: 0, + returns_value: true, +}; + +fn gen_range(_vm: &mut VM, args: &[Primitive]) -> NativeFunctionResult { + let min = args.get(0).cloned(); + let max = args.get(1).cloned(); + + let (Some(Integer(min)), Some(Integer(max))) = (min, max) else { + return Err(native::Error::InvalidArgument); + }; + + let value = rand::thread_rng().gen_range(min..max); + + Ok(Integer(value)) +} + +pub const GEN_RANGE_FUNCTION: NativeFunction = NativeFunction { + name: "rand$gen_range", + function: gen_range, + arity: 2, + returns_value: true, +}; diff --git a/crates/sloth_vm/src/sloth_std/stdio.rs b/crates/sloth_vm/src/sloth_std/stdio.rs new file mode 100644 index 0000000..a743ad1 --- /dev/null +++ b/crates/sloth_vm/src/sloth_std/stdio.rs @@ -0,0 +1,51 @@ +use std::io::{stdin, BufRead}; + +use crate::native::{self, NativeFunction, NativeFunctionResult}; +use crate::value::{Object, ObjectType, Primitive}; +use crate::VM; + +fn write(vm: &mut VM, args: &[Primitive]) -> NativeFunctionResult { + let Some(Primitive::Object(ptr)) = args.get(0).cloned() else { + return Err(native::Error::InvalidArgument); + }; + + let object = vm + .objects() + .get(ptr as usize) + .ok_or(native::Error::InvalidArgument)?; + + let ObjectType::String(str) = &object.typ else { + return Err(native::Error::InvalidArgument); + }; + + println!("{str}"); + + Ok(Primitive::Empty) +} + +pub const WRITE_FUNCTION: NativeFunction = NativeFunction { + name: "write", + function: write, + arity: 1, + returns_value: false, +}; + +fn read(vm: &mut VM, _args: &[Primitive]) -> NativeFunctionResult { + let mut line = String::new(); + stdin() + .lock() + .read_line(&mut line) + .map_err(|it| native::Error::Unknown(it.to_string()))?; + + let object = Object::new(ObjectType::String(line)); + let ptr = vm.objects_mut().allocate(object); + + Ok(Primitive::Object(ptr as u32)) +} + +pub const READ_FUNCTION: NativeFunction = NativeFunction { + name: "read", + function: read, + arity: 0, + returns_value: true, +}; |
