]> Repositorios git - scryer-prolog.git/commitdiff
flatten CompiledQuery and CompiledFact in Code, remove CompiledQuery
authorMark Thom <[email protected]>
Thu, 7 Feb 2019 05:25:41 +0000 (22:25 -0700)
committerMark Thom <[email protected]>
Thu, 7 Feb 2019 05:25:41 +0000 (22:25 -0700)
src/main.rs
src/prolog/codegen.rs
src/prolog/compile.rs
src/prolog/fixtures.rs
src/prolog/instructions.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/toplevel.rs

index 48dc33d49d23dcb1ad210d84064d0c11112e0771..6b85d72ca7a5235c5b970d765ffcf6f9a81381ac 100644 (file)
@@ -19,7 +19,7 @@ mod tests;
 
 fn prolog_repl() {
     let mut wam = Machine::new();
-
+    
     loop {
         print!("prolog> ");
         stdout().flush().unwrap();
index 9409bf46a23bb9341b5c02fa4a16d737f1f2fb53..46a86114af9d5f9686e9b46a3077596e2e23b479 100644 (file)
@@ -47,24 +47,40 @@ impl<'a> ConjunctInfo<'a>
     fn mark_unsafe_vars(&self, mut unsafe_var_marker: UnsafeVarMarker, code: &mut Code) {
         // target the last goal of the rule for handling unsafe variables.
         // we use this weird logic to find the last goal.
-        let index = if let &Line::Control(_) = code.last().unwrap() {
+        let right_index = if let &Line::Control(_) = code.last().unwrap() {
             code.len() - 2
         } else {
             code.len() - 1
         };
 
-        if let Line::Query(_) = &code[index] {
+        let mut index = right_index;
+
+        if let Line::Query(_) = &code[right_index] {
+            while let Line::Query(_) = &code[index] { // index >= 0.
+                if index == 0 {
+                    break;
+                } else {
+                    index -= 1;
+                }
+            }
+
+            if let Line::Query(_) = &code[index] {} else {
+                index += 1;
+            }
+
             unsafe_var_marker.record_unsafe_vars(&self.perm_vs);
 
             for line in code.iter_mut() {
-                if let &mut Line::Query(ref mut query) = line {
-                    unsafe_var_marker.mark_safe_vars(query);
+                if let &mut Line::Query(ref mut query_instr) = line {
+                    unsafe_var_marker.mark_safe_vars(query_instr);
                 }
             }
-        }
 
-        if let &mut Line::Query(ref mut query) = &mut code[index] {
-            unsafe_var_marker.mark_unsafe_vars(query);
+            for index in index .. right_index + 1 {
+                if let &mut Line::Query(ref mut query_instr) = &mut code[index] {
+                    unsafe_var_marker.mark_unsafe_vars(query_instr);
+                }
+            }
         }
     }
 }
@@ -110,7 +126,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                 self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target);
 
                 if !target.is_empty() {
-                    code.push(Line::Query(target));
+                    for query_instr in target {
+                        code.push(Line::Query(query_instr));
+                    }
                 }
 
                 vr.get().norm()
@@ -445,7 +463,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                                      term_loc, &mut target);
 
                 if !target.is_empty() {
-                    code.push(Line::Query(target));
+                    for query_instr in target {
+                        code.push(Line::Query(query_instr));
+                    }
                 }
 
                 if use_default_call_policy {
@@ -455,9 +475,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                 }
             },
             &Term::Constant(_, ref c @ Constant::Number(_)) => {
-                code.push(query![put_constant!(Level::Shallow,
-                                               c.clone(),
-                                               temp_v!(1))]);
+                code.push(Line::Query(put_constant!(Level::Shallow,
+                                                    c.clone(),
+                                                    temp_v!(1))));
 
                 if use_default_call_policy {
                     code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1))))
@@ -490,7 +510,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                                              term_loc, &mut target);
 
                         if !target.is_empty() {
-                            code.push(Line::Query(target));
+                            for query_instr in target {
+                                code.push(Line::Query(query_instr));
+                            }
                         }
 
                         code.push(get_level_and_unify!(cell.get().norm()));
