]> Repositorios git - scryer-prolog.git/commitdiff
shift to builtins
authorMark Thom <[email protected]>
Wed, 9 May 2018 04:38:49 +0000 (22:38 -0600)
committerMark Thom <[email protected]>
Wed, 9 May 2018 04:38:49 +0000 (22:38 -0600)
src/main.rs
src/prolog/ast.rs
src/prolog/builtins.rs
src/prolog/io.rs
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/parser
src/prolog/toplevel.rs

index da05f8663f08c1dba18662a7218c38f9b8a7d8ab..1e4a7e29d173a3f1496bdd95d3c2441a5e3a1ea5 100644 (file)
@@ -1,6 +1,7 @@
 #[macro_use] extern crate downcast;
 extern crate termion;
 
+#[macro_use]
 mod prolog;
 
 use prolog::ast::*;
@@ -10,6 +11,7 @@ use prolog::machine::*;
 #[cfg(test)]
 mod tests;
 
+pub static BUILTINS: &str = include_str!("./prolog/lib/builtins.pl");
 pub static LISTS: &str   = include_str!("./prolog/lib/lists.pl");
 pub static CONTROL: &str = include_str!("./prolog/lib/control.pl");
 pub static QUEUES: &str = include_str!("./prolog/lib/queues.pl");
@@ -33,12 +35,19 @@ fn load_init_str(wam: &mut Machine, src_str: &str)
     }
 }
 
