From bae107f8cdf149f32eac76f19ab5dff238962fcc Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Wed, 9 May 2018 22:58:23 -0600 Subject: [PATCH] eliminate need for embedded, handwritten WAM code. --- src/prolog/and_stack.rs | 6 +- src/prolog/ast.rs | 387 ++++++++++----- src/prolog/builtins.rs | 7 +- src/prolog/codegen.rs | 25 +- src/prolog/io.rs | 6 - src/prolog/iterators.rs | 3 +- src/prolog/lib/builtins.pl | 29 ++ src/prolog/machine/machine_state.rs | 162 +++--- src/prolog/machine/machine_state_impl.rs | 169 ++++--- src/prolog/machine/mod.rs | 76 +-- src/prolog/macros.rs | 601 ++--------------------- src/prolog/or_stack.rs | 6 +- src/prolog/toplevel.rs | 8 +- 13 files changed, 546 insertions(+), 939 deletions(-) create mode 100644 src/prolog/lib/builtins.pl diff --git a/src/prolog/and_stack.rs b/src/prolog/and_stack.rs index 3e2e653d..fdf22c29 100644 --- a/src/prolog/and_stack.rs +++ b/src/prolog/and_stack.rs @@ -7,12 +7,12 @@ use std::vec::Vec; pub struct Frame { pub global_index: usize, pub e: usize, - pub cp: CodePtr, + pub cp: LocalCodePtr, perms: Vec } 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 { global_index, e: e, @@ -29,7 +29,7 @@ impl AndStack { 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(); self.0.push(Frame::new(global_index, len, e, cp, n)); } diff --git a/src/prolog/ast.rs b/src/prolog/ast.rs index 969c587d..34623fee 100644 --- a/src/prolog/ast.rs +++ b/src/prolog/ast.rs @@ -193,7 +193,7 @@ pub trait SubModuleUser { fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) -> bool { let name = name.defrock_brackets(); let mut found_op = false; - + { let mut insert_op_dir = |fix| { if let Some(op_data) = submodule.op_dir.get(&(name.clone(), fix)) { @@ -229,7 +229,7 @@ pub trait SubModuleUser { return EvalSession::from(SessionError::ModuleDoesNotContainExport); } } - + EvalSession::EntrySuccess } @@ -561,59 +561,83 @@ pub enum Term { Var(Cell, Rc) } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq)] pub enum InlinedClauseType { - CompareNumber(CompareNumberQT), - IsAtom, - IsAtomic, - IsCompound, - IsInteger, - IsRational, - IsString, - IsFloat, - IsNonVar, - IsVar, + CompareNumber(CompareNumberQT, RegType, RegType), + IsAtom(RegType), + IsAtomic(RegType), + IsCompound(RegType), + IsInteger(RegType), + IsRational(RegType), + IsString(RegType), + IsFloat(RegType), + IsNonVar(RegType), + IsVar(RegType), } impl InlinedClauseType { pub fn name(&self) -> &'static str { match self { - &InlinedClauseType::CompareNumber(qt) => qt.name(), - &InlinedClauseType::IsAtom => "atom", - &InlinedClauseType::IsAtomic => "atomic", - &InlinedClauseType::IsCompound => "compound", - &InlinedClauseType::IsInteger => "integer", - &InlinedClauseType::IsRational => "rational", - &InlinedClauseType::IsString => "string", - &InlinedClauseType::IsFloat => "float", - &InlinedClauseType::IsNonVar => "nonvar", - &InlinedClauseType::IsVar => "var" + &InlinedClauseType::CompareNumber(qt, ..) => qt.name(), + &InlinedClauseType::IsAtom(..) => "atom", + &InlinedClauseType::IsAtomic(..) => "atomic", + &InlinedClauseType::IsCompound(..) => "compound", + &InlinedClauseType::IsInteger (..) => "integer", + &InlinedClauseType::IsRational(..) => "rational", + &InlinedClauseType::IsString(..) => "string", + &InlinedClauseType::IsFloat (..) => "float", + &InlinedClauseType::IsNonVar(..) => "nonvar", + &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 { + let r1 = temp_v!(1); + let r2 = temp_v!(2); + match (name, arity) { - (">", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThan)), - ("<", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThan)), - (">=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThanOrEqual)), - ("=<", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThanOrEqual)), - ("=\\=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::NotEqual)), - ("=:=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::Equal)), - ("atom", 1) => Some(InlinedClauseType::IsAtom), - ("atomic", 1) => Some(InlinedClauseType::IsAtomic), - ("compound", 1) => Some(InlinedClauseType::IsCompound), - ("integer", 1) => Some(InlinedClauseType::IsInteger), - ("rational", 1) => Some(InlinedClauseType::IsRational), - ("string", 1) => Some(InlinedClauseType::IsString), - ("float", 1) => Some(InlinedClauseType::IsFloat), - ("nonvar", 1) => Some(InlinedClauseType::IsNonVar), - ("var", 1) => Some(InlinedClauseType::IsVar), + (">", 2) => + Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThan, r1, r2)), + ("<", 2) => + Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThan, r1, r2)), + (">=", 2) => + Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThanOrEqual,r1, r2)), + ("=<", 2) => + Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThanOrEqual, r1, r2)), + ("=\\=", 2) => + Some(InlinedClauseType::CompareNumber(CompareNumberQT::NotEqual, r1, r2)), + ("=:=", 2) => + Some(InlinedClauseType::CompareNumber(CompareNumberQT::Equal, r1, r2)), + ("atom", 1) => Some(InlinedClauseType::IsAtom(r1)), + ("atomic", 1) => Some(InlinedClauseType::IsAtomic(r1)), + ("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 } } } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq)] pub enum CompareNumberQT { GreaterThan, LessThan, @@ -636,7 +660,7 @@ impl CompareNumberQT { } } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq)] pub enum CompareTermQT { LessThan, LessThanOrEqual, @@ -685,18 +709,28 @@ pub struct Rule { pub clauses: Vec } -#[derive(Clone)] +#[derive(Copy, Clone, PartialEq)] pub enum SystemClauseType { SkipMaxList } impl SystemClauseType { + pub fn arity(&self) -> usize { + match self { + &SystemClauseType::SkipMaxList => 4 + } + } + + pub fn fixity(&self) -> Option { + None + } + pub fn name(&self) -> ClauseName { match self { &SystemClauseType::SkipMaxList => clause_name!("$skip_max_list"), } } - + pub fn from(name: &str, arity: usize) -> Option { match (name, arity) { ("$skip_max_list", 4) => Some(SystemClauseType::SkipMaxList), @@ -705,13 +739,9 @@ impl SystemClauseType { } } -#[derive(Clone)] -pub enum ClauseType { - AcyclicTerm, - Arg, - CallN, - CallWithInferenceLimit, - Catch, +#[derive(Copy, Clone, PartialEq)] +pub enum BuiltInClauseType { + AcyclicTerm, Compare, CompareTerm(CompareTermQT), CyclicTerm, @@ -720,16 +750,20 @@ pub enum ClauseType { Eq, Functor, Ground, - Inlined(InlinedClauseType), Is, KeySort, NotEq, - Op(ClauseName, Fixity, CodeIndex), - Named(ClauseName, CodeIndex), - SetupCallCleanup, Sort, - System(SystemClauseType), - Throw, + System(SystemClauseType) +} + +#[derive(Clone)] +pub enum ClauseType { + BuiltIn(BuiltInClauseType), + CallN, + Inlined(InlinedClauseType), + Op(ClauseName, Fixity, CodeIndex), + Named(ClauseName, CodeIndex) } #[derive(Clone)] @@ -797,12 +831,84 @@ impl ClauseName { } } +impl BuiltInClauseType { + fn fixity(&self) -> Option { + 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 { + 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 { pub fn fixity(&self) -> Option { match self { - &ClauseType::Compare | &ClauseType::CompareTerm(_) - | &ClauseType::Inlined(InlinedClauseType::CompareNumber(_)) - | &ClauseType::NotEq | &ClauseType::Is | &ClauseType::Eq => Some(Fixity::In), + &ClauseType::BuiltIn(ref built_in) => built_in.fixity(), + &ClauseType::Inlined(InlinedClauseType::CompareNumber(..)) => Some(Fixity::In), &ClauseType::Op(_, fixity, _) => Some(fixity), _ => None } @@ -810,68 +916,30 @@ impl ClauseType { pub fn name(&self) -> ClauseName { match self { - &ClauseType::AcyclicTerm => clause_name!("acyclic_term"), - &ClauseType::Arg => clause_name!("arg"), - &ClauseType::CallN => clause_name!("call"), - &ClauseType::CallWithInferenceLimit => clause_name!("call_with_inference_limit"), - &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::CallN => clause_name!("call"), + &ClauseType::BuiltIn(built_in) => built_in.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::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) -> Self { - if let Some(inlined_ct) = InlinedClauseType::from(name.as_str(), arity) { - return ClauseType::Inlined(inlined_ct); - } - - match (name.as_str(), arity) { - ("acyclic_term", 1) => ClauseType::AcyclicTerm, - ("arg", 3) => ClauseType::Arg, - ("call", _) => ClauseType::CallN, - ("call_with_inference_limit", 3) => ClauseType::CallWithInferenceLimit, - ("catch", 3) => ClauseType::Catch, - ("compare", 3) => ClauseType::Compare, - ("cyclic_term", 1) => ClauseType::CyclicTerm, - ("@>", 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()) - } - } + InlinedClauseType::from(name.as_str(), arity) + .map(ClauseType::Inlined) + .unwrap_or_else(|| { + BuiltInClauseType::from(name.as_str(), arity) + .map(ClauseType::BuiltIn) + .unwrap_or_else(|| { + if let Some(fixity) = fixity { + ClauseType::Op(name, fixity, CodeIndex::default()) + } else if name.as_str() == "call" { + ClauseType::CallN + } else { + ClauseType::Named(name, CodeIndex::default()) + } + }) + }) } } @@ -902,18 +970,21 @@ impl<'a> TermRef<'a> { } } +#[derive(Clone)] pub enum ChoiceInstruction { RetryMeElse(usize), TrustMe, TryMeElse(usize) } +#[derive(Clone)] pub enum CutInstruction { Cut(RegType), GetLevel(RegType), NeckCut } +#[derive(Clone)] pub enum IndexedChoiceInstruction { Retry(usize), Trust(usize), @@ -1219,6 +1290,7 @@ impl ArithmeticTerm { } } +#[derive(Clone)] pub enum ArithmeticInstruction { Add(ArithmeticTerm, ArithmeticTerm, usize), Sub(ArithmeticTerm, ArithmeticTerm, usize), @@ -1237,8 +1309,8 @@ pub enum ArithmeticInstruction { Neg(ArithmeticTerm, usize) } +#[derive(Clone)] pub enum BuiltInInstruction { - CallInlined(InlinedClauseType, Vec), CleanUpBlock, CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm), DefaultRetryMeElse(usize), @@ -1254,13 +1326,12 @@ pub enum BuiltInInstruction { InstallCleaner, InstallInferenceCounter(RegType, RegType, RegType), InstallNewBlock, - InternalCallN, RemoveCallPolicyCheck, RemoveInferenceCounter(RegType, RegType), ResetBlock, RestoreCutPolicy, SetBall, - SetCutPoint(RegType), + SetCutPoint(RegType), Succeed, Unify, UnwindStack @@ -1292,6 +1363,7 @@ impl ControlInstruction { } } +#[derive(Clone)] pub enum IndexingInstruction { SwitchOnTerm(usize, usize, usize, usize), SwitchOnConstant(usize, HashMap), @@ -1304,6 +1376,7 @@ impl From for Line { } } +#[derive(Clone)] pub enum FactInstruction { GetConstant(Level, Constant, RegType), GetList(Level, RegType), @@ -1317,6 +1390,7 @@ pub enum FactInstruction { UnifyVoid(usize) } +#[derive(Clone)] pub enum QueryInstruction { GetVariable(RegType, usize), PutConstant(Level, Constant, RegType), @@ -1336,6 +1410,7 @@ pub type CompiledFact = Vec; pub type CompiledQuery = Vec; +#[derive(Clone)] pub enum Line { Arithmetic(ArithmeticInstruction), BuiltIn(BuiltInInstruction), @@ -1474,27 +1549,60 @@ impl From<(usize, ClauseName)> for CodeIndex { #[derive(Clone, PartialEq)] 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. TopLevel(usize, usize) // chunk_num, offset. } -impl CodePtr { +impl LocalCodePtr { pub fn module_name(&self) -> ClauseName { match self { - &CodePtr::DirEntry(_, ref name) => name.clone(), + &LocalCodePtr::DirEntry(_, ref name) => name.clone(), _ => ClauseName::BuiltIn("user") } } + + pub fn assign_if_local(&mut self, cp: CodePtr) { + match cp { + CodePtr::Local(local) => *self = local, + _ => {} + } + } } impl PartialOrd for CodePtr { fn partial_cmp(&self, other: &CodePtr) -> Option { 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 for LocalCodePtr { + fn partial_cmp(&self, other: &LocalCodePtr) -> Option { + match (self, other) { + (&LocalCodePtr::DirEntry(p1, _), &LocalCodePtr::DirEntry(p2, _)) => p1.partial_cmp(&p2), - (&CodePtr::DirEntry(..), &CodePtr::TopLevel(_, _)) => + (&LocalCodePtr::DirEntry(..), &LocalCodePtr::TopLevel(_, _)) => Some(Ordering::Less), - (&CodePtr::TopLevel(_, p1), &CodePtr::TopLevel(_, ref p2)) => + (&LocalCodePtr::TopLevel(_, p1), &LocalCodePtr::TopLevel(_, ref p2)) => p1.partial_cmp(p2), _ => Some(Ordering::Greater) } @@ -1503,7 +1611,33 @@ impl PartialOrd for CodePtr { impl Default for CodePtr { fn default() -> Self { - CodePtr::TopLevel(0, 0) + CodePtr::Local(LocalCodePtr::default()) + } +} + +impl Default for LocalCodePtr { + fn default() -> Self { + LocalCodePtr::TopLevel(0, 0) + } +} + +impl Add 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 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 for CodePtr { fn add(self, rhs: usize) -> Self::Output { match self { - CodePtr::DirEntry(p, name) => CodePtr::DirEntry(p + rhs, name), - CodePtr::TopLevel(cn, p) => CodePtr::TopLevel(cn, p + rhs) + CodePtr::Local(local) => CodePtr::Local(local + rhs), + CodePtr::BuiltInClause(_, local) => CodePtr::Local(local + rhs), + CodePtr::CallN(_, local) => CodePtr::Local(local + rhs), } } } @@ -1521,8 +1656,8 @@ impl Add for CodePtr { impl AddAssign for CodePtr { fn add_assign(&mut self, rhs: usize) { match self { - &mut CodePtr::DirEntry(ref mut p, _) | - &mut CodePtr::TopLevel(_, ref mut p) => *p += rhs + &mut CodePtr::Local(ref mut local) => *local += rhs, + _ => *self = CodePtr::Local(self.local() + rhs) } } } diff --git a/src/prolog/builtins.rs b/src/prolog/builtins.rs index 0222ecf7..ab9d4903 100644 --- a/src/prolog/builtins.rs +++ b/src/prolog/builtins.rs @@ -1,8 +1,6 @@ use prolog::ast::*; -use prolog::num::bigint::{BigInt}; use std::collections::HashMap; -use std::rc::Rc; // from 7.12.2 b) of 13211-1:1995 #[derive(Clone, Copy)] @@ -92,7 +90,8 @@ impl EvalError { } } -fn get_builtins() -> Code { +/* +fn get_builtins() -> Code { vec![internal_call_n!(), // callN/N, 0. is_atomic!(temp_v!(1)), // atomic/1, 1. proceed!(), @@ -737,7 +736,7 @@ fn get_builtins() -> Code { acyclic_term_execute!(), // acyclic_term/1, 485. cyclic_term_execute!(), // cyclic_term/1, 486. ] -} +} */ pub fn default_op_dir() -> OpDir { diff --git a/src/prolog/codegen.rs b/src/prolog/codegen.rs index 521fbf06..4e6d9ed3 100644 --- a/src/prolog/codegen.rs +++ b/src/prolog/codegen.rs @@ -254,18 +254,18 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator -> Result<(), ParserError> { match ct { - InlinedClauseType::CompareNumber(cmp) => { + InlinedClauseType::CompareNumber(cmp, ..) => { 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)?; code.append(&mut lcode); code.append(&mut rcode); - + code.push(compare_number_instr!(cmp, at_1.unwrap_or(interm!(1)), at_2.unwrap_or(interm!(2)))); }, - InlinedClauseType::IsAtom => + InlinedClauseType::IsAtom(..) => match terms[0].as_ref() { &Term::Constant(_, Constant::Atom(_)) => { code.push(succeed!()); @@ -278,7 +278,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator code.push(fail!()); } }, - InlinedClauseType::IsAtomic => + InlinedClauseType::IsAtomic(..) => match terms[0].as_ref() { &Term::AnonVar | &Term::Clause(..) | &Term::Cons(..) => { code.push(fail!()); @@ -291,7 +291,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator code.push(is_atomic!(r)); } }, - InlinedClauseType::IsCompound => + InlinedClauseType::IsCompound(..) => match terms[0].as_ref() { &Term::Clause(..) | &Term::Cons(..) => { code.push(succeed!()); @@ -304,7 +304,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator code.push(fail!()); } }, - InlinedClauseType::IsRational => + InlinedClauseType::IsRational(..) => match terms[0].as_ref() { &Term::Constant(_, Constant::Number(Number::Rational(_))) => { code.push(succeed!()); @@ -317,7 +317,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator code.push(fail!()); } }, - InlinedClauseType::IsFloat => + InlinedClauseType::IsFloat(..) => match terms[0].as_ref() { &Term::Constant(_, Constant::Number(Number::Float(_))) => { code.push(succeed!()); @@ -330,7 +330,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator code.push(fail!()); } }, - InlinedClauseType::IsString => + InlinedClauseType::IsString(..) => match terms[0].as_ref() { &Term::Constant(_, Constant::String(_)) => { code.push(succeed!()); @@ -343,7 +343,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator code.push(fail!()); } }, - InlinedClauseType::IsNonVar => + InlinedClauseType::IsNonVar(..) => match terms[0].as_ref() { &Term::AnonVar => { code.push(fail!()); @@ -356,7 +356,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator code.push(succeed!()); } }, - InlinedClauseType::IsInteger => + InlinedClauseType::IsInteger(..) => match terms[0].as_ref() { &Term::Constant(_, Constant::Number(Number::Integer(_))) => { code.push(succeed!()); @@ -369,7 +369,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator code.push(fail!()); }, }, - InlinedClauseType::IsVar => + InlinedClauseType::IsVar(..) => match terms[0].as_ref() { &Term::Constant(..) | &Term::Clause(..) | &Term::Cons(..) => { code.push(fail!()); @@ -416,7 +416,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator } else { 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)?; code.append(&mut acode); diff --git a/src/prolog/io.rs b/src/prolog/io.rs index eceacfa1..52876615 100644 --- a/src/prolog/io.rs +++ b/src/prolog/io.rs @@ -173,10 +173,6 @@ impl fmt::Display for IndexedChoiceInstruction { impl fmt::Display for BuiltInInstruction { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 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 => write!(f, "clean_up_block"), &BuiltInInstruction::CompareNumber(cmp, ref at_1, ref at_2) => @@ -209,8 +205,6 @@ impl fmt::Display for BuiltInInstruction { write!(f, "install_cleaner"), &BuiltInInstruction::InstallNewBlock => write!(f, "install_new_block"), - &BuiltInInstruction::InternalCallN => - write!(f, "internal_call_N"), &BuiltInInstruction::RemoveCallPolicyCheck => write!(f, "remove_call_policy_check"), &BuiltInInstruction::RemoveInferenceCounter(r1, r2) => diff --git a/src/prolog/iterators.rs b/src/prolog/iterators.rs index 23c5aad4..5ce7f36e 100644 --- a/src/prolog/iterators.rs +++ b/src/prolog/iterators.rs @@ -341,7 +341,8 @@ impl<'a> ChunkedIterator<'a> result.push(term), ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::Inlined(_), _)) => result.push(term), - ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::CallN, ref subterms)) => { + ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::CallN, ref subterms)) => + { result.push(term); arity = subterms.len() + 1; break; diff --git a/src/prolog/lib/builtins.pl b/src/prolog/lib/builtins.pl new file mode 100644 index 00000000..7a46bf8d --- /dev/null +++ b/src/prolog/lib/builtins.pl @@ -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, =<). diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index f9dad13e..7913137a 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -209,7 +209,7 @@ pub struct MachineState { pub(super) b0: usize, pub(super) e: usize, pub(super) num_of_args: usize, - pub(super) cp: CodePtr, + pub(super) cp: LocalCodePtr, pub(super) fail: bool, pub(crate) heap: Heap, pub(super) mode: MachineMode, @@ -248,10 +248,10 @@ pub(crate) trait CallPolicy: Any { IndexPtr::Index(compiled_tl_index) => { 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.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.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(()) } - fn try_call_clause<'a>(&mut self, machine_st: &mut MachineState, code_dirs: CodeDirs<'a>, - ct: &ClauseType, arity: usize, lco: bool) - -> CallResult + fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize, + code_dirs: CodeDirs<'a>, lco: bool) + -> CallResult { - match ct { - &ClauseType::AcyclicTerm => { - let addr = machine_st[temp_v!(1)].clone(); - machine_st.fail = machine_st.is_cyclic_term(addr); - return_from_clause!(lco, machine_st) - }, - &ClauseType::Arg => { - if !lco { - machine_st.cp = machine_st.p.clone() + 1; + 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)); + } + }; + } - machine_st.num_of_args = 3; - machine_st.b0 = machine_st.b; - machine_st.p = CodePtr::DirEntry(166, clause_name!("builtin")); + break; + } - Ok(()) - }, - &ClauseType::Catch => { - if !lco { - machine_st.cp = machine_st.p.clone() + 1; - } + Ok(()) + } - machine_st.num_of_args = 3; - machine_st.b0 = machine_st.b; - machine_st.p = CodePtr::DirEntry(5, clause_name!("builtin")); + fn system_call(&mut self, machine_st: &mut MachineState, ct: &SystemClauseType) -> CallResult + { + match ct { + &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(); + machine_st.fail = machine_st.is_cyclic_term(addr); + return_from_clause!(lco, machine_st) }, - &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 => { + &BuiltInClauseType::Compare => { let a1 = machine_st[temp_v!(1)].clone(); let a2 = machine_st[temp_v!(2)].clone(); let a3 = machine_st[temp_v!(3)].clone(); @@ -462,7 +473,7 @@ pub(crate) trait CallPolicy: Any { machine_st.unify(a1, c); return_from_clause!(lco, machine_st) }, - &ClauseType::CompareTerm(qt) => { + &BuiltInClauseType::CompareTerm(qt) => { match qt { CompareTermQT::Equal => machine_st.fail = machine_st.structural_eq_test(), @@ -473,12 +484,12 @@ pub(crate) trait CallPolicy: Any { return_from_clause!(lco, machine_st) }, - &ClauseType::CyclicTerm => { + &BuiltInClauseType::CyclicTerm => { let addr = machine_st[temp_v!(1)].clone(); machine_st.fail = !machine_st.is_cyclic_term(addr); return_from_clause!(lco, machine_st) }, - &ClauseType::Display => { + &BuiltInClauseType::Display => { let output = machine_st.print_term(machine_st[temp_v!(1)].clone(), DisplayFormatter {}, PrinterOutputter::new()); @@ -486,27 +497,27 @@ pub(crate) trait CallPolicy: Any { println!("{}", output.result()); return_from_clause!(lco, machine_st) }, - &ClauseType::DuplicateTerm => { + &BuiltInClauseType::DuplicateTerm => { machine_st.duplicate_term(); return_from_clause!(lco, machine_st) }, - &ClauseType::Eq => { + &BuiltInClauseType::Eq => { machine_st.fail = machine_st.eq_test(); return_from_clause!(lco, machine_st) }, - &ClauseType::Ground => { + &BuiltInClauseType::Ground => { machine_st.fail = machine_st.ground_test(); return_from_clause!(lco, machine_st) }, - &ClauseType::Functor => { + &BuiltInClauseType::Functor => { machine_st.try_functor()?; return_from_clause!(lco, machine_st) }, - &ClauseType::NotEq => { + &BuiltInClauseType::NotEq => { machine_st.fail = !machine_st.eq_test(); return_from_clause!(lco, machine_st) }, - &ClauseType::Sort => { + &BuiltInClauseType::Sort => { machine_st.check_sort_errors()?; 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) }, - &ClauseType::KeySort => { + &BuiltInClauseType::KeySort => { machine_st.check_keysort_errors()?; 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) }, - &ClauseType::Throw => { - 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 => { + &BuiltInClauseType::Is => { let a = machine_st[temp_v!(1)].clone(); let result = machine_st.arith_eval_by_metacall(temp_v!(2))?; @@ -571,14 +564,8 @@ pub(crate) trait CallPolicy: Any { Ok(()) }, - &ClauseType::Inlined(ref inlined) => { - machine_st.execute_inlined(inlined, &vec![temp_v!(1), temp_v!(2)]); - Ok(()) - }, - &ClauseType::System(ref system) => { - machine_st.execute_system(system)?; - return_from_clause!(lco, machine_st) - } + &BuiltInClauseType::System(ref ct) => + self.system_call(machine_st, ct), } } } @@ -680,11 +667,10 @@ impl CallPolicy for CallWithInferenceLimitCallPolicy { self.increment() } - fn try_call_clause<'a>(&mut self, machine_st: &mut MachineState, code_dirs: CodeDirs<'a>, - ct: &ClauseType, arity: usize, lco: bool) - -> CallResult + fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType, lco: bool) + -> 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() } } @@ -757,11 +743,11 @@ impl CutPolicy for SetupCallCleanupCutPolicy { machine_st.p += 1; 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.b0 = machine_st.b; // 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")); } } } diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index 5665eea2..bc12c399 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -38,7 +38,7 @@ impl MachineState { b0: 0, e: 0, num_of_args: 0, - cp: CodePtr::default(), + cp: LocalCodePtr::default(), fail: false, heap: Heap::with_capacity(256), mode: MachineMode::Write, @@ -670,7 +670,7 @@ impl MachineState { &ArithmeticInstruction::Xor(ref a1, ref a2, t) => { let n1 = try_or_fail!(self, self.get_number(a1)); let n2 = try_or_fail!(self, self.get_number(a2)); - + self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.xor(n1, n2))); self.p += 1; }, @@ -1011,8 +1011,7 @@ impl MachineState { } } - fn handle_internal_call_n<'a>(&mut self, call_policy: &mut Box, - code_dirs: CodeDirs<'a>) + pub(super) fn handle_internal_call_n(&mut self) { let arity = self.num_of_args + 1; let pred = self.registers[1].clone(); @@ -1023,32 +1022,20 @@ impl MachineState { if arity > 1 { self.registers[arity - 1] = pred; - - 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; - } - } + return; } 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) { let addr = self[temp_v!(1)].clone(); self.ball.boundary = self.heap.h; - + let mut duplicator = DuplicateBallTerm::new(self); - duplicator.duplicate_term(addr); + duplicator.duplicate_term(addr); } - + pub(super) fn unwind_stack(&mut self) { self.b = self.block; self.or_stack.truncate(self.b); @@ -1071,7 +1058,6 @@ impl MachineState { self.error_form(self.representation_error(RepFlag::MaxArity), stub); self.throw_exception(representation_error); - return None; } @@ -1334,20 +1320,15 @@ impl MachineState { }; } - pub(super) fn execute_inlined(&mut self, inlined: &InlinedClauseType, rs: &Vec) - { - let r1 = rs[0].clone(); - + pub(super) fn execute_inlined(&mut self, inlined: &InlinedClauseType) { match inlined { - &InlinedClauseType::CompareNumber(cmp) => { - let r2 = rs[1].clone(); - + &InlinedClauseType::CompareNumber(cmp, r1, r2) => { let n1 = try_or_fail!(self, self.arith_eval_by_metacall(r1)); let n2 = try_or_fail!(self, self.arith_eval_by_metacall(r2)); self.compare_numbers(cmp, n1, n2); }, - &InlinedClauseType::IsAtom => { + &InlinedClauseType::IsAtom(r1) => { let d = self.store(self.deref(self[r1].clone())); match d { @@ -1355,7 +1336,7 @@ impl MachineState { _ => self.fail = true }; }, - &InlinedClauseType::IsAtomic => { + &InlinedClauseType::IsAtomic(r1) => { let d = self.store(self.deref(self[r1].clone())); match d { @@ -1363,7 +1344,7 @@ impl MachineState { _ => self.fail = true }; }, - &InlinedClauseType::IsInteger => { + &InlinedClauseType::IsInteger(r1) => { let d = self.store(self.deref(self[r1].clone())); match d { @@ -1371,7 +1352,7 @@ impl MachineState { _ => self.fail = true }; }, - &InlinedClauseType::IsCompound => { + &InlinedClauseType::IsCompound(r1) => { let d = self.store(self.deref(self[r1].clone())); match d { @@ -1379,7 +1360,7 @@ impl MachineState { _ => self.fail = true }; }, - &InlinedClauseType::IsFloat => { + &InlinedClauseType::IsFloat(r1) => { let d = self.store(self.deref(self[r1].clone())); match d { @@ -1387,7 +1368,7 @@ impl MachineState { _ => self.fail = true }; }, - &InlinedClauseType::IsRational => { + &InlinedClauseType::IsRational(r1) => { let d = self.store(self.deref(self[r1].clone())); match d { @@ -1395,7 +1376,7 @@ impl MachineState { _ => self.fail = true }; }, - &InlinedClauseType::IsString => { + &InlinedClauseType::IsString(r1) => { let d = self.store(self.deref(self[r1].clone())); match d { @@ -1403,7 +1384,7 @@ impl MachineState { _ => self.fail = true }; }, - &InlinedClauseType::IsNonVar => { + &InlinedClauseType::IsNonVar(r1) => { let d = self.store(self.deref(self[r1].clone())); match d { @@ -1411,7 +1392,7 @@ impl MachineState { _ => self.p += 1 }; }, - &InlinedClauseType::IsVar => { + &InlinedClauseType::IsVar(r1) => { let d = self.store(self.deref(self[r1].clone())); match d { @@ -1428,8 +1409,6 @@ impl MachineState { instr: &BuiltInInstruction) { match instr { - &BuiltInInstruction::CallInlined(ref inlined, ref rs) => - self.execute_inlined(inlined, rs), &BuiltInInstruction::CompareNumber(cmp, ref at_1, ref at_2) => { let n1 = try_or_fail!(self, self.get_number(at_1)); let n2 = try_or_fail!(self, self.get_number(at_2)); @@ -1457,7 +1436,7 @@ impl MachineState { let val = self.try_get_arg(); if lco { - self.p = self.cp.clone(); + self.p = CodePtr::Local(self.cp.clone()); } else { self.p += 1; } @@ -1658,8 +1637,6 @@ impl MachineState { }, &BuiltInInstruction::UnwindStack => self.unwind_stack(), - &BuiltInInstruction::InternalCallN => - self.handle_internal_call_n(call_policy, code_dirs), &BuiltInInstruction::Fail => { self.fail = true; self.p += 1; @@ -1946,66 +1923,86 @@ impl MachineState { false } - pub(super) fn execute_ctrl_instr<'a>(&mut self, code_dirs: CodeDirs<'a>, - call_policy: &mut Box, - cut_policy: &mut Box, - instr: &ControlInstruction) - { - match instr { - &ControlInstruction::Allocate(num_cells) => { - let gi = self.next_global_index(); + 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 += 1; + self.p = CodePtr::BuiltInClause(ct, self.p.local()); + } - 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); + pub(super) fn allocate(&mut self, num_cells: usize) { + let gi = self.next_global_index(); - if and_gi > or_gi { - let index = self.e + 1; + self.p += 1; - self.and_stack[index].e = self.e; - self.and_stack[index].cp = self.cp.clone(); - self.and_stack[index].global_index = gi; + 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); - self.and_stack.resize(index, num_cells); + if and_gi > or_gi { + let index = self.e + 1; - self.e = index; + self.and_stack[index].e = self.e; + self.and_stack[index].cp = self.cp.clone(); + self.and_stack[index].global_index = gi; - return; - } - } + self.and_stack.resize(index, num_cells); + self.e = index; - 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)), + 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>, + call_policy: &mut Box, + cut_policy: &mut Box, + instr: &ControlInstruction) + { + match instr { + &ControlInstruction::Allocate(num_cells) => + self.allocate(num_cells), + &ControlInstruction::CallClause(ClauseType::CallN, arity, _, lco) => + try_or_fail!(self, call_policy.call_n(self, arity, code_dirs, lco)), + &ControlInstruction::CallClause(ClauseType::BuiltIn(ref ct), _, _, lco) => + try_or_fail!(self, call_policy.call_builtin(self, ct, lco)), + &ControlInstruction::CallClause(ClauseType::Inlined(ref ct), _, _, lco) => + self.execute_inlined(ct), + &ControlInstruction::CallClause(ClauseType::Named(ref name, ref idx), arity, _, lco) + | &ControlInstruction::CallClause(ClauseType::Op(ref name, _, ref idx), arity, _, lco) => + try_or_fail!(self, call_policy.context_call(self, name.clone(), arity, idx.clone(), + lco)), &ControlInstruction::CheckCpExecute => { let a = self.store(self.deref(self[temp_v!(2)].clone())); match a { 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.b0 = self.b; // goto sgc_on_success/2, 382. - self.p = CodePtr::DirEntry(382, clause_name!("builtin")); + self.p = dir_entry!(382, clause_name!("builtin")); } }; }, - &ControlInstruction::Deallocate => { - let e = self.e; - - self.cp = self.and_stack[e].cp.clone(); - self.e = self.and_stack[e].e; - - self.p += 1; - }, + &ControlInstruction::Deallocate => self.deallocate(), &ControlInstruction::GetCleanerCall => { let dest = self[temp_v!(1)].clone(); @@ -2032,7 +2029,7 @@ impl MachineState { self.fail = true; }, &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) => { let a1 = self[r].clone(); let a2 = try_or_fail!(self, self.get_number(at)); @@ -2042,7 +2039,7 @@ impl MachineState { }, &ControlInstruction::JmpBy(arity, offset, _, lco) => { if !lco { - self.cp = self.p.clone() + 1; + self.cp.assign_if_local(self.p.clone() + 1); } self.num_of_args = arity; @@ -2050,13 +2047,13 @@ impl MachineState { self.p += offset; }, &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) { if !lco { - self.cp = self.p.clone() + 1; + self.cp.assign_if_local(self.p.clone() + 1); } self.num_of_args = arity; @@ -2169,7 +2166,7 @@ impl MachineState { self.s = 0; self.tr = 0; self.p = CodePtr::default(); - self.cp = CodePtr::default(); + self.cp = LocalCodePtr::default(); self.num_of_args = 0; self.fail = false; diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 5377949e..163c0b16 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -34,18 +34,18 @@ pub struct Machine { cached_query: Option } -impl Index for Machine { +impl Index for Machine { type Output = Line; - fn index(&self, ptr: CodePtr) -> &Self::Output { + fn index(&self, ptr: LocalCodePtr) -> &Self::Output { match ptr { - CodePtr::TopLevel(_, p) => { + LocalCodePtr::TopLevel(_, p) => { match &self.cached_query { &Some(ref cq) => &cq[p], &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 { + 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) { - let instr = match self.ms.p { - CodePtr::TopLevel(_, p) => { - match &self.cached_query { - &Some(ref cq) => &cq[p], - &None => return - } - }, - CodePtr::DirEntry(p, _) => &self.code[p] + let instr = match self.lookup_instr(self.ms.p.clone()) { + Some(instr) => instr, + None => return }; match instr { - &Line::Arithmetic(ref arith_instr) => + Line::Arithmetic(ref 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); self.ms.execute_built_in_instr(code_dirs, &mut self.call_policy, &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), - &Line::Cut(ref cut_instr) => + Line::Cut(ref cut_instr) => 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); self.ms.execute_ctrl_instr(code_dirs, &mut self.call_policy, &mut self.cut_policy, control_instr) }, - &Line::Fact(ref fact) => { + Line::Fact(ref fact) => { for fact_instr in fact { if self.failed() { break; @@ -263,11 +274,11 @@ impl Machine { self.ms.p += 1; }, - &Line::Indexing(ref indexing_instr) => + Line::Indexing(ref 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), - &Line::Query(ref query) => { + Line::Query(ref query) => { for query_instr in query { if self.failed() { break; @@ -289,13 +300,13 @@ impl Machine { self.ms.b0 = self.ms.or_stack[b].b0; 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; } else { self.ms.fail = false; } } 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 { - CodePtr::DirEntry(p, _) if p < self.code.len() => {}, - _ => break + CodePtr::Local(LocalCodePtr::DirEntry(p, _)) if p < self.code.len() => {}, + CodePtr::Local(_) => break, + _ => {} }; } } @@ -342,11 +354,11 @@ impl Machine { 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 { - if let CodePtr::TopLevel(mut cn, p) = self.ms.p { - match &self[CodePtr::TopLevel(cn, p)] { + if let CodePtr::Local(LocalCodePtr::TopLevel(mut cn, p)) = self.ms.p { + match &self[LocalCodePtr::TopLevel(cn, p)] { &Line::Control(ref ctrl_instr) if ctrl_instr.is_jump_instr() => { self.record_var_places(cn, alloc_locs, heap_locs); 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(); match self.ms.p { - CodePtr::TopLevel(_, p) if p > 0 => {}, + CodePtr::Local(LocalCodePtr::TopLevel(_, p)) if p > 0 => {}, _ => { if heap_locs.is_empty() { self.record_var_places(0, alloc_locs, heap_locs); @@ -377,7 +389,7 @@ impl Machine { if self.ms.ball.stub.len() > 0 { let h = self.ms.heap.h; self.ms.copy_and_align_ball_to_heap(); - + let error_str = self.ms.print_exception(Addr::HeapCell(h), &heap_locs, TermFormatter {}, @@ -410,7 +422,7 @@ impl Machine { let b = self.ms.b - 1; 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); } diff --git a/src/prolog/macros.rs b/src/prolog/macros.rs index 140791f9..a665add2 100644 --- a/src/prolog/macros.rs +++ b/src/prolog/macros.rs @@ -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 { ($cmp: expr, $at_1: expr, $at_2: expr) => ( 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 { ($x:expr) => ( 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 { ($r:expr) => ( - Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsAtom, vec![$r])) + call_clause!(ClauseType::Inlined(InlinedClauseType::IsAtom($r)), 1, 0) ) } macro_rules! is_atomic { ($r:expr) => ( - Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsAtomic, vec![$r])) + call_clause!(ClauseType::Inlined(InlinedClauseType::IsAtomic($r)), 1, 0) ) } macro_rules! is_integer { ($r:expr) => ( - Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsInteger, vec![$r])) + call_clause!(ClauseType::Inlined(InlinedClauseType::IsInteger($r)), 1, 0) ) } macro_rules! is_compound { ($r:expr) => ( - Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsCompound, vec![$r])) + call_clause!(ClauseType::Inlined(InlinedClauseType::IsCompound($r)), 1, 0) ) } macro_rules! is_float { ($r:expr) => ( - Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsFloat, vec![$r])) + call_clause!(ClauseType::Inlined(InlinedClauseType::IsFloat($r)), 1, 0) ) } macro_rules! is_rational { ($r:expr) => ( - Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsRational, vec![$r])) + call_clause!(ClauseType::Inlined(InlinedClauseType::IsRational($r)), 1, 0) ) } macro_rules! is_nonvar { ($r:expr) => ( - Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsNonVar, vec![$r])) + call_clause!(ClauseType::Inlined(InlinedClauseType::IsNonVar($r)), 1, 0) ) } macro_rules! is_string { ($r:expr) => ( - Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsString, vec![$r])) + call_clause!(ClauseType::Inlined(InlinedClauseType::IsString($r)), 1, 0) ) } macro_rules! is_var { ($r:expr) => ( - Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsVar, vec![$r])) - ) -} - -macro_rules! trust_me { - () => ( - Line::Choice(ChoiceInstruction::TrustMe) + call_clause!(ClauseType::Inlined(InlinedClauseType::IsVar($r)), 1, 0) ) } @@ -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 { () => ( 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 { ($r:expr, $at:expr) => ( 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 { () => ( 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 { ($r:expr) => ( Line::BuiltIn(BuiltInInstruction::SetCutPoint($r)) ) } -macro_rules! get_cp { - ($r:expr) => ( - Line::BuiltIn(BuiltInInstruction::GetCutPoint($r)) - ) -} - macro_rules! integer { ($i:expr) => ( 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 { ($e:expr) => ( 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 { ($arity:expr, $offset:expr, $pvs:expr) => ( 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 { ($e:expr) => ( 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 { ($lco:expr, $machine_st:expr) => {{ if $lco { - $machine_st.p = $machine_st.cp.clone(); + $machine_st.p = CodePtr::Local($machine_st.cp.clone()); } else { $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 { ($idx:expr, $ip:expr, $mod_name:expr) => {{ 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 } ) } + +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)) + ) +} diff --git a/src/prolog/or_stack.rs b/src/prolog/or_stack.rs index 07041ed3..d32c490f 100644 --- a/src/prolog/or_stack.rs +++ b/src/prolog/or_stack.rs @@ -6,7 +6,7 @@ use std::vec::Vec; pub struct Frame { pub global_index: usize, pub e: usize, - pub cp: CodePtr, + pub cp: LocalCodePtr, pub b: usize, pub bp: CodePtr, pub tr: usize, @@ -18,7 +18,7 @@ pub struct Frame { impl Frame { fn new(global_index: usize, e: usize, - cp: CodePtr, + cp: LocalCodePtr, b: usize, bp: CodePtr, tr: usize, @@ -55,7 +55,7 @@ impl OrStack { pub fn push(&mut self, global_index: usize, e: usize, - cp: CodePtr, + cp: LocalCodePtr, b: usize, bp: CodePtr, tr: usize, diff --git a/src/prolog/toplevel.rs b/src/prolog/toplevel.rs index 3c122dfc..addb26e9 100644 --- a/src/prolog/toplevel.rs +++ b/src/prolog/toplevel.rs @@ -233,7 +233,7 @@ fn unfold_by_str(mut term: Term, s: &str) -> Vec terms.push(fst); term = snd; } - + terms.push(term); terms } @@ -397,10 +397,8 @@ impl RelationWorker { }, Term::Var(_, ref v) if v.as_str() == "!" => Ok(QueryTerm::UnblockedCut(Cell::default())), - Term::Clause(r, name, mut terms, fixity) => - if let Some(system_ct) = SystemClauseType::from(name.as_str(), terms.len()) { - Ok(QueryTerm::Clause(r, ClauseType::System(system_ct), terms)) - } else if name.as_str() == ";" { + Term::Clause(r, name, mut terms, fixity) => + if name.as_str() == ";" { if terms.len() == 2 { let term = Term::Clause(r, name.clone(), terms, fixity); let (stub, clauses) = self.fabricate_disjunct(term); -- 2.54.0