diff options
| author | nic-gaffney <gaffney_nic@protonmail.com> | 2023-04-14 03:20:23 -0500 |
|---|---|---|
| committer | nic-gaffney <gaffney_nic@protonmail.com> | 2023-04-14 03:20:23 -0500 |
| commit | f6e14f4b2b15b0ace8ed312252ae107f139bd33d (patch) | |
| tree | 34d844e1c4f1be2c95ef87e6363a76b3502bb40f | |
| parent | 97b7cd10d2bec408cc237e13c61562c810d8fd29 (diff) | |
| download | sloth-f6e14f4b2b15b0ace8ed312252ae107f139bd33d.tar.gz | |
Terminal and file stuff
| -rw-r--r-- | crates/sloth_vm/src/sloth_std/file.rs | 73 | ||||
| -rw-r--r-- | crates/sloth_vm/src/sloth_std/mod.rs | 9 | ||||
| -rw-r--r-- | crates/sloth_vm/src/sloth_std/stdio.rs | 28 | ||||
| -rw-r--r-- | crates/sloth_vm/src/sloth_std/term.rs | 32 |
4 files changed, 141 insertions, 1 deletions
diff --git a/crates/sloth_vm/src/sloth_std/file.rs b/crates/sloth_vm/src/sloth_std/file.rs new file mode 100644 index 0000000..b6c8adf --- /dev/null +++ b/crates/sloth_vm/src/sloth_std/file.rs @@ -0,0 +1,73 @@ +use std::fs; + +use crate::native::{self, NativeFunction, NativeFunctionResult}; +use crate::value::{Object, ObjectType, Primitive}; +use crate::VM; + +fn file_read(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); + }; + + let contents = fs::read_to_string(str).expect("IO Error: Failed to read file!"); + + let object = Object::new(ObjectType::String(contents)); + let ptr = vm.objects_mut().allocate(object); + + Ok(Primitive::Object(ptr as u32)) +} + +pub const FILE_READ: NativeFunction = NativeFunction { + name: "file$read", + function: file_read, + arity: 1, + returns_value: true, +}; + +fn file_write(vm: &mut VM, args: &[Primitive]) -> NativeFunctionResult { + let Some(Primitive::Object(path_ptr)) = args.get(0).cloned() else { + return Err(native::Error::InvalidArgument); + }; + + let path_object = vm + .objects() + .get(path_ptr as usize) + .ok_or(native::Error::InvalidArgument)?; + + let ObjectType::String(path) = &path_object.typ else { + return Err(native::Error::InvalidArgument); + }; + + let Some(Primitive::Object(content_ptr)) = args.get(1).cloned() else { + return Err(native::Error::InvalidArgument); + }; + + let content_object = vm + .objects() + .get(content_ptr as usize) + .ok_or(native::Error::InvalidArgument)?; + + let ObjectType::String(content) = &content_object.typ else { + return Err(native::Error::InvalidArgument); + }; + + let _ = fs::write(path, content); + + Ok(Primitive::Empty) +} + +pub const FILE_WRITE: NativeFunction = NativeFunction { + name: "file$write", + function: file_write, + arity: 2, + returns_value: false, +}; diff --git a/crates/sloth_vm/src/sloth_std/mod.rs b/crates/sloth_vm/src/sloth_std/mod.rs index 86611d7..b40fb9a 100644 --- a/crates/sloth_vm/src/sloth_std/mod.rs +++ b/crates/sloth_vm/src/sloth_std/mod.rs @@ -4,8 +4,10 @@ use once_cell::sync::Lazy; use crate::native::NativeFunction; +pub mod file; pub mod rand; pub mod stdio; +pub mod term; pub static NATIVE_LIBRARY: Lazy<HashMap<&'static str, NativeFunction>> = Lazy::new(|| { let mut map = HashMap::new(); @@ -16,9 +18,16 @@ pub static NATIVE_LIBRARY: Lazy<HashMap<&'static str, NativeFunction>> = Lazy::n // stdio map.insert("write", stdio::WRITE_FUNCTION); + map.insert("writeln", stdio::WRITELN_FUNCTION); map.insert("read", stdio::READ_FUNCTION); + // term + map.insert("term$clear", term::TERM_CLEAR); + map.insert("term$setpos", term::TERM_SETPOS); + // filesystem + map.insert("file$read", file::FILE_READ); + map.insert("file$write", file::FILE_WRITE); map }); diff --git a/crates/sloth_vm/src/sloth_std/stdio.rs b/crates/sloth_vm/src/sloth_std/stdio.rs index a743ad1..75029bd 100644 --- a/crates/sloth_vm/src/sloth_std/stdio.rs +++ b/crates/sloth_vm/src/sloth_std/stdio.rs @@ -18,7 +18,7 @@ fn write(vm: &mut VM, args: &[Primitive]) -> NativeFunctionResult { return Err(native::Error::InvalidArgument); }; - println!("{str}"); + print!("{str}"); Ok(Primitive::Empty) } @@ -30,6 +30,32 @@ pub const WRITE_FUNCTION: NativeFunction = NativeFunction { returns_value: false, }; +fn writeln(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 WRITELN_FUNCTION: NativeFunction = NativeFunction { + name: "writeln", + function: writeln, + arity: 1, + returns_value: false, +}; + fn read(vm: &mut VM, _args: &[Primitive]) -> NativeFunctionResult { let mut line = String::new(); stdin() diff --git a/crates/sloth_vm/src/sloth_std/term.rs b/crates/sloth_vm/src/sloth_std/term.rs new file mode 100644 index 0000000..cffa1e8 --- /dev/null +++ b/crates/sloth_vm/src/sloth_std/term.rs @@ -0,0 +1,32 @@ +use crate::native::{self, NativeFunction, NativeFunctionResult}; +use crate::value::Primitive; +use crate::value::Primitive::Integer; +use crate::VM; + +pub const TERM_CLEAR: NativeFunction = NativeFunction { + name: "term$clear", + function: |_vm, _args| { + print!("\x1b[2J\x1b[H"); + Ok(Primitive::Empty) + }, + arity: 0, + returns_value: false, +}; + +fn term_setpos(_vm: &mut VM, args: &[Primitive]) -> NativeFunctionResult { + let x = args.get(0).cloned(); + let y = args.get(1).cloned(); + + let (Some(Integer(x)), Some(Integer(y))) = (x, y) else { + return Err(native::Error::InvalidArgument); + }; + print!("\x1b[{x};{y}H"); + Ok(Primitive::Empty) +} + +pub const TERM_SETPOS: NativeFunction = NativeFunction { + name: "term$setpos", + function: term_setpos, + arity: 2, + returns_value: false, +}; |
