add current_output, printing of stream terms

This commit is contained in:
Mark Thom
2020-03-11 00:38:01 -06:00
parent 25babff827
commit 4c88e97330
14 changed files with 236 additions and 32 deletions

View File

@@ -615,17 +615,19 @@ impl ModuleStub {
}
pub(crate) type ModuleStubDir = IndexMap<ClauseName, ModuleStub>;
pub(crate) type StreamAliasDir = IndexMap<ClauseName, Stream>;
pub struct IndexStore {
pub(super) atom_tbl: TabledData<Atom>,
pub(super) code_dir: CodeDir,
pub(super) module_dir: ModuleDir,
pub(super) dynamic_code_dir: DynamicCodeDir,
pub(super) global_variables: GlobalVarDir,
pub(super) in_situ_code_dir: InSituCodeDir,
pub(super) in_situ_module_dir: ModuleStubDir,
pub(super) module_dir: ModuleDir,
pub(super) modules: ModuleDir,
pub(super) op_dir: OpDir,
pub(super) stream_aliases: StreamAliasDir,
}
impl IndexStore {
@@ -712,6 +714,7 @@ impl IndexStore {
in_situ_module_dir: ModuleStubDir::new(),
op_dir: default_op_dir(),
modules: ModuleDir::new(),
stream_aliases: StreamAliasDir::new(),
}
}

View File

