]> Repositorios git - scryer-prolog.git/commitdiff
term_expansion beginnings
authorMark Thom <[email protected]>
Sat, 22 Sep 2018 22:25:32 +0000 (16:25 -0600)
committerMark Thom <[email protected]>
Sat, 22 Sep 2018 22:25:32 +0000 (16:25 -0600)
Cargo.lock
Cargo.toml
src/prolog/compile.rs
src/prolog/instructions.rs
src/prolog/lib/builtins.pl
src/prolog/lib/numbervars.pl
src/prolog/machine/mod.rs
src/prolog/machine/system_calls.rs
src/prolog/machine/term_expansion.rs
src/prolog/read.rs
src/prolog/toplevel.rs

index 5053b63bc29dca0a40b6afa05c6066d62f50da7c..d46db9b5a4bf2d73f2342086b1346bd4fc264f24 100644 (file)
@@ -87,7 +87,6 @@ dependencies = [
 [[package]]
 name = "prolog_parser"
 version = "0.7.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -113,7 +112,7 @@ dependencies = [
  "downcast 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "prolog_parser 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "prolog_parser 0.7.14",
  "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -152,7 +151,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
 "checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
 "checksum ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f"
-"checksum prolog_parser 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "5a7a659f57a1c0e9c375a82cc224462dc1b7c259e645fcc283928ef38947b584"
 "checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
 "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
 "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
index 8fb7c224f1c2d92d7c8f279f3e837668888ba237..6fa9e632ea2b7441c4c60e5c84831fe2e8a04105 100644 (file)
@@ -10,7 +10,7 @@ license = "BSD-3-Clause"
 downcast = "0.9.1"
 num = "0.2"
 ordered-float = "0.5.0"
-prolog_parser = "0.7.14"
+prolog_parser = { path = "../prolog_parser", version = "0.7.14" }
 
 [dependencies.termion]
 version = "1.4.0"
\ No newline at end of file
index 4eaafc8a77317d6e99458a27085015d4445ced0f..557bb162537b54a0a71d0bf1c3d4d7544e5f0f59 100644 (file)
@@ -235,6 +235,8 @@ impl ListingCompiler {
                     -> Result<(), SessionError>
     {
         match decl {
+            Declaration::Hook(CompileTimeHook::TermExpansion, clause) =>
+                Ok(wam.add_term_expansion_clause(clause)?),
             Declaration::NonCountedBacktracking(name, arity) =>
                 Ok(self.add_non_counted_bt_flag(name, arity)),
             Declaration::Op(op_decl) =>
index 558154450f5888622419783c735694c619c77afa..b8267a5ca29a5c0239ff3251a6def3f4703896f4 100644 (file)
@@ -238,8 +238,7 @@ pub enum SystemClauseType {
     SetDoubleQuotes,
     SkipMaxList,
     Succeed,
-    UnwindStack,
-    CompileAndRunQuery
+    UnwindStack
 }
 
 impl SystemClauseType {
@@ -277,7 +276,6 @@ 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")
         }
     }
 
@@ -311,7 +309,6 @@ 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
         }
     }
@@ -1176,9 +1173,10 @@ impl SubModuleUser for Module {
     }
 }
 
