]> Repositorios git - scryer-prolog.git/commitdiff
add user_error stream (#917)
authorMark Thom <[email protected]>
Sat, 1 May 2021 03:58:03 +0000 (21:58 -0600)
committerMark Thom <[email protected]>
Sat, 1 May 2021 03:58:03 +0000 (21:58 -0600)
src/bin/scryer-prolog.rs
src/heap_print.rs
src/machine/code_walker.rs
src/machine/machine_state.rs
src/machine/machine_state_impl.rs
src/machine/mod.rs
src/machine/partial_string.rs
src/machine/raw_block.rs
src/machine/streams.rs
src/machine/system_calls.rs

index 4260bdd5d16f7e1cd1ec41ac70aa349fb5f5d2ee..a1cf2a99967222a0df03dcb7276cb387e6f94368 100644 (file)
@@ -6,7 +6,11 @@ fn main() {
     let handler = signal::SigHandler::Handler(handle_sigint);
     unsafe { signal::signal(signal::Signal::SIGINT, handler) }.unwrap();
 
-    let mut wam = machine::Machine::new(readline::input_stream(), machine::Stream::stdout());
+    let mut wam = machine::Machine::new(
+        readline::input_stream(),
+        machine::Stream::stdout(),
+        machine::Stream::stderr(),
+    );
     wam.run_top_level();
 }
 
index 3b2dce9d1b3b57f824ef6ef4e00107e7f967db61..7655983bf02f432d1e3985577ebe00eebd3febe2 100644 (file)
@@ -1331,7 +1331,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
             self.print_atom(alias);
         } else {
             if self.format_struct(iter, max_depth, 1, clause_name!("$stream")) {
-                let atom = if stream.is_stdout() || stream.is_stdin() {
+                let atom = if stream.is_stdout() || stream.is_stdin() || stream.is_stderr() {
                     TokenOrRedirect::Atom(clause_name!("user"))
                 } else {
                     TokenOrRedirect::RawPtr(stream.as_ptr())
index 9bde8a360fb17cf3d309715099d0fe78c7966177..fe63347f6fc27a84998f3702c8048940cf1c5318 100644 (file)
@@ -14,13 +14,15 @@ fn capture_offset(line: &Line, index: usize, stack: &mut Vec<usize>) -> bool {
             stack.push(index + offset);
         }
         &Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Next(offset)))
-            if offset > 0 => {
-                stack.push(index + offset);
-            }
+            if offset > 0 =>
+        {
+            stack.push(index + offset);
+        }
         &Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Next(offset)))
-            if offset > 0 => {
-                stack.push(index + offset);
-            }
+            if offset > 0 =>
+        {
+            stack.push(index + offset);
+        }
         &Line::Control(ControlInstruction::JmpBy(_, offset, _, false)) => {
             stack.push(index + offset);
         }
