]> Repositorios git - scryer-prolog.git/commitdiff
transition to MachineCodeIndices internally
authorMark Thom <[email protected]>
Sat, 8 Sep 2018 08:31:33 +0000 (02:31 -0600)
committerMark Thom <[email protected]>
Sat, 8 Sep 2018 08:31:33 +0000 (02:31 -0600)
12 files changed:
src/prolog/compile.rs
src/prolog/instructions.rs
src/prolog/lib/builtins.pl
src/prolog/machine/machine_errors.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/machine/mod.rs
src/prolog/machine/system_calls.rs
src/prolog/macros.rs
src/prolog/mod.rs
src/prolog/term_writer.rs [new file with mode: 0644]
src/prolog/toplevel.rs

index 931fb37aa46f6eb9cc0bf0f878e2708b6acb3af6..eb57251c61403aeb43729d03498dfd9141d857f6 100644 (file)
@@ -42,12 +42,9 @@ pub fn parse_code(wam: &mut Machine, buffer: &str) -> Result<TopLevelPacket, Par
     let atom_tbl = wam.atom_tbl();
     let flags = wam.machine_flags();
 
-    let index = MachineCodeIndices {
-        code_dir: &mut wam.code_dir,
-        op_dir: &mut wam.op_dir,
-    };
+    let indices = machine_code_indices!(&mut wam.code_dir, &mut wam.op_dir, &mut HashMap::new());
 
-    let mut worker = TopLevelWorker::new(buffer.as_bytes(), atom_tbl, flags, index);
+    let mut worker = TopLevelWorker::new(buffer.as_bytes(), atom_tbl, flags, indices);
     worker.parse_code()
 }
 
@@ -139,7 +136,7 @@ fn compile_decl(wam: &mut Machine, tl: TopLevel, queue: Vec<TopLevel>) -> EvalSe
             let mut code = try_eval_session!(compile_relation(&tl, false, wam.machine_flags()));
             try_eval_session!(compile_appendix(&mut code, queue, false, wam.machine_flags()));
 
