]> Repositorios git - scryer-prolog.git/commitdiff
add current_output, printing of stream terms
authorMark Thom <[email protected]>
Wed, 11 Mar 2020 06:38:01 +0000 (00:38 -0600)
committerMark Thom <[email protected]>
Wed, 11 Mar 2020 06:38:01 +0000 (00:38 -0600)
14 files changed:
Cargo.lock
Cargo.toml
src/main.rs
src/prolog/clause_types.rs
src/prolog/heap_print.rs
src/prolog/lib/builtins.pl
src/prolog/machine/machine_indices.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/machine/mod.rs
src/prolog/machine/streams.rs
src/prolog/machine/system_calls.rs
src/prolog/machine/term_expansion.rs
src/prolog/macros.rs

index 0aafa8b7afbc3f2c637f27141de5044619806ed1..61c28d82f916c71300faa3963d643bfc8181d5d8 100644 (file)
@@ -444,7 +444,7 @@ dependencies = [
 
 [[package]]
 name = "prolog_parser"
-version = "0.8.44"
+version = "0.8.47"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "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)",
  "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)",
- "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)",
  "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)",
@@ -791,7 +791,7 @@ dependencies = [
 "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 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 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"
index cc978a291c2dd053f3c7b1b99d7e084b2a2d56a9..278c8948ea6825981ed8a18fdf520efe0c4246fb 100644 (file)
@@ -25,7 +25,7 @@ libc = "0.2.62"
 nix = "0.15.0"
 num-rug-adapter = { optional = true, version = "0.1.1" }
 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"
 rug = { version = "1.4.0", optional = true }
 rustyline = "6.0.0"
index 86cdd844a5271d7ca03c4c1ddc9b1e3d8b012282..b7cd3152201f99e467ca0fbe5a6ec1614181e1d4 100644 (file)
@@ -16,6 +16,7 @@ use nix::sys::signal;
 mod prolog;
 
 use crate::prolog::machine::*;
+use crate::prolog::machine::streams::*;
 use crate::prolog::read::*;
 
 use std::sync::atomic::Ordering;
@@ -31,6 +32,6 @@ fn main() {
     let handler = signal::SigHandler::Handler(handle_sigint);
     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();
 }
index e0cfbe903bbfdfd89a4ee6f775e98675c0d8c39e..4ccddfdb5f9dfb9e73d0dab68bbfbde4df53d33f 100644 (file)
@@ -171,6 +171,7 @@ pub enum SystemClauseType {
     CopyToLiftedHeap,
     CreatePartialString,
     CurrentInput,
+    CurrentOutput,
     DeleteAttribute,
     DeleteHeadAttribute,
     DynamicModuleResolution(usize),
@@ -285,6 +286,7 @@ impl SystemClauseType {
             &SystemClauseType::CopyTermWithoutAttrVars => clause_name!("$copy_term_without_attr_vars"),
             &SystemClauseType::CreatePartialString => clause_name!("$create_partial_string"),
             &SystemClauseType::CurrentInput => clause_name!("$current_input"),
+            &SystemClauseType::CurrentOutput => clause_name!("$current_output"),
             &SystemClauseType::REPL(REPLCodePtr::CompileBatch) => clause_name!("$compile_batch"),
            &SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"),
            &SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule) => {
@@ -436,6 +438,7 @@ impl SystemClauseType {
             ("$compile_batch", 0) => Some(SystemClauseType::REPL(REPLCodePtr::CompileBatch)),
             ("$copy_to_lh", 2) => Some(SystemClauseType::CopyToLiftedHeap),
             ("$current_input", 1) => Some(SystemClauseType::CurrentInput),
+            ("$current_output", 1) => Some(SystemClauseType::CurrentOutput),
             ("$del_attr_non_head", 1) => Some(SystemClauseType::DeleteAttribute),
             ("$del_attr_head", 1) => Some(SystemClauseType::DeleteHeadAttribute),
             ("$get_next_db_ref", 2) => Some(SystemClauseType::GetNextDBRef),
index b7c25ded31cf7c0daa9d5c27fc071ead8f28f5ba..0c2e846b960490ac128bd4dee622391565cfd584 100644 (file)
@@ -958,6 +958,20 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
                     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) => {
                 if let Some(offset_str) = self.offset_as_string(iter, addr) {
                     push_space_if_amb!(self, &offset_str, {
index c8d85b9a345542392038a82e60dc5ac9b92fbbb6..92807ac6aab07c7935ac7dfd6753902273e58ca3 100644 (file)
@@ -44,12 +44,12 @@ user:term_expansion((:- op(Pred, Spec, [Op | OtherOps])), OpResults) :-
                      abolish/1, asserta/1, assertz/1, atom_chars/2,
                      atom_codes/2, atom_concat/3, atom_length/2,
                      bagof/3, catch/3, char_code/2, clause/2,
-                    current_input/1, current_op/3, current_predicate/1,
-                     current_prolog_flag/2, expand_goal/2,
-                     expand_term/2, fail/0, false/0, findall/3,
-                     findall/4, get_char/1, halt/0, max_arity/1,
-                     number_chars/2, number_codes/2, once/1, op/3,
-                     read_term/2, repeat/0, retract/1,
+                     current_input/1, current_output/1, current_op/3,
+                     current_predicate/1, current_prolog_flag/2,
+                     expand_goal/2, expand_term/2, fail/0, false/0,
+                     findall/3, findall/4, get_char/1, halt/0,
+                     max_arity/1, number_chars/2, number_codes/2,
+                     once/1, op/3, read_term/2, repeat/0, retract/1,
                      set_prolog_flag/2, setof/3, sub_atom/5,
                      subsumes_term/2, term_variables/2, throw/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).
 
 current_input(S) :- '$current_input'(S).    
+
+current_output(S) :- '$current_output'(S).
index be54937efdb7c80804ab89851b695b4bd599ee11..53f5e1594b1af19f45d282625b96aaa76f0ba641 100644 (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(),
         }
     }
 
index f3cc271aef3b58e6496f8dec1bd3a1009d0c8fe8..58e7f12782f4f0fa85bab5db9cd3bad2a8142b34 100644 (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)
     }
 }
index 3e35f0cc569f5c546840c5f0a4296a60f2bd5811..00b2eb97d2caede579e3955e425765a82b34dd68 100644 (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,
index 67afac2e1776e75e36f7e67027692d3fdb580626..64bc4dd936eaf9e03e0c836ab5daf5b7c745b07f 100644 (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;
                         }
index 57d4835afc9d391ce00a18a27c21fa80f19f155c..b8cd4247f72d059bbce0dae46abdf6698649cfc0 100644 (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,
index 6aa0432d5dd4e523fd94b8225d2195a3a9b1463e..137c5ce08780cab12c892550f08db149ca909058 100644 (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;
index 8a7f7e94b64b1b8b7112a79e47d4e1f838035147..20ea91d68bbd71306324d7a0db0870ede7519385 100644 (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 {
index 89f971e71f966222720e6dce3029bffb1e51eacd..7968aa34954a9c64541d9e8d2155cbdd008aea5a 100644 (file)
@@ -237,7 +237,8 @@ macro_rules! index_store {
             in_situ_code_dir: InSituCodeDir::new(),
             in_situ_module_dir: ModuleStubDir::new(),
             op_dir: $op_dir,
-            modules: $modules,            
+            modules: $modules,
+            stream_aliases: StreamAliasDir::new(),
         }
     };
 }