@@ -574,7 +596,10 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
 
         if !fact.is_empty() {
             unsafe_var_marker = self.mark_unsafe_fact_vars(&mut fact);
-            code.push(Line::Fact(fact));
+
+            for fact_instr in fact {
+                code.push(Line::Fact(fact_instr));
+            }
         }
 
         let iter = ChunkedIterator::from_rule_body(p1, clauses);
@@ -637,7 +662,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
             self.mark_unsafe_fact_vars(&mut compiled_fact);
 
             if !compiled_fact.is_empty() {
-                code.push(Line::Fact(compiled_fact));
+                for fact_instr in compiled_fact {
+                    code.push(Line::Fact(fact_instr));
+                }
             }
         }
 
@@ -654,7 +681,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
         let query = self.compile_target(iter, term_loc, is_exposed);
 
         if !query.is_empty() {
-            code.push(Line::Query(query));
+            for query_instr in query {
+                code.push(Line::Query(query_instr));
+            }
         }
 
         Self::add_conditional_call(code, term, num_perm_vars_left);
index 49c1f491deee0ce42ba347bf1a59af26048055a2..0c8053454a9c602f777abb3a522fde7c75d202aa 100644 (file)
@@ -18,10 +18,8 @@ fn print_code(code: &Code) {
         match clause {
             &Line::Arithmetic(ref arith) =>
                 println!("{}", arith),
-            &Line::Fact(ref fact) =>
-                for fact_instr in fact {
-                    println!("{}", fact_instr);
-                },
+            &Line::Fact(ref fact_instr) =>
+                println!("{}", fact_instr),
             &Line::Cut(ref cut) =>
                 println!("{}", cut),
             &Line::Choice(ref choice) =>
@@ -32,10 +30,8 @@ fn print_code(code: &Code) {
                 println!("{}", choice),
             &Line::Indexing(ref indexing) =>
                 println!("{}", indexing),
-            &Line::Query(ref query) =>
-                for query_instr in query {
-                    println!("{}", query_instr);
-                }
+            &Line::Query(ref query_instr) =>
+                println!("{}", query_instr)
         }
     }
 }
@@ -122,7 +118,7 @@ fn compile_query(terms: Vec<QueryTerm>, queue: VecDeque<TopLevel>, flags: Machin
     let mut code = try!(cg.compile_query(&terms));
 
     compile_appendix(&mut code, &queue, false, flags)?;
-    
+
     Ok((code, cg.take_vars()))
 }
 
