add current_output, printing of stream terms
This commit is contained in:
6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -444,7 +444,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prolog_parser"
|
name = "prolog_parser"
|
||||||
version = "0.8.44"
|
version = "0.8.47"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lexical 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lexical 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -580,7 +580,7 @@ dependencies = [
|
|||||||
"nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-rug-adapter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-rug-adapter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"prolog_parser 0.8.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
"prolog_parser 0.8.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rug 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rug 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustyline 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustyline 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -791,7 +791,7 @@ dependencies = [
|
|||||||
"checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc"
|
"checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc"
|
||||||
"checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1"
|
"checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1"
|
||||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||||
"checksum prolog_parser 0.8.44 (registry+https://github.com/rust-lang/crates.io-index)" = "c113cce59b3e97ff141e933d09eb1618e44b11cad9fa2ce6eb53ef832c38dc5c"
|
"checksum prolog_parser 0.8.47 (registry+https://github.com/rust-lang/crates.io-index)" = "2cf575fc8b91b2d9a9487f13655cffb6f697a5294b74de9b24b6a5fbe987e229"
|
||||||
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||||
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||||
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ libc = "0.2.62"
|
|||||||
nix = "0.15.0"
|
nix = "0.15.0"
|
||||||
num-rug-adapter = { optional = true, version = "0.1.1" }
|
num-rug-adapter = { optional = true, version = "0.1.1" }
|
||||||
ordered-float = "0.5.0"
|
ordered-float = "0.5.0"
|
||||||
prolog_parser = { version = "0.8.44", default-features = false }
|
prolog_parser = { version = "0.8.47", default-features = false }
|
||||||
ref_thread_local = "0.0.0"
|
ref_thread_local = "0.0.0"
|
||||||
rug = { version = "1.4.0", optional = true }
|
rug = { version = "1.4.0", optional = true }
|
||||||
rustyline = "6.0.0"
|
rustyline = "6.0.0"
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ use nix::sys::signal;
|
|||||||
mod prolog;
|
mod prolog;
|
||||||
|
|
||||||
use crate::prolog::machine::*;
|
use crate::prolog::machine::*;
|
||||||
|
use crate::prolog::machine::streams::*;
|
||||||
use crate::prolog::read::*;
|
use crate::prolog::read::*;
|
||||||
|
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
@@ -31,6 +32,6 @@ fn main() {
|
|||||||
let handler = signal::SigHandler::Handler(handle_sigint);
|
let handler = signal::SigHandler::Handler(handle_sigint);
|
||||||
unsafe { signal::signal(signal::Signal::SIGINT, handler) }.unwrap();
|
unsafe { signal::signal(signal::Signal::SIGINT, handler) }.unwrap();
|
||||||
|
|
||||||
let mut wam = Machine::new(readline::input_stream());
|
let mut wam = Machine::new(readline::input_stream(), Stream::stdout());
|
||||||
wam.run_top_level();
|
wam.run_top_level();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -171,6 +171,7 @@ pub enum SystemClauseType {
|
|||||||
CopyToLiftedHeap,
|
CopyToLiftedHeap,
|
||||||
CreatePartialString,
|
CreatePartialString,
|
||||||
CurrentInput,
|
CurrentInput,
|
||||||
|
CurrentOutput,
|
||||||
DeleteAttribute,
|
DeleteAttribute,
|
||||||
DeleteHeadAttribute,
|
DeleteHeadAttribute,
|
||||||
DynamicModuleResolution(usize),
|
DynamicModuleResolution(usize),
|
||||||
@@ -285,6 +286,7 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::CopyTermWithoutAttrVars => clause_name!("$copy_term_without_attr_vars"),
|
&SystemClauseType::CopyTermWithoutAttrVars => clause_name!("$copy_term_without_attr_vars"),
|
||||||
&SystemClauseType::CreatePartialString => clause_name!("$create_partial_string"),
|
&SystemClauseType::CreatePartialString => clause_name!("$create_partial_string"),
|
||||||
&SystemClauseType::CurrentInput => clause_name!("$current_input"),
|
&SystemClauseType::CurrentInput => clause_name!("$current_input"),
|
||||||
|
&SystemClauseType::CurrentOutput => clause_name!("$current_output"),
|
||||||
&SystemClauseType::REPL(REPLCodePtr::CompileBatch) => clause_name!("$compile_batch"),
|
&SystemClauseType::REPL(REPLCodePtr::CompileBatch) => clause_name!("$compile_batch"),
|
||||||
&SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"),
|
&SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"),
|
||||||
&SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule) => {
|
&SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule) => {
|
||||||
@@ -436,6 +438,7 @@ impl SystemClauseType {
|
|||||||
("$compile_batch", 0) => Some(SystemClauseType::REPL(REPLCodePtr::CompileBatch)),
|
("$compile_batch", 0) => Some(SystemClauseType::REPL(REPLCodePtr::CompileBatch)),
|
||||||
("$copy_to_lh", 2) => Some(SystemClauseType::CopyToLiftedHeap),
|
("$copy_to_lh", 2) => Some(SystemClauseType::CopyToLiftedHeap),
|
||||||
("$current_input", 1) => Some(SystemClauseType::CurrentInput),
|
("$current_input", 1) => Some(SystemClauseType::CurrentInput),
|
||||||
|
("$current_output", 1) => Some(SystemClauseType::CurrentOutput),
|
||||||
("$del_attr_non_head", 1) => Some(SystemClauseType::DeleteAttribute),
|
("$del_attr_non_head", 1) => Some(SystemClauseType::DeleteAttribute),
|
||||||
("$del_attr_head", 1) => Some(SystemClauseType::DeleteHeadAttribute),
|
("$del_attr_head", 1) => Some(SystemClauseType::DeleteHeadAttribute),
|
||||||
("$get_next_db_ref", 2) => Some(SystemClauseType::GetNextDBRef),
|
("$get_next_db_ref", 2) => Some(SystemClauseType::GetNextDBRef),
|
||||||
|
|||||||
@@ -958,6 +958,20 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
self.push_list();
|
self.push_list();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
HeapCellValue::Addr(Addr::Stream(stream)) => {
|
||||||
|
if let Some(alias) = &stream.options.alias {
|
||||||
|
self.print_atom(alias);
|
||||||
|
} else {
|
||||||
|
if stream.is_stdout() || stream.is_stdin() {
|
||||||
|
self.append_str("user");
|
||||||
|
} else {
|
||||||
|
self.append_str(&format!(
|
||||||
|
"'$stream'(0x{:x})",
|
||||||
|
stream.as_ptr() as usize,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
HeapCellValue::Addr(addr) => {
|
HeapCellValue::Addr(addr) => {
|
||||||
if let Some(offset_str) = self.offset_as_string(iter, addr) {
|
if let Some(offset_str) = self.offset_as_string(iter, addr) {
|
||||||
push_space_if_amb!(self, &offset_str, {
|
push_space_if_amb!(self, &offset_str, {
|
||||||
|
|||||||
@@ -44,12 +44,12 @@ user:term_expansion((:- op(Pred, Spec, [Op | OtherOps])), OpResults) :-
|
|||||||
abolish/1, asserta/1, assertz/1, atom_chars/2,
|
abolish/1, asserta/1, assertz/1, atom_chars/2,
|
||||||
atom_codes/2, atom_concat/3, atom_length/2,
|
atom_codes/2, atom_concat/3, atom_length/2,
|
||||||
bagof/3, catch/3, char_code/2, clause/2,
|
bagof/3, catch/3, char_code/2, clause/2,
|
||||||
current_input/1, current_op/3, current_predicate/1,
|
current_input/1, current_output/1, current_op/3,
|
||||||
current_prolog_flag/2, expand_goal/2,
|
current_predicate/1, current_prolog_flag/2,
|
||||||
expand_term/2, fail/0, false/0, findall/3,
|
expand_goal/2, expand_term/2, fail/0, false/0,
|
||||||
findall/4, get_char/1, halt/0, max_arity/1,
|
findall/3, findall/4, get_char/1, halt/0,
|
||||||
number_chars/2, number_codes/2, once/1, op/3,
|
max_arity/1, number_chars/2, number_codes/2,
|
||||||
read_term/2, repeat/0, retract/1,
|
once/1, op/3, read_term/2, repeat/0, retract/1,
|
||||||
set_prolog_flag/2, setof/3, sub_atom/5,
|
set_prolog_flag/2, setof/3, sub_atom/5,
|
||||||
subsumes_term/2, term_variables/2, throw/1,
|
subsumes_term/2, term_variables/2, throw/1,
|
||||||
true/0, unify_with_occurs_check/2, write/1,
|
true/0, unify_with_occurs_check/2, write/1,
|
||||||
@@ -1014,3 +1014,5 @@ subsumes_term(General, Specific) :-
|
|||||||
unify_with_occurs_check(X, Y) :- '$unify_with_occurs_check'(X, Y).
|
unify_with_occurs_check(X, Y) :- '$unify_with_occurs_check'(X, Y).
|
||||||
|
|
||||||
current_input(S) :- '$current_input'(S).
|
current_input(S) :- '$current_input'(S).
|
||||||
|
|
||||||
|
current_output(S) :- '$current_output'(S).
|
||||||
|
|||||||
@@ -615,17 +615,19 @@ impl ModuleStub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) type ModuleStubDir = IndexMap<ClauseName, ModuleStub>;
|
pub(crate) type ModuleStubDir = IndexMap<ClauseName, ModuleStub>;
|
||||||
|
pub(crate) type StreamAliasDir = IndexMap<ClauseName, Stream>;
|
||||||
|
|
||||||
pub struct IndexStore {
|
pub struct IndexStore {
|
||||||
pub(super) atom_tbl: TabledData<Atom>,
|
pub(super) atom_tbl: TabledData<Atom>,
|
||||||
pub(super) code_dir: CodeDir,
|
pub(super) code_dir: CodeDir,
|
||||||
pub(super) module_dir: ModuleDir,
|
|
||||||
pub(super) dynamic_code_dir: DynamicCodeDir,
|
pub(super) dynamic_code_dir: DynamicCodeDir,
|
||||||
pub(super) global_variables: GlobalVarDir,
|
pub(super) global_variables: GlobalVarDir,
|
||||||
pub(super) in_situ_code_dir: InSituCodeDir,
|
pub(super) in_situ_code_dir: InSituCodeDir,
|
||||||
pub(super) in_situ_module_dir: ModuleStubDir,
|
pub(super) in_situ_module_dir: ModuleStubDir,
|
||||||
|
pub(super) module_dir: ModuleDir,
|
||||||
pub(super) modules: ModuleDir,
|
pub(super) modules: ModuleDir,
|
||||||
pub(super) op_dir: OpDir,
|
pub(super) op_dir: OpDir,
|
||||||
|
pub(super) stream_aliases: StreamAliasDir,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IndexStore {
|
impl IndexStore {
|
||||||
@@ -712,6 +714,7 @@ impl IndexStore {
|
|||||||
in_situ_module_dir: ModuleStubDir::new(),
|
in_situ_module_dir: ModuleStubDir::new(),
|
||||||
op_dir: default_op_dir(),
|
op_dir: default_op_dir(),
|
||||||
modules: ModuleDir::new(),
|
modules: ModuleDir::new(),
|
||||||
|
stream_aliases: StreamAliasDir::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use crate::prolog::rug::Integer;
|
|||||||
use downcast::Any;
|
use downcast::Any;
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::io::{stdout, Write};
|
use std::io::Write;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::{Index, IndexMut};
|
use std::ops::{Index, IndexMut};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@@ -722,6 +722,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
ct: &BuiltInClauseType,
|
ct: &BuiltInClauseType,
|
||||||
indices: &mut IndexStore,
|
indices: &mut IndexStore,
|
||||||
current_input_stream: &mut Stream,
|
current_input_stream: &mut Stream,
|
||||||
|
current_output_stream: &mut Stream,
|
||||||
) -> CallResult {
|
) -> CallResult {
|
||||||
match ct {
|
match ct {
|
||||||
&BuiltInClauseType::AcyclicTerm => {
|
&BuiltInClauseType::AcyclicTerm => {
|
||||||
@@ -760,11 +761,10 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
machine_st.compare_term(qt);
|
machine_st.compare_term(qt);
|
||||||
return_from_clause!(machine_st.last_call, machine_st)
|
return_from_clause!(machine_st.last_call, machine_st)
|
||||||
}
|
}
|
||||||
&BuiltInClauseType::Nl => {
|
&BuiltInClauseType::Nl => {
|
||||||
let mut stdout = stdout();
|
write!(current_output_stream, "\n").unwrap();
|
||||||
|
current_output_stream.flush().unwrap();
|
||||||
write!(stdout, "\n").unwrap();
|
|
||||||
stdout.flush().unwrap();
|
|
||||||
return_from_clause!(machine_st.last_call, machine_st)
|
return_from_clause!(machine_st.last_call, machine_st)
|
||||||
}
|
}
|
||||||
&BuiltInClauseType::Read => {
|
&BuiltInClauseType::Read => {
|
||||||
@@ -896,12 +896,19 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
arity: usize,
|
arity: usize,
|
||||||
indices: &mut IndexStore,
|
indices: &mut IndexStore,
|
||||||
current_input_stream: &mut Stream,
|
current_input_stream: &mut Stream,
|
||||||
|
current_output_stream: &mut Stream,
|
||||||
) -> CallResult {
|
) -> CallResult {
|
||||||
if let Some((name, arity)) = machine_st.setup_call_n(arity) {
|
if let Some((name, arity)) = machine_st.setup_call_n(arity) {
|
||||||
match ClauseType::from(name.clone(), arity, None) {
|
match ClauseType::from(name.clone(), arity, None) {
|
||||||
ClauseType::BuiltIn(built_in) => {
|
ClauseType::BuiltIn(built_in) => {
|
||||||
machine_st.setup_built_in_call(built_in.clone());
|
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 => {
|
ClauseType::CallN => {
|
||||||
machine_st.handle_internal_call_n(arity);
|
machine_st.handle_internal_call_n(arity);
|
||||||
@@ -982,9 +989,16 @@ impl CallPolicy for CWILCallPolicy {
|
|||||||
ct: &BuiltInClauseType,
|
ct: &BuiltInClauseType,
|
||||||
indices: &mut IndexStore,
|
indices: &mut IndexStore,
|
||||||
current_input_stream: &mut Stream,
|
current_input_stream: &mut Stream,
|
||||||
|
current_output_stream: &mut Stream,
|
||||||
) -> CallResult {
|
) -> CallResult {
|
||||||
self.prev_policy
|
self.prev_policy.call_builtin(
|
||||||
.call_builtin(machine_st, ct, indices, current_input_stream)?;
|
machine_st,
|
||||||
|
ct,
|
||||||
|
indices,
|
||||||
|
current_input_stream,
|
||||||
|
current_output_stream
|
||||||
|
)?;
|
||||||
|
|
||||||
self.increment(machine_st)
|
self.increment(machine_st)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -994,9 +1008,16 @@ impl CallPolicy for CWILCallPolicy {
|
|||||||
arity: usize,
|
arity: usize,
|
||||||
indices: &mut IndexStore,
|
indices: &mut IndexStore,
|
||||||
current_input_stream: &mut Stream,
|
current_input_stream: &mut Stream,
|
||||||
|
current_output_stream: &mut Stream,
|
||||||
) -> CallResult {
|
) -> CallResult {
|
||||||
self.prev_policy
|
self.prev_policy.call_n(
|
||||||
.call_n(machine_st, arity, indices, current_input_stream)?;
|
machine_st,
|
||||||
|
arity,
|
||||||
|
indices,
|
||||||
|
current_input_stream,
|
||||||
|
current_output_stream,
|
||||||
|
)?;
|
||||||
|
|
||||||
self.increment(machine_st)
|
self.increment(machine_st)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3219,6 +3219,7 @@ impl MachineState {
|
|||||||
call_policy: &mut Box<dyn CallPolicy>,
|
call_policy: &mut Box<dyn CallPolicy>,
|
||||||
cut_policy: &mut Box<dyn CutPolicy>,
|
cut_policy: &mut Box<dyn CutPolicy>,
|
||||||
current_input_stream: &mut Stream,
|
current_input_stream: &mut Stream,
|
||||||
|
current_output_stream: &mut Stream,
|
||||||
ct: &ClauseType,
|
ct: &ClauseType,
|
||||||
arity: usize,
|
arity: usize,
|
||||||
lco: bool,
|
lco: bool,
|
||||||
@@ -3245,11 +3246,17 @@ impl MachineState {
|
|||||||
match ct {
|
match ct {
|
||||||
&ClauseType::BuiltIn(ref ct) => try_or_fail!(
|
&ClauseType::BuiltIn(ref ct) => try_or_fail!(
|
||||||
self,
|
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!(
|
&ClauseType::CallN => try_or_fail!(
|
||||||
self,
|
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::Hook(ref hook) => try_or_fail!(self, call_policy.compile_hook(self, hook)),
|
||||||
&ClauseType::Inlined(ref ct) => {
|
&ClauseType::Inlined(ref ct) => {
|
||||||
@@ -3274,6 +3281,7 @@ impl MachineState {
|
|||||||
call_policy,
|
call_policy,
|
||||||
cut_policy,
|
cut_policy,
|
||||||
current_input_stream,
|
current_input_stream,
|
||||||
|
current_output_stream,
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
@@ -3288,6 +3296,7 @@ impl MachineState {
|
|||||||
call_policy: &mut Box<dyn CallPolicy>,
|
call_policy: &mut Box<dyn CallPolicy>,
|
||||||
cut_policy: &mut Box<dyn CutPolicy>,
|
cut_policy: &mut Box<dyn CutPolicy>,
|
||||||
current_input_stream: &mut Stream,
|
current_input_stream: &mut Stream,
|
||||||
|
current_output_stream: &mut Stream,
|
||||||
instr: &ControlInstruction,
|
instr: &ControlInstruction,
|
||||||
) {
|
) {
|
||||||
match instr {
|
match instr {
|
||||||
@@ -3301,6 +3310,7 @@ impl MachineState {
|
|||||||
call_policy,
|
call_policy,
|
||||||
cut_policy,
|
cut_policy,
|
||||||
current_input_stream,
|
current_input_stream,
|
||||||
|
current_output_stream,
|
||||||
ct,
|
ct,
|
||||||
arity,
|
arity,
|
||||||
lco,
|
lco,
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ pub mod modules;
|
|||||||
mod partial_string;
|
mod partial_string;
|
||||||
mod raw_block;
|
mod raw_block;
|
||||||
mod stack;
|
mod stack;
|
||||||
pub(super) mod streams;
|
pub(crate) mod streams;
|
||||||
pub(super) mod term_expansion;
|
pub(super) mod term_expansion;
|
||||||
pub mod toplevel;
|
pub mod toplevel;
|
||||||
|
|
||||||
@@ -77,6 +77,7 @@ pub struct Machine {
|
|||||||
pub(super) code_repo: CodeRepo,
|
pub(super) code_repo: CodeRepo,
|
||||||
pub(super) toplevel_idx: usize,
|
pub(super) toplevel_idx: usize,
|
||||||
pub(super) current_input_stream: Stream,
|
pub(super) current_input_stream: Stream,
|
||||||
|
pub(super) current_output_stream: Stream,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Index<LocalCodePtr> for CodeRepo {
|
impl Index<LocalCodePtr> for CodeRepo {
|
||||||
@@ -344,7 +345,7 @@ impl Machine {
|
|||||||
self.run_query();
|
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 {
|
let mut wam = Machine {
|
||||||
machine_st: MachineState::new(),
|
machine_st: MachineState::new(),
|
||||||
@@ -354,6 +355,7 @@ impl Machine {
|
|||||||
code_repo: CodeRepo::new(),
|
code_repo: CodeRepo::new(),
|
||||||
toplevel_idx: 0,
|
toplevel_idx: 0,
|
||||||
current_input_stream,
|
current_input_stream,
|
||||||
|
current_output_stream,
|
||||||
};
|
};
|
||||||
|
|
||||||
let atom_tbl = wam.indices.atom_tbl.clone();
|
let atom_tbl = wam.indices.atom_tbl.clone();
|
||||||
@@ -775,6 +777,7 @@ impl Machine {
|
|||||||
&mut self.policies,
|
&mut self.policies,
|
||||||
&mut self.code_repo,
|
&mut self.code_repo,
|
||||||
&mut self.current_input_stream,
|
&mut self.current_input_stream,
|
||||||
|
&mut self.current_output_stream,
|
||||||
);
|
);
|
||||||
|
|
||||||
match self.machine_st.p {
|
match self.machine_st.p {
|
||||||
@@ -811,6 +814,7 @@ impl MachineState {
|
|||||||
policies: &mut MachinePolicies,
|
policies: &mut MachinePolicies,
|
||||||
code_repo: &CodeRepo,
|
code_repo: &CodeRepo,
|
||||||
current_input_stream: &mut Stream,
|
current_input_stream: &mut Stream,
|
||||||
|
current_output_stream: &mut Stream,
|
||||||
) {
|
) {
|
||||||
match instr {
|
match instr {
|
||||||
&Line::Arithmetic(ref arith_instr) => self.execute_arith_instr(arith_instr),
|
&Line::Arithmetic(ref arith_instr) => self.execute_arith_instr(arith_instr),
|
||||||
@@ -826,6 +830,7 @@ impl MachineState {
|
|||||||
&mut policies.call_policy,
|
&mut policies.call_policy,
|
||||||
&mut policies.cut_policy,
|
&mut policies.cut_policy,
|
||||||
current_input_stream,
|
current_input_stream,
|
||||||
|
current_output_stream,
|
||||||
control_instr,
|
control_instr,
|
||||||
),
|
),
|
||||||
&Line::Fact(ref fact_instr) => {
|
&Line::Fact(ref fact_instr) => {
|
||||||
@@ -849,6 +854,7 @@ impl MachineState {
|
|||||||
policies: &mut MachinePolicies,
|
policies: &mut MachinePolicies,
|
||||||
code_repo: &CodeRepo,
|
code_repo: &CodeRepo,
|
||||||
current_input_stream: &mut Stream,
|
current_input_stream: &mut Stream,
|
||||||
|
current_output_stream: &mut Stream,
|
||||||
) {
|
) {
|
||||||
let instr = match code_repo.lookup_instr(self.last_call, &self.p) {
|
let instr = match code_repo.lookup_instr(self.last_call, &self.p) {
|
||||||
Some(instr) => instr,
|
Some(instr) => instr,
|
||||||
@@ -861,6 +867,7 @@ impl MachineState {
|
|||||||
policies,
|
policies,
|
||||||
code_repo,
|
code_repo,
|
||||||
current_input_stream,
|
current_input_stream,
|
||||||
|
current_output_stream,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -913,6 +920,7 @@ impl MachineState {
|
|||||||
policies: &mut MachinePolicies,
|
policies: &mut MachinePolicies,
|
||||||
code_repo: &mut CodeRepo,
|
code_repo: &mut CodeRepo,
|
||||||
current_input_stream: &mut Stream,
|
current_input_stream: &mut Stream,
|
||||||
|
current_output_stream: &mut Stream,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
loop {
|
loop {
|
||||||
let instr = match code_repo.lookup_instr(self.last_call, &self.p) {
|
let instr = match code_repo.lookup_instr(self.last_call, &self.p) {
|
||||||
@@ -933,7 +941,8 @@ impl MachineState {
|
|||||||
indices,
|
indices,
|
||||||
policies,
|
policies,
|
||||||
code_repo,
|
code_repo,
|
||||||
current_input_stream
|
current_input_stream,
|
||||||
|
current_output_stream,
|
||||||
);
|
);
|
||||||
|
|
||||||
if self.fail {
|
if self.fail {
|
||||||
@@ -959,9 +968,16 @@ impl MachineState {
|
|||||||
policies: &mut MachinePolicies,
|
policies: &mut MachinePolicies,
|
||||||
code_repo: &mut CodeRepo,
|
code_repo: &mut CodeRepo,
|
||||||
current_input_stream: &mut Stream,
|
current_input_stream: &mut Stream,
|
||||||
|
current_output_stream: &mut Stream,
|
||||||
) {
|
) {
|
||||||
loop {
|
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 {
|
if self.fail {
|
||||||
self.backtrack();
|
self.backtrack();
|
||||||
@@ -977,7 +993,13 @@ impl MachineState {
|
|||||||
if !instigating_instr.as_ref().is_head_instr() {
|
if !instigating_instr.as_ref().is_head_instr() {
|
||||||
let cp = self.p.local();
|
let cp = self.p.local();
|
||||||
self.run_verify_attr_interrupt(cp);
|
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 {
|
if self.fail {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use std::cell::RefCell;
|
|||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fs::File;
|
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::hash::{Hash, Hasher};
|
||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@@ -31,6 +31,8 @@ pub enum StreamInstance {
|
|||||||
DynReadSource(Box<dyn Read>),
|
DynReadSource(Box<dyn Read>),
|
||||||
File(File),
|
File(File),
|
||||||
ReadlineStream(ReadlineStream),
|
ReadlineStream(ReadlineStream),
|
||||||
|
Stdin,
|
||||||
|
Stdout,
|
||||||
TcpStream(TcpStream),
|
TcpStream(TcpStream),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,6 +178,88 @@ impl Stream {
|
|||||||
|
|
||||||
ptr
|
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 {
|
impl Read for Stream {
|
||||||
@@ -196,6 +280,15 @@ impl Read for Stream {
|
|||||||
StreamInstance::Bytes(ref mut cursor) => {
|
StreamInstance::Bytes(ref mut cursor) => {
|
||||||
cursor.read(buf)
|
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) => {
|
StreamInstance::Bytes(ref mut cursor) => {
|
||||||
cursor.write(buf)
|
cursor.write(buf)
|
||||||
}
|
}
|
||||||
|
StreamInstance::Stdout => {
|
||||||
|
stdout().write(buf)
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
Err(std::io::Error::new(
|
Err(std::io::Error::new(
|
||||||
ErrorKind::PermissionDenied,
|
ErrorKind::PermissionDenied,
|
||||||
@@ -232,6 +328,9 @@ impl Write for Stream {
|
|||||||
StreamInstance::Bytes(ref mut cursor) => {
|
StreamInstance::Bytes(ref mut cursor) => {
|
||||||
cursor.flush()
|
cursor.flush()
|
||||||
}
|
}
|
||||||
|
StreamInstance::Stdout => {
|
||||||
|
stdout().flush()
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
Err(std::io::Error::new(
|
Err(std::io::Error::new(
|
||||||
ErrorKind::PermissionDenied,
|
ErrorKind::PermissionDenied,
|
||||||
|
|||||||
@@ -673,6 +673,7 @@ impl MachineState {
|
|||||||
call_policy: &mut Box<dyn CallPolicy>,
|
call_policy: &mut Box<dyn CallPolicy>,
|
||||||
cut_policy: &mut Box<dyn CutPolicy>,
|
cut_policy: &mut Box<dyn CutPolicy>,
|
||||||
current_input_stream: &mut Stream,
|
current_input_stream: &mut Stream,
|
||||||
|
current_output_stream: &mut Stream,
|
||||||
) -> CallResult {
|
) -> CallResult {
|
||||||
match ct {
|
match ct {
|
||||||
&SystemClauseType::AbolishClause => {
|
&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 => {
|
&SystemClauseType::AtEndOfExpansion => {
|
||||||
if self.cp == LocalCodePtr::TopLevel(0, 0) {
|
if self.cp == LocalCodePtr::TopLevel(0, 0) {
|
||||||
self.at_end_of_expansion = true;
|
self.at_end_of_expansion = true;
|
||||||
|
|||||||
@@ -364,6 +364,7 @@ impl MachineState {
|
|||||||
&mut wam.policies,
|
&mut wam.policies,
|
||||||
&mut wam.code_repo,
|
&mut wam.code_repo,
|
||||||
&mut readline::input_stream(),
|
&mut readline::input_stream(),
|
||||||
|
&mut Stream::stdout(),
|
||||||
);
|
);
|
||||||
|
|
||||||
if self.fail || self.at_end_of_expansion {
|
if self.fail || self.at_end_of_expansion {
|
||||||
|
|||||||
@@ -237,7 +237,8 @@ macro_rules! index_store {
|
|||||||
in_situ_code_dir: InSituCodeDir::new(),
|
in_situ_code_dir: InSituCodeDir::new(),
|
||||||
in_situ_module_dir: ModuleStubDir::new(),
|
in_situ_module_dir: ModuleStubDir::new(),
|
||||||
op_dir: $op_dir,
|
op_dir: $op_dir,
|
||||||
modules: $modules,
|
modules: $modules,
|
||||||
|
stream_aliases: StreamAliasDir::new(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user