eliminate need for embedded, handwritten WAM code.
This commit is contained in:
@@ -7,12 +7,12 @@ use std::vec::Vec;
|
|||||||
pub struct Frame {
|
pub struct Frame {
|
||||||
pub global_index: usize,
|
pub global_index: usize,
|
||||||
pub e: usize,
|
pub e: usize,
|
||||||
pub cp: CodePtr,
|
pub cp: LocalCodePtr,
|
||||||
perms: Vec<Addr>
|
perms: Vec<Addr>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Frame {
|
impl Frame {
|
||||||
fn new(global_index: usize, fr: usize, e: usize, cp: CodePtr, n: usize) -> Self {
|
fn new(global_index: usize, fr: usize, e: usize, cp: LocalCodePtr, n: usize) -> Self {
|
||||||
Frame {
|
Frame {
|
||||||
global_index,
|
global_index,
|
||||||
e: e,
|
e: e,
|
||||||
@@ -29,7 +29,7 @@ impl AndStack {
|
|||||||
AndStack(Vec::new())
|
AndStack(Vec::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(&mut self, global_index: usize, e: usize, cp: CodePtr, n: usize) {
|
pub fn push(&mut self, global_index: usize, e: usize, cp: LocalCodePtr, n: usize) {
|
||||||
let len = self.0.len();
|
let len = self.0.len();
|
||||||
self.0.push(Frame::new(global_index, len, e, cp, n));
|
self.0.push(Frame::new(global_index, len, e, cp, n));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -561,59 +561,83 @@ pub enum Term {
|
|||||||
Var(Cell<VarReg>, Rc<Var>)
|
Var(Cell<VarReg>, Rc<Var>)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
pub enum InlinedClauseType {
|
pub enum InlinedClauseType {
|
||||||
CompareNumber(CompareNumberQT),
|
CompareNumber(CompareNumberQT, RegType, RegType),
|
||||||
IsAtom,
|
IsAtom(RegType),
|
||||||
IsAtomic,
|
IsAtomic(RegType),
|
||||||
IsCompound,
|
IsCompound(RegType),
|
||||||
IsInteger,
|
IsInteger(RegType),
|
||||||
IsRational,
|
IsRational(RegType),
|
||||||
IsString,
|
IsString(RegType),
|
||||||
IsFloat,
|
IsFloat(RegType),
|
||||||
IsNonVar,
|
IsNonVar(RegType),
|
||||||
IsVar,
|
IsVar(RegType),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InlinedClauseType {
|
impl InlinedClauseType {
|
||||||
pub fn name(&self) -> &'static str {
|
pub fn name(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
&InlinedClauseType::CompareNumber(qt) => qt.name(),
|
&InlinedClauseType::CompareNumber(qt, ..) => qt.name(),
|
||||||
&InlinedClauseType::IsAtom => "atom",
|
&InlinedClauseType::IsAtom(..) => "atom",
|
||||||
&InlinedClauseType::IsAtomic => "atomic",
|
&InlinedClauseType::IsAtomic(..) => "atomic",
|
||||||
&InlinedClauseType::IsCompound => "compound",
|
&InlinedClauseType::IsCompound(..) => "compound",
|
||||||
&InlinedClauseType::IsInteger => "integer",
|
&InlinedClauseType::IsInteger (..) => "integer",
|
||||||
&InlinedClauseType::IsRational => "rational",
|
&InlinedClauseType::IsRational(..) => "rational",
|
||||||
&InlinedClauseType::IsString => "string",
|
&InlinedClauseType::IsString(..) => "string",
|
||||||
&InlinedClauseType::IsFloat => "float",
|
&InlinedClauseType::IsFloat (..) => "float",
|
||||||
&InlinedClauseType::IsNonVar => "nonvar",
|
&InlinedClauseType::IsNonVar(..) => "nonvar",
|
||||||
&InlinedClauseType::IsVar => "var"
|
&InlinedClauseType::IsVar(..) => "var"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn arity(&self) -> usize {
|
||||||
|
match self {
|
||||||
|
&InlinedClauseType::CompareNumber(..) => 2,
|
||||||
|
&InlinedClauseType::IsAtom(..) => 1,
|
||||||
|
&InlinedClauseType::IsAtomic(..) => 1,
|
||||||
|
&InlinedClauseType::IsCompound(..) => 1,
|
||||||
|
&InlinedClauseType::IsInteger (..) => 1,
|
||||||
|
&InlinedClauseType::IsRational(..) => 1,
|
||||||
|
&InlinedClauseType::IsString(..) => 1,
|
||||||
|
&InlinedClauseType::IsFloat (..) => 1,
|
||||||
|
&InlinedClauseType::IsNonVar(..) => 1,
|
||||||
|
&InlinedClauseType::IsVar(..) => 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from(name: &str, arity: usize) -> Option<Self> {
|
pub fn from(name: &str, arity: usize) -> Option<Self> {
|
||||||
|
let r1 = temp_v!(1);
|
||||||
|
let r2 = temp_v!(2);
|
||||||
|
|
||||||
match (name, arity) {
|
match (name, arity) {
|
||||||
(">", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThan)),
|
(">", 2) =>
|
||||||
("<", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThan)),
|
Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThan, r1, r2)),
|
||||||
(">=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThanOrEqual)),
|
("<", 2) =>
|
||||||
("=<", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThanOrEqual)),
|
Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThan, r1, r2)),
|
||||||
("=\\=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::NotEqual)),
|
(">=", 2) =>
|
||||||
("=:=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::Equal)),
|
Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThanOrEqual,r1, r2)),
|
||||||
("atom", 1) => Some(InlinedClauseType::IsAtom),
|
("=<", 2) =>
|
||||||
("atomic", 1) => Some(InlinedClauseType::IsAtomic),
|
Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThanOrEqual, r1, r2)),
|
||||||
("compound", 1) => Some(InlinedClauseType::IsCompound),
|
("=\\=", 2) =>
|
||||||
("integer", 1) => Some(InlinedClauseType::IsInteger),
|
Some(InlinedClauseType::CompareNumber(CompareNumberQT::NotEqual, r1, r2)),
|
||||||
("rational", 1) => Some(InlinedClauseType::IsRational),
|
("=:=", 2) =>
|
||||||
("string", 1) => Some(InlinedClauseType::IsString),
|
Some(InlinedClauseType::CompareNumber(CompareNumberQT::Equal, r1, r2)),
|
||||||
("float", 1) => Some(InlinedClauseType::IsFloat),
|
("atom", 1) => Some(InlinedClauseType::IsAtom(r1)),
|
||||||
("nonvar", 1) => Some(InlinedClauseType::IsNonVar),
|
("atomic", 1) => Some(InlinedClauseType::IsAtomic(r1)),
|
||||||
("var", 1) => Some(InlinedClauseType::IsVar),
|
("compound", 1) => Some(InlinedClauseType::IsCompound(r1)),
|
||||||
|
("integer", 1) => Some(InlinedClauseType::IsInteger(r1)),
|
||||||
|
("rational", 1) => Some(InlinedClauseType::IsRational(r1)),
|
||||||
|
("string", 1) => Some(InlinedClauseType::IsString(r1)),
|
||||||
|
("float", 1) => Some(InlinedClauseType::IsFloat(r1)),
|
||||||
|
("nonvar", 1) => Some(InlinedClauseType::IsNonVar(r1)),
|
||||||
|
("var", 1) => Some(InlinedClauseType::IsVar(r1)),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
pub enum CompareNumberQT {
|
pub enum CompareNumberQT {
|
||||||
GreaterThan,
|
GreaterThan,
|
||||||
LessThan,
|
LessThan,
|
||||||
@@ -636,7 +660,7 @@ impl CompareNumberQT {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
pub enum CompareTermQT {
|
pub enum CompareTermQT {
|
||||||
LessThan,
|
LessThan,
|
||||||
LessThanOrEqual,
|
LessThanOrEqual,
|
||||||
@@ -685,12 +709,22 @@ pub struct Rule {
|
|||||||
pub clauses: Vec<QueryTerm>
|
pub clauses: Vec<QueryTerm>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
pub enum SystemClauseType {
|
pub enum SystemClauseType {
|
||||||
SkipMaxList
|
SkipMaxList
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SystemClauseType {
|
impl SystemClauseType {
|
||||||
|
pub fn arity(&self) -> usize {
|
||||||
|
match self {
|
||||||
|
&SystemClauseType::SkipMaxList => 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fixity(&self) -> Option<Fixity> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> ClauseName {
|
pub fn name(&self) -> ClauseName {
|
||||||
match self {
|
match self {
|
||||||
&SystemClauseType::SkipMaxList => clause_name!("$skip_max_list"),
|
&SystemClauseType::SkipMaxList => clause_name!("$skip_max_list"),
|
||||||
@@ -705,13 +739,9 @@ impl SystemClauseType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
pub enum ClauseType {
|
pub enum BuiltInClauseType {
|
||||||
AcyclicTerm,
|
AcyclicTerm,
|
||||||
Arg,
|
|
||||||
CallN,
|
|
||||||
CallWithInferenceLimit,
|
|
||||||
Catch,
|
|
||||||
Compare,
|
Compare,
|
||||||
CompareTerm(CompareTermQT),
|
CompareTerm(CompareTermQT),
|
||||||
CyclicTerm,
|
CyclicTerm,
|
||||||
@@ -720,16 +750,20 @@ pub enum ClauseType {
|
|||||||
Eq,
|
Eq,
|
||||||
Functor,
|
Functor,
|
||||||
Ground,
|
Ground,
|
||||||
Inlined(InlinedClauseType),
|
|
||||||
Is,
|
Is,
|
||||||
KeySort,
|
KeySort,
|
||||||
NotEq,
|
NotEq,
|
||||||
Op(ClauseName, Fixity, CodeIndex),
|
|
||||||
Named(ClauseName, CodeIndex),
|
|
||||||
SetupCallCleanup,
|
|
||||||
Sort,
|
Sort,
|
||||||
System(SystemClauseType),
|
System(SystemClauseType)
|
||||||
Throw,
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum ClauseType {
|
||||||
|
BuiltIn(BuiltInClauseType),
|
||||||
|
CallN,
|
||||||
|
Inlined(InlinedClauseType),
|
||||||
|
Op(ClauseName, Fixity, CodeIndex),
|
||||||
|
Named(ClauseName, CodeIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -797,12 +831,84 @@ impl ClauseName {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BuiltInClauseType {
|
||||||
|
fn fixity(&self) -> Option<Fixity> {
|
||||||
|
match self {
|
||||||
|
&BuiltInClauseType::Compare | &BuiltInClauseType::CompareTerm(_)
|
||||||
|
| &BuiltInClauseType::NotEq | &BuiltInClauseType::Is | &BuiltInClauseType::Eq
|
||||||
|
=> Some(Fixity::In),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> ClauseName {
|
||||||
|
match self {
|
||||||
|
&BuiltInClauseType::AcyclicTerm => clause_name!("acyclic_term"),
|
||||||
|
&BuiltInClauseType::Compare => clause_name!("compare"),
|
||||||
|
&BuiltInClauseType::CompareTerm(qt) => clause_name!(qt.name()),
|
||||||
|
&BuiltInClauseType::CyclicTerm => clause_name!("cyclic_term"),
|
||||||
|
&BuiltInClauseType::Display => clause_name!("display"),
|
||||||
|
&BuiltInClauseType::DuplicateTerm => clause_name!("duplicate_term"),
|
||||||
|
&BuiltInClauseType::Eq => clause_name!("=="),
|
||||||
|
&BuiltInClauseType::Functor => clause_name!("functor"),
|
||||||
|
&BuiltInClauseType::Ground => clause_name!("ground"),
|
||||||
|
&BuiltInClauseType::Is => clause_name!("is"),
|
||||||
|
&BuiltInClauseType::KeySort => clause_name!("keysort"),
|
||||||
|
&BuiltInClauseType::NotEq => clause_name!("\\=="),
|
||||||
|
&BuiltInClauseType::Sort => clause_name!("sort"),
|
||||||
|
&BuiltInClauseType::System(system) => system.name()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn arity(&self) -> usize {
|
||||||
|
match self {
|
||||||
|
&BuiltInClauseType::AcyclicTerm => 1,
|
||||||
|
&BuiltInClauseType::Compare => 2,
|
||||||
|
&BuiltInClauseType::CompareTerm(_) => 2,
|
||||||
|
&BuiltInClauseType::CyclicTerm => 1,
|
||||||
|
&BuiltInClauseType::Display => 1,
|
||||||
|
&BuiltInClauseType::DuplicateTerm => 2,
|
||||||
|
&BuiltInClauseType::Eq => 2,
|
||||||
|
&BuiltInClauseType::Functor => 3,
|
||||||
|
&BuiltInClauseType::Ground => 1,
|
||||||
|
&BuiltInClauseType::Is => 2,
|
||||||
|
&BuiltInClauseType::KeySort => 2,
|
||||||
|
&BuiltInClauseType::NotEq => 2,
|
||||||
|
&BuiltInClauseType::Sort => 2,
|
||||||
|
&BuiltInClauseType::System(system) => system.arity()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from(name: &str, arity: usize) -> Option<Self> {
|
||||||
|
match (name, arity) {
|
||||||
|
("acyclic_term", 1) => Some(BuiltInClauseType::AcyclicTerm),
|
||||||
|
("compare", 3) => Some(BuiltInClauseType::Compare),
|
||||||
|
("cyclic_term", 1) => Some(BuiltInClauseType::CyclicTerm),
|
||||||
|
("@>", 2) => Some(BuiltInClauseType::CompareTerm(CompareTermQT::GreaterThan)),
|
||||||
|
("@<", 2) => Some(BuiltInClauseType::CompareTerm(CompareTermQT::LessThan)),
|
||||||
|
("@>=", 2) => Some(BuiltInClauseType::CompareTerm(CompareTermQT::GreaterThanOrEqual)),
|
||||||
|
("@<=", 2) => Some(BuiltInClauseType::CompareTerm(CompareTermQT::LessThanOrEqual)),
|
||||||
|
("\\=@=", 2) => Some(BuiltInClauseType::CompareTerm(CompareTermQT::NotEqual)),
|
||||||
|
("=@=", 2) => Some(BuiltInClauseType::CompareTerm(CompareTermQT::Equal)),
|
||||||
|
("display", 1) => Some(BuiltInClauseType::Display),
|
||||||
|
("duplicate_term", 2) => Some(BuiltInClauseType::DuplicateTerm),
|
||||||
|
("==", 2) => Some(BuiltInClauseType::Eq),
|
||||||
|
("functor", 3) => Some(BuiltInClauseType::Functor),
|
||||||
|
("ground", 1) => Some(BuiltInClauseType::Ground),
|
||||||
|
("is", 2) => Some(BuiltInClauseType::Is),
|
||||||
|
("keysort", 2) => Some(BuiltInClauseType::KeySort),
|
||||||
|
("\\==", 2) => Some(BuiltInClauseType::NotEq),
|
||||||
|
("sort", 2) => Some(BuiltInClauseType::Sort),
|
||||||
|
_ => SystemClauseType::from(name, arity).map(BuiltInClauseType::System)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ClauseType {
|
impl ClauseType {
|
||||||
pub fn fixity(&self) -> Option<Fixity> {
|
pub fn fixity(&self) -> Option<Fixity> {
|
||||||
match self {
|
match self {
|
||||||
&ClauseType::Compare | &ClauseType::CompareTerm(_)
|
&ClauseType::BuiltIn(ref built_in) => built_in.fixity(),
|
||||||
| &ClauseType::Inlined(InlinedClauseType::CompareNumber(_))
|
&ClauseType::Inlined(InlinedClauseType::CompareNumber(..)) => Some(Fixity::In),
|
||||||
| &ClauseType::NotEq | &ClauseType::Is | &ClauseType::Eq => Some(Fixity::In),
|
|
||||||
&ClauseType::Op(_, fixity, _) => Some(fixity),
|
&ClauseType::Op(_, fixity, _) => Some(fixity),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
@@ -810,68 +916,30 @@ impl ClauseType {
|
|||||||
|
|
||||||
pub fn name(&self) -> ClauseName {
|
pub fn name(&self) -> ClauseName {
|
||||||
match self {
|
match self {
|
||||||
&ClauseType::AcyclicTerm => clause_name!("acyclic_term"),
|
|
||||||
&ClauseType::Arg => clause_name!("arg"),
|
|
||||||
&ClauseType::CallN => clause_name!("call"),
|
&ClauseType::CallN => clause_name!("call"),
|
||||||
&ClauseType::CallWithInferenceLimit => clause_name!("call_with_inference_limit"),
|
&ClauseType::BuiltIn(built_in) => built_in.name(),
|
||||||
&ClauseType::Catch => clause_name!("catch"),
|
|
||||||
&ClauseType::Compare => clause_name!("compare"),
|
|
||||||
&ClauseType::CompareTerm(qt) => clause_name!(qt.name()),
|
|
||||||
&ClauseType::CyclicTerm => clause_name!("cyclic_term"),
|
|
||||||
&ClauseType::Display => clause_name!("display"),
|
|
||||||
&ClauseType::DuplicateTerm => clause_name!("duplicate_term"),
|
|
||||||
&ClauseType::Eq => clause_name!("=="),
|
|
||||||
&ClauseType::Functor => clause_name!("functor"),
|
|
||||||
&ClauseType::Ground => clause_name!("ground"),
|
|
||||||
&ClauseType::Inlined(inlined) => clause_name!(inlined.name()),
|
&ClauseType::Inlined(inlined) => clause_name!(inlined.name()),
|
||||||
&ClauseType::Is => clause_name!("is"),
|
|
||||||
&ClauseType::KeySort => clause_name!("keysort"),
|
|
||||||
&ClauseType::NotEq => clause_name!("\\=="),
|
|
||||||
&ClauseType::Op(ref name, ..) => name.clone(),
|
&ClauseType::Op(ref name, ..) => name.clone(),
|
||||||
&ClauseType::Named(ref name, ..) => name.clone(),
|
&ClauseType::Named(ref name, ..) => name.clone(),
|
||||||
&ClauseType::SetupCallCleanup => clause_name!("setup_call_cleanup"),
|
|
||||||
&ClauseType::System(ref system) => system.name(),
|
|
||||||
&ClauseType::Sort => clause_name!("sort"),
|
|
||||||
&ClauseType::Throw => clause_name!("throw")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from(name: ClauseName, arity: usize, fixity: Option<Fixity>) -> Self {
|
pub fn from(name: ClauseName, arity: usize, fixity: Option<Fixity>) -> Self {
|
||||||
if let Some(inlined_ct) = InlinedClauseType::from(name.as_str(), arity) {
|
InlinedClauseType::from(name.as_str(), arity)
|
||||||
return ClauseType::Inlined(inlined_ct);
|
.map(ClauseType::Inlined)
|
||||||
}
|
.unwrap_or_else(|| {
|
||||||
|
BuiltInClauseType::from(name.as_str(), arity)
|
||||||
match (name.as_str(), arity) {
|
.map(ClauseType::BuiltIn)
|
||||||
("acyclic_term", 1) => ClauseType::AcyclicTerm,
|
.unwrap_or_else(|| {
|
||||||
("arg", 3) => ClauseType::Arg,
|
if let Some(fixity) = fixity {
|
||||||
("call", _) => ClauseType::CallN,
|
ClauseType::Op(name, fixity, CodeIndex::default())
|
||||||
("call_with_inference_limit", 3) => ClauseType::CallWithInferenceLimit,
|
} else if name.as_str() == "call" {
|
||||||
("catch", 3) => ClauseType::Catch,
|
ClauseType::CallN
|
||||||
("compare", 3) => ClauseType::Compare,
|
} else {
|
||||||
("cyclic_term", 1) => ClauseType::CyclicTerm,
|
ClauseType::Named(name, CodeIndex::default())
|
||||||
("@>", 2) => ClauseType::CompareTerm(CompareTermQT::GreaterThan),
|
}
|
||||||
("@<", 2) => ClauseType::CompareTerm(CompareTermQT::LessThan),
|
})
|
||||||
("@>=", 2) => ClauseType::CompareTerm(CompareTermQT::GreaterThanOrEqual),
|
})
|
||||||
("@<=", 2) => ClauseType::CompareTerm(CompareTermQT::LessThanOrEqual),
|
|
||||||
("\\=@=", 2) => ClauseType::CompareTerm(CompareTermQT::NotEqual),
|
|
||||||
("=@=", 2) => ClauseType::CompareTerm(CompareTermQT::Equal),
|
|
||||||
("display", 1) => ClauseType::Display,
|
|
||||||
("duplicate_term", 2) => ClauseType::DuplicateTerm,
|
|
||||||
("==", 2) => ClauseType::Eq,
|
|
||||||
("functor", 3) => ClauseType::Functor,
|
|
||||||
("ground", 1) => ClauseType::Ground,
|
|
||||||
("is", 2) => ClauseType::Is,
|
|
||||||
("keysort", 2) => ClauseType::KeySort,
|
|
||||||
("\\==", 2) => ClauseType::NotEq,
|
|
||||||
("setup_call_cleanup", 3) => ClauseType::SetupCallCleanup,
|
|
||||||
("sort", 2) => ClauseType::Sort,
|
|
||||||
("throw", 1) => ClauseType::Throw,
|
|
||||||
_ => if let Some(fixity) = fixity {
|
|
||||||
ClauseType::Op(name, fixity, CodeIndex::default())
|
|
||||||
} else {
|
|
||||||
ClauseType::Named(name, CodeIndex::default())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -902,18 +970,21 @@ impl<'a> TermRef<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum ChoiceInstruction {
|
pub enum ChoiceInstruction {
|
||||||
RetryMeElse(usize),
|
RetryMeElse(usize),
|
||||||
TrustMe,
|
TrustMe,
|
||||||
TryMeElse(usize)
|
TryMeElse(usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum CutInstruction {
|
pub enum CutInstruction {
|
||||||
Cut(RegType),
|
Cut(RegType),
|
||||||
GetLevel(RegType),
|
GetLevel(RegType),
|
||||||
NeckCut
|
NeckCut
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum IndexedChoiceInstruction {
|
pub enum IndexedChoiceInstruction {
|
||||||
Retry(usize),
|
Retry(usize),
|
||||||
Trust(usize),
|
Trust(usize),
|
||||||
@@ -1219,6 +1290,7 @@ impl ArithmeticTerm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum ArithmeticInstruction {
|
pub enum ArithmeticInstruction {
|
||||||
Add(ArithmeticTerm, ArithmeticTerm, usize),
|
Add(ArithmeticTerm, ArithmeticTerm, usize),
|
||||||
Sub(ArithmeticTerm, ArithmeticTerm, usize),
|
Sub(ArithmeticTerm, ArithmeticTerm, usize),
|
||||||
@@ -1237,8 +1309,8 @@ pub enum ArithmeticInstruction {
|
|||||||
Neg(ArithmeticTerm, usize)
|
Neg(ArithmeticTerm, usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum BuiltInInstruction {
|
pub enum BuiltInInstruction {
|
||||||
CallInlined(InlinedClauseType, Vec<RegType>),
|
|
||||||
CleanUpBlock,
|
CleanUpBlock,
|
||||||
CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm),
|
CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm),
|
||||||
DefaultRetryMeElse(usize),
|
DefaultRetryMeElse(usize),
|
||||||
@@ -1254,7 +1326,6 @@ pub enum BuiltInInstruction {
|
|||||||
InstallCleaner,
|
InstallCleaner,
|
||||||
InstallInferenceCounter(RegType, RegType, RegType),
|
InstallInferenceCounter(RegType, RegType, RegType),
|
||||||
InstallNewBlock,
|
InstallNewBlock,
|
||||||
InternalCallN,
|
|
||||||
RemoveCallPolicyCheck,
|
RemoveCallPolicyCheck,
|
||||||
RemoveInferenceCounter(RegType, RegType),
|
RemoveInferenceCounter(RegType, RegType),
|
||||||
ResetBlock,
|
ResetBlock,
|
||||||
@@ -1292,6 +1363,7 @@ impl ControlInstruction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum IndexingInstruction {
|
pub enum IndexingInstruction {
|
||||||
SwitchOnTerm(usize, usize, usize, usize),
|
SwitchOnTerm(usize, usize, usize, usize),
|
||||||
SwitchOnConstant(usize, HashMap<Constant, usize>),
|
SwitchOnConstant(usize, HashMap<Constant, usize>),
|
||||||
@@ -1304,6 +1376,7 @@ impl From<IndexingInstruction> for Line {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum FactInstruction {
|
pub enum FactInstruction {
|
||||||
GetConstant(Level, Constant, RegType),
|
GetConstant(Level, Constant, RegType),
|
||||||
GetList(Level, RegType),
|
GetList(Level, RegType),
|
||||||
@@ -1317,6 +1390,7 @@ pub enum FactInstruction {
|
|||||||
UnifyVoid(usize)
|
UnifyVoid(usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum QueryInstruction {
|
pub enum QueryInstruction {
|
||||||
GetVariable(RegType, usize),
|
GetVariable(RegType, usize),
|
||||||
PutConstant(Level, Constant, RegType),
|
PutConstant(Level, Constant, RegType),
|
||||||
@@ -1336,6 +1410,7 @@ pub type CompiledFact = Vec<FactInstruction>;
|
|||||||
|
|
||||||
pub type CompiledQuery = Vec<QueryInstruction>;
|
pub type CompiledQuery = Vec<QueryInstruction>;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum Line {
|
pub enum Line {
|
||||||
Arithmetic(ArithmeticInstruction),
|
Arithmetic(ArithmeticInstruction),
|
||||||
BuiltIn(BuiltInInstruction),
|
BuiltIn(BuiltInInstruction),
|
||||||
@@ -1474,27 +1549,60 @@ impl From<(usize, ClauseName)> for CodeIndex {
|
|||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub enum CodePtr {
|
pub enum CodePtr {
|
||||||
|
BuiltInClause(BuiltInClauseType, LocalCodePtr), // local is the successor call.
|
||||||
|
CallN(usize, LocalCodePtr), // the arity of the call, successor call.
|
||||||
|
Local(LocalCodePtr)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CodePtr {
|
||||||
|
pub fn local(&self) -> LocalCodePtr {
|
||||||
|
match self {
|
||||||
|
&CodePtr::BuiltInClause(_, ref local)
|
||||||
|
| &CodePtr::CallN(_, ref local)
|
||||||
|
| &CodePtr::Local(ref local) => local.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq)]
|
||||||
|
pub enum LocalCodePtr {
|
||||||
DirEntry(usize, ClauseName), // offset, resident module name.
|
DirEntry(usize, ClauseName), // offset, resident module name.
|
||||||
TopLevel(usize, usize) // chunk_num, offset.
|
TopLevel(usize, usize) // chunk_num, offset.
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CodePtr {
|
impl LocalCodePtr {
|
||||||
pub fn module_name(&self) -> ClauseName {
|
pub fn module_name(&self) -> ClauseName {
|
||||||
match self {
|
match self {
|
||||||
&CodePtr::DirEntry(_, ref name) => name.clone(),
|
&LocalCodePtr::DirEntry(_, ref name) => name.clone(),
|
||||||
_ => ClauseName::BuiltIn("user")
|
_ => ClauseName::BuiltIn("user")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn assign_if_local(&mut self, cp: CodePtr) {
|
||||||
|
match cp {
|
||||||
|
CodePtr::Local(local) => *self = local,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialOrd<CodePtr> for CodePtr {
|
impl PartialOrd<CodePtr> for CodePtr {
|
||||||
fn partial_cmp(&self, other: &CodePtr) -> Option<Ordering> {
|
fn partial_cmp(&self, other: &CodePtr) -> Option<Ordering> {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(&CodePtr::DirEntry(p1, _), &CodePtr::DirEntry(p2, _)) =>
|
(&CodePtr::Local(ref l1), &CodePtr::Local(ref l2)) => l1.partial_cmp(l2),
|
||||||
|
_ => Some(Ordering::Greater)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd<LocalCodePtr> for LocalCodePtr {
|
||||||
|
fn partial_cmp(&self, other: &LocalCodePtr) -> Option<Ordering> {
|
||||||
|
match (self, other) {
|
||||||
|
(&LocalCodePtr::DirEntry(p1, _), &LocalCodePtr::DirEntry(p2, _)) =>
|
||||||
p1.partial_cmp(&p2),
|
p1.partial_cmp(&p2),
|
||||||
(&CodePtr::DirEntry(..), &CodePtr::TopLevel(_, _)) =>
|
(&LocalCodePtr::DirEntry(..), &LocalCodePtr::TopLevel(_, _)) =>
|
||||||
Some(Ordering::Less),
|
Some(Ordering::Less),
|
||||||
(&CodePtr::TopLevel(_, p1), &CodePtr::TopLevel(_, ref p2)) =>
|
(&LocalCodePtr::TopLevel(_, p1), &LocalCodePtr::TopLevel(_, ref p2)) =>
|
||||||
p1.partial_cmp(p2),
|
p1.partial_cmp(p2),
|
||||||
_ => Some(Ordering::Greater)
|
_ => Some(Ordering::Greater)
|
||||||
}
|
}
|
||||||
@@ -1503,7 +1611,33 @@ impl PartialOrd<CodePtr> for CodePtr {
|
|||||||
|
|
||||||
impl Default for CodePtr {
|
impl Default for CodePtr {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
CodePtr::TopLevel(0, 0)
|
CodePtr::Local(LocalCodePtr::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for LocalCodePtr {
|
||||||
|
fn default() -> Self {
|
||||||
|
LocalCodePtr::TopLevel(0, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add<usize> for LocalCodePtr {
|
||||||
|
type Output = LocalCodePtr;
|
||||||
|
|
||||||
|
fn add(self, rhs: usize) -> Self::Output {
|
||||||
|
match self {
|
||||||
|
LocalCodePtr::DirEntry(p, name) => LocalCodePtr::DirEntry(p + rhs, name),
|
||||||
|
LocalCodePtr::TopLevel(cn, p) => LocalCodePtr::TopLevel(cn, p + rhs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AddAssign<usize> for LocalCodePtr {
|
||||||
|
fn add_assign(&mut self, rhs: usize) {
|
||||||
|
match self {
|
||||||
|
&mut LocalCodePtr::DirEntry(ref mut p, _) |
|
||||||
|
&mut LocalCodePtr::TopLevel(_, ref mut p) => *p += rhs
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1512,8 +1646,9 @@ impl Add<usize> for CodePtr {
|
|||||||
|
|
||||||
fn add(self, rhs: usize) -> Self::Output {
|
fn add(self, rhs: usize) -> Self::Output {
|
||||||
match self {
|
match self {
|
||||||
CodePtr::DirEntry(p, name) => CodePtr::DirEntry(p + rhs, name),
|
CodePtr::Local(local) => CodePtr::Local(local + rhs),
|
||||||
CodePtr::TopLevel(cn, p) => CodePtr::TopLevel(cn, p + rhs)
|
CodePtr::BuiltInClause(_, local) => CodePtr::Local(local + rhs),
|
||||||
|
CodePtr::CallN(_, local) => CodePtr::Local(local + rhs),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1521,8 +1656,8 @@ impl Add<usize> for CodePtr {
|
|||||||
impl AddAssign<usize> for CodePtr {
|
impl AddAssign<usize> for CodePtr {
|
||||||
fn add_assign(&mut self, rhs: usize) {
|
fn add_assign(&mut self, rhs: usize) {
|
||||||
match self {
|
match self {
|
||||||
&mut CodePtr::DirEntry(ref mut p, _) |
|
&mut CodePtr::Local(ref mut local) => *local += rhs,
|
||||||
&mut CodePtr::TopLevel(_, ref mut p) => *p += rhs
|
_ => *self = CodePtr::Local(self.local() + rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
use prolog::ast::*;
|
use prolog::ast::*;
|
||||||
use prolog::num::bigint::{BigInt};
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
// from 7.12.2 b) of 13211-1:1995
|
// from 7.12.2 b) of 13211-1:1995
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
@@ -92,6 +90,7 @@ impl EvalError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
fn get_builtins() -> Code {
|
fn get_builtins() -> Code {
|
||||||
vec![internal_call_n!(), // callN/N, 0.
|
vec![internal_call_n!(), // callN/N, 0.
|
||||||
is_atomic!(temp_v!(1)), // atomic/1, 1.
|
is_atomic!(temp_v!(1)), // atomic/1, 1.
|
||||||
@@ -737,7 +736,7 @@ fn get_builtins() -> Code {
|
|||||||
acyclic_term_execute!(), // acyclic_term/1, 485.
|
acyclic_term_execute!(), // acyclic_term/1, 485.
|
||||||
cyclic_term_execute!(), // cyclic_term/1, 486.
|
cyclic_term_execute!(), // cyclic_term/1, 486.
|
||||||
]
|
]
|
||||||
}
|
} */
|
||||||
|
|
||||||
pub fn default_op_dir() -> OpDir
|
pub fn default_op_dir() -> OpDir
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
|
|||||||
-> Result<(), ParserError>
|
-> Result<(), ParserError>
|
||||||
{
|
{
|
||||||
match ct {
|
match ct {
|
||||||
InlinedClauseType::CompareNumber(cmp) => {
|
InlinedClauseType::CompareNumber(cmp, ..) => {
|
||||||
let (mut lcode, at_1) = self.call_arith_eval(terms[0].as_ref(), 1)?;
|
let (mut lcode, at_1) = self.call_arith_eval(terms[0].as_ref(), 1)?;
|
||||||
let (mut rcode, at_2) = self.call_arith_eval(terms[1].as_ref(), 2)?;
|
let (mut rcode, at_2) = self.call_arith_eval(terms[1].as_ref(), 2)?;
|
||||||
|
|
||||||
@@ -265,7 +265,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
|
|||||||
at_1.unwrap_or(interm!(1)),
|
at_1.unwrap_or(interm!(1)),
|
||||||
at_2.unwrap_or(interm!(2))));
|
at_2.unwrap_or(interm!(2))));
|
||||||
},
|
},
|
||||||
InlinedClauseType::IsAtom =>
|
InlinedClauseType::IsAtom(..) =>
|
||||||
match terms[0].as_ref() {
|
match terms[0].as_ref() {
|
||||||
&Term::Constant(_, Constant::Atom(_)) => {
|
&Term::Constant(_, Constant::Atom(_)) => {
|
||||||
code.push(succeed!());
|
code.push(succeed!());
|
||||||
@@ -278,7 +278,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
|
|||||||
code.push(fail!());
|
code.push(fail!());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InlinedClauseType::IsAtomic =>
|
InlinedClauseType::IsAtomic(..) =>
|
||||||
match terms[0].as_ref() {
|
match terms[0].as_ref() {
|
||||||
&Term::AnonVar | &Term::Clause(..) | &Term::Cons(..) => {
|
&Term::AnonVar | &Term::Clause(..) | &Term::Cons(..) => {
|
||||||
code.push(fail!());
|
code.push(fail!());
|
||||||
@@ -291,7 +291,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
|
|||||||
code.push(is_atomic!(r));
|
code.push(is_atomic!(r));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InlinedClauseType::IsCompound =>
|
InlinedClauseType::IsCompound(..) =>
|
||||||
match terms[0].as_ref() {
|
match terms[0].as_ref() {
|
||||||
&Term::Clause(..) | &Term::Cons(..) => {
|
&Term::Clause(..) | &Term::Cons(..) => {
|
||||||
code.push(succeed!());
|
code.push(succeed!());
|
||||||
@@ -304,7 +304,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
|
|||||||
code.push(fail!());
|
code.push(fail!());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InlinedClauseType::IsRational =>
|
InlinedClauseType::IsRational(..) =>
|
||||||
match terms[0].as_ref() {
|
match terms[0].as_ref() {
|
||||||
&Term::Constant(_, Constant::Number(Number::Rational(_))) => {
|
&Term::Constant(_, Constant::Number(Number::Rational(_))) => {
|
||||||
code.push(succeed!());
|
code.push(succeed!());
|
||||||
@@ -317,7 +317,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
|
|||||||
code.push(fail!());
|
code.push(fail!());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InlinedClauseType::IsFloat =>
|
InlinedClauseType::IsFloat(..) =>
|
||||||
match terms[0].as_ref() {
|
match terms[0].as_ref() {
|
||||||
&Term::Constant(_, Constant::Number(Number::Float(_))) => {
|
&Term::Constant(_, Constant::Number(Number::Float(_))) => {
|
||||||
code.push(succeed!());
|
code.push(succeed!());
|
||||||
@@ -330,7 +330,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
|
|||||||
code.push(fail!());
|
code.push(fail!());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InlinedClauseType::IsString =>
|
InlinedClauseType::IsString(..) =>
|
||||||
match terms[0].as_ref() {
|
match terms[0].as_ref() {
|
||||||
&Term::Constant(_, Constant::String(_)) => {
|
&Term::Constant(_, Constant::String(_)) => {
|
||||||
code.push(succeed!());
|
code.push(succeed!());
|
||||||
@@ -343,7 +343,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
|
|||||||
code.push(fail!());
|
code.push(fail!());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InlinedClauseType::IsNonVar =>
|
InlinedClauseType::IsNonVar(..) =>
|
||||||
match terms[0].as_ref() {
|
match terms[0].as_ref() {
|
||||||
&Term::AnonVar => {
|
&Term::AnonVar => {
|
||||||
code.push(fail!());
|
code.push(fail!());
|
||||||
@@ -356,7 +356,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
|
|||||||
code.push(succeed!());
|
code.push(succeed!());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InlinedClauseType::IsInteger =>
|
InlinedClauseType::IsInteger(..) =>
|
||||||
match terms[0].as_ref() {
|
match terms[0].as_ref() {
|
||||||
&Term::Constant(_, Constant::Number(Number::Integer(_))) => {
|
&Term::Constant(_, Constant::Number(Number::Integer(_))) => {
|
||||||
code.push(succeed!());
|
code.push(succeed!());
|
||||||
@@ -369,7 +369,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
|
|||||||
code.push(fail!());
|
code.push(fail!());
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
InlinedClauseType::IsVar =>
|
InlinedClauseType::IsVar(..) =>
|
||||||
match terms[0].as_ref() {
|
match terms[0].as_ref() {
|
||||||
&Term::Constant(..) | &Term::Clause(..) | &Term::Cons(..) => {
|
&Term::Constant(..) | &Term::Clause(..) | &Term::Cons(..) => {
|
||||||
code.push(fail!());
|
code.push(fail!());
|
||||||
@@ -416,7 +416,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
|
|||||||
} else {
|
} else {
|
||||||
Line::Cut(CutInstruction::Cut(perm_v!(1)))
|
Line::Cut(CutInstruction::Cut(perm_v!(1)))
|
||||||
}),
|
}),
|
||||||
&QueryTerm::Clause(_, ClauseType::Is, ref terms) => {
|
&QueryTerm::Clause(_, ClauseType::BuiltIn(BuiltInClauseType::Is), ref terms) =>
|
||||||
|
{
|
||||||
let (mut acode, at) = self.call_arith_eval(terms[1].as_ref(), 1)?;
|
let (mut acode, at) = self.call_arith_eval(terms[1].as_ref(), 1)?;
|
||||||
code.append(&mut acode);
|
code.append(&mut acode);
|
||||||
|
|
||||||
|
|||||||
@@ -173,10 +173,6 @@ impl fmt::Display for IndexedChoiceInstruction {
|
|||||||
impl fmt::Display for BuiltInInstruction {
|
impl fmt::Display for BuiltInInstruction {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
&BuiltInInstruction::CallInlined(InlinedClauseType::CompareNumber(cmp), ref rs) =>
|
|
||||||
write!(f, "number_test {}, {}, {}", cmp, &rs[0], &rs[1]),
|
|
||||||
&BuiltInInstruction::CallInlined(ict, ref rs) =>
|
|
||||||
write!(f, "call_inlined_{}, {}", ict.name(), &rs[0]),
|
|
||||||
&BuiltInInstruction::CleanUpBlock =>
|
&BuiltInInstruction::CleanUpBlock =>
|
||||||
write!(f, "clean_up_block"),
|
write!(f, "clean_up_block"),
|
||||||
&BuiltInInstruction::CompareNumber(cmp, ref at_1, ref at_2) =>
|
&BuiltInInstruction::CompareNumber(cmp, ref at_1, ref at_2) =>
|
||||||
@@ -209,8 +205,6 @@ impl fmt::Display for BuiltInInstruction {
|
|||||||
write!(f, "install_cleaner"),
|
write!(f, "install_cleaner"),
|
||||||
&BuiltInInstruction::InstallNewBlock =>
|
&BuiltInInstruction::InstallNewBlock =>
|
||||||
write!(f, "install_new_block"),
|
write!(f, "install_new_block"),
|
||||||
&BuiltInInstruction::InternalCallN =>
|
|
||||||
write!(f, "internal_call_N"),
|
|
||||||
&BuiltInInstruction::RemoveCallPolicyCheck =>
|
&BuiltInInstruction::RemoveCallPolicyCheck =>
|
||||||
write!(f, "remove_call_policy_check"),
|
write!(f, "remove_call_policy_check"),
|
||||||
&BuiltInInstruction::RemoveInferenceCounter(r1, r2) =>
|
&BuiltInInstruction::RemoveInferenceCounter(r1, r2) =>
|
||||||
|
|||||||
@@ -341,7 +341,8 @@ impl<'a> ChunkedIterator<'a>
|
|||||||
result.push(term),
|
result.push(term),
|
||||||
ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::Inlined(_), _)) =>
|
ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::Inlined(_), _)) =>
|
||||||
result.push(term),
|
result.push(term),
|
||||||
ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::CallN, ref subterms)) => {
|
ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::CallN, ref subterms)) =>
|
||||||
|
{
|
||||||
result.push(term);
|
result.push(term);
|
||||||
arity = subterms.len() + 1;
|
arity = subterms.len() + 1;
|
||||||
break;
|
break;
|
||||||
|
|||||||
29
src/prolog/lib/builtins.pl
Normal file
29
src/prolog/lib/builtins.pl
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
:- op(400, yfx, /).
|
||||||
|
|
||||||
|
:- module(builtins, [(+)/2, (*)/2, (-)/2, (/)/2, (/\)/2, (\/)/2, (is)/2,
|
||||||
|
(xor)/2, (div)/2, (//)/2, (rdiv)/2, (<<)/2, (>>)/2, (mod)/2,
|
||||||
|
(rem)/2, (>)/2, (<)/2, (=\=)/2, (=:=)/2, (>=)/2, (=<)/2]).
|
||||||
|
|
||||||
|
% arithmetic operators.
|
||||||
|
:- op(700, xfx, is).
|
||||||
|
:- op(500, yfx, +).
|
||||||
|
:- op(500, yfx, -).
|
||||||
|
:- op(400, yfx, *).
|
||||||
|
:- op(500, yfx, /\).
|
||||||
|
:- op(500, yfx, \/).
|
||||||
|
:- op(500, yfx, xor).
|
||||||
|
:- op(400, yfx, div).
|
||||||
|
:- op(400, yfx, //).
|
||||||
|
:- op(400, yfx, rdiv).
|
||||||
|
:- op(400, yfx, <<).
|
||||||
|
:- op(400, yfx, >>).
|
||||||
|
:- op(400, yfx, mod).
|
||||||
|
:- op(400, yfx, rem).
|
||||||
|
|
||||||
|
% arithmetic comparison operators.
|
||||||
|
:- op(700, xfx, >).
|
||||||
|
:- op(700, xfx, <).
|
||||||
|
:- op(700, xfx, =\=).
|
||||||
|
:- op(700, xfx, =:=).
|
||||||
|
:- op(700, xfx, >=).
|
||||||
|
:- op(700, xfx, =<).
|
||||||
@@ -209,7 +209,7 @@ pub struct MachineState {
|
|||||||
pub(super) b0: usize,
|
pub(super) b0: usize,
|
||||||
pub(super) e: usize,
|
pub(super) e: usize,
|
||||||
pub(super) num_of_args: usize,
|
pub(super) num_of_args: usize,
|
||||||
pub(super) cp: CodePtr,
|
pub(super) cp: LocalCodePtr,
|
||||||
pub(super) fail: bool,
|
pub(super) fail: bool,
|
||||||
pub(crate) heap: Heap,
|
pub(crate) heap: Heap,
|
||||||
pub(super) mode: MachineMode,
|
pub(super) mode: MachineMode,
|
||||||
@@ -248,10 +248,10 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
IndexPtr::Index(compiled_tl_index) => {
|
IndexPtr::Index(compiled_tl_index) => {
|
||||||
let module_name = idx.0.borrow().1.clone();
|
let module_name = idx.0.borrow().1.clone();
|
||||||
|
|
||||||
machine_st.cp = machine_st.p.clone() + 1;
|
machine_st.cp.assign_if_local(machine_st.p.clone() + 1);
|
||||||
machine_st.num_of_args = arity;
|
machine_st.num_of_args = arity;
|
||||||
machine_st.b0 = machine_st.b;
|
machine_st.b0 = machine_st.b;
|
||||||
machine_st.p = CodePtr::DirEntry(compiled_tl_index, module_name);
|
machine_st.p = dir_entry!(compiled_tl_index, module_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,7 +270,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
|
|
||||||
machine_st.num_of_args = arity;
|
machine_st.num_of_args = arity;
|
||||||
machine_st.b0 = machine_st.b;
|
machine_st.b0 = machine_st.b;
|
||||||
machine_st.p = CodePtr::DirEntry(compiled_tl_index, module_name);
|
machine_st.p = dir_entry!(compiled_tl_index, module_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,55 +400,66 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_call_clause<'a>(&mut self, machine_st: &mut MachineState, code_dirs: CodeDirs<'a>,
|
fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize,
|
||||||
ct: &ClauseType, arity: usize, lco: bool)
|
code_dirs: CodeDirs<'a>, lco: bool)
|
||||||
-> CallResult
|
-> CallResult
|
||||||
|
{
|
||||||
|
loop {
|
||||||
|
if let Some((name, mut arity)) = machine_st.setup_call_n(arity) {
|
||||||
|
let user = clause_name!("user");
|
||||||
|
|
||||||
|
if machine_st.fail {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
match ClauseType::from(name.clone(), arity, None) {
|
||||||
|
ClauseType::CallN => {
|
||||||
|
machine_st.num_of_args = arity;
|
||||||
|
machine_st.handle_internal_call_n();
|
||||||
|
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
ClauseType::BuiltIn(built_in) =>
|
||||||
|
machine_st.setup_built_in_call(built_in, lco),
|
||||||
|
ClauseType::Inlined(inlined) =>
|
||||||
|
machine_st.execute_inlined(&inlined),
|
||||||
|
ClauseType::Op(..) | ClauseType::Named(..) =>
|
||||||
|
if let Some(idx) = code_dirs.get(name.clone(), arity, user) {
|
||||||
|
self.context_call(machine_st, name, arity, idx, lco)?;
|
||||||
|
} else {
|
||||||
|
return Err(machine_st.existence_error(name, arity));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn system_call(&mut self, machine_st: &mut MachineState, ct: &SystemClauseType) -> CallResult
|
||||||
{
|
{
|
||||||
match ct {
|
match ct {
|
||||||
&ClauseType::AcyclicTerm => {
|
&SystemClauseType::SkipMaxList => {
|
||||||
|
machine_st.skip_max_list()?;
|
||||||
|
machine_st.p += 1;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType, lco: bool)
|
||||||
|
-> CallResult
|
||||||
|
{
|
||||||
|
match ct {
|
||||||
|
&BuiltInClauseType::AcyclicTerm => {
|
||||||
let addr = machine_st[temp_v!(1)].clone();
|
let addr = machine_st[temp_v!(1)].clone();
|
||||||
machine_st.fail = machine_st.is_cyclic_term(addr);
|
machine_st.fail = machine_st.is_cyclic_term(addr);
|
||||||
return_from_clause!(lco, machine_st)
|
return_from_clause!(lco, machine_st)
|
||||||
},
|
},
|
||||||
&ClauseType::Arg => {
|
&BuiltInClauseType::Compare => {
|
||||||
if !lco {
|
|
||||||
machine_st.cp = machine_st.p.clone() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
machine_st.num_of_args = 3;
|
|
||||||
machine_st.b0 = machine_st.b;
|
|
||||||
machine_st.p = CodePtr::DirEntry(166, clause_name!("builtin"));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
&ClauseType::Catch => {
|
|
||||||
if !lco {
|
|
||||||
machine_st.cp = machine_st.p.clone() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
machine_st.num_of_args = 3;
|
|
||||||
machine_st.b0 = machine_st.b;
|
|
||||||
machine_st.p = CodePtr::DirEntry(5, clause_name!("builtin"));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
&ClauseType::CallN =>
|
|
||||||
if let Some((name, arity)) = machine_st.setup_call_n(arity) {
|
|
||||||
let user = clause_name!("user");
|
|
||||||
|
|
||||||
match ClauseType::from(name.clone(), arity, None) {
|
|
||||||
ClauseType::Op(..) | ClauseType::Named(..) =>
|
|
||||||
if let Some(idx) = code_dirs.get(name.clone(), arity, user) {
|
|
||||||
self.context_call(machine_st, name, arity, idx, lco)
|
|
||||||
} else {
|
|
||||||
Err(machine_st.existence_error(name, arity))
|
|
||||||
},
|
|
||||||
ct => self.try_call_clause(machine_st, code_dirs, &ct, arity, lco),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
&ClauseType::Compare => {
|
|
||||||
let a1 = machine_st[temp_v!(1)].clone();
|
let a1 = machine_st[temp_v!(1)].clone();
|
||||||
let a2 = machine_st[temp_v!(2)].clone();
|
let a2 = machine_st[temp_v!(2)].clone();
|
||||||
let a3 = machine_st[temp_v!(3)].clone();
|
let a3 = machine_st[temp_v!(3)].clone();
|
||||||
@@ -462,7 +473,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
machine_st.unify(a1, c);
|
machine_st.unify(a1, c);
|
||||||
return_from_clause!(lco, machine_st)
|
return_from_clause!(lco, machine_st)
|
||||||
},
|
},
|
||||||
&ClauseType::CompareTerm(qt) => {
|
&BuiltInClauseType::CompareTerm(qt) => {
|
||||||
match qt {
|
match qt {
|
||||||
CompareTermQT::Equal =>
|
CompareTermQT::Equal =>
|
||||||
machine_st.fail = machine_st.structural_eq_test(),
|
machine_st.fail = machine_st.structural_eq_test(),
|
||||||
@@ -473,12 +484,12 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
|
|
||||||
return_from_clause!(lco, machine_st)
|
return_from_clause!(lco, machine_st)
|
||||||
},
|
},
|
||||||
&ClauseType::CyclicTerm => {
|
&BuiltInClauseType::CyclicTerm => {
|
||||||
let addr = machine_st[temp_v!(1)].clone();
|
let addr = machine_st[temp_v!(1)].clone();
|
||||||
machine_st.fail = !machine_st.is_cyclic_term(addr);
|
machine_st.fail = !machine_st.is_cyclic_term(addr);
|
||||||
return_from_clause!(lco, machine_st)
|
return_from_clause!(lco, machine_st)
|
||||||
},
|
},
|
||||||
&ClauseType::Display => {
|
&BuiltInClauseType::Display => {
|
||||||
let output = machine_st.print_term(machine_st[temp_v!(1)].clone(),
|
let output = machine_st.print_term(machine_st[temp_v!(1)].clone(),
|
||||||
DisplayFormatter {},
|
DisplayFormatter {},
|
||||||
PrinterOutputter::new());
|
PrinterOutputter::new());
|
||||||
@@ -486,27 +497,27 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
println!("{}", output.result());
|
println!("{}", output.result());
|
||||||
return_from_clause!(lco, machine_st)
|
return_from_clause!(lco, machine_st)
|
||||||
},
|
},
|
||||||
&ClauseType::DuplicateTerm => {
|
&BuiltInClauseType::DuplicateTerm => {
|
||||||
machine_st.duplicate_term();
|
machine_st.duplicate_term();
|
||||||
return_from_clause!(lco, machine_st)
|
return_from_clause!(lco, machine_st)
|
||||||
},
|
},
|
||||||
&ClauseType::Eq => {
|
&BuiltInClauseType::Eq => {
|
||||||
machine_st.fail = machine_st.eq_test();
|
machine_st.fail = machine_st.eq_test();
|
||||||
return_from_clause!(lco, machine_st)
|
return_from_clause!(lco, machine_st)
|
||||||
},
|
},
|
||||||
&ClauseType::Ground => {
|
&BuiltInClauseType::Ground => {
|
||||||
machine_st.fail = machine_st.ground_test();
|
machine_st.fail = machine_st.ground_test();
|
||||||
return_from_clause!(lco, machine_st)
|
return_from_clause!(lco, machine_st)
|
||||||
},
|
},
|
||||||
&ClauseType::Functor => {
|
&BuiltInClauseType::Functor => {
|
||||||
machine_st.try_functor()?;
|
machine_st.try_functor()?;
|
||||||
return_from_clause!(lco, machine_st)
|
return_from_clause!(lco, machine_st)
|
||||||
},
|
},
|
||||||
&ClauseType::NotEq => {
|
&BuiltInClauseType::NotEq => {
|
||||||
machine_st.fail = !machine_st.eq_test();
|
machine_st.fail = !machine_st.eq_test();
|
||||||
return_from_clause!(lco, machine_st)
|
return_from_clause!(lco, machine_st)
|
||||||
},
|
},
|
||||||
&ClauseType::Sort => {
|
&BuiltInClauseType::Sort => {
|
||||||
machine_st.check_sort_errors()?;
|
machine_st.check_sort_errors()?;
|
||||||
|
|
||||||
let stub = machine_st.functor_stub(clause_name!("sort"), 2);
|
let stub = machine_st.functor_stub(clause_name!("sort"), 2);
|
||||||
@@ -522,7 +533,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
|
|
||||||
return_from_clause!(lco, machine_st)
|
return_from_clause!(lco, machine_st)
|
||||||
},
|
},
|
||||||
&ClauseType::KeySort => {
|
&BuiltInClauseType::KeySort => {
|
||||||
machine_st.check_keysort_errors()?;
|
machine_st.check_keysort_errors()?;
|
||||||
|
|
||||||
let stub = machine_st.functor_stub(clause_name!("keysort"), 2);
|
let stub = machine_st.functor_stub(clause_name!("keysort"), 2);
|
||||||
@@ -544,25 +555,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
|
|
||||||
return_from_clause!(lco, machine_st)
|
return_from_clause!(lco, machine_st)
|
||||||
},
|
},
|
||||||
&ClauseType::Throw => {
|
&BuiltInClauseType::Is => {
|
||||||
if !lco {
|
|
||||||
machine_st.cp = machine_st.p.clone() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
machine_st.goto_throw();
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
&ClauseType::Named(ref name, ref idx) | &ClauseType::Op(ref name, _, ref idx) =>
|
|
||||||
self.context_call(machine_st, name.clone(), arity, idx.clone(), lco),
|
|
||||||
&ClauseType::CallWithInferenceLimit => {
|
|
||||||
machine_st.goto_ptr(CodePtr::DirEntry(409, clause_name!("builtin")), 3, lco);
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
&ClauseType::SetupCallCleanup => {
|
|
||||||
machine_st.goto_ptr(CodePtr::DirEntry(310, clause_name!("builtin")), 3, lco);
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
&ClauseType::Is => {
|
|
||||||
let a = machine_st[temp_v!(1)].clone();
|
let a = machine_st[temp_v!(1)].clone();
|
||||||
let result = machine_st.arith_eval_by_metacall(temp_v!(2))?;
|
let result = machine_st.arith_eval_by_metacall(temp_v!(2))?;
|
||||||
|
|
||||||
@@ -571,14 +564,8 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
&ClauseType::Inlined(ref inlined) => {
|
&BuiltInClauseType::System(ref ct) =>
|
||||||
machine_st.execute_inlined(inlined, &vec![temp_v!(1), temp_v!(2)]);
|
self.system_call(machine_st, ct),
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
&ClauseType::System(ref system) => {
|
|
||||||
machine_st.execute_system(system)?;
|
|
||||||
return_from_clause!(lco, machine_st)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -680,11 +667,10 @@ impl CallPolicy for CallWithInferenceLimitCallPolicy {
|
|||||||
self.increment()
|
self.increment()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_call_clause<'a>(&mut self, machine_st: &mut MachineState, code_dirs: CodeDirs<'a>,
|
fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType, lco: bool)
|
||||||
ct: &ClauseType, arity: usize, lco: bool)
|
-> CallResult
|
||||||
-> CallResult
|
|
||||||
{
|
{
|
||||||
self.prev_policy.try_call_clause(machine_st, code_dirs, ct, arity, lco)?;
|
self.prev_policy.call_builtin(machine_st, ct, lco)?;
|
||||||
self.increment()
|
self.increment()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -757,11 +743,11 @@ impl CutPolicy for SetupCallCleanupCutPolicy {
|
|||||||
machine_st.p += 1;
|
machine_st.p += 1;
|
||||||
|
|
||||||
if !self.out_of_cont_pts() {
|
if !self.out_of_cont_pts() {
|
||||||
machine_st.cp = machine_st.p.clone();
|
machine_st.cp.assign_if_local(machine_st.p.clone());
|
||||||
machine_st.num_of_args = 0;
|
machine_st.num_of_args = 0;
|
||||||
machine_st.b0 = machine_st.b;
|
machine_st.b0 = machine_st.b;
|
||||||
// goto_call run_cleaners_without_handling/0, 370.
|
// goto_call run_cleaners_without_handling/0, 370.
|
||||||
machine_st.p = CodePtr::DirEntry(370, clause_name!("builtin"));
|
machine_st.p = dir_entry!(370, clause_name!("builtin"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ impl MachineState {
|
|||||||
b0: 0,
|
b0: 0,
|
||||||
e: 0,
|
e: 0,
|
||||||
num_of_args: 0,
|
num_of_args: 0,
|
||||||
cp: CodePtr::default(),
|
cp: LocalCodePtr::default(),
|
||||||
fail: false,
|
fail: false,
|
||||||
heap: Heap::with_capacity(256),
|
heap: Heap::with_capacity(256),
|
||||||
mode: MachineMode::Write,
|
mode: MachineMode::Write,
|
||||||
@@ -1011,8 +1011,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_internal_call_n<'a>(&mut self, call_policy: &mut Box<CallPolicy>,
|
pub(super) fn handle_internal_call_n(&mut self)
|
||||||
code_dirs: CodeDirs<'a>)
|
|
||||||
{
|
{
|
||||||
let arity = self.num_of_args + 1;
|
let arity = self.num_of_args + 1;
|
||||||
let pred = self.registers[1].clone();
|
let pred = self.registers[1].clone();
|
||||||
@@ -1023,24 +1022,12 @@ impl MachineState {
|
|||||||
|
|
||||||
if arity > 1 {
|
if arity > 1 {
|
||||||
self.registers[arity - 1] = pred;
|
self.registers[arity - 1] = pred;
|
||||||
|
return;
|
||||||
if let Some((name, arity)) = self.setup_call_n(arity - 1) {
|
|
||||||
if let Some(idx) = code_dirs.get(name.clone(), arity, self.p.module_name()) {
|
|
||||||
try_or_fail!(self, call_policy.try_execute(self, name, arity, idx));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.fail = true;
|
self.fail = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn goto_throw(&mut self) {
|
|
||||||
self.num_of_args = 1;
|
|
||||||
self.b0 = self.b;
|
|
||||||
self.p = CodePtr::DirEntry(59, clause_name!("builtin"));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn set_ball(&mut self) {
|
pub(super) fn set_ball(&mut self) {
|
||||||
let addr = self[temp_v!(1)].clone();
|
let addr = self[temp_v!(1)].clone();
|
||||||
self.ball.boundary = self.heap.h;
|
self.ball.boundary = self.heap.h;
|
||||||
@@ -1071,7 +1058,6 @@ impl MachineState {
|
|||||||
self.error_form(self.representation_error(RepFlag::MaxArity), stub);
|
self.error_form(self.representation_error(RepFlag::MaxArity), stub);
|
||||||
|
|
||||||
self.throw_exception(representation_error);
|
self.throw_exception(representation_error);
|
||||||
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1334,20 +1320,15 @@ impl MachineState {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn execute_inlined(&mut self, inlined: &InlinedClauseType, rs: &Vec<RegType>)
|
pub(super) fn execute_inlined(&mut self, inlined: &InlinedClauseType) {
|
||||||
{
|
|
||||||
let r1 = rs[0].clone();
|
|
||||||
|
|
||||||
match inlined {
|
match inlined {
|
||||||
&InlinedClauseType::CompareNumber(cmp) => {
|
&InlinedClauseType::CompareNumber(cmp, r1, r2) => {
|
||||||
let r2 = rs[1].clone();
|
|
||||||
|
|
||||||
let n1 = try_or_fail!(self, self.arith_eval_by_metacall(r1));
|
let n1 = try_or_fail!(self, self.arith_eval_by_metacall(r1));
|
||||||
let n2 = try_or_fail!(self, self.arith_eval_by_metacall(r2));
|
let n2 = try_or_fail!(self, self.arith_eval_by_metacall(r2));
|
||||||
|
|
||||||
self.compare_numbers(cmp, n1, n2);
|
self.compare_numbers(cmp, n1, n2);
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsAtom => {
|
&InlinedClauseType::IsAtom(r1) => {
|
||||||
let d = self.store(self.deref(self[r1].clone()));
|
let d = self.store(self.deref(self[r1].clone()));
|
||||||
|
|
||||||
match d {
|
match d {
|
||||||
@@ -1355,7 +1336,7 @@ impl MachineState {
|
|||||||
_ => self.fail = true
|
_ => self.fail = true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsAtomic => {
|
&InlinedClauseType::IsAtomic(r1) => {
|
||||||
let d = self.store(self.deref(self[r1].clone()));
|
let d = self.store(self.deref(self[r1].clone()));
|
||||||
|
|
||||||
match d {
|
match d {
|
||||||
@@ -1363,7 +1344,7 @@ impl MachineState {
|
|||||||
_ => self.fail = true
|
_ => self.fail = true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsInteger => {
|
&InlinedClauseType::IsInteger(r1) => {
|
||||||
let d = self.store(self.deref(self[r1].clone()));
|
let d = self.store(self.deref(self[r1].clone()));
|
||||||
|
|
||||||
match d {
|
match d {
|
||||||
@@ -1371,7 +1352,7 @@ impl MachineState {
|
|||||||
_ => self.fail = true
|
_ => self.fail = true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsCompound => {
|
&InlinedClauseType::IsCompound(r1) => {
|
||||||
let d = self.store(self.deref(self[r1].clone()));
|
let d = self.store(self.deref(self[r1].clone()));
|
||||||
|
|
||||||
match d {
|
match d {
|
||||||
@@ -1379,7 +1360,7 @@ impl MachineState {
|
|||||||
_ => self.fail = true
|
_ => self.fail = true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsFloat => {
|
&InlinedClauseType::IsFloat(r1) => {
|
||||||
let d = self.store(self.deref(self[r1].clone()));
|
let d = self.store(self.deref(self[r1].clone()));
|
||||||
|
|
||||||
match d {
|
match d {
|
||||||
@@ -1387,7 +1368,7 @@ impl MachineState {
|
|||||||
_ => self.fail = true
|
_ => self.fail = true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsRational => {
|
&InlinedClauseType::IsRational(r1) => {
|
||||||
let d = self.store(self.deref(self[r1].clone()));
|
let d = self.store(self.deref(self[r1].clone()));
|
||||||
|
|
||||||
match d {
|
match d {
|
||||||
@@ -1395,7 +1376,7 @@ impl MachineState {
|
|||||||
_ => self.fail = true
|
_ => self.fail = true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsString => {
|
&InlinedClauseType::IsString(r1) => {
|
||||||
let d = self.store(self.deref(self[r1].clone()));
|
let d = self.store(self.deref(self[r1].clone()));
|
||||||
|
|
||||||
match d {
|
match d {
|
||||||
@@ -1403,7 +1384,7 @@ impl MachineState {
|
|||||||
_ => self.fail = true
|
_ => self.fail = true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsNonVar => {
|
&InlinedClauseType::IsNonVar(r1) => {
|
||||||
let d = self.store(self.deref(self[r1].clone()));
|
let d = self.store(self.deref(self[r1].clone()));
|
||||||
|
|
||||||
match d {
|
match d {
|
||||||
@@ -1411,7 +1392,7 @@ impl MachineState {
|
|||||||
_ => self.p += 1
|
_ => self.p += 1
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsVar => {
|
&InlinedClauseType::IsVar(r1) => {
|
||||||
let d = self.store(self.deref(self[r1].clone()));
|
let d = self.store(self.deref(self[r1].clone()));
|
||||||
|
|
||||||
match d {
|
match d {
|
||||||
@@ -1428,8 +1409,6 @@ impl MachineState {
|
|||||||
instr: &BuiltInInstruction)
|
instr: &BuiltInInstruction)
|
||||||
{
|
{
|
||||||
match instr {
|
match instr {
|
||||||
&BuiltInInstruction::CallInlined(ref inlined, ref rs) =>
|
|
||||||
self.execute_inlined(inlined, rs),
|
|
||||||
&BuiltInInstruction::CompareNumber(cmp, ref at_1, ref at_2) => {
|
&BuiltInInstruction::CompareNumber(cmp, ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_fail!(self, self.get_number(at_1));
|
let n1 = try_or_fail!(self, self.get_number(at_1));
|
||||||
let n2 = try_or_fail!(self, self.get_number(at_2));
|
let n2 = try_or_fail!(self, self.get_number(at_2));
|
||||||
@@ -1457,7 +1436,7 @@ impl MachineState {
|
|||||||
let val = self.try_get_arg();
|
let val = self.try_get_arg();
|
||||||
|
|
||||||
if lco {
|
if lco {
|
||||||
self.p = self.cp.clone();
|
self.p = CodePtr::Local(self.cp.clone());
|
||||||
} else {
|
} else {
|
||||||
self.p += 1;
|
self.p += 1;
|
||||||
}
|
}
|
||||||
@@ -1658,8 +1637,6 @@ impl MachineState {
|
|||||||
},
|
},
|
||||||
&BuiltInInstruction::UnwindStack =>
|
&BuiltInInstruction::UnwindStack =>
|
||||||
self.unwind_stack(),
|
self.unwind_stack(),
|
||||||
&BuiltInInstruction::InternalCallN =>
|
|
||||||
self.handle_internal_call_n(call_policy, code_dirs),
|
|
||||||
&BuiltInInstruction::Fail => {
|
&BuiltInInstruction::Fail => {
|
||||||
self.fail = true;
|
self.fail = true;
|
||||||
self.p += 1;
|
self.p += 1;
|
||||||
@@ -1946,66 +1923,86 @@ impl MachineState {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn setup_built_in_call(&mut self, ct: BuiltInClauseType, lco: bool)
|
||||||
|
{
|
||||||
|
self.num_of_args = ct.arity();
|
||||||
|
self.b0 = self.b;
|
||||||
|
|
||||||
|
self.p = CodePtr::BuiltInClause(ct, self.p.local());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn allocate(&mut self, num_cells: usize) {
|
||||||
|
let gi = self.next_global_index();
|
||||||
|
|
||||||
|
self.p += 1;
|
||||||
|
|
||||||
|
if self.e + 1 < self.and_stack.len() {
|
||||||
|
let and_gi = self.and_stack[self.e].global_index;
|
||||||
|
let or_gi = self.or_stack.top()
|
||||||
|
.map(|or_fr| or_fr.global_index)
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
if and_gi > or_gi {
|
||||||
|
let index = self.e + 1;
|
||||||
|
|
||||||
|
self.and_stack[index].e = self.e;
|
||||||
|
self.and_stack[index].cp = self.cp.clone();
|
||||||
|
self.and_stack[index].global_index = gi;
|
||||||
|
|
||||||
|
self.and_stack.resize(index, num_cells);
|
||||||
|
self.e = index;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.and_stack.push(gi, self.e, self.cp.clone(), num_cells);
|
||||||
|
self.e = self.and_stack.len() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deallocate(&mut self) {
|
||||||
|
let e = self.e;
|
||||||
|
|
||||||
|
self.cp = self.and_stack[e].cp.clone();
|
||||||
|
self.e = self.and_stack[e].e;
|
||||||
|
|
||||||
|
self.p += 1;
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn execute_ctrl_instr<'a>(&mut self, code_dirs: CodeDirs<'a>,
|
pub(super) fn execute_ctrl_instr<'a>(&mut self, code_dirs: CodeDirs<'a>,
|
||||||
call_policy: &mut Box<CallPolicy>,
|
call_policy: &mut Box<CallPolicy>,
|
||||||
cut_policy: &mut Box<CutPolicy>,
|
cut_policy: &mut Box<CutPolicy>,
|
||||||
instr: &ControlInstruction)
|
instr: &ControlInstruction)
|
||||||
{
|
{
|
||||||
match instr {
|
match instr {
|
||||||
&ControlInstruction::Allocate(num_cells) => {
|
&ControlInstruction::Allocate(num_cells) =>
|
||||||
let gi = self.next_global_index();
|
self.allocate(num_cells),
|
||||||
|
&ControlInstruction::CallClause(ClauseType::CallN, arity, _, lco) =>
|
||||||
self.p += 1;
|
try_or_fail!(self, call_policy.call_n(self, arity, code_dirs, lco)),
|
||||||
|
&ControlInstruction::CallClause(ClauseType::BuiltIn(ref ct), _, _, lco) =>
|
||||||
if self.e + 1 < self.and_stack.len() {
|
try_or_fail!(self, call_policy.call_builtin(self, ct, lco)),
|
||||||
let and_gi = self.and_stack[self.e].global_index;
|
&ControlInstruction::CallClause(ClauseType::Inlined(ref ct), _, _, lco) =>
|
||||||
let or_gi = self.or_stack.top()
|
self.execute_inlined(ct),
|
||||||
.map(|or_fr| or_fr.global_index)
|
&ControlInstruction::CallClause(ClauseType::Named(ref name, ref idx), arity, _, lco)
|
||||||
.unwrap_or(0);
|
| &ControlInstruction::CallClause(ClauseType::Op(ref name, _, ref idx), arity, _, lco) =>
|
||||||
|
try_or_fail!(self, call_policy.context_call(self, name.clone(), arity, idx.clone(),
|
||||||
if and_gi > or_gi {
|
lco)),
|
||||||
let index = self.e + 1;
|
|
||||||
|
|
||||||
self.and_stack[index].e = self.e;
|
|
||||||
self.and_stack[index].cp = self.cp.clone();
|
|
||||||
self.and_stack[index].global_index = gi;
|
|
||||||
|
|
||||||
self.and_stack.resize(index, num_cells);
|
|
||||||
|
|
||||||
self.e = index;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.and_stack.push(gi, self.e, self.cp.clone(), num_cells);
|
|
||||||
self.e = self.and_stack.len() - 1;
|
|
||||||
},
|
|
||||||
&ControlInstruction::CallClause(ref ct, arity, _, lco) =>
|
|
||||||
try_or_fail!(self, call_policy.try_call_clause(self, code_dirs, ct, arity, lco)),
|
|
||||||
&ControlInstruction::CheckCpExecute => {
|
&ControlInstruction::CheckCpExecute => {
|
||||||
let a = self.store(self.deref(self[temp_v!(2)].clone()));
|
let a = self.store(self.deref(self[temp_v!(2)].clone()));
|
||||||
|
|
||||||
match a {
|
match a {
|
||||||
Addr::Con(Constant::Usize(old_b)) if self.b > old_b + 1 => {
|
Addr::Con(Constant::Usize(old_b)) if self.b > old_b + 1 => {
|
||||||
self.p = self.cp.clone();
|
self.p = CodePtr::Local(self.cp.clone());
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
self.num_of_args = 2;
|
self.num_of_args = 2;
|
||||||
self.b0 = self.b;
|
self.b0 = self.b;
|
||||||
// goto sgc_on_success/2, 382.
|
// goto sgc_on_success/2, 382.
|
||||||
self.p = CodePtr::DirEntry(382, clause_name!("builtin"));
|
self.p = dir_entry!(382, clause_name!("builtin"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
&ControlInstruction::Deallocate => {
|
&ControlInstruction::Deallocate => self.deallocate(),
|
||||||
let e = self.e;
|
|
||||||
|
|
||||||
self.cp = self.and_stack[e].cp.clone();
|
|
||||||
self.e = self.and_stack[e].e;
|
|
||||||
|
|
||||||
self.p += 1;
|
|
||||||
},
|
|
||||||
&ControlInstruction::GetCleanerCall => {
|
&ControlInstruction::GetCleanerCall => {
|
||||||
let dest = self[temp_v!(1)].clone();
|
let dest = self[temp_v!(1)].clone();
|
||||||
|
|
||||||
@@ -2032,7 +2029,7 @@ impl MachineState {
|
|||||||
self.fail = true;
|
self.fail = true;
|
||||||
},
|
},
|
||||||
&ControlInstruction::Goto(p, arity, lco) =>
|
&ControlInstruction::Goto(p, arity, lco) =>
|
||||||
self.goto_ptr(CodePtr::DirEntry(p, clause_name!("builtin")), arity, lco),
|
self.goto_ptr(dir_entry!(p, clause_name!("builtin")), arity, lco),
|
||||||
&ControlInstruction::IsClause(lco, r, ref at) => {
|
&ControlInstruction::IsClause(lco, r, ref at) => {
|
||||||
let a1 = self[r].clone();
|
let a1 = self[r].clone();
|
||||||
let a2 = try_or_fail!(self, self.get_number(at));
|
let a2 = try_or_fail!(self, self.get_number(at));
|
||||||
@@ -2042,7 +2039,7 @@ impl MachineState {
|
|||||||
},
|
},
|
||||||
&ControlInstruction::JmpBy(arity, offset, _, lco) => {
|
&ControlInstruction::JmpBy(arity, offset, _, lco) => {
|
||||||
if !lco {
|
if !lco {
|
||||||
self.cp = self.p.clone() + 1;
|
self.cp.assign_if_local(self.p.clone() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.num_of_args = arity;
|
self.num_of_args = arity;
|
||||||
@@ -2050,13 +2047,13 @@ impl MachineState {
|
|||||||
self.p += offset;
|
self.p += offset;
|
||||||
},
|
},
|
||||||
&ControlInstruction::Proceed =>
|
&ControlInstruction::Proceed =>
|
||||||
self.p = self.cp.clone(),
|
self.p = CodePtr::Local(self.cp.clone())
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn goto_ptr(&mut self, p: CodePtr, arity: usize, lco:bool) {
|
pub(super) fn goto_ptr(&mut self, p: CodePtr, arity: usize, lco:bool) {
|
||||||
if !lco {
|
if !lco {
|
||||||
self.cp = self.p.clone() + 1;
|
self.cp.assign_if_local(self.p.clone() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.num_of_args = arity;
|
self.num_of_args = arity;
|
||||||
@@ -2169,7 +2166,7 @@ impl MachineState {
|
|||||||
self.s = 0;
|
self.s = 0;
|
||||||
self.tr = 0;
|
self.tr = 0;
|
||||||
self.p = CodePtr::default();
|
self.p = CodePtr::default();
|
||||||
self.cp = CodePtr::default();
|
self.cp = LocalCodePtr::default();
|
||||||
self.num_of_args = 0;
|
self.num_of_args = 0;
|
||||||
|
|
||||||
self.fail = false;
|
self.fail = false;
|
||||||
|
|||||||
@@ -34,18 +34,18 @@ pub struct Machine {
|
|||||||
cached_query: Option<Code>
|
cached_query: Option<Code>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Index<CodePtr> for Machine {
|
impl Index<LocalCodePtr> for Machine {
|
||||||
type Output = Line;
|
type Output = Line;
|
||||||
|
|
||||||
fn index(&self, ptr: CodePtr) -> &Self::Output {
|
fn index(&self, ptr: LocalCodePtr) -> &Self::Output {
|
||||||
match ptr {
|
match ptr {
|
||||||
CodePtr::TopLevel(_, p) => {
|
LocalCodePtr::TopLevel(_, p) => {
|
||||||
match &self.cached_query {
|
match &self.cached_query {
|
||||||
&Some(ref cq) => &cq[p],
|
&Some(ref cq) => &cq[p],
|
||||||
&None => panic!("Out-of-bounds top level index.")
|
&None => panic!("Out-of-bounds top level index.")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CodePtr::DirEntry(p, _) => &self.code[p]
|
LocalCodePtr::DirEntry(p, _) => &self.code[p]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,36 +223,47 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn lookup_instr(&self, p: CodePtr) -> Option<Line> {
|
||||||
|
match p {
|
||||||
|
CodePtr::Local(LocalCodePtr::TopLevel(_, p)) =>
|
||||||
|
match &self.cached_query {
|
||||||
|
&Some(ref cq) => Some(cq[p].clone()),
|
||||||
|
&None => None
|
||||||
|
},
|
||||||
|
CodePtr::Local(LocalCodePtr::DirEntry(p, _)) =>
|
||||||
|
Some(self.code[p].clone()),
|
||||||
|
CodePtr::BuiltInClause(built_in, _) =>
|
||||||
|
Some(call_clause!(ClauseType::BuiltIn(built_in), built_in.arity(), 0)),
|
||||||
|
CodePtr::CallN(arity, _) =>
|
||||||
|
Some(call_clause!(ClauseType::CallN, arity, 0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_instr(&mut self)
|
fn execute_instr(&mut self)
|
||||||
{
|
{
|
||||||
let instr = match self.ms.p {
|
let instr = match self.lookup_instr(self.ms.p.clone()) {
|
||||||
CodePtr::TopLevel(_, p) => {
|
Some(instr) => instr,
|
||||||
match &self.cached_query {
|
None => return
|
||||||
&Some(ref cq) => &cq[p],
|
|
||||||
&None => return
|
|
||||||
}
|
|
||||||
},
|
|
||||||
CodePtr::DirEntry(p, _) => &self.code[p]
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match instr {
|
match instr {
|
||||||
&Line::Arithmetic(ref arith_instr) =>
|
Line::Arithmetic(ref arith_instr) =>
|
||||||
self.ms.execute_arith_instr(arith_instr),
|
self.ms.execute_arith_instr(arith_instr),
|
||||||
&Line::BuiltIn(ref built_in_instr) => {
|
Line::BuiltIn(ref built_in_instr) => {
|
||||||
let code_dirs = CodeDirs::new(&self.code_dir, &self.modules);
|
let code_dirs = CodeDirs::new(&self.code_dir, &self.modules);
|
||||||
self.ms.execute_built_in_instr(code_dirs, &mut self.call_policy,
|
self.ms.execute_built_in_instr(code_dirs, &mut self.call_policy,
|
||||||
&mut self.cut_policy, built_in_instr);
|
&mut self.cut_policy, built_in_instr);
|
||||||
},
|
},
|
||||||
&Line::Choice(ref choice_instr) =>
|
Line::Choice(ref choice_instr) =>
|
||||||
self.ms.execute_choice_instr(choice_instr, &mut self.call_policy),
|
self.ms.execute_choice_instr(choice_instr, &mut self.call_policy),
|
||||||
&Line::Cut(ref cut_instr) =>
|
Line::Cut(ref cut_instr) =>
|
||||||
self.ms.execute_cut_instr(cut_instr, &mut self.cut_policy),
|
self.ms.execute_cut_instr(cut_instr, &mut self.cut_policy),
|
||||||
&Line::Control(ref control_instr) => {
|
Line::Control(ref control_instr) => {
|
||||||
let code_dirs = CodeDirs::new(&self.code_dir, &self.modules);
|
let code_dirs = CodeDirs::new(&self.code_dir, &self.modules);
|
||||||
self.ms.execute_ctrl_instr(code_dirs, &mut self.call_policy,
|
self.ms.execute_ctrl_instr(code_dirs, &mut self.call_policy,
|
||||||
&mut self.cut_policy, control_instr)
|
&mut self.cut_policy, control_instr)
|
||||||
},
|
},
|
||||||
&Line::Fact(ref fact) => {
|
Line::Fact(ref fact) => {
|
||||||
for fact_instr in fact {
|
for fact_instr in fact {
|
||||||
if self.failed() {
|
if self.failed() {
|
||||||
break;
|
break;
|
||||||
@@ -263,11 +274,11 @@ impl Machine {
|
|||||||
|
|
||||||
self.ms.p += 1;
|
self.ms.p += 1;
|
||||||
},
|
},
|
||||||
&Line::Indexing(ref indexing_instr) =>
|
Line::Indexing(ref indexing_instr) =>
|
||||||
self.ms.execute_indexing_instr(&indexing_instr),
|
self.ms.execute_indexing_instr(&indexing_instr),
|
||||||
&Line::IndexedChoice(ref choice_instr) =>
|
Line::IndexedChoice(ref choice_instr) =>
|
||||||
self.ms.execute_indexed_choice_instr(choice_instr, &mut self.call_policy),
|
self.ms.execute_indexed_choice_instr(choice_instr, &mut self.call_policy),
|
||||||
&Line::Query(ref query) => {
|
Line::Query(ref query) => {
|
||||||
for query_instr in query {
|
for query_instr in query {
|
||||||
if self.failed() {
|
if self.failed() {
|
||||||
break;
|
break;
|
||||||
@@ -289,13 +300,13 @@ impl Machine {
|
|||||||
self.ms.b0 = self.ms.or_stack[b].b0;
|
self.ms.b0 = self.ms.or_stack[b].b0;
|
||||||
self.ms.p = self.ms.or_stack[b].bp.clone();
|
self.ms.p = self.ms.or_stack[b].bp.clone();
|
||||||
|
|
||||||
if let CodePtr::TopLevel(_, p) = self.ms.p {
|
if let CodePtr::Local(LocalCodePtr::TopLevel(_, p)) = self.ms.p {
|
||||||
self.ms.fail = p == 0;
|
self.ms.fail = p == 0;
|
||||||
} else {
|
} else {
|
||||||
self.ms.fail = false;
|
self.ms.fail = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.ms.p = CodePtr::TopLevel(0, 0);
|
self.ms.p = CodePtr::Local(LocalCodePtr::TopLevel(0, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,8 +320,9 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match self.ms.p {
|
match self.ms.p {
|
||||||
CodePtr::DirEntry(p, _) if p < self.code.len() => {},
|
CodePtr::Local(LocalCodePtr::DirEntry(p, _)) if p < self.code.len() => {},
|
||||||
_ => break
|
CodePtr::Local(_) => break,
|
||||||
|
_ => {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -342,11 +354,11 @@ impl Machine {
|
|||||||
|
|
||||||
fn run_query(&mut self, alloc_locs: &AllocVarDict, heap_locs: &mut HeapVarDict)
|
fn run_query(&mut self, alloc_locs: &AllocVarDict, heap_locs: &mut HeapVarDict)
|
||||||
{
|
{
|
||||||
let end_ptr = CodePtr::TopLevel(0, self.cached_query_size());
|
let end_ptr = top_level_code_ptr!(0, self.cached_query_size());
|
||||||
|
|
||||||
while self.ms.p < end_ptr {
|
while self.ms.p < end_ptr {
|
||||||
if let CodePtr::TopLevel(mut cn, p) = self.ms.p {
|
if let CodePtr::Local(LocalCodePtr::TopLevel(mut cn, p)) = self.ms.p {
|
||||||
match &self[CodePtr::TopLevel(cn, p)] {
|
match &self[LocalCodePtr::TopLevel(cn, p)] {
|
||||||
&Line::Control(ref ctrl_instr) if ctrl_instr.is_jump_instr() => {
|
&Line::Control(ref ctrl_instr) if ctrl_instr.is_jump_instr() => {
|
||||||
self.record_var_places(cn, alloc_locs, heap_locs);
|
self.record_var_places(cn, alloc_locs, heap_locs);
|
||||||
cn += 1;
|
cn += 1;
|
||||||
@@ -354,13 +366,13 @@ impl Machine {
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ms.p = CodePtr::TopLevel(cn, p);
|
self.ms.p = top_level_code_ptr!(cn, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.query_stepper();
|
self.query_stepper();
|
||||||
|
|
||||||
match self.ms.p {
|
match self.ms.p {
|
||||||
CodePtr::TopLevel(_, p) if p > 0 => {},
|
CodePtr::Local(LocalCodePtr::TopLevel(_, p)) if p > 0 => {},
|
||||||
_ => {
|
_ => {
|
||||||
if heap_locs.is_empty() {
|
if heap_locs.is_empty() {
|
||||||
self.record_var_places(0, alloc_locs, heap_locs);
|
self.record_var_places(0, alloc_locs, heap_locs);
|
||||||
@@ -410,7 +422,7 @@ impl Machine {
|
|||||||
let b = self.ms.b - 1;
|
let b = self.ms.b - 1;
|
||||||
self.ms.p = self.ms.or_stack[b].bp.clone();
|
self.ms.p = self.ms.or_stack[b].bp.clone();
|
||||||
|
|
||||||
if let CodePtr::TopLevel(_, 0) = self.ms.p {
|
if let CodePtr::Local(LocalCodePtr::TopLevel(_, 0)) = self.ms.p {
|
||||||
return EvalSession::from(SessionError::QueryFailure);
|
return EvalSession::from(SessionError::QueryFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,24 +19,6 @@ macro_rules! atom {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! internal_call_n {
|
|
||||||
() => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::InternalCallN)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! allocate {
|
|
||||||
($cells:expr) => (
|
|
||||||
Line::Control(ControlInstruction::Allocate($cells))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! deallocate {
|
|
||||||
() => (
|
|
||||||
Line::Control(ControlInstruction::Deallocate)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! compare_number_instr {
|
macro_rules! compare_number_instr {
|
||||||
($cmp: expr, $at_1: expr, $at_2: expr) => (
|
($cmp: expr, $at_1: expr, $at_2: expr) => (
|
||||||
Line::BuiltIn(BuiltInInstruction::CompareNumber($cmp, $at_1, $at_2))
|
Line::BuiltIn(BuiltInInstruction::CompareNumber($cmp, $at_1, $at_2))
|
||||||
@@ -88,12 +70,6 @@ macro_rules! functor {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! fact {
|
|
||||||
[$($x:expr),+] => (
|
|
||||||
Line::Fact(vec![$($x),+])
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! temp_v {
|
macro_rules! temp_v {
|
||||||
($x:expr) => (
|
($x:expr) => (
|
||||||
RegType::Temp($x)
|
RegType::Temp($x)
|
||||||
@@ -106,150 +82,58 @@ macro_rules! perm_v {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! get_var_in_query {
|
|
||||||
($r:expr, $arg:expr) => (
|
|
||||||
QueryInstruction::GetVariable($r, $arg)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
macro_rules! get_value {
|
|
||||||
($r:expr, $arg:expr) => (
|
|
||||||
FactInstruction::GetValue($r, $arg)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! set_void {
|
|
||||||
($n:expr) => (
|
|
||||||
QueryInstruction::SetVoid($n)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! set_value {
|
|
||||||
($r:expr) => (
|
|
||||||
QueryInstruction::SetValue($r)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! get_var_in_fact {
|
|
||||||
($r:expr, $arg:expr) => (
|
|
||||||
FactInstruction::GetVariable($r, $arg)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! put_var {
|
|
||||||
($r:expr, $arg:expr) => (
|
|
||||||
QueryInstruction::PutVariable($r, $arg)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! put_structure {
|
|
||||||
($atom:expr, $arity:expr, $r:expr, Some($fix:expr)) => (
|
|
||||||
QueryInstruction::PutStructure(ClauseType::Op(clause_name!($atom), $fix, CodeIndex::default()),
|
|
||||||
$arity,
|
|
||||||
$r)
|
|
||||||
);
|
|
||||||
($atom:expr, $arity:expr, $r:expr, None) => (
|
|
||||||
QueryInstruction::PutStructure(ClauseType::Named(clause_name!($atom), CodeIndex::default()),
|
|
||||||
$arity,
|
|
||||||
$r)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! put_constant {
|
|
||||||
($lvl:expr, $cons:expr, $r:expr) => (
|
|
||||||
QueryInstruction::PutConstant($lvl, $cons, $r)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! set_constant {
|
|
||||||
($cons:expr) => (
|
|
||||||
QueryInstruction::SetConstant($cons)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! put_value {
|
|
||||||
($r:expr, $arg:expr) => (
|
|
||||||
QueryInstruction::PutValue($r, $arg)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! put_unsafe_value {
|
|
||||||
($r:expr, $arg:expr) => (
|
|
||||||
QueryInstruction::PutUnsafeValue($r, $arg)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! try_me_else {
|
|
||||||
($o:expr) => (
|
|
||||||
Line::Choice(ChoiceInstruction::TryMeElse($o))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! retry_me_else {
|
|
||||||
($o:expr) => (
|
|
||||||
Line::Choice(ChoiceInstruction::RetryMeElse($o))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! is_atom {
|
macro_rules! is_atom {
|
||||||
($r:expr) => (
|
($r:expr) => (
|
||||||
Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsAtom, vec![$r]))
|
call_clause!(ClauseType::Inlined(InlinedClauseType::IsAtom($r)), 1, 0)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! is_atomic {
|
macro_rules! is_atomic {
|
||||||
($r:expr) => (
|
($r:expr) => (
|
||||||
Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsAtomic, vec![$r]))
|
call_clause!(ClauseType::Inlined(InlinedClauseType::IsAtomic($r)), 1, 0)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! is_integer {
|
macro_rules! is_integer {
|
||||||
($r:expr) => (
|
($r:expr) => (
|
||||||
Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsInteger, vec![$r]))
|
call_clause!(ClauseType::Inlined(InlinedClauseType::IsInteger($r)), 1, 0)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! is_compound {
|
macro_rules! is_compound {
|
||||||
($r:expr) => (
|
($r:expr) => (
|
||||||
Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsCompound, vec![$r]))
|
call_clause!(ClauseType::Inlined(InlinedClauseType::IsCompound($r)), 1, 0)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! is_float {
|
macro_rules! is_float {
|
||||||
($r:expr) => (
|
($r:expr) => (
|
||||||
Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsFloat, vec![$r]))
|
call_clause!(ClauseType::Inlined(InlinedClauseType::IsFloat($r)), 1, 0)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! is_rational {
|
macro_rules! is_rational {
|
||||||
($r:expr) => (
|
($r:expr) => (
|
||||||
Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsRational, vec![$r]))
|
call_clause!(ClauseType::Inlined(InlinedClauseType::IsRational($r)), 1, 0)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
macro_rules! is_nonvar {
|
macro_rules! is_nonvar {
|
||||||
($r:expr) => (
|
($r:expr) => (
|
||||||
Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsNonVar, vec![$r]))
|
call_clause!(ClauseType::Inlined(InlinedClauseType::IsNonVar($r)), 1, 0)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! is_string {
|
macro_rules! is_string {
|
||||||
($r:expr) => (
|
($r:expr) => (
|
||||||
Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsString, vec![$r]))
|
call_clause!(ClauseType::Inlined(InlinedClauseType::IsString($r)), 1, 0)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! is_var {
|
macro_rules! is_var {
|
||||||
($r:expr) => (
|
($r:expr) => (
|
||||||
Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsVar, vec![$r]))
|
call_clause!(ClauseType::Inlined(InlinedClauseType::IsVar($r)), 1, 0)
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! trust_me {
|
|
||||||
() => (
|
|
||||||
Line::Choice(ChoiceInstruction::TrustMe)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,84 +143,12 @@ macro_rules! call_clause {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! call_n {
|
|
||||||
($arity:expr) => (
|
|
||||||
Line::Control(ControlInstruction::CallClause(ClauseType::CallN, $arity, 0, false))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! execute_n {
|
|
||||||
($arity:expr) => (
|
|
||||||
Line::Control(ControlInstruction::CallClause(ClauseType::CallN, $arity, 0, true))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! proceed {
|
macro_rules! proceed {
|
||||||
() => (
|
() => (
|
||||||
Line::Control(ControlInstruction::Proceed)
|
Line::Control(ControlInstruction::Proceed)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! cut {
|
|
||||||
($r:expr) => (
|
|
||||||
Line::Cut(CutInstruction::Cut($r))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! neck_cut {
|
|
||||||
() => (
|
|
||||||
Line::Cut(CutInstruction::NeckCut)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! get_current_block {
|
|
||||||
() => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::GetCurrentBlock)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! install_new_block {
|
|
||||||
() => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::InstallNewBlock)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! goto_call {
|
|
||||||
($line:expr, $arity:expr) => (
|
|
||||||
Line::Control(ControlInstruction::Goto($line, $arity, false))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! goto_execute {
|
|
||||||
($line:expr, $arity:expr) => (
|
|
||||||
Line::Control(ControlInstruction::Goto($line, $arity, true))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! reset_block {
|
|
||||||
() => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::ResetBlock)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! get_ball {
|
|
||||||
() => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::GetBall)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! erase_ball {
|
|
||||||
() => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::EraseBall)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! unify {
|
|
||||||
() => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::Unify)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! is_call {
|
macro_rules! is_call {
|
||||||
($r:expr, $at:expr) => (
|
($r:expr, $at:expr) => (
|
||||||
Line::Control(ControlInstruction::IsClause(false, $r, $at))
|
Line::Control(ControlInstruction::IsClause(false, $r, $at))
|
||||||
@@ -344,24 +156,6 @@ macro_rules! is_call {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! unwind_stack {
|
|
||||||
() => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::UnwindStack)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! clean_up_block {
|
|
||||||
() => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::CleanUpBlock)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! set_ball {
|
|
||||||
() => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::SetBall)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! fail {
|
macro_rules! fail {
|
||||||
() => (
|
() => (
|
||||||
Line::BuiltIn(BuiltInInstruction::Fail)
|
Line::BuiltIn(BuiltInInstruction::Fail)
|
||||||
@@ -374,133 +168,18 @@ macro_rules! succeed {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! duplicate_term {
|
|
||||||
() => (
|
|
||||||
Line::Control(ControlInstruction::CallClause(ClauseType::DuplicateTerm, 2, 0, false))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! get_level {
|
|
||||||
($r:expr) => (
|
|
||||||
Line::Cut(CutInstruction::GetLevel($r))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! switch_on_term {
|
|
||||||
($v:expr, $c:expr, $l:expr, $s:expr) => (
|
|
||||||
Line::Indexing(IndexingInstruction::SwitchOnTerm($v, $c, $l, $s))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! indexed_try {
|
|
||||||
($i:expr) => (
|
|
||||||
Line::IndexedChoice(IndexedChoiceInstruction::Try($i))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! retry {
|
|
||||||
($i:expr) => (
|
|
||||||
Line::IndexedChoice(IndexedChoiceInstruction::Retry($i))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! trust {
|
|
||||||
($i:expr) => (
|
|
||||||
Line::IndexedChoice(IndexedChoiceInstruction::Trust($i))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! get_constant {
|
|
||||||
($c:expr, $r:expr) => (
|
|
||||||
FactInstruction::GetConstant(Level::Shallow, $c, $r)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! get_structure {
|
|
||||||
($atom:expr, $arity:expr, $r:expr, Some($fix:expr)) => (
|
|
||||||
FactInstruction::GetStructure(ClauseType::Op(clause_name!($atom), $fix, CodeIndex::default()),
|
|
||||||
$arity,
|
|
||||||
$r)
|
|
||||||
);
|
|
||||||
($atom:expr, $arity:expr, $r:expr, None) => (
|
|
||||||
FactInstruction::GetStructure(ClauseType::Named(clause_name!($atom), CodeIndex::default()),
|
|
||||||
$arity,
|
|
||||||
$r)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! functor_call {
|
|
||||||
() => (
|
|
||||||
Line::Control(ControlInstruction::CallClause(ClauseType::Functor, 3, 0, false))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! functor_execute {
|
|
||||||
() => (
|
|
||||||
Line::Control(ControlInstruction::CallClause(ClauseType::Functor, 3, 0, true))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! unify_value {
|
|
||||||
($r:expr) => (
|
|
||||||
FactInstruction::UnifyValue($r)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! unify_variable {
|
|
||||||
($r:expr) => (
|
|
||||||
FactInstruction::UnifyVariable($r)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! unify_void {
|
|
||||||
($n:expr) => (
|
|
||||||
FactInstruction::UnifyVoid($n)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! set_cp {
|
macro_rules! set_cp {
|
||||||
($r:expr) => (
|
($r:expr) => (
|
||||||
Line::BuiltIn(BuiltInInstruction::SetCutPoint($r))
|
Line::BuiltIn(BuiltInInstruction::SetCutPoint($r))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! get_cp {
|
|
||||||
($r:expr) => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::GetCutPoint($r))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! integer {
|
macro_rules! integer {
|
||||||
($i:expr) => (
|
($i:expr) => (
|
||||||
Constant::Number(Number::Integer(Rc::new(BigInt::from($i))))
|
Constant::Number(Number::Integer(Rc::new(BigInt::from($i))))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! add {
|
|
||||||
($at_1:expr, $at_2:expr, $o:expr) => (
|
|
||||||
Line::Arithmetic(ArithmeticInstruction::Add($at_1, $at_2, $o))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! sub {
|
|
||||||
($at_1:expr, $at_2:expr, $o:expr) => (
|
|
||||||
Line::Arithmetic(ArithmeticInstruction::Sub($at_1, $at_2, $o))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! get_arg_call {
|
|
||||||
() => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::GetArg(false))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! get_arg_execute {
|
|
||||||
() => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::GetArg(true))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! rc_integer {
|
macro_rules! rc_integer {
|
||||||
($e:expr) => (
|
($e:expr) => (
|
||||||
Number::Integer(Rc::new(BigInt::from($e)))
|
Number::Integer(Rc::new(BigInt::from($e)))
|
||||||
@@ -513,229 +192,12 @@ macro_rules! rc_atom {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! infix {
|
|
||||||
() => (
|
|
||||||
Fixity::In
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! display {
|
|
||||||
() => (
|
|
||||||
Line::Control(ControlInstruction::CallClause(ClauseType::Display, 1, 0, false))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! dynamic_is {
|
|
||||||
() => (
|
|
||||||
Line::Control(ControlInstruction::CallClause(ClauseType::Is, 2, 0, false))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! dynamic_num_test {
|
|
||||||
($cmp:expr) => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::CompareNumber($cmp),
|
|
||||||
vec![temp_v!(1), temp_v!(2)]))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! cmp_gt {
|
|
||||||
() => (
|
|
||||||
CompareNumberQT::GreaterThan
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! cmp_lt {
|
|
||||||
() => (
|
|
||||||
CompareNumberQT::LessThan
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! cmp_gte {
|
|
||||||
() => (
|
|
||||||
CompareNumberQT::GreaterThanOrEqual
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! cmp_lte {
|
|
||||||
() => (
|
|
||||||
CompareNumberQT::LessThanOrEqual
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! cmp_ne {
|
|
||||||
() => (
|
|
||||||
CompareNumberQT::NotEqual
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! cmp_eq {
|
|
||||||
() => (
|
|
||||||
CompareNumberQT::Equal
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! jmp_call {
|
macro_rules! jmp_call {
|
||||||
($arity:expr, $offset:expr, $pvs:expr) => (
|
($arity:expr, $offset:expr, $pvs:expr) => (
|
||||||
Line::Control(ControlInstruction::JmpBy($arity, $offset, $pvs, false))
|
Line::Control(ControlInstruction::JmpBy($arity, $offset, $pvs, false))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! jmp_execute {
|
|
||||||
($arity:expr, $offset:expr, $pvs:expr) => (
|
|
||||||
Line::Control(ControlInstruction::JmpBy($arity, $offset, $pvs, true))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! get_list {
|
|
||||||
($lvl:expr, $r:expr) => (
|
|
||||||
FactInstruction::GetList($lvl, $r)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! unify_constant {
|
|
||||||
($c:expr) => (
|
|
||||||
FactInstruction::UnifyConstant($c)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! install_cleaner {
|
|
||||||
() => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::InstallCleaner)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! check_cp_execute {
|
|
||||||
() => (
|
|
||||||
Line::Control(ControlInstruction::CheckCpExecute)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! get_cleaner_call {
|
|
||||||
() => (
|
|
||||||
Line::Control(ControlInstruction::GetCleanerCall)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! restore_cut_policy {
|
|
||||||
() => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::RestoreCutPolicy)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! ground_execute {
|
|
||||||
() => (
|
|
||||||
Line::Control(ControlInstruction::CallClause(ClauseType::Ground, 1, 0, true))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! eq_execute {
|
|
||||||
() => (
|
|
||||||
Line::Control(ControlInstruction::CallClause(ClauseType::Eq, 2, 0, true))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! not_eq_execute {
|
|
||||||
() => (
|
|
||||||
Line::Control(ControlInstruction::CallClause(ClauseType::NotEq, 2, 0, true))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! compare_term_execute {
|
|
||||||
($qt:expr) => (
|
|
||||||
Line::Control(ControlInstruction::CallClause(ClauseType::CompareTerm($qt), 2, 0, true))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! term_cmp_gt {
|
|
||||||
() => (
|
|
||||||
CompareTermQT::GreaterThan
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! term_cmp_lt {
|
|
||||||
() => (
|
|
||||||
CompareTermQT::LessThan
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! term_cmp_gte {
|
|
||||||
() => (
|
|
||||||
CompareTermQT::GreaterThanOrEqual
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! term_cmp_lte {
|
|
||||||
() => (
|
|
||||||
CompareTermQT::LessThanOrEqual
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! term_cmp_ne {
|
|
||||||
() => (
|
|
||||||
CompareTermQT::NotEqual
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! term_cmp_eq {
|
|
||||||
() => (
|
|
||||||
CompareTermQT::Equal
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! install_inference_counter {
|
|
||||||
($r1:expr, $r2:expr, $r3:expr) => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::InstallInferenceCounter($r1, $r2, $r3))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! remove_inference_counter {
|
|
||||||
($r1:expr, $r2:expr) => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::RemoveInferenceCounter($r1, $r2))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! inference_level {
|
|
||||||
($r1:expr, $r2:expr) => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::InferenceLevel($r1, $r2))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! default_set_cp {
|
|
||||||
($r:expr) => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::DefaultSetCutPoint($r))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! default_retry_me_else {
|
|
||||||
($o:expr) => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::DefaultRetryMeElse($o))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! default_trust_me {
|
|
||||||
() => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::DefaultTrustMe)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! remove_call_policy_check {
|
|
||||||
() => (
|
|
||||||
Line::BuiltIn(BuiltInInstruction::RemoveCallPolicyCheck)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! compare_execute {
|
|
||||||
() => (
|
|
||||||
Line::Control(ControlInstruction::CallClause(ClauseType::Compare, 2, 0, true))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! module_decl {
|
|
||||||
($name:expr, $decls:expr) => (
|
|
||||||
ModuleDecl { name: $name, exports: $decls }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! try_eval_session {
|
macro_rules! try_eval_session {
|
||||||
($e:expr) => (
|
($e:expr) => (
|
||||||
match $e {
|
match $e {
|
||||||
@@ -744,35 +206,10 @@ macro_rules! try_eval_session {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! sort_execute {
|
|
||||||
() => (
|
|
||||||
Line::Control(ControlInstruction::CallClause(ClauseType::Sort, 2, 0, true))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! keysort_execute {
|
|
||||||
() => (
|
|
||||||
Line::Control(ControlInstruction::CallClause(ClauseType::KeySort, 2, 0, true))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! acyclic_term_execute {
|
|
||||||
() => (
|
|
||||||
Line::Control(ControlInstruction::CallClause(ClauseType::AcyclicTerm, 1, 0, true))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! cyclic_term_execute {
|
|
||||||
() => (
|
|
||||||
Line::Control(ControlInstruction::CallClause(ClauseType::CyclicTerm, 1, 0, true))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! return_from_clause {
|
macro_rules! return_from_clause {
|
||||||
($lco:expr, $machine_st:expr) => {{
|
($lco:expr, $machine_st:expr) => {{
|
||||||
if $lco {
|
if $lco {
|
||||||
$machine_st.p = $machine_st.cp.clone();
|
$machine_st.p = CodePtr::Local($machine_st.cp.clone());
|
||||||
} else {
|
} else {
|
||||||
$machine_st.p += 1;
|
$machine_st.p += 1;
|
||||||
}
|
}
|
||||||
@@ -781,6 +218,12 @@ macro_rules! return_from_clause {
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! dir_entry {
|
||||||
|
($idx:expr, $module_name:expr) => (
|
||||||
|
CodePtr::Local(LocalCodePtr::DirEntry($idx, $module_name))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! set_code_index {
|
macro_rules! set_code_index {
|
||||||
($idx:expr, $ip:expr, $mod_name:expr) => {{
|
($idx:expr, $ip:expr, $mod_name:expr) => {{
|
||||||
let mut idx = $idx.0.borrow_mut();
|
let mut idx = $idx.0.borrow_mut();
|
||||||
@@ -795,3 +238,15 @@ macro_rules! machine_code_index {
|
|||||||
MachineCodeIndex { code_dir: $code_dir, op_dir: $op_dir }
|
MachineCodeIndex { code_dir: $code_dir, op_dir: $op_dir }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! put_constant {
|
||||||
|
($lvl:expr, $cons:expr, $r:expr) => (
|
||||||
|
QueryInstruction::PutConstant($lvl, $cons, $r)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! top_level_code_ptr {
|
||||||
|
($p:expr, $q_sz:expr) => (
|
||||||
|
CodePtr::Local(LocalCodePtr::TopLevel($p, $q_sz))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use std::vec::Vec;
|
|||||||
pub struct Frame {
|
pub struct Frame {
|
||||||
pub global_index: usize,
|
pub global_index: usize,
|
||||||
pub e: usize,
|
pub e: usize,
|
||||||
pub cp: CodePtr,
|
pub cp: LocalCodePtr,
|
||||||
pub b: usize,
|
pub b: usize,
|
||||||
pub bp: CodePtr,
|
pub bp: CodePtr,
|
||||||
pub tr: usize,
|
pub tr: usize,
|
||||||
@@ -18,7 +18,7 @@ pub struct Frame {
|
|||||||
impl Frame {
|
impl Frame {
|
||||||
fn new(global_index: usize,
|
fn new(global_index: usize,
|
||||||
e: usize,
|
e: usize,
|
||||||
cp: CodePtr,
|
cp: LocalCodePtr,
|
||||||
b: usize,
|
b: usize,
|
||||||
bp: CodePtr,
|
bp: CodePtr,
|
||||||
tr: usize,
|
tr: usize,
|
||||||
@@ -55,7 +55,7 @@ impl OrStack {
|
|||||||
pub fn push(&mut self,
|
pub fn push(&mut self,
|
||||||
global_index: usize,
|
global_index: usize,
|
||||||
e: usize,
|
e: usize,
|
||||||
cp: CodePtr,
|
cp: LocalCodePtr,
|
||||||
b: usize,
|
b: usize,
|
||||||
bp: CodePtr,
|
bp: CodePtr,
|
||||||
tr: usize,
|
tr: usize,
|
||||||
|
|||||||
@@ -398,9 +398,7 @@ impl RelationWorker {
|
|||||||
Term::Var(_, ref v) if v.as_str() == "!" =>
|
Term::Var(_, ref v) if v.as_str() == "!" =>
|
||||||
Ok(QueryTerm::UnblockedCut(Cell::default())),
|
Ok(QueryTerm::UnblockedCut(Cell::default())),
|
||||||
Term::Clause(r, name, mut terms, fixity) =>
|
Term::Clause(r, name, mut terms, fixity) =>
|
||||||
if let Some(system_ct) = SystemClauseType::from(name.as_str(), terms.len()) {
|
if name.as_str() == ";" {
|
||||||
Ok(QueryTerm::Clause(r, ClauseType::System(system_ct), terms))
|
|
||||||
} else if name.as_str() == ";" {
|
|
||||||
if terms.len() == 2 {
|
if terms.len() == 2 {
|
||||||
let term = Term::Clause(r, name.clone(), terms, fixity);
|
let term = Term::Clause(r, name.clone(), terms, fixity);
|
||||||
let (stub, clauses) = self.fabricate_disjunct(term);
|
let (stub, clauses) = self.fabricate_disjunct(term);
|
||||||
|
|||||||
Reference in New Issue
Block a user