index ee48340acfc85cf0e1cec8fccbc86c3bc9bf1b9f..2d8e6d47df0fa54f8563b61e7b7195c010f18b16 100644 (file)
@@ -310,49 +310,55 @@ pub(crate) struct MachineState {
 impl fmt::Debug for MachineState {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.debug_struct("MachineState")
-         .field("atom_tbl", &self.atom_tbl)
-         .field("s", &self.s)
-         .field("p", &self.p)
-         .field("b", &self.b)
-         .field("b0", &self.b0)
-         .field("e", &self.e)
-         .field("num_of_args", &self.num_of_args)
-         .field("cp", &self.cp)
-         .field("attr_var_init", &self.attr_var_init)
-         .field("fail", &self.fail)
-         .field("heap", &self.heap)
-         .field("mode", &self.mode)
-         .field("stack", &self.stack)
-         .field("registers", &self.registers)
-         .field("trail", &self.trail)
-         .field("tr", &self.tr)
-         .field("hb", &self.hb)
-         .field("block", &self.block)
-         .field("ball", &self.ball)
-         .field("lifted_heap", &self.lifted_heap)
-         .field("interms", &self.interms)
-         .field("last_call", &self.last_call)
-         .field("flags", &self.flags)
-         .field("cc", &self.cc)
-         .field("global_clock", &self.global_clock)
-         .field("dynamic_mode", &self.dynamic_mode)
-         .field("unify_fn",
+            .field("atom_tbl", &self.atom_tbl)
+            .field("s", &self.s)
+            .field("p", &self.p)
+            .field("b", &self.b)
+            .field("b0", &self.b0)
+            .field("e", &self.e)
+            .field("num_of_args", &self.num_of_args)
+            .field("cp", &self.cp)
+            .field("attr_var_init", &self.attr_var_init)
+            .field("fail", &self.fail)
+            .field("heap", &self.heap)
+            .field("mode", &self.mode)
+            .field("stack", &self.stack)
+            .field("registers", &self.registers)
+            .field("trail", &self.trail)
+            .field("tr", &self.tr)
+            .field("hb", &self.hb)
+            .field("block", &self.block)
+            .field("ball", &self.ball)
+            .field("lifted_heap", &self.lifted_heap)
+            .field("interms", &self.interms)
+            .field("last_call", &self.last_call)
+            .field("flags", &self.flags)
+            .field("cc", &self.cc)
+            .field("global_clock", &self.global_clock)
+            .field("dynamic_mode", &self.dynamic_mode)
+            .field(
+                "unify_fn",
                 if self.unify_fn as usize == MachineState::unify as usize {
                     &"MachineState::unify"
                 } else if self.unify_fn as usize == MachineState::unify_with_occurs_check as usize {
                     &"MachineState::unify_with_occurs_check"
                 } else {
                     &"MachineState::unify_with_occurs_check_with_error"
-                })
-         .field("bind_fn",
+                },
+            )
+            .field(
+                "bind_fn",
                 if self.bind_fn as usize == MachineState::bind as usize {
                     &"MachineState::bind"
-                } else if self.bind_fn as usize == MachineState::bind_with_occurs_check_wrapper as usize {
+                } else if self.bind_fn as usize
+                    == MachineState::bind_with_occurs_check_wrapper as usize
+                {
                     &"MachineState::bind_with_occurs_check"
                 } else {
                     &"MachineState::bind_with_occurs_check_with_error_wrapper"
-                })
-         .finish()
+                },
+            )
+            .finish()
     }
 }
 
index a6539ee2e20951f7f584cb1dc27f30c5bcd0560b..946d0945777a3751f6a4577bcbefb1d7c5e3bc6a 100644 (file)
@@ -222,7 +222,7 @@ impl MachineState {
         &mut self,
         a1: Addr,
         a2: Addr,
-        mut occurs_trigger: impl FnMut()
+        mut occurs_trigger: impl FnMut(),
     ) {
         let mut pdl = vec![a1, a2];
         let mut tabu_list: IndexSet<(Addr, Addr)> = IndexSet::new();
@@ -1241,7 +1241,8 @@ impl MachineState {
                         let h = self.heap.h();
 
                         self.heap.push(HeapCellValue::Addr(Addr::Str(h + 1)));
-                        self.heap.push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec()));
+                        self.heap
+                            .push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec()));
 
                         self.bind(addr.as_var().unwrap(), Addr::HeapCell(h));
 
@@ -1380,7 +1381,7 @@ impl MachineState {
                 _ => {}
             }
 
