Added directfs

Added a very rudimentary file I/O system suitable for experimenting
with the language further. A better one will be designed when we have
sensible error management.
This commit is contained in:
2023-09-17 16:37:39 +01:00
parent 1078835e8b
commit 7396078304
84 changed files with 563 additions and 721 deletions

View File

@@ -1,10 +1,11 @@
use super::flow::IOCmdHandlePack;
use super::instances::{
BRead, ReadCmd, SRead, SinkHandle, SourceHandle, WriteCmd,
BRead, ReadCmd, SRead, WriteCmd, Sink, Source,
};
use crate::foreign::cps_box::init_cps;
use crate::foreign::{Atom, Atomic};
use crate::representations::OrcString;
use crate::systems::scheduler::SharedHandle;
use crate::systems::stl::Binary;
use crate::systems::RuntimeError;
use crate::{ast, define_fn, ConstTree, Interner, Primitive};
@@ -22,17 +23,13 @@ define_fn! {
cmd: ReadCmd::RBytes(BRead::All),
handle: x.downcast()?
}));
ReadBytes {
stream: SourceHandle,
n: u64
} => Ok(init_cps(3, IOCmdHandlePack{
cmd: ReadCmd::RBytes(BRead::N(n.try_into().unwrap())),
handle: stream.clone()
}));
ReadUntil {
stream: SourceHandle,
pattern: u64
} => {
ReadBytes { stream: SharedHandle<Source>, n: u64 } => {
Ok(init_cps(3, IOCmdHandlePack{
cmd: ReadCmd::RBytes(BRead::N(n.try_into().unwrap())),
handle: stream.clone()
}))
};
ReadUntil { stream: SharedHandle<Source>, pattern: u64 } => {
let delim = pattern.try_into().map_err(|_| RuntimeError::ext(
"greater than 255".to_string(),
"converting number to byte"
@@ -42,20 +39,18 @@ define_fn! {
handle: stream
}))
};
WriteStr {
stream: SinkHandle,
string: OrcString
} => Ok(init_cps(3, IOCmdHandlePack {
cmd: WriteCmd::WStr(string.get_string()),
handle: stream.clone(),
}));
WriteBin {
stream: SinkHandle,
bytes: Binary
} => Ok(init_cps(3, IOCmdHandlePack {
cmd: WriteCmd::WBytes(bytes),
handle: stream.clone(),
}));
WriteStr { stream: SharedHandle<Sink>, string: OrcString } => {
Ok(init_cps(3, IOCmdHandlePack {
cmd: WriteCmd::WStr(string.get_string()),
handle: stream.clone(),
}))
};
WriteBin { stream: SharedHandle<Sink>, bytes: Binary } => {
Ok(init_cps(3, IOCmdHandlePack {
cmd: WriteCmd::WBytes(bytes),
handle: stream.clone(),
}))
};
Flush = |x| Ok(init_cps(3, IOCmdHandlePack {
cmd: WriteCmd::Flush,
handle: x.downcast()?

View File

@@ -9,12 +9,11 @@ use crate::systems::scheduler::{Canceller, SharedHandle};
use crate::systems::stl::Binary;
use crate::Literal;
/// Any type that we can read controlled amounts of data from
pub type Source = BufReader<Box<dyn Read + Send>>;
/// Any type that we can write data to
pub type Sink = Box<dyn Write + Send>;
pub type SourceHandle = SharedHandle<Source>;
pub type SinkHandle = SharedHandle<Sink>;
/// String reading command
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum SRead {
@@ -39,7 +38,7 @@ pub enum ReadCmd {
impl IOCmd for ReadCmd {
type Stream = Source;
type Result = ReadResult;
type Handle = SourceHandle;
type Handle = SharedHandle<Source>;
// This is a buggy rule, check manually
#[allow(clippy::read_zero_byte_vec)]
@@ -82,22 +81,21 @@ impl ReadResult {
pub fn dispatch(self, succ: ExprInst, fail: ExprInst) -> Vec<ExprInst> {
match self {
ReadResult::RBin(_, Err(e)) | ReadResult::RStr(_, Err(e)) => {
vec![call(fail, vec![wrap_io_error(e)]).wrap()]
vec![call(fail, [wrap_io_error(e)]).wrap()]
},
ReadResult::RBin(_, Ok(bytes)) => {
let arg = Binary(Arc::new(bytes)).atom_cls().wrap();
vec![call(succ, vec![arg]).wrap()]
vec![call(succ, [arg]).wrap()]
},
ReadResult::RStr(_, Ok(text)) => {
vec![call(succ, vec![Literal::Str(text.into()).into()]).wrap()]
vec![call(succ, [Literal::Str(text.into()).into()]).wrap()]
},
}
}
}
/// Placeholder function for an eventual conversion from [io::Error] to Orchid
/// data
fn wrap_io_error(_e: io::Error) -> ExprInst { Literal::Uint(0u64).into() }
/// Function to convert [io::Error] to Orchid data
pub fn wrap_io_error(_e: io::Error) -> ExprInst { Literal::Uint(0u64).into() }
/// Writing command (string or binary)
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -109,7 +107,7 @@ pub enum WriteCmd {
impl IOCmd for WriteCmd {
type Stream = Sink;
type Handle = SinkHandle;
type Handle = SharedHandle<Sink>;
type Result = WriteResult;
fn execute(

View File

@@ -9,3 +9,4 @@ mod service;
// pub use facade::{io_system, IOStream, IOSystem};
pub use service::{Service, Stream, StreamTable};
pub use instances::{wrap_io_error, Source, Sink};

View File

@@ -1,6 +1,7 @@
#[allow(unused)] // for doc
use std::io::{BufReader, Read, Write};
use itertools::Itertools;
use rust_embed::RustEmbed;
use trait_set::trait_set;
@@ -69,8 +70,8 @@ impl<'a, ST: IntoIterator<Item = (&'a str, Stream)>> IntoSystem<'static>
|stream| (stream, Vec::new()),
);
match result {
Ok(cancel) => Ok(call(tail, vec![init_cps(1, cancel).wrap()]).wrap()),
Err(e) => Ok(call(fail, vec![e.atom_exi()]).wrap()),
Ok(cancel) => Ok(call(tail, [init_cps(1, cancel).wrap()]).wrap()),
Err(e) => Ok(call(fail, [e.atom_exi()]).wrap()),
}
});
let scheduler = self.scheduler.clone();
@@ -87,8 +88,8 @@ impl<'a, ST: IntoIterator<Item = (&'a str, Stream)>> IntoSystem<'static>
|stream| (stream, Vec::new()),
);
match result {
Ok(cancel) => Ok(call(tail, vec![init_cps(1, cancel).wrap()]).wrap()),
Err(e) => Ok(call(fail, vec![e.atom_exi()]).wrap()),
Ok(cancel) => Ok(call(tail, [init_cps(1, cancel).wrap()]).wrap()),
Err(e) => Ok(call(fail, [e.atom_exi()]).wrap()),
}
});
let streams = self.global_streams.into_iter().map(|(n, stream)| {
@@ -101,7 +102,7 @@ impl<'a, ST: IntoIterator<Item = (&'a str, Stream)>> IntoSystem<'static>
});
System {
handlers,
name: vec!["system".to_string(), "io".to_string()],
name: ["system", "io"].into_iter().map_into().collect(),
constants: io_bindings(i, streams).unwrap_tree(),
code: embed_to_map::<IOEmbed>(".orc", i),
prelude: vec![FileEntry {