-pub enum Declaration {
-    NonCountedBacktracking(ClauseName, usize), // name, arity
+pub enum Declaration {    
+    Hook(CompileTimeHook, PredicateClause),    
     Module(ModuleDecl),
+    NonCountedBacktracking(ClauseName, usize), // name, arity
     Op(OpDecl),
     UseModule(ClauseName),
     UseQualifiedModule(ClauseName, Vec<PredicateKey>)
@@ -1193,10 +1191,10 @@ impl Declaration {
 
 pub enum TopLevel {
     Declaration(Declaration),
-    Fact(Term),
+    Fact(Term),    
     Predicate(Predicate),
     Query(Vec<QueryTerm>),
-    Rule(Rule)
+    Rule(Rule),    
 }
 
 impl TopLevel {
index bb6a18a484fa579a8ad8acb06c0a203e049591c5..5e82723a1631a8a2fcf784b656ba68555d9ca41e 100644 (file)
@@ -307,5 +307,3 @@ 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 84a1431d4a4511d93e6157e079f9b39ca710c561..7d81e89f6686c3648d69b073ef55a45f15470138 100644 (file)
@@ -14,7 +14,7 @@ numbervars(Term, NewTerm, N1, N2) :- compound(Term), !,
     Term =.. [Name | Args],
     NewTerm =.. [Name | NewArgs],
     fold_numbervars(Args, NewArgs, N1, N2).
-numbervars(_, _, _, _).
+numbervars(_, _, N, N).
 
 marked_already(Term, NewTerm) :-
     var(Term), nonvar(NewTerm), NewTerm = '$VAR'(_).
@@ -23,9 +23,7 @@ marked_already(Term, NewTerm) :-
 
 fold_numbervars([HeadTerm | Terms], [NewHeadTerm | NewTerms], N1, Nn) :-
     ( marked_already(HeadTerm, NewHeadTerm) -> N1 = N2
-    ; numbervars(HeadTerm, NewHeadTerm, N1, N2),
-      ( var(N2) -> N1 = N2
-      ; true )
+    ; numbervars(HeadTerm, NewHeadTerm, N1, N2)
     ),
     fold_numbervars(Terms, NewTerms, N2, Nn).
 fold_numbervars([], [], _, _).
index 8c46b57c1f7fdc3ec2f1dc47f1acbcd59104050b..bbc3e863e01b80fbc4fa8b59f67061c3eaed29a8 100644 (file)
@@ -1,9 +1,11 @@
 use prolog_parser::ast::*;
 use prolog_parser::tabled_rc::*;
 
-use prolog::instructions::*;
+use prolog::codegen::*;
 use prolog::compile::*;
+use prolog::debray_allocator::*;
 use prolog::heap_print::*;
+use prolog::instructions::*;
 
 mod machine_errors;
 pub(super) mod machine_state;
@@ -249,6 +251,21 @@ impl Machine {
         }
     }
 
+    #[inline]
+    pub(super)
+    fn add_term_expansion_clause(&mut self, clause: PredicateClause) -> Result<(), ParserError>
+    {
+        let key = (clause_name!("term_expansion"), 2);
+        let preds = self.term_dir.entry(key).or_insert(Predicate(vec![]));
+        
+        preds.0.push(clause);
+                
+        let mut cg = CodeGenerator::<DebrayAllocator>::new(false, self.ms.flags);
+        let code = cg.compile_predicate(&preds.0)?;
+
+        Ok(self.term_expanders = code)
+    }
+    
     fn lookup_instr(&self, p: CodePtr) -> Option<Line> {
         match p {
             CodePtr::Local(LocalCodePtr::UserTermExpansion(p)) =>
index 5c69e5d6986f60949ea688e9204b2176770f513f..f94800e2f63ad17ced9018d7923c4d5872155efe 100644 (file)
@@ -203,7 +203,7 @@ impl MachineState {
             },
             &SystemClauseType::GetDoubleQuotes => {
                 let a1 = self[temp_v!(1)].clone();
-                
+
                 match self.flags.double_quotes {
                     DoubleQuotes::Chars =>
                         self.unify(a1, Addr::Con(atom!("chars"))),
@@ -435,14 +435,7 @@ impl MachineState {
                 return Err(err);
             },
             &SystemClauseType::Succeed => {},
-            &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) => 
-            }*/
+            &SystemClauseType::UnwindStack => self.unwind_stack()
         };
 
         self.set_p();
index eabca7a92e1ea1a2f920f7df849357d5e6318adf..cc9337fad500aa8f66355154f288f6f6ca2eae96 100644 (file)
@@ -24,6 +24,11 @@ impl<R: Read> TermStream<R> {
         }
     }
 
+    #[inline]
+    pub fn add_to_top(&mut self, buf: &str) {
+        self.parser.add_to_top(buf);
+    }
+
     #[inline]
     pub fn eof(&mut self) -> Result<bool, ParserError> {
         Ok(self.stack.is_empty() && self.parser.eof()?)
index 0b88037380e6f51b6386e2dc170a4100e5f12e11..b546f5ae1255f36f6321d3f651e8ffa86169be76 100644 (file)
@@ -5,6 +5,7 @@ use prolog::instructions::*;
 use prolog::iterators::*;
 use prolog::machine::*;
 use prolog::machine::machine_state::MachineState;
+use prolog::machine::term_expansion::*;
 
 use std::collections::VecDeque;
 use std::io::{Read, stdin};
@@ -29,7 +30,7 @@ pub enum Input {
     Term(Term)
 }
 
-pub fn read_toplevel(wam: &Machine) -> Result<Input, ParserError> {    
+pub fn read_toplevel(wam: &mut Machine) -> Result<Input, ParserError> {    
     let mut buffer = String::new();
 
     let stdin = stdin();
@@ -43,10 +44,10 @@ pub fn read_toplevel(wam: &Machine) -> Result<Input, ParserError> {
             Ok(Input::Batch)
         },
         _ => {
-            let mut parser = Parser::new(stdin.lock(), wam.atom_tbl(), wam.machine_flags());
-            parser.add_to_top(buffer.as_str());
+            let mut term_stream = TermStream::new(stdin.lock(), wam.atom_tbl(), wam.machine_flags());
+            term_stream.add_to_top(buffer.as_str());
 
-            Ok(Input::Term(parser.read_term(composite_op!(&wam.op_dir))?))
+            Ok(Input::Term(term_stream.read_term(wam, &OpDir::new())?))
         }
     }
 }
index 040524f9bb9df8316e142b11586a41a6514a713e..23134fff067ac7ec6993f24b6e7a25635a7c959b 100644 (file)
@@ -69,6 +69,21 @@ impl<'a, 'b : 'a> CompositeIndices<'a, 'b>
     }
 }
 
+#[inline]
+fn is_term_expansion(name: &ClauseName, terms: &Vec<Box<Term>>) -> bool {
+    if name.as_str() == ":-" {
+        if let Some(ref term) = terms.first() {
+            if let &Term::Clause(_, ref name, ref terms, None) = term.as_ref() {
+                return (name.as_str(), terms.len()) == ("term_expansion", 2);
+            }
+        }
+    } else if name.as_str() == "term_expansion" {
+        return terms.len() == 2;
+    }
+
+    false
+}
+
 fn setup_fact(term: Term) -> Result<Term, ParserError>
 {
     match term {
@@ -604,6 +619,24 @@ impl RelationWorker {
         Ok(query_terms)
     }
 
+    fn setup_hook(&mut self, indices: &mut CompositeIndices, term: Term)
+                  -> Result<(CompileTimeHook, PredicateClause), ParserError>
+    {
+        match term {
+            Term::Clause(r, name, terms, _) => 
+                if name.as_str() == "term_expansion" && terms.len() == 2 {
+                    let term = Term::Clause(r, name, terms, None);
+                    Ok((CompileTimeHook::TermExpansion, PredicateClause::Fact(term)))
+                } else if name.as_str() == ":-" {
+                    let rule = self.setup_rule(indices, terms, false)?;                    
+                    Ok((CompileTimeHook::TermExpansion, PredicateClause::Rule(rule)))
+                } else {
+                    Err(ParserError::InvalidHook)
+                },
+            _ => Err(ParserError::InvalidHook)
+        }
+    }
+    
     fn setup_rule(&mut self, indices: &mut CompositeIndices, mut terms: Vec<Box<Term>>, blocks_cuts: bool)
                   -> Result<Rule, ParserError>
     {
@@ -626,7 +659,12 @@ impl RelationWorker {
     {
         match term {
             Term::Clause(r, name, mut terms, fixity) =>
-                if name.as_str() == "?-" {
+                if is_term_expansion(&name, &terms) {
+                    let term = Term::Clause(r, name, terms, fixity);
+                    let (hook, clauses) = self.setup_hook(indices, term)?;
+                    
+                    Ok(TopLevel::Declaration(Declaration::Hook(hook, clauses)))
+                } else if name.as_str() == "?-" {
                     Ok(TopLevel::Query(try!(self.setup_query(indices, terms, blocks_cuts))))
                 } else if name.as_str() == ":-" && terms.len() > 1 {
                     Ok(TopLevel::Rule(try!(self.setup_rule(indices, terms, blocks_cuts))))
@@ -634,8 +672,9 @@ impl RelationWorker {
                     let term = *terms.pop().unwrap();
                     Ok(TopLevel::Declaration(try!(setup_declaration(term))))
                 } else {
-                    Ok(TopLevel::Fact(try!(setup_fact(Term::Clause(r, name, terms, fixity)))))
-                },
+                    let term = Term::Clause(r, name, terms, fixity);                        
+                    Ok(TopLevel::Fact(try!(setup_fact(term))))
+                },        
             term => Ok(TopLevel::Fact(try!(setup_fact(term))))
         }
     }
@@ -660,8 +699,8 @@ impl RelationWorker {
         while let Some(terms) = self.queue.pop_front() {
             let clauses = merge_clauses(&mut self.try_terms_to_tls(indices, terms, false)?)?;
             queue.push_back(clauses);
+        
         }
-
         Ok(queue)
     }
 
@@ -738,7 +777,7 @@ impl<R: Read> TopLevelBatchWorker<R> {
                 TopLevel::Fact(fact) => preds.push(PredicateClause::Fact(fact)),
                 TopLevel::Rule(rule) => preds.push(PredicateClause::Rule(rule)),
                 TopLevel::Predicate(pred) => preds.extend(pred.0),
-                TopLevel::Declaration(decl) => return Ok(Some(decl)),
+                TopLevel::Declaration(decl) => return Ok(Some(decl)),                
                 TopLevel::Query(_) => return Err(SessionError::NamelessEntry)
             }
         }