-            match &code[p-1] {
+            match &code[p - 1] {
                 &Line::Choice(ChoiceInstruction::DynamicInternalElse(birth, death, _)) => {
                     if birth < machine_st.cc && Death::Finite(machine_st.cc) <= death {
                         return true;
@@ -1411,9 +1412,7 @@ impl MachineState {
                         Addr::LoadStatePayload(_) | Addr::Stream(_) | Addr::TcpListener(_) => {
                             IndexingCodePtr::Fail
                         }
-                        Addr::HeapCell(_) | Addr::StackCell(..) | Addr::AttrVar(..) => {
-                            v
-                        }
+                        Addr::HeapCell(_) | Addr::StackCell(..) | Addr::AttrVar(..) => v,
                         Addr::PStrLocation(..) => l,
                         Addr::Char(_)
                         | Addr::Con(_)
@@ -3203,15 +3202,11 @@ impl MachineState {
 
         match code_repo.find_living_dynamic(p, self.cc) {
             Some((offset, oi, ii, is_next_clause)) => {
-                self.p = CodePtr::Local(LocalCodePtr::IndexingBuf(
-                    p.abs_loc(), oi, ii,
-                ));
+                self.p = CodePtr::Local(LocalCodePtr::IndexingBuf(p.abs_loc(), oi, ii));
 
                 match self.dynamic_mode {
                     FirstOrNext::First if !is_next_clause => {
-                        self.p = CodePtr::Local(LocalCodePtr::DirEntry(
-                            p.abs_loc() + offset,
-                        ));
+                        self.p = CodePtr::Local(LocalCodePtr::DirEntry(p.abs_loc() + offset));
                     }
                     FirstOrNext::First => {
                         // there's a leading DynamicElse that sets self.cc.
@@ -3234,9 +3229,8 @@ impl MachineState {
                                 self.num_of_args -= 1;
                             }
                             None => {
-                                self.p = CodePtr::Local(LocalCodePtr::DirEntry(
-                                    p.abs_loc() + offset,
-                                ));
+                                self.p =
+                                    CodePtr::Local(LocalCodePtr::DirEntry(p.abs_loc() + offset));
                             }
                         }
                     }
@@ -3261,33 +3255,18 @@ impl MachineState {
                                 Some(_) => {
                                     try_or_fail!(
                                         self,
-                                        call_policy.retry(
-                                            self,
-                                            offset,
-                                            global_variables,
-                                        )
+                                        call_policy.retry(self, offset, global_variables,)
                                     )
                                 }
                                 None => {
                                     try_or_fail!(
                                         self,
-                                        call_policy.trust(
-                                            self,
-                                            offset,
-                                            global_variables,
-                                        )
+                                        call_policy.trust(self, offset, global_variables,)
                                     )
                                 }
                             }
                         } else {
-                            try_or_fail!(
-                                self,
-                                call_policy.trust(
-                                    self,
-                                    offset,
-                                    global_variables,
-                                )
-                            )
+                            try_or_fail!(self, call_policy.trust(self, offset, global_variables,))
                         }
                     }
                 }
@@ -3297,7 +3276,7 @@ impl MachineState {
             None => {
                 self.fail = true;
             }
-                }
+        }
     }
 
     pub(super) fn execute_indexed_choice_instr(
@@ -3415,20 +3394,14 @@ impl MachineState {
                                         None => {
                                             try_or_fail!(
                                                 self,
-                                                call_policy.trust_me(
-                                                    self,
-                                                    global_variables,
-                                                )
+                                                call_policy.trust_me(self, global_variables,)
                                             )
                                         }
                                     }
                                 } else {
                                     try_or_fail!(
                                         self,
-                                        call_policy.trust_me(
-                                            self,
-                                            global_variables,
-                                        )
+                                        call_policy.trust_me(self, global_variables,)
                                     )
                                 }
                             }
@@ -3500,20 +3473,14 @@ impl MachineState {
                                         None => {
                                             try_or_fail!(
                                                 self,
-                                                call_policy.trust_me(
-                                                    self,
-                                                    global_variables,
-                                                )
+                                                call_policy.trust_me(self, global_variables,)
                                             )
                                         }
                                     }
                                 } else {
                                     try_or_fail!(
                                         self,
-                                        call_policy.trust_me(
-                                            self,
-                                            global_variables,
-                                        )
+                                        call_policy.trust_me(self, global_variables,)
                                     )
                                 }
                             }
index 44a40e3277511d8e6ec51f3e157e1a4411c7e080..5712fe4dcb0952469360aebd61da28fa6cd2201c 100644 (file)
@@ -115,6 +115,7 @@ pub struct Machine {
     pub(super) code_repo: CodeRepo,
     pub(super) user_input: Stream,
     pub(super) user_output: Stream,
+    pub(super) user_error: Stream,
     pub(super) load_contexts: Vec<LoadContext>,
 }
 
@@ -274,7 +275,7 @@ impl Machine {
         }
     }
 
