diff options
Diffstat (limited to 'matrix-stdlib/src/io.rs')
-rw-r--r-- | matrix-stdlib/src/io.rs | 175 |
1 files changed, 0 insertions, 175 deletions
diff --git a/matrix-stdlib/src/io.rs b/matrix-stdlib/src/io.rs deleted file mode 100644 index d72248c..0000000 --- a/matrix-stdlib/src/io.rs +++ /dev/null @@ -1,175 +0,0 @@ -use std::{io::{self, Read, Write}, cell::RefCell, fs::OpenOptions, rc::Rc}; - -use matrix::{value::Value, self, vm::Vm, Result, unpack_varargs, iter, unpack_args}; -use matrix_macros::native_func; -use crate::{error, VmArgs}; - -#[native_func(0..)] -fn print(_: VmArgs, args: Vec<Value>) -> Result<Value> { - let ([], varags) = unpack_varargs!(args); - for (i, value) in varags.into_iter().enumerate() { - if i != 0 { - print!(" "); - } - print!("{value}"); - } - Ok(Value::Nil) -} - -#[native_func(0..)] -fn println(_: VmArgs, args: Vec<Value>) -> Result<Value> { - let ([], varags) = unpack_varargs!(args); - for (i, value) in varags.into_iter().enumerate() { - if i != 0 { - print!(" "); - } - print!("{value}"); - } - print!("\n"); - Ok(Value::Nil) -} - -#[native_func(0)] -fn readln(_: VmArgs, _: Vec<Value>) -> Result<Value> { - let mut input = String::new(); - match io::stdin().read_line(&mut input) { - Ok(_) => { - match input.pop() { - Some(c) if c == '\n' => {}, - Some(c) => input.push(c), - None => {} - }; - Ok(Value::String(input.into())) - }, - Err(err) => error!("cant read from stdin: {err}") - } -} - -#[native_func(1)] -fn input(_: VmArgs, args: Vec<Value>) -> Result<Value> { - let [prompt] = unpack_args!(args); - let mut input = String::new(); - print!("{prompt}"); - let _ = io::stdout().flush(); - match io::stdin().read_line(&mut input) { - Ok(_) => { - match input.pop() { - Some(c) if c == '\n' => {}, - Some(c) => input.push(c), - None => {} - }; - Ok(Value::String(input.into())) - }, - Err(err) => error!("cant read from stdin: {err}") - } -} - -#[native_func(0)] -fn readlines(_: VmArgs, _: Vec<Value>) -> Result<Value> { - let lines = RefCell::new(io::stdin().lines()); - Ok(iter!(move |_,_| { - match lines.borrow_mut().next() { - Some(Ok(line)) => Ok(Value::String(line.into())), - _ => Ok(Value::Nil) - } - })) -} - -#[native_func(2)] -fn file_open(_: VmArgs, args: Vec<Value>) -> Result<Value> { - let [path, mode] = unpack_args!(args); - let Value::String(mode) = mode else { - return error!("open mode must be a string") - }; - let Value::String(path) = path else { - return error!("open path must be a string") - }; - let file = match mode.as_ref() { - "r" => OpenOptions::new().read(true).open(path.as_ref()), - "w" => OpenOptions::new().write(true).create(true).truncate(true).open(path.as_ref()), - "a" => OpenOptions::new().write(true).create(true).append(true).open(path.as_ref()), - "r+" => OpenOptions::new().read(true).write(true).open(path.as_ref()), - "w+" => OpenOptions::new().read(true).write(true).create(true).truncate(true).open(path.as_ref()), - "a+" => OpenOptions::new().read(true).write(true).create(true).append(true).open(path.as_ref()), - _ => return error!("invalid open mode: {mode}") - }; - - match file { - Ok(file) => Ok(Value::File(Rc::new(RefCell::new(file)))), - Err(err) => return error!("cannot open '{path}': {err}") - } -} - -#[native_func(1)] -fn file_read(_: VmArgs, args: Vec<Value>) -> Result<Value> { - let [file] = unpack_args!(args); - let Value::File(file) = file else { - return error!("file read requires a file") - }; - let mut contents = String::new(); - if let Err(err) = file.try_borrow_mut().unwrap().read_to_string(&mut contents) { - return error!("cannot read file: '{err}'") - }; - Ok(Value::String(contents.into())) -} - -#[native_func(1)] -fn file_lines(_: VmArgs, args: Vec<Value>) -> Result<Value> { - let [file] = unpack_args!(args); - let Value::File(file) = file else { - return error!("file read requires a file") - }; - let mut contents = String::new(); - if let Err(err) = file.try_borrow_mut().unwrap().read_to_string(&mut contents) { - return error!("cannot read file: '{err}'") - }; - let lines: Vec<Rc<str>> = contents.split_inclusive("\n").map(|s| Rc::from(s)).collect(); - let lines = RefCell::new(lines.into_iter()); - Ok(iter!(move |_,_| { - match lines.borrow_mut().next() { - Some(line) => Ok(Value::String(line)), - None => Ok(Value::Nil) - } - })) -} - -#[native_func(2)] -fn file_write(_: VmArgs, args: Vec<Value>) -> Result<Value> { - let [file, content] = unpack_args!(args); - let Value::File(file) = file else { - return error!("file write requires a file") - }; - let content = format!("{content}"); - if let Err(err) = file.try_borrow_mut().unwrap().write_all(content.as_bytes()) { - return error!("cannot write file: '{err}'") - }; - Ok(Value::Nil) -} - -#[native_func(0..)] -fn throw(_: VmArgs, args: Vec<Value>) -> Result<Value> { - let ([], varargs) = unpack_varargs!(args); - - let mut str = String::new(); - for (i, v) in varargs.into_iter().enumerate() { - if i != 0 { - str.push_str(" "); - } - str.push_str(&format!("{v}")); - } - - error!("{str}") -} - -pub fn load(vm: &mut Vm) { - vm.load_global_fn(print(), "print"); - vm.load_global_fn(println(), "println"); - vm.load_global_fn(readln(), "readln"); - vm.load_global_fn(input(), "input"); - vm.load_global_fn(readlines(), "readlines"); - vm.load_global_fn(file_open(), "file_open"); - vm.load_global_fn(file_read(), "file_read"); - vm.load_global_fn(file_lines(), "file_lines"); - vm.load_global_fn(file_write(), "file_write"); - vm.load_global_fn(throw(), "throw"); -} |