-            if !code.is_empty() {                
+            if !code.is_empty() {
                 wam.add_user_code(name, tl.arity(), code, tl.as_predicate().ok().unwrap())
             } else {
                 EvalSession::from(SessionError::ImpermissibleEntry(String::from("no code generated.")))
@@ -289,7 +286,8 @@ fn compile_listing(wam: &mut Machine, src_str: &str, mut indices: MachineCodeInd
 }
 
 pub fn compile_user_module(wam: &mut Machine, src_str: &str) -> EvalSession {
-    let mut indices = machine_code_indices!(&mut CodeDir::new(), &mut default_op_dir());
+    let mut indices = machine_code_indices!(&mut CodeDir::new(), &mut default_op_dir(),
+                                            &mut HashMap::new());
 
     if let Some(ref builtins) = wam.modules.get(&clause_name!("builtins")) {
         indices.use_module(builtins);
index 2134a8026b272183b99abaaa4c330ddb9ef10fdd..770e23ae246083d19323b080305f26fa0f2a7197 100644 (file)
@@ -238,7 +238,8 @@ pub enum SystemClauseType {
     SetDoubleQuotes,
     SkipMaxList,
     Succeed,
-    UnwindStack
+    UnwindStack,
+    CompileAndRunQuery
 }
 
 impl SystemClauseType {
@@ -276,6 +277,7 @@ impl SystemClauseType {
             &SystemClauseType::SkipMaxList => clause_name!("$skip_max_list"),
             &SystemClauseType::Succeed => clause_name!("$succeed"),
             &SystemClauseType::UnwindStack => clause_name!("$unwind_stack"),
+            &SystemClauseType::CompileAndRunQuery => clause_name!("$compile_and_run_query")
         }
     }
 
@@ -309,6 +311,7 @@ impl SystemClauseType {
             ("$set_double_quotes", 1) => Some(SystemClauseType::SetDoubleQuotes),
             ("$skip_max_list", 4) => Some(SystemClauseType::SkipMaxList),
             ("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack),
+            ("$compile_and_run_query", 1) => Some(SystemClauseType::CompileAndRunQuery),
             _ => None
         }
     }
index 5e82723a1631a8a2fcf784b656ba68555d9ca41e..bb6a18a484fa579a8ad8acb06c0a203e049591c5 100644 (file)
@@ -307,3 +307,5 @@ handle_ball(C, C, R) :- !, '$erase_ball', call(R).
 handle_ball(_, _, _) :- '$unwind_stack'.
 
 throw(Ball) :- '$set_ball'(Ball), '$unwind_stack'.
+
+repl :- read(X), '$compile_and_run_query'(X), repl.
index 066dde16cddf57aea21e3204f56a67b28b060477..692c6654157514c744518bd228a9de6c4b46ca81 100644 (file)
@@ -111,6 +111,7 @@ impl MachineError {
         };
         
         stub.extend(err.into_iter());
+        
         MachineError { stub, from: ErrorProvenance::Constructed }
     }
 
index fe6c928767e9d7a9fef1c80334ac616308740097..6d85fd02ab6693eeb1345416d4bae62c97275750 100644 (file)
@@ -5,6 +5,7 @@ use prolog::instructions::*;
 use prolog::and_stack::*;
 use prolog::copier::*;
 use prolog::heap_print::*;
+use prolog::machine::MachineCodeIndices;
 use prolog::machine::machine_errors::*;
 use prolog::num::{BigInt, BigUint, Zero, One};
 use prolog::or_stack::*;
@@ -46,19 +47,6 @@ impl<'a> CodeDirs<'a> {
         CodeDirs { code_dir, op_dir, modules }
     }
 
-    pub(super) fn get(&self, name: ClauseName, arity: usize, in_mod: ClauseName) -> Option<CodeIndex>
-    {
-        match in_mod.as_str() {
-            "user" | "builtin" => self.code_dir.get(&(name, arity)).cloned(),
-            _ =>
-                match self.modules.get(&in_mod) {
-                    Some(&Module { ref code_dir, .. }) =>
-                        code_dir.get(&(name, arity)).cloned().map(CodeIndex::from),
-                    None => None
-                }
-        }
-    }
-
     fn get_internal(&self, name: ClauseName, arity: usize, in_mod: ClauseName) -> Option<ModuleCodeIndex> {
         self.modules.get(&in_mod)
             .and_then(|ref module| module.code_dir.get(&(name, arity)))
@@ -90,9 +78,34 @@ pub trait CodeDirsAdapter<'a> {
     fn op_dir(&self) -> &OpDir;
 }
 
+fn get_code_index(code_dir: &CodeDir, modules: &ModuleDir, key: PredicateKey, module: ClauseName)
+                  -> Option<CodeIndex>
+{
+    match module.as_str() {
+        "user" | "builtin" => code_dir.get(&key).cloned(),
+        _ => modules.get(&module).and_then(|ref module| {
+            module.code_dir.get(&key).cloned().map(CodeIndex::from)
+        })
+    }
+}
+
+impl<'a> CodeDirsAdapter<'a> for MachineCodeIndices<'a> {
+    fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option<CodeIndex> {
+        get_code_index(&self.code_dir, &self.modules, key, module)
+    }
+
+    fn get_op(&self, key: OpDirKey) -> Option<(Specifier, usize, ClauseName)> {
+        self.op_dir.get(&key).cloned()
+    }
+
+    fn op_dir(&self) -> &OpDir {
+        &self.op_dir
+    }
+}
+
 impl<'a> CodeDirsAdapter<'a> for CodeDirs<'a> {
     fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option<CodeIndex> {
-        self.get(key.0, key.1, module)
+        get_code_index(&self.code_dir, &self.modules, key, module)
     }
 
     fn get_op(&self, key: OpDirKey) -> Option<(Specifier, usize, ClauseName)> {
@@ -433,18 +446,18 @@ pub(crate) trait CallPolicy: Any {
     }
 
     fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName, arity: usize,
-                        idx: CodeIndex, code_dirs: CodeDirs)
-                        -> CallResult
+                    idx: CodeIndex, indices: MachineCodeIndices)
+                    -> CallResult
     {
         if machine_st.last_call {
-            self.try_execute(machine_st, name, arity, idx, code_dirs)
+            self.try_execute(machine_st, name, arity, idx, indices)
         } else {
-            self.try_call(machine_st, name, arity, idx, code_dirs)
+            self.try_call(machine_st, name, arity, idx, indices)
         }
     }
 
     fn try_call<'a>(&mut self, machine_st: &mut MachineState, name: ClauseName, arity: usize,
-                    idx: CodeIndex, code_dirs: CodeDirs)
+                    idx: CodeIndex, indices: MachineCodeIndices<'a>)
                     -> CallResult
     {
         match idx.0.borrow().0 {
@@ -453,7 +466,7 @@ pub(crate) trait CallPolicy: Any {
                 let module_name = idx.0.borrow().1.clone();
                 let h = machine_st.heap.h;
 
-                if let Some(ref idx) = code_dirs.get_code_index((name.clone(), arity), module_name.clone())
+                if let Some(ref idx) = indices.get_code_index((name.clone(), arity), module_name.clone())
                 {
                     if let IndexPtr::Index(compiled_tl_index) = idx.0.borrow().0 {
                         call_at_index(machine_st, module_name, arity, compiled_tl_index);
@@ -481,7 +494,7 @@ pub(crate) trait CallPolicy: Any {
     }
 
     fn try_execute<'a>(&mut self, machine_st: &mut MachineState, name: ClauseName,
-                       arity: usize, idx: CodeIndex, code_dirs: CodeDirs)
+                       arity: usize, idx: CodeIndex, indices: MachineCodeIndices<'a>)
                        -> CallResult
     {
         match idx.0.borrow().0 {
@@ -490,7 +503,7 @@ pub(crate) trait CallPolicy: Any {
                 let module_name = idx.0.borrow().1.clone();
                 let h = machine_st.heap.h;
 
-                if let Some(ref idx) = code_dirs.get_code_index((name.clone(), arity), module_name.clone())
+                if let Some(ref idx) = indices.get_code_index((name.clone(), arity), module_name.clone())
                 {
                     if let IndexPtr::Index(compiled_tl_index) = idx.0.borrow().0 {
                         execute_at_index(machine_st, module_name, arity, compiled_tl_index);
@@ -518,10 +531,10 @@ pub(crate) trait CallPolicy: Any {
     }
 
     fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType,
-                        code_dirs: CodeDirs)
+                        indices: MachineCodeIndices<'a>) //code_dirs: CodeDirs)
                         -> CallResult
     {
-        match ct {            
+        match ct {
             &BuiltInClauseType::AcyclicTerm => {
                 let addr = machine_st[temp_v!(1)].clone();
                 machine_st.fail = machine_st.is_cyclic_term(addr);
@@ -564,7 +577,7 @@ pub(crate) trait CallPolicy: Any {
             &BuiltInClauseType::Read => {
                 let mut reader = Reader::new(machine_st);
 
-                match reader.read_stdin(code_dirs.op_dir()) {
+                match reader.read_stdin(&indices.op_dir) {
                     Ok(offset) => {
                         let addr = reader.machine_st[temp_v!(1)].clone();
                         reader.machine_st.unify(addr, Addr::HeapCell(offset));
@@ -574,7 +587,7 @@ pub(crate) trait CallPolicy: Any {
                         let stub = MachineError::functor_stub(clause_name!("read"), 1);
                         let err  = MachineError::syntax_error(h, e);
                         let err  = reader.machine_st.error_form(err, stub);
-                        
+
                         return Err(err);
                     }
                 };
@@ -614,7 +627,7 @@ pub(crate) trait CallPolicy: Any {
                 } else {
                     false
                 };
-                
+
                 return_from_clause!(machine_st.last_call, machine_st)
             },
             &BuiltInClauseType::PartialString => {
@@ -679,7 +692,7 @@ pub(crate) trait CallPolicy: Any {
     }
 
     fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize,
-                  code_dirs: CodeDirs)
+                  indices: MachineCodeIndices<'a>) //code_dirs: CodeDirs)
                   -> CallResult
     {
         if let Some((name, arity)) = machine_st.setup_call_n(arity) {
@@ -697,13 +710,13 @@ pub(crate) trait CallPolicy: Any {
                 },
                 ClauseType::BuiltIn(built_in) => {
                     machine_st.setup_built_in_call(built_in.clone());
-                    self.call_builtin(machine_st, &built_in, code_dirs)?;
+                    self.call_builtin(machine_st, &built_in, indices)?;
                 },
                 ClauseType::Inlined(inlined) =>
                     machine_st.execute_inlined(&inlined),
                 ClauseType::Op(..) | ClauseType::Named(..) =>
-                    if let Some(idx) = code_dirs.get_code_index((name.clone(), arity), user) {
-                        self.context_call(machine_st, name, arity, idx, code_dirs)?;
+                    if let Some(idx) = indices.get_code_index((name.clone(), arity), user) {
+                        self.context_call(machine_st, name, arity, idx, indices)?;
                     } else {
                         let h = machine_st.heap.h;
                         let stub = MachineError::functor_stub(clause_name!("call"), arity + 1);
@@ -727,10 +740,10 @@ pub(crate) trait CallPolicy: Any {
 
 impl CallPolicy for CWILCallPolicy {
     fn context_call<'a>(&mut self, machine_st: &mut MachineState, name: ClauseName,
-                        arity: usize, idx: CodeIndex, code_dirs: CodeDirs)
+                        arity: usize, idx: CodeIndex, indices: MachineCodeIndices<'a>)
                         -> CallResult
     {
-        self.prev_policy.context_call(machine_st, name, arity, idx, code_dirs)?;
+        self.prev_policy.context_call(machine_st, name, arity, idx, indices)?;
         self.increment(machine_st)
     }
 
@@ -759,18 +772,17 @@ impl CallPolicy for CWILCallPolicy {
     }
 
     fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType,
-                        code_dirs: CodeDirs)
+                        indices: MachineCodeIndices<'a>)
                         -> CallResult
     {
-        self.prev_policy.call_builtin(machine_st, ct, code_dirs)?;
+        self.prev_policy.call_builtin(machine_st, ct, indices)?;
         self.increment(machine_st)
     }
 
-    fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize,
-                  code_dirs: CodeDirs)
+    fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize, indices: MachineCodeIndices<'a>)
                   -> CallResult
     {
-        self.prev_policy.call_n(machine_st, arity, code_dirs)?;
+        self.prev_policy.call_n(machine_st, arity, indices)?;
         self.increment(machine_st)
     }
 }
index 4791f5126f944575bfe93463bccd29db6c657e0f..aa6440ddbbcf793ac70b4720aefc5b08fb76345a 100644 (file)
@@ -6,6 +6,7 @@ use prolog::and_stack::*;
 use prolog::copier::*;
 use prolog::heap_iter::*;
 use prolog::heap_print::*;
+use prolog::machine::MachineCodeIndices;
 use prolog::machine::machine_errors::*;
 use prolog::machine::machine_state::*;
 use prolog::num::{Integer, Signed, ToPrimitive, Zero};
@@ -2045,7 +2046,7 @@ impl MachineState {
         self.p += 1;
     }
 
-    fn handle_call_clause<'a>(&mut self, code_dirs: CodeDirs<'a>,
+    fn handle_call_clause<'a>(&mut self, indices: MachineCodeIndices<'a>,
                               call_policy: &mut Box<CallPolicy>,
                               cut_policy:  &mut Box<CutPolicy>,
                               ct: &ClauseType,
@@ -2064,20 +2065,20 @@ impl MachineState {
 
         match ct {
             &ClauseType::BuiltIn(ref ct) =>
-                try_or_fail!(self, call_policy.call_builtin(self, ct, code_dirs)),
+                try_or_fail!(self, call_policy.call_builtin(self, ct, indices)),
             &ClauseType::CallN =>
-                try_or_fail!(self, call_policy.call_n(self, arity, code_dirs)),
+                try_or_fail!(self, call_policy.call_n(self, arity, indices)),
             &ClauseType::Inlined(ref ct) =>
                 self.execute_inlined(ct),
             &ClauseType::Named(ref name, ref idx) | &ClauseType::Op(ref name, _, ref idx) =>
                 try_or_fail!(self, call_policy.context_call(self, name.clone(), arity, idx.clone(),
-                                                            code_dirs)),
+                                                            indices)),
             &ClauseType::System(ref ct) =>
-                try_or_fail!(self, self.system_call(ct, code_dirs, call_policy, cut_policy))
+                try_or_fail!(self, self.system_call(ct, indices, call_policy, cut_policy))
         };
     }
 
-    pub(super) fn execute_ctrl_instr<'a>(&mut self, code_dirs: CodeDirs<'a>,
+    pub(super) fn execute_ctrl_instr<'a>(&mut self, indices: MachineCodeIndices<'a>,
                                          call_policy: &mut Box<CallPolicy>,
                                          cut_policy:  &mut Box<CutPolicy>,
                                          instr: &ControlInstruction)
@@ -2086,7 +2087,7 @@ impl MachineState {
             &ControlInstruction::Allocate(num_cells) =>
                 self.allocate(num_cells),
             &ControlInstruction::CallClause(ref ct, arity, _, lco, use_default_cp) =>
-                self.handle_call_clause(code_dirs, call_policy, cut_policy, ct, arity, lco,
+                self.handle_call_clause(indices, call_policy, cut_policy, ct, arity, lco,
                                         use_default_cp),
             &ControlInstruction::Deallocate => self.deallocate(),
             &ControlInstruction::JmpBy(arity, offset, _, lco) => {
index 8d7e1ef9ceee4fc8527d87fc57867e7c9a9fc25b..5db6062efc6e7fb7125faedaa28e45f75d30f4e2 100644 (file)
@@ -23,6 +23,7 @@ static BUILTINS: &str = include_str!("../lib/builtins.pl");
 pub struct MachineCodeIndices<'a> {
     pub(super) code_dir: &'a mut CodeDir,
     pub(super) op_dir: &'a mut OpDir,
+    pub(super) modules: &'a mut ModuleDir
 }
 
 impl<'a> MachineCodeIndices<'a> {
@@ -45,6 +46,13 @@ impl<'a> MachineCodeIndices<'a> {
             ct => ct
         }
     }
+
+    #[inline]
+    pub(super) fn to_code_dirs(self) -> CodeDirs<'a> {
+        CodeDirs { code_dir: self.code_dir,
+                   op_dir: self.op_dir,
+                   modules: self.modules }
+    }
 }
 
 pub struct Machine {
@@ -107,13 +115,15 @@ impl Machine {
             cut_policy: Box::new(DefaultCutPolicy {}),
             code: Code::new(),
             code_dir: CodeDir::new(),
-            term_dir: TermDir::new(),
             op_dir: default_op_dir(),
+            term_dir: TermDir::new(),            
             modules: HashMap::new(),
             cached_query: None
         };
 
-        let indices = machine_code_indices!(&mut CodeDir::new(), &mut default_op_dir());
+        let indices = machine_code_indices!(&mut CodeDir::new(), &mut default_op_dir(),
+                                            &mut HashMap::new());
+        
         compile_listing(&mut wam, BUILTINS, indices);
 
         compile_user_module(&mut wam, LISTS);
@@ -194,7 +204,8 @@ impl Machine {
 
         if let Some(mut module) = self.modules.remove(&name) {
             let result = {
-                let mut indices = machine_code_indices!(&mut self.code_dir, &mut self.op_dir);
+                let mut indices = machine_code_indices!(&mut self.code_dir, &mut self.op_dir,
+                                                        &mut self.modules);
                 indices.use_qualified_module(&mut module, &exports)
             };
 
@@ -211,7 +222,8 @@ impl Machine {
 
         if let Some(mut module) = self.modules.remove(&name) {
             let result = {
-                let mut indices = machine_code_indices!(&mut self.code_dir, &mut self.op_dir);
+                let mut indices = machine_code_indices!(&mut self.code_dir, &mut self.op_dir,
+                                                        &mut self.modules);
                 indices.use_module(&mut module)
             };
 
@@ -308,9 +320,11 @@ impl Machine {
             Line::Cut(ref cut_instr) =>
                 self.ms.execute_cut_instr(cut_instr, &mut self.cut_policy),
             Line::Control(ref control_instr) => {
-                let code_dirs = CodeDirs::new(&self.code_dir, &self.op_dir,
-                                              &self.modules);
-                self.ms.execute_ctrl_instr(code_dirs, &mut self.call_policy,
+                let indices = machine_code_indices!(&mut self.code_dir, &mut self.op_dir,
+                                                    &mut self.modules);
+//                let code_dirs = CodeDirs::new(&self.code_dir, &self.op_dir,
+//                                              &self.modules);
+                self.ms.execute_ctrl_instr(indices, &mut self.call_policy,
                                            &mut self.cut_policy, control_instr)
             },
             Line::Fact(ref fact) => {
index acb3af3480a2a55360eaf0d4eba055964b247f64..65e27953c6679233a93859678174642f9fc20dab 100644 (file)
@@ -1,10 +1,12 @@
 use prolog_parser::ast::*;
 
 use prolog::instructions::*;
+use prolog::machine::MachineCodeIndices;
 use prolog::machine::machine_errors::*;
 use prolog::machine::machine_state::*;
 use prolog::num::{ToPrimitive, Zero};
 use prolog::num::bigint::{BigInt};
+//use prolog::term_writer::*;
 
 use std::rc::Rc;
 
@@ -164,6 +166,7 @@ impl MachineState {
         Ok(())
     }
 
+    #[inline]
     fn install_new_block(&mut self, r: RegType) -> usize {
         self.block = self.b;
 
@@ -174,6 +177,7 @@ impl MachineState {
         self.block
     }
 
+    #[inline]
     fn set_p(&mut self) {
         if self.last_call {
             self.p = CodePtr::Local(self.cp.clone());
@@ -183,7 +187,7 @@ impl MachineState {
     }
 
     pub(super) fn system_call<'a>(&mut self, ct: &SystemClauseType,
-                                  code_dirs: CodeDirs<'a>,
+                                  indices: MachineCodeIndices<'a>,
                                   call_policy: &mut Box<CallPolicy>,
                                   cut_policy:  &mut Box<CutPolicy>,)
                                   -> CallResult
@@ -237,7 +241,7 @@ impl MachineState {
                 let prev_block = self.block;
 
                 if cut_policy.downcast_ref::<SCCCutPolicy>().is_err() {
-                    let (r_c_w_h, r_c_wo_h) = code_dirs.get_cleaner_sites();
+                    let (r_c_w_h, r_c_wo_h) = indices.to_code_dirs().get_cleaner_sites();
                     *cut_policy = Box::new(SCCCutPolicy::new(r_c_w_h, r_c_wo_h));
                 }
 
@@ -431,7 +435,14 @@ impl MachineState {
                 return Err(err);
             },
             &SystemClauseType::Succeed => {},
-            &SystemClauseType::UnwindStack => self.unwind_stack()
+            &SystemClauseType::UnwindStack => self.unwind_stack(),
+            &SystemClauseType::CompileAndRunQuery => {}
+/*              let addr = self[temp_v!(1)].clone();
+                
+                match term_write(&self, addr) {
+                    Err(e)   => machine_error
+                    Ok(term) => 
+            }*/
         };
 
         self.set_p();
index f348ed0d0a4c67ddc94d70bf1b594622c7907eaf..02b2629b1dead934f84ffab571bc10765bda5821 100644 (file)
@@ -216,8 +216,9 @@ macro_rules! set_code_index {
 }
 
 macro_rules! machine_code_indices {
-    ($code_dir:expr, $op_dir:expr) => ( //, $modules:expr) => (
-        MachineCodeIndices { code_dir: $code_dir, op_dir: $op_dir } //, modules: $modules }
+    ($code_dir:expr, $op_dir:expr, $modules:expr) => ( //, $modules:expr) => (
+        MachineCodeIndices { code_dir: $code_dir, op_dir: $op_dir,
+                             modules: $modules} //, modules: $modules }
     )
 }
 
index 1e137abbe7f5dc97c556360bdd3e1f5c4197982a..138b3e4946de72954a44b28e46e3cb92b6eab6db 100644 (file)
@@ -3,22 +3,22 @@ extern crate ordered_float;
 extern crate prolog_parser;
 
 #[macro_use] pub mod instructions;
-pub mod and_stack;
-#[macro_use] pub mod macros;
-#[macro_use] pub mod allocator;
-pub mod toplevel;
+mod and_stack;
+#[macro_use] mod macros;
+#[macro_use] mod allocator;
+mod toplevel;
 pub mod machine;
 pub mod compile;
-pub mod arithmetic;
-pub mod codegen;
-pub mod copier;
-pub mod debray_allocator;
-pub mod fixtures;
-pub mod heap_iter;
-pub mod indexing;
+mod arithmetic;
+mod codegen;
+mod copier;
+mod debray_allocator;
+mod fixtures;
+mod heap_iter;
+mod indexing;
 pub mod io;
-pub mod iterators;
-pub mod or_stack;
+mod iterators;
+mod or_stack;
 pub mod heap_print;
-pub mod targets;
-pub mod read;
+mod targets;
+mod read;
diff --git a/src/prolog/term_writer.rs b/src/prolog/term_writer.rs
new file mode 100644 (file)
index 0000000..84cb149
--- /dev/null
@@ -0,0 +1,43 @@
+use prolog_parser::ast::*;
+
+use prolog::heap_iter::*;
+use prolog::instructions::HeapCellValue;
+use prolog::machine::machine_state::MachineState;
+
+pub fn term_write(machine_st: &'a MachineState, addr: Addr) -> Result<Term, ParserError> {
+    let pre_order_iter  = HCPreOrderIterator::new(machine_st, addr);
+    let post_order_iter = HCPostOrderIterator::new(pre_order_iter);
+    let acyclic_post_order_iter = HCAcyclicIterator::new(post_order_iter);
+
+    let mut stack = vec![];
+    
+    for value in acyclic_post_order_iter {
+        match value {
+            HeapCellValue::NamedStr(arity, name, fixity)
+                if stack.len() >= arity => {
+                    let subterms: Vec<_> = stack[stack.len() - arity ..].drain().collect();
+                    stack.push(Box::new(Term::Clause(Cell::default(), name, subterms, fixity)));
+                },
+            HeapCellValue::Addr(Addr::Con(constant)) =>
+                stack.push(Box::new(Term::Constant(Cell::default(), constant))),
+            HeapCellValue::Addr(Addr::Lis(_))
+                if stack.len() >= 2 => {
+                    let subterms: Vec<_> = stack[stack.len() - 2 ..].drain().collect();                    
+                    stack.push(Box::new(Term::Cons(Cell::default(), subterms[0], subterms[1])));
+                },
+            HeapCellValue::Addr(Addr::HeapCell(h)) =>
+                stack.push(Box::new(Term::Var(Cell::default(), Rc::new(format!("_{}", h))))),
+            HeapCellValue::Addr(Addr::StackCell(fr, sc)) =>
+                stack.push(Box::new(Term::Var(Cell::default(), Rc::new(format!("_{}_{}", sc, fr))))),
+            _ => return Err(ParserError::IncompleteReduction)
+        }
+    }
+
+    if let Some(term) = stack.pop() {
+        if stack.is_empty() {
+            return Ok(term);
+        } 
+    }
+
+    Err(ParserError::IncompleteReduction)
+}
index aaef8bfa108421d462f41a22ab0750b9e74c341e..fac313b5234daca58dd08f4266cf2879145a73e7 100644 (file)
@@ -496,8 +496,7 @@ impl RelationWorker {
         }
     }
 
-    fn pre_query_term(&mut self, idx: &mut MachineCodeIndices, term: Term)
-                      -> Result<QueryTerm, ParserError>
+    fn pre_query_term(&mut self, idx: &mut MachineCodeIndices, term: Term) -> Result<QueryTerm, ParserError>
     {
         match term {
             Term::Clause(r, name, mut subterms, fixity) =>