-    pub fn new(user_input: Stream, user_output: Stream) -> Self {
+    pub fn new(user_input: Stream, user_output: Stream, user_error: Stream) -> Self {
         use ref_thread_local::RefThreadLocal;
 
         let mut wam = Machine {
@@ -285,6 +286,7 @@ impl Machine {
             code_repo: CodeRepo::new(),
             user_input,
             user_output,
+            user_error,
             load_contexts: vec![],
         };
 
@@ -367,6 +369,12 @@ impl Machine {
             .stream_aliases
             .insert(clause_name!("user_output"), self.user_output.clone());
 
+        self.user_error.options_mut().alias = Some(clause_name!("user_error"));
+
+        self.indices
+            .stream_aliases
+            .insert(clause_name!("user_error"), self.user_error.clone());
+
         self.indices.streams.insert(self.user_output.clone());
     }
 
@@ -528,14 +536,12 @@ impl MachineState {
     ) {
         match instr {
             &Line::Arithmetic(ref arith_instr) => self.execute_arith_instr(arith_instr),
-            &Line::Choice(ref choice_instr) => {
-                self.execute_choice_instr(
-                    choice_instr,
-                    code_repo,
-                    &mut policies.call_policy,
-                    &mut indices.global_variables,
-                )
-            }
+            &Line::Choice(ref choice_instr) => self.execute_choice_instr(
+                choice_instr,
+                code_repo,
+                &mut policies.call_policy,
+                &mut indices.global_variables,
+            ),
             &Line::Cut(ref cut_instr) => {
                 self.execute_cut_instr(cut_instr, &mut policies.cut_policy)
             }
@@ -553,25 +559,18 @@ impl MachineState {
                 self.p += 1;
             }
             &Line::IndexingCode(ref indexing_lines) => {
-                self.execute_indexing_instr(
-                    indexing_lines,
-                    code_repo,
-                )
-            }
-            &Line::IndexedChoice(ref choice_instr) => {
-                self.execute_indexed_choice_instr(
-                    choice_instr,
-                    &mut policies.call_policy,
-                    &mut indices.global_variables,
-                )
-            }
-            &Line::DynamicIndexedChoice(_) => {
-                self.execute_dynamic_indexed_choice_instr(
-                    code_repo,
-                    &mut policies.call_policy,
-                    &mut indices.global_variables,
-                )
+                self.execute_indexing_instr(indexing_lines, code_repo)
             }
+            &Line::IndexedChoice(ref choice_instr) => self.execute_indexed_choice_instr(
+                choice_instr,
+                &mut policies.call_policy,
+                &mut indices.global_variables,
+            ),
+            &Line::DynamicIndexedChoice(_) => self.execute_dynamic_indexed_choice_instr(
+                code_repo,
+                &mut policies.call_policy,
+                &mut indices.global_variables,
+            ),
             &Line::Query(ref query_instr) => {
                 self.execute_query_instr(&query_instr);
                 self.p += 1;
index 58f8cf375c0196e99fb016203c12c5999b341e10..79354874785ba44c0516a3de007b123821eb1f99 100644 (file)
@@ -409,13 +409,11 @@ pub(super) fn compare_pstr_prefixes<'a>(
 
         let machine_st = i1.machine_st;
 
-        let check_focuses = || {
-            match (i1.focus(), i2.focus()) {
-                (Addr::EmptyList, Addr::EmptyList) => Some(Ordering::Equal),
-                (Addr::EmptyList, _) => Some(Ordering::Less),
-                (_, Addr::EmptyList) => Some(Ordering::Greater),
-                _ => None,
-            }
+        let check_focuses = || match (i1.focus(), i2.focus()) {
+            (Addr::EmptyList, Addr::EmptyList) => Some(Ordering::Equal),
+            (Addr::EmptyList, _) => Some(Ordering::Less),
+            (_, Addr::EmptyList) => Some(Ordering::Greater),
+            _ => None,
         };
 
         return match r1 {
@@ -430,12 +428,8 @@ pub(super) fn compare_pstr_prefixes<'a>(
                     unreachable!()
                 }
             }
-            Some(PStrIteratee::Char(_)) => {
-                Some(ordering)
-            }
-            None => {
-                check_focuses()
-            }
+            Some(PStrIteratee::Char(_)) => Some(ordering),
+            None => check_focuses(),
         };
     }
 }
index e44b714b7fb1920155ba72aebbd725f82525d963..1b5d79fbeb6a570d1d2831df2b0ebea5f8278600 100644 (file)
@@ -23,12 +23,13 @@ pub(crate) struct RawBlock<T: RawBlockTraits> {
 }
 
 impl<T: RawBlockTraits> RawBlock<T> {
-    pub(crate)
-    fn new() -> Self {
-        let mut block = RawBlock { size: 0,
-                                   base: ptr::null(),
-                                   top: ptr::null(),
-                                   _marker: PhantomData };
+    pub(crate) fn new() -> Self {
+        let mut block = RawBlock {
+            size: 0,
+            base: ptr::null(),
+            top: ptr::null(),
+            _marker: PhantomData,
+        };
 
         unsafe {
             block.grow();
@@ -46,45 +47,47 @@ impl<T: RawBlockTraits> RawBlock<T> {
         self.top = T::base_offset(self.base);
     }
 
-    pub(super)
-    unsafe fn grow(&mut self) {
+    pub(super) unsafe fn grow(&mut self) {
         if self.size == 0 {
             self.init_at_size(T::init_size());
         } else {
             let layout = alloc::Layout::from_size_align_unchecked(T::init_size(), T::align());
             let top_dist = self.top as usize - self.base as usize;
 
-            self.base = alloc::realloc(self.base as *mut _, layout, self.size*2) as *const _;
+            self.base = alloc::realloc(self.base as *mut _, layout, self.size * 2) as *const _;
             self.top = (self.base as usize + top_dist) as *const _;
             self.size *= 2;
         }
     }
 
     fn empty_block() -> Self {
-        RawBlock { size: 0,
-                 base: ptr::null(),
-                 top: ptr::null(),
-                 _marker: PhantomData }
+        RawBlock {
+            size: 0,
+            base: ptr::null(),
+            top: ptr::null(),
+            _marker: PhantomData,
+        }
     }
 
     #[inline]
-    pub(crate)
-    fn take(&mut self) -> Self {
+    pub(crate) fn take(&mut self) -> Self {
         mem::replace(self, Self::empty_block())
     }
 
     #[inline]
     fn free_space(&self) -> usize {
-        debug_assert!(self.top >= self.base,
-                      "self.top = {:?} < {:?} = self.base",
-                      self.top, self.base);
+        debug_assert!(
+            self.top >= self.base,
+            "self.top = {:?} < {:?} = self.base",
+            self.top,
+            self.base
+        );
 
         self.size - (self.top as usize - self.base as usize)
     }
 
     #[inline]
-    pub(crate)
-    unsafe fn new_block(&mut self, size: usize) -> *const u8 {
+    pub(crate) unsafe fn new_block(&mut self, size: usize) -> *const u8 {
         loop {
             if self.free_space() >= size {
                 return (self.top as usize + size) as *const _;
@@ -94,14 +97,13 @@ impl<T: RawBlockTraits> RawBlock<T> {
         }
     }
 
-    pub(crate)
-    fn deallocate(&mut self) {
+    pub(crate) fn deallocate(&mut self) {
         unsafe {
             let layout = alloc::Layout::from_size_align_unchecked(self.size, T::align());
 
             alloc::dealloc(self.base as *mut u8, layout);
 
-            self.top  = ptr::null();
+            self.top = ptr::null();
             self.base = ptr::null();
             self.size = 0;
         }
index 97c3b494b916c82b03a722a80734bd8cf5c7e3f9..642bbf1785a6fdca8c651de879a61befa39a946d 100644 (file)
@@ -14,7 +14,7 @@ use std::fmt;
 use std::fs::File;
 use std::hash::{Hash, Hasher};
 use std::io;
-use std::io::{stdout, Cursor, ErrorKind, Read, Seek, SeekFrom, Write};
+use std::io::{stderr, stdout, Cursor, ErrorKind, Read, Seek, SeekFrom, Write};
 use std::mem;
 use std::net::{Shutdown, TcpStream};
 use std::ops::DerefMut;
@@ -114,6 +114,7 @@ enum StreamInstance {
     PausedPrologStream(Vec<u8>, Box<StreamInstance>),
     ReadlineStream(ReadlineStream),
     StaticStr(Cursor<&'static str>),
+    Stderr,
     Stdout,
     TcpStream(ClauseName, TcpStream),
     TlsStream(ClauseName, TlsStream<TcpStream>),
@@ -148,12 +149,13 @@ impl StreamInstance {
             StreamInstance::ReadlineStream(ref mut rl_stream) => rl_stream.read(buf),
             StreamInstance::StaticStr(ref mut src) => src.read(buf),
             StreamInstance::Bytes(ref mut cursor) => cursor.read(buf),
-            StreamInstance::OutputFile(..) | StreamInstance::Stdout | StreamInstance::Null => {
-                Err(std::io::Error::new(
-                    ErrorKind::PermissionDenied,
-                    StreamError::ReadFromOutputStream,
-                ))
-            }
+            StreamInstance::OutputFile(..)
+            | StreamInstance::Stderr
+            | StreamInstance::Stdout
+            | StreamInstance::Null => Err(std::io::Error::new(
+                ErrorKind::PermissionDenied,
+                StreamError::ReadFromOutputStream,
+            )),
         }
     }
 }
@@ -186,6 +188,7 @@ impl fmt::Debug for StreamInstance {
             &StreamInstance::ReadlineStream(ref readline_stream) => {
                 write!(fmt, "ReadlineStream({:?})", readline_stream)
             }
+            &StreamInstance::Stderr => write!(fmt, "Stderr"),
             &StreamInstance::Stdout => write!(fmt, "Stdout"),
             &StreamInstance::TcpStream(_, ref tcp_stream) => {
                 write!(fmt, "TcpStream({:?})", tcp_stream)
@@ -521,7 +524,9 @@ impl Stream {
             | StreamInstance::InputFile(..) => "read",
             StreamInstance::TcpStream(..) | StreamInstance::TlsStream(..) => "read_append",
             StreamInstance::OutputFile(_, _, true) => "append",
-            StreamInstance::Stdout | StreamInstance::OutputFile(_, _, false) => "write",
+            StreamInstance::Stderr
+            | StreamInstance::Stdout
+            | StreamInstance::OutputFile(_, _, false) => "write",
             StreamInstance::Null => "",
         }
     }
@@ -538,6 +543,11 @@ impl Stream {
         Stream::from_inst(StreamInstance::Stdout)
     }
 
+    #[inline]
+    pub fn stderr() -> Self {
+        Stream::from_inst(StreamInstance::Stderr)
+    }
+
     #[inline]
     pub(crate) fn from_tcp_stream(address: ClauseName, tcp_stream: TcpStream) -> Self {
         tcp_stream.set_read_timeout(None).unwrap();
@@ -561,6 +571,14 @@ impl Stream {
         Stream::from_inst(StreamInstance::InputFile(name, file))
     }
 
+    #[inline]
+    pub(crate) fn is_stderr(&self) -> bool {
+        match self.stream_inst.0.borrow().stream_inst {
+            StreamInstance::Stderr => true,
+            _ => false,
+        }
+    }
+
     #[inline]
     pub(crate) fn is_stdout(&self) -> bool {
         match self.stream_inst.0.borrow().stream_inst {
@@ -608,7 +626,8 @@ impl Stream {
     #[inline]
     pub(crate) fn is_output_stream(&self) -> bool {
         match self.stream_inst.0.borrow().stream_inst {
-            StreamInstance::Stdout
+            StreamInstance::Stderr
+            | StreamInstance::Stdout
             | StreamInstance::TcpStream(..)
             | StreamInstance::TlsStream(..)
             | StreamInstance::Bytes(_)
@@ -1110,6 +1129,7 @@ impl Write for Stream {
             StreamInstance::TlsStream(_, ref mut tls_stream) => tls_stream.write(buf),
             StreamInstance::Bytes(ref mut cursor) => cursor.write(buf),
             StreamInstance::Stdout => stdout().write(buf),
+            StreamInstance::Stderr => stderr().write(buf),
             StreamInstance::PausedPrologStream(..)
             | StreamInstance::StaticStr(_)
             | StreamInstance::ReadlineStream(_)
@@ -1127,6 +1147,7 @@ impl Write for Stream {
             StreamInstance::TcpStream(_, ref mut tcp_stream) => tcp_stream.flush(),
             StreamInstance::TlsStream(_, ref mut tls_stream) => tls_stream.flush(),
             StreamInstance::Bytes(ref mut cursor) => cursor.flush(),
+            StreamInstance::Stderr => stderr().flush(),
             StreamInstance::Stdout => stdout().flush(),
             StreamInstance::PausedPrologStream(..)
             | StreamInstance::StaticStr(_)
index 00aa6d6e563cfde35fe3515e13890d4b7f3cbc36..556ad604fd40f9c29b2de0ba7f5f421a87e9ab03 100644 (file)
@@ -1852,26 +1852,24 @@ impl MachineState {
                 let addr = self[temp_v!(2)];
 
                 match indices.global_variables.get_mut(&key) {
-                    Some((ref ball, ref mut loc)) => {
-                        match loc {
-                            Some(ref value_addr) => {
-                                (self.unify_fn)(self, addr, *value_addr);
-                            }
-                            loc @ None if !ball.stub.is_empty() => {
-                                let h = self.heap.h();
-                                let stub = ball.copy_and_align(h);
+                    Some((ref ball, ref mut loc)) => match loc {
+                        Some(ref value_addr) => {
+                            (self.unify_fn)(self, addr, *value_addr);
+                        }
+                        loc @ None if !ball.stub.is_empty() => {
+                            let h = self.heap.h();
+                            let stub = ball.copy_and_align(h);
 
-                                self.heap.extend(stub.into_iter());
-                                (self.unify_fn)(self, addr, Addr::HeapCell(h));
+                            self.heap.extend(stub.into_iter());
+                            (self.unify_fn)(self, addr, Addr::HeapCell(h));
 
-                                if !self.fail {
-                                    *loc = Some(Addr::HeapCell(h));
-                                    self.trail(TrailRef::BlackboardEntry(key_h));
-                                }
+                            if !self.fail {
+                                *loc = Some(Addr::HeapCell(h));
+                                self.trail(TrailRef::BlackboardEntry(key_h));
                             }
-                            _ => self.fail = true,
                         }
-                    }
+                        _ => self.fail = true,
+                    },
                     None => self.fail = true,
                 };
             }
@@ -2617,7 +2615,7 @@ impl MachineState {
                     indices.streams.insert(current_output_stream.clone());
                 }
 
-                if !stream.is_stdin() && !stream.is_stdout() {
+                if !stream.is_stdin() && !stream.is_stdout() && !stream.is_stderr() {
                     stream.close();
 
                     if let Some(ref alias) = stream.options().alias {
@@ -3472,17 +3470,22 @@ impl MachineState {
                 self.fail = match self.store(self.deref(self[temp_v!(2)])) {
                     Addr::Str(s) => match &self.heap[s] {
                         &HeapCellValue::NamedStr(arity, ref name, ref spec) => {
-                            if CLAUSE_TYPE_FORMS.borrow().get(&(name.as_str(), arity)).is_some() {
+                            if CLAUSE_TYPE_FORMS
+                                .borrow()
+                                .get(&(name.as_str(), arity))
+                                .is_some()
+                            {
                                 true
                             } else {
-                                let index = indices.get_predicate_code_index(
-                                    name.clone(),
-                                    arity,
-                                    module_name,
-                                    spec.clone(),
-                                )
-                                .map(|index| index.get())
-                                .unwrap_or(IndexPtr::DynamicUndefined);
+                                let index = indices
+                                    .get_predicate_code_index(
+                                        name.clone(),
+                                        arity,
+                                        module_name,
+                                        spec.clone(),
+                                    )
+                                    .map(|index| index.get())
+                                    .unwrap_or(IndexPtr::DynamicUndefined);
 
                                 match index {
                                     IndexPtr::DynamicUndefined => false,
@@ -3499,17 +3502,22 @@ impl MachineState {
                             let spec =
                                 fetch_atom_op_spec(name.clone(), spec.clone(), &indices.op_dir);
 
-                            if CLAUSE_TYPE_FORMS.borrow().get(&(name.as_str(), 0)).is_some() {
+                            if CLAUSE_TYPE_FORMS
+                                .borrow()
+                                .get(&(name.as_str(), 0))
+                                .is_some()
+                            {
                                 true
                             } else {
-                                let index = indices.get_predicate_code_index(
-                                    name.clone(),
-                                    0,
-                                    module_name,
-                                    spec.clone(),
-                                )
-                                .map(|index| index.get())
-                                .unwrap_or(IndexPtr::DynamicUndefined);
+                                let index = indices
+                                    .get_predicate_code_index(
+                                        name.clone(),
+                                        0,
+                                        module_name,
+                                        spec.clone(),
+                                    )
+                                    .map(|index| index.get())
+                                    .unwrap_or(IndexPtr::DynamicUndefined);
 
                                 match index {
                                     IndexPtr::DynamicUndefined => false,
@@ -4482,22 +4490,22 @@ impl MachineState {
                 let new_value = self.store(self.deref(self[temp_v!(2)]));
 
                 match indices.global_variables.get_mut(&key) {
-                    Some((_, ref mut loc)) => {
-                        match loc {
-                            Some(ref mut value) => {
-                                let old_value_loc = self.heap.push(HeapCellValue::Addr(*value));
-                                self.trail(TrailRef::BlackboardOffset(key_h, old_value_loc));
-                                *value = new_value;
-                            }
-                            loc @ None => {
-                                self.trail(TrailRef::BlackboardEntry(key_h));
-                                *loc = Some(new_value);
-                            }
+                    Some((_, ref mut loc)) => match loc {
+                        Some(ref mut value) => {
+                            let old_value_loc = self.heap.push(HeapCellValue::Addr(*value));
+                            self.trail(TrailRef::BlackboardOffset(key_h, old_value_loc));
+                            *value = new_value;
                         }
-                    }
+                        loc @ None => {
+                            self.trail(TrailRef::BlackboardEntry(key_h));
+                            *loc = Some(new_value);
+                        }
+                    },
                     None => {
                         self.trail(TrailRef::BlackboardEntry(key_h));
-                        indices.global_variables.insert(key, (Ball::new(), Some(new_value)));
+                        indices
+                            .global_variables
+                            .insert(key, (Ball::new(), Some(new_value)));
                     }
                 }
             }
@@ -5361,21 +5369,23 @@ impl MachineState {
             }
             &SystemClauseType::IsSTOEnabled => {
                 if self.unify_fn as usize == MachineState::unify_with_occurs_check as usize {
-                    let value = self.heap.to_unifiable(
-                        HeapCellValue::Atom(clause_name!("true"), None),
-                    );
+                    let value = self
+                        .heap
+                        .to_unifiable(HeapCellValue::Atom(clause_name!("true"), None));
 
                     (self.unify_fn)(self, self[temp_v!(1)], value);
-                } else if self.unify_fn as usize == MachineState::unify_with_occurs_check_with_error as usize {
-                    let value = self.heap.to_unifiable(
-                        HeapCellValue::Atom(clause_name!("error"), None),
-                    );
+                } else if self.unify_fn as usize
+                    == MachineState::unify_with_occurs_check_with_error as usize
+                {
+                    let value = self
+                        .heap
+                        .to_unifiable(HeapCellValue::Atom(clause_name!("error"), None));
 
                     (self.unify_fn)(self, self[temp_v!(1)], value);
                 } else {
-                    let value = self.heap.to_unifiable(
-                        HeapCellValue::Atom(clause_name!("false"), None),
-                    );
+                    let value = self
+                        .heap
+                        .to_unifiable(HeapCellValue::Atom(clause_name!("false"), None));
 
                     (self.unify_fn)(self, self[temp_v!(1)], value);
                 }