forked from Orchid/orchid
105 lines
2.6 KiB
Rust
105 lines
2.6 KiB
Rust
use super::flow::IOCmdHandlePack;
|
|
use super::instances::{
|
|
BRead, ReadCmd, SRead, SinkHandle, SourceHandle, WriteCmd,
|
|
};
|
|
use crate::foreign::cps_box::init_cps;
|
|
use crate::foreign::{Atom, Atomic};
|
|
use crate::representations::OrcString;
|
|
use crate::systems::stl::Binary;
|
|
use crate::systems::RuntimeError;
|
|
use crate::{ast, define_fn, ConstTree, Interner, Primitive};
|
|
|
|
define_fn! {
|
|
ReadString = |x| Ok(init_cps(3, IOCmdHandlePack{
|
|
cmd: ReadCmd::RStr(SRead::All),
|
|
handle: x.try_into()?
|
|
}))
|
|
}
|
|
define_fn! {
|
|
ReadLine = |x| Ok(init_cps(3, IOCmdHandlePack{
|
|
cmd: ReadCmd::RStr(SRead::Line),
|
|
handle: x.try_into()?
|
|
}))
|
|
}
|
|
define_fn! {
|
|
ReadBin = |x| Ok(init_cps(3, IOCmdHandlePack{
|
|
cmd: ReadCmd::RBytes(BRead::All),
|
|
handle: x.try_into()?
|
|
}))
|
|
}
|
|
define_fn! {
|
|
ReadBytes {
|
|
stream: SourceHandle,
|
|
n: u64
|
|
} => Ok(init_cps(3, IOCmdHandlePack{
|
|
cmd: ReadCmd::RBytes(BRead::N((*n).try_into().unwrap())),
|
|
handle: *stream
|
|
}))
|
|
}
|
|
define_fn! {
|
|
ReadUntil {
|
|
stream: SourceHandle,
|
|
pattern: u64
|
|
} => {
|
|
let delim = (*pattern).try_into().map_err(|_| RuntimeError::ext(
|
|
"greater than 255".to_string(),
|
|
"converting number to byte"
|
|
))?;
|
|
Ok(init_cps(3, IOCmdHandlePack{
|
|
cmd: ReadCmd::RBytes(BRead::Until(delim)),
|
|
handle: *stream
|
|
}))
|
|
}
|
|
}
|
|
define_fn! {
|
|
WriteStr {
|
|
stream: SinkHandle,
|
|
string: OrcString
|
|
} => Ok(init_cps(3, IOCmdHandlePack {
|
|
cmd: WriteCmd::WStr(string.get_string()),
|
|
handle: *stream,
|
|
}))
|
|
}
|
|
define_fn! {
|
|
WriteBin {
|
|
stream: SinkHandle,
|
|
bytes: Binary
|
|
} => Ok(init_cps(3, IOCmdHandlePack {
|
|
cmd: WriteCmd::WBytes(bytes.clone()),
|
|
handle: *stream
|
|
}))
|
|
}
|
|
define_fn! {
|
|
Flush = |x| Ok(init_cps(3, IOCmdHandlePack {
|
|
cmd: WriteCmd::Flush,
|
|
handle: x.try_into()?
|
|
}))
|
|
}
|
|
|
|
pub fn io_bindings(
|
|
i: &Interner,
|
|
std_streams: impl IntoIterator<Item = (&'static str, Box<dyn Atomic>)>,
|
|
) -> ConstTree {
|
|
ConstTree::namespace(
|
|
[i.i("system"), i.i("io")],
|
|
ConstTree::tree([
|
|
(i.i("read_string"), ConstTree::xfn(ReadString)),
|
|
(i.i("read_line"), ConstTree::xfn(ReadLine)),
|
|
(i.i("read_bin"), ConstTree::xfn(ReadBin)),
|
|
(i.i("read_n_bytes"), ConstTree::xfn(ReadBytes)),
|
|
(i.i("read_until"), ConstTree::xfn(ReadUntil)),
|
|
(i.i("write_str"), ConstTree::xfn(WriteStr)),
|
|
(i.i("write_bin"), ConstTree::xfn(WriteBin)),
|
|
(i.i("flush"), ConstTree::xfn(Flush)),
|
|
]) + ConstTree::Tree(
|
|
std_streams
|
|
.into_iter()
|
|
.map(|(n, at)| {
|
|
let expr = ast::Clause::P(Primitive::Atom(Atom(at))).into_expr();
|
|
(i.i(n), ConstTree::Const(expr))
|
|
})
|
|
.collect(),
|
|
),
|
|
)
|
|
}
|