add read support for user:term_expansion and user:goal_expansion
This commit is contained in:
@@ -101,9 +101,9 @@ impl CodeRepo {
|
|||||||
compile_appendix(&mut code, &preds.1, false, flags)?;
|
compile_appendix(&mut code, &preds.1, false, flags)?;
|
||||||
|
|
||||||
Ok(match hook {
|
Ok(match hook {
|
||||||
CompileTimeHook::TermExpansion =>
|
CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion =>
|
||||||
self.term_expanders = code,
|
self.term_expanders = code,
|
||||||
CompileTimeHook::GoalExpansion =>
|
CompileTimeHook::UserGoalExpansion | CompileTimeHook::GoalExpansion =>
|
||||||
self.goal_expanders = code
|
self.goal_expanders = code
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -371,21 +371,27 @@ pub enum BuiltInClauseType {
|
|||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum CompileTimeHook {
|
pub enum CompileTimeHook {
|
||||||
GoalExpansion,
|
GoalExpansion,
|
||||||
TermExpansion
|
TermExpansion,
|
||||||
|
UserGoalExpansion,
|
||||||
|
UserTermExpansion
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompileTimeHook {
|
impl CompileTimeHook {
|
||||||
pub fn name(self) -> ClauseName {
|
pub fn name(self) -> ClauseName {
|
||||||
match self {
|
match self {
|
||||||
CompileTimeHook::GoalExpansion => clause_name!("goal_expansion"),
|
CompileTimeHook::UserGoalExpansion
|
||||||
CompileTimeHook::TermExpansion => clause_name!("term_expansion")
|
| CompileTimeHook::GoalExpansion => clause_name!("goal_expansion"),
|
||||||
|
CompileTimeHook::UserTermExpansion
|
||||||
|
| CompileTimeHook::TermExpansion => clause_name!("term_expansion")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn arity(self) -> usize {
|
pub fn arity(self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
CompileTimeHook::GoalExpansion => 2,
|
CompileTimeHook::UserGoalExpansion
|
||||||
CompileTimeHook::TermExpansion => 2
|
| CompileTimeHook::GoalExpansion => 2,
|
||||||
|
CompileTimeHook::UserTermExpansion
|
||||||
|
| CompileTimeHook::TermExpansion => 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,10 @@
|
|||||||
instructions are unchanged. */
|
instructions are unchanged. */
|
||||||
:- op(700, fx, non_counted_backtracking).
|
:- 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([Op | OtherOps], Pred, Spec, OpResults).
|
||||||
|
|
||||||
expand_op_list([], _, _, []).
|
expand_op_list([], _, _, []).
|
||||||
@@ -47,9 +50,6 @@ expand_op_list([Op | OtherOps], Pred, Spec, [(:- op(Pred, Spec, Op)) | OtherResu
|
|||||||
% term comparison.
|
% term comparison.
|
||||||
:- op(700, xfx, [==, \==, @=<, @>=, @<, @>, =@=, \=@=]).
|
:- 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).
|
% the maximum arity flag. needs to be replaced with current_prolog_flag(max_arity, MAX_ARITY).
|
||||||
max_arity(63).
|
max_arity(63).
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ phrase(G, Ls0, Ls2) :-
|
|||||||
phrase(G, Ls0, Ls1) :-
|
phrase(G, Ls0, Ls1) :-
|
||||||
call(G, Ls0, Ls1).
|
call(G, Ls0, Ls1).
|
||||||
|
|
||||||
term_expansion(Term0, Term) :-
|
user:term_expansion(Term0, Term) :-
|
||||||
numbervars(Term0, 0, N),
|
numbervars(Term0, 0, N),
|
||||||
expand_dcgs(Term0, N, Term).
|
expand_dcgs(Term0, N, Term).
|
||||||
|
|
||||||
|
|||||||
@@ -665,9 +665,9 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
machine_st.b0 = machine_st.b;
|
machine_st.b0 = machine_st.b;
|
||||||
|
|
||||||
machine_st.p = match hook {
|
machine_st.p = match hook {
|
||||||
CompileTimeHook::TermExpansion =>
|
CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion =>
|
||||||
CodePtr::Local(LocalCodePtr::UserTermExpansion(0)),
|
CodePtr::Local(LocalCodePtr::UserTermExpansion(0)),
|
||||||
CompileTimeHook::GoalExpansion =>
|
CompileTimeHook::UserGoalExpansion | CompileTimeHook::GoalExpansion =>
|
||||||
CodePtr::Local(LocalCodePtr::UserGoalExpansion(0))
|
CodePtr::Local(LocalCodePtr::UserGoalExpansion(0))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -131,14 +131,15 @@ impl<'a, R: Read> TermStream<'a, R> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn incr_expansion_lens(&mut self, hook: CompileTimeHook, len: usize, queue_len: usize) {
|
pub fn incr_expansion_lens(&mut self, hook: CompileTimeHook, len: usize, queue_len: usize) {
|
||||||
match hook {
|
match hook {
|
||||||
CompileTimeHook::TermExpansion => {
|
CompileTimeHook::UserTermExpansion => {
|
||||||
self.term_expansion_lens.0 += len;
|
self.term_expansion_lens.0 += len;
|
||||||
self.term_expansion_lens.1 += queue_len;
|
self.term_expansion_lens.1 += queue_len;
|
||||||
},
|
},
|
||||||
CompileTimeHook::GoalExpansion => {
|
CompileTimeHook::UserGoalExpansion => {
|
||||||
self.goal_expansion_lens.0 += len;
|
self.goal_expansion_lens.0 += len;
|
||||||
self.goal_expansion_lens.1 += queue_len;
|
self.goal_expansion_lens.1 += queue_len;
|
||||||
}
|
},
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use prolog::machine::machine_state::MachineState;
|
|||||||
use prolog::machine::term_expansion::*;
|
use prolog::machine::term_expansion::*;
|
||||||
use prolog::num::*;
|
use prolog::num::*;
|
||||||
|
|
||||||
|
use std::borrow::BorrowMut;
|
||||||
use std::collections::{HashSet, VecDeque};
|
use std::collections::{HashSet, VecDeque};
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
@@ -70,11 +71,28 @@ impl<'a, 'b> CompositeIndices<'a, 'b>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn as_compile_time_hook(name: &str, arity: usize, terms: &Vec<Box<Term>>) -> Option<CompileTimeHook>
|
||||||
fn as_compile_time_hook(name: &str, arity: usize) -> Option<CompileTimeHook> {
|
{
|
||||||
match (name, arity) {
|
match (name, arity) {
|
||||||
("term_expansion", 2) => Some(CompileTimeHook::TermExpansion),
|
("term_expansion", 2) => Some(CompileTimeHook::TermExpansion),
|
||||||
("goal_expansion", 2) => Some(CompileTimeHook::GoalExpansion),
|
("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
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,13 +101,13 @@ fn as_compile_time_hook(name: &str, arity: usize) -> Option<CompileTimeHook> {
|
|||||||
fn is_compile_time_hook(name: &ClauseName, terms: &Vec<Box<Term>>) -> Option<CompileTimeHook> {
|
fn is_compile_time_hook(name: &ClauseName, terms: &Vec<Box<Term>>) -> Option<CompileTimeHook> {
|
||||||
if name.as_str() == ":-" {
|
if name.as_str() == ":-" {
|
||||||
if let Some(ref term) = terms.first() {
|
if let Some(ref term) = terms.first() {
|
||||||
if let &Term::Clause(_, ref name, ref terms, None) = term.as_ref() {
|
if let &Term::Clause(_, ref name, ref terms, _) = term.as_ref() {
|
||||||
return as_compile_time_hook(name.as_str(), terms.len());
|
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>);
|
type CompileTimeHookCompileInfo = (CompileTimeHook, PredicateClause, VecDeque<TopLevel>);
|
||||||
@@ -349,6 +367,28 @@ fn module_resolution_call(mod_name: Term, body: Term) -> Result<QueryTerm, Parse
|
|||||||
Err(ParserError::InvalidModuleResolution)
|
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 {
|
pub enum TopLevelPacket {
|
||||||
Query(Vec<QueryTerm>, VecDeque<TopLevel>),
|
Query(Vec<QueryTerm>, VecDeque<TopLevel>),
|
||||||
Decl(TopLevel, VecDeque<TopLevel>)
|
Decl(TopLevel, VecDeque<TopLevel>)
|
||||||
@@ -594,7 +634,7 @@ impl RelationWorker {
|
|||||||
fn setup_hook(&mut self, hook: CompileTimeHook, indices: &mut CompositeIndices, term: Term)
|
fn setup_hook(&mut self, hook: CompileTimeHook, indices: &mut CompositeIndices, term: Term)
|
||||||
-> Result<CompileTimeHookCompileInfo, ParserError>
|
-> Result<CompileTimeHookCompileInfo, ParserError>
|
||||||
{
|
{
|
||||||
match term {
|
match flatten_hook(term) {
|
||||||
Term::Clause(r, name, terms, _) =>
|
Term::Clause(r, name, terms, _) =>
|
||||||
if name == hook.name() && terms.len() == hook.arity() {
|
if name == hook.name() && terms.len() == hook.arity() {
|
||||||
let term = setup_fact(Term::Clause(r, name, terms, None))?;
|
let term = setup_fact(Term::Clause(r, name, terms, None))?;
|
||||||
|
|||||||
Reference in New Issue
Block a user