From: bakaq Date: Mon, 30 Sep 2024 00:30:27 +0000 (-0300) Subject: Machine and stream config rework X-Git-Tag: v0.10.0~92^2~25 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=658e39aae6996ff6f8f1b6b1e2a58abea846b80f;p=scryer-prolog.git Machine and stream config rework --- diff --git a/src/machine/config.rs b/src/machine/config.rs index 6268c8d8..79752f31 100644 --- a/src/machine/config.rs +++ b/src/machine/config.rs @@ -1,32 +1,74 @@ -pub struct MachineConfig { - pub streams: StreamConfig, - pub toplevel: &'static str, +/// Describes how the streams of a `crate::Machine` will be handled. +/// +/// Defaults to using standard IO. +pub struct StreamConfig { + pub(crate) inner: StreamConfigInner, +} + +impl Default for StreamConfig { + fn default() -> Self { + Self::stdio() + } +} + +impl StreamConfig { + /// Binds the input, output and error streams to stdin, stdout and stderr. + pub fn stdio() -> Self { + StreamConfig { + inner: StreamConfigInner::Stdio, + } + } + + /// Binds the output stream to a memory buffer, and the error stream to stderr. + /// + /// The input stream is ignored. + pub fn in_memory() -> Self { + StreamConfig { + inner: StreamConfigInner::Memory, + } + } } -pub enum StreamConfig { +pub(crate) enum StreamConfigInner { Stdio, Memory, } +/// Describes how a `crate::Machine` will be configured. +pub struct MachineConfig { + pub(crate) streams: StreamConfig, + pub(crate) toplevel: &'static str, +} + impl Default for MachineConfig { fn default() -> Self { MachineConfig { - streams: StreamConfig::Stdio, - toplevel: include_str!("../toplevel.pl"), + streams: Default::default(), + toplevel: default_toplevel(), } } } impl MachineConfig { - pub fn in_memory() -> Self { - MachineConfig { - streams: StreamConfig::Memory, - ..Default::default() - } + /// Creates a default configuration. + pub fn new() -> Self { + Default::default() + } + + /// Uses the given `crate::StreamConfig` in this configuration. + pub fn with_streams(mut self, streams: StreamConfig) -> Self { + self.streams = streams; + self } + /// Uses the given toplevel in this configuration. pub fn with_toplevel(mut self, toplevel: &'static str) -> Self { self.toplevel = toplevel; self } } + +/// Returns a static string slice to the default toplevel +pub fn default_toplevel() -> &'static str { + include_str!("../toplevel.pl") +} diff --git a/src/machine/lib_machine.rs b/src/machine/lib_machine.rs index 52fb3e02..abfe87bf 100644 --- a/src/machine/lib_machine.rs +++ b/src/machine/lib_machine.rs @@ -1,6 +1,6 @@ use std::collections::BTreeMap; -use crate::atom_table; +use crate::{atom_table, StreamConfig}; use crate::machine::machine_indices::VarKey; use crate::machine::mock_wam::CompositeOpDir; use crate::machine::{BREAK_FROM_DISPATCH_LOOP_LOC, LIB_QUERY_SUCCESS}; @@ -144,7 +144,7 @@ impl Iterator for QueryState<'_> { impl Machine { pub fn new_lib() -> Self { - Machine::new(MachineConfig::in_memory()) + Machine::new(MachineConfig::default().with_streams(StreamConfig::in_memory())) } pub fn load_module_string(&mut self, module_name: &str, program: String) { diff --git a/src/machine/mock_wam.rs b/src/machine/mock_wam.rs index 90aefa0e..2c7e37d6 100644 --- a/src/machine/mock_wam.rs +++ b/src/machine/mock_wam.rs @@ -6,6 +6,7 @@ pub use crate::machine::*; pub use crate::parser::ast::*; use crate::read::*; pub use crate::types::*; +use crate::StreamConfig; use std::sync::Arc; @@ -232,7 +233,7 @@ pub(crate) fn parse_and_write_parsed_term_to_heap( impl Machine { pub fn with_test_streams() -> Self { - Machine::new(MachineConfig::in_memory()) + Machine::new(MachineConfig::default().with_streams(StreamConfig::in_memory())) } pub fn test_load_file(&mut self, file: &str) -> Vec { diff --git a/src/machine/mod.rs b/src/machine/mod.rs index f3528892..94f2842f 100644 --- a/src/machine/mod.rs +++ b/src/machine/mod.rs @@ -485,13 +485,13 @@ impl Machine { let args = MachineArgs::new(); let mut machine_st = MachineState::new(); - let (user_input, user_output, user_error) = match config.streams { - config::StreamConfig::Stdio => ( + let (user_input, user_output, user_error) = match config.streams.inner { + config::StreamConfigInner::Stdio => ( Stream::stdin(&mut machine_st.arena, args.add_history), Stream::stdout(&mut machine_st.arena), Stream::stderr(&mut machine_st.arena), ), - config::StreamConfig::Memory => ( + config::StreamConfigInner::Memory => ( Stream::Null(StreamOptions::default()), Stream::from_owned_string("".to_owned(), &mut machine_st.arena), Stream::stderr(&mut machine_st.arena),