]> Repositorios git - scryer-prolog.git/commitdiff
remove need for taking code_dir
authorMark Thom <[email protected]>
Sat, 6 Oct 2018 22:25:10 +0000 (16:25 -0600)
committerMark Thom <[email protected]>
Sat, 6 Oct 2018 22:25:10 +0000 (16:25 -0600)
src/prolog/compile.rs
src/prolog/machine/mod.rs
src/prolog/machine/term_expansion.rs
src/prolog/read.rs
src/prolog/toplevel.rs

index aa09b1b7600c61a4bc8f1165cb91aebf011bf476..ecbb1b8ced2c2ed5a2d910d86815cd42401e5a5f 100644 (file)
@@ -97,16 +97,20 @@ fn compile_query(terms: Vec<QueryTerm>, queue: Vec<TopLevel>, flags: MachineFlag
     Ok((code, cg.take_vars()))
 }
 
-fn package_term(wam: &mut Machine, term: Term) -> Result<TopLevelPacket, ParserError> {
-    let mut code_dir = wam.take_code_dir();
-    let packet = consume_term(&mut code_dir, term, &mut wam.indices)?;
-    wam.swap_code_dir(&mut code_dir);
-    Ok(packet)
+fn compile_decl(wam: &mut Machine, compiler: &mut ListingCompiler, decl: Declaration)
+                -> Result<IndexStore, SessionError>
+{
+    let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
+    let wam_indices = &mut wam.indices;
+    
+    compiler.process_decl(decl, wam_indices, &mut indices)?;
+
+    Ok(indices)
 }
 
 pub fn compile_term(wam: &mut Machine, term: Term) -> EvalSession
 {
-    let packet = try_eval_session!(package_term(wam, term));
+    let packet = try_eval_session!(consume_term(term, &mut wam.indices));
 
     match packet {
         TopLevelPacket::Query(terms, queue) =>
@@ -116,9 +120,8 @@ pub fn compile_term(wam: &mut Machine, term: Term) -> EvalSession
             },
         TopLevelPacket::Decl(TopLevel::Declaration(decl), _) => {
             let mut compiler = ListingCompiler::new();
-            let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
 
-            try_eval_session!(compiler.process_decl(decl, wam, &mut indices));
+            let indices = try_eval_session!(compile_decl(wam, &mut compiler, decl));
             try_eval_session!(compiler.add_code(wam, vec![], indices));
 
             EvalSession::EntrySuccess
@@ -127,6 +130,12 @@ pub fn compile_term(wam: &mut Machine, term: Term) -> EvalSession
     }
 }
 
+struct GatherResult {
+    worker_results: Vec<(Predicate, VecDeque<TopLevel>)>,
+    toplevel_results: Vec<(Predicate, VecDeque<TopLevel>)>,
+    toplevel_indices: IndexStore
+}
+
 pub struct ListingCompiler {
     non_counted_bt_preds: HashSet<PredicateKey>,
     module: Option<Module>,
@@ -140,41 +149,38 @@ impl ListingCompiler {
         }
     }
 
-    fn use_module(&mut self, submodule: Module, wam: &mut Machine, indices: &mut IndexStore)
+    fn use_module(&mut self, submodule: &Module, indices: &mut IndexStore)
                   -> Result<(), SessionError>
     {
         let mod_name = self.get_module_name();
 
-        indices.use_module(&submodule)?;
+        indices.use_module(submodule)?;
 
         if let &mut Some(ref mut module) = &mut self.module {
-            module.remove_module(mod_name, &submodule);
-            module.use_module(&submodule)?;
-        } else {
-            wam.remove_module(&submodule);
+            module.remove_module(mod_name, submodule);
+            module.use_module(submodule)?;
         }
 
-        Ok(wam.insert_module(submodule))
+        Ok(())
     }
 
-    fn use_qualified_module(&mut self, submodule: Module, wam: &mut Machine,
-                            exports: &Vec<PredicateKey>, indices: &mut IndexStore)
+    fn use_qualified_module(&mut self, submodule: &Module, exports: &Vec<PredicateKey>,
+                            indices: &mut IndexStore)
                             -> Result<(), SessionError>
     {
         let mod_name = self.get_module_name();
 
-        indices.use_qualified_module(&submodule, exports)?;
+        indices.use_qualified_module(submodule, exports)?;
 
         if let &mut Some(ref mut module) = &mut self.module {
-            module.remove_module(mod_name, &submodule);
-            module.use_qualified_module(&submodule, exports)?;
-        } else {
-            wam.remove_module(&submodule);
+            module.remove_module(mod_name, submodule);
+            module.use_qualified_module(submodule, exports)?;
         }
 
-        Ok(wam.insert_module(submodule))
+        Ok(())
     }
 
+    #[inline]
     fn get_module_name(&self) -> ClauseName {
         self.module.as_ref()
             .map(|module| module.module_decl.name.clone())
@@ -233,25 +239,26 @@ impl ListingCompiler {
         self.non_counted_bt_preds.insert((name, arity));
     }
 
-    fn process_decl(&mut self, decl: Declaration, wam: &mut Machine, indices: &mut IndexStore)
+    fn process_decl(&mut self, decl: Declaration, wam_indices: &IndexStore, indices: &mut IndexStore)
                     -> Result<(), SessionError>
     {
         match decl {
             Declaration::Hook(CompileTimeHook::TermExpansion, clause) =>
-                Ok(wam.add_term_expansion_clause(clause)?),
+            //Ok(wam.add_term_expansion_clause(clause)?),
+                Ok(()),
             Declaration::NonCountedBacktracking(name, arity) =>
                 Ok(self.add_non_counted_bt_flag(name, arity)),
             Declaration::Op(op_decl) =>
                 op_decl.submit(self.get_module_name(), &mut indices.op_dir),
             Declaration::UseModule(name) =>
-                if let Some(submodule) = wam.take_module(name) {
-                    self.use_module(submodule, wam, indices)
+                if let Some(ref submodule) = wam_indices.modules.get(&name) {
+                    self.use_module(submodule, indices)
                 } else {
                     Err(SessionError::ModuleNotFound)
                 },
             Declaration::UseQualifiedModule(name, exports) =>
-                if let Some(submodule) = wam.take_module(name) {
-                    self.use_qualified_module(submodule, wam, &exports, indices)
+                if let Some(ref submodule) = wam_indices.modules.get(&name) {
+                    self.use_qualified_module(submodule, &exports, indices)
                 } else {
                     Err(SessionError::ModuleNotFound)
                 },
@@ -266,45 +273,60 @@ impl ListingCompiler {
                 }
         }
     }
-}
 
-pub
-fn compile_listing<R: Read>(wam: &mut Machine, src: R, mut indices: IndexStore) -> EvalSession
-{
-    let code_dir = wam.take_code_dir();
-    let mut worker = TopLevelBatchWorker::new(src, wam.indices.atom_tbl.clone(),
-                                              wam.machine_flags(),
-                                              code_dir);
+    fn gather_items<R: Read>(&mut self, wam: &mut Machine, src: R, indices: &mut IndexStore)
+                             -> Result<GatherResult, SessionError>
+    {
+        let flags = wam.machine_flags();
+        let machine_st  = &mut wam.machine_st;
+        let wam_indices = &mut wam.indices;
 
-    let mut compiler = ListingCompiler::new();
-    let mut toplevel_results = vec![];
-    let mut toplevel_indices = default_index_store!(wam.indices.atom_tbl.clone());
+        let atom_tbl   = wam_indices.atom_tbl.clone();
+
+        let mut worker = TopLevelBatchWorker::new(src, atom_tbl.clone(), flags,
+                                                  wam_indices, &mut wam.policies,
+                                                  &mut wam.code_repo);
 
-    while let Some(decl) = try_eval_session!(worker.consume(wam, &mut indices)) {
-        if decl.is_module_decl() {
-            toplevel_indices.copy_and_swap(&mut indices);
-            mem::swap(&mut worker.results, &mut toplevel_results);
-            worker.in_module = true;
+        let mut toplevel_results = vec![];
+        let mut toplevel_indices = default_index_store!(atom_tbl.clone());
 
-            try_eval_session!(compiler.process_decl(decl, wam, &mut indices));
+        while let Some(decl) = worker.consume(machine_st, indices)? {
+            if decl.is_module_decl() {
+                toplevel_indices.copy_and_swap(indices);
+                mem::swap(&mut worker.results, &mut toplevel_results);
+                worker.in_module = true;
 
-            if let &Some(ref module) = &compiler.module {
-                worker.term_stream.set_atom_tbl(module.atom_tbl.clone());
+                self.process_decl(decl, worker.term_stream.indices, indices)?;
+
+                if let &Some(ref module) = &self.module {
+                    worker.term_stream.set_atom_tbl(module.atom_tbl.clone());
+                }
+            } else {
+                self.process_decl(decl, worker.term_stream.indices, indices)?;
             }
-        } else {
-            try_eval_session!(compiler.process_decl(decl, wam, &mut indices));
         }
+
+        Ok(GatherResult {
+            worker_results: worker.results,
+            toplevel_results,
+            toplevel_indices
+        })
     }
+}
 
-    wam.swap_code_dir(&mut worker.static_code_dir);
+pub
+fn compile_listing<R: Read>(wam: &mut Machine, src: R, mut indices: IndexStore) -> EvalSession
+{
+    let mut compiler = ListingCompiler::new();
+    let mut results = try_eval_session!(compiler.gather_items(wam, src, &mut indices));
 
-    let module_code = try_eval_session!(compiler.generate_code(worker.results, wam,
+    let module_code = try_eval_session!(compiler.generate_code(results.worker_results, wam,
                                                                &mut indices.code_dir));
-    let toplvl_code = try_eval_session!(compiler.generate_code(toplevel_results, wam,
-                                                               &mut toplevel_indices.code_dir));
+    let toplvl_code = try_eval_session!(compiler.generate_code(results.toplevel_results, wam,
+                                                               &mut results.toplevel_indices.code_dir));
 
     try_eval_session!(compiler.add_code(wam, module_code, indices));
-    try_eval_session!(compiler.add_code(wam, toplvl_code, toplevel_indices));
+    try_eval_session!(compiler.add_code(wam, toplvl_code, results.toplevel_indices));
 
     EvalSession::EntrySuccess
 }
index 30dd08701b7a5d16719be4fc7961f035deb5a552..e192b4fc41a6b3cb2a4bfb35d540b99ef604cf2c 100644 (file)
@@ -107,6 +107,14 @@ impl CodeRepo {
             code: Code::new()
         }
     }
+
+    #[inline]
+    fn size_of_cached_query(&self) -> usize {
+        match &self.cached_query {
+            &Some(ref query) => query.len(),
+            _ => 0
+        }
+    }
     
     fn lookup_instr<'a>(&'a self, last_call: bool, p: &CodePtr) -> Option<RefOrOwned<'a, Line>>
     {
@@ -138,32 +146,54 @@ impl CodeRepo {
     }
 }
 
-pub struct Machine {
-    ms: MachineState,
+pub struct MachinePolicies {
     call_policy: Box<CallPolicy>,
     cut_policy: Box<CutPolicy>,
+}
+
+impl MachinePolicies {
+    #[inline]
+    fn new() -> Self {
+        MachinePolicies {
+            call_policy: Box::new(DefaultCallPolicy {}),
+            cut_policy: Box::new(DefaultCutPolicy {}),
+        }
+    }
+}
+
+pub struct Machine {
+    pub(super) machine_st: MachineState,
+    pub(super) policies: MachinePolicies,
     pub(super) indices: IndexStore,
     term_dir: TermDir,
     pub(super) code_repo: CodeRepo  
 }
 
-impl Index<LocalCodePtr> for Machine {
+impl Index<LocalCodePtr> for CodeRepo {
     type Output = Line;
 
     fn index(&self, ptr: LocalCodePtr) -> &Self::Output {
         match ptr {
             LocalCodePtr::TopLevel(_, p) => {
-                match &self.code_repo.cached_query {
+                match &self.cached_query {
                     &Some(ref cq) => &cq[p],
                     &None => panic!("Out-of-bounds top level index.")
                 }
             },
-            LocalCodePtr::DirEntry(p) => &self.code_repo.code[p],
-            LocalCodePtr::UserTermExpansion(p) => &self.code_repo.term_expanders[p]
+            LocalCodePtr::DirEntry(p) => &self.code[p],
+            LocalCodePtr::UserTermExpansion(p) => &self.term_expanders[p]
         }
     }
 }
 
+impl Index<LocalCodePtr> for Machine {
+    type Output = Line;
+
+    fn index(&self, ptr: LocalCodePtr) -> &Self::Output {
+        &self.code_repo[ptr]
+    }
+}
+
 impl SubModuleUser for IndexStore {
     fn atom_tbl(&self) -> TabledData<Atom> {
         self.atom_tbl.clone()
@@ -211,9 +241,8 @@ static TERMS: &str   = include_str!("../lib/terms.pl");
 impl Machine {
     pub fn new() -> Self {
         let mut wam = Machine {
-            ms: MachineState::new(),
-            call_policy: Box::new(DefaultCallPolicy {}),
-            cut_policy: Box::new(DefaultCutPolicy {}),
+            machine_st: MachineState::new(),
+            policies: MachinePolicies::new(),
             indices: IndexStore::new(),
             term_dir: TermDir::new(),
             code_repo: CodeRepo::new()
@@ -235,12 +264,12 @@ impl Machine {
 
     #[inline]
     pub fn machine_flags(&self) -> MachineFlags {
-        self.ms.flags
+        self.machine_st.flags
     }
 
     #[inline]
     pub fn failed(&self) -> bool {
-        self.ms.fail
+        self.machine_st.fail
     }
 
     pub fn add_batched_code(&mut self, code: Code, code_dir: CodeDir) -> Result<(), SessionError>
@@ -305,16 +334,6 @@ impl Machine {
     pub fn take_module(&mut self, name: ClauseName) -> Option<Module> {
         self.indices.modules.remove(&name)
     }
-
-    #[inline]
-    pub fn take_code_dir(&mut self) -> CodeDir {
-        mem::replace(&mut self.indices.code_dir, CodeDir::new())
-    }
-    
-    #[inline]
-    pub fn swap_code_dir(&mut self, code_dir: &mut CodeDir) {
-        mem::swap(&mut self.indices.code_dir, code_dir);        
-    }
     
     #[inline]
     pub fn insert_module(&mut self, module: Module) {
@@ -347,104 +366,190 @@ impl Machine {
 
         preds.0.push(clause);
 
-        let mut cg = CodeGenerator::<DebrayAllocator>::new(false, self.ms.flags);
+        let mut cg = CodeGenerator::<DebrayAllocator>::new(false, self.machine_st.flags);
         let code = cg.compile_predicate(&preds.0)?;
 
         Ok(self.code_repo.term_expanders = code)
     }
 
-    fn execute_instr(&mut self)
+    fn fail(&mut self, heap_locs: &HeapVarDict) -> EvalSession
     {
-        let instr = match self.code_repo.lookup_instr(self.ms.last_call, &self.ms.p) {
+        if self.machine_st.ball.stub.len() > 0 {
+            let h = self.machine_st.heap.h;
+            self.machine_st.copy_and_align_ball_to_heap();
+
+            let error_str = self.machine_st.print_exception(Addr::HeapCell(h),
+                                                    &heap_locs,
+                                                    TermFormatter {},
+                                                    PrinterOutputter::new())
+                                .result();
+
+            EvalSession::from(SessionError::QueryFailureWithException(error_str))
+        } else {
+            EvalSession::from(SessionError::QueryFailure)
+        }
+    }
+
+    pub fn submit_query(&mut self, code: Code, alloc_locs: AllocVarDict) -> EvalSession
+    {
+        let mut heap_locs = HashMap::new();
+
+        self.code_repo.cached_query = Some(code);
+        self.machine_st.run_query(&mut self.indices, &mut self.policies, &self.code_repo, &alloc_locs, &mut heap_locs);
+
+        if self.machine_st.fail {
+            self.fail(&heap_locs)
+        } else {
+            EvalSession::InitialQuerySuccess(alloc_locs, heap_locs)
+        }
+    }
+
+    pub fn continue_query(&mut self, alloc_l: &AllocVarDict, heap_l: &mut HeapVarDict) -> EvalSession
+    {
+        if !self.or_stack_is_empty() {
+            let b = self.machine_st.b - 1;
+            self.machine_st.p = self.machine_st.or_stack[b].bp.clone();
+
+            if let CodePtr::Local(LocalCodePtr::TopLevel(_, 0)) = self.machine_st.p {
+                return EvalSession::from(SessionError::QueryFailure);
+            }
+
+            self.machine_st.run_query(&mut self.indices, &mut self.policies, &self.code_repo,
+                                      alloc_l, heap_l);
+            
+            if self.machine_st.fail {
+                self.fail(&heap_l)
+            } else {
+                EvalSession::SubsequentQuerySuccess
+            }
+        } else {
+            EvalSession::from(SessionError::QueryFailure)
+        }
+    }
+
+    pub fn heap_view<Outputter>(&self, var_dir: &HeapVarDict, mut output: Outputter) -> Outputter
+       where Outputter: HCValueOutputter
+    {
+        let mut sorted_vars: Vec<(&Rc<Var>, &Addr)> = var_dir.iter().collect();
+        sorted_vars.sort_by_key(|ref v| v.0);
+
+        for (var, addr) in sorted_vars {
+            let fmt = TermFormatter {};
+            output = self.machine_st.print_var_eq(var.clone(), addr.clone(), var_dir, fmt, output);
+        }
+
+        output
+    }
+
+    pub fn or_stack_is_empty(&self) -> bool {
+        self.machine_st.b == 0
+    }
+
+    pub fn clear(&mut self) {
+        let mut machine = Machine::new();
+        mem::swap(self, &mut machine);
+    }
+
+    pub fn reset(&mut self) {
+        self.policies.cut_policy = Box::new(DefaultCutPolicy {});
+        self.machine_st.reset();
+    }
+}
+
+
+impl MachineState {    
+    fn execute_instr(&mut self, indices: &mut IndexStore, policies: &mut MachinePolicies,
+                     code_repo: &CodeRepo)
+    {
+        let instr = match code_repo.lookup_instr(self.last_call, &self.p) {
             Some(instr) => instr,
             None => return
         };
 
         match instr.as_ref() {
             &Line::Arithmetic(ref arith_instr) =>
-                self.ms.execute_arith_instr(arith_instr),
+                self.execute_arith_instr(arith_instr),
             &Line::Choice(ref choice_instr) =>
-                self.ms.execute_choice_instr(choice_instr, &mut self.call_policy),
+                self.execute_choice_instr(choice_instr, &mut policies.call_policy),
             &Line::Cut(ref cut_instr) =>
-                self.ms.execute_cut_instr(cut_instr, &mut self.cut_policy),
+                self.execute_cut_instr(cut_instr, &mut policies.cut_policy),
             &Line::Control(ref control_instr) => 
-                self.ms.execute_ctrl_instr(&mut self.indices, &mut self.call_policy,
-                                           &mut self.cut_policy, control_instr),            
+                self.execute_ctrl_instr(indices, &mut policies.call_policy,
+                                        &mut policies.cut_policy, control_instr),            
             &Line::Fact(ref fact) => {
                 for fact_instr in fact {
-                    if self.failed() {
+                    if self.fail {
                         break;
                     }
 
-                    self.ms.execute_fact_instr(&fact_instr);
+                    self.execute_fact_instr(&fact_instr);
                 }
 
-                self.ms.p += 1;
+                self.p += 1;
             },
             &Line::Indexing(ref indexing_instr) =>
-                self.ms.execute_indexing_instr(&indexing_instr),
+                self.execute_indexing_instr(&indexing_instr),
             &Line::IndexedChoice(ref choice_instr) =>
-                self.ms.execute_indexed_choice_instr(choice_instr, &mut self.call_policy),
+                self.execute_indexed_choice_instr(choice_instr, &mut policies.call_policy),
             &Line::Query(ref query) => {
                 for query_instr in query {
-                    if self.failed() {
+                    if self.fail {
                         break;
                     }
 
-                    self.ms.execute_query_instr(&query_instr);
+                    self.execute_query_instr(&query_instr);
                 }
 
-                self.ms.p += 1;
+                self.p += 1;
             }
         }
     }
 
     fn backtrack(&mut self)
     {
-        if self.ms.b > 0 {
-            let b = self.ms.b - 1;
+        if self.b > 0 {
+            let b = self.b - 1;
 
-            self.ms.b0 = self.ms.or_stack[b].b0;
-            self.ms.p  = self.ms.or_stack[b].bp.clone();
+            self.b0 = self.or_stack[b].b0;
+            self.p  = self.or_stack[b].bp.clone();
 
-            if let CodePtr::Local(LocalCodePtr::TopLevel(_, p)) = self.ms.p {
-                self.ms.fail = p == 0;
+            if let CodePtr::Local(LocalCodePtr::TopLevel(_, p)) = self.p {
+                self.fail = p == 0;
             } else {
-                self.ms.fail = false;
+                self.fail = false;
             }
         } else {
-            self.ms.p = CodePtr::Local(LocalCodePtr::TopLevel(0, 0));
+            self.p = CodePtr::Local(LocalCodePtr::TopLevel(0, 0));
         }
     }
 
-    fn query_stepper<'a>(&mut self)
+    fn query_stepper(&mut self, indices: &mut IndexStore, policies: &mut MachinePolicies, code_repo: &CodeRepo)
     {
         loop {
-            self.execute_instr();
+            self.execute_instr(indices, policies, code_repo);
 
-            if self.failed() {
+            if self.fail {
                 self.backtrack();
             }
 
-            match self.ms.p {
-                CodePtr::Local(LocalCodePtr::DirEntry(p)) if p < self.code_repo.code.len() => {},
-                CodePtr::Local(LocalCodePtr::UserTermExpansion(p)) if p < self.code_repo.term_expanders.len() => {},
-                CodePtr::Local(LocalCodePtr::UserTermExpansion(_)) => self.ms.fail = true,
+            match self.p {
+                CodePtr::Local(LocalCodePtr::DirEntry(p)) if p < code_repo.code.len() => {},
+                CodePtr::Local(LocalCodePtr::UserTermExpansion(p)) if p < code_repo.term_expanders.len() => {},
+                CodePtr::Local(LocalCodePtr::UserTermExpansion(_)) => self.fail = true,
                 CodePtr::Local(_) => break,
                 _ => {}
             };
         }
     }
 
-    fn record_var_places(&self, chunk_num: usize, alloc_locs: &AllocVarDict,
-                         heap_locs: &mut HeapVarDict)
+    fn record_var_places(&self, chunk_num: usize, alloc_locs: &AllocVarDict, heap_locs: &mut HeapVarDict)
     {
         for (var, var_data) in alloc_locs {
             match var_data {
                 &VarData::Perm(p) if p > 0 => {
-                    let e = self.ms.e;
+                    let e = self.e;
                     let r = var_data.as_reg_type().reg_num();
-                    let addr = self.ms.and_stack[e][r].clone();
+                    let addr = self.and_stack[e][r].clone();
 
                     heap_locs.insert(var.clone(), addr);
                 },
@@ -452,7 +557,7 @@ impl Machine {
                     let r = var_data.as_reg_type();
 
                     if r.reg_num() != 0 {
-                        let addr = self.ms[r].clone();
+                        let addr = self[r].clone();
                         heap_locs.insert(var.clone(), addr);
                     }
                 },
@@ -461,13 +566,16 @@ impl Machine {
         }
     }
 
-    fn run_query(&mut self, alloc_locs: &AllocVarDict, heap_locs: &mut HeapVarDict)
+    pub(super)
+    fn run_query(&mut self, indices: &mut IndexStore,
+                 policies: &mut MachinePolicies, code_repo: &CodeRepo,
+                 alloc_locs: &AllocVarDict, heap_locs: &mut HeapVarDict)
     {
-        let end_ptr = top_level_code_ptr!(0, self.cached_query_size());
+        let end_ptr = top_level_code_ptr!(0, code_repo.size_of_cached_query());
 
-        while self.ms.p < end_ptr {
-            if let CodePtr::Local(LocalCodePtr::TopLevel(mut cn, p)) = self.ms.p {
-                match &self[LocalCodePtr::TopLevel(cn, p)] {
+        while self.p < end_ptr {
+            if let CodePtr::Local(LocalCodePtr::TopLevel(mut cn, p)) = self.p {
+                match &code_repo[LocalCodePtr::TopLevel(cn, p)] {
                     &Line::Control(ref ctrl_instr) if ctrl_instr.is_jump_instr() => {
                         self.record_var_places(cn, alloc_locs, heap_locs);
                         cn += 1;
@@ -475,12 +583,12 @@ impl Machine {
                     _ => {}
                 }
 
-                self.ms.p = top_level_code_ptr!(cn, p);
+                self.p = top_level_code_ptr!(cn, p);
             }
 
-            self.query_stepper();
+            self.query_stepper(indices, policies, code_repo);
 
-            match self.ms.p {
+            match self.p {
                 CodePtr::Local(LocalCodePtr::TopLevel(_, p)) if p > 0 => {},
                 _ => {
                     if heap_locs.is_empty() {
@@ -491,87 +599,6 @@ impl Machine {
                 }
             };
         }
-    }
-
-    fn fail(&mut self, heap_locs: &HeapVarDict) -> EvalSession
-    {
-        if self.ms.ball.stub.len() > 0 {
-            let h = self.ms.heap.h;
-            self.ms.copy_and_align_ball_to_heap();
-
-            let error_str = self.ms.print_exception(Addr::HeapCell(h),
-                                                    &heap_locs,
-                                                    TermFormatter {},
-                                                    PrinterOutputter::new())
-                                .result();
-
-            EvalSession::from(SessionError::QueryFailureWithException(error_str))
-        } else {
-            EvalSession::from(SessionError::QueryFailure)
-        }
-    }
-
-    pub fn submit_query(&mut self, code: Code, alloc_locs: AllocVarDict) -> EvalSession
-    {
-        let mut heap_locs = HashMap::new();
-
-        self.code_repo.cached_query = Some(code);
-        self.run_query(&alloc_locs, &mut heap_locs);
-
-        if self.failed() {
-            self.fail(&heap_locs)
-        } else {
-            EvalSession::InitialQuerySuccess(alloc_locs, heap_locs)
-        }
-    }
-
-    pub fn continue_query(&mut self, alloc_l: &AllocVarDict, heap_l: &mut HeapVarDict) -> EvalSession
-    {
-        if !self.or_stack_is_empty() {
-            let b = self.ms.b - 1;
-            self.ms.p = self.ms.or_stack[b].bp.clone();
-
-            if let CodePtr::Local(LocalCodePtr::TopLevel(_, 0)) = self.ms.p {
-                return EvalSession::from(SessionError::QueryFailure);
-            }
-
-            self.run_query(alloc_l, heap_l);
-
-            if self.failed() {
-                self.fail(&heap_l)
-            } else {
-                EvalSession::SubsequentQuerySuccess
-            }
-        } else {
-            EvalSession::from(SessionError::QueryFailure)
-        }
-    }
-
-    pub fn heap_view<Outputter>(&self, var_dir: &HeapVarDict, mut output: Outputter) -> Outputter
-       where Outputter: HCValueOutputter
-    {
-        let mut sorted_vars: Vec<(&Rc<Var>, &Addr)> = var_dir.iter().collect();
-        sorted_vars.sort_by_key(|ref v| v.0);
-
-        for (var, addr) in sorted_vars {
-            let fmt = TermFormatter {};
-            output = self.ms.print_var_eq(var.clone(), addr.clone(), var_dir, fmt, output);
-        }
-
-        output
-    }
-
-    pub fn or_stack_is_empty(&self) -> bool {
-        self.ms.b == 0
-    }
-
-    pub fn clear(&mut self) {
-        let mut machine = Machine::new();
-        mem::swap(self, &mut machine);
-    }
-
-    pub fn reset(&mut self) {
-        self.cut_policy = Box::new(DefaultCutPolicy {});
-        self.ms.reset();
-    }
+    }    
 }
+
index e4ee205679c71332a5e2bb558743476319fe0199..97a148bad6d2e868f57cfadd25666994c95a3a0d 100644 (file)
@@ -9,16 +9,26 @@ use prolog::read::*;
 use std::cell::Cell;
 use std::io::Read;
 
-pub struct TermStream<R: Read> {
+pub struct TermStream<'a, R: Read> {
     stack: Vec<Term>,
+    pub(crate) indices: &'a mut IndexStore,
+    policies: &'a mut MachinePolicies,
+    code_repo: &'a mut CodeRepo,    
     parser: Parser<R>,
     in_module: bool
 }
 
-impl<R: Read> TermStream<R> {
-    pub fn new(src: R, atom_tbl: TabledData<Atom>, flags: MachineFlags) -> Self {
+impl<'a, R: Read> TermStream<'a, R> {
+    pub fn new(src: R, atom_tbl: TabledData<Atom>, flags: MachineFlags,
+               indices: &'a mut IndexStore, policies: &'a mut MachinePolicies,
+               code_repo: &'a mut CodeRepo)
+               -> Self
+    {
         TermStream {
             stack: Vec::new(),
+            indices,
+            policies,
+            code_repo,
             parser: Parser::new(src, atom_tbl, flags),
             in_module: false
         }
@@ -67,40 +77,47 @@ impl<R: Read> TermStream<R> {
         }
     }
 
-    pub fn read_term(&mut self, wam: &mut Machine, op_dir: &OpDir) -> Result<Term, ParserError>
+    pub fn read_term(&mut self, machine_st: &mut MachineState, op_dir: &OpDir)
+                     -> Result<Term, ParserError>
     {
         loop {
             while let Some(term) = self.stack.pop() {
-                match wam.try_expand_term(&term)? {
+                match machine_st.try_expand_term(self.indices, self.policies, self.code_repo, &term)? {
                     Some(term) => self.enqueue_term(term)?,
                     None => return Ok(term)
                 };
             }
 
-            let term = self.parser.read_term(composite_op!(self.in_module, &wam.indices.op_dir,
+            let term = self.parser.read_term(composite_op!(self.in_module,
+                                                           &self.indices.op_dir,
                                                            op_dir))?;
             self.stack.push(term);
         }
     }
 }
 
-impl Machine {
-    fn try_expand_term(&mut self, term: &Term) -> Result<Option<Term>, ParserError> {
-        let term_h = write_term_to_heap(term, &mut self.ms);
-        let h = self.ms.heap.h;
+impl MachineState {
+    fn try_expand_term(&mut self, indices: &mut IndexStore, policies: &mut MachinePolicies,
+                       code_repo: &mut CodeRepo, term: &Term)
+                       -> Result<Option<Term>, ParserError>
+    {
+        let term_h = write_term_to_heap(term, self);
+        let h = self.heap.h;
 
-        self.ms[temp_v!(1)] = Addr::HeapCell(term_h);
-        self.ms.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
-        self.ms[temp_v!(2)] = Addr::HeapCell(h);
+        self[temp_v!(1)] = Addr::HeapCell(term_h);
+        self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
+        self[temp_v!(2)] = Addr::HeapCell(h);
 
         let code = vec![call_clause!(ClauseType::Hook(CompileTimeHook::TermExpansion), 2, 0, true)];
-        self.submit_query(code, AllocVarDict::new());
 
-        if self.failed() {
+        code_repo.cached_query = Some(code);
+        self.run_query(indices, policies, code_repo, &AllocVarDict::new(), &mut HeapVarDict::new());
+
+        if self.fail {
             self.reset();
             Ok(None)
         } else {
-            let term = read_term_from_heap(&self.ms, Addr::HeapCell(h))?;
+            let term = read_term_from_heap(&self, Addr::HeapCell(h))?;
             self.reset();            
             Ok(Some(term))
         }
index 1b87b6f6a34ba97e61888bc5975b1449e2a5db10..8ea8c4141753fb4aab0ec064c6965409232d57bd 100644 (file)
@@ -46,10 +46,11 @@ pub fn read_toplevel(wam: &mut Machine) -> Result<Input, ParserError> {
         },
         _ => {
             let mut term_stream = TermStream::new(stdin.lock(), wam.indices.atom_tbl.clone(),
-                                                  wam.machine_flags());
+                                                  wam.machine_flags(), &mut wam.indices,
+                                                  &mut wam.policies, &mut wam.code_repo);
+            
             term_stream.add_to_top(buffer.as_str());
-
-            Ok(Input::Term(term_stream.read_term(wam, &OpDir::new())?))
+            Ok(Input::Term(term_stream.read_term(&mut wam.machine_st, &OpDir::new())?))
         }
     }
 }
index f5b15c0ed337cb9e446d284f8c8aeaf5db3efd66..8ea97ec0c925ff5708fef687dceb1b0957504c32 100644 (file)
@@ -4,6 +4,7 @@ use prolog_parser::tabled_rc::*;
 use prolog::instructions::*;
 use prolog::iterators::*;
 use prolog::machine::*;
+use prolog::machine::machine_state::MachineState;
 use prolog::machine::term_expansion::*;
 use prolog::num::*;
 
@@ -15,7 +16,7 @@ use std::rc::Rc;
 
 struct CompositeIndices<'a, 'b> {
     local: &'a mut IndexStore,
-    static_code_dir: Option<&'b mut CodeDir>
+    static_code_dir: Option<&'b CodeDir>
 }
 
 macro_rules! composite_indices {
@@ -720,11 +721,11 @@ pub fn parse_term<R: Read>(wam: &Machine, buf: R) -> Result<Term, ParserError>
 }
 
 pub
-fn consume_term(static_code_dir: &mut CodeDir, term: Term, indices: &mut IndexStore)
-                -> Result<TopLevelPacket, ParserError>
+fn consume_term(term: Term, indices: &mut IndexStore) -> Result<TopLevelPacket, ParserError>
 {
     let mut rel_worker = RelationWorker::new();
-    let mut indices = composite_indices!(false, indices, static_code_dir);
+    let mut _code_dir = CodeDir::new();
+    let mut indices = composite_indices!(false, indices, &mut _code_dir);
 
     let tl = rel_worker.try_term_to_tl(&mut indices, term, true)?;
     let results = rel_worker.parse_queue(&mut indices)?;
@@ -732,49 +733,52 @@ fn consume_term(static_code_dir: &mut CodeDir, term: Term, indices: &mut IndexSt
     Ok(deque_to_packet(tl, results))
 }
 
-pub struct TopLevelBatchWorker<R: Read> {
-    pub(crate) term_stream: TermStream<R>,
+pub struct TopLevelBatchWorker<'a, R: Read> {
+    pub(crate) term_stream: TermStream<'a, R>,
     rel_worker: RelationWorker,
-    pub(super) static_code_dir: CodeDir,
     pub(crate) results: Vec<(Predicate, VecDeque<TopLevel>)>,
     pub(crate) in_module: bool
 }
 
-impl<R: Read> TopLevelBatchWorker<R> {
-    pub fn new(inner: R, atom_tbl: TabledData<Atom>, flags: MachineFlags, static_code_dir: CodeDir)
+impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
+    pub fn new(inner: R,
+               atom_tbl: TabledData<Atom>,
+               flags: MachineFlags,
+               indices: &'a mut IndexStore,
+               policies: &'a mut MachinePolicies,
+               code_repo: &'a mut CodeRepo)
                -> Self
     {
-        TopLevelBatchWorker { term_stream: TermStream::new(inner, atom_tbl, flags),
+        let term_stream = TermStream::new(inner, atom_tbl, flags,
+                                          indices, policies, code_repo);
+
+        TopLevelBatchWorker { term_stream,
                               rel_worker: RelationWorker::new(),
-                              static_code_dir,
                               results: vec![],
                               in_module: false }
     }
 
     pub
-    fn consume(&mut self, wam: &mut Machine, indices: &mut IndexStore)
+    fn consume(&mut self, machine_st: &mut MachineState, indices: &mut IndexStore)
                -> Result<Option<Declaration>, SessionError>
     {
         let mut preds = vec![];
 
         while !self.term_stream.eof()? {
-            self.term_stream.empty_tokens(); // empty the parser stack of token descriptions.
+            // empty the parser stack of token descriptions.
+            self.term_stream.empty_tokens();
 
             let mut new_rel_worker = RelationWorker::new();
-            
-            let term = {                
-                wam.swap_code_dir(&mut self.static_code_dir);
-                self.term_stream.read_term(wam, &indices.op_dir)?
-            };
-        
-            self.static_code_dir = wam.take_code_dir();
-            
-            let mut indices = composite_indices!(self.in_module, indices,
-                                                 &mut self.static_code_dir);
+            let term = self.term_stream.read_term(machine_st, &indices.op_dir)?;
+
+            let mut indices =
+                composite_indices!(self.in_module, indices,
+                                   &mut self.term_stream.indices.code_dir);
             
             let tl = new_rel_worker.try_term_to_tl(&mut indices, term, true)?;
 
-            if !is_consistent(&tl, &preds) {  // if is_consistent returns false, preds is non-empty.
+            // if is_consistent returns false, preds is non-empty.
+            if !is_consistent(&tl, &preds) {
                 let result_queue = self.rel_worker.parse_queue(&mut indices)?;
                 self.results.push((append_preds(&mut preds), result_queue));
             }
@@ -791,8 +795,9 @@ impl<R: Read> TopLevelBatchWorker<R> {
         }
 
         if !preds.is_empty() {
-            let mut indices = composite_indices!(self.in_module, indices,
-                                                 &mut self.static_code_dir);
+            let mut indices =
+                composite_indices!(self.in_module, indices,
+                                   &mut self.term_stream.indices.code_dir);
 
             let result_queue = self.rel_worker.parse_queue(&mut indices)?;
             self.results.push((append_preds(&mut preds), result_queue));