@@ -15,7 +15,7 @@ use crate::prolog::rug::Integer;
use downcast::Any;
use std::cmp::Ordering;
use std::io::{stdout, Write};
use std::io::Write;
use std::mem;
use std::ops::{Index, IndexMut};
use std::rc::Rc;
@@ -722,6 +722,7 @@ pub(crate) trait CallPolicy: Any {
ct: &BuiltInClauseType,
indices: &mut IndexStore,
current_input_stream: &mut Stream,
current_output_stream: &mut Stream,
) -> CallResult {
match ct {
&BuiltInClauseType::AcyclicTerm => {
@@ -760,11 +761,10 @@ pub(crate) trait CallPolicy: Any {
machine_st.compare_term(qt);
return_from_clause!(machine_st.last_call, machine_st)
}
&BuiltInClauseType::Nl => {
let mut stdout = stdout();
write!(stdout, "\n").unwrap();
stdout.flush().unwrap();
&BuiltInClauseType::Nl => {
write!(current_output_stream, "\n").unwrap();
current_output_stream.flush().unwrap();
return_from_clause!(machine_st.last_call, machine_st)
}
&BuiltInClauseType::Read => {
@@ -896,12 +896,19 @@ pub(crate) trait CallPolicy: Any {
arity: usize,
indices: &mut IndexStore,
current_input_stream: &mut Stream,
current_output_stream: &mut Stream,
) -> CallResult {
if let Some((name, arity)) = machine_st.setup_call_n(arity) {
match ClauseType::from(name.clone(), arity, None) {
ClauseType::BuiltIn(built_in) => {
machine_st.setup_built_in_call(built_in.clone());
self.call_builtin(machine_st, &built_in, indices, current_input_stream)?;
self.call_builtin(
machine_st,
&built_in,
indices,
current_input_stream,
current_output_stream,
)?;
}
ClauseType::CallN => {
machine_st.handle_internal_call_n(arity);
@@ -982,9 +989,16 @@ impl CallPolicy for CWILCallPolicy {
ct: &BuiltInClauseType,
indices: &mut IndexStore,
current_input_stream: &mut Stream,
current_output_stream: &mut Stream,
) -> CallResult {
self.prev_policy
.call_builtin(machine_st, ct, indices, current_input_stream)?;
self.prev_policy.call_builtin(
machine_st,
ct,
indices,
current_input_stream,
current_output_stream
)?;
self.increment(machine_st)
}
@@ -994,9 +1008,16 @@ impl CallPolicy for CWILCallPolicy {
arity: usize,
indices: &mut IndexStore,
current_input_stream: &mut Stream,
current_output_stream: &mut Stream,
) -> CallResult {
self.prev_policy
.call_n(machine_st, arity, indices, current_input_stream)?;
self.prev_policy.call_n(
machine_st,
arity,
indices,
current_input_stream,
current_output_stream,
)?;
self.increment(machine_st)
}
}

View File

@@ -3219,6 +3219,7 @@ impl MachineState {
call_policy: &mut Box<dyn CallPolicy>,
cut_policy: &mut Box<dyn CutPolicy>,
current_input_stream: &mut Stream,
current_output_stream: &mut Stream,
ct: &ClauseType,
arity: usize,
lco: bool,
@@ -3245,11 +3246,17 @@ impl MachineState {
match ct {
&ClauseType::BuiltIn(ref ct) => try_or_fail!(
self,
call_policy.call_builtin(self, ct, indices, current_input_stream)
call_policy.call_builtin(
self,
ct,
indices,
current_input_stream,
current_output_stream,
)
),
&ClauseType::CallN => try_or_fail!(
self,
call_policy.call_n(self, arity, indices, current_input_stream)
call_policy.call_n(self, arity, indices, current_input_stream, current_output_stream)
),
&ClauseType::Hook(ref hook) => try_or_fail!(self, call_policy.compile_hook(self, hook)),
&ClauseType::Inlined(ref ct) => {
@@ -3274,6 +3281,7 @@ impl MachineState {
call_policy,
cut_policy,
current_input_stream,
current_output_stream,
)
),
};
@@ -3288,6 +3296,7 @@ impl MachineState {
call_policy: &mut Box<dyn CallPolicy>,
cut_policy: &mut Box<dyn CutPolicy>,
current_input_stream: &mut Stream,
current_output_stream: &mut Stream,
instr: &ControlInstruction,
) {
match instr {
@@ -3301,6 +3310,7 @@ impl MachineState {
call_policy,
cut_policy,
current_input_stream,
current_output_stream,
ct,
arity,
lco,

View File

@@ -22,7 +22,7 @@ pub mod modules;
mod partial_string;
mod raw_block;
mod stack;
pub(super) mod streams;
pub(crate) mod streams;
pub(super) mod term_expansion;
pub mod toplevel;
@@ -77,6 +77,7 @@ pub struct Machine {
pub(super) code_repo: CodeRepo,
pub(super) toplevel_idx: usize,
pub(super) current_input_stream: Stream,
pub(super) current_output_stream: Stream,
}
impl Index<LocalCodePtr> for CodeRepo {
@@ -344,7 +345,7 @@ impl Machine {
self.run_query();
}
pub fn new(current_input_stream: Stream) -> Self
pub fn new(current_input_stream: Stream, current_output_stream: Stream) -> Self
{
let mut wam = Machine {
machine_st: MachineState::new(),
@@ -354,6 +355,7 @@ impl Machine {
code_repo: CodeRepo::new(),
toplevel_idx: 0,
current_input_stream,
current_output_stream,
};
let atom_tbl = wam.indices.atom_tbl.clone();
@@ -775,6 +777,7 @@ impl Machine {
&mut self.policies,
&mut self.code_repo,
&mut self.current_input_stream,
&mut self.current_output_stream,
);
match self.machine_st.p {
@@ -811,6 +814,7 @@ impl MachineState {
policies: &mut MachinePolicies,
code_repo: &CodeRepo,
current_input_stream: &mut Stream,
current_output_stream: &mut Stream,
) {
match instr {
&Line::Arithmetic(ref arith_instr) => self.execute_arith_instr(arith_instr),
@@ -826,6 +830,7 @@ impl MachineState {
&mut policies.call_policy,
&mut policies.cut_policy,
current_input_stream,
current_output_stream,
control_instr,
),
&Line::Fact(ref fact_instr) => {
@@ -849,6 +854,7 @@ impl MachineState {
policies: &mut MachinePolicies,
code_repo: &CodeRepo,
current_input_stream: &mut Stream,
current_output_stream: &mut Stream,
) {
let instr = match code_repo.lookup_instr(self.last_call, &self.p) {
Some(instr) => instr,
@@ -861,6 +867,7 @@ impl MachineState {
policies,
code_repo,
current_input_stream,
current_output_stream,
);
}
@@ -913,6 +920,7 @@ impl MachineState {
policies: &mut MachinePolicies,
code_repo: &mut CodeRepo,
current_input_stream: &mut Stream,
current_output_stream: &mut Stream,
) -> bool {
loop {
let instr = match code_repo.lookup_instr(self.last_call, &self.p) {
@@ -933,7 +941,8 @@ impl MachineState {
indices,
policies,
code_repo,
current_input_stream
current_input_stream,
current_output_stream,
);
if self.fail {
@@ -959,9 +968,16 @@ impl MachineState {
policies: &mut MachinePolicies,
code_repo: &mut CodeRepo,
current_input_stream: &mut Stream,
current_output_stream: &mut Stream,
) {
loop {
self.execute_instr(indices, policies, code_repo, current_input_stream);
self.execute_instr(
indices,
policies,
code_repo,
current_input_stream,
current_output_stream,
);
if self.fail {
self.backtrack();
@@ -977,7 +993,13 @@ impl MachineState {
if !instigating_instr.as_ref().is_head_instr() {
let cp = self.p.local();
self.run_verify_attr_interrupt(cp);
} else if !self.verify_attr_stepper(indices, policies, code_repo, current_input_stream) {
} else if !self.verify_attr_stepper(
indices,
policies,
code_repo,
current_input_stream,
current_output_stream,
) {
if self.fail {
break;
}

View File

@@ -6,7 +6,7 @@ use std::cell::RefCell;
use std::error::Error;
use std::fmt;
use std::fs::File;
use std::io::{Cursor, ErrorKind, Read, Write};
use std::io::{stdin, stdout, Cursor, ErrorKind, Read, Write};
use std::hash::{Hash, Hasher};
use std::net::TcpStream;
use std::rc::Rc;
@@ -31,6 +31,8 @@ pub enum StreamInstance {
DynReadSource(Box<dyn Read>),
File(File),
ReadlineStream(ReadlineStream),
Stdin,
Stdout,
TcpStream(TcpStream),
}
@@ -176,6 +178,88 @@ impl Stream {
ptr
}
#[inline]
pub(crate)
fn stdout() -> Self {
Stream {
options: StreamOptions::default(),
stream_inst: WrappedStreamInstance::new(
StreamInstance::Stdout
),
}
}
#[inline]
pub(crate)
fn stdin() -> Self {
Stream {
options: StreamOptions::default(),
stream_inst: WrappedStreamInstance::new(
StreamInstance::Stdin
),
}
}
#[inline]
pub(crate)
fn is_stdout(&self) -> bool {
match *self.stream_inst.0.borrow() {
StreamInstance::Stdout => {
true
}
_ => {
false
}
}
}
#[inline]
pub(crate)
fn is_stdin(&self) -> bool {
match *self.stream_inst.0.borrow() {
StreamInstance::Stdin | StreamInstance::ReadlineStream(_) => {
true
}
_ => {
false
}
}
}
#[inline]
pub(crate)
fn is_input_stream(&self) -> bool {
match *self.stream_inst.0.borrow() {
StreamInstance::Stdin
| StreamInstance::TcpStream(_)
| StreamInstance::Bytes(_)
| StreamInstance::ReadlineStream(_)
| StreamInstance::DynReadSource(_)
| StreamInstance::File(_) => {
true
}
_ => {
false
}
}
}
#[inline]
pub(crate)
fn is_output_stream(&self) -> bool {
match *self.stream_inst.0.borrow() {
StreamInstance::Stdout
| StreamInstance::TcpStream(_)
| StreamInstance::Bytes(_)
| StreamInstance::File(_) => {
true
}
_ => {
false
}
}
}
}
impl Read for Stream {
@@ -196,6 +280,15 @@ impl Read for Stream {
StreamInstance::Bytes(ref mut cursor) => {
cursor.read(buf)
}
StreamInstance::Stdin => {
stdin().read(buf)
}
StreamInstance::Stdout => {
Err(std::io::Error::new(
ErrorKind::PermissionDenied,
StreamError::ReadFromOutputStream,
))
}
}
}
}
@@ -212,6 +305,9 @@ impl Write for Stream {
StreamInstance::Bytes(ref mut cursor) => {
cursor.write(buf)
}
StreamInstance::Stdout => {
stdout().write(buf)
}
_ => {
Err(std::io::Error::new(
ErrorKind::PermissionDenied,
@@ -232,6 +328,9 @@ impl Write for Stream {
StreamInstance::Bytes(ref mut cursor) => {
cursor.flush()
}
StreamInstance::Stdout => {
stdout().flush()
}
_ => {
Err(std::io::Error::new(
ErrorKind::PermissionDenied,

View File

@@ -673,6 +673,7 @@ impl MachineState {
call_policy: &mut Box<dyn CallPolicy>,
cut_policy: &mut Box<dyn CutPolicy>,
current_input_stream: &mut Stream,
current_output_stream: &mut Stream,
) -> CallResult {
match ct {
&SystemClauseType::AbolishClause => {
@@ -748,6 +749,32 @@ impl MachineState {
}
}
}
&SystemClauseType::CurrentOutput => {
let addr = self.store(self.deref(self[temp_v!(1)].clone()));
let stream = current_output_stream.clone();
match addr {
addr if addr.is_ref() => {
self.unify(Addr::Stream(stream), addr);
}
Addr::Stream(other_stream) => {
self.fail = stream != other_stream;
}
addr => {
let stub = MachineError::functor_stub(
clause_name!("current_input"),
1,
);
let err = MachineError::domain_error(
DomainError::Stream,
addr,
);
return Err(self.error_form(err, stub));
}
}
}
&SystemClauseType::AtEndOfExpansion => {
if self.cp == LocalCodePtr::TopLevel(0, 0) {
self.at_end_of_expansion = true;

View File

@@ -364,6 +364,7 @@ impl MachineState {
&mut wam.policies,
&mut wam.code_repo,
&mut readline::input_stream(),
&mut Stream::stdout(),
);
if self.fail || self.at_end_of_expansion {