@@ -147,9 +143,9 @@ pub fn compile_term(wam: &mut Machine, packet: TopLevelPacket) -> EvalSession
                 Err(e) => EvalSession::from(e)
             },
         TopLevelPacket::Decl(TopLevel::Declaration(decl), _) => {
-            let mut compiler = ListingCompiler::new(&wam.code_repo);
-
+            let mut compiler = ListingCompiler::new(&wam.code_repo, wam.code_size());
             let indices = try_eval_session!(compile_decl(wam, &mut compiler, decl));
+
             try_eval_session!(compiler.add_code(wam, vec![], indices));
 
             EvalSession::EntrySuccess
@@ -166,6 +162,7 @@ struct GatherResult {
 }
 
 pub struct ListingCompiler {
+    code_size_offset: usize,
     non_counted_bt_preds: HashSet<PredicateKey>,
     module: Option<Module>,
     user_term_dir: TermDir,
@@ -175,9 +172,11 @@ pub struct ListingCompiler {
 
 impl ListingCompiler {
     #[inline]
-    pub fn new(code_repo: &CodeRepo) -> Self {
+    pub fn new(code_repo: &CodeRepo, code_size_offset: usize) -> Self {
         ListingCompiler {
-            module: None, non_counted_bt_preds: HashSet::new(),
+            code_size_offset,
+            non_counted_bt_preds: HashSet::new(),
+            module: None,
             user_term_dir: TermDir::new(),
             orig_term_expansion_lens: code_repo.term_dir_entry_len((clause_name!("term_expansion"), 2)),
             orig_goal_expansion_lens: code_repo.term_dir_entry_len((clause_name!("goal_expansion"), 2)),
@@ -239,8 +238,8 @@ impl ListingCompiler {
             .unwrap_or(ClauseName::BuiltIn("user"))
     }
 
-    fn generate_code(&mut self, decls: Vec<PredicateCompileQueue>,
-                     wam: &Machine, code_dir: &mut CodeDir)
+    fn generate_code(&mut self, decls: Vec<PredicateCompileQueue>, wam: &Machine,
+                     code_dir: &mut CodeDir)
                      -> Result<Code, SessionError>
     {
         let mut code = vec![];
@@ -250,10 +249,10 @@ impl ListingCompiler {
                 let arity = cl.arity();
                 cl.name().map(|name| (name, arity))
             }).ok_or(SessionError::NamelessEntry)?;
-            
+
             let non_counted_bt = self.non_counted_bt_preds.contains(&(name.clone(), arity));
 
-            let p = code.len() + wam.code_size();                                    
+            let p = code.len() + self.code_size_offset;
             let mut decl_code = compile_relation(&TopLevel::Predicate(decl), non_counted_bt,
                                                  wam.machine_flags())?;
 
@@ -346,7 +345,7 @@ impl ListingCompiler {
                 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) =>                
+            Declaration::UseModule(name) =>
                 self.use_module(name, code_repo, flags, wam_indices, indices),
             Declaration::UseQualifiedModule(name, exports) =>
                 self.use_qualified_module(name, code_repo, flags, &exports, wam_indices, indices),
@@ -382,11 +381,9 @@ impl ListingCompiler {
                              -> Result<GatherResult, SessionError>
     {
         let flags = wam.machine_flags();
-        let wam_indices = &mut wam.indices;
-
-        let atom_tbl   = 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.indices, &mut wam.policies,
                                                   &mut wam.code_repo);
 
         let mut toplevel_results = vec![];
@@ -463,10 +460,24 @@ fn compile_work<R: Read>(compiler: &mut ListingCompiler, wam: &mut Machine, src:
     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>(wam: &mut Machine, src: R) -> Result<Code, SessionError>
+{
+    let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
+    setup_indices(wam, &mut indices)?;
+
+    let mut compiler = ListingCompiler::new(&wam.code_repo, 0);
+    let results = compiler.gather_items(wam, src, &mut indices)?;
+
+    compiler.generate_code(results.worker_results, wam, &mut indices.code_dir)
+}
+
 #[inline]
 pub fn compile_listing<R: Read>(wam: &mut Machine, src: R, indices: IndexStore) -> EvalSession
 {
-    let mut compiler = ListingCompiler::new(&wam.code_repo);
+    let mut compiler = ListingCompiler::new(&wam.code_repo, wam.code_size());
 
     match compile_work(&mut compiler, wam, src, indices) {
         EvalSession::Error(e) => EvalSession::Error(compiler.drop_expansions(wam, e)),
@@ -488,6 +499,6 @@ fn setup_indices(wam: &mut Machine, indices: &mut IndexStore) -> Result<(), Sess
 
 pub fn compile_user_module<R: Read>(wam: &mut Machine, src: R) -> EvalSession {
     let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
-    try_eval_session!(setup_indices(wam, &mut indices));    
+    try_eval_session!(setup_indices(wam, &mut indices));
     compile_listing(wam, src, indices)
 }
index 71805c5c58d570f2bc432d6cc44ee4f8b8e9c2c1..34d3c4a6a9d780cb52e87c9803c9d05638df8efb 100644 (file)
@@ -197,42 +197,38 @@ impl UnsafeVarMarker {
         }
     }
 
-    pub fn mark_safe_vars(&mut self, query: &mut CompiledQuery) {
-        for query_instr in query.iter_mut() {
-            match query_instr {
-                &mut QueryInstruction::PutVariable(RegType::Temp(r), _) =>
-                    if let Some(found) = self.unsafe_vars.get_mut(&RegType::Temp(r)) {
-                        *found = true;
-                    },
-                &mut QueryInstruction::SetVariable(reg) =>
-                    if let Some(found) = self.unsafe_vars.get_mut(&reg) {
-                        *found = true;
-                    },
-                _ => {}
-            }
+    pub fn mark_safe_vars(&mut self, query_instr: &mut QueryInstruction) {
+        match query_instr {
+            &mut QueryInstruction::PutVariable(RegType::Temp(r), _) =>
+                if let Some(found) = self.unsafe_vars.get_mut(&RegType::Temp(r)) {
+                    *found = true;
+                },
+            &mut QueryInstruction::SetVariable(reg) =>
+                if let Some(found) = self.unsafe_vars.get_mut(&reg) {
+                    *found = true;
+                },
+            _ => {}
         }
     }
 
-    pub fn mark_unsafe_vars(&mut self, query: &mut CompiledQuery)
+    pub fn mark_unsafe_vars(&mut self, query_instr: &mut QueryInstruction)
     {
-        for query_instr in query.iter_mut() {
-            match query_instr {
-                &mut QueryInstruction::PutValue(RegType::Perm(i), arg) =>
-                    if let Some(found) = self.unsafe_vars.get_mut(&RegType::Perm(i)) {
-                        if !*found {
-                            *found = true;
-                            *query_instr = QueryInstruction::PutUnsafeValue(i, arg);
-                        }
-                    },
-                &mut QueryInstruction::SetValue(reg) =>
-                    if let Some(found) = self.unsafe_vars.get_mut(&reg) {
-                        if !*found {
-                            *found = true;
-                            *query_instr = QueryInstruction::SetLocalValue(reg);
-                        }
-                    },
-                _ => {}
-            };
+        match query_instr {
+            &mut QueryInstruction::PutValue(RegType::Perm(i), arg) =>
+                if let Some(found) = self.unsafe_vars.get_mut(&RegType::Perm(i)) {
+                    if !*found {
+                        *found = true;
+                        *query_instr = QueryInstruction::PutUnsafeValue(i, arg);
+                    }
+                },
+            &mut QueryInstruction::SetValue(reg) =>
+                if let Some(found) = self.unsafe_vars.get_mut(&reg) {
+                    if !*found {
+                        *found = true;
+                        *query_instr = QueryInstruction::SetLocalValue(reg);
+                    }
+                },
+            _ => {}
         }
     }
 }
index 1cf717506ce669ad721ae1eee04ecabb69d57076..d56c1733475e3440fc51809a0e07e60e6ea53b09 100644 (file)
@@ -216,6 +216,7 @@ pub struct CodeRepo {
     pub(super) term_expanders: Code,
     pub(super) code: Code,
     pub(super) in_situ_code: Code,
+    pub(super) verify_attrs_code: Code,
     pub(super) term_dir: TermDir
 }
 
@@ -248,6 +249,7 @@ pub enum SystemClauseType {
     GetSCCCleaner,
     InstallSCCCleaner,
     InstallInferenceCounter,
+    ModuleOf,
     RemoveCallPolicyCheck,
     RemoveInferenceCounter,
     RestoreCutPolicy,
@@ -262,6 +264,7 @@ pub enum SystemClauseType {
     GetDoubleQuotes,
     InstallNewBlock,
     ResetBlock,
+    RestoreCodePtrFromSpecialFormCP,
     SetBall,
     SetCutPointByDefault(RegType),
     SetDoubleQuotes,
@@ -286,12 +289,10 @@ impl SystemClauseType {
             &SystemClauseType::GetDoubleQuotes => clause_name!("$get_double_quotes"),
             &SystemClauseType::GetSCCCleaner => clause_name!("$get_scc_cleaner"),
             &SystemClauseType::InstallSCCCleaner => clause_name!("$install_scc_cleaner"),
-            &SystemClauseType::InstallInferenceCounter =>
-                clause_name!("$install_inference_counter"),
-            &SystemClauseType::RemoveCallPolicyCheck =>
-                clause_name!("$remove_call_policy_check"),
-            &SystemClauseType::RemoveInferenceCounter =>
-                clause_name!("$remove_inference_counter"),
+            &SystemClauseType::InstallInferenceCounter => clause_name!("$install_inference_counter"),
+            &SystemClauseType::ModuleOf => clause_name!("$module_of"),
+            &SystemClauseType::RemoveCallPolicyCheck => clause_name!("$remove_call_policy_check"),
+            &SystemClauseType::RemoveInferenceCounter => clause_name!("$remove_inference_counter"),
             &SystemClauseType::RestoreCutPolicy => clause_name!("$restore_cut_policy"),
             &SystemClauseType::SetCutPoint(_) => clause_name!("$set_cp"),
             &SystemClauseType::InferenceLevel => clause_name!("$inference_level"),
@@ -303,6 +304,7 @@ impl SystemClauseType {
             &SystemClauseType::GetCurrentBlock => clause_name!("$get_current_block"),
             &SystemClauseType::InstallNewBlock => clause_name!("$install_new_block"),
             &SystemClauseType::ResetBlock => clause_name!("$reset_block"),
+            &SystemClauseType::RestoreCodePtrFromSpecialFormCP => clause_name!("$restore_p_from_sfcp"),
             &SystemClauseType::SetBall => clause_name!("$set_ball"),
             &SystemClauseType::SetCutPointByDefault(_) => clause_name!("$set_cp_by_default"),
             &SystemClauseType::SetDoubleQuotes => clause_name!("$set_double_quotes"),
@@ -326,14 +328,11 @@ impl SystemClauseType {
             ("$get_b_value", 1) => Some(SystemClauseType::GetBValue),
             ("$get_double_quotes", 1) => Some(SystemClauseType::GetDoubleQuotes),
             ("$get_scc_cleaner", 1) => Some(SystemClauseType::GetSCCCleaner),
-            ("$install_scc_cleaner", 2) =>
-                Some(SystemClauseType::InstallSCCCleaner),
-            ("$install_inference_counter", 3) =>
-                Some(SystemClauseType::InstallInferenceCounter),
-            ("$remove_call_policy_check", 1) =>
-                Some(SystemClauseType::RemoveCallPolicyCheck),
-            ("$remove_inference_counter", 2) =>
-                Some(SystemClauseType::RemoveInferenceCounter),
+            ("$install_scc_cleaner", 2) => Some(SystemClauseType::InstallSCCCleaner),
+            ("$install_inference_counter", 3) => Some(SystemClauseType::InstallInferenceCounter),
+            ("$module_of", 2) => Some(SystemClauseType::ModuleOf),
+            ("$remove_call_policy_check", 1) => Some(SystemClauseType::RemoveCallPolicyCheck),
+            ("$remove_inference_counter", 2) => Some(SystemClauseType::RemoveInferenceCounter),
             ("$restore_cut_policy", 0) => Some(SystemClauseType::RestoreCutPolicy),
             ("$set_cp", 1) => Some(SystemClauseType::SetCutPoint(temp_v!(1))),
             ("$inference_level", 2) => Some(SystemClauseType::InferenceLevel),
@@ -345,6 +344,7 @@ impl SystemClauseType {
             ("$get_cp", 1) => Some(SystemClauseType::GetCutPoint),
             ("$install_new_block", 1) => Some(SystemClauseType::InstallNewBlock),
             ("$reset_block", 1) => Some(SystemClauseType::ResetBlock),
+            ("$restore_p_from_sfcp", 0) => Some(SystemClauseType::RestoreCodePtrFromSpecialFormCP),
             ("$set_ball", 1) => Some(SystemClauseType::SetBall),
             ("$set_cp_by_default", 1) => Some(SystemClauseType::SetCutPointByDefault(temp_v!(1))),
             ("$set_double_quotes", 1) => Some(SystemClauseType::SetDoubleQuotes),
@@ -696,17 +696,15 @@ pub enum QueryInstruction {
 
 pub type CompiledFact = Vec<FactInstruction>;
 
-pub type CompiledQuery = Vec<QueryInstruction>;
-
 pub enum Line {
     Arithmetic(ArithmeticInstruction),
     Choice(ChoiceInstruction),
     Control(ControlInstruction),
     Cut(CutInstruction),
-    Fact(CompiledFact),
+    Fact(FactInstruction),
     Indexing(IndexingInstruction),
     IndexedChoice(IndexedChoiceInstruction),
-    Query(CompiledQuery)
+    Query(QueryInstruction)
 }
 
 pub type ThirdLevelIndex = Vec<IndexedChoiceInstruction>;
index efecc20da08bac748102c79b4a05b3aaacf6e930..90ce7731a8aa9a8680d32b383b2375720adea787 100644 (file)
@@ -206,6 +206,7 @@ pub struct MachineState {
     pub(super) e: usize,
     pub(super) num_of_args: usize,
     pub(super) cp: LocalCodePtr,
+    pub(super) special_form_cp: CodePtr,
     pub(super) fail: bool,
     pub(crate) heap: Heap,
     pub(super) mode: MachineMode,
index 0743b062e1f6997abdf5b56821a5b9fbf8d53151..13d7143bf7874ea156e4c58a1873fb269672d70c 100644 (file)
@@ -40,6 +40,7 @@ impl MachineState {
             e: 0,
             num_of_args: 0,
             cp: LocalCodePtr::default(),
+            special_form_cp: CodePtr::default(),
             fail: false,
             heap: Heap::with_capacity(256),
             mode: MachineMode::Write,
@@ -2363,6 +2364,7 @@ impl MachineState {
         self.pstr_tr = 0;
         self.p = CodePtr::default();
         self.cp = LocalCodePtr::default();
+        self.special_form_cp = CodePtr::default();
         self.num_of_args = 0;
 
         self.fail = false;
index 1b8ca01a7298195fa487b9e128c0ddac100b74b3..f9f185f9ae23c808bbb472db6b296a9aa6e83368 100644 (file)
@@ -7,6 +7,7 @@ use prolog::debray_allocator::*;
 use prolog::heap_print::*;
 use prolog::instructions::*;
 
+mod attributed_variables;
 mod machine_errors;
 pub(super) mod machine_state;
 pub(super) mod term_expansion;
@@ -14,6 +15,7 @@ pub(super) mod term_expansion;
 #[macro_use] mod machine_state_impl;
 mod system_calls;
 
+use prolog::machine::attributed_variables::*;
 use prolog::machine::machine_state::*;
 
 use std::collections::{HashMap, VecDeque};
@@ -21,8 +23,6 @@ use std::mem;
 use std::ops::Index;
 use std::rc::Rc;
 
-static BUILTINS: &str = include_str!("../lib/builtins.pl");
-
 pub type InSituCodeDir = HashMap<PredicateKey, usize>;
 
 pub struct IndexStore {
@@ -118,6 +118,7 @@ impl CodeRepo {
             term_expanders: Code::new(),
             code: Code::new(),
             in_situ_code: Code::new(),
+            verify_attrs_code: Code::new(),
             term_dir: TermDir::new()
         }
     }
@@ -308,15 +309,23 @@ impl SubModuleUser for IndexStore {
     }
 }
 
-static LISTS: &str   = include_str!("../lib/lists.pl");
-static CONTROL: &str = include_str!("../lib/control.pl");
-static QUEUES: &str  = include_str!("../lib/queues.pl");
-static ERROR: &str   = include_str!("../lib/error.pl");
-static TERMS: &str   = include_str!("../lib/terms.pl");
-static DCGS: &str    = include_str!("../lib/dcgs.pl");
-static ATTS: &str    = include_str!("../lib/atts.pl");
+static BUILTINS: &str = include_str!("../lib/builtins.pl");
+static LISTS: &str    = include_str!("../lib/lists.pl");
+static CONTROL: &str  = include_str!("../lib/control.pl");
+static QUEUES: &str   = include_str!("../lib/queues.pl");
+static ERROR: &str    = include_str!("../lib/error.pl");
+static TERMS: &str    = include_str!("../lib/terms.pl");
+static DCGS: &str     = include_str!("../lib/dcgs.pl");
+static ATTS: &str     = include_str!("../lib/atts.pl");
 
 impl Machine {
+    fn compile_special_forms(&mut self) {
+        match compile_special_form(self, VERIFY_ATTRS.as_bytes()) {
+            Ok(code) => self.code_repo.verify_attrs_code = code,
+            Err(_e)  => panic!("Machine::compile_special_forms() failed")
+        }
+    }
+
     pub fn new() -> Self {
         let mut wam = Machine {
             machine_st: MachineState::new(),
@@ -338,6 +347,7 @@ impl Machine {
         compile_user_module(&mut wam, DCGS.as_bytes());
         compile_user_module(&mut wam, ATTS.as_bytes());
 
+        wam.compile_special_forms();
         wam
     }
 
@@ -512,30 +522,16 @@ impl MachineState {
             &Line::Control(ref 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.fail {
-                        break;
-                    }
-
-                    self.execute_fact_instr(&fact_instr);
-                }
-
+            &Line::Fact(ref fact_instr) => {
+                self.execute_fact_instr(&fact_instr);
                 self.p += 1;
             },
             &Line::Indexing(ref indexing_instr) =>
                 self.execute_indexing_instr(&indexing_instr),
             &Line::IndexedChoice(ref choice_instr) =>
                 self.execute_indexed_choice_instr(choice_instr, &mut policies.call_policy),
-            &Line::Query(ref query) => {
-                for query_instr in query {
-                    if self.fail {
-                        break;
-                    }
-
-                    self.execute_query_instr(&query_instr);
-                }
-
+            &Line::Query(ref query_instr) => {
+                self.execute_query_instr(&query_instr);
                 self.p += 1;
             }
         }
index b6df24b88bfd6905d170f3e67179a1ddbfd26195..04772e986184697bbb23fae8568d51aa7fb70493 100644 (file)
@@ -375,6 +375,29 @@ impl MachineState {
                     }
                 };
             },
+            &SystemClauseType::ModuleOf => {
+                let module = self.store(self.deref(self[temp_v!(2)].clone()));
+
+                match module {
+                    Addr::Con(Constant::Atom(name, _)) => {
+                        let module = Addr::Con(Constant::Atom(name.owning_module(), None));
+                        let target = self[temp_v!(1)].clone();
+
+                        self.unify(target, module);
+                    },
+                    Addr::Str(s) =>
+                        match self.heap[s].clone() {
+                            HeapCellValue::NamedStr(_, name, ..) => {
+                                let module = Addr::Con(Constant::Atom(name.owning_module(), None));
+                                let target = self[temp_v!(1)].clone();
+
+                                self.unify(target, module);
+                            },
+                            _ => self.fail = true
+                        },
+                    _ => self.fail = true
+                };
+            },
             &SystemClauseType::RemoveCallPolicyCheck => {
                 let restore_default =
                     match call_policy.downcast_mut::<CWILCallPolicy>().ok() {
@@ -418,6 +441,10 @@ impl MachineState {
                     None => panic!("remove_inference_counter: requires \\
                                     CWILCallPolicy.")
                 },
+            &SystemClauseType::RestoreCodePtrFromSpecialFormCP => {
+                self.p = self.special_form_cp.clone();
+                return Ok(());
+            },
             &SystemClauseType::RestoreCutPolicy => {
                 let restore_default =
                     if let Ok(cut_policy) = cut_policy.downcast_ref::<SCCCutPolicy>() {
index 47f7a13155e0b4c16a387351152c4bf8dd63c43e..4a94c43bb0a7a94d8eb40e0de53a9f8723330226 100644 (file)
@@ -4,12 +4,6 @@ macro_rules! interm {
     )
 }
 
-macro_rules! query {
-    [$($x:expr),+] => (
-        Line::Query(vec![$($x),+])
-    )
-}
-
 macro_rules! heap_str {
     ($s:expr) => (
         HeapCellValue::Addr(Addr::Str($s))
index edafbe2d237882f82d18ed8c660f11a4bde5c48b..7730241aebe0d5622879bfcc2461da45204ce2e1 100644 (file)
@@ -814,8 +814,7 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
         Ok(result)
     }
 
-    pub
-    fn consume(&mut self, indices: &mut IndexStore) -> Result<Option<Declaration>, SessionError>
+    pub fn consume(&mut self, indices: &mut IndexStore) -> Result<Option<Declaration>, SessionError>
     {
         let mut preds = vec![];