#[derive(Clone, Copy)]
pub enum CompileTimeHook {
GoalExpansion,
- TermExpansion
+ TermExpansion,
+ UserGoalExpansion,
+ UserTermExpansion
}
impl CompileTimeHook {
pub fn name(self) -> ClauseName {
match self {
- CompileTimeHook::GoalExpansion => clause_name!("goal_expansion"),
- CompileTimeHook::TermExpansion => clause_name!("term_expansion")
+ CompileTimeHook::UserGoalExpansion
+ | CompileTimeHook::GoalExpansion => clause_name!("goal_expansion"),
+ CompileTimeHook::UserTermExpansion
+ | CompileTimeHook::TermExpansion => clause_name!("term_expansion")
}
}
pub fn arity(self) -> usize {
match self {
- CompileTimeHook::GoalExpansion => 2,
- CompileTimeHook::TermExpansion => 2
+ CompileTimeHook::UserGoalExpansion
+ | CompileTimeHook::GoalExpansion => 2,
+ CompileTimeHook::UserTermExpansion
+ | CompileTimeHook::TermExpansion => 2
}
}
}
instructions are unchanged. */
:- op(700, fx, non_counted_backtracking).
-term_expansion((:- op(Pred, Spec, [Op | OtherOps])), OpResults) :-
+% module resolution operator.
+:- op(600, xfy, :).
+
+user:term_expansion((:- op(Pred, Spec, [Op | OtherOps])), OpResults) :-
expand_op_list([Op | OtherOps], Pred, Spec, OpResults).
expand_op_list([], _, _, []).
% term comparison.
:- op(700, xfx, [==, \==, @=<, @>=, @<, @>, =@=, \=@=]).
-% module resolution operator.
-:- op(600, xfy, :).
-
% the maximum arity flag. needs to be replaced with current_prolog_flag(max_arity, MAX_ARITY).
max_arity(63).
use prolog::machine::term_expansion::*;
use prolog::num::*;
+use std::borrow::BorrowMut;
use std::collections::{HashSet, VecDeque};
use std::cell::{Cell, RefCell};
use std::io::Read;
}
}
-#[inline]
-fn as_compile_time_hook(name: &str, arity: usize) -> Option<CompileTimeHook> {
+fn as_compile_time_hook(name: &str, arity: usize, terms: &Vec<Box<Term>>) -> Option<CompileTimeHook>
+{
match (name, arity) {
("term_expansion", 2) => Some(CompileTimeHook::TermExpansion),
("goal_expansion", 2) => Some(CompileTimeHook::GoalExpansion),
+ (":", 2) => {
+ if let &Term::Constant(_, Constant::Atom(ref name, _)) = &terms[0].as_ref() {
+ if name.as_str() == "user" {
+ if let &Term::Clause(_, ref name, ref terms, _) = &terms[1].as_ref() {
+ return match name.as_str() {
+ "term_expansion" if terms.len() == 2 =>
+ Some(CompileTimeHook::UserTermExpansion),
+ "goal_expansion" if terms.len() == 2 =>
+ Some(CompileTimeHook::UserGoalExpansion),
+ _ => None
+ }
+ }
+ }
+ }
+
+ None
+ },
_ => None
}
}
fn is_compile_time_hook(name: &ClauseName, terms: &Vec<Box<Term>>) -> Option<CompileTimeHook> {
if name.as_str() == ":-" {
if let Some(ref term) = terms.first() {
- if let &Term::Clause(_, ref name, ref terms, None) = term.as_ref() {
- return as_compile_time_hook(name.as_str(), terms.len());
+ if let &Term::Clause(_, ref name, ref terms, _) = term.as_ref() {
+ return as_compile_time_hook(name.as_str(), terms.len(), terms);
}
}
}
- as_compile_time_hook(name.as_str(), terms.len())
+ as_compile_time_hook(name.as_str(), terms.len(), terms)
}
type CompileTimeHookCompileInfo = (CompileTimeHook, PredicateClause, VecDeque<TopLevel>);
Err(ParserError::InvalidModuleResolution)
}
+fn flatten_hook(mut term: Term) -> Term {
+ if let &mut Term::Clause(_, ref mut name, ref mut terms, _) = &mut term {
+ if name.as_str() == ":-" && terms.len() == 2 {
+ let inner_term = match terms.first_mut().map(|term| term.borrow_mut()) {
+ Some(&mut Term::Clause(_, ref name, ref mut inner_terms, _)) =>
+ if name.as_str() == ":" && inner_terms.len() == 2 {
+ Some(*inner_terms.pop().unwrap())
+ } else {
+ None
+ },
+ _ => None
+ };
+
+ if let Some(mut inner_term) = inner_term {
+ mem::swap(&mut terms[0], &mut Box::new(inner_term));
+ }
+ }
+ }
+
+ term
+}
+
pub enum TopLevelPacket {
Query(Vec<QueryTerm>, VecDeque<TopLevel>),
Decl(TopLevel, VecDeque<TopLevel>)
fn setup_hook(&mut self, hook: CompileTimeHook, indices: &mut CompositeIndices, term: Term)
-> Result<CompileTimeHookCompileInfo, ParserError>
{
- match term {
+ match flatten_hook(term) {
Term::Clause(r, name, terms, _) =>
if name == hook.name() && terms.len() == hook.arity() {
let term = setup_fact(Term::Clause(r, name, terms, None))?;