From: Mark Thom Date: Sat, 22 Sep 2018 22:25:32 +0000 (-0600) Subject: term_expansion beginnings X-Git-Tag: v0.8.110~369^2~1 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=4d57989c2b209f4753b7070b99005a7f84e98b32;p=scryer-prolog.git term_expansion beginnings --- diff --git a/Cargo.lock b/Cargo.lock index 5053b63b..d46db9b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index 8fb7c224..6fa9e632 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 diff --git a/src/prolog/compile.rs b/src/prolog/compile.rs index 4eaafc8a..557bb162 100644 --- a/src/prolog/compile.rs +++ b/src/prolog/compile.rs @@ -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) => diff --git a/src/prolog/instructions.rs b/src/prolog/instructions.rs index 55815445..b8267a5c 100644 --- a/src/prolog/instructions.rs +++ b/src/prolog/instructions.rs @@ -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) @@ -1193,10 +1191,10 @@ impl Declaration { pub enum TopLevel { Declaration(Declaration), - Fact(Term), + Fact(Term), Predicate(Predicate), Query(Vec), - Rule(Rule) + Rule(Rule), } impl TopLevel { diff --git a/src/prolog/lib/builtins.pl b/src/prolog/lib/builtins.pl index bb6a18a4..5e82723a 100644 --- a/src/prolog/lib/builtins.pl +++ b/src/prolog/lib/builtins.pl @@ -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. diff --git a/src/prolog/lib/numbervars.pl b/src/prolog/lib/numbervars.pl index 84a1431d..7d81e89f 100644 --- a/src/prolog/lib/numbervars.pl +++ b/src/prolog/lib/numbervars.pl @@ -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([], [], _, _). diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 8c46b57c..bbc3e863 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -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::::new(false, self.ms.flags); + let code = cg.compile_predicate(&preds.0)?; + + Ok(self.term_expanders = code) + } + fn lookup_instr(&self, p: CodePtr) -> Option { match p { CodePtr::Local(LocalCodePtr::UserTermExpansion(p)) => diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index 5c69e5d6..f94800e2 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -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(); diff --git a/src/prolog/machine/term_expansion.rs b/src/prolog/machine/term_expansion.rs index eabca7a9..cc9337fa 100644 --- a/src/prolog/machine/term_expansion.rs +++ b/src/prolog/machine/term_expansion.rs @@ -24,6 +24,11 @@ impl TermStream { } } + #[inline] + pub fn add_to_top(&mut self, buf: &str) { + self.parser.add_to_top(buf); + } + #[inline] pub fn eof(&mut self) -> Result { Ok(self.stack.is_empty() && self.parser.eof()?) diff --git a/src/prolog/read.rs b/src/prolog/read.rs index 0b880373..b546f5ae 100644 --- a/src/prolog/read.rs +++ b/src/prolog/read.rs @@ -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 { +pub fn read_toplevel(wam: &mut Machine) -> Result { let mut buffer = String::new(); let stdin = stdin(); @@ -43,10 +44,10 @@ pub fn read_toplevel(wam: &Machine) -> Result { 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())?)) } } } diff --git a/src/prolog/toplevel.rs b/src/prolog/toplevel.rs index 040524f9..23134fff 100644 --- a/src/prolog/toplevel.rs +++ b/src/prolog/toplevel.rs @@ -69,6 +69,21 @@ impl<'a, 'b : 'a> CompositeIndices<'a, 'b> } } +#[inline] +fn is_term_expansion(name: &ClauseName, terms: &Vec>) -> 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 { 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>, blocks_cuts: bool) -> Result { @@ -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 TopLevelBatchWorker { 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) } }