[[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)",
"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)",
]
"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"
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
-> 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) =>
SetDoubleQuotes,
SkipMaxList,
Succeed,
- UnwindStack,
- CompileAndRunQuery
+ UnwindStack
}
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")
}
}
("$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
}
}
}
}
-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>)
pub enum TopLevel {
Declaration(Declaration),
- Fact(Term),
+ Fact(Term),
Predicate(Predicate),
Query(Vec<QueryTerm>),
- Rule(Rule)
+ Rule(Rule),
}
impl TopLevel {
handle_ball(_, _, _) :- '$unwind_stack'.
throw(Ball) :- '$set_ball'(Ball), '$unwind_stack'.
-
-repl :- read(X), '$compile_and_run_query'(X), repl.
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'(_).
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([], [], _, _).
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;
}
}
+ #[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)) =>
},
&SystemClauseType::GetDoubleQuotes => {
let a1 = self[temp_v!(1)].clone();
-
+
match self.flags.double_quotes {
DoubleQuotes::Chars =>
self.unify(a1, Addr::Con(atom!("chars"))),
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();
}
}
+ #[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()?)
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};
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();
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())?))
}
}
}
}
}
+#[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 {
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>
{
{
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))))
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))))
}
}
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)
}
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)
}
}