]> Repositorios git - scryer-prolog.git/commitdiff
add streams.rs, consume them in place of the old PrologStream
authorMark Thom <[email protected]>
Mon, 9 Mar 2020 17:56:16 +0000 (11:56 -0600)
committerMark Thom <[email protected]>
Mon, 9 Mar 2020 17:56:16 +0000 (11:56 -0600)
17 files changed:
src/prolog/clause_types.rs
src/prolog/heap_iter.rs
src/prolog/lib/builtins.pl
src/prolog/machine/compile.rs
src/prolog/machine/copier.rs
src/prolog/machine/dynamic_database.rs
src/prolog/machine/machine_errors.rs
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 [new file with mode: 0644]
src/prolog/machine/system_calls.rs
src/prolog/machine/term_expansion.rs
src/prolog/machine/toplevel.rs
src/prolog/read.rs
src/prolog/write.rs

index 62604b6da08eb77cd1aa0656abb55fef9737c6fd..e0cfbe903bbfdfd89a4ee6f775e98675c0d8c39e 100644 (file)
@@ -170,6 +170,7 @@ pub enum SystemClauseType {
     CheckCutPoint,
     CopyToLiftedHeap,
     CreatePartialString,
+    CurrentInput,
     DeleteAttribute,
     DeleteHeadAttribute,
     DynamicModuleResolution(usize),
@@ -283,6 +284,7 @@ impl SystemClauseType {
             &SystemClauseType::CodesToNumber => clause_name!("$codes_to_number"),
             &SystemClauseType::CopyTermWithoutAttrVars => clause_name!("$copy_term_without_attr_vars"),
             &SystemClauseType::CreatePartialString => clause_name!("$create_partial_string"),
+            &SystemClauseType::CurrentInput => clause_name!("$current_input"),
             &SystemClauseType::REPL(REPLCodePtr::CompileBatch) => clause_name!("$compile_batch"),
            &SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"),
            &SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule) => {
@@ -433,6 +435,7 @@ impl SystemClauseType {
             ("$check_cp", 1) => Some(SystemClauseType::CheckCutPoint),
             ("$compile_batch", 0) => Some(SystemClauseType::REPL(REPLCodePtr::CompileBatch)),
             ("$copy_to_lh", 2) => Some(SystemClauseType::CopyToLiftedHeap),
+            ("$current_input", 1) => Some(SystemClauseType::CurrentInput),
             ("$del_attr_non_head", 1) => Some(SystemClauseType::DeleteAttribute),
             ("$del_attr_head", 1) => Some(SystemClauseType::DeleteHeadAttribute),
             ("$get_next_db_ref", 2) => Some(SystemClauseType::GetNextDBRef),
index e3780b209526caa13a99e61dd83e191d7cf810a6..275761cf63e24b13312424b6aa04513b36f64d28 100644 (file)
@@ -72,7 +72,7 @@ impl<'a> HCPreOrderIterator<'a> {
 
                 Addr::Con(Constant::String(n, s))
             }
-            Addr::Con(_) | Addr::DBRef(_) => {
+            Addr::Con(_) | Addr::DBRef(_) | Addr::Stream(_) => {
                 da
             }
             Addr::Lis(a) => {
index 6a3f091e9fe15dd90123e8e3a4c64dbc3343a03c..c8d85b9a345542392038a82e60dc5ac9b92fbbb6 100644 (file)
@@ -44,7 +44,7 @@ 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_op/3, current_predicate/1,
+                    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,
@@ -1012,3 +1012,5 @@ subsumes_term(General, Specific) :-
    ).
 
 unify_with_occurs_check(X, Y) :- '$unify_with_occurs_check'(X, Y).
+
+current_input(S) :- '$current_input'(S).    
index 5241bacf5e87f60e59f923b3048f528d3e6949a9..03359b58680fd9a4ba66c84eedd623bede187c95 100644 (file)
@@ -21,7 +21,6 @@ use ref_thread_local::RefThreadLocal;
 use std::cell::Cell;
 use std::collections::VecDeque;
 use std::fs::File;
-use std::io::Read;
 use std::mem;
 use std::path::PathBuf;
 
@@ -60,9 +59,9 @@ fn fix_filename(
     Ok(path)
 }
 
-fn load_module<R: Read>(
+fn load_module(
     wam: &mut Machine,
-    stream: ParsingStream<R>,
+    stream: Stream,
     suppress_warnings: bool,
     listing_src: &ListingSource,
 ) -> Result<ClauseName, SessionError> {
@@ -78,7 +77,11 @@ fn load_module<R: Read>(
         listing_src.clone(),
     );
 
-    let results = compiler.gather_items(wam, stream, &mut indices);
+    let results = compiler.gather_items(
+        wam,
+        &mut parsing_stream(stream),
+        &mut indices,
+    );
 
     let module_name = if let Some(ref module) = &compiler.module {
         module.module_decl.name.clone()
@@ -114,14 +117,14 @@ fn load_module_from_file(
     let mut path_buf = fix_filename(wam.indices.atom_tbl.clone(), path_buf)?;
     let filename = clause_name!(path_buf.to_string_lossy().to_string(), wam.indices.atom_tbl);
 
-    let file_handle = File::open(&path_buf).or_else(|_| {
+    let file_handle = Stream::from(File::open(&path_buf).or_else(|_| {
         Err(SessionError::InvalidFileName(filename.clone()))
-    })?;
+    })?);
 
     path_buf.pop();
 
     let listing_src = ListingSource::from_file_and_path(filename, path_buf);
-    load_module(wam, parsing_stream(file_handle), suppress_warnings, &listing_src)
+    load_module(wam, file_handle, suppress_warnings, &listing_src)
 }
 
 pub type PredicateCompileQueue = (Predicate, VecDeque<TopLevel>);
@@ -320,10 +323,11 @@ fn setup_module_expansions(wam: &mut Machine, module: &Module) {
     );
 }
 
-pub(super) fn compile_into_module<R: Read>(
+pub(super)
+fn compile_into_module(
     wam: &mut Machine,
     module_name: ClauseName,
-    src: ParsingStream<R>,
+    src: Stream,
     name: ClauseName,
 ) -> EvalSession {
     let mut indices = default_index_store!(wam.atom_tbl_of(&name));
@@ -333,7 +337,11 @@ pub(super) fn compile_into_module<R: Read>(
     indices.op_dir   = module.op_dir.clone();
     indices.atom_tbl = module.atom_tbl.clone();
 
-    let mut compiler = ListingCompiler::new(&wam.code_repo, true, module.listing_src.clone());
+    let mut compiler = ListingCompiler::new(
+        &wam.code_repo,
+        true,
+        module.listing_src.clone(),
+    );
 
     match compile_into_module_impl(wam, &mut compiler, module, src, indices) {
         Ok(()) => EvalSession::EntrySuccess,
@@ -348,11 +356,11 @@ pub(super) fn compile_into_module<R: Read>(
     }
 }
 
-fn compile_into_module_impl<R: Read>(
+fn compile_into_module_impl(
     wam: &mut Machine,
     compiler: &mut ListingCompiler,
     module: Module,
-    src: ParsingStream<R>,
+    src: Stream,
     mut indices: IndexStore,
 ) -> Result<(), SessionError> {
     setup_module_expansions(wam, &module);
@@ -363,7 +371,11 @@ fn compile_into_module_impl<R: Read>(
     wam.code_repo.compile_hook(CompileTimeHook::TermExpansion)?;
     wam.code_repo.compile_hook(CompileTimeHook::GoalExpansion)?;
 
-    let mut results = compiler.gather_items(wam, src, &mut indices)?;
+    let mut results = compiler.gather_items(
+        wam,
+        &mut parsing_stream(src),
+        &mut indices,
+    )?;
 
     compiler.adapt_in_situ_code(
         results.worker_results,
@@ -392,7 +404,6 @@ fn compile_into_module_impl<R: Read>(
     );
 
     wam.code_repo.code.extend(results.in_situ_code.into_iter());
-
     clause_code_generator.add_clause_code(wam, results.dynamic_clause_map);
 
     Ok(compiler.drop_expansions(&mut wam.code_repo))
@@ -591,7 +602,7 @@ fn load_library(
 
             load_module(
                 wam,
-                parsing_stream(code.as_bytes()),
+                Stream::from(*code),
                 suppress_warnings,
                 &listing_src,
             )
@@ -1022,10 +1033,10 @@ impl ListingCompiler {
         }
     }
 
-    fn setup_multifile_decl<R: Read>(
+    fn setup_multifile_decl(
         &self,
         indicator: MultiFileIndicator,
-        worker: &mut TopLevelBatchWorker<R>,
+        worker: &mut TopLevelBatchWorker,
     ) -> Result<(), SessionError> {
         match indicator {
             MultiFileIndicator::LocalScoped(name, arity) => {
@@ -1055,10 +1066,10 @@ impl ListingCompiler {
         Ok(())
     }
 
-    fn process_and_commit_decl<R: Read>(
+    fn process_and_commit_decl(
         &mut self,
         decl: Declaration,
-        worker: &mut TopLevelBatchWorker<R>,
+        worker: &mut TopLevelBatchWorker,
         indices: &mut IndexStore,
         flags: MachineFlags,
     ) -> Result<(), SessionError> {
@@ -1105,15 +1116,15 @@ impl ListingCompiler {
         result
     }
 
-    pub(crate) fn gather_items<R: Read>(
+    pub(crate) fn gather_items(
         &mut self,
         wam: &mut Machine,
-        mut src: ParsingStream<R>,
+        src: &mut ParsingStream<Stream>,
         indices: &mut IndexStore,
     ) -> Result<GatherResult, SessionError> {
         let flags = wam.machine_flags();
         let atom_tbl = indices.atom_tbl.clone();
-        let mut worker = TopLevelBatchWorker::new(&mut src, atom_tbl.clone(), flags, wam);
+        let mut worker = TopLevelBatchWorker::new(src, atom_tbl.clone(), flags, wam);
 
         let mut toplevel_results = vec![];
         let mut toplevel_indices = default_index_store!(atom_tbl.clone());
@@ -1306,28 +1317,32 @@ fn compile_work_impl(
     Ok(())
 }
 
-fn compile_work<R: Read>(
+fn compile_work(
     compiler: &mut ListingCompiler,
     wam: &mut Machine,
-    src: ParsingStream<R>,
+    src: Stream,
     mut indices: IndexStore,
 ) -> EvalSession {
+    let src = &mut parsing_stream(src);
     let results = try_eval_session!(compiler.gather_items(wam, src, &mut indices));
+
     try_eval_session!(compile_work_impl(compiler, wam, indices, results));
+
     EvalSession::EntrySuccess
 }
 
 /* This is a truncated version of compile_user_module, used for
 compiling code composing special forms, ie. the code that calls
 M:verify_attributes on attributed variables. */
-pub fn compile_special_form<R: Read>(
+pub fn compile_special_form(
     wam: &mut Machine,
-    src: ParsingStream<R>,
+    src: Stream,
     listing_src: ListingSource,
 ) -> Result<usize, SessionError> {
     let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
     setup_indices(wam, clause_name!("builtins"), &mut indices)?;
 
+    let src = &mut parsing_stream(src);
     let mut compiler = ListingCompiler::new(&wam.code_repo, true, listing_src);
     let mut results = compiler.gather_items(wam, src, &mut indices)?;
 
@@ -1352,9 +1367,9 @@ pub fn compile_special_form<R: Read>(
 }
 
 #[inline]
-pub fn compile_listing<R: Read>(
+pub fn compile_listing(
     wam: &mut Machine,
-    src: ParsingStream<R>,
+    src: Stream,
     indices: IndexStore,
     suppress_warnings: bool,
     listing_src: ListingSource,
@@ -1388,9 +1403,9 @@ pub(super) fn setup_indices(
     }
 }
 
-pub fn compile_user_module<R: Read>(
+pub fn compile_user_module(
     wam: &mut Machine,
-    src: ParsingStream<R>,
+    src: Stream,
     suppress_warnings: bool,
     listing_src: ListingSource,
 ) -> EvalSession {
index 1dda5d66d0ef2cb6479ec42d651ceab402e9e275..8cc5dbd6e53aa0f29f1affb7613ce04a4cc6d3f2 100644 (file)
@@ -330,7 +330,7 @@ impl<T: CopierTarget> CopyTermState<T> {
                         Addr::PStrLocation(addr, n) => {
                             self.copy_partial_string_from(addr, n);
                         }
-                        Addr::Con(_) | Addr::DBRef(_) => {
+                        Addr::Con(_) | Addr::DBRef(_) | Addr::Stream(_) => {
                             self.scan += 1;
                         }
                     }
index 44871b4c6e3e210a81b8c303e36d3af210a87e12..e5151589bdb9b092182a99edd2658e948ccc866e 100644 (file)
@@ -1,11 +1,10 @@
 use prolog_parser::ast::*;
 
 use crate::prolog::heap_print::*;
+use crate::prolog::machine::*;
 use crate::prolog::machine::compile::*;
 use crate::prolog::machine::machine_errors::*;
-use crate::prolog::machine::*;
-
-use std::io::Read;
+use crate::prolog::machine::streams::*;
 
 impl Machine {
     pub(super) fn atom_tbl_of(&self, name: &ClauseName) -> TabledData<Atom> {
@@ -15,9 +14,9 @@ impl Machine {
         }
     }
 
-    fn compile_into_machine<R: Read>(
+    fn compile_into_machine(
         &mut self,
-        src: ParsingStream<R>,
+        src: Stream,
         name: ClauseName,
         arity: usize,
     ) -> EvalSession {
@@ -130,7 +129,12 @@ impl Machine {
     ) {
         let machine_st = mem::replace(&mut self.machine_st, MachineState::new());
 
-        let result = self.compile_into_machine(parsing_stream(pred_str.as_bytes()), name, arity);
+        let result = self.compile_into_machine(
+            Stream::from(pred_str),
+            name,
+            arity,
+        );
+        
         self.machine_st = machine_st;
 
         if let EvalSession::Error(err) = result {
index 7986261971f0ba03b132a8e58bc04d011d367854..073b3f3d5d4555a325d905e1705bdfdf06f8b0ca 100644 (file)
@@ -333,12 +333,14 @@ impl ValidType {
 #[derive(Clone, Copy)]
 pub enum DomainError {
     NotLessThanZero,
+    Stream,
 }
 
 impl DomainError {
     pub fn as_str(self) -> &'static str {
         match self {
             DomainError::NotLessThanZero => "not_less_than_zero",
+            DomainError::Stream => "stream",
         }
     }
 }
index 142d30e15f90313970ce6c0fe871b02cf69649f2..be54937efdb7c80804ab89851b695b4bd599ee11 100644 (file)
@@ -9,6 +9,7 @@ use crate::prolog::machine::Ball;
 use crate::prolog::machine::heap::*;
 use crate::prolog::machine::partial_string::*;
 use crate::prolog::machine::raw_block::RawBlockTraits;
+use crate::prolog::machine::streams::Stream;
 use crate::prolog::instructions::*;
 use crate::prolog::rug::Integer;
 
@@ -49,6 +50,7 @@ pub enum Addr {
     Str(usize),
     PStrLocation(usize, usize), // location of pstr in heap, offset into string in bytes.
     PStrTail(usize, usize), // location of pstr in heap, offset into string in bytes.
+    Stream(Stream),
 }
 
 #[derive(Clone, Copy, Hash, Eq, PartialEq)]
index b2f009726a8df89b8ad744a4fe61e9e45b8debcd..f3cc271aef3b58e6496f8dec1bd3a1009d0c8fe8 100644 (file)
@@ -9,7 +9,7 @@ use crate::prolog::machine::machine_errors::*;
 use crate::prolog::machine::machine_indices::*;
 use crate::prolog::machine::modules::*;
 use crate::prolog::machine::stack::*;
-use crate::prolog::read::PrologStream;
+use crate::prolog::machine::streams::*;
 use crate::prolog::rug::Integer;
 
 use downcast::Any;
@@ -721,7 +721,7 @@ pub(crate) trait CallPolicy: Any {
         machine_st: &mut MachineState,
         ct: &BuiltInClauseType,
         indices: &mut IndexStore,
-        parsing_stream: &mut PrologStream,
+        current_input_stream: &mut Stream,
     ) -> CallResult {
         match ct {
             &BuiltInClauseType::AcyclicTerm => {
@@ -768,7 +768,11 @@ pub(crate) trait CallPolicy: Any {
                 return_from_clause!(machine_st.last_call, machine_st)
             }
             &BuiltInClauseType::Read => {
-                match machine_st.read(parsing_stream, indices.atom_tbl.clone(), &indices.op_dir) {
+                match machine_st.read(
+                    &mut parsing_stream(current_input_stream.clone()),
+                    indices.atom_tbl.clone(),
+                    &indices.op_dir,
+                ) {
                     Ok(offset) => {
                         let addr = machine_st[temp_v!(1)].clone();
                         machine_st.unify(addr, Addr::HeapCell(offset.heap_loc));
@@ -891,13 +895,13 @@ pub(crate) trait CallPolicy: Any {
         machine_st: &mut MachineState,
         arity: usize,
         indices: &mut IndexStore,
-        parsing_stream: &mut PrologStream,
+        current_input_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, parsing_stream)?;
+                    self.call_builtin(machine_st, &built_in, indices, current_input_stream)?;
                 }
                 ClauseType::CallN => {
                     machine_st.handle_internal_call_n(arity);
@@ -977,10 +981,10 @@ impl CallPolicy for CWILCallPolicy {
         machine_st: &mut MachineState,
         ct: &BuiltInClauseType,
         indices: &mut IndexStore,
-        parsing_stream: &mut PrologStream,
+        current_input_stream: &mut Stream,
     ) -> CallResult {
         self.prev_policy
-            .call_builtin(machine_st, ct, indices, parsing_stream)?;
+            .call_builtin(machine_st, ct, indices, current_input_stream)?;
         self.increment(machine_st)
     }
 
@@ -989,10 +993,10 @@ impl CallPolicy for CWILCallPolicy {
         machine_st: &mut MachineState,
         arity: usize,
         indices: &mut IndexStore,
-        parsing_stream: &mut PrologStream,
+        current_input_stream: &mut Stream,
     ) -> CallResult {
         self.prev_policy
-            .call_n(machine_st, arity, indices, parsing_stream)?;
+            .call_n(machine_st, arity, indices, current_input_stream)?;
         self.increment(machine_st)
     }
 }
index fec480458e39ec21ba67e1083907c5419d6b8229..3e35f0cc569f5c546840c5f0a4296a60f2bd5811 100644 (file)
@@ -15,8 +15,8 @@ use crate::prolog::machine::machine_errors::*;
 use crate::prolog::machine::machine_indices::*;
 use crate::prolog::machine::machine_state::*;
 use crate::prolog::machine::stack::*;
+use crate::prolog::machine::streams::*;
 use crate::prolog::ordered_float::*;
-use crate::prolog::read::PrologStream;
 use crate::prolog::rug::{Integer, Rational};
 
 use indexmap::{IndexMap, IndexSet};
@@ -1768,7 +1768,8 @@ impl MachineState {
 
                 let offset = match addr {
                     Addr::HeapCell(_) | Addr::StackCell(..)
-                  | Addr::AttrVar(..) | Addr::PStrTail(..) => {
+                  | Addr::AttrVar(..) | Addr::PStrTail(..) 
+                  | Addr::Stream(_) => {
                         v
                     }
                     Addr::Con(Constant::String(n, ref s)) => {
@@ -1790,7 +1791,7 @@ impl MachineState {
                     }
                     Addr::Str(_) => {
                         s
-                    }
+                    }                    
                     Addr::DBRef(_) => {
                         self.fail = true;
                         return;
@@ -2788,7 +2789,7 @@ impl MachineState {
         let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
 
         match a1.clone() {
-            Addr::DBRef(_) => self.fail = true,
+            Addr::Stream(_) | Addr::DBRef(_) => self.fail = true,
             Addr::Con(Constant::String(n, ref s))
                 if !self.flags.double_quotes.is_atom() && !s[n ..].is_empty() =>
             {
@@ -3217,7 +3218,7 @@ impl MachineState {
         code_repo: &CodeRepo,
         call_policy: &mut Box<dyn CallPolicy>,
         cut_policy: &mut Box<dyn CutPolicy>,
-        parsing_stream: &mut PrologStream,
+        current_input_stream: &mut Stream,
         ct: &ClauseType,
         arity: usize,
         lco: bool,
@@ -3244,11 +3245,11 @@ impl MachineState {
         match ct {
             &ClauseType::BuiltIn(ref ct) => try_or_fail!(
                 self,
-                call_policy.call_builtin(self, ct, indices, parsing_stream)
+                call_policy.call_builtin(self, ct, indices, current_input_stream)
             ),
             &ClauseType::CallN => try_or_fail!(
                 self,
-                call_policy.call_n(self, arity, indices, parsing_stream)
+                call_policy.call_n(self, arity, indices, current_input_stream)
             ),
             &ClauseType::Hook(ref hook) => try_or_fail!(self, call_policy.compile_hook(self, hook)),
             &ClauseType::Inlined(ref ct) => {
@@ -3272,7 +3273,7 @@ impl MachineState {
                     indices,
                     call_policy,
                     cut_policy,
-                    parsing_stream
+                    current_input_stream,
                 )
             ),
         };
@@ -3286,18 +3287,20 @@ impl MachineState {
         code_repo: &CodeRepo,
         call_policy: &mut Box<dyn CallPolicy>,
         cut_policy: &mut Box<dyn CutPolicy>,
-        parsing_stream: &mut PrologStream,
+        current_input_stream: &mut Stream,
         instr: &ControlInstruction,
     ) {
         match instr {
-            &ControlInstruction::Allocate(num_cells) => self.allocate(num_cells),
+            &ControlInstruction::Allocate(num_cells) => {
+                self.allocate(num_cells);
+            }
             &ControlInstruction::CallClause(ref ct, arity, _, lco, use_default_cp) => self
                 .handle_call_clause(
                     indices,
                     code_repo,
                     call_policy,
                     cut_policy,
-                    parsing_stream,
+                    current_input_stream,
                     ct,
                     arity,
                     lco,
@@ -3313,7 +3316,9 @@ impl MachineState {
                 self.b0 = self.b;
                 self.p += offset;
             }
-            &ControlInstruction::Proceed => self.p = CodePtr::Local(self.cp.clone())
+            &ControlInstruction::Proceed => {
+                self.p = CodePtr::Local(self.cp.clone());
+            }
         };
     }
 
index aff02e435e96f2ca56855db9eac2ade39a23ec71..67afac2e1776e75e36f7e67027692d3fdb580626 100644 (file)
@@ -22,6 +22,7 @@ pub mod modules;
 mod partial_string;
 mod raw_block;
 mod stack;
+pub(super) mod streams;
 pub(super) mod term_expansion;
 pub mod toplevel;
 
@@ -36,14 +37,13 @@ use crate::prolog::machine::machine_errors::*;
 use crate::prolog::machine::machine_indices::*;
 use crate::prolog::machine::machine_state::*;
 use crate::prolog::machine::modules::*;
+use crate::prolog::machine::streams::*;
 use crate::prolog::machine::toplevel::*;
-use crate::prolog::read::PrologStream;
 
 use indexmap::IndexMap;
 
 use std::collections::VecDeque;
 use std::fs::File;
-use std::io::Read;
 use std::mem;
 use std::ops::Index;
 use std::path::PathBuf;
@@ -76,7 +76,7 @@ pub struct Machine {
     pub(super) indices: IndexStore,
     pub(super) code_repo: CodeRepo,
     pub(super) toplevel_idx: usize,
-    pub(super) prolog_stream: ParsingStream<Box<dyn Read>>,
+    pub(super) current_input_stream: Stream,
 }
 
 impl Index<LocalCodePtr> for CodeRepo {
@@ -216,7 +216,11 @@ impl Machine {
             current_dir.clone(),
         );
 
-        match compile_special_form(self, parsing_stream(VERIFY_ATTRS.as_bytes()), verify_attrs_src)
+        match compile_special_form(
+            self,
+            Stream::from(VERIFY_ATTRS),
+            verify_attrs_src,
+        )
         {
             Ok(p) => {
                 self.machine_st.attr_var_init.verify_attrs_loc = p;
@@ -230,7 +234,11 @@ impl Machine {
             current_dir,
         );
 
-        match compile_special_form(self, parsing_stream(PROJECT_ATTRS.as_bytes()), project_attrs_src)
+        match compile_special_form(
+            self,
+            Stream::from(PROJECT_ATTRS),
+            project_attrs_src,
+        )
         {
             Ok(p) => {
                 self.machine_st.attr_var_init.project_attrs_loc = p;
@@ -254,7 +262,7 @@ impl Machine {
 
         compile_user_module(
             self,
-            parsing_stream(TOPLEVEL.as_bytes()),
+            Stream::from(TOPLEVEL),
             true,
             top_lvl_src,
         );
@@ -282,7 +290,7 @@ impl Machine {
 
         if path.is_file() {
             let file_src = match File::open(&path) {
-                Ok(file_handle) => parsing_stream(file_handle),
+                Ok(file_handle) => Stream::from(file_handle),
                 Err(_) => return,
             };
 
@@ -297,7 +305,7 @@ impl Machine {
 
     #[cfg(test)]
     pub fn reset(&mut self) {
-        self.prolog_stream = readline::input_stream();
+        self.current_input_stream = readline::input_stream();
         self.policies.cut_policy = Box::new(DefaultCutPolicy {});
         self.machine_st.reset();
     }
@@ -336,7 +344,7 @@ impl Machine {
         self.run_query();
     }
 
-    pub fn new(prolog_stream: PrologStream) -> Self
+    pub fn new(current_input_stream: Stream) -> Self
     {
         let mut wam = Machine {
             machine_st: MachineState::new(),
@@ -345,7 +353,7 @@ impl Machine {
             indices: IndexStore::new(),
             code_repo: CodeRepo::new(),
             toplevel_idx: 0,
-            prolog_stream,
+            current_input_stream,
         };
 
         let atom_tbl = wam.indices.atom_tbl.clone();
@@ -358,7 +366,7 @@ impl Machine {
 
         compile_listing(
             &mut wam,
-            parsing_stream(BUILTINS.as_bytes()),
+            Stream::from(BUILTINS),
             default_index_store!(atom_tbl.clone()),
             true,
             ListingSource::from_file_and_path(
@@ -369,25 +377,36 @@ impl Machine {
 
         wam.compile_special_forms();
 
-        compile_user_module(&mut wam, parsing_stream(ERROR.as_bytes()), true,
+        compile_user_module(&mut wam,
+                            Stream::from(ERROR),
+                            true,
                             ListingSource::from_file_and_path(
                                 clause_name!("error"),
                                 lib_path.clone(),
                             )
         );
-        compile_user_module(&mut wam, parsing_stream(LISTS.as_bytes()), true,
+        
+        compile_user_module(&mut wam,
+                            Stream::from(LISTS),
+                            true,
                             ListingSource::from_file_and_path(
                                 clause_name!("lists"),
                                 lib_path.clone(),
                             ),
         );
-        compile_user_module(&mut wam, parsing_stream(ISO_EXT.as_bytes()), true,
+        
+        compile_user_module(&mut wam,
+                            Stream::from(ISO_EXT),
+                            true,
                             ListingSource::from_file_and_path(
                                 clause_name!("iso_ext"),
                                 lib_path.clone(),
                             )
         );
-        compile_user_module(&mut wam, parsing_stream(SI.as_bytes()), true,
+        
+        compile_user_module(&mut wam,
+                            Stream::from(SI),
+                            true,
                             ListingSource::from_file_and_path(
                                 clause_name!("si"),
                                 lib_path.clone(),
@@ -755,12 +774,15 @@ impl Machine {
                 &mut self.indices,
                 &mut self.policies,
                 &mut self.code_repo,
-                &mut self.prolog_stream,
+                &mut self.current_input_stream,
             );
 
             match self.machine_st.p {
-                CodePtr::Local(LocalCodePtr::TopLevel(_, p)) if p > 0 => {}
-                CodePtr::REPL(code_ptr, p) => self.handle_toplevel_command(code_ptr, p),
+                CodePtr::Local(LocalCodePtr::TopLevel(_, p)) if p > 0 => {
+                }
+                CodePtr::REPL(code_ptr, p) => {
+                    self.handle_toplevel_command(code_ptr, p)
+                }
                 CodePtr::DynamicTransaction(trans_type, p) => {
                     // self.code_repo.cached_query is about to be overwritten by the term expander,
                     // so hold onto it locally and restore it after the compiler has finished.
@@ -788,7 +810,7 @@ impl MachineState {
         indices: &mut IndexStore,
         policies: &mut MachinePolicies,
         code_repo: &CodeRepo,
-        prolog_stream: &mut PrologStream,
+        current_input_stream: &mut Stream,
     ) {
         match instr {
             &Line::Arithmetic(ref arith_instr) => self.execute_arith_instr(arith_instr),
@@ -803,7 +825,7 @@ impl MachineState {
                 code_repo,
                 &mut policies.call_policy,
                 &mut policies.cut_policy,
-                prolog_stream,
+                current_input_stream,
                 control_instr,
             ),
             &Line::Fact(ref fact_instr) => {
@@ -826,14 +848,20 @@ impl MachineState {
         indices: &mut IndexStore,
         policies: &mut MachinePolicies,
         code_repo: &CodeRepo,
-        prolog_stream: &mut PrologStream,
+        current_input_stream: &mut Stream,
     ) {
         let instr = match code_repo.lookup_instr(self.last_call, &self.p) {
             Some(instr) => instr,
             None => return,
         };
 
-        self.dispatch_instr(instr.as_ref(), indices, policies, code_repo, prolog_stream);
+        self.dispatch_instr(
+            instr.as_ref(),
+            indices,
+            policies,
+            code_repo,
+            current_input_stream,
+        );
     }
 
     fn backtrack(&mut self) {
@@ -884,7 +912,7 @@ impl MachineState {
         indices: &mut IndexStore,
         policies: &mut MachinePolicies,
         code_repo: &mut CodeRepo,
-        prolog_stream: &mut PrologStream,
+        current_input_stream: &mut Stream,
     ) -> bool {
         loop {
             let instr = match code_repo.lookup_instr(self.last_call, &self.p) {
@@ -900,7 +928,13 @@ impl MachineState {
                 None => return false,
             };
 
-            self.dispatch_instr(instr.as_ref(), indices, policies, code_repo, prolog_stream);
+            self.dispatch_instr(
+                instr.as_ref(),
+                indices,
+                policies,
+                code_repo,
+                current_input_stream
+            );
 
             if self.fail {
                 self.backtrack();
@@ -924,10 +958,10 @@ impl MachineState {
         indices: &mut IndexStore,
         policies: &mut MachinePolicies,
         code_repo: &mut CodeRepo,
-        prolog_stream: &mut PrologStream,
+        current_input_stream: &mut Stream,
     ) {
         loop {
-            self.execute_instr(indices, policies, code_repo, prolog_stream);
+            self.execute_instr(indices, policies, code_repo, current_input_stream);
 
             if self.fail {
                 self.backtrack();
@@ -943,7 +977,7 @@ 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, prolog_stream) {
+                    } else if !self.verify_attr_stepper(indices, policies, code_repo, current_input_stream) {
                         if self.fail {
                             break;
                         }
diff --git a/src/prolog/machine/streams.rs b/src/prolog/machine/streams.rs
new file mode 100644 (file)
index 0000000..57d4835
--- /dev/null
@@ -0,0 +1,245 @@
+use crate::prolog_parser::ast::*;
+
+use crate::prolog::read::readline::*;
+
+use std::cell::RefCell;
+use std::error::Error;
+use std::fmt;
+use std::fs::File;
+use std::io::{Cursor, ErrorKind, Read, Write};
+use std::hash::{Hash, Hasher};
+use std::net::TcpStream;
+use std::rc::Rc;
+
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+pub enum StreamType {
+    Binary,
+    Text,
+}
+
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+pub enum EOFAction {
+    EOFCode,
+    Error,
+    Reset,
+}
+
+/* all these streams are closed automatically when the instance is
+ * dropped. */
+pub enum StreamInstance {
+    Bytes(Cursor<Vec<u8>>),
+    DynReadSource(Box<dyn Read>),
+    File(File),    
+    ReadlineStream(ReadlineStream),
+    TcpStream(TcpStream),
+}
+
+#[derive(Clone)]
+struct WrappedStreamInstance(Rc<RefCell<StreamInstance>>);
+
+impl WrappedStreamInstance {
+    #[inline]
+    fn new(stream_inst: StreamInstance) -> Self {
+        WrappedStreamInstance(Rc::new(RefCell::new(stream_inst)))
+    }
+}
+
+impl PartialEq for WrappedStreamInstance {
+    #[inline]
+    fn eq(&self, other: &Self) -> bool {
+        Rc::ptr_eq(&self.0, &other.0)
+    }
+}
+
+impl Eq for WrappedStreamInstance {}
+
+impl Hash for WrappedStreamInstance {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        let rc = &self.0;
+        let ptr = Rc::into_raw(rc.clone());
+
+        state.write_usize(ptr as usize);
+
+        unsafe {
+            // necessary to avoid memory leak.
+            let _ = Rc::from_raw(ptr);
+        };
+    }
+}
+
+#[derive(Debug)]
+enum StreamError {
+    ReadFromOutputStream,
+    WriteToInputStream,
+    FlushToInputStream,
+}
+
+impl fmt::Display for StreamError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            StreamError::ReadFromOutputStream => {
+                write!(f, "attempted to read from a write-only stream")
+            }
+            StreamError::WriteToInputStream => {
+                write!(f, "attempted to write to a read-only stream")
+            }
+            StreamError::FlushToInputStream => {
+                write!(f, "attempted to flush a read-only stream")
+            }
+        }
+    }
+}
+
+impl Error for StreamError {}
+
+#[derive(Clone, PartialEq, Eq, Hash)]
+pub struct StreamOptions {
+    pub stream_type: StreamType,
+    pub reposition: bool,
+    pub alias: Option<ClauseName>,
+    pub eof_action: EOFAction,
+}
+
+impl Default for StreamOptions {
+    #[inline]
+    fn default() -> Self {
+        StreamOptions {
+            stream_type: StreamType::Text,
+            reposition: false,
+            alias: None,
+            eof_action: EOFAction::EOFCode,
+        }
+    }
+}
+
+#[derive(Clone, PartialEq, Eq, Hash)]
+pub struct Stream {
+    pub options: StreamOptions,
+    stream_inst: WrappedStreamInstance,
+}
+
+impl From<String> for Stream {
+    fn from(string: String) -> Self {
+        Stream {
+            options: StreamOptions::default(),
+            stream_inst: WrappedStreamInstance::new(
+                StreamInstance::Bytes(Cursor::new(string.into_bytes()))
+            )
+        }
+    }
+}
+
+impl From<ReadlineStream> for Stream {
+    fn from(rl_stream: ReadlineStream) -> Self {
+        Stream {
+            options: StreamOptions::default(),
+            stream_inst: WrappedStreamInstance::new(
+                StreamInstance::ReadlineStream(rl_stream)
+            ),
+        }
+    }
+}
+
+impl From<&'static str> for Stream {
+    fn from(src: &'static str) -> Stream {
+        Stream {
+            options: StreamOptions::default(),
+            stream_inst: WrappedStreamInstance::new(
+                StreamInstance::DynReadSource(Box::new(src.as_bytes()))
+            ),
+        }
+    }
+}
+
+impl From<File> for Stream {
+    fn from(file: File) -> Stream {
+        Stream {
+            options: StreamOptions::default(),
+            stream_inst: WrappedStreamInstance::new(
+                StreamInstance::File(file)
+            ),
+        }
+    }
+}
+
+impl Stream {
+    #[inline]
+    pub(crate)
+    fn as_ptr(&self) -> *const RefCell<StreamInstance> {
+        let rc = self.stream_inst.0.clone();
+        let ptr = Rc::into_raw(rc);
+
+        unsafe {
+            // must be done to avoid memory leak.
+            let _ = Rc::from_raw(ptr);
+        }
+
+        ptr
+    }
+}
+
+impl Read for Stream {
+    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
+        match *self.stream_inst.0.borrow_mut() {
+            StreamInstance::File(ref mut file) => {
+                file.read(buf)
+            }
+            StreamInstance::TcpStream(ref mut tcp_stream) => {
+                tcp_stream.read(buf)
+            }
+            StreamInstance::ReadlineStream(ref mut rl_stream) => {
+                rl_stream.read(buf)
+            }
+            StreamInstance::DynReadSource(ref mut src) => {
+                src.read(buf)
+            }
+            StreamInstance::Bytes(ref mut cursor) => {
+                cursor.read(buf)
+            }
+        }
+    }
+}
+
+impl Write for Stream {
+    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
+        match *self.stream_inst.0.borrow_mut() {
+            StreamInstance::File(ref mut file) => {
+                file.write(buf)
+            }
+            StreamInstance::TcpStream(ref mut tcp_stream) => {
+                tcp_stream.write(buf)
+            }
+            StreamInstance::Bytes(ref mut cursor) => {
+                cursor.write(buf)
+            }
+            _ => {
+                Err(std::io::Error::new(
+                    ErrorKind::PermissionDenied,
+                    StreamError::WriteToInputStream,
+                ))
+            }
+        }
+    }
+
+    fn flush(&mut self) -> std::io::Result<()> {
+        match *self.stream_inst.0.borrow_mut() {
+            StreamInstance::File(ref mut file) => {
+                file.flush()
+            }
+            StreamInstance::TcpStream(ref mut tcp_stream) => {
+                tcp_stream.flush()
+            }
+            StreamInstance::Bytes(ref mut cursor) => {
+                cursor.flush()
+            }
+            _ => {
+                Err(std::io::Error::new(
+                    ErrorKind::PermissionDenied,
+                    StreamError::FlushToInputStream,
+                ))
+            }
+        }
+    }
+}
+
+//TODO: write a Seek instance.
index a2496fbb00393fd9dd6b3d6bd4c549d25b9ffc65..6aa0432d5dd4e523fd94b8225d2195a3a9b1463e 100644 (file)
@@ -12,9 +12,10 @@ use crate::prolog::machine::code_walker::*;
 use crate::prolog::machine::machine_errors::*;
 use crate::prolog::machine::machine_indices::*;
 use crate::prolog::machine::machine_state::*;
+use crate::prolog::machine::streams::*;
 use crate::prolog::machine::toplevel::to_op_decl;
 use crate::prolog::ordered_float::OrderedFloat;
-use crate::prolog::read::{readline, PrologStream};
+use crate::prolog::read::readline;
 use crate::prolog::rug::Integer;
 
 use crate::ref_thread_local::RefThreadLocal;
@@ -354,12 +355,12 @@ impl MachineState {
     }
 
     fn read_term(&mut self,
-                 current_input_stream: &mut PrologStream,
+                 current_input_stream: &mut Stream,
                  indices: &mut IndexStore)
                  -> CallResult
     {
         match self.read(
-            current_input_stream,
+            &mut parsing_stream(current_input_stream.clone()),
             indices.atom_tbl.clone(),
             &indices.op_dir,
         ) {
@@ -671,7 +672,7 @@ impl MachineState {
         indices: &mut IndexStore,
         call_policy: &mut Box<dyn CallPolicy>,
         cut_policy: &mut Box<dyn CutPolicy>,
-        current_input_stream: &mut PrologStream,
+        current_input_stream: &mut Stream,
     ) -> CallResult {
         match ct {
             &SystemClauseType::AbolishClause => {
@@ -721,6 +722,32 @@ impl MachineState {
                 self.p = CodePtr::DynamicTransaction(trans_type, p);
                 return Ok(());
             }
+            &SystemClauseType::CurrentInput => {
+                let addr = self.store(self.deref(self[temp_v!(1)].clone()));
+                let stream = current_input_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;
@@ -1177,7 +1204,9 @@ impl MachineState {
                 };
             }
             &SystemClauseType::GetChar => {
-                let result = current_input_stream.next();
+                let mut iter = parsing_stream(current_input_stream.clone());
+                let result = iter.next();
+                
                 let a1 = self[temp_v!(1)].clone();
 
                 match result {
@@ -2315,7 +2344,7 @@ impl MachineState {
                         // get the call site so that the number of active permanent variables can be read
                         // from it later.
                         let cp = (self.stack.index_and_frame(e).prelude.cp - 1).unwrap();
-
+                        
                         let p = cp.as_functor(&mut self.heap);
                         let e = self.stack.index_and_frame(e).prelude.e;
 
index da5dcd909d1bd7d07818395a78a78adf2eebfa03..8a7f7e94b64b1b8b7112a79e47d4e1f838035147 100644 (file)
@@ -8,7 +8,6 @@ use crate::prolog::rug::Integer;
 
 use std::cell::Cell;
 use std::collections::VecDeque;
-use std::io::Read;
 use std::iter::Rev;
 use std::vec::IntoIter;
 
@@ -28,7 +27,11 @@ where
     term
 }
 
-fn extract_from_list(head: Box<Term>, tail: Box<Term>) -> Result<Rev<IntoIter<Term>>, ParserError> {
+fn extract_from_list(
+    head: Box<Term>,
+    tail: Box<Term>,
+) -> Result<Rev<IntoIter<Term>>, ParserError>
+{
     let mut terms = vec![*head];
     let mut tail = *tail;
 
@@ -44,10 +47,10 @@ fn extract_from_list(head: Box<Term>, tail: Box<Term>) -> Result<Rev<IntoIter<Te
     }
 }
 
-pub struct TermStream<'a, R: Read> {
+pub struct TermStream<'a> {
     stack: Vec<Term>,
     pub(crate) wam: &'a mut Machine,
-    parser: Parser<'a, R>,
+    parser: Parser<'a, Stream>,
     pub(crate) flags: MachineFlags,
     term_expansion_lens: (usize, usize),
     goal_expansion_lens: (usize, usize),
@@ -75,7 +78,7 @@ impl ExpansionAdditionResult {
     }
 }
 
-impl<'a, R: Read> Drop for TermStream<'a, R> {
+impl<'a> Drop for TermStream<'a> {
     fn drop(&mut self) {
         self.wam.indices.in_situ_code_dir.clear();
         self.wam.indices.in_situ_module_dir.clear();
@@ -85,9 +88,9 @@ impl<'a, R: Read> Drop for TermStream<'a, R> {
     }
 }
 
-impl<'a, R: Read> TermStream<'a, R> {
+impl<'a> TermStream<'a> {
     pub fn new(
-        src: &'a mut ParsingStream<R>,
+        src: &'a mut ParsingStream<Stream>,
         atom_tbl: TabledData<Atom>,
         flags: MachineFlags,
         wam: &'a mut Machine,
index 9b685b762947bcf6ec72f8429b1aa7cf5ee5dece..bcfe128c67a1c4569a779bacb879450232d3fd48 100644 (file)
@@ -13,7 +13,6 @@ use indexmap::{IndexMap, IndexSet};
 use std::borrow::BorrowMut;
 use std::cell::Cell;
 use std::collections::VecDeque;
-use std::io::Read;
 use std::mem;
 use std::ops::DerefMut;
 use std::rc::Rc;
@@ -30,15 +29,15 @@ fn op_dir<'a, 'b: 'a>(from: &'b IndexSource<'a, IndexStore>) -> RefOrOwned<'a, O
     }
 }
 
-struct CompositeIndices<'a, 'b, 'c, R: Read> {
-    term_stream: &'b mut TermStream<'a, R>,
+struct CompositeIndices<'a, 'b, 'c> {
+    term_stream: &'b mut TermStream<'a>,
     index_src: IndexSource<'c, IndexStore>,
     static_code_dir: Option<IndexSource<'c, CodeDir>>
 }
 
-impl<'a, 'b, 'c, R: Read> CompositeIndices<'a, 'b, 'c, R> {
+impl<'a, 'b, 'c> CompositeIndices<'a, 'b, 'c> {
     fn new(
-        term_stream: &'b mut TermStream<'a, R>,
+        term_stream: &'b mut TermStream<'a>,
         index_src: IndexSource<'c, IndexStore>,
         static_code_dir: Option<IndexSource<'c, CodeDir>>,
     ) -> Self {
@@ -577,8 +576,8 @@ fn draw_from_term_dir_impl(
     }
 }
 
-fn draw_from_term_dir<R: Read>(
-    indices: &CompositeIndices<R>,
+fn draw_from_term_dir(
+    indices: &CompositeIndices,
     intra_module_term_dirs: &mut IndexMap<ClauseName, TermDirQuantum>,
     top_level_term_dirs: &mut TermDirQuantum,
     key: &PredicateKey,
@@ -615,8 +614,8 @@ fn draw_from_term_dir<R: Read>(
     );
 }
 
-fn setup_declaration<'a, 'b, 'c, R: Read>(
-    indices: &mut CompositeIndices<'a, 'b, 'c, R>,
+fn setup_declaration<'a, 'b, 'c>(
+    indices: &mut CompositeIndices<'a, 'b, 'c>,
     flags: MachineFlags,
     mut terms: Vec<Box<Term>>,
     line_num: usize,
@@ -796,9 +795,9 @@ impl RelationWorker {
         self.fabricate_rule(fold_by_str(prec_seq.into_iter(), body_term, comma_sym))
     }
 
-    fn to_query_term<'a, 'b, 'c, R: Read>(
+    fn to_query_term<'a, 'b, 'c>(
         &mut self,
-        indices: &mut CompositeIndices<'a, 'b, 'c, R>,
+        indices: &mut CompositeIndices<'a, 'b, 'c>,
         term: Term,
     ) -> Result<QueryTerm, ParserError> {
         match term {
@@ -872,9 +871,9 @@ impl RelationWorker {
         }
     }
 
-    fn pre_query_term<'a, 'b, 'c, R: Read>(
+    fn pre_query_term<'a, 'b, 'c>(
         &mut self,
-        indices: &mut CompositeIndices<'a, 'b, 'c, R>,
+        indices: &mut CompositeIndices<'a, 'b, 'c>,
         term: Term,
     ) -> Result<QueryTerm, ParserError> {
         match term {
@@ -893,9 +892,9 @@ impl RelationWorker {
         }
     }
 
-    fn setup_query<'a, 'b, 'c, R: Read>(
+    fn setup_query<'a, 'b, 'c>(
         &mut self,
-        indices: &mut CompositeIndices<'a, 'b, 'c, R>,
+        indices: &mut CompositeIndices<'a, 'b, 'c>,
         terms: Vec<Box<Term>>,
         blocks_cuts: bool,
     ) -> Result<Vec<QueryTerm>, ParserError> {
@@ -946,10 +945,10 @@ impl RelationWorker {
         Ok(query_terms)
     }
 
-    fn setup_hook<'a, 'b, 'c, R: Read>(
+    fn setup_hook<'a, 'b, 'c>(
         &mut self,
         hook: CompileTimeHook,
-        indices: &mut CompositeIndices<'a, 'b, 'c, R>,
+        indices: &mut CompositeIndices<'a, 'b, 'c>,
         term: Term,
     ) -> Result<CompileTimeHookCompileInfo, ParserError> {
         match flatten_hook(term) {
@@ -970,9 +969,9 @@ impl RelationWorker {
         }
     }
 
-    fn setup_rule<'a, 'b, 'c, R: Read>(
+    fn setup_rule<'a, 'b, 'c>(
         &mut self,
-        indices: &mut CompositeIndices<'a, 'b, 'c, R>,
+        indices: &mut CompositeIndices<'a, 'b, 'c>,
         mut terms: Vec<Box<Term>>,
         blocks_cuts: bool,
         assume_dyn: bool,
@@ -1003,9 +1002,9 @@ impl RelationWorker {
         }
     }
 
-    fn try_term_to_query<'a, 'b, 'c, R: Read>(
+    fn try_term_to_query<'a, 'b, 'c>(
         &mut self,
-        indices: &mut CompositeIndices<'a, 'b, 'c, R>,
+        indices: &mut CompositeIndices<'a, 'b, 'c>,
         terms: Vec<Box<Term>>,
         blocks_cuts: bool,
     ) -> Result<TopLevel, ParserError> {
@@ -1016,10 +1015,10 @@ impl RelationWorker {
         )?))
     }
 
-    fn compact_module_scoped_head<'a, 'b, 'c, R: Read>(
+    fn compact_module_scoped_head<'a, 'b, 'c>(
         &self,
         term: &mut Term,
-        indices: &mut CompositeIndices<'a, 'b, 'c, R>,
+        indices: &mut CompositeIndices<'a, 'b, 'c>,
     ) {
         let inner_term = match term {
             Term::Clause(_, ref name, ref mut inner_terms, _)
@@ -1044,9 +1043,9 @@ impl RelationWorker {
         *term = inner_term;
     }
 
-    fn try_term_to_tl<'a, 'b, 'c, R: Read>(
+    fn try_term_to_tl<'a, 'b, 'c>(
         &mut self,
-        indices: &mut CompositeIndices<'a, 'b, 'c, R>,
+        indices: &mut CompositeIndices<'a, 'b, 'c>,
         term: Term,
         blocks_cuts: bool,
     ) -> Result<TopLevel, ParserError> {
@@ -1085,14 +1084,14 @@ impl RelationWorker {
         }
     }
 
-    fn try_terms_to_tls<'a, 'b, 'c, I, R>(
+    fn try_terms_to_tls<'a, 'b, 'c, I>(
         &mut self,
-        indices: &mut CompositeIndices<'a, 'b, 'c, R>,
+        indices: &mut CompositeIndices<'a, 'b, 'c>,
         terms: I,
         blocks_cuts: bool,
     ) -> Result<VecDeque<TopLevel>, ParserError>
     where
-        I: IntoIterator<Item = Term>, R: Read
+        I: IntoIterator<Item = Term>
     {
         let mut results = VecDeque::new();
 
@@ -1103,9 +1102,9 @@ impl RelationWorker {
         Ok(results)
     }
 
-    fn parse_queue<'a, 'b, 'c, R: Read>(
+    fn parse_queue<'a, 'b, 'c>(
         &mut self,
-        indices: &mut CompositeIndices<'a, 'b, 'c, R>,
+        indices: &mut CompositeIndices<'a, 'b, 'c>,
     ) -> Result<VecDeque<TopLevel>, ParserError> {
         let mut queue = VecDeque::new();
 
@@ -1128,8 +1127,8 @@ pub type DynamicClause = Vec<(Term, Term)>;
 
 pub type DynamicClauseMap = IndexMap<(ClauseName, usize), DynamicClause>;
 
-pub struct TopLevelBatchWorker<'a, R: Read> {
-    pub(crate) term_stream: TermStream<'a, R>,
+pub struct TopLevelBatchWorker<'a> {
+    pub(crate) term_stream: TermStream<'a>,
     rel_worker: RelationWorker,
     pub(crate) results: Vec<(Predicate, VecDeque<TopLevel>)>,
     pub(crate) dynamic_clause_map: DynamicClauseMap,
@@ -1139,14 +1138,14 @@ pub struct TopLevelBatchWorker<'a, R: Read> {
     pub(crate) non_counted_bt_preds: IndexSet<PredicateKey>,
 }
 
-impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
+impl<'a> TopLevelBatchWorker<'a> {
     pub fn new(
-        inner: &'a mut ParsingStream<R>,
+        stream: &'a mut ParsingStream<Stream>,
         atom_tbl: TabledData<Atom>,
         flags: MachineFlags,
         wam: &'a mut Machine,
     ) -> Self {
-        let term_stream = TermStream::new(inner, atom_tbl, flags, wam);
+        let term_stream = TermStream::new(stream, atom_tbl, flags, wam);
 
         let line_num = term_stream.line_num();
         let col_num  = term_stream.col_num();
index d45a74141fd29d6567e900b0b645dc7b36d7b7fe..32d45224bbbece2e6e2763256943cef32955a7a0 100644 (file)
@@ -6,9 +6,9 @@ use crate::prolog::forms::*;
 use crate::prolog::iterators::*;
 use crate::prolog::machine::machine_indices::*;
 use crate::prolog::machine::machine_state::MachineState;
+use crate::prolog::machine::streams::Stream;
 
 use std::collections::VecDeque;
-use std::io::Read;
 
 type SubtermDeque = VecDeque<(usize, usize)>;
 
@@ -23,10 +23,10 @@ impl<'a> TermRef<'a> {
     }
 }
 
-pub type PrologStream = ParsingStream<Box<dyn Read>>;
+pub type PrologStream = ParsingStream<Stream>;
 
 pub mod readline {
-    use prolog_parser::ast::*;
+    use crate::prolog::machine::streams::Stream;
     use crate::prolog::rustyline::error::ReadlineError;
     use crate::prolog::rustyline::{Cmd, Editor, KeyPress};
     use std::io::{Cursor, Read};
@@ -52,10 +52,10 @@ pub mod readline {
     }
 
     impl ReadlineStream {
-        fn input_stream(pending_input: String) -> Self {
+        pub fn input_stream(pending_input: String) -> Stream {
             let mut rl = Editor::<()>::new();
             rl.bind_sequence(KeyPress::Tab, Cmd::Insert(1, "\t".to_string()));
-            ReadlineStream { rl, pending_input: Cursor::new(pending_input) }
+            Stream::from(ReadlineStream { rl, pending_input: Cursor::new(pending_input) })
         }
 
         fn call_readline(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
@@ -99,9 +99,9 @@ pub mod readline {
     }
 
     #[inline]
-    pub fn input_stream() -> crate::PrologStream {
-        let reader: Box<dyn Read> = Box::new(ReadlineStream::input_stream(String::from("")));
-        parsing_stream(reader)
+    pub fn input_stream() -> Stream {
+        let input_stream = ReadlineStream::input_stream(String::from(""));
+        Stream::from(input_stream)
     }
 }
 
index 96a52919646406bb79bdd353c73da15b437b9639..870a833077dcb49d6fd3164cd991c2ccb49160fa 100644 (file)
@@ -184,6 +184,7 @@ impl fmt::Display for Addr {
             &Addr::Str(s) => write!(f, "Addr::Str({})", s),
             &Addr::PStrLocation(h, n) => write!(f, "Addr::PStrLocation({}, {})", h, n),
             &Addr::PStrTail(h, n) => write!(f, "Addr::PStrTail({}, {})", h, n),
+            &Addr::Stream(ref stream) => write!(f, "Addr::Stream({})", stream.as_ptr() as usize),
         }
     }
 }