+fn load_init_str_and_include(wam: &mut Machine, src_str: &str, module: &'static str)
+{
+    load_init_str(wam, src_str);
+    wam.use_module_in_toplevel(clause_name!(module));
+}
+
 fn prolog_repl() {
     let mut wam = Machine::new();
 
-    load_init_str(&mut wam, LISTS);
-    load_init_str(&mut wam, CONTROL);
-    load_init_str(&mut wam, QUEUES);
+    load_init_str_and_include(&mut wam, BUILTINS, "builtins");
+//    load_init_str(&mut wam, LISTS);
+//    load_init_str(&mut wam, CONTROL);
+//    load_init_str(&mut wam, QUEUES);
 
     loop {
         print!("prolog> ");
index d3dcfc2c1f6bc22bbff0385ddff2fe1b7854ec6d..969c587d3b8d03c244b4178d9f0e524e853b4329 100644 (file)
@@ -192,11 +192,13 @@ pub trait SubModuleUser {
     // returns true on successful import.
     fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) -> bool {
         let name = name.defrock_brackets();
-
+        let mut found_op = false;
+        
         {
             let mut insert_op_dir = |fix| {
                 if let Some(op_data) = submodule.op_dir.get(&(name.clone(), fix)) {
                     self.op_dir().insert((name.clone(), fix), op_data.clone());
+                    found_op = true;
                 }
             };
 
@@ -212,7 +214,7 @@ pub trait SubModuleUser {
             self.insert_dir_entry(name, arity, code_data.clone());
             true
         } else {
-            false
+            found_op
         }
     }
 
@@ -227,7 +229,7 @@ pub trait SubModuleUser {
                 return EvalSession::from(SessionError::ModuleDoesNotContainExport);
             }
         }
-
+        
         EvalSession::EntrySuccess
     }
 
@@ -594,7 +596,7 @@ impl InlinedClauseType {
             (">", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThan)),
             ("<", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThan)),
             (">=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThanOrEqual)),
-            ("<=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThanOrEqual)),
+            ("=<", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThanOrEqual)),
             ("=\\=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::NotEqual)),
             ("=:=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::Equal)),
             ("atom", 1) => Some(InlinedClauseType::IsAtom),
@@ -808,14 +810,14 @@ impl ClauseType {
 
     pub fn name(&self) -> ClauseName {
         match self {
-            &ClauseType::AcyclicTerm => clause_name!("$acyclic_term"),
+            &ClauseType::AcyclicTerm => clause_name!("acyclic_term"),
             &ClauseType::Arg => clause_name!("arg"),
             &ClauseType::CallN => clause_name!("call"),
             &ClauseType::CallWithInferenceLimit => clause_name!("call_with_inference_limit"),
             &ClauseType::Catch => clause_name!("catch"),
             &ClauseType::Compare => clause_name!("compare"),
             &ClauseType::CompareTerm(qt) => clause_name!(qt.name()),
-            &ClauseType::CyclicTerm => clause_name!("$cyclic_term"),
+            &ClauseType::CyclicTerm => clause_name!("cyclic_term"),
             &ClauseType::Display => clause_name!("display"),
             &ClauseType::DuplicateTerm => clause_name!("duplicate_term"),
             &ClauseType::Eq => clause_name!("=="),
@@ -823,26 +825,30 @@ impl ClauseType {
             &ClauseType::Ground  => clause_name!("ground"),
             &ClauseType::Inlined(inlined) => clause_name!(inlined.name()),
             &ClauseType::Is => clause_name!("is"),
-            &ClauseType::KeySort => clause_name!("$keysort"),
+            &ClauseType::KeySort => clause_name!("keysort"),
             &ClauseType::NotEq => clause_name!("\\=="),
             &ClauseType::Op(ref name, ..) => name.clone(),
             &ClauseType::Named(ref name, ..) => name.clone(),
             &ClauseType::SetupCallCleanup => clause_name!("setup_call_cleanup"),
             &ClauseType::System(ref system) => system.name(),
-            &ClauseType::Sort => clause_name!("$sort"),
+            &ClauseType::Sort => clause_name!("sort"),
             &ClauseType::Throw => clause_name!("throw")
         }
     }
 
     pub fn from(name: ClauseName, arity: usize, fixity: Option<Fixity>) -> Self {
+        if let Some(inlined_ct) = InlinedClauseType::from(name.as_str(), arity) {
+            return ClauseType::Inlined(inlined_ct);
+        }
+        
         match (name.as_str(), arity) {
-            ("$acyclic_term", 1) => ClauseType::AcyclicTerm,
+            ("acyclic_term", 1) => ClauseType::AcyclicTerm,
             ("arg", 3)   => ClauseType::Arg,
             ("call", _)  => ClauseType::CallN,
             ("call_with_inference_limit", 3) => ClauseType::CallWithInferenceLimit,
             ("catch", 3) => ClauseType::Catch,
             ("compare", 3) => ClauseType::Compare,
-            ("$cyclic_term", 1) => ClauseType::CyclicTerm,
+            ("cyclic_term", 1) => ClauseType::CyclicTerm,
             ("@>", 2) => ClauseType::CompareTerm(CompareTermQT::GreaterThan),
             ("@<", 2) => ClauseType::CompareTerm(CompareTermQT::LessThan),
             ("@>=", 2) => ClauseType::CompareTerm(CompareTermQT::GreaterThanOrEqual),
@@ -855,10 +861,10 @@ impl ClauseType {
             ("functor", 3) => ClauseType::Functor,
             ("ground", 1) => ClauseType::Ground,
             ("is", 2) => ClauseType::Is,
-            ("$keysort", 2) => ClauseType::KeySort,
+            ("keysort", 2) => ClauseType::KeySort,
             ("\\==", 2) => ClauseType::NotEq,
             ("setup_call_cleanup", 3) => ClauseType::SetupCallCleanup,            
-            ("$sort", 2) => ClauseType::Sort,
+            ("sort", 2) => ClauseType::Sort,
             ("throw", 1) => ClauseType::Throw,
             _ => if let Some(fixity) = fixity {
                 ClauseType::Op(name, fixity, CodeIndex::default())
index 6633904c4d052ead6cc9ae5418ffff035b5aa9c5..0222ecf72a9992e2d6215951a0255668e886749a 100644 (file)
@@ -739,17 +739,17 @@ fn get_builtins() -> Code {
     ]
 }
 
-pub fn build_code_and_op_dirs() -> (CodeDir, OpDir)
+pub fn default_op_dir() -> OpDir
 {
-    let mut code_dir = HashMap::new();
-    let mut op_dir   = HashMap::new();
-
-    let builtin = ClauseName::BuiltIn("builtin");
-
-    op_dir.insert((clause_name!(":-"), Fixity::In),   (XFX, 1200, builtin.clone()));
-    op_dir.insert((clause_name!(":-"), Fixity::Pre),  (FX, 1200, builtin.clone()));
-    op_dir.insert((clause_name!("?-"), Fixity::Pre),  (FX, 1200, builtin.clone()));
-
+    let mut op_dir = HashMap::new();    
+    let module_name = clause_name!("builtins");
+    
+    op_dir.insert((clause_name!(":-"), Fixity::In),  (XFX, 1200, module_name.clone()));
+    op_dir.insert((clause_name!(":-"), Fixity::Pre), (FX, 1200, module_name.clone()));
+    op_dir.insert((clause_name!("?-"), Fixity::Pre), (FX, 1200, module_name.clone()));    
+    // op_dir.insert((clause_name!("/"), Fixity::In), (YFX, 400, module_name.clone()));
+    
+/*
     // control operators.
     op_dir.insert((clause_name!("\\+"), Fixity::Pre), (FY, 900, builtin.clone()));
     op_dir.insert((clause_name!("="), Fixity::In), (XFX, 700, builtin.clone()));
@@ -761,8 +761,7 @@ pub fn build_code_and_op_dirs() -> (CodeDir, OpDir)
     op_dir.insert((clause_name!("/\\"), Fixity::In), (YFX, 500, builtin.clone()));
     op_dir.insert((clause_name!("\\/"), Fixity::In), (YFX, 500, builtin.clone()));
     op_dir.insert((clause_name!("xor"), Fixity::In), (YFX, 500, builtin.clone()));
-    op_dir.insert((clause_name!("//"), Fixity::In), (YFX, 400, builtin.clone()));
-    op_dir.insert((clause_name!("/"), Fixity::In), (YFX, 400, builtin.clone()));
+    op_dir.insert((clause_name!("//"), Fixity::In), (YFX, 400, builtin.clone()));    
     op_dir.insert((clause_name!("div"), Fixity::In), (YFX, 400, builtin.clone()));
     op_dir.insert((clause_name!("*"), Fixity::In), (YFX, 400, builtin.clone()));
     op_dir.insert((clause_name!("-"), Fixity::Pre), (FY, 200, builtin.clone()));
@@ -819,7 +818,7 @@ pub fn build_code_and_op_dirs() -> (CodeDir, OpDir)
     code_dir.insert((clause_name!("integer"), 1), CodeIndex::from((163, builtin.clone())));
     code_dir.insert((clause_name!("display"), 1), CodeIndex::from((208, builtin.clone())));
 
-    code_dir.insert((clause_name!("is"), 2), CodeIndex::from((210, builtin.clone())));
+    //code_dir.insert((clause_name!("is"), 2), CodeIndex::from((210, builtin.clone())));
     code_dir.insert((clause_name!(">"), 2), CodeIndex::from((212, builtin.clone())));
     code_dir.insert((clause_name!("<"), 2), CodeIndex::from((214, builtin.clone())));
     code_dir.insert((clause_name!(">="), 2), CodeIndex::from((216, builtin.clone())));
@@ -851,14 +850,13 @@ pub fn build_code_and_op_dirs() -> (CodeDir, OpDir)
     code_dir.insert((clause_name!("\\=@="), 2), CodeIndex::from((408, builtin.clone())));
     code_dir.insert((clause_name!("compare"), 3), CodeIndex::from((480, builtin.clone())));
     code_dir.insert((clause_name!("atom"), 1), CodeIndex::from((481, builtin.clone())));
-    code_dir.insert((clause_name!("sort"), 2), CodeIndex::from((483, builtin.clone())));
-    code_dir.insert((clause_name!("keysort"), 2), CodeIndex::from((484, builtin.clone())));
-    code_dir.insert((clause_name!("acyclic_term"), 1), CodeIndex::from((485, builtin.clone())));
-    code_dir.insert((clause_name!("cyclic_term"), 1), CodeIndex::from((486, builtin.clone())));
     
     (code_dir, op_dir)
+     */
+    op_dir
 }
 
+/*
 pub fn default_build() -> (Code, CodeDir, OpDir)
 {
     let builtin_code = get_builtins();
@@ -866,64 +864,4 @@ pub fn default_build() -> (Code, CodeDir, OpDir)
 
     (builtin_code, code_dir, op_dir)
 }
-
-#[allow(dead_code)]
-pub fn builtin_module() -> Module
-{
-    let (code_dir, op_dir) = build_code_and_op_dirs();
-    let mut module_decl = module_decl!(clause_name!("builtin"),
-                                       vec![(clause_name!("atomic"), 1),
-                                            (clause_name!("var"), 1),
-                                            (clause_name!("false"), 0),
-                                            (clause_name!("catch"), 3),
-                                            (clause_name!("throw"), 1),
-                                            (clause_name!("(\\+)"), 1),
-                                            (clause_name!("duplicate_term"), 2),
-                                            (clause_name!("(=)"), 2),
-                                            (clause_name!("true"), 0),
-                                            (clause_name!("(,)"), 2),
-                                            (clause_name!("(;)"), 2),
-                                            (clause_name!("->"), 2),
-                                            (clause_name!("functor"), 3),
-                                            (clause_name!("arg"), 3),
-                                            (clause_name!("(=..)"), 3),
-                                            (clause_name!("display"), 1),
-                                            (clause_name!("is"), 2),
-                                            (clause_name!("(>)"), 2),
-                                            (clause_name!("(<)"), 2),
-                                            (clause_name!("(>=)"), 2),
-                                            (clause_name!("(=<)"), 2),
-                                            (clause_name!("(=\\=)"), 2),
-                                            (clause_name!("(=:=)"), 2),
-                                            (clause_name!("(@>)"), 2),
-                                            (clause_name!("(@<)"), 2),
-                                            (clause_name!("(@>=)"), 2),
-                                            (clause_name!("(@=<)"), 2),
-                                            (clause_name!("(=@=)"), 2),
-                                            (clause_name!("(\\=@=)"), 2),
-                                            (clause_name!("(==)"), 2),
-                                            (clause_name!("(\\==)"), 2),
-                                            (clause_name!("length"), 2),
-                                            (clause_name!("compound"), 1),
-                                            (clause_name!("rational"), 1),
-                                            (clause_name!("integer"), 1),
-                                            (clause_name!("string"), 1),
-                                            (clause_name!("float"), 1),
-                                            (clause_name!("nonvar"), 1),
-                                            (clause_name!("ground"), 1),
-                                            (clause_name!("setup_call_cleanup"), 3),
-                                            (clause_name!("call_with_inference_limit"), 3),
-                                            (clause_name!("compare"), 3),
-                                            (clause_name!("atom"), 1),
-                                            (clause_name!("sort"), 2),
-                                            (clause_name!("keysort"), 2),
-                                            (clause_name!("acyclic_term"), 1),
-                                            (clause_name!("cyclic_term"), 1),
-                                            (clause_name!("$skip_max_list"), 4)]);
-
-    for arity in 0 .. 63 {
-        module_decl.exports.push((clause_name!("call"), arity));
-    }
-
-    Module { module_decl, code_dir: as_module_code_dir(code_dir), op_dir }
-}
+*/
index e51635d35cf2c6b55d73cfe1586e478361cc568b..eceacfa18d75b011f30336f469ac6bb34cb3b292 100644 (file)
@@ -550,7 +550,7 @@ fn compile_query(terms: Vec<QueryTerm>, queue: Vec<TopLevel>, code_size: usize,
     let mut code = try!(cg.compile_query(&terms));
 
     compile_appendix(&mut code, queue)?;
-
+    
     let query_info = QueryInfo {};
     query_info.label_clauses(code_size, code_dir, &mut code);
 
@@ -617,7 +617,9 @@ pub fn compile_listing(wam: &mut Machine, src_str: &str) -> EvalSession
     }
 
     let mut module: Option<Module> = None;
-    let (mut code_dir, mut op_dir) = build_code_and_op_dirs();
+    
+    let mut code_dir = CodeDir::new();
+    let mut op_dir   = default_op_dir();
 
     let mut code = Vec::new();
 
@@ -630,10 +632,10 @@ pub fn compile_listing(wam: &mut Machine, src_str: &str) -> EvalSession
                 return EvalSession::from(ParserError::ExpectedRel),
             TopLevelPacket::Decl(TopLevel::Declaration(Declaration::Module(module_decl)), _) =>
                 if module.is_none() {
-                    let (builtin_code_dir, builtin_op_dir) = build_code_and_op_dirs();
+                    // let builtin_op_dir = default_module_setup(module_decl.name.clone());
 
-                    code_dir.extend(builtin_code_dir.into_iter());
-                    op_dir.extend(builtin_op_dir.into_iter());
+                    // code_dir.extend(builtin_code_dir.into_iter());
+                    // op_dir.extend(builtin_op_dir.into_iter());
 
                     module = Some(Module::new(module_decl));
                 } else {
index e16111d8b470bf69456c27893c29d7acf6a4a46f..984cf4d2d8a3e06e808a40e69b1c1311b661f318 100644 (file)
@@ -141,6 +141,8 @@ impl MachineState {
         self.heap.append(err);
 
         self.registers[1] = Addr::HeapCell(h);
-        self.goto_throw();
+
+        self.set_ball();
+        self.unwind_stack();       
     }
 }
index 90b80afcd37d5837e521cdb8a47d38183ad33ae9..f9dad13e7109306edd8ca0c4ec97783fa7e8a290 100644 (file)
@@ -434,10 +434,16 @@ pub(crate) trait CallPolicy: Any {
             },
             &ClauseType::CallN =>
                 if let Some((name, arity)) = machine_st.setup_call_n(arity) {
-                    if let Some(idx) = code_dirs.get(name.clone(), arity, clause_name!("user")) {
-                        self.context_call(machine_st, name, arity, idx, lco)
-                    } else {
-                        Err(machine_st.existence_error(name, arity))
+                    let user = clause_name!("user");
+                    
+                    match ClauseType::from(name.clone(), arity, None) {
+                        ClauseType::Op(..) | ClauseType::Named(..) =>
+                            if let Some(idx) = code_dirs.get(name.clone(), arity, user) {
+                                self.context_call(machine_st, name, arity, idx, lco)
+                            } else {
+                                Err(machine_st.existence_error(name, arity))
+                            },
+                        ct => self.try_call_clause(machine_st, code_dirs, &ct, arity, lco),
                     }
                 } else {
                     Ok(())
index 35534955e754897de86425b44746a61ec5969586..5665eea29b0332f04c7d4f18fbcccf44d26f9cce 100644 (file)
@@ -1041,7 +1041,15 @@ impl MachineState {
         self.p  = CodePtr::DirEntry(59, clause_name!("builtin"));
     }
 
-    fn unwind_stack(&mut self) {
+    pub(super) fn set_ball(&mut self) {
+        let addr = self[temp_v!(1)].clone();
+        self.ball.boundary = self.heap.h;
+             
+        let mut duplicator = DuplicateBallTerm::new(self);
+        duplicator.duplicate_term(addr);        
+    }
+    
+    pub(super) fn unwind_stack(&mut self) {
         self.b = self.block;
         self.or_stack.truncate(self.b);
 
@@ -1614,14 +1622,7 @@ impl MachineState {
                 self.p += 1;
             },
             &BuiltInInstruction::SetBall => {
-                let addr = self[temp_v!(1)].clone();
-                self.ball.boundary = self.heap.h;
-
-                {
-                    let mut duplicator = DuplicateBallTerm::new(self);
-                    duplicator.duplicate_term(addr);
-                };
-
+                self.set_ball();
                 self.p += 1;
             },
             &BuiltInInstruction::SetCutPoint(r) =>
index 5df7085c8e869658c5e5afa84cb21defa38e5631..5377949e57d9bd05eb7031365bb55bafad8b130c 100644 (file)
@@ -70,14 +70,15 @@ impl<'a> SubModuleUser for MachineCodeIndex<'a> {
 impl Machine {
     pub fn new() -> Self {
         let atom_tbl = Rc::new(RefCell::new(HashSet::new()));
-        let (code, code_dir, op_dir) = default_build();
+        let op_dir = default_op_dir(); //TODO: change to the builtins module once it's done.
+        //let (code, code_dir, op_dir) = default_build();
 
         Machine {
             ms: MachineState::new(atom_tbl),
             call_policy: Box::new(DefaultCallPolicy {}),
             cut_policy: Box::new(DefaultCutPolicy {}),
-            code,
-            code_dir,
+            code: Code::new(),
+            code_dir: CodeDir::new(),
             term_dir: TermDir::new(),
             op_dir,
             modules: HashMap::new(),
index 1b3bcc77f2b9d264c9753653ae87bfa3b4c11081..51e38dd24252431432ec7deb5ad80e2fc11a5753 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 1b3bcc77f2b9d264c9753653ae87bfa3b4c11081
+Subproject commit 51e38dd24252431432ec7deb5ad80e2fc11a5753
index abab06881958a2d6e823c005beaeb626a93346e3..3c122dfc744dea77358c71131f11cdd4f99d0bac 100644 (file)
@@ -393,17 +393,13 @@ impl RelationWorker {
                 if name.as_str() == "!" || name.as_str() == "blocked_!" {
                     Ok(QueryTerm::BlockedCut)
                 } else {
-                    Ok(QueryTerm::Clause(r, ClauseType::Named(name, CodeIndex::default()),
-                                         vec![]))
+                    Ok(QueryTerm::Clause(r, ClauseType::Named(name, CodeIndex::default()), vec![]))
                 },
             Term::Var(_, ref v) if v.as_str() == "!" =>
                 Ok(QueryTerm::UnblockedCut(Cell::default())),
             Term::Clause(r, name, mut terms, fixity) =>
                 if let Some(system_ct) = SystemClauseType::from(name.as_str(), terms.len()) {
                     Ok(QueryTerm::Clause(r, ClauseType::System(system_ct), terms))
-                }
-                else if let Some(inlined_ct) = InlinedClauseType::from(name.as_str(), terms.len()) {
-                    Ok(QueryTerm::Clause(r, ClauseType::Inlined(inlined_ct), terms))
                 } else if name.as_str() == ";" {
                     if terms.len() == 2 {
                         let term = Term::Clause(r, name.clone(), terms, fixity);
@@ -612,7 +608,10 @@ impl<R: Read> TopLevelWorker<R> {
             };
         }
 
-        results.push(deque_to_packet(append_preds(&mut preds), rel_worker.parse_queue()?));
+        if !preds.is_empty() {
+            results.push(deque_to_packet(append_preds(&mut preds), rel_worker.parse_queue()?));
+        }
+        
         Ok(results)
     }