talc/talc-std/src/io.rs

64 lines
1.8 KiB
Rust

use std::{io::Write, time::{SystemTime, UNIX_EPOCH}};
use talc_lang::{value::Value, vmcall, Vm, exception::{throw, Result}};
use talc_macros::native_func;
use crate::{unpack_args, SYM_IO_ERROR};
#[native_func(1)]
pub fn print(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
if let Err(e) = write!(std::io::stdout(), "{}", args[1]) {
throw!(*SYM_IO_ERROR, "{e}")
}
Ok(Value::Nil)
}
#[native_func(1)]
pub fn println(_: &mut Vm, args: Vec<Value>) -> Result<Value> {
if let Err(e) = writeln!(std::io::stdout(), "{}", args[1]) {
throw!(*SYM_IO_ERROR, "{e}")
}
Ok(Value::Nil)
}
#[native_func(0)]
pub fn readln(_: &mut Vm, _: Vec<Value>) -> Result<Value> {
let mut buf = String::new();
if let Err(e) = std::io::stdin().read_line(&mut buf) {
throw!(*SYM_IO_ERROR, "{e}")
}
Ok(buf.into())
}
#[native_func(0)]
pub fn time(_: &mut Vm, _: Vec<Value>) -> Result<Value> {
let time = SystemTime::now().duration_since(UNIX_EPOCH).expect("time went backwards");
Ok(time.as_secs_f64().into())
}
#[native_func(0)]
pub fn time_ns(_: &mut Vm, _: Vec<Value>) -> Result<Value> {
let time = SystemTime::now().duration_since(UNIX_EPOCH).expect("time went backwards");
Ok(vec![(time.as_secs() as i64).into(), (time.subsec_nanos() as i64).into()].into())
}
#[native_func(1)]
pub fn time_fn(vm: &mut Vm, args: Vec<Value>) -> Result<Value> {
let [_, func] = unpack_args!(args);
let t0 = SystemTime::now();
vmcall!(vm; func)?;
let tf = SystemTime::now();
let time = tf.duration_since(t0).expect("time went backwards");
Ok(time.as_secs_f64().into())
}
pub fn load(vm: &mut Vm) {
vm.set_global_name("print", print().into());
vm.set_global_name("println", println().into());
vm.set_global_name("readln", readln().into());
vm.set_global_name("time", time().into());
vm.set_global_name("time_ns", time_ns().into());
vm.set_global_name("time_fn", time_fn().into());
}