-#[macro_use] extern crate cfg_if;
-#[macro_use] extern crate downcast;
+#[macro_use]
+extern crate cfg_if;
+#[macro_use]
+extern crate downcast;
extern crate indexmap;
-#[macro_use] extern crate prolog_parser;
-#[macro_use] extern crate ref_thread_local;
+#[macro_use]
+extern crate prolog_parser;
+#[macro_use]
+extern crate ref_thread_local;
cfg_if! {
if #[cfg(feature = "readline_rs_compat")] {
use std::cell::Cell;
use std::rc::Rc;
-pub trait Allocator<'a>
-{
+pub trait Allocator<'a> {
fn new() -> Self;
fn mark_anon_var<Target>(&mut self, Level, GenContext, &mut Vec<Target>)
- where Target: CompilationTarget<'a>;
+ where
+ Target: CompilationTarget<'a>;
fn mark_non_var<Target>(&mut self, Level, GenContext, &'a Cell<RegType>, &mut Vec<Target>)
- where Target: CompilationTarget<'a>;
- fn mark_reserved_var<Target>(&mut self, Rc<Var>, Level, &'a Cell<VarReg>, GenContext,
- &mut Vec<Target>, RegType, bool)
- where Target: CompilationTarget<'a>;
+ where
+ Target: CompilationTarget<'a>;
+ fn mark_reserved_var<Target>(
+ &mut self,
+ Rc<Var>,
+ Level,
+ &'a Cell<VarReg>,
+ GenContext,
+ &mut Vec<Target>,
+ RegType,
+ bool,
+ ) where
+ Target: CompilationTarget<'a>;
fn mark_var<Target>(&mut self, Rc<Var>, Level, &'a Cell<VarReg>, GenContext, &mut Vec<Target>)
- where Target: CompilationTarget<'a>;
+ where
+ Target: CompilationTarget<'a>;
fn reset(&mut self);
fn reset_contents(&mut self) {}
fn take_bindings(self) -> AllocVarDict;
- fn drain_var_data(&mut self, vs: VariableFixtures<'a>) -> VariableFixtures<'a>
- {
+ fn drain_var_data(&mut self, vs: VariableFixtures<'a>) -> VariableFixtures<'a> {
let mut perm_vs = VariableFixtures::new();
for (var, (var_status, cells)) in vs.into_iter() {
match var_status {
VarStatus::Temp(chunk_num, tvd) => {
- self.bindings_mut().insert(var.clone(), VarData::Temp(chunk_num, 0, tvd));
- },
+ self.bindings_mut()
+ .insert(var.clone(), VarData::Temp(chunk_num, 0, tvd));
+ }
VarStatus::Perm(_) => {
self.bindings_mut().insert(var.clone(), VarData::Perm(0));
perm_vs.insert(var, (var_status, cells));
}
fn get(&self, var: Rc<Var>) -> RegType {
- self.bindings().get(&var).map_or(temp_v!(0), |v| v.as_reg_type())
+ self.bindings()
+ .get(&var)
+ .map_or(temp_v!(0), |v| v.as_reg_type())
}
fn is_unbound(&self, var: Rc<Var>) -> bool {
fn record_register(&mut self, var: Rc<Var>, r: RegType) {
match self.bindings_mut().get_mut(&var).unwrap() {
&mut VarData::Temp(_, ref mut s, _) => *s = r.reg_num(),
- &mut VarData::Perm(ref mut s) => *s = r.reg_num()
+ &mut VarData::Perm(ref mut s) => *s = r.reg_num(),
}
}
}
use prolog::machine::machine_indices::*;
use prolog::ordered_float::*;
-use prolog::rug::{Assign, Integer, Rational};
use prolog::rug::ops::PowAssign;
+use prolog::rug::{Assign, Integer, Rational};
use std::cell::Cell;
-use std::cmp::{Ordering, min, max};
+use std::cmp::{max, min, Ordering};
use std::f64;
use std::num::FpCategory;
-use std::ops::{Add, Sub, Div, Mul, Neg};
+use std::ops::{Add, Div, Mul, Neg, Sub};
use std::rc::Rc;
use std::vec::Vec;
pub struct ArithInstructionIterator<'a> {
- state_stack: Vec<TermIterState<'a>>
+ state_stack: Vec<TermIterState<'a>>,
}
pub type ArithCont = (Code, Option<ArithmeticTerm>);
impl<'a> ArithInstructionIterator<'a> {
fn push_subterm(&mut self, lvl: Level, term: &'a Term) {
- self.state_stack.push(TermIterState::subterm_to_state(lvl, term));
+ self.state_stack
+ .push(TermIterState::subterm_to_state(lvl, term));
}
fn new(term: &'a Term) -> Result<Self, ArithmeticError> {
let state = match term {
- &Term::AnonVar =>
- return Err(ArithmeticError::UninstantiatedVar),
- &Term::Clause(ref cell, ref name, ref terms, ref fixity) =>
+ &Term::AnonVar => return Err(ArithmeticError::UninstantiatedVar),
+ &Term::Clause(ref cell, ref name, ref terms, ref fixity) => {
match ClauseType::from(name.clone(), terms.len(), fixity.clone()) {
- ct @ ClauseType::Named(..) | ct @ ClauseType::Op(..) =>
- Ok(TermIterState::Clause(Level::Shallow, 0, cell, ct, terms)),
+ ct @ ClauseType::Named(..) | ct @ ClauseType::Op(..) => {
+ Ok(TermIterState::Clause(Level::Shallow, 0, cell, ct, terms))
+ }
ClauseType::Inlined(InlinedClauseType::IsFloat(_)) => {
let ct = ClauseType::Named(clause_name!("float"), 1, CodeIndex::default());
Ok(TermIterState::Clause(Level::Shallow, 0, cell, ct, terms))
- },
- _ => Err(ArithmeticError::NonEvaluableFunctor(Constant::Atom(name.clone(),
- fixity.clone()),
- terms.len()))
- }?,
- &Term::Constant(ref cell, ref cons) =>
- TermIterState::Constant(Level::Shallow, cell, cons),
- &Term::Cons(_, _, _) =>
- return Err(ArithmeticError::NonEvaluableFunctor(atom!("'.'"), 2)),
- &Term::Var(ref cell, ref var) =>
- TermIterState::Var(Level::Shallow, cell, var.clone())
+ }
+ _ => Err(ArithmeticError::NonEvaluableFunctor(
+ Constant::Atom(name.clone(), fixity.clone()),
+ terms.len(),
+ )),
+ }?
+ }
+ &Term::Constant(ref cell, ref cons) => {
+ TermIterState::Constant(Level::Shallow, cell, cons)
+ }
+ &Term::Cons(_, _, _) => {
+ return Err(ArithmeticError::NonEvaluableFunctor(atom!("'.'"), 2))
+ }
+ &Term::Var(ref cell, ref var) => TermIterState::Var(Level::Shallow, cell, var.clone()),
};
- Ok(ArithInstructionIterator { state_stack: vec![state] })
+ Ok(ArithInstructionIterator {
+ state_stack: vec![state],
+ })
}
}
pub enum ArithTermRef<'a> {
Constant(&'a Constant),
Op(ClauseName, usize), // name, arity.
- Var(&'a Cell<VarReg>, Rc<Var>)
+ Var(&'a Cell<VarReg>, Rc<Var>),
}
impl<'a> Iterator for ArithInstructionIterator<'a> {
fn next(&mut self) -> Option<Self::Item> {
while let Some(iter_state) = self.state_stack.pop() {
match iter_state {
- TermIterState::AnonVar(_) =>
- return Some(Err(ArithmeticError::UninstantiatedVar)),
+ TermIterState::AnonVar(_) => return Some(Err(ArithmeticError::UninstantiatedVar)),
TermIterState::Clause(lvl, child_num, cell, ct, subterms) => {
let arity = subterms.len();
if child_num == arity {
return Some(Ok(ArithTermRef::Op(ct.name(), arity)));
} else {
- self.state_stack.push(TermIterState::Clause(lvl, child_num + 1, cell, ct, subterms));
+ self.state_stack.push(TermIterState::Clause(
+ lvl,
+ child_num + 1,
+ cell,
+ ct,
+ subterms,
+ ));
self.push_subterm(lvl, subterms[child_num].as_ref());
}
- },
- TermIterState::Constant(_, _, c) =>
- return Some(Ok(ArithTermRef::Constant(c))),
- TermIterState::Var(_, cell, var) =>
- return Some(Ok(ArithTermRef::Var(cell, var.clone()))),
- _ =>
- return Some(Err(ArithmeticError::NonEvaluableFunctor(atom!("'.'"), 2)))
+ }
+ TermIterState::Constant(_, _, c) => return Some(Ok(ArithTermRef::Constant(c))),
+ TermIterState::Var(_, cell, var) => {
+ return Some(Ok(ArithTermRef::Var(cell, var.clone())))
+ }
+ _ => return Some(Err(ArithmeticError::NonEvaluableFunctor(atom!("'.'"), 2))),
};
}
pub struct ArithmeticEvaluator<'a> {
bindings: &'a AllocVarDict,
interm: Vec<ArithmeticTerm>,
- interm_c: usize
+ interm_c: usize,
}
pub trait ArithmeticTermIter<'a> {
- type Iter : Iterator<Item=Result<ArithTermRef<'a>, ArithmeticError>>;
+ type Iter: Iterator<Item = Result<ArithTermRef<'a>, ArithmeticError>>;
fn iter(self) -> Result<Self::Iter, ArithmeticError>;
}
}
}
-impl<'a> ArithmeticEvaluator<'a>
-{
+impl<'a> ArithmeticEvaluator<'a> {
pub fn new(bindings: &'a AllocVarDict, target_int: usize) -> Self {
- ArithmeticEvaluator { bindings, interm: Vec::new(), interm_c: target_int }
+ ArithmeticEvaluator {
+ bindings,
+ interm: Vec::new(),
+ interm_c: target_int,
+ }
}
- fn get_unary_instr(name: ClauseName, a1: ArithmeticTerm, t: usize)
- -> Result<ArithmeticInstruction, ArithmeticError>
- {
+ fn get_unary_instr(
+ name: ClauseName,
+ a1: ArithmeticTerm,
+ t: usize,
+ ) -> Result<ArithmeticInstruction, ArithmeticError> {
match name.as_str() {
"abs" => Ok(ArithmeticInstruction::Abs(a1, t)),
"-" => Ok(ArithmeticInstruction::Neg(a1, t)),
"ceiling" => Ok(ArithmeticInstruction::Ceiling(a1, t)),
"floor" => Ok(ArithmeticInstruction::Floor(a1, t)),
"\\" => Ok(ArithmeticInstruction::BitwiseComplement(a1, t)),
- _ => Err(ArithmeticError::NonEvaluableFunctor(Constant::Atom(name, None), 1))
+ _ => Err(ArithmeticError::NonEvaluableFunctor(
+ Constant::Atom(name, None),
+ 1,
+ )),
}
}
- fn get_binary_instr(name: ClauseName, a1: ArithmeticTerm, a2: ArithmeticTerm, t: usize)
- -> Result<ArithmeticInstruction, ArithmeticError>
- {
+ fn get_binary_instr(
+ name: ClauseName,
+ a1: ArithmeticTerm,
+ a2: ArithmeticTerm,
+ t: usize,
+ ) -> Result<ArithmeticInstruction, ArithmeticError> {
match name.as_str() {
- "+" => Ok(ArithmeticInstruction::Add(a1, a2, t)),
- "-" => Ok(ArithmeticInstruction::Sub(a1, a2, t)),
- "/" => Ok(ArithmeticInstruction::Div(a1, a2, t)),
- "//" => Ok(ArithmeticInstruction::IDiv(a1, a2, t)),
- "max" => Ok(ArithmeticInstruction::Max(a1, a2, t)),
- "min" => Ok(ArithmeticInstruction::Min(a1, a2, t)),
- "div" => Ok(ArithmeticInstruction::IntFloorDiv(a1, a2, t)),
+ "+" => Ok(ArithmeticInstruction::Add(a1, a2, t)),
+ "-" => Ok(ArithmeticInstruction::Sub(a1, a2, t)),
+ "/" => Ok(ArithmeticInstruction::Div(a1, a2, t)),
+ "//" => Ok(ArithmeticInstruction::IDiv(a1, a2, t)),
+ "max" => Ok(ArithmeticInstruction::Max(a1, a2, t)),
+ "min" => Ok(ArithmeticInstruction::Min(a1, a2, t)),
+ "div" => Ok(ArithmeticInstruction::IntFloorDiv(a1, a2, t)),
"rdiv" => Ok(ArithmeticInstruction::RDiv(a1, a2, t)),
- "*" => Ok(ArithmeticInstruction::Mul(a1, a2, t)),
- "**" => Ok(ArithmeticInstruction::Pow(a1, a2, t)),
- "^" => Ok(ArithmeticInstruction::IntPow(a1, a2, t)),
- ">>" => Ok(ArithmeticInstruction::Shr(a1, a2, t)),
- "<<" => Ok(ArithmeticInstruction::Shl(a1, a2, t)),
- "/\\" => Ok(ArithmeticInstruction::And(a1, a2, t)),
- "\\/" => Ok(ArithmeticInstruction::Or(a1, a2, t)),
- "xor" => Ok(ArithmeticInstruction::Xor(a1, a2, t)),
- "mod" => Ok(ArithmeticInstruction::Mod(a1, a2, t)),
- "rem" => Ok(ArithmeticInstruction::Rem(a1, a2, t)),
+ "*" => Ok(ArithmeticInstruction::Mul(a1, a2, t)),
+ "**" => Ok(ArithmeticInstruction::Pow(a1, a2, t)),
+ "^" => Ok(ArithmeticInstruction::IntPow(a1, a2, t)),
+ ">>" => Ok(ArithmeticInstruction::Shr(a1, a2, t)),
+ "<<" => Ok(ArithmeticInstruction::Shl(a1, a2, t)),
+ "/\\" => Ok(ArithmeticInstruction::And(a1, a2, t)),
+ "\\/" => Ok(ArithmeticInstruction::Or(a1, a2, t)),
+ "xor" => Ok(ArithmeticInstruction::Xor(a1, a2, t)),
+ "mod" => Ok(ArithmeticInstruction::Mod(a1, a2, t)),
+ "rem" => Ok(ArithmeticInstruction::Rem(a1, a2, t)),
"atan2" => Ok(ArithmeticInstruction::ATan2(a1, a2, t)),
- _ => Err(ArithmeticError::NonEvaluableFunctor(Constant::Atom(name, None), 2))
+ _ => Err(ArithmeticError::NonEvaluableFunctor(
+ Constant::Atom(name, None),
+ 2,
+ )),
}
}
temp
}
- fn instr_from_clause(&mut self, name: ClauseName, arity: usize)
- -> Result<ArithmeticInstruction, ArithmeticError>
- {
+ fn instr_from_clause(
+ &mut self,
+ name: ClauseName,
+ arity: usize,
+ ) -> Result<ArithmeticInstruction, ArithmeticError> {
match arity {
1 => {
let a1 = self.interm.pop().unwrap();
};
Self::get_unary_instr(name, a1, ninterm)
- },
+ }
2 => {
let a2 = self.interm.pop().unwrap();
let a1 = self.interm.pop().unwrap();
};
Self::get_binary_instr(name, a1, a2, ninterm)
- },
- _ => Err(ArithmeticError::NonEvaluableFunctor(Constant::Atom(name, None), arity))
+ }
+ _ => Err(ArithmeticError::NonEvaluableFunctor(
+ Constant::Atom(name, None),
+ arity,
+ )),
}
}
fn push_constant(&mut self, c: &Constant) -> Result<(), ArithmeticError> {
match c {
- &Constant::Integer(ref n) =>
- self.interm.push(ArithmeticTerm::Number(Number::Integer(n.clone()))),
- &Constant::Float(ref n) =>
- self.interm.push(ArithmeticTerm::Number(Number::Float(n.clone()))),
- &Constant::Rational(ref n) =>
- self.interm.push(ArithmeticTerm::Number(Number::Rational(n.clone()))),
- &Constant::Atom(ref name, _) if name.as_str() == "pi" =>
- self.interm.push(ArithmeticTerm::Number(Number::Float(OrderedFloat(f64::consts::PI)))),
- _ =>
- return Err(ArithmeticError::NonEvaluableFunctor(c.clone(), 0))
+ &Constant::Integer(ref n) => self
+ .interm
+ .push(ArithmeticTerm::Number(Number::Integer(n.clone()))),
+ &Constant::Float(ref n) => self
+ .interm
+ .push(ArithmeticTerm::Number(Number::Float(n.clone()))),
+ &Constant::Rational(ref n) => self
+ .interm
+ .push(ArithmeticTerm::Number(Number::Rational(n.clone()))),
+ &Constant::Atom(ref name, _) if name.as_str() == "pi" => {
+ self.interm
+ .push(ArithmeticTerm::Number(Number::Float(OrderedFloat(
+ f64::consts::PI,
+ ))))
+ }
+ _ => return Err(ArithmeticError::NonEvaluableFunctor(c.clone(), 0)),
}
Ok(())
}
pub fn eval<Iter>(&mut self, src: Iter) -> Result<ArithCont, ArithmeticError>
- where Iter: ArithmeticTermIter<'a>
+ where
+ Iter: ArithmeticTermIter<'a>,
{
let mut code = vec![];
- for term_ref in src.iter()?
- {
+ for term_ref in src.iter()? {
match term_ref? {
ArithTermRef::Constant(c) => self.push_constant(c)?,
ArithTermRef::Var(cell, name) => {
match self.bindings.get(&name) {
Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t),
Some(&VarData::Perm(p)) if p != 0 => RegType::Perm(p),
- _ => return Err(ArithmeticError::UninstantiatedVar)
+ _ => return Err(ArithmeticError::UninstantiatedVar),
}
} else {
cell.get().norm()
};
self.interm.push(ArithmeticTerm::Reg(r));
- },
+ }
ArithTermRef::Op(name, arity) => {
code.push(Line::Arithmetic(self.instr_from_clause(name, arity)?));
}
// integer division rounding function -- 9.1.3.1.
pub fn rnd_i<'a>(n: &'a Number) -> RefOrOwned<'a, Integer> {
match n {
- &Number::Integer(ref n) =>
- RefOrOwned::Borrowed(n),
- &Number::Float(OrderedFloat(f)) =>
- RefOrOwned::Owned(Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0))),
+ &Number::Integer(ref n) => RefOrOwned::Borrowed(n),
+ &Number::Float(OrderedFloat(f)) => {
+ RefOrOwned::Owned(Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0)))
+ }
&Number::Rational(ref r) => {
let r_ref = r.fract_floor_ref();
let (mut fract, mut floor) = (Rational::new(), Integer::new());
match n {
&Number::Integer(ref n) => n.to_f64(),
&Number::Float(OrderedFloat(f)) => f,
- &Number::Rational(ref r) => r.to_f64()
+ &Number::Rational(ref r) => r.to_f64(),
}
}
// floating point result function -- 9.1.4.2.
pub fn result_f<Round>(n: &Number, round: Round) -> Result<f64, EvalError>
- where Round: Fn(&Number) -> f64
+where
+ Round: Fn(&Number) -> f64,
{
let f = rnd_f(n);
classify_float(f, round)
}
fn classify_float<Round>(f: f64, round: Round) -> Result<f64, EvalError>
- where Round: Fn(&Number) -> f64
+where
+ Round: Fn(&Number) -> f64,
{
match f.classify() {
- FpCategory::Normal | FpCategory::Zero =>
- Ok(round(&Number::Float(OrderedFloat(f)))),
+ FpCategory::Normal | FpCategory::Zero => Ok(round(&Number::Float(OrderedFloat(f)))),
FpCategory::Infinite => {
let f = round(&Number::Float(OrderedFloat(f)));
} else {
Err(EvalError::FloatOverflow)
}
- },
+ }
FpCategory::Nan => Err(EvalError::Undefined),
- _ => Ok(round(&Number::Float(OrderedFloat(f))))
+ _ => Ok(round(&Number::Float(OrderedFloat(f)))),
}
}
fn add(self, rhs: Number) -> Self::Output {
match (self, rhs) {
- (Number::Integer(n1), Number::Integer(n2)) =>
- Ok(Number::Integer(n1 + n2)), // add_i
+ (Number::Integer(n1), Number::Integer(n2)) => Ok(Number::Integer(n1 + n2)), // add_i
(Number::Integer(n1), Number::Float(OrderedFloat(n2)))
- | (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) =>
- Ok(Number::Float(add_f(float_i_to_f(&n1)?, n2)?)),
+ | (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
+ Ok(Number::Float(add_f(float_i_to_f(&n1)?, n2)?))
+ }
(Number::Integer(n1), Number::Rational(n2))
- | (Number::Rational(n2), Number::Integer(n1)) =>
- Ok(Number::Rational(Rational::from(n1) + n2)),
+ | (Number::Rational(n2), Number::Integer(n1)) => {
+ Ok(Number::Rational(Rational::from(n1) + n2))
+ }
(Number::Rational(n1), Number::Float(OrderedFloat(n2)))
- | (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) =>
- Ok(Number::Float(add_f(float_r_to_f(&n1)?, n2)?)),
- (Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) =>
- Ok(Number::Float(add_f(f1, f2)?)),
- (Number::Rational(r1), Number::Rational(r2)) =>
- Ok(Number::Rational(r1 + r2))
+ | (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => {
+ Ok(Number::Float(add_f(float_r_to_f(&n1)?, n2)?))
+ }
+ (Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => {
+ Ok(Number::Float(add_f(f1, f2)?))
+ }
+ (Number::Rational(r1), Number::Rational(r2)) => Ok(Number::Rational(r1 + r2)),
}
}
}
match self {
Number::Integer(n) => Number::Integer(-n),
Number::Float(OrderedFloat(f)) => Number::Float(OrderedFloat(-f)),
- Number::Rational(r) => Number::Rational(-r)
+ Number::Rational(r) => Number::Rational(-r),
}
}
}
fn mul(self, rhs: Number) -> Self::Output {
match (self, rhs) {
- (Number::Integer(n1), Number::Integer(n2)) =>
- Ok(Number::Integer(n1 * n2)), // mul_i
+ (Number::Integer(n1), Number::Integer(n2)) => Ok(Number::Integer(n1 * n2)), // mul_i
(Number::Integer(n1), Number::Float(OrderedFloat(n2)))
- | (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) =>
- Ok(Number::Float(mul_f(float_i_to_f(&n1)?, n2)?)),
+ | (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
+ Ok(Number::Float(mul_f(float_i_to_f(&n1)?, n2)?))
+ }
(Number::Integer(n1), Number::Rational(n2))
- | (Number::Rational(n2), Number::Integer(n1)) =>
- Ok(Number::Rational(Rational::from(n1) * n2)),
+ | (Number::Rational(n2), Number::Integer(n1)) => {
+ Ok(Number::Rational(Rational::from(n1) * n2))
+ }
(Number::Rational(n1), Number::Float(OrderedFloat(n2)))
- | (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) =>
- Ok(Number::Float(mul_f(float_r_to_f(&n1)?, n2)?)),
- (Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) =>
- Ok(Number::Float(mul_f(f1, f2)?)),
- (Number::Rational(r1), Number::Rational(r2)) =>
- Ok(Number::Rational(r1 * r2))
+ | (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => {
+ Ok(Number::Float(mul_f(float_r_to_f(&n1)?, n2)?))
+ }
+ (Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => {
+ Ok(Number::Float(mul_f(f1, f2)?))
+ }
+ (Number::Rational(r1), Number::Rational(r2)) => Ok(Number::Rational(r1 * r2)),
}
}
}
fn div(self, rhs: Number) -> Self::Output {
match (self, rhs) {
- (Number::Integer(n1), Number::Integer(n2)) =>
- Ok(Number::Float(div_f(float_i_to_f(&n1)?, float_i_to_f(&n2)?)?)),
- (Number::Integer(n1), Number::Float(OrderedFloat(n2))) =>
- Ok(Number::Float(div_f(float_i_to_f(&n1)?, n2)?)),
- (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) =>
- Ok(Number::Float(div_f(n2, float_i_to_f(&n1)?)?)),
- (Number::Integer(n1), Number::Rational(n2)) =>
- Ok(Number::Float(div_f(float_i_to_f(&n1)?, float_r_to_f(&n2)?)?)),
- (Number::Rational(n2), Number::Integer(n1)) =>
- Ok(Number::Float(div_f(float_r_to_f(&n2)?, float_i_to_f(&n1)?)?)),
- (Number::Rational(n1), Number::Float(OrderedFloat(n2))) =>
- Ok(Number::Float(div_f(float_r_to_f(&n1)?, n2)?)),
- (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) =>
- Ok(Number::Float(div_f(n2, float_r_to_f(&n1)?)?)),
- (Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) =>
- Ok(Number::Float(div_f(f1, f2)?)),
- (Number::Rational(r1), Number::Rational(r2)) =>
- Ok(Number::Float(div_f(float_r_to_f(&r1)?, float_r_to_f(&r2)?)?))
+ (Number::Integer(n1), Number::Integer(n2)) => Ok(Number::Float(div_f(
+ float_i_to_f(&n1)?,
+ float_i_to_f(&n2)?,
+ )?)),
+ (Number::Integer(n1), Number::Float(OrderedFloat(n2))) => {
+ Ok(Number::Float(div_f(float_i_to_f(&n1)?, n2)?))
+ }
+ (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
+ Ok(Number::Float(div_f(n2, float_i_to_f(&n1)?)?))
+ }
+ (Number::Integer(n1), Number::Rational(n2)) => Ok(Number::Float(div_f(
+ float_i_to_f(&n1)?,
+ float_r_to_f(&n2)?,
+ )?)),
+ (Number::Rational(n2), Number::Integer(n1)) => Ok(Number::Float(div_f(
+ float_r_to_f(&n2)?,
+ float_i_to_f(&n1)?,
+ )?)),
+ (Number::Rational(n1), Number::Float(OrderedFloat(n2))) => {
+ Ok(Number::Float(div_f(float_r_to_f(&n1)?, n2)?))
+ }
+ (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => {
+ Ok(Number::Float(div_f(n2, float_r_to_f(&n1)?)?))
+ }
+ (Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => {
+ Ok(Number::Float(div_f(f1, f2)?))
+ }
+ (Number::Rational(r1), Number::Rational(r2)) => Ok(Number::Float(div_f(
+ float_r_to_f(&r1)?,
+ float_r_to_f(&r2)?,
+ )?)),
}
}
}
impl PartialOrd for Number {
fn partial_cmp(&self, rhs: &Number) -> Option<Ordering> {
match (self, rhs) {
- (&Number::Integer(ref n1), &Number::Integer(ref n2)) =>
- Some(n1.cmp(n2)),
- (&Number::Integer(_), Number::Float(_)) =>
- Some(Ordering::Greater),
- (&Number::Float(_), &Number::Integer(_)) =>
- Some(Ordering::Less),
- (&Number::Integer(_), &Number::Rational(_)) =>
- Some(Ordering::Greater),
- (&Number::Rational(_), &Number::Integer(_)) =>
- Some(Ordering::Less),
- (&Number::Rational(_), Number::Float(_)) =>
- Some(Ordering::Greater),
- (&Number::Float(_), &Number::Rational(_)) =>
- Some(Ordering::Less),
- (&Number::Float(f1), &Number::Float(f2)) =>
- Some(f1.cmp(&f2)),
- (&Number::Rational(ref r1), &Number::Rational(ref r2)) =>
- Some(r1.cmp(&r2))
+ (&Number::Integer(ref n1), &Number::Integer(ref n2)) => Some(n1.cmp(n2)),
+ (&Number::Integer(_), Number::Float(_)) => Some(Ordering::Greater),
+ (&Number::Float(_), &Number::Integer(_)) => Some(Ordering::Less),
+ (&Number::Integer(_), &Number::Rational(_)) => Some(Ordering::Greater),
+ (&Number::Rational(_), &Number::Integer(_)) => Some(Ordering::Less),
+ (&Number::Rational(_), Number::Float(_)) => Some(Ordering::Greater),
+ (&Number::Float(_), &Number::Rational(_)) => Some(Ordering::Less),
+ (&Number::Float(f1), &Number::Float(f2)) => Some(f1.cmp(&f2)),
+ (&Number::Rational(ref r1), &Number::Rational(ref r2)) => Some(r1.cmp(&r2)),
}
}
}
impl Ord for Number {
fn cmp(&self, rhs: &Number) -> Ordering {
match (self, rhs) {
- (&Number::Integer(ref n1), &Number::Integer(ref n2)) =>
- n1.cmp(n2),
- (&Number::Integer(_), Number::Float(_)) =>
- Ordering::Greater,
- (&Number::Float(_), &Number::Integer(_)) =>
- Ordering::Less,
- (&Number::Integer(_), &Number::Rational(_)) =>
- Ordering::Greater,
- (&Number::Rational(_), &Number::Integer(_)) =>
- Ordering::Less,
- (&Number::Rational(_), Number::Float(_)) =>
- Ordering::Greater,
- (&Number::Float(_), &Number::Rational(_)) =>
- Ordering::Less,
- (&Number::Float(f1), &Number::Float(f2)) =>
- f1.cmp(&f2),
- (&Number::Rational(ref r1), &Number::Rational(ref r2)) =>
- r1.cmp(&r2)
+ (&Number::Integer(ref n1), &Number::Integer(ref n2)) => n1.cmp(n2),
+ (&Number::Integer(_), Number::Float(_)) => Ordering::Greater,
+ (&Number::Float(_), &Number::Integer(_)) => Ordering::Less,
+ (&Number::Integer(_), &Number::Rational(_)) => Ordering::Greater,
+ (&Number::Rational(_), &Number::Integer(_)) => Ordering::Less,
+ (&Number::Rational(_), Number::Float(_)) => Ordering::Greater,
+ (&Number::Float(_), &Number::Rational(_)) => Ordering::Less,
+ (&Number::Float(f1), &Number::Float(f2)) => f1.cmp(&f2),
+ (&Number::Rational(ref r1), &Number::Rational(ref r2)) => r1.cmp(&r2),
}
}
}
// Computes n ^ power. Ignores the sign of power.
-pub fn binary_pow(mut n: Integer, power: Integer) -> Integer
-{
+pub fn binary_pow(mut n: Integer, power: Integer) -> Integer {
let mut power = power.abs();
if power == 0 {
GreaterThanOrEqual,
LessThanOrEqual,
NotEqual,
- Equal
+ Equal,
}
impl CompareNumberQT {
CompareNumberQT::GreaterThanOrEqual => ">=",
CompareNumberQT::LessThanOrEqual => "=<",
CompareNumberQT::NotEqual => "=\\=",
- CompareNumberQT::Equal => "=:="
+ CompareNumberQT::Equal => "=:=",
}
}
}
pub enum ArithmeticTerm {
Reg(RegType),
Interm(usize),
- Number(Number)
+ Number(Number),
}
impl ArithmeticTerm {
IsFloat(RegType),
IsNonVar(RegType),
IsPartialString(RegType),
- IsVar(RegType)
+ IsVar(RegType),
}
ref_thread_local! {
&InlinedClauseType::IsAtom(..) => "atom",
&InlinedClauseType::IsAtomic(..) => "atomic",
&InlinedClauseType::IsCompound(..) => "compound",
- &InlinedClauseType::IsInteger (..) => "integer",
+ &InlinedClauseType::IsInteger(..) => "integer",
&InlinedClauseType::IsRational(..) => "rational",
&InlinedClauseType::IsString(..) => "string",
- &InlinedClauseType::IsFloat (..) => "float",
+ &InlinedClauseType::IsFloat(..) => "float",
&InlinedClauseType::IsNonVar(..) => "nonvar",
&InlinedClauseType::IsPartialString(..) => "is_partial_string",
&InlinedClauseType::IsVar(..) => "var",
UnwindStack,
Variant,
WAMInstructions,
- WriteTerm
+ WriteTerm,
}
impl SystemClauseType {
&SystemClauseType::AtomChars => clause_name!("$atom_chars"),
&SystemClauseType::AtomCodes => clause_name!("$atom_codes"),
&SystemClauseType::AtomLength => clause_name!("$atom_length"),
- &SystemClauseType::ModuleAssertDynamicPredicateToFront => clause_name!("$module_asserta"),
- &SystemClauseType::ModuleAssertDynamicPredicateToBack => clause_name!("$module_assertz"),
+ &SystemClauseType::ModuleAssertDynamicPredicateToFront => {
+ clause_name!("$module_asserta")
+ }
+ &SystemClauseType::ModuleAssertDynamicPredicateToBack => {
+ clause_name!("$module_assertz")
+ }
&SystemClauseType::CharCode => clause_name!("$char_code"),
&SystemClauseType::CharsToNumber => clause_name!("$chars_to_number"),
&SystemClauseType::CodesToNumber => clause_name!("$codes_to_number"),
&SystemClauseType::CheckCutPoint => clause_name!("$check_cp"),
&SystemClauseType::REPL(REPLCodePtr::CompileBatch) => clause_name!("$compile_batch"),
- &SystemClauseType::REPL(REPLCodePtr::SubmitQueryAndPrintResults) =>
- clause_name!("$submit_query_and_print_results"),
+ &SystemClauseType::REPL(REPLCodePtr::SubmitQueryAndPrintResults) => {
+ clause_name!("$submit_query_and_print_results")
+ }
&SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"),
&SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"),
&SystemClauseType::DeleteHeadAttribute => clause_name!("$del_attr_head"),
&SystemClauseType::ExpandGoal => clause_name!("$expand_goal"),
&SystemClauseType::FetchGlobalVar => clause_name!("$fetch_global_var"),
&SystemClauseType::GetChar => clause_name!("$get_char"),
- &SystemClauseType::TruncateIfNoLiftedHeapGrowth => clause_name!("$truncate_if_no_lh_growth"),
- &SystemClauseType::TruncateIfNoLiftedHeapGrowthDiff => clause_name!("$truncate_if_no_lh_growth_diff"),
+ &SystemClauseType::TruncateIfNoLiftedHeapGrowth => {
+ clause_name!("$truncate_if_no_lh_growth")
+ }
+ &SystemClauseType::TruncateIfNoLiftedHeapGrowthDiff => {
+ clause_name!("$truncate_if_no_lh_growth_diff")
+ }
&SystemClauseType::GetAttributedVariableList => clause_name!("$get_attr_list"),
- &SystemClauseType::GetAttrVarQueueDelimiter => clause_name!("$get_attr_var_queue_delim"),
+ &SystemClauseType::GetAttrVarQueueDelimiter => {
+ clause_name!("$get_attr_var_queue_delim")
+ }
&SystemClauseType::GetAttrVarQueueBeyond => clause_name!("$get_attr_var_queue_beyond"),
&SystemClauseType::GetLiftedHeapFromOffset => clause_name!("$get_lh_from_offset"),
- &SystemClauseType::GetLiftedHeapFromOffsetDiff => clause_name!("$get_lh_from_offset_diff"),
+ &SystemClauseType::GetLiftedHeapFromOffsetDiff => {
+ clause_name!("$get_lh_from_offset_diff")
+ }
&SystemClauseType::GetBValue => clause_name!("$get_b_value"),
&SystemClauseType::GetClause => clause_name!("$get_clause"),
&SystemClauseType::GetNextDBRef => clause_name!("$get_next_db_ref"),
&SystemClauseType::HeadIsDynamic => clause_name!("$head_is_dynamic"),
&SystemClauseType::OpDeclaration => clause_name!("$op$"),
&SystemClauseType::InstallSCCCleaner => clause_name!("$install_scc_cleaner"),
- &SystemClauseType::InstallInferenceCounter => clause_name!("$install_inference_counter"),
+ &SystemClauseType::InstallInferenceCounter => {
+ clause_name!("$install_inference_counter")
+ }
&SystemClauseType::LiftedHeapLength => clause_name!("$lh_length"),
&SystemClauseType::ModuleHeadIsDynamic => clause_name!("$module_head_is_dynamic"),
&SystemClauseType::ModuleOf => clause_name!("$module_of"),
&SystemClauseType::ResetGlobalVarAtKey => clause_name!("$reset_global_var_at_key"),
&SystemClauseType::RetractClause => clause_name!("$retract_clause"),
&SystemClauseType::ResetBlock => clause_name!("$reset_block"),
- &SystemClauseType::ReturnFromAttributeGoals => clause_name!("$return_from_attribute_goals"),
+ &SystemClauseType::ReturnFromAttributeGoals => {
+ clause_name!("$return_from_attribute_goals")
+ }
&SystemClauseType::ReturnFromVerifyAttr => clause_name!("$return_from_verify_attr"),
&SystemClauseType::SetBall => clause_name!("$set_ball"),
&SystemClauseType::SetCutPointByDefault(_) => clause_name!("$set_cp_by_default"),
pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
match (name, arity) {
("$abolish_clause", 2) => Some(SystemClauseType::AbolishClause),
- ("$atom_chars", 2) => Some(SystemClauseType::AtomChars),
- ("$atom_codes", 2) => Some(SystemClauseType::AtomCodes),
+ ("$atom_chars", 2) => Some(SystemClauseType::AtomChars),
+ ("$atom_codes", 2) => Some(SystemClauseType::AtomCodes),
("$atom_length", 2) => Some(SystemClauseType::AtomLength),
("$abolish_module_clause", 3) => Some(SystemClauseType::AbolishModuleClause),
("$module_asserta", 5) => Some(SystemClauseType::ModuleAssertDynamicPredicateToFront),
("$expand_goal", 2) => Some(SystemClauseType::ExpandGoal),
("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar),
("$get_char", 1) => Some(SystemClauseType::GetChar),
- ("$truncate_if_no_lh_growth", 1) => Some(SystemClauseType::TruncateIfNoLiftedHeapGrowth),
- ("$truncate_if_no_lh_growth_diff", 2) => Some(SystemClauseType::TruncateIfNoLiftedHeapGrowthDiff),
+ ("$truncate_if_no_lh_growth", 1) => {
+ Some(SystemClauseType::TruncateIfNoLiftedHeapGrowth)
+ }
+ ("$truncate_if_no_lh_growth_diff", 2) => {
+ Some(SystemClauseType::TruncateIfNoLiftedHeapGrowthDiff)
+ }
("$get_attr_list", 2) => Some(SystemClauseType::GetAttributedVariableList),
("$get_b_value", 1) => Some(SystemClauseType::GetBValue),
("$get_clause", 2) => Some(SystemClauseType::GetClause),
("$set_double_quotes", 1) => Some(SystemClauseType::SetDoubleQuotes),
("$skip_max_list", 4) => Some(SystemClauseType::SkipMaxList),
("$store_global_var", 2) => Some(SystemClauseType::StoreGlobalVar),
- ("$submit_query_and_print_results", 2) =>
- Some(SystemClauseType::REPL(REPLCodePtr::SubmitQueryAndPrintResults)),
+ ("$submit_query_and_print_results", 2) => Some(SystemClauseType::REPL(
+ REPLCodePtr::SubmitQueryAndPrintResults,
+ )),
("$term_variables", 2) => Some(SystemClauseType::TermVariables),
("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack),
("$variant", 2) => Some(SystemClauseType::Variant),
("$write_term", 5) => Some(SystemClauseType::WriteTerm),
("$wam_instructions", 3) => Some(SystemClauseType::WAMInstructions),
- _ => None
+ _ => None,
}
}
}
Inlined(InlinedClauseType),
Named(ClauseName, usize, CodeIndex), // name, arity, index.
Op(ClauseName, SharedOpDesc, CodeIndex),
- System(SystemClauseType)
+ System(SystemClauseType),
}
impl BuiltInClauseType {
&BuiltInClauseType::CopyTerm => clause_name!("copy_term"),
&BuiltInClauseType::Eq => clause_name!("=="),
&BuiltInClauseType::Functor => clause_name!("functor"),
- &BuiltInClauseType::Ground => clause_name!("ground"),
- &BuiltInClauseType::Is(..) => clause_name!("is"),
+ &BuiltInClauseType::Ground => clause_name!("ground"),
+ &BuiltInClauseType::Is(..) => clause_name!("is"),
&BuiltInClauseType::KeySort => clause_name!("keysort"),
&BuiltInClauseType::Nl => clause_name!("nl"),
&BuiltInClauseType::NotEq => clause_name!("\\=="),
&BuiltInClauseType::CopyTerm => 2,
&BuiltInClauseType::Eq => 2,
&BuiltInClauseType::Functor => 3,
- &BuiltInClauseType::Ground => 1,
+ &BuiltInClauseType::Ground => 1,
&BuiltInClauseType::Is(..) => 2,
&BuiltInClauseType::KeySort => 2,
&BuiltInClauseType::NotEq => 2,
impl ClauseType {
pub fn spec(&self) -> Option<SharedOpDesc> {
match self {
- &ClauseType::Op(_, ref spec, _) =>
- Some(spec.clone()),
+ &ClauseType::Op(_, ref spec, _) => Some(spec.clone()),
&ClauseType::Inlined(InlinedClauseType::CompareNumber(..))
- | &ClauseType::BuiltIn(BuiltInClauseType::Is(..))
- | &ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(_))
- | &ClauseType::BuiltIn(BuiltInClauseType::NotEq)
- | &ClauseType::BuiltIn(BuiltInClauseType::Eq) =>
- Some(SharedOpDesc::new(700, XFX)),
- _ => None
+ | &ClauseType::BuiltIn(BuiltInClauseType::Is(..))
+ | &ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(_))
+ | &ClauseType::BuiltIn(BuiltInClauseType::NotEq)
+ | &ClauseType::BuiltIn(BuiltInClauseType::Eq) => Some(SharedOpDesc::new(700, XFX)),
+ _ => None,
}
}
}
pub fn from(name: ClauseName, arity: usize, spec: Option<SharedOpDesc>) -> Self {
- CLAUSE_TYPE_FORMS.borrow().get(&(name.as_str(), arity)).cloned()
- .unwrap_or_else(||
+ CLAUSE_TYPE_FORMS
+ .borrow()
+ .get(&(name.as_str(), arity))
+ .cloned()
+ .unwrap_or_else(|| {
SystemClauseType::from(name.as_str(), arity)
.map(ClauseType::System)
- .unwrap_or_else(||
+ .unwrap_or_else(|| {
if let Some(spec) = spec {
ClauseType::Op(name, spec, CodeIndex::default())
} else if name.as_str() == "call" {
ClauseType::CallN
} else {
ClauseType::Named(name, arity, CodeIndex::default())
- }))
+ }
+ })
+ })
}
}
flags: MachineFlags,
marker: TermMarker,
var_count: IndexMap<Rc<Var>, usize>,
- non_counted_bt: bool
+ non_counted_bt: bool,
}
pub struct ConjunctInfo<'a> {
pub has_deep_cut: bool,
}
-impl<'a> ConjunctInfo<'a>
-{
+impl<'a> ConjunctInfo<'a> {
fn new(perm_vs: VariableFixtures<'a>, num_of_chunks: usize, has_deep_cut: bool) -> Self {
- ConjunctInfo { perm_vs, num_of_chunks, has_deep_cut }
+ ConjunctInfo {
+ perm_vs,
+ num_of_chunks,
+ has_deep_cut,
+ }
}
fn allocates(&self) -> bool {
let mut index = right_index;
if let Line::Query(_) = &code[right_index] {
- while let Line::Query(_) = &code[index] { // index >= 0.
+ while let Line::Query(_) = &code[index] {
+ // index >= 0.
if index == 0 {
break;
} else {
}
}
- if let Line::Query(_) = &code[index] {} else {
+ if let Line::Query(_) = &code[index] {
+ } else {
index += 1;
}
}
}
- for index in index .. right_index + 1 {
+ for index in index..right_index + 1 {
if let &mut Line::Query(ref mut query_instr) = &mut code[index] {
unsafe_var_marker.mark_unsafe_vars(query_instr);
}
}
}
-impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
-{
+impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
pub fn new(non_counted_bt: bool, flags: MachineFlags) -> Self {
- CodeGenerator { marker: Allocator::new(),
- var_count: IndexMap::new(),
- non_counted_bt,
- flags }
+ CodeGenerator {
+ marker: Allocator::new(),
+ var_count: IndexMap::new(),
+ non_counted_bt,
+ flags,
+ }
}
pub fn take_vars(self) -> AllocVarDict {
self.marker.take_bindings()
}
- fn update_var_count<Iter: Iterator<Item=TermRef<'a>>>(&mut self, iter: Iter)
- {
+ fn update_var_count<Iter: Iterator<Item = TermRef<'a>>>(&mut self, iter: Iter) {
for term in iter {
if let TermRef::Var(_, _, var) = term {
let entry = self.var_count.entry(var).or_insert(0);
*self.var_count.get(var).unwrap()
}
- fn mark_non_callable(&mut self, name: Rc<Var>, arity: usize, term_loc: GenContext,
- vr: &'a Cell<VarReg>, code: &mut Code)
- -> RegType
- {
+ fn mark_non_callable(
+ &mut self,
+ name: Rc<Var>,
+ arity: usize,
+ term_loc: GenContext,
+ vr: &'a Cell<VarReg>,
+ code: &mut Code,
+ ) -> RegType {
match self.marker.bindings().get(&name) {
Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t),
Some(&VarData::Perm(p)) if p != 0 => RegType::Perm(p),
let mut target = Vec::new();
self.marker.reset_arg(arity);
- self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target);
+ self.marker
+ .mark_var(name, Level::Shallow, vr, term_loc, &mut target);
if !target.is_empty() {
for query_instr in target {
}
fn add_or_increment_void_instr<Target>(target: &mut Vec<Target>)
- where Target: CompilationTarget<'a>
+ where
+ Target: CompilationTarget<'a>,
{
if let Some(ref mut instr) = target.last_mut() {
if Target::is_void_instr(&*instr) {
target.push(Target::to_void(1));
}
- fn subterm_to_instr<Target>(&mut self,
- subterm: &'a Term,
- term_loc: GenContext,
- is_exposed: bool,
- target: &mut Vec<Target>)
- where Target: CompilationTarget<'a>
+ fn subterm_to_instr<Target>(
+ &mut self,
+ subterm: &'a Term,
+ term_loc: GenContext,
+ is_exposed: bool,
+ target: &mut Vec<Target>,
+ ) where
+ Target: CompilationTarget<'a>,
{
match subterm {
- &Term::AnonVar if is_exposed =>
- self.marker.mark_anon_var(Level::Deep, term_loc, target),
- &Term::AnonVar =>
- Self::add_or_increment_void_instr(target),
+ &Term::AnonVar if is_exposed => {
+ self.marker.mark_anon_var(Level::Deep, term_loc, target)
+ }
+ &Term::AnonVar => Self::add_or_increment_void_instr(target),
&Term::Cons(ref cell, _, _) | &Term::Clause(ref cell, _, _, _) => {
- self.marker.mark_non_var(Level::Deep, term_loc, cell, target);
+ self.marker
+ .mark_non_var(Level::Deep, term_loc, cell, target);
target.push(Target::clause_arg_to_instr(cell.get()));
- },
- &Term::Constant(_, ref constant) =>
- target.push(Target::constant_subterm(constant.clone())),
- &Term::Var(ref cell, ref var) =>
+ }
+ &Term::Constant(_, ref constant) => {
+ target.push(Target::constant_subterm(constant.clone()))
+ }
+ &Term::Var(ref cell, ref var) => {
if is_exposed || self.get_var_count(var) > 1 {
- self.marker.mark_var(var.clone(), Level::Deep, cell, term_loc, target);
+ self.marker
+ .mark_var(var.clone(), Level::Deep, cell, term_loc, target);
} else {
Self::add_or_increment_void_instr(target);
}
+ }
};
}
- fn compile_target<Target, Iter>(&mut self, iter: Iter, term_loc: GenContext, is_exposed: bool)
- -> Vec<Target>
- where Target: CompilationTarget<'a>, Iter: Iterator<Item=TermRef<'a>>
+ fn compile_target<Target, Iter>(
+ &mut self,
+ iter: Iter,
+ term_loc: GenContext,
+ is_exposed: bool,
+ ) -> Vec<Target>
+ where
+ Target: CompilationTarget<'a>,
+ Iter: Iterator<Item = TermRef<'a>>,
{
let mut target = Vec::new();
for subterm in terms {
self.subterm_to_instr(subterm.as_ref(), term_loc, is_exposed, &mut target);
}
- },
+ }
TermRef::Cons(lvl, cell, head, tail) => {
self.marker.mark_non_var(lvl, term_loc, cell, &mut target);
target.push(Target::to_list(lvl, cell.get()));
self.subterm_to_instr(head, term_loc, is_exposed, &mut target);
self.subterm_to_instr(tail, term_loc, is_exposed, &mut target);
- },
+ }
TermRef::Constant(lvl @ Level::Shallow, cell, constant) => {
self.marker.mark_non_var(lvl, term_loc, cell, &mut target);
target.push(Target::to_constant(lvl, constant.clone(), cell.get()));
- },
- TermRef::AnonVar(lvl @ Level::Shallow) =>
+ }
+ TermRef::AnonVar(lvl @ Level::Shallow) => {
if let GenContext::Head = term_loc {
self.marker.advance_arg();
} else {
self.marker.mark_anon_var(lvl, term_loc, &mut target);
- },
+ }
+ }
TermRef::Var(lvl @ Level::Shallow, cell, ref var) if var.as_str() == "!" => {
if self.marker.is_unbound(var.clone()) {
if term_loc != GenContext::Head {
- self.marker.mark_reserved_var(var.clone(), lvl, cell, term_loc,
- &mut target, perm_v!(1), false);
+ self.marker.mark_reserved_var(
+ var.clone(),
+ lvl,
+ cell,
+ term_loc,
+ &mut target,
+ perm_v!(1),
+ false,
+ );
continue;
}
}
- self.marker.mark_var(var.clone(), lvl, cell, term_loc, &mut target);
- },
- TermRef::Var(lvl @ Level::Shallow, cell, var) =>
- self.marker.mark_var(var.clone(), lvl, cell, term_loc, &mut target),
+ self.marker
+ .mark_var(var.clone(), lvl, cell, term_loc, &mut target);
+ }
+ TermRef::Var(lvl @ Level::Shallow, cell, var) => {
+ self.marker
+ .mark_var(var.clone(), lvl, cell, term_loc, &mut target)
+ }
_ => {}
};
}
target
}
- fn collect_var_data(&mut self, mut iter: ChunkedIterator<'a>) -> ConjunctInfo<'a>
- {
+ fn collect_var_data(&mut self, mut iter: ChunkedIterator<'a>) -> ConjunctInfo<'a> {
let mut vs = VariableFixtures::new();
while let Some((chunk_num, lt_arity, chunked_terms)) = iter.next() {
for (i, chunked_term) in chunked_terms.iter().enumerate() {
let term_loc = match chunked_term {
&ChunkedTerm::HeadClause(..) => GenContext::Head,
- &ChunkedTerm::BodyTerm(_) => if i < chunked_terms.len() - 1 {
- GenContext::Mid(chunk_num)
- } else {
- GenContext::Last(chunk_num)
+ &ChunkedTerm::BodyTerm(_) => {
+ if i < chunked_terms.len() - 1 {
+ GenContext::Mid(chunk_num)
+ } else {
+ GenContext::Last(chunk_num)
+ }
}
};
}
let num_of_chunks = iter.chunk_num;
- let has_deep_cut = iter.encountered_deep_cut();
+ let has_deep_cut = iter.encountered_deep_cut();
vs.populate_restricting_sets();
vs.set_perm_vals(has_deep_cut);
ConjunctInfo::new(vs, num_of_chunks, has_deep_cut)
}
- fn add_conditional_call(code: &mut Code, qt: &QueryTerm, pvs: usize)
- {
+ fn add_conditional_call(code: &mut Code, qt: &QueryTerm, pvs: usize) {
match qt {
- &QueryTerm::Jump(ref vars) =>
- code.push(jmp_call!(vars.len(), 0, pvs)),
- &QueryTerm::Clause(_, ref ct, ref terms, true) =>
- code.push(call_clause_by_default!(ct.clone(), terms.len(), pvs)),
- &QueryTerm::Clause(_, ref ct, ref terms, false) =>
- code.push(call_clause!(ct.clone(), terms.len(), pvs)),
+ &QueryTerm::Jump(ref vars) => code.push(jmp_call!(vars.len(), 0, pvs)),
+ &QueryTerm::Clause(_, ref ct, ref terms, true) => {
+ code.push(call_clause_by_default!(ct.clone(), terms.len(), pvs))
+ }
+ &QueryTerm::Clause(_, ref ct, ref terms, false) => {
+ code.push(call_clause!(ct.clone(), terms.len(), pvs))
+ }
_ => {}
}
}
- fn lco(code: &mut Code) -> usize
- {
+ fn lco(code: &mut Code) -> usize {
let mut dealloc_index = code.len() - 1;
match code.last_mut() {
- Some(&mut Line::Control(ref mut ctrl)) =>
- match ctrl {
- &mut ControlInstruction::CallClause(_, _, _, ref mut last_call, _) =>
- *last_call = true,
- &mut ControlInstruction::JmpBy(_, _, _, ref mut last_call) =>
- *last_call = true,
- &mut ControlInstruction::Proceed => {},
- _ => dealloc_index += 1
- },
- Some(&mut Line::Cut(CutInstruction::Cut(_))) =>
- dealloc_index += 1,
+ Some(&mut Line::Control(ref mut ctrl)) => match ctrl {
+ &mut ControlInstruction::CallClause(_, _, _, ref mut last_call, _) => {
+ *last_call = true
+ }
+ &mut ControlInstruction::JmpBy(_, _, _, ref mut last_call) => *last_call = true,
+ &mut ControlInstruction::Proceed => {}
+ _ => dealloc_index += 1,
+ },
+ Some(&mut Line::Cut(CutInstruction::Cut(_))) => dealloc_index += 1,
_ => {}
};
dealloc_index
}
- fn compile_inlined(&mut self, ct: &InlinedClauseType, terms: &'a Vec<Box<Term>>,
- term_loc: GenContext, code: &mut Code)
- -> Result<(), ParserError>
- {
+ fn compile_inlined(
+ &mut self,
+ ct: &InlinedClauseType,
+ terms: &'a Vec<Box<Term>>,
+ term_loc: GenContext,
+ code: &mut Code,
+ ) -> Result<(), ParserError> {
match ct {
&InlinedClauseType::CompareNumber(cmp, ..) => {
if let &Term::Var(ref vr, ref name) = terms[0].as_ref() {
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))));
+ code.push(compare_number_instr!(
+ cmp,
+ at_1.unwrap_or(interm!(1)),
+ at_2.unwrap_or(interm!(2))
+ ));
+ }
+ &InlinedClauseType::IsAtom(..) => match terms[0].as_ref() {
+ &Term::Constant(_, Constant::Char(_))
+ | &Term::Constant(_, Constant::EmptyList)
+ | &Term::Constant(_, Constant::Atom(..)) => {
+ code.push(succeed!());
+ }
+ &Term::Var(ref vr, ref name) => {
+ let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
+ code.push(is_atom!(r));
+ }
+ _ => {
+ code.push(fail!());
+ }
},
- &InlinedClauseType::IsAtom(..) =>
- match terms[0].as_ref() {
- &Term::Constant(_, Constant::Char(_))
- | &Term::Constant(_, Constant::EmptyList)
- | &Term::Constant(_, Constant::Atom(..)) => {
- code.push(succeed!());
- },
- &Term::Var(ref vr, ref name) => {
- let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
- code.push(is_atom!(r));
- }
- _ => {
- code.push(fail!());
- }
- },
- &InlinedClauseType::IsAtomic(..) =>
- match terms[0].as_ref() {
- &Term::AnonVar | &Term::Clause(..) | &Term::Cons(..) => {
- code.push(fail!());
- },
- &Term::Constant(..) => {
- code.push(succeed!());
- },
- &Term::Var(ref vr, ref name) => {
- let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
- code.push(is_atomic!(r));
- }
- },
- &InlinedClauseType::IsCompound(..) =>
- match terms[0].as_ref() {
- &Term::Clause(..) | &Term::Cons(..) => {
- code.push(succeed!());
- },
- &Term::Var(ref vr, ref name) => {
- let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
- code.push(is_compound!(r));
- },
- _ => {
- code.push(fail!());
- }
- },
- &InlinedClauseType::IsRational(..) =>
- match terms[0].as_ref() {
- &Term::Constant(_, Constant::Rational(_)) => {
- code.push(succeed!());
- },
- &Term::Var(ref vr, ref name) => {
- let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
- code.push(is_rational!(r));
- },
- _ => {
- code.push(fail!());
- }
- },
- &InlinedClauseType::IsFloat(..) =>
- match terms[0].as_ref() {
- &Term::Constant(_, Constant::Float(_)) => {
- code.push(succeed!());
- },
- &Term::Var(ref vr, ref name) => {
- let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
- code.push(is_float!(r));
- },
- _ => {
- code.push(fail!());
- }
- },
- &InlinedClauseType::IsString(..) =>
- match terms[0].as_ref() {
- &Term::Constant(_, Constant::String(_)) => {
- code.push(succeed!());
- },
- &Term::Var(ref vr, ref name) => {
- let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
- code.push(is_string!(r));
- },
- _ => {
- code.push(fail!());
- }
- },
- &InlinedClauseType::IsNonVar(..) =>
- match terms[0].as_ref() {
- &Term::AnonVar => {
- code.push(fail!());
- },
- &Term::Var(ref vr, ref name) => {
- let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
- code.push(is_nonvar!(r));
- },
- _ => {
- code.push(succeed!());
- }
- },
- &InlinedClauseType::IsInteger(..) =>
- match terms[0].as_ref() {
- &Term::Constant(_, Constant::CharCode(_))
- | &Term::Constant(_, Constant::Integer(_)) => {
- code.push(succeed!());
- },
- &Term::Var(ref vr, ref name) => {
- let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
- code.push(is_integer!(r));
- },
- _ => {
- code.push(fail!());
- },
- },
- &InlinedClauseType::IsVar(..) =>
- match terms[0].as_ref() {
- &Term::Constant(..) | &Term::Clause(..) | &Term::Cons(..) => {
- code.push(fail!());
- },
- &Term::AnonVar => {
- code.push(succeed!());
- },
- &Term::Var(ref vr, ref name) => {
- let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
- code.push(is_var!(r));
- }
- },
- &InlinedClauseType::IsPartialString(..) =>
- match terms[0].as_ref() {
- &Term::Var(ref vr, ref name) => {
- let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
- code.push(is_partial_string!(r));
- },
- _ => code.push(fail!())
+ &InlinedClauseType::IsAtomic(..) => match terms[0].as_ref() {
+ &Term::AnonVar | &Term::Clause(..) | &Term::Cons(..) => {
+ code.push(fail!());
+ }
+ &Term::Constant(..) => {
+ code.push(succeed!());
+ }
+ &Term::Var(ref vr, ref name) => {
+ let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
+ code.push(is_atomic!(r));
+ }
+ },
+ &InlinedClauseType::IsCompound(..) => match terms[0].as_ref() {
+ &Term::Clause(..) | &Term::Cons(..) => {
+ code.push(succeed!());
+ }
+ &Term::Var(ref vr, ref name) => {
+ let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
+ code.push(is_compound!(r));
+ }
+ _ => {
+ code.push(fail!());
+ }
+ },
+ &InlinedClauseType::IsRational(..) => match terms[0].as_ref() {
+ &Term::Constant(_, Constant::Rational(_)) => {
+ code.push(succeed!());
+ }
+ &Term::Var(ref vr, ref name) => {
+ let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
+ code.push(is_rational!(r));
+ }
+ _ => {
+ code.push(fail!());
}
+ },
+ &InlinedClauseType::IsFloat(..) => match terms[0].as_ref() {
+ &Term::Constant(_, Constant::Float(_)) => {
+ code.push(succeed!());
+ }
+ &Term::Var(ref vr, ref name) => {
+ let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
+ code.push(is_float!(r));
+ }
+ _ => {
+ code.push(fail!());
+ }
+ },
+ &InlinedClauseType::IsString(..) => match terms[0].as_ref() {
+ &Term::Constant(_, Constant::String(_)) => {
+ code.push(succeed!());
+ }
+ &Term::Var(ref vr, ref name) => {
+ let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
+ code.push(is_string!(r));
+ }
+ _ => {
+ code.push(fail!());
+ }
+ },
+ &InlinedClauseType::IsNonVar(..) => match terms[0].as_ref() {
+ &Term::AnonVar => {
+ code.push(fail!());
+ }
+ &Term::Var(ref vr, ref name) => {
+ let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
+ code.push(is_nonvar!(r));
+ }
+ _ => {
+ code.push(succeed!());
+ }
+ },
+ &InlinedClauseType::IsInteger(..) => match terms[0].as_ref() {
+ &Term::Constant(_, Constant::CharCode(_))
+ | &Term::Constant(_, Constant::Integer(_)) => {
+ code.push(succeed!());
+ }
+ &Term::Var(ref vr, ref name) => {
+ let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
+ code.push(is_integer!(r));
+ }
+ _ => {
+ code.push(fail!());
+ }
+ },
+ &InlinedClauseType::IsVar(..) => match terms[0].as_ref() {
+ &Term::Constant(..) | &Term::Clause(..) | &Term::Cons(..) => {
+ code.push(fail!());
+ }
+ &Term::AnonVar => {
+ code.push(succeed!());
+ }
+ &Term::Var(ref vr, ref name) => {
+ let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
+ code.push(is_var!(r));
+ }
+ },
+ &InlinedClauseType::IsPartialString(..) => match terms[0].as_ref() {
+ &Term::Var(ref vr, ref name) => {
+ let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
+ code.push(is_partial_string!(r));
+ }
+ _ => code.push(fail!()),
+ },
}
Ok(())
}
- fn call_arith_eval(&self, term: &'a Term, target_int: usize) -> Result<ArithCont, ArithmeticError>
- {
+ fn call_arith_eval(
+ &self,
+ term: &'a Term,
+ target_int: usize,
+ ) -> Result<ArithCont, ArithmeticError> {
let mut evaluator = ArithmeticEvaluator::new(self.marker.bindings(), target_int);
evaluator.eval(term)
}
- fn compile_is_call(&mut self, terms: &'a Vec<Box<Term>>, code: &mut Code,
- term_loc: GenContext, use_default_call_policy: bool)
- -> Result<(), ParserError>
- {
+ fn compile_is_call(
+ &mut self,
+ terms: &'a Vec<Box<Term>>,
+ code: &mut Code,
+ term_loc: GenContext,
+ use_default_call_policy: bool,
+ ) -> Result<(), ParserError> {
let (mut acode, at) = self.call_arith_eval(terms[1].as_ref(), 1)?;
code.append(&mut acode);
let mut target = vec![];
self.marker.reset_arg(2);
- self.marker.mark_var(name.clone(), Level::Shallow, vr,
- term_loc, &mut target);
+ self.marker
+ .mark_var(name.clone(), Level::Shallow, vr, term_loc, &mut target);
if !target.is_empty() {
code.extend(target.into_iter().map(Line::Query));
} else {
code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1))))
}
- },
+ }
&Term::Constant(_, ref c @ Constant::Integer(_)) => {
- code.push(Line::Query(put_constant!(Level::Shallow, c.clone(), temp_v!(1))));
+ code.push(Line::Query(put_constant!(
+ Level::Shallow,
+ c.clone(),
+ temp_v!(1)
+ )));
if use_default_call_policy {
code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1))))
} else {
code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1))))
}
- },
+ }
&Term::Constant(_, ref c @ Constant::Float(_)) => {
- code.push(Line::Query(put_constant!(Level::Shallow, c.clone(), temp_v!(1))));
+ code.push(Line::Query(put_constant!(
+ Level::Shallow,
+ c.clone(),
+ temp_v!(1)
+ )));
if use_default_call_policy {
code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1))))
} else {
code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1))))
}
- },
+ }
&Term::Constant(_, ref c @ Constant::Rational(_)) => {
- code.push(Line::Query(put_constant!(Level::Shallow, c.clone(), temp_v!(1))));
+ code.push(Line::Query(put_constant!(
+ Level::Shallow,
+ c.clone(),
+ temp_v!(1)
+ )));
if use_default_call_policy {
code.push(is_call_by_default!(temp_v!(1), at.unwrap_or(interm!(1))))
} else {
code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1))))
}
- },
- _ => code.push(fail!())
+ }
+ _ => code.push(fail!()),
})
}
#[inline]
- fn compile_unblocked_cut(&mut self, code: &mut Code, cell: &'a Cell<VarReg>)
- {
+ fn compile_unblocked_cut(&mut self, code: &mut Code, cell: &'a Cell<VarReg>) {
let r = self.marker.get(Rc::new(String::from("!")));
cell.set(VarReg::Norm(r));
code.push(set_cp!(cell.get().norm()));
}
- fn compile_get_level_and_unify(&mut self, code: &mut Code, cell: &'a Cell<VarReg>,
- var: Rc<Var>, term_loc: GenContext)
- {
+ fn compile_get_level_and_unify(
+ &mut self,
+ code: &mut Code,
+ cell: &'a Cell<VarReg>,
+ var: Rc<Var>,
+ term_loc: GenContext,
+ ) {
let mut target = Vec::new();
self.marker.reset_arg(1);
- self.marker.mark_var(var, Level::Shallow, cell, term_loc, &mut target);
+ self.marker
+ .mark_var(var, Level::Shallow, cell, term_loc, &mut target);
if !target.is_empty() {
- code.extend(target.into_iter().map(|query_instr| Line::Query(query_instr)));
+ code.extend(
+ target
+ .into_iter()
+ .map(|query_instr| Line::Query(query_instr)),
+ );
}
code.push(get_level_and_unify!(cell.get().norm()));
}
- fn compile_seq(&mut self, iter: ChunkedIterator<'a>, conjunct_info: &ConjunctInfo<'a>,
- code: &mut Code, is_exposed: bool)
- -> Result<(), ParserError>
- {
+ fn compile_seq(
+ &mut self,
+ iter: ChunkedIterator<'a>,
+ conjunct_info: &ConjunctInfo<'a>,
+ code: &mut Code,
+ is_exposed: bool,
+ ) -> Result<(), ParserError> {
for (chunk_num, _, terms) in iter.rule_body_iter() {
for (i, term) in terms.iter().enumerate() {
let term_loc = if i + 1 < terms.len() {
};
match *term {
- &QueryTerm::GetLevelAndUnify(ref cell, ref var) =>
- self.compile_get_level_and_unify(code, cell, var.clone(), term_loc),
- &QueryTerm::UnblockedCut(ref cell) =>
- self.compile_unblocked_cut(code, cell),
- &QueryTerm::BlockedCut =>
- code.push(if chunk_num == 0 {
- Line::Cut(CutInstruction::NeckCut)
- } else {
- Line::Cut(CutInstruction::Cut(perm_v!(1)))
- }),
- &QueryTerm::Clause(_, ClauseType::BuiltIn(BuiltInClauseType::Is(..)),
- ref terms, use_default_call_policy)
- => self.compile_is_call(terms, code, term_loc, use_default_call_policy)?,
- &QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _)
- => self.compile_inlined(ct, terms, term_loc, code)?,
+ &QueryTerm::GetLevelAndUnify(ref cell, ref var) => {
+ self.compile_get_level_and_unify(code, cell, var.clone(), term_loc)
+ }
+ &QueryTerm::UnblockedCut(ref cell) => self.compile_unblocked_cut(code, cell),
+ &QueryTerm::BlockedCut => code.push(if chunk_num == 0 {
+ Line::Cut(CutInstruction::NeckCut)
+ } else {
+ Line::Cut(CutInstruction::Cut(perm_v!(1)))
+ }),
+ &QueryTerm::Clause(
+ _,
+ ClauseType::BuiltIn(BuiltInClauseType::Is(..)),
+ ref terms,
+ use_default_call_policy,
+ ) => self.compile_is_call(terms, code, term_loc, use_default_call_policy)?,
+ &QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) => {
+ self.compile_inlined(ct, terms, term_loc, code)?
+ }
_ => {
let num_perm_vars = if chunk_num == 0 {
conjunct_info.perm_vars()
};
self.compile_query_line(term, term_loc, code, num_perm_vars, is_exposed);
- },
+ }
}
}
Ok(())
}
- fn compile_seq_prelude(&mut self, conjunct_info: &ConjunctInfo, body: &mut Code)
- {
+ fn compile_seq_prelude(&mut self, conjunct_info: &ConjunctInfo, body: &mut Code) {
if conjunct_info.allocates() {
let perm_vars = conjunct_info.perm_vars();
}
}
- fn compile_cleanup(code: &mut Code, conjunct_info: &ConjunctInfo, toc: &'a QueryTerm)
- {
+ fn compile_cleanup(code: &mut Code, conjunct_info: &ConjunctInfo, toc: &'a QueryTerm) {
// add a proceed to bookend any trailing cuts.
match toc {
&QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => code.push(proceed!()),
}
}
- pub fn compile_rule<'b: 'a>(&mut self, rule: &'b Rule) -> Result<Code, ParserError>
- {
+ pub fn compile_rule<'b: 'a>(&mut self, rule: &'b Rule) -> Result<Code, ParserError> {
let iter = ChunkedIterator::from_rule(rule);
let conjunct_info = self.collect_var_data(iter);
- let &Rule { head: (_, ref args, ref p1), ref clauses } = rule;
+ let &Rule {
+ head: (_, ref args, ref p1),
+ ref clauses,
+ } = rule;
let mut code = Vec::new();
self.marker.reset_at_head(args);
Ok(code)
}
- fn mark_unsafe_fact_vars(&self, fact: &mut CompiledFact) -> UnsafeVarMarker
- {
+ fn mark_unsafe_fact_vars(&self, fact: &mut CompiledFact) -> UnsafeVarMarker {
let mut unsafe_vars = IndexMap::new();
for var_status in self.marker.bindings().values() {
for fact_instr in fact.iter_mut() {
match fact_instr {
- &mut FactInstruction::UnifyValue(reg) =>
+ &mut FactInstruction::UnifyValue(reg) => {
if let Some(found) = unsafe_vars.get_mut(®) {
if !*found {
*found = true;
*fact_instr = FactInstruction::UnifyLocalValue(reg);
}
- },
- &mut FactInstruction::UnifyVariable(reg) =>
+ }
+ }
+ &mut FactInstruction::UnifyVariable(reg) => {
if let Some(found) = unsafe_vars.get_mut(®) {
*found = true;
- },
+ }
+ }
_ => {}
};
}
UnsafeVarMarker { unsafe_vars }
}
- pub fn compile_fact<'b: 'a>(&mut self, term: &'b Term) -> Code
- {
+ pub fn compile_fact<'b: 'a>(&mut self, term: &'b Term) -> Code {
self.update_var_count(post_order_iter(term));
let mut vs = VariableFixtures::new();
code
}
- fn compile_query_line(&mut self, term: &'a QueryTerm, term_loc: GenContext,
- code: &mut Code, num_perm_vars_left: usize, is_exposed: bool)
- {
+ fn compile_query_line(
+ &mut self,
+ term: &'a QueryTerm,
+ term_loc: GenContext,
+ code: &mut Code,
+ num_perm_vars_left: usize,
+ is_exposed: bool,
+ ) {
self.marker.reset_arg(term.arity());
- let iter = query_term_post_order_iter(term);
+ let iter = query_term_post_order_iter(term);
let query = self.compile_target(iter, term_loc, is_exposed);
if !query.is_empty() {
Self::add_conditional_call(code, term, num_perm_vars_left);
}
- pub fn compile_query(&mut self, query: &'a Vec<QueryTerm>) -> Result<Code, ParserError>
- {
+ pub fn compile_query(&mut self, query: &'a Vec<QueryTerm>) -> Result<Code, ParserError> {
let iter = ChunkedIterator::from_term_sequence(query);
let conjunct_info = self.collect_var_data(iter);
Ok(code)
}
- fn split_predicate(clauses: &Vec<PredicateClause>) -> Vec<(usize, usize)>
- {
+ fn split_predicate(clauses: &Vec<PredicateClause>) -> Vec<(usize, usize)> {
let mut subseqs = Vec::new();
let mut left_index = 0;
subseqs.push((right_index, right_index + 1));
left_index = right_index + 1;
- },
+ }
_ => {}
}
}
}
}
- fn compile_pred_subseq<'b: 'a>(&mut self, clauses: &'b [PredicateClause])
- -> Result<Code, ParserError>
- {
+ fn compile_pred_subseq<'b: 'a>(
+ &mut self,
+ clauses: &'b [PredicateClause],
+ ) -> Result<Code, ParserError> {
let mut code_body = Vec::new();
let mut code_offsets = CodeOffsets::new(self.flags);
- let num_clauses = clauses.len();
+ let num_clauses = clauses.len();
for (i, clause) in clauses.iter().enumerate() {
self.marker.reset();
let mut clause_code = match clause {
- &PredicateClause::Fact(ref fact) =>
- self.compile_fact(fact),
- &PredicateClause::Rule(ref rule) =>
- try!(self.compile_rule(rule))
+ &PredicateClause::Fact(ref fact) => self.compile_fact(fact),
+ &PredicateClause::Rule(ref rule) => try!(self.compile_rule(rule)),
};
if num_clauses > 1 {
let choice = match i {
0 => ChoiceInstruction::TryMeElse(clause_code.len() + 1),
_ if i == num_clauses - 1 => self.trust_me(),
- _ => self.retry_me_else(clause_code.len() + 1)
+ _ => self.retry_me_else(clause_code.len() + 1),
};
code_body.push(Line::Choice(choice));
Ok(code)
}
- pub fn compile_predicate<'b: 'a>(&mut self, clauses: &'b Vec<PredicateClause>)
- -> Result<Code, ParserError>
- {
- let mut code = Vec::new();
+ pub fn compile_predicate<'b: 'a>(
+ &mut self,
+ clauses: &'b Vec<PredicateClause>,
+ ) -> Result<Code, ParserError> {
+ let mut code = Vec::new();
let split_pred = Self::split_predicate(&clauses);
- let multi_seq = split_pred.len() > 1;
+ let multi_seq = split_pred.len() > 1;
for (l, r) in split_pred {
- let mut code_segment = try!(self.compile_pred_subseq(&clauses[l .. r]));
+ let mut code_segment = try!(self.compile_pred_subseq(&clauses[l..r]));
if multi_seq {
let choice = match l {
0 => ChoiceInstruction::TryMeElse(code_segment.len() + 1),
_ if r == clauses.len() => self.trust_me(),
- _ => self.retry_me_else(code_segment.len() + 1)
+ _ => self.retry_me_else(code_segment.len() + 1),
};
code.push(Line::Choice(choice));
use prolog_parser::ast::*;
use prolog::allocator::*;
-use prolog::forms::*;
use prolog::fixtures::*;
+use prolog::forms::*;
use prolog::machine::machine_indices::*;
use prolog::targets::*;
pub struct DebrayAllocator {
bindings: IndexMap<Rc<Var>, VarData>,
- arg_c: usize,
- temp_lb: usize,
- arity: usize, // 0 if not at head.
+ arg_c: usize,
+ temp_lb: usize,
+ arity: usize, // 0 if not at head.
contents: IndexMap<usize, Rc<Var>>,
- in_use: BTreeSet<usize>,
+ in_use: BTreeSet<usize>,
}
impl DebrayAllocator {
fn is_curr_arg_distinct_from(&self, var: &Var) -> bool {
match self.contents.get(&self.arg_c) {
Some(t_var) if **t_var != *var => true,
- _ => false
+ _ => false,
}
}
- fn occurs_shallowly_in_head(&self, var: &Var, r: usize) -> bool
- {
+ fn occurs_shallowly_in_head(&self, var: &Var, r: usize) -> bool {
match self.bindings.get(var).unwrap() {
- &VarData::Temp(_, _, ref tvd) =>
- tvd.use_set.contains(&(GenContext::Head, r)),
- _ => false
+ &VarData::Temp(_, _, ref tvd) => tvd.use_set.contains(&(GenContext::Head, r)),
+ _ => false,
}
}
in_use_range || self.in_use.contains(&r)
}
- fn alloc_with_cr(&self, var: &Var) -> usize
- {
+ fn alloc_with_cr(&self, var: &Var) -> usize {
match self.bindings.get(var) {
Some(&VarData::Temp(_, _, ref tvd)) => {
for &(_, reg) in tvd.use_set.iter() {
let mut result = 0;
- for reg in self.temp_lb .. {
+ for reg in self.temp_lb.. {
if !self.is_in_use(reg) {
if !tvd.no_use_set.contains(®) {
result = reg;
}
result
- },
- _ => 0
+ }
+ _ => 0,
}
}
- fn alloc_with_ca(&self, var: &Var) -> usize
- {
+ fn alloc_with_ca(&self, var: &Var) -> usize {
match self.bindings.get(var) {
Some(&VarData::Temp(_, _, ref tvd)) => {
for &(_, reg) in tvd.use_set.iter() {
let mut result = 0;
- for reg in self.temp_lb .. {
+ for reg in self.temp_lb.. {
if !self.is_in_use(reg) {
if !tvd.no_use_set.contains(®) {
if !tvd.conflict_set.contains(®) {
}
result
- },
- _ => 0
+ }
+ _ => 0,
}
}
- fn alloc_in_last_goal_hint(&self, chunk_num: usize) -> Option<(Rc<Var>, usize)>
- {
+ fn alloc_in_last_goal_hint(&self, chunk_num: usize) -> Option<(Rc<Var>, usize)> {
// we want to allocate a register to the k^{th} parameter, par_k.
// par_k may not be a temporary variable.
let k = self.arg_c;
}
None
- },
- _ => None
+ }
+ _ => None,
}
}
fn evacuate_arg<'a, Target>(&mut self, chunk_num: usize, target: &mut Vec<Target>)
- where Target: CompilationTarget<'a>
+ where
+ Target: CompilationTarget<'a>,
{
match self.alloc_in_last_goal_hint(chunk_num) {
Some((var, r)) => {
self.record_register(var, r);
self.in_use.insert(r.reg_num());
}
- },
+ }
_ => {}
};
}
- fn alloc_reg_to_var<'a, Target>(&mut self, var: &Var, lvl: Level, term_loc: GenContext,
- target: &mut Vec<Target>)
- -> usize
- where Target: CompilationTarget<'a>
+ fn alloc_reg_to_var<'a, Target>(
+ &mut self,
+ var: &Var,
+ lvl: Level,
+ term_loc: GenContext,
+ target: &mut Vec<Target>,
+ ) -> usize
+ where
+ Target: CompilationTarget<'a>,
{
match term_loc {
- GenContext::Head =>
+ GenContext::Head => {
if let Level::Shallow = lvl {
self.evacuate_arg(0, target);
self.alloc_with_cr(var)
} else {
self.alloc_with_ca(var)
- },
- GenContext::Mid(_) =>
- self.alloc_with_ca(var),
- GenContext::Last(chunk_num) =>
+ }
+ }
+ GenContext::Mid(_) => self.alloc_with_ca(var),
+ GenContext::Last(chunk_num) => {
if let Level::Shallow = lvl {
self.evacuate_arg(chunk_num, target);
self.alloc_with_cr(var)
} else {
self.alloc_with_ca(var)
}
+ }
}
}
- fn alloc_reg_to_non_var(&mut self) -> usize
- {
+ fn alloc_reg_to_non_var(&mut self) -> usize {
let mut final_index = 0;
- for index in self.temp_lb .. {
- if !self.in_use.contains(&index) {
+ for index in self.temp_lb.. {
+ if !self.in_use.contains(&index) {
final_index = index;
break;
}
final_index
}
- fn in_place(&self, var: &Var, term_loc: GenContext, r: RegType, k: usize) -> bool
- {
+ fn in_place(&self, var: &Var, term_loc: GenContext, r: RegType, k: usize) -> bool {
match term_loc {
GenContext::Head if !r.is_perm() => r.reg_num() == k,
_ => match self.bindings().get(var).unwrap() {
- &VarData::Temp(_, o, _) if r.reg_num() == k => o == k,
- _ => false
- }
+ &VarData::Temp(_, o, _) if r.reg_num() == k => o == k,
+ _ => false,
+ },
}
}
}
-impl<'a> Allocator<'a> for DebrayAllocator
-{
+impl<'a> Allocator<'a> for DebrayAllocator {
fn new() -> DebrayAllocator {
DebrayAllocator {
- arity: 0,
- arg_c: 1,
+ arity: 0,
+ arg_c: 1,
temp_lb: 1,
bindings: IndexMap::new(),
contents: IndexMap::new(),
- in_use: BTreeSet::new()
+ in_use: BTreeSet::new(),
}
}
fn mark_anon_var<Target>(&mut self, lvl: Level, term_loc: GenContext, target: &mut Vec<Target>)
- where Target: CompilationTarget<'a>
+ where
+ Target: CompilationTarget<'a>,
{
let r = RegType::Temp(self.alloc_reg_to_non_var());
}
self.arg_c += 1;
-
+
target.push(Target::argument_to_variable(r, k));
}
};
}
- fn mark_non_var<Target>(&mut self, lvl: Level, term_loc: GenContext,
- cell: &Cell<RegType>, target: &mut Vec<Target>)
- where Target: CompilationTarget<'a>
+ fn mark_non_var<Target>(
+ &mut self,
+ lvl: Level,
+ term_loc: GenContext,
+ cell: &Cell<RegType>,
+ target: &mut Vec<Target>,
+ ) where
+ Target: CompilationTarget<'a>,
{
let r = cell.get();
self.arg_c += 1;
RegType::Temp(k)
- },
+ }
_ if r.reg_num() == 0 => RegType::Temp(self.alloc_reg_to_non_var()),
_ => {
self.in_use.insert(r.reg_num());
cell.set(r);
}
- fn mark_var<Target>(&mut self, var: Rc<Var>, lvl: Level, cell: &'a Cell<VarReg>,
- term_loc: GenContext, target: &mut Vec<Target>)
- where Target: CompilationTarget<'a>
+ fn mark_var<Target>(
+ &mut self,
+ var: Rc<Var>,
+ lvl: Level,
+ cell: &'a Cell<VarReg>,
+ term_loc: GenContext,
+ target: &mut Vec<Target>,
+ ) where
+ Target: CompilationTarget<'a>,
{
let (r, is_new_var) = match self.get(var.clone()) {
RegType::Temp(0) => {
// here, r is temporary *and* unassigned.
let o = self.alloc_reg_to_var(&var, lvl, term_loc, target);
cell.set(VarReg::Norm(RegType::Temp(o)));
-
+
(RegType::Temp(o), true)
- },
+ }
RegType::Perm(0) => {
let pr = cell.get().norm();
self.record_register(var.clone(), pr);
-
+
(pr, true)
- },
- r => (r, false)
+ }
+ r => (r, false),
};
self.mark_reserved_var(var, lvl, cell, term_loc, target, r, is_new_var);
}
- fn mark_reserved_var<Target>(&mut self, var: Rc<Var>, lvl: Level, cell: &'a Cell<VarReg>,
- term_loc: GenContext, target: &mut Vec<Target>, r: RegType,
- is_new_var: bool)
- where Target: CompilationTarget<'a>
+ fn mark_reserved_var<Target>(
+ &mut self,
+ var: Rc<Var>,
+ lvl: Level,
+ cell: &'a Cell<VarReg>,
+ term_loc: GenContext,
+ target: &mut Vec<Target>,
+ r: RegType,
+ is_new_var: bool,
+ ) where
+ Target: CompilationTarget<'a>,
{
match lvl {
Level::Root | Level::Shallow => {
target.push(Target::argument_to_value(r, k));
}
}
- },
- Level::Deep if is_new_var =>
+ }
+ Level::Deep if is_new_var => {
if let GenContext::Head = term_loc {
if self.occurs_shallowly_in_head(&var, r.reg_num()) {
target.push(Target::subterm_to_value(r));
}
} else {
target.push(Target::subterm_to_variable(r));
- },
- Level::Deep =>
- target.push(Target::subterm_to_value(r))
+ }
+ }
+ Level::Deep => target.push(Target::subterm_to_value(r)),
};
if !r.is_perm() {
}
fn reset_arg(&mut self, arity: usize) {
- self.arity = 0;
- self.arg_c = 1;
+ self.arity = 0;
+ self.arg_c = 1;
self.temp_lb = arity + 1;
}
}
use indexmap::IndexMap;
use std::cell::Cell;
-use std::collections::{BTreeMap, BTreeSet};
use std::collections::btree_map::{IntoIter, IterMut, Values};
+use std::collections::{BTreeMap, BTreeSet};
use std::mem::swap;
use std::rc::Rc;
use std::vec::Vec;
// labeled with chunk numbers.
pub enum VarStatus {
- Perm(usize), Temp(usize, TempVarData) // Perm(chunk_num) | Temp(chunk_num, _)
+ Perm(usize),
+ Temp(usize, TempVarData), // Perm(chunk_num) | Temp(chunk_num, _)
}
pub type OccurrenceSet = BTreeSet<(GenContext, usize)>;
// Perm: 0 initially, a stack register once processed.
// Temp: labeled with chunk_num and temp offset (unassigned if 0).
pub enum VarData {
- Perm(usize), Temp(usize, usize, TempVarData)
+ Perm(usize),
+ Temp(usize, usize, TempVarData),
}
impl VarData {
pub fn as_reg_type(&self) -> RegType {
match self {
&VarData::Temp(_, r, _) => RegType::Temp(r),
- &VarData::Perm(r) => RegType::Perm(r)
+ &VarData::Perm(r) => RegType::Perm(r),
}
}
}
pub last_term_arity: usize,
pub use_set: OccurrenceSet,
pub no_use_set: BTreeSet<usize>,
- pub conflict_set: BTreeSet<usize>
+ pub conflict_set: BTreeSet<usize>,
}
impl TempVarData {
last_term_arity: last_term_arity,
use_set: BTreeSet::new(),
no_use_set: BTreeSet::new(),
- conflict_set: BTreeSet::new()
+ conflict_set: BTreeSet::new(),
}
}
pub fn populate_conflict_set(&mut self) {
if self.last_term_arity > 0 {
let arity = self.last_term_arity;
- let mut conflict_set : BTreeSet<usize> = (1..arity).collect();
+ let mut conflict_set: BTreeSet<usize> = (1..arity).collect();
for &(_, reg) in self.use_set.iter() {
conflict_set.remove(®);
type VariableFixture<'a> = (VarStatus, Vec<&'a Cell<VarReg>>);
pub struct VariableFixtures<'a>(BTreeMap<Rc<Var>, VariableFixture<'a>>);
-impl<'a> VariableFixtures<'a>
-{
+impl<'a> VariableFixtures<'a> {
pub fn new() -> Self {
VariableFixtures(BTreeMap::new())
}
}
// computes no_use and conflict sets for all temp vars.
- pub fn populate_restricting_sets(&mut self)
- {
+ pub fn populate_restricting_sets(&mut self) {
// three stages:
// 1. move the use sets of each variable to a local IndexMap, use_set
// (iterate mutably, swap mutable refs).
&mut (VarStatus::Temp(_, ref mut u_data), _) => {
u_data.use_set = use_set;
u_data.populate_conflict_set();
- },
+ }
_ => {}
};
}
self.0.iter_mut()
}
- fn record_temp_info(&mut self,
- tvd: &mut TempVarData,
- arg_c: usize,
- term_loc: GenContext)
- {
+ fn record_temp_info(&mut self, tvd: &mut TempVarData, arg_c: usize, term_loc: GenContext) {
match term_loc {
GenContext::Head | GenContext::Last(_) => {
tvd.use_set.insert((term_loc, arg_c));
- },
+ }
_ => {}
};
}
- pub fn vars_above_threshold(&self, index: usize) -> usize
- {
+ pub fn vars_above_threshold(&self, index: usize) -> usize {
let mut var_count = 0;
for &(ref var_status, _) in self.values() {
}
pub fn mark_vars_in_chunk<I>(&mut self, iter: I, lt_arity: usize, term_loc: GenContext)
- where I: Iterator<Item=TermRef<'a>>
+ where
+ I: Iterator<Item = TermRef<'a>>,
{
let chunk_num = term_loc.chunk_num();
let mut arg_c = 1;
for term_ref in iter {
if let &TermRef::Var(lvl, cell, ref var) = &term_ref {
- let mut status = self.0.remove(var)
- .unwrap_or((VarStatus::Temp(chunk_num, TempVarData::new(lt_arity)),
- Vec::new()));
+ let mut status = self.0.remove(var).unwrap_or((
+ VarStatus::Temp(chunk_num, TempVarData::new(lt_arity)),
+ Vec::new(),
+ ));
status.1.push(cell);
match status.0 {
- VarStatus::Temp(cn, ref mut tvd) if cn == chunk_num =>
+ VarStatus::Temp(cn, ref mut tvd) if cn == chunk_num => {
if let Level::Shallow = lvl {
self.record_temp_info(tvd, arg_c, term_loc);
- },
- _ => status.0 = VarStatus::Perm(chunk_num)
+ }
+ }
+ _ => status.0 = VarStatus::Perm(chunk_num),
};
self.0.insert(var.clone(), status);
self.0.len()
}
- pub fn set_perm_vals(&self, has_deep_cuts: bool)
- {
- let mut values_vec : Vec<_> = self.values()
- .filter_map(|ref v| {
- match &v.0 {
- &VarStatus::Perm(i) => Some((i, &v.1)),
- _ => None
- }
+ pub fn set_perm_vals(&self, has_deep_cuts: bool) {
+ let mut values_vec: Vec<_> = self
+ .values()
+ .filter_map(|ref v| match &v.0 {
+ &VarStatus::Perm(i) => Some((i, &v.1)),
+ _ => None,
})
.collect();
}
pub struct UnsafeVarMarker {
- pub unsafe_vars: IndexMap<RegType, bool>
+ pub unsafe_vars: IndexMap<RegType, bool>,
}
impl UnsafeVarMarker {
pub fn new() -> Self {
UnsafeVarMarker {
- unsafe_vars: IndexMap::new()
+ unsafe_vars: IndexMap::new(),
}
}
pub fn mark_safe_vars(&mut self, query_instr: &mut QueryInstruction) {
match query_instr {
- &mut QueryInstruction::PutVariable(RegType::Temp(r), _) =>
+ &mut QueryInstruction::PutVariable(RegType::Temp(r), _) => {
if let Some(found) = self.unsafe_vars.get_mut(&RegType::Temp(r)) {
*found = true;
- },
- &mut QueryInstruction::SetVariable(reg) =>
+ }
+ }
+ &mut QueryInstruction::SetVariable(reg) => {
if let Some(found) = self.unsafe_vars.get_mut(®) {
*found = true;
- },
+ }
+ }
_ => {}
}
}
- pub fn mark_unsafe_vars(&mut self, query_instr: &mut QueryInstruction)
- {
+ pub fn mark_unsafe_vars(&mut self, query_instr: &mut QueryInstruction) {
match query_instr {
- &mut QueryInstruction::PutValue(RegType::Perm(i), arg) =>
+ &mut QueryInstruction::PutValue(RegType::Perm(i), arg) => {
if let Some(found) = self.unsafe_vars.get_mut(&RegType::Perm(i)) {
if !*found {
*found = true;
*query_instr = QueryInstruction::PutUnsafeValue(i, arg);
}
- },
- &mut QueryInstruction::SetValue(reg) =>
+ }
+ }
+ &mut QueryInstruction::SetValue(reg) => {
if let Some(found) = self.unsafe_vars.get_mut(®) {
if !*found {
*found = true;
*query_instr = QueryInstruction::SetLocalValue(reg);
}
- },
+ }
+ }
_ => {}
}
}
match self {
&TopLevel::Declaration(_) => None,
&TopLevel::Fact(ref term) => term.name(),
- &TopLevel::Predicate(ref clauses) =>
- clauses.0.first().and_then(|ref term| term.name()),
+ &TopLevel::Predicate(ref clauses) => clauses.0.first().and_then(|ref term| term.name()),
&TopLevel::Query(_) => None,
- &TopLevel::Rule(Rule { ref head, .. }) =>
- Some(head.0.clone())
+ &TopLevel::Rule(Rule { ref head, .. }) => Some(head.0.clone()),
}
}
match self {
&TopLevel::Declaration(_) => 0,
&TopLevel::Fact(ref term) => term.arity(),
- &TopLevel::Predicate(ref clauses) =>
- clauses.0.first().map(|t| t.arity()).unwrap_or(0),
+ &TopLevel::Predicate(ref clauses) => clauses.0.first().map(|t| t.arity()).unwrap_or(0),
&TopLevel::Query(_) => 0,
- &TopLevel::Rule(Rule { ref head, .. }) => head.1.len()
+ &TopLevel::Rule(Rule { ref head, .. }) => head.1.len(),
}
}
pub fn is_end_of_file_atom(&self) -> bool {
match self {
- &TopLevel::Fact(Term::Constant(_, Constant::Atom(ref name, _))) =>
- return name.as_str() == "end_of_file",
- _ =>
- false
+ &TopLevel::Fact(Term::Constant(_, Constant::Atom(ref name, _))) => {
+ return name.as_str() == "end_of_file"
+ }
+ _ => false,
}
}
}
#[derive(Clone, Copy)]
pub enum Level {
- Deep, Root, Shallow
+ Deep,
+ Root,
+ Shallow,
}
impl Level {
pub fn child_level(self) -> Level {
match self {
Level::Root => Level::Shallow,
- _ => Level::Deep
+ _ => Level::Deep,
}
}
}
BlockedCut, // a cut which is 'blocked by letters', like the P term in P -> Q.
UnblockedCut(Cell<VarReg>),
GetLevelAndUnify(Cell<VarReg>, Rc<Var>),
- Jump(JumpStub)
+ Jump(JumpStub),
}
impl QueryTerm {
#[derive(Clone)]
pub struct Rule {
pub head: (ClauseName, Vec<Box<Term>>, QueryTerm),
- pub clauses: Vec<QueryTerm>
+ pub clauses: Vec<QueryTerm>,
}
#[derive(Clone)]
#[inline]
pub fn predicate_indicator(&self) -> Option<(ClauseName, usize)> {
- self.0.first()
+ self.0
+ .first()
.and_then(|clause| clause.name().map(|name| (name, clause.arity())))
}
}
#[derive(Clone)]
pub enum PredicateClause {
Fact(Term),
- Rule(Rule)
+ Rule(Rule),
}
impl PredicateClause {
pub fn arity(&self) -> usize {
match self {
&PredicateClause::Fact(ref term) => term.arity(),
- &PredicateClause::Rule(ref rule) => rule.head.1.len()
+ &PredicateClause::Rule(ref rule) => rule.head.1.len(),
}
}
#[derive(Clone)]
pub enum ModuleSource {
Library(ClauseName),
- File(ClauseName)
+ File(ClauseName),
}
#[derive(Clone)]
NonCountedBacktracking(ClauseName, usize), // name, arity
Op(OpDecl),
UseModule(ModuleSource),
- UseQualifiedModule(ModuleSource, Vec<PredicateKey>)
+ UseQualifiedModule(ModuleSource, Vec<PredicateKey>),
}
impl Declaration {
#[inline]
pub fn is_module_decl(&self) -> bool {
- if let &Declaration::Module(_) = self { true } else { false }
+ if let &Declaration::Module(_) = self {
+ true
+ } else {
+ false
+ }
}
#[inline]
pub fn is_end_of_file(&self) -> bool {
- if let &Declaration::EndOfFile = self { true } else { false }
+ if let &Declaration::EndOfFile = self {
+ true
+ } else {
+ false
+ }
}
}
self.insert_into_op_dir(clause_name!(""), op_dir, 0);
}
- fn insert_into_op_dir(&self, module: ClauseName, op_dir: &mut OpDir, prec: usize)
- {
+ fn insert_into_op_dir(&self, module: ClauseName, op_dir: &mut OpDir, prec: usize) {
let (spec, name) = (self.1, self.2.clone());
let fixity = match spec {
XFY | XFX | YFX => Fixity::In,
XF | YF => Fixity::Post,
FX | FY => Fixity::Pre,
- _ => return
+ _ => return,
};
match op_dir.get(&(name.clone(), fixity)) {
op_dir.insert((name, fixity), OpDirValue::new(spec, prec, module));
}
- pub fn submit(&self, module: ClauseName, existing_desc: Option<OpDesc>, op_dir: &mut OpDir)
- -> Result<(), SessionError>
- {
+ pub fn submit(
+ &self,
+ module: ClauseName,
+ existing_desc: Option<OpDesc>,
+ op_dir: &mut OpDir,
+ ) -> Result<(), SessionError> {
let (prec, spec, name) = (self.0, self.1, self.2.clone());
if is_infix!(spec) {
}
}
-pub
-fn fetch_atom_op_spec(name: ClauseName, spec: Option<SharedOpDesc>, op_dir: &OpDir)
- -> Option<SharedOpDesc>
-{
+pub fn fetch_atom_op_spec(
+ name: ClauseName,
+ spec: Option<SharedOpDesc>,
+ op_dir: &OpDir,
+) -> Option<SharedOpDesc> {
fetch_op_spec(name.clone(), 1, spec.clone(), op_dir)
.or_else(|| fetch_op_spec(name, 2, spec, op_dir))
}
-pub
-fn fetch_op_spec(name: ClauseName, arity: usize, spec: Option<SharedOpDesc>, op_dir: &OpDir)
- -> Option<SharedOpDesc>
-{
- spec.or_else(|| {
- match arity {
- 2 => op_dir.get(&(name, Fixity::In)).and_then(|OpDirValue(spec, _)|
+pub fn fetch_op_spec(
+ name: ClauseName,
+ arity: usize,
+ spec: Option<SharedOpDesc>,
+ op_dir: &OpDir,
+) -> Option<SharedOpDesc> {
+ spec.or_else(|| match arity {
+ 2 => op_dir
+ .get(&(name, Fixity::In))
+ .and_then(|OpDirValue(spec, _)| {
if spec.prec() > 0 {
Some(spec.clone())
} else {
None
- }),
- 1 => {
- if let Some(OpDirValue(spec, _)) = op_dir.get(&(name.clone(), Fixity::Pre)) {
- if spec.prec() > 0 {
- return Some(spec.clone());
- }
}
+ }),
+ 1 => {
+ if let Some(OpDirValue(spec, _)) = op_dir.get(&(name.clone(), Fixity::Pre)) {
+ if spec.prec() > 0 {
+ return Some(spec.clone());
+ }
+ }
- op_dir.get(&(name.clone(), Fixity::Post))
- .and_then(|OpDirValue(spec, _)|
- if spec.prec() > 0 {
- Some(spec.clone())
- } else {
- None
- })
- },
- _ => None
+ op_dir
+ .get(&(name.clone(), Fixity::Post))
+ .and_then(|OpDirValue(spec, _)| {
+ if spec.prec() > 0 {
+ Some(spec.clone())
+ } else {
+ None
+ }
+ })
}
+ _ => None,
})
}
#[derive(Clone)]
pub struct ModuleDecl {
pub name: ClauseName,
- pub exports: Vec<PredicateKey>
+ pub exports: Vec<PredicateKey>,
}
pub struct Module {
pub goal_expansions: (Predicate, VecDeque<TopLevel>),
pub user_term_expansions: (Predicate, VecDeque<TopLevel>), // term expansions inherited from the user scope.
pub user_goal_expansions: (Predicate, VecDeque<TopLevel>), // same for goal_expansions.
- pub inserted_expansions: bool // has the module been successfully inserted into toplevel??
+ pub inserted_expansions: bool, // has the module been successfully inserted into toplevel??
}
#[derive(Clone, PartialEq, Eq)]
pub enum Number {
Float(OrderedFloat<f64>),
Integer(Integer),
- Rational(Rational)
+ Rational(Rational),
}
impl Default for Number {
match self {
Number::Integer(n) => Constant::Integer(n),
Number::Float(f) => Constant::Float(f),
- Number::Rational(r) => Constant::Rational(r)
+ Number::Rational(r) => Constant::Rational(r),
}
}
match self {
&Number::Integer(ref n) => n > &0,
&Number::Float(OrderedFloat(f)) => f.is_sign_positive(),
- &Number::Rational(ref r) => r > &0
+ &Number::Rational(ref r) => r > &0,
}
}
match self {
&Number::Integer(ref n) => n < &0,
&Number::Float(OrderedFloat(f)) => f.is_sign_negative(),
- &Number::Rational(ref r) => r < &0
+ &Number::Rational(ref r) => r < &0,
}
}
match self {
&Number::Integer(ref n) => n == &0,
&Number::Float(f) => f == OrderedFloat(0f64),
- &Number::Rational(ref r) => r == &0
+ &Number::Rational(ref r) => r == &0,
}
}
match self {
Number::Integer(n) => Number::Integer(n.abs()),
Number::Float(f) => Number::Float(OrderedFloat(f.abs())),
- Number::Rational(r) => Number::Rational(r.abs())
+ Number::Rational(r) => Number::Rational(r.abs()),
}
}
}
pub struct HCPreOrderIterator<'a> {
pub machine_st: &'a MachineState,
- pub state_stack: Vec<Addr>
+ pub state_stack: Vec<Addr>,
}
impl<'a> HCPreOrderIterator<'a> {
- pub fn new(machine_st: &'a MachineState, a: Addr) -> Self
- {
+ pub fn new(machine_st: &'a MachineState, a: Addr) -> Self {
HCPreOrderIterator {
- machine_st, state_stack: vec![a]
+ machine_st,
+ state_stack: vec![a],
}
}
&self.machine_st
}
- fn follow_heap(&mut self, h: usize) -> Addr
- {
+ fn follow_heap(&mut self, h: usize) -> Addr {
match &self.machine_st.heap[h] {
&HeapCellValue::NamedStr(arity, _, _) => {
- for idx in (1 .. arity + 1).rev() {
+ for idx in (1..arity + 1).rev() {
self.state_stack.push(Addr::HeapCell(h + idx));
}
Addr::HeapCell(h)
- },
- &HeapCellValue::Addr(ref a) =>
- self.follow(a.clone())
+ }
+ &HeapCellValue::Addr(ref a) => self.follow(a.clone()),
}
}
// called under the assumption that the location at r is about to
// be visited, and so any follow up states need to be added to
// state_stack. returns the dereferenced Addr from Ref.
- fn follow(&mut self, addr: Addr) -> Addr
- {
+ fn follow(&mut self, addr: Addr) -> Addr {
let da = self.machine_st.store(self.machine_st.deref(addr));
match da {
Addr::Con(Constant::String(ref s)) => {
match self.machine_st.machine_flags().double_quotes {
- DoubleQuotes::Chars =>
+ DoubleQuotes::Chars => {
if let Some(c) = s.head() {
let tail = s.tail();
self.state_stack.push(Addr::Con(Constant::String(tail)));
self.state_stack.push(Addr::Con(Constant::Char(c)));
- },
- DoubleQuotes::Codes =>
+ }
+ }
+ DoubleQuotes::Codes => {
if let Some(c) = s.head() {
let tail = s.tail();
self.state_stack.push(Addr::Con(Constant::String(tail)));
- self.state_stack.push(Addr::Con(Constant::CharCode(c as u8)));
- },
+ self.state_stack
+ .push(Addr::Con(Constant::CharCode(c as u8)));
+ }
+ }
_ => {}
}
Addr::Con(Constant::String(s.clone()))
- },
+ }
Addr::Con(_) | Addr::DBRef(_) => da,
Addr::Lis(a) => {
self.state_stack.push(Addr::HeapCell(a + 1));
self.state_stack.push(Addr::HeapCell(a));
da
- },
+ }
Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => da,
- Addr::Str(s) => self.follow_heap(s) // record terms of structure.
+ Addr::Str(s) => self.follow_heap(s), // record terms of structure.
}
}
}
type Item = HeapCellValue;
fn next(&mut self) -> Option<Self::Item> {
- self.state_stack.pop().map(|a| {
- match self.follow(a) {
- Addr::HeapCell(h) =>
- self.machine_st.heap[h].clone(),
- Addr::StackCell(fr, sc) =>
- HeapCellValue::Addr(self.machine_st.and_stack[fr][sc].clone()),
- da =>
- HeapCellValue::Addr(da)
+ self.state_stack.pop().map(|a| match self.follow(a) {
+ Addr::HeapCell(h) => self.machine_st.heap[h].clone(),
+ Addr::StackCell(fr, sc) => {
+ HeapCellValue::Addr(self.machine_st.and_stack[fr][sc].clone())
}
+ da => HeapCellValue::Addr(da),
})
}
}
-pub trait MutStackHCIterator where Self: Iterator<Item=HeapCellValue> {
+pub trait MutStackHCIterator
+where
+ Self: Iterator<Item = HeapCellValue>,
+{
fn stack(&mut self) -> &mut Vec<Addr>;
}
pub struct HCPostOrderIterator<HCIter> {
- base_iter: HCIter,
- parent_stack: Vec<(usize, HeapCellValue)> // number of children, parent node.
+ base_iter: HCIter,
+ parent_stack: Vec<(usize, HeapCellValue)>, // number of children, parent node.
}
impl<HCIter> Deref for HCPostOrderIterator<HCIter> {
}
}
-impl<HCIter: Iterator<Item=HeapCellValue>> HCPostOrderIterator<HCIter> {
+impl<HCIter: Iterator<Item = HeapCellValue>> HCPostOrderIterator<HCIter> {
pub fn new(base_iter: HCIter) -> Self {
HCPostOrderIterator {
base_iter,
- parent_stack: vec![]
+ parent_stack: vec![],
}
}
}
-impl<HCIter: Iterator<Item=HeapCellValue>> Iterator for HCPostOrderIterator<HCIter> {
+impl<HCIter: Iterator<Item = HeapCellValue>> Iterator for HCPostOrderIterator<HCIter> {
type Item = HeapCellValue;
fn next(&mut self) -> Option<Self::Item> {
if let Some(item) = self.base_iter.next() {
match item {
- HeapCellValue::NamedStr(arity, name, fix) =>
- self.parent_stack.push((arity, HeapCellValue::NamedStr(arity, name, fix))),
- HeapCellValue::Addr(Addr::Lis(a)) =>
- self.parent_stack.push((2, HeapCellValue::Addr(Addr::Lis(a)))),
+ HeapCellValue::NamedStr(arity, name, fix) => self
+ .parent_stack
+ .push((arity, HeapCellValue::NamedStr(arity, name, fix))),
+ HeapCellValue::Addr(Addr::Lis(a)) => self
+ .parent_stack
+ .push((2, HeapCellValue::Addr(Addr::Lis(a)))),
child_node => {
return Some(child_node);
}
HCPostOrderIterator::new(HCPreOrderIterator::new(self, a))
}
- pub fn acyclic_pre_order_iter<'a>(&'a self, a: Addr) -> HCAcyclicIterator<HCPreOrderIterator<'a>>
- {
+ pub fn acyclic_pre_order_iter<'a>(
+ &'a self,
+ a: Addr,
+ ) -> HCAcyclicIterator<HCPreOrderIterator<'a>> {
HCAcyclicIterator::new(HCPreOrderIterator::new(self, a))
}
- pub fn zipped_acyclic_pre_order_iter<'a>(&'a self, a1: Addr, a2: Addr)
- -> HCZippedAcyclicIterator<HCPreOrderIterator<'a>>
- {
- HCZippedAcyclicIterator::new(HCPreOrderIterator::new(self, a1),
- HCPreOrderIterator::new(self, a2))
+ pub fn zipped_acyclic_pre_order_iter<'a>(
+ &'a self,
+ a1: Addr,
+ a2: Addr,
+ ) -> HCZippedAcyclicIterator<HCPreOrderIterator<'a>> {
+ HCZippedAcyclicIterator::new(
+ HCPreOrderIterator::new(self, a1),
+ HCPreOrderIterator::new(self, a2),
+ )
}
}
pub struct HCAcyclicIterator<HCIter> {
iter: HCIter,
- seen: IndexSet<Addr>
+ seen: IndexSet<Addr>,
}
-impl<HCIter: MutStackHCIterator> HCAcyclicIterator<HCIter>
-{
+impl<HCIter: MutStackHCIterator> HCAcyclicIterator<HCIter> {
pub fn new(iter: HCIter) -> Self {
- HCAcyclicIterator { iter, seen: IndexSet::new() }
+ HCAcyclicIterator {
+ iter,
+ seen: IndexSet::new(),
+ }
}
}
}
impl<HCIter> Iterator for HCAcyclicIterator<HCIter>
- where HCIter: Iterator<Item=HeapCellValue> + MutStackHCIterator
+where
+ HCIter: Iterator<Item = HeapCellValue> + MutStackHCIterator,
{
type Item = HeapCellValue;
i1: HCIter,
i2: HCIter,
seen: IndexSet<(Addr, Addr)>,
- pub first_to_expire: Ordering
+ pub first_to_expire: Ordering,
}
-impl<HCIter: MutStackHCIterator> HCZippedAcyclicIterator<HCIter>
-{
+impl<HCIter: MutStackHCIterator> HCZippedAcyclicIterator<HCIter> {
pub fn new(i1: HCIter, i2: HCIter) -> Self {
- HCZippedAcyclicIterator { i1, i2, seen: IndexSet::new(),
- first_to_expire: Ordering::Equal }
+ HCZippedAcyclicIterator {
+ i1,
+ i2,
+ seen: IndexSet::new(),
+ first_to_expire: Ordering::Equal,
+ }
}
}
impl<HCIter> Iterator for HCZippedAcyclicIterator<HCIter>
- where HCIter: Iterator<Item=HeapCellValue> + MutStackHCIterator
+where
+ HCIter: Iterator<Item = HeapCellValue> + MutStackHCIterator,
{
type Item = (HeapCellValue, HeapCellValue);
}
match (self.i1.next(), self.i2.next()) {
- (Some(v1), Some(v2)) =>
- Some((v1, v2)),
+ (Some(v1), Some(v2)) => Some((v1, v2)),
(Some(_), None) => {
self.first_to_expire = Ordering::Greater;
None
- },
+ }
(None, Some(_)) => {
self.first_to_expire = Ordering::Less;
None
- },
- _ => None
+ }
+ _ => None,
}
}
}
use prolog::machine::machine_indices::*;
use prolog::machine::machine_state::*;
use prolog::ordered_float::OrderedFloat;
-use prolog::rug::{Integer};
+use prolog::rug::Integer;
use indexmap::{IndexMap, IndexSet};
#[derive(Clone)]
pub enum DirectedOp {
Left(ClauseName, SharedOpDesc),
- Right(ClauseName, SharedOpDesc)
+ Right(ClauseName, SharedOpDesc),
}
impl DirectedOp {
#[inline]
fn as_str(&self) -> &str {
match self {
- &DirectedOp::Left(ref name, _) | &DirectedOp::Right(ref name, _) =>
- name.as_str()
+ &DirectedOp::Left(ref name, _) | &DirectedOp::Right(ref name, _) => name.as_str(),
}
}
#[inline]
fn is_negative_sign(&self) -> bool {
match self {
- &DirectedOp::Left(ref name, ref cell) | &DirectedOp::Right(ref name, ref cell) =>
+ &DirectedOp::Left(ref name, ref cell) | &DirectedOp::Right(ref name, ref cell) => {
name.as_str() == "-" && is_prefix!(cell.assoc())
+ }
}
}
}
}
-fn needs_bracketing(child_spec: &SharedOpDesc, op: &DirectedOp) -> bool
-{
+fn needs_bracketing(child_spec: &SharedOpDesc, op: &DirectedOp) -> bool {
match op {
&DirectedOp::Left(ref name, ref cell) => {
let (priority, spec) = cell.get();
let is_strict_right = is_yfx!(spec) || is_xfx!(spec) || is_fx!(spec);
child_spec.prec() > priority || (child_spec.prec() == priority && is_strict_right)
- },
+ }
&DirectedOp::Right(_, ref cell) => {
let (priority, spec) = cell.get();
let is_strict_left = is_xfx!(spec) || is_xfy!(spec) || is_xf!(spec);
* by brackets.
*/
fn leftmost_leaf_has_property<P>(&self, property_check: P) -> bool
- where P: Fn(Constant) -> bool
+ where
+ P: Fn(Constant) -> bool,
{
let mut addr = match self.state_stack.last().cloned() {
Some(addr) => addr,
- None => return false
+ None => return false,
};
let mut parent_spec = DirectedOp::Left(clause_name!("-"), SharedOpDesc::new(200, FY));
loop {
match self.machine_st.store(self.machine_st.deref(addr)) {
- Addr::Str(s) =>
- match &self.machine_st.heap[s] {
- &HeapCellValue::NamedStr(_, ref name, Some(ref spec))
- if is_postfix!(spec.assoc()) || is_infix!(spec.assoc()) =>
- if needs_bracketing(spec, &parent_spec) {
- return false;
- } else {
- addr = Addr::HeapCell(s+1);
- parent_spec = DirectedOp::Right(name.clone(), spec.clone());
- },
- _ =>
- return false
- },
- Addr::Con(Constant::Integer(n)) =>
- return property_check(Constant::Integer(n)),
- Addr::Con(Constant::Float(n)) =>
- return property_check(Constant::Float(n)),
- Addr::Con(Constant::Rational(n)) =>
- return property_check(Constant::Rational(n)),
- _ =>
- return false
+ Addr::Str(s) => match &self.machine_st.heap[s] {
+ &HeapCellValue::NamedStr(_, ref name, Some(ref spec))
+ if is_postfix!(spec.assoc()) || is_infix!(spec.assoc()) =>
+ {
+ if needs_bracketing(spec, &parent_spec) {
+ return false;
+ } else {
+ addr = Addr::HeapCell(s + 1);
+ parent_spec = DirectedOp::Right(name.clone(), spec.clone());
+ }
+ }
+ _ => return false,
+ },
+ Addr::Con(Constant::Integer(n)) => return property_check(Constant::Integer(n)),
+ Addr::Con(Constant::Float(n)) => return property_check(Constant::Float(n)),
+ Addr::Con(Constant::Rational(n)) => return property_check(Constant::Rational(n)),
+ _ => return false,
}
}
}
fn immediate_leaf_has_property<P>(&self, property_check: P) -> bool
- where P: Fn(Constant) -> bool
+ where
+ P: Fn(Constant) -> bool,
{
let addr = match self.state_stack.last().cloned() {
Some(addr) => addr,
- None => return false
+ None => return false,
};
match self.machine_st.store(self.machine_st.deref(addr)) {
Addr::Con(c) => property_check(c),
- _ => false
+ _ => false,
}
}
}
'\u{0c}' => "\\f".to_string(), // UTF-8 form feed
'\u{08}' => "\\b".to_string(), // UTF-8 backspace
'\u{07}' => "\\a".to_string(), // UTF-8 alert
- '\x20' ... '\x7e' => c.to_string(),
- _ => format!("\\x{:x}\\", c as u32)
+ '\x20'...'\x7e' => c.to_string(),
+ _ => format!("\\x{:x}\\", c as u32),
}
}
}
pub struct PrinterOutputter {
- contents: String
+ contents: String,
}
impl HCValueOutputter for PrinterOutputter {
type Output = String;
fn new() -> Self {
- PrinterOutputter { contents: String::new() }
+ PrinterOutputter {
+ contents: String::new(),
+ }
}
fn append(&mut self, contents: &str) {
}
#[inline]
-fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp>) -> bool
-{
+fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp>) -> bool {
if let &Some(ref op) = op {
- op.is_negative_sign() && iter.leftmost_leaf_has_property(|c| {
- match c {
+ op.is_negative_sign()
+ && iter.leftmost_leaf_has_property(|c| match c {
Constant::Integer(n) => n > 0,
Constant::Float(f) => f > OrderedFloat(0f64),
Constant::Rational(r) => r > 0,
- _ => false
- }
- })
+ _ => false,
+ })
} else {
false
}
impl MachineState {
pub fn numbervar(&self, offset: &Integer, addr: Addr) -> Option<Var> {
- static CHAR_CODES: [char; 26] = ['A','B','C','D','E','F','G','H','I','J',
- 'K','L','M','N','O','P','Q','R','S','T',
- 'U','V','W','X','Y','Z'];
+ static CHAR_CODES: [char; 26] = [
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
+ 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ ];
match self.store(self.deref(addr)) {
- Addr::Con(Constant::Integer(ref n))
- if n >= &0 => {
- let n = Integer::from(offset + n);
-
- let i = n.mod_u(26) as usize;
- let j = n.div_rem_floor(Integer::from(26));
- let j = <(Integer, Integer)>::from(j).1;
-
- Some(if j == 0 {
- CHAR_CODES[i].to_string()
- } else {
- format!("{}{}", CHAR_CODES[i], j)
- })
- },
- _ => None
+ Addr::Con(Constant::Integer(ref n)) if n >= &0 => {
+ let n = Integer::from(offset + n);
+
+ let i = n.mod_u(26) as usize;
+ let j = n.div_rem_floor(Integer::from(26));
+ let j = <(Integer, Integer)>::from(j).1;
+
+ Some(if j == 0 {
+ CHAR_CODES[i].to_string()
+ } else {
+ format!("{}{}", CHAR_CODES[i], j)
+ })
+ }
+ _ => None,
}
}
}
cyclic_terms: IndexMap<Addr, usize>,
pub(crate) var_names: IndexMap<Addr, String>,
pub(crate) numbervars_offset: Integer,
- pub(crate) numbervars: bool,
- pub(crate) quoted: bool,
- pub(crate) ignore_ops: bool
+ pub(crate) numbervars: bool,
+ pub(crate) quoted: bool,
+ pub(crate) ignore_ops: bool,
}
macro_rules! push_space_if_amb {
- ($self:expr, $atom:expr, $action:block) => (
+ ($self:expr, $atom:expr, $action:block) => {
if $self.ambiguity_check($atom) {
$self.outputter.push_char(' ');
$action;
} else {
$action;
}
- )
+ };
}
pub fn requires_space(atom: &str, op: &str) -> bool {
match atom.chars().last() {
- Some(ac) => op.chars().next().map(|oc| {
- if ac == '0' {
- oc == 'b' || oc == 'x' || oc == 'o' || oc == '\''
- } else if alpha_numeric_char!(ac) {
- oc == '(' || alpha_numeric_char!(oc)
- } else if graphic_token_char!(ac) {
- graphic_token_char!(oc)
- } else if variable_indicator_char!(ac) {
- alpha_numeric_char!(oc)
- } else if capital_letter_char!(ac) {
- alpha_numeric_char!(oc)
- } else if sign_char!(ac) {
- sign_char!(oc) || decimal_digit_char!(oc)
- } else if single_quote_char!(ac) {
- single_quote_char!(oc)
- } else {
- false
- }
- }).unwrap_or(false),
- _ => false
+ Some(ac) => op
+ .chars()
+ .next()
+ .map(|oc| {
+ if ac == '0' {
+ oc == 'b' || oc == 'x' || oc == 'o' || oc == '\''
+ } else if alpha_numeric_char!(ac) {
+ oc == '(' || alpha_numeric_char!(oc)
+ } else if graphic_token_char!(ac) {
+ graphic_token_char!(oc)
+ } else if variable_indicator_char!(ac) {
+ alpha_numeric_char!(oc)
+ } else if capital_letter_char!(ac) {
+ alpha_numeric_char!(oc)
+ } else if sign_char!(ac) {
+ sign_char!(oc) || decimal_digit_char!(oc)
+ } else if single_quote_char!(ac) {
+ single_quote_char!(oc)
+ } else {
+ false
+ }
+ })
+ .unwrap_or(false),
+ _ => false,
}
}
-fn reverse_heap_locs<'a>(machine_st: &'a MachineState) -> ReverseHeapVarDict
-{
- machine_st.heap_locs.iter().map(|(var, var_addr)| {
- (machine_st.store(machine_st.deref(var_addr.clone())), var.clone())
- }).collect()
+fn reverse_heap_locs<'a>(machine_st: &'a MachineState) -> ReverseHeapVarDict {
+ machine_st
+ .heap_locs
+ .iter()
+ .map(|(var, var_addr)| {
+ (
+ machine_st.store(machine_st.deref(var_addr.clone())),
+ var.clone(),
+ )
+ })
+ .collect()
}
-fn non_quoted_graphic_token<Iter: Iterator<Item=char>>(mut iter: Iter, c: char) -> bool {
+fn non_quoted_graphic_token<Iter: Iterator<Item = char>>(mut iter: Iter, c: char) -> bool {
if c == '/' {
return match iter.next() {
None => true,
Some('*') => false, // if we start with comment token, we must quote.
- Some(c) => if graphic_token_char!(c) {
- iter.all(|c| graphic_token_char!(c))
- } else {
- false
+ Some(c) => {
+ if graphic_token_char!(c) {
+ iter.all(|c| graphic_token_char!(c))
+ } else {
+ false
+ }
}
- }
+ };
} else if c == '.' {
return match iter.next() {
None => false,
- Some(c) => if graphic_token_char!(c) {
- iter.all(|c| graphic_token_char!(c))
- } else {
- false
+ Some(c) => {
+ if graphic_token_char!(c) {
+ iter.all(|c| graphic_token_char!(c))
+ } else {
+ false
+ }
}
- }
+ };
} else {
iter.all(|c| graphic_token_char!(c))
}
}
-fn non_quoted_token<Iter: Iterator<Item=char>>(mut iter: Iter) -> bool {
+fn non_quoted_token<Iter: Iterator<Item = char>>(mut iter: Iter) -> bool {
if let Some(c) = iter.next() {
if small_letter_char!(c) {
iter.all(|c| alpha_numeric_char!(c))
}
}
-impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
-{
- pub fn new(machine_st: &'a MachineState, op_dir: &'a OpDir, output: Outputter) -> Self
- {
- HCPrinter { outputter: output,
- machine_st,
- op_dir,
- state_stack: vec![],
- heap_locs: ReverseHeapVarDict::new(),
- toplevel_spec: None,
- printed_vars: IndexSet::new(),
- last_item_idx: 0,
- numbervars: false,
- numbervars_offset: Integer::from(0),
- quoted: false,
- ignore_ops: false,
- cyclic_terms: IndexMap::new(),
- var_names: IndexMap::new() }
- }
-
- pub fn from_heap_locs(machine_st: &'a MachineState, op_dir: &'a OpDir, output: Outputter)
- -> Self
- {
+impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
+ pub fn new(machine_st: &'a MachineState, op_dir: &'a OpDir, output: Outputter) -> Self {
+ HCPrinter {
+ outputter: output,
+ machine_st,
+ op_dir,
+ state_stack: vec![],
+ heap_locs: ReverseHeapVarDict::new(),
+ toplevel_spec: None,
+ printed_vars: IndexSet::new(),
+ last_item_idx: 0,
+ numbervars: false,
+ numbervars_offset: Integer::from(0),
+ quoted: false,
+ ignore_ops: false,
+ cyclic_terms: IndexMap::new(),
+ var_names: IndexMap::new(),
+ }
+ }
+
+ pub fn from_heap_locs(
+ machine_st: &'a MachineState,
+ op_dir: &'a OpDir,
+ output: Outputter,
+ ) -> Self {
let mut printer = Self::new(machine_st, op_dir, output);
- printer.toplevel_spec = Some(DirectedOp::Right(clause_name!("="), SharedOpDesc::new(700, XFX)));
+ printer.toplevel_spec = Some(DirectedOp::Right(
+ clause_name!("="),
+ SharedOpDesc::new(700, XFX),
+ ));
printer.heap_locs = reverse_heap_locs(machine_st);
printer
}
#[inline]
- fn ambiguity_check(&self, atom: &str) -> bool
- {
- let tail = self.outputter.range_from(self.last_item_idx ..);
+ fn ambiguity_check(&self, atom: &str) -> bool {
+ let tail = self.outputter.range_from(self.last_item_idx..);
requires_space(tail, atom)
}
let right_directed_op = DirectedOp::Right(ct.name(), spec.clone());
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
- self.state_stack.push(TokenOrRedirect::CompositeRedirect(right_directed_op));
+ self.state_stack
+ .push(TokenOrRedirect::CompositeRedirect(right_directed_op));
} else if is_prefix!(spec.assoc()) {
match ct.name().as_str() {
"-" | "\\" => {
let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
- self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
+ self.state_stack
+ .push(TokenOrRedirect::CompositeRedirect(left_directed_op));
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
- } else { // if is_infix!(spec.assoc())
+ } else {
+ // if is_infix!(spec.assoc())
match ct.name().as_str() {
"|" => {
self.format_bar_separator_op(ct.name(), spec);
return;
- },
+ }
_ => {}
};
- let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
+ let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
let right_directed_op = DirectedOp::Right(ct.name(), spec.clone());
- self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
+ self.state_stack
+ .push(TokenOrRedirect::CompositeRedirect(left_directed_op));
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
- self.state_stack.push(TokenOrRedirect::CompositeRedirect(right_directed_op));
+ self.state_stack
+ .push(TokenOrRedirect::CompositeRedirect(right_directed_op));
}
}
- fn format_struct(&mut self, arity: usize, name: ClauseName)
- {
+ fn format_struct(&mut self, arity: usize, name: ClauseName) {
self.state_stack.push(TokenOrRedirect::Close);
- for _ in 0 .. arity {
+ for _ in 0..arity {
self.state_stack.push(TokenOrRedirect::FunctorRedirect);
self.state_stack.push(TokenOrRedirect::Comma);
}
self.state_stack.push(TokenOrRedirect::Atom(name));
}
- fn format_prefix_op_with_space(&mut self, name: ClauseName, spec: SharedOpDesc)
- {
+ fn format_prefix_op_with_space(&mut self, name: ClauseName, spec: SharedOpDesc) {
let op = DirectedOp::Left(name.clone(), spec);
- self.state_stack.push(TokenOrRedirect::CompositeRedirect(op));
+ self.state_stack
+ .push(TokenOrRedirect::CompositeRedirect(op));
self.state_stack.push(TokenOrRedirect::Space);
self.state_stack.push(TokenOrRedirect::Atom(name));
}
- fn format_bar_separator_op(&mut self, name: ClauseName, spec: SharedOpDesc)
- {
- let left_directed_op = DirectedOp::Left(name.clone(), spec.clone());
+ fn format_bar_separator_op(&mut self, name: ClauseName, spec: SharedOpDesc) {
+ let left_directed_op = DirectedOp::Left(name.clone(), spec.clone());
let right_directed_op = DirectedOp::Right(name.clone(), spec.clone());
- self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
+ self.state_stack
+ .push(TokenOrRedirect::CompositeRedirect(left_directed_op));
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
- self.state_stack.push(TokenOrRedirect::CompositeRedirect(right_directed_op));
+ self.state_stack
+ .push(TokenOrRedirect::CompositeRedirect(right_directed_op));
}
- fn format_curly_braces(&mut self)
- {
+ fn format_curly_braces(&mut self) {
self.state_stack.push(TokenOrRedirect::RightCurly);
self.state_stack.push(TokenOrRedirect::FunctorRedirect);
self.state_stack.push(TokenOrRedirect::LeftCurly);
}
- fn format_numbered_vars(&mut self, iter: &mut HCPreOrderIterator) -> bool
- {
+ fn format_numbered_vars(&mut self, iter: &mut HCPreOrderIterator) -> bool {
let addr = iter.stack().last().cloned().unwrap();
// 7.10.4
false
}
- fn format_clause(&mut self, iter: &mut HCPreOrderIterator, arity: usize, ct: ClauseType)
- {
+ fn format_clause(&mut self, iter: &mut HCPreOrderIterator, arity: usize, ct: ClauseType) {
if self.numbervars && is_numbered_var(&ct, arity) {
if self.format_numbered_vars(iter) {
return;
match (ct.name().as_str(), arity) {
("{}", 1) if !self.ignore_ops => self.format_curly_braces(),
- _ => self.format_struct(arity, ct.name())
+ _ => self.format_struct(arity, ct.name()),
};
}
self.outputter.append(s);
}
- fn offset_as_string(&self, iter: &mut HCPreOrderIterator, addr: Addr) -> Option<String>
- {
+ fn offset_as_string(&self, iter: &mut HCPreOrderIterator, addr: Addr) -> Option<String> {
if let Some(var) = self.var_names.get(&addr) {
if addr.as_var().is_some() {
return Some(format!("{}", var));
}
match addr {
- Addr::AttrVar(h) =>
- Some(format!("_{}", h + 1)),
- Addr::HeapCell(h) | Addr::Lis(h) | Addr::Str(h) =>
- Some(format!("_{}", h)),
- Addr::StackCell(fr, sc) =>
- Some(format!("_s_{}_{}", fr, sc)),
- _ => None
+ Addr::AttrVar(h) => Some(format!("_{}", h + 1)),
+ Addr::HeapCell(h) | Addr::Lis(h) | Addr::Str(h) => Some(format!("_{}", h)),
+ Addr::StackCell(fr, sc) => Some(format!("_s_{}_{}", fr, sc)),
+ _ => None,
}
}
- fn check_for_seen(&mut self, iter: &mut HCPreOrderIterator) -> Option<HeapCellValue>
- {
+ fn check_for_seen(&mut self, iter: &mut HCPreOrderIterator) -> Option<HeapCellValue> {
iter.stack().last().cloned().and_then(|addr| {
let addr = self.machine_st.store(self.machine_st.deref(addr));
match self.heap_locs.get(&addr).cloned() {
- Some(var) => if !self.printed_vars.contains(&addr) {
- self.printed_vars.insert(addr);
- return iter.next();
- } else {
- iter.stack().pop();
- push_space_if_amb!(self, &var, {
- self.append_str(&var);
- });
+ Some(var) => {
+ if !self.printed_vars.contains(&addr) {
+ self.printed_vars.insert(addr);
+ return iter.next();
+ } else {
+ iter.stack().pop();
+ push_space_if_amb!(self, &var, {
+ self.append_str(&var);
+ });
- return None;
- },
- None => if self.machine_st.is_cyclic_term(addr.clone()) {
- match self.cyclic_terms.get(&addr).cloned() {
- Some(reps) =>
- if reps > 0 {
- self.cyclic_terms.insert(addr, reps - 1);
+ return None;
+ }
+ }
+ None => {
+ if self.machine_st.is_cyclic_term(addr.clone()) {
+ match self.cyclic_terms.get(&addr).cloned() {
+ Some(reps) => {
+ if reps > 0 {
+ self.cyclic_terms.insert(addr, reps - 1);
+ iter.next()
+ } else {
+ push_space_if_amb!(self, "...", {
+ self.append_str("...");
+ });
+
+ iter.stack().pop();
+ self.cyclic_terms.remove(&addr);
+ None
+ }
+ }
+ None => {
+ self.cyclic_terms.insert(addr, 2);
iter.next()
- } else {
- push_space_if_amb!(self, "...", {
- self.append_str("...");
- });
-
- iter.stack().pop();
- self.cyclic_terms.remove(&addr);
- None
- },
- None => {
- self.cyclic_terms.insert(addr, 2);
- iter.next()
+ }
}
+ } else {
+ iter.next()
}
- } else {
- iter.next()
}
}
})
}
match n {
- Number::Float(fl) =>
+ Number::Float(fl) => {
if &fl == &OrderedFloat(0f64) {
push_space_if_amb!(self, "0", {
self.append_str("0");
push_space_if_amb!(self, &output_str, {
self.append_str(&output_str.trim());
});
- },
+ }
+ }
n => {
let output_str = format!("{}", n);
fn print_constant(&mut self, c: Constant, op: &Option<DirectedOp>) {
match c {
- Constant::Atom(atom, spec) =>
+ Constant::Atom(atom, spec) => {
if let Some(_) = fetch_atom_op_spec(atom.clone(), spec, self.op_dir) {
let mut result = String::new();
push_space_if_amb!(self, atom.as_str(), {
self.print_atom(&atom);
});
- },
+ }
+ }
Constant::Char(c) if non_quoted_token(once(c)) => {
let c = char_to_string(c);
push_space_if_amb!(self, &c, {
self.append_str(c.as_str());
});
- },
+ }
Constant::Char(c) => {
let mut result = String::new();
push_space_if_amb!(self, &result, {
self.append_str(result.as_str());
});
- },
- Constant::CharCode(c) =>
- self.append_str(&format!("{}", c)),
- Constant::EmptyList =>
- self.append_str("[]"),
- Constant::Integer(n) =>
- self.print_number(Number::Integer(n), op),
- Constant::Float(n) =>
- self.print_number(Number::Float(n), op),
- Constant::Rational(n) =>
- self.print_number(Number::Rational(n), op),
- Constant::String(s) =>
- self.print_string(s),
- Constant::Usize(i) =>
- self.append_str(&format!("u{}", i))
+ }
+ Constant::CharCode(c) => self.append_str(&format!("{}", c)),
+ Constant::EmptyList => self.append_str("[]"),
+ Constant::Integer(n) => self.print_number(Number::Integer(n), op),
+ Constant::Float(n) => self.print_number(Number::Float(n), op),
+ Constant::Rational(n) => self.print_number(Number::Rational(n), op),
+ Constant::String(s) => self.print_string(s),
+ Constant::Usize(i) => self.append_str(&format!("u{}", i)),
}
}
fn print_string(&mut self, s: StringList) {
match self.machine_st.machine_flags().double_quotes {
- DoubleQuotes::Chars | DoubleQuotes::Codes =>
+ DoubleQuotes::Chars | DoubleQuotes::Codes => {
if !s.is_empty() {
if self.ignore_ops {
self.format_struct(2, clause_name!("."));
}
} else if !self.at_cdr("") {
self.append_str("[]");
- },
+ }
+ }
DoubleQuotes::Atom => {
let borrowed_str = s.borrow();
let mut atom = String::new();
- for c in borrowed_str[s.cursor() ..].chars() {
+ for c in borrowed_str[s.cursor()..].chars() {
atom += &char_to_string(c);
}
fn push_list(&mut self) {
let cell = Rc::new(Cell::new(true));
- self.state_stack.push(TokenOrRedirect::CloseList(cell.clone()));
+ self.state_stack
+ .push(TokenOrRedirect::CloseList(cell.clone()));
self.state_stack.push(TokenOrRedirect::FunctorRedirect);
self.state_stack.push(TokenOrRedirect::HeadTailSeparator); // bar
self.state_stack.push(TokenOrRedirect::OpenList(cell));
}
- fn handle_op_as_struct(&mut self, name: ClauseName, arity: usize, iter: &mut HCPreOrderIterator,
- op: &Option<DirectedOp>, is_functor_redirect: bool, spec: SharedOpDesc,
- negated_operand: bool)
- {
+ fn handle_op_as_struct(
+ &mut self,
+ name: ClauseName,
+ arity: usize,
+ iter: &mut HCPreOrderIterator,
+ op: &Option<DirectedOp>,
+ is_functor_redirect: bool,
+ spec: SharedOpDesc,
+ negated_operand: bool,
+ ) {
let add_brackets = if !self.ignore_ops {
- negated_operand || if let Some(ref op) = op {
- if self.numbervars && arity == 1 && name.as_str() == "$VAR" {
- !iter.immediate_leaf_has_property(|c| {
- match c {
+ negated_operand
+ || if let Some(ref op) = op {
+ if self.numbervars && arity == 1 && name.as_str() == "$VAR" {
+ !iter.immediate_leaf_has_property(|c| match c {
Constant::Integer(n) => n >= 0,
Constant::Float(f) => f >= OrderedFloat(0f64),
Constant::Rational(r) => r >= 0,
- _ => false
- }
- }) && needs_bracketing(&spec, op)
+ _ => false,
+ }) && needs_bracketing(&spec, op)
+ } else {
+ needs_bracketing(&spec, op)
+ }
} else {
- needs_bracketing(&spec, op)
+ is_functor_redirect && spec.prec() >= 1000
}
- } else {
- is_functor_redirect && spec.prec() >= 1000
- }
} else {
false
};
}
}
-
- fn handle_heap_term(&mut self, iter: &mut HCPreOrderIterator, op: Option<DirectedOp>,
- is_functor_redirect: bool)
- {
+ fn handle_heap_term(
+ &mut self,
+ iter: &mut HCPreOrderIterator,
+ op: Option<DirectedOp>,
+ is_functor_redirect: bool,
+ ) {
let negated_operand = negated_op_needs_bracketing(iter, &op);
let heap_val = match self.check_for_seen(iter) {
Some(heap_val) => heap_val,
- None => return
+ None => return,
};
match heap_val {
- HeapCellValue::NamedStr(arity, name, spec) =>
+ HeapCellValue::NamedStr(arity, name, spec) => {
if let Some(spec) = fetch_op_spec(name.clone(), arity, spec.clone(), self.op_dir) {
- self.handle_op_as_struct(name, arity, iter, &op, is_functor_redirect, spec,
- negated_operand);
+ self.handle_op_as_struct(
+ name,
+ arity,
+ iter,
+ &op,
+ is_functor_redirect,
+ spec,
+ negated_operand,
+ );
} else {
push_space_if_amb!(self, name.as_str(), {
let ct = ClauseType::from(name, arity, spec);
self.format_clause(iter, arity, ct);
});
- },
- HeapCellValue::Addr(Addr::Con(Constant::EmptyList)) =>
+ }
+ }
+ HeapCellValue::Addr(Addr::Con(Constant::EmptyList)) => {
if !self.at_cdr("") {
self.append_str("[]");
- },
- HeapCellValue::Addr(Addr::Con(c)) =>
- self.print_constant(c, &op),
- HeapCellValue::Addr(Addr::Lis(_)) =>
+ }
+ }
+ HeapCellValue::Addr(Addr::Con(c)) => self.print_constant(c, &op),
+ HeapCellValue::Addr(Addr::Lis(_)) => {
if self.ignore_ops {
self.format_struct(2, clause_name!("."));
} else {
self.push_list();
- },
- HeapCellValue::Addr(addr) =>
+ }
+ }
+ HeapCellValue::Addr(addr) => {
if let Some(offset_str) = self.offset_as_string(iter, addr) {
push_space_if_amb!(self, &offset_str, {
self.append_str(offset_str.as_str());
})
}
+ }
}
}
loop {
if let Some(loc_data) = self.state_stack.pop() {
match loc_data {
- TokenOrRedirect::Atom(atom) =>
- self.print_atom(&atom),
- TokenOrRedirect::Op(atom, _) =>
- self.print_op(atom.as_str()),
- TokenOrRedirect::NumberedVar(num_var) =>
- self.append_str(num_var.as_str()),
- TokenOrRedirect::CompositeRedirect(op) =>
- self.handle_heap_term(&mut iter, Some(op), false),
- TokenOrRedirect::FunctorRedirect =>
- self.handle_heap_term(&mut iter, None, true),
- TokenOrRedirect::Close =>
- self.push_char(')'),
- TokenOrRedirect::Open =>
- self.push_char('('),
- TokenOrRedirect::OpenList(delimit) =>
+ TokenOrRedirect::Atom(atom) => self.print_atom(&atom),
+ TokenOrRedirect::Op(atom, _) => self.print_op(atom.as_str()),
+ TokenOrRedirect::NumberedVar(num_var) => self.append_str(num_var.as_str()),
+ TokenOrRedirect::CompositeRedirect(op) => {
+ self.handle_heap_term(&mut iter, Some(op), false)
+ }
+ TokenOrRedirect::FunctorRedirect => {
+ self.handle_heap_term(&mut iter, None, true)
+ }
+ TokenOrRedirect::Close => self.push_char(')'),
+ TokenOrRedirect::Open => self.push_char('('),
+ TokenOrRedirect::OpenList(delimit) => {
if !self.at_cdr(",") {
self.push_char('[');
} else {
delimit.set(false);
- },
- TokenOrRedirect::CloseList(delimit) =>
+ }
+ }
+ TokenOrRedirect::CloseList(delimit) => {
if delimit.get() {
self.push_char(']');
- },
- TokenOrRedirect::HeadTailSeparator =>
- self.append_str("|"),
- TokenOrRedirect::Comma =>
- self.append_str(","),
- TokenOrRedirect::Space =>
- self.push_char(' '),
- TokenOrRedirect::LeftCurly =>
- self.push_char('{'),
- TokenOrRedirect::RightCurly =>
- self.push_char('}'),
+ }
+ }
+ TokenOrRedirect::HeadTailSeparator => self.append_str("|"),
+ TokenOrRedirect::Comma => self.append_str(","),
+ TokenOrRedirect::Space => self.push_char(' '),
+ TokenOrRedirect::LeftCurly => self.push_char('{'),
+ TokenOrRedirect::RightCurly => self.push_char('}'),
}
} else if !iter.stack().is_empty() {
let spec = self.toplevel_spec.take();
#[derive(Clone, Copy)]
enum IntIndex {
- External(usize), Fail, Internal(usize)
+ External(usize),
+ Fail,
+ Internal(usize),
}
pub struct CodeOffsets {
flags: MachineFlags,
- pub constants: IndexMap<Constant, ThirdLevelIndex>,
+ pub constants: IndexMap<Constant, ThirdLevelIndex>,
pub lists: ThirdLevelIndex,
- pub structures: IndexMap<(ClauseName, usize), ThirdLevelIndex>
+ pub structures: IndexMap<(ClauseName, usize), ThirdLevelIndex>,
}
impl CodeOffsets {
flags,
constants: IndexMap::new(),
lists: Vec::new(),
- structures: IndexMap::new()
+ structures: IndexMap::new(),
}
}
fn cap_choice_seq_with_trust(prelude: &mut ThirdLevelIndex) {
prelude.last_mut().map(|instr| {
match instr {
- &mut IndexedChoiceInstruction::Retry(i) =>
- *instr = IndexedChoiceInstruction::Trust(i),
+ &mut IndexedChoiceInstruction::Retry(i) => {
+ *instr = IndexedChoiceInstruction::Trust(i)
+ }
_ => {}
};
});
}
}
- pub fn index_term(&mut self, first_arg: &Term, index: usize)
- {
+ pub fn index_term(&mut self, first_arg: &Term, index: usize) {
match first_arg {
&Term::Clause(_, ref name, ref terms, _) => {
- let code = self.structures.entry((name.clone(), terms.len()))
- .or_insert(Vec::new());
+ let code = self
+ .structures
+ .entry((name.clone(), terms.len()))
+ .or_insert(Vec::new());
let is_initial_index = code.is_empty();
code.push(Self::add_index(is_initial_index, index));
- },
+ }
&Term::Cons(..) => {
let is_initial_index = self.lists.is_empty();
self.lists.push(Self::add_index(is_initial_index, index));
- },
+ }
&Term::Constant(_, Constant::String(ref s))
- if !self.flags.double_quotes.is_atom() && !s.is_empty() => { // strings are lists in this case.
- let is_initial_index = self.lists.is_empty();
- self.lists.push(Self::add_index(is_initial_index, index));
- },
+ if !self.flags.double_quotes.is_atom() && !s.is_empty() =>
+ {
+ // strings are lists in this case.
+ let is_initial_index = self.lists.is_empty();
+ self.lists.push(Self::add_index(is_initial_index, index));
+ }
&Term::Constant(_, Constant::String(ref s))
- if !self.flags.double_quotes.is_atom() && s.is_expandable() => {
- let is_initial_index = self.lists.is_empty();
- self.lists.push(Self::add_index(is_initial_index, index));
- },
+ if !self.flags.double_quotes.is_atom() && s.is_expandable() =>
+ {
+ let is_initial_index = self.lists.is_empty();
+ self.lists.push(Self::add_index(is_initial_index, index));
+ }
&Term::Constant(_, ref constant) => {
- let code = self.constants.entry(constant.clone())
- .or_insert(Vec::new());
+ let code = self.constants.entry(constant.clone()).or_insert(Vec::new());
let is_initial_index = code.is_empty();
code.push(Self::add_index(is_initial_index, index));
- },
+ }
_ => {}
};
}
- fn second_level_index<Index>(indices: IndexMap<Index, ThirdLevelIndex>, prelude: &mut CodeDeque)
- -> IndexMap<Index, IntIndex>
- where Index: Eq + Hash
+ fn second_level_index<Index>(
+ indices: IndexMap<Index, ThirdLevelIndex>,
+ prelude: &mut CodeDeque,
+ ) -> IndexMap<Index, IntIndex>
+ where
+ Index: Eq + Hash,
{
let mut index_locs = IndexMap::new();
no_constants && no_structures && no_lists
}
- fn flatten_index<Index>(index: IndexMap<Index, IntIndex>, len: usize)
- -> IndexMap<Index, usize>
- where Index: Eq + Hash
+ fn flatten_index<Index>(index: IndexMap<Index, IntIndex>, len: usize) -> IndexMap<Index, usize>
+ where
+ Index: Eq + Hash,
{
let mut flattened_index = IndexMap::new();
match int_index {
IntIndex::External(offset) => {
flattened_index.insert(key, offset + len + 1);
- },
+ }
IntIndex::Internal(offset) => {
flattened_index.insert(key, offset + 1);
- },
+ }
_ => {}
};
}
flattened_index
}
- fn adjust_internal_index(index: IntIndex) -> IntIndex
- {
+ fn adjust_internal_index(index: IntIndex) -> IntIndex {
match index {
IntIndex::Internal(o) => IntIndex::Internal(o + 1),
IntIndex::External(o) => IntIndex::External(o),
- _ => IntIndex::Fail
+ _ => IntIndex::Fail,
}
}
- fn switch_on_constant(con_ind: IndexMap<Constant, ThirdLevelIndex>, prelude: &mut CodeDeque)
- -> IntIndex
- {
+ fn switch_on_constant(
+ con_ind: IndexMap<Constant, ThirdLevelIndex>,
+ prelude: &mut CodeDeque,
+ ) -> IntIndex {
let con_ind = Self::second_level_index(con_ind, prelude);
if con_ind.len() > 1 {
IntIndex::Internal(1)
} else {
- con_ind.values().next()
- .map(|index| Self::adjust_internal_index(*index))
- .unwrap_or(IntIndex::Fail)
+ con_ind
+ .values()
+ .next()
+ .map(|index| Self::adjust_internal_index(*index))
+ .unwrap_or(IntIndex::Fail)
}
}
- fn switch_on_structure(str_ind: IndexMap<(ClauseName, usize), ThirdLevelIndex>,
- prelude: &mut CodeDeque)
- -> IntIndex
- {
+ fn switch_on_structure(
+ str_ind: IndexMap<(ClauseName, usize), ThirdLevelIndex>,
+ prelude: &mut CodeDeque,
+ ) -> IntIndex {
let str_ind = Self::second_level_index(str_ind, prelude);
if str_ind.len() > 1 {
IntIndex::Internal(1)
} else {
- str_ind.values().next()
- .map(|index| Self::adjust_internal_index(*index))
- .unwrap_or(IntIndex::Fail)
+ str_ind
+ .values()
+ .next()
+ .map(|index| Self::adjust_internal_index(*index))
+ .unwrap_or(IntIndex::Fail)
}
}
- fn switch_on_list(mut lists: ThirdLevelIndex, prelude: &mut CodeDeque) -> IntIndex
- {
+ fn switch_on_list(mut lists: ThirdLevelIndex, prelude: &mut CodeDeque) -> IntIndex {
if lists.len() > 1 {
Self::cap_choice_seq_with_trust(&mut lists);
prelude.extend(lists.into_iter().map(|i| Line::from(i)));
IntIndex::Internal(0)
} else {
- lists.first()
- .map(|i| IntIndex::External(i.offset()))
- .unwrap_or(IntIndex::Fail)
+ lists
+ .first()
+ .map(|i| IntIndex::External(i.offset()))
+ .unwrap_or(IntIndex::Fail)
}
}
- fn switch_on_str_offset_from(str_loc: IntIndex, prelude_len: usize, con_loc: IntIndex)
- -> usize
- {
+ fn switch_on_str_offset_from(
+ str_loc: IntIndex,
+ prelude_len: usize,
+ con_loc: IntIndex,
+ ) -> usize {
match str_loc {
IntIndex::External(o) => o + prelude_len + 1,
IntIndex::Fail => 0,
IntIndex::Internal(_) => match con_loc {
IntIndex::Internal(_) => 2,
- _ => 1
- }
+ _ => 1,
+ },
}
}
- fn switch_on_con_offset_from(con_loc: IntIndex, prelude_len: usize) -> usize
- {
+ fn switch_on_con_offset_from(con_loc: IntIndex, prelude_len: usize) -> usize {
match con_loc {
IntIndex::External(offset) => offset + prelude_len + 1,
IntIndex::Fail => 0,
}
}
- fn switch_on_lst_offset_from(lst_loc: IntIndex, prelude_len: usize, lst_offset: usize)
- -> usize
- {
+ fn switch_on_lst_offset_from(
+ lst_loc: IntIndex,
+ prelude_len: usize,
+ lst_offset: usize,
+ ) -> usize {
match lst_loc {
IntIndex::External(o) => o + prelude_len + 1,
IntIndex::Fail => 0,
- IntIndex::Internal(_) => prelude_len - lst_offset + 1
+ IntIndex::Internal(_) => prelude_len - lst_offset + 1,
}
}
- pub fn add_indices(self, code: &mut Code, mut code_body: Code)
- {
+ pub fn add_indices(self, code: &mut Code, mut code_body: Code) {
if self.no_indices() {
*code = code_body;
return;
for (index, line) in prelude.iter_mut().enumerate() {
match line {
- &mut Line::IndexedChoice(IndexedChoiceInstruction::Try(ref mut i))
+ &mut Line::IndexedChoice(IndexedChoiceInstruction::Try(ref mut i))
| &mut Line::IndexedChoice(IndexedChoiceInstruction::Retry(ref mut i))
- | &mut Line::IndexedChoice(IndexedChoiceInstruction::Trust(ref mut i)) =>
- *i += prelude_length - index,
+ | &mut Line::IndexedChoice(IndexedChoiceInstruction::Trust(ref mut i)) => {
+ *i += prelude_length - index
+ }
_ => {}
}
}
let con_loc = Self::switch_on_con_offset_from(con_loc, prelude.len());
let lst_loc = Self::switch_on_lst_offset_from(lst_loc, prelude.len(), lst_offset);
- let switch_instr = IndexingInstruction::SwitchOnTerm(prelude.len() + 1,
- con_loc,
- lst_loc,
- str_loc);
+ let switch_instr =
+ IndexingInstruction::SwitchOnTerm(prelude.len() + 1, con_loc, lst_loc, str_loc);
prelude.push_front(Line::from(switch_instr));
fn reg_type_into_functor(r: RegType) -> MachineStub {
match r {
- RegType::Temp(r) =>
- functor!("x", 1, [heap_integer!(Integer::from(r))]),
- RegType::Perm(r) =>
- functor!("y", 1, [heap_integer!(Integer::from(r))])
+ RegType::Temp(r) => functor!("x", 1, [heap_integer!(Integer::from(r))]),
+ RegType::Perm(r) => functor!("y", 1, [heap_integer!(Integer::from(r))]),
}
}
impl Level {
fn into_functor(self) -> MachineStub {
match self {
- Level::Root =>
- functor!("level", 1, [heap_atom!("root")]),
- Level::Shallow =>
- functor!("level", 1, [heap_atom!("shallow")]),
- Level::Deep =>
- functor!("level", 1, [heap_atom!("deep")]),
+ Level::Root => functor!("level", 1, [heap_atom!("root")]),
+ Level::Shallow => functor!("level", 1, [heap_atom!("shallow")]),
+ Level::Deep => functor!("level", 1, [heap_atom!("deep")]),
}
}
}
impl ArithmeticTerm {
fn into_functor(&self) -> MachineStub {
match self {
- &ArithmeticTerm::Reg(r) =>
- reg_type_into_functor(r),
- &ArithmeticTerm::Interm(i) =>
- functor!("intermediate", 1, [heap_integer!(Integer::from(i))]),
- &ArithmeticTerm::Number(ref n) =>
- vec![heap_con!(n.clone().to_constant())]
+ &ArithmeticTerm::Reg(r) => reg_type_into_functor(r),
+ &ArithmeticTerm::Interm(i) => {
+ functor!("intermediate", 1, [heap_integer!(Integer::from(i))])
+ }
+ &ArithmeticTerm::Number(ref n) => vec![heap_con!(n.clone().to_constant())],
}
}
}
DefaultTrustMe,
RetryMeElse(usize),
TrustMe,
- TryMeElse(usize)
+ TryMeElse(usize),
}
impl ChoiceInstruction {
pub fn to_functor(&self) -> MachineStub {
match self {
- &ChoiceInstruction::TryMeElse(offset) =>
- functor!("try_me_else", 1, [heap_integer!(Integer::from(offset))]),
- &ChoiceInstruction::RetryMeElse(offset) =>
- functor!("retry_me_else", 1, [heap_integer!(Integer::from(offset))]),
- &ChoiceInstruction::TrustMe =>
- vec![heap_atom!("trust_me")],
- &ChoiceInstruction::DefaultRetryMeElse(offset) =>
- functor!("default_retry_me_else", 1, [heap_integer!(Integer::from(offset))]),
- &ChoiceInstruction::DefaultTrustMe =>
- vec![heap_atom!("default_trust_me")],
+ &ChoiceInstruction::TryMeElse(offset) => {
+ functor!("try_me_else", 1, [heap_integer!(Integer::from(offset))])
+ }
+ &ChoiceInstruction::RetryMeElse(offset) => {
+ functor!("retry_me_else", 1, [heap_integer!(Integer::from(offset))])
+ }
+ &ChoiceInstruction::TrustMe => vec![heap_atom!("trust_me")],
+ &ChoiceInstruction::DefaultRetryMeElse(offset) => functor!(
+ "default_retry_me_else",
+ 1,
+ [heap_integer!(Integer::from(offset))]
+ ),
+ &ChoiceInstruction::DefaultTrustMe => vec![heap_atom!("default_trust_me")],
}
}
}
Cut(RegType),
GetLevel(RegType),
GetLevelAndUnify(RegType),
- NeckCut
+ NeckCut,
}
impl CutInstruction {
let mut stub = functor!("cut", 1, [heap_str!(h + 2)]);
stub.append(&mut reg_type_into_functor(r));
stub
- },
+ }
&CutInstruction::GetLevel(r) => {
let mut stub = functor!("get_level", 1, [heap_str!(h + 2)]);
stub.append(&mut reg_type_into_functor(r));
stub
- },
+ }
&CutInstruction::GetLevelAndUnify(r) => {
let mut stub = functor!("get_level_and_unify", 1, [heap_str!(h + 2)]);
stub.append(&mut reg_type_into_functor(r));
stub
- },
- &CutInstruction::NeckCut =>
- vec![heap_atom!("neck_cut")]
+ }
+ &CutInstruction::NeckCut => vec![heap_atom!("neck_cut")],
}
}
}
pub enum IndexedChoiceInstruction {
Retry(usize),
Trust(usize),
- Try(usize)
+ Try(usize),
}
impl From<IndexedChoiceInstruction> for Line {
match self {
&IndexedChoiceInstruction::Retry(offset) => offset,
&IndexedChoiceInstruction::Trust(offset) => offset,
- &IndexedChoiceInstruction::Try(offset) => offset
+ &IndexedChoiceInstruction::Try(offset) => offset,
}
}
pub fn to_functor(&self) -> MachineStub {
match self {
- &IndexedChoiceInstruction::Try(offset) =>
- functor!("try", 1, [heap_integer!(Integer::from(offset))]),
- &IndexedChoiceInstruction::Trust(offset) =>
- functor!("trust", 1, [heap_integer!(Integer::from(offset))]),
- &IndexedChoiceInstruction::Retry(offset) =>
+ &IndexedChoiceInstruction::Try(offset) => {
+ functor!("try", 1, [heap_integer!(Integer::from(offset))])
+ }
+ &IndexedChoiceInstruction::Trust(offset) => {
+ functor!("trust", 1, [heap_integer!(Integer::from(offset))])
+ }
+ &IndexedChoiceInstruction::Retry(offset) => {
functor!("retry", 1, [heap_integer!(Integer::from(offset))])
+ }
}
}
}
Fact(FactInstruction),
Indexing(IndexingInstruction),
IndexedChoice(IndexedChoiceInstruction),
- Query(QueryInstruction)
+ Query(QueryInstruction),
}
impl Line {
&Line::Cut(_) => true,
&Line::Fact(_) => true,
&Line::Query(_) => true,
- _ => false
+ _ => false,
}
}
&Line::Fact(ref fact_instr) => fact_instr.to_functor(h),
&Line::Indexing(ref indexing_instr) => indexing_instr.to_functor(),
&Line::IndexedChoice(ref indexed_choice_instr) => indexed_choice_instr.to_functor(),
- &Line::Query(ref query_instr) => query_instr.to_functor(h)
+ &Line::Query(ref query_instr) => query_instr.to_functor(h),
}
}
}
Floor(ArithmeticTerm, usize),
Neg(ArithmeticTerm, usize),
Plus(ArithmeticTerm, usize),
- BitwiseComplement(ArithmeticTerm, usize)
+ BitwiseComplement(ArithmeticTerm, usize),
}
-fn arith_instr_unary_functor(h: usize, name: &'static str, at: &ArithmeticTerm, t: usize)
- -> MachineStub
-{
+fn arith_instr_unary_functor(
+ h: usize,
+ name: &'static str,
+ at: &ArithmeticTerm,
+ t: usize,
+) -> MachineStub {
let at_stub = at.into_functor();
- let mut stub = functor!(name, 2,
- [heap_cell!(h + 4),
- heap_integer!(Integer::from(t))]);
+ let mut stub = functor!(
+ name,
+ 2,
+ [heap_cell!(h + 4), heap_integer!(Integer::from(t))]
+ );
stub.extend(at_stub.into_iter());
stub
}
-fn arith_instr_bin_functor(h: usize, name: &'static str, at_1: &ArithmeticTerm,
- at_2: &ArithmeticTerm, t: usize)
- -> MachineStub
-{
+fn arith_instr_bin_functor(
+ h: usize,
+ name: &'static str,
+ at_1: &ArithmeticTerm,
+ at_2: &ArithmeticTerm,
+ t: usize,
+) -> MachineStub {
let at_1_stub = at_1.into_functor();
let at_2_stub = at_2.into_functor();
- let mut stub = functor!(name, 3,
- [heap_cell!(h + 4),
- heap_cell!(h + 4 + at_1_stub.len()),
- heap_integer!(Integer::from(t))]);
+ let mut stub = functor!(
+ name,
+ 3,
+ [
+ heap_cell!(h + 4),
+ heap_cell!(h + 4 + at_1_stub.len()),
+ heap_integer!(Integer::from(t))
+ ]
+ );
stub.extend(at_1_stub.into_iter());
stub.extend(at_2_stub.into_iter());
impl ArithmeticInstruction {
pub fn to_functor(&self, h: usize) -> MachineStub {
match self {
- &ArithmeticInstruction::Add(ref at_1, ref at_2, t) =>
- arith_instr_bin_functor(h, "add", at_1, at_2, t),
- &ArithmeticInstruction::Sub(ref at_1, ref at_2, t) =>
- arith_instr_bin_functor(h, "sub", at_1, at_2, t),
- &ArithmeticInstruction::Mul(ref at_1, ref at_2, t) =>
- arith_instr_bin_functor(h, "mul", at_1, at_2, t),
- &ArithmeticInstruction::IntPow(ref at_1, ref at_2, t) =>
- arith_instr_bin_functor(h, "int_pow", at_1, at_2, t),
- &ArithmeticInstruction::Pow(ref at_1, ref at_2, t) =>
- arith_instr_bin_functor(h, "pow", at_1, at_2, t),
- &ArithmeticInstruction::IDiv(ref at_1, ref at_2, t) =>
- arith_instr_bin_functor(h, "idiv", at_1, at_2, t),
- &ArithmeticInstruction::Max(ref at_1, ref at_2, t) =>
- arith_instr_bin_functor(h, "max", at_1, at_2, t),
- &ArithmeticInstruction::Min(ref at_1, ref at_2, t) =>
- arith_instr_bin_functor(h, "min", at_1, at_2, t),
- &ArithmeticInstruction::IntFloorDiv(ref at_1, ref at_2, t) =>
- arith_instr_bin_functor(h, "int_floor_div", at_1, at_2, t),
- &ArithmeticInstruction::RDiv(ref at_1, ref at_2, t) =>
- arith_instr_bin_functor(h, "rdiv", at_1, at_2, t),
- &ArithmeticInstruction::Div(ref at_1, ref at_2, t) =>
- arith_instr_bin_functor(h, "div", at_1, at_2, t),
- &ArithmeticInstruction::Shl(ref at_1, ref at_2, t) =>
- arith_instr_bin_functor(h, "shl", at_1, at_2, t),
- &ArithmeticInstruction::Shr(ref at_1, ref at_2, t) =>
- arith_instr_bin_functor(h, "shr", at_1, at_2, t),
- &ArithmeticInstruction::Xor(ref at_1, ref at_2, t) =>
- arith_instr_bin_functor(h, "xor", at_1, at_2, t),
- &ArithmeticInstruction::And(ref at_1, ref at_2, t) =>
- arith_instr_bin_functor(h, "and", at_1, at_2, t),
- &ArithmeticInstruction::Or(ref at_1, ref at_2, t) =>
- arith_instr_bin_functor(h, "or", at_1, at_2, t),
- &ArithmeticInstruction::Mod(ref at_1, ref at_2, t) =>
- arith_instr_bin_functor(h, "mod", at_1, at_2, t),
- &ArithmeticInstruction::Rem(ref at_1, ref at_2, t) =>
- arith_instr_bin_functor(h, "rem", at_1, at_2, t),
- &ArithmeticInstruction::ATan2(ref at_1, ref at_2, t) =>
- arith_instr_bin_functor(h, "rem", at_1, at_2, t),
- &ArithmeticInstruction::Cos(ref at, t) =>
- arith_instr_unary_functor(h, "cos", at, t),
- &ArithmeticInstruction::Sin(ref at, t) =>
- arith_instr_unary_functor(h, "sin", at, t),
- &ArithmeticInstruction::Tan(ref at, t) =>
- arith_instr_unary_functor(h, "tan", at, t),
- &ArithmeticInstruction::Log(ref at, t) =>
- arith_instr_unary_functor(h, "log", at, t),
- &ArithmeticInstruction::Exp(ref at, t) =>
- arith_instr_unary_functor(h, "exp", at, t),
- &ArithmeticInstruction::ACos(ref at, t) =>
- arith_instr_unary_functor(h, "acos", at, t),
- &ArithmeticInstruction::ASin(ref at, t) =>
- arith_instr_unary_functor(h, "asin", at, t),
- &ArithmeticInstruction::ATan(ref at, t) =>
- arith_instr_unary_functor(h, "atan", at, t),
- &ArithmeticInstruction::Sqrt(ref at, t) =>
- arith_instr_unary_functor(h, "sqrt", at, t),
- &ArithmeticInstruction::Abs(ref at, t) =>
- arith_instr_unary_functor(h, "abs", at, t),
- &ArithmeticInstruction::Float(ref at, t) =>
- arith_instr_unary_functor(h, "float", at, t),
- &ArithmeticInstruction::Truncate(ref at, t) =>
- arith_instr_unary_functor(h, "truncate", at, t),
- &ArithmeticInstruction::Round(ref at, t) =>
- arith_instr_unary_functor(h, "round", at, t),
- &ArithmeticInstruction::Ceiling(ref at, t) =>
- arith_instr_unary_functor(h, "ceiling", at, t),
- &ArithmeticInstruction::Floor(ref at, t) =>
- arith_instr_unary_functor(h, "floor", at, t),
- &ArithmeticInstruction::Neg(ref at, t) =>
- arith_instr_unary_functor(h, "-", at, t),
- &ArithmeticInstruction::Plus(ref at, t) =>
- arith_instr_unary_functor(h, "+", at, t),
- &ArithmeticInstruction::BitwiseComplement(ref at, t) =>
- arith_instr_unary_functor(h, "\\", at, t),
+ &ArithmeticInstruction::Add(ref at_1, ref at_2, t) => {
+ arith_instr_bin_functor(h, "add", at_1, at_2, t)
+ }
+ &ArithmeticInstruction::Sub(ref at_1, ref at_2, t) => {
+ arith_instr_bin_functor(h, "sub", at_1, at_2, t)
+ }
+ &ArithmeticInstruction::Mul(ref at_1, ref at_2, t) => {
+ arith_instr_bin_functor(h, "mul", at_1, at_2, t)
+ }
+ &ArithmeticInstruction::IntPow(ref at_1, ref at_2, t) => {
+ arith_instr_bin_functor(h, "int_pow", at_1, at_2, t)
+ }
+ &ArithmeticInstruction::Pow(ref at_1, ref at_2, t) => {
+ arith_instr_bin_functor(h, "pow", at_1, at_2, t)
+ }
+ &ArithmeticInstruction::IDiv(ref at_1, ref at_2, t) => {
+ arith_instr_bin_functor(h, "idiv", at_1, at_2, t)
+ }
+ &ArithmeticInstruction::Max(ref at_1, ref at_2, t) => {
+ arith_instr_bin_functor(h, "max", at_1, at_2, t)
+ }
+ &ArithmeticInstruction::Min(ref at_1, ref at_2, t) => {
+ arith_instr_bin_functor(h, "min", at_1, at_2, t)
+ }
+ &ArithmeticInstruction::IntFloorDiv(ref at_1, ref at_2, t) => {
+ arith_instr_bin_functor(h, "int_floor_div", at_1, at_2, t)
+ }
+ &ArithmeticInstruction::RDiv(ref at_1, ref at_2, t) => {
+ arith_instr_bin_functor(h, "rdiv", at_1, at_2, t)
+ }
+ &ArithmeticInstruction::Div(ref at_1, ref at_2, t) => {
+ arith_instr_bin_functor(h, "div", at_1, at_2, t)
+ }
+ &ArithmeticInstruction::Shl(ref at_1, ref at_2, t) => {
+ arith_instr_bin_functor(h, "shl", at_1, at_2, t)
+ }
+ &ArithmeticInstruction::Shr(ref at_1, ref at_2, t) => {
+ arith_instr_bin_functor(h, "shr", at_1, at_2, t)
+ }
+ &ArithmeticInstruction::Xor(ref at_1, ref at_2, t) => {
+ arith_instr_bin_functor(h, "xor", at_1, at_2, t)
+ }
+ &ArithmeticInstruction::And(ref at_1, ref at_2, t) => {
+ arith_instr_bin_functor(h, "and", at_1, at_2, t)
+ }
+ &ArithmeticInstruction::Or(ref at_1, ref at_2, t) => {
+ arith_instr_bin_functor(h, "or", at_1, at_2, t)
+ }
+ &ArithmeticInstruction::Mod(ref at_1, ref at_2, t) => {
+ arith_instr_bin_functor(h, "mod", at_1, at_2, t)
+ }
+ &ArithmeticInstruction::Rem(ref at_1, ref at_2, t) => {
+ arith_instr_bin_functor(h, "rem", at_1, at_2, t)
+ }
+ &ArithmeticInstruction::ATan2(ref at_1, ref at_2, t) => {
+ arith_instr_bin_functor(h, "rem", at_1, at_2, t)
+ }
+ &ArithmeticInstruction::Cos(ref at, t) => arith_instr_unary_functor(h, "cos", at, t),
+ &ArithmeticInstruction::Sin(ref at, t) => arith_instr_unary_functor(h, "sin", at, t),
+ &ArithmeticInstruction::Tan(ref at, t) => arith_instr_unary_functor(h, "tan", at, t),
+ &ArithmeticInstruction::Log(ref at, t) => arith_instr_unary_functor(h, "log", at, t),
+ &ArithmeticInstruction::Exp(ref at, t) => arith_instr_unary_functor(h, "exp", at, t),
+ &ArithmeticInstruction::ACos(ref at, t) => arith_instr_unary_functor(h, "acos", at, t),
+ &ArithmeticInstruction::ASin(ref at, t) => arith_instr_unary_functor(h, "asin", at, t),
+ &ArithmeticInstruction::ATan(ref at, t) => arith_instr_unary_functor(h, "atan", at, t),
+ &ArithmeticInstruction::Sqrt(ref at, t) => arith_instr_unary_functor(h, "sqrt", at, t),
+ &ArithmeticInstruction::Abs(ref at, t) => arith_instr_unary_functor(h, "abs", at, t),
+ &ArithmeticInstruction::Float(ref at, t) => {
+ arith_instr_unary_functor(h, "float", at, t)
+ }
+ &ArithmeticInstruction::Truncate(ref at, t) => {
+ arith_instr_unary_functor(h, "truncate", at, t)
+ }
+ &ArithmeticInstruction::Round(ref at, t) => {
+ arith_instr_unary_functor(h, "round", at, t)
+ }
+ &ArithmeticInstruction::Ceiling(ref at, t) => {
+ arith_instr_unary_functor(h, "ceiling", at, t)
+ }
+ &ArithmeticInstruction::Floor(ref at, t) => {
+ arith_instr_unary_functor(h, "floor", at, t)
+ }
+ &ArithmeticInstruction::Neg(ref at, t) => arith_instr_unary_functor(h, "-", at, t),
+ &ArithmeticInstruction::Plus(ref at, t) => arith_instr_unary_functor(h, "+", at, t),
+ &ArithmeticInstruction::BitwiseComplement(ref at, t) => {
+ arith_instr_unary_functor(h, "\\", at, t)
+ }
}
}
}
CallClause(ClauseType, usize, usize, bool, bool),
Deallocate,
JmpBy(usize, usize, usize, bool), // arity, global_offset, perm_vars after threshold, last call.
- Proceed
+ Proceed,
}
impl ControlInstruction {
pub fn is_jump_instr(&self) -> bool {
match self {
- &ControlInstruction::CallClause(..) => true,
+ &ControlInstruction::CallClause(..) => true,
&ControlInstruction::JmpBy(..) => true,
- _ => false
+ _ => false,
}
}
pub fn to_functor(&self) -> MachineStub {
match self {
- &ControlInstruction::Allocate(num_frames) =>
- functor!("allocate", 1, [heap_integer!(Integer::from(num_frames))]),
- &ControlInstruction::CallClause(ref ct, arity, _, false, _) =>
- functor!("call", 2, [heap_con!(Constant::Atom(ct.name(), None)),
- heap_integer!(Integer::from(arity))]),
- &ControlInstruction::CallClause(ref ct, arity, _, true, _) =>
- functor!("execute", 2, [heap_con!(Constant::Atom(ct.name(), None)),
- heap_integer!(Integer::from(arity))]),
- &ControlInstruction::Deallocate =>
- vec![heap_atom!("deallocate")],
- &ControlInstruction::JmpBy(_, offset, ..) =>
- functor!("jmp_by", 1, [heap_integer!(Integer::from(offset))]),
- &ControlInstruction::Proceed =>
- vec![heap_atom!("proceed")]
+ &ControlInstruction::Allocate(num_frames) => {
+ functor!("allocate", 1, [heap_integer!(Integer::from(num_frames))])
+ }
+ &ControlInstruction::CallClause(ref ct, arity, _, false, _) => functor!(
+ "call",
+ 2,
+ [
+ heap_con!(Constant::Atom(ct.name(), None)),
+ heap_integer!(Integer::from(arity))
+ ]
+ ),
+ &ControlInstruction::CallClause(ref ct, arity, _, true, _) => functor!(
+ "execute",
+ 2,
+ [
+ heap_con!(Constant::Atom(ct.name(), None)),
+ heap_integer!(Integer::from(arity))
+ ]
+ ),
+ &ControlInstruction::Deallocate => vec![heap_atom!("deallocate")],
+ &ControlInstruction::JmpBy(_, offset, ..) => {
+ functor!("jmp_by", 1, [heap_integer!(Integer::from(offset))])
+ }
+ &ControlInstruction::Proceed => vec![heap_atom!("proceed")],
}
}
}
pub enum IndexingInstruction {
SwitchOnTerm(usize, usize, usize, usize),
SwitchOnConstant(usize, IndexMap<Constant, usize>),
- SwitchOnStructure(usize, IndexMap<(ClauseName, usize), usize>)
+ SwitchOnStructure(usize, IndexMap<(ClauseName, usize), usize>),
}
impl From<IndexingInstruction> for Line {
impl IndexingInstruction {
pub fn to_functor(&self) -> MachineStub {
match self {
- &IndexingInstruction::SwitchOnTerm(vars, constants, lists, structures) =>
- functor!("switch_on_term", 4,
- [heap_integer!(Integer::from(vars)),
- heap_integer!(Integer::from(constants)),
- heap_integer!(Integer::from(lists)),
- heap_integer!(Integer::from(structures))]),
- &IndexingInstruction::SwitchOnConstant(constants, _) =>
- functor!("switch_on_constant", 1,
- [heap_integer!(Integer::from(constants))]),
- &IndexingInstruction::SwitchOnStructure(structures, _) =>
- functor!("switch_on_structure", 1,
- [heap_integer!(Integer::from(structures))])
+ &IndexingInstruction::SwitchOnTerm(vars, constants, lists, structures) => functor!(
+ "switch_on_term",
+ 4,
+ [
+ heap_integer!(Integer::from(vars)),
+ heap_integer!(Integer::from(constants)),
+ heap_integer!(Integer::from(lists)),
+ heap_integer!(Integer::from(structures))
+ ]
+ ),
+ &IndexingInstruction::SwitchOnConstant(constants, _) => functor!(
+ "switch_on_constant",
+ 1,
+ [heap_integer!(Integer::from(constants))]
+ ),
+ &IndexingInstruction::SwitchOnStructure(structures, _) => functor!(
+ "switch_on_structure",
+ 1,
+ [heap_integer!(Integer::from(structures))]
+ ),
}
}
}
UnifyLocalValue(RegType),
UnifyVariable(RegType),
UnifyValue(RegType),
- UnifyVoid(usize)
+ UnifyVoid(usize),
}
impl FactInstruction {
pub fn to_functor(&self, h: usize) -> MachineStub {
match self {
&FactInstruction::GetConstant(lvl, ref constant, r) => {
- let mut stub = functor!("get_constant", 3,
- [heap_str!(h + 4),
- heap_con!(constant.clone()),
- heap_str!(h + 6)]);
+ let mut stub = functor!(
+ "get_constant",
+ 3,
+ [
+ heap_str!(h + 4),
+ heap_con!(constant.clone()),
+ heap_str!(h + 6)
+ ]
+ );
stub.append(&mut lvl.into_functor());
stub.append(&mut reg_type_into_functor(r));
stub
- },
+ }
&FactInstruction::GetList(lvl, r) => {
- let mut stub = functor!("get_list", 2,
- [heap_str!(h + 3),
- heap_str!(h + 5)]);
+ let mut stub = functor!("get_list", 2, [heap_str!(h + 3), heap_str!(h + 5)]);
stub.append(&mut lvl.into_functor());
stub.append(&mut reg_type_into_functor(r));
stub
- },
+ }
&FactInstruction::GetStructure(ref ct, arity, r) => {
- let mut stub = functor!("get_structure", 3,
- [heap_con!(Constant::Atom(ct.name(), None)),
- heap_integer!(Integer::from(arity)),
- heap_str!(h + 4)]);
+ let mut stub = functor!(
+ "get_structure",
+ 3,
+ [
+ heap_con!(Constant::Atom(ct.name(), None)),
+ heap_integer!(Integer::from(arity)),
+ heap_str!(h + 4)
+ ]
+ );
stub.append(&mut reg_type_into_functor(r));
stub
- },
+ }
&FactInstruction::GetValue(r, arg) => {
- let mut stub = functor!("get_value", 2,
- [heap_str!(h + 3),
- heap_integer!(Integer::from(arg))]);
+ let mut stub = functor!(
+ "get_value",
+ 2,
+ [heap_str!(h + 3), heap_integer!(Integer::from(arg))]
+ );
stub.append(&mut reg_type_into_functor(r));
stub
- },
+ }
&FactInstruction::GetVariable(r, arg) => {
- let mut stub = functor!("get_variable", 2,
- [heap_str!(h + 3),
- heap_integer!(Integer::from(arg))]);
+ let mut stub = functor!(
+ "get_variable",
+ 2,
+ [heap_str!(h + 3), heap_integer!(Integer::from(arg))]
+ );
stub.append(&mut reg_type_into_functor(r));
stub
- },
- &FactInstruction::UnifyConstant(ref constant) =>
- functor!("unify_constant", 1, [heap_con!(constant.clone())]),
+ }
+ &FactInstruction::UnifyConstant(ref constant) => {
+ functor!("unify_constant", 1, [heap_con!(constant.clone())])
+ }
&FactInstruction::UnifyLocalValue(r) => {
let mut stub = functor!("unify_local_value", 1, [heap_str!(h + 2)]);
stub.append(&mut reg_type_into_functor(r));
stub
- },
+ }
&FactInstruction::UnifyVariable(r) => {
let mut stub = functor!("unify_variable", 1, [heap_str!(h + 2)]);
stub.append(&mut reg_type_into_functor(r));
stub
- },
+ }
&FactInstruction::UnifyValue(r) => {
let mut stub = functor!("unify_value", 1, [heap_str!(h + 2)]);
stub.append(&mut reg_type_into_functor(r));
stub
- },
- &FactInstruction::UnifyVoid(vars) =>
+ }
+ &FactInstruction::UnifyVoid(vars) => {
functor!("unify_void", 1, [heap_integer!(Integer::from(vars))])
+ }
}
}
}
SetLocalValue(RegType),
SetVariable(RegType),
SetValue(RegType),
- SetVoid(usize)
+ SetVoid(usize),
}
impl QueryInstruction {
pub fn to_functor(&self, h: usize) -> MachineStub {
match self {
- &QueryInstruction::PutUnsafeValue(norm, arg) =>
- functor!("put_unsafe_value", 2,
- [heap_integer!(Integer::from(norm)),
- heap_integer!(Integer::from(arg))]),
+ &QueryInstruction::PutUnsafeValue(norm, arg) => functor!(
+ "put_unsafe_value",
+ 2,
+ [
+ heap_integer!(Integer::from(norm)),
+ heap_integer!(Integer::from(arg))
+ ]
+ ),
&QueryInstruction::PutConstant(lvl, ref constant, r) => {
- let mut stub = functor!("put_constant", 3,
- [heap_str!(h + 4),
- heap_con!(constant.clone()),
- heap_str!(h + 6)]);
+ let mut stub = functor!(
+ "put_constant",
+ 3,
+ [
+ heap_str!(h + 4),
+ heap_con!(constant.clone()),
+ heap_str!(h + 6)
+ ]
+ );
stub.append(&mut lvl.into_functor());
stub.append(&mut reg_type_into_functor(r));
stub
- },
+ }
&QueryInstruction::PutList(lvl, r) => {
- let mut stub = functor!("put_list", 2,
- [heap_str!(h + 3),
- heap_str!(h + 5)]);
+ let mut stub = functor!("put_list", 2, [heap_str!(h + 3), heap_str!(h + 5)]);
stub.append(&mut lvl.into_functor());
stub.append(&mut reg_type_into_functor(r));
stub
- },
+ }
&QueryInstruction::PutStructure(ref ct, arity, r) => {
- let mut stub = functor!("put_structure", 3,
- [heap_con!(Constant::Atom(ct.name(), None)),
- heap_integer!(Integer::from(arity)),
- heap_str!(h + 4)]);
+ let mut stub = functor!(
+ "put_structure",
+ 3,
+ [
+ heap_con!(Constant::Atom(ct.name(), None)),
+ heap_integer!(Integer::from(arity)),
+ heap_str!(h + 4)
+ ]
+ );
stub.append(&mut reg_type_into_functor(r));
stub
- },
+ }
&QueryInstruction::PutValue(r, arg) => {
- let mut stub = functor!("put_value", 2,
- [heap_str!(h + 3),
- heap_integer!(Integer::from(arg))]);
+ let mut stub = functor!(
+ "put_value",
+ 2,
+ [heap_str!(h + 3), heap_integer!(Integer::from(arg))]
+ );
stub.append(&mut reg_type_into_functor(r));
stub
- },
+ }
&QueryInstruction::GetVariable(r, arg) => {
- let mut stub = functor!("get_variable", 2,
- [heap_str!(h + 3),
- heap_integer!(Integer::from(arg))]);
+ let mut stub = functor!(
+ "get_variable",
+ 2,
+ [heap_str!(h + 3), heap_integer!(Integer::from(arg))]
+ );
stub.append(&mut reg_type_into_functor(r));
stub
- },
+ }
&QueryInstruction::PutVariable(r, arg) => {
- let mut stub = functor!("put_variable", 2,
- [heap_str!(h + 3),
- heap_integer!(Integer::from(arg))]);
+ let mut stub = functor!(
+ "put_variable",
+ 2,
+ [heap_str!(h + 3), heap_integer!(Integer::from(arg))]
+ );
stub.append(&mut reg_type_into_functor(r));
stub
- },
- &QueryInstruction::SetConstant(ref constant) =>
- functor!("set_constant", 1, [heap_con!(constant.clone())]),
+ }
+ &QueryInstruction::SetConstant(ref constant) => {
+ functor!("set_constant", 1, [heap_con!(constant.clone())])
+ }
&QueryInstruction::SetLocalValue(r) => {
let mut stub = functor!("set_local_value", 1, [heap_str!(h + 2)]);
stub.append(&mut reg_type_into_functor(r));
stub
- },
+ }
&QueryInstruction::SetVariable(r) => {
let mut stub = functor!("set_variable", 1, [heap_str!(h + 2)]);
stub.append(&mut reg_type_into_functor(r));
stub
- },
+ }
&QueryInstruction::SetValue(r) => {
let mut stub = functor!("set_value", 1, [heap_str!(h + 2)]);
stub.append(&mut reg_type_into_functor(r));
stub
- },
- &QueryInstruction::SetVoid(vars) =>
+ }
+ &QueryInstruction::SetVoid(vars) => {
functor!("set_void", 1, [heap_integer!(Integer::from(vars))])
+ }
}
}
}
Cons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
Constant(Level, &'a Cell<RegType>, &'a Constant),
Clause(Level, &'a Cell<RegType>, ClauseType, &'a Vec<Box<Term>>),
- Var(Level, &'a Cell<VarReg>, Rc<Var>)
+ Var(Level, &'a Cell<VarReg>, Rc<Var>),
}
impl<'a> TermRef<'a> {
pub fn level(self) -> Level {
match self {
TermRef::AnonVar(lvl)
- | TermRef::Cons(lvl, ..)
- | TermRef::Constant(lvl, ..)
- | TermRef::Var(lvl, ..)
- | TermRef::Clause(lvl, ..) => lvl
+ | TermRef::Cons(lvl, ..)
+ | TermRef::Constant(lvl, ..)
+ | TermRef::Var(lvl, ..)
+ | TermRef::Clause(lvl, ..) => lvl,
}
}
}
pub enum TermIterState<'a> {
AnonVar(Level),
Constant(Level, &'a Cell<RegType>, &'a Constant),
- Clause(Level, usize, &'a Cell<RegType>, ClauseType, &'a Vec<Box<Term>>),
+ Clause(
+ Level,
+ usize,
+ &'a Cell<RegType>,
+ ClauseType,
+ &'a Vec<Box<Term>>,
+ ),
InitialCons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
FinalCons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
- Var(Level, &'a Cell<VarReg>, Rc<Var>)
+ Var(Level, &'a Cell<VarReg>, Rc<Var>),
}
impl<'a> TermIterState<'a> {
pub fn subterm_to_state(lvl: Level, term: &'a Term) -> TermIterState<'a> {
match term {
- &Term::AnonVar =>
- TermIterState::AnonVar(lvl),
+ &Term::AnonVar => TermIterState::AnonVar(lvl),
&Term::Clause(ref cell, ref name, ref subterms, ref spec) => {
let ct = if let Some(spec) = spec {
ClauseType::Op(name.clone(), spec.clone(), CodeIndex::default())
};
TermIterState::Clause(lvl, 0, cell, ct, subterms)
- },
- &Term::Cons(ref cell, ref head, ref tail) =>
- TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref()),
- &Term::Constant(ref cell, ref constant) =>
- TermIterState::Constant(lvl, cell, constant),
- &Term::Var(ref cell, ref var) =>
- TermIterState::Var(lvl, cell, var.clone())
+ }
+ &Term::Cons(ref cell, ref head, ref tail) => {
+ TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref())
+ }
+ &Term::Constant(ref cell, ref constant) => TermIterState::Constant(lvl, cell, constant),
+ &Term::Var(ref cell, ref var) => TermIterState::Var(lvl, cell, var.clone()),
}
}
}
impl<'a> QueryIterator<'a> {
fn push_subterm(&mut self, lvl: Level, term: &'a Term) {
- self.state_stack.push(TermIterState::subterm_to_state(lvl, term));
+ self.state_stack
+ .push(TermIterState::subterm_to_state(lvl, term));
}
fn from_rule_head_clause(terms: &'a Vec<Box<Term>>) -> Self {
- let state_stack = terms.iter().rev()
+ let state_stack = terms
+ .iter()
+ .rev()
.map(|bt| TermIterState::subterm_to_state(Level::Shallow, bt.as_ref()))
.collect();
fn from_term(term: &'a Term) -> Self {
let state = match term {
- &Term::AnonVar =>
- return QueryIterator { state_stack: vec![] },
- &Term::Clause(ref r, ref name, ref terms, ref fixity) =>
- TermIterState::Clause(Level::Root, 0, r,
- ClauseType::from(name.clone(), terms.len(), fixity.clone()),
- terms),
- &Term::Cons(..) =>
- return QueryIterator { state_stack: vec![] },
- &Term::Constant(_, _) =>
- return QueryIterator { state_stack: vec![] },
- &Term::Var(ref cell, ref var) =>
- TermIterState::Var(Level::Root, cell, (*var).clone())
+ &Term::AnonVar => {
+ return QueryIterator {
+ state_stack: vec![],
+ }
+ }
+ &Term::Clause(ref r, ref name, ref terms, ref fixity) => TermIterState::Clause(
+ Level::Root,
+ 0,
+ r,
+ ClauseType::from(name.clone(), terms.len(), fixity.clone()),
+ terms,
+ ),
+ &Term::Cons(..) => {
+ return QueryIterator {
+ state_stack: vec![],
+ }
+ }
+ &Term::Constant(_, _) => {
+ return QueryIterator {
+ state_stack: vec![],
+ }
+ }
+ &Term::Var(ref cell, ref var) => TermIterState::Var(Level::Root, cell, (*var).clone()),
};
- QueryIterator { state_stack: vec![state] }
+ QueryIterator {
+ state_stack: vec![state],
+ }
}
fn new(term: &'a QueryTerm) -> Self {
- match term {
+ match term {
&QueryTerm::Clause(ref cell, ClauseType::CallN, ref terms, _) => {
let state = TermIterState::Clause(Level::Root, 1, cell, ClauseType::CallN, terms);
- QueryIterator { state_stack: vec![state] }
- },
+ QueryIterator {
+ state_stack: vec![state],
+ }
+ }
&QueryTerm::Clause(ref cell, ref ct, ref terms, _) => {
let state = TermIterState::Clause(Level::Root, 0, cell, ct.clone(), terms);
- QueryIterator { state_stack: vec![state] }
- },
+ QueryIterator {
+ state_stack: vec![state],
+ }
+ }
&QueryTerm::UnblockedCut(ref cell) => {
let state = TermIterState::Var(Level::Root, cell, rc_atom!("!"));
- QueryIterator { state_stack: vec![state] }
- },
+ QueryIterator {
+ state_stack: vec![state],
+ }
+ }
&QueryTerm::GetLevelAndUnify(ref cell, ref var) => {
let state = TermIterState::Var(Level::Root, cell, var.clone());
- QueryIterator { state_stack: vec![state] }
- },
+ QueryIterator {
+ state_stack: vec![state],
+ }
+ }
&QueryTerm::Jump(ref vars) => {
- let state_stack = vars.iter().rev().map(|t| {
- TermIterState::subterm_to_state(Level::Shallow, t)
- }).collect();
+ let state_stack = vars
+ .iter()
+ .rev()
+ .map(|t| TermIterState::subterm_to_state(Level::Shallow, t))
+ .collect();
QueryIterator { state_stack }
- },
- &QueryTerm::BlockedCut =>
- QueryIterator { state_stack: vec![] },
+ }
+ &QueryTerm::BlockedCut => QueryIterator {
+ state_stack: vec![],
+ },
}
}
}
fn next(&mut self) -> Option<Self::Item> {
while let Some(iter_state) = self.state_stack.pop() {
match iter_state {
- TermIterState::AnonVar(lvl) =>
- return Some(TermRef::AnonVar(lvl)),
+ TermIterState::AnonVar(lvl) => return Some(TermRef::AnonVar(lvl)),
TermIterState::Clause(lvl, child_num, cell, ct, child_terms) => {
if child_num == child_terms.len() {
match ct {
- ClauseType::CallN =>
- self.push_subterm(Level::Shallow, child_terms[0].as_ref()),
- ClauseType::Named(..) | ClauseType::Op(..) =>
+ ClauseType::CallN => {
+ self.push_subterm(Level::Shallow, child_terms[0].as_ref())
+ }
+ ClauseType::Named(..) | ClauseType::Op(..) => {
return match lvl {
Level::Root => None,
- lvl => Some(TermRef::Clause(lvl, cell, ct, child_terms))
- },
- _ =>
- return None
+ lvl => Some(TermRef::Clause(lvl, cell, ct, child_terms)),
+ }
+ }
+ _ => return None,
};
} else {
- self.state_stack.push(TermIterState::Clause(lvl, child_num + 1,
- cell, ct, child_terms));
+ self.state_stack.push(TermIterState::Clause(
+ lvl,
+ child_num + 1,
+ cell,
+ ct,
+ child_terms,
+ ));
self.push_subterm(lvl.child_level(), child_terms[child_num].as_ref());
}
- },
+ }
TermIterState::InitialCons(lvl, cell, head, tail) => {
- self.state_stack.push(TermIterState::FinalCons(lvl, cell, head, tail));
+ self.state_stack
+ .push(TermIterState::FinalCons(lvl, cell, head, tail));
self.push_subterm(lvl.child_level(), tail);
self.push_subterm(lvl.child_level(), head);
- },
- TermIterState::FinalCons(lvl, cell, head, tail) =>
- return Some(TermRef::Cons(lvl, cell, head, tail)),
- TermIterState::Constant(lvl, cell, constant) =>
- return Some(TermRef::Constant(lvl, cell, constant)),
- TermIterState::Var(lvl, cell, var) =>
- return Some(TermRef::Var(lvl, cell, var))
+ }
+ TermIterState::FinalCons(lvl, cell, head, tail) => {
+ return Some(TermRef::Cons(lvl, cell, head, tail))
+ }
+ TermIterState::Constant(lvl, cell, constant) => {
+ return Some(TermRef::Constant(lvl, cell, constant))
+ }
+ TermIterState::Var(lvl, cell, var) => return Some(TermRef::Var(lvl, cell, var)),
};
}
pub struct FactIterator<'a> {
state_queue: VecDeque<TermIterState<'a>>,
- iterable_root: bool
+ iterable_root: bool,
}
impl<'a> FactIterator<'a> {
fn push_subterm(&mut self, lvl: Level, term: &'a Term) {
- self.state_queue.push_back(TermIterState::subterm_to_state(lvl, term));
+ self.state_queue
+ .push_back(TermIterState::subterm_to_state(lvl, term));
}
pub fn from_rule_head_clause(terms: &'a Vec<Box<Term>>) -> Self {
- let state_queue = terms.iter()
+ let state_queue = terms
+ .iter()
.map(|bt| TermIterState::subterm_to_state(Level::Shallow, bt.as_ref()))
.collect();
- FactIterator { state_queue, iterable_root: false }
+ FactIterator {
+ state_queue,
+ iterable_root: false,
+ }
}
fn new(term: &'a Term, iterable_root: bool) -> Self {
let states = match term {
- &Term::AnonVar =>
- vec![TermIterState::AnonVar(Level::Root)],
+ &Term::AnonVar => vec![TermIterState::AnonVar(Level::Root)],
&Term::Clause(ref cell, ref name, ref terms, ref fixity) => {
let ct = ClauseType::from(name.clone(), terms.len(), fixity.clone());
vec![TermIterState::Clause(Level::Root, 0, cell, ct, terms)]
- },
- &Term::Cons(ref cell, ref head, ref tail) =>
- vec![TermIterState::InitialCons(Level::Root, cell, head.as_ref(), tail.as_ref())],
- &Term::Constant(ref cell, ref constant) =>
- vec![TermIterState::Constant(Level::Root, cell, constant)],
- &Term::Var(ref cell, ref var) =>
+ }
+ &Term::Cons(ref cell, ref head, ref tail) => vec![TermIterState::InitialCons(
+ Level::Root,
+ cell,
+ head.as_ref(),
+ tail.as_ref(),
+ )],
+ &Term::Constant(ref cell, ref constant) => {
+ vec![TermIterState::Constant(Level::Root, cell, constant)]
+ }
+ &Term::Var(ref cell, ref var) => {
vec![TermIterState::Var(Level::Root, cell, var.clone())]
+ }
};
- FactIterator { state_queue: VecDeque::from(states), iterable_root }
+ FactIterator {
+ state_queue: VecDeque::from(states),
+ iterable_root,
+ }
}
}
fn next(&mut self) -> Option<Self::Item> {
while let Some(state) = self.state_queue.pop_front() {
match state {
- TermIterState::AnonVar(lvl) =>
- return Some(TermRef::AnonVar(lvl)),
+ TermIterState::AnonVar(lvl) => return Some(TermRef::AnonVar(lvl)),
TermIterState::Clause(lvl, _, cell, ct, child_terms) => {
for child_term in child_terms {
self.push_subterm(lvl.child_level(), child_term);
match lvl {
Level::Root if !self.iterable_root => continue,
- _ => return Some(TermRef::Clause(lvl, cell, ct, child_terms))
+ _ => return Some(TermRef::Clause(lvl, cell, ct, child_terms)),
};
- },
+ }
TermIterState::InitialCons(lvl, cell, head, tail) => {
self.push_subterm(Level::Deep, head);
self.push_subterm(Level::Deep, tail);
return Some(TermRef::Cons(lvl, cell, head, tail));
- },
- TermIterState::Constant(lvl, cell, constant) =>
- return Some(TermRef::Constant(lvl, cell, constant)),
- TermIterState::Var(lvl, cell, var) =>
- return Some(TermRef::Var(lvl, cell, var)),
+ }
+ TermIterState::Constant(lvl, cell, constant) => {
+ return Some(TermRef::Constant(lvl, cell, constant))
+ }
+ TermIterState::Var(lvl, cell, var) => return Some(TermRef::Var(lvl, cell, var)),
_ => {}
}
}
pub enum ChunkedTerm<'a> {
HeadClause(ClauseName, &'a Vec<Box<Term>>),
- BodyTerm(&'a QueryTerm)
+ BodyTerm(&'a QueryTerm),
}
pub fn query_term_post_order_iter<'a>(query_term: &'a QueryTerm) -> QueryIterator<'a> {
impl<'a> ChunkedTerm<'a> {
pub fn post_order_iter(&self) -> QueryIterator<'a> {
match self {
- &ChunkedTerm::BodyTerm(ref qt) =>
- QueryIterator::new(qt),
- &ChunkedTerm::HeadClause(_, terms) =>
- QueryIterator::from_rule_head_clause(terms)
+ &ChunkedTerm::BodyTerm(ref qt) => QueryIterator::new(qt),
+ &ChunkedTerm::HeadClause(_, terms) => QueryIterator::from_rule_head_clause(terms),
}
}
}
-fn contains_cut_var<'a, Iter: Iterator<Item=&'a Term>>(terms: Iter) -> bool {
+fn contains_cut_var<'a, Iter: Iterator<Item = &'a Term>>(terms: Iter) -> bool {
for term in terms {
if let &Term::Var(_, ref var) = term {
if var.as_str() == "!" {
false
}
-pub struct ChunkedIterator<'a>
-{
+pub struct ChunkedIterator<'a> {
pub chunk_num: usize,
- iter: Box<Iterator<Item=ChunkedTerm<'a>> + 'a>,
+ iter: Box<Iterator<Item = ChunkedTerm<'a>> + 'a>,
deep_cut_encountered: bool,
- cut_var_in_head: bool
+ cut_var_in_head: bool,
}
-type ChunkedIteratorItem<'a> = (usize, usize, Vec<ChunkedTerm<'a>>);
+type ChunkedIteratorItem<'a> = (usize, usize, Vec<ChunkedTerm<'a>>);
type RuleBodyIteratorItem<'a> = (usize, usize, Vec<&'a QueryTerm>);
-impl<'a> ChunkedIterator<'a>
-{
- pub fn rule_body_iter(self) -> Box<Iterator<Item=RuleBodyIteratorItem<'a>> + 'a>
- {
+impl<'a> ChunkedIterator<'a> {
+ pub fn rule_body_iter(self) -> Box<Iterator<Item = RuleBodyIteratorItem<'a>> + 'a> {
Box::new(self.filter_map(|(cn, lt_arity, terms)| {
- let filtered_terms: Vec<_> = terms.into_iter().filter_map(|ct| {
- match ct {
- ChunkedTerm::BodyTerm(qt) => Some(qt),
- _ => None
- }
- }).collect();
+ let filtered_terms: Vec<_> = terms
+ .into_iter()
+ .filter_map(|ct| match ct {
+ ChunkedTerm::BodyTerm(qt) => Some(qt),
+ _ => None,
+ })
+ .collect();
if filtered_terms.is_empty() {
None
}))
}
- pub fn from_term_sequence(terms: &'a [QueryTerm]) -> Self
- {
+ pub fn from_term_sequence(terms: &'a [QueryTerm]) -> Self {
ChunkedIterator {
chunk_num: 0,
iter: Box::new(terms.iter().map(|t| ChunkedTerm::BodyTerm(t))),
deep_cut_encountered: false,
- cut_var_in_head: false
+ cut_var_in_head: false,
}
}
- pub fn from_rule_body(p1: &'a QueryTerm, clauses: &'a Vec<QueryTerm>) -> Self
- {
+ pub fn from_rule_body(p1: &'a QueryTerm, clauses: &'a Vec<QueryTerm>) -> Self {
let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1)));
let iter = inner_iter.chain(clauses.iter().map(|t| ChunkedTerm::BodyTerm(t)));
chunk_num: 0,
iter: Box::new(iter),
deep_cut_encountered: false,
- cut_var_in_head: false
+ cut_var_in_head: false,
}
}
- pub fn from_rule(rule: &'a Rule) -> Self
- {
- let &Rule { head: (ref name, ref args, ref p1), ref clauses } = rule;
+ pub fn from_rule(rule: &'a Rule) -> Self {
+ let &Rule {
+ head: (ref name, ref args, ref p1),
+ ref clauses,
+ } = rule;
let iter = once(ChunkedTerm::HeadClause(name.clone(), args));
let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1)));
chunk_num: 0,
iter: Box::new(iter),
deep_cut_encountered: false,
- cut_var_in_head: false
+ cut_var_in_head: false,
}
}
self.deep_cut_encountered
}
- fn take_chunk(&mut self, term: ChunkedTerm<'a>) -> (usize, usize, Vec<ChunkedTerm<'a>>)
- {
- let mut arity = 0;
- let mut item = Some(term);
+ fn take_chunk(&mut self, term: ChunkedTerm<'a>) -> (usize, usize, Vec<ChunkedTerm<'a>>) {
+ let mut arity = 0;
+ let mut item = Some(term);
let mut result = Vec::new();
while let Some(term) = item {
}
result.push(term);
- },
+ }
ChunkedTerm::BodyTerm(&QueryTerm::Jump(ref vars)) => {
result.push(term);
arity = vars.len();
}
break;
- },
+ }
ChunkedTerm::BodyTerm(&QueryTerm::BlockedCut) => {
result.push(term);
if self.chunk_num > 0 {
self.deep_cut_encountered = true;
}
- },
+ }
ChunkedTerm::BodyTerm(&QueryTerm::GetLevelAndUnify(..)) => {
self.deep_cut_encountered = true;
-
+
result.push(term);
arity = 1;
break;
- },
- ChunkedTerm::BodyTerm(&QueryTerm::UnblockedCut(..)) =>
- result.push(term),
- ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::Inlined(_), ..)) =>
- result.push(term),
- ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::CallN, ref subterms, _)) => {
+ }
+ ChunkedTerm::BodyTerm(&QueryTerm::UnblockedCut(..)) => result.push(term),
+ ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::Inlined(_), ..)) => {
+ result.push(term)
+ }
+ ChunkedTerm::BodyTerm(&QueryTerm::Clause(
+ _,
+ ClauseType::CallN,
+ ref subterms,
+ _,
+ )) => {
result.push(term);
arity = subterms.len() + 1;
break;
- },
+ }
ChunkedTerm::BodyTerm(qt) => {
result.push(term);
arity = qt.arity();
}
}
-impl<'a> Iterator for ChunkedIterator<'a>
-{
+impl<'a> Iterator for ChunkedIterator<'a> {
// the chunk number, last term arity, and vector of references.
type Item = ChunkedIteratorItem<'a>;
pub e: usize,
pub cp: LocalCodePtr,
pub interrupt_cp: LocalCodePtr,
- perms: Vec<Addr>
+ perms: Vec<Addr>,
}
impl Frame {
e: e,
cp: cp,
interrupt_cp: LocalCodePtr::default(),
- perms: (1 .. n+1).map(|i| Addr::StackCell(fr, i)).collect()
+ perms: (1..n + 1).map(|i| Addr::StackCell(fr, i)).collect(),
}
}
pub(crate) fn take(&mut self) -> Self {
AndStack(mem::replace(&mut self.0, vec![]))
}
-
+
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));
if len < n {
self[fr].perms.reserve(n - len);
- for i in len .. n {
+ for i in len..n {
self[fr].perms.push(Addr::StackCell(fr, i));
}
}
use std::vec::IntoIter;
-pub static VERIFY_ATTRS: &str = include_str!("attributed_variables.pl");
+pub static VERIFY_ATTRS: &str = include_str!("attributed_variables.pl");
pub static PROJECT_ATTRS: &str = include_str!("project_attributes.pl");
pub(super) type Bindings = Vec<(usize, Addr)>;
bindings: vec![],
cp: LocalCodePtr::default(),
verify_attrs_loc,
- project_attrs_loc
+ project_attrs_loc,
}
}
}
impl MachineState {
- pub(super) fn push_attr_var_binding(&mut self, h: usize, addr: Addr)
- {
+ pub(super) fn push_attr_var_binding(&mut self, h: usize, addr: Addr) {
if self.attr_var_init.bindings.is_empty() {
self.attr_var_init.cp = self.p.local();
self.p = CodePtr::VerifyAttrInterrupt(self.attr_var_init.verify_attrs_loc);
}
fn populate_var_and_value_lists(&mut self) -> (Addr, Addr) {
- let iter = self.attr_var_init.bindings.iter().map(|(ref h, _)| Addr::AttrVar(*h));
+ let iter = self
+ .attr_var_init
+ .bindings
+ .iter()
+ .map(|(ref h, _)| Addr::AttrVar(*h));
let var_list_addr = Addr::HeapCell(self.heap.to_list(iter));
- let iter = self.attr_var_init.bindings.iter().map(|(_, ref addr)| addr.clone());
+ let iter = self
+ .attr_var_init
+ .bindings
+ .iter()
+ .map(|(_, ref addr)| addr.clone());
let value_list_addr = Addr::HeapCell(self.heap.to_list(iter));
(var_list_addr, value_list_addr)
}
- fn verify_attributes(&mut self)
- {
+ fn verify_attributes(&mut self) {
for (h, _) in &self.attr_var_init.bindings {
self.heap[*h] = HeapCellValue::Addr(Addr::AttrVar(*h));
}
self[temp_v!(2)] = value_list_addr;
}
- pub(super)
- fn gather_attr_vars_created_since(&self, b: usize) -> IntoIter<Addr>
- {
- let mut attr_vars: Vec<_> = self.attr_var_init.attr_var_queue[b ..]
- .iter().filter_map(|h|
- match self.store(self.deref(Addr::HeapCell(*h))) {
- Addr::AttrVar(h) => Some(Addr::AttrVar(h)),
- _ => None
- }).collect();
+ pub(super) fn gather_attr_vars_created_since(&self, b: usize) -> IntoIter<Addr> {
+ let mut attr_vars: Vec<_> = self.attr_var_init.attr_var_queue[b..]
+ .iter()
+ .filter_map(|h| match self.store(self.deref(Addr::HeapCell(*h))) {
+ Addr::AttrVar(h) => Some(Addr::AttrVar(h)),
+ _ => None,
+ })
+ .collect();
attr_vars.sort_unstable_by(|a1, a2| self.compare_term_test(a1, a2));
attr_vars.into_iter()
}
- fn populate_project_attr_lists(&mut self) -> (Addr, Addr)
- {
+ fn populate_project_attr_lists(&mut self) -> (Addr, Addr) {
let mut query_vars = IndexSet::new();
let attr_vars = self.gather_attr_vars_created_since(0);
match value {
HeapCellValue::Addr(Addr::HeapCell(h)) => {
query_vars.insert(Addr::HeapCell(h));
- },
+ }
HeapCellValue::Addr(Addr::StackCell(fr, sc)) => {
query_vars.insert(Addr::StackCell(fr, sc));
- },
+ }
_ => {}
};
}
}
let query_var_list = Addr::HeapCell(self.heap.to_list(query_vars.into_iter()));
- let attr_var_list = Addr::HeapCell(self.heap.to_list(attr_vars));
+ let attr_var_list = Addr::HeapCell(self.heap.to_list(attr_vars));
(query_var_list, attr_var_list)
}
- pub(super)
- fn verify_attr_interrupt(&mut self, p: usize) {
+ pub(super) fn verify_attr_interrupt(&mut self, p: usize) {
let rs = MAX_ARITY;
// store temp vars in perm vars slots along with self.b0 and
let e = self.e;
self.and_stack[e].interrupt_cp = self.attr_var_init.cp;
- for i in 1 .. rs + 1 {
+ for i in 1..rs + 1 {
self.and_stack[e][i] = self[RegType::Temp(i)].clone();
}
self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
}
- fn print_attribute_goals_string(&mut self, op_dir: &OpDir) -> String
- {
+ fn print_attribute_goals_string(&mut self, op_dir: &OpDir) -> String {
let mut attr_goals = mem::replace(&mut self.attr_var_init.attribute_goals, vec![]);
if attr_goals.is_empty() {
}
impl Machine {
- pub
- fn attribute_goals(&mut self) -> String
- {
+ pub fn attribute_goals(&mut self) -> String {
let p = self.machine_st.attr_var_init.project_attrs_loc;
let (query_vars, attr_vars) = self.machine_st.populate_project_attr_lists();
self.machine_st[temp_v!(2)] = attr_vars;
self.machine_st.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
- self.machine_st.query_stepper(&mut self.indices, &mut self.policies, &mut self.code_repo,
- &mut readline::input_stream());
-
- self.machine_st.print_attribute_goals_string(&self.indices.op_dir)
+ self.machine_st.query_stepper(
+ &mut self.indices,
+ &mut self.policies,
+ &mut self.code_repo,
+ &mut readline::input_stream(),
+ );
+
+ self.machine_st
+ .print_attribute_goals_string(&self.indices.op_dir)
}
}
pub(super) term_expanders: Code,
pub(super) code: Code,
pub(super) in_situ_code: Code,
- pub(super) term_dir: TermDir
+ pub(super) term_dir: TermDir,
}
impl CodeRepo {
term_expanders: Code::new(),
code: Code::new(),
in_situ_code: Code::new(),
- term_dir: TermDir::new()
+ term_dir: TermDir::new(),
}
}
-
+
#[inline]
pub fn term_dir_entry_len(&self, key: PredicateKey) -> (usize, usize) {
- self.term_dir.get(&key)
+ self.term_dir
+ .get(&key)
.map(|entry| ((entry.0).0.len(), entry.1.len()))
- .unwrap_or((0,0))
+ .unwrap_or((0, 0))
}
#[inline]
- pub fn truncate_terms(&mut self, key: PredicateKey, len: usize, queue_len: usize)
- -> (Predicate, VecDeque<TopLevel>)
- {
- self.term_dir.get_mut(&key)
- .map(|entry| (Predicate((entry.0).0.drain(len ..).collect()),
- entry.1.drain(queue_len ..).collect()))
+ pub fn truncate_terms(
+ &mut self,
+ key: PredicateKey,
+ len: usize,
+ queue_len: usize,
+ ) -> (Predicate, VecDeque<TopLevel>) {
+ self.term_dir
+ .get_mut(&key)
+ .map(|entry| {
+ (
+ Predicate((entry.0).0.drain(len..).collect()),
+ entry.1.drain(queue_len..).collect(),
+ )
+ })
.unwrap_or((Predicate::new(), VecDeque::from(vec![])))
}
- pub fn add_in_situ_result(&mut self, result: &CompiledResult, in_situ_code_dir: &mut InSituCodeDir,
- flags: MachineFlags)
- -> Result<(), SessionError>
- {
+ pub fn add_in_situ_result(
+ &mut self,
+ result: &CompiledResult,
+ in_situ_code_dir: &mut InSituCodeDir,
+ flags: MachineFlags,
+ ) -> Result<(), SessionError> {
let (ref decl, ref queue) = result;
- let (name, arity) = decl.0.first().and_then(|cl| {
- let arity = cl.arity();
- cl.name().map(|name| (name, arity))
- }).ok_or(SessionError::NamelessEntry)?;
+ let (name, arity) = decl
+ .0
+ .first()
+ .and_then(|cl| {
+ let arity = cl.arity();
+ cl.name().map(|name| (name, arity))
+ })
+ .ok_or(SessionError::NamelessEntry)?;
let p = self.in_situ_code.len();
in_situ_code_dir.insert((name, arity), p);
}
#[inline]
- pub(super)
- fn size_of_cached_query(&self) -> usize {
+ pub(super) fn size_of_cached_query(&self) -> usize {
self.cached_query.len()
}
- pub(super)
- fn lookup_instr<'a>(&'a self, last_call: bool, p: &CodePtr) -> Option<RefOrOwned<'a, Line>>
- {
+ pub(super) fn lookup_instr<'a>(
+ &'a self,
+ last_call: bool,
+ p: &CodePtr,
+ ) -> Option<RefOrOwned<'a, Line>> {
match p {
- &CodePtr::Local(LocalCodePtr::UserGoalExpansion(p)) =>
+ &CodePtr::Local(LocalCodePtr::UserGoalExpansion(p)) => {
if p < self.goal_expanders.len() {
Some(RefOrOwned::Borrowed(&self.goal_expanders[p]))
} else {
None
- },
- &CodePtr::Local(LocalCodePtr::UserTermExpansion(p)) =>
+ }
+ }
+ &CodePtr::Local(LocalCodePtr::UserTermExpansion(p)) => {
if p < self.term_expanders.len() {
Some(RefOrOwned::Borrowed(&self.term_expanders[p]))
} else {
None
- },
- &CodePtr::Local(LocalCodePtr::TopLevel(_, p)) =>
+ }
+ }
+ &CodePtr::Local(LocalCodePtr::TopLevel(_, p)) => {
if p < self.cached_query.len() {
Some(RefOrOwned::Borrowed(&self.cached_query[p]))
} else {
None
- },
- &CodePtr::Local(LocalCodePtr::InSituDirEntry(p)) =>
- Some(RefOrOwned::Borrowed(&self.in_situ_code[p])),
- &CodePtr::Local(LocalCodePtr::DirEntry(p)) =>
- Some(RefOrOwned::Borrowed(&self.code[p])),
- &CodePtr::REPL(..) =>
- None,
+ }
+ }
+ &CodePtr::Local(LocalCodePtr::InSituDirEntry(p)) => {
+ Some(RefOrOwned::Borrowed(&self.in_situ_code[p]))
+ }
+ &CodePtr::Local(LocalCodePtr::DirEntry(p)) => Some(RefOrOwned::Borrowed(&self.code[p])),
+ &CodePtr::REPL(..) => None,
&CodePtr::BuiltInClause(ref built_in, _) => {
- let call_clause = call_clause!(ClauseType::BuiltIn(built_in.clone()),
- built_in.arity(),
- 0, last_call);
+ let call_clause = call_clause!(
+ ClauseType::BuiltIn(built_in.clone()),
+ built_in.arity(),
+ 0,
+ last_call
+ );
Some(RefOrOwned::Owned(call_clause))
- },
+ }
&CodePtr::CallN(arity, _) => {
let call_clause = call_clause!(ClauseType::CallN, arity, 0, last_call);
Some(RefOrOwned::Owned(call_clause))
- },
- &CodePtr::VerifyAttrInterrupt(p) =>
- Some(RefOrOwned::Borrowed(&self.code[p])),
- &CodePtr::DynamicTransaction(..) =>
- None
+ }
+ &CodePtr::VerifyAttrInterrupt(p) => Some(RefOrOwned::Borrowed(&self.code[p])),
+ &CodePtr::DynamicTransaction(..) => None,
}
}
}
use prolog_parser::parser::get_desc;
use prolog_parser::tabled_rc::TabledData;
-use prolog::instructions::*;
use prolog::codegen::*;
use prolog::debray_allocator::*;
use prolog::forms::*;
-use prolog::machine::*;
+use prolog::instructions::*;
use prolog::machine::machine_errors::*;
use prolog::machine::machine_indices::*;
-use prolog::machine::term_expansion::{ExpansionAdditionResult};
+use prolog::machine::term_expansion::ExpansionAdditionResult;
use prolog::machine::toplevel::*;
+use prolog::machine::*;
use indexmap::{IndexMap, IndexSet};
fn print_code(code: &Code) {
for clause in code {
match clause {
- &Line::Arithmetic(ref arith) =>
- println!("{}", arith),
- &Line::Fact(ref fact_instr) =>
- println!("{}", fact_instr),
- &Line::Cut(ref cut) =>
- println!("{}", cut),
- &Line::Choice(ref choice) =>
- println!("{}", choice),
- &Line::Control(ref control) =>
- println!("{}", control),
- &Line::IndexedChoice(ref choice) =>
- println!("{}", choice),
- &Line::Indexing(ref indexing) =>
- println!("{}", indexing),
- &Line::Query(ref query_instr) =>
- println!("{}", query_instr)
+ &Line::Arithmetic(ref arith) => println!("{}", arith),
+ &Line::Fact(ref fact_instr) => println!("{}", fact_instr),
+ &Line::Cut(ref cut) => println!("{}", cut),
+ &Line::Choice(ref choice) => println!("{}", choice),
+ &Line::Control(ref control) => println!("{}", control),
+ &Line::IndexedChoice(ref choice) => println!("{}", choice),
+ &Line::Indexing(ref indexing) => println!("{}", indexing),
+ &Line::Query(ref query_instr) => println!("{}", query_instr),
}
}
}
-fn fix_filename(atom_tbl: TabledData<Atom>, filename: &str) -> Result<PathBuf, SessionError>
-{
+fn fix_filename(atom_tbl: TabledData<Atom>, filename: &str) -> Result<PathBuf, SessionError> {
let mut path = PathBuf::from(filename);
if !path.is_file() {
Ok(path)
}
-fn load_module_from_file(wam: &mut Machine, filename: &str) -> Result<ClauseName, SessionError>
-{
+fn load_module_from_file(wam: &mut Machine, filename: &str) -> Result<ClauseName, SessionError> {
let path = fix_filename(wam.indices.atom_tbl.clone(), filename)?;
let file_handle = File::open(&path).or_else(|_| {
match compile_work_impl(&mut compiler, wam, indices, results) {
EvalSession::Error(e) => Err(e),
- _ => Ok(module_name)
+ _ => Ok(module_name),
}
}
pub type PredicateCompileQueue = (Predicate, VecDeque<TopLevel>);
// throw errors if declaration or query found.
-fn compile_relation(tl: &TopLevel, non_counted_bt: bool, flags: MachineFlags)
- -> Result<Code, ParserError>
-{
+fn compile_relation(
+ tl: &TopLevel,
+ non_counted_bt: bool,
+ flags: MachineFlags,
+) -> Result<Code, ParserError> {
let mut cg = CodeGenerator::<DebrayAllocator>::new(non_counted_bt, flags);
match tl {
- &TopLevel::Declaration(_) | &TopLevel::Query(_) =>
- Err(ParserError::ExpectedRel),
- &TopLevel::Predicate(ref clauses) =>
- cg.compile_predicate(&clauses.0),
- &TopLevel::Fact(ref fact) =>
- Ok(cg.compile_fact(fact)),
- &TopLevel::Rule(ref rule) =>
- cg.compile_rule(rule)
+ &TopLevel::Declaration(_) | &TopLevel::Query(_) => Err(ParserError::ExpectedRel),
+ &TopLevel::Predicate(ref clauses) => cg.compile_predicate(&clauses.0),
+ &TopLevel::Fact(ref fact) => Ok(cg.compile_fact(fact)),
+ &TopLevel::Rule(ref rule) => cg.compile_rule(rule),
}
}
// set first jmp_by_call or jmp_by_index instruction to code.len() -
// idx, where idx is the place it occurs. It only does this to the
// *first* uninitialized jmp index it encounters, then returns.
-fn set_first_index(code: &mut Code)
-{
+fn set_first_index(code: &mut Code) {
let code_len = code.len();
for (idx, line) in code.iter_mut().enumerate() {
match line {
- &mut Line::Control(ControlInstruction::JmpBy(_, ref mut offset, ..)) if *offset == 0 => {
+ &mut Line::Control(ControlInstruction::JmpBy(_, ref mut offset, ..))
+ if *offset == 0 =>
+ {
*offset = code_len - idx;
break;
- },
+ }
_ => {}
};
}
}
-pub fn compile_appendix(code: &mut Code, queue: &VecDeque<TopLevel>, non_counted_bt: bool,
- flags: MachineFlags)
- -> Result<(), ParserError>
-{
+pub fn compile_appendix(
+ code: &mut Code,
+ queue: &VecDeque<TopLevel>,
+ non_counted_bt: bool,
+ flags: MachineFlags,
+) -> Result<(), ParserError> {
for tl in queue.iter() {
set_first_index(code);
code.append(&mut compile_relation(tl, non_counted_bt, flags)?);
}
impl CodeRepo {
- pub fn compile_hook(&mut self, hook: CompileTimeHook, flags: MachineFlags)
- -> Result<(), ParserError>
- {
+ pub fn compile_hook(
+ &mut self,
+ hook: CompileTimeHook,
+ flags: MachineFlags,
+ ) -> Result<(), ParserError> {
let key = (hook.name(), hook.arity());
-
+
match self.term_dir.get(&key) {
Some(preds) => {
let mut cg = CodeGenerator::<DebrayAllocator>::new(false, flags);
compile_appendix(&mut code, &preds.1, false, flags)?;
Ok(match hook {
- CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion =>
- self.term_expanders = code,
- CompileTimeHook::UserGoalExpansion | CompileTimeHook::GoalExpansion =>
+ CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion => {
+ self.term_expanders = code
+ }
+ CompileTimeHook::UserGoalExpansion | CompileTimeHook::GoalExpansion => {
self.goal_expanders = code
+ }
})
- },
- None => Ok(())
+ }
+ None => Ok(()),
}
}
}
-fn compile_query(terms: Vec<QueryTerm>, queue: VecDeque<TopLevel>, flags: MachineFlags)
- -> Result<(Code, AllocVarDict), ParserError>
-{
+fn compile_query(
+ terms: Vec<QueryTerm>,
+ queue: VecDeque<TopLevel>,
+ flags: MachineFlags,
+) -> Result<(Code, AllocVarDict), ParserError> {
// count backtracking inferences.
let mut cg = CodeGenerator::<DebrayAllocator>::new(false, flags);
let mut code = try!(cg.compile_query(&terms));
Ok((code, cg.take_vars()))
}
-fn compile_decl(wam: &mut Machine, compiler: &mut ListingCompiler, decl: Declaration)
- -> Result<IndexStore, SessionError>
-{
+fn compile_decl(
+ wam: &mut Machine,
+ compiler: &mut ListingCompiler,
+ decl: Declaration,
+) -> Result<IndexStore, SessionError> {
let flags = wam.machine_flags();
let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
Ok(indices)
}
-pub fn compile_term(wam: &mut Machine, packet: TopLevelPacket) -> EvalSession
-{
+pub fn compile_term(wam: &mut Machine, packet: TopLevelPacket) -> EvalSession {
match packet {
- TopLevelPacket::Query(terms, queue) =>
+ TopLevelPacket::Query(terms, queue) => {
match compile_query(terms, queue, wam.machine_flags()) {
Ok((code, vars)) => wam.submit_query(code, vars),
- Err(e) => EvalSession::from(e)
- },
+ Err(e) => EvalSession::from(e),
+ }
+ }
TopLevelPacket::Decl(TopLevel::Declaration(decl), _) => {
let mut compiler = ListingCompiler::new(&wam.code_repo);
let indices = try_eval_session!(compile_decl(wam, &mut compiler, decl));
add_toplevel_code(wam, vec![], indices);
EvalSession::EntrySuccess
- },
- _ => EvalSession::from(SessionError::UserPrompt)
+ }
+ _ => EvalSession::from(SessionError::UserPrompt),
}
}
-fn update_module_indices(wam: &Machine, module_name: ClauseName, mut indices: IndexStore)
-{
+fn update_module_indices(wam: &Machine, module_name: ClauseName, mut indices: IndexStore) {
match wam.indices.modules.get(&module_name) {
Some(module) => {
let code_dir = mem::replace(&mut indices.code_dir, CodeDir::new());
}
match wam.indices.code_dir.get(&key) {
- Some(idx) => if idx.0.borrow().1 == module_name {
- set_code_index!(idx, p, module_name.clone());
- },
+ Some(idx) => {
+ if idx.0.borrow().1 == module_name {
+ set_code_index!(idx, p, module_name.clone());
+ }
+ }
_ => {}
}
}
- },
- _ => unreachable!()
+ }
+ _ => unreachable!(),
};
}
-fn add_hooks_to_mockup(code_repo: &mut CodeRepo, hook: CompileTimeHook,
- expansions: (Predicate, VecDeque<TopLevel>))
-{
+fn add_hooks_to_mockup(
+ code_repo: &mut CodeRepo,
+ hook: CompileTimeHook,
+ expansions: (Predicate, VecDeque<TopLevel>),
+) {
let key = (hook.name(), hook.arity());
- let preds = code_repo.term_dir.entry(key.clone())
+ let preds = code_repo
+ .term_dir
+ .entry(key.clone())
.or_insert((Predicate::new(), VecDeque::from(vec![])));
(preds.0).0.extend((expansions.0).0.into_iter());
preds.1.extend(expansions.1.into_iter());
}
-fn setup_module_expansions(wam: &mut Machine, module_name: ClauseName)
-{
+fn setup_module_expansions(wam: &mut Machine, module_name: ClauseName) {
match wam.indices.modules.get(&module_name) {
Some(module) => {
let term_expansions = module.term_expansions.clone();
let goal_expansions = module.goal_expansions.clone();
- add_hooks_to_mockup(&mut wam.code_repo, CompileTimeHook::TermExpansion,
- term_expansions);
- add_hooks_to_mockup(&mut wam.code_repo, CompileTimeHook::GoalExpansion,
- goal_expansions);
- },
- _ => unreachable!()
+ add_hooks_to_mockup(
+ &mut wam.code_repo,
+ CompileTimeHook::TermExpansion,
+ term_expansions,
+ );
+ add_hooks_to_mockup(
+ &mut wam.code_repo,
+ CompileTimeHook::GoalExpansion,
+ goal_expansions,
+ );
+ }
+ _ => unreachable!(),
}
}
-pub(super)
-fn compile_into_module<R: Read>(wam: &mut Machine, module_name: ClauseName,
- src: ParsingStream<R>, name: ClauseName)
- -> EvalSession
-{
+pub(super) fn compile_into_module<R: Read>(
+ wam: &mut Machine,
+ module_name: ClauseName,
+ src: ParsingStream<R>,
+ name: ClauseName,
+) -> EvalSession {
let mut indices = default_index_store!(wam.atom_tbl_of(&name));
try_eval_session!(setup_indices(wam, module_name.clone(), &mut indices));
}
}
-fn compile_into_module_impl<R: Read>(wam: &mut Machine, compiler: &mut ListingCompiler,
- module_name: ClauseName, src: ParsingStream<R>,
- mut indices: IndexStore)
- -> Result<(), SessionError>
-{
+fn compile_into_module_impl<R: Read>(
+ wam: &mut Machine,
+ compiler: &mut ListingCompiler,
+ module_name: ClauseName,
+ src: ParsingStream<R>,
+ mut indices: IndexStore,
+) -> Result<(), SessionError> {
setup_module_expansions(wam, module_name.clone());
let flags = wam.machine_flags();
- wam.code_repo.compile_hook(CompileTimeHook::TermExpansion, flags)?;
- wam.code_repo.compile_hook(CompileTimeHook::GoalExpansion, flags)?;
+ wam.code_repo
+ .compile_hook(CompileTimeHook::TermExpansion, flags)?;
+ wam.code_repo
+ .compile_hook(CompileTimeHook::GoalExpansion, flags)?;
let results = compiler.gather_items(wam, src, &mut indices)?;
- let module_code = compiler.generate_code(results.worker_results, wam,
- &mut indices.code_dir, 0)?;
+ let module_code =
+ compiler.generate_code(results.worker_results, wam, &mut indices.code_dir, 0)?;
let mut clause_code_generator = ClauseCodeGenerator::new(module_code.len());
clause_code_generator.generate_clause_code(results.dynamic_clause_map, wam)?;
pub(crate) worker_results: Vec<PredicateCompileQueue>,
toplevel_results: Vec<PredicateCompileQueue>,
toplevel_indices: IndexStore,
- addition_results: ExpansionAdditionResult
+ addition_results: ExpansionAdditionResult,
}
pub struct ClauseCodeGenerator {
len_offset: usize,
code: Code,
- pi_to_loc: IndexMap<PredicateKey, usize>
+ pi_to_loc: IndexMap<PredicateKey, usize>,
}
impl ClauseCodeGenerator {
#[inline]
fn new(len_offset: usize) -> Self {
- ClauseCodeGenerator { len_offset, code: vec![], pi_to_loc: IndexMap::new() }
+ ClauseCodeGenerator {
+ len_offset,
+ code: vec![],
+ pi_to_loc: IndexMap::new(),
+ }
}
- fn generate_clause_code(&mut self, dynamic_clause_map: DynamicClauseMap, wam: &Machine)
- -> Result<(), SessionError>
- {
+ fn generate_clause_code(
+ &mut self,
+ dynamic_clause_map: DynamicClauseMap,
+ wam: &Machine,
+ ) -> Result<(), SessionError> {
for ((name, arity), heads_and_tails) in dynamic_clause_map {
if heads_and_tails.is_empty() {
continue;
}
- let predicate = Predicate(heads_and_tails.into_iter().map(|(head, tail)| {
- let clause = Term::Clause(Cell::default(), clause_name!("clause"),
- vec![Box::new(head), Box::new(tail)],
- None);
- PredicateClause::Fact(clause)
- }).collect());
+ let predicate = Predicate(
+ heads_and_tails
+ .into_iter()
+ .map(|(head, tail)| {
+ let clause = Term::Clause(
+ Cell::default(),
+ clause_name!("clause"),
+ vec![Box::new(head), Box::new(tail)],
+ None,
+ );
+ PredicateClause::Fact(clause)
+ })
+ .collect(),
+ );
let p = self.code.len() + wam.code_repo.code.len() + self.len_offset;
- let mut decl_code = compile_relation(&TopLevel::Predicate(predicate), false,
- wam.machine_flags())?;
+ let mut decl_code =
+ compile_relation(&TopLevel::Predicate(predicate), false, wam.machine_flags())?;
compile_appendix(&mut decl_code, &VecDeque::new(), false, wam.machine_flags())?;
wam.code_repo.code.extend(self.code.into_iter());
for ((name, arity), p) in self.pi_to_loc {
- let entry = wam.indices.dynamic_code_dir.entry((name.owning_module(), name, arity))
- .or_insert(DynamicPredicateInfo::default());
+ let entry = wam
+ .indices
+ .dynamic_code_dir
+ .entry((name.owning_module(), name, arity))
+ .or_insert(DynamicPredicateInfo::default());
entry.clauses_subsection_p = p;
}
module: Option<Module>,
user_term_dir: TermDir,
orig_term_expansion_lens: (usize, usize),
- orig_goal_expansion_lens: (usize, usize)
+ orig_goal_expansion_lens: (usize, usize),
}
-fn add_toplevel_code(wam: &mut Machine, code: Code, mut indices: IndexStore)
-{
+fn add_toplevel_code(wam: &mut Machine, code: Code, mut indices: IndexStore) {
let code_dir = mem::replace(&mut indices.code_dir, CodeDir::new());
- let op_dir = mem::replace(&mut indices.op_dir, OpDir::new());
+ let op_dir = mem::replace(&mut indices.op_dir, OpDir::new());
wam.add_batched_code(code, code_dir);
wam.add_batched_ops(op_dir);
}
#[inline]
-fn add_module_code(wam: &mut Machine, mut module: Module, code: Code, mut indices: IndexStore)
-{
+fn add_module_code(wam: &mut Machine, mut module: Module, code: Code, mut indices: IndexStore) {
let code_dir = mem::replace(&mut indices.code_dir, CodeDir::new());
- let op_dir = mem::replace(&mut indices.op_dir, OpDir::new());
+ let op_dir = mem::replace(&mut indices.op_dir, OpDir::new());
module.code_dir.extend(code_dir);
module.op_dir.extend(op_dir.into_iter());
for (name, arity) in indices.code_dir.keys().cloned() {
if name.owning_module() == module.module_decl.name {
- wam.indices.dynamic_code_dir.remove(&(name.owning_module(), name, arity));
+ wam.indices
+ .dynamic_code_dir
+ .remove(&(name.owning_module(), name, arity));
}
}
wam.add_module(module, code);
}
-fn add_non_module_code(wam: &mut Machine, dynamic_clause_map: DynamicClauseMap, code: Code,
- indices: IndexStore)
- -> Result<(), SessionError>
-{
+fn add_non_module_code(
+ wam: &mut Machine,
+ dynamic_clause_map: DynamicClauseMap,
+ code: Code,
+ indices: IndexStore,
+) -> Result<(), SessionError> {
wam.check_toplevel_code(&indices)?;
let mut clause_code_generator = ClauseCodeGenerator::new(code.len());
non_counted_bt_preds: IndexSet::new(),
module: None,
user_term_dir: TermDir::new(),
- orig_term_expansion_lens: code_repo.term_dir_entry_len((clause_name!("term_expansion"), 2)),
- orig_goal_expansion_lens: code_repo.term_dir_entry_len((clause_name!("goal_expansion"), 2)),
+ orig_term_expansion_lens: code_repo
+ .term_dir_entry_len((clause_name!("term_expansion"), 2)),
+ orig_goal_expansion_lens: code_repo
+ .term_dir_entry_len((clause_name!("goal_expansion"), 2)),
}
}
Replace calls to self with a localized index cell, not available to the global CodeIndex.
This is done to implement logical update semantics for dynamic database updates.
*/
- fn localize_self_calls(&mut self, name: ClauseName, arity: usize, code: &mut Code, p: usize)
- {
+ fn localize_self_calls(&mut self, name: ClauseName, arity: usize, code: &mut Code, p: usize) {
let self_idx = CodeIndex::default();
set_code_index!(self_idx, IndexPtr::Index(p), self.get_module_name());
if let &mut Line::Control(ControlInstruction::CallClause(ref mut ct, ..)) = instr {
match ct {
&mut ClauseType::Named(ref ct_name, ct_arity, ref mut idx)
- if ct_name == &name && arity == ct_arity => {
- *idx = self_idx.clone();
- },
+ if ct_name == &name && arity == ct_arity =>
+ {
+ *idx = self_idx.clone();
+ }
&mut ClauseType::Op(ref op_name, ref shared_op_desc, ref mut idx)
- if op_name == &name && shared_op_desc.arity() == arity => {
- *idx = self_idx.clone();
- },
+ if op_name == &name && shared_op_desc.arity() == arity =>
+ {
+ *idx = self_idx.clone();
+ }
_ => {}
}
}
}
}
- fn use_module(&mut self, submodule: ClauseName, code_repo: &mut CodeRepo, flags: MachineFlags,
- wam_indices: &mut IndexStore, indices: &mut IndexStore)
- -> Result<(), SessionError>
- {
+ fn use_module(
+ &mut self,
+ submodule: ClauseName,
+ code_repo: &mut CodeRepo,
+ flags: MachineFlags,
+ wam_indices: &mut IndexStore,
+ indices: &mut IndexStore,
+ ) -> Result<(), SessionError> {
let module_name = self.get_module_name();
if let Some(mut submodule) = wam_indices.take_module(submodule) {
- unwind_protect!(indices.use_module(code_repo, flags, &submodule),
- wam_indices.insert_module(submodule));
+ unwind_protect!(
+ indices.use_module(code_repo, flags, &submodule),
+ wam_indices.insert_module(submodule)
+ );
if let &mut Some(ref mut module) = &mut self.module {
module.remove_module(module_name, &submodule);
- unwind_protect!(module.use_module(code_repo, flags, &submodule),
- wam_indices.insert_module(submodule));
+ unwind_protect!(
+ module.use_module(code_repo, flags, &submodule),
+ wam_indices.insert_module(submodule)
+ );
} else {
submodule.inserted_expansions = true;
wam_indices.remove_module(clause_name!("user"), &submodule);
}
}
- fn use_qualified_module(&mut self, submodule: ClauseName, code_repo: &mut CodeRepo,
- flags: MachineFlags, exports: &Vec<PredicateKey>,
- wam_indices: &mut IndexStore, indices: &mut IndexStore)
- -> Result<(), SessionError>
- {
+ fn use_qualified_module(
+ &mut self,
+ submodule: ClauseName,
+ code_repo: &mut CodeRepo,
+ flags: MachineFlags,
+ exports: &Vec<PredicateKey>,
+ wam_indices: &mut IndexStore,
+ indices: &mut IndexStore,
+ ) -> Result<(), SessionError> {
let module_name = self.get_module_name();
if let Some(mut submodule) = wam_indices.take_module(submodule) {
- unwind_protect!(indices.use_qualified_module(code_repo, flags, &submodule, exports),
- wam_indices.insert_module(submodule));
+ unwind_protect!(
+ indices.use_qualified_module(code_repo, flags, &submodule, exports),
+ wam_indices.insert_module(submodule)
+ );
if let &mut Some(ref mut module) = &mut self.module {
module.remove_module(module_name, &submodule);
- unwind_protect!(module.use_qualified_module(code_repo, flags, &submodule, exports),
- wam_indices.insert_module(submodule));
+ unwind_protect!(
+ module.use_qualified_module(code_repo, flags, &submodule, exports),
+ wam_indices.insert_module(submodule)
+ );
} else {
submodule.inserted_expansions = true;
wam_indices.remove_module(clause_name!("user"), &submodule);
#[inline]
fn get_module_name(&self) -> ClauseName {
- self.module.as_ref()
+ self.module
+ .as_ref()
.map(|module| module.module_decl.name.clone())
.unwrap_or(ClauseName::BuiltIn("user"))
}
- pub(crate)
- fn generate_code(&mut self, decls: Vec<PredicateCompileQueue>, wam: &Machine,
- code_dir: &mut CodeDir, code_offset: usize)
- -> Result<Code, SessionError>
- {
+ pub(crate) fn generate_code(
+ &mut self,
+ decls: Vec<PredicateCompileQueue>,
+ wam: &Machine,
+ code_dir: &mut CodeDir,
+ code_offset: usize,
+ ) -> Result<Code, SessionError> {
let mut code = vec![];
for (decl, queue) in decls {
- let (name, arity) = decl.predicate_indicator().ok_or(SessionError::NamelessEntry)?;
+ let (name, arity) = decl
+ .predicate_indicator()
+ .ok_or(SessionError::NamelessEntry)?;
let non_counted_bt = self.non_counted_bt_preds.contains(&(name.clone(), arity));
let p = code.len() + wam.code_repo.code.len() + code_offset;
- let mut decl_code = compile_relation(&TopLevel::Predicate(decl), non_counted_bt,
- wam.machine_flags())?;
+ let mut decl_code = compile_relation(
+ &TopLevel::Predicate(decl),
+ non_counted_bt,
+ wam.machine_flags(),
+ )?;
compile_appendix(&mut decl_code, &queue, non_counted_bt, wam.machine_flags())?;
- let idx = code_dir.entry((name.clone(), arity)).or_insert(CodeIndex::default());
+ let idx = code_dir
+ .entry((name.clone(), arity))
+ .or_insert(CodeIndex::default());
set_code_index!(idx, IndexPtr::Index(p), self.get_module_name());
self.localize_self_calls(name, arity, &mut decl_code, p);
self.non_counted_bt_preds.insert((name, arity));
}
- fn add_term_dir_terms(&mut self, hook: CompileTimeHook, code_repo: &mut CodeRepo,
- key: PredicateKey, clause: PredicateClause, queue: VecDeque<TopLevel>)
- -> (usize, usize)
- {
- let preds = code_repo.term_dir.entry(key.clone())
+ fn add_term_dir_terms(
+ &mut self,
+ hook: CompileTimeHook,
+ code_repo: &mut CodeRepo,
+ key: PredicateKey,
+ clause: PredicateClause,
+ queue: VecDeque<TopLevel>,
+ ) -> (usize, usize) {
+ let preds = code_repo
+ .term_dir
+ .entry(key.clone())
.or_insert((Predicate::new(), VecDeque::from(vec![])));
let (mut len, mut queue_len) = ((preds.0).0.len(), preds.1.len());
if self.module.is_some() && hook.has_module_scope() {
- let module_preds = self.user_term_dir.entry(key.clone())
+ let module_preds = self
+ .user_term_dir
+ .entry(key.clone())
.or_insert((Predicate::new(), VecDeque::from(vec![])));
if let Some(ref mut module) = &mut self.module {
(preds.0).0.extend((module_preds.0).0.iter().cloned());
preds.1.extend(module_preds.1.iter().cloned());
} else {
- let module_preds = self.user_term_dir.entry(key.clone())
+ let module_preds = self
+ .user_term_dir
+ .entry(key.clone())
.or_insert((Predicate::new(), VecDeque::from(vec![])));
len += 1;
(len, queue_len)
}
- fn process_decl(&mut self, decl: Declaration, wam: &mut Machine, indices: &mut IndexStore,
- flags: MachineFlags)
- -> Result<(), SessionError>
- {
+ fn process_decl(
+ &mut self,
+ decl: Declaration,
+ wam: &mut Machine,
+ indices: &mut IndexStore,
+ flags: MachineFlags,
+ ) -> Result<(), SessionError> {
match decl {
Declaration::EndOfFile => Ok(()),
Declaration::Hook(hook, clause, queue) => {
let key = (hook.name(), hook.arity());
- let (len, queue_len) = self.add_term_dir_terms(hook, &mut wam.code_repo,
- key.clone(), clause, queue);
+ let (len, queue_len) =
+ self.add_term_dir_terms(hook, &mut wam.code_repo, key.clone(), clause, queue);
- let result = wam.code_repo.compile_hook(hook, flags).map_err(SessionError::from);
+ let result = wam
+ .code_repo
+ .compile_hook(hook, flags)
+ .map_err(SessionError::from);
wam.code_repo.truncate_terms(key, len, queue_len);
result
- },
- Declaration::NonCountedBacktracking(name, arity) =>
- Ok(self.add_non_counted_bt_flag(name, arity)),
+ }
+ Declaration::NonCountedBacktracking(name, arity) => {
+ Ok(self.add_non_counted_bt_flag(name, arity))
+ }
Declaration::Op(op_decl) => {
- let spec = get_desc(op_decl.name(), composite_op!(self.module.is_some(),
- &wam.indices.op_dir,
- &mut indices.op_dir));
+ let spec = get_desc(
+ op_decl.name(),
+ composite_op!(
+ self.module.is_some(),
+ &wam.indices.op_dir,
+ &mut indices.op_dir
+ ),
+ );
op_decl.submit(self.get_module_name(), spec, &mut indices.op_dir)
- },
- Declaration::UseModule(ModuleSource::Library(name)) =>
- self.use_module(name, &mut wam.code_repo, flags, &mut wam.indices,
- indices),
- Declaration::UseQualifiedModule(ModuleSource::Library(name), exports) =>
- self.use_qualified_module(name, &mut wam.code_repo, flags, &exports,
- &mut wam.indices, indices),
- Declaration::Module(module_decl) =>
+ }
+ Declaration::UseModule(ModuleSource::Library(name)) => {
+ self.use_module(name, &mut wam.code_repo, flags, &mut wam.indices, indices)
+ }
+ Declaration::UseQualifiedModule(ModuleSource::Library(name), exports) => self
+ .use_qualified_module(
+ name,
+ &mut wam.code_repo,
+ flags,
+ &exports,
+ &mut wam.indices,
+ indices,
+ ),
+ Declaration::Module(module_decl) => {
if self.module.is_none() {
let module_name = module_decl.name.clone();
let atom_tbl = TabledData::new(module_name.to_rc());
Ok(self.module = Some(Module::new(module_decl, atom_tbl)))
} else {
Err(SessionError::from(ParserError::InvalidModuleDecl))
- },
+ }
+ }
Declaration::UseModule(ModuleSource::File(filename)) => {
let name = load_module_from_file(wam, filename.as_str())?;
self.use_module(name, &mut wam.code_repo, flags, &mut wam.indices, indices)
- },
+ }
Declaration::UseQualifiedModule(ModuleSource::File(filename), exports) => {
let name = load_module_from_file(wam, filename.as_str())?;
- self.use_qualified_module(name, &mut wam.code_repo, flags, &exports,
- &mut wam.indices, indices)
- },
- Declaration::Dynamic(..) => Ok(())
+ self.use_qualified_module(
+ name,
+ &mut wam.code_repo,
+ flags,
+ &exports,
+ &mut wam.indices,
+ indices,
+ )
+ }
+ Declaration::Dynamic(..) => Ok(()),
}
}
- fn process_and_commit_decl<R: Read>(&mut self, decl: Declaration,
- worker: &mut TopLevelBatchWorker<R>,
- indices: &mut IndexStore, flags: MachineFlags)
- -> Result<(), SessionError>
- {
+ fn process_and_commit_decl<R: Read>(
+ &mut self,
+ decl: Declaration,
+ worker: &mut TopLevelBatchWorker<R>,
+ indices: &mut IndexStore,
+ flags: MachineFlags,
+ ) -> Result<(), SessionError> {
let mut update_expansion_lengths = false;
match &decl {
&Declaration::Dynamic(ref name, arity) => {
- worker.dynamic_clause_map.entry((name.clone(), arity)).or_insert(vec![]);
- },
- &Declaration::Hook(hook, _, ref queue) if self.module.is_none() =>
- worker.term_stream.incr_expansion_lens(hook.user_scope(), 1, queue.len()),
- &Declaration::Hook(hook, _, ref queue) if !hook.has_module_scope() =>
- worker.term_stream.incr_expansion_lens(hook, 1, queue.len()),
+ worker
+ .dynamic_clause_map
+ .entry((name.clone(), arity))
+ .or_insert(vec![]);
+ }
+ &Declaration::Hook(hook, _, ref queue) if self.module.is_none() => worker
+ .term_stream
+ .incr_expansion_lens(hook.user_scope(), 1, queue.len()),
+ &Declaration::Hook(hook, _, ref queue) if !hook.has_module_scope() => {
+ worker.term_stream.incr_expansion_lens(hook, 1, queue.len())
+ }
&Declaration::UseModule(ModuleSource::File(_))
- | &Declaration::UseQualifiedModule(ModuleSource::File(_), _) =>
- update_expansion_lengths = true,
+ | &Declaration::UseQualifiedModule(ModuleSource::File(_), _) => {
+ update_expansion_lengths = true
+ }
_ => {}
};
result
}
- pub(crate)
- fn gather_items<R: Read>(&mut self, wam: &mut Machine, mut src: ParsingStream<R>,
- indices: &mut IndexStore)
- -> Result<GatherResult, SessionError>
- {
- let flags = wam.machine_flags();
- let atom_tbl = indices.atom_tbl.clone();
+ pub(crate) fn gather_items<R: Read>(
+ &mut self,
+ wam: &mut Machine,
+ mut src: ParsingStream<R>,
+ indices: &mut IndexStore,
+ ) -> Result<GatherResult, SessionError> {
+ let flags = wam.machine_flags();
+ let atom_tbl = indices.atom_tbl.clone();
let mut worker = TopLevelBatchWorker::new(&mut src, atom_tbl.clone(), flags, wam);
let mut toplevel_results = vec![];
dynamic_clause_map: worker.dynamic_clause_map,
toplevel_results,
toplevel_indices,
- addition_results
+ addition_results,
})
}
- fn drop_expansions(&self, flags: MachineFlags, code_repo: &mut CodeRepo)
- {
+ fn drop_expansions(&self, flags: MachineFlags, code_repo: &mut CodeRepo) {
let (te_len, te_queue_len) = self.orig_term_expansion_lens;
let (ge_len, ge_queue_len) = self.orig_goal_expansion_lens;
}
}
-fn compile_work_impl(compiler: &mut ListingCompiler, wam: &mut Machine,
- mut indices: IndexStore, mut results: GatherResult)
- -> EvalSession
-{
- let module_code = try_eval_session!(compiler.generate_code(results.worker_results, wam,
- &mut indices.code_dir, 0));
- let toplvl_code = try_eval_session!(compiler.generate_code(results.toplevel_results, wam,
- &mut results.toplevel_indices.code_dir,
- module_code.len()));
+fn compile_work_impl(
+ compiler: &mut ListingCompiler,
+ wam: &mut Machine,
+ mut indices: IndexStore,
+ mut results: GatherResult,
+) -> EvalSession {
+ let module_code = try_eval_session!(compiler.generate_code(
+ results.worker_results,
+ wam,
+ &mut indices.code_dir,
+ 0
+ ));
+ let toplvl_code = try_eval_session!(compiler.generate_code(
+ results.toplevel_results,
+ wam,
+ &mut results.toplevel_indices.code_dir,
+ module_code.len()
+ ));
if let Some(ref mut module) = &mut compiler.module {
module.user_term_expansions = results.addition_results.take_term_expansions();
let flags = wam.machine_flags();
- try_eval_session!(wam.code_repo.compile_hook(CompileTimeHook::UserTermExpansion, flags));
- try_eval_session!(wam.code_repo.compile_hook(CompileTimeHook::UserGoalExpansion, flags));
+ try_eval_session!(wam
+ .code_repo
+ .compile_hook(CompileTimeHook::UserTermExpansion, flags));
+ try_eval_session!(wam
+ .code_repo
+ .compile_hook(CompileTimeHook::UserGoalExpansion, flags));
if let Some(module) = compiler.module.take() {
- let mut clause_code_generator = ClauseCodeGenerator::new(module_code.len() + toplvl_code.len());
+ let mut clause_code_generator =
+ ClauseCodeGenerator::new(module_code.len() + toplvl_code.len());
try_eval_session!(wam.check_toplevel_code(&results.toplevel_indices));
- try_eval_session!(clause_code_generator.generate_clause_code(results.dynamic_clause_map,
- wam));
+ try_eval_session!(
+ clause_code_generator.generate_clause_code(results.dynamic_clause_map, wam)
+ );
add_module_code(wam, module, module_code, indices);
add_toplevel_code(wam, toplvl_code, results.toplevel_indices);
clause_code_generator.add_clause_code(wam);
} else {
- try_eval_session!(add_non_module_code(wam, results.dynamic_clause_map, module_code,
- indices));
+ try_eval_session!(add_non_module_code(
+ wam,
+ results.dynamic_clause_map,
+ module_code,
+ indices
+ ));
}
EvalSession::EntrySuccess
}
-fn compile_work<R: Read>(compiler: &mut ListingCompiler, wam: &mut Machine,
- src: ParsingStream<R>, mut indices: IndexStore)
- -> EvalSession
-{
+fn compile_work<R: Read>(
+ compiler: &mut ListingCompiler,
+ wam: &mut Machine,
+ src: ParsingStream<R>,
+ mut indices: IndexStore,
+) -> EvalSession {
let results = try_eval_session!(compiler.gather_items(wam, src, &mut indices));
compile_work_impl(compiler, wam, indices, results)
}
/* This is a truncated version of compile_user_module, used for
- compiling code composing special forms, ie. the code that calls
- M:verify_attributes on attributed variables. */
-pub fn compile_special_form<R: Read>(wam: &mut Machine, src: ParsingStream<R>)
- -> Result<Code, SessionError>
-{
+compiling code composing special forms, ie. the code that calls
+M:verify_attributes on attributed variables. */
+pub fn compile_special_form<R: Read>(
+ wam: &mut Machine,
+ src: ParsingStream<R>,
+) -> Result<Code, SessionError> {
let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
setup_indices(wam, clause_name!("builtins"), &mut indices)?;
}
#[inline]
-pub
-fn compile_listing<R: Read>(wam: &mut Machine, src: ParsingStream<R>, indices: IndexStore)
- -> EvalSession
-{
+pub fn compile_listing<R: Read>(
+ wam: &mut Machine,
+ src: ParsingStream<R>,
+ indices: IndexStore,
+) -> EvalSession {
let mut compiler = ListingCompiler::new(&wam.code_repo);
match compile_work(&mut compiler, wam, src, indices) {
EvalSession::Error(e) => {
compiler.drop_expansions(wam.machine_flags(), &mut wam.code_repo);
EvalSession::Error(e)
- },
- result => result
+ }
+ result => result,
}
}
-pub(super)
-fn setup_indices(wam: &mut Machine, module: ClauseName, indices: &mut IndexStore)
- -> Result<(), SessionError>
-{
+pub(super) fn setup_indices(
+ wam: &mut Machine,
+ module: ClauseName,
+ indices: &mut IndexStore,
+) -> Result<(), SessionError> {
if let Some(module) = wam.indices.take_module(module) {
- let flags = wam.machine_flags();
+ let flags = wam.machine_flags();
let result = indices.use_module(&mut wam.code_repo, flags, &module);
wam.indices.insert_module(module);
type Trail = Vec<(Ref, HeapCellValue)>;
-pub(crate) trait CopierTarget: IndexMut<usize, Output=HeapCellValue>
-{
+pub(crate) trait CopierTarget: IndexMut<usize, Output = HeapCellValue> {
fn threshold(&self) -> usize;
fn push(&mut self, HeapCellValue);
fn store(&self, Addr) -> Addr;
fn stack(&mut self) -> &mut AndStack;
}
-pub(crate)
-fn copy_term<T: CopierTarget>(target: T, addr: Addr)
-{
+pub(crate) fn copy_term<T: CopierTarget>(target: T, addr: Addr) {
let mut copy_term_state = CopyTermState::new(target);
copy_term_state.copy_term_impl(addr);
}
trail: Trail,
scan: usize,
old_h: usize,
- target: T
+ target: T,
}
impl<T: CopierTarget> CopyTermState<T> {
fn new(target: T) -> Self {
CopyTermState {
trail: vec![],
- scan: 0,
+ scan: 0,
old_h: target.threshold(),
- target
+ target,
}
}
&mut self.target[scan]
}
- fn reinstantiate_var(&mut self, addr: Addr, threshold: usize)
- {
+ fn reinstantiate_var(&mut self, addr: Addr, threshold: usize) {
match addr {
Addr::HeapCell(h) => {
self.target[threshold] = HeapCellValue::Addr(Addr::HeapCell(threshold));
self.target[h] = HeapCellValue::Addr(Addr::HeapCell(threshold));
- self.trail.push((Ref::HeapCell(h), HeapCellValue::Addr(Addr::HeapCell(h))));
- },
+ self.trail
+ .push((Ref::HeapCell(h), HeapCellValue::Addr(Addr::HeapCell(h))));
+ }
Addr::StackCell(fr, sc) => {
self.target[threshold] = HeapCellValue::Addr(Addr::HeapCell(threshold));
self.target.stack()[fr][sc] = Addr::HeapCell(threshold);
- self.trail.push((Ref::StackCell(fr, sc), HeapCellValue::Addr(Addr::StackCell(fr, sc))));
- },
+ self.trail.push((
+ Ref::StackCell(fr, sc),
+ HeapCellValue::Addr(Addr::StackCell(fr, sc)),
+ ));
+ }
Addr::AttrVar(h) => {
self.target[threshold] = HeapCellValue::Addr(Addr::AttrVar(threshold));
self.target[h] = HeapCellValue::Addr(Addr::AttrVar(threshold));
- self.trail.push((Ref::AttrVar(h), HeapCellValue::Addr(Addr::AttrVar(h))));
- },
+ self.trail
+ .push((Ref::AttrVar(h), HeapCellValue::Addr(Addr::AttrVar(h))));
+ }
_ => {}
}
}
let rd = self.target.store(self.target.deref(ra));
match rd.clone() {
- Addr::AttrVar(h) | Addr::HeapCell(h) if h >= self.old_h =>
- self.target[threshold] = HeapCellValue::Addr(rd),
- ra @ Addr::AttrVar(_) | ra @ Addr::HeapCell(..) | ra @ Addr::StackCell(..) =>
+ Addr::AttrVar(h) | Addr::HeapCell(h) if h >= self.old_h => {
+ self.target[threshold] = HeapCellValue::Addr(rd)
+ }
+ ra @ Addr::AttrVar(_) | ra @ Addr::HeapCell(..) | ra @ Addr::StackCell(..) => {
if ra == rd {
self.reinstantiate_var(ra, threshold);
} else {
self.target[threshold] = HeapCellValue::Addr(ra);
- },
+ }
+ }
_ => {
- self.trail.push((Ref::HeapCell(addr), self.target[addr].clone()));
+ self.trail
+ .push((Ref::HeapCell(addr), self.target[addr].clone()));
self.target[addr] = HeapCellValue::Addr(Addr::Lis(threshold))
}
};
Addr::AttrVar(h) | Addr::HeapCell(h) if h >= self.old_h => {
*self.value_at_scan() = HeapCellValue::Addr(rd);
self.scan += 1;
- },
+ }
Addr::AttrVar(h) if addr == rd => {
let threshold = self.target.threshold();
- self.target.push(HeapCellValue::Addr(Addr::AttrVar(threshold)));
+ self.target
+ .push(HeapCellValue::Addr(Addr::AttrVar(threshold)));
let list_val = self.target[h + 1].clone();
self.target.push(list_val);
self.reinstantiate_var(addr, threshold);
*self.value_at_scan() = HeapCellValue::Addr(Addr::AttrVar(threshold));
- },
+ }
_ if addr == rd => {
let scan = self.scan;
self.reinstantiate_var(addr, scan);
self.scan += 1;
- },
- _ => *self.value_at_scan() = HeapCellValue::Addr(rd)
+ }
+ _ => *self.value_at_scan() = HeapCellValue::Addr(rd),
}
}
*self.value_at_scan() = HeapCellValue::Addr(Addr::Str(threshold));
self.target[addr] = HeapCellValue::Addr(Addr::Str(threshold));
- self.trail.push((Ref::HeapCell(addr),
- HeapCellValue::NamedStr(arity, name.clone(), fixity.clone())));
+ self.trail.push((
+ Ref::HeapCell(addr),
+ HeapCellValue::NamedStr(arity, name.clone(), fixity.clone()),
+ ));
- self.target.push(HeapCellValue::NamedStr(arity, name, fixity));
+ self.target
+ .push(HeapCellValue::NamedStr(arity, name, fixity));
- for i in 0 .. arity {
+ for i in 0..arity {
let hcv = self.target[addr + 1 + i].clone();
self.target.push(hcv);
}
- },
- HeapCellValue::Addr(Addr::Str(addr)) =>
- *self.value_at_scan() = HeapCellValue::Addr(Addr::Str(addr)),
+ }
+ HeapCellValue::Addr(Addr::Str(addr)) => {
+ *self.value_at_scan() = HeapCellValue::Addr(Addr::Str(addr))
+ }
_ => {}
}
while self.scan < self.target.threshold() {
match self.value_at_scan().clone() {
- HeapCellValue::NamedStr(..) =>
- self.scan += 1,
- HeapCellValue::Addr(addr) =>
- match addr {
- Addr::Lis(addr) =>
- self.copy_list(addr),
- addr @ Addr::AttrVar(_)
- | addr @ Addr::HeapCell(_)
- | addr @ Addr::StackCell(..) =>
- self.copy_var(addr),
- Addr::Str(addr) =>
- self.copy_structure(addr),
- Addr::Con(_) | Addr::DBRef(_) =>
- self.scan += 1
- }
+ HeapCellValue::NamedStr(..) => self.scan += 1,
+ HeapCellValue::Addr(addr) => match addr {
+ Addr::Lis(addr) => self.copy_list(addr),
+ addr @ Addr::AttrVar(_)
+ | addr @ Addr::HeapCell(_)
+ | addr @ Addr::StackCell(..) => self.copy_var(addr),
+ Addr::Str(addr) => self.copy_structure(addr),
+ Addr::Con(_) | Addr::DBRef(_) => self.scan += 1,
+ },
}
}
}
fn unwind_trail(&mut self) {
- for (r, value) in self.trail.drain(0 ..) {
+ for (r, value) in self.trail.drain(0..) {
match r {
- Ref::AttrVar(h) | Ref::HeapCell(h) =>
- self.target[h] = value,
- Ref::StackCell(fr, sc) =>
- self.target.stack()[fr][sc] = value.as_addr(0)
+ Ref::AttrVar(h) | Ref::HeapCell(h) => self.target[h] = value,
+ Ref::StackCell(fr, sc) => self.target.stack()[fr][sc] = value.as_addr(0),
}
}
}
use prolog_parser::ast::*;
use prolog::heap_print::*;
-use prolog::machine::*;
use prolog::machine::compile::*;
use prolog::machine::machine_errors::*;
+use prolog::machine::*;
use std::io::Read;
impl Machine {
- pub(super)
- fn atom_tbl_of(&self, name: &ClauseName) -> TabledData<Atom> {
+ pub(super) fn atom_tbl_of(&self, name: &ClauseName) -> TabledData<Atom> {
match name {
&ClauseName::User(ref rc) => rc.table.clone(),
- _ => self.indices.atom_tbl()
+ _ => self.indices.atom_tbl(),
}
}
- fn compile_into_machine<R: Read>(&mut self, src: ParsingStream<R>, name: ClauseName, arity: usize)
- -> EvalSession
- {
+ fn compile_into_machine<R: Read>(
+ &mut self,
+ src: ParsingStream<R>,
+ name: ClauseName,
+ arity: usize,
+ ) -> EvalSession {
match name.owning_module().as_str() {
"user" => match self.indices.code_dir.get(&(name.clone(), arity)).cloned() {
Some(idx) => {
match module.as_str() {
"user" => compile_user_module(self, src),
- _ => compile_into_module(self, module, src, name)
+ _ => compile_into_module(self, module, src, name),
}
- },
- None => compile_user_module(self, src)
+ }
+ None => compile_user_module(self, src),
},
- _ => compile_into_module(self, name.owning_module(), src, name)
+ _ => compile_into_module(self, name.owning_module(), src, name),
}
}
- fn get_predicate_key(&self, name: RegType, arity: RegType) -> PredicateKey
- {
- let name = self.machine_st[name].clone();
+ fn get_predicate_key(&self, name: RegType, arity: RegType) -> PredicateKey {
+ let name = self.machine_st[name].clone();
let arity = self.machine_st[arity].clone();
let name = match self.machine_st.store(self.machine_st.deref(name)) {
Addr::Con(Constant::Atom(name, _)) => name,
- _ => unreachable!()
+ _ => unreachable!(),
};
let arity = match self.machine_st.store(self.machine_st.deref(arity)) {
- Addr::Con(Constant::Integer(arity)) =>
- arity.to_usize().unwrap(),
- _ => unreachable!()
+ Addr::Con(Constant::Integer(arity)) => arity.to_usize().unwrap(),
+ _ => unreachable!(),
};
(name, arity)
}
- fn print_new_dynamic_clause(&self, addrs: VecDeque<Addr>, name: ClauseName, arity: usize)
- -> String
- {
+ fn print_new_dynamic_clause(
+ &self,
+ addrs: VecDeque<Addr>,
+ name: ClauseName,
+ arity: usize,
+ ) -> String {
let mut output = PrinterOutputter::new();
output.append(format!(":- dynamic({}/{}). ", name.as_str(), arity).as_str());
output.result()
}
- fn abolish_dynamic_clause(&mut self, name: RegType, arity: RegType)
- {
+ fn abolish_dynamic_clause(&mut self, name: RegType, arity: RegType) {
let (name, arity) = self.get_predicate_key(name, arity);
if let Some(idx) = self.indices.code_dir.get(&(name.clone(), arity)) {
}
self.indices.remove_code_index((name.clone(), arity));
- self.indices.remove_clause_subsection(name.owning_module(), name, arity);
+ self.indices
+ .remove_clause_subsection(name.owning_module(), name, arity);
}
- fn abolish_dynamic_clause_in_module(&mut self, name: RegType, arity: RegType, module: RegType)
- {
+ fn abolish_dynamic_clause_in_module(&mut self, name: RegType, arity: RegType, module: RegType) {
let (name, arity) = self.get_predicate_key(name, arity);
let module_addr = self.machine_st[module].clone();
let module_name = match self.machine_st.store(self.machine_st.deref(module_addr)) {
- Addr::Con(Constant::Atom(module, _)) =>
- match self.indices.modules.get_mut(&module) {
- Some(ref mut module) => {
- module.code_dir.remove(&(name.clone(), arity));
- module.module_decl.name.clone()
- },
- _ => {
- self.machine_st.fail = true;
- return;
- }
- },
- _ => unreachable!()
+ Addr::Con(Constant::Atom(module, _)) => match self.indices.modules.get_mut(&module) {
+ Some(ref mut module) => {
+ module.code_dir.remove(&(name.clone(), arity));
+ module.module_decl.name.clone()
+ }
+ _ => {
+ self.machine_st.fail = true;
+ return;
+ }
+ },
+ _ => unreachable!(),
};
if let Some(idx) = self.indices.code_dir.get(&(name.clone(), arity)) {
}
self.indices.remove_code_index((name.clone(), arity));
- self.indices.remove_clause_subsection(module_name, name, arity);
+ self.indices
+ .remove_clause_subsection(module_name, name, arity);
}
- fn handle_eval_result_from_dynamic_compile(&mut self, pred_str: String, name: ClauseName,
- arity: usize, src: ClauseName)
- {
+ fn handle_eval_result_from_dynamic_compile(
+ &mut self,
+ pred_str: String,
+ name: ClauseName,
+ arity: usize,
+ src: ClauseName,
+ ) {
let machine_st = mem::replace(&mut self.machine_st, MachineState::new());
let result = self.compile_into_machine(parsing_stream(pred_str.as_bytes()), name, arity);
self.machine_st = machine_st;
if let EvalSession::Error(err) = result {
- let h = self.machine_st.heap.h;
+ let h = self.machine_st.heap.h;
let stub = MachineError::functor_stub(src, 1);
- let err = MachineError::session_error(h, err);
- let err = self.machine_st.error_form(err, stub);
+ let err = MachineError::session_error(h, err);
+ let err = self.machine_st.error_form(err, stub);
self.machine_st.throw_exception(err);
}
}
- fn recompile_dynamic_predicate_impl(&mut self, place: DynamicAssertPlace, name: ClauseName,
- arity: usize)
- {
+ fn recompile_dynamic_predicate_impl(
+ &mut self,
+ place: DynamicAssertPlace,
+ name: ClauseName,
+ arity: usize,
+ ) {
let stub = MachineError::functor_stub(place.predicate_name(), 1);
let pred_str = match self.machine_st.try_from_list(temp_v!(2), stub) {
Ok(addrs) => {
place.push_to_queue(&mut addrs, added_clause);
self.print_new_dynamic_clause(addrs, name.clone(), arity)
- },
- Err(err) =>
- return self.machine_st.throw_exception(err)
+ }
+ Err(err) => return self.machine_st.throw_exception(err),
};
self.handle_eval_result_from_dynamic_compile(pred_str, name, arity, place.predicate_name());
}
- fn set_module_atom_tbl(&mut self, module_addr: Addr, name: &mut ClauseName) -> bool
- {
+ fn set_module_atom_tbl(&mut self, module_addr: Addr, name: &mut ClauseName) -> bool {
let atom_tbl = match self.machine_st.store(self.machine_st.deref(module_addr)) {
- Addr::Con(Constant::Atom(module, _)) =>
- match self.indices.modules.get(&module) {
- Some(ref module) => module.atom_tbl.clone(),
- None => {
- self.machine_st.fail = true;
- return false;
- }
- },
- _ => unreachable!()
+ Addr::Con(Constant::Atom(module, _)) => match self.indices.modules.get(&module) {
+ Some(ref module) => module.atom_tbl.clone(),
+ None => {
+ self.machine_st.fail = true;
+ return false;
+ }
+ },
+ _ => unreachable!(),
};
if let &mut ClauseName::User(ref mut rc) = name {
true
}
- fn recompile_dynamic_predicate_in_module(&mut self, place: DynamicAssertPlace)
- {
+ fn recompile_dynamic_predicate_in_module(&mut self, place: DynamicAssertPlace) {
let (mut name, arity) = self.get_predicate_key(temp_v!(3), temp_v!(4));
let module_addr = self.machine_st[temp_v!(5)].clone();
}
}
- fn recompile_dynamic_predicate(&mut self, place: DynamicAssertPlace)
- {
+ fn recompile_dynamic_predicate(&mut self, place: DynamicAssertPlace) {
let (name, arity) = self.get_predicate_key(temp_v!(3), temp_v!(4));
self.recompile_dynamic_predicate_impl(place, name, arity);
}
- fn retract_from_dynamic_predicate_in_module(&mut self)
- {
+ fn retract_from_dynamic_predicate_in_module(&mut self) {
let index = self.machine_st[temp_v!(3)].clone();
let index = match self.machine_st.store(self.machine_st.deref(index)) {
Addr::Con(Constant::Integer(n)) => n.to_usize().unwrap(),
- _ => unreachable!()
+ _ => unreachable!(),
};
let (mut name, arity) = self.get_predicate_key(temp_v!(1), temp_v!(2));
addrs.remove(index);
if addrs.is_empty() {
- self.abolish_dynamic_clause_in_module(temp_v!(1), temp_v!(2),
- temp_v!(5));
+ self.abolish_dynamic_clause_in_module(temp_v!(1), temp_v!(2), temp_v!(5));
return;
}
self.print_new_dynamic_clause(addrs, name.clone(), arity)
- },
- Err(err) =>
- return self.machine_st.throw_exception(err)
+ }
+ Err(err) => return self.machine_st.throw_exception(err),
};
- self.handle_eval_result_from_dynamic_compile(pred_str, name, arity,
- clause_name!("retract"));
+ self.handle_eval_result_from_dynamic_compile(
+ pred_str,
+ name,
+ arity,
+ clause_name!("retract"),
+ );
}
}
- fn retract_from_dynamic_predicate(&mut self)
- {
+ fn retract_from_dynamic_predicate(&mut self) {
let index = self.machine_st[temp_v!(3)].clone();
let index = match self.machine_st.store(self.machine_st.deref(index)) {
Addr::Con(Constant::Integer(n)) => n.to_usize().unwrap(),
- _ => unreachable!()
+ _ => unreachable!(),
};
let (name, arity) = self.get_predicate_key(temp_v!(1), temp_v!(2));
}
self.print_new_dynamic_clause(addrs, name.clone(), arity)
- },
- Err(err) =>
- return self.machine_st.throw_exception(err)
+ }
+ Err(err) => return self.machine_st.throw_exception(err),
};
- self.handle_eval_result_from_dynamic_compile(pred_str, name, arity,
- clause_name!("retract"));
+ self.handle_eval_result_from_dynamic_compile(
+ pred_str,
+ name,
+ arity,
+ clause_name!("retract"),
+ );
}
- pub(super)
- fn dynamic_transaction(&mut self, trans_type: DynamicTransactionType, p: LocalCodePtr)
- {
+ pub(super) fn dynamic_transaction(
+ &mut self,
+ trans_type: DynamicTransactionType,
+ p: LocalCodePtr,
+ ) {
match trans_type {
- DynamicTransactionType::Abolish =>
- self.abolish_dynamic_clause(temp_v!(1), temp_v!(2)),
- DynamicTransactionType::Assert(place) =>
- self.recompile_dynamic_predicate(place),
- DynamicTransactionType::ModuleAbolish =>
- self.abolish_dynamic_clause_in_module(temp_v!(1), temp_v!(2), temp_v!(3)),
- DynamicTransactionType::ModuleAssert(place) =>
- self.recompile_dynamic_predicate_in_module(place),
- DynamicTransactionType::ModuleRetract =>
- self.retract_from_dynamic_predicate_in_module(),
- DynamicTransactionType::Retract =>
- self.retract_from_dynamic_predicate()
+ DynamicTransactionType::Abolish => self.abolish_dynamic_clause(temp_v!(1), temp_v!(2)),
+ DynamicTransactionType::Assert(place) => self.recompile_dynamic_predicate(place),
+ DynamicTransactionType::ModuleAbolish => {
+ self.abolish_dynamic_clause_in_module(temp_v!(1), temp_v!(2), temp_v!(3))
+ }
+ DynamicTransactionType::ModuleAssert(place) => {
+ self.recompile_dynamic_predicate_in_module(place)
+ }
+ DynamicTransactionType::ModuleRetract => {
+ self.retract_from_dynamic_predicate_in_module()
+ }
+ DynamicTransactionType::Retract => self.retract_from_dynamic_predicate(),
}
self.machine_st.p = CodePtr::Local(p);
impl Heap {
pub fn with_capacity(cap: usize) -> Self {
- Heap { heap: Vec::with_capacity(cap),
- h: 0 }
+ Heap {
+ heap: Vec::with_capacity(cap),
+ h: 0,
+ }
}
#[inline]
Heap {
heap: mem::replace(&mut self.heap, vec![]),
- h
+ h,
}
}
self.h = 0;
}
- pub fn to_list<Iter: Iterator<Item=Addr>>(&mut self, values: Iter) -> usize {
+ pub fn to_list<Iter: Iterator<Item = Addr>>(&mut self, values: Iter) -> usize {
let head_addr = self.h;
for value in values {
let h = self.h;
- self.push(HeapCellValue::Addr(Addr::Lis(h+1)));
+ self.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
self.push(HeapCellValue::Addr(value));
}
head_addr
}
- pub fn extend<Iter: Iterator<Item=HeapCellValue>>(&mut self, iter: Iter) {
+ pub fn extend<Iter: Iterator<Item = HeapCellValue>>(&mut self, iter: Iter) {
for hcv in iter {
self.push(hcv);
}
#[derive(Clone, Copy)]
enum ErrorProvenance {
Constructed, // if constructed, offset the addresses.
- Received // otherwise, preserve the addresses.
+ Received, // otherwise, preserve the addresses.
}
pub(super) struct MachineError {
stub: MachineStub,
location: Option<(usize, usize)>, // line_num, col_num
- from: ErrorProvenance
+ from: ErrorProvenance,
}
impl MachineError {
pub(super) fn functor_stub(name: ClauseName, arity: usize) -> MachineStub {
let name = HeapCellValue::Addr(Addr::Con(Constant::Atom(name, None)));
- functor!("/", 2, [name, heap_integer!(Integer::from(arity))], SharedOpDesc::new(400, YFX))
+ functor!(
+ "/",
+ 2,
+ [name, heap_integer!(Integer::from(arity))],
+ SharedOpDesc::new(400, YFX)
+ )
}
pub(super) fn evaluation_error(eval_error: EvalError) -> Self {
let stub = functor!("evaluation_error", 1, [heap_atom!(eval_error.as_str())]);
- MachineError { stub, location: None, from: ErrorProvenance::Received }
+ MachineError {
+ stub,
+ location: None,
+ from: ErrorProvenance::Received,
+ }
}
pub(super) fn type_error(valid_type: ValidType, culprit: Addr) -> Self {
- let stub = functor!("type_error", 2, [heap_atom!(valid_type.as_str()),
- HeapCellValue::Addr(culprit)]);
-
- MachineError { stub, location: None, from: ErrorProvenance::Received }
+ let stub = functor!(
+ "type_error",
+ 2,
+ [
+ heap_atom!(valid_type.as_str()),
+ HeapCellValue::Addr(culprit)
+ ]
+ );
+
+ MachineError {
+ stub,
+ location: None,
+ from: ErrorProvenance::Received,
+ }
}
- pub(super)
- fn module_resolution_error(h: usize, mod_name: ClauseName, name: ClauseName, arity: usize) -> Self
- {
+ pub(super) fn module_resolution_error(
+ h: usize,
+ mod_name: ClauseName,
+ name: ClauseName,
+ arity: usize,
+ ) -> Self {
let mod_name = HeapCellValue::Addr(Addr::Con(Constant::Atom(mod_name, None)));
let name = HeapCellValue::Addr(Addr::Con(Constant::Atom(name, None)));
- let mut stub = functor!("evaluation_error", 1, [HeapCellValue::Addr(Addr::HeapCell(h + 2))]);
-
- stub.append(&mut functor!("/", 2, [HeapCellValue::Addr(Addr::HeapCell(h + 2 + 3)),
- heap_integer!(Integer::from(arity))],
- SharedOpDesc::new(400, YFX)));
- stub.append(&mut functor!(":", 2, [mod_name, name], SharedOpDesc::new(600, XFY)));
-
- MachineError { stub, location: None, from: ErrorProvenance::Constructed }
+ let mut stub = functor!(
+ "evaluation_error",
+ 1,
+ [HeapCellValue::Addr(Addr::HeapCell(h + 2))]
+ );
+
+ stub.append(&mut functor!(
+ "/",
+ 2,
+ [
+ HeapCellValue::Addr(Addr::HeapCell(h + 2 + 3)),
+ heap_integer!(Integer::from(arity))
+ ],
+ SharedOpDesc::new(400, YFX)
+ ));
+ stub.append(&mut functor!(
+ ":",
+ 2,
+ [mod_name, name],
+ SharedOpDesc::new(600, XFY)
+ ));
+
+ MachineError {
+ stub,
+ location: None,
+ from: ErrorProvenance::Constructed,
+ }
}
- pub(super) fn existence_error(h: usize, err: ExistenceError) -> Self
- {
+ pub(super) fn existence_error(h: usize, err: ExistenceError) -> Self {
match err {
ExistenceError::Procedure(name, arity) => {
- let mut stub = functor!("existence_error", 2, [heap_atom!("procedure"), heap_str!(3 + h)]);
+ let mut stub = functor!(
+ "existence_error",
+ 2,
+ [heap_atom!("procedure"), heap_str!(3 + h)]
+ );
stub.append(&mut Self::functor_stub(name, arity));
- MachineError { stub, location: None, from: ErrorProvenance::Constructed }
- },
+ MachineError {
+ stub,
+ location: None,
+ from: ErrorProvenance::Constructed,
+ }
+ }
ExistenceError::Module(name) => {
let name = HeapCellValue::Addr(Addr::Con(Constant::Atom(name, None)));
let stub = functor!("existence_error", 2, [heap_atom!("module"), name]);
- MachineError { stub, location: None, from: ErrorProvenance::Constructed }
+ MachineError {
+ stub,
+ location: None,
+ from: ErrorProvenance::Constructed,
+ }
}
}
}
match err {
SessionError::ParserError(err) => Self::syntax_error(h, err),
SessionError::CannotOverwriteBuiltIn(pred_str)
- | SessionError::CannotOverwriteImport(pred_str) =>
- Self::permission_error(PermissionError::Modify, "private_procedure", pred_str),
- SessionError::InvalidFileName(filename) =>
- Self::existence_error(h, ExistenceError::Module(filename)),
- SessionError::ModuleDoesNotContainExport =>
- Self::permission_error(PermissionError::Access,
- "private_procedure",
- clause_name!("module_does_not_contain_claimed_export")),
- SessionError::ModuleNotFound =>
- Self::permission_error(PermissionError::Access,
- "private_procedure",
- clause_name!("module_does_not_exist")),
- SessionError::NoModuleDeclaration(name) =>
- Self::existence_error(h, ExistenceError::Module(name)),
- SessionError::OpIsInfixAndPostFix(op) =>
- Self::permission_error(PermissionError::Create,
- "operator",
- op),
- _ => unreachable!()
+ | SessionError::CannotOverwriteImport(pred_str) => {
+ Self::permission_error(PermissionError::Modify, "private_procedure", pred_str)
+ }
+ SessionError::InvalidFileName(filename) => {
+ Self::existence_error(h, ExistenceError::Module(filename))
+ }
+ SessionError::ModuleDoesNotContainExport => Self::permission_error(
+ PermissionError::Access,
+ "private_procedure",
+ clause_name!("module_does_not_contain_claimed_export"),
+ ),
+ SessionError::ModuleNotFound => Self::permission_error(
+ PermissionError::Access,
+ "private_procedure",
+ clause_name!("module_does_not_exist"),
+ ),
+ SessionError::NoModuleDeclaration(name) => {
+ Self::existence_error(h, ExistenceError::Module(name))
+ }
+ SessionError::OpIsInfixAndPostFix(op) => {
+ Self::permission_error(PermissionError::Create, "operator", op)
+ }
+ _ => unreachable!(),
}
}
- pub(super)
- fn permission_error(err: PermissionError, index_str: &'static str, pred_str: ClauseName) -> Self
- {
+ pub(super) fn permission_error(
+ err: PermissionError,
+ index_str: &'static str,
+ pred_str: ClauseName,
+ ) -> Self {
let pred_str = HeapCellValue::Addr(Addr::Con(Constant::Atom(pred_str, None)));
let err = vec![heap_atom!(err.as_str()), heap_atom!(index_str), pred_str];
stub.extend(err.into_iter());
- MachineError { stub, location: None, from: ErrorProvenance::Constructed }
+ MachineError {
+ stub,
+ location: None,
+ from: ErrorProvenance::Constructed,
+ }
}
fn arithmetic_error(h: usize, err: ArithmeticError) -> Self {
match err {
- ArithmeticError::UninstantiatedVar =>
- Self::instantiation_error(),
+ ArithmeticError::UninstantiatedVar => Self::instantiation_error(),
ArithmeticError::NonEvaluableFunctor(name, arity) => {
let name = HeapCellValue::Addr(Addr::Con(name));
- let culprit = functor!("/", 2, [name, heap_integer!(Integer::from(arity))],
- SharedOpDesc::new(400, YFX));
-
- let mut stub = Self::type_error(ValidType::Evaluable, Addr::HeapCell(3+h)).stub;
+ let culprit = functor!(
+ "/",
+ 2,
+ [name, heap_integer!(Integer::from(arity))],
+ SharedOpDesc::new(400, YFX)
+ );
+
+ let mut stub = Self::type_error(ValidType::Evaluable, Addr::HeapCell(3 + h)).stub;
stub.extend(culprit.into_iter());
- MachineError { stub, location: None, from: ErrorProvenance::Constructed }
+ MachineError {
+ stub,
+ location: None,
+ from: ErrorProvenance::Constructed,
+ }
}
}
}
stub.extend(err.into_iter());
- MachineError { stub, location, from: ErrorProvenance::Constructed }
+ MachineError {
+ stub,
+ location,
+ from: ErrorProvenance::Constructed,
+ }
}
pub(super) fn domain_error(error: DomainError, culprit: Addr) -> Self {
- let stub = functor!("domain_error", 2, [heap_atom!(error.as_str()),
- HeapCellValue::Addr(culprit)]);
- MachineError { stub, location: None, from: ErrorProvenance::Received }
+ let stub = functor!(
+ "domain_error",
+ 2,
+ [heap_atom!(error.as_str()), HeapCellValue::Addr(culprit)]
+ );
+ MachineError {
+ stub,
+ location: None,
+ from: ErrorProvenance::Received,
+ }
}
pub(super) fn instantiation_error() -> Self {
let stub = functor!("instantiation_error");
- MachineError { stub, location: None, from: ErrorProvenance::Received }
+ MachineError {
+ stub,
+ location: None,
+ from: ErrorProvenance::Received,
+ }
}
pub(super) fn representation_error(flag: RepFlag) -> Self {
let stub = functor!("representation_error", 1, [heap_atom!(flag.as_str())]);
- MachineError { stub, location: None, from: ErrorProvenance::Received }
+ MachineError {
+ stub,
+ location: None,
+ from: ErrorProvenance::Received,
+ }
}
- fn into_iter(self, offset: usize) -> Box<Iterator<Item=HeapCellValue>> {
+ fn into_iter(self, offset: usize) -> Box<Iterator<Item = HeapCellValue>> {
match self.from {
- ErrorProvenance::Constructed =>
- Box::new(self.stub.into_iter().map(move |hcv| {
- match hcv {
- HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr + offset),
- hcv => hcv
- }
- })),
- ErrorProvenance::Received =>
- Box::new(self.stub.into_iter())
+ ErrorProvenance::Constructed => {
+ Box::new(self.stub.into_iter().map(move |hcv| match hcv {
+ HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr + offset),
+ hcv => hcv,
+ }))
+ }
+ ErrorProvenance::Received => Box::new(self.stub.into_iter()),
}
}
match self {
PermissionError::Access => "access",
PermissionError::Create => "create",
- PermissionError::Modify => "modify"
+ PermissionError::Modify => "modify",
}
}
}
pub enum ValidType {
Atom,
Atomic,
-// Boolean,
-// Byte,
+ // Boolean,
+ // Byte,
Callable,
Character,
Compound,
Evaluable,
Float,
-// InByte,
-// InCharacter,
+ // InByte,
+ // InCharacter,
Integer,
List,
-// Number,
+ // Number,
Pair,
-// PredicateIndicator,
-// Variable
+ // PredicateIndicator,
+ // Variable
}
impl ValidType {
match self {
ValidType::Atom => "atom",
ValidType::Atomic => "atomic",
-// ValidType::Boolean => "boolean",
-// ValidType::Byte => "byte",
+ // ValidType::Boolean => "boolean",
+ // ValidType::Byte => "byte",
ValidType::Callable => "callable",
ValidType::Character => "character",
ValidType::Compound => "compound",
ValidType::Evaluable => "evaluable",
ValidType::Float => "float",
-// ValidType::InByte => "in_byte",
-// ValidType::InCharacter => "in_character",
+ // ValidType::InByte => "in_byte",
+ // ValidType::InCharacter => "in_character",
ValidType::Integer => "integer",
ValidType::List => "list",
-// ValidType::Number => "number",
+ // ValidType::Number => "number",
ValidType::Pair => "pair",
-// ValidType::PredicateIndicator => "predicate_indicator",
-// ValidType::Variable => "variable"
+ // ValidType::PredicateIndicator => "predicate_indicator",
+ // ValidType::Variable => "variable"
}
}
}
#[derive(Clone, Copy)]
pub enum DomainError {
- NotLessThanZero
+ NotLessThanZero,
}
impl DomainError {
pub fn as_str(self) -> &'static str {
match self {
- DomainError::NotLessThanZero => "not_less_than_zero"
+ DomainError::NotLessThanZero => "not_less_than_zero",
}
}
}
pub enum RepFlag {
Character,
CharacterCode,
-// InCharacterCode,
+ // InCharacterCode,
MaxArity,
-// MaxInteger,
-// MinInteger
+ // MaxInteger,
+ // MinInteger
}
impl RepFlag {
match self {
RepFlag::Character => "character",
RepFlag::CharacterCode => "character_code",
-// RepFlag::InCharacterCode => "in_character_code",
+ // RepFlag::InCharacterCode => "in_character_code",
RepFlag::MaxArity => "max_arity",
-// RepFlag::MaxInteger => "max_integer",
-// RepFlag::MinInteger => "min_integer"
+ // RepFlag::MaxInteger => "max_integer",
+ // RepFlag::MinInteger => "min_integer"
}
}
}
pub enum EvalError {
FloatOverflow,
Undefined,
-// Underflow,
+ // Underflow,
ZeroDivisor,
}
match self {
EvalError::FloatOverflow => "float_overflow",
EvalError::Undefined => "undefined",
-// EvalError::FloatUnderflow => "underflow",
+ // EvalError::FloatUnderflow => "underflow",
EvalError::ZeroDivisor => "zero_divisor",
}
}
EmptyList,
NotList,
PartialList(usize, usize), // the list length (up to max), and an offset into the heap.
- ProperList(usize), // the list length.
+ ProperList(usize), // the list length.
String(usize, StringList), // the number of elements iterated, the string tail.
- UntouchedList(usize) // the address of an uniterated Addr::Lis(address).
+ UntouchedList(usize), // the address of an uniterated Addr::Lis(address).
}
impl MachineState {
// see 8.4.3 of Draft Technical Corrigendum 2.
pub(super) fn check_sort_errors(&self) -> CallResult {
- let stub = MachineError::functor_stub(clause_name!("sort"), 2);
- let list = self.store(self.deref(self[temp_v!(1)].clone()));
+ let stub = MachineError::functor_stub(clause_name!("sort"), 2);
+ let list = self.store(self.deref(self[temp_v!(1)].clone()));
let sorted = self.store(self.deref(self[temp_v!(2)].clone()));
match self.detect_cycles(list.clone()) {
- CycleSearchResult::PartialList(..) =>
- return Err(self.error_form(MachineError::instantiation_error(), stub)),
- CycleSearchResult::NotList =>
- return Err(self.error_form(MachineError::type_error(ValidType::List, list), stub)),
+ CycleSearchResult::PartialList(..) => {
+ return Err(self.error_form(MachineError::instantiation_error(), stub))
+ }
+ CycleSearchResult::NotList => {
+ return Err(self.error_form(MachineError::type_error(ValidType::List, list), stub))
+ }
_ => {}
};
match self.detect_cycles(sorted.clone()) {
- CycleSearchResult::NotList if !sorted.is_ref() =>
- Err(self.error_form(MachineError::type_error(ValidType::List, sorted), stub)),
- _ => Ok(())
+ CycleSearchResult::NotList if !sorted.is_ref() => {
+ Err(self.error_form(MachineError::type_error(ValidType::List, sorted), stub))
+ }
+ _ => Ok(()),
}
}
let stub = MachineError::functor_stub(clause_name!("keysort"), 2);
match self.detect_cycles(list.clone()) {
- CycleSearchResult::NotList if !list.is_ref() =>
- Err(self.error_form(MachineError::type_error(ValidType::List, list), stub)),
+ CycleSearchResult::NotList if !list.is_ref() => {
+ Err(self.error_form(MachineError::type_error(ValidType::List, list), stub))
+ }
_ => {
let mut addr = list;
match self.heap[new_l].clone() {
HeapCellValue::Addr(Addr::Str(l)) => new_l = l,
HeapCellValue::NamedStr(2, ref name, Some(_))
- if name.as_str() == "-" => break,
+ if name.as_str() == "-" =>
+ {
+ break
+ }
HeapCellValue::Addr(Addr::HeapCell(_)) => break,
HeapCellValue::Addr(Addr::StackCell(..)) => break,
- _ => return Err(self.error_form(MachineError::type_error(ValidType::Pair,
- Addr::HeapCell(l)),
- stub))
+ _ => {
+ return Err(self.error_form(
+ MachineError::type_error(ValidType::Pair, Addr::HeapCell(l)),
+ stub,
+ ))
+ }
};
}
// see 8.4.4 of Draft Technical Corrigendum 2.
pub(super) fn check_keysort_errors(&self) -> CallResult {
- let stub = MachineError::functor_stub(clause_name!("keysort"), 2);
- let pairs = self.store(self.deref(self[temp_v!(1)].clone()));
+ let stub = MachineError::functor_stub(clause_name!("keysort"), 2);
+ let pairs = self.store(self.deref(self[temp_v!(1)].clone()));
let sorted = self.store(self.deref(self[temp_v!(2)].clone()));
match self.detect_cycles(pairs.clone()) {
- CycleSearchResult::PartialList(..) =>
- Err(self.error_form(MachineError::instantiation_error(), stub)),
- CycleSearchResult::NotList =>
- Err(self.error_form(MachineError::type_error(ValidType::List, pairs), stub)),
- _ => Ok(())
+ CycleSearchResult::PartialList(..) => {
+ Err(self.error_form(MachineError::instantiation_error(), stub))
+ }
+ CycleSearchResult::NotList => {
+ Err(self.error_form(MachineError::type_error(ValidType::List, pairs), stub))
+ }
+ _ => Ok(()),
}?;
self.check_for_list_pairs(sorted)
let err_len = err.len();
let h = self.heap.h;
- let mut stub = vec![HeapCellValue::NamedStr(2, clause_name!("error"), None),
- HeapCellValue::Addr(Addr::HeapCell(h + 3)),
- HeapCellValue::Addr(Addr::HeapCell(h + 3 + err_len))];
+ let mut stub = vec![
+ HeapCellValue::NamedStr(2, clause_name!("error"), None),
+ HeapCellValue::Addr(Addr::HeapCell(h + 3)),
+ HeapCellValue::Addr(Addr::HeapCell(h + 3 + err_len)),
+ ];
stub.extend(err.into_iter(3));
if let Some((line_num, _)) = location {
let colon_op_desc = Some(SharedOpDesc::new(600, XFY));
- stub.extend(vec![HeapCellValue::NamedStr(2, clause_name!(":"), colon_op_desc),
- HeapCellValue::Addr(Addr::HeapCell(h + 6 + err_len)),
- heap_integer!(Integer::from(line_num))].into_iter());
+ stub.extend(
+ vec![
+ HeapCellValue::NamedStr(2, clause_name!(":"), colon_op_desc),
+ HeapCellValue::Addr(Addr::HeapCell(h + 6 + err_len)),
+ heap_integer!(Integer::from(line_num)),
+ ]
+ .into_iter(),
+ );
}
stub.extend(src.into_iter());
pub enum ExistenceError {
Module(ClauseName),
- Procedure(ClauseName, usize)
+ Procedure(ClauseName, usize),
}
pub enum SessionError {
NoModuleDeclaration(ClauseName),
OpIsInfixAndPostFix(ClauseName),
ParserError(ParserError),
- UserPrompt
+ UserPrompt,
}
pub enum EvalSession {
#[derive(Clone, PartialEq, Eq, Hash)]
pub enum DBRef {
NamedPred(ClauseName, usize, Option<SharedOpDesc>),
- Op(usize, Specifier, ClauseName, Rc<OssifiedOpDir>, SharedOpDesc)
+ Op(
+ usize,
+ Specifier,
+ ClauseName,
+ Rc<OssifiedOpDir>,
+ SharedOpDesc,
+ ),
}
#[derive(Clone, PartialEq, Eq, Hash)]
Lis(usize),
HeapCell(usize),
StackCell(usize, usize),
- Str(usize)
+ Str(usize),
}
#[derive(Clone, Copy, Hash, Eq, PartialEq)]
pub enum Ref {
AttrVar(usize),
HeapCell(usize),
- StackCell(usize, usize)
+ StackCell(usize, usize),
}
impl Ref {
pub fn as_addr(self) -> Addr {
match self {
- Ref::AttrVar(h) => Addr::AttrVar(h),
- Ref::HeapCell(h) => Addr::HeapCell(h),
- Ref::StackCell(fr, sc) => Addr::StackCell(fr, sc)
+ Ref::AttrVar(h) => Addr::AttrVar(h),
+ Ref::HeapCell(h) => Addr::HeapCell(h),
+ Ref::StackCell(fr, sc) => Addr::StackCell(fr, sc),
}
}
}
impl PartialOrd<Ref> for Addr {
fn partial_cmp(&self, r: &Ref) -> Option<Ordering> {
match self {
- &Addr::StackCell(fr, sc) =>
- match *r {
- Ref::AttrVar(_) | Ref::HeapCell(_) =>
- Some(Ordering::Greater),
- Ref::StackCell(fr1, sc1) =>
- if fr1 < fr || (fr1 == fr && sc1 < sc) {
- Some(Ordering::Greater)
- } else if fr1 == fr && sc1 == sc {
- Some(Ordering::Equal)
- } else {
- Some(Ordering::Less)
- }
- },
- &Addr::HeapCell(h) | &Addr::AttrVar(h) =>
- match r {
- &Ref::StackCell(..) => Some(Ordering::Less),
- &Ref::AttrVar(h1) | &Ref::HeapCell(h1) => h.partial_cmp(&h1)
- },
- _ => None
+ &Addr::StackCell(fr, sc) => match *r {
+ Ref::AttrVar(_) | Ref::HeapCell(_) => Some(Ordering::Greater),
+ Ref::StackCell(fr1, sc1) => {
+ if fr1 < fr || (fr1 == fr && sc1 < sc) {
+ Some(Ordering::Greater)
+ } else if fr1 == fr && sc1 == sc {
+ Some(Ordering::Equal)
+ } else {
+ Some(Ordering::Less)
+ }
+ }
+ },
+ &Addr::HeapCell(h) | &Addr::AttrVar(h) => match r {
+ &Ref::StackCell(..) => Some(Ordering::Less),
+ &Ref::AttrVar(h1) | &Ref::HeapCell(h1) => h.partial_cmp(&h1),
+ },
+ _ => None,
}
}
}
pub fn is_ref(&self) -> bool {
match self {
&Addr::AttrVar(_) | &Addr::HeapCell(_) | &Addr::StackCell(_, _) => true,
- _ => false
+ _ => false,
}
}
&Addr::AttrVar(h) => Some(Ref::AttrVar(h)),
&Addr::HeapCell(h) => Some(Ref::HeapCell(h)),
&Addr::StackCell(fr, sc) => Some(Ref::StackCell(fr, sc)),
- _ => None
+ _ => None,
}
}
pub fn is_protected(&self, e: usize) -> bool {
match self {
&Addr::StackCell(addr, _) if addr >= e => false,
- _ => true
+ _ => true,
}
}
}
Addr::AttrVar(h) => Addr::AttrVar(h + rhs),
Addr::HeapCell(h) => Addr::HeapCell(h + rhs),
Addr::Str(s) => Addr::Str(s + rhs),
- _ => self
+ _ => self,
}
}
}
Addr::AttrVar(h) => Addr::AttrVar(h + rhs.abs() as usize),
Addr::HeapCell(h) => Addr::HeapCell(h + rhs.abs() as usize),
Addr::Str(s) => Addr::Str(s + rhs.abs() as usize),
- _ => self
+ _ => self,
}
} else {
self.sub(rhs as usize)
Addr::AttrVar(h) => Addr::AttrVar(h - rhs),
Addr::HeapCell(h) => Addr::HeapCell(h - rhs),
Addr::Str(s) => Addr::Str(s - rhs),
- _ => self
+ _ => self,
}
}
}
impl From<Ref> for Addr {
fn from(r: Ref) -> Self {
match r {
- Ref::AttrVar(h) => Addr::AttrVar(h),
- Ref::HeapCell(h) => Addr::HeapCell(h),
- Ref::StackCell(fr, sc) => Addr::StackCell(fr, sc)
+ Ref::AttrVar(h) => Addr::AttrVar(h),
+ Ref::HeapCell(h) => Addr::HeapCell(h),
+ Ref::StackCell(fr, sc) => Addr::StackCell(fr, sc),
}
}
}
#[derive(Clone)]
pub enum TrailRef {
Ref(Ref),
- AttrVarLink(usize, Addr)
+ AttrVarLink(usize, Addr),
}
impl From<Ref> for TrailRef {
pub fn as_addr(&self, focus: usize) -> Addr {
match self {
&HeapCellValue::Addr(ref a) => a.clone(),
- &HeapCellValue::NamedStr(_, _, _) => Addr::Str(focus)
+ &HeapCellValue::NamedStr(_, _, _) => Addr::Str(focus),
}
}
}
pub fn local(&self) -> Option<usize> {
match self.0.borrow().0 {
IndexPtr::Index(i) => Some(i),
- _ => None
+ _ => None,
}
}
}
impl Default for CodeIndex {
fn default() -> Self {
- CodeIndex(Rc::new(RefCell::new((IndexPtr::Undefined, clause_name!("")))))
+ CodeIndex(Rc::new(RefCell::new((
+ IndexPtr::Undefined,
+ clause_name!(""),
+ ))))
}
}
#[derive(Clone, Copy, PartialEq)]
pub enum DynamicAssertPlace {
- Back, Front
+ Back,
+ Front,
}
impl DynamicAssertPlace {
#[inline]
pub fn predicate_name(self) -> ClauseName {
match self {
- DynamicAssertPlace::Back => clause_name!("assertz"),
- DynamicAssertPlace::Front => clause_name!("asserta")
+ DynamicAssertPlace::Back => clause_name!("assertz"),
+ DynamicAssertPlace::Front => clause_name!("asserta"),
}
}
#[inline]
pub fn push_to_queue(self, addrs: &mut VecDeque<Addr>, new_addr: Addr) {
match self {
- DynamicAssertPlace::Back => addrs.push_back(new_addr),
- DynamicAssertPlace::Front => addrs.push_front(new_addr)
+ DynamicAssertPlace::Back => addrs.push_back(new_addr),
+ DynamicAssertPlace::Front => addrs.push_front(new_addr),
}
}
}
ModuleAbolish,
ModuleAssert(DynamicAssertPlace),
ModuleRetract,
- Retract // dynamic index of the clause to remove.
+ Retract, // dynamic index of the clause to remove.
}
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
pub enum REPLCodePtr {
CompileBatch,
- SubmitQueryAndPrintResults
+ SubmitQueryAndPrintResults,
}
#[derive(Clone, PartialEq)]
pub enum CodePtr {
BuiltInClause(BuiltInClauseType, LocalCodePtr), // local is the successor call.
- CallN(usize, LocalCodePtr), // arity, local.
+ CallN(usize, LocalCodePtr), // arity, local.
Local(LocalCodePtr),
DynamicTransaction(DynamicTransactionType, LocalCodePtr), // the type of transaction, the return pointer.
- REPL(REPLCodePtr, LocalCodePtr), // the REPL code, the return pointer.
- VerifyAttrInterrupt(usize) // location of the verify attribute interrupt code in the CodeDir.
+ REPL(REPLCodePtr, LocalCodePtr), // the REPL code, the return pointer.
+ VerifyAttrInterrupt(usize), // location of the verify attribute interrupt code in the CodeDir.
}
impl CodePtr {
pub fn local(&self) -> LocalCodePtr {
match self {
&CodePtr::BuiltInClause(_, ref local)
- | &CodePtr::CallN(_, ref local)
- | &CodePtr::Local(ref local) => local.clone(),
+ | &CodePtr::CallN(_, ref local)
+ | &CodePtr::Local(ref local) => local.clone(),
&CodePtr::VerifyAttrInterrupt(p) => LocalCodePtr::DirEntry(p),
- &CodePtr::REPL(_, p)
- | &CodePtr::DynamicTransaction(_, p) => p
+ &CodePtr::REPL(_, p) | &CodePtr::DynamicTransaction(_, p) => p,
}
}
}
InSituDirEntry(usize),
TopLevel(usize, usize), // chunk_num, offset.
UserGoalExpansion(usize),
- UserTermExpansion(usize)
+ UserTermExpansion(usize),
}
impl LocalCodePtr {
fn partial_cmp(&self, other: &CodePtr) -> Option<Ordering> {
match (self, other) {
(&CodePtr::Local(ref l1), &CodePtr::Local(ref l2)) => l1.partial_cmp(l2),
- _ => Some(Ordering::Greater)
+ _ => Some(Ordering::Greater),
}
}
}
fn partial_cmp(&self, other: &LocalCodePtr) -> Option<Ordering> {
match (self, other) {
(&LocalCodePtr::InSituDirEntry(p1), &LocalCodePtr::InSituDirEntry(ref p2))
- | (&LocalCodePtr::DirEntry(p1), &LocalCodePtr::DirEntry(ref p2))
- | (&LocalCodePtr::UserTermExpansion(p1), &LocalCodePtr::UserTermExpansion(ref p2))
- | (&LocalCodePtr::UserGoalExpansion(p1), &LocalCodePtr::UserGoalExpansion(ref p2))
- | (&LocalCodePtr::TopLevel(_, p1), &LocalCodePtr::TopLevel(_, ref p2)) =>
- p1.partial_cmp(p2),
- (_, &LocalCodePtr::TopLevel(_, _)) =>
- Some(Ordering::Less),
- _ => Some(Ordering::Greater)
+ | (&LocalCodePtr::DirEntry(p1), &LocalCodePtr::DirEntry(ref p2))
+ | (&LocalCodePtr::UserTermExpansion(p1), &LocalCodePtr::UserTermExpansion(ref p2))
+ | (&LocalCodePtr::UserGoalExpansion(p1), &LocalCodePtr::UserGoalExpansion(ref p2))
+ | (&LocalCodePtr::TopLevel(_, p1), &LocalCodePtr::TopLevel(_, ref p2)) => {
+ p1.partial_cmp(p2)
+ }
+ (_, &LocalCodePtr::TopLevel(_, _)) => Some(Ordering::Less),
+ _ => Some(Ordering::Greater),
}
}
}
fn add_assign(&mut self, rhs: usize) {
match self {
&mut LocalCodePtr::InSituDirEntry(ref mut p)
- | &mut LocalCodePtr::UserGoalExpansion(ref mut p)
- | &mut LocalCodePtr::UserTermExpansion(ref mut p)
- | &mut LocalCodePtr::DirEntry(ref mut p)
- | &mut LocalCodePtr::TopLevel(_, ref mut p) => *p += rhs
+ | &mut LocalCodePtr::UserGoalExpansion(ref mut p)
+ | &mut LocalCodePtr::UserTermExpansion(ref mut p)
+ | &mut LocalCodePtr::DirEntry(ref mut p)
+ | &mut LocalCodePtr::TopLevel(_, ref mut p) => *p += rhs,
}
}
}
fn add(self, rhs: usize) -> Self::Output {
match self {
p @ CodePtr::REPL(..)
- | p @ CodePtr::VerifyAttrInterrupt(_)
- | p @ CodePtr::DynamicTransaction(..) => p,
+ | p @ CodePtr::VerifyAttrInterrupt(_)
+ | p @ CodePtr::DynamicTransaction(..) => p,
CodePtr::Local(local) => CodePtr::Local(local + rhs),
- CodePtr::CallN(_, local) | CodePtr::BuiltInClause(_, local) => CodePtr::Local(local + rhs)
+ CodePtr::CallN(_, local) | CodePtr::BuiltInClause(_, local) => {
+ CodePtr::Local(local + rhs)
+ }
}
}
}
impl AddAssign<usize> for CodePtr {
fn add_assign(&mut self, rhs: usize) {
match self {
- &mut CodePtr::VerifyAttrInterrupt(_) => {},
+ &mut CodePtr::VerifyAttrInterrupt(_) => {}
&mut CodePtr::Local(ref mut local) => *local += rhs,
- _ => *self = CodePtr::Local(self.local() + rhs)
+ _ => *self = CodePtr::Local(self.local() + rhs),
}
}
}
-pub type HeapVarDict = IndexMap<Rc<Var>, Addr>;
+pub type HeapVarDict = IndexMap<Rc<Var>, Addr>;
pub type AllocVarDict = IndexMap<Rc<Var>, VarData>;
#[derive(Clone)]
impl Default for DynamicPredicateInfo {
fn default() -> Self {
- DynamicPredicateInfo { clauses_subsection_p: 0 }
+ DynamicPredicateInfo {
+ clauses_subsection_p: 0,
+ }
}
}
-pub type InSituCodeDir = IndexMap<PredicateKey, usize>;
+pub type InSituCodeDir = IndexMap<PredicateKey, usize>;
// key type: module name, predicate indicator.
pub type DynamicCodeDir = IndexMap<(ClauseName, ClauseName, usize), DynamicPredicateInfo>;
}
impl IndexStore {
- pub fn predicate_exists(&self, name: ClauseName, module: ClauseName, arity: usize,
- op_spec: Option<SharedOpDesc>)
- -> bool
- {
+ pub fn predicate_exists(
+ &self,
+ name: ClauseName,
+ module: ClauseName,
+ arity: usize,
+ op_spec: Option<SharedOpDesc>,
+ ) -> bool {
match self.modules.get(&module) {
- Some(module) =>
- match ClauseType::from(name, arity, op_spec) {
- ClauseType::Named(name, arity, _) =>
- module.code_dir.contains_key(&(name, arity)),
- ClauseType::Op(name, spec, ..) =>
- module.code_dir.contains_key(&(name, spec.arity())),
- _ =>
- true
- },
- None =>
- match ClauseType::from(name, arity, op_spec) {
- ClauseType::Named(name, arity, _) =>
- self.code_dir.contains_key(&(name, arity)),
- ClauseType::Op(name, spec, ..) =>
- self.code_dir.contains_key(&(name, spec.arity())),
- _ =>
- true
+ Some(module) => match ClauseType::from(name, arity, op_spec) {
+ ClauseType::Named(name, arity, _) => module.code_dir.contains_key(&(name, arity)),
+ ClauseType::Op(name, spec, ..) => {
+ module.code_dir.contains_key(&(name, spec.arity()))
}
+ _ => true,
+ },
+ None => match ClauseType::from(name, arity, op_spec) {
+ ClauseType::Named(name, arity, _) => self.code_dir.contains_key(&(name, arity)),
+ ClauseType::Op(name, spec, ..) => self.code_dir.contains_key(&(name, spec.arity())),
+ _ => true,
+ },
}
}
#[inline]
- pub fn remove_clause_subsection(&mut self, module: ClauseName, name: ClauseName, arity: usize)
- {
+ pub fn remove_clause_subsection(&mut self, module: ClauseName, name: ClauseName, arity: usize) {
self.dynamic_code_dir.remove(&(module, name, arity));
}
#[inline]
- pub fn get_clause_subsection(&self, module: ClauseName, name: ClauseName, arity: usize)
- -> Option<DynamicPredicateInfo>
- {
+ pub fn get_clause_subsection(
+ &self,
+ module: ClauseName,
+ name: ClauseName,
+ arity: usize,
+ ) -> Option<DynamicPredicateInfo> {
self.dynamic_code_dir.get(&(module, name, arity)).cloned()
}
in_situ_code_dir: InSituCodeDir::new(),
op_dir: default_op_dir(),
modules: ModuleDir::new(),
-// parsing_stream: readline::parsing_stream(String::new())
+ // parsing_stream: readline::parsing_stream(String::new())
}
}
}
#[inline]
- fn get_internal(&self, name: ClauseName, arity: usize, in_mod: ClauseName) -> Option<CodeIndex>
- {
- self.modules.get(&in_mod)
+ fn get_internal(
+ &self,
+ name: ClauseName,
+ arity: usize,
+ in_mod: ClauseName,
+ ) -> Option<CodeIndex> {
+ self.modules
+ .get(&in_mod)
.and_then(|ref module| module.code_dir.get(&(name, arity)))
.cloned()
}
pub(super) fn get_cleaner_sites(&self) -> (usize, usize) {
- let r_w_h = clause_name!("run_cleaners_with_handling");
+ let r_w_h = clause_name!("run_cleaners_with_handling");
let r_wo_h = clause_name!("run_cleaners_without_handling");
let non_iso = clause_name!("non_iso");
- let r_w_h = self.get_internal(r_w_h, 0, non_iso.clone()).and_then(|item| item.local());
- let r_wo_h = self.get_internal(r_wo_h, 1, non_iso).and_then(|item| item.local());
+ let r_w_h = self
+ .get_internal(r_w_h, 0, non_iso.clone())
+ .and_then(|item| item.local());
+ let r_wo_h = self
+ .get_internal(r_wo_h, 1, non_iso)
+ .and_then(|item| item.local());
if let Some(r_w_h) = r_w_h {
if let Some(r_wo_h) = r_wo_h {
GoalExpansion,
TermExpansion,
UserGoalExpansion,
- UserTermExpansion
+ UserTermExpansion,
}
impl CompileTimeHook {
pub fn name(self) -> ClauseName {
match self {
- CompileTimeHook::UserGoalExpansion
- | CompileTimeHook::GoalExpansion => clause_name!("goal_expansion"),
- CompileTimeHook::UserTermExpansion
- | CompileTimeHook::TermExpansion => clause_name!("term_expansion")
+ CompileTimeHook::UserGoalExpansion | CompileTimeHook::GoalExpansion => {
+ clause_name!("goal_expansion")
+ }
+ CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion => {
+ clause_name!("term_expansion")
+ }
}
}
#[inline]
pub fn arity(self) -> usize {
match self {
- CompileTimeHook::UserGoalExpansion
- | CompileTimeHook::GoalExpansion => 2,
- CompileTimeHook::UserTermExpansion
- | CompileTimeHook::TermExpansion => 2
+ CompileTimeHook::UserGoalExpansion | CompileTimeHook::GoalExpansion => 2,
+ CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion => 2,
}
}
#[inline]
pub fn user_scope(self) -> Self {
match self {
- CompileTimeHook::UserGoalExpansion | CompileTimeHook::GoalExpansion =>
- CompileTimeHook::UserGoalExpansion,
- CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion =>
- CompileTimeHook::UserTermExpansion,
+ CompileTimeHook::UserGoalExpansion | CompileTimeHook::GoalExpansion => {
+ CompileTimeHook::UserGoalExpansion
+ }
+ CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion => {
+ CompileTimeHook::UserTermExpansion
+ }
}
}
pub fn has_module_scope(self) -> bool {
match self {
CompileTimeHook::UserTermExpansion | CompileTimeHook::UserGoalExpansion => false,
- _ => true
+ _ => true,
}
}
}
pub enum RefOrOwned<'a, T: 'a> {
Borrowed(&'a T),
- Owned(T)
+ Owned(T),
}
impl<'a, T> RefOrOwned<'a, T> {
pub fn as_ref(&'a self) -> &'a T {
match self {
&RefOrOwned::Borrowed(r) => r,
- &RefOrOwned::Owned(ref r) => r
+ &RefOrOwned::Owned(ref r) => r,
}
}
pub fn to_owned(self) -> T
- where T: Clone
+ where
+ T: Clone,
{
match self {
RefOrOwned::Borrowed(item) => item.clone(),
- RefOrOwned::Owned(item) => item
+ RefOrOwned::Owned(item) => item,
}
}
}
use downcast::Any;
use std::cmp::Ordering;
-use std::io::{Write, stdout};
+use std::io::{stdout, Write};
use std::mem;
use std::ops::{Index, IndexMut};
impl Ball {
pub(super) fn new() -> Self {
- Ball { boundary: 0, stub: MachineStub::new() }
+ Ball {
+ boundary: 0,
+ stub: MachineStub::new(),
+ }
}
pub(super) fn reset(&mut self) {
Ball {
boundary,
- stub: mem::replace(&mut self.stub, vec![])
+ stub: mem::replace(&mut self.stub, vec![]),
}
}
}
pub(super) struct CopyTerm<'a> {
- state: &'a mut MachineState
+ state: &'a mut MachineState,
}
impl<'a> CopyTerm<'a> {
}
impl<'a> CopyBallTerm<'a> {
- pub(super) fn new(and_stack: &'a mut AndStack, heap: &'a mut Heap, stub: &'a mut MachineStub) -> Self
- {
+ pub(super) fn new(
+ and_stack: &'a mut AndStack,
+ heap: &'a mut Heap,
+ stub: &'a mut MachineStub,
+ ) -> Self {
let hb = heap.len();
- CopyBallTerm { and_stack, heap, heap_boundary: hb, stub }
+ CopyBallTerm {
+ and_stack,
+ heap,
+ heap_boundary: hb,
+ stub,
+ }
}
}
fn store(&self, addr: Addr) -> Addr {
match addr {
- Addr::HeapCell(h) | Addr::AttrVar(h) if h < self.heap_boundary =>
- self.heap[h].as_addr(h),
+ Addr::HeapCell(h) | Addr::AttrVar(h) if h < self.heap_boundary => {
+ self.heap[h].as_addr(h)
+ }
Addr::HeapCell(h) | Addr::AttrVar(h) => {
let index = h - self.heap_boundary;
self.stub[index].as_addr(h)
- },
- Addr::StackCell(fr, sc) =>
- self.and_stack[fr][sc].clone(),
- addr => addr
+ }
+ Addr::StackCell(fr, sc) => self.and_stack[fr][sc].clone(),
+ addr => addr,
}
}
}
return addr;
- };
+ }
}
fn stack(&mut self) -> &mut AndStack {
#[derive(Clone, Copy)]
pub(super) enum MachineMode {
Read,
- Write
+ Write,
}
pub struct MachineState {
pub(super) interms: Vec<Number>, // intermediate numbers.
pub(super) last_call: bool,
pub(crate) heap_locs: HeapVarDict,
- pub(crate) flags: MachineFlags
+ pub(crate) flags: MachineFlags,
}
impl MachineState {
- pub(super)
- fn try_char_list(&self, addrs: Vec<Addr>) -> Result<String, MachineError>
- {
+ pub(super) fn try_char_list(&self, addrs: Vec<Addr>) -> Result<String, MachineError> {
let mut chars = String::new();
let mut iter = addrs.iter();
while let Some(addr) = iter.next() {
match addr {
- &Addr::Con(Constant::String(ref s))
- if self.flags.double_quotes.is_chars() => {
- chars += s.borrow().as_str();
-
- if iter.next().is_some() {
- return Err(MachineError::type_error(ValidType::Character, addr.clone()));
- }
- },
- &Addr::Con(Constant::Char(c)) =>
- chars.push(c),
- &Addr::Con(Constant::Atom(ref name, _))
- if name.as_str().len() == 1 => {
- chars += name.as_str();
- },
- _ =>
- return Err(MachineError::type_error(ValidType::Character, addr.clone()))
+ &Addr::Con(Constant::String(ref s)) if self.flags.double_quotes.is_chars() => {
+ chars += s.borrow().as_str();
+
+ if iter.next().is_some() {
+ return Err(MachineError::type_error(ValidType::Character, addr.clone()));
+ }
+ }
+ &Addr::Con(Constant::Char(c)) => chars.push(c),
+ &Addr::Con(Constant::Atom(ref name, _)) if name.as_str().len() == 1 => {
+ chars += name.as_str();
+ }
+ _ => return Err(MachineError::type_error(ValidType::Character, addr.clone())),
}
}
Ok(chars)
}
- pub(super)
- fn try_code_list(&self, addrs: Vec<Addr>) -> Result<Vec<u8>, MachineError>
- {
+ pub(super) fn try_code_list(&self, addrs: Vec<Addr>) -> Result<Vec<u8>, MachineError> {
let mut codes = vec![];
- let mut iter = addrs.iter();
+ let mut iter = addrs.iter();
while let Some(addr) = iter.next() {
match addr {
- &Addr::Con(Constant::String(ref s))
- if self.flags.double_quotes.is_codes() => {
- codes.extend(s.borrow().chars().map(|c| c as u8));
-
- if iter.next().is_some() {
- return Err(MachineError::representation_error(RepFlag::CharacterCode));
- }
- },
- &Addr::Con(Constant::CharCode(c)) =>
- codes.push(c),
- &Addr::Con(Constant::Integer(ref n)) =>
+ &Addr::Con(Constant::String(ref s)) if self.flags.double_quotes.is_codes() => {
+ codes.extend(s.borrow().chars().map(|c| c as u8));
+
+ if iter.next().is_some() {
+ return Err(MachineError::representation_error(RepFlag::CharacterCode));
+ }
+ }
+ &Addr::Con(Constant::CharCode(c)) => codes.push(c),
+ &Addr::Con(Constant::Integer(ref n)) => {
if let Some(c) = n.to_u8() {
codes.push(c);
} else {
return Err(MachineError::representation_error(RepFlag::CharacterCode));
- },
- _ =>
- return Err(MachineError::representation_error(RepFlag::CharacterCode))
+ }
+ }
+ _ => return Err(MachineError::representation_error(RepFlag::CharacterCode)),
}
}
Ok(codes)
}
-
- fn call_at_index(&mut self, arity: usize, p: usize)
- {
+
+ fn call_at_index(&mut self, arity: usize, p: usize) {
self.cp.assign_if_local(self.p.clone() + 1);
self.num_of_args = arity;
self.b0 = self.b;
self.p = dir_entry!(p);
}
- pub(super)
- fn execute_at_index(&mut self, arity: usize, p: usize)
- {
+ pub(super) fn execute_at_index(&mut self, arity: usize, p: usize) {
self.num_of_args = arity;
self.b0 = self.b;
self.p = dir_entry!(p);
}
- pub(super)
- fn module_lookup(&mut self, indices: &IndexStore, key: PredicateKey, module_name: ClauseName,
- last_call: bool)
- -> CallResult
- {
+ pub(super) fn module_lookup(
+ &mut self,
+ indices: &IndexStore,
+ key: PredicateKey,
+ module_name: ClauseName,
+ last_call: bool,
+ ) -> CallResult {
let (name, arity) = key;
- if let Some(ref idx) = indices.get_code_index((name.clone(), arity), module_name.clone())
- {
+ if let Some(ref idx) = indices.get_code_index((name.clone(), arity), module_name.clone()) {
if let IndexPtr::Index(compiled_tl_index) = idx.0.borrow().0 {
if last_call {
self.execute_at_index(arity, compiled_tl_index);
}
}
-fn try_in_situ_lookup(name: ClauseName, arity: usize, indices: &IndexStore) -> Option<usize>
-{
+fn try_in_situ_lookup(name: ClauseName, arity: usize, indices: &IndexStore) -> Option<usize> {
match indices.in_situ_code_dir.get(&(name.clone(), arity)) {
Some(p) => Some(*p),
None => match indices.code_dir.get(&(name, arity)) {
- Some(ref idx) => if let &IndexPtr::Index(p) = &idx.0.borrow().0 {
- Some(p)
- } else {
- None
- },
- _ => None
- }
+ Some(ref idx) => {
+ if let &IndexPtr::Index(p) = &idx.0.borrow().0 {
+ Some(p)
+ } else {
+ None
+ }
+ }
+ _ => None,
+ },
}
}
-fn try_in_situ(machine_st: &mut MachineState, name: ClauseName, arity: usize,
- indices: &IndexStore, last_call: bool)
- -> CallResult
-{
+fn try_in_situ(
+ machine_st: &mut MachineState,
+ name: ClauseName,
+ arity: usize,
+ indices: &IndexStore,
+ last_call: bool,
+) -> CallResult {
if let Some(p) = try_in_situ_lookup(name.clone(), arity, indices) {
if last_call {
machine_st.execute_at_index(arity, p);
pub(crate) type CallResult = Result<(), Vec<HeapCellValue>>;
pub(crate) trait CallPolicy: Any {
- fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult
- {
+ fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
let b = machine_st.b - 1;
let n = machine_st.or_stack[b].num_args();
- for i in 1 .. n + 1 {
+ for i in 1..n + 1 {
machine_st.registers[i] = machine_st.or_stack[b][i].clone();
}
- machine_st.e = machine_st.or_stack[b].e;
+ machine_st.e = machine_st.or_stack[b].e;
machine_st.cp = machine_st.or_stack[b].cp.clone();
machine_st.or_stack[b].bp = machine_st.p.clone() + offset;
- let old_tr = machine_st.or_stack[b].tr;
+ let old_tr = machine_st.or_stack[b].tr;
let curr_tr = machine_st.tr;
machine_st.unwind_trail(old_tr, curr_tr);
machine_st.trail.truncate(machine_st.tr);
- let old_pstr_tr = machine_st.or_stack[b].pstr_tr;
+ let old_pstr_tr = machine_st.or_stack[b].pstr_tr;
let curr_pstr_tr = machine_st.pstr_tr;
machine_st.unwind_pstr_trail(old_pstr_tr, curr_pstr_tr);
machine_st.heap.truncate(machine_st.or_stack[b].h);
let attr_var_init_b = machine_st.or_stack[b].attr_var_init_b;
- machine_st.attr_var_init.attr_var_queue.truncate(attr_var_init_b);
+ machine_st
+ .attr_var_init
+ .attr_var_queue
+ .truncate(attr_var_init_b);
machine_st.hb = machine_st.heap.h;
machine_st.p += 1;
Ok(())
}
- fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult
- {
+ fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
let b = machine_st.b - 1;
let n = machine_st.or_stack[b].num_args();
- for i in 1 .. n + 1 {
+ for i in 1..n + 1 {
machine_st.registers[i] = machine_st.or_stack[b][i].clone();
}
- machine_st.e = machine_st.or_stack[b].e;
+ machine_st.e = machine_st.or_stack[b].e;
machine_st.cp = machine_st.or_stack[b].cp.clone();
machine_st.or_stack[b].bp = machine_st.p.clone() + 1;
- let old_tr = machine_st.or_stack[b].tr;
+ let old_tr = machine_st.or_stack[b].tr;
let curr_tr = machine_st.tr;
machine_st.unwind_trail(old_tr, curr_tr);
machine_st.trail.truncate(machine_st.tr);
- let old_pstr_tr = machine_st.or_stack[b].pstr_tr;
+ let old_pstr_tr = machine_st.or_stack[b].pstr_tr;
let curr_pstr_tr = machine_st.pstr_tr;
machine_st.unwind_pstr_trail(old_pstr_tr, curr_pstr_tr);
machine_st.heap.truncate(machine_st.or_stack[b].h);
let attr_var_init_b = machine_st.or_stack[b].attr_var_init_b;
- machine_st.attr_var_init.attr_var_queue.truncate(attr_var_init_b);
+ machine_st
+ .attr_var_init
+ .attr_var_queue
+ .truncate(attr_var_init_b);
machine_st.hb = machine_st.heap.h;
machine_st.p += offset;
Ok(())
}
- fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult
- {
+ fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
let b = machine_st.b - 1;
let n = machine_st.or_stack[b].num_args();
- for i in 1 .. n + 1 {
+ for i in 1..n + 1 {
machine_st.registers[i] = machine_st.or_stack[b][i].clone();
}
- machine_st.e = machine_st.or_stack[b].e;
+ machine_st.e = machine_st.or_stack[b].e;
machine_st.cp = machine_st.or_stack[b].cp.clone();
- let old_tr = machine_st.or_stack[b].tr;
+ let old_tr = machine_st.or_stack[b].tr;
let curr_tr = machine_st.tr;
machine_st.unwind_trail(old_tr, curr_tr);
machine_st.trail.truncate(machine_st.tr);
- let old_pstr_tr = machine_st.or_stack[b].pstr_tr;
+ let old_pstr_tr = machine_st.or_stack[b].pstr_tr;
let curr_pstr_tr = machine_st.pstr_tr;
machine_st.unwind_pstr_trail(old_pstr_tr, curr_pstr_tr);
machine_st.heap.truncate(machine_st.or_stack[b].h);
let attr_var_init_b = machine_st.or_stack[b].attr_var_init_b;
- machine_st.attr_var_init.attr_var_queue.truncate(attr_var_init_b);
+ machine_st
+ .attr_var_init
+ .attr_var_queue
+ .truncate(attr_var_init_b);
machine_st.b = machine_st.or_stack[b].b;
machine_st.or_stack.truncate(machine_st.b);
Ok(())
}
- fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult
- {
+ fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult {
let b = machine_st.b - 1;
let n = machine_st.or_stack[b].num_args();
- for i in 1 .. n + 1 {
+ for i in 1..n + 1 {
machine_st.registers[i] = machine_st.or_stack[b][i].clone();
}
- machine_st.e = machine_st.or_stack[b].e;
+ machine_st.e = machine_st.or_stack[b].e;
machine_st.cp = machine_st.or_stack[b].cp.clone();
- let old_tr = machine_st.or_stack[b].tr;
+ let old_tr = machine_st.or_stack[b].tr;
let curr_tr = machine_st.tr;
machine_st.unwind_trail(old_tr, curr_tr);
machine_st.trail.truncate(machine_st.tr);
- let old_pstr_tr = machine_st.or_stack[b].pstr_tr;
+ let old_pstr_tr = machine_st.or_stack[b].pstr_tr;
let curr_pstr_tr = machine_st.pstr_tr;
machine_st.unwind_pstr_trail(old_pstr_tr, curr_pstr_tr);
machine_st.heap.truncate(machine_st.or_stack[b].h);
let attr_var_init_b = machine_st.or_stack[b].attr_var_init_b;
- machine_st.attr_var_init.attr_var_queue.truncate(attr_var_init_b);
+ machine_st
+ .attr_var_init
+ .attr_var_queue
+ .truncate(attr_var_init_b);
machine_st.b = machine_st.or_stack[b].b;
machine_st.or_stack.truncate(machine_st.b);
Ok(())
}
- fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName,
- arity: usize, idx: CodeIndex, indices: &mut IndexStore)
- -> CallResult
- {
+ fn context_call(
+ &mut self,
+ machine_st: &mut MachineState,
+ name: ClauseName,
+ arity: usize,
+ idx: CodeIndex,
+ indices: &mut IndexStore,
+ ) -> CallResult {
if machine_st.last_call {
self.try_execute(machine_st, name, arity, idx, indices)
} else {
}
}
- fn try_call(&mut self, machine_st: &mut MachineState, name: ClauseName, arity: usize,
- idx: CodeIndex, indices: &IndexStore)
- -> CallResult
- {
+ fn try_call(
+ &mut self,
+ machine_st: &mut MachineState,
+ name: ClauseName,
+ arity: usize,
+ idx: CodeIndex,
+ indices: &IndexStore,
+ ) -> CallResult {
match idx.0.borrow().0 {
- IndexPtr::Undefined =>
- return try_in_situ(machine_st, name, arity, indices, false),
- IndexPtr::Index(compiled_tl_index) =>
+ IndexPtr::Undefined => return try_in_situ(machine_st, name, arity, indices, false),
+ IndexPtr::Index(compiled_tl_index) => {
machine_st.call_at_index(arity, compiled_tl_index)
+ }
}
Ok(())
}
- fn try_execute(&mut self, machine_st: &mut MachineState, name: ClauseName,
- arity: usize, idx: CodeIndex, indices: &IndexStore)
- -> CallResult
- {
+ fn try_execute(
+ &mut self,
+ machine_st: &mut MachineState,
+ name: ClauseName,
+ arity: usize,
+ idx: CodeIndex,
+ indices: &IndexStore,
+ ) -> CallResult {
match idx.0.borrow().0 {
- IndexPtr::Undefined =>
- return try_in_situ(machine_st, name, arity, indices, true),
- IndexPtr::Index(compiled_tl_index) =>
+ IndexPtr::Undefined => return try_in_situ(machine_st, name, arity, indices, true),
+ IndexPtr::Index(compiled_tl_index) => {
machine_st.execute_at_index(arity, compiled_tl_index)
+ }
}
Ok(())
}
- fn call_builtin(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType,
- indices: &mut IndexStore, parsing_stream: &mut PrologStream)
- -> CallResult
- {
+ fn call_builtin(
+ &mut self,
+ machine_st: &mut MachineState,
+ ct: &BuiltInClauseType,
+ indices: &mut IndexStore,
+ parsing_stream: &mut PrologStream,
+ ) -> 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!(machine_st.last_call, machine_st)
- },
+ }
&BuiltInClauseType::Arg => {
machine_st.try_arg()?;
return_from_clause!(machine_st.last_call, machine_st)
- },
+ }
&BuiltInClauseType::Compare => {
let a1 = machine_st[temp_v!(1)].clone();
let a2 = machine_st[temp_v!(2)].clone();
Ordering::Greater => {
let spec = fetch_atom_op_spec(clause_name!(">"), None, &indices.op_dir);
Addr::Con(Constant::Atom(clause_name!(">"), spec))
- },
+ }
Ordering::Equal => {
let spec = fetch_atom_op_spec(clause_name!("="), None, &indices.op_dir);
Addr::Con(Constant::Atom(clause_name!("="), spec))
- },
+ }
Ordering::Less => {
let spec = fetch_atom_op_spec(clause_name!("<"), None, &indices.op_dir);
Addr::Con(Constant::Atom(clause_name!("<"), spec))
machine_st.unify(a1, c);
return_from_clause!(machine_st.last_call, machine_st)
- },
+ }
&BuiltInClauseType::CompareTerm(qt) => {
machine_st.compare_term(qt);
return_from_clause!(machine_st.last_call, machine_st)
- },
+ }
&BuiltInClauseType::CyclicTerm => {
let addr = machine_st[temp_v!(1)].clone();
machine_st.fail = !machine_st.is_cyclic_term(addr);
return_from_clause!(machine_st.last_call, machine_st)
- },
+ }
&BuiltInClauseType::Nl => {
let mut stdout = stdout();
write!(stdout, "\n\r").unwrap();
stdout.flush().unwrap();
return_from_clause!(machine_st.last_call, machine_st)
- },
+ }
&BuiltInClauseType::Read => {
match machine_st.read(parsing_stream, indices.atom_tbl.clone(), &indices.op_dir) {
Ok(offset) => {
let addr = machine_st[temp_v!(1)].clone();
machine_st.unify(addr, Addr::HeapCell(offset.heap_loc));
- },
+ }
Err(e) => {
- let h = machine_st.heap.h;
+ let h = machine_st.heap.h;
let stub = MachineError::functor_stub(clause_name!("read"), 1);
- let err = MachineError::syntax_error(h, e);
- let err = machine_st.error_form(err, stub);
+ let err = MachineError::syntax_error(h, e);
+ let err = machine_st.error_form(err, stub);
return Err(err);
}
};
return_from_clause!(machine_st.last_call, machine_st)
- },
+ }
&BuiltInClauseType::CopyTerm => {
machine_st.copy_term();
return_from_clause!(machine_st.last_call, machine_st)
- },
+ }
&BuiltInClauseType::Eq => {
machine_st.fail = machine_st.eq_test();
return_from_clause!(machine_st.last_call, machine_st)
- },
+ }
&BuiltInClauseType::Ground => {
machine_st.fail = machine_st.ground_test();
return_from_clause!(machine_st.last_call, machine_st)
- },
+ }
&BuiltInClauseType::Functor => {
machine_st.try_functor(&indices)?;
return_from_clause!(machine_st.last_call, machine_st)
- },
+ }
&BuiltInClauseType::NotEq => {
let a1 = machine_st[temp_v!(1)].clone();
let a2 = machine_st[temp_v!(2)].clone();
};
return_from_clause!(machine_st.last_call, machine_st)
- },
+ }
&BuiltInClauseType::PartialString => {
let s = machine_st.try_string_list(temp_v!(1))?;
let a2 = machine_st[temp_v!(2)].clone();
machine_st.write_constant_to_var(a2, Constant::String(s));
return_from_clause!(machine_st.last_call, machine_st)
- },
+ }
&BuiltInClauseType::Sort => {
machine_st.check_sort_errors()?;
machine_st.unify(r2, heap_addr);
return_from_clause!(machine_st.last_call, machine_st)
- },
+ }
&BuiltInClauseType::KeySort => {
machine_st.check_keysort_errors()?;
machine_st.unify(r2, heap_addr);
return_from_clause!(machine_st.last_call, machine_st)
- },
+ }
&BuiltInClauseType::Is(r, ref at) => {
let a1 = machine_st[r].clone();
let a2 = machine_st.get_number(at)?;
machine_st.unify(a1, Addr::Con(a2.to_constant()));
return_from_clause!(machine_st.last_call, machine_st)
- },
+ }
}
}
- fn compile_hook(&mut self, machine_st: &mut MachineState, hook: &CompileTimeHook) -> CallResult
- {
+ fn compile_hook(
+ &mut self,
+ machine_st: &mut MachineState,
+ hook: &CompileTimeHook,
+ ) -> CallResult {
machine_st.cp = LocalCodePtr::TopLevel(0, 0);
machine_st.num_of_args = hook.arity();
machine_st.b0 = machine_st.b;
machine_st.p = match hook {
- CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion =>
- CodePtr::Local(LocalCodePtr::UserTermExpansion(0)),
- CompileTimeHook::UserGoalExpansion | CompileTimeHook::GoalExpansion =>
+ CompileTimeHook::UserTermExpansion | CompileTimeHook::TermExpansion => {
+ CodePtr::Local(LocalCodePtr::UserTermExpansion(0))
+ }
+ CompileTimeHook::UserGoalExpansion | CompileTimeHook::GoalExpansion => {
CodePtr::Local(LocalCodePtr::UserGoalExpansion(0))
+ }
};
Ok(())
}
- fn call_n(&mut self, machine_st: &mut MachineState, arity: usize, indices: &mut IndexStore,
- parsing_stream: &mut PrologStream)
- -> CallResult
- {
+ fn call_n(
+ &mut self,
+ machine_st: &mut MachineState,
+ arity: usize,
+ indices: &mut IndexStore,
+ parsing_stream: &mut PrologStream,
+ ) -> CallResult {
if let Some((name, arity)) = machine_st.setup_call_n(arity) {
match ClauseType::from(name.clone(), arity, None) {
ClauseType::CallN => {
}
machine_st.p = CodePtr::CallN(arity, machine_st.p.local());
- },
+ }
ClauseType::BuiltIn(built_in) => {
machine_st.setup_built_in_call(built_in.clone());
self.call_builtin(machine_st, &built_in, indices, parsing_stream)?;
- },
+ }
ClauseType::Inlined(inlined) => {
machine_st.execute_inlined(&inlined);
if machine_st.last_call {
machine_st.p = CodePtr::Local(machine_st.cp);
}
- },
+ }
ClauseType::Op(..) | ClauseType::Named(..) => {
let module = name.owning_module();
let stub = MachineError::functor_stub(clause_name!("call"), arity + 1);
let key = ExistenceError::Procedure(name, arity);
- return Err(machine_st.error_form(MachineError::existence_error(h, key),
- stub));
+ return Err(
+ machine_st.error_form(MachineError::existence_error(h, key), stub)
+ );
}
- },
+ }
ClauseType::Hook(_) | ClauseType::System(_) => {
let name = Addr::Con(Constant::Atom(name, None));
let stub = MachineError::functor_stub(clause_name!("call"), arity + 1);
- return Err(machine_st.error_form(MachineError::type_error(ValidType::Callable,
- name),
- stub));
+ return Err(machine_st
+ .error_form(MachineError::type_error(ValidType::Callable, name), stub));
}
};
}
}
impl CallPolicy for CWILCallPolicy {
- fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName,
- arity: usize, idx: CodeIndex, indices: &mut IndexStore)
- -> CallResult
- {
- self.prev_policy.context_call(machine_st, name, arity, idx, indices)?;
+ fn context_call(
+ &mut self,
+ machine_st: &mut MachineState,
+ name: ClauseName,
+ arity: usize,
+ idx: CodeIndex,
+ indices: &mut IndexStore,
+ ) -> CallResult {
+ self.prev_policy
+ .context_call(machine_st, name, arity, idx, indices)?;
self.increment(machine_st)
}
- fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult
- {
+ fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
self.prev_policy.retry_me_else(machine_st, offset)?;
self.increment(machine_st)
}
- fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult
- {
+ fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
self.prev_policy.retry(machine_st, offset)?;
self.increment(machine_st)
}
- fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult
- {
+ fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult {
self.prev_policy.trust_me(machine_st)?;
self.increment(machine_st)
}
- fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult
- {
+ fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
self.prev_policy.trust(machine_st, offset)?;
self.increment(machine_st)
}
- fn call_builtin(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType,
- indices: &mut IndexStore, parsing_stream: &mut PrologStream)
- -> CallResult
- {
- self.prev_policy.call_builtin(machine_st, ct, indices, parsing_stream)?;
+ fn call_builtin(
+ &mut self,
+ machine_st: &mut MachineState,
+ ct: &BuiltInClauseType,
+ indices: &mut IndexStore,
+ parsing_stream: &mut PrologStream,
+ ) -> CallResult {
+ self.prev_policy
+ .call_builtin(machine_st, ct, indices, parsing_stream)?;
self.increment(machine_st)
}
- fn call_n(&mut self, machine_st: &mut MachineState, arity: usize, indices: &mut IndexStore,
- parsing_stream: &mut PrologStream)
- -> CallResult
- {
- self.prev_policy.call_n(machine_st, arity, indices, parsing_stream)?;
+ fn call_n(
+ &mut self,
+ machine_st: &mut MachineState,
+ arity: usize,
+ indices: &mut IndexStore,
+ parsing_stream: &mut PrologStream,
+ ) -> CallResult {
+ self.prev_policy
+ .call_n(machine_st, arity, indices, parsing_stream)?;
self.increment(machine_st)
}
}
pub(crate) struct CWILCallPolicy {
pub(crate) prev_policy: Box<CallPolicy>,
- count: Integer,
+ count: Integer,
limits: Vec<(Integer, usize)>,
- inference_limit_exceeded: bool
+ inference_limit_exceeded: bool,
}
impl CWILCallPolicy {
- pub(crate) fn new_in_place(policy: &mut Box<CallPolicy>)
- {
+ pub(crate) fn new_in_place(policy: &mut Box<CallPolicy>) {
let mut prev_policy: Box<CallPolicy> = Box::new(DefaultCallPolicy {});
mem::swap(&mut prev_policy, policy);
- let new_policy = CWILCallPolicy { prev_policy,
- count: Integer::from(0),
- limits: vec![],
- inference_limit_exceeded: false };
+ let new_policy = CWILCallPolicy {
+ prev_policy,
+ count: Integer::from(0),
+ limits: vec![],
+ inference_limit_exceeded: false,
+ };
*policy = Box::new(new_policy);
}
if let Some(&(ref limit, bp)) = self.limits.last() {
if self.count == *limit {
self.inference_limit_exceeded = true;
- return Err(functor!("inference_limit_exceeded", 1,
- [HeapCellValue::Addr(Addr::Con(Constant::Usize(bp)))]));
+ return Err(functor!(
+ "inference_limit_exceeded",
+ 1,
+ [HeapCellValue::Addr(Addr::Con(Constant::Usize(bp)))]
+ ));
} else {
self.count += 1;
}
limit += &self.count;
match self.limits.last().cloned() {
- Some((ref inner_limit, _)) if *inner_limit <= limit => {},
- _ => self.limits.push((limit, b))
+ Some((ref inner_limit, _)) if *inner_limit <= limit => {}
+ _ => self.limits.push((limit, b)),
};
&self.count
pub(crate) struct SCCCutPolicy {
// locations of cleaners, cut points, the previous block
cont_pts: Vec<(Addr, usize, usize)>,
- r_c_w_h: usize,
- r_c_wo_h: usize
+ r_c_w_h: usize,
+ r_c_wo_h: usize,
}
impl SCCCutPolicy {
pub(crate) fn new(r_c_w_h: usize, r_c_wo_h: usize) -> Self {
- SCCCutPolicy { cont_pts: vec![], r_c_w_h, r_c_wo_h }
+ SCCCutPolicy {
+ cont_pts: vec![],
+ r_c_w_h,
+ r_c_wo_h,
+ }
}
pub(crate) fn out_of_cont_pts(&self) -> bool {
use prolog::heap_iter::*;
use prolog::heap_print::*;
use prolog::instructions::*;
-use prolog::machine::attributed_variables::*;
use prolog::machine::and_stack::*;
+use prolog::machine::attributed_variables::*;
use prolog::machine::code_repo::CodeRepo;
use prolog::machine::copier::*;
use prolog::machine::heap::*;
-use prolog::machine::or_stack::*;
use prolog::machine::machine_errors::*;
use prolog::machine::machine_indices::*;
use prolog::machine::machine_state::*;
+use prolog::machine::or_stack::*;
use prolog::ordered_float::*;
-use prolog::rug::{Integer, Rational};
use prolog::read::PrologStream;
+use prolog::rug::{Integer, Rational};
use indexmap::{IndexMap, IndexSet};
-use std::cmp::{min, max, Ordering};
+use std::cmp::{max, min, Ordering};
use std::f64;
use std::mem;
use std::rc::Rc;
macro_rules! try_numeric_result {
($s: ident, $e: expr, $caller: expr) => {{
match $e {
- Ok(val) =>
- Ok(val),
- Err(e) =>
- Err($s.error_form(MachineError::evaluation_error(e), $caller))
+ Ok(val) => Ok(val),
+ Err(e) => Err($s.error_form(MachineError::evaluation_error(e), $caller)),
}
- }}
+ }};
}
macro_rules! try_or_fail {
($s:ident, $e:expr) => {{
match $e {
- Ok(val) => val,
+ Ok(val) => val,
Err(msg) => {
$s.throw_exception(msg);
return;
}
}
- }}
+ }};
}
impl MachineState {
interms: vec![Number::default(); 256],
last_call: false,
heap_locs: HeapVarDict::new(),
- flags: MachineFlags::default()
+ flags: MachineFlags::default(),
}
}
interms: vec![Number::default(); 0],
last_call: false,
heap_locs: HeapVarDict::new(),
- flags: MachineFlags::default()
+ flags: MachineFlags::default(),
}
}
#[allow(dead_code)]
pub fn print_heap(&self) {
- for h in 0 .. self.heap.h {
+ for h in 0..self.heap.h {
println!("{} : {}", h, self.heap[h]);
}
}
}
fn next_global_index(&self) -> usize {
- max(if self.and_stack.len() > 0 { self.and_stack[self.e].global_index } else { 0 },
- if self.b > 0 { self.or_stack[self.b - 1].global_index } else { 0 }) + 1
+ max(
+ if self.and_stack.len() > 0 {
+ self.and_stack[self.e].global_index
+ } else {
+ 0
+ },
+ if self.b > 0 {
+ self.or_stack[self.b - 1].global_index
+ } else {
+ 0
+ },
+ ) + 1
}
pub(crate) fn store(&self, addr: Addr) -> Addr {
match addr {
Addr::AttrVar(h) | Addr::HeapCell(h) => self.heap[h].as_addr(h),
Addr::StackCell(fr, sc) => self.and_stack[fr][sc].clone(),
- addr => addr
+ addr => addr,
}
}
}
return addr;
- };
+ }
}
fn bind_attr_var(&mut self, h: usize, addr: Addr) {
Some(Ref::HeapCell(hc)) => {
self.heap[hc] = HeapCellValue::Addr(Addr::AttrVar(h));
self.trail(TrailRef::Ref(Ref::HeapCell(hc)));
- },
+ }
Some(Ref::StackCell(fr, sc)) => {
self.and_stack[fr][sc] = Addr::AttrVar(h);
self.trail(TrailRef::Ref(Ref::StackCell(fr, sc)));
- },
+ }
_ => {
self.push_attr_var_binding(h, addr.clone());
self.heap[h] = HeapCellValue::Addr(addr);
if t1.is_ref() && (!t2.is_ref() || a2 < r1) {
match r1 {
- Ref::StackCell(fr, sc) =>
- self.and_stack[fr][sc] = t2,
- Ref::HeapCell(h) =>
- self.heap[h] = HeapCellValue::Addr(t2),
- Ref::AttrVar(h) =>
- return self.bind_attr_var(h, t2)
+ Ref::StackCell(fr, sc) => self.and_stack[fr][sc] = t2,
+ Ref::HeapCell(h) => self.heap[h] = HeapCellValue::Addr(t2),
+ Ref::AttrVar(h) => return self.bind_attr_var(h, t2),
};
self.trail(TrailRef::from(r1));
Some(Ref::StackCell(fr, sc)) => {
self.and_stack[fr][sc] = t1;
self.trail(TrailRef::Ref(Ref::StackCell(fr, sc)));
- },
+ }
Some(Ref::HeapCell(h)) => {
self.heap[h] = HeapCellValue::Addr(t1);
self.trail(TrailRef::Ref(Ref::HeapCell(h)));
- },
- Some(Ref::AttrVar(h)) =>
- return self.bind_attr_var(h, t1),
+ }
+ Some(Ref::AttrVar(h)) => return self.bind_attr_var(h, t1),
None => {}
}
}
}
- pub(super)
- fn print_var_eq<Outputter>(&self, var: Rc<Var>, addr: Addr, op_dir: &OpDir, mut output: Outputter)
- -> Outputter
- where Outputter: HCValueOutputter
+ pub(super) fn print_var_eq<Outputter>(
+ &self,
+ var: Rc<Var>,
+ addr: Addr,
+ op_dir: &OpDir,
+ mut output: Outputter,
+ ) -> Outputter
+ where
+ Outputter: HCValueOutputter,
{
let orig_len = output.len();
output
}
- pub(super)
- fn unify_strings(&mut self, pdl: &mut Vec<Addr>, s1: &mut StringList, s2: &mut StringList) -> bool
- {
+ pub(super) fn unify_strings(
+ &mut self,
+ pdl: &mut Vec<Addr>,
+ s1: &mut StringList,
+ s2: &mut StringList,
+ ) -> bool {
if let Some(c1) = s1.head() {
if let Some(c2) = s2.head() {
if c1 == c2 {
false
}
- fn deconstruct_chars(&mut self, s: &mut StringList, offset: usize, pdl: &mut Vec<Addr>) -> bool
- {
+ fn deconstruct_chars(
+ &mut self,
+ s: &mut StringList,
+ offset: usize,
+ pdl: &mut Vec<Addr>,
+ ) -> bool {
if let Some(c) = s.head() {
pdl.push(Addr::Con(Constant::String(s.tail())));
pdl.push(Addr::HeapCell(offset + 1));
self.pstr_trail(prev_s);
stepper(c);
return true;
- },
- HeapCellValue::Addr(Addr::Con(Constant::Atom(ref a, _))) =>
+ }
+ HeapCellValue::Addr(Addr::Con(Constant::Atom(ref a, _))) => {
if let Some(c) = a.as_str().chars().next() {
if c.len_utf8() == a.as_str().len() {
self.pstr_trail(prev_s);
stepper(c);
return true;
}
- },
+ }
+ }
_ => {}
}
}
false
}
- fn deconstruct_codes(&mut self, s: &mut StringList, offset: usize, pdl: &mut Vec<Addr>) -> bool
- {
+ fn deconstruct_codes(
+ &mut self,
+ s: &mut StringList,
+ offset: usize,
+ pdl: &mut Vec<Addr>,
+ ) -> bool {
if let Some(c) = s.head() {
pdl.push(Addr::Con(Constant::String(s.tail())));
pdl.push(Addr::HeapCell(offset + 1));
self.pstr_trail(prev_s);
stepper(c as char);
return true;
- },
- HeapCellValue::Addr(Addr::Con(Constant::Integer(n))) =>
+ }
+ HeapCellValue::Addr(Addr::Con(Constant::Integer(n))) => {
if let Some(c) = n.to_u8() {
self.pstr_trail(prev_s);
stepper(c as char);
return true;
- },
+ }
+ }
_ => {}
}
}
}
match (d1.clone(), d2.clone()) {
- (Addr::AttrVar(h), addr) | (addr, Addr::AttrVar(h)) =>
- self.bind_with_occurs_check(Ref::AttrVar(h), addr),
- (Addr::HeapCell(h), addr) | (addr, Addr::HeapCell(h)) =>
- self.bind_with_occurs_check(Ref::HeapCell(h), addr),
- (Addr::StackCell(fr, sc), addr) | (addr, Addr::StackCell(fr, sc)) =>
- self.bind_with_occurs_check(Ref::StackCell(fr, sc), addr),
+ (Addr::AttrVar(h), addr) | (addr, Addr::AttrVar(h)) => {
+ self.bind_with_occurs_check(Ref::AttrVar(h), addr)
+ }
+ (Addr::HeapCell(h), addr) | (addr, Addr::HeapCell(h)) => {
+ self.bind_with_occurs_check(Ref::HeapCell(h), addr)
+ }
+ (Addr::StackCell(fr, sc), addr) | (addr, Addr::StackCell(fr, sc)) => {
+ self.bind_with_occurs_check(Ref::StackCell(fr, sc), addr)
+ }
(Addr::Lis(a1), Addr::Str(a2)) | (Addr::Str(a2), Addr::Lis(a1)) => {
if let &HeapCellValue::NamedStr(n2, ref f2, _) = &self.heap[a2] {
if f2.as_str() == "." && n2 == 2 {
}
self.fail = true;
- },
+ }
(Addr::Lis(a1), Addr::Con(Constant::String(ref mut s)))
- | (Addr::Con(Constant::String(ref mut s)), Addr::Lis(a1)) => {
- if match self.flags.double_quotes {
- DoubleQuotes::Chars => self.deconstruct_chars(s, a1, &mut pdl),
- DoubleQuotes::Codes => self.deconstruct_codes(s, a1, &mut pdl),
- DoubleQuotes::Atom => false
- } {
- continue;
- }
-
- self.fail = true;
- },
+ | (Addr::Con(Constant::String(ref mut s)), Addr::Lis(a1)) => {
+ if match self.flags.double_quotes {
+ DoubleQuotes::Chars => self.deconstruct_chars(s, a1, &mut pdl),
+ DoubleQuotes::Codes => self.deconstruct_codes(s, a1, &mut pdl),
+ DoubleQuotes::Atom => false,
+ } {
+ continue;
+ }
+
+ self.fail = true;
+ }
(Addr::Con(Constant::EmptyList), Addr::Con(Constant::String(ref s)))
- | (Addr::Con(Constant::String(ref s)), Addr::Con(Constant::EmptyList))
- if !self.flags.double_quotes.is_atom() => {
- if s.is_expandable() && s.is_empty() {
- self.pstr_trail(s.clone());
- s.set_expandable(false);
- continue;
- }
+ | (Addr::Con(Constant::String(ref s)), Addr::Con(Constant::EmptyList))
+ if !self.flags.double_quotes.is_atom() =>
+ {
+ if s.is_expandable() && s.is_empty() {
+ self.pstr_trail(s.clone());
+ s.set_expandable(false);
+ continue;
+ }
- self.fail = !s.is_empty();
- },
+ self.fail = !s.is_empty();
+ }
(Addr::Lis(a1), Addr::Lis(a2)) => {
pdl.push(Addr::HeapCell(a1));
pdl.push(Addr::HeapCell(a2));
pdl.push(Addr::HeapCell(a1 + 1));
pdl.push(Addr::HeapCell(a2 + 1));
- },
- (Addr::Con(Constant::String(ref mut s1)),
- Addr::Con(Constant::String(ref mut s2))) =>
+ }
+ (
+ Addr::Con(Constant::String(ref mut s1)),
+ Addr::Con(Constant::String(ref mut s2)),
+ ) => {
self.fail = !(self.unify_strings(&mut pdl, s1, s2)
- || self.unify_strings(&mut pdl, s2, s1)),
- (Addr::Con(ref c1), Addr::Con(ref c2)) =>
+ || self.unify_strings(&mut pdl, s2, s1))
+ }
+ (Addr::Con(ref c1), Addr::Con(ref c2)) => {
if c1 != c2 {
self.fail = true;
- },
+ }
+ }
(Addr::Str(a1), Addr::Str(a2)) => {
let r1 = &self.heap[a1];
let r2 = &self.heap[a2];
if let &HeapCellValue::NamedStr(n1, ref f1, _) = r1 {
if let &HeapCellValue::NamedStr(n2, ref f2, _) = r2 {
if n1 == n2 && *f1 == *f2 {
- for i in 1 .. n1 + 1 {
+ for i in 1..n1 + 1 {
pdl.push(Addr::HeapCell(a1 + i));
pdl.push(Addr::HeapCell(a2 + i));
}
}
self.fail = true;
- },
- _ => self.fail = true
+ }
+ _ => self.fail = true,
};
}
}
}
match (d1.clone(), d2.clone()) {
- (Addr::AttrVar(h), addr) | (addr, Addr::AttrVar(h)) =>
- self.bind(Ref::AttrVar(h), addr),
- (Addr::HeapCell(h), _) =>
- self.bind(Ref::HeapCell(h), d2),
- (_, Addr::HeapCell(h)) =>
- self.bind(Ref::HeapCell(h), d1),
- (Addr::StackCell(fr, sc), _) =>
- self.bind(Ref::StackCell(fr, sc), d2),
- (_, Addr::StackCell(fr, sc)) =>
- self.bind(Ref::StackCell(fr, sc), d1),
+ (Addr::AttrVar(h), addr) | (addr, Addr::AttrVar(h)) => {
+ self.bind(Ref::AttrVar(h), addr)
+ }
+ (Addr::HeapCell(h), _) => self.bind(Ref::HeapCell(h), d2),
+ (_, Addr::HeapCell(h)) => self.bind(Ref::HeapCell(h), d1),
+ (Addr::StackCell(fr, sc), _) => self.bind(Ref::StackCell(fr, sc), d2),
+ (_, Addr::StackCell(fr, sc)) => self.bind(Ref::StackCell(fr, sc), d1),
(Addr::Lis(a1), Addr::Str(a2)) | (Addr::Str(a2), Addr::Lis(a1)) => {
if let &HeapCellValue::NamedStr(n2, ref f2, _) = &self.heap[a2] {
if f2.as_str() == "." && n2 == 2 {
}
self.fail = true;
- },
+ }
(Addr::Lis(a1), Addr::Con(Constant::String(ref mut s)))
- | (Addr::Con(Constant::String(ref mut s)), Addr::Lis(a1)) => {
- if match self.flags.double_quotes {
- DoubleQuotes::Chars => self.deconstruct_chars(s, a1, &mut pdl),
- DoubleQuotes::Codes => self.deconstruct_codes(s, a1, &mut pdl),
- DoubleQuotes::Atom => false
- } {
- continue;
- }
-
- self.fail = true;
- },
+ | (Addr::Con(Constant::String(ref mut s)), Addr::Lis(a1)) => {
+ if match self.flags.double_quotes {
+ DoubleQuotes::Chars => self.deconstruct_chars(s, a1, &mut pdl),
+ DoubleQuotes::Codes => self.deconstruct_codes(s, a1, &mut pdl),
+ DoubleQuotes::Atom => false,
+ } {
+ continue;
+ }
+
+ self.fail = true;
+ }
(Addr::Con(Constant::EmptyList), Addr::Con(Constant::String(ref s)))
- | (Addr::Con(Constant::String(ref s)), Addr::Con(Constant::EmptyList))
- if !self.flags.double_quotes.is_atom() => {
- if s.is_expandable() && s.is_empty() {
- self.pstr_trail(s.clone());
- s.set_expandable(false);
- continue;
- }
+ | (Addr::Con(Constant::String(ref s)), Addr::Con(Constant::EmptyList))
+ if !self.flags.double_quotes.is_atom() =>
+ {
+ if s.is_expandable() && s.is_empty() {
+ self.pstr_trail(s.clone());
+ s.set_expandable(false);
+ continue;
+ }
- self.fail = !s.is_empty();
- },
+ self.fail = !s.is_empty();
+ }
(Addr::Lis(a1), Addr::Lis(a2)) => {
pdl.push(Addr::HeapCell(a1));
pdl.push(Addr::HeapCell(a2));
pdl.push(Addr::HeapCell(a1 + 1));
pdl.push(Addr::HeapCell(a2 + 1));
- },
- (Addr::Con(Constant::String(ref mut s1)),
- Addr::Con(Constant::String(ref mut s2))) =>
+ }
+ (
+ Addr::Con(Constant::String(ref mut s1)),
+ Addr::Con(Constant::String(ref mut s2)),
+ ) => {
self.fail = !(self.unify_strings(&mut pdl, s1, s2)
- || self.unify_strings(&mut pdl, s2, s1)),
- (Addr::Con(ref c1), Addr::Con(ref c2)) =>
+ || self.unify_strings(&mut pdl, s2, s1))
+ }
+ (Addr::Con(ref c1), Addr::Con(ref c2)) => {
if c1 != c2 {
self.fail = true;
- },
+ }
+ }
(Addr::Str(a1), Addr::Str(a2)) => {
let r1 = &self.heap[a1];
let r2 = &self.heap[a2];
if let &HeapCellValue::NamedStr(n1, ref f1, _) = r1 {
if let &HeapCellValue::NamedStr(n2, ref f2, _) = r2 {
if n1 == n2 && *f1 == *f2 {
- for i in 1 .. n1 + 1 {
+ for i in 1..n1 + 1 {
pdl.push(Addr::HeapCell(a1 + i));
pdl.push(Addr::HeapCell(a2 + i));
}
}
self.fail = true;
- },
- _ => self.fail = true
+ }
+ _ => self.fail = true,
};
}
}
pub(super) fn trail(&mut self, r: TrailRef) {
match r {
- TrailRef::Ref(Ref::HeapCell(h)) =>
+ TrailRef::Ref(Ref::HeapCell(h)) => {
if h < self.hb {
self.trail.push(TrailRef::Ref(Ref::HeapCell(h)));
self.tr += 1;
- },
- TrailRef::Ref(Ref::AttrVar(h)) =>
+ }
+ }
+ TrailRef::Ref(Ref::AttrVar(h)) => {
if h < self.hb {
self.trail.push(TrailRef::Ref(Ref::AttrVar(h)));
self.tr += 1;
- },
- TrailRef::AttrVarLink(h, prev_addr) =>
+ }
+ }
+ TrailRef::AttrVarLink(h, prev_addr) => {
if h < self.hb {
self.trail.push(TrailRef::AttrVarLink(h, prev_addr));
self.tr += 1;
- },
+ }
+ }
TrailRef::Ref(Ref::StackCell(fr, sc)) => {
let fr_gi = self.and_stack[fr].global_index;
- let b_gi = if !self.or_stack.is_empty() {
+ let b_gi = if !self.or_stack.is_empty() {
if self.b > 0 {
let b = self.b - 1;
self.or_stack[b].global_index
// the sequence is reversed to respect the chronology of trail
// additions, now that deleted attributes can be undeleted by
// backtracking.
- for i in (a1 .. a2).rev() {
+ for i in (a1..a2).rev() {
match self.trail[i].clone() {
- TrailRef::Ref(Ref::HeapCell(h)) =>
- self.heap[h] = HeapCellValue::Addr(Addr::HeapCell(h)),
- TrailRef::Ref(Ref::AttrVar(h)) =>
- self.heap[h] = HeapCellValue::Addr(Addr::AttrVar(h)),
- TrailRef::Ref(Ref::StackCell(fr, sc)) =>
- self.and_stack[fr][sc] = Addr::StackCell(fr, sc),
- TrailRef::AttrVarLink(h, prev_addr) =>
+ TrailRef::Ref(Ref::HeapCell(h)) => {
+ self.heap[h] = HeapCellValue::Addr(Addr::HeapCell(h))
+ }
+ TrailRef::Ref(Ref::AttrVar(h)) => {
+ self.heap[h] = HeapCellValue::Addr(Addr::AttrVar(h))
+ }
+ TrailRef::Ref(Ref::StackCell(fr, sc)) => {
+ self.and_stack[fr][sc] = Addr::StackCell(fr, sc)
+ }
+ TrailRef::AttrVarLink(h, prev_addr) => {
self.heap[h] = HeapCellValue::Addr(prev_addr)
+ }
}
}
}
pub(super) fn unwind_pstr_trail(&mut self, a1: usize, a2: usize) {
- for i in a1 .. a2 {
+ for i in a1..a2 {
let (_, mut s, end) = self.pstr_trail[i].clone();
s.truncate(end);
}
match tr_i {
TrailRef::Ref(Ref::AttrVar(tr_i))
- | TrailRef::Ref(Ref::HeapCell(tr_i))
- | TrailRef::AttrVarLink(tr_i, _) =>
+ | TrailRef::Ref(Ref::HeapCell(tr_i))
+ | TrailRef::AttrVarLink(tr_i, _) => {
if tr_i < hb {
i += 1;
} else {
self.trail[i] = val;
self.trail.pop();
self.tr -= 1;
- },
+ }
+ }
TrailRef::Ref(Ref::StackCell(fr, _)) => {
let b = self.b - 1;
let fr_gi = self.and_stack[fr].global_index;
- let b_gi = if !self.or_stack.is_empty() {
+ let b_gi = if !self.or_stack.is_empty() {
self.or_stack[b].global_index
} else {
0
self.pstr_trail(s.clone());
let new_s = s.push_char(c);
- self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::String(new_s))));
+ self.heap
+ .push(HeapCellValue::Addr(Addr::Con(Constant::String(new_s))));
false
}
fn write_constant_to_string(&mut self, s: &mut StringList, c: Constant) -> bool {
match c {
- Constant::EmptyList if !self.flags.double_quotes.is_atom() =>
- !s.is_empty(),
- Constant::String(ref s2)
- if s.is_expandable() && s2.starts_with(s) => {
- self.pstr_trail(s.clone());
- s.append_suffix(s2);
- s.set_expandable(s2.is_expandable());
- false
- },
- Constant::String(s2) =>
- s.borrow()[s.cursor() ..] != s2.borrow()[s2.cursor() ..],
- Constant::Atom(ref a, _)
- if a.as_str().starts_with(&s.borrow()[s.cursor() ..]) =>
+ Constant::EmptyList if !self.flags.double_quotes.is_atom() => !s.is_empty(),
+ Constant::String(ref s2) if s.is_expandable() && s2.starts_with(s) => {
+ self.pstr_trail(s.clone());
+ s.append_suffix(s2);
+ s.set_expandable(s2.is_expandable());
+ false
+ }
+ Constant::String(s2) => s.borrow()[s.cursor()..] != s2.borrow()[s2.cursor()..],
+ Constant::Atom(ref a, _) if a.as_str().starts_with(&s.borrow()[s.cursor()..]) => {
if let Some(c) = a.as_str().chars().next() {
if c.len_utf8() == a.as_str().len() {
// detect chars masquerading as atoms.
}
} else {
true
- },
- Constant::Char(ref c) if s.is_empty() && s.is_expandable() =>
+ }
+ }
+ Constant::Char(ref c) if s.is_empty() && s.is_expandable() => {
match self.flags.double_quotes {
DoubleQuotes::Chars => self.write_char_to_string(s, *c),
- _ => false
- },
- Constant::Char(ref c) =>
- match self.flags.double_quotes {
- DoubleQuotes::Chars =>
- if s.borrow().chars().next() == Some(*c) && c.len_utf8() == s.len() {
- s.set_expandable(false);
- false
- } else {
- true
- },
- _ => false
- },
- Constant::CharCode(ref c) if s.is_empty() && s.is_expandable() =>
+ _ => false,
+ }
+ }
+ Constant::Char(ref c) => match self.flags.double_quotes {
+ DoubleQuotes::Chars => {
+ if s.borrow().chars().next() == Some(*c) && c.len_utf8() == s.len() {
+ s.set_expandable(false);
+ false
+ } else {
+ true
+ }
+ }
+ _ => false,
+ },
+ Constant::CharCode(ref c) if s.is_empty() && s.is_expandable() => {
match self.flags.double_quotes {
DoubleQuotes::Codes => self.write_char_to_string(s, *c as char),
- _ => false
- },
- Constant::CharCode(ref c) =>
- match self.flags.double_quotes {
- DoubleQuotes::Codes =>
- if s.borrow().chars().next() == Some(*c as char) && 1 == s.len() {
- s.set_expandable(false);
- false
- } else {
- true
- },
- _ => false
- },
- _ => true
+ _ => false,
+ }
+ }
+ Constant::CharCode(ref c) => match self.flags.double_quotes {
+ DoubleQuotes::Codes => {
+ if s.borrow().chars().next() == Some(*c as char) && 1 == s.len() {
+ s.set_expandable(false);
+ false
+ } else {
+ true
+ }
+ }
+ _ => false,
+ },
+ _ => true,
}
}
pub(super) fn write_constant_to_var(&mut self, addr: Addr, c: Constant) {
match self.store(self.deref(addr)) {
- Addr::Con(Constant::String(ref mut s)) =>
- self.fail = self.write_constant_to_string(s, c),
- Addr::Con(c1) =>
+ Addr::Con(Constant::String(ref mut s)) => {
+ self.fail = self.write_constant_to_string(s, c)
+ }
+ Addr::Con(c1) => {
if c1 != c {
self.fail = true;
- },
- Addr::Lis(l) =>
- self.unify(Addr::Lis(l), Addr::Con(c)),
- addr => if let Some(r) = addr.as_var() {
- self.bind(r, Addr::Con(c));
- } else {
- self.fail = true;
+ }
+ }
+ Addr::Lis(l) => self.unify(Addr::Lis(l), Addr::Con(c)),
+ addr => {
+ if let Some(r) = addr.as_var() {
+ self.bind(r, Addr::Con(c));
+ } else {
+ self.fail = true;
+ }
}
};
}
pub(super) fn get_number(&mut self, at: &ArithmeticTerm) -> Result<Number, MachineStub> {
match at {
- &ArithmeticTerm::Reg(r) =>
- self.arith_eval_by_metacall(r),
- &ArithmeticTerm::Interm(i) =>
- Ok(mem::replace(&mut self.interms[i-1], Number::Integer(Integer::from(0)))),
- &ArithmeticTerm::Number(ref n) =>
- Ok(n.clone()),
+ &ArithmeticTerm::Reg(r) => self.arith_eval_by_metacall(r),
+ &ArithmeticTerm::Interm(i) => Ok(mem::replace(
+ &mut self.interms[i - 1],
+ Number::Integer(Integer::from(0)),
+ )),
+ &ArithmeticTerm::Number(ref n) => Ok(n.clone()),
}
}
- fn rational_from_number(&self, n: Number, caller: &MachineStub) -> Result<Rational, MachineStub>
- {
+ fn rational_from_number(
+ &self,
+ n: Number,
+ caller: &MachineStub,
+ ) -> Result<Rational, MachineStub> {
match n {
Number::Rational(r) => Ok(r),
- Number::Float(OrderedFloat(f)) =>
- Rational::from_f64(f).ok_or_else(|| {
- self.error_form(MachineError::instantiation_error(), caller.clone())
- }),
- Number::Integer(n) =>
- Ok(Rational::from(n))
+ Number::Float(OrderedFloat(f)) => Rational::from_f64(f).ok_or_else(|| {
+ self.error_form(MachineError::instantiation_error(), caller.clone())
+ }),
+ Number::Integer(n) => Ok(Rational::from(n)),
}
}
- fn get_rational(&mut self, at: &ArithmeticTerm, caller: &MachineStub)
- -> Result<Rational, MachineStub>
- {
+ fn get_rational(
+ &mut self,
+ at: &ArithmeticTerm,
+ caller: &MachineStub,
+ ) -> Result<Rational, MachineStub> {
let n = self.get_number(at)?;
self.rational_from_number(n, caller)
}
- pub(super)
- fn arith_eval_by_metacall(&self, r: RegType) -> Result<Number, MachineStub>
- {
+ pub(super) fn arith_eval_by_metacall(&self, r: RegType) -> Result<Number, MachineStub> {
let a = self[r].clone();
let caller = MachineError::functor_stub(clause_name!("(is)"), 2);
"*" => interms.push(try_numeric_result!(self, a1 * a2, caller.clone())?),
"/" => interms.push(self.div(a1, a2)?),
"**" => interms.push(self.pow(a1, a2, "(is)")?),
- "^" => interms.push(self.int_pow(a1, a2)?),
- "max" => interms.push(self.max(a1, a2)?),
- "min" => interms.push(self.min(a1, a2)?),
+ "^" => interms.push(self.int_pow(a1, a2)?),
+ "max" => interms.push(self.max(a1, a2)?),
+ "min" => interms.push(self.min(a1, a2)?),
"rdiv" => {
let r1 = self.rational_from_number(a1, &caller)?;
let r2 = self.rational_from_number(a2, &caller)?;
let result = Number::Rational(self.rdiv(r1, r2)?);
interms.push(result)
- },
- "//" => interms.push(Number::Integer(self.idiv(a1, a2)?)),
+ }
+ "//" => interms.push(Number::Integer(self.idiv(a1, a2)?)),
"div" => interms.push(Number::Integer(self.int_floor_div(a1, a2)?)),
- ">>" => interms.push(Number::Integer(self.shr(a1, a2)?)),
- "<<" => interms.push(Number::Integer(self.shl(a1, a2)?)),
+ ">>" => interms.push(Number::Integer(self.shr(a1, a2)?)),
+ "<<" => interms.push(Number::Integer(self.shl(a1, a2)?)),
"/\\" => interms.push(Number::Integer(self.and(a1, a2)?)),
"\\/" => interms.push(Number::Integer(self.or(a1, a2)?)),
"xor" => interms.push(Number::Integer(self.xor(a1, a2)?)),
"mod" => interms.push(Number::Integer(self.modulus(a1, a2)?)),
"rem" => interms.push(Number::Integer(self.remainder(a1, a2)?)),
"atan2" => interms.push(Number::Float(OrderedFloat(self.atan2(a1, a2)?))),
- _ => return Err(self.error_form(MachineError::instantiation_error(),
- caller))
+ _ => {
+ return Err(self.error_form(MachineError::instantiation_error(), caller))
+ }
}
- },
+ }
HeapCellValue::NamedStr(1, name, _) => {
let a1 = interms.pop().unwrap();
match name.as_str() {
- "-" => interms.push(- a1),
- "+" => interms.push(a1),
+ "-" => interms.push(-a1),
+ "+" => interms.push(a1),
"cos" => interms.push(Number::Float(OrderedFloat(self.cos(a1)?))),
"sin" => interms.push(Number::Float(OrderedFloat(self.sin(a1)?))),
"tan" => interms.push(Number::Float(OrderedFloat(self.tan(a1)?))),
"acos" => interms.push(Number::Float(OrderedFloat(self.acos(a1)?))),
"asin" => interms.push(Number::Float(OrderedFloat(self.asin(a1)?))),
"atan" => interms.push(Number::Float(OrderedFloat(self.atan(a1)?))),
- "abs" => interms.push(a1.abs()),
+ "abs" => interms.push(a1.abs()),
"float" => interms.push(Number::Float(OrderedFloat(self.float(a1)?))),
"truncate" => interms.push(Number::Integer(self.truncate(a1))),
"round" => interms.push(Number::Integer(self.round(a1)?)),
"ceiling" => interms.push(Number::Integer(self.ceiling(a1))),
"floor" => interms.push(Number::Integer(self.floor(a1))),
"\\" => interms.push(Number::Integer(self.bitwise_complement(a1)?)),
- _ => return Err(self.error_form(MachineError::instantiation_error(),
- caller))
+ _ => {
+ return Err(self.error_form(MachineError::instantiation_error(), caller))
+ }
}
- },
- HeapCellValue::Addr(Addr::Con(Constant::Integer(n))) =>
- interms.push(Number::Integer(n)),
- HeapCellValue::Addr(Addr::Con(Constant::Float(n))) =>
- interms.push(Number::Float(n)),
- HeapCellValue::Addr(Addr::Con(Constant::Rational(n))) =>
- interms.push(Number::Rational(n)),
+ }
+ HeapCellValue::Addr(Addr::Con(Constant::Integer(n))) => {
+ interms.push(Number::Integer(n))
+ }
+ HeapCellValue::Addr(Addr::Con(Constant::Float(n))) => {
+ interms.push(Number::Float(n))
+ }
+ HeapCellValue::Addr(Addr::Con(Constant::Rational(n))) => {
+ interms.push(Number::Rational(n))
+ }
HeapCellValue::Addr(Addr::Con(Constant::Atom(ref name, _)))
if name.as_str() == "pi" =>
- interms.push(Number::Float(OrderedFloat(f64::consts::PI))),
- _ =>
- return Err(self.error_form(MachineError::instantiation_error(), caller))
+ {
+ interms.push(Number::Float(OrderedFloat(f64::consts::PI)))
+ }
+ _ => return Err(self.error_form(MachineError::instantiation_error(), caller)),
}
- };
+ }
Ok(interms.pop().unwrap())
}
- fn rdiv(&self, r1: Rational, r2: Rational) -> Result<Rational, MachineStub>
- {
+ fn rdiv(&self, r1: Rational, r2: Rational) -> Result<Rational, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(rdiv)"), 2);
if r2 == 0 {
}
}
- fn int_floor_div(&self, n1: Number, n2: Number) -> Result<Integer, MachineStub>
- {
+ fn int_floor_div(&self, n1: Number, n2: Number) -> Result<Integer, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(div)"), 2);
match n1 / n2 {
Ok(result) => Ok(rnd_i(&result).to_owned()),
- Err(e) => Err(self.error_form(MachineError::evaluation_error(e), stub))
+ Err(e) => Err(self.error_form(MachineError::evaluation_error(e), stub)),
}
}
- fn idiv(&self, n1: Number, n2: Number) -> Result<Integer, MachineStub>
- {
+ fn idiv(&self, n1: Number, n2: Number) -> Result<Integer, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) =>
+ (Number::Integer(n1), Number::Integer(n2)) => {
if n2 == 0 {
- Err(self.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor),
- stub))
+ Err(self
+ .error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
} else {
Ok(n1.div_rem(n2).0)
- },
- (Number::Integer(_), n2) =>
- Err(self.error_form(MachineError::type_error(ValidType::Integer,
- Addr::Con(n2.to_constant())),
- stub)),
- (n1, _) =>
- Err(self.error_form(MachineError::type_error(ValidType::Integer,
- Addr::Con(n1.to_constant())),
- stub))
+ }
+ }
+ (Number::Integer(_), n2) => Err(self.error_form(
+ MachineError::type_error(ValidType::Integer, Addr::Con(n2.to_constant())),
+ stub,
+ )),
+ (n1, _) => Err(self.error_form(
+ MachineError::type_error(ValidType::Integer, Addr::Con(n1.to_constant())),
+ stub,
+ )),
}
}
- fn div(&self, n1: Number, n2: Number) -> Result<Number, MachineStub>
- {
+ fn div(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(/)"), 2);
if n2.is_zero() {
}
}
- fn atan2(&self, n1: Number, n2: Number) -> Result<f64, MachineStub>
- {
+ fn atan2(&self, n1: Number, n2: Number) -> Result<f64, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(is)"), 2);
if n1.is_zero() && n2.is_zero() {
}
}
- fn int_pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub>
- {
+ fn int_pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
if n1.is_zero() && n2.is_negative() {
let stub = MachineError::functor_stub(clause_name!("(is)"), 2);
return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub));
}
match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) =>
+ (Number::Integer(n1), Number::Integer(n2)) => {
if n1 != 1 && n2 < 0 {
let n = Addr::Con(Constant::Integer(n1));
let stub = MachineError::functor_stub(clause_name!("^"), 2);
Err(self.error_form(MachineError::type_error(ValidType::Float, n), stub))
} else {
Ok(Number::Integer(binary_pow(n1, n2)))
- },
+ }
+ }
(n1, Number::Integer(n2)) => {
let f1 = self.float(n1)?;
let f2 = self.float(Number::Integer(n2))?;
self.unary_float_fn_template(Number::Float(OrderedFloat(f1)), |f| f.powf(f2))
.map(|f| Number::Float(OrderedFloat(f)))
- },
+ }
(n1, n2) => {
let f2 = self.float(n2)?;
if n1.is_negative() && f2 != f2.floor() {
let stub = MachineError::functor_stub(clause_name!("(is)"), 2);
- return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub));
+ return Err(
+ self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub)
+ );
}
let f1 = self.float(n1)?;
}
}
- fn float_pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub>
- {
+ fn float_pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
let f1 = result_f(&n1, rnd_f);
let f2 = result_f(&n2, rnd_f);
let result = result_f(&Number::Float(OrderedFloat(f1.powf(f2))), rnd_f);
- Ok(Number::Float(OrderedFloat(try_numeric_result!(self, result, stub)?)))
+ Ok(Number::Float(OrderedFloat(try_numeric_result!(
+ self, result, stub
+ )?)))
}
- fn pow(&self, n1: Number, n2: Number, culprit: &'static str) -> Result<Number, MachineStub>
- {
+ fn pow(&self, n1: Number, n2: Number, culprit: &'static str) -> Result<Number, MachineStub> {
if n2.is_negative() {
let stub = MachineError::functor_stub(clause_name!(culprit), 2);
return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub));
}
match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) =>
- Ok(Number::Integer(binary_pow(n1, n2))),
- (n1, n2) =>
- self.float_pow(n1, n2)
+ (Number::Integer(n1), Number::Integer(n2)) => Ok(Number::Integer(binary_pow(n1, n2))),
+ (n1, n2) => self.float_pow(n1, n2),
}
}
fn unary_float_fn_template<FloatFn>(&self, n1: Number, f: FloatFn) -> Result<f64, MachineStub>
- where FloatFn: Fn(f64) -> f64
+ where
+ FloatFn: Fn(f64) -> f64,
{
let stub = MachineError::functor_stub(clause_name!("(is)"), 2);
try_numeric_result!(self, f1, stub)
}
- fn sin(&self, n1: Number) -> Result<f64, MachineStub>
- {
+ fn sin(&self, n1: Number) -> Result<f64, MachineStub> {
self.unary_float_fn_template(n1, |f| f.sin())
}
- fn cos(&self, n1: Number) -> Result<f64, MachineStub>
- {
+ fn cos(&self, n1: Number) -> Result<f64, MachineStub> {
self.unary_float_fn_template(n1, |f| f.cos())
}
- fn tan(&self, n1: Number) -> Result<f64, MachineStub>
- {
+ fn tan(&self, n1: Number) -> Result<f64, MachineStub> {
self.unary_float_fn_template(n1, |f| f.tan())
}
- fn log(&self, n1: Number) -> Result<f64, MachineStub>
- {
+ fn log(&self, n1: Number) -> Result<f64, MachineStub> {
self.unary_float_fn_template(n1, |f| f.log(f64::consts::E))
}
- fn exp(&self, n1: Number) -> Result<f64, MachineStub>
- {
+ fn exp(&self, n1: Number) -> Result<f64, MachineStub> {
self.unary_float_fn_template(n1, |f| f.exp())
}
- fn asin(&self, n1: Number) -> Result<f64, MachineStub>
- {
+ fn asin(&self, n1: Number) -> Result<f64, MachineStub> {
self.unary_float_fn_template(n1, |f| f.asin())
}
- fn acos(&self, n1: Number) -> Result<f64, MachineStub>
- {
+ fn acos(&self, n1: Number) -> Result<f64, MachineStub> {
self.unary_float_fn_template(n1, |f| f.acos())
}
- fn atan(&self, n1: Number) -> Result<f64, MachineStub>
- {
+ fn atan(&self, n1: Number) -> Result<f64, MachineStub> {
self.unary_float_fn_template(n1, |f| f.atan())
}
- fn sqrt(&self, n1: Number) -> Result<f64, MachineStub>
- {
+ fn sqrt(&self, n1: Number) -> Result<f64, MachineStub> {
if n1.is_negative() {
let stub = MachineError::functor_stub(clause_name!("(is)"), 2);
return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub));
self.unary_float_fn_template(n1, |f| f.sqrt())
}
- fn float(&self, n: Number) -> Result<f64, MachineStub>
- {
+ fn float(&self, n: Number) -> Result<f64, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(is)"), 2);
try_numeric_result!(self, result_f(&n, rnd_f), stub)
}
- fn floor(&self, n1: Number) -> Integer
- {
+ fn floor(&self, n1: Number) -> Integer {
rnd_i(&n1).to_owned()
}
- fn ceiling(&self, n1: Number) -> Integer
- {
+ fn ceiling(&self, n1: Number) -> Integer {
-self.floor(-n1)
}
- fn truncate(&self, n: Number) -> Integer
- {
+ fn truncate(&self, n: Number) -> Integer {
if n.is_negative() {
-self.floor(n.abs())
} else {
}
}
- fn round(&self, n: Number) -> Result<Integer, MachineStub>
- {
+ fn round(&self, n: Number) -> Result<Integer, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(is)"), 2);
let result = n + Number::Float(OrderedFloat(0.5f64));
Ok(self.floor(result))
}
- fn shr(&self, n1: Number, n2: Number) -> Result<Integer, MachineStub>
- {
+ fn shr(&self, n1: Number, n2: Number) -> Result<Integer, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(>>)"), 2);
match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) =>
- match n2.to_u32() {
- Some(n2) => Ok(n1 >> n2),
- _ => Ok(n1 >> u32::max_value())
- },
- (Number::Integer(_), n2) =>
- Err(self.error_form(MachineError::type_error(ValidType::Integer,
- Addr::Con(n2.to_constant())),
- stub)),
- (n1, _) =>
- Err(self.error_form(MachineError::type_error(ValidType::Integer,
- Addr::Con(n1.to_constant())),
- stub))
+ (Number::Integer(n1), Number::Integer(n2)) => match n2.to_u32() {
+ Some(n2) => Ok(n1 >> n2),
+ _ => Ok(n1 >> u32::max_value()),
+ },
+ (Number::Integer(_), n2) => Err(self.error_form(
+ MachineError::type_error(ValidType::Integer, Addr::Con(n2.to_constant())),
+ stub,
+ )),
+ (n1, _) => Err(self.error_form(
+ MachineError::type_error(ValidType::Integer, Addr::Con(n1.to_constant())),
+ stub,
+ )),
}
}
- fn shl(&self, n1: Number, n2: Number) -> Result<Integer, MachineStub>
- {
+ fn shl(&self, n1: Number, n2: Number) -> Result<Integer, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(<<)"), 2);
match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) =>
- match n2.to_u32() {
- Some(n2) => Ok(n1 << n2),
- _ => Ok(n1 << u32::max_value())
- },
- (Number::Integer(_), n2) =>
- Err(self.error_form(MachineError::type_error(ValidType::Integer,
- Addr::Con(n2.to_constant())),
- stub)),
- (n1, _) =>
- Err(self.error_form(MachineError::type_error(ValidType::Integer,
- Addr::Con(n1.to_constant())),
- stub))
+ (Number::Integer(n1), Number::Integer(n2)) => match n2.to_u32() {
+ Some(n2) => Ok(n1 << n2),
+ _ => Ok(n1 << u32::max_value()),
+ },
+ (Number::Integer(_), n2) => Err(self.error_form(
+ MachineError::type_error(ValidType::Integer, Addr::Con(n2.to_constant())),
+ stub,
+ )),
+ (n1, _) => Err(self.error_form(
+ MachineError::type_error(ValidType::Integer, Addr::Con(n1.to_constant())),
+ stub,
+ )),
}
}
- fn bitwise_complement(&self, n1: Number) -> Result<Integer, MachineStub>
- {
+ fn bitwise_complement(&self, n1: Number) -> Result<Integer, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(\\)"), 2);
match n1 {
- Number::Integer(n1) =>
- Ok(!n1),
- _ =>
- Err(self.error_form(MachineError::type_error(ValidType::Integer,
- Addr::Con(n1.to_constant())),
- stub))
+ Number::Integer(n1) => Ok(!n1),
+ _ => Err(self.error_form(
+ MachineError::type_error(ValidType::Integer, Addr::Con(n1.to_constant())),
+ stub,
+ )),
}
}
- fn xor(&self, n1: Number, n2: Number) -> Result<Integer, MachineStub>
- {
+ fn xor(&self, n1: Number, n2: Number) -> Result<Integer, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(xor)"), 2);
match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) =>
- Ok(n1 ^ n2),
- (Number::Integer(_), n2) =>
- Err(self.error_form(MachineError::type_error(ValidType::Integer,
- Addr::Con(n2.to_constant())),
- stub)),
- (n1, _) =>
- Err(self.error_form(MachineError::type_error(ValidType::Integer,
- Addr::Con(n1.to_constant())),
- stub))
+ (Number::Integer(n1), Number::Integer(n2)) => Ok(n1 ^ n2),
+ (Number::Integer(_), n2) => Err(self.error_form(
+ MachineError::type_error(ValidType::Integer, Addr::Con(n2.to_constant())),
+ stub,
+ )),
+ (n1, _) => Err(self.error_form(
+ MachineError::type_error(ValidType::Integer, Addr::Con(n1.to_constant())),
+ stub,
+ )),
}
}
- fn and(&self, n1: Number, n2: Number) -> Result<Integer, MachineStub>
- {
+ fn and(&self, n1: Number, n2: Number) -> Result<Integer, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(/\\)"), 2);
match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) =>
- Ok(n1 & n2),
- (Number::Integer(_), n2) =>
- Err(self.error_form(MachineError::type_error(ValidType::Integer,
- Addr::Con(n2.to_constant())),
- stub)),
- (n1, _) =>
- Err(self.error_form(MachineError::type_error(ValidType::Integer,
- Addr::Con(n1.to_constant())),
- stub))
+ (Number::Integer(n1), Number::Integer(n2)) => Ok(n1 & n2),
+ (Number::Integer(_), n2) => Err(self.error_form(
+ MachineError::type_error(ValidType::Integer, Addr::Con(n2.to_constant())),
+ stub,
+ )),
+ (n1, _) => Err(self.error_form(
+ MachineError::type_error(ValidType::Integer, Addr::Con(n1.to_constant())),
+ stub,
+ )),
}
}
- fn modulus(&self, x: Number, y: Number) -> Result<Integer, MachineStub>
- {
+ fn modulus(&self, x: Number, y: Number) -> Result<Integer, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(mod)"), 2);
match (x, y) {
- (Number::Integer(x), Number::Integer(y)) =>
+ (Number::Integer(x), Number::Integer(y)) => {
if y == 0 {
- Err(self.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
+ Err(self
+ .error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
} else {
Ok(x.div_rem_floor(y).1)
- },
- (Number::Integer(_), n2) =>
- Err(self.error_form(MachineError::type_error(ValidType::Integer,
- Addr::Con(n2.to_constant())),
- stub)),
- (n1, _) =>
- Err(self.error_form(MachineError::type_error(ValidType::Integer,
- Addr::Con(n1.to_constant())),
- stub))
+ }
+ }
+ (Number::Integer(_), n2) => Err(self.error_form(
+ MachineError::type_error(ValidType::Integer, Addr::Con(n2.to_constant())),
+ stub,
+ )),
+ (n1, _) => Err(self.error_form(
+ MachineError::type_error(ValidType::Integer, Addr::Con(n1.to_constant())),
+ stub,
+ )),
}
}
fn max(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) =>
+ (Number::Integer(n1), Number::Integer(n2)) => {
if n1 > n2 {
Ok(Number::Integer(n1))
} else {
Ok(Number::Integer(n2))
- },
+ }
+ }
(n1, n2) => {
let stub = MachineError::functor_stub(clause_name!("max"), 2);
fn min(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) =>
+ (Number::Integer(n1), Number::Integer(n2)) => {
if n1 < n2 {
Ok(Number::Integer(n1))
} else {
Ok(Number::Integer(n2))
- },
+ }
+ }
(n1, n2) => {
let stub = MachineError::functor_stub(clause_name!("max"), 2);
-
+
let f1 = try_numeric_result!(self, result_f(&n1, rnd_f), stub.clone())?;
let f2 = try_numeric_result!(self, result_f(&n2, rnd_f), stub)?;
}
}
- fn remainder(&self, n1: Number, n2: Number) -> Result<Integer, MachineStub>
- {
+ fn remainder(&self, n1: Number, n2: Number) -> Result<Integer, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(rem)"), 2);
match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) =>
+ (Number::Integer(n1), Number::Integer(n2)) => {
if n2 == 0 {
- Err(self.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor),
- stub))
+ Err(self
+ .error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
} else {
Ok(n1 % n2)
- },
- (Number::Integer(_), n2) =>
- Err(self.error_form(MachineError::type_error(ValidType::Integer,
- Addr::Con(n2.to_constant())),
- stub)),
- (n1, _) =>
- Err(self.error_form(MachineError::type_error(ValidType::Integer,
- Addr::Con(n1.to_constant())),
- stub))
+ }
+ }
+ (Number::Integer(_), n2) => Err(self.error_form(
+ MachineError::type_error(ValidType::Integer, Addr::Con(n2.to_constant())),
+ stub,
+ )),
+ (n1, _) => Err(self.error_form(
+ MachineError::type_error(ValidType::Integer, Addr::Con(n1.to_constant())),
+ stub,
+ )),
}
}
- fn or(&self, n1: Number, n2: Number) -> Result<Integer, MachineStub>
- {
+ fn or(&self, n1: Number, n2: Number) -> Result<Integer, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(\\/)"), 2);
match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) =>
- Ok(n1 | n2),
- (Number::Integer(_), n2) =>
- Err(self.error_form(MachineError::type_error(ValidType::Integer,
- Addr::Con(n2.to_constant())),
- stub)),
- (n1, _) =>
- Err(self.error_form(MachineError::type_error(ValidType::Integer,
- Addr::Con(n1.to_constant())),
- stub))
+ (Number::Integer(n1), Number::Integer(n2)) => Ok(n1 | n2),
+ (Number::Integer(_), n2) => Err(self.error_form(
+ MachineError::type_error(ValidType::Integer, Addr::Con(n2.to_constant())),
+ stub,
+ )),
+ (n1, _) => Err(self.error_form(
+ MachineError::type_error(ValidType::Integer, Addr::Con(n1.to_constant())),
+ stub,
+ )),
}
}
- pub(super)
- fn execute_arith_instr(&mut self, instr: &ArithmeticInstruction)
- {
+ pub(super) fn execute_arith_instr(&mut self, instr: &ArithmeticInstruction) {
let stub = MachineError::functor_stub(clause_name!("(is)"), 2);
match instr {
self.interms[t - 1] = try_or_fail!(self, try_numeric_result!(self, n1 + n2, stub));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Sub(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] = try_or_fail!(self, try_numeric_result!(self, n1 - n2, stub));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Mul(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] = try_or_fail!(self, try_numeric_result!(self, n1 * n2, stub));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Max(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] = try_or_fail!(self, self.max(n1, n2));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Min(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] = try_or_fail!(self, self.min(n1, n2));
self.p += 1;
- },
+ }
&ArithmeticInstruction::IntPow(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] = try_or_fail!(self, self.int_pow(n1, n2));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Pow(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] = try_or_fail!(self, self.pow(n1, n2, "(**)"));
self.p += 1;
- },
+ }
&ArithmeticInstruction::RDiv(ref a1, ref a2, t) => {
let stub = MachineError::functor_stub(clause_name!("(rdiv)"), 2);
self.interms[t - 1] = Number::Rational(try_or_fail!(self, self.rdiv(r1, r2)));
self.p += 1;
- },
+ }
&ArithmeticInstruction::IntFloorDiv(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.int_floor_div(n1, n2)));
+ self.interms[t - 1] =
+ Number::Integer(try_or_fail!(self, self.int_floor_div(n1, n2)));
self.p += 1;
- },
+ }
&ArithmeticInstruction::IDiv(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.idiv(n1, n2)));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Abs(ref a1, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
self.interms[t - 1] = n1.abs();
self.p += 1;
- },
+ }
&ArithmeticInstruction::Neg(ref a1, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
- self.interms[t - 1] = - n1;
+ self.interms[t - 1] = -n1;
self.p += 1;
- },
+ }
&ArithmeticInstruction::BitwiseComplement(ref a1, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
- self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.bitwise_complement(n1)));
+ self.interms[t - 1] =
+ Number::Integer(try_or_fail!(self, self.bitwise_complement(n1)));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Div(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] = try_or_fail!(self, self.div(n1, n2));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Shr(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.shr(n1, n2)));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Shl(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.shl(n1, n2)));
self.p += 1;
- },
+ }
&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;
- },
+ }
&ArithmeticInstruction::And(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.and(n1, n2)));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Or(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.or(n1, n2)));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Mod(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.modulus(n1, n2)));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Rem(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.remainder(n1, n2)));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Cos(ref a1, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.cos(n1))));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Sin(ref a1, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.sin(n1))));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Tan(ref a1, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.tan(n1))));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Sqrt(ref a1, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
- self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.sqrt(n1))));
+ self.interms[t - 1] =
+ Number::Float(OrderedFloat(try_or_fail!(self, self.sqrt(n1))));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Log(ref a1, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.log(n1))));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Exp(ref a1, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.exp(n1))));
self.p += 1;
- },
+ }
&ArithmeticInstruction::ACos(ref a1, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
- self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.acos(n1))));
+ self.interms[t - 1] =
+ Number::Float(OrderedFloat(try_or_fail!(self, self.acos(n1))));
self.p += 1;
- },
+ }
&ArithmeticInstruction::ASin(ref a1, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
- self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.asin(n1))));
+ self.interms[t - 1] =
+ Number::Float(OrderedFloat(try_or_fail!(self, self.asin(n1))));
self.p += 1;
- },
+ }
&ArithmeticInstruction::ATan(ref a1, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
- self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.atan(n1))));
+ self.interms[t - 1] =
+ Number::Float(OrderedFloat(try_or_fail!(self, self.atan(n1))));
self.p += 1;
- },
+ }
&ArithmeticInstruction::ATan2(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::Float(OrderedFloat(try_or_fail!(self, self.atan2(n1, n2))));
+ self.interms[t - 1] =
+ Number::Float(OrderedFloat(try_or_fail!(self, self.atan2(n1, n2))));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Float(ref a1, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
- self.interms[t - 1] = Number::Float(OrderedFloat(try_or_fail!(self, self.float(n1))));
+ self.interms[t - 1] =
+ Number::Float(OrderedFloat(try_or_fail!(self, self.float(n1))));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Truncate(ref a1, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
self.interms[t - 1] = Number::Integer(self.truncate(n1));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Round(ref a1, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.round(n1)));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Ceiling(ref a1, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
self.interms[t - 1] = Number::Integer(self.ceiling(n1));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Floor(ref a1, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
self.interms[t - 1] = Number::Integer(self.floor(n1));
self.p += 1;
- },
+ }
&ArithmeticInstruction::Plus(ref a1, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
self.interms[t - 1] = n1;
self.p += 1;
- },
+ }
};
}
let h = self.heap.h;
if let Some(c) = s.head() {
- self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::Char(c))));
- self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::String(s.tail()))));
+ self.heap
+ .push(HeapCellValue::Addr(Addr::Con(Constant::Char(c))));
+ self.heap
+ .push(HeapCellValue::Addr(Addr::Con(Constant::String(s.tail()))));
self.s = h;
self.mode = MachineMode::Read;
} else if s.is_expandable() {
- self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::String(s.clone()))));
+ self.heap
+ .push(HeapCellValue::Addr(Addr::Con(Constant::String(s.clone()))));
self.s = h;
self.mode = MachineMode::Read;
let h = self.heap.h;
if let Some(c) = s.head() {
- self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::CharCode(c as u8))));
- self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::String(s.tail()))));
+ self.heap
+ .push(HeapCellValue::Addr(Addr::Con(Constant::CharCode(c as u8))));
+ self.heap
+ .push(HeapCellValue::Addr(Addr::Con(Constant::String(s.tail()))));
self.s = h;
self.mode = MachineMode::Read;
} else if s.is_expandable() {
- self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::String(s.clone()))));
+ self.heap
+ .push(HeapCellValue::Addr(Addr::Con(Constant::String(s.clone()))));
self.s = h;
self.mode = MachineMode::Read;
&FactInstruction::GetConstant(_, ref c, reg) => {
let addr = self[reg].clone();
self.write_constant_to_var(addr, c.clone());
- },
+ }
&FactInstruction::GetList(_, reg) => {
let addr = self.store(self.deref(self[reg].clone()));
match addr {
- Addr::Con(Constant::String(ref s)) =>
- match self.flags.double_quotes {
- DoubleQuotes::Chars => self.get_char_list(s),
- DoubleQuotes::Codes => self.get_code_list(s),
- _ => self.fail = true
- },
- addr @ Addr::AttrVar(_) | addr @ Addr::StackCell(..) | addr @ Addr::HeapCell(_) => {
+ Addr::Con(Constant::String(ref s)) => match self.flags.double_quotes {
+ DoubleQuotes::Chars => self.get_char_list(s),
+ DoubleQuotes::Codes => self.get_code_list(s),
+ _ => self.fail = true,
+ },
+ addr @ Addr::AttrVar(_)
+ | addr @ Addr::StackCell(..)
+ | addr @ Addr::HeapCell(_) => {
let h = self.heap.h;
- self.heap.push(HeapCellValue::Addr(Addr::Lis(h+1)));
+ self.heap.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
self.bind(addr.as_var().unwrap(), Addr::HeapCell(h));
self.mode = MachineMode::Write;
- },
+ }
Addr::Lis(a) => {
self.s = a;
self.mode = MachineMode::Read;
- },
- _ => self.fail = true
+ }
+ _ => self.fail = true,
};
- },
+ }
&FactInstruction::GetStructure(ref ct, arity, reg) => {
let addr = self.deref(self[reg].clone());
self.fail = true;
}
}
- },
+ }
Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => {
let h = self.heap.h;
self.heap.push(HeapCellValue::Addr(Addr::Str(h + 1)));
- self.heap.push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec()));
+ self.heap
+ .push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec()));
self.bind(addr.as_var().unwrap(), Addr::HeapCell(h));
self.mode = MachineMode::Write;
- },
- _ => self.fail = true
+ }
+ _ => self.fail = true,
};
- },
- &FactInstruction::GetVariable(norm, arg) =>
- self[norm] = self.registers[arg].clone(),
+ }
+ &FactInstruction::GetVariable(norm, arg) => self[norm] = self.registers[arg].clone(),
&FactInstruction::GetValue(norm, arg) => {
let norm_addr = self[norm].clone();
- let reg_addr = self.registers[arg].clone();
+ let reg_addr = self.registers[arg].clone();
self.unify(norm_addr, reg_addr);
- },
+ }
&FactInstruction::UnifyConstant(ref c) => {
match self.mode {
- MachineMode::Read => {
+ MachineMode::Read => {
let addr = Addr::HeapCell(self.s);
self.write_constant_to_var(addr, c.clone());
- },
+ }
MachineMode::Write => {
self.heap.push(HeapCellValue::Addr(Addr::Con(c.clone())));
}
};
self.s += 1;
- },
+ }
&FactInstruction::UnifyVariable(reg) => {
match self.mode {
- MachineMode::Read =>
- self[reg] = self.heap[self.s].as_addr(self.s),
+ MachineMode::Read => self[reg] = self.heap[self.s].as_addr(self.s),
MachineMode::Write => {
let h = self.heap.h;
};
self.s += 1;
- },
+ }
&FactInstruction::UnifyLocalValue(reg) => {
let s = self.s;
match self.mode {
- MachineMode::Read => {
+ MachineMode::Read => {
let reg_addr = self[reg].clone();
self.unify(reg_addr, Addr::HeapCell(s));
- },
+ }
MachineMode::Write => {
let addr = self.deref(self[reg].clone());
- let h = self.heap.h;
+ let h = self.heap.h;
if let Addr::HeapCell(hc) = addr {
if hc < h {
};
self.s += 1;
- },
+ }
&FactInstruction::UnifyValue(reg) => {
let s = self.s;
match self.mode {
- MachineMode::Read => {
+ MachineMode::Read => {
let reg_addr = self[reg].clone();
self.unify(reg_addr, Addr::HeapCell(s));
- },
+ }
MachineMode::Write => {
let heap_val = self.store(self[reg].clone());
self.heap.push(HeapCellValue::Addr(heap_val));
};
self.s += 1;
- },
+ }
&FactInstruction::UnifyVoid(n) => {
match self.mode {
- MachineMode::Read =>
- self.s += n,
+ MachineMode::Read => self.s += n,
MachineMode::Write => {
let h = self.heap.h;
- for i in h .. h + n {
+ for i in h..h + n {
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(i)));
}
}
let offset = match addr {
Addr::HeapCell(_) | Addr::StackCell(..) | Addr::AttrVar(..) => v,
- Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() =>
- if s.is_empty() && !s.is_expandable() { c } else { l },
+ Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() => {
+ if s.is_empty() && !s.is_expandable() {
+ c
+ } else {
+ l
+ }
+ }
Addr::Con(_) => c,
Addr::Lis(_) => l,
Addr::Str(_) => s,
match offset {
0 => self.fail = true,
- o => self.p += o
+ o => self.p += o,
};
- },
+ }
&IndexingInstruction::SwitchOnConstant(_, ref hm) => {
let a1 = self.registers[1].clone();
let addr = self.store(self.deref(a1));
let offset = match addr {
- Addr::Con(constant) => {
- match hm.get(&constant) {
- Some(offset) => *offset,
- _ => 0
- }
+ Addr::Con(constant) => match hm.get(&constant) {
+ Some(offset) => *offset,
+ _ => 0,
},
- _ => 0
+ _ => 0,
};
match offset {
0 => self.fail = true,
o => self.p += o,
};
- },
+ }
&IndexingInstruction::SwitchOnStructure(_, ref hm) => {
let a1 = self.registers[1].clone();
let addr = self.store(self.deref(a1));
if let &HeapCellValue::NamedStr(arity, ref name, _) = &self.heap[s] {
match hm.get(&(name.clone(), arity)) {
Some(offset) => *offset,
- _ => 0
+ _ => 0,
}
} else {
0
}
- },
- _ => 0
+ }
+ _ => 0,
};
match offset {
0 => self.fail = true,
- o => self.p += o
+ o => self.p += o,
};
}
};
pub(super) fn execute_query_instr(&mut self, instr: &QueryInstruction) {
match instr {
- &QueryInstruction::GetVariable(norm, arg) =>
- self[norm] = self.registers[arg].clone(),
- &QueryInstruction::PutConstant(_, ref constant, reg) =>
- self[reg] = Addr::Con(constant.clone()),
- &QueryInstruction::PutList(_, reg) =>
- self[reg] = Addr::Lis(self.heap.h),
+ &QueryInstruction::GetVariable(norm, arg) => self[norm] = self.registers[arg].clone(),
+ &QueryInstruction::PutConstant(_, ref constant, reg) => {
+ self[reg] = Addr::Con(constant.clone())
+ }
+ &QueryInstruction::PutList(_, reg) => self[reg] = Addr::Lis(self.heap.h),
&QueryInstruction::PutStructure(ref ct, arity, reg) => {
let h = self.heap.h;
- self.heap.push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec()));
+ self.heap
+ .push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec()));
self[reg] = Addr::Str(h);
- },
+ }
&QueryInstruction::PutUnsafeValue(n, arg) => {
- let e = self.e;
+ let e = self.e;
let addr = self.deref(Addr::StackCell(e, n));
if addr.is_protected(e) {
self.registers[arg] = self.heap[h].as_addr(h);
}
- },
- &QueryInstruction::PutValue(norm, arg) =>
- self.registers[arg] = self[norm].clone(),
+ }
+ &QueryInstruction::PutValue(norm, arg) => self.registers[arg] = self[norm].clone(),
&QueryInstruction::PutVariable(norm, arg) => {
match norm {
RegType::Perm(n) => {
self[norm] = Addr::StackCell(e, n);
self.registers[arg] = self[norm].clone();
- },
+ }
RegType::Temp(_) => {
let h = self.heap.h;
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
self.registers[arg] = Addr::HeapCell(h);
}
};
- },
+ }
&QueryInstruction::SetConstant(ref c) => {
self.heap.push(HeapCellValue::Addr(Addr::Con(c.clone())));
- },
+ }
&QueryInstruction::SetLocalValue(reg) => {
let addr = self.deref(self[reg].clone());
- let h = self.heap.h;
+ let h = self.heap.h;
if let Addr::HeapCell(hc) = addr {
if hc < h {
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
self.bind(Ref::HeapCell(h), addr);
- },
+ }
&QueryInstruction::SetVariable(reg) => {
let h = self.heap.h;
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
self[reg] = Addr::HeapCell(h);
- },
+ }
&QueryInstruction::SetValue(reg) => {
let heap_val = self[reg].clone();
self.heap.push(HeapCellValue::Addr(heap_val));
- },
+ }
&QueryInstruction::SetVoid(n) => {
let h = self.heap.h;
- for i in h .. h + n {
+ for i in h..h + n {
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(i)));
}
}
}
}
- pub(super) fn handle_internal_call_n(&mut self, arity: usize)
- {
+ pub(super) fn handle_internal_call_n(&mut self, arity: usize) {
let arity = arity + 1;
- let pred = self.registers[1].clone();
+ let pred = self.registers[1].clone();
- for i in 2 .. arity {
- self.registers[i-1] = self.registers[i].clone();
+ for i in 2..arity {
+ self.registers[i - 1] = self.registers[i].clone();
}
if arity > 1 {
pub(super) fn set_ball(&mut self) {
let addr = self[temp_v!(1)].clone();
self.ball.boundary = self.heap.h;
- copy_term(CopyBallTerm::new(&mut self.and_stack, &mut self.heap, &mut self.ball.stub), addr);
+ copy_term(
+ CopyBallTerm::new(&mut self.and_stack, &mut self.heap, &mut self.ball.stub),
+ addr,
+ );
}
- pub(super) fn setup_call_n(&mut self, arity: usize) -> Option<PredicateKey>
- {
+ pub(super) fn setup_call_n(&mut self, arity: usize) -> Option<PredicateKey> {
let stub = MachineError::functor_stub(clause_name!("call"), arity + 1);
let addr = self.store(self.deref(self.registers[arity].clone()));
if let HeapCellValue::NamedStr(narity, name, _) = result {
if narity + arity > 63 {
- let representation_error =
- self.error_form(MachineError::representation_error(RepFlag::MaxArity), stub);
+ let representation_error = self.error_form(
+ MachineError::representation_error(RepFlag::MaxArity),
+ stub,
+ );
self.throw_exception(representation_error);
return None;
}
- for i in (1 .. arity).rev() {
+ for i in (1..arity).rev() {
self.registers[i + narity] = self.registers[i].clone();
}
- for i in 1 .. narity + 1 {
+ for i in 1..narity + 1 {
self.registers[i] = self.heap[a + i].as_addr(a + i);
}
self.fail = true;
return None;
}
- },
+ }
Addr::Con(Constant::Atom(name, _)) => (name, 0),
Addr::HeapCell(_) | Addr::StackCell(_, _) => {
- let instantiation_error = self.error_form(MachineError::instantiation_error(), stub);
+ let instantiation_error =
+ self.error_form(MachineError::instantiation_error(), stub);
self.throw_exception(instantiation_error);
return None;
- },
+ }
_ => {
- let type_error = self.error_form(MachineError::type_error(ValidType::Callable, addr), stub);
+ let type_error =
+ self.error_form(MachineError::type_error(ValidType::Callable, addr), stub);
self.throw_exception(type_error);
return None;
let diff = self.heap_ball_boundary_diff();
let mut stub = vec![];
- for index in 0 .. self.ball.stub.len() {
+ for index in 0..self.ball.stub.len() {
let heap_value = self.ball.stub[index].clone();
stub.push(match heap_value {
HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr - diff),
- _ => heap_value
+ _ => heap_value,
});
}
}
// arg(+N, +Term, ?Arg)
- pub(super) fn try_arg(&mut self) -> CallResult
- {
+ pub(super) fn try_arg(&mut self) -> CallResult {
let stub = MachineError::functor_stub(clause_name!("arg"), 3);
let n = self.store(self.deref(self[temp_v!(1)].clone()));
match n {
- Addr::HeapCell(_) | Addr::StackCell(..) => // 8.5.2.3 a)
- return Err(self.error_form(MachineError::instantiation_error(), stub)),
+ Addr::HeapCell(_) | Addr::StackCell(..) =>
+ // 8.5.2.3 a)
+ {
+ return Err(self.error_form(MachineError::instantiation_error(), stub))
+ }
Addr::Con(Constant::Integer(n)) => {
if n < 0 {
// 8.5.2.3 e)
let term = self.store(self.deref(self[temp_v!(2)].clone()));
match term {
- Addr::HeapCell(_) | Addr::StackCell(..) => // 8.5.2.3 b)
- return Err(self.error_form(MachineError::instantiation_error(), stub)),
- Addr::Str(o) =>
- match self.heap[o].clone() {
- HeapCellValue::NamedStr(arity, _, _) if 1 <= n && n <= arity => {
- let a3 = self[temp_v!(3)].clone();
- let h_a = Addr::HeapCell(o + n);
-
- self.unify(a3, h_a);
- },
- _ => self.fail = true
- },
- Addr::Lis(l) =>
+ Addr::HeapCell(_) | Addr::StackCell(..) =>
+ // 8.5.2.3 b)
+ {
+ return Err(self.error_form(MachineError::instantiation_error(), stub))
+ }
+ Addr::Str(o) => match self.heap[o].clone() {
+ HeapCellValue::NamedStr(arity, _, _) if 1 <= n && n <= arity => {
+ let a3 = self[temp_v!(3)].clone();
+ let h_a = Addr::HeapCell(o + n);
+
+ self.unify(a3, h_a);
+ }
+ _ => self.fail = true,
+ },
+ Addr::Lis(l) => {
if n == 1 || n == 2 {
- let a3 = self[temp_v!(3)].clone();
+ let a3 = self[temp_v!(3)].clone();
let h_a = Addr::HeapCell(l + n - 1);
self.unify(a3, h_a);
} else {
self.fail = true;
- },
+ }
+ }
Addr::Con(Constant::String(ref s))
- if !self.flags.double_quotes.is_atom() && !s.is_empty() => {
- if n == 1 || n == 2 {
- let a3 = self[temp_v!(3)].clone();
- let h_a = if n == 1 {
- if self.flags.double_quotes.is_chars() {
- Addr::Con(Constant::Char(s.head().unwrap()))
- } else {
- Addr::Con(Constant::CharCode(s.head().unwrap() as u8))
- }
+ if !self.flags.double_quotes.is_atom() && !s.is_empty() =>
+ {
+ if n == 1 || n == 2 {
+ let a3 = self[temp_v!(3)].clone();
+ let h_a = if n == 1 {
+ if self.flags.double_quotes.is_chars() {
+ Addr::Con(Constant::Char(s.head().unwrap()))
} else {
- Addr::Con(Constant::String(s.tail()))
- };
-
- self.unify(a3, h_a);
+ Addr::Con(Constant::CharCode(s.head().unwrap() as u8))
+ }
} else {
- self.fail = true;
- }
+ Addr::Con(Constant::String(s.tail()))
+ };
+
+ self.unify(a3, h_a);
+ } else {
+ self.fail = true;
}
- _ => // 8.5.2.3 d)
- return Err(self.error_form(MachineError::type_error(ValidType::Compound, term),
- stub))
+ }
+ _ =>
+ // 8.5.2.3 d)
+ {
+ return Err(self
+ .error_form(MachineError::type_error(ValidType::Compound, term), stub))
+ }
}
-
-
- },
- _ => // 8.5.2.3 c)
+ }
+ _ =>
+ // 8.5.2.3 c)
+ {
return Err(self.error_form(MachineError::type_error(ValidType::Integer, n), stub))
+ }
}
Ok(())
CompareNumberQT::LessThanOrEqual if ordering != Ordering::Greater => false,
CompareNumberQT::NotEqual if ordering != Ordering::Equal => false,
CompareNumberQT::Equal if ordering == Ordering::Equal => false,
- _ => true
+ _ => true,
};
self.p += 1;
let a2 = self[temp_v!(2)].clone();
match self.compare_term_test(&a1, &a2) {
- Ordering::Greater =>
- match qt {
- CompareTermQT::GreaterThan | CompareTermQT::GreaterThanOrEqual => return,
- _ => self.fail = true
- },
- Ordering::Equal =>
- match qt {
- CompareTermQT::GreaterThanOrEqual | CompareTermQT::LessThanOrEqual => return,
- _ => self.fail = true
- },
- Ordering::Less =>
- match qt {
- CompareTermQT::LessThan | CompareTermQT::LessThanOrEqual => return,
- _ => self.fail = true
- }
+ Ordering::Greater => match qt {
+ CompareTermQT::GreaterThan | CompareTermQT::GreaterThanOrEqual => return,
+ _ => self.fail = true,
+ },
+ Ordering::Equal => match qt {
+ CompareTermQT::GreaterThanOrEqual | CompareTermQT::LessThanOrEqual => return,
+ _ => self.fail = true,
+ },
+ Ordering::Less => match qt {
+ CompareTermQT::LessThan | CompareTermQT::LessThanOrEqual => return,
+ _ => self.fail = true,
+ },
};
}
// returns true on failure.
- pub(super) fn eq_test(&self) -> bool
- {
+ pub(super) fn eq_test(&self) -> bool {
let a1 = self[temp_v!(1)].clone();
let a2 = self[temp_v!(2)].clone();
while let Some((v1, v2)) = iter.next() {
match (v1, v2) {
- (HeapCellValue::NamedStr(ar1, n1, _), HeapCellValue::NamedStr(ar2, n2, _)) =>
+ (HeapCellValue::NamedStr(ar1, n1, _), HeapCellValue::NamedStr(ar2, n2, _)) => {
if ar1 != ar2 || n1 != n2 {
return true;
- },
- (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Lis(_))) =>
- continue,
- (HeapCellValue::Addr(a1), HeapCellValue::Addr(a2)) =>
+ }
+ }
+ (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Lis(_))) => continue,
+ (HeapCellValue::Addr(a1), HeapCellValue::Addr(a2)) => {
if a1 != a2 {
return true;
- },
- _ => return true
+ }
+ }
+ _ => return true,
}
}
while let Some((v1, v2)) = iter.next() {
match (v1, v2) {
- (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Con(Constant::String(_))))
- | (HeapCellValue::Addr(Addr::Con(Constant::String(_))), HeapCellValue::Addr(Addr::Lis(_)))
- if !self.flags.double_quotes.is_atom() => {},
- (HeapCellValue::Addr(Addr::Con(Constant::EmptyList)),
- HeapCellValue::Addr(Addr::Con(Constant::String(ref s))))
- if !self.flags.double_quotes.is_atom() => if s.is_empty() {
+ (
+ HeapCellValue::Addr(Addr::Lis(_)),
+ HeapCellValue::Addr(Addr::Con(Constant::String(_))),
+ )
+ | (
+ HeapCellValue::Addr(Addr::Con(Constant::String(_))),
+ HeapCellValue::Addr(Addr::Lis(_)),
+ ) if !self.flags.double_quotes.is_atom() => {}
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::EmptyList)),
+ HeapCellValue::Addr(Addr::Con(Constant::String(ref s))),
+ ) if !self.flags.double_quotes.is_atom() => {
+ if s.is_empty() {
return Ordering::Equal;
} else {
return Ordering::Greater;
- },
- (HeapCellValue::Addr(Addr::Con(Constant::Atom(atom, _))),
- HeapCellValue::Addr(Addr::Con(Constant::Char(c)))) =>
+ }
+ }
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::Atom(atom, _))),
+ HeapCellValue::Addr(Addr::Con(Constant::Char(c))),
+ ) => {
return if atom.as_str().chars().count() == 1 {
atom.as_str().chars().next().cmp(&Some(c))
} else {
Ordering::Greater
- },
- (HeapCellValue::Addr(Addr::Con(Constant::Char(c))),
- HeapCellValue::Addr(Addr::Con(Constant::Atom(atom, _)))) =>
+ }
+ }
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::Char(c))),
+ HeapCellValue::Addr(Addr::Con(Constant::Atom(atom, _))),
+ ) => {
return if atom.as_str().chars().count() == 1 {
Some(c).cmp(&atom.as_str().chars().next())
} else {
Ordering::Less
- },
- (HeapCellValue::Addr(Addr::Con(Constant::String(ref s))),
- HeapCellValue::Addr(Addr::Con(Constant::EmptyList)))
- if !self.flags.double_quotes.is_atom() => if s.is_empty() {
+ }
+ }
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::String(ref s))),
+ HeapCellValue::Addr(Addr::Con(Constant::EmptyList)),
+ ) if !self.flags.double_quotes.is_atom() => {
+ if s.is_empty() {
return Ordering::Equal;
} else {
return Ordering::Less;
- },
- (HeapCellValue::Addr(Addr::HeapCell(hc1)),
- HeapCellValue::Addr(Addr::HeapCell(hc2)))
- | (HeapCellValue::Addr(Addr::AttrVar(hc1)),
- HeapCellValue::Addr(Addr::HeapCell(hc2)))
- | (HeapCellValue::Addr(Addr::HeapCell(hc1)),
- HeapCellValue::Addr(Addr::AttrVar(hc2)))
- | (HeapCellValue::Addr(Addr::AttrVar(hc1)),
- HeapCellValue::Addr(Addr::AttrVar(hc2))) =>
+ }
+ }
+ (
+ HeapCellValue::Addr(Addr::HeapCell(hc1)),
+ HeapCellValue::Addr(Addr::HeapCell(hc2)),
+ )
+ | (
+ HeapCellValue::Addr(Addr::AttrVar(hc1)),
+ HeapCellValue::Addr(Addr::HeapCell(hc2)),
+ )
+ | (
+ HeapCellValue::Addr(Addr::HeapCell(hc1)),
+ HeapCellValue::Addr(Addr::AttrVar(hc2)),
+ )
+ | (
+ HeapCellValue::Addr(Addr::AttrVar(hc1)),
+ HeapCellValue::Addr(Addr::AttrVar(hc2)),
+ ) => {
if hc1 != hc2 {
return hc1.cmp(&hc2);
- },
+ }
+ }
(HeapCellValue::Addr(Addr::HeapCell(_)), _)
- | (HeapCellValue::Addr(Addr::AttrVar(_)), _) =>
- return Ordering::Less,
- (HeapCellValue::Addr(Addr::StackCell(fr1, sc1)),
- HeapCellValue::Addr(Addr::StackCell(fr2, sc2))) =>
+ | (HeapCellValue::Addr(Addr::AttrVar(_)), _) => return Ordering::Less,
+ (
+ HeapCellValue::Addr(Addr::StackCell(fr1, sc1)),
+ HeapCellValue::Addr(Addr::StackCell(fr2, sc2)),
+ ) => {
if fr1 > fr2 {
return Ordering::Greater;
} else if fr1 < fr2 || sc1 < sc2 {
return Ordering::Less;
} else if sc1 > sc2 {
return Ordering::Greater;
- },
- (HeapCellValue::Addr(Addr::StackCell(..)),
- HeapCellValue::Addr(Addr::HeapCell(_)))
- | (HeapCellValue::Addr(Addr::StackCell(..)),
- HeapCellValue::Addr(Addr::AttrVar(_))) =>
- return Ordering::Greater,
- (HeapCellValue::Addr(Addr::StackCell(..)), _) =>
- return Ordering::Less,
- (HeapCellValue::Addr(Addr::Con(Constant::Integer(..))),
- HeapCellValue::Addr(Addr::HeapCell(_)))
- | (HeapCellValue::Addr(Addr::Con(Constant::Integer(..))),
- HeapCellValue::Addr(Addr::AttrVar(_))) =>
- return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::Integer(..))),
- HeapCellValue::Addr(Addr::StackCell(..))) =>
- return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::Integer(n1))),
- HeapCellValue::Addr(Addr::Con(Constant::Integer(n2)))) =>
+ }
+ }
+ (
+ HeapCellValue::Addr(Addr::StackCell(..)),
+ HeapCellValue::Addr(Addr::HeapCell(_)),
+ )
+ | (
+ HeapCellValue::Addr(Addr::StackCell(..)),
+ HeapCellValue::Addr(Addr::AttrVar(_)),
+ ) => return Ordering::Greater,
+ (HeapCellValue::Addr(Addr::StackCell(..)), _) => return Ordering::Less,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::Integer(..))),
+ HeapCellValue::Addr(Addr::HeapCell(_)),
+ )
+ | (
+ HeapCellValue::Addr(Addr::Con(Constant::Integer(..))),
+ HeapCellValue::Addr(Addr::AttrVar(_)),
+ ) => return Ordering::Greater,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::Integer(..))),
+ HeapCellValue::Addr(Addr::StackCell(..)),
+ ) => return Ordering::Greater,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::Integer(n1))),
+ HeapCellValue::Addr(Addr::Con(Constant::Integer(n2))),
+ ) => {
if n1 != n2 {
return n1.cmp(&n2);
- },
- (HeapCellValue::Addr(Addr::Con(Constant::Integer(_))), _) =>
- return Ordering::Less,
- (HeapCellValue::Addr(Addr::Con(Constant::Float(..))),
- HeapCellValue::Addr(Addr::HeapCell(_)))
- | (HeapCellValue::Addr(Addr::Con(Constant::Float(..))),
- HeapCellValue::Addr(Addr::AttrVar(_))) =>
- return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::Float(..))),
- HeapCellValue::Addr(Addr::StackCell(..))) =>
- return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::Float(n1))),
- HeapCellValue::Addr(Addr::Con(Constant::Float(n2)))) =>
+ }
+ }
+ (HeapCellValue::Addr(Addr::Con(Constant::Integer(_))), _) => return Ordering::Less,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::Float(..))),
+ HeapCellValue::Addr(Addr::HeapCell(_)),
+ )
+ | (
+ HeapCellValue::Addr(Addr::Con(Constant::Float(..))),
+ HeapCellValue::Addr(Addr::AttrVar(_)),
+ ) => return Ordering::Greater,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::Float(..))),
+ HeapCellValue::Addr(Addr::StackCell(..)),
+ ) => return Ordering::Greater,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::Float(n1))),
+ HeapCellValue::Addr(Addr::Con(Constant::Float(n2))),
+ ) => {
if n1 != n2 {
return n1.cmp(&n2);
- },
- (HeapCellValue::Addr(Addr::Con(Constant::Float(_))), _) =>
- return Ordering::Less,
- (HeapCellValue::Addr(Addr::Con(Constant::Rational(..))),
- HeapCellValue::Addr(Addr::HeapCell(_)))
- | (HeapCellValue::Addr(Addr::Con(Constant::Rational(..))),
- HeapCellValue::Addr(Addr::AttrVar(_))) =>
- return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::Rational(..))),
- HeapCellValue::Addr(Addr::StackCell(..))) =>
- return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::Rational(n1))),
- HeapCellValue::Addr(Addr::Con(Constant::Rational(n2)))) =>
+ }
+ }
+ (HeapCellValue::Addr(Addr::Con(Constant::Float(_))), _) => return Ordering::Less,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::Rational(..))),
+ HeapCellValue::Addr(Addr::HeapCell(_)),
+ )
+ | (
+ HeapCellValue::Addr(Addr::Con(Constant::Rational(..))),
+ HeapCellValue::Addr(Addr::AttrVar(_)),
+ ) => return Ordering::Greater,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::Rational(..))),
+ HeapCellValue::Addr(Addr::StackCell(..)),
+ ) => return Ordering::Greater,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::Rational(n1))),
+ HeapCellValue::Addr(Addr::Con(Constant::Rational(n2))),
+ ) => {
if n1 != n2 {
return n1.cmp(&n2);
- },
- (HeapCellValue::Addr(Addr::Con(Constant::Rational(_))), _) =>
- return Ordering::Less,
- (HeapCellValue::Addr(Addr::Con(Constant::String(..))),
- HeapCellValue::Addr(Addr::HeapCell(_)))
- | (HeapCellValue::Addr(Addr::Con(Constant::String(..))),
- HeapCellValue::Addr(Addr::AttrVar(_))) =>
- return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::String(..))),
- HeapCellValue::Addr(Addr::StackCell(..))) =>
- return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::String(_))),
- HeapCellValue::Addr(Addr::Con(Constant::Integer(_)))) =>
- return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::String(_))),
- HeapCellValue::Addr(Addr::Con(Constant::Rational(_)))) =>
- return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::String(_))),
- HeapCellValue::Addr(Addr::Con(Constant::Float(_)))) =>
- return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::String(s1))),
- HeapCellValue::Addr(Addr::Con(Constant::String(s2)))) =>
+ }
+ }
+ (HeapCellValue::Addr(Addr::Con(Constant::Rational(_))), _) => {
+ return Ordering::Less
+ }
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::String(..))),
+ HeapCellValue::Addr(Addr::HeapCell(_)),
+ )
+ | (
+ HeapCellValue::Addr(Addr::Con(Constant::String(..))),
+ HeapCellValue::Addr(Addr::AttrVar(_)),
+ ) => return Ordering::Greater,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::String(..))),
+ HeapCellValue::Addr(Addr::StackCell(..)),
+ ) => return Ordering::Greater,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::String(_))),
+ HeapCellValue::Addr(Addr::Con(Constant::Integer(_))),
+ ) => return Ordering::Greater,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::String(_))),
+ HeapCellValue::Addr(Addr::Con(Constant::Rational(_))),
+ ) => return Ordering::Greater,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::String(_))),
+ HeapCellValue::Addr(Addr::Con(Constant::Float(_))),
+ ) => return Ordering::Greater,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::String(s1))),
+ HeapCellValue::Addr(Addr::Con(Constant::String(s2))),
+ ) => {
return if s1.is_expandable() {
if s2.is_expandable() {
s1.cmp(&s2)
} else {
s1.cmp(&s2)
}
- },
- (HeapCellValue::Addr(Addr::Con(Constant::String(_))), _) =>
- return Ordering::Less,
- (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
- HeapCellValue::Addr(Addr::HeapCell(_)))
- | (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
- HeapCellValue::Addr(Addr::AttrVar(_))) =>
- return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
- HeapCellValue::Addr(Addr::StackCell(..))) =>
- return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
- HeapCellValue::Addr(Addr::Con(Constant::Float(_)))) =>
- return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
- HeapCellValue::Addr(Addr::Con(Constant::Integer(_)))) =>
- return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
- HeapCellValue::Addr(Addr::Con(Constant::Rational(_)))) =>
- return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
- HeapCellValue::Addr(Addr::Con(Constant::String(_)))) =>
- return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::Atom(s1, _))),
- HeapCellValue::Addr(Addr::Con(Constant::Atom(s2, _)))) =>
+ }
+ }
+ (HeapCellValue::Addr(Addr::Con(Constant::String(_))), _) => return Ordering::Less,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
+ HeapCellValue::Addr(Addr::HeapCell(_)),
+ )
+ | (
+ HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
+ HeapCellValue::Addr(Addr::AttrVar(_)),
+ ) => return Ordering::Greater,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
+ HeapCellValue::Addr(Addr::StackCell(..)),
+ ) => return Ordering::Greater,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
+ HeapCellValue::Addr(Addr::Con(Constant::Float(_))),
+ ) => return Ordering::Greater,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
+ HeapCellValue::Addr(Addr::Con(Constant::Integer(_))),
+ ) => return Ordering::Greater,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
+ HeapCellValue::Addr(Addr::Con(Constant::Rational(_))),
+ ) => return Ordering::Greater,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
+ HeapCellValue::Addr(Addr::Con(Constant::String(_))),
+ ) => return Ordering::Greater,
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::Atom(s1, _))),
+ HeapCellValue::Addr(Addr::Con(Constant::Atom(s2, _))),
+ ) => {
if s1 != s2 {
return s1.cmp(&s2);
- },
- (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))), _) =>
- return Ordering::Less,
- (HeapCellValue::NamedStr(ar1, n1, _), HeapCellValue::NamedStr(ar2, n2, _)) =>
+ }
+ }
+ (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))), _) => return Ordering::Less,
+ (HeapCellValue::NamedStr(ar1, n1, _), HeapCellValue::NamedStr(ar2, n2, _)) => {
if ar1 < ar2 {
return Ordering::Less;
} else if ar1 > ar2 {
return Ordering::Greater;
} else if n1 != n2 {
return n1.cmp(&n2);
- },
- (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Lis(_))) =>
- continue,
+ }
+ }
+ (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Lis(_))) => continue,
(HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::NamedStr(ar, n, _))
- | (HeapCellValue::NamedStr(ar, n, _), HeapCellValue::Addr(Addr::Lis(_))) =>
+ | (HeapCellValue::NamedStr(ar, n, _), HeapCellValue::Addr(Addr::Lis(_))) => {
if ar == 2 && n.as_str() == "." {
continue;
} else if ar < 2 {
return Ordering::Less;
} else {
return n.as_str().cmp(".");
- },
- (HeapCellValue::NamedStr(..), _) =>
- return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Lis(_)), _) =>
- return Ordering::Greater,
+ }
+ }
+ (HeapCellValue::NamedStr(..), _) => return Ordering::Greater,
+ (HeapCellValue::Addr(Addr::Lis(_)), _) => return Ordering::Greater,
_ => {}
}
- };
+ }
iter.first_to_expire
}
pub(super) fn reset_block(&mut self, addr: Addr) {
match self.store(addr) {
Addr::Con(Constant::Usize(b)) => self.block = b,
- _ => self.fail = true
+ _ => self.fail = true,
};
}
let n2 = try_or_fail!(self, self.get_number(at_2));
self.compare_numbers(cmp, n1, n2);
- },
+ }
&InlinedClauseType::IsAtom(r1) => {
let d = self.store(self.deref(self[r1].clone()));
match d {
Addr::Con(Constant::Atom(..)) | Addr::Con(Constant::Char(_)) => self.p += 1,
Addr::Con(Constant::EmptyList) => self.p += 1,
- _ => self.fail = true
+ _ => self.fail = true,
};
- },
+ }
&InlinedClauseType::IsAtomic(r1) => {
let d = self.store(self.deref(self[r1].clone()));
match d {
Addr::Con(_) => self.p += 1,
- _ => self.fail = true
+ _ => self.fail = true,
};
- },
+ }
&InlinedClauseType::IsInteger(r1) => {
let d = self.store(self.deref(self[r1].clone()));
match d {
- Addr::Con(Constant::Integer(_)) => self.p += 1,
+ Addr::Con(Constant::Integer(_)) => self.p += 1,
Addr::Con(Constant::CharCode(_)) => self.p += 1,
- Addr::Con(Constant::Rational(r)) =>
+ Addr::Con(Constant::Rational(r)) => {
if r.denom() == &1 {
self.p += 1;
} else {
self.fail = true;
- },
- _ => self.fail = true
+ }
+ }
+ _ => self.fail = true,
};
- },
+ }
&InlinedClauseType::IsCompound(r1) => {
let d = self.store(self.deref(self[r1].clone()));
match d {
Addr::Str(_) | Addr::Lis(_) => self.p += 1,
- _ => self.fail = true
+ _ => self.fail = true,
};
- },
+ }
&InlinedClauseType::IsFloat(r1) => {
let d = self.store(self.deref(self[r1].clone()));
match d {
Addr::Con(Constant::Float(_)) => self.p += 1,
- _ => self.fail = true
+ _ => self.fail = true,
};
- },
+ }
&InlinedClauseType::IsRational(r1) => {
let d = self.store(self.deref(self[r1].clone()));
match d {
Addr::Con(Constant::Rational(_)) => self.p += 1,
- _ => self.fail = true
+ _ => self.fail = true,
};
- },
+ }
&InlinedClauseType::IsString(r1) => {
let d = self.store(self.deref(self[r1].clone()));
match d {
Addr::Con(Constant::String(_)) => self.p += 1,
- _ => self.fail = true
+ _ => self.fail = true,
};
- },
+ }
&InlinedClauseType::IsNonVar(r1) => {
let d = self.store(self.deref(self[r1].clone()));
match d {
Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(..) => self.fail = true,
- _ => self.p += 1
+ _ => self.p += 1,
};
- },
+ }
&InlinedClauseType::IsVar(r1) => {
let d = self.store(self.deref(self[r1].clone()));
match d {
- Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_,_) => self.p += 1,
- _ => self.fail = true
+ Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => self.p += 1,
+ _ => self.fail = true,
};
- },
+ }
&InlinedClauseType::IsPartialString(r1) => {
let d = self.store(self.deref(self[r1].clone()));
match d {
Addr::Con(Constant::String(ref s)) if s.is_expandable() => self.p += 1,
- _ => self.fail = true
+ _ => self.fail = true,
};
}
}
}
}
- fn try_functor_compound_case(&mut self, name: ClauseName, arity: usize, spec: Option<SharedOpDesc>)
- {
- let name = Addr::Con(Constant::Atom(name, spec));
+ fn try_functor_compound_case(
+ &mut self,
+ name: ClauseName,
+ arity: usize,
+ spec: Option<SharedOpDesc>,
+ ) {
+ let name = Addr::Con(Constant::Atom(name, spec));
let arity = Addr::Con(Constant::Integer(Integer::from(arity)));
self.try_functor_unify_components(name, arity);
}
- fn try_functor_fabricate_struct(&mut self, name: ClauseName, arity: isize,
- spec: Option<SharedOpDesc>, op_dir: &OpDir,
- r: Ref)
- {
+ fn try_functor_fabricate_struct(
+ &mut self,
+ name: ClauseName,
+ arity: isize,
+ spec: Option<SharedOpDesc>,
+ op_dir: &OpDir,
+ r: Ref,
+ ) {
let spec = fetch_atom_op_spec(name.clone(), spec, op_dir);
let f_a = if name.as_str() == "." && arity == 2 {
Addr::Lis(self.heap.h)
} else {
let h = self.heap.h;
- self.heap.push(HeapCellValue::NamedStr(arity as usize, name, spec));
+ self.heap
+ .push(HeapCellValue::NamedStr(arity as usize, name, spec));
Addr::Str(h)
};
- for _ in 0 .. arity {
+ for _ in 0..arity {
let h = self.heap.h;
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
}
let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
match a1.clone() {
- Addr::DBRef(_) =>
- self.fail = true,
+ Addr::DBRef(_) => self.fail = true,
Addr::Con(Constant::String(ref s))
- if !self.flags.double_quotes.is_atom() && !s.is_empty() => {
- let shared_op_desc = fetch_op_spec(clause_name!("."), 2, None, &indices.op_dir);
- self.try_functor_compound_case(clause_name!("."), 2, shared_op_desc)
- },
- Addr::Con(_) =>
- self.try_functor_unify_components(a1, Addr::Con(Constant::Integer(Integer::from(0)))),
- Addr::Str(o) =>
- match self.heap[o].clone() {
- HeapCellValue::NamedStr(arity, name, spec) => {
- let spec = fetch_op_spec(name.clone(), arity, spec, &indices.op_dir);
- self.try_functor_compound_case(name, arity, spec)
- },
- _ => self.fail = true
- },
- Addr::Lis(_) => {
+ if !self.flags.double_quotes.is_atom() && !s.is_empty() =>
+ {
let shared_op_desc = fetch_op_spec(clause_name!("."), 2, None, &indices.op_dir);
self.try_functor_compound_case(clause_name!("."), 2, shared_op_desc)
+ }
+ Addr::Con(_) => self
+ .try_functor_unify_components(a1, Addr::Con(Constant::Integer(Integer::from(0)))),
+ Addr::Str(o) => match self.heap[o].clone() {
+ HeapCellValue::NamedStr(arity, name, spec) => {
+ let spec = fetch_op_spec(name.clone(), arity, spec, &indices.op_dir);
+ self.try_functor_compound_case(name, arity, spec)
+ }
+ _ => self.fail = true,
},
+ Addr::Lis(_) => {
+ let shared_op_desc = fetch_op_spec(clause_name!("."), 2, None, &indices.op_dir);
+ self.try_functor_compound_case(clause_name!("."), 2, shared_op_desc)
+ }
Addr::AttrVar(..) | Addr::HeapCell(_) | Addr::StackCell(..) => {
- let name = self.store(self.deref(self[temp_v!(2)].clone()));
+ let name = self.store(self.deref(self[temp_v!(2)].clone()));
let arity = self.store(self.deref(self[temp_v!(3)].clone()));
- if name.is_ref() || arity.is_ref() { // 8.5.1.3 a) & 8.5.1.3 b)
+ if name.is_ref() || arity.is_ref() {
+ // 8.5.1.3 a) & 8.5.1.3 b)
return Err(self.error_form(MachineError::instantiation_error(), stub));
}
return Err(self.error_form(rep_err, stub));
} else if arity < 0 {
// 8.5.1.3 g)
- let arity = Integer::from(arity);
- let dom_err = MachineError::domain_error(DomainError::NotLessThanZero,
- Addr::Con(Constant::Integer(arity)));
+ let arity = Integer::from(arity);
+ let dom_err = MachineError::domain_error(
+ DomainError::NotLessThanZero,
+ Addr::Con(Constant::Integer(arity)),
+ );
return Err(self.error_form(dom_err, stub));
}
match name {
- Addr::Con(_) if arity == 0 =>
- self.unify(a1, name),
- Addr::Con(Constant::Atom(name, spec)) =>
- self.try_functor_fabricate_struct(name, arity, spec, &indices.op_dir,
- a1.as_var().unwrap()),
+ Addr::Con(_) if arity == 0 => self.unify(a1, name),
+ Addr::Con(Constant::Atom(name, spec)) => self.try_functor_fabricate_struct(
+ name,
+ arity,
+ spec,
+ &indices.op_dir,
+ a1.as_var().unwrap(),
+ ),
Addr::Con(Constant::Char(c)) => {
let name = clause_name!(c.to_string(), indices.atom_tbl);
- self.try_functor_fabricate_struct(name, arity, None, &indices.op_dir,
- a1.as_var().unwrap());
- },
- Addr::Con(_) =>
- return Err(self.error_form(MachineError::type_error(ValidType::Atom, name),
- stub)), // 8.5.1.3 e)
- _ =>
- return Err(self.error_form(MachineError::type_error(ValidType::Atomic, name),
- stub)) // 8.5.1.3 c)
+ self.try_functor_fabricate_struct(
+ name,
+ arity,
+ None,
+ &indices.op_dir,
+ a1.as_var().unwrap(),
+ );
+ }
+ Addr::Con(_) => {
+ return Err(self
+ .error_form(MachineError::type_error(ValidType::Atom, name), stub))
+ } // 8.5.1.3 e)
+ _ => {
+ return Err(self.error_form(
+ MachineError::type_error(ValidType::Atomic, name),
+ stub,
+ ))
+ } // 8.5.1.3 c)
};
} else if !arity.is_ref() {
// 8.5.1.3 d)
- return Err(self.error_form(MachineError::type_error(ValidType::Integer, arity), stub));
+ return Err(
+ self.error_form(MachineError::type_error(ValidType::Integer, arity), stub)
+ );
}
}
};
*list = result;
}
- pub(super)
- fn try_string_list(&self, r: RegType) -> Result<StringList, MachineStub> {
+ pub(super) fn try_string_list(&self, r: RegType) -> Result<StringList, MachineStub> {
let a1 = self[r].clone();
let a1 = self.store(self.deref(a1));
let stub = MachineError::functor_stub(clause_name!("partial_string"), 2);
match self.try_from_list(r, stub.clone()) {
- Ok(addrs) =>
- Ok(StringList::new(match self.try_char_list(addrs) {
+ Ok(addrs) => Ok(StringList::new(
+ match self.try_char_list(addrs) {
Ok(string) => string,
Err(err) => {
return Err(self.error_form(err, stub));
}
- }, false)),
- Err(err) => return Err(err)
+ },
+ false,
+ )),
+ Err(err) => return Err(err),
}
}
}
- pub(super)
- fn try_from_list(&self, r: RegType, caller: MachineStub) -> Result<Vec<Addr>, MachineStub>
- {
+ pub(super) fn try_from_list(
+ &self,
+ r: RegType,
+ caller: MachineStub,
+ ) -> Result<Vec<Addr>, MachineStub> {
let a1 = self.store(self.deref(self[r].clone()));
match a1.clone() {
loop {
match self.heap[l].clone() {
- HeapCellValue::Addr(addr) =>
- match self.store(self.deref(addr)) {
- Addr::Lis(hcp) => {
- result.push(self.heap[hcp].as_addr(hcp));
- l = hcp + 1;
- },
- Addr::Con(Constant::String(ref s))
- if !self.flags.double_quotes.is_atom() => {
- result.push(Addr::Con(Constant::String(s.clone())));
- break;
- },
- Addr::Con(Constant::EmptyList) =>
- break,
- Addr::HeapCell(_) | Addr::StackCell(..) =>
- return Err(self.error_form(MachineError::instantiation_error(), caller)),
- _ =>
- return Err(self.error_form(MachineError::type_error(ValidType::List, a1),
- caller))
- },
- _ =>
- return Err(self.error_form(MachineError::type_error(ValidType::List, a1),
- caller))
+ HeapCellValue::Addr(addr) => match self.store(self.deref(addr)) {
+ Addr::Lis(hcp) => {
+ result.push(self.heap[hcp].as_addr(hcp));
+ l = hcp + 1;
+ }
+ Addr::Con(Constant::String(ref s))
+ if !self.flags.double_quotes.is_atom() =>
+ {
+ result.push(Addr::Con(Constant::String(s.clone())));
+ break;
+ }
+ Addr::Con(Constant::EmptyList) => break,
+ Addr::HeapCell(_) | Addr::StackCell(..) => {
+ return Err(
+ self.error_form(MachineError::instantiation_error(), caller)
+ )
+ }
+ _ => {
+ return Err(self.error_form(
+ MachineError::type_error(ValidType::List, a1),
+ caller,
+ ))
+ }
+ },
+ _ => {
+ return Err(self
+ .error_form(MachineError::type_error(ValidType::List, a1), caller))
+ }
}
}
Ok(result)
- },
- Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() =>
- Ok(vec![Addr::Con(Constant::String(s.clone()))]),
- Addr::HeapCell(_) | Addr::StackCell(..) =>
- Err(self.error_form(MachineError::instantiation_error(), caller)),
- Addr::Con(Constant::EmptyList) =>
- Ok(vec![]),
- _ =>
- Err(self.error_form(MachineError::type_error(ValidType::List, a1), caller))
+ }
+ Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() => {
+ Ok(vec![Addr::Con(Constant::String(s.clone()))])
+ }
+ Addr::HeapCell(_) | Addr::StackCell(..) => {
+ Err(self.error_form(MachineError::instantiation_error(), caller))
+ }
+ Addr::Con(Constant::EmptyList) => Ok(vec![]),
+ _ => Err(self.error_form(MachineError::type_error(ValidType::List, a1), caller)),
}
}
let stub = MachineError::functor_stub(clause_name!("keysort"), 2);
match self.store(self.deref(a)) {
- Addr::HeapCell(_) | Addr::StackCell(..) =>
- Err(self.error_form(MachineError::instantiation_error(), stub)),
- Addr::Str(s) =>
- match self.heap[s].clone() {
- HeapCellValue::NamedStr(2, ref name, Some(_))
- if *name == clause_name!("-") =>
- Ok(Addr::HeapCell(s+1)),
- _ =>
- Err(self.error_form(MachineError::type_error(ValidType::Pair,
- self.heap[s].as_addr(s)),
- stub))
- },
- a => Err(self.error_form(MachineError::type_error(ValidType::Pair, a), stub))
+ Addr::HeapCell(_) | Addr::StackCell(..) => {
+ Err(self.error_form(MachineError::instantiation_error(), stub))
+ }
+ Addr::Str(s) => match self.heap[s].clone() {
+ HeapCellValue::NamedStr(2, ref name, Some(_)) if *name == clause_name!("-") => {
+ Ok(Addr::HeapCell(s + 1))
+ }
+ _ => Err(self.error_form(
+ MachineError::type_error(ValidType::Pair, self.heap[s].as_addr(s)),
+ stub,
+ )),
+ },
+ a => Err(self.error_form(MachineError::type_error(ValidType::Pair, a), stub)),
}
}
}
// returns true on failure.
- pub(super) fn structural_eq_test(&self) -> bool
- {
+ pub(super) fn structural_eq_test(&self) -> bool {
let a1 = self[temp_v!(1)].clone();
let a2 = self[temp_v!(2)].clone();
for (v1, v2) in iter {
match (v1, v2) {
- (HeapCellValue::Addr(Addr::Lis(l)), HeapCellValue::Addr(Addr::Con(Constant::String(ref s))))
- | (HeapCellValue::Addr(Addr::Con(Constant::String(ref s))), HeapCellValue::Addr(Addr::Lis(l)))
- if !self.flags.double_quotes.is_atom() => {
- match self.flags.double_quotes {
- DoubleQuotes::Chars =>
- if self.structural_char_list_test(s, l) {
- continue;
- },
- DoubleQuotes::Codes =>
- if self.structural_code_list_test(s, l) {
- continue;
- },
- DoubleQuotes::Atom => unreachable!()
+ (
+ HeapCellValue::Addr(Addr::Lis(l)),
+ HeapCellValue::Addr(Addr::Con(Constant::String(ref s))),
+ )
+ | (
+ HeapCellValue::Addr(Addr::Con(Constant::String(ref s))),
+ HeapCellValue::Addr(Addr::Lis(l)),
+ ) if !self.flags.double_quotes.is_atom() => match self.flags.double_quotes {
+ DoubleQuotes::Chars => {
+ if self.structural_char_list_test(s, l) {
+ continue;
}
- },
- (HeapCellValue::Addr(Addr::Con(Constant::String(ref s1))),
- HeapCellValue::Addr(Addr::Con(Constant::String(ref s2)))) =>
- match s1.head() {
- Some(c1) => if let Some(c2) = s2.head() {
+ }
+ DoubleQuotes::Codes => {
+ if self.structural_code_list_test(s, l) {
+ continue;
+ }
+ }
+ DoubleQuotes::Atom => unreachable!(),
+ },
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::String(ref s1))),
+ HeapCellValue::Addr(Addr::Con(Constant::String(ref s2))),
+ ) => match s1.head() {
+ Some(c1) => {
+ if let Some(c2) = s2.head() {
if c1 != c2 {
return true;
}
} else {
return true;
- },
- None => return !s2.is_empty()
- },
- (HeapCellValue::Addr(Addr::Con(Constant::String(ref s))),
- HeapCellValue::Addr(Addr::Con(Constant::EmptyList)))
- | (HeapCellValue::Addr(Addr::Con(Constant::EmptyList)),
- HeapCellValue::Addr(Addr::Con(Constant::String(ref s))))
- if !self.flags.double_quotes.is_atom() => if !s.is_empty() {
+ }
+ }
+ None => return !s2.is_empty(),
+ },
+ (
+ HeapCellValue::Addr(Addr::Con(Constant::String(ref s))),
+ HeapCellValue::Addr(Addr::Con(Constant::EmptyList)),
+ )
+ | (
+ HeapCellValue::Addr(Addr::Con(Constant::EmptyList)),
+ HeapCellValue::Addr(Addr::Con(Constant::String(ref s))),
+ ) if !self.flags.double_quotes.is_atom() => {
+ if !s.is_empty() {
return true;
- },
- (HeapCellValue::NamedStr(ar1, n1, _), HeapCellValue::NamedStr(ar2, n2, _)) =>
+ }
+ }
+ (HeapCellValue::NamedStr(ar1, n1, _), HeapCellValue::NamedStr(ar2, n2, _)) => {
if ar1 != ar2 || n1 != n2 {
return true;
- },
- (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Lis(_))) =>
- continue,
- (HeapCellValue::Addr(v1 @ Addr::HeapCell(_)), HeapCellValue::Addr(v2 @ Addr::AttrVar(_)))
- | (HeapCellValue::Addr(v1 @ Addr::StackCell(..)), HeapCellValue::Addr(v2 @ Addr::AttrVar(_)))
- | (HeapCellValue::Addr(v1 @ Addr::AttrVar(_)), HeapCellValue::Addr(v2 @ Addr::AttrVar(_)))
- | (HeapCellValue::Addr(v1 @ Addr::AttrVar(_)), HeapCellValue::Addr(v2 @ Addr::HeapCell(_)))
- | (HeapCellValue::Addr(v1 @ Addr::AttrVar(_)), HeapCellValue::Addr(v2 @ Addr::StackCell(..)))
- | (HeapCellValue::Addr(v1 @ Addr::HeapCell(_)), HeapCellValue::Addr(v2 @ Addr::HeapCell(_)))
- | (HeapCellValue::Addr(v1 @ Addr::HeapCell(_)), HeapCellValue::Addr(v2 @ Addr::StackCell(..)))
- | (HeapCellValue::Addr(v1 @ Addr::StackCell(..)), HeapCellValue::Addr(v2 @ Addr::StackCell(..)))
- | (HeapCellValue::Addr(v1 @ Addr::StackCell(..)), HeapCellValue::Addr(v2 @ Addr::HeapCell(_))) =>
- match (var_pairs.get(&v1).cloned(), var_pairs.get(&v2).cloned()) {
- (Some(ref v2_p), Some(ref v1_p)) if *v1_p == v1 && *v2_p == v2 =>
- continue,
- (Some(_), _) | (_, Some(_)) =>
- return true,
- (None, None) => {
- var_pairs.insert(v1.clone(), v2.clone());
- var_pairs.insert(v2, v1);
- }
- },
- (HeapCellValue::Addr(a1), HeapCellValue::Addr(a2)) =>
+ }
+ }
+ (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Lis(_))) => continue,
+ (
+ HeapCellValue::Addr(v1 @ Addr::HeapCell(_)),
+ HeapCellValue::Addr(v2 @ Addr::AttrVar(_)),
+ )
+ | (
+ HeapCellValue::Addr(v1 @ Addr::StackCell(..)),
+ HeapCellValue::Addr(v2 @ Addr::AttrVar(_)),
+ )
+ | (
+ HeapCellValue::Addr(v1 @ Addr::AttrVar(_)),
+ HeapCellValue::Addr(v2 @ Addr::AttrVar(_)),
+ )
+ | (
+ HeapCellValue::Addr(v1 @ Addr::AttrVar(_)),
+ HeapCellValue::Addr(v2 @ Addr::HeapCell(_)),
+ )
+ | (
+ HeapCellValue::Addr(v1 @ Addr::AttrVar(_)),
+ HeapCellValue::Addr(v2 @ Addr::StackCell(..)),
+ )
+ | (
+ HeapCellValue::Addr(v1 @ Addr::HeapCell(_)),
+ HeapCellValue::Addr(v2 @ Addr::HeapCell(_)),
+ )
+ | (
+ HeapCellValue::Addr(v1 @ Addr::HeapCell(_)),
+ HeapCellValue::Addr(v2 @ Addr::StackCell(..)),
+ )
+ | (
+ HeapCellValue::Addr(v1 @ Addr::StackCell(..)),
+ HeapCellValue::Addr(v2 @ Addr::StackCell(..)),
+ )
+ | (
+ HeapCellValue::Addr(v1 @ Addr::StackCell(..)),
+ HeapCellValue::Addr(v2 @ Addr::HeapCell(_)),
+ ) => match (var_pairs.get(&v1).cloned(), var_pairs.get(&v2).cloned()) {
+ (Some(ref v2_p), Some(ref v1_p)) if *v1_p == v1 && *v2_p == v2 => continue,
+ (Some(_), _) | (_, Some(_)) => return true,
+ (None, None) => {
+ var_pairs.insert(v1.clone(), v2.clone());
+ var_pairs.insert(v2, v1);
+ }
+ },
+ (HeapCellValue::Addr(a1), HeapCellValue::Addr(a2)) => {
if a1 != a2 {
return true;
- },
- _ => return true
+ }
+ }
+ _ => return true,
}
}
}
// returns true on failure.
- pub(super) fn ground_test(&self) -> bool
- {
+ pub(super) fn ground_test(&self) -> bool {
let a = self.store(self.deref(self[temp_v!(1)].clone()));
for v in self.acyclic_pre_order_iter(a) {
match v {
- HeapCellValue::Addr(Addr::HeapCell(..)) =>
- return true,
- HeapCellValue::Addr(Addr::StackCell(..)) =>
- return true,
+ HeapCellValue::Addr(Addr::HeapCell(..)) => return true,
+ HeapCellValue::Addr(Addr::StackCell(..)) => return true,
_ => {}
}
- };
+ }
false
}
- pub(super) fn setup_built_in_call(&mut self, ct: BuiltInClauseType)
- {
+ pub(super) fn setup_built_in_call(&mut self, ct: BuiltInClauseType) {
self.num_of_args = ct.arity();
self.b0 = self.b;
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()
+ let or_gi = self
+ .or_stack
+ .top()
.map(|or_fr| or_fr.global_index)
.unwrap_or(0);
if and_gi > or_gi {
let new_e = self.e + 1;
- self.and_stack[new_e].e = self.e;
+ self.and_stack[new_e].e = self.e;
self.and_stack[new_e].cp = self.cp.clone();
self.and_stack[new_e].global_index = gi;
let e = self.e;
self.cp = self.and_stack[e].cp.clone();
- self.e = self.and_stack[e].e;
+ self.e = self.and_stack[e].e;
self.p += 1;
}
- fn handle_call_clause(&mut self, indices: &mut IndexStore,
- code_repo: &CodeRepo,
- call_policy: &mut Box<CallPolicy>,
- cut_policy: &mut Box<CutPolicy>,
- parsing_stream: &mut PrologStream,
- ct: &ClauseType,
- arity: usize,
- lco: bool,
- use_default_cp: bool)
- {
+ fn handle_call_clause(
+ &mut self,
+ indices: &mut IndexStore,
+ code_repo: &CodeRepo,
+ call_policy: &mut Box<CallPolicy>,
+ cut_policy: &mut Box<CutPolicy>,
+ parsing_stream: &mut PrologStream,
+ ct: &ClauseType,
+ arity: usize,
+ lco: bool,
+ use_default_cp: bool,
+ ) {
let mut default_call_policy: Box<CallPolicy> = Box::new(DefaultCallPolicy {});
let call_policy = if use_default_cp {
&mut default_call_policy
self.last_call = lco;
match ct {
- &ClauseType::BuiltIn(ref ct) =>
- try_or_fail!(self, call_policy.call_builtin(self, ct, indices, parsing_stream)),
- &ClauseType::CallN =>
- try_or_fail!(self, call_policy.call_n(self, arity, indices, parsing_stream)),
- &ClauseType::Hook(ref hook) =>
- try_or_fail!(self, call_policy.compile_hook(self, hook)),
+ &ClauseType::BuiltIn(ref ct) => try_or_fail!(
+ self,
+ call_policy.call_builtin(self, ct, indices, parsing_stream)
+ ),
+ &ClauseType::CallN => try_or_fail!(
+ self,
+ call_policy.call_n(self, arity, indices, parsing_stream)
+ ),
+ &ClauseType::Hook(ref hook) => try_or_fail!(self, call_policy.compile_hook(self, hook)),
&ClauseType::Inlined(ref ct) => {
self.execute_inlined(ct);
if lco {
self.p = CodePtr::Local(self.cp);
}
- },
- &ClauseType::Named(ref name, _, ref idx) | &ClauseType::Op(ref name, _, ref idx) =>
- try_or_fail!(self, call_policy.context_call(self, name.clone(), arity, idx.clone(),
- indices)),
- &ClauseType::System(ref ct) =>
- try_or_fail!(self, self.system_call(ct, code_repo, indices, call_policy, cut_policy,
- parsing_stream))
+ }
+ &ClauseType::Named(ref name, _, ref idx) | &ClauseType::Op(ref name, _, ref idx) => {
+ try_or_fail!(
+ self,
+ call_policy.context_call(self, name.clone(), arity, idx.clone(), indices)
+ )
+ }
+ &ClauseType::System(ref ct) => try_or_fail!(
+ self,
+ self.system_call(
+ ct,
+ code_repo,
+ indices,
+ call_policy,
+ cut_policy,
+ parsing_stream
+ )
+ ),
};
}
- pub(super)
- fn execute_ctrl_instr(&mut self,
- indices: &mut IndexStore,
- code_repo: &CodeRepo,
- call_policy: &mut Box<CallPolicy>,
- cut_policy: &mut Box<CutPolicy>,
- parsing_stream: &mut PrologStream,
- instr: &ControlInstruction)
- {
+ pub(super) fn execute_ctrl_instr(
+ &mut self,
+ indices: &mut IndexStore,
+ code_repo: &CodeRepo,
+ call_policy: &mut Box<CallPolicy>,
+ cut_policy: &mut Box<CutPolicy>,
+ parsing_stream: &mut PrologStream,
+ instr: &ControlInstruction,
+ ) {
match instr {
- &ControlInstruction::Allocate(num_cells) =>
- self.allocate(num_cells),
- &ControlInstruction::CallClause(ref ct, arity, _, lco, use_default_cp) =>
- self.handle_call_clause(indices, code_repo, call_policy, cut_policy,
- parsing_stream, ct, arity, lco,
- use_default_cp),
+ &ControlInstruction::Allocate(num_cells) => self.allocate(num_cells),
+ &ControlInstruction::CallClause(ref ct, arity, _, lco, use_default_cp) => self
+ .handle_call_clause(
+ indices,
+ code_repo,
+ call_policy,
+ cut_policy,
+ parsing_stream,
+ ct,
+ arity,
+ lco,
+ use_default_cp,
+ ),
&ControlInstruction::Deallocate => self.deallocate(),
&ControlInstruction::JmpBy(arity, offset, _, lco) => {
if !lco {
self.num_of_args = arity;
self.b0 = self.b;
self.p += offset;
- },
- &ControlInstruction::Proceed =>
- self.p = CodePtr::Local(self.cp.clone())
+ }
+ &ControlInstruction::Proceed => self.p = CodePtr::Local(self.cp.clone()),
};
}
- pub(super) fn execute_indexed_choice_instr(&mut self, instr: &IndexedChoiceInstruction,
- call_policy: &mut Box<CallPolicy>)
- {
+ pub(super) fn execute_indexed_choice_instr(
+ &mut self,
+ instr: &IndexedChoiceInstruction,
+ call_policy: &mut Box<CallPolicy>,
+ ) {
match instr {
&IndexedChoiceInstruction::Try(l) => {
let n = self.num_of_args;
let gi = self.next_global_index();
- self.or_stack.push(gi,
- self.e,
- self.cp.clone(),
- self.attr_var_init.attr_var_queue.len(),
- self.b,
- self.p.clone() + 1,
- self.tr,
- self.pstr_tr,
- self.heap.h,
- self.b0,
- self.num_of_args);
+ self.or_stack.push(
+ gi,
+ self.e,
+ self.cp.clone(),
+ self.attr_var_init.attr_var_queue.len(),
+ self.b,
+ self.p.clone() + 1,
+ self.tr,
+ self.pstr_tr,
+ self.heap.h,
+ self.b0,
+ self.num_of_args,
+ );
self.b = self.or_stack.len();
let b = self.b - 1;
- for i in 1 .. n + 1 {
+ for i in 1..n + 1 {
self.or_stack[b][i] = self.registers[i].clone();
}
self.hb = self.heap.h;
self.p += l;
- },
- &IndexedChoiceInstruction::Retry(l) =>
- try_or_fail!(self, call_policy.retry(self, l)),
- &IndexedChoiceInstruction::Trust(l) =>
- try_or_fail!(self, call_policy.trust(self, l))
+ }
+ &IndexedChoiceInstruction::Retry(l) => try_or_fail!(self, call_policy.retry(self, l)),
+ &IndexedChoiceInstruction::Trust(l) => try_or_fail!(self, call_policy.trust(self, l)),
};
}
- pub(super) fn execute_choice_instr(&mut self, instr: &ChoiceInstruction,
- call_policy: &mut Box<CallPolicy>)
- {
+ pub(super) fn execute_choice_instr(
+ &mut self,
+ instr: &ChoiceInstruction,
+ call_policy: &mut Box<CallPolicy>,
+ ) {
match instr {
&ChoiceInstruction::TryMeElse(offset) => {
let n = self.num_of_args;
let gi = self.next_global_index();
- self.or_stack.push(gi,
- self.e,
- self.cp.clone(),
- self.attr_var_init.attr_var_queue.len(),
- self.b,
- self.p.clone() + offset,
- self.tr,
- self.pstr_tr,
- self.heap.h,
- self.b0,
- self.num_of_args);
+ self.or_stack.push(
+ gi,
+ self.e,
+ self.cp.clone(),
+ self.attr_var_init.attr_var_queue.len(),
+ self.b,
+ self.p.clone() + offset,
+ self.tr,
+ self.pstr_tr,
+ self.heap.h,
+ self.b0,
+ self.num_of_args,
+ );
self.b = self.or_stack.len();
- let b = self.b - 1;
+ let b = self.b - 1;
- for i in 1 .. n + 1 {
+ for i in 1..n + 1 {
self.or_stack[b][i] = self.registers[i].clone();
}
self.hb = self.heap.h;
self.p += 1;
- },
+ }
&ChoiceInstruction::DefaultRetryMeElse(offset) => {
let mut call_policy = DefaultCallPolicy {};
try_or_fail!(self, call_policy.retry_me_else(self, offset))
- },
+ }
&ChoiceInstruction::DefaultTrustMe => {
let mut call_policy = DefaultCallPolicy {};
try_or_fail!(self, call_policy.trust_me(self))
- },
- &ChoiceInstruction::RetryMeElse(offset) =>
- try_or_fail!(self, call_policy.retry_me_else(self, offset)),
- &ChoiceInstruction::TrustMe =>
- try_or_fail!(self, call_policy.trust_me(self))
+ }
+ &ChoiceInstruction::RetryMeElse(offset) => {
+ try_or_fail!(self, call_policy.retry_me_else(self, offset))
+ }
+ &ChoiceInstruction::TrustMe => try_or_fail!(self, call_policy.trust_me(self)),
}
}
- pub(super) fn execute_cut_instr(&mut self, instr: &CutInstruction,
- cut_policy: &mut Box<CutPolicy>)
- {
+ pub(super) fn execute_cut_instr(
+ &mut self,
+ instr: &CutInstruction,
+ cut_policy: &mut Box<CutPolicy>,
+ ) {
match instr {
&CutInstruction::NeckCut => {
- let b = self.b;
+ let b = self.b;
let b0 = self.b0;
if b > b0 {
self.b = b0;
self.tidy_trail();
- self.tidy_pstr_trail();
+ self.tidy_pstr_trail();
self.or_stack.truncate(self.b);
}
self.p += 1;
- },
+ }
&CutInstruction::GetLevel(r) => {
let b0 = self.b0;
self[r] = Addr::Con(Constant::Usize(b0));
self.p += 1;
- },
+ }
&CutInstruction::GetLevelAndUnify(r) => {
let b0 = self[perm_v!(1)].clone();
- let a = self[r].clone();
+ let a = self[r].clone();
self.unify(a, b0);
self.p += 1;
- },
- &CutInstruction::Cut(r) => if !cut_policy.cut(self, r) {
- self.p += 1;
+ }
+ &CutInstruction::Cut(r) => {
+ if !cut_policy.cut(self, r) {
+ self.p += 1;
+ }
}
}
}
self.lifted_heap.clear();
}
- pub(super)
- fn sink_to_snapshot(&mut self) -> MachineState {
+ pub(super) fn sink_to_snapshot(&mut self) -> MachineState {
let mut snapshot = MachineState::with_capacity(0);
snapshot.hb = self.hb;
snapshot
}
- pub(super)
- fn absorb_snapshot(&mut self, mut snapshot: MachineState) {
+ pub(super) fn absorb_snapshot(&mut self, mut snapshot: MachineState) {
self.hb = snapshot.hb;
self.e = snapshot.e;
self.b = snapshot.b;
use prolog::heap_print::*;
use prolog::instructions::*;
use prolog::read::*;
-use prolog::write::{ContinueResult, next_keypress};
+use prolog::write::{next_keypress, ContinueResult};
-pub mod machine_indices;
-pub mod heap;
mod and_stack;
-mod or_stack;
mod attributed_variables;
+pub(super) mod code_repo;
+pub mod compile;
mod copier;
mod dynamic_database;
+pub mod heap;
pub mod machine_errors;
-pub mod toplevel;
-pub mod compile;
-pub(super) mod code_repo;
-pub mod modules;
+pub mod machine_indices;
pub(super) mod machine_state;
+pub mod modules;
+mod or_stack;
pub(super) mod term_expansion;
+pub mod toplevel;
-#[macro_use] mod machine_state_impl;
+#[macro_use]
+mod machine_state_impl;
mod system_calls;
use prolog::machine::attributed_variables::*;
-use prolog::machine::compile::*;
use prolog::machine::code_repo::*;
+use prolog::machine::compile::*;
use prolog::machine::machine_errors::*;
use prolog::machine::machine_indices::*;
use prolog::machine::machine_state::*;
use indexmap::IndexMap;
use std::collections::VecDeque;
-use std::io::{Read, Write, stdout};
use std::fs::File;
+use std::io::{stdout, Read, Write};
use std::mem;
use std::ops::Index;
use std::rc::Rc;
-use termion::raw::{IntoRawMode};
+use termion::raw::IntoRawMode;
pub struct MachinePolicies {
call_policy: Box<CallPolicy>,
pub(super) indices: IndexStore,
pub(super) code_repo: CodeRepo,
pub(super) toplevel_idx: usize,
- pub(super) prolog_stream: ParsingStream<Box<Read>>
+ pub(super) prolog_stream: ParsingStream<Box<Read>>,
}
impl Index<LocalCodePtr> for CodeRepo {
&mut self.op_dir
}
- fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option<CodeIndex>
- {
+ fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option<CodeIndex> {
match module.as_str() {
"user" | "builtin" => self.code_dir.get(&key).cloned(),
- _ => self.modules.get(&module).and_then(|ref module| {
- module.code_dir.get(&key).cloned().map(CodeIndex::from)
- })
+ _ => self
+ .modules
+ .get(&module)
+ .and_then(|ref module| module.code_dir.get(&key).cloned().map(CodeIndex::from)),
}
}
- fn remove_code_index(&mut self, key: PredicateKey)
- {
+ fn remove_code_index(&mut self, key: PredicateKey) {
self.code_dir.remove(&key);
}
- fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: CodeIndex)
- {
+ fn insert_dir_entry(&mut self, name: ClauseName, arity: usize, idx: CodeIndex) {
if let Some(ref code_idx) = self.code_dir.get(&(name.clone(), arity)) {
if !code_idx.is_undefined() {
println!("warning: overwriting {}/{}", &name, arity);
self.code_dir.insert((name, arity), idx);
}
- fn use_qualified_module(&mut self, code_repo: &mut CodeRepo, flags: MachineFlags,
- submodule: &Module, exports: &Vec<PredicateKey>)
- -> Result<(), SessionError>
- {
+ fn use_qualified_module(
+ &mut self,
+ code_repo: &mut CodeRepo,
+ flags: MachineFlags,
+ submodule: &Module,
+ exports: &Vec<PredicateKey>,
+ ) -> Result<(), SessionError> {
use_qualified_module(self, submodule, exports)?;
- submodule.dump_expansions(code_repo, flags).map_err(SessionError::from)
+ submodule
+ .dump_expansions(code_repo, flags)
+ .map_err(SessionError::from)
}
- fn use_module(&mut self, code_repo: &mut CodeRepo, flags: MachineFlags, submodule: &Module)
- -> Result<(), SessionError>
- {
+ fn use_module(
+ &mut self,
+ code_repo: &mut CodeRepo,
+ flags: MachineFlags,
+ submodule: &Module,
+ ) -> Result<(), SessionError> {
use_module(self, submodule)?;
if !submodule.inserted_expansions {
- submodule.dump_expansions(code_repo, flags).map_err(SessionError::from)
+ submodule
+ .dump_expansions(code_repo, flags)
+ .map_err(SessionError::from)
} else {
Ok(())
}
}
static BUILTINS: &str = include_str!("../lib/builtins.pl");
-static ERROR: &str = include_str!("../lib/error.pl");
-static LISTS: &str = include_str!("../lib/lists.pl");
-static NON_ISO: &str = include_str!("../lib/non_iso.pl");
+static ERROR: &str = include_str!("../lib/error.pl");
+static LISTS: &str = include_str!("../lib/lists.pl");
+static NON_ISO: &str = include_str!("../lib/non_iso.pl");
static TOPLEVEL: &str = include_str!("../toplevel.pl");
impl Machine {
Ok(code) => {
self.machine_st.attr_var_init.verify_attrs_loc = self.code_repo.code.len();
self.code_repo.code.extend(code.into_iter());
- },
- Err(_) => panic!("Machine::compile_special_forms() failed at VERIFY_ATTRS")
+ }
+ Err(_) => panic!("Machine::compile_special_forms() failed at VERIFY_ATTRS"),
}
match compile_special_form(self, parsing_stream(PROJECT_ATTRS.as_bytes())) {
Ok(code) => {
self.machine_st.attr_var_init.project_attrs_loc = self.code_repo.code.len();
self.code_repo.code.extend(code.into_iter());
- },
- Err(_) => panic!("Machine::compile_special_forms() failed at PROJECT_ATTRS")
+ }
+ Err(_) => panic!("Machine::compile_special_forms() failed at PROJECT_ATTRS"),
}
}
fn compile_scryerrc(&mut self) {
let mut path = match dirs::home_dir() {
Some(path) => path,
- None => return
+ None => return,
};
-
+
path.push(".scryerrc");
if path.is_file() {
let file_src = match File::open(&path) {
Ok(file_handle) => parsing_stream(file_handle),
- Err(_) => return
+ Err(_) => return,
};
compile_user_module(self, file_src);
indices: IndexStore::new(),
code_repo: CodeRepo::new(),
toplevel_idx: 0,
- prolog_stream
+ prolog_stream,
};
let atom_tbl = wam.indices.atom_tbl.clone();
- compile_listing(&mut wam, parsing_stream(BUILTINS.as_bytes()),
- default_index_store!(atom_tbl.clone()));
+ compile_listing(
+ &mut wam,
+ parsing_stream(BUILTINS.as_bytes()),
+ default_index_store!(atom_tbl.clone()),
+ );
wam.compile_special_forms();
wam.compile_top_level();
self.machine_st.flags
}
- pub fn check_toplevel_code(&self, indices: &IndexStore) -> Result<(), SessionError>
- {
+ pub fn check_toplevel_code(&self, indices: &IndexStore) -> Result<(), SessionError> {
for (key, idx) in &indices.code_dir {
match ClauseType::from(key.0.clone(), key.1, None) {
- ClauseType::Named(..) | ClauseType::Op(..) => {},
+ ClauseType::Named(..) | ClauseType::Op(..) => {}
_ => {
// ensure we don't try to overwrite the name/arity of a builtin.
let err_str = format!("{}/{}", key.0, key.1);
}
if existing_idx.module_name() != idx.module_name() {
- let err_str = format!("{}/{} from module {}", key.0, key.1,
- existing_idx.module_name().as_str());
+ let err_str = format!(
+ "{}/{} from module {}",
+ key.0,
+ key.1,
+ existing_idx.module_name().as_str()
+ );
let err_str = clause_name!(err_str, self.indices.atom_tbl());
return Err(SessionError::CannotOverwriteImport(err_str));
Ok(())
}
- pub fn add_batched_code(&mut self, code: Code, code_dir: CodeDir)
- {
+ pub fn add_batched_code(&mut self, code: Code, code_dir: CodeDir) {
// error detection has finished, so update the master index of keys.
for (key, idx) in code_dir {
if let Some(ref mut master_idx) = self.indices.code_dir.get_mut(&key) {
#[inline]
pub fn add_module(&mut self, module: Module, code: Code) {
- self.indices.modules.insert(module.module_decl.name.clone(), module);
+ self.indices
+ .modules
+ .insert(module.module_decl.name.clone(), module);
self.code_repo.code.extend(code.into_iter());
}
- pub fn submit_query(&mut self, code: Code, alloc_locs: AllocVarDict) -> EvalSession
- {
+ pub fn submit_query(&mut self, code: Code, alloc_locs: AllocVarDict) -> EvalSession {
self.code_repo.cached_query = code;
self.run_query(&alloc_locs);
pub fn throw_session_error(&mut self, err: SessionError, key: PredicateKey) {
let h = self.machine_st.heap.h;
- let err = MachineError::session_error(h, err);
+ let err = MachineError::session_error(h, err);
let stub = MachineError::functor_stub(key.0, key.1);
- let err = self.machine_st.error_form(err, stub);
+ let err = self.machine_st.error_form(err, stub);
self.machine_st.throw_exception(err);
return;
}
- fn handle_toplevel_command(&mut self, code_ptr: REPLCodePtr, p: LocalCodePtr)
- {
+ fn handle_toplevel_command(&mut self, code_ptr: REPLCodePtr, p: LocalCodePtr) {
match code_ptr {
REPLCodePtr::CompileBatch => {
#[cfg(feature = "readline_rs_compat")]
EvalSession::Error(e) => self.throw_session_error(e, (clause_name!("repl"), 0)),
_ => {}
};
- },
+ }
REPLCodePtr::SubmitQueryAndPrintResults => {
let term = self.machine_st[temp_v!(1)].clone();
let stub = MachineError::functor_stub(clause_name!("repl"), 0);
for addr in addrs {
match addr {
Addr::Str(s) => {
- let var_atom = match self.machine_st.heap[s+1].as_addr(s+1) {
- Addr::Con(Constant::Atom(var_atom, _)) =>
- Rc::new(var_atom.to_string()),
- _ => unreachable!()
+ let var_atom = match self.machine_st.heap[s + 1].as_addr(s + 1)
+ {
+ Addr::Con(Constant::Atom(var_atom, _)) => {
+ Rc::new(var_atom.to_string())
+ }
+ _ => unreachable!(),
};
- let var_addr = self.machine_st.heap[s+2].as_addr(s+2);
+ let var_addr = self.machine_st.heap[s + 2].as_addr(s + 2);
var_dict.insert(var_atom, var_addr);
- },
- _ => unreachable!()
+ }
+ _ => unreachable!(),
};
}
let term_output = self.machine_st.print_query(term, &self.indices.op_dir);
term_output.result()
- },
+ }
Err(err_stub) => {
self.machine_st.throw_exception(err_stub);
return;
let result = match stream_to_toplevel(stream, self) {
Ok(packet) => compile_term(self, packet),
- Err(e) => EvalSession::from(e)
+ Err(e) => EvalSession::from(e),
};
self.handle_eval_session(result, snapshot);
fn handle_eval_session(&mut self, result: EvalSession, snapshot: MachineState) {
match result {
- EvalSession::InitialQuerySuccess(alloc_locs) =>
- loop {
- let bindings = {
- let output = PrinterOutputter::new();
- self.toplevel_heap_view(output).result()
- };
-
- let attr_goals = self.attribute_goals();
+ EvalSession::InitialQuerySuccess(alloc_locs) => loop {
+ let bindings = {
+ let output = PrinterOutputter::new();
+ self.toplevel_heap_view(output).result()
+ };
- if !(self.machine_st.b > 0) {
- if bindings.is_empty() {
- let space = if requires_space(&attr_goals, ".") { " " } else { "" };
+ let attr_goals = self.attribute_goals();
- if !attr_goals.is_empty() {
- println!("{}{}.", attr_goals, space);
- } else {
- println!("true.");
- }
+ if !(self.machine_st.b > 0) {
+ if bindings.is_empty() {
+ let space = if requires_space(&attr_goals, ".") {
+ " "
+ } else {
+ ""
+ };
- self.machine_st.absorb_snapshot(snapshot);
- return;
+ if !attr_goals.is_empty() {
+ println!("{}{}.", attr_goals, space);
+ } else {
+ println!("true.");
}
- } else if bindings.is_empty() && attr_goals.is_empty() {
- print!("true");
- stdout().flush().unwrap();
+
+ self.machine_st.absorb_snapshot(snapshot);
+ return;
}
+ } else if bindings.is_empty() && attr_goals.is_empty() {
+ print!("true");
+ stdout().flush().unwrap();
+ }
- let mut raw_stdout = stdout().into_raw_mode().unwrap();
+ let mut raw_stdout = stdout().into_raw_mode().unwrap();
- if !attr_goals.is_empty() {
- if bindings.is_empty() {
- write!(raw_stdout, "{}", attr_goals).unwrap();
- } else {
- write!(raw_stdout, "{}, {}", bindings, attr_goals).unwrap();
- }
- } else if !bindings.is_empty() {
- write!(raw_stdout, "{}", bindings).unwrap();
+ if !attr_goals.is_empty() {
+ if bindings.is_empty() {
+ write!(raw_stdout, "{}", attr_goals).unwrap();
+ } else {
+ write!(raw_stdout, "{}, {}", bindings, attr_goals).unwrap();
}
+ } else if !bindings.is_empty() {
+ write!(raw_stdout, "{}", bindings).unwrap();
+ }
- if self.machine_st.b > 0 {
- raw_stdout.flush().unwrap();
+ if self.machine_st.b > 0 {
+ raw_stdout.flush().unwrap();
- let result = match next_keypress() {
- ContinueResult::ContinueQuery => {
- write!(raw_stdout, " ;\r\n").unwrap();
- self.continue_query(&alloc_locs)
- },
- ContinueResult::Conclude => {
- write!(raw_stdout, " ...\r\n").unwrap();
- self.machine_st.absorb_snapshot(snapshot);
+ let result = match next_keypress() {
+ ContinueResult::ContinueQuery => {
+ write!(raw_stdout, " ;\r\n").unwrap();
+ self.continue_query(&alloc_locs)
+ }
+ ContinueResult::Conclude => {
+ write!(raw_stdout, " ...\r\n").unwrap();
+ self.machine_st.absorb_snapshot(snapshot);
+ return;
+ }
+ };
+
+ let mut raw_stdout = stdout().into_raw_mode().unwrap();
+
+ match result {
+ EvalSession::QueryFailure => {
+ if self.machine_st.ball.stub.len() > 0 {
+ self.propagate_exception_to_toplevel(snapshot);
return;
- }
- };
+ } else {
+ write!(raw_stdout, "false.\r\n").unwrap();
+ raw_stdout.flush().unwrap();
- let mut raw_stdout = stdout().into_raw_mode().unwrap();
-
- match result {
- EvalSession::QueryFailure =>
- if self.machine_st.ball.stub.len() > 0 {
- self.propagate_exception_to_toplevel(snapshot);
- return;
- } else {
- write!(raw_stdout, "false.\r\n").unwrap();
- raw_stdout.flush().unwrap();
-
- self.machine_st.absorb_snapshot(snapshot);
- return;
- },
- EvalSession::Error(err) => {
self.machine_st.absorb_snapshot(snapshot);
- self.throw_session_error(err, (clause_name!("repl"), 0));
return;
- },
- _ => {}
+ }
+ }
+ EvalSession::Error(err) => {
+ self.machine_st.absorb_snapshot(snapshot);
+ self.throw_session_error(err, (clause_name!("repl"), 0));
+ return;
}
+ _ => {}
+ }
+ } else {
+ if bindings.is_empty() && attr_goals.is_empty() {
+ write!(raw_stdout, "true.\r\n").unwrap();
} else {
- if bindings.is_empty() && attr_goals.is_empty() {
- write!(raw_stdout, "true.\r\n").unwrap();
+ let space = if !attr_goals.is_empty() {
+ if requires_space(&attr_goals, ".") {
+ " "
+ } else {
+ ""
+ }
} else {
- let space = if !attr_goals.is_empty() {
- if requires_space(&attr_goals, ".") { " " } else { "" }
+ if requires_space(&bindings, ".") {
+ " "
} else {
- if requires_space(&bindings, ".") { " " } else { "" }
- };
-
- write!(raw_stdout, "{}.\r\n", space).unwrap();
- }
+ ""
+ }
+ };
- break;
+ write!(raw_stdout, "{}.\r\n", space).unwrap();
}
- },
+
+ break;
+ }
+ },
EvalSession::Error(err) => {
self.machine_st.absorb_snapshot(snapshot);
self.throw_session_error(err, (clause_name!("repl"), 0));
return;
- },
- EvalSession::QueryFailure =>
+ }
+ EvalSession::QueryFailure => {
if self.machine_st.ball.stub.len() > 0 {
return self.propagate_exception_to_toplevel(snapshot);
} else {
println!("false.");
- },
+ }
+ }
_ => {}
}
self.machine_st.absorb_snapshot(snapshot);
}
- pub(super)
- fn run_query(&mut self, alloc_locs: &AllocVarDict)
- {
+ pub(super) fn run_query(&mut self, alloc_locs: &AllocVarDict) {
let end_ptr = top_level_code_ptr!(0, self.code_repo.size_of_cached_query());
while self.machine_st.p < end_ptr {
&Line::Control(ref ctrl_instr) if ctrl_instr.is_jump_instr() => {
self.machine_st.record_var_places(cn, alloc_locs);
cn += 1;
- },
+ }
_ => {}
}
self.machine_st.p = top_level_code_ptr!(cn, p);
}
- self.machine_st.query_stepper(&mut self.indices, &mut self.policies, &mut self.code_repo,
- &mut self.prolog_stream);
+ self.machine_st.query_stepper(
+ &mut self.indices,
+ &mut self.policies,
+ &mut self.code_repo,
+ &mut self.prolog_stream,
+ );
match self.machine_st.p {
- CodePtr::Local(LocalCodePtr::TopLevel(_, p)) if p > 0 => {},
- CodePtr::REPL(code_ptr, p) =>
- self.handle_toplevel_command(code_ptr, p),
+ CodePtr::Local(LocalCodePtr::TopLevel(_, p)) if p > 0 => {}
+ CodePtr::REPL(code_ptr, p) => self.handle_toplevel_command(code_ptr, p),
CodePtr::DynamicTransaction(trans_type, p) => {
// self.code_repo.cached_query is about to be overwritten by the term expander,
// so hold onto it locally and restore it after the compiler has finished.
}
self.code_repo.cached_query = cached_query;
- },
+ }
_ => {
if self.machine_st.heap_locs.is_empty() {
self.machine_st.record_var_places(0, alloc_locs);
}
}
- pub fn continue_query(&mut self, alloc_locs: &AllocVarDict) -> EvalSession
- {
+ pub fn continue_query(&mut self, alloc_locs: &AllocVarDict) -> EvalSession {
if !self.or_stack_is_empty() {
let b = self.machine_st.b - 1;
self.machine_st.p = self.machine_st.or_stack[b].bp.clone();
}
pub fn toplevel_heap_view<Outputter>(&self, mut output: Outputter) -> Outputter
- where Outputter: HCValueOutputter
+ where
+ Outputter: HCValueOutputter,
{
let mut sorted_vars: Vec<_> = self.machine_st.heap_locs.iter().collect();
sorted_vars.sort_by_key(|ref v| v.0);
for (var, addr) in sorted_vars {
let addr = self.machine_st.store(self.machine_st.deref(addr.clone()));
- output = self.machine_st.print_var_eq(var.clone(), addr, &self.indices.op_dir,
- output);
+ output = self
+ .machine_st
+ .print_var_eq(var.clone(), addr, &self.indices.op_dir, output);
}
output
#[cfg(test)]
pub fn test_heap_view<Outputter>(&self, mut output: Outputter) -> Outputter
- where Outputter: HCValueOutputter
+ where
+ Outputter: HCValueOutputter,
{
let mut sorted_vars: Vec<(&Rc<Var>, &Addr)> = self.machine_st.heap_locs.iter().collect();
sorted_vars.sort_by_key(|ref v| v.0);
for (var, addr) in sorted_vars {
- output = self.machine_st.print_var_eq(var.clone(), addr.clone(), &self.indices.op_dir,
- output);
+ output = self.machine_st.print_var_eq(
+ var.clone(),
+ addr.clone(),
+ &self.indices.op_dir,
+ output,
+ );
}
output
}
impl MachineState {
- fn record_var_places(&mut self, chunk_num: usize, alloc_locs: &AllocVarDict)
- {
+ fn record_var_places(&mut self, chunk_num: usize, alloc_locs: &AllocVarDict) {
for (var, var_data) in alloc_locs {
match var_data {
- &VarData::Perm(p) if p > 0 =>
+ &VarData::Perm(p) if p > 0 => {
if !self.heap_locs.contains_key(var) {
let e = self.e;
let r = var_data.as_reg_type().reg_num();
let addr = self.and_stack[e][r].clone();
self.heap_locs.insert(var.clone(), addr);
- },
+ }
+ }
&VarData::Temp(cn, _, _) if cn == chunk_num => {
let r = var_data.as_reg_type();
let addr = self[r].clone();
self.heap_locs.insert(var.clone(), addr);
}
- },
+ }
_ => {}
}
}
}
- fn print_query(&mut self, addr: Addr, op_dir: &OpDir) -> PrinterOutputter
- {
+ fn print_query(&mut self, addr: Addr, op_dir: &OpDir) -> PrinterOutputter {
let flags = self.flags;
let mut output = {
- self.flags = MachineFlags { double_quotes: DoubleQuotes::Atom };
+ self.flags = MachineFlags {
+ double_quotes: DoubleQuotes::Atom,
+ };
let output = PrinterOutputter::new();
let mut printer = HCPrinter::from_heap_locs(&self, op_dir, output);
output
}
- fn dispatch_instr(&mut self, instr: &Line, indices: &mut IndexStore, policies: &mut MachinePolicies,
- code_repo: &CodeRepo, prolog_stream: &mut PrologStream)
- {
+ fn dispatch_instr(
+ &mut self,
+ instr: &Line,
+ indices: &mut IndexStore,
+ policies: &mut MachinePolicies,
+ code_repo: &CodeRepo,
+ prolog_stream: &mut PrologStream,
+ ) {
match instr {
- &Line::Arithmetic(ref arith_instr) =>
- self.execute_arith_instr(arith_instr),
- &Line::Choice(ref choice_instr) =>
- self.execute_choice_instr(choice_instr, &mut policies.call_policy),
- &Line::Cut(ref cut_instr) =>
- self.execute_cut_instr(cut_instr, &mut policies.cut_policy),
- &Line::Control(ref control_instr) =>
- self.execute_ctrl_instr(indices, code_repo, &mut policies.call_policy,
- &mut policies.cut_policy, prolog_stream,
- control_instr),
+ &Line::Arithmetic(ref arith_instr) => self.execute_arith_instr(arith_instr),
+ &Line::Choice(ref choice_instr) => {
+ self.execute_choice_instr(choice_instr, &mut policies.call_policy)
+ }
+ &Line::Cut(ref cut_instr) => {
+ self.execute_cut_instr(cut_instr, &mut policies.cut_policy)
+ }
+ &Line::Control(ref control_instr) => self.execute_ctrl_instr(
+ indices,
+ code_repo,
+ &mut policies.call_policy,
+ &mut policies.cut_policy,
+ prolog_stream,
+ control_instr,
+ ),
&Line::Fact(ref fact_instr) => {
self.execute_fact_instr(&fact_instr);
self.p += 1;
- },
- &Line::Indexing(ref indexing_instr) =>
- self.execute_indexing_instr(&indexing_instr),
- &Line::IndexedChoice(ref choice_instr) =>
- self.execute_indexed_choice_instr(choice_instr, &mut policies.call_policy),
+ }
+ &Line::Indexing(ref indexing_instr) => self.execute_indexing_instr(&indexing_instr),
+ &Line::IndexedChoice(ref choice_instr) => {
+ self.execute_indexed_choice_instr(choice_instr, &mut policies.call_policy)
+ }
&Line::Query(ref query_instr) => {
self.execute_query_instr(&query_instr);
self.p += 1;
}
}
- fn execute_instr(&mut self, indices: &mut IndexStore, policies: &mut MachinePolicies,
- code_repo: &CodeRepo, prolog_stream: &mut PrologStream)
- {
+ fn execute_instr(
+ &mut self,
+ indices: &mut IndexStore,
+ policies: &mut MachinePolicies,
+ code_repo: &CodeRepo,
+ prolog_stream: &mut PrologStream,
+ ) {
let instr = match code_repo.lookup_instr(self.last_call, &self.p) {
Some(instr) => instr,
- None => return
+ None => return,
};
self.dispatch_instr(instr.as_ref(), indices, policies, code_repo, prolog_stream);
}
- fn backtrack(&mut self)
- {
+ fn backtrack(&mut self) {
if self.b > 0 {
let b = self.b - 1;
self.b0 = self.or_stack[b].b0;
- self.p = self.or_stack[b].bp.clone();
+ self.p = self.or_stack[b].bp.clone();
if let CodePtr::Local(LocalCodePtr::TopLevel(_, p)) = self.p {
self.fail = p == 0;
fn check_machine_index(&mut self, code_repo: &CodeRepo) -> bool {
match self.p {
- CodePtr::Local(LocalCodePtr::DirEntry(p))
- if p < code_repo.code.len() => {},
+ CodePtr::Local(LocalCodePtr::DirEntry(p)) if p < code_repo.code.len() => {}
CodePtr::Local(LocalCodePtr::UserTermExpansion(p))
- if p < code_repo.term_expanders.len() => {},
- CodePtr::Local(LocalCodePtr::UserTermExpansion(_)) =>
- self.fail = true,
+ if p < code_repo.term_expanders.len() => {}
+ CodePtr::Local(LocalCodePtr::UserTermExpansion(_)) => self.fail = true,
CodePtr::Local(LocalCodePtr::UserGoalExpansion(p))
- if p < code_repo.goal_expanders.len() => {},
- CodePtr::Local(LocalCodePtr::UserGoalExpansion(_)) =>
- self.fail = true,
- CodePtr::Local(LocalCodePtr::InSituDirEntry(p))
- if p < code_repo.in_situ_code.len() => {},
- CodePtr::Local(_) | CodePtr::REPL(..) =>
- return false,
+ if p < code_repo.goal_expanders.len() => {}
+ CodePtr::Local(LocalCodePtr::UserGoalExpansion(_)) => self.fail = true,
+ CodePtr::Local(LocalCodePtr::InSituDirEntry(p)) if p < code_repo.in_situ_code.len() => {
+ }
+ CodePtr::Local(_) | CodePtr::REPL(..) => return false,
CodePtr::DynamicTransaction(..) => {
// prevent use of dynamic transactions from
// succeeding in expansions. self.fail will be toggled
// back to false later.
self.fail = true;
return false;
- },
+ }
_ => {}
}
}
// return true iff verify_attr_interrupt is called.
- fn verify_attr_stepper(&mut self, indices: &mut IndexStore, policies: &mut MachinePolicies,
- code_repo: &mut CodeRepo, prolog_stream: &mut PrologStream)
- -> bool
- {
+ fn verify_attr_stepper(
+ &mut self,
+ indices: &mut IndexStore,
+ policies: &mut MachinePolicies,
+ code_repo: &mut CodeRepo,
+ prolog_stream: &mut PrologStream,
+ ) -> bool {
loop {
let instr = match code_repo.lookup_instr(self.last_call, &self.p) {
Some(instr) => {
self.run_verify_attr_interrupt(cp);
return true;
}
- },
- None => return false
+ }
+ None => return false,
};
self.dispatch_instr(instr.as_ref(), indices, policies, code_repo, prolog_stream);
self.verify_attr_interrupt(p);
}
- fn query_stepper(&mut self, indices: &mut IndexStore, policies: &mut MachinePolicies,
- code_repo: &mut CodeRepo, prolog_stream: &mut PrologStream)
- {
+ fn query_stepper(
+ &mut self,
+ indices: &mut IndexStore,
+ policies: &mut MachinePolicies,
+ code_repo: &mut CodeRepo,
+ prolog_stream: &mut PrologStream,
+ ) {
loop {
self.execute_instr(indices, policies, code_repo, prolog_stream);
}
match self.p {
- CodePtr::VerifyAttrInterrupt(_) => {
+ CodePtr::VerifyAttrInterrupt(_) => {
self.p = CodePtr::Local(self.attr_var_init.cp + 1);
if !self.verify_attr_stepper(indices, policies, code_repo, prolog_stream) {
let cp = self.p.local();
self.run_verify_attr_interrupt(cp);
}
- },
- _ =>
+ }
+ _ => {
if !self.check_machine_index(code_repo) {
break;
}
+ }
}
}
}
use prolog::machine::machine_errors::*;
use prolog::machine::machine_indices::*;
-use std::collections::{VecDeque};
+use std::collections::VecDeque;
// Module's and related types are defined in forms.
impl Module {
pub fn new(module_decl: ModuleDecl, atom_tbl: TabledData<Atom>) -> Self {
- Module { module_decl, atom_tbl,
- user_term_expansions: (Predicate::new(), VecDeque::from(vec![])),
- user_goal_expansions: (Predicate::new(), VecDeque::from(vec![])),
- term_expansions: (Predicate::new(), VecDeque::from(vec![])),
- goal_expansions: (Predicate::new(), VecDeque::from(vec![])),
- code_dir: CodeDir::new(),
- op_dir: default_op_dir(),
- inserted_expansions: false }
+ Module {
+ module_decl,
+ atom_tbl,
+ user_term_expansions: (Predicate::new(), VecDeque::from(vec![])),
+ user_goal_expansions: (Predicate::new(), VecDeque::from(vec![])),
+ term_expansions: (Predicate::new(), VecDeque::from(vec![])),
+ goal_expansions: (Predicate::new(), VecDeque::from(vec![])),
+ code_dir: CodeDir::new(),
+ op_dir: default_op_dir(),
+ inserted_expansions: false,
+ }
}
- pub fn dump_expansions(&self, code_repo: &mut CodeRepo, flags: MachineFlags)
- -> Result<(), ParserError>
- {
+ pub fn dump_expansions(
+ &self,
+ code_repo: &mut CodeRepo,
+ flags: MachineFlags,
+ ) -> Result<(), ParserError> {
{
- let te = code_repo.term_dir.entry((clause_name!("term_expansion"), 2))
+ let te = code_repo
+ .term_dir
+ .entry((clause_name!("term_expansion"), 2))
.or_insert((Predicate::new(), VecDeque::from(vec![])));
- (te.0).0.extend((self.user_term_expansions.0).0.iter().cloned());
+ (te.0)
+ .0
+ .extend((self.user_term_expansions.0).0.iter().cloned());
te.1.extend(self.user_term_expansions.1.iter().cloned());
}
{
- let ge = code_repo.term_dir.entry((clause_name!("goal_expansion"), 2))
+ let ge = code_repo
+ .term_dir
+ .entry((clause_name!("goal_expansion"), 2))
.or_insert((Predicate::new(), VecDeque::from(vec![])));
- (ge.0).0.extend((self.user_goal_expansions.0).0.iter().cloned());
+ (ge.0)
+ .0
+ .extend((self.user_goal_expansions.0).0.iter().cloned());
ge.1.extend(self.user_goal_expansions.1.iter().cloned());
}
Ok(())
}
- pub fn add_module_expansion_record(&mut self, hook: CompileTimeHook, clause: PredicateClause,
- queue: VecDeque<TopLevel>)
- {
+ pub fn add_module_expansion_record(
+ &mut self,
+ hook: CompileTimeHook,
+ clause: PredicateClause,
+ queue: VecDeque<TopLevel>,
+ ) {
match hook {
CompileTimeHook::TermExpansion | CompileTimeHook::UserTermExpansion => {
(self.term_expansions.0).0.push(clause);
self.term_expansions.1.extend(queue.into_iter());
- },
+ }
CompileTimeHook::GoalExpansion | CompileTimeHook::UserGoalExpansion => {
(self.goal_expansions.0).0.push(clause);
self.goal_expansions.1.extend(queue.into_iter());
}
}
-pub trait SubModuleUser
-{
+pub trait SubModuleUser {
fn atom_tbl(&self) -> TabledData<Atom>;
fn op_dir(&mut self) -> &mut OpDir;
fn remove_code_index(&mut self, PredicateKey);
fn insert_dir_entry(&mut self, ClauseName, usize, CodeIndex);
- fn get_op_module_name(&mut self, name: ClauseName, fixity: Fixity) -> Option<ClauseName>
- {
- self.op_dir().get(&(name, fixity)).map(|op_val| op_val.owning_module())
+ fn get_op_module_name(&mut self, name: ClauseName, fixity: Fixity) -> Option<ClauseName> {
+ self.op_dir()
+ .get(&(name, fixity))
+ .map(|op_val| op_val.owning_module())
}
- fn remove_module(&mut self, mod_name: ClauseName, module: &Module)
- {
+ fn remove_module(&mut self, mod_name: ClauseName, module: &Module) {
for (name, arity) in module.module_decl.exports.iter().cloned() {
let name = name.defrock_brackets();
match self.get_code_index((name.clone(), arity), mod_name.clone()) {
- Some(CodeIndex (ref code_idx)) => {
+ Some(CodeIndex(ref code_idx)) => {
if &code_idx.borrow().1 != &module.module_decl.name {
continue;
}
// remove or respecify ops.
if arity == 2 {
- if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::In)
- {
+ if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::In) {
if mod_name == module.module_decl.name {
self.op_dir().remove(&(name.clone(), Fixity::In));
}
}
} else if arity == 1 {
- if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::Pre)
- {
+ if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::Pre) {
if mod_name == module.module_decl.name {
self.op_dir().remove(&(name.clone(), Fixity::Pre));
}
}
}
}
- },
+ }
_ => {}
};
}
}
-
+
// returns true on successful import.
- fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) -> bool
- {
+ fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) -> bool {
let name = name.defrock_brackets();
let mut found_op = false;
}
}
- fn use_qualified_module(&mut self, &mut CodeRepo, MachineFlags, &Module, &Vec<PredicateKey>)
- -> Result<(), SessionError>;
+ fn use_qualified_module(
+ &mut self,
+ &mut CodeRepo,
+ MachineFlags,
+ &Module,
+ &Vec<PredicateKey>,
+ ) -> Result<(), SessionError>;
fn use_module(&mut self, &mut CodeRepo, MachineFlags, &Module) -> Result<(), SessionError>;
}
-pub fn use_qualified_module<User>(user: &mut User, submodule: &Module, exports: &Vec<PredicateKey>)
- -> Result<(), SessionError>
- where User: SubModuleUser
+pub fn use_qualified_module<User>(
+ user: &mut User,
+ submodule: &Module,
+ exports: &Vec<PredicateKey>,
+) -> Result<(), SessionError>
+where
+ User: SubModuleUser,
{
for (name, arity) in exports.iter().cloned() {
- if !submodule.module_decl.exports.contains(&(name.clone(), arity)) {
+ if !submodule
+ .module_decl
+ .exports
+ .contains(&(name.clone(), arity))
+ {
continue;
}
Ok(())
}
-pub fn use_module<User: SubModuleUser>(user: &mut User, submodule: &Module)
- -> Result<(), SessionError>
-{
+pub fn use_module<User: SubModuleUser>(
+ user: &mut User,
+ submodule: &Module,
+) -> Result<(), SessionError> {
for (name, arity) in submodule.module_decl.exports.iter().cloned() {
if !user.import_decl(name, arity, submodule) {
return Err(SessionError::ModuleDoesNotContainExport);
self.code_dir.insert((name, arity), idx);
}
- fn use_qualified_module(&mut self, _: &mut CodeRepo, _: MachineFlags, submodule: &Module,
- exports: &Vec<PredicateKey>)
- -> Result<(), SessionError>
- {
+ fn use_qualified_module(
+ &mut self,
+ _: &mut CodeRepo,
+ _: MachineFlags,
+ submodule: &Module,
+ exports: &Vec<PredicateKey>,
+ ) -> Result<(), SessionError> {
use_qualified_module(self, submodule, exports)?;
- (self.user_term_expansions.0).0.extend((submodule.term_expansions.0).0.iter().cloned());
- self.user_term_expansions.1.extend(submodule.term_expansions.1.iter().cloned());
+ (self.user_term_expansions.0)
+ .0
+ .extend((submodule.term_expansions.0).0.iter().cloned());
+ self.user_term_expansions
+ .1
+ .extend(submodule.term_expansions.1.iter().cloned());
- (self.user_goal_expansions.0).0.extend((submodule.goal_expansions.0).0.iter().cloned());
- self.user_goal_expansions.1.extend(submodule.goal_expansions.1.iter().cloned());
+ (self.user_goal_expansions.0)
+ .0
+ .extend((submodule.goal_expansions.0).0.iter().cloned());
+ self.user_goal_expansions
+ .1
+ .extend(submodule.goal_expansions.1.iter().cloned());
Ok(())
}
- fn use_module(&mut self, _: &mut CodeRepo, _: MachineFlags, submodule: &Module)
- -> Result<(), SessionError>
- {
+ fn use_module(
+ &mut self,
+ _: &mut CodeRepo,
+ _: MachineFlags,
+ submodule: &Module,
+ ) -> Result<(), SessionError> {
use_module(self, submodule)?;
- (self.user_term_expansions.0).0.extend((submodule.term_expansions.0).0.iter().cloned());
- self.user_term_expansions.1.extend(submodule.term_expansions.1.iter().cloned());
-
- (self.user_goal_expansions.0).0.extend((submodule.goal_expansions.0).0.iter().cloned());
- self.user_goal_expansions.1.extend(submodule.goal_expansions.1.iter().cloned());
+ (self.user_term_expansions.0)
+ .0
+ .extend((submodule.term_expansions.0).0.iter().cloned());
+ self.user_term_expansions
+ .1
+ .extend(submodule.term_expansions.1.iter().cloned());
+
+ (self.user_goal_expansions.0)
+ .0
+ .extend((submodule.goal_expansions.0).0.iter().cloned());
+ self.user_goal_expansions
+ .1
+ .extend(submodule.goal_expansions.1.iter().cloned());
Ok(())
}
pub e: usize,
pub cp: LocalCodePtr,
pub attr_var_init_b: usize,
- pub b: usize,
+ pub b: usize,
pub bp: CodePtr,
pub tr: usize,
pub pstr_tr: usize,
pub h: usize,
pub b0: usize,
- args: Vec<Addr>
+ args: Vec<Addr>,
}
impl Frame {
- fn new(global_index: usize,
- e: usize,
- cp: LocalCodePtr,
- attr_var_init_b: usize,
- b: usize,
- bp: CodePtr,
- tr: usize,
- pstr_tr: usize,
- h: usize,
- b0: usize,
- n: usize)
- -> Self
- {
+ fn new(
+ global_index: usize,
+ e: usize,
+ cp: LocalCodePtr,
+ attr_var_init_b: usize,
+ b: usize,
+ bp: CodePtr,
+ tr: usize,
+ pstr_tr: usize,
+ h: usize,
+ b0: usize,
+ n: usize,
+ ) -> Self {
Frame {
global_index,
e,
pstr_tr,
h,
b0,
- args: vec![Addr::HeapCell(0); n]
+ args: vec![Addr::HeapCell(0); n],
}
}
OrStack(Vec::new())
}
- pub fn push(&mut self,
- global_index: usize,
- e: usize,
- cp: LocalCodePtr,
- attr_var_init_b: usize,
- b: usize,
- bp: CodePtr,
- tr: usize,
- pstr_tr: usize,
- h: usize,
- b0: usize,
- n: usize)
- {
- self.0.push(Frame::new(global_index, e, cp, attr_var_init_b, b, bp, tr, pstr_tr, h, b0, n));
+ pub fn push(
+ &mut self,
+ global_index: usize,
+ e: usize,
+ cp: LocalCodePtr,
+ attr_var_init_b: usize,
+ b: usize,
+ bp: CodePtr,
+ tr: usize,
+ pstr_tr: usize,
+ h: usize,
+ b0: usize,
+ n: usize,
+ ) {
+ self.0.push(Frame::new(
+ global_index,
+ e,
+ cp,
+ attr_var_init_b,
+ b,
+ bp,
+ tr,
+ pstr_tr,
+ h,
+ b0,
+ n,
+ ));
}
#[inline]
pub fn clear(&mut self) {
self.0.clear()
}
-
+
pub fn top(&self) -> Option<&Frame> {
self.0.last()
}
pub fn truncate(&mut self, new_b: usize) {
self.0.truncate(new_b);
}
-
+
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
use prolog::machine::machine_errors::*;
use prolog::machine::machine_indices::*;
use prolog::machine::machine_state::*;
-use prolog::machine::toplevel::{to_op_decl};
+use prolog::machine::toplevel::to_op_decl;
use prolog::ordered_float::OrderedFloat;
-use prolog::read::{PrologStream, readline};
+use prolog::read::{readline, PrologStream};
use prolog::rug::Integer;
use indexmap::{IndexMap, IndexSet};
hare: usize,
tortoise: usize,
power: usize,
- steps: usize
+ steps: usize,
}
impl BrentAlgState {
fn new(hare: usize) -> Self {
- BrentAlgState { hare, tortoise: hare, power: 2, steps: 1 }
+ BrentAlgState {
+ hare,
+ tortoise: hare,
+ power: 2,
+ steps: 1,
+ }
}
}
fn scan_for_trust_me(code: &Code, jmp_offsets: &mut VecDeque<usize>, after_idx: &mut usize) {
- for (idx, instr) in code[*after_idx ..].iter().enumerate() {
+ for (idx, instr) in code[*after_idx..].iter().enumerate() {
match instr {
&Line::Choice(ChoiceInstruction::TrustMe)
- | &Line::IndexedChoice(IndexedChoiceInstruction::Trust(..)) => {
+ | &Line::IndexedChoice(IndexedChoiceInstruction::Trust(..)) => {
*after_idx += idx;
return;
- },
- &Line::Control(ControlInstruction::JmpBy(_, offset, ..)) =>
- jmp_offsets.push_back(*after_idx + idx + offset),
+ }
+ &Line::Control(ControlInstruction::JmpBy(_, offset, ..)) => {
+ jmp_offsets.push_back(*after_idx + idx + offset)
+ }
_ => {}
}
}
impl MachineState {
// a step in Brent's algorithm.
- fn brents_alg_step(&self, brent_st: &mut BrentAlgState) -> Option<CycleSearchResult>
- {
+ fn brents_alg_step(&self, brent_st: &mut BrentAlgState) -> Option<CycleSearchResult> {
match self.heap[brent_st.hare].clone() {
- HeapCellValue::NamedStr(..) =>
- Some(CycleSearchResult::NotList),
- HeapCellValue::Addr(addr) =>
- match self.store(self.deref(addr)) {
- Addr::Con(Constant::EmptyList) =>
- Some(CycleSearchResult::ProperList(brent_st.steps)),
- Addr::HeapCell(_) | Addr::StackCell(..) =>
- Some(CycleSearchResult::PartialList(brent_st.steps, brent_st.hare)),
- Addr::Con(Constant::String(ref s))
- if self.flags.double_quotes.is_chars() =>
- Some(CycleSearchResult::String(brent_st.steps, s.clone())),
- Addr::Lis(l) => {
- brent_st.hare = l + 1;
- brent_st.steps += 1;
-
- if brent_st.tortoise == brent_st.hare {
- return Some(CycleSearchResult::NotList);
- } else if brent_st.steps == brent_st.power {
- brent_st.tortoise = brent_st.hare;
- brent_st.power <<= 1;
- }
+ HeapCellValue::NamedStr(..) => Some(CycleSearchResult::NotList),
+ HeapCellValue::Addr(addr) => match self.store(self.deref(addr)) {
+ Addr::Con(Constant::EmptyList) => {
+ Some(CycleSearchResult::ProperList(brent_st.steps))
+ }
+ Addr::HeapCell(_) | Addr::StackCell(..) => Some(CycleSearchResult::PartialList(
+ brent_st.steps,
+ brent_st.hare,
+ )),
+ Addr::Con(Constant::String(ref s)) if self.flags.double_quotes.is_chars() => {
+ Some(CycleSearchResult::String(brent_st.steps, s.clone()))
+ }
+ Addr::Lis(l) => {
+ brent_st.hare = l + 1;
+ brent_st.steps += 1;
+
+ if brent_st.tortoise == brent_st.hare {
+ return Some(CycleSearchResult::NotList);
+ } else if brent_st.steps == brent_st.power {
+ brent_st.tortoise = brent_st.hare;
+ brent_st.power <<= 1;
+ }
- None
- },
- _ =>
- Some(CycleSearchResult::NotList)
+ None
}
+ _ => Some(CycleSearchResult::NotList),
+ },
}
}
- pub(super) fn detect_cycles_with_max(&self, max_steps: usize, addr: Addr) -> CycleSearchResult
- {
+ pub(super) fn detect_cycles_with_max(&self, max_steps: usize, addr: Addr) -> CycleSearchResult {
let addr = self.store(self.deref(addr));
let hare = match addr {
Addr::Lis(offset) if max_steps > 0 => offset + 1,
Addr::Lis(offset) => return CycleSearchResult::UntouchedList(offset),
Addr::Con(Constant::EmptyList) => return CycleSearchResult::EmptyList,
- Addr::Con(Constant::String(ref s))
- if !self.flags.double_quotes.is_atom() =>
- return CycleSearchResult::String(0, s.clone()),
- _ => return CycleSearchResult::NotList
+ Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() => {
+ return CycleSearchResult::String(0, s.clone())
+ }
+ _ => return CycleSearchResult::NotList,
};
let mut brent_st = BrentAlgState::new(hare);
}
}
- pub(super) fn detect_cycles(&self, addr: Addr) -> CycleSearchResult
- {
+ pub(super) fn detect_cycles(&self, addr: Addr) -> CycleSearchResult {
let addr = self.store(self.deref(addr));
let hare = match addr {
Addr::Lis(offset) => offset + 1,
Addr::Con(Constant::EmptyList) => return CycleSearchResult::EmptyList,
- Addr::Con(Constant::String(ref s))
- if !self.flags.double_quotes.is_atom() =>
- return CycleSearchResult::String(0, s.clone()),
- _ => return CycleSearchResult::NotList
+ Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() => {
+ return CycleSearchResult::String(0, s.clone())
+ }
+ _ => return CycleSearchResult::NotList,
};
let mut brent_st = BrentAlgState::new(hare);
let max_steps = self.store(self.deref(self[temp_v!(2)].clone()));
match max_steps {
- Addr::Con(Constant::Integer(ref max_steps)) =>
+ Addr::Con(Constant::Integer(ref max_steps)) => {
if max_steps.to_isize().map(|i| i >= -1).unwrap_or(false) {
let n = self.store(self.deref(self[temp_v!(1)].clone()));
match n {
Addr::Con(Constant::Integer(ref n)) if n == &0 => {
let xs0 = self[temp_v!(3)].clone();
- let xs = self[temp_v!(4)].clone();
+ let xs = self[temp_v!(4)].clone();
self.unify(xs0, xs);
- },
+ }
_ => {
let (max_steps, search_result) =
if let Some(max_steps) = max_steps.to_isize() {
- (max_steps, if max_steps == -1 {
- self.detect_cycles(self[temp_v!(3)].clone())
- } else {
- self.detect_cycles_with_max(max_steps as usize,
- self[temp_v!(3)].clone())
- })
+ (
+ max_steps,
+ if max_steps == -1 {
+ self.detect_cycles(self[temp_v!(3)].clone())
+ } else {
+ self.detect_cycles_with_max(
+ max_steps as usize,
+ self[temp_v!(3)].clone(),
+ )
+ },
+ )
} else {
(-1, self.detect_cycles(self[temp_v!(3)].clone()))
};
match search_result {
- CycleSearchResult::String(n, s) =>
+ CycleSearchResult::String(n, s) => {
if max_steps == -1 {
- self.finalize_skip_max_list(n + s.len(),
- Addr::Con(Constant::EmptyList))
+ self.finalize_skip_max_list(
+ n + s.len(),
+ Addr::Con(Constant::EmptyList),
+ )
} else {
let i = (max_steps as usize) - n;
if s.len() < i {
- self.finalize_skip_max_list(n + s.len(),
- Addr::Con(Constant::EmptyList))
+ self.finalize_skip_max_list(
+ n + s.len(),
+ Addr::Con(Constant::EmptyList),
+ )
} else {
- let s = StringList::new(s.char_span(i), s.is_expandable());
- self.finalize_skip_max_list(i + n,
- Addr::Con(Constant::String(s)))
+ let s =
+ StringList::new(s.char_span(i), s.is_expandable());
+ self.finalize_skip_max_list(
+ i + n,
+ Addr::Con(Constant::String(s)),
+ )
}
- },
- CycleSearchResult::UntouchedList(l) =>
- self.finalize_skip_max_list(0, Addr::Lis(l)),
- CycleSearchResult::EmptyList =>
- self.finalize_skip_max_list(0, Addr::Con(Constant::EmptyList)),
- CycleSearchResult::PartialList(n, hc) =>
- self.finalize_skip_max_list(n, Addr::HeapCell(hc)),
- CycleSearchResult::ProperList(n) =>
- self.finalize_skip_max_list(n, Addr::Con(Constant::EmptyList)),
+ }
+ }
+ CycleSearchResult::UntouchedList(l) => {
+ self.finalize_skip_max_list(0, Addr::Lis(l))
+ }
+ CycleSearchResult::EmptyList => {
+ self.finalize_skip_max_list(0, Addr::Con(Constant::EmptyList))
+ }
+ CycleSearchResult::PartialList(n, hc) => {
+ self.finalize_skip_max_list(n, Addr::HeapCell(hc))
+ }
+ CycleSearchResult::ProperList(n) => {
+ self.finalize_skip_max_list(n, Addr::Con(Constant::EmptyList))
+ }
CycleSearchResult::NotList => {
let xs0 = self[temp_v!(3)].clone();
self.finalize_skip_max_list(0, xs0);
}
} else {
self.fail = true;
- },
+ }
+ }
Addr::HeapCell(_) | Addr::StackCell(..) => {
let stub = MachineError::functor_stub(clause_name!("$skip_max_list"), 4);
return Err(self.error_form(MachineError::instantiation_error(), stub));
- },
+ }
addr => {
let stub = MachineError::functor_stub(clause_name!("$skip_max_list"), 4);
- return Err(self.error_form(MachineError::type_error(ValidType::Integer, addr),
- stub));
+ return Err(
+ self.error_form(MachineError::type_error(ValidType::Integer, addr), stub)
+ );
}
};
self.block
}
- fn copy_findall_solution(&mut self, lh_offset: usize, copy_target: Addr) -> usize
- {
+ fn copy_findall_solution(&mut self, lh_offset: usize, copy_target: Addr) -> usize {
let threshold = self.lifted_heap.len() - lh_offset;
- let mut copy_ball_term = CopyBallTerm::new(&mut self.and_stack, &mut self.heap,
- &mut self.lifted_heap);
+ let mut copy_ball_term =
+ CopyBallTerm::new(&mut self.and_stack, &mut self.heap, &mut self.lifted_heap);
copy_ball_term.push(HeapCellValue::Addr(Addr::Lis(threshold + 1)));
copy_ball_term.push(HeapCellValue::Addr(Addr::HeapCell(threshold + 3)));
}
fn truncate_if_no_lifted_heap_diff<AddrConstr>(&mut self, addr_constr: AddrConstr)
- where AddrConstr: Fn(usize) -> Addr
+ where
+ AddrConstr: Fn(usize) -> Addr,
{
match self.store(self.deref(self[temp_v!(1)].clone())) {
Addr::Con(Constant::Usize(lh_offset)) => {
self.lifted_heap.truncate(lh_offset);
} else {
let threshold = self.lifted_heap.len() - lh_offset;
- self.lifted_heap.push(HeapCellValue::Addr(addr_constr(threshold)));
+ self.lifted_heap
+ .push(HeapCellValue::Addr(addr_constr(threshold)));
}
- },
- _ =>
- self.fail = true
+ }
+ _ => self.fail = true,
}
}
match db_ref {
&DBRef::NamedPred(ref name, arity, _) => {
let key = (name.clone(), arity);
- let mut iter = indices.code_dir.range(key ..).skip(1);
+ let mut iter = indices.code_dir.range(key..).skip(1);
while let Some(((name, arity), idx)) = iter.next() {
if idx.is_undefined() {
let a2 = self[temp_v!(2)].clone();
if let Some(r) = a2.as_var() {
- let spec = get_clause_spec(name.clone(), *arity,
- composite_op!(&indices.op_dir));
+ let spec =
+ get_clause_spec(name.clone(), *arity, composite_op!(&indices.op_dir));
self.bind(r, Addr::DBRef(DBRef::NamedPred(name.clone(), *arity, spec)));
return;
}
}
self.fail = true;
- },
+ }
&DBRef::Op(_, spec, ref name, ref op_dir, _) => {
let fixity = match spec {
XF | YF => Fixity::Post,
FX | FY => Fixity::Pre,
- _ => Fixity::In
+ _ => Fixity::In,
};
let key = OrderedOpDirKey(name.clone(), fixity);
- match op_dir.range(key ..).skip(1).next() {
+ match op_dir.range(key..).skip(1).next() {
Some((OrderedOpDirKey(name, _), (priority, spec))) => {
let a2 = self[temp_v!(2)].clone();
if let Some(r) = a2.as_var() {
- self.bind(r, Addr::DBRef(DBRef::Op(*priority, *spec, name.clone(),
- op_dir.clone(),
- SharedOpDesc::new(*priority, *spec))));
+ self.bind(
+ r,
+ Addr::DBRef(DBRef::Op(
+ *priority,
+ *spec,
+ name.clone(),
+ op_dir.clone(),
+ SharedOpDesc::new(*priority, *spec),
+ )),
+ );
} else {
self.fail = true;
}
- },
- None => self.fail = true
+ }
+ None => self.fail = true,
}
}
}
}
- fn int_to_char_code(&mut self, n: &Integer, stub: &'static str, arity: usize)
- -> Result<u8, MachineStub>
- {
+ fn int_to_char_code(
+ &mut self,
+ n: &Integer,
+ stub: &'static str,
+ arity: usize,
+ ) -> Result<u8, MachineStub> {
if let Some(c) = n.to_u8() {
Ok(c)
} else {
}
}
- fn parse_number_from_string(&mut self, mut string: String, indices: &IndexStore, stub: MachineStub)
- -> CallResult
- {
- let nx = self[temp_v!(2)].clone();
+ fn parse_number_from_string(
+ &mut self,
+ mut string: String,
+ indices: &IndexStore,
+ stub: MachineStub,
+ ) -> CallResult {
+ let nx = self[temp_v!(2)].clone();
if let Some(c) = string.chars().last() {
if layout_char!(c) {
- let (line_num, col_num) = string.chars().fold((0, 0), |(line_num, col_num), c|
- if new_line_char!(c) { (1 + line_num, 0) } else { (line_num, col_num + 1) }
- );
+ let (line_num, col_num) = string.chars().fold((0, 0), |(line_num, col_num), c| {
+ if new_line_char!(c) {
+ (1 + line_num, 0)
+ } else {
+ (line_num, col_num + 1)
+ }
+ });
let err = ParserError::UnexpectedChar(c, line_num, col_num);
let h = self.heap.h;
string.push('.');
let mut stream = parsing_stream(std::io::Cursor::new(string));
- let mut parser = Parser::new(&mut stream, indices.atom_tbl.clone(),
- self.machine_flags());
+ let mut parser = Parser::new(&mut stream, indices.atom_tbl.clone(), self.machine_flags());
match parser.read_term(composite_op!(&indices.op_dir)) {
Err(err) => {
let err = MachineError::syntax_error(h, err);
return Err(self.error_form(err, stub));
- },
- Ok(Term::Constant(_, Constant::Rational(n))) =>
- self.unify(nx, Addr::Con(Constant::Rational(n))),
- Ok(Term::Constant(_, Constant::Float(n))) =>
- self.unify(nx, Addr::Con(Constant::Float(n))),
- Ok(Term::Constant(_, Constant::Integer(n))) =>
- self.unify(nx, Addr::Con(Constant::Integer(n))),
- Ok(Term::Constant(_, Constant::CharCode(c))) =>
- self.unify(nx, Addr::Con(Constant::CharCode(c))),
+ }
+ Ok(Term::Constant(_, Constant::Rational(n))) => {
+ self.unify(nx, Addr::Con(Constant::Rational(n)))
+ }
+ Ok(Term::Constant(_, Constant::Float(n))) => {
+ self.unify(nx, Addr::Con(Constant::Float(n)))
+ }
+ Ok(Term::Constant(_, Constant::Integer(n))) => {
+ self.unify(nx, Addr::Con(Constant::Integer(n)))
+ }
+ Ok(Term::Constant(_, Constant::CharCode(c))) => {
+ self.unify(nx, Addr::Con(Constant::CharCode(c)))
+ }
_ => {
let err = ParserError::ParseBigInt(0, 0);
Ok(())
}
- fn create_instruction_functors(&mut self, code: &Code, first_idx: usize) -> Vec<Addr>
- {
+ fn create_instruction_functors(&mut self, code: &Code, first_idx: usize) -> Vec<Addr> {
let mut queue = VecDeque::new();
let mut functors = vec![];
let mut h = self.heap.h;
loop {
match &code[last_idx] {
&Line::Choice(ChoiceInstruction::TryMeElse(..))
- | &Line::IndexedChoice(IndexedChoiceInstruction::Try(..)) => {
+ | &Line::IndexedChoice(IndexedChoiceInstruction::Try(..)) => {
last_idx += 1;
scan_for_trust_me(code, &mut queue, &mut last_idx);
- },
+ }
&Line::Control(ControlInstruction::JmpBy(_, offset, _, false)) => {
queue.push_back(last_idx + offset);
last_idx += 1;
- },
+ }
&Line::Control(ControlInstruction::JmpBy(_, offset, _, true)) => {
queue.push_back(last_idx + offset);
break;
- },
+ }
&Line::Control(ControlInstruction::Proceed)
- | &Line::Control(ControlInstruction::CallClause(_, _, _, true, _)) =>
- break,
- _ =>
- last_idx += 1
+ | &Line::Control(ControlInstruction::CallClause(_, _, _, true, _)) => break,
+ _ => last_idx += 1,
};
}
- for instr in &code[first_idx .. last_idx + 1] {
+ for instr in &code[first_idx..last_idx + 1] {
let section = instr.to_functor(h);
functors.push(Addr::HeapCell(h));
functors
}
- pub(super)
- fn system_call(&mut self,
- ct: &SystemClauseType,
- code_repo: &CodeRepo,
- indices: &mut IndexStore,
- call_policy: &mut Box<CallPolicy>,
- cut_policy: &mut Box<CutPolicy>,
- current_input_stream: &mut PrologStream)
- -> CallResult
- {
+ pub(super) fn system_call(
+ &mut self,
+ ct: &SystemClauseType,
+ code_repo: &CodeRepo,
+ indices: &mut IndexStore,
+ call_policy: &mut Box<CallPolicy>,
+ cut_policy: &mut Box<CutPolicy>,
+ current_input_stream: &mut PrologStream,
+ ) -> CallResult {
match ct {
&SystemClauseType::AbolishClause => {
let p = self.cp;
self.p = CodePtr::DynamicTransaction(trans_type, p);
return Ok(());
- },
+ }
&SystemClauseType::AbolishModuleClause => {
let p = self.cp;
let trans_type = DynamicTransactionType::ModuleAbolish;
self.p = CodePtr::DynamicTransaction(trans_type, p);
return Ok(());
- },
+ }
&SystemClauseType::AssertDynamicPredicateToFront => {
let p = self.cp;
let trans_type = DynamicTransactionType::Assert(DynamicAssertPlace::Front);
self.p = CodePtr::DynamicTransaction(trans_type, p);
return Ok(());
- },
+ }
&SystemClauseType::AssertDynamicPredicateToBack => {
let p = self.cp;
let trans_type = DynamicTransactionType::Assert(DynamicAssertPlace::Back);
self.p = CodePtr::DynamicTransaction(trans_type, p);
return Ok(());
- },
+ }
&SystemClauseType::AtomChars => {
let a1 = self[temp_v!(1)].clone();
let a2 = self[temp_v!(2)].clone();
self.unify(a2, list_of_chars);
- },
+ }
Addr::Con(Constant::Atom(name, _)) => {
let iter = name.as_str().chars().map(|c| Addr::Con(Constant::Char(c)));
let list_of_chars = Addr::HeapCell(self.heap.to_list(iter));
let a2 = self[temp_v!(2)].clone();
self.unify(a2, list_of_chars);
- },
+ }
Addr::Con(Constant::EmptyList) => {
let a2 = self[temp_v!(2)].clone();
- let chars = vec![Addr::Con(Constant::Char('[')),
- Addr::Con(Constant::Char(']'))];
+ let chars = vec![
+ Addr::Con(Constant::Char('[')),
+ Addr::Con(Constant::Char(']')),
+ ];
let list_of_chars = Addr::HeapCell(self.heap.to_list(chars.into_iter()));
self.unify(a2, list_of_chars);
- },
+ }
ref addr if addr.is_ref() => {
let stub = MachineError::functor_stub(clause_name!("atom_chars"), 2);
match self.try_from_list(temp_v!(2), stub.clone()) {
Err(e) => return Err(e),
- Ok(addrs) =>
- match self.try_char_list(addrs) {
- Ok(string) => {
- let chars = clause_name!(string, indices.atom_tbl);
- self.unify(addr.clone(), Addr::Con(Constant::Atom(chars, None)));
- },
- Err(err) =>
- return Err(self.error_form(err, stub))
+ Ok(addrs) => match self.try_char_list(addrs) {
+ Ok(string) => {
+ let chars = clause_name!(string, indices.atom_tbl);
+ self.unify(
+ addr.clone(),
+ Addr::Con(Constant::Atom(chars, None)),
+ );
}
+ Err(err) => return Err(self.error_form(err, stub)),
+ },
}
- },
- _ => unreachable!()
+ }
+ _ => unreachable!(),
};
- },
+ }
&SystemClauseType::AtomCodes => {
let a1 = self[temp_v!(1)].clone();
let a2 = self[temp_v!(2)].clone();
self.unify(a2, list_of_codes);
- },
+ }
Addr::Con(Constant::Atom(name, _)) => {
- let iter = name.as_str().chars().map(|c| Addr::Con(Constant::CharCode(c as u8)));
+ let iter = name
+ .as_str()
+ .chars()
+ .map(|c| Addr::Con(Constant::CharCode(c as u8)));
let list_of_codes = Addr::HeapCell(self.heap.to_list(iter));
let a2 = self[temp_v!(2)].clone();
self.unify(a2, list_of_codes);
- },
+ }
Addr::Con(Constant::EmptyList) => {
let a2 = self[temp_v!(2)].clone();
- let chars = vec![Addr::Con(Constant::CharCode('[' as u8)),
- Addr::Con(Constant::CharCode(']' as u8))];
+ let chars = vec![
+ Addr::Con(Constant::CharCode('[' as u8)),
+ Addr::Con(Constant::CharCode(']' as u8)),
+ ];
let list_of_codes = Addr::HeapCell(self.heap.to_list(chars.into_iter()));
self.unify(a2, list_of_codes);
- },
+ }
ref addr if addr.is_ref() => {
let stub = MachineError::functor_stub(clause_name!("atom_codes"), 2);
&Addr::Con(Constant::Integer(ref n)) => {
let c = self.int_to_char_code(&n, "atom_codes", 2)?;
chars.push(c as char);
- },
- &Addr::Con(Constant::CharCode(c)) =>
- chars.push(c as char),
+ }
+ &Addr::Con(Constant::CharCode(c)) => chars.push(c as char),
_ => {
- let err = MachineError::type_error(ValidType::Integer, addr.clone());
+ let err = MachineError::type_error(
+ ValidType::Integer,
+ addr.clone(),
+ );
return Err(self.error_form(err, stub));
}
}
self.unify(addr.clone(), Addr::Con(Constant::Atom(chars, None)));
}
}
- },
- _ => unreachable!()
+ }
+ _ => unreachable!(),
};
- },
+ }
&SystemClauseType::AtomLength => {
let a1 = self[temp_v!(1)].clone();
Addr::Con(Constant::Atom(name, _)) => name,
Addr::Con(Constant::EmptyList) => clause_name!("[]"),
Addr::Con(Constant::Char(c)) => clause_name!(c.to_string(), indices.atom_tbl),
- _ => unreachable!()
+ _ => unreachable!(),
};
let len = Integer::from(atom.as_str().len());
- let a2 = self[temp_v!(2)].clone();
+ let a2 = self[temp_v!(2)].clone();
self.unify(a2, Addr::Con(Constant::Integer(len)));
- },
+ }
&SystemClauseType::CharsToNumber => {
let stub = MachineError::functor_stub(clause_name!("number_chars"), 2);
match self.try_from_list(temp_v!(1), stub.clone()) {
Err(e) => return Err(e),
- Ok(addrs) =>
- match self.try_char_list(addrs) {
- Ok(string) =>
- self.parse_number_from_string(string, indices, stub)?,
- Err(err) =>
- return Err(self.error_form(err, stub))
- }
+ Ok(addrs) => match self.try_char_list(addrs) {
+ Ok(string) => self.parse_number_from_string(string, indices, stub)?,
+ Err(err) => return Err(self.error_form(err, stub)),
+ },
}
- },
+ }
&SystemClauseType::NumberToChars => {
let n = self[temp_v!(1)].clone();
let chs = self[temp_v!(2)].clone();
let string = match self.store(self.deref(n)) {
- Addr::Con(Constant::Float(OrderedFloat(n))) =>
- format!("{0:<20?}", n),
- Addr::Con(Constant::Integer(n)) =>
- n.to_string(),
- _ => unreachable!()
+ Addr::Con(Constant::Float(OrderedFloat(n))) => format!("{0:<20?}", n),
+ Addr::Con(Constant::Integer(n)) => n.to_string(),
+ _ => unreachable!(),
};
let chars = string.trim().chars().map(|c| Addr::Con(Constant::Char(c)));
let char_list = Addr::HeapCell(self.heap.to_list(chars));
self.unify(char_list, chs);
- },
+ }
&SystemClauseType::NumberToCodes => {
let n = self[temp_v!(1)].clone();
let chs = self[temp_v!(2)].clone();
let string = match self.store(self.deref(n)) {
- Addr::Con(Constant::Float(OrderedFloat(n))) =>
- format!("{0:<20?}", n),
- Addr::Con(Constant::Integer(n)) =>
- n.to_string(),
- _ => unreachable!()
+ Addr::Con(Constant::Float(OrderedFloat(n))) => format!("{0:<20?}", n),
+ Addr::Con(Constant::Integer(n)) => n.to_string(),
+ _ => unreachable!(),
};
- let codes = string.trim().chars().map(|c| Addr::Con(Constant::CharCode(c as u8)));
+ let codes = string
+ .trim()
+ .chars()
+ .map(|c| Addr::Con(Constant::CharCode(c as u8)));
let codes_list = Addr::HeapCell(self.heap.to_list(codes));
self.unify(codes_list, chs);
- },
+ }
&SystemClauseType::CodesToNumber => {
let stub = MachineError::functor_stub(clause_name!("number_codes"), 2);
match self.try_from_list(temp_v!(1), stub.clone()) {
Err(e) => return Err(e),
- Ok(addrs) =>
- match self.try_code_list(addrs) {
- Ok(codes) => {
- let string = codes.iter().map(|c| *c as char).collect();
- self.parse_number_from_string(string, indices, stub)?
- },
- Err(err) =>
- return Err(self.error_form(err, stub))
+ Ok(addrs) => match self.try_code_list(addrs) {
+ Ok(codes) => {
+ let string = codes.iter().map(|c| *c as char).collect();
+ self.parse_number_from_string(string, indices, stub)?
}
+ Err(err) => return Err(self.error_form(err, stub)),
+ },
}
- },
+ }
&SystemClauseType::ModuleAssertDynamicPredicateToFront => {
let p = self.cp;
let trans_type = DynamicTransactionType::ModuleAssert(DynamicAssertPlace::Front);
self.p = CodePtr::DynamicTransaction(trans_type, p);
return Ok(());
- },
+ }
&SystemClauseType::ModuleAssertDynamicPredicateToBack => {
let p = self.cp;
let trans_type = DynamicTransactionType::ModuleAssert(DynamicAssertPlace::Back);
self.p = CodePtr::DynamicTransaction(trans_type, p);
return Ok(());
- },
+ }
&SystemClauseType::LiftedHeapLength => {
let a1 = self[temp_v!(1)].clone();
let lh_len = Addr::Con(Constant::Usize(self.lifted_heap.len()));
self.unify(a1, lh_len);
- },
+ }
&SystemClauseType::CharCode => {
let a1 = self[temp_v!(1)].clone();
let a2 = self[temp_v!(2)].clone();
self.unify(Addr::Con(Constant::CharCode(c as u8)), a2);
- },
+ }
Addr::Con(Constant::Char(c)) => {
let a2 = self[temp_v!(2)].clone();
self.unify(Addr::Con(Constant::CharCode(c as u8)), a2);
- },
+ }
ref addr if addr.is_ref() => {
let a2 = self[temp_v!(2)].clone();
match self.store(self.deref(a2)) {
- Addr::Con(Constant::CharCode(code)) =>
- self.unify(Addr::Con(Constant::Char(code as char)), addr.clone()),
+ Addr::Con(Constant::CharCode(code)) => {
+ self.unify(Addr::Con(Constant::Char(code as char)), addr.clone())
+ }
Addr::Con(Constant::Integer(n)) => {
let c = self.int_to_char_code(&n, "char_code", 2)?;
self.unify(Addr::Con(Constant::Char(c as char)), addr.clone());
- },
- _ => self.fail = true
+ }
+ _ => self.fail = true,
};
- },
- _ => unreachable!()
+ }
+ _ => unreachable!(),
};
- },
+ }
&SystemClauseType::CheckCutPoint => {
let addr = self.store(self.deref(self[temp_v!(1)].clone()));
match addr {
- Addr::Con(Constant::Usize(old_b)) if self.b <= old_b + 2 => {},
- _ => self.fail = true
+ Addr::Con(Constant::Usize(old_b)) if self.b <= old_b + 2 => {}
+ _ => self.fail = true,
};
- },
+ }
&SystemClauseType::FetchGlobalVar => {
let key = self[temp_v!(1)].clone();
let key = match self.store(self.deref(key)) {
Addr::Con(Constant::Atom(atom, _)) => atom,
- _ => unreachable!()
+ _ => unreachable!(),
};
let addr = self[temp_v!(2)].clone();
match indices.global_variables.get(&key).cloned() {
Some(sought_addr) => self.unify(addr, sought_addr),
- None => self.fail = true
+ None => self.fail = true,
};
- },
+ }
&SystemClauseType::GetChar => {
let result = current_input_stream.next();
let a1 = self[temp_v!(1)].clone();
Some(Err(_)) => {
let end_of_file = clause_name!("end_of_file");
self.unify(a1, Addr::Con(Constant::Atom(end_of_file, None)));
- },
+ }
None => {
let stub = MachineError::functor_stub(clause_name!("get_char"), 1);
let err = MachineError::representation_error(RepFlag::Character);
let err = self.error_form(err, stub);
return Err(err);
- },
+ }
}
- },
+ }
&SystemClauseType::GetModuleClause => {
let module = self[temp_v!(3)].clone();
let head = self[temp_v!(1)].clone();
let module = match self.store(self.deref(module)) {
- Addr::Con(Constant::Atom(module, _)) =>
- module,
+ Addr::Con(Constant::Atom(module, _)) => module,
_ => {
self.fail = true;
return Ok(());
};
let subsection = match self.store(self.deref(head)) {
- Addr::Str(s) =>
- match self.heap[s].clone() {
- HeapCellValue::NamedStr(arity, name, ..) =>
- indices.get_clause_subsection(module, name, arity),
- _ => unreachable!()
- },
- Addr::Con(Constant::Atom(name, _)) =>
- indices.get_clause_subsection(module, name, 0),
- _ => unreachable!()
+ Addr::Str(s) => match self.heap[s].clone() {
+ HeapCellValue::NamedStr(arity, name, ..) => {
+ indices.get_clause_subsection(module, name, arity)
+ }
+ _ => unreachable!(),
+ },
+ Addr::Con(Constant::Atom(name, _)) => {
+ indices.get_clause_subsection(module, name, 0)
+ }
+ _ => unreachable!(),
};
match subsection {
Some(dynamic_predicate_info) => {
self.execute_at_index(2, dynamic_predicate_info.clauses_subsection_p);
return Ok(());
- },
- None => self.fail = true
+ }
+ None => self.fail = true,
}
- },
+ }
&SystemClauseType::ModuleHeadIsDynamic => {
let module = self[temp_v!(2)].clone();
let head = self[temp_v!(1)].clone();
let module = match self.store(self.deref(module)) {
- Addr::Con(Constant::Atom(module, _)) =>
- module,
+ Addr::Con(Constant::Atom(module, _)) => module,
_ => {
self.fail = true;
return Ok(());
};
self.fail = !match self.store(self.deref(head)) {
- Addr::Str(s) =>
- match self.heap[s].clone() {
- HeapCellValue::NamedStr(arity, name, ..) =>
- indices.get_clause_subsection(module, name, arity).is_some(),
- _ => unreachable!()
- },
- Addr::Con(Constant::Atom(name, _)) =>
- indices.get_clause_subsection(module, name, 0).is_some(),
- _ => unreachable!()
+ Addr::Str(s) => match self.heap[s].clone() {
+ HeapCellValue::NamedStr(arity, name, ..) => {
+ indices.get_clause_subsection(module, name, arity).is_some()
+ }
+ _ => unreachable!(),
+ },
+ Addr::Con(Constant::Atom(name, _)) => {
+ indices.get_clause_subsection(module, name, 0).is_some()
+ }
+ _ => unreachable!(),
};
- },
+ }
&SystemClauseType::HeadIsDynamic => {
let head = self[temp_v!(1)].clone();
self.fail = !match self.store(self.deref(head)) {
- Addr::Str(s) =>
- match self.heap[s].clone() {
- HeapCellValue::NamedStr(arity, name, ..) =>
- indices.get_clause_subsection(name.owning_module(), name, arity).is_some(),
- _ => unreachable!()
- },
- Addr::Con(Constant::Atom(name, _)) =>
- indices.get_clause_subsection(name.owning_module(), name, 0).is_some(),
- _ => unreachable!()
+ Addr::Str(s) => match self.heap[s].clone() {
+ HeapCellValue::NamedStr(arity, name, ..) => indices
+ .get_clause_subsection(name.owning_module(), name, arity)
+ .is_some(),
+ _ => unreachable!(),
+ },
+ Addr::Con(Constant::Atom(name, _)) => indices
+ .get_clause_subsection(name.owning_module(), name, 0)
+ .is_some(),
+ _ => unreachable!(),
};
- },
- &SystemClauseType::CopyToLiftedHeap =>
+ }
+ &SystemClauseType::CopyToLiftedHeap => {
match self.store(self.deref(self[temp_v!(1)].clone())) {
Addr::Con(Constant::Usize(lh_offset)) => {
let copy_target = self[temp_v!(2)].clone();
let old_threshold = self.copy_findall_solution(lh_offset, copy_target);
let new_threshold = self.lifted_heap.len() - lh_offset;
- self.lifted_heap[old_threshold] = HeapCellValue::Addr(Addr::HeapCell(new_threshold));
+ self.lifted_heap[old_threshold] =
+ HeapCellValue::Addr(Addr::HeapCell(new_threshold));
- for index in old_threshold + 1 .. self.lifted_heap.len() {
+ for index in old_threshold + 1..self.lifted_heap.len() {
match &mut self.lifted_heap[index] {
- &mut HeapCellValue::Addr(ref mut addr) =>
- *addr -= self.heap.len() + lh_offset,
+ &mut HeapCellValue::Addr(ref mut addr) => {
+ *addr -= self.heap.len() + lh_offset
+ }
_ => {}
}
}
- },
- _ => self.fail = true
- },
+ }
+ _ => self.fail = true,
+ }
+ }
&SystemClauseType::DeleteAttribute => {
let ls0 = self.store(self.deref(self[temp_v!(1)].clone()));
self.trail(TrailRef::AttrVarLink(l1 + 1, addr));
}
}
- },
+ }
&SystemClauseType::DeleteHeadAttribute => {
let addr = self.store(self.deref(self[temp_v!(1)].clone()));
match addr {
Addr::AttrVar(h) => {
- let addr = self.heap[h+1].as_addr(h+1).clone();
+ let addr = self.heap[h + 1].as_addr(h + 1).clone();
let addr = self.store(self.deref(addr));
match addr {
Addr::Lis(l) => {
- self.heap[h+1] = HeapCellValue::Addr(Addr::HeapCell(l+1));
- self.trail(TrailRef::AttrVarLink(h+1, Addr::Lis(l)));
- },
- _ => unreachable!()
+ self.heap[h + 1] = HeapCellValue::Addr(Addr::HeapCell(l + 1));
+ self.trail(TrailRef::AttrVarLink(h + 1, Addr::Lis(l)));
+ }
+ _ => unreachable!(),
}
- },
- _ => unreachable!()
+ }
+ _ => unreachable!(),
}
- },
+ }
&SystemClauseType::DynamicModuleResolution => {
let module_name = self.store(self.deref(self[temp_v!(1)].clone()));
if let Addr::Con(Constant::Atom(module_name, _)) = module_name {
match self.store(self.deref(self[temp_v!(2)].clone())) {
- Addr::Str(a) =>
+ Addr::Str(a) => {
if let HeapCellValue::NamedStr(arity, name, _) = self.heap[a].clone() {
- for i in 1 .. arity + 1 {
- self.registers[i] = self.heap[a+i].as_addr(a+i);
+ for i in 1..arity + 1 {
+ self.registers[i] = self.heap[a + i].as_addr(a + i);
}
- return self.module_lookup(indices, (name, arity), module_name, true);
- },
- Addr::Con(Constant::Atom(name, _)) =>
- return self.module_lookup(indices, (name, 0), module_name, true),
+ return self.module_lookup(
+ indices,
+ (name, arity),
+ module_name,
+ true,
+ );
+ }
+ }
+ Addr::Con(Constant::Atom(name, _)) => {
+ return self.module_lookup(indices, (name, 0), module_name, true)
+ }
addr => {
let stub = MachineError::functor_stub(clause_name!("(:)"), 2);
}
}
};
- },
+ }
&SystemClauseType::EnqueueAttributeGoal => {
let addr = self[temp_v!(1)].clone();
self.attr_var_init.attribute_goals.push(addr);
- },
+ }
&SystemClauseType::EnqueueAttributedVar => {
let addr = self[temp_v!(1)].clone();
match self.store(self.deref(addr)) {
- Addr::AttrVar(h) =>
- self.attr_var_init.attr_var_queue.push(h),
+ Addr::AttrVar(h) => self.attr_var_init.attr_var_queue.push(h),
_ => {}
}
- },
+ }
&SystemClauseType::ExpandGoal => {
self.p = CodePtr::Local(LocalCodePtr::UserGoalExpansion(0));
return Ok(());
- },
+ }
&SystemClauseType::ExpandTerm => {
self.p = CodePtr::Local(LocalCodePtr::UserTermExpansion(0));
return Ok(());
- },
+ }
&SystemClauseType::GetNextDBRef => {
let a1 = self[temp_v!(1)].clone();
match self.store(self.deref(a1)) {
addr @ Addr::HeapCell(_)
- | addr @ Addr::StackCell(..)
- | addr @ Addr::AttrVar(_) => {
- let mut iter = indices.code_dir.iter();
+ | addr @ Addr::StackCell(..)
+ | addr @ Addr::AttrVar(_) => {
+ let mut iter = indices.code_dir.iter();
- while let Some(((name, arity), _)) = iter.next() {
- if is_builtin_predicate(&name) {
- continue;
- }
+ while let Some(((name, arity), _)) = iter.next() {
+ if is_builtin_predicate(&name) {
+ continue;
+ }
- let spec = get_clause_spec(name.clone(), *arity,
- composite_op!(&indices.op_dir));
- let db_ref = DBRef::NamedPred(name.clone(), *arity, spec);
- let r = addr.as_var().unwrap();
+ let spec = get_clause_spec(
+ name.clone(),
+ *arity,
+ composite_op!(&indices.op_dir),
+ );
+ let db_ref = DBRef::NamedPred(name.clone(), *arity, spec);
+ let r = addr.as_var().unwrap();
- self.bind(r, Addr::DBRef(db_ref));
- return return_from_clause!(self.last_call, self);
- }
+ self.bind(r, Addr::DBRef(db_ref));
+ return return_from_clause!(self.last_call, self);
+ }
- self.fail = true;
- },
+ self.fail = true;
+ }
Addr::DBRef(DBRef::Op(..)) => self.fail = true,
- Addr::DBRef(ref db_ref) =>
- self.get_next_db_ref(&indices, db_ref),
+ Addr::DBRef(ref db_ref) => self.get_next_db_ref(&indices, db_ref),
_ => {
- self.fail = true;
+ self.fail = true;
}
};
- },
+ }
&SystemClauseType::GetNextOpDBRef => {
let a1 = self[temp_v!(1)].clone();
match self.store(self.deref(a1)) {
addr @ Addr::HeapCell(_)
- | addr @ Addr::StackCell(..)
- | addr @ Addr::AttrVar(_) => {
- let mut unossified_op_dir = OssifiedOpDir::new();
-
- unossified_op_dir.extend(indices.op_dir.iter().filter_map(|(key, op_dir_val)| {
- let (name, fixity) = key.clone();
+ | addr @ Addr::StackCell(..)
+ | addr @ Addr::AttrVar(_) => {
+ let mut unossified_op_dir = OssifiedOpDir::new();
- let prec = op_dir_val.shared_op_desc().prec();
+ unossified_op_dir.extend(indices.op_dir.iter().filter_map(
+ |(key, op_dir_val)| {
+ let (name, fixity) = key.clone();
- if prec == 0 {
- return None;
- }
+ let prec = op_dir_val.shared_op_desc().prec();
- let assoc = op_dir_val.shared_op_desc().assoc();
-
- Some((OrderedOpDirKey(name, fixity), (prec, assoc)))
- }));
-
- let ossified_op_dir = Rc::new(unossified_op_dir);
+ if prec == 0 {
+ return None;
+ }
- match ossified_op_dir.iter().next() {
- Some((OrderedOpDirKey(name, _), (priority, spec))) => {
- let db_ref = DBRef::Op(*priority, *spec, name.clone(),
- ossified_op_dir.clone(),
- SharedOpDesc::new(*priority, *spec));
- let r = addr.as_var().unwrap();
+ let assoc = op_dir_val.shared_op_desc().assoc();
- self.bind(r, Addr::DBRef(db_ref));
- },
- None => {
- self.fail = true;
- return Ok(());
- }
- }
- },
- Addr::DBRef(DBRef::NamedPred(..)) =>
- self.fail = true,
- Addr::DBRef(ref db_ref) =>
- self.get_next_db_ref(&indices, db_ref),
+ Some((OrderedOpDirKey(name, fixity), (prec, assoc)))
+ },
+ ));
+
+ let ossified_op_dir = Rc::new(unossified_op_dir);
+
+ match ossified_op_dir.iter().next() {
+ Some((OrderedOpDirKey(name, _), (priority, spec))) => {
+ let db_ref = DBRef::Op(
+ *priority,
+ *spec,
+ name.clone(),
+ ossified_op_dir.clone(),
+ SharedOpDesc::new(*priority, *spec),
+ );
+ let r = addr.as_var().unwrap();
+
+ self.bind(r, Addr::DBRef(db_ref));
+ }
+ None => {
+ self.fail = true;
+ return Ok(());
+ }
+ }
+ }
+ Addr::DBRef(DBRef::NamedPred(..)) => self.fail = true,
+ Addr::DBRef(ref db_ref) => self.get_next_db_ref(&indices, db_ref),
_ => {
self.fail = true;
}
}
- },
+ }
&SystemClauseType::LookupDBRef => {
let a1 = self[temp_v!(1)].clone();
match self.store(self.deref(a1)) {
- Addr::DBRef(db_ref) =>
- match db_ref {
- DBRef::NamedPred(name, arity, spec) => {
- let a2 = self[temp_v!(2)].clone();
- let a3 = self[temp_v!(3)].clone();
+ Addr::DBRef(db_ref) => match db_ref {
+ DBRef::NamedPred(name, arity, spec) => {
+ let a2 = self[temp_v!(2)].clone();
+ let a3 = self[temp_v!(3)].clone();
- let arity = Integer::from(arity);
+ let arity = Integer::from(arity);
- self.unify(a2, Addr::Con(Constant::Atom(name, spec)));
+ self.unify(a2, Addr::Con(Constant::Atom(name, spec)));
- if !self.fail {
- self.unify(a3, Addr::Con(Constant::Integer(arity)));
- }
- },
- _ => self.fail = true
- },
- _ => self.fail = true
+ if !self.fail {
+ self.unify(a3, Addr::Con(Constant::Integer(arity)));
+ }
+ }
+ _ => self.fail = true,
+ },
+ _ => self.fail = true,
}
- },
+ }
&SystemClauseType::LookupOpDBRef => {
let a1 = self[temp_v!(1)].clone();
match self.store(self.deref(a1)) {
- Addr::DBRef(db_ref) =>
- match db_ref {
- DBRef::Op(priority, spec, name, _, shared_op_desc) => {
- let prec = self[temp_v!(2)].clone();
- let specifier = self[temp_v!(3)].clone();
- let op = self[temp_v!(4)].clone();
-
- let spec = match spec {
- FX => "fx",
- FY => "fy",
- XF => "xf",
- YF => "yf",
- XFX => "xfx",
- XFY => "xfy",
- YFX => "yfx",
- _ => {
- self.fail = true;
- return Ok(());
- }
- };
+ Addr::DBRef(db_ref) => match db_ref {
+ DBRef::Op(priority, spec, name, _, shared_op_desc) => {
+ let prec = self[temp_v!(2)].clone();
+ let specifier = self[temp_v!(3)].clone();
+ let op = self[temp_v!(4)].clone();
+
+ let spec = match spec {
+ FX => "fx",
+ FY => "fy",
+ XF => "xf",
+ YF => "yf",
+ XFX => "xfx",
+ XFY => "xfy",
+ YFX => "yfx",
+ _ => {
+ self.fail = true;
+ return Ok(());
+ }
+ };
- let a2 = Integer::from(priority);
- let a3 = Addr::Con(Constant::Atom(clause_name!(spec), None));
- let a4 = Addr::Con(Constant::Atom(name, Some(shared_op_desc)));
+ let a2 = Integer::from(priority);
+ let a3 = Addr::Con(Constant::Atom(clause_name!(spec), None));
+ let a4 = Addr::Con(Constant::Atom(name, Some(shared_op_desc)));
- self.unify(Addr::Con(Constant::Integer(a2)), prec);
+ self.unify(Addr::Con(Constant::Integer(a2)), prec);
- if !self.fail {
- self.unify(a3, specifier);
- }
+ if !self.fail {
+ self.unify(a3, specifier);
+ }
- if !self.fail {
- self.unify(a4, op);
- }
- },
- _ => self.fail = true
- },
- _ => self.fail = true
+ if !self.fail {
+ self.unify(a4, op);
+ }
+ }
+ _ => self.fail = true,
+ },
+ _ => self.fail = true,
}
- },
+ }
&SystemClauseType::OpDeclaration => {
- let priority = self[temp_v!(1)].clone();
+ let priority = self[temp_v!(1)].clone();
let specifier = self[temp_v!(2)].clone();
let op = self[temp_v!(3)].clone();
let priority = match self.store(self.deref(priority)) {
Addr::Con(Constant::Integer(n)) => n.to_usize().unwrap(),
- _ => unreachable!()
+ _ => unreachable!(),
};
let specifier = match self.store(self.deref(specifier)) {
Addr::Con(Constant::Atom(name, _)) => name,
- _ => unreachable!()
+ _ => unreachable!(),
};
let op = match self.store(self.deref(op)) {
Addr::Con(Constant::Atom(name, _)) => name,
- Addr::Con(Constant::Char(c)) =>
- clause_name!(c.to_string(), indices.atom_tbl),
- _ => unreachable!()
+ Addr::Con(Constant::Char(c)) => clause_name!(c.to_string(), indices.atom_tbl),
+ _ => unreachable!(),
};
let module = op.owning_module();
});
match result {
- Ok(()) => {},
+ Ok(()) => {}
Err(e) => {
// 8.14.3.3 l)
let e = MachineError::session_error(self.heap.h, e);
return Err(permission_error);
}
};
- },
- &SystemClauseType::TruncateIfNoLiftedHeapGrowthDiff =>
- self.truncate_if_no_lifted_heap_diff(|h| Addr::HeapCell(h)),
- &SystemClauseType::TruncateIfNoLiftedHeapGrowth =>
- self.truncate_if_no_lifted_heap_diff(|_| Addr::Con(Constant::EmptyList)),
+ }
+ &SystemClauseType::TruncateIfNoLiftedHeapGrowthDiff => {
+ self.truncate_if_no_lifted_heap_diff(|h| Addr::HeapCell(h))
+ }
+ &SystemClauseType::TruncateIfNoLiftedHeapGrowth => {
+ self.truncate_if_no_lifted_heap_diff(|_| Addr::Con(Constant::EmptyList))
+ }
&SystemClauseType::GetAttributedVariableList => {
let attr_var = self.store(self.deref(self[temp_v!(1)].clone()));
let attr_var_list = match attr_var {
self.bind(Ref::AttrVar(h), attr_var);
h + 1
- },
+ }
_ => {
self.fail = true;
return Ok(());
let list_addr = self[temp_v!(2)].clone();
self.unify(Addr::HeapCell(attr_var_list), list_addr);
- },
+ }
&SystemClauseType::GetAttrVarQueueDelimiter => {
- let addr = self[temp_v!(1)].clone();
+ let addr = self[temp_v!(1)].clone();
let value = Addr::Con(Constant::Usize(self.attr_var_init.attr_var_queue.len()));
self.unify(addr, value);
- },
+ }
&SystemClauseType::GetAttrVarQueueBeyond => {
let addr = self[temp_v!(1)].clone();
let list_addr = self[temp_v!(2)].clone();
self.unify(var_list_addr, list_addr);
- },
- _ => self.fail = true
+ }
+ _ => self.fail = true,
}
- },
+ }
&SystemClauseType::GetLiftedHeapFromOffsetDiff => {
let lh_offset = self[temp_v!(1)].clone();
match self.store(self.deref(lh_offset)) {
- Addr::Con(Constant::Usize(lh_offset)) =>
+ Addr::Con(Constant::Usize(lh_offset)) => {
if lh_offset >= self.lifted_heap.len() {
let solutions = self[temp_v!(2)].clone();
let diff = self[temp_v!(3)].clone();
} else {
let h = self.heap.h;
- for index in lh_offset .. self.lifted_heap.len() {
+ for index in lh_offset..self.lifted_heap.len() {
match self.lifted_heap[index].clone() {
- HeapCellValue::Addr(addr) =>
- self.heap.push(HeapCellValue::Addr(addr + h)),
- value =>
- self.heap.push(value)
+ HeapCellValue::Addr(addr) => {
+ self.heap.push(HeapCellValue::Addr(addr + h))
+ }
+ value => self.heap.push(value),
}
}
let solutions = self[temp_v!(2)].clone();
self.unify(Addr::HeapCell(h), solutions);
- },
- _ => self.fail = true
+ }
+ }
+ _ => self.fail = true,
}
- },
+ }
&SystemClauseType::GetLiftedHeapFromOffset => {
let lh_offset = self[temp_v!(1)].clone();
match self.store(self.deref(lh_offset)) {
- Addr::Con(Constant::Usize(lh_offset)) =>
+ Addr::Con(Constant::Usize(lh_offset)) => {
if lh_offset >= self.lifted_heap.len() {
let solutions = self[temp_v!(2)].clone();
self.unify(solutions, Addr::Con(Constant::EmptyList));
} else {
let h = self.heap.h;
- for index in lh_offset .. self.lifted_heap.len() {
+ for index in lh_offset..self.lifted_heap.len() {
match self.lifted_heap[index].clone() {
- HeapCellValue::Addr(addr) =>
- self.heap.push(HeapCellValue::Addr(addr + h)),
- value =>
- self.heap.push(value)
+ HeapCellValue::Addr(addr) => {
+ self.heap.push(HeapCellValue::Addr(addr + h))
+ }
+ value => self.heap.push(value),
}
}
let solutions = self[temp_v!(2)].clone();
self.unify(Addr::HeapCell(h), solutions);
- },
- _ => self.fail = true
+ }
+ }
+ _ => self.fail = true,
}
- },
+ }
&SystemClauseType::GetDoubleQuotes => {
let a1 = self[temp_v!(1)].clone();
match self.flags.double_quotes {
- DoubleQuotes::Chars =>
- self.unify(a1, Addr::Con(atom!("chars"))),
- DoubleQuotes::Atom =>
- self.unify(a1, Addr::Con(atom!("atom"))),
- DoubleQuotes::Codes =>
- self.unify(a1, Addr::Con(atom!("codes")))
+ DoubleQuotes::Chars => self.unify(a1, Addr::Con(atom!("chars"))),
+ DoubleQuotes::Atom => self.unify(a1, Addr::Con(atom!("atom"))),
+ DoubleQuotes::Codes => self.unify(a1, Addr::Con(atom!("codes"))),
}
- },
+ }
&SystemClauseType::GetSCCCleaner => {
let dest = self[temp_v!(1)].clone();
match cut_policy.downcast_mut::<SCCCutPolicy>().ok() {
- Some(sgc_policy) =>
+ Some(sgc_policy) => {
if let Some((addr, b_cutoff, prev_b)) = sgc_policy.pop_cont_pt() {
if self.b <= b_cutoff + 1 {
self.block = prev_b;
} else {
sgc_policy.push_cont_pt(addr, b_cutoff, prev_b);
}
- },
- None => panic!("expected SCCCutPolicy trait object.")
+ }
+ }
+ None => panic!("expected SCCCutPolicy trait object."),
};
self.fail = true;
- },
- &SystemClauseType::Halt =>
- std::process::exit(0),
+ }
+ &SystemClauseType::Halt => std::process::exit(0),
&SystemClauseType::InstallSCCCleaner => {
let addr = self[temp_v!(1)].clone();
let b = self.b;
*cut_policy = Box::new(SCCCutPolicy::new(r_c_w_h, r_c_wo_h));
}
- match cut_policy.downcast_mut::<SCCCutPolicy>().ok()
- {
+ match cut_policy.downcast_mut::<SCCCutPolicy>().ok() {
Some(cut_policy) => {
self.install_new_block(temp_v!(2));
cut_policy.push_cont_pt(addr, b, prev_block);
- },
- None => panic!("install_cleaner: should have installed \\
- SCCCutPolicy.")
+ }
+ None => panic!(
+ "install_cleaner: should have installed \\
+ SCCCutPolicy."
+ ),
};
- },
- &SystemClauseType::InstallInferenceCounter => { // A1 = B, A2 = L
+ }
+ &SystemClauseType::InstallInferenceCounter => {
+ // A1 = B, A2 = L
let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
let a2 = self.store(self.deref(self[temp_v!(2)].clone()));
}
match (a1, a2.clone()) {
- (Addr::Con(Constant::Usize(bp)),
- Addr::Con(Constant::Integer(n))) =>
+ (Addr::Con(Constant::Usize(bp)), Addr::Con(Constant::Integer(n))) => {
match call_policy.downcast_mut::<CWILCallPolicy>().ok() {
Some(call_policy) => {
let count = call_policy.add_limit(n, bp);
let a3 = self[temp_v!(3)].clone();
self.unify(a3, count);
- },
- None => panic!("install_inference_counter: should have installed \\
- CWILCallPolicy.")
- },
+ }
+ None => panic!(
+ "install_inference_counter: should have installed \\
+ CWILCallPolicy."
+ ),
+ }
+ }
_ => {
- let stub = MachineError::functor_stub(clause_name!("call_with_inference_limit"), 3);
- let type_error = self.error_form(MachineError::type_error(ValidType::Integer, a2),
- stub);
+ let stub = MachineError::functor_stub(
+ clause_name!("call_with_inference_limit"),
+ 3,
+ );
+ let type_error =
+ self.error_form(MachineError::type_error(ValidType::Integer, a2), stub);
self.throw_exception(type_error)
}
};
- },
+ }
&SystemClauseType::ModuleOf => {
let module = self.store(self.deref(self[temp_v!(2)].clone()));
let target = self[temp_v!(1)].clone();
self.unify(target, module);
- },
- Addr::Str(s) =>
- match self.heap[s].clone() {
- HeapCellValue::NamedStr(_, name, ..) => {
- let module = Addr::Con(Constant::Atom(name.owning_module(), None));
- let target = self[temp_v!(1)].clone();
+ }
+ Addr::Str(s) => match self.heap[s].clone() {
+ HeapCellValue::NamedStr(_, name, ..) => {
+ let module = Addr::Con(Constant::Atom(name.owning_module(), None));
+ let target = self[temp_v!(1)].clone();
- self.unify(target, module);
- },
- _ => self.fail = true
- },
- _ => self.fail = true
+ self.unify(target, module);
+ }
+ _ => self.fail = true,
+ },
+ _ => self.fail = true,
};
- },
+ }
&SystemClauseType::NoSuchPredicate => {
let head = self[temp_v!(1)].clone();
self.fail = match self.store(self.deref(head)) {
- Addr::Str(s) =>
- match self.heap[s].clone() {
- HeapCellValue::NamedStr(arity, name, op_spec) => {
- let module = name.owning_module();
- indices.predicate_exists(name, module, arity, op_spec)
- },
- _ => unreachable!()
- },
+ Addr::Str(s) => match self.heap[s].clone() {
+ HeapCellValue::NamedStr(arity, name, op_spec) => {
+ let module = name.owning_module();
+ indices.predicate_exists(name, module, arity, op_spec)
+ }
+ _ => unreachable!(),
+ },
Addr::Con(Constant::Atom(name, spec)) => {
let module = name.owning_module();
let spec = fetch_atom_op_spec(name.clone(), spec, &indices.op_dir);
indices.predicate_exists(name, module, 0, spec)
- },
+ }
head => {
let err = MachineError::type_error(ValidType::Callable, head);
let stub = MachineError::functor_stub(clause_name!("clause"), 2);
return Err(self.error_form(err, stub));
}
};
- },
+ }
&SystemClauseType::RedoAttrVarBindings => {
let bindings = mem::replace(&mut self.attr_var_init.bindings, vec![]);
for (h, addr) in bindings {
self.heap[h] = HeapCellValue::Addr(addr);
}
- },
+ }
&SystemClauseType::ResetGlobalVarAtKey => {
let key = self[temp_v!(1)].clone();
let key = match self.store(self.deref(key)) {
Addr::Con(Constant::Atom(atom, _)) => atom,
- _ => unreachable!()
+ _ => unreachable!(),
};
indices.global_variables.remove(&key);
- },
+ }
&SystemClauseType::RemoveCallPolicyCheck => {
- let restore_default =
- match call_policy.downcast_mut::<CWILCallPolicy>().ok() {
- Some(call_policy) => {
- let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
+ let restore_default = match call_policy.downcast_mut::<CWILCallPolicy>().ok() {
+ Some(call_policy) => {
+ let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
- if let Addr::Con(Constant::Usize(bp)) = a1 {
- if call_policy.is_empty() && bp == self.b {
- Some(call_policy.into_inner())
- } else {
- None
- }
+ if let Addr::Con(Constant::Usize(bp)) = a1 {
+ if call_policy.is_empty() && bp == self.b {
+ Some(call_policy.into_inner())
} else {
- panic!("remove_call_policy_check: expected Usize in A1.");
+ None
}
- },
- None => panic!("remove_call_policy_check: requires \\
- CWILCallPolicy.")
- };
+ } else {
+ panic!("remove_call_policy_check: expected Usize in A1.");
+ }
+ }
+ None => panic!(
+ "remove_call_policy_check: requires \\
+ CWILCallPolicy."
+ ),
+ };
if let Some(new_policy) = restore_default {
*call_policy = new_policy;
}
- },
- &SystemClauseType::RemoveInferenceCounter =>
+ }
+ &SystemClauseType::RemoveInferenceCounter => {
match call_policy.downcast_mut::<CWILCallPolicy>().ok() {
Some(call_policy) => {
let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
} else {
panic!("remove_inference_counter: expected Usize in A1.");
}
- },
- None => panic!("remove_inference_counter: requires \\
- CWILCallPolicy.")
- },
- &SystemClauseType::REPL(repl_code_ptr) =>
- return self.repl_redirect(repl_code_ptr),
+ }
+ None => panic!(
+ "remove_inference_counter: requires \\
+ CWILCallPolicy."
+ ),
+ }
+ }
+ &SystemClauseType::REPL(repl_code_ptr) => return self.repl_redirect(repl_code_ptr),
&SystemClauseType::ModuleRetractClause => {
let p = self.cp;
let trans_type = DynamicTransactionType::ModuleRetract;
self.p = CodePtr::DynamicTransaction(trans_type, p);
return Ok(());
- },
+ }
&SystemClauseType::RetractClause => {
let p = self.cp;
let trans_type = DynamicTransactionType::Retract;
self.p = CodePtr::DynamicTransaction(trans_type, p);
return Ok(());
- },
+ }
&SystemClauseType::ReturnFromAttributeGoals => {
self.deallocate();
self.p = CodePtr::Local(LocalCodePtr::TopLevel(0, 0));
return Ok(());
- },
+ }
&SystemClauseType::ReturnFromVerifyAttr => {
let e = self.e;
let frame_len = self.and_stack[e].len();
- for i in 1 .. frame_len - 1 {
+ for i in 1..frame_len - 1 {
self[RegType::Temp(i)] = self.and_stack[e][i].clone();
}
self.deallocate();
return Ok(());
- },
+ }
&SystemClauseType::RestoreCutPolicy => {
let restore_default =
if let Ok(cut_policy) = cut_policy.downcast_ref::<SCCCutPolicy>() {
if restore_default {
*cut_policy = Box::new(DefaultCutPolicy {});
}
+ }
+ &SystemClauseType::SetCutPoint(r) => {
+ if cut_policy.cut(self, r) {
+ return Ok(());
+ }
+ }
+ &SystemClauseType::SetCutPointByDefault(r) => deref_cut(self, r),
+ &SystemClauseType::SetDoubleQuotes => match self[temp_v!(1)].clone() {
+ Addr::Con(Constant::Atom(ref atom, _)) if atom.as_str() == "chars" => {
+ self.flags.double_quotes = DoubleQuotes::Chars
+ }
+ Addr::Con(Constant::Atom(ref atom, _)) if atom.as_str() == "atom" => {
+ self.flags.double_quotes = DoubleQuotes::Atom
+ }
+ Addr::Con(Constant::Atom(ref atom, _)) if atom.as_str() == "codes" => {
+ self.flags.double_quotes = DoubleQuotes::Codes
+ }
+ _ => self.fail = true,
},
- &SystemClauseType::SetCutPoint(r) => if cut_policy.cut(self, r) {
- return Ok(());
- },
- &SystemClauseType::SetCutPointByDefault(r) =>
- deref_cut(self, r),
- &SystemClauseType::SetDoubleQuotes =>
- match self[temp_v!(1)].clone() {
- Addr::Con(Constant::Atom(ref atom, _)) if atom.as_str() == "chars" =>
- self.flags.double_quotes = DoubleQuotes::Chars,
- Addr::Con(Constant::Atom(ref atom, _)) if atom.as_str() == "atom" =>
- self.flags.double_quotes = DoubleQuotes::Atom,
- Addr::Con(Constant::Atom(ref atom, _)) if atom.as_str() == "codes" =>
- self.flags.double_quotes = DoubleQuotes::Codes,
- _ => self.fail = true
- },
&SystemClauseType::InferenceLevel => {
let a1 = self[temp_v!(1)].clone();
let a2 = self.store(self.deref(self[temp_v!(2)].clone()));
match a2 {
- Addr::Con(Constant::Usize(bp)) =>
+ Addr::Con(Constant::Usize(bp)) => {
if self.b <= bp + 1 {
let a2 = Addr::Con(atom!("!"));
self.unify(a1, a2);
} else {
let a2 = Addr::Con(atom!("true"));
self.unify(a1, a2);
- },
- _ => self.fail = true
+ }
+ }
+ _ => self.fail = true,
};
- },
+ }
&SystemClauseType::CleanUpBlock => {
let nb = self.store(self.deref(self[temp_v!(1)].clone()));
self.b = self.or_stack[nb - 1].b;
self.or_stack.truncate(self.b);
}
- },
- _ => self.fail = true
+ }
+ _ => self.fail = true,
};
- },
+ }
&SystemClauseType::EraseBall => self.ball.reset(),
&SystemClauseType::Fail => self.fail = true,
&SystemClauseType::GetBall => {
match addr.as_var() {
Some(r) => self.bind(r, ball),
- _ => self.fail = true
+ _ => self.fail = true,
};
- },
+ }
&SystemClauseType::GetCurrentBlock => {
let c = Constant::Usize(self.block);
let addr = self[temp_v!(1)].clone();
self.write_constant_to_var(addr, c);
- },
+ }
&SystemClauseType::GetBValue => {
let a1 = self[temp_v!(1)].clone();
let a2 = Addr::Con(Constant::Usize(self.b));
self.unify(a1, a2);
- },
+ }
&SystemClauseType::GetClause => {
let head = self[temp_v!(1)].clone();
let subsection = match self.store(self.deref(head)) {
- Addr::Str(s) =>
- match self.heap[s].clone() {
- HeapCellValue::NamedStr(arity, name, ..) =>
- indices.get_clause_subsection(name.owning_module(), name, arity),
- _ => unreachable!()
- },
- Addr::Con(Constant::Atom(name, _)) =>
- indices.get_clause_subsection(name.owning_module(), name, 0),
- _ => unreachable!()
+ Addr::Str(s) => match self.heap[s].clone() {
+ HeapCellValue::NamedStr(arity, name, ..) => {
+ indices.get_clause_subsection(name.owning_module(), name, arity)
+ }
+ _ => unreachable!(),
+ },
+ Addr::Con(Constant::Atom(name, _)) => {
+ indices.get_clause_subsection(name.owning_module(), name, 0)
+ }
+ _ => unreachable!(),
};
match subsection {
Some(dynamic_predicate_info) => {
self.execute_at_index(2, dynamic_predicate_info.clauses_subsection_p);
return Ok(());
- },
- _ => unreachable!()
+ }
+ _ => unreachable!(),
}
- },
+ }
&SystemClauseType::GetCutPoint => {
let a1 = self[temp_v!(1)].clone();
let a2 = Addr::Con(Constant::Usize(self.b0));
self.unify(a1, a2);
- },
+ }
&SystemClauseType::InstallNewBlock => {
self.install_new_block(temp_v!(1));
- },
+ }
&SystemClauseType::ReadTerm => {
- match self.read(current_input_stream, indices.atom_tbl.clone(), &indices.op_dir) {
+ match self.read(
+ current_input_stream,
+ indices.atom_tbl.clone(),
+ &indices.op_dir,
+ ) {
Ok(term_write_result) => {
let a1 = self[temp_v!(1)].clone();
self.unify(Addr::HeapCell(term_write_result.heap_loc), a1);
let h = self.heap.h;
let spec = fetch_atom_op_spec(clause_name!("="), None, &indices.op_dir);
- self.heap.push(HeapCellValue::NamedStr(2, clause_name!("="), spec));
+ self.heap
+ .push(HeapCellValue::NamedStr(2, clause_name!("="), spec));
self.heap.push(HeapCellValue::Addr(Addr::Con(var_atom)));
self.heap.push(HeapCellValue::Addr(binding));
}
let a2 = self[temp_v!(2)].clone();
- let list_offset = Addr::HeapCell(self.heap.to_list(list_of_var_eqs.into_iter()));
+ let list_offset =
+ Addr::HeapCell(self.heap.to_list(list_of_var_eqs.into_iter()));
self.unify(list_offset, a2);
- },
+ }
Err(err) => {
if let ParserError::UnexpectedEOF = err {
std::process::exit(0);
return Err(self.error_form(syntax_error, stub));
}
}
- },
+ }
&SystemClauseType::ResetBlock => {
let addr = self.deref(self[temp_v!(1)].clone());
self.reset_block(addr);
- },
+ }
&SystemClauseType::SetBall => self.set_ball(),
- &SystemClauseType::SkipMaxList => if let Err(err) = self.skip_max_list() {
- return Err(err);
- },
+ &SystemClauseType::SkipMaxList => {
+ if let Err(err) = self.skip_max_list() {
+ return Err(err);
+ }
+ }
&SystemClauseType::StoreGlobalVar => {
let key = self[temp_v!(1)].clone();
let key = match self.store(self.deref(key)) {
Addr::Con(Constant::Atom(atom, _)) => atom,
- _ => unreachable!()
+ _ => unreachable!(),
};
let value = self[temp_v!(2)].clone();
indices.global_variables.insert(key, value);
}
- &SystemClauseType::Succeed => {},
+ &SystemClauseType::Succeed => {}
&SystemClauseType::TermVariables => {
let a1 = self[temp_v!(1)].clone();
let mut seen_vars = IndexSet::new();
for item in self.acyclic_pre_order_iter(a1) {
match item {
- HeapCellValue::Addr(addr) =>
+ HeapCellValue::Addr(addr) => {
if addr.is_ref() {
seen_vars.insert(addr);
- },
+ }
+ }
_ => {}
}
}
let a2 = self[temp_v!(2)].clone();
self.unify(a2, outcome);
- },
- &SystemClauseType::TruncateLiftedHeapTo =>
+ }
+ &SystemClauseType::TruncateLiftedHeapTo => {
match self.store(self.deref(self[temp_v!(1)].clone())) {
- Addr::Con(Constant::Usize(lh_offset)) =>
- self.lifted_heap.truncate(lh_offset),
- _ => self.fail = true
- },
+ Addr::Con(Constant::Usize(lh_offset)) => self.lifted_heap.truncate(lh_offset),
+ _ => self.fail = true,
+ }
+ }
&SystemClauseType::UnifyWithOccursCheck => {
let a1 = self[temp_v!(1)].clone();
let a2 = self[temp_v!(2)].clone();
self.unify_with_occurs_check(a1, a2);
- },
- &SystemClauseType::UnwindStack =>
- self.unwind_stack(),
- &SystemClauseType::Variant =>
- self.fail = self.structural_eq_test(),
+ }
+ &SystemClauseType::UnwindStack => self.unwind_stack(),
+ &SystemClauseType::Variant => self.fail = self.structural_eq_test(),
&SystemClauseType::WAMInstructions => {
- let name = self[temp_v!(1)].clone();
+ let name = self[temp_v!(1)].clone();
let arity = self[temp_v!(2)].clone();
let name = match self.store(self.deref(name)) {
Addr::Con(Constant::Atom(name, _)) => name,
- _ => unreachable!()
+ _ => unreachable!(),
};
let arity = match self.store(self.deref(arity)) {
Addr::Con(Constant::Integer(n)) => n,
- _ => unreachable!()
+ _ => unreachable!(),
};
- let first_idx = match indices.code_dir.get(&(name.clone(), arity.to_usize().unwrap()))
+ let first_idx = match indices
+ .code_dir
+ .get(&(name.clone(), arity.to_usize().unwrap()))
{
- Some(ref idx) =>
+ Some(ref idx) => {
if let Some(idx) = idx.local() {
idx
} else {
let stub = MachineError::functor_stub(name.clone(), arity);
let h = self.heap.h;
- let err = MachineError::existence_error(h, ExistenceError::Procedure(name, arity));
+ let err = MachineError::existence_error(
+ h,
+ ExistenceError::Procedure(name, arity),
+ );
let err = self.error_form(err, stub);
self.throw_exception(err);
return Ok(());
- },
+ }
+ }
None => {
let arity = arity.to_usize().unwrap();
let stub = MachineError::functor_stub(name.clone(), arity);
let h = self.heap.h;
- let err = MachineError::existence_error(h, ExistenceError::Procedure(name, arity));
+ let err = MachineError::existence_error(
+ h,
+ ExistenceError::Procedure(name, arity),
+ );
let err = self.error_form(err, stub);
self.throw_exception(err);
};
let functors = self.create_instruction_functors(&code_repo.code, first_idx);
- let listing = Addr::HeapCell(self.heap.to_list(functors.into_iter()));
+ let listing = Addr::HeapCell(self.heap.to_list(functors.into_iter()));
let listing_var = self[temp_v!(3)].clone();
self.unify(listing, listing_var);
- },
+ }
&SystemClauseType::WriteTerm => {
let addr = self[temp_v!(1)].clone();
for addr in addrs {
match addr {
- Addr::Str(s) =>
- match &self.heap[s] {
- &HeapCellValue::NamedStr(2, ref name, _)
- if name.as_str() == "=" => {
- let atom = self.heap[s+1].as_addr(s+1);
- let var = self.heap[s+2].as_addr(s+2);
-
- let atom = match self.store(self.deref(atom)) {
- Addr::Con(Constant::Atom(atom, _)) => atom.to_string(),
- Addr::Con(Constant::Char(c)) => c.to_string(),
- _ => unreachable!()
- };
-
- let var = self.store(self.deref(var));
-
- if var_names.contains_key(&var) {
- continue;
- }
-
- var_names.insert(var, atom);
- },
- _ => unreachable!()
- },
- _ => unreachable!()
+ Addr::Str(s) => match &self.heap[s] {
+ &HeapCellValue::NamedStr(2, ref name, _)
+ if name.as_str() == "=" =>
+ {
+ let atom = self.heap[s + 1].as_addr(s + 1);
+ let var = self.heap[s + 2].as_addr(s + 2);
+
+ let atom = match self.store(self.deref(atom)) {
+ Addr::Con(Constant::Atom(atom, _)) => atom.to_string(),
+ Addr::Con(Constant::Char(c)) => c.to_string(),
+ _ => unreachable!(),
+ };
+
+ let var = self.store(self.deref(var));
+
+ if var_names.contains_key(&var) {
+ continue;
+ }
+
+ var_names.insert(var, atom);
+ }
+ _ => unreachable!(),
+ },
+ _ => unreachable!(),
}
}
printer.var_names = var_names;
- },
- Err(err) =>
- return Err(err)
+ }
+ Err(err) => return Err(err),
}
- let output = printer.print(addr);
+ let output = printer.print(addr);
print!("{}", output.result());
stdout().flush().unwrap();
}
use prolog_parser::ast::*;
use prolog_parser::parser::*;
-use prolog::machine::*;
use prolog::machine::machine_indices::HeapCellValue;
-use prolog::rug::Integer;
+use prolog::machine::*;
use prolog::rug::ops::Pow;
+use prolog::rug::Integer;
use std::cell::Cell;
use std::collections::VecDeque;
use std::iter::Rev;
use std::vec::IntoIter;
-fn unfold_by_str_once(term: &mut Term, s: &str) -> Option<(Term, Term)>
-{
+fn unfold_by_str_once(term: &mut Term, s: &str) -> Option<(Term, Term)> {
if let &mut Term::Clause(_, ref name, ref mut subterms, _) = term {
if name.as_str() == s && subterms.len() == 2 {
let snd = *subterms.pop().unwrap();
None
}
-pub fn unfold_by_str(mut term: Term, s: &str) -> Vec<Term>
-{
+pub fn unfold_by_str(mut term: Term, s: &str) -> Vec<Term> {
let mut terms = vec![];
while let Some((fst, snd)) = unfold_by_str_once(&mut term, s) {
}
pub fn fold_by_str<I>(terms: I, mut term: Term, sym: ClauseName) -> Term
- where I: DoubleEndedIterator<Item=Term>
+where
+ I: DoubleEndedIterator<Item = Term>,
{
for prec in terms.rev() {
- term = Term::Clause(Cell::default(), sym.clone(),
- vec![Box::new(prec), Box::new(term)],
- None);
+ term = Term::Clause(
+ Cell::default(),
+ sym.clone(),
+ vec![Box::new(prec), Box::new(term)],
+ None,
+ );
}
term
}
-fn extract_from_list(head: Box<Term>, tail: Box<Term>)
- -> Result<Rev<IntoIter<Term>>, ParserError>
-{
+fn extract_from_list(head: Box<Term>, tail: Box<Term>) -> Result<Rev<IntoIter<Term>>, ParserError> {
let mut terms = vec![*head];
- let mut tail = *tail;
+ let mut tail = *tail;
while let Term::Cons(_, head, next_tail) = tail {
terms.push(*head);
pub struct ExpansionAdditionResult {
term_expansion_additions: (Predicate, VecDeque<TopLevel>),
- goal_expansion_additions: (Predicate, VecDeque<TopLevel>)
+ goal_expansion_additions: (Predicate, VecDeque<TopLevel>),
}
impl ExpansionAdditionResult {
pub fn take_term_expansions(&mut self) -> (Predicate, VecDeque<TopLevel>) {
- let tes = mem::replace(&mut self.term_expansion_additions.0, Predicate::new());
+ let tes = mem::replace(&mut self.term_expansion_additions.0, Predicate::new());
let teqs = mem::replace(&mut self.term_expansion_additions.1, VecDeque::from(vec![]));
(tes, teqs)
}
pub fn take_goal_expansions(&mut self) -> (Predicate, VecDeque<TopLevel>) {
- let ges = mem::replace(&mut self.goal_expansion_additions.0, Predicate::new());
+ let ges = mem::replace(&mut self.goal_expansion_additions.0, Predicate::new());
let geqs = mem::replace(&mut self.goal_expansion_additions.1, VecDeque::from(vec![]));
(ges, geqs)
}
impl<'a, R: Read> TermStream<'a, R> {
- pub fn new(src: &'a mut ParsingStream<R>, atom_tbl: TabledData<Atom>, flags: MachineFlags, wam: &'a mut Machine)
- -> Self
- {
+ pub fn new(
+ src: &'a mut ParsingStream<R>,
+ atom_tbl: TabledData<Atom>,
+ flags: MachineFlags,
+ wam: &'a mut Machine,
+ ) -> Self {
TermStream {
stack: Vec::new(),
- term_expansion_lens: wam.code_repo.term_dir_entry_len((clause_name!("term_expansion"), 2)),
- goal_expansion_lens: wam.code_repo.term_dir_entry_len((clause_name!("goal_expansion"), 2)),
+ term_expansion_lens: wam
+ .code_repo
+ .term_dir_entry_len((clause_name!("term_expansion"), 2)),
+ goal_expansion_lens: wam
+ .code_repo
+ .term_dir_entry_len((clause_name!("goal_expansion"), 2)),
wam,
parser: Parser::new(src, atom_tbl, flags),
in_module: false,
- flags
+ flags,
}
}
CompileTimeHook::UserTermExpansion => {
self.term_expansion_lens.0 += len;
self.term_expansion_lens.1 += queue_len;
- },
+ }
CompileTimeHook::UserGoalExpansion => {
self.goal_expansion_lens.0 += len;
self.goal_expansion_lens.1 += queue_len;
- },
+ }
_ => {}
}
}
Ok(self.stack.is_empty() && self.parser.eof()?)
}
- pub fn rollback_expansion_code(&mut self) -> Result<ExpansionAdditionResult, ParserError>
- {
+ pub fn rollback_expansion_code(&mut self) -> Result<ExpansionAdditionResult, ParserError> {
let te_len = self.term_expansion_lens.0;
let te_queue_len = self.term_expansion_lens.1;
let ge_len = self.goal_expansion_lens.0;
let ge_queue_len = self.goal_expansion_lens.1;
- let term_expansion_additions =
- self.wam.code_repo.truncate_terms((clause_name!("term_expansion"), 2),
- te_len, te_queue_len);
- let goal_expansion_additions =
- self.wam.code_repo.truncate_terms((clause_name!("goal_expansion"), 2),
- ge_len, ge_queue_len);
-
- self.wam.code_repo.compile_hook(CompileTimeHook::TermExpansion, self.flags)?;
- self.wam.code_repo.compile_hook(CompileTimeHook::GoalExpansion, self.flags)?;
+ let term_expansion_additions = self.wam.code_repo.truncate_terms(
+ (clause_name!("term_expansion"), 2),
+ te_len,
+ te_queue_len,
+ );
+ let goal_expansion_additions = self.wam.code_repo.truncate_terms(
+ (clause_name!("goal_expansion"), 2),
+ ge_len,
+ ge_queue_len,
+ );
+
+ self.wam
+ .code_repo
+ .compile_hook(CompileTimeHook::TermExpansion, self.flags)?;
+ self.wam
+ .code_repo
+ .compile_hook(CompileTimeHook::GoalExpansion, self.flags)?;
Ok(ExpansionAdditionResult {
term_expansion_additions,
- goal_expansion_additions
+ goal_expansion_additions,
})
}
Term::Cons(_, head, tail) => {
let iter = extract_from_list(head, tail)?;
Ok(self.stack.extend(iter))
- },
- Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) =>
- Ok(self.stack.push(term)),
- _ =>
- Err(ParserError::ExpectedTopLevelTerm)
+ }
+ Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) => Ok(self.stack.push(term)),
+ _ => Err(ParserError::ExpectedTopLevelTerm),
}
}
- fn parse_expansion_output(&self, term_string: &str, op_dir: &OpDir) -> Result<Term, ParserError>
- {
+ fn parse_expansion_output(
+ &self,
+ term_string: &str,
+ op_dir: &OpDir,
+ ) -> Result<Term, ParserError> {
let mut stream = parsing_stream(term_string.trim().as_bytes());
let mut parser = Parser::new(&mut stream, self.parser.get_atom_tbl(), self.flags);
- parser.read_term(composite_op!(self.in_module, &self.wam.indices.op_dir, op_dir))
+ parser.read_term(composite_op!(
+ self.in_module,
+ &self.wam.indices.op_dir,
+ op_dir
+ ))
}
- pub fn read_term(&mut self, op_dir: &OpDir) -> Result<Term, ParserError>
- {
+ pub fn read_term(&mut self, op_dir: &OpDir) -> Result<Term, ParserError> {
let mut machine_st = MachineState::new();
loop {
while let Some(term) = self.stack.pop() {
- match machine_st.try_expand_term(self.wam, &term, CompileTimeHook::TermExpansion)
- {
+ match machine_st.try_expand_term(self.wam, &term, CompileTimeHook::TermExpansion) {
Some(term_string) => {
let term = self.parse_expansion_output(term_string.as_str(), op_dir)?;
self.enqueue_term(term)?
- },
+ }
None => {
let term = self.run_goal_expanders(&mut machine_st, op_dir, term)?;
return Ok(term);
}
self.parser.reset();
- let term = self.parser.read_term(composite_op!(self.in_module, &self.wam.indices.op_dir,
- op_dir))?;
+ let term = self.parser.read_term(composite_op!(
+ self.in_module,
+ &self.wam.indices.op_dir,
+ op_dir
+ ))?;
self.stack.push(term);
}
}
- pub(crate)
- fn run_goal_expanders(&mut self, machine_st: &mut MachineState, op_dir: &OpDir, term: Term)
- -> Result<Term, ParserError>
- {
+ pub(crate) fn run_goal_expanders(
+ &mut self,
+ machine_st: &mut MachineState,
+ op_dir: &OpDir,
+ term: Term,
+ ) -> Result<Term, ParserError> {
match term {
Term::Clause(cell, name, mut terms, arity) => {
let mut new_terms = {
(":-", 2) => {
let comma_term = *terms.pop().unwrap();
unfold_by_str(comma_term, ",")
- },
+ }
("?-", 1) => unfold_by_str(*terms.pop().unwrap(), ","),
- _ => return Ok(Term::Clause(cell, name, terms, arity))
+ _ => return Ok(Term::Clause(cell, name, terms, arity)),
};
self.expand_goals(machine_st, op_dir, VecDeque::from(old_terms))?
};
let initial_term = new_terms.pop().unwrap();
- terms.push(Box::new(fold_by_str(new_terms.into_iter(), initial_term,
- clause_name!(","))));
+ terms.push(Box::new(fold_by_str(
+ new_terms.into_iter(),
+ initial_term,
+ clause_name!(","),
+ )));
Ok(Term::Clause(cell, name, terms, arity))
- },
- _ =>
- Ok(term)
+ }
+ _ => Ok(term),
}
}
- fn expand_goals(&mut self, machine_st: &mut MachineState, op_dir: &OpDir, mut terms: VecDeque<Term>)
- -> Result<Vec<Term>, ParserError>
- {
+ fn expand_goals(
+ &mut self,
+ machine_st: &mut MachineState,
+ op_dir: &OpDir,
+ mut terms: VecDeque<Term>,
+ ) -> Result<Vec<Term>, ParserError> {
let mut results = vec![];
while let Some(term) = terms.pop_front() {
- match machine_st.try_expand_term(self.wam, &term, CompileTimeHook::GoalExpansion)
- {
+ match machine_st.try_expand_term(self.wam, &term, CompileTimeHook::GoalExpansion) {
Some(term_string) => {
println!("trying to goal expand {}", term_string);
let term = self.parse_expansion_output(term_string.as_str(), op_dir)?;
match term {
- Term::Cons(_, head, tail) =>
+ Term::Cons(_, head, tail) => {
for term in extract_from_list(head, tail)? {
terms.push_front(term);
- },
- term => terms.push_front(term)
+ }
+ }
+ term => terms.push_front(term),
};
- },
- None => results.push(term)
+ }
+ None => results.push(term),
}
}
}
impl MachineState {
- pub(super)
- fn print_with_locs(&self, addr: Addr, op_dir: &OpDir) -> PrinterOutputter
- {
+ pub(super) fn print_with_locs(&self, addr: Addr, op_dir: &OpDir) -> PrinterOutputter {
let output = PrinterOutputter::new();
let mut printer = HCPrinter::from_heap_locs(&self, op_dir, output);
let mut max_var_length = 0;
output
}
- fn try_expand_term(&mut self, wam: &mut Machine, term: &Term, hook: CompileTimeHook)
- -> Option<String>
- {
+ fn try_expand_term(
+ &mut self,
+ wam: &mut Machine,
+ term: &Term,
+ hook: CompileTimeHook,
+ ) -> Option<String> {
let term_write_result = write_term_to_heap(term, self);
let h = self.heap.h;
let code = vec![call_clause!(ClauseType::Hook(hook), 2, 0, true)];
wam.code_repo.cached_query = code;
- self.query_stepper(&mut wam.indices, &mut wam.policies, &mut wam.code_repo, &mut readline::input_stream());
+ self.query_stepper(
+ &mut wam.indices,
+ &mut wam.policies,
+ &mut wam.code_repo,
+ &mut readline::input_stream(),
+ );
if self.fail {
self.reset();
use prolog::forms::*;
use prolog::iterators::*;
-use prolog::machine::*;
use prolog::machine::machine_errors::*;
use prolog::machine::machine_indices::*;
use prolog::machine::machine_state::MachineState;
use prolog::machine::term_expansion::*;
+use prolog::machine::*;
use indexmap::{IndexMap, IndexSet};
use std::borrow::BorrowMut;
-use std::collections::VecDeque;
use std::cell::Cell;
+use std::collections::VecDeque;
use std::io::Read;
use std::mem;
use std::rc::Rc;
struct CompositeIndices<'a, 'b> {
local: &'a mut IndexStore,
- static_code_dir: Option<&'b CodeDir>
+ static_code_dir: Option<&'b CodeDir>,
}
macro_rules! composite_indices {
- ($in_module: expr, $local: expr, $static_code_dir: expr) => (
- CompositeIndices { local: $local,
- static_code_dir: if $in_module {
- None
- } else {
- Some($static_code_dir)
- }}
- );
- ($local: expr) => (
- CompositeIndices { local: $local, static_code_dir: None }
- )
+ ($in_module: expr, $local: expr, $static_code_dir: expr) => {
+ CompositeIndices {
+ local: $local,
+ static_code_dir: if $in_module {
+ None
+ } else {
+ Some($static_code_dir)
+ },
+ }
+ };
+ ($local: expr) => {
+ CompositeIndices {
+ local: $local,
+ static_code_dir: None,
+ }
+ };
}
-impl<'a, 'b> CompositeIndices<'a, 'b>
-{
+impl<'a, 'b> CompositeIndices<'a, 'b> {
fn get_code_index(&mut self, name: ClauseName, arity: usize) -> CodeIndex {
- let idx_opt = self.local.code_dir.get(&(name.clone(), arity))
- .or_else(|| {
- match &self.static_code_dir {
- &Some(ref code_dir) => code_dir.get(&(name.clone(), arity)),
- _ => None
- }
- }).cloned();
+ let idx_opt = self
+ .local
+ .code_dir
+ .get(&(name.clone(), arity))
+ .or_else(|| match &self.static_code_dir {
+ &Some(ref code_dir) => code_dir.get(&(name.clone(), arity)),
+ _ => None,
+ })
+ .cloned();
if let Some(idx) = idx_opt {
self.local.code_dir.insert((name, arity), idx.clone());
}
}
- fn get_clause_type(&mut self, name: ClauseName, arity: usize, spec: Option<SharedOpDesc>) -> ClauseType
- {
+ fn get_clause_type(
+ &mut self,
+ name: ClauseName,
+ arity: usize,
+ spec: Option<SharedOpDesc>,
+ ) -> ClauseType {
match ClauseType::from(name, arity, spec) {
ClauseType::Named(name, arity, _) => {
let idx = self.get_code_index(name.clone(), arity);
ClauseType::Named(name, arity, idx.clone())
- },
+ }
ClauseType::Op(name, spec, _) => {
let idx = self.get_code_index(name.clone(), arity);
ClauseType::Op(name, spec, idx.clone())
- },
- ct => ct
+ }
+ ct => ct,
}
}
}
-fn as_compile_time_hook(name: &str, arity: usize, terms: &Vec<Box<Term>>) -> Option<CompileTimeHook>
-{
+fn as_compile_time_hook(
+ name: &str,
+ arity: usize,
+ terms: &Vec<Box<Term>>,
+) -> Option<CompileTimeHook> {
match (name, arity) {
("term_expansion", 2) => Some(CompileTimeHook::TermExpansion),
("goal_expansion", 2) => Some(CompileTimeHook::GoalExpansion),
if name.as_str() == "user" {
if let &Term::Clause(_, ref name, ref terms, _) = &terms[1].as_ref() {
return match name.as_str() {
- "term_expansion" if terms.len() == 2 =>
- Some(CompileTimeHook::UserTermExpansion),
- "goal_expansion" if terms.len() == 2 =>
- Some(CompileTimeHook::UserGoalExpansion),
- _ => None
- }
+ "term_expansion" if terms.len() == 2 => {
+ Some(CompileTimeHook::UserTermExpansion)
+ }
+ "goal_expansion" if terms.len() == 2 => {
+ Some(CompileTimeHook::UserGoalExpansion)
+ }
+ _ => None,
+ };
}
}
}
None
- },
- _ => None
+ }
+ _ => None,
}
}
type CompileTimeHookCompileInfo = (CompileTimeHook, PredicateClause, VecDeque<TopLevel>);
-pub fn to_op_decl(prec: usize, spec: &str, name: ClauseName) -> Result<OpDecl, ParserError>
-{
+pub fn to_op_decl(prec: usize, spec: &str, name: ClauseName) -> Result<OpDecl, ParserError> {
match spec {
"xfx" => Ok(OpDecl(prec, XFX, name)),
"xfy" => Ok(OpDecl(prec, XFY, name)),
"yfx" => Ok(OpDecl(prec, YFX, name)),
- "fx" => Ok(OpDecl(prec, FX, name)),
- "fy" => Ok(OpDecl(prec, FY, name)),
- "xf" => Ok(OpDecl(prec, XF, name)),
- "yf" => Ok(OpDecl(prec, YF, name)),
- _ => Err(ParserError::InconsistentEntry)
+ "fx" => Ok(OpDecl(prec, FX, name)),
+ "fy" => Ok(OpDecl(prec, FY, name)),
+ "xf" => Ok(OpDecl(prec, XF, name)),
+ "yf" => Ok(OpDecl(prec, YF, name)),
+ _ => Err(ParserError::InconsistentEntry),
}
}
-fn setup_op_decl(mut terms: Vec<Box<Term>>) -> Result<OpDecl, ParserError>
-{
+fn setup_op_decl(mut terms: Vec<Box<Term>>) -> Result<OpDecl, ParserError> {
let name = match *terms.pop().unwrap() {
Term::Constant(_, Constant::Atom(name, _)) => name,
- _ => return Err(ParserError::InconsistentEntry)
+ _ => return Err(ParserError::InconsistentEntry),
};
let spec = match *terms.pop().unwrap() {
Term::Constant(_, Constant::Atom(name, _)) => name,
- _ => return Err(ParserError::InconsistentEntry)
+ _ => return Err(ParserError::InconsistentEntry),
};
let prec = match *terms.pop().unwrap() {
- Term::Constant(_, Constant::Integer(bi)) =>
- match bi.to_usize() {
- Some(n) if n <= 1200 => n,
- _ => return Err(ParserError::InconsistentEntry)
- },
- _ => return Err(ParserError::InconsistentEntry)
+ Term::Constant(_, Constant::Integer(bi)) => match bi.to_usize() {
+ Some(n) if n <= 1200 => n,
+ _ => return Err(ParserError::InconsistentEntry),
+ },
+ _ => return Err(ParserError::InconsistentEntry),
};
to_op_decl(prec, spec.as_str(), name)
}
-fn setup_predicate_indicator(mut term: Term) -> Result<PredicateKey, ParserError>
-{
+fn setup_predicate_indicator(mut term: Term) -> Result<PredicateKey, ParserError> {
match term {
Term::Clause(_, ref name, ref mut terms, Some(_))
- if name.as_str() == "/" && terms.len() == 2 => {
- let arity = *terms.pop().unwrap();
- let name = *terms.pop().unwrap();
-
- let arity = arity.to_constant().and_then(|c| c.to_integer())
- .and_then(|n| n.to_usize())
- .ok_or(ParserError::InvalidModuleExport)?;
-
- let name = name.to_constant().and_then(|c| c.to_atom())
- .ok_or(ParserError::InvalidModuleExport)?;
-
- Ok((name, arity))
- },
- _ => Err(ParserError::InvalidModuleExport)
+ if name.as_str() == "/" && terms.len() == 2 =>
+ {
+ let arity = *terms.pop().unwrap();
+ let name = *terms.pop().unwrap();
+
+ let arity = arity
+ .to_constant()
+ .and_then(|c| c.to_integer())
+ .and_then(|n| n.to_usize())
+ .ok_or(ParserError::InvalidModuleExport)?;
+
+ let name = name
+ .to_constant()
+ .and_then(|c| c.to_atom())
+ .ok_or(ParserError::InvalidModuleExport)?;
+
+ Ok((name, arity))
+ }
+ _ => Err(ParserError::InvalidModuleExport),
}
}
-fn setup_module_decl(mut terms: Vec<Box<Term>>) -> Result<ModuleDecl, ParserError>
-{
+fn setup_module_decl(mut terms: Vec<Box<Term>>) -> Result<ModuleDecl, ParserError> {
let mut export_list = *terms.pop().unwrap();
- let name = terms.pop().unwrap().to_constant().and_then(|c| c.to_atom())
+ let name = terms
+ .pop()
+ .unwrap()
+ .to_constant()
+ .and_then(|c| c.to_atom())
.ok_or(ParserError::InvalidModuleDecl)?;
let mut exports = Vec::new();
}
}
-fn setup_use_module_decl(mut terms: Vec<Box<Term>>) -> Result<ModuleSource, ParserError>
-{
+fn setup_use_module_decl(mut terms: Vec<Box<Term>>) -> Result<ModuleSource, ParserError> {
match *terms.pop().unwrap() {
Term::Clause(_, ref name, ref mut terms, None)
- if name.as_str() == "library" && terms.len() == 1 => {
- terms.pop().unwrap().to_constant()
- .and_then(|c| c.to_atom())
- .map(|c| ModuleSource::Library(c))
- .ok_or(ParserError::InvalidUseModuleDecl)
- },
- Term::Constant(_, Constant::Atom(ref name, _)) =>
- Ok(ModuleSource::File(name.clone())),
- _ => Err(ParserError::InvalidUseModuleDecl)
+ if name.as_str() == "library" && terms.len() == 1 =>
+ {
+ terms
+ .pop()
+ .unwrap()
+ .to_constant()
+ .and_then(|c| c.to_atom())
+ .map(|c| ModuleSource::Library(c))
+ .ok_or(ParserError::InvalidUseModuleDecl)
+ }
+ Term::Constant(_, Constant::Atom(ref name, _)) => Ok(ModuleSource::File(name.clone())),
+ _ => Err(ParserError::InvalidUseModuleDecl),
}
}
type UseModuleExport = (ModuleSource, Vec<PredicateKey>);
-fn setup_qualified_import(mut terms: Vec<Box<Term>>) -> Result<UseModuleExport, ParserError>
-{
+fn setup_qualified_import(mut terms: Vec<Box<Term>>) -> Result<UseModuleExport, ParserError> {
let mut export_list = *terms.pop().unwrap();
let module_src = match *terms.pop().unwrap() {
Term::Clause(_, ref name, ref mut terms, None)
- if name.as_str() == "library" && terms.len() == 1 => {
- terms.pop().unwrap().to_constant()
- .and_then(|c| c.to_atom())
- .map(|c| ModuleSource::Library(c))
- .ok_or(ParserError::InvalidUseModuleDecl)
- },
- Term::Constant(_, Constant::Atom(ref name, _)) =>
- Ok(ModuleSource::File(name.clone())),
- _ => Err(ParserError::InvalidUseModuleDecl)
+ if name.as_str() == "library" && terms.len() == 1 =>
+ {
+ terms
+ .pop()
+ .unwrap()
+ .to_constant()
+ .and_then(|c| c.to_atom())
+ .map(|c| ModuleSource::Library(c))
+ .ok_or(ParserError::InvalidUseModuleDecl)
+ }
+ Term::Constant(_, Constant::Atom(ref name, _)) => Ok(ModuleSource::File(name.clone())),
+ _ => Err(ParserError::InvalidUseModuleDecl),
}?;
let mut exports = Vec::new();
}
}
-fn setup_declaration(mut terms: Vec<Box<Term>>) -> Result<Declaration, ParserError>
-{
+fn setup_declaration(mut terms: Vec<Box<Term>>) -> Result<Declaration, ParserError> {
let term = *terms.pop().unwrap();
match term {
- Term::Clause(_, name, mut terms, _) =>
+ Term::Clause(_, name, mut terms, _) => {
if name.as_str() == "op" && terms.len() == 3 {
Ok(Declaration::Op(setup_op_decl(terms)?))
} else if name.as_str() == "module" && terms.len() == 2 {
Ok(Declaration::Dynamic(name, arity))
} else {
Err(ParserError::InconsistentEntry)
- },
- _ => return Err(ParserError::InconsistentEntry)
+ }
+ }
+ _ => return Err(ParserError::InconsistentEntry),
}
}
-fn is_consistent(tl: &TopLevel, clauses: &Vec<PredicateClause>) -> bool
-{
+fn is_consistent(tl: &TopLevel, clauses: &Vec<PredicateClause>) -> bool {
match clauses.first() {
Some(ref cl) => tl.name() == cl.name() && tl.arity() == cl.arity(),
- None => true
+ None => true,
}
}
-fn deque_to_packet(head: TopLevel, deque: VecDeque<TopLevel>) -> TopLevelPacket
-{
+fn deque_to_packet(head: TopLevel, deque: VecDeque<TopLevel>) -> TopLevelPacket {
match head {
TopLevel::Query(query) => TopLevelPacket::Query(query, deque),
- tl => TopLevelPacket::Decl(tl, deque)
+ tl => TopLevelPacket::Decl(tl, deque),
}
}
-fn merge_clauses(tls: &mut VecDeque<TopLevel>) -> Result<TopLevel, ParserError>
-{
+fn merge_clauses(tls: &mut VecDeque<TopLevel>) -> Result<TopLevel, ParserError> {
let mut clauses: Vec<PredicateClause> = vec![];
while let Some(tl) = tls.pop_front() {
match tl {
- TopLevel::Query(_) if clauses.is_empty() && tls.is_empty() =>
- return Ok(tl),
- TopLevel::Declaration(_) if clauses.is_empty() =>
- return Ok(tl),
- TopLevel::Query(_) =>
- return Err(ParserError::InconsistentEntry),
- TopLevel::Fact(_) if is_consistent(&tl, &clauses) =>
+ TopLevel::Query(_) if clauses.is_empty() && tls.is_empty() => return Ok(tl),
+ TopLevel::Declaration(_) if clauses.is_empty() => return Ok(tl),
+ TopLevel::Query(_) => return Err(ParserError::InconsistentEntry),
+ TopLevel::Fact(_) if is_consistent(&tl, &clauses) => {
if let TopLevel::Fact(fact) = tl {
let clause = PredicateClause::Fact(fact);
clauses.push(clause);
- },
- TopLevel::Rule(_) if is_consistent(&tl, &clauses) =>
+ }
+ }
+ TopLevel::Rule(_) if is_consistent(&tl, &clauses) => {
if let TopLevel::Rule(rule) = tl {
let clause = PredicateClause::Rule(rule);
clauses.push(clause);
- },
- TopLevel::Predicate(_) if is_consistent(&tl, &clauses) =>
+ }
+ }
+ TopLevel::Predicate(_) if is_consistent(&tl, &clauses) => {
if let TopLevel::Predicate(pred) = tl {
clauses.extend(pred.clauses().into_iter())
- },
+ }
+ }
_ => {
tls.push_front(tl);
break;
fn mark_cut_variables_as(terms: &mut Vec<Term>, name: ClauseName) {
for term in terms.iter_mut() {
match term {
- &mut Term::Constant(_, Constant::Atom(ref mut var, _)) if var.as_str() == "!" =>
- *var = name.clone(),
+ &mut Term::Constant(_, Constant::Atom(ref mut var, _)) if var.as_str() == "!" => {
+ *var = name.clone()
+ }
_ => {}
}
}
fn mark_cut_variable(term: &mut Term) -> bool {
let cut_var_found = match term {
&mut Term::Constant(_, Constant::Atom(ref var, _)) if var.as_str() == "!" => true,
- _ => false
+ _ => false,
};
if cut_var_found {
match (name.as_str(), terms.len()) {
(":-", 2) => {
let inner_term = match terms.first_mut().map(|term| term.borrow_mut()) {
- Some(&mut Term::Clause(_, ref name, ref mut inner_terms, _)) =>
+ Some(&mut Term::Clause(_, ref name, ref mut inner_terms, _)) => {
if name.as_str() == ":" && inner_terms.len() == 2 {
Some(*inner_terms.pop().unwrap())
} else {
None
- },
- _ => None
+ }
+ }
+ _ => None,
};
if let Some(inner_term) = inner_term {
mem::swap(&mut terms[0], &mut Box::new(inner_term));
}
- },
+ }
(":", 2) => return *terms.pop().unwrap(),
_ => {}
}
pub enum TopLevelPacket {
Query(Vec<QueryTerm>, VecDeque<TopLevel>),
- Decl(TopLevel, VecDeque<TopLevel>)
+ Decl(TopLevel, VecDeque<TopLevel>),
}
struct RelationWorker {
impl RelationWorker {
fn new(flags: MachineFlags) -> Self {
- RelationWorker { dynamic_clauses: vec![],
- flags,
- queue: VecDeque::new() }
+ RelationWorker {
+ dynamic_clauses: vec![],
+ flags,
+ queue: VecDeque::new(),
+ }
}
- fn setup_fact(&mut self, term: Term, assume_dyn: bool) -> Result<Term, ParserError>
- {
+ fn setup_fact(&mut self, term: Term, assume_dyn: bool) -> Result<Term, ParserError> {
match term {
Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) => {
- let tail = Term::Constant(Cell::default(),
- Constant::Atom(clause_name!("true"), None));
+ let tail =
+ Term::Constant(Cell::default(), Constant::Atom(clause_name!("true"), None));
if assume_dyn {
self.dynamic_clauses.push((term.clone(), tail));
}
Ok(term)
- },
- _ =>
- Err(ParserError::InadmissibleFact)
+ }
+ _ => Err(ParserError::InadmissibleFact),
}
}
- fn compute_head(&self, term: &Term) -> Vec<Term>
- {
+ fn compute_head(&self, term: &Term) -> Vec<Term> {
let mut vars = IndexSet::new();
for term in post_order_iter(term) {
.collect()
}
- fn fabricate_rule_body(&self, vars: &Vec<Term>, body_term: Term) -> Term
- {
+ fn fabricate_rule_body(&self, vars: &Vec<Term>, body_term: Term) -> Term {
let vars_of_head = vars.iter().cloned().map(Box::new).collect();
let head_term = Term::Clause(Cell::default(), clause_name!(""), vars_of_head, None);
// the terms form the body of the rule. We create a head, by
// gathering variables from the body of terms and recording them
// in the head clause.
- fn fabricate_rule(&self, body_term: Term) -> (JumpStub, VecDeque<Term>)
- {
+ fn fabricate_rule(&self, body_term: Term) -> (JumpStub, VecDeque<Term>) {
// collect the vars of body_term into a head, return the num_vars
// (the arity) as well.
let vars = self.compute_head(&body_term);
(vars, VecDeque::from(vec![rule]))
}
- fn fabricate_disjunct(&self, body_term: Term) -> (JumpStub, VecDeque<Term>)
- {
+ fn fabricate_disjunct(&self, body_term: Term) -> (JumpStub, VecDeque<Term>) {
let vars = self.compute_head(&body_term);
- let clauses: Vec<_> = unfold_by_str(body_term, ";").into_iter()
+ let clauses: Vec<_> = unfold_by_str(body_term, ";")
+ .into_iter()
.map(|term| {
let mut subterms = unfold_by_str(term, ",");
mark_cut_variables(&mut subterms);
let term = subterms.pop().unwrap();
fold_by_str(subterms.into_iter(), term, clause_name!(","))
- }).collect();
+ })
+ .collect();
- let results = clauses.into_iter()
+ let results = clauses
+ .into_iter()
.map(|clause| self.fabricate_rule_body(&vars, clause))
.collect();
(vars, results)
}
- fn fabricate_if_then(&self, prec: Term, conq: Term) -> (JumpStub, VecDeque<Term>)
- {
+ fn fabricate_if_then(&self, prec: Term, conq: Term) -> (JumpStub, VecDeque<Term>) {
let mut prec_seq = unfold_by_str(prec, ",");
- let comma_sym = clause_name!(",");
- let cut_sym = atom!("!");
+ let comma_sym = clause_name!(",");
+ let cut_sym = atom!("!");
prec_seq.push(Term::Constant(Cell::default(), cut_sym));
mark_cut_variables(&mut conq_seq);
prec_seq.extend(conq_seq.into_iter());
- let back_term = Box::new(prec_seq.pop().unwrap());
+ let back_term = Box::new(prec_seq.pop().unwrap());
let front_term = Box::new(prec_seq.pop().unwrap());
- let body_term = Term::Clause(Cell::default(), comma_sym.clone(),
- vec![front_term, back_term], None);
+ let body_term = Term::Clause(
+ Cell::default(),
+ comma_sym.clone(),
+ vec![front_term, back_term],
+ None,
+ );
self.fabricate_rule(fold_by_str(prec_seq.into_iter(), body_term, comma_sym))
}
- fn to_query_term(&mut self, indices: &mut CompositeIndices, term: Term) -> Result<QueryTerm, ParserError>
- {
+ fn to_query_term(
+ &mut self,
+ indices: &mut CompositeIndices,
+ term: Term,
+ ) -> Result<QueryTerm, ParserError> {
match term {
- Term::Constant(_, Constant::Atom(name, fixity)) =>
+ Term::Constant(_, Constant::Atom(name, fixity)) => {
if name.as_str() == "!" || name.as_str() == "blocked_!" {
Ok(QueryTerm::BlockedCut)
} else {
let ct = indices.get_clause_type(name, 0, fixity);
Ok(QueryTerm::Clause(Cell::default(), ct, vec![], false))
- },
- Term::Var(_, ref v) if v.as_str() == "!" =>
- Ok(QueryTerm::UnblockedCut(Cell::default())),
- Term::Clause(r, name, mut terms, fixity) =>
- match (name.as_str(), terms.len()) {
- (";", 2) => {
- let term = Term::Clause(r, name.clone(), terms, fixity);
- let (stub, clauses) = self.fabricate_disjunct(term);
-
- self.queue.push_back(clauses);
- Ok(QueryTerm::Jump(stub))
- },
- ("->", 2) => {
- let conq = *terms.pop().unwrap();
- let prec = *terms.pop().unwrap();
-
- let (stub, clauses) = self.fabricate_if_then(prec, conq);
-
- self.queue.push_back(clauses);
- Ok(QueryTerm::Jump(stub))
- },
- ("$get_level", 1) =>
- if let Term::Var(_, ref var) = *terms[0] {
- Ok(QueryTerm::GetLevelAndUnify(Cell::default(), var.clone()))
- } else {
- Err(ParserError::InadmissibleQueryTerm)
- },
- ("partial_string", 2) => {
- let ct = ClauseType::BuiltIn(BuiltInClauseType::PartialString);
- return Ok(QueryTerm::Clause(Cell::default(), ct, terms, false));
- },
- _ => {
- let ct = indices.get_clause_type(name, terms.len(), fixity);
- Ok(QueryTerm::Clause(Cell::default(), ct, terms, false))
+ }
+ }
+ Term::Var(_, ref v) if v.as_str() == "!" => {
+ Ok(QueryTerm::UnblockedCut(Cell::default()))
+ }
+ Term::Clause(r, name, mut terms, fixity) => match (name.as_str(), terms.len()) {
+ (";", 2) => {
+ let term = Term::Clause(r, name.clone(), terms, fixity);
+ let (stub, clauses) = self.fabricate_disjunct(term);
+
+ self.queue.push_back(clauses);
+ Ok(QueryTerm::Jump(stub))
+ }
+ ("->", 2) => {
+ let conq = *terms.pop().unwrap();
+ let prec = *terms.pop().unwrap();
+
+ let (stub, clauses) = self.fabricate_if_then(prec, conq);
+
+ self.queue.push_back(clauses);
+ Ok(QueryTerm::Jump(stub))
+ }
+ ("$get_level", 1) => {
+ if let Term::Var(_, ref var) = *terms[0] {
+ Ok(QueryTerm::GetLevelAndUnify(Cell::default(), var.clone()))
+ } else {
+ Err(ParserError::InadmissibleQueryTerm)
}
- },
- Term::Var(..) =>
- Ok(QueryTerm::Clause(Cell::default(), ClauseType::CallN, vec![Box::new(term)], false)),
- _ => Err(ParserError::InadmissibleQueryTerm)
+ }
+ ("partial_string", 2) => {
+ let ct = ClauseType::BuiltIn(BuiltInClauseType::PartialString);
+ return Ok(QueryTerm::Clause(Cell::default(), ct, terms, false));
+ }
+ _ => {
+ let ct = indices.get_clause_type(name, terms.len(), fixity);
+ Ok(QueryTerm::Clause(Cell::default(), ct, terms, false))
+ }
+ },
+ Term::Var(..) => Ok(QueryTerm::Clause(
+ Cell::default(),
+ ClauseType::CallN,
+ vec![Box::new(term)],
+ false,
+ )),
+ _ => Err(ParserError::InadmissibleQueryTerm),
}
}
// never blocks cuts in the consequent.
- fn prepend_if_then(&self, prec: Term, conq: Term, queue: &mut VecDeque<Box<Term>>,
- blocks_cuts: bool)
- {
+ fn prepend_if_then(
+ &self,
+ prec: Term,
+ conq: Term,
+ queue: &mut VecDeque<Box<Term>>,
+ blocks_cuts: bool,
+ ) {
let cut_symb = atom!("blocked_!");
let mut terms_seq = unfold_by_str(prec, ",");
}
}
- fn pre_query_term(&mut self, indices: &mut CompositeIndices, term: Term) -> Result<QueryTerm, ParserError>
- {
+ fn pre_query_term(
+ &mut self,
+ indices: &mut CompositeIndices,
+ term: Term,
+ ) -> Result<QueryTerm, ParserError> {
match term {
- Term::Clause(r, name, mut subterms, fixity) =>
+ Term::Clause(r, name, mut subterms, fixity) => {
if subterms.len() == 1 && name.as_str() == "$call_with_default_policy" {
self.to_query_term(indices, *subterms.pop().unwrap())
.map(|mut query_term| {
})
} else {
self.to_query_term(indices, Term::Clause(r, name, subterms, fixity))
- },
- _ => self.to_query_term(indices, term)
+ }
+ }
+ _ => self.to_query_term(indices, term),
}
}
- fn setup_query(&mut self, indices: &mut CompositeIndices, terms: Vec<Box<Term>>,
- blocks_cuts: bool)
- -> Result<Vec<QueryTerm>, ParserError>
- {
+ fn setup_query(
+ &mut self,
+ indices: &mut CompositeIndices,
+ terms: Vec<Box<Term>>,
+ blocks_cuts: bool,
+ ) -> Result<Vec<QueryTerm>, ParserError> {
let mut query_terms = vec![];
let mut work_queue = VecDeque::from(terms);
Ok(query_terms)
}
- fn setup_hook(&mut self, hook: CompileTimeHook, indices: &mut CompositeIndices, term: Term)
- -> Result<CompileTimeHookCompileInfo, ParserError>
- {
+ fn setup_hook(
+ &mut self,
+ hook: CompileTimeHook,
+ indices: &mut CompositeIndices,
+ term: Term,
+ ) -> Result<CompileTimeHookCompileInfo, ParserError> {
match flatten_hook(term) {
- Term::Clause(r, name, terms, _) =>
+ Term::Clause(r, name, terms, _) => {
if name == hook.name() && terms.len() == hook.arity() {
let term = self.setup_fact(Term::Clause(r, name, terms, None), false)?;
Ok((hook, PredicateClause::Fact(term), VecDeque::from(vec![])))
Ok((hook, PredicateClause::Rule(rule), results_queue))
} else {
Err(ParserError::InvalidHook)
- },
- _ => Err(ParserError::InvalidHook)
+ }
+ }
+ _ => Err(ParserError::InvalidHook),
}
}
- fn setup_rule(&mut self, indices: &mut CompositeIndices, mut terms: Vec<Box<Term>>,
- blocks_cuts: bool, assume_dyn: bool)
- -> Result<Rule, ParserError>
- {
+ fn setup_rule(
+ &mut self,
+ indices: &mut CompositeIndices,
+ mut terms: Vec<Box<Term>>,
+ blocks_cuts: bool,
+ assume_dyn: bool,
+ ) -> Result<Rule, ParserError> {
let head = *terms.first().cloned().unwrap();
- let post_head_terms: Vec<_> = terms.drain(1 .. ).collect();
+ let post_head_terms: Vec<_> = terms.drain(1..).collect();
let tail = *post_head_terms.first().cloned().unwrap();
}
let mut query_terms = self.setup_query(indices, post_head_terms, blocks_cuts)?;
- let clauses = query_terms.drain(1 ..).collect();
+ let clauses = query_terms.drain(1..).collect();
let qt = query_terms.pop().unwrap();
match *terms.pop().unwrap() {
- Term::Clause(_, name, terms, _) =>
- Ok(Rule { head: (name, terms, qt), clauses }),
- Term::Constant(_, Constant::Atom(name, _)) =>
- Ok(Rule { head: (name, vec![], qt), clauses }),
- _ => Err(ParserError::InvalidRuleHead)
+ Term::Clause(_, name, terms, _) => Ok(Rule {
+ head: (name, terms, qt),
+ clauses,
+ }),
+ Term::Constant(_, Constant::Atom(name, _)) => Ok(Rule {
+ head: (name, vec![], qt),
+ clauses,
+ }),
+ _ => Err(ParserError::InvalidRuleHead),
}
}
- fn try_term_to_query(&mut self, indices: &mut CompositeIndices, terms: Vec<Box<Term>>, blocks_cuts: bool)
- -> Result<TopLevel, ParserError>
- {
+ fn try_term_to_query(
+ &mut self,
+ indices: &mut CompositeIndices,
+ terms: Vec<Box<Term>>,
+ blocks_cuts: bool,
+ ) -> Result<TopLevel, ParserError> {
match setup_declaration(terms.iter().cloned().collect()) {
- Ok(Declaration::Op(..)) => {}, // this is now a predicate call in the query context.
+ Ok(Declaration::Op(..)) => {} // this is now a predicate call in the query context.
Ok(decl) => return Ok(TopLevel::Declaration(decl)),
_ => {}
};
- Ok(TopLevel::Query(self.setup_query(indices, terms, blocks_cuts)?))
+ Ok(TopLevel::Query(self.setup_query(
+ indices,
+ terms,
+ blocks_cuts,
+ )?))
}
- fn try_term_to_tl(&mut self, indices: &mut CompositeIndices, term: Term, blocks_cuts: bool)
- -> Result<TopLevel, ParserError>
- {
+ fn try_term_to_tl(
+ &mut self,
+ indices: &mut CompositeIndices,
+ term: Term,
+ blocks_cuts: bool,
+ ) -> Result<TopLevel, ParserError> {
match term {
- Term::Clause(r, name, terms, fixity) =>
+ Term::Clause(r, name, terms, fixity) => {
if let Some(hook) = is_compile_time_hook(&name, &terms) {
let term = Term::Clause(r, name, terms, fixity);
let (hook, clause, queue) = self.setup_hook(hook, indices, term)?;
- Ok(TopLevel::Declaration(Declaration::Hook(hook, clause, queue)))
+ Ok(TopLevel::Declaration(Declaration::Hook(
+ hook, clause, queue,
+ )))
} else if name.as_str() == "?-" {
self.try_term_to_query(indices, terms, blocks_cuts)
} else if name.as_str() == ":-" && terms.len() == 2 {
- Ok(TopLevel::Rule(self.setup_rule(indices, terms, blocks_cuts, true)?))
+ Ok(TopLevel::Rule(self.setup_rule(
+ indices,
+ terms,
+ blocks_cuts,
+ true,
+ )?))
} else if name.as_str() == ":-" && terms.len() == 1 {
Ok(TopLevel::Declaration(setup_declaration(terms)?))
} else {
let term = Term::Clause(r, name, terms, fixity);
Ok(TopLevel::Fact(try!(self.setup_fact(term, true))))
- },
- term => Ok(TopLevel::Fact(try!(self.setup_fact(term, true))))
+ }
+ }
+ term => Ok(TopLevel::Fact(try!(self.setup_fact(term, true)))),
}
}
- fn try_terms_to_tls<I>(&mut self, indices: &mut CompositeIndices, terms: I, blocks_cuts: bool)
- -> Result<VecDeque<TopLevel>, ParserError>
- where I: IntoIterator<Item=Term>
+ fn try_terms_to_tls<I>(
+ &mut self,
+ indices: &mut CompositeIndices,
+ terms: I,
+ blocks_cuts: bool,
+ ) -> Result<VecDeque<TopLevel>, ParserError>
+ where
+ I: IntoIterator<Item = Term>,
{
let mut results = VecDeque::new();
Ok(results)
}
- fn parse_queue(&mut self, indices: &mut CompositeIndices) -> Result<VecDeque<TopLevel>, ParserError>
- {
+ fn parse_queue(
+ &mut self,
+ indices: &mut CompositeIndices,
+ ) -> Result<VecDeque<TopLevel>, ParserError> {
let mut queue = VecDeque::new();
while let Some(terms) = self.queue.pop_front() {
fn absorb(&mut self, other: RelationWorker) {
self.queue.extend(other.queue.into_iter());
- self.dynamic_clauses.extend(other.dynamic_clauses.into_iter());
+ self.dynamic_clauses
+ .extend(other.dynamic_clauses.into_iter());
}
- fn expand_queue_contents<R>(&mut self, term_stream: &mut TermStream<R>, op_dir: &OpDir)
- -> Result<(), SessionError>
- where R: Read
+ fn expand_queue_contents<R>(
+ &mut self,
+ term_stream: &mut TermStream<R>,
+ op_dir: &OpDir,
+ ) -> Result<(), SessionError>
+ where
+ R: Read,
{
let mut machine_st = MachineState::new();
- let mut new_queue = VecDeque::new();
+ let mut new_queue = VecDeque::new();
while let Some(terms) = self.queue.pop_front() {
let mut new_terms = VecDeque::new();
for term in terms {
- new_terms.push_back(term_stream.run_goal_expanders(&mut machine_st, &op_dir, term)?);
+ new_terms.push_back(term_stream.run_goal_expanders(
+ &mut machine_st,
+ &op_dir,
+ term,
+ )?);
}
new_queue.push_back(new_terms);
}
}
-fn term_to_toplevel<R>(term_stream: &mut TermStream<R>, code_dir: &mut CodeDir, term: Term, flags: MachineFlags)
- -> Result<(TopLevel, RelationWorker), ParserError>
- where R: Read
+fn term_to_toplevel<R>(
+ term_stream: &mut TermStream<R>,
+ code_dir: &mut CodeDir,
+ term: Term,
+ flags: MachineFlags,
+) -> Result<(TopLevel, RelationWorker), ParserError>
+where
+ R: Read,
{
let mut rel_worker = RelationWorker::new(flags);
let mut indices = composite_indices!(false, &mut term_stream.wam.indices, code_dir);
Ok((tl, rel_worker))
}
-pub
-fn stream_to_toplevel<R: Read>(mut buffer: ParsingStream<R>, wam: &mut Machine)
- -> Result<TopLevelPacket, SessionError>
-{
+pub fn stream_to_toplevel<R: Read>(
+ mut buffer: ParsingStream<R>,
+ wam: &mut Machine,
+) -> Result<TopLevelPacket, SessionError> {
let flags = wam.machine_flags();
- let mut term_stream = TermStream::new(&mut buffer, wam.indices.atom_tbl(),
- wam.machine_flags(), wam);
+ let mut term_stream = TermStream::new(
+ &mut buffer,
+ wam.indices.atom_tbl(),
+ wam.machine_flags(),
+ wam,
+ );
term_stream.add_to_top("?- ");
rel_worker: RelationWorker,
pub(crate) results: Vec<(Predicate, VecDeque<TopLevel>)>,
pub(crate) dynamic_clause_map: DynamicClauseMap,
- pub(crate) in_module: bool
+ pub(crate) in_module: bool,
}
impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
-
- pub fn new(inner: &'a mut ParsingStream<R>, atom_tbl: TabledData<Atom>,
- flags: MachineFlags, wam: &'a mut Machine)
- -> Self
- {
+ pub fn new(
+ inner: &'a mut ParsingStream<R>,
+ atom_tbl: TabledData<Atom>,
+ flags: MachineFlags,
+ wam: &'a mut Machine,
+ ) -> Self {
let term_stream = TermStream::new(inner, atom_tbl, flags, wam);
- TopLevelBatchWorker { term_stream,
- rel_worker: RelationWorker::new(flags),
- results: vec![],
- dynamic_clause_map: IndexMap::new(),
- in_module: false }
+ TopLevelBatchWorker {
+ term_stream,
+ rel_worker: RelationWorker::new(flags),
+ results: vec![],
+ dynamic_clause_map: IndexMap::new(),
+ in_module: false,
+ }
}
- fn try_term_to_tl(&self, indices: &mut IndexStore, term: Term)
- -> Result<(TopLevel, RelationWorker), SessionError>
- {
+ fn try_term_to_tl(
+ &self,
+ indices: &mut IndexStore,
+ term: Term,
+ ) -> Result<(TopLevel, RelationWorker), SessionError> {
let mut new_rel_worker = RelationWorker::new(self.rel_worker.flags);
- let mut indices = composite_indices!(self.in_module, indices,
- &self.term_stream.wam.indices.code_dir);
-
- Ok((new_rel_worker.try_term_to_tl(&mut indices, term, true)?, new_rel_worker))
+ let mut indices = composite_indices!(
+ self.in_module,
+ indices,
+ &self.term_stream.wam.indices.code_dir
+ );
+
+ Ok((
+ new_rel_worker.try_term_to_tl(&mut indices, term, true)?,
+ new_rel_worker,
+ ))
}
- fn process_result(&mut self, indices: &mut IndexStore, preds: &mut Vec<PredicateClause>)
- -> Result<(), SessionError>
- {
- self.rel_worker.expand_queue_contents(&mut self.term_stream, &indices.op_dir)?;
-
- let mut indices = composite_indices!(self.in_module, indices,
- &mut self.term_stream.wam.indices.code_dir);
-
- let queue = self.rel_worker.parse_queue(&mut indices)?;
+ fn process_result(
+ &mut self,
+ indices: &mut IndexStore,
+ preds: &mut Vec<PredicateClause>,
+ ) -> Result<(), SessionError> {
+ self.rel_worker
+ .expand_queue_contents(&mut self.term_stream, &indices.op_dir)?;
+
+ let mut indices = composite_indices!(
+ self.in_module,
+ indices,
+ &mut self.term_stream.wam.indices.code_dir
+ );
+
+ let queue = self.rel_worker.parse_queue(&mut indices)?;
let result = (append_preds(preds), queue);
let in_situ_code_dir = &mut self.term_stream.wam.indices.in_situ_code_dir;
- self.term_stream.wam.code_repo.add_in_situ_result(&result, in_situ_code_dir,
- self.term_stream.flags)?;
+ self.term_stream.wam.code_repo.add_in_situ_result(
+ &result,
+ in_situ_code_dir,
+ self.term_stream.flags,
+ )?;
Ok(self.results.push(result))
}
fn take_dynamic_clauses(&mut self) {
let (name, arity) = match self.rel_worker.dynamic_clauses.first() {
- Some((head, _)) =>
- (head.name().unwrap(), head.arity()),
- None =>
- return
+ Some((head, _)) => (head.name().unwrap(), head.arity()),
+ None => return,
};
match self.dynamic_clause_map.get_mut(&(name.clone(), arity)) {
Some(ref mut entry) => {
entry.clear(); // don't treat dynamic predicates as if they're discontiguous.
- entry.extend(self.rel_worker.dynamic_clauses.drain(0 ..));
- },
+ entry.extend(self.rel_worker.dynamic_clauses.drain(0..));
+ }
_ => {
self.rel_worker.dynamic_clauses.clear();
}
}
}
- pub fn consume(&mut self, indices: &mut IndexStore) -> Result<Option<Declaration>, SessionError>
- {
+ pub fn consume(
+ &mut self,
+ indices: &mut IndexStore,
+ ) -> Result<Option<Declaration>, SessionError> {
let mut preds = vec![];
while !self.term_stream.eof()? {
TopLevel::Rule(rule) => preds.push(PredicateClause::Rule(rule)),
TopLevel::Predicate(pred) => preds.extend(pred.0),
TopLevel::Declaration(decl) => return Ok(Some(decl)),
- TopLevel::Query(_) => return Err(SessionError::NamelessEntry)
+ TopLevel::Query(_) => return Err(SessionError::NamelessEntry),
}
}
macro_rules! interm {
- ($n: expr) => (
+ ($n: expr) => {
ArithmeticTerm::Interm($n)
- )
+ };
}
macro_rules! heap_str {
- ($s:expr) => (
+ ($s:expr) => {
HeapCellValue::Addr(Addr::Str($s))
- )
+ };
}
macro_rules! heap_integer {
- ($i:expr) => (
+ ($i:expr) => {
HeapCellValue::Addr(Addr::Con(Constant::Integer($i)))
- )
+ };
}
macro_rules! heap_cell {
- ($i:expr) => (
+ ($i:expr) => {
HeapCellValue::Addr(Addr::HeapCell($i))
- )
+ };
}
macro_rules! heap_con {
- ($i:expr) => (
+ ($i:expr) => {
HeapCellValue::Addr(Addr::Con($i))
- )
+ };
}
macro_rules! heap_atom {
- ($name:expr) => (
+ ($name:expr) => {
HeapCellValue::Addr(Addr::Con(atom!($name)))
- );
- ($name:expr, $tbl:expr) => (
+ };
+ ($name:expr, $tbl:expr) => {
HeapCellValue::Addr(Addr::Con(atom!($name, $tbl)))
- )
+ };
}
macro_rules! functor {
}
macro_rules! is_atom {
- ($r:expr) => (
+ ($r:expr) => {
call_clause!(ClauseType::Inlined(InlinedClauseType::IsAtom($r)), 1, 0)
- )
+ };
}
macro_rules! is_atomic {
- ($r:expr) => (
+ ($r:expr) => {
call_clause!(ClauseType::Inlined(InlinedClauseType::IsAtomic($r)), 1, 0)
- )
+ };
}
macro_rules! is_integer {
- ($r:expr) => (
+ ($r:expr) => {
call_clause!(ClauseType::Inlined(InlinedClauseType::IsInteger($r)), 1, 0)
- )
+ };
}
macro_rules! is_compound {
- ($r:expr) => (
+ ($r:expr) => {
call_clause!(ClauseType::Inlined(InlinedClauseType::IsCompound($r)), 1, 0)
- )
+ };
}
macro_rules! is_float {
- ($r:expr) => (
+ ($r:expr) => {
call_clause!(ClauseType::Inlined(InlinedClauseType::IsFloat($r)), 1, 0)
- )
+ };
}
macro_rules! is_rational {
- ($r:expr) => (
+ ($r:expr) => {
call_clause!(ClauseType::Inlined(InlinedClauseType::IsRational($r)), 1, 0)
- )
+ };
}
-
macro_rules! is_nonvar {
- ($r:expr) => (
+ ($r:expr) => {
call_clause!(ClauseType::Inlined(InlinedClauseType::IsNonVar($r)), 1, 0)
- )
+ };
}
macro_rules! is_string {
- ($r:expr) => (
+ ($r:expr) => {
call_clause!(ClauseType::Inlined(InlinedClauseType::IsString($r)), 1, 0)
- )
+ };
}
macro_rules! is_var {
- ($r:expr) => (
+ ($r:expr) => {
call_clause!(ClauseType::Inlined(InlinedClauseType::IsVar($r)), 1, 0)
- )
+ };
}
macro_rules! is_partial_string {
- ($r:expr) => (
- call_clause!(ClauseType::Inlined(InlinedClauseType::IsPartialString($r)), 1, 0)
- )
+ ($r:expr) => {
+ call_clause!(
+ ClauseType::Inlined(InlinedClauseType::IsPartialString($r)),
+ 1,
+ 0
+ )
+ };
}
macro_rules! call_clause {
- ($ct:expr, $arity:expr, $pvs:expr) => (
- Line::Control(ControlInstruction::CallClause($ct, $arity, $pvs, false, false))
- );
- ($ct:expr, $arity:expr, $pvs:expr, $lco:expr) => (
- Line::Control(ControlInstruction::CallClause($ct, $arity, $pvs, $lco, false))
- )
+ ($ct:expr, $arity:expr, $pvs:expr) => {
+ Line::Control(ControlInstruction::CallClause(
+ $ct, $arity, $pvs, false, false,
+ ))
+ };
+ ($ct:expr, $arity:expr, $pvs:expr, $lco:expr) => {
+ Line::Control(ControlInstruction::CallClause(
+ $ct, $arity, $pvs, $lco, false,
+ ))
+ };
}
macro_rules! call_clause_by_default {
- ($ct:expr, $arity:expr, $pvs:expr) => (
- Line::Control(ControlInstruction::CallClause($ct, $arity, $pvs, false, true))
- );
- ($ct:expr, $arity:expr, $pvs:expr, $lco:expr) => (
- Line::Control(ControlInstruction::CallClause($ct, $arity, $pvs, $lco, true))
- )
+ ($ct:expr, $arity:expr, $pvs:expr) => {
+ Line::Control(ControlInstruction::CallClause(
+ $ct, $arity, $pvs, false, true,
+ ))
+ };
+ ($ct:expr, $arity:expr, $pvs:expr, $lco:expr) => {
+ Line::Control(ControlInstruction::CallClause(
+ $ct, $arity, $pvs, $lco, true,
+ ))
+ };
}
macro_rules! proceed {
- () => (
+ () => {
Line::Control(ControlInstruction::Proceed)
- )
+ };
}
macro_rules! is_call {
- ($r:expr, $at:expr) => (
+ ($r:expr, $at:expr) => {
call_clause!(ClauseType::BuiltIn(BuiltInClauseType::Is($r, $at)), 2, 0)
- )
+ };
}
macro_rules! is_call_by_default {
- ($r:expr, $at:expr) => (
+ ($r:expr, $at:expr) => {
call_clause_by_default!(ClauseType::BuiltIn(BuiltInClauseType::Is($r, $at)), 2, 0)
- )
+ };
}
macro_rules! set_cp {
- ($r:expr) => (
+ ($r:expr) => {
call_clause!(ClauseType::System(SystemClauseType::SetCutPoint($r)), 1, 0)
- )
+ };
}
macro_rules! succeed {
- () => (
+ () => {
call_clause!(ClauseType::System(SystemClauseType::Succeed), 0, 0)
- )
+ };
}
macro_rules! fail {
- () => (
+ () => {
call_clause!(ClauseType::System(SystemClauseType::Fail), 0, 0)
- )
+ };
}
macro_rules! compare_number_instr {
($cmp: expr, $at_1: expr, $at_2: expr) => {{
let ct = ClauseType::Inlined(InlinedClauseType::CompareNumber($cmp, $at_1, $at_2));
call_clause!(ct, 2, 0)
- }}
+ }};
}
macro_rules! jmp_call {
- ($arity:expr, $offset:expr, $pvs:expr) => (
+ ($arity:expr, $offset:expr, $pvs:expr) => {
Line::Control(ControlInstruction::JmpBy($arity, $offset, $pvs, false))
- )
+ };
}
macro_rules! try_eval_session {
- ($e:expr) => (
+ ($e:expr) => {
match $e {
Ok(result) => result,
- Err(e) => return EvalSession::from(e)
+ Err(e) => return EvalSession::from(e),
}
- )
+ };
}
macro_rules! return_from_clause {
($lco:expr, $machine_st:expr) => {{
if let CodePtr::VerifyAttrInterrupt(_) = $machine_st.p {
return Ok(());
}
-
+
if $lco {
$machine_st.p = CodePtr::Local($machine_st.cp);
} else {
}
Ok(())
- }}
+ }};
}
macro_rules! dir_entry {
- ($idx:expr) => (
+ ($idx:expr) => {
CodePtr::Local(LocalCodePtr::DirEntry($idx))
- )
+ };
}
macro_rules! in_situ_dir_entry {
- ($idx:expr) => (
+ ($idx:expr) => {
CodePtr::Local(LocalCodePtr::InSituDirEntry($idx))
- )
+ };
}
macro_rules! set_code_index {
idx.0 = $ip;
idx.1 = $mod_name.clone();
- }}
+ }};
}
macro_rules! index_store {
- ($atom_tbl:expr, $code_dir:expr, $op_dir:expr, $modules:expr) => (
- IndexStore { atom_tbl: $atom_tbl,
- code_dir: $code_dir,
- dynamic_code_dir: DynamicCodeDir::new(),
- global_variables: GlobalVarDir::new(),
- in_situ_code_dir: InSituCodeDir::new(),
- op_dir: $op_dir,
- modules: $modules }
- )
+ ($atom_tbl:expr, $code_dir:expr, $op_dir:expr, $modules:expr) => {
+ IndexStore {
+ atom_tbl: $atom_tbl,
+ code_dir: $code_dir,
+ dynamic_code_dir: DynamicCodeDir::new(),
+ global_variables: GlobalVarDir::new(),
+ in_situ_code_dir: InSituCodeDir::new(),
+ op_dir: $op_dir,
+ modules: $modules,
+ }
+ };
}
macro_rules! default_index_store {
- ($atom_tbl:expr) => (
+ ($atom_tbl:expr) => {
index_store!($atom_tbl, CodeDir::new(), default_op_dir(), IndexMap::new())
- )
+ };
}
macro_rules! put_constant {
- ($lvl:expr, $cons:expr, $r:expr) => (
+ ($lvl:expr, $cons:expr, $r:expr) => {
QueryInstruction::PutConstant($lvl, $cons, $r)
- )
+ };
}
macro_rules! top_level_code_ptr {
- ($p:expr, $q_sz:expr) => (
+ ($p:expr, $q_sz:expr) => {
CodePtr::Local(LocalCodePtr::TopLevel($p, $q_sz))
- )
+ };
}
macro_rules! get_level_and_unify {
- ($r: expr) => (
+ ($r: expr) => {
Line::Cut(CutInstruction::GetLevelAndUnify($r))
- )
+ };
}
macro_rules! unwind_protect {
- ($e: expr, $protected: expr) => (
+ ($e: expr, $protected: expr) => {
match $e {
- Err(e) => { $protected; return Err(e); },
+ Err(e) => {
+ $protected;
+ return Err(e);
+ }
_ => {}
}
- )
+ };
}
macro_rules! discard_result {
- ($f: expr) => (
+ ($f: expr) => {
match $f {
- _ => ()
+ _ => (),
}
- )
+ };
}
macro_rules! ar_reg {
- ($r: expr) => (
+ ($r: expr) => {
ArithmeticTerm::Reg($r)
- )
+ };
}
extern crate prolog_parser;
extern crate rug;
-#[macro_use] mod macros;
-pub mod instructions;
+#[macro_use]
+mod macros;
mod clause_types;
-#[macro_use] mod allocator;
-mod fixtures;
-pub mod machine;
-mod forms;
+pub mod instructions;
+#[macro_use]
+mod allocator;
mod arithmetic;
mod codegen;
mod debray_allocator;
+mod fixtures;
+mod forms;
mod heap_iter;
+pub mod heap_print;
mod indexing;
-pub mod write;
mod iterators;
-pub mod heap_print;
-mod targets;
+pub mod machine;
pub mod read;
+mod targets;
+pub mod write;
pub type PrologStream = ParsingStream<Box<Read>>;
#[cfg(feature = "readline_rs_compat")]
-pub mod readline
-{
+pub mod readline {
use prolog_parser::ast::*;
use readline_rs_compat::readline::*;
use std::io::{Error, Read};
#[derive(Clone, Copy)]
pub enum LineMode {
Single,
- Multi
+ Multi,
}
pub struct ReadlineStream {
- pending_input: String
+ pending_input: String,
}
impl ReadlineStream {
Some(text) => {
self.pending_input += &text;
Ok(self.write_to_buf(buf))
- },
- None => Err(Error::last_os_error())
+ }
+ None => Err(Error::last_os_error()),
}
}
let output_len = self.split_pending(buf, split_idx);
if split_idx < self.pending_input.len() {
- self.pending_input = self.pending_input[split_idx ..].to_string();
+ self.pending_input = self.pending_input[split_idx..].to_string();
} else {
self.pending_input.clear();
}
}
#[cfg(not(feature = "readline_rs_compat"))]
-pub mod readline
-{
+pub mod readline {
use prolog_parser::ast::*;
- use std::io::{BufReader, Read, Stdin, stdin};
+ use std::io::{stdin, BufReader, Read, Stdin};
struct StdinWrapper {
- buf: BufReader<Stdin>
+ buf: BufReader<Stdin>,
}
impl Read for StdinWrapper {
#[inline]
pub fn input_stream() -> ::PrologStream {
- let reader: Box<Read> = Box::new(StdinWrapper { buf: BufReader::new(stdin()) });
+ let reader: Box<Read> = Box::new(StdinWrapper {
+ buf: BufReader::new(stdin()),
+ });
parsing_stream(reader)
}
}
impl MachineState {
- pub fn read(&mut self, inner: &mut PrologStream, atom_tbl: TabledData<Atom>, op_dir: &OpDir)
- -> Result<TermWriteResult, ParserError>
- {
+ pub fn read(
+ &mut self,
+ inner: &mut PrologStream,
+ atom_tbl: TabledData<Atom>,
+ op_dir: &OpDir,
+ ) -> Result<TermWriteResult, ParserError> {
let mut parser = Parser::new(inner, atom_tbl, self.flags);
let term = parser.read_term(composite_op!(op_dir))?;
machine_st.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
}
-fn modify_head_of_queue(machine_st: &mut MachineState, queue: &mut SubtermDeque, term: TermRef, h: usize)
-{
+fn modify_head_of_queue(
+ machine_st: &mut MachineState,
+ queue: &mut SubtermDeque,
+ term: TermRef,
+ h: usize,
+) {
if let Some((arity, site_h)) = queue.pop_front() {
machine_st.heap[site_h] = HeapCellValue::Addr(term.as_addr(h));
pub(crate) var_dict: HeapVarDict,
}
-pub(crate)
-fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) -> TermWriteResult
-{
+pub(crate) fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) -> TermWriteResult {
let heap_loc = machine_st.heap.h;
let mut queue = SubtermDeque::new();
match &term {
&TermRef::Cons(lvl, ..) => {
- queue.push_back((2, h+1));
- machine_st.heap.push(HeapCellValue::Addr(Addr::Lis(h+1)));
+ queue.push_back((2, h + 1));
+ machine_st.heap.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
push_stub_addr(machine_st);
push_stub_addr(machine_st);
if let Level::Root = lvl {
continue;
}
- },
+ }
&TermRef::Clause(lvl, _, ref ct, subterms) => {
- queue.push_back((subterms.len(), h+1));
+ queue.push_back((subterms.len(), h + 1));
let named = HeapCellValue::NamedStr(subterms.len(), ct.name(), ct.spec());
machine_st.heap.push(named);
- for _ in 0 .. subterms.len() {
+ for _ in 0..subterms.len() {
push_stub_addr(machine_st);
}
if let Level::Root = lvl {
continue;
}
- },
- &TermRef::AnonVar(Level::Root) | &TermRef::Constant(Level::Root, ..) =>
- machine_st.heap.push(HeapCellValue::Addr(term.as_addr(h))),
- &TermRef::Var(Level::Root, ..) =>
- machine_st.heap.push(HeapCellValue::Addr(term.as_addr(h))),
+ }
+ &TermRef::AnonVar(Level::Root) | &TermRef::Constant(Level::Root, ..) => {
+ machine_st.heap.push(HeapCellValue::Addr(term.as_addr(h)))
+ }
+ &TermRef::Var(Level::Root, ..) => {
+ machine_st.heap.push(HeapCellValue::Addr(term.as_addr(h)))
+ }
&TermRef::AnonVar(_) => {
if let Some((arity, site_h)) = queue.pop_front() {
if arity > 1 {
}
continue;
- },
+ }
&TermRef::Var(_, _, ref var) => {
if let Some((arity, site_h)) = queue.pop_front() {
if let Some(addr) = var_dict.get(var).cloned() {
}
continue;
- },
+ }
_ => {}
};
use prolog::iterators::*;
pub trait CompilationTarget<'a> {
- type Iterator : Iterator<Item=TermRef<'a>>;
+ type Iterator: Iterator<Item = TermRef<'a>>;
fn iter(&'a Term) -> Self::Iterator;
FactInstruction::GetConstant(lvl, constant, reg)
}
- fn to_structure(ct: ClauseType, arity: usize, reg: RegType) -> Self
- {
+ fn to_structure(ct: ClauseType, arity: usize, reg: RegType) -> Self {
FactInstruction::GetStructure(ct, arity, reg)
}
fn is_void_instr(&self) -> bool {
match self {
&FactInstruction::UnifyVoid(_) => true,
- _ => false
+ _ => false,
}
}
fn is_void_instr(&self) -> bool {
match self {
&QueryInstruction::SetVoid(_) => true,
- _ => false
+ _ => false,
}
}
use prolog::machine::machine_errors::*;
use prolog::machine::machine_indices::*;
-use termion::input::TermRead;
use termion::event::Key;
+use termion::input::TermRead;
-use std::io::stdin;
use std::fmt;
+use std::io::stdin;
impl fmt::Display for LocalCodePtr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- LocalCodePtr::DirEntry(p) =>
- write!(f, "LocalCodePtr::DirEntry({})", p),
- LocalCodePtr::InSituDirEntry(p) =>
- write!(f, "LocalCodePtr::InSituDirEntry({})", p),
- LocalCodePtr::TopLevel(cn, p) =>
- write!(f, "LocalCodePtr::TopLevel({}, {})", cn, p),
- LocalCodePtr::UserGoalExpansion(p) =>
- write!(f, "LocalCodePtr::UserGoalExpansion({})", p),
- LocalCodePtr::UserTermExpansion(p) =>
- write!(f, "LocalCodePtr::UserTermExpansion({})", p),
+ LocalCodePtr::DirEntry(p) => write!(f, "LocalCodePtr::DirEntry({})", p),
+ LocalCodePtr::InSituDirEntry(p) => write!(f, "LocalCodePtr::InSituDirEntry({})", p),
+ LocalCodePtr::TopLevel(cn, p) => write!(f, "LocalCodePtr::TopLevel({}, {})", cn, p),
+ LocalCodePtr::UserGoalExpansion(p) => {
+ write!(f, "LocalCodePtr::UserGoalExpansion({})", p)
+ }
+ LocalCodePtr::UserTermExpansion(p) => {
+ write!(f, "LocalCodePtr::UserTermExpansion({})", p)
+ }
}
}
}
impl fmt::Display for REPLCodePtr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- REPLCodePtr::CompileBatch =>
- write!(f, "REPLCodePtr::CompileBatch"),
- REPLCodePtr::SubmitQueryAndPrintResults =>
+ REPLCodePtr::CompileBatch => write!(f, "REPLCodePtr::CompileBatch"),
+ REPLCodePtr::SubmitQueryAndPrintResults => {
write!(f, "REPLCodePtr::SubmitQueryAndPrintResults")
+ }
}
}
}
impl fmt::Display for IndexPtr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- &IndexPtr::Undefined =>
- write!(f, "undefined"),
- &IndexPtr::Index(i) =>
- write!(f, "{}", i)
+ &IndexPtr::Undefined => write!(f, "undefined"),
+ &IndexPtr::Index(i) => write!(f, "{}", i),
}
}
}
impl fmt::Display for FactInstruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- &FactInstruction::GetConstant(lvl, ref constant, ref r) =>
- write!(f, "get_constant {}, {}{}", constant, lvl, r.reg_num()),
- &FactInstruction::GetList(lvl, ref r) =>
- write!(f, "get_list {}{}", lvl, r.reg_num()),
- &FactInstruction::GetStructure(ref ct, ref arity, ref r) =>
- write!(f, "get_structure {}/{}, {}", ct.name(), arity, r),
- &FactInstruction::GetValue(ref x, ref a) =>
- write!(f, "get_value {}, A{}", x, a),
- &FactInstruction::GetVariable(ref x, ref a) =>
- write!(f, "fact:get_variable {}, A{}", x, a),
- &FactInstruction::UnifyConstant(ref constant) =>
- write!(f, "unify_constant {}", constant),
- &FactInstruction::UnifyVariable(ref r) =>
- write!(f, "unify_variable {}", r),
- &FactInstruction::UnifyLocalValue(ref r) =>
- write!(f, "unify_local_value {}", r),
- &FactInstruction::UnifyValue(ref r) =>
- write!(f, "unify_value {}", r),
- &FactInstruction::UnifyVoid(n) =>
- write!(f, "unify_void {}", n)
+ &FactInstruction::GetConstant(lvl, ref constant, ref r) => {
+ write!(f, "get_constant {}, {}{}", constant, lvl, r.reg_num())
+ }
+ &FactInstruction::GetList(lvl, ref r) => write!(f, "get_list {}{}", lvl, r.reg_num()),
+ &FactInstruction::GetStructure(ref ct, ref arity, ref r) => {
+ write!(f, "get_structure {}/{}, {}", ct.name(), arity, r)
+ }
+ &FactInstruction::GetValue(ref x, ref a) => write!(f, "get_value {}, A{}", x, a),
+ &FactInstruction::GetVariable(ref x, ref a) => {
+ write!(f, "fact:get_variable {}, A{}", x, a)
+ }
+ &FactInstruction::UnifyConstant(ref constant) => {
+ write!(f, "unify_constant {}", constant)
+ }
+ &FactInstruction::UnifyVariable(ref r) => write!(f, "unify_variable {}", r),
+ &FactInstruction::UnifyLocalValue(ref r) => write!(f, "unify_local_value {}", r),
+ &FactInstruction::UnifyValue(ref r) => write!(f, "unify_value {}", r),
+ &FactInstruction::UnifyVoid(n) => write!(f, "unify_void {}", n),
}
}
}
impl fmt::Display for QueryInstruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- &QueryInstruction::GetVariable(ref x, ref a) =>
- write!(f, "query:get_variable {}, A{}", x, a),
- &QueryInstruction::PutConstant(lvl, ref constant, ref r) =>
- write!(f, "put_constant {}, {}{}", constant, lvl, r.reg_num()),
- &QueryInstruction::PutList(lvl, ref r) =>
- write!(f, "put_list {}{}", lvl, r.reg_num()),
- &QueryInstruction::PutStructure(ref ct, ref arity, ref r) =>
- write!(f, "put_structure {}/{}, {}", ct.name(), arity, r),
- &QueryInstruction::PutUnsafeValue(y, a) =>
- write!(f, "put_unsafe_value Y{}, A{}", y, a),
- &QueryInstruction::PutValue(ref x, ref a) =>
- write!(f, "put_value {}, A{}", x, a),
- &QueryInstruction::PutVariable(ref x, ref a) =>
- write!(f, "put_variable {}, A{}", x, a),
- &QueryInstruction::SetConstant(ref constant) =>
- write!(f, "set_constant {}", constant),
- &QueryInstruction::SetLocalValue(ref r) =>
- write!(f, "set_local_value {}", r),
- &QueryInstruction::SetVariable(ref r) =>
- write!(f, "set_variable {}", r),
- &QueryInstruction::SetValue(ref r) =>
- write!(f, "set_value {}", r),
- &QueryInstruction::SetVoid(n) =>
- write!(f, "set_void {}", n)
+ &QueryInstruction::GetVariable(ref x, ref a) => {
+ write!(f, "query:get_variable {}, A{}", x, a)
+ }
+ &QueryInstruction::PutConstant(lvl, ref constant, ref r) => {
+ write!(f, "put_constant {}, {}{}", constant, lvl, r.reg_num())
+ }
+ &QueryInstruction::PutList(lvl, ref r) => write!(f, "put_list {}{}", lvl, r.reg_num()),
+ &QueryInstruction::PutStructure(ref ct, ref arity, ref r) => {
+ write!(f, "put_structure {}/{}, {}", ct.name(), arity, r)
+ }
+ &QueryInstruction::PutUnsafeValue(y, a) => write!(f, "put_unsafe_value Y{}, A{}", y, a),
+ &QueryInstruction::PutValue(ref x, ref a) => write!(f, "put_value {}, A{}", x, a),
+ &QueryInstruction::PutVariable(ref x, ref a) => write!(f, "put_variable {}, A{}", x, a),
+ &QueryInstruction::SetConstant(ref constant) => write!(f, "set_constant {}", constant),
+ &QueryInstruction::SetLocalValue(ref r) => write!(f, "set_local_value {}", r),
+ &QueryInstruction::SetVariable(ref r) => write!(f, "set_variable {}", r),
+ &QueryInstruction::SetValue(ref r) => write!(f, "set_value {}", r),
+ &QueryInstruction::SetVoid(n) => write!(f, "set_void {}", n),
}
}
}
impl fmt::Display for ClauseType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- &ClauseType::System(SystemClauseType::SetCutPoint(r)) =>
- write!(f, "$set_cp({})", r),
- &ClauseType::Named(ref name, _, ref idx)
- | &ClauseType::Op(ref name, _, ref idx) =>
- {
+ &ClauseType::System(SystemClauseType::SetCutPoint(r)) => write!(f, "$set_cp({})", r),
+ &ClauseType::Named(ref name, _, ref idx) | &ClauseType::Op(ref name, _, ref idx) => {
let idx = idx.0.borrow();
write!(f, "{}:{}/{}", idx.1, name, idx.0)
- },
- ref ct => write!(f, "{}", ct.name())
+ }
+ ref ct => write!(f, "{}", ct.name()),
}
}
}
impl fmt::Display for HeapCellValue {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- &HeapCellValue::Addr(ref addr) =>
- write!(f, "{}", addr),
- &HeapCellValue::NamedStr(arity, ref name, Some(ref cell)) =>
- write!(f, "{}/{} (op, priority: {}, spec: {})", name.as_str(), arity,
- cell.prec(), cell.assoc()),
- &HeapCellValue::NamedStr(arity, ref name, None) =>
+ &HeapCellValue::Addr(ref addr) => write!(f, "{}", addr),
+ &HeapCellValue::NamedStr(arity, ref name, Some(ref cell)) => write!(
+ f,
+ "{}/{} (op, priority: {}, spec: {})",
+ name.as_str(),
+ arity,
+ cell.prec(),
+ cell.assoc()
+ ),
+ &HeapCellValue::NamedStr(arity, ref name, None) => {
write!(f, "{}/{}", name.as_str(), arity)
+ }
}
}
}
impl fmt::Display for DBRef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- &DBRef::NamedPred(ref name, arity, _) => write!(f, "db_ref:named:{}/{}", name, arity),
- &DBRef::Op(priority, spec, ref name, ..) => write!(f, "db_ref:op({}, {}, {})", priority,
- spec, name)
+ &DBRef::NamedPred(ref name, arity, _) => write!(f, "db_ref:named:{}/{}", name, arity),
+ &DBRef::Op(priority, spec, ref name, ..) => {
+ write!(f, "db_ref:op({}, {}, {})", priority, spec, name)
+ }
}
}
}
&Addr::Lis(l) => write!(f, "Addr::Lis({})", l),
&Addr::AttrVar(h) => write!(f, "Addr::AttrVar({})", h),
&Addr::HeapCell(h) => write!(f, "Addr::HeapCell({})", h),
- &Addr::StackCell(fr, sc)=> write!(f, "Addr::StackCell({}, {})", fr, sc),
- &Addr::Str(s) => write!(f, "Addr::Str({})", s)
+ &Addr::StackCell(fr, sc) => write!(f, "Addr::StackCell({}, {})", fr, sc),
+ &Addr::Str(s) => write!(f, "Addr::Str({})", s),
}
}
}
impl fmt::Display for ControlInstruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- &ControlInstruction::Allocate(num_cells) =>
- write!(f, "allocate {}", num_cells),
- &ControlInstruction::CallClause(ref ct, arity, pvs, true, true) =>
- write!(f, "call_with_default_policy {}/{}, {}", ct, arity, pvs),
- &ControlInstruction::CallClause(ref ct, arity, pvs, false, true) =>
- write!(f, "execute_with_default_policy {}/{}, {}", ct, arity, pvs),
- &ControlInstruction::CallClause(ref ct, arity, pvs, true, false) =>
- write!(f, "execute {}/{}, {}", ct, arity, pvs),
- &ControlInstruction::CallClause(ref ct, arity, pvs, false, false) =>
- write!(f, "call {}/{}, {}", ct, arity, pvs),
- &ControlInstruction::Deallocate =>
- write!(f, "deallocate"),
- &ControlInstruction::JmpBy(arity, offset, pvs, false) =>
- write!(f, "jmp_by_call {}/{}, {}", offset, arity, pvs),
- &ControlInstruction::JmpBy(arity, offset, pvs, true) =>
- write!(f, "jmp_by_execute {}/{}, {}", offset, arity, pvs),
- &ControlInstruction::Proceed =>
- write!(f, "proceed"),
+ &ControlInstruction::Allocate(num_cells) => write!(f, "allocate {}", num_cells),
+ &ControlInstruction::CallClause(ref ct, arity, pvs, true, true) => {
+ write!(f, "call_with_default_policy {}/{}, {}", ct, arity, pvs)
+ }
+ &ControlInstruction::CallClause(ref ct, arity, pvs, false, true) => {
+ write!(f, "execute_with_default_policy {}/{}, {}", ct, arity, pvs)
+ }
+ &ControlInstruction::CallClause(ref ct, arity, pvs, true, false) => {
+ write!(f, "execute {}/{}, {}", ct, arity, pvs)
+ }
+ &ControlInstruction::CallClause(ref ct, arity, pvs, false, false) => {
+ write!(f, "call {}/{}, {}", ct, arity, pvs)
+ }
+ &ControlInstruction::Deallocate => write!(f, "deallocate"),
+ &ControlInstruction::JmpBy(arity, offset, pvs, false) => {
+ write!(f, "jmp_by_call {}/{}, {}", offset, arity, pvs)
+ }
+ &ControlInstruction::JmpBy(arity, offset, pvs, true) => {
+ write!(f, "jmp_by_execute {}/{}, {}", offset, arity, pvs)
+ }
+ &ControlInstruction::Proceed => write!(f, "proceed"),
}
}
}
impl fmt::Display for IndexedChoiceInstruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- &IndexedChoiceInstruction::Try(offset) =>
- write!(f, "try {}", offset),
- &IndexedChoiceInstruction::Retry(offset) =>
- write!(f, "retry {}", offset),
- &IndexedChoiceInstruction::Trust(offset) =>
- write!(f, "trust {}", offset)
+ &IndexedChoiceInstruction::Try(offset) => write!(f, "try {}", offset),
+ &IndexedChoiceInstruction::Retry(offset) => write!(f, "retry {}", offset),
+ &IndexedChoiceInstruction::Trust(offset) => write!(f, "trust {}", offset),
}
}
}
impl fmt::Display for ChoiceInstruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- &ChoiceInstruction::TryMeElse(offset) =>
- write!(f, "try_me_else {}", offset),
- &ChoiceInstruction::DefaultRetryMeElse(offset) =>
- write!(f, "retry_me_else_by_default {}", offset),
- &ChoiceInstruction::RetryMeElse(offset) =>
- write!(f, "retry_me_else {}", offset),
- &ChoiceInstruction::DefaultTrustMe =>
- write!(f, "trust_me_by_default"),
- &ChoiceInstruction::TrustMe =>
- write!(f, "trust_me")
+ &ChoiceInstruction::TryMeElse(offset) => write!(f, "try_me_else {}", offset),
+ &ChoiceInstruction::DefaultRetryMeElse(offset) => {
+ write!(f, "retry_me_else_by_default {}", offset)
+ }
+ &ChoiceInstruction::RetryMeElse(offset) => write!(f, "retry_me_else {}", offset),
+ &ChoiceInstruction::DefaultTrustMe => write!(f, "trust_me_by_default"),
+ &ChoiceInstruction::TrustMe => write!(f, "trust_me"),
}
}
}
impl fmt::Display for IndexingInstruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- &IndexingInstruction::SwitchOnTerm(v, c, l, s) =>
- write!(f, "switch_on_term {}, {}, {}, {}", v, c, l, s),
- &IndexingInstruction::SwitchOnConstant(num_cs, _) =>
- write!(f, "switch_on_constant {}", num_cs),
- &IndexingInstruction::SwitchOnStructure(num_ss, _) =>
+ &IndexingInstruction::SwitchOnTerm(v, c, l, s) => {
+ write!(f, "switch_on_term {}, {}, {}, {}", v, c, l, s)
+ }
+ &IndexingInstruction::SwitchOnConstant(num_cs, _) => {
+ write!(f, "switch_on_constant {}", num_cs)
+ }
+ &IndexingInstruction::SwitchOnStructure(num_ss, _) => {
write!(f, "switch_on_structure {}", num_ss)
+ }
}
}
}
impl fmt::Display for SessionError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- &SessionError::CannotOverwriteBuiltIn(ref msg) =>
- write!(f, "cannot overwrite {}", msg),
- &SessionError::CannotOverwriteImport(ref msg) =>
- write!(f, "cannot overwrite import {}", msg),
- &SessionError::InvalidFileName(ref filename) =>
- write!(f, "filename {} is invalid", filename),
+ &SessionError::CannotOverwriteBuiltIn(ref msg) => write!(f, "cannot overwrite {}", msg),
+ &SessionError::CannotOverwriteImport(ref msg) => {
+ write!(f, "cannot overwrite import {}", msg)
+ }
+ &SessionError::InvalidFileName(ref filename) => {
+ write!(f, "filename {} is invalid", filename)
+ }
&SessionError::ModuleNotFound => write!(f, "module not found."),
- &SessionError::ModuleDoesNotContainExport =>
- write!(f, "module does not contain claimed export."),
- &SessionError::NoModuleDeclaration(ref name) =>
- write!(f, "file {}.pl lacks an expected module declaration.", name),
- &SessionError::OpIsInfixAndPostFix(_) =>
- write!(f, "cannot define an op to be both postfix and infix."),
- &SessionError::NamelessEntry =>
- write!(f, "the predicate head is not an atom or clause."),
- &SessionError::ParserError(ref e) =>
- write!(f, "syntax_error({})", e.as_str()),
- &SessionError::UserPrompt =>
- write!(f, "enter predicate at [user] prompt")
+ &SessionError::ModuleDoesNotContainExport => {
+ write!(f, "module does not contain claimed export.")
+ }
+ &SessionError::NoModuleDeclaration(ref name) => {
+ write!(f, "file {}.pl lacks an expected module declaration.", name)
+ }
+ &SessionError::OpIsInfixAndPostFix(_) => {
+ write!(f, "cannot define an op to be both postfix and infix.")
+ }
+ &SessionError::NamelessEntry => {
+ write!(f, "the predicate head is not an atom or clause.")
+ }
+ &SessionError::ParserError(ref e) => write!(f, "syntax_error({})", e.as_str()),
+ &SessionError::UserPrompt => write!(f, "enter predicate at [user] prompt"),
}
}
}
match self {
&Number::Float(fl) => write!(f, "{}", fl),
&Number::Integer(ref bi) => write!(f, "{}", bi),
- &Number::Rational(ref r) => write!(f, "{}", r)
+ &Number::Rational(ref r) => write!(f, "{}", r),
}
}
}
impl fmt::Display for ArithmeticInstruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- &ArithmeticInstruction::Abs(ref a1, ref t) =>
- write!(f, "abs {}, @{}", a1, t),
- &ArithmeticInstruction::Add(ref a1, ref a2, ref t) =>
- write!(f, "add {}, {}, @{}", a1, a2, t),
- &ArithmeticInstruction::Sub(ref a1, ref a2, ref t) =>
- write!(f, "sub {}, {}, @{}", a1, a2, t),
- &ArithmeticInstruction::Mul(ref a1, ref a2, ref t) =>
- write!(f, "mul {}, {}, @{}", a1, a2, t),
- &ArithmeticInstruction::Pow(ref a1, ref a2, ref t) =>
- write!(f, "** {}, {}, @{}", a1, a2, t),
- &ArithmeticInstruction::IntPow(ref a1, ref a2, ref t) =>
- write!(f, "^ {}, {}, @{}", a1, a2, t),
- &ArithmeticInstruction::Div(ref a1, ref a2, ref t) =>
- write!(f, "div {}, {}, @{}", a1, a2, t),
- &ArithmeticInstruction::IDiv(ref a1, ref a2, ref t) =>
- write!(f, "idiv {}, {}, @{}", a1, a2, t),
- &ArithmeticInstruction::Max(ref a1, ref a2, ref t) =>
- write!(f, "max {}, {}, @{}", a1, a2, t),
- &ArithmeticInstruction::Min(ref a1, ref a2, ref t) =>
- write!(f, "min {}, {}, @{}", a1, a2, t),
- &ArithmeticInstruction::IntFloorDiv(ref a1, ref a2, ref t) =>
- write!(f, "int_floor_div {}, {}, @{}", a1, a2, t),
- &ArithmeticInstruction::RDiv(ref a1, ref a2, ref t) =>
- write!(f, "rdiv {}, {}, @{}", a1, a2, t),
- &ArithmeticInstruction::Shl(ref a1, ref a2, ref t) =>
- write!(f, "shl {}, {}, @{}", a1, a2, t),
- &ArithmeticInstruction::Shr(ref a1, ref a2, ref t) =>
- write!(f, "shr {}, {}, @{}", a1, a2, t),
- &ArithmeticInstruction::Xor(ref a1, ref a2, ref t) =>
- write!(f, "xor {}, {}, @{}", a1, a2, t),
- &ArithmeticInstruction::And(ref a1, ref a2, ref t) =>
- write!(f, "and {}, {}, @{}", a1, a2, t),
- &ArithmeticInstruction::Or(ref a1, ref a2, ref t) =>
- write!(f, "or {}, {}, @{}", a1, a2, t),
- &ArithmeticInstruction::Mod(ref a1, ref a2, ref t) =>
- write!(f, "mod {}, {}, @{}", a1, a2, t),
- &ArithmeticInstruction::Rem(ref a1, ref a2, ref t) =>
- write!(f, "rem {}, {}, @{}", a1, a2, t),
- &ArithmeticInstruction::ATan2(ref a1, ref a2, ref t) =>
- write!(f, "atan2 {}, {}, @{}", a1, a2, t),
- &ArithmeticInstruction::Plus(ref a, ref t) =>
- write!(f, "plus {}, @{}", a, t),
- &ArithmeticInstruction::Neg(ref a, ref t) =>
- write!(f, "neg {}, @{}", a, t),
- &ArithmeticInstruction::Cos(ref a, ref t) =>
- write!(f, "cos {}, @{}", a, t),
- &ArithmeticInstruction::Sin(ref a, ref t) =>
- write!(f, "sin {}, @{}", a, t),
- &ArithmeticInstruction::Tan(ref a, ref t) =>
- write!(f, "tan {}, @{}", a, t),
- &ArithmeticInstruction::ATan(ref a, ref t) =>
- write!(f, "atan {}, @{}", a, t),
- &ArithmeticInstruction::ASin(ref a, ref t) =>
- write!(f, "asin {}, @{}", a, t),
- &ArithmeticInstruction::ACos(ref a, ref t) =>
- write!(f, "acos {}, @{}", a, t),
- &ArithmeticInstruction::Log(ref a, ref t) =>
- write!(f, "log {}, @{}", a, t),
- &ArithmeticInstruction::Exp(ref a, ref t) =>
- write!(f, "exp {}, @{}", a, t),
- &ArithmeticInstruction::Sqrt(ref a, ref t) =>
- write!(f, "sqrt {}, @{}", a, t),
- &ArithmeticInstruction::BitwiseComplement(ref a, ref t) =>
- write!(f, "bitwise_complement {}, @{}", a, t),
- &ArithmeticInstruction::Truncate(ref a, ref t) =>
- write!(f, "truncate {}, @{}", a, t),
- &ArithmeticInstruction::Round(ref a, ref t) =>
- write!(f, "round {}, @{}", a, t),
- &ArithmeticInstruction::Ceiling(ref a, ref t) =>
- write!(f, "ceiling {}, @{}", a, t),
- &ArithmeticInstruction::Floor(ref a, ref t) =>
- write!(f, "floor {}, @{}", a, t),
- &ArithmeticInstruction::Float(ref a, ref t) =>
- write!(f, "float {}, @{}", a, t),
+ &ArithmeticInstruction::Abs(ref a1, ref t) => write!(f, "abs {}, @{}", a1, t),
+ &ArithmeticInstruction::Add(ref a1, ref a2, ref t) => {
+ write!(f, "add {}, {}, @{}", a1, a2, t)
+ }
+ &ArithmeticInstruction::Sub(ref a1, ref a2, ref t) => {
+ write!(f, "sub {}, {}, @{}", a1, a2, t)
+ }
+ &ArithmeticInstruction::Mul(ref a1, ref a2, ref t) => {
+ write!(f, "mul {}, {}, @{}", a1, a2, t)
+ }
+ &ArithmeticInstruction::Pow(ref a1, ref a2, ref t) => {
+ write!(f, "** {}, {}, @{}", a1, a2, t)
+ }
+ &ArithmeticInstruction::IntPow(ref a1, ref a2, ref t) => {
+ write!(f, "^ {}, {}, @{}", a1, a2, t)
+ }
+ &ArithmeticInstruction::Div(ref a1, ref a2, ref t) => {
+ write!(f, "div {}, {}, @{}", a1, a2, t)
+ }
+ &ArithmeticInstruction::IDiv(ref a1, ref a2, ref t) => {
+ write!(f, "idiv {}, {}, @{}", a1, a2, t)
+ }
+ &ArithmeticInstruction::Max(ref a1, ref a2, ref t) => {
+ write!(f, "max {}, {}, @{}", a1, a2, t)
+ }
+ &ArithmeticInstruction::Min(ref a1, ref a2, ref t) => {
+ write!(f, "min {}, {}, @{}", a1, a2, t)
+ }
+ &ArithmeticInstruction::IntFloorDiv(ref a1, ref a2, ref t) => {
+ write!(f, "int_floor_div {}, {}, @{}", a1, a2, t)
+ }
+ &ArithmeticInstruction::RDiv(ref a1, ref a2, ref t) => {
+ write!(f, "rdiv {}, {}, @{}", a1, a2, t)
+ }
+ &ArithmeticInstruction::Shl(ref a1, ref a2, ref t) => {
+ write!(f, "shl {}, {}, @{}", a1, a2, t)
+ }
+ &ArithmeticInstruction::Shr(ref a1, ref a2, ref t) => {
+ write!(f, "shr {}, {}, @{}", a1, a2, t)
+ }
+ &ArithmeticInstruction::Xor(ref a1, ref a2, ref t) => {
+ write!(f, "xor {}, {}, @{}", a1, a2, t)
+ }
+ &ArithmeticInstruction::And(ref a1, ref a2, ref t) => {
+ write!(f, "and {}, {}, @{}", a1, a2, t)
+ }
+ &ArithmeticInstruction::Or(ref a1, ref a2, ref t) => {
+ write!(f, "or {}, {}, @{}", a1, a2, t)
+ }
+ &ArithmeticInstruction::Mod(ref a1, ref a2, ref t) => {
+ write!(f, "mod {}, {}, @{}", a1, a2, t)
+ }
+ &ArithmeticInstruction::Rem(ref a1, ref a2, ref t) => {
+ write!(f, "rem {}, {}, @{}", a1, a2, t)
+ }
+ &ArithmeticInstruction::ATan2(ref a1, ref a2, ref t) => {
+ write!(f, "atan2 {}, {}, @{}", a1, a2, t)
+ }
+ &ArithmeticInstruction::Plus(ref a, ref t) => write!(f, "plus {}, @{}", a, t),
+ &ArithmeticInstruction::Neg(ref a, ref t) => write!(f, "neg {}, @{}", a, t),
+ &ArithmeticInstruction::Cos(ref a, ref t) => write!(f, "cos {}, @{}", a, t),
+ &ArithmeticInstruction::Sin(ref a, ref t) => write!(f, "sin {}, @{}", a, t),
+ &ArithmeticInstruction::Tan(ref a, ref t) => write!(f, "tan {}, @{}", a, t),
+ &ArithmeticInstruction::ATan(ref a, ref t) => write!(f, "atan {}, @{}", a, t),
+ &ArithmeticInstruction::ASin(ref a, ref t) => write!(f, "asin {}, @{}", a, t),
+ &ArithmeticInstruction::ACos(ref a, ref t) => write!(f, "acos {}, @{}", a, t),
+ &ArithmeticInstruction::Log(ref a, ref t) => write!(f, "log {}, @{}", a, t),
+ &ArithmeticInstruction::Exp(ref a, ref t) => write!(f, "exp {}, @{}", a, t),
+ &ArithmeticInstruction::Sqrt(ref a, ref t) => write!(f, "sqrt {}, @{}", a, t),
+ &ArithmeticInstruction::BitwiseComplement(ref a, ref t) => {
+ write!(f, "bitwise_complement {}, @{}", a, t)
+ }
+ &ArithmeticInstruction::Truncate(ref a, ref t) => write!(f, "truncate {}, @{}", a, t),
+ &ArithmeticInstruction::Round(ref a, ref t) => write!(f, "round {}, @{}", a, t),
+ &ArithmeticInstruction::Ceiling(ref a, ref t) => write!(f, "ceiling {}, @{}", a, t),
+ &ArithmeticInstruction::Floor(ref a, ref t) => write!(f, "floor {}, @{}", a, t),
+ &ArithmeticInstruction::Float(ref a, ref t) => write!(f, "float {}, @{}", a, t),
}
}
}
impl fmt::Display for CutInstruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- &CutInstruction::Cut(r) =>
- write!(f, "cut {}", r),
- &CutInstruction::NeckCut =>
- write!(f, "neck_cut"),
- &CutInstruction::GetLevel(r) =>
- write!(f, "get_level {}", r),
- &CutInstruction::GetLevelAndUnify(r) =>
- write!(f, "get_level_and_unify {}", r)
+ &CutInstruction::Cut(r) => write!(f, "cut {}", r),
+ &CutInstruction::NeckCut => write!(f, "neck_cut"),
+ &CutInstruction::GetLevel(r) => write!(f, "get_level {}", r),
+ &CutInstruction::GetLevelAndUnify(r) => write!(f, "get_level_and_unify {}", r),
}
}
}
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&Level::Root | &Level::Shallow => write!(f, "A"),
- &Level::Deep => write!(f, "X")
+ &Level::Deep => write!(f, "X"),
}
}
}
pub enum ContinueResult {
ContinueQuery,
- Conclude
+ Conclude,
}
-pub
-fn next_keypress() -> ContinueResult
-{
+pub fn next_keypress() -> ContinueResult {
let stdin = stdin();
for c in stdin.keys() {
match c.unwrap() {
- Key::Char(' ') | Key::Char(';') =>
- return ContinueResult::ContinueQuery,
- Key::Char('.') =>
- return ContinueResult::Conclude,
+ Key::Char(' ') | Key::Char(';') => return ContinueResult::ContinueQuery,
+ Key::Char('.') => return ContinueResult::Conclude,
_ => {}
}
}
use prolog_parser::ast::parsing_stream;
use prolog::heap_print::*;
-use prolog::machine::*;
use prolog::machine::compile::*;
use prolog::machine::machine_errors::*;
use prolog::machine::machine_indices::*;
use prolog::machine::toplevel::*;
+use prolog::machine::*;
use prolog::read::readline;
use indexmap::IndexSet;
pub struct TestOutputter {
results: Vec<IndexSet<String>>,
contents: IndexSet<String>,
- focus: String
+ focus: String,
}
impl TestOutputter {
type Output = Vec<IndexSet<String>>;
fn new() -> Self {
- TestOutputter { results: vec![],
- contents: IndexSet::new(),
- focus: String::new() }
+ TestOutputter {
+ results: vec![],
+ contents: IndexSet::new(),
+ focus: String::new(),
+ }
}
fn append(&mut self, focus: &str) {
}
}
-pub fn collect_test_output(wam: &mut Machine, alloc_locs: AllocVarDict) -> Vec<IndexSet<String>>
-{
+pub fn collect_test_output(wam: &mut Machine, alloc_locs: AllocVarDict) -> Vec<IndexSet<String>> {
let mut output = TestOutputter::new();
output = wam.test_heap_view(output);
output.result()
}
-pub fn collect_test_output_with_limit(wam: &mut Machine, alloc_locs: AllocVarDict, limit: usize)
- -> Vec<IndexSet<String>>
-{
+pub fn collect_test_output_with_limit(
+ wam: &mut Machine,
+ alloc_locs: AllocVarDict,
+ limit: usize,
+) -> Vec<IndexSet<String>> {
let mut output = TestOutputter::new();
output = wam.test_heap_view(output);
output.cache();
- let mut count = 1;
+ let mut count = 1;
if count == limit {
return output.result();
}
- while let EvalSession::SubsequentQuerySuccess = wam.continue_query(&alloc_locs)
- {
+ while let EvalSession::SubsequentQuerySuccess = wam.continue_query(&alloc_locs) {
output = wam.test_heap_view(output);
output.cache();
}
#[allow(dead_code)]
-pub fn submit(wam: &mut Machine, buffer: &str) -> bool
-{
+pub fn submit(wam: &mut Machine, buffer: &str) -> bool {
wam.reset();
match submit_code(wam, buffer) {
- EvalSession::InitialQuerySuccess(_) |
- EvalSession::EntrySuccess |
- EvalSession::SubsequentQuerySuccess =>
- true,
- _ => false
+ EvalSession::InitialQuerySuccess(_)
+ | EvalSession::EntrySuccess
+ | EvalSession::SubsequentQuerySuccess => true,
+ _ => false,
}
}
#[allow(dead_code)]
-pub fn submit_query(wam: &mut Machine, buffer: &str, result: Vec<IndexSet<String>>) -> bool
-{
+pub fn submit_query(wam: &mut Machine, buffer: &str, result: Vec<IndexSet<String>>) -> bool {
wam.reset();
match stream_to_toplevel(parsing_stream(buffer.as_bytes()), wam) {
- Ok(term) =>
- match compile_term(wam, term) {
- EvalSession::InitialQuerySuccess(alloc_locs) =>
- result == collect_test_output(wam, alloc_locs),
- EvalSession::EntrySuccess => true,
- _ => false
- },
- Err(_) => panic!("syntax error")
+ Ok(term) => match compile_term(wam, term) {
+ EvalSession::InitialQuerySuccess(alloc_locs) => {
+ result == collect_test_output(wam, alloc_locs)
+ }
+ EvalSession::EntrySuccess => true,
+ _ => false,
+ },
+ Err(_) => panic!("syntax error"),
}
}
#[allow(dead_code)]
-pub fn submit_query_without_results(wam: &mut Machine, buffer: &str) -> bool
-{
+pub fn submit_query_without_results(wam: &mut Machine, buffer: &str) -> bool {
wam.reset();
match stream_to_toplevel(parsing_stream(buffer.as_bytes()), wam) {
- Ok(term) =>
- match compile_term(wam, term) {
- EvalSession::InitialQuerySuccess(..)
- | EvalSession::EntrySuccess => true,
- _ => false
- },
- Err(_) => panic!("syntax error")
+ Ok(term) => match compile_term(wam, term) {
+ EvalSession::InitialQuerySuccess(..) | EvalSession::EntrySuccess => true,
+ _ => false,
+ },
+ Err(_) => panic!("syntax error"),
}
}
#[allow(dead_code)]
-pub fn submit_query_with_limit(wam: &mut Machine, buffer: &str,
- result: Vec<IndexSet<String>>, limit: usize)
- -> bool
-{
+pub fn submit_query_with_limit(
+ wam: &mut Machine,
+ buffer: &str,
+ result: Vec<IndexSet<String>>,
+ limit: usize,
+) -> bool {
wam.reset();
match stream_to_toplevel(parsing_stream(buffer.as_bytes()), wam) {
- Ok(term) =>
- match compile_term(wam, term) {
- EvalSession::InitialQuerySuccess(alloc_locs) =>
- result == collect_test_output_with_limit(wam, alloc_locs, limit),
- EvalSession::EntrySuccess => true,
- _ => false
- },
- Err(_) => panic!("syntax_error")
+ Ok(term) => match compile_term(wam, term) {
+ EvalSession::InitialQuerySuccess(alloc_locs) => {
+ result == collect_test_output_with_limit(wam, alloc_locs, limit)
+ }
+ EvalSession::EntrySuccess => true,
+ _ => false,
+ },
+ Err(_) => panic!("syntax_error"),
}
}
#[allow(unused_macros)]
macro_rules! expand_strs {
- ($arr:expr) => (
+ ($arr:expr) => {
$arr.into_iter().map(|s| String::from(*s)).collect()
- )
+ };
}
#[allow(unused_macros)]
#[allow(unused_macros)]
macro_rules! assert_prolog_failure {
- ($wam: expr, $buf: expr) => (
+ ($wam: expr, $buf: expr) => {
assert_eq!(submit_query_without_results($wam, $buf), false)
- )
+ };
}
#[allow(unused_macros)]
}
#[test]
-fn test_queries_on_facts()
-{
+fn test_queries_on_facts() {
let mut wam = Machine::new(readline::input_stream());
submit(&mut wam, "p(Z, Z).");
submit(&mut wam, "p(f(X), h(Y, f(a)), Y).");
- assert_prolog_success!(&mut wam, "p(Z, h(Z, W), f(W)).", [["W = f(a)", "Z = f(f(a))"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "p(Z, h(Z, W), f(W)).",
+ [["W = f(a)", "Z = f(f(a))"]]
+ );
}
#[test]
submit(&mut wam, "p(f(f(a), g(b), X), g(b), h) :- q(X, Y).");
submit(&mut wam, "q(X, Y).");
- assert_prolog_success!(&mut wam, "p(f(X, Y, Z), g(b), h).",
- [["Z = _3", "Y = g(b)", "X = f(a)"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "p(f(X, Y, Z), g(b), h).",
+ [["Z = _3", "Y = g(b)", "X = f(a)"]]
+ );
assert_prolog_failure!(&mut wam, "p(f(X, g(Y), Z), g(Z), X).");
- assert_prolog_success!(&mut wam, "p(f(X, g(Y), Z), g(Z), h).",
- [["Z = b", "Y = b", "X = f(a)"]]);
- assert_prolog_success!(&mut wam, "p(Z, Y, X).",
- [["X = h", "Y = g(b)", "Z = f(f(a),g(b),_7)"]]);
- assert_prolog_success!(&mut wam, "p(f(X, Y, Z), Y, h).",
- [["Y = g(b)", "Z = _3", "X = f(a)"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "p(f(X, g(Y), Z), g(Z), h).",
+ [["Z = b", "Y = b", "X = f(a)"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "p(Z, Y, X).",
+ [["X = h", "Y = g(b)", "Z = f(f(a),g(b),_7)"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "p(f(X, Y, Z), Y, h).",
+ [["Y = g(b)", "Z = _3", "X = f(a)"]]
+ );
submit(&mut wam, "p(_, f(_, Y, _)) :- h(Y).");
submit(&mut wam, "h(y).");
submit(&mut wam, "p(X, a). p(b, X).");
assert_prolog_success!(&mut wam, "p(x, Y).", [["Y = a"]]);
- assert_prolog_success!(&mut wam, "p(X, a).", [["X = _0"], // 1st case
- ["X = b"]]); // 2nd case.
- assert_prolog_success!(&mut wam, "p(b, X).", [["X = a"], // 1st case
- ["X = _0"]]); // 2nd case.
- assert_prolog_success!(&mut wam, "p(X, X).", [["X = a"],
- ["X = b"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "p(X, a).",
+ [
+ ["X = _0"], // 1st case
+ ["X = b"]
+ ]
+ ); // 2nd case.
+ assert_prolog_success!(
+ &mut wam,
+ "p(b, X).",
+ [
+ ["X = a"], // 1st case
+ ["X = _0"]
+ ]
+ ); // 2nd case.
+ assert_prolog_success!(&mut wam, "p(X, X).", [["X = a"], ["X = b"]]);
assert_prolog_success!(&mut wam, "p(b, a).");
assert_prolog_failure!(&mut wam, "p(a, b).");
submit(&mut wam, "p(X, Y, a). p(X, a, Y). p(X, Y, a).");
- assert_prolog_success!(&mut wam, "p(c, d, X).", [["X = a"],
- ["X = a"]]);
+ assert_prolog_success!(&mut wam, "p(c, d, X).", [["X = a"], ["X = a"]]);
assert_prolog_success!(&mut wam, "p(a, a, a).");
assert_prolog_failure!(&mut wam, "p(b, c, d).");
submit(&mut wam, "q(z).");
- assert_prolog_success_with_limit!(&mut wam, "p(X, b).", [["X = a"],
- ["X = a"],
- ["X = a"]],
- 3);
+ assert_prolog_success_with_limit!(&mut wam, "p(X, b).", [["X = a"], ["X = a"], ["X = a"]], 3);
assert_prolog_success!(&mut wam, "p(x, a).");
- assert_prolog_success_with_limit!(&mut wam, "p(X, Y).", [["X = _0", "Y = a"],
- ["Y = _1", "X = a"],
- ["Y = _1", "X = a"]],
- 3);
+ assert_prolog_success_with_limit!(
+ &mut wam,
+ "p(X, Y).",
+ [
+ ["X = _0", "Y = a"],
+ ["Y = _1", "X = a"],
+ ["Y = _1", "X = a"]
+ ],
+ 3
+ );
submit(&mut wam, "p(X, a). p(X, Y) :- q(Y), p(X, X).");
- assert_prolog_success_with_limit!(&mut wam, "p(X, Y).", [["X = _0", "Y = a"],
- ["Y = z", "X = a"]],
- 2);
+ assert_prolog_success_with_limit!(
+ &mut wam,
+ "p(X, Y).",
+ [["X = _0", "Y = a"], ["Y = z", "X = a"]],
+ 2
+ );
assert_prolog_failure!(&mut wam, "p(X, b).");
submit(&mut wam, "p(a, z). p(X, Y) :- q(Y), p(X, Y).");
- assert_prolog_success_with_limit!(&mut wam, "p(X, Y).", [["X = a", "Y = z"],
- ["X = a", "Y = z"]],
- 2);
+ assert_prolog_success_with_limit!(
+ &mut wam,
+ "p(X, Y).",
+ [["X = a", "Y = z"], ["X = a", "Y = z"]],
+ 2
+ );
- assert_prolog_success_with_limit!(&mut wam, "p(X, z).", [["X = a"],
- ["X = a"]],
- 2);
+ assert_prolog_success_with_limit!(&mut wam, "p(X, z).", [["X = a"], ["X = a"]], 2);
assert_prolog_success!(&mut wam, "p(a, z).");
- assert_prolog_success_with_limit!(&mut wam, "p(a, X).", [["X = z"],
- ["X = z"]],
- 2);
+ assert_prolog_success_with_limit!(&mut wam, "p(a, X).", [["X = z"], ["X = z"]], 2);
assert_prolog_failure!(&mut wam, "p(b, a).");
- submit(&mut wam, "p(X, Y, Z) :- q(X), r(Y), s(Z).
- p(a, b, Z) :- q(Z).");
+ submit(
+ &mut wam,
+ "p(X, Y, Z) :- q(X), r(Y), s(Z).
+ p(a, b, Z) :- q(Z).",
+ );
submit(&mut wam, "q(x).");
submit(&mut wam, "r(y).");
submit(&mut wam, "s(z).");
- assert_prolog_success!(&mut wam, "p(X, Y, Z).", [["Y = y", "X = x", "Z = z"],
- ["Y = b", "X = a", "Z = x"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "p(X, Y, Z).",
+ [["Y = y", "X = x", "Z = z"], ["Y = b", "X = a", "Z = x"]]
+ );
assert_prolog_failure!(&mut wam, "p(a, b, c).");
assert_prolog_success!(&mut wam, "p(a, b, C).", [["C = x"]]);
submit(&mut wam, "s(x, t).");
submit(&mut wam, "t(y, u).");
- assert_prolog_success!(&mut wam, "p(X).", [["X = x"],
- ["X = y"]]);
+ assert_prolog_success!(&mut wam, "p(X).", [["X = x"], ["X = y"]]);
assert_prolog_success!(&mut wam, "p(x).");
assert_prolog_success!(&mut wam, "p(y).");
assert_prolog_failure!(&mut wam, "p(z).");
- submit(&mut wam, "p(f(f(X)), h(W), Y) :- g(W), h(W), f(X).
- p(X, Y, Z) :- h(Y), g(W), z(Z).");
+ submit(
+ &mut wam,
+ "p(f(f(X)), h(W), Y) :- g(W), h(W), f(X).
+ p(X, Y, Z) :- h(Y), g(W), z(Z).",
+ );
submit(&mut wam, "g(f(X)) :- z(X). g(X) :- h(X).");
submit(&mut wam, "h(w). h(x). h(z).");
submit(&mut wam, "f(s).");
submit(&mut wam, "z(Z).");
- assert_prolog_success!(&mut wam, "p(X, Y, Z).", [["Y = h(w)", "X = f(f(s))", "Z = _2"],
- ["Y = h(x)", "X = f(f(s))", "Z = _2"],
- ["Y = h(z)", "X = f(f(s))", "Z = _2"],
- ["Y = w", "Z = _2", "X = _0"],
- ["Y = w", "Z = _2", "X = _0"],
- ["Y = w", "Z = _2", "X = _0"],
- ["Y = w", "Z = _2", "X = _0"],
- ["Y = x", "Z = _2", "X = _0"],
- ["Y = x", "Z = _2", "X = _0"],
- ["Y = x", "Z = _2", "X = _0"],
- ["Y = x", "Z = _2", "X = _0"],
- ["Y = z", "Z = _2", "X = _0"],
- ["Y = z", "Z = _2", "X = _0"],
- ["Y = z", "Z = _2", "X = _0"],
- ["Y = z", "Z = _2", "X = _0"]]);
- assert_prolog_success!(&mut wam, "p(X, X, Z).", [["Z = _1", "X = w"],
- ["Z = _1", "X = w"],
- ["Z = _1", "X = w"],
- ["Z = _1", "X = w"],
- ["Z = _1", "X = x"],
- ["Z = _1", "X = x"],
- ["Z = _1", "X = x"],
- ["Z = _1", "X = x"],
- ["Z = _1", "X = z"],
- ["Z = _1", "X = z"],
- ["Z = _1", "X = z"],
- ["Z = _1", "X = z"]]);
- assert_prolog_success!(&mut wam, "p(f(f(Z)), Y, Z).", [["Y = h(w)", "Z = s"],
- ["Y = h(x)", "Z = s"],
- ["Y = h(z)", "Z = s"],
- ["Y = w", "Z = _1"],
- ["Y = w", "Z = _1"],
- ["Y = w", "Z = _1"],
- ["Y = w", "Z = _1"],
- ["Y = x", "Z = _1"],
- ["Y = x", "Z = _1"],
- ["Y = x", "Z = _1"],
- ["Y = x", "Z = _1"],
- ["Y = z", "Z = _1"],
- ["Y = z", "Z = _1"],
- ["Y = z", "Z = _1"],
- ["Y = z", "Z = _1"]]);
- assert_prolog_success!(&mut wam, "p(X, X, X).", [["X = w"],
- ["X = w"],
- ["X = w"],
- ["X = w"],
- ["X = x"],
- ["X = x"],
- ["X = x"],
- ["X = x"],
- ["X = z"],
- ["X = z"],
- ["X = z"],
- ["X = z"]]);
- assert_prolog_success!(&mut wam, "p(X, Y, X).", [["Y = h(w)", "X = f(f(s))"],
- ["Y = h(x)", "X = f(f(s))"],
- ["Y = h(z)", "X = f(f(s))"],
- ["Y = w", "X = _0"],
- ["Y = w", "X = _0"],
- ["Y = w", "X = _0"],
- ["Y = w", "X = _0"],
- ["Y = x", "X = _0"],
- ["Y = x", "X = _0"],
- ["Y = x", "X = _0"],
- ["Y = x", "X = _0"],
- ["Y = z", "X = _0"],
- ["Y = z", "X = _0"],
- ["Y = z", "X = _0"],
- ["Y = z", "X = _0"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "p(X, Y, Z).",
+ [
+ ["Y = h(w)", "X = f(f(s))", "Z = _2"],
+ ["Y = h(x)", "X = f(f(s))", "Z = _2"],
+ ["Y = h(z)", "X = f(f(s))", "Z = _2"],
+ ["Y = w", "Z = _2", "X = _0"],
+ ["Y = w", "Z = _2", "X = _0"],
+ ["Y = w", "Z = _2", "X = _0"],
+ ["Y = w", "Z = _2", "X = _0"],
+ ["Y = x", "Z = _2", "X = _0"],
+ ["Y = x", "Z = _2", "X = _0"],
+ ["Y = x", "Z = _2", "X = _0"],
+ ["Y = x", "Z = _2", "X = _0"],
+ ["Y = z", "Z = _2", "X = _0"],
+ ["Y = z", "Z = _2", "X = _0"],
+ ["Y = z", "Z = _2", "X = _0"],
+ ["Y = z", "Z = _2", "X = _0"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "p(X, X, Z).",
+ [
+ ["Z = _1", "X = w"],
+ ["Z = _1", "X = w"],
+ ["Z = _1", "X = w"],
+ ["Z = _1", "X = w"],
+ ["Z = _1", "X = x"],
+ ["Z = _1", "X = x"],
+ ["Z = _1", "X = x"],
+ ["Z = _1", "X = x"],
+ ["Z = _1", "X = z"],
+ ["Z = _1", "X = z"],
+ ["Z = _1", "X = z"],
+ ["Z = _1", "X = z"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "p(f(f(Z)), Y, Z).",
+ [
+ ["Y = h(w)", "Z = s"],
+ ["Y = h(x)", "Z = s"],
+ ["Y = h(z)", "Z = s"],
+ ["Y = w", "Z = _1"],
+ ["Y = w", "Z = _1"],
+ ["Y = w", "Z = _1"],
+ ["Y = w", "Z = _1"],
+ ["Y = x", "Z = _1"],
+ ["Y = x", "Z = _1"],
+ ["Y = x", "Z = _1"],
+ ["Y = x", "Z = _1"],
+ ["Y = z", "Z = _1"],
+ ["Y = z", "Z = _1"],
+ ["Y = z", "Z = _1"],
+ ["Y = z", "Z = _1"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "p(X, X, X).",
+ [
+ ["X = w"],
+ ["X = w"],
+ ["X = w"],
+ ["X = w"],
+ ["X = x"],
+ ["X = x"],
+ ["X = x"],
+ ["X = x"],
+ ["X = z"],
+ ["X = z"],
+ ["X = z"],
+ ["X = z"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "p(X, Y, X).",
+ [
+ ["Y = h(w)", "X = f(f(s))"],
+ ["Y = h(x)", "X = f(f(s))"],
+ ["Y = h(z)", "X = f(f(s))"],
+ ["Y = w", "X = _0"],
+ ["Y = w", "X = _0"],
+ ["Y = w", "X = _0"],
+ ["Y = w", "X = _0"],
+ ["Y = x", "X = _0"],
+ ["Y = x", "X = _0"],
+ ["Y = x", "X = _0"],
+ ["Y = x", "X = _0"],
+ ["Y = z", "X = _0"],
+ ["Y = z", "X = _0"],
+ ["Y = z", "X = _0"],
+ ["Y = z", "X = _0"]
+ ]
+ );
assert_prolog_failure!(&mut wam, "p(f(f(X)), h(f(X)), Y).");
submit(&mut wam, "p(X) :- f(Y), g(Y), i(X, Y).");
submit(&mut wam, "f(f(a)). f(f(b)). f(f(c)).");
submit(&mut wam, "i(X, X).");
- assert_prolog_success!(&mut wam, "p(X).", [["X = f(a)"],
- ["X = f(b)"],
- ["X = f(c)"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "p(X).",
+ [["X = f(a)"], ["X = f(b)"], ["X = f(c)"]]
+ );
submit(&mut wam, "p(X) :- f(f(Y)), g(Y, f(Y)), i(X, f(Y)).");
submit(&mut wam, "g(Y, f(Y)) :- g(f(Y)).");
- assert_prolog_success!(&mut wam, "p(X).", [["X = f(a)"],
- ["X = f(b)"],
- ["X = f(c)"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "p(X).",
+ [["X = f(a)"], ["X = f(b)"], ["X = f(c)"]]
+ );
}
#[test]
let mut wam = Machine::new(readline::input_stream());
// test shallow cuts.
- submit(&mut wam, "memberchk(X, [X|_]) :- !.
- memberchk(X, [_|Xs]) :- memberchk(X, Xs).");
+ submit(
+ &mut wam,
+ "memberchk(X, [X|_]) :- !.
+ memberchk(X, [_|Xs]) :- memberchk(X, Xs).",
+ );
assert_prolog_success!(&mut wam, "memberchk(X, [a,b,c]).", [["X = a"]]);
- assert_prolog_success!(&mut wam, "memberchk([X,X], [a,b,c,[d,e],[d,d]]).", [["X = d"]]);
- assert_prolog_success!(&mut wam, "memberchk([X,X], [a,b,c,[D,d],[e,e]]).", [["X = d", "D = d"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "memberchk([X,X], [a,b,c,[d,e],[d,d]]).",
+ [["X = d"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "memberchk([X,X], [a,b,c,[D,d],[e,e]]).",
+ [["X = d", "D = d"]]
+ );
assert_prolog_failure!(&mut wam, "memberchk([X,X], [a,b,c,[e,d],[f,e]]).");
assert_prolog_failure!(&mut wam, "memberchk([X,X,Y], [a,b,c,[e,d],[f,e]]).");
- assert_prolog_success!(&mut wam, "memberchk([X,X,Y], [a,b,c,[e,e,d],[f,e]]).", [["X = e", "Y = d"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "memberchk([X,X,Y], [a,b,c,[e,e,d],[f,e]]).",
+ [["X = e", "Y = d"]]
+ );
// test deep cuts.
submit(&mut wam, "commit :- a, !.");
}
#[test]
-fn test_queries_on_lists()
-{
+fn test_queries_on_lists() {
let mut wam = Machine::new(readline::input_stream());
submit(&mut wam, "p([Z, W]).");
assert_prolog_failure!(&mut wam, "p([Z | [W]]).");
assert_prolog_success!(&mut wam, "p([Z | []]).", [["Z = _0"]]);
- submit(&mut wam, "member(X, [X|_]).
- member(X, [_|Xs]) :- member(X, Xs).");
+ submit(
+ &mut wam,
+ "member(X, [X|_]).
+ member(X, [_|Xs]) :- member(X, Xs).",
+ );
assert_prolog_failure!(&mut wam, "member(a, [c, [X, Y]]).");
assert_prolog_failure!(&mut wam, "member(c, [a, [X, Y]]).");
assert_prolog_success!(&mut wam, "member(a, [a, [X, Y]]).", [["X = _2", "Y = _0"]]);
- assert_prolog_success!(&mut wam, "member(a, [X, Y, Z]).", [["Y = _2", "X = a", "Z = _0"],
- ["Y = a", "X = _4", "Z = _0"],
- ["Y = _2", "X = _4", "Z = a"]]);
-
- assert_prolog_success!(&mut wam, "member([X, X], [a, [X, Y]]).", [["X = _0", "Y = _0"]]);
- assert_prolog_success!(&mut wam, "member([X, X], [a, [b, c], [b, b], [Z, x], [d, f]]).",
- [["Z = _14", "X = b"],
- ["Z = x", "X = x"]]);
- assert_prolog_failure!(&mut wam, "member([X, X], [a, [b, c], [b, d], [foo, x], [d, f]]).");
- assert_prolog_success!(&mut wam, "member([X, Y], [a, [b, c], [b, b], [Z, x], [d, f]]).",
- [["X = b", "Y = c", "Z = _14"],
- ["X = b", "Y = b", "Z = _14"],
- ["X = _2", "Y = x", "Z = _2"],
- ["X = d", "Y = f", "Z = _14"]]);
- assert_prolog_failure!(&mut wam, "member([X, Y, Y], [a, [b, c], [b, b], [Z, x], [d, f]]).");
- assert_prolog_failure!(&mut wam, "member([X, Y, Z], [a, [b, c], [b, b], [Z, x], [d, f]]).");
+ assert_prolog_success!(
+ &mut wam,
+ "member(a, [X, Y, Z]).",
+ [
+ ["Y = _2", "X = a", "Z = _0"],
+ ["Y = a", "X = _4", "Z = _0"],
+ ["Y = _2", "X = _4", "Z = a"]
+ ]
+ );
+
+ assert_prolog_success!(
+ &mut wam,
+ "member([X, X], [a, [X, Y]]).",
+ [["X = _0", "Y = _0"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "member([X, X], [a, [b, c], [b, b], [Z, x], [d, f]]).",
+ [["Z = _14", "X = b"], ["Z = x", "X = x"]]
+ );
+ assert_prolog_failure!(
+ &mut wam,
+ "member([X, X], [a, [b, c], [b, d], [foo, x], [d, f]])."
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "member([X, Y], [a, [b, c], [b, b], [Z, x], [d, f]]).",
+ [
+ ["X = b", "Y = c", "Z = _14"],
+ ["X = b", "Y = b", "Z = _14"],
+ ["X = _2", "Y = x", "Z = _2"],
+ ["X = d", "Y = f", "Z = _14"]
+ ]
+ );
+ assert_prolog_failure!(
+ &mut wam,
+ "member([X, Y, Y], [a, [b, c], [b, b], [Z, x], [d, f]])."
+ );
+ assert_prolog_failure!(
+ &mut wam,
+ "member([X, Y, Z], [a, [b, c], [b, b], [Z, x], [d, f]])."
+ );
}
#[test]
submit(&mut wam, "p(a, [f(g(X))]).");
submit(&mut wam, "q(Y, c).");
- assert_prolog_success!(&mut wam, "p(X, Y), q(Y, Z).", [["Y = [f(g(_9))]", "X = a", "Z = c"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "p(X, Y), q(Y, Z).",
+ [["Y = [f(g(_9))]", "X = a", "Z = c"]]
+ );
assert_prolog_failure!(&mut wam, "p(X, Y), q(Y, X).");
- submit(&mut wam, "member(X, [X|_]).
- member(X, [_|Xs]) :- member(X, Xs).");
-
- assert_prolog_success!(&mut wam, "member(X, [a,b,c]), member(X, [a,b,c]).",
- [["X = a"],
- ["X = b"],
- ["X = c"]]);
- assert_prolog_success!(&mut wam, "member(X, [a,b,c]), member(X, [b,c]).",
- [["X = b"],
- ["X = c"]]);
- assert_prolog_success!(&mut wam, "member(X, [a,c]), member(X, [b,c]).",
- [["X = c"]]);
- assert_prolog_success!(&mut wam, "member(X, [a,b,c,d]), !, member(X, [a,d]).",
- [["X = a"]]);
+ submit(
+ &mut wam,
+ "member(X, [X|_]).
+ member(X, [_|Xs]) :- member(X, Xs).",
+ );
+
+ assert_prolog_success!(
+ &mut wam,
+ "member(X, [a,b,c]), member(X, [a,b,c]).",
+ [["X = a"], ["X = b"], ["X = c"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "member(X, [a,b,c]), member(X, [b,c]).",
+ [["X = b"], ["X = c"]]
+ );
+ assert_prolog_success!(&mut wam, "member(X, [a,c]), member(X, [b,c]).", [["X = c"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "member(X, [a,b,c,d]), !, member(X, [a,d]).",
+ [["X = a"]]
+ );
assert_prolog_failure!(&mut wam, "member(X, [a,b,c,d]), !, member(X, [e]).");
- assert_prolog_success!(&mut wam, "member([X,X],[a,b,c,[d,d],[e,d]]),
+ assert_prolog_success!(
+ &mut wam,
+ "member([X,X],[a,b,c,[d,d],[e,d]]),
member(X, [a,b,c,d,e,f,g]),
member(Y, [X, a, b, c, d]).",
- [["X = d", "Y = d"],
- ["X = d", "Y = a"],
- ["X = d", "Y = b"],
- ["X = d", "Y = c"],
- ["X = d", "Y = d"]]);
+ [
+ ["X = d", "Y = d"],
+ ["X = d", "Y = a"],
+ ["X = d", "Y = b"],
+ ["X = d", "Y = c"],
+ ["X = d", "Y = d"]
+ ]
+ );
submit(&mut wam, "p(a, [f(g(X))]). p(X, c) :- c.");
submit(&mut wam, "c.");
submit(&mut wam, "q(Y, c).");
- assert_prolog_success!(&mut wam, "p(X, Y), q(Y, Z).",
- [["X = a", "Z = c", "Y = [f(g(_9))]"],
- ["X = _0", "Z = c", "Y = c"]]);
- assert_prolog_success!(&mut wam, "p(X, Y), !, q(Y, Z).",
- [["Z = c", "Y = [f(g(_9))]", "X = a"]]);
-
- submit(&mut wam, "q([f(g(x))], Z). q([f(g(y))], Y). q([f(g(z))], a).");
-
- assert_prolog_success!(&mut wam, "p(X, Y), q(Y, Z).",
- [["Z = _11", "X = a", "Y = [f(g(x))]"],
- ["Z = _11", "X = a", "Y = [f(g(y))]"],
- ["Z = a", "X = a", "Y = [f(g(z))]"]]);
- assert_prolog_success!(&mut wam, "p(X, Y), !, q(Y, Z).",
- [["X = a", "Y = [f(g(x))]", "Z = _11"],
- ["X = a", "Y = [f(g(y))]", "Z = _11"],
- ["X = a", "Y = [f(g(z))]", "Z = a"]]);
- assert_prolog_success!(&mut wam, "p(X, Y), !, q(Y, X).",
- [["X = a", "Y = [f(g(x))]"],
- ["X = a", "Y = [f(g(y))]"],
- ["X = a", "Y = [f(g(z))]"]]);
-
- submit(&mut wam, "p(X, [f(g(x))]). p(X, [f(g(y))]). p(X, [f(g(z))]).");
+ assert_prolog_success!(
+ &mut wam,
+ "p(X, Y), q(Y, Z).",
+ [
+ ["X = a", "Z = c", "Y = [f(g(_9))]"],
+ ["X = _0", "Z = c", "Y = c"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "p(X, Y), !, q(Y, Z).",
+ [["Z = c", "Y = [f(g(_9))]", "X = a"]]
+ );
+
+ submit(
+ &mut wam,
+ "q([f(g(x))], Z). q([f(g(y))], Y). q([f(g(z))], a).",
+ );
+
+ assert_prolog_success!(
+ &mut wam,
+ "p(X, Y), q(Y, Z).",
+ [
+ ["Z = _11", "X = a", "Y = [f(g(x))]"],
+ ["Z = _11", "X = a", "Y = [f(g(y))]"],
+ ["Z = a", "X = a", "Y = [f(g(z))]"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "p(X, Y), !, q(Y, Z).",
+ [
+ ["X = a", "Y = [f(g(x))]", "Z = _11"],
+ ["X = a", "Y = [f(g(y))]", "Z = _11"],
+ ["X = a", "Y = [f(g(z))]", "Z = a"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "p(X, Y), !, q(Y, X).",
+ [
+ ["X = a", "Y = [f(g(x))]"],
+ ["X = a", "Y = [f(g(y))]"],
+ ["X = a", "Y = [f(g(z))]"]
+ ]
+ );
+
+ submit(
+ &mut wam,
+ "p(X, [f(g(x))]). p(X, [f(g(y))]). p(X, [f(g(z))]).",
+ );
assert_prolog_failure!(&mut wam, "q(f(X), Y), p(X, Y).");
- assert_prolog_success!(&mut wam, "q(X, Y), p(X, Y).",
- [["Y = [f(g(x))]", "X = [f(g(x))]"],
- ["Y = [f(g(y))]", "X = [f(g(x))]"],
- ["Y = [f(g(z))]", "X = [f(g(x))]"],
- ["Y = [f(g(x))]", "X = [f(g(y))]"],
- ["Y = [f(g(y))]", "X = [f(g(y))]"],
- ["Y = [f(g(z))]", "X = [f(g(y))]"]]);
- assert_prolog_success!(&mut wam, "p(X, Y), q(X, Y).",
- [["Y = [f(g(x))]", "X = [f(g(x))]"],
- ["Y = [f(g(x))]", "X = [f(g(y))]"],
- ["Y = [f(g(y))]", "X = [f(g(x))]"],
- ["Y = [f(g(y))]", "X = [f(g(y))]"],
- ["Y = [f(g(z))]", "X = [f(g(x))]"],
- ["Y = [f(g(z))]", "X = [f(g(y))]"]]);
- assert_prolog_success!(&mut wam, "p(X, Y), q(Y, X).",
- [["Y = [f(g(x))]", "X = _10"],
- ["Y = [f(g(y))]", "X = _10"],
- ["Y = [f(g(z))]", "X = a"]]);
- assert_prolog_success!(&mut wam, "q(X, Y), p(Y, X).",
- [["Y = _9", "X = [f(g(x))]"],
- ["Y = _9", "X = [f(g(y))]"],
- ["Y = a" , "X = [f(g(z))]"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "q(X, Y), p(X, Y).",
+ [
+ ["Y = [f(g(x))]", "X = [f(g(x))]"],
+ ["Y = [f(g(y))]", "X = [f(g(x))]"],
+ ["Y = [f(g(z))]", "X = [f(g(x))]"],
+ ["Y = [f(g(x))]", "X = [f(g(y))]"],
+ ["Y = [f(g(y))]", "X = [f(g(y))]"],
+ ["Y = [f(g(z))]", "X = [f(g(y))]"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "p(X, Y), q(X, Y).",
+ [
+ ["Y = [f(g(x))]", "X = [f(g(x))]"],
+ ["Y = [f(g(x))]", "X = [f(g(y))]"],
+ ["Y = [f(g(y))]", "X = [f(g(x))]"],
+ ["Y = [f(g(y))]", "X = [f(g(y))]"],
+ ["Y = [f(g(z))]", "X = [f(g(x))]"],
+ ["Y = [f(g(z))]", "X = [f(g(y))]"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "p(X, Y), q(Y, X).",
+ [
+ ["Y = [f(g(x))]", "X = _10"],
+ ["Y = [f(g(y))]", "X = _10"],
+ ["Y = [f(g(z))]", "X = a"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "q(X, Y), p(Y, X).",
+ [
+ ["Y = _9", "X = [f(g(x))]"],
+ ["Y = _9", "X = [f(g(y))]"],
+ ["Y = a", "X = [f(g(z))]"]
+ ]
+ );
}
#[test]
-fn test_queries_on_call_n()
-{
+fn test_queries_on_call_n() {
let mut wam = Machine::new(readline::input_stream());
- submit(&mut wam, "maplist(_, []).
- maplist(P, [X|Xs]) :- call(P, X), maplist(P, Xs).");
+ submit(
+ &mut wam,
+ "maplist(_, []).
+ maplist(P, [X|Xs]) :- call(P, X), maplist(P, Xs).",
+ );
submit(&mut wam, "f(a). f(b). f(c).");
- assert_prolog_success!(&mut wam, "maplist(f, [X,Y,Z]).",
- [["X = a", "Y = a", "Z = a"],
- ["X = a", "Y = a", "Z = b"],
- ["X = a", "Y = a", "Z = c"],
- ["X = a", "Y = b", "Z = a"],
- ["X = a", "Y = b", "Z = b"],
- ["X = a", "Y = b", "Z = c"],
- ["X = a", "Y = c", "Z = a"],
- ["X = a", "Y = c", "Z = b"],
- ["X = a", "Y = c", "Z = c"],
- ["X = b", "Y = a", "Z = a"],
- ["X = b", "Y = a", "Z = b"],
- ["X = b", "Y = a", "Z = c"],
- ["X = b", "Y = b", "Z = a"],
- ["X = b", "Y = b", "Z = b"],
- ["X = b", "Y = b", "Z = c"],
- ["X = b", "Y = c", "Z = a"],
- ["X = b", "Y = c", "Z = b"],
- ["X = b", "Y = c", "Z = c"],
- ["X = c", "Y = a", "Z = a"],
- ["X = c", "Y = a", "Z = b"],
- ["X = c", "Y = a", "Z = c"],
- ["X = c", "Y = b", "Z = a"],
- ["X = c", "Y = b", "Z = b"],
- ["X = c", "Y = b", "Z = c"],
- ["X = c", "Y = c", "Z = a"],
- ["X = c", "Y = c", "Z = b"],
- ["X = c", "Y = c", "Z = c"]]);
-
- assert_prolog_success!(&mut wam, "maplist(f, [a,Y,Z]).",
- [["Y = a", "Z = a"],
- ["Y = a", "Z = b"],
- ["Y = a", "Z = c"],
- ["Y = b", "Z = a"],
- ["Y = b", "Z = b"],
- ["Y = b", "Z = c"],
- ["Y = c", "Z = a"],
- ["Y = c", "Z = b"],
- ["Y = c", "Z = c"]]);
-
- assert_prolog_success!(&mut wam, "maplist(f, [X,a,b]).",
- [["X = a"],
- ["X = b"],
- ["X = c"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "maplist(f, [X,Y,Z]).",
+ [
+ ["X = a", "Y = a", "Z = a"],
+ ["X = a", "Y = a", "Z = b"],
+ ["X = a", "Y = a", "Z = c"],
+ ["X = a", "Y = b", "Z = a"],
+ ["X = a", "Y = b", "Z = b"],
+ ["X = a", "Y = b", "Z = c"],
+ ["X = a", "Y = c", "Z = a"],
+ ["X = a", "Y = c", "Z = b"],
+ ["X = a", "Y = c", "Z = c"],
+ ["X = b", "Y = a", "Z = a"],
+ ["X = b", "Y = a", "Z = b"],
+ ["X = b", "Y = a", "Z = c"],
+ ["X = b", "Y = b", "Z = a"],
+ ["X = b", "Y = b", "Z = b"],
+ ["X = b", "Y = b", "Z = c"],
+ ["X = b", "Y = c", "Z = a"],
+ ["X = b", "Y = c", "Z = b"],
+ ["X = b", "Y = c", "Z = c"],
+ ["X = c", "Y = a", "Z = a"],
+ ["X = c", "Y = a", "Z = b"],
+ ["X = c", "Y = a", "Z = c"],
+ ["X = c", "Y = b", "Z = a"],
+ ["X = c", "Y = b", "Z = b"],
+ ["X = c", "Y = b", "Z = c"],
+ ["X = c", "Y = c", "Z = a"],
+ ["X = c", "Y = c", "Z = b"],
+ ["X = c", "Y = c", "Z = c"]
+ ]
+ );
+
+ assert_prolog_success!(
+ &mut wam,
+ "maplist(f, [a,Y,Z]).",
+ [
+ ["Y = a", "Z = a"],
+ ["Y = a", "Z = b"],
+ ["Y = a", "Z = c"],
+ ["Y = b", "Z = a"],
+ ["Y = b", "Z = b"],
+ ["Y = b", "Z = c"],
+ ["Y = c", "Z = a"],
+ ["Y = c", "Z = b"],
+ ["Y = c", "Z = c"]
+ ]
+ );
+
+ assert_prolog_success!(
+ &mut wam,
+ "maplist(f, [X,a,b]).",
+ [["X = a"], ["X = b"], ["X = c"]]
+ );
assert_prolog_success!(&mut wam, "maplist(f, [c,a,b]).");
assert_prolog_failure!(&mut wam, "maplist(f, [d,e,f]).");
assert_prolog_success!(&mut wam, "maplist(f, []).");
submit(&mut wam, "p(x). p(y).");
assert_prolog_failure!(&mut wam, "f(p).");
- assert_prolog_success!(&mut wam, "f(p(X)).", [["X = x"],
- ["X = y"]]);
+ assert_prolog_success!(&mut wam, "f(p(X)).", [["X = x"], ["X = y"]]);
assert_prolog_success!(&mut wam, "f(p(x)).");
assert_prolog_failure!(&mut wam, "f(p(w)).");
assert_prolog_failure!(&mut wam, "f(p(X, Y)).");
submit(&mut wam, "f(P, X, Y) :- call(P, X), call(P, Y).");
- assert_prolog_success!(&mut wam, "f(p, X, Y).", [["Y = x", "X = x"],
- ["Y = y", "X = x"],
- ["Y = x", "X = y"],
- ["Y = y", "X = y"]]);
- assert_prolog_success!(&mut wam, "f(p, x, Y).", [["Y = x"],
- ["Y = y"]]);
- assert_prolog_success!(&mut wam, "f(p, X, y).", [["X = x"],
- ["X = y"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "f(p, X, Y).",
+ [
+ ["Y = x", "X = x"],
+ ["Y = y", "X = x"],
+ ["Y = x", "X = y"],
+ ["Y = y", "X = y"]
+ ]
+ );
+ assert_prolog_success!(&mut wam, "f(p, x, Y).", [["Y = x"], ["Y = y"]]);
+ assert_prolog_success!(&mut wam, "f(p, X, y).", [["X = x"], ["X = y"]]);
assert_prolog_success!(&mut wam, "f(p, x, y).");
assert_prolog_failure!(&mut wam, "f(p, X, z).");
assert_prolog_failure!(&mut wam, "f(p, z, Y).");
- assert_prolog_success!(&mut wam, "call(p, X).", [["X = x"],
- ["X = y"]]);
+ assert_prolog_success!(&mut wam, "call(p, X).", [["X = x"], ["X = y"]]);
assert_prolog_success!(&mut wam, "call(p, x).");
assert_prolog_success!(&mut wam, "call(p, y).");
assert_prolog_failure!(&mut wam, "call(p, z).");
submit(&mut wam, "r(f(X)) :- p(X). r(g(Y)) :- p(Y).");
- assert_prolog_success!(&mut wam, "f(r, X, Y).",
- [["X = f(x)", "Y = f(x)"],
- ["X = f(x)", "Y = f(y)"],
- ["X = f(x)", "Y = g(x)"],
- ["X = f(x)", "Y = g(y)"],
- ["X = f(y)", "Y = f(x)"],
- ["X = f(y)", "Y = f(y)"],
- ["X = f(y)", "Y = g(x)"],
- ["X = f(y)", "Y = g(y)"],
- ["X = g(x)", "Y = f(x)"],
- ["X = g(x)", "Y = f(y)"],
- ["X = g(x)", "Y = g(x)"],
- ["X = g(x)", "Y = g(y)"],
- ["X = g(y)", "Y = f(x)"],
- ["X = g(y)", "Y = f(y)"],
- ["X = g(y)", "Y = g(x)"],
- ["X = g(y)", "Y = g(y)"]]);
- assert_prolog_success!(&mut wam, "f(r, X, X).",
- [["X = f(x)"],
- ["X = f(y)"],
- ["X = g(x)"],
- ["X = g(y)"]]);
- assert_prolog_success!(&mut wam, "f(r, f(X), g(Y)).",
- [["X = x", "Y = x"],
- ["X = x", "Y = y"],
- ["X = y", "Y = x"],
- ["X = y", "Y = y"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "f(r, X, Y).",
+ [
+ ["X = f(x)", "Y = f(x)"],
+ ["X = f(x)", "Y = f(y)"],
+ ["X = f(x)", "Y = g(x)"],
+ ["X = f(x)", "Y = g(y)"],
+ ["X = f(y)", "Y = f(x)"],
+ ["X = f(y)", "Y = f(y)"],
+ ["X = f(y)", "Y = g(x)"],
+ ["X = f(y)", "Y = g(y)"],
+ ["X = g(x)", "Y = f(x)"],
+ ["X = g(x)", "Y = f(y)"],
+ ["X = g(x)", "Y = g(x)"],
+ ["X = g(x)", "Y = g(y)"],
+ ["X = g(y)", "Y = f(x)"],
+ ["X = g(y)", "Y = f(y)"],
+ ["X = g(y)", "Y = g(x)"],
+ ["X = g(y)", "Y = g(y)"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "f(r, X, X).",
+ [["X = f(x)"], ["X = f(y)"], ["X = g(x)"], ["X = g(y)"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "f(r, f(X), g(Y)).",
+ [
+ ["X = x", "Y = x"],
+ ["X = x", "Y = y"],
+ ["X = y", "Y = x"],
+ ["X = y", "Y = y"]
+ ]
+ );
assert_prolog_failure!(&mut wam, "f(r, j(X), h(Y)).");
submit(&mut wam, "p(one, one). p(one, two). p(two, two).");
- assert_prolog_success!(&mut wam, "f(p(one), X, Y).",
- [["X = one", "Y = one"],
- ["X = one", "Y = two"],
- ["X = two", "Y = one"],
- ["X = two", "Y = two"]]);
- assert_prolog_success!(&mut wam, "f(p(one), X, X).",
- [["X = one"],
- ["X = two"]]);
- assert_prolog_success!(&mut wam, "f(p(one), one, Y).",
- [["Y = one"],
- ["Y = two"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "f(p(one), X, Y).",
+ [
+ ["X = one", "Y = one"],
+ ["X = one", "Y = two"],
+ ["X = two", "Y = one"],
+ ["X = two", "Y = two"]
+ ]
+ );
+ assert_prolog_success!(&mut wam, "f(p(one), X, X).", [["X = one"], ["X = two"]]);
+ assert_prolog_success!(&mut wam, "f(p(one), one, Y).", [["Y = one"], ["Y = two"]]);
assert_prolog_success!(&mut wam, "f(p(one), one, two).");
assert_prolog_failure!(&mut wam, "f(p(one), one, three).");
submit(&mut wam, "p(f(g(X)), compound, [lists,are,good]).");
- assert_prolog_success!(&mut wam, "call(p(f(g(X))),Y,Z).",
- [["Y = compound","Z = [lists,are,good]","X = _3"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "call(p(f(g(X))),Y,Z).",
+ [["Y = compound", "Z = [lists,are,good]", "X = _3"]]
+ );
- submit(&mut wam, "david_lynch(coffee).
+ submit(
+ &mut wam,
+ "david_lynch(coffee).
david_lynch(pie).
- david_lynch(kyle(Film)) :- kyle(Film).");
+ david_lynch(kyle(Film)) :- kyle(Film).",
+ );
- submit(&mut wam, "kyle(dune).
+ submit(
+ &mut wam,
+ "kyle(dune).
kyle(blue_velvet).
kyle(showgirls).
- kyle(flintstones).");
-
- assert_prolog_success!(&mut wam, "call(david_lynch,X).",
- [["X = coffee"],
- ["X = pie"],
- ["X = kyle(dune)"],
- ["X = kyle(blue_velvet)"],
- ["X = kyle(showgirls)"],
- ["X = kyle(flintstones)"]]);
- assert_prolog_success!(&mut wam, "call(david_lynch,kyle(Film)).",
- [["Film = dune"],
- ["Film = blue_velvet"],
- ["Film = showgirls"],
- ["Film = flintstones"]]);
+ kyle(flintstones).",
+ );
+
+ assert_prolog_success!(
+ &mut wam,
+ "call(david_lynch,X).",
+ [
+ ["X = coffee"],
+ ["X = pie"],
+ ["X = kyle(dune)"],
+ ["X = kyle(blue_velvet)"],
+ ["X = kyle(showgirls)"],
+ ["X = kyle(flintstones)"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call(david_lynch,kyle(Film)).",
+ [
+ ["Film = dune"],
+ ["Film = blue_velvet"],
+ ["Film = showgirls"],
+ ["Film = flintstones"]
+ ]
+ );
assert_prolog_failure!(&mut wam, "call(david_lynch,kyle(Film),_).");
submit(&mut wam, "call_mult(P,X) :- call(call(P),X).");
- assert_prolog_success!(&mut wam, "call_mult(p(X),Y).",
- [["Y = one","X = one"],
- ["Y = two","X = one"],
- ["Y = two","X = two"]]);
- assert_prolog_success!(&mut wam, "call_mult(p(X),X).",
- [["X = one"],
- ["X = two"]]);
- assert_prolog_success!(&mut wam, "call_mult(p(one),X).",
- [["X = one"],
- ["X = two"]]);
- assert_prolog_success!(&mut wam, "call_mult(p(X),one).",
- [["X = one"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "call_mult(p(X),Y).",
+ [
+ ["Y = one", "X = one"],
+ ["Y = two", "X = one"],
+ ["Y = two", "X = two"]
+ ]
+ );
+ assert_prolog_success!(&mut wam, "call_mult(p(X),X).", [["X = one"], ["X = two"]]);
+ assert_prolog_success!(&mut wam, "call_mult(p(one),X).", [["X = one"], ["X = two"]]);
+ assert_prolog_success!(&mut wam, "call_mult(p(X),one).", [["X = one"]]);
assert_prolog_failure!(&mut wam, "call_mult(p(two),one).");
assert_prolog_success!(&mut wam, "call_mult(p(two),two).");
- assert_prolog_success!(&mut wam, "call(call(p(one)),X),call(call(p(two)),two).",
- [["X = one"],
- ["X = two"]]);
- assert_prolog_success!(&mut wam, "call(call(p(one,X))),call(call(p(two,two))).",
- [["X = one"],
- ["X = two"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "call(call(p(one)),X),call(call(p(two)),two).",
+ [["X = one"], ["X = two"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call(call(p(one,X))),call(call(p(two,two))).",
+ [["X = one"], ["X = two"]]
+ );
assert_prolog_failure!(&mut wam, "call(call(p(one)),X),call(call(p(two)),one).");
- assert_prolog_success!(&mut wam, "call(call(p(X)),X),call(call(p(Y)),Y).",
- [["X = one","Y = one"],
- ["X = one","Y = two"],
- ["X = two","Y = one"],
- ["X = two","Y = two"]]);
- assert_prolog_success!(&mut wam, "call(call(p(X)),Y),call(call(p(Y)),X).",
- [["X = one","Y = one"],
- ["X = two","Y = two"]]);
- assert_prolog_success!(&mut wam, "call(call(p),X,Y),call(call(call(p)),X,Y).",
- [["X = one","Y = one"],
- ["Y = two","X = one"],
- ["Y = two","X = two"]]);
- assert_prolog_success!(&mut wam, "call(call(p),X,Y),call(call(call(p(X))),Y).",
- [["X = one","Y = one"],
- ["Y = two","X = one"],
- ["Y = two","X = two"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "call(call(p(X)),X),call(call(p(Y)),Y).",
+ [
+ ["X = one", "Y = one"],
+ ["X = one", "Y = two"],
+ ["X = two", "Y = one"],
+ ["X = two", "Y = two"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call(call(p(X)),Y),call(call(p(Y)),X).",
+ [["X = one", "Y = one"], ["X = two", "Y = two"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call(call(p),X,Y),call(call(call(p)),X,Y).",
+ [
+ ["X = one", "Y = one"],
+ ["Y = two", "X = one"],
+ ["Y = two", "X = two"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call(call(p),X,Y),call(call(call(p(X))),Y).",
+ [
+ ["X = one", "Y = one"],
+ ["Y = two", "X = one"],
+ ["Y = two", "X = two"]
+ ]
+ );
assert_prolog_failure!(&mut wam, "call(call(p),X,Y),call(call(call(p(X))),X,Y).");
- assert_prolog_success!(&mut wam, "call(call(p),X,Y),call(call(call(p(X))),X).",
- [["X = one","Y = one"],
- ["Y = two","X = one"],
- ["Y = two","X = two"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "call(call(p),X,Y),call(call(call(p(X))),X).",
+ [
+ ["X = one", "Y = one"],
+ ["Y = two", "X = one"],
+ ["Y = two", "X = two"]
+ ]
+ );
submit(&mut wam, "f(call(f,undefined)). f(undefined).");
submit(&mut wam, "call_var(P) :- P.");
- assert_prolog_success!(&mut wam, "f(X),call_var(X).",
- [["X = call(f,undefined)"]]);
- assert_prolog_success!(&mut wam, "f(call(f,Q)),call_var(call(f,Q)).",
- [["Q = undefined"]]);
+ assert_prolog_success!(&mut wam, "f(X),call_var(X).", [["X = call(f,undefined)"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "f(call(f,Q)),call_var(call(f,Q)).",
+ [["Q = undefined"]]
+ );
assert_prolog_failure!(&mut wam, "call_var(call(undefined,Q)).");
assert_prolog_failure!(&mut wam, "call(call).");
assert_prolog_failure!(&mut wam, "call(call(call(call))).");
assert_prolog_failure!(&mut wam, "call(call(call(call(call)))).");
assert_prolog_failure!(&mut wam, "call(call(call(call(call(call))))).");
- assert_prolog_success!(&mut wam, "call(call(call(call(call(call(p(X))))))).",
- [["X = x"],
- ["X = y"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "call(call(call(call(call(call(p(X))))))).",
+ [["X = x"], ["X = y"]]
+ );
}
#[test]
-fn test_queries_on_arithmetic()
-{
+fn test_queries_on_arithmetic() {
let mut wam = Machine::new(readline::input_stream());
assert_prolog_success!(&mut wam, "X is 1, X is X.", [["X = 1"]]);
// assert_prolog_failure!(&mut wam, "X is 1 + a.");
// assert_prolog_failure!(&mut wam, "X is 1 + Y.");
- assert_prolog_success!(&mut wam, "Y is 2 + 2 - 2, X is 1 + Y, X = 3.",
- [["X = 3", "Y = 2"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "Y is 2 + 2 - 2, X is 1 + Y, X = 3.",
+ [["X = 3", "Y = 2"]]
+ );
assert_prolog_failure!(&mut wam, "Y is 2 + 2 - 2, X is 1 + Y, X = 2.");
assert_prolog_success!(&mut wam, "6 is 6.");
submit(&mut wam, "f(X) :- X is 5 // 0.");
- assert_prolog_success!(&mut wam, "catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
- [["E = zero_divisor", "X = _1"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
+ [["E = zero_divisor", "X = _1"]]
+ );
submit(&mut wam, "f(X) :- X is (5 rdiv 1) / 0.");
- assert_prolog_success!(&mut wam, "catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
- [["E = zero_divisor", "X = _1"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
+ [["E = zero_divisor", "X = _1"]]
+ );
submit(&mut wam, "f(X) :- X is 5.0 / 0.");
- assert_prolog_success!(&mut wam, "catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
- [["E = zero_divisor", "X = _1"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
+ [["E = zero_divisor", "X = _1"]]
+ );
- assert_prolog_success!(&mut wam, "X is ((3 + 4) // 2) + 2 - 1 // 1, Y is 2+2, Z is X+Y.",
- [["Y = 4", "X = 4", "Z = 8"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "X is ((3 + 4) // 2) + 2 - 1 // 1, Y is 2+2, Z is X+Y.",
+ [["Y = 4", "X = 4", "Z = 8"]]
+ );
- assert_prolog_success!(&mut wam, "X is ((3 + 4) // 2) + 2 - 1 // 1, Y is 2+2, Z = 8, Y is 4.",
- [["Y = 4", "X = 4", "Z = 8"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "X is ((3 + 4) // 2) + 2 - 1 // 1, Y is 2+2, Z = 8, Y is 4.",
+ [["Y = 4", "X = 4", "Z = 8"]]
+ );
- assert_prolog_success!(&mut wam, "X is (3 rdiv 4) / 2, Y is 3 rdiv 8.",
- [["X = 0.375", "Y = 3/8"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "X is (3 rdiv 4) / 2, Y is 3 rdiv 8.",
+ [["X = 0.375", "Y = 3/8"]]
+ );
assert_prolog_success!(&mut wam, "X is 10 xor -4, X is -10.", [["X = -10"]]);
assert_prolog_success!(&mut wam, "X is 4 xor -7, X is -3.", [["X = -3"]]);
assert_prolog_success!(&mut wam, "X is 10 xor 5 + 55, X = 70.", [["X = 70"]]);
- assert_prolog_success!(&mut wam, "X is 10 rem -3, X = 1.", [["X = 1"]]);
+ assert_prolog_success!(&mut wam, "X is 10 rem -3, X = 1.", [["X = 1"]]);
assert_prolog_success!(&mut wam, "X is 10 mod -3, X is -2.", [["X = -2"]]);
assert_prolog_success!(&mut wam, "call(is, X, 3 + 4).", [["X = 7"]]);
- assert_prolog_success!(&mut wam, "Y is 3 + 3, call(is, X, Y + 4).", [["Y = 6", "X = 10"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "Y is 3 + 3, call(is, X, Y + 4).",
+ [["Y = 6", "X = 10"]]
+ );
assert_prolog_success!(&mut wam, "call(is, X, 3 + 4.5).", [["X = 7.5"]]);
- assert_prolog_success!(&mut wam, "X is 2 rdiv 3, call(is, Y, X*X).", [["X = 2/3", "Y = 4/9"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "X is 2 rdiv 3, call(is, Y, X*X).",
+ [["X = 2/3", "Y = 4/9"]]
+ );
assert_prolog_failure!(&mut wam, "call(>, 3, 3 + 3).");
assert_prolog_failure!(&mut wam, "X is 3 + 3, call(>, 3, X).");
assert_prolog_success!(&mut wam, "X is 3 + 3, call(<, 3, X).", [["X = 6"]]);
assert_prolog_success!(&mut wam, "X is 3 + 3, X =:= 3 + 3.", [["X = 6"]]);
- assert_prolog_success!(&mut wam, "catch(call(is, X, 3 // 0), error(E, _), true).",
- [["X = _5", "E = evaluation_error(zero_divisor)"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(call(is, X, 3 // 0), error(E, _), true).",
+ [["X = _5", "E = evaluation_error(zero_divisor)"]]
+ );
- assert_prolog_success!(&mut wam, "catch(call(is, X, 3 // 3), _, true).", [["X = 1"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(call(is, X, 3 // 3), _, true).",
+ [["X = 1"]]
+ );
- submit(&mut wam, "f(X, Sum) :- ( integer(X) -> Sum is X + X * X + 3 ;
- var(X) -> Sum = 1, X = 1 ).");
+ submit(
+ &mut wam,
+ "f(X, Sum) :- ( integer(X) -> Sum is X + X * X + 3 ;
+ var(X) -> Sum = 1, X = 1 ).",
+ );
assert_prolog_success!(&mut wam, "f(X, Sum).", [["X = 1", "Sum = 1"]]);
assert_prolog_success!(&mut wam, "f(5, Sum).", [["Sum = 33"]]);
submit(&mut wam, ":- op(900, xfx, ~).");
submit(&mut wam, "X ~ Y :- abs(X - Y) =< 1 rdiv 10000.");
- assert_prolog_success!(&mut wam, "X is 3 ** 3.",
- [["X = 27"]]);
- assert_prolog_success!(&mut wam, "X is 3 ** 0.",
- [["X = 1"]]);
- assert_prolog_success!(&mut wam, "X is 3 ** -0.",
- [["X = 1"]]);
- assert_prolog_success!(&mut wam, "X is 3 ** 1.",
- [["X = 3"]]);
- assert_prolog_success!(&mut wam, "X is (-3) ** 3.",
- [["X = -27"]]);
- assert_prolog_success!(&mut wam, "X is (-3) ** 3.",
- [["X = -27"]]);
- assert_prolog_success!(&mut wam, "X is (-3) ** 0.",
- [["X = 1"]]);
- assert_prolog_success!(&mut wam, "X is (-3) ** -0.",
- [["X = 1"]]);
- assert_prolog_success!(&mut wam, "X is (-3) ** 1.",
- [["X = -3"]]);
-// assert_prolog_success!(&mut wam, "X is (1 rdiv 27) ** -3, X ~ 19683.");
-// assert_prolog_success!(&mut wam, "X is (-1 rdiv 27) ** -3, X ~ -19683.");
-
- assert_prolog_success!(&mut wam, "X is 0.0 ** 0.",
- [["X = 1.0"]]);
- assert_prolog_success!(&mut wam, "catch(_ is 0.0 ** -2342, error(E, _), true).",
- [["E = evaluation_error(undefined)"]]);
- assert_prolog_success!(&mut wam, "X is 0.0 ** 2342.",
- [["X = 0"]]);
-
- assert_prolog_success!(&mut wam, "catch(_ is (-3) ** (1 rdiv 2), error(E, _), true).",
- [["E = evaluation_error(undefined)"]]);
- assert_prolog_success!(&mut wam, "catch(_ is (-3/2) ** (1 rdiv 2), error(E, _), true).",
- [["E = evaluation_error(undefined)"]]);
- assert_prolog_success!(&mut wam, "catch(_ is (-3 rdiv 2) ** (1 rdiv 4), error(E, _), true).",
- [["E = evaluation_error(undefined)"]]);
- assert_prolog_success!(&mut wam, "catch(_ is (-3 rdiv 2) ** (-1 rdiv 4), error(E, _), true).",
- [["E = evaluation_error(undefined)"]]);
- assert_prolog_success!(&mut wam, "catch(_ is 0 ** (-5 rdiv 4), error(E, _), true).",
- [["E = evaluation_error(undefined)"]]);
+ assert_prolog_success!(&mut wam, "X is 3 ** 3.", [["X = 27"]]);
+ assert_prolog_success!(&mut wam, "X is 3 ** 0.", [["X = 1"]]);
+ assert_prolog_success!(&mut wam, "X is 3 ** -0.", [["X = 1"]]);
+ assert_prolog_success!(&mut wam, "X is 3 ** 1.", [["X = 3"]]);
+ assert_prolog_success!(&mut wam, "X is (-3) ** 3.", [["X = -27"]]);
+ assert_prolog_success!(&mut wam, "X is (-3) ** 3.", [["X = -27"]]);
+ assert_prolog_success!(&mut wam, "X is (-3) ** 0.", [["X = 1"]]);
+ assert_prolog_success!(&mut wam, "X is (-3) ** -0.", [["X = 1"]]);
+ assert_prolog_success!(&mut wam, "X is (-3) ** 1.", [["X = -3"]]);
+ // assert_prolog_success!(&mut wam, "X is (1 rdiv 27) ** -3, X ~ 19683.");
+ // assert_prolog_success!(&mut wam, "X is (-1 rdiv 27) ** -3, X ~ -19683.");
+
+ assert_prolog_success!(&mut wam, "X is 0.0 ** 0.", [["X = 1.0"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(_ is 0.0 ** -2342, error(E, _), true).",
+ [["E = evaluation_error(undefined)"]]
+ );
+ assert_prolog_success!(&mut wam, "X is 0.0 ** 2342.", [["X = 0"]]);
+
+ assert_prolog_success!(
+ &mut wam,
+ "catch(_ is (-3) ** (1 rdiv 2), error(E, _), true).",
+ [["E = evaluation_error(undefined)"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(_ is (-3/2) ** (1 rdiv 2), error(E, _), true).",
+ [["E = evaluation_error(undefined)"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(_ is (-3 rdiv 2) ** (1 rdiv 4), error(E, _), true).",
+ [["E = evaluation_error(undefined)"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(_ is (-3 rdiv 2) ** (-1 rdiv 4), error(E, _), true).",
+ [["E = evaluation_error(undefined)"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(_ is 0 ** (-5 rdiv 4), error(E, _), true).",
+ [["E = evaluation_error(undefined)"]]
+ );
assert_prolog_success!(&mut wam, "X is 3 ** (1 rdiv 3), Y is X ** 3, Y ~ 3.");
-// assert_prolog_success!(&mut wam, "X is (-3) ** (1 rdiv 3), Y is X ** 3, Y ~ -3.");
-// assert_prolog_failure!(&mut wam, "X is (-5) ** (1 rdiv 3), Y is X ** 3, Y ~ -3.");
+ // assert_prolog_success!(&mut wam, "X is (-3) ** (1 rdiv 3), Y is X ** 3, Y ~ -3.");
+ // assert_prolog_failure!(&mut wam, "X is (-5) ** (1 rdiv 3), Y is X ** 3, Y ~ -3.");
assert_prolog_success!(&mut wam, "X is 5 ** (1 rdiv 3), Y is X ** 3, Y ~ 5.");
- assert_prolog_success!(&mut wam, "X is (1 rdiv 3) ** 0.5, Y is X ** 2, 1 rdiv 3 ~ Y.");
-
-// assert_prolog_success!(&mut wam, "X is (-5) ** (-1 rdiv 3), Y is X ** 3, Y ~ -1 rdiv 5.");
-// assert_prolog_failure!(&mut wam, "X is (-5) ** (-1 rdiv 3), Y is X ** 3, Y ~ 1 rdiv 5.");
-
- assert_prolog_success!(&mut wam, "X is (0 rdiv 5) ** 5.",
- [["X = 0"]]);
- assert_prolog_success!(&mut wam, "X is (-0 rdiv 5) ** 5.",
- [["X = 0"]]);
- assert_prolog_success!(&mut wam, "X is (0 rdiv 5) ** 0.",
- [["X = 1.0"]]);
- assert_prolog_success!(&mut wam, "catch(_ is (0 rdiv 0) ** 5, error(E, _), true).",
- [["E = evaluation_error(zero_divisor)"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "X is (1 rdiv 3) ** 0.5, Y is X ** 2, 1 rdiv 3 ~ Y."
+ );
+
+ // assert_prolog_success!(&mut wam, "X is (-5) ** (-1 rdiv 3), Y is X ** 3, Y ~ -1 rdiv 5.");
+ // assert_prolog_failure!(&mut wam, "X is (-5) ** (-1 rdiv 3), Y is X ** 3, Y ~ 1 rdiv 5.");
+
+ assert_prolog_success!(&mut wam, "X is (0 rdiv 5) ** 5.", [["X = 0"]]);
+ assert_prolog_success!(&mut wam, "X is (-0 rdiv 5) ** 5.", [["X = 0"]]);
+ assert_prolog_success!(&mut wam, "X is (0 rdiv 5) ** 0.", [["X = 1.0"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(_ is (0 rdiv 0) ** 5, error(E, _), true).",
+ [["E = evaluation_error(zero_divisor)"]]
+ );
}
#[test]
-fn test_queries_on_exceptions()
-{
+fn test_queries_on_exceptions() {
let mut wam = Machine::new(readline::input_stream());
submit(&mut wam, "f(a). f(_) :- throw(stuff).");
submit(&mut wam, "handle(stuff).");
- assert_prolog_success!(&mut wam, "catch(f(X), E, handle(E)).",
- [["E = _2", "X = a"],
- ["E = stuff", "X = _1"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(f(X), E, handle(E)).",
+ [["E = _2", "X = a"], ["E = stuff", "X = _1"]]
+ );
submit(&mut wam, "f(a). f(X) :- g(X).");
submit(&mut wam, "g(x). g(y). g(z).");
submit(&mut wam, "handle(x). handle(y).");
- assert_prolog_success!(&mut wam, "catch(f(X), X, handle(X)).",
- [["X = a"],
- ["X = x"],
- ["X = y"],
- ["X = z"]]);
- assert_prolog_success!(&mut wam, "catch(f(a), _, handle(X)).",
- [["X = _4"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(f(X), X, handle(X)).",
+ [["X = a"], ["X = x"], ["X = y"], ["X = z"]]
+ );
+ assert_prolog_success!(&mut wam, "catch(f(a), _, handle(X)).", [["X = _4"]]);
assert_prolog_failure!(&mut wam, "catch(f(b), _, handle(X)).");
submit(&mut wam, "g(x). g(X) :- throw(x).");
- assert_prolog_success!(&mut wam, "catch(f(X), x, handle(X)).",
- [["X = a"],
- ["X = x"],
- ["X = x"],
- ["X = y"]]);
- assert_prolog_success!(&mut wam, "catch(f(X), x, handle(z)).",
- [["X = a"],
- ["X = x"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(f(X), x, handle(X)).",
+ [["X = a"], ["X = x"], ["X = x"], ["X = y"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(f(X), x, handle(z)).",
+ [["X = a"], ["X = x"]]
+ );
assert_prolog_success!(&mut wam, "catch(f(z), x, handle(x)).");
assert_prolog_success!(&mut wam, "catch(f(z), x, handle(y)).");
assert_prolog_failure!(&mut wam, "catch(f(z), x, handle(z)).");
submit(&mut wam, "handle(stuff). handle(other_stuff).");
// the first 3 cases should deterministically succeed.
- assert_prolog_success!(&mut wam, "catch(f(X), E, handle(E)).",
- [["X = _1", "E = stuff"]]);
- assert_prolog_success!(&mut wam, "catch(f(X), E, handle(stuff)).",
- [["X = _1", "E = stuff"]]);
- assert_prolog_success!(&mut wam, "catch(f(X), E, handle(other_stuff)).",
- [["X = _1", "E = stuff"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(f(X), E, handle(E)).",
+ [["X = _1", "E = stuff"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(f(X), E, handle(stuff)).",
+ [["X = _1", "E = stuff"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(f(X), E, handle(other_stuff)).",
+ [["X = _1", "E = stuff"]]
+ );
assert_prolog_failure!(&mut wam, "catch(f(X), E, handle(not_stuff)).");
submit(&mut wam, "f(success). f(X) :- catch(g(X), E, handle(E)).");
submit(&mut wam, "g(g_success). g(g_success_2). g(X) :- throw(X).");
submit(&mut wam, "handle(x). handle(y). handle(z).");
- assert_prolog_success!(&mut wam, "catch(f(X), E, E).",
- [["X = success", "E = _2"],
- ["X = g_success", "E = _2"],
- ["X = g_success_2", "E = _2"],
- ["X = _1", "E = _2"],
- ["X = _1", "E = _2"],
- ["X = _1", "E = _2"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(f(X), E, E).",
+ [
+ ["X = success", "E = _2"],
+ ["X = g_success", "E = _2"],
+ ["X = g_success_2", "E = _2"],
+ ["X = _1", "E = _2"],
+ ["X = _1", "E = _2"],
+ ["X = _1", "E = _2"]
+ ]
+ );
assert_prolog_failure!(&mut wam, "catch(f(fail), _, _).");
assert_prolog_success!(&mut wam, "catch(f(x), _, _).");
assert_prolog_success!(&mut wam, "catch(f(y), _, _).");
submit(&mut wam, "f(success). f(E) :- catch(g(E), E, handle(E)).");
submit(&mut wam, "g(g_success). g(g_success_2). g(X) :- throw(X).");
- submit(&mut wam, "handle(x). handle(y). handle(z). handle(v) :- throw(X).");
+ submit(
+ &mut wam,
+ "handle(x). handle(y). handle(z). handle(v) :- throw(X).",
+ );
- assert_prolog_success!(&mut wam, "catch(f(X), E, E).",
- [["X = success", "E = _2"],
- ["X = g_success", "E = _2"],
- ["X = g_success_2", "E = _2"],
- ["X = x", "E = _2"],
- ["X = y", "E = _2"],
- ["X = z", "E = _2"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(f(X), E, E).",
+ [
+ ["X = success", "E = _2"],
+ ["X = g_success", "E = _2"],
+ ["X = g_success_2", "E = _2"],
+ ["X = x", "E = _2"],
+ ["X = y", "E = _2"],
+ ["X = z", "E = _2"]
+ ]
+ );
- submit(&mut wam, "handle(x). handle(y). handle(z). handle(v) :- throw(handle_top(X)).");
+ submit(
+ &mut wam,
+ "handle(x). handle(y). handle(z). handle(v) :- throw(handle_top(X)).",
+ );
submit(&mut wam, "handle_top(an_error_1). handle_top(an_error_2).");
- assert_prolog_success!(&mut wam, "catch(f(X), E, E).",
- [["X = success", "E = _2"],
- ["X = g_success", "E = _2"],
- ["X = g_success_2", "E = _2"],
- ["X = x", "E = _2"],
- ["X = y", "E = _2"],
- ["X = z", "E = _2"],
- ["X = _1", "E = handle_top(an_error_1)"],
- ["X = _1", "E = handle_top(an_error_2)"]]);
-
- submit(&mut wam, "handle(x). handle(y). handle(z). handle(v) :- throw(X).");
-
- assert_prolog_success!(&mut wam, "catch(f(X), E, handle_top(E)).",
- [["X = success", "E = _2"],
- ["X = g_success", "E = _2"],
- ["X = g_success_2", "E = _2"],
- ["X = x", "E = _2"],
- ["X = y", "E = _2"],
- ["X = z", "E = _2"],
- ["E = an_error_1", "X = _1"],
- ["E = an_error_2", "X = _1"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(f(X), E, E).",
+ [
+ ["X = success", "E = _2"],
+ ["X = g_success", "E = _2"],
+ ["X = g_success_2", "E = _2"],
+ ["X = x", "E = _2"],
+ ["X = y", "E = _2"],
+ ["X = z", "E = _2"],
+ ["X = _1", "E = handle_top(an_error_1)"],
+ ["X = _1", "E = handle_top(an_error_2)"]
+ ]
+ );
+
+ submit(
+ &mut wam,
+ "handle(x). handle(y). handle(z). handle(v) :- throw(X).",
+ );
+
+ assert_prolog_success!(
+ &mut wam,
+ "catch(f(X), E, handle_top(E)).",
+ [
+ ["X = success", "E = _2"],
+ ["X = g_success", "E = _2"],
+ ["X = g_success_2", "E = _2"],
+ ["X = x", "E = _2"],
+ ["X = y", "E = _2"],
+ ["X = z", "E = _2"],
+ ["E = an_error_1", "X = _1"],
+ ["E = an_error_2", "X = _1"]
+ ]
+ );
}
#[test]
let mut wam = Machine::new(readline::input_stream());
// test on proper and empty lists.
- assert_prolog_success!(&mut wam, "'$skip_max_list'(N,5,[],Xs).",
- [["Xs = []","N = 0"]]);
- assert_prolog_success!(&mut wam, "'$skip_max_list'(N,5,[a,b,c],Xs).",
- [["Xs = []","N = 3"]]);
- assert_prolog_success!(&mut wam, "'$skip_max_list'(N,2,[a,b,c],Xs).",
- [["Xs = [c]","N = 2"]]);
- assert_prolog_success!(&mut wam, "'$skip_max_list'(N,3,[a,b,c],Xs).",
- [["Xs = []","N = 3"]]);
-
- assert_prolog_success!(&mut wam, "'$skip_max_list'(N,0,[],Xs).",
- [["Xs = []","N = 0"]]);
- assert_prolog_success!(&mut wam, "'$skip_max_list'(N,0,[a,b,c],Xs).",
- [["Xs = [a,b,c]","N = 0"]]);
- assert_prolog_success!(&mut wam, "'$skip_max_list'(N,0,[a,b,c],Xs).",
- [["Xs = [a,b,c]","N = 0"]]);
- assert_prolog_success!(&mut wam, "'$skip_max_list'(N,0,[a,b,c],Xs).",
- [["Xs = [a,b,c]","N = 0"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "'$skip_max_list'(N,5,[],Xs).",
+ [["Xs = []", "N = 0"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "'$skip_max_list'(N,5,[a,b,c],Xs).",
+ [["Xs = []", "N = 3"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "'$skip_max_list'(N,2,[a,b,c],Xs).",
+ [["Xs = [c]", "N = 2"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "'$skip_max_list'(N,3,[a,b,c],Xs).",
+ [["Xs = []", "N = 3"]]
+ );
+
+ assert_prolog_success!(
+ &mut wam,
+ "'$skip_max_list'(N,0,[],Xs).",
+ [["Xs = []", "N = 0"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "'$skip_max_list'(N,0,[a,b,c],Xs).",
+ [["Xs = [a,b,c]", "N = 0"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "'$skip_max_list'(N,0,[a,b,c],Xs).",
+ [["Xs = [a,b,c]", "N = 0"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "'$skip_max_list'(N,0,[a,b,c],Xs).",
+ [["Xs = [a,b,c]", "N = 0"]]
+ );
assert_prolog_failure!(&mut wam, "'$skip_max_list'(4,0,[],Xs).");
assert_prolog_failure!(&mut wam, "'$skip_max_list'(3,0,[a,b,c],Xs).");
assert_prolog_failure!(&mut wam, "'$skip_max_list'(2,0,[a,b,c],Xs).");
assert_prolog_failure!(&mut wam, "'$skip_max_list'(1,0,[a,b,c],Xs).");
- assert_prolog_success!(&mut wam, "'$skip_max_list'(0,5,[],Xs).",
- [["Xs = []"]]);
- assert_prolog_success!(&mut wam, "'$skip_max_list'(3,5,[a,b,c],Xs).",
- [["Xs = []"]]);
- assert_prolog_success!(&mut wam, "'$skip_max_list'(2,2,[a,b,c],Xs).",
- [["Xs = [c]"]]);
- assert_prolog_success!(&mut wam, "'$skip_max_list'(3,3,[a,b,c],Xs).",
- [["Xs = []"]]);
+ assert_prolog_success!(&mut wam, "'$skip_max_list'(0,5,[],Xs).", [["Xs = []"]]);
+ assert_prolog_success!(&mut wam, "'$skip_max_list'(3,5,[a,b,c],Xs).", [["Xs = []"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "'$skip_max_list'(2,2,[a,b,c],Xs).",
+ [["Xs = [c]"]]
+ );
+ assert_prolog_success!(&mut wam, "'$skip_max_list'(3,3,[a,b,c],Xs).", [["Xs = []"]]);
// tests on proper and empty lists with no max.
// test on proper and empty lists.
- assert_prolog_success!(&mut wam, "'$skip_max_list'(N,-1,[],Xs).",
- [["Xs = []","N = 0"]]);
- assert_prolog_success!(&mut wam, "'$skip_max_list'(N,-1,[a,b,c],Xs).",
- [["Xs = []","N = 3"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "'$skip_max_list'(N,-1,[],Xs).",
+ [["Xs = []", "N = 0"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "'$skip_max_list'(N,-1,[a,b,c],Xs).",
+ [["Xs = []", "N = 3"]]
+ );
- assert_prolog_success!(&mut wam, "'$skip_max_list'(N,-1,[],Xs).",
- [["Xs = []","N = 0"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "'$skip_max_list'(N,-1,[],Xs).",
+ [["Xs = []", "N = 0"]]
+ );
assert_prolog_failure!(&mut wam, "'$skip_max_list'(4,-1,[],Xs).");
- assert_prolog_success!(&mut wam, "'$skip_max_list'(3,-1,[a,b,c],Xs).",
- [["Xs = []"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "'$skip_max_list'(3,-1,[a,b,c],Xs).",
+ [["Xs = []"]]
+ );
- assert_prolog_success!(&mut wam, "'$skip_max_list'(0,-1,[],Xs).",
- [["Xs = []"]]);
- assert_prolog_success!(&mut wam, "'$skip_max_list'(3,-1,[a,b,c],Xs).",
- [["Xs = []"]]);
+ assert_prolog_success!(&mut wam, "'$skip_max_list'(0,-1,[],Xs).", [["Xs = []"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "'$skip_max_list'(3,-1,[a,b,c],Xs).",
+ [["Xs = []"]]
+ );
// tests on partial lists.
- assert_prolog_success!(&mut wam, "'$skip_max_list'(3,4,[a,b,c|X],Xs0).",
- [["X = _1","Xs0 = _1"]]);
- assert_prolog_success!(&mut wam, "'$skip_max_list'(3,3,[a,b,c|X],Xs0).",
- [["X = _1","Xs0 = _1"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "'$skip_max_list'(3,4,[a,b,c|X],Xs0).",
+ [["X = _1", "Xs0 = _1"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "'$skip_max_list'(3,3,[a,b,c|X],Xs0).",
+ [["X = _1", "Xs0 = _1"]]
+ );
assert_prolog_failure!(&mut wam, "'$skip_max_list'(3,2,[a,b,c|X],Xs0).");
assert_prolog_failure!(&mut wam, "'$skip_max_list'(3,1,[a,b,c|X],Xs0).");
assert_prolog_failure!(&mut wam, "'$skip_max_list'(3,0,[a,b,c|X],Xs0).");
// tests on cyclic lists.
assert_prolog_failure!(&mut wam, "Xs = [a,b|Xs],'$skip_max_list'(3,5,X,Xs0).");
- assert_prolog_failure!(&mut wam, "X = [a,b|Y],Y = [c,d|X],'$skip_max_list'(4,5,X,Xs0).");
- assert_prolog_failure!(&mut wam, "X = [a,b|Y],Y = [c,d|X],'$skip_max_list'(4,3,X,Xs0).");
+ assert_prolog_failure!(
+ &mut wam,
+ "X = [a,b|Y],Y = [c,d|X],'$skip_max_list'(4,5,X,Xs0)."
+ );
+ assert_prolog_failure!(
+ &mut wam,
+ "X = [a,b|Y],Y = [c,d|X],'$skip_max_list'(4,3,X,Xs0)."
+ );
// tests on non lists.
- assert_prolog_success!(&mut wam, "'$skip_max_list'(N,9,non_list,Xs).",
- [["Xs = non_list","N = 0"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "'$skip_max_list'(N,9,non_list,Xs).",
+ [["Xs = non_list", "N = 0"]]
+ );
}
#[test]
-fn test_queries_on_conditionals()
-{
+fn test_queries_on_conditionals() {
let mut wam = Machine::new(readline::input_stream());
- submit(&mut wam, "test(A) :- ( A =:= 2 -> writeq(\"A is 2\")
+ submit(
+ &mut wam,
+ "test(A) :- ( A =:= 2 -> writeq(\"A is 2\")
; A =:= 3 -> writeq(\"A is 3\")
; A = \"not 2 or 3\"
- ).");
+ ).",
+ );
- assert_prolog_success!(&mut wam, "catch(test(A), error(instantiation_error, _), true).");
+ assert_prolog_success!(
+ &mut wam,
+ "catch(test(A), error(instantiation_error, _), true)."
+ );
assert_prolog_success!(&mut wam, "A = 2, test(A).", [["A = 2"]]);
- assert_prolog_success!(&mut wam, "A = 3, test(A), B = 3, test(B).", [["A = 3", "B = 3"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "A = 3, test(A), B = 3, test(B).",
+ [["A = 3", "B = 3"]]
+ );
submit(&mut wam, "f(a). f(b).");
submit(&mut wam, "g(1). g(2). g(3).");
- submit(&mut wam, "typed_dispatch(X) :- ( var(X) -> f(X)
+ submit(
+ &mut wam,
+ "typed_dispatch(X) :- ( var(X) -> f(X)
; integer(X) -> g(X)
- ; atomic(X)).");
+ ; atomic(X)).",
+ );
assert_prolog_success!(&mut wam, "typed_dispatch(X).", [["X = a"], ["X = b"]]);
assert_prolog_success!(&mut wam, "typed_dispatch(a).");
assert_prolog_failure!(&mut wam, "typed_dispatch(compound(term)).");
submit(&mut wam, "f(a). f(b). f(compound(term)).");
- submit(&mut wam, "g(X, Y) :- f(X), (atomic(X) -> X = a ; X = a ; X = compound(Y)).");
+ submit(
+ &mut wam,
+ "g(X, Y) :- f(X), (atomic(X) -> X = a ; X = a ; X = compound(Y)).",
+ );
- assert_prolog_success!(&mut wam, "g(X, Y).",
- [["Y = _1", "X = a"],
- ["Y = term", "X = compound(term)"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "g(X, Y).",
+ [["Y = _1", "X = a"], ["Y = term", "X = compound(term)"]]
+ );
assert_prolog_success!(&mut wam, "g(X, X).", [["X = a"]]);
assert_prolog_success!(&mut wam, "g(compound(X), X).", [["X = term"]]);
assert_prolog_success!(&mut wam, "g(a, _).");
assert_prolog_success!(&mut wam, "g(X, _), X = a.", [["X = a"]]);
- submit(&mut wam, "g(X) :- var(X) -> (var(X) -> X is 3 + 3 ; X = not_6).");
+ submit(
+ &mut wam,
+ "g(X) :- var(X) -> (var(X) -> X is 3 + 3 ; X = not_6).",
+ );
assert_prolog_success!(&mut wam, "g(X).", [["X = 6"]]);
assert_prolog_failure!(&mut wam, "g(1).");
assert_prolog_success!(&mut wam, "f(X), (g(Y), !).", [["X = a", "Y = 6"]]);
- submit(&mut wam, "test(X, [X]) :- (atomic(X) -> true ; throw(type_error(atomic_expected, X))).
- test(_, _).");
+ submit(
+ &mut wam,
+ "test(X, [X]) :- (atomic(X) -> true ; throw(type_error(atomic_expected, X))).
+ test(_, _).",
+ );
- assert_prolog_success!(&mut wam, "catch(test(a, [a]), type_error(E), true).",
- [["E = _6"], ["E = _6"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(test(a, [a]), type_error(E), true).",
+ [["E = _6"], ["E = _6"]]
+ );
- assert_prolog_success!(&mut wam, "f(X), call(->, atomic(X), true).",
- [["X = a"], ["X = b"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "f(X), call(->, atomic(X), true).",
+ [["X = a"], ["X = b"]]
+ );
}
#[test]
-fn test_queries_on_modules()
-{
+fn test_queries_on_modules() {
let mut wam = Machine::new(readline::input_stream());
submit(&mut wam, ":- use_module('src/prolog/lib/lists.pl').");
- submit_code(&mut wam, "
+ submit_code(
+ &mut wam,
+ "
:- module(my_lists, [local_member/2, reverse/2]).
:- use_module('src/prolog/lib/lists.pl', [member/2]).
local_member(X, Xs) :- member(X, Xs).
-reverse(Xs, Ys) :- lists:reverse(Xs, Ys).");
+reverse(Xs, Ys) :- lists:reverse(Xs, Ys).",
+ );
assert_prolog_success!(&mut wam, "my_lists:local_member(1, [1,2,3]).");
assert_prolog_success!(&mut wam, "my_lists:reverse([a,b,c], [c,b,a]).");
- submit_code(&mut wam, "
+ submit_code(
+ &mut wam,
+ "
:- module(my_lists_2, [local_member/2]).
-:- use_module(library(my_lists), [local_member/2]).");
+:- use_module(library(my_lists), [local_member/2]).",
+ );
assert_prolog_success!(&mut wam, "my_lists_2:local_member(1, [1,2,3]).");
- assert_prolog_success!(&mut wam, "catch(local_member(X, Xs), error(E, _), true).",
- [["X = _1", "E = existence_error(procedure,local_member/2)", "Xs = _2"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(local_member(X, Xs), error(E, _), true).",
+ [[
+ "X = _1",
+ "E = existence_error(procedure,local_member/2)",
+ "Xs = _2"
+ ]]
+ );
- submit(&mut wam, ":- use_module('src/prolog/lib/lists.pl', [reverse/2]).");
+ submit(
+ &mut wam,
+ ":- use_module('src/prolog/lib/lists.pl', [reverse/2]).",
+ );
- assert_prolog_success!(&mut wam, "catch(member(_, _), error(existence_error(procedure, P), _), true).",
- [["P = member/2"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(member(_, _), error(existence_error(procedure, P), _), true).",
+ [["P = member/2"]]
+ );
assert_prolog_success!(&mut wam, "reverse(_, _).");
submit(&mut wam, ":- use_module('src/prolog/lib/lists.pl', []).");
- assert_prolog_success!(&mut wam, "catch(reverse(_, _), error(existence_error(procedure, P), _), true).",
- [["P = reverse/2"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(reverse(_, _), error(existence_error(procedure, P), _), true).",
+ [["P = reverse/2"]]
+ );
}
#[test]
-fn test_queries_on_builtins()
-{
+fn test_queries_on_builtins() {
let mut wam = Machine::new(readline::input_stream());
submit(&mut wam, ":- use_module('src/prolog/lib/lists.pl').");
assert_prolog_success!(&mut wam, "arg(3, f(a,b,c,d), Arg).", [["Arg = c"]]);
assert_prolog_success!(&mut wam, "arg(4, f(a,b,c,d), Arg).", [["Arg = d"]]);
- assert_prolog_success!(&mut wam, "catch(arg(N, f, Arg), error(E, _), true).",
- [["E = instantiation_error", "Arg = _3", "N = _1"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(arg(N, f, Arg), error(E, _), true).",
+ [["E = instantiation_error", "Arg = _3", "N = _1"]]
+ );
assert_prolog_failure!(&mut wam, "arg(N, f(arg, arg, arg), not_arg).");
assert_prolog_failure!(&mut wam, "arg(1, f(arg, not_arg, not_arg), not_arg).");
assert_prolog_success!(&mut wam, "arg(2, f(arg, not_arg, not_arg), not_arg).");
assert_prolog_success!(&mut wam, "arg(3, f(arg, not_arg, not_arg), not_arg).");
- assert_prolog_success!(&mut wam, "functor(f(a,b,c), F, Arity).",
- [["F = f", "Arity = 3"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "functor(f(a,b,c), F, Arity).",
+ [["F = f", "Arity = 3"]]
+ );
- assert_prolog_success!(&mut wam, "functor(f(a,b,c), F, N).",
- [["F = f", "N = 3"]]);
+ assert_prolog_success!(&mut wam, "functor(f(a,b,c), F, N).", [["F = f", "N = 3"]]);
assert_prolog_failure!(&mut wam, "functor(f(a,b,c), g, N).");
assert_prolog_success!(&mut wam, "functor(f(a,b,c), F, 3).", [["F = f"]]);
assert_prolog_failure!(&mut wam, "functor(f(a,b,c), F, 4).");
assert_prolog_success!(&mut wam, "functor(F, f, 0).", [["F = f"]]);
- assert_prolog_success!(&mut wam, "functor(Func,f,3).",[["Func = f(_2,_3,_4)"]]);
- assert_prolog_success!(&mut wam, "functor(Func,f,4).",[["Func = f(_2,_3,_4,_5)"]]);
+ assert_prolog_success!(&mut wam, "functor(Func,f,3).", [["Func = f(_2,_3,_4)"]]);
+ assert_prolog_success!(&mut wam, "functor(Func,f,4).", [["Func = f(_2,_3,_4,_5)"]]);
- assert_prolog_success!(&mut wam, "catch(functor(F,\"sdf\",3),error(E,_),true).",
- [["E = type_error(atom,[s,d,f])","F = _1"]]);
- assert_prolog_success!(&mut wam, "catch(functor(Func,F,3),error(E,_),true).",
- [["E = instantiation_error","Func = _1","F = _2"]]);
- assert_prolog_success!(&mut wam, "catch(functor(Func,f,N),error(E,_),true).",
- [["E = instantiation_error","Func = _1","N = _3"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(functor(F,\"sdf\",3),error(E,_),true).",
+ [["E = type_error(atom,[s,d,f])", "F = _1"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(functor(Func,F,3),error(E,_),true).",
+ [["E = instantiation_error", "Func = _1", "F = _2"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(functor(Func,f,N),error(E,_),true).",
+ [["E = instantiation_error", "Func = _1", "N = _3"]]
+ );
assert_prolog_failure!(&mut wam, "catch(functor(Func,f,N),error(E,_),false).");
assert_prolog_success!(&mut wam, "X is 3,call(integer,X).");
assert_prolog_success!(&mut wam, "X is 3 + 3.5,\\+ call(integer,X).");
assert_prolog_success!(&mut wam, "X is 3 + 3.5,\\+ integer(X).");
- assert_prolog_success!(&mut wam, "Func =.. [atom].",[["Func = atom"]]);
- assert_prolog_success!(&mut wam, "Func =.. [\"sdf\"].",[["Func = [s,d,f]"]]);
- assert_prolog_success!(&mut wam, "Func =.. [1].",[["Func = 1"]]);
- assert_prolog_success!(&mut wam, "catch(Func =.. [1,2],error(type_error(atom,1),_),true).");
- assert_prolog_success!(&mut wam, "f(1,2,3) =.. List.",[["List = [f,1,2,3]"]]);
+ assert_prolog_success!(&mut wam, "Func =.. [atom].", [["Func = atom"]]);
+ assert_prolog_success!(&mut wam, "Func =.. [\"sdf\"].", [["Func = [s,d,f]"]]);
+ assert_prolog_success!(&mut wam, "Func =.. [1].", [["Func = 1"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(Func =.. [1,2],error(type_error(atom,1),_),true)."
+ );
+ assert_prolog_success!(&mut wam, "f(1,2,3) =.. List.", [["List = [f,1,2,3]"]]);
assert_prolog_success!(&mut wam, "f(1,2,3) =.. [f,1,2,3].");
assert_prolog_failure!(&mut wam, "f(1,2,3) =.. [f,1].");
assert_prolog_failure!(&mut wam, "f(1,2,3) =.. [g,1,2,3].");
- assert_prolog_success!(&mut wam, "f(1,2,3) =.. [f,X,Y,Z].",
- [["X = 1","Y = 2","Z = 3"]]);
-
- assert_prolog_success!(&mut wam, "length([a,b,c],N).",[["N = 3"]]);
- assert_prolog_success_with_limit!(&mut wam, "length(Xs,N).",
- [["N = 0","Xs = []"],
- ["N = 1","Xs = [_4]"],
- ["N = 2","Xs = [_4,_8]"],
- ["N = 3","Xs = [_4,_8,_12]"],
- ["N = 4","Xs = [_4,_8,_12,_16]"],
- ["N = 5","Xs = [_4,_8,_12,_16,_20]"]],
- 6);
-
- assert_prolog_success!(&mut wam, "length(Xs,3).",[["Xs = [_5,_9,_13]"]]);
- assert_prolog_success!(&mut wam, "length([],N).",[["N = 0"]]);
- assert_prolog_success!(&mut wam, "length(Xs,0).",[["Xs = []"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "f(1,2,3) =.. [f,X,Y,Z].",
+ [["X = 1", "Y = 2", "Z = 3"]]
+ );
+
+ assert_prolog_success!(&mut wam, "length([a,b,c],N).", [["N = 3"]]);
+ assert_prolog_success_with_limit!(
+ &mut wam,
+ "length(Xs,N).",
+ [
+ ["N = 0", "Xs = []"],
+ ["N = 1", "Xs = [_4]"],
+ ["N = 2", "Xs = [_4,_8]"],
+ ["N = 3", "Xs = [_4,_8,_12]"],
+ ["N = 4", "Xs = [_4,_8,_12,_16]"],
+ ["N = 5", "Xs = [_4,_8,_12,_16,_20]"]
+ ],
+ 6
+ );
+
+ assert_prolog_success!(&mut wam, "length(Xs,3).", [["Xs = [_5,_9,_13]"]]);
+ assert_prolog_success!(&mut wam, "length([],N).", [["N = 0"]]);
+ assert_prolog_success!(&mut wam, "length(Xs,0).", [["Xs = []"]]);
assert_prolog_success!(&mut wam, "length([a,b,[a,b,c]],3).");
assert_prolog_failure!(&mut wam, "length([a,b,[a,b,c]],2).");
- assert_prolog_success!(&mut wam, "catch(length(a,[]),error(E,_),true).",
- [["E = type_error(integer,[])"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(length(a,[]),error(E,_),true).",
+ [["E = type_error(integer,[])"]]
+ );
- assert_prolog_success!(&mut wam, "copy_term([1,2,3],[X,Y,Z]).",
- [["Z = 3","Y = 2","X = 1"]]);
- assert_prolog_success!(&mut wam, "copy_term(f(X,[a],Z),f(X,Y,Z)).",
- [["X = _3","Y = [a]","Z = _5"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "copy_term([1,2,3],[X,Y,Z]).",
+ [["Z = 3", "Y = 2", "X = 1"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "copy_term(f(X,[a],Z),f(X,Y,Z)).",
+ [["X = _3", "Y = [a]", "Z = _5"]]
+ );
assert_prolog_failure!(&mut wam, "copy_term(g(X),f(X)).");
- assert_prolog_success!(&mut wam, "copy_term(f(X),f(X)).",
- [["X = _1"]]);
- assert_prolog_success!(&mut wam, "copy_term([[[[X,Y],Y],X]],Term).",
- [["Term = [[[[_22,_26],_26],_22]]","X = _2","Y = _0"]]);
- assert_prolog_success!(&mut wam, "copy_term([X,[Y,[X]]],Term).",
- [["Term = [_12,[_16,[_12]]]","X = _0","Y = _4"]]);
+ assert_prolog_success!(&mut wam, "copy_term(f(X),f(X)).", [["X = _1"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "copy_term([[[[X,Y],Y],X]],Term).",
+ [["Term = [[[[_22,_26],_26],_22]]", "X = _2", "Y = _0"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "copy_term([X,[Y,[X]]],Term).",
+ [["Term = [_12,[_16,[_12]]]", "X = _0", "Y = _4"]]
+ );
// test copy_term on cyclic terms.
assert_prolog_failure!(&mut wam, "X = g(X,Y),Y = f(X),copy_term(Y,g(Z)).");
- assert_prolog_success!(&mut wam, "X = g(X,Y),Y = f(X),copy_term(Y,f(Z)).",
- [["Y = f(g(X,Y))","X = g(X,f(X))","Z = g(Z,f(Z))"]]);
- assert_prolog_success!(&mut wam, "X = g(X,Y),Y = f(X),copy_term(Y,V).",
- [["V = f(g(g(g(...,V),V),V))","X = g(X,f(X))","Y = f(g(X,Y))"]]);
- assert_prolog_success!(&mut wam, "f(Y,Y,[X,a,[],Y]) = Term,copy_term(Term,NewTerm).",
- [["NewTerm = f(_16,_16,[_19,a,[],_16])",
- "Term = f(_0,Y,[_6,a,[],Y])",
- "X = _6","Y = _0"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "X = g(X,Y),Y = f(X),copy_term(Y,f(Z)).",
+ [["Y = f(g(X,Y))", "X = g(X,f(X))", "Z = g(Z,f(Z))"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "X = g(X,Y),Y = f(X),copy_term(Y,V).",
+ [[
+ "V = f(g(g(g(...,V),V),V))",
+ "X = g(X,f(X))",
+ "Y = f(g(X,Y))"
+ ]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "f(Y,Y,[X,a,[],Y]) = Term,copy_term(Term,NewTerm).",
+ [[
+ "NewTerm = f(_16,_16,[_19,a,[],_16])",
+ "Term = f(_0,Y,[_6,a,[],Y])",
+ "X = _6",
+ "Y = _0"
+ ]]
+ );
assert_prolog_success!(&mut wam, "float(3.14159269).");
assert_prolog_failure!(&mut wam, "float(3).");
assert_prolog_failure!(&mut wam, "B = f(A),ground(B).");
assert_prolog_failure!(&mut wam, "B = f(A),ground(A).");
- assert_prolog_success!(&mut wam, "ground(x),ground(f(x)),X = f(x),ground(g(f(X),[a,b])).");
+ assert_prolog_success!(
+ &mut wam,
+ "ground(x),ground(f(x)),X = f(x),ground(g(f(X),[a,b]))."
+ );
assert_prolog_success!(&mut wam, "A = f(A),g(A,B) == g(f(A),B).");
assert_prolog_failure!(&mut wam, "A = f(A),g(A,B) == g(f(A),b).");
assert_prolog_success!(&mut wam, "1 @=< 1.0.");
submit(&mut wam, ":- use_module('src/prolog/lib/non_iso.pl').");
-
+
assert_prolog_success!(&mut wam, "variant(X, Y).");
assert_prolog_failure!(&mut wam, "variant(f(X), f(x)).");
assert_prolog_success!(&mut wam, "variant(X, X).");
assert_prolog_success!(&mut wam, "variant([X,Y,X], [V,W,V]).");
assert_prolog_success!(&mut wam, "g(B) = B, g(A) = A, variant(A, B).");
- assert_prolog_success!(&mut wam, "keysort([1-1,1-1],Sorted).",
- [["Sorted = [1-1,1-1]"]]);
- assert_prolog_success!(&mut wam, "keysort([2-99,1-a,3-f(_),1-z,1-a,2-44],Sorted).",
- [["Sorted = [1-a,1-z,1-a,2-99,2-44,3-f(_7)]"]]);
- assert_prolog_success!(&mut wam, "keysort([X-1,1-1],[2-1,1-1]).",
- [["X = 2"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "keysort([1-1,1-1],Sorted).",
+ [["Sorted = [1-1,1-1]"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "keysort([2-99,1-a,3-f(_),1-z,1-a,2-44],Sorted).",
+ [["Sorted = [1-a,1-z,1-a,2-99,2-44,3-f(_7)]"]]
+ );
+ assert_prolog_success!(&mut wam, "keysort([X-1,1-1],[2-1,1-1]).", [["X = 2"]]);
assert_prolog_failure!(&mut wam, "Pairs = [a-a|Pairs],keysort(Pairs,_).");
- assert_prolog_success!(&mut wam, "Pairs = [a-a|Pairs],catch(keysort(Pairs,_),error(E,_),true).",
- [["E = type_error(list,[a-a,a-a,a-a|...])","Pairs = [a-a|Pairs]"]]);
-
- assert_prolog_success!(&mut wam, "keysort([],L).",
- [["L = []"]]);
- assert_prolog_success!(&mut wam, "catch(keysort([a|_],_),error(E,_),true).",
- [["E = instantiation_error"]]);
- assert_prolog_success!(&mut wam, "catch(keysort([],[a|a]),error(Pat,_),true).",
- [["Pat = type_error(list,[a|a])"]]);
- assert_prolog_success!(&mut wam, "catch(keysort(_,_),error(E,_),true).",
- [["E = type_error(list,_16)"]]);
- assert_prolog_success!(&mut wam, "catch(keysort([a-1],[_|b]),error(E,_),true).",
- [["E = type_error(list,[_27|b])"]]);
- assert_prolog_success!(&mut wam, "catch(keysort([a-1],[a-b,c-d,a]),error(E,_),true).",
- [["E = type_error(pair,a)"]]);
- assert_prolog_success!(&mut wam, "catch(keysort([a],[a-b]),error(E,_),true).",
- [["E = type_error(pair,a)"]]);
-
- assert_prolog_success!(&mut wam, "catch(sort([a|_],_),error(E,_),true).",
- [["E = instantiation_error"]]);
- assert_prolog_success!(&mut wam, "catch(sort([],[a|a]),error(Pat,_),true).",
- [["Pat = type_error(list,[a|a])"]]);
- assert_prolog_success!(&mut wam, "sort([],L).",
- [["L = []"]]);
- assert_prolog_success!(&mut wam, "catch(sort(_,[]),error(E,_),true).",
- [["E = type_error(list,_16)"]]);
- assert_prolog_success!(&mut wam, "catch(sort([a,b,c],not_a_list),error(E,_),true).",
- [["E = type_error(list,not_a_list)"]]);
-
- assert_prolog_success!(&mut wam, "call(((G = 2 ; fail),B=3,!)).",
- [["G = 2","B = 3"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "Pairs = [a-a|Pairs],catch(keysort(Pairs,_),error(E,_),true).",
+ [[
+ "E = type_error(list,[a-a,a-a,a-a|...])",
+ "Pairs = [a-a|Pairs]"
+ ]]
+ );
+
+ assert_prolog_success!(&mut wam, "keysort([],L).", [["L = []"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(keysort([a|_],_),error(E,_),true).",
+ [["E = instantiation_error"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(keysort([],[a|a]),error(Pat,_),true).",
+ [["Pat = type_error(list,[a|a])"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(keysort(_,_),error(E,_),true).",
+ [["E = type_error(list,_16)"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(keysort([a-1],[_|b]),error(E,_),true).",
+ [["E = type_error(list,[_27|b])"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(keysort([a-1],[a-b,c-d,a]),error(E,_),true).",
+ [["E = type_error(pair,a)"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(keysort([a],[a-b]),error(E,_),true).",
+ [["E = type_error(pair,a)"]]
+ );
+
+ assert_prolog_success!(
+ &mut wam,
+ "catch(sort([a|_],_),error(E,_),true).",
+ [["E = instantiation_error"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(sort([],[a|a]),error(Pat,_),true).",
+ [["Pat = type_error(list,[a|a])"]]
+ );
+ assert_prolog_success!(&mut wam, "sort([],L).", [["L = []"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(sort(_,[]),error(E,_),true).",
+ [["E = type_error(list,_16)"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(sort([a,b,c],not_a_list),error(E,_),true).",
+ [["E = type_error(list,not_a_list)"]]
+ );
+
+ assert_prolog_success!(
+ &mut wam,
+ "call(((G = 2 ; fail),B=3,!)).",
+ [["G = 2", "B = 3"]]
+ );
assert_prolog_success!(&mut wam, "call_with_inference_limit((setup_call_cleanup(S=1,(G=2;fail),writeq(S+G>B)),B=3,!),135,R).",
[["G = 2","B = 3","R = !","S = 1"]]);
- assert_prolog_success!(&mut wam, "call_with_inference_limit((setup_call_cleanup(S=1,(G=2;fail),writeq(S+G>B)),B=3,!),10,R).",
- [["S = _1","G = _4","B = _14","R = inference_limit_exceeded"]]);
-
- assert_prolog_success!(&mut wam, "X = '\\033\\'.",
- [["X = '\\x1b\\'"]]);
-
- assert_prolog_success!(&mut wam, "X = '\\n'.",
- [["X = '\\n'"]]);
- assert_prolog_success!(&mut wam, "X = '\\b'.",
- [["X = '\\b'"]]);
- assert_prolog_success!(&mut wam, "X = '\\v'.",
- [["X = '\\v'"]]);
- assert_prolog_success!(&mut wam, "X = '\\a'.",
- [["X = '\\a'"]]);
- assert_prolog_success!(&mut wam, "X = '\\f'.",
- [["X = '\\f'"]]);
- assert_prolog_success!(&mut wam, "X = '\\b\\r\\f\\t\\n'.",
- [["X = '\\b\\r\\f\\t\\n'"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit((setup_call_cleanup(S=1,(G=2;fail),writeq(S+G>B)),B=3,!),10,R).",
+ [[
+ "S = _1",
+ "G = _4",
+ "B = _14",
+ "R = inference_limit_exceeded"
+ ]]
+ );
+
+ assert_prolog_success!(&mut wam, "X = '\\033\\'.", [["X = '\\x1b\\'"]]);
+
+ assert_prolog_success!(&mut wam, "X = '\\n'.", [["X = '\\n'"]]);
+ assert_prolog_success!(&mut wam, "X = '\\b'.", [["X = '\\b'"]]);
+ assert_prolog_success!(&mut wam, "X = '\\v'.", [["X = '\\v'"]]);
+ assert_prolog_success!(&mut wam, "X = '\\a'.", [["X = '\\a'"]]);
+ assert_prolog_success!(&mut wam, "X = '\\f'.", [["X = '\\f'"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "X = '\\b\\r\\f\\t\\n'.",
+ [["X = '\\b\\r\\f\\t\\n'"]]
+ );
assert_prolog_success!(&mut wam, "(- (1)) = -(1).");
assert_prolog_success!(&mut wam, "(- -1) = -(-1).");
- assert_prolog_success!(&mut wam, "X = ((*)=(*)).",
- [["X = ((*)=(*))"]]);
- assert_prolog_success!(&mut wam, "X = [.,.(.,.,.)].",
- [["X = ['.','.'('.','.','.')]"]]);
- assert_prolog_success!(&mut wam, "X = a+(b*c).",
- [["X = a+b*c"]]);
- assert_prolog_success!(&mut wam, "X = a*(b+c).",
- [["X = a*(b+c)"]]);
- assert_prolog_success!(&mut wam, "X = [:-,-].",
- [["X = [:-,-]"]]);
- assert_prolog_success!(&mut wam, "X = a*(b+c).",
- [["X = a*(b+c)"]]);
- assert_prolog_success!(&mut wam, "X = (-)-(-).",
- [["X = (-)-(-)"]]);
- assert_prolog_success!(&mut wam, "X = ((:-):-(:-)).",
- [["X = ((:-):-(:-))"]]);
- assert_prolog_success!(&mut wam, "X = (a:-b,c).",
- [["X = (a:-b,c)"]]);
- assert_prolog_success!(&mut wam, "X = f((f:-a,b,c)).",
- [["X = f((f:-a,b,c))"]]);
- assert_prolog_success!(&mut wam, "X = f((f:-a,(b,c))).",
- [["X = f((f:-a,b,c))"]]);
- assert_prolog_success!(&mut wam, "X = f((a,b,c)).",
- [["X = f((a,b,c))"]]);
- assert_prolog_success!(&mut wam, "X = f((a,(b,c))).",
- [["X = f((a,b,c))"]]);
- assert_prolog_success!(&mut wam, "X = f(((a,b),c)).",
- [["X = f(((a,b),c))"]]);
- assert_prolog_success!(&mut wam, "X = f(((a,b),(c,d))).",
- [["X = f(((a,b),c,d))"]]);
-
- assert_prolog_success!(&mut wam, "findall(X,(X = 1 ; X = 2),S).",
- [["S = [1,2]","X = _0"]]);
- assert_prolog_success!(&mut wam, "findall(X+Y,(X = 1),S).",
- [["S = [1+_36]","X = _1","Y = _2"]]);
- assert_prolog_success!(&mut wam, "findall(X,false,S).",
- [["S = []","X = _0"]]);
- assert_prolog_success!(&mut wam, "findall(X,(X = 1 ; X = 1),S).",
- [["S = [1,1]","X = _0"]]);
+ assert_prolog_success!(&mut wam, "X = ((*)=(*)).", [["X = ((*)=(*))"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "X = [.,.(.,.,.)].",
+ [["X = ['.','.'('.','.','.')]"]]
+ );
+ assert_prolog_success!(&mut wam, "X = a+(b*c).", [["X = a+b*c"]]);
+ assert_prolog_success!(&mut wam, "X = a*(b+c).", [["X = a*(b+c)"]]);
+ assert_prolog_success!(&mut wam, "X = [:-,-].", [["X = [:-,-]"]]);
+ assert_prolog_success!(&mut wam, "X = a*(b+c).", [["X = a*(b+c)"]]);
+ assert_prolog_success!(&mut wam, "X = (-)-(-).", [["X = (-)-(-)"]]);
+ assert_prolog_success!(&mut wam, "X = ((:-):-(:-)).", [["X = ((:-):-(:-))"]]);
+ assert_prolog_success!(&mut wam, "X = (a:-b,c).", [["X = (a:-b,c)"]]);
+ assert_prolog_success!(&mut wam, "X = f((f:-a,b,c)).", [["X = f((f:-a,b,c))"]]);
+ assert_prolog_success!(&mut wam, "X = f((f:-a,(b,c))).", [["X = f((f:-a,b,c))"]]);
+ assert_prolog_success!(&mut wam, "X = f((a,b,c)).", [["X = f((a,b,c))"]]);
+ assert_prolog_success!(&mut wam, "X = f((a,(b,c))).", [["X = f((a,b,c))"]]);
+ assert_prolog_success!(&mut wam, "X = f(((a,b),c)).", [["X = f(((a,b),c))"]]);
+ assert_prolog_success!(&mut wam, "X = f(((a,b),(c,d))).", [["X = f(((a,b),c,d))"]]);
+
+ assert_prolog_success!(
+ &mut wam,
+ "findall(X,(X = 1 ; X = 2),S).",
+ [["S = [1,2]", "X = _0"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "findall(X+Y,(X = 1),S).",
+ [["S = [1+_36]", "X = _1", "Y = _2"]]
+ );
+ assert_prolog_success!(&mut wam, "findall(X,false,S).", [["S = []", "X = _0"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "findall(X,(X = 1 ; X = 1),S).",
+ [["S = [1,1]", "X = _0"]]
+ );
assert_prolog_failure!(&mut wam, "findall(X,(X = 2 ; X = 1),[1,2]).");
- assert_prolog_success!(&mut wam, "findall(X,(X = 1 ; X = 2),[X,Y]).",
- [["X = 1","Y = 2"]]);
- assert_prolog_success!(&mut wam, "catch(findall(X,4,S),error(type_error(callable,4),_),true).",
- [["S = _3","X = _1"]]);
-
- assert_prolog_success!(&mut wam, "bagof(X,(X=Y; X=Z),S).",
- [["S = [_3,_6]","X = _0","Y = _3","Z = _6"]]);
- assert_prolog_success!(&mut wam, "bagof(X,(X=1 ; X = 2),X).",
- [["X = [1,2]"]]);
- assert_prolog_success!(&mut wam, "bagof(X,(X=1 ; X = 2),S).",
- [["S = [1,2]","X = _0"]]);
- assert_prolog_success!(&mut wam, "bagof(1,(Y=1 ; Y=2),L).",
- [["L = [1]","Y = 1"],
- ["L = [1]","Y = 2"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "findall(X,(X = 1 ; X = 2),[X,Y]).",
+ [["X = 1", "Y = 2"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(findall(X,4,S),error(type_error(callable,4),_),true).",
+ [["S = _3", "X = _1"]]
+ );
+
+ assert_prolog_success!(
+ &mut wam,
+ "bagof(X,(X=Y; X=Z),S).",
+ [["S = [_3,_6]", "X = _0", "Y = _3", "Z = _6"]]
+ );
+ assert_prolog_success!(&mut wam, "bagof(X,(X=1 ; X = 2),X).", [["X = [1,2]"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "bagof(X,(X=1 ; X = 2),S).",
+ [["S = [1,2]", "X = _0"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "bagof(1,(Y=1 ; Y=2),L).",
+ [["L = [1]", "Y = 1"], ["L = [1]", "Y = 2"]]
+ );
submit(&mut wam, "b(1,1). b(1,1). b(1,2). b(2,1). b(2,2). b(2,2).");
- assert_prolog_success!(&mut wam, "bagof(X,b(X,Y),L).",
- [["L = [1,Y,2]","X = _0","Y = 1"],
- ["L = [1,2,Y]","X = _0","Y = 2"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "bagof(X,b(X,Y),L).",
+ [
+ ["L = [1,Y,2]", "X = _0", "Y = 1"],
+ ["L = [1,2,Y]", "X = _0", "Y = 2"]
+ ]
+ );
- assert_prolog_success!(&mut wam, "bagof(X,(X=Y; X=Z; Y=1),L).",
- [["L = [_3,_6]","X = _0","Y = _3","Z = _6"],
- ["L = [_112]","X = _0","Y = 1","Z = _6"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "bagof(X,(X=Y; X=Z; Y=1),L).",
+ [
+ ["L = [_3,_6]", "X = _0", "Y = _3", "Z = _6"],
+ ["L = [_112]", "X = _0", "Y = 1", "Z = _6"]
+ ]
+ );
submit(&mut wam, "a(1,f(_)). a(2,f(_)).");
- assert_prolog_success!(&mut wam, "bagof(X,a(X,Y),L).",
- [["L = [1,2]","X = _0","Y = f(_78)"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "bagof(X,a(X,Y),L).",
+ [["L = [1,2]", "X = _0", "Y = f(_78)"]]
+ );
- assert_prolog_success!(&mut wam, "setof(X,(X = 1 ; X = 2),S).",
- [["S = [1,2]","X = _0"]]);
- assert_prolog_success!(&mut wam, "setof(X,(X=Y ; X=Z),S).",
- [["S = [_3,_6]","X = _0","Y = _3","Z = _6"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "setof(X,(X = 1 ; X = 2),S).",
+ [["S = [1,2]", "X = _0"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "setof(X,(X=Y ; X=Z),S).",
+ [["S = [_3,_6]", "X = _0", "Y = _3", "Z = _6"]]
+ );
assert_prolog_failure!(&mut wam, "setof(X,false,S).");
- assert_prolog_success!(&mut wam, "setof(1,(Y=1 ; Y=2),L).",
- [["L = [1]","Y = 1"],
- ["L = [1]","Y = 2"]]);
- assert_prolog_success!(&mut wam, "setof(X,(X=Y; X=Z; Y=1),L).",
- [["L = [_3,_6]","X = _0","Y = _3","Z = _6"],
- ["L = [_112]","Y = 1","X = _0","Y = 1","Z = _6"]]);
- assert_prolog_failure!(&mut wam, "setof(X,member(X,[f(U,b),f(V,c)]),[f(a,c),f(a,b)]).");
- assert_prolog_success!(&mut wam, "setof(X,member(X,[f(U,b),f(V,c)]),[f(a,b),f(a,c)]).",
- [["U = a","V = a","X = _0"]]);
- assert_prolog_success!(&mut wam, "setof(X,member(X,[V,U,f(U),f(V)]),L).",
- [["L = [_2,_4,f(U),f(V)]","U = _2","V = _4","X = _0"]]);
- assert_prolog_success!(&mut wam, "setof(X,member(X,[V,U,f(U),f(V)]),[a,b,f(a),f(b)]).",
- [["U = a","V = b","X = _0"]]);
-
- assert_prolog_success!(&mut wam, "findall(X,(X = 1 ; X = 2),S0,S1).",
- [["S0 = [1,2|_11]","S1 = _11","X = _0"]]);
- assert_prolog_success!(&mut wam, "findall(X+Y,(X = 1),S0,S1).",
- [["S0 = [1+_44|_7]","S1 = _7","X = _1","Y = _2"]]);
- assert_prolog_success!(&mut wam, "findall(X,false,S,_).",
- [["S = []","X = _0"]]);
- assert_prolog_success!(&mut wam, "findall(X,(X = 1 ; X = 1),S0,S1).",
- [["S0 = [1,1|_11]","S1 = _11","X = _0"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "setof(1,(Y=1 ; Y=2),L).",
+ [["L = [1]", "Y = 1"], ["L = [1]", "Y = 2"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "setof(X,(X=Y; X=Z; Y=1),L).",
+ [
+ ["L = [_3,_6]", "X = _0", "Y = _3", "Z = _6"],
+ ["L = [_112]", "Y = 1", "X = _0", "Y = 1", "Z = _6"]
+ ]
+ );
+ assert_prolog_failure!(
+ &mut wam,
+ "setof(X,member(X,[f(U,b),f(V,c)]),[f(a,c),f(a,b)])."
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "setof(X,member(X,[f(U,b),f(V,c)]),[f(a,b),f(a,c)]).",
+ [["U = a", "V = a", "X = _0"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "setof(X,member(X,[V,U,f(U),f(V)]),L).",
+ [["L = [_2,_4,f(U),f(V)]", "U = _2", "V = _4", "X = _0"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "setof(X,member(X,[V,U,f(U),f(V)]),[a,b,f(a),f(b)]).",
+ [["U = a", "V = b", "X = _0"]]
+ );
+
+ assert_prolog_success!(
+ &mut wam,
+ "findall(X,(X = 1 ; X = 2),S0,S1).",
+ [["S0 = [1,2|_11]", "S1 = _11", "X = _0"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "findall(X+Y,(X = 1),S0,S1).",
+ [["S0 = [1+_44|_7]", "S1 = _7", "X = _1", "Y = _2"]]
+ );
+ assert_prolog_success!(&mut wam, "findall(X,false,S,_).", [["S = []", "X = _0"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "findall(X,(X = 1 ; X = 1),S0,S1).",
+ [["S0 = [1,1|_11]", "S1 = _11", "X = _0"]]
+ );
assert_prolog_failure!(&mut wam, "findall(X,(X = 2 ; X = 1),[1,2|S],S).");
- assert_prolog_success!(&mut wam, "findall(X,(X = 1 ; X = 2),[X,Y|S],S).",
- [["S = _11","X = 1","Y = 2"]]);
- assert_prolog_success!(&mut wam, "catch(findall(X,4,S0,S1),error(type_error(callable,4),_),true).",
- [["S0 = _3","S1 = _4","X = _1"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "findall(X,(X = 1 ; X = 2),[X,Y|S],S).",
+ [["S = _11", "X = 1", "Y = 2"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(findall(X,4,S0,S1),error(type_error(callable,4),_),true).",
+ [["S0 = _3", "S1 = _4", "X = _1"]]
+ );
// bagof & setof with existential variables.
- assert_prolog_success!(&mut wam, "bagof(X,Y^((X = 1,Y = 1; (X = 2,Y = 2))),S).",
- [["S = [1,2]","X = _0","Y = _5"]]);
- assert_prolog_success!(&mut wam, "bagof(X,Y^((X = 1 ; Y = 1) ; (X = 2,Y = 2)),S).",
- [["S = [1,_126,2]","X = _0","Y = _5"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "bagof(X,Y^((X = 1,Y = 1; (X = 2,Y = 2))),S).",
+ [["S = [1,2]", "X = _0", "Y = _5"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "bagof(X,Y^((X = 1 ; Y = 1) ; (X = 2,Y = 2)),S).",
+ [["S = [1,_126,2]", "X = _0", "Y = _5"]]
+ );
- assert_prolog_success!(&mut wam, "setof(X,Y^((X = 1,Y = 1; (X = 2,Y = 2))),S).",
- [["S = [1,2]","X = _0","Y = _5"]]);
- assert_prolog_success!(&mut wam, "setof(X,Y^((X = 1 ; Y = 1) ; (X = 2,Y = 2)),S).",
- [["S = [_126,1,2]","X = _0","Y = _5"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "setof(X,Y^((X = 1,Y = 1; (X = 2,Y = 2))),S).",
+ [["S = [1,2]", "X = _0", "Y = _5"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "setof(X,Y^((X = 1 ; Y = 1) ; (X = 2,Y = 2)),S).",
+ [["S = [_126,1,2]", "X = _0", "Y = _5"]]
+ );
assert_prolog_failure!(&mut wam, "forall(true,false).");
assert_prolog_success!(&mut wam, "forall(false,true).");
- assert_prolog_success!(&mut wam, "catch(forall(_,true),error(instantiation_error,_),true).");
- assert_prolog_success!(&mut wam, "catch(forall(true,_),error(instantiation_error,_),true).");
- assert_prolog_success!(&mut wam, "catch(forall(1,true),error(type_error(callable,1),_),true).");
- assert_prolog_success!(&mut wam, "catch(forall(true,1),error(type_error(callable,1),_),true).");
+ assert_prolog_success!(
+ &mut wam,
+ "catch(forall(_,true),error(instantiation_error,_),true)."
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(forall(true,_),error(instantiation_error,_),true)."
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(forall(1,true),error(type_error(callable,1),_),true)."
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(forall(true,1),error(type_error(callable,1),_),true)."
+ );
- submit(&mut wam, "
+ submit(
+ &mut wam,
+ "
:- dynamic(cat/0).
cat.
:- dynamic(insect/1).
insect(ant).
-insect(bee).");
+insect(bee).",
+ );
assert_prolog_success!(&mut wam, "clause(cat,true).");
assert_prolog_success!(&mut wam, "clause(dog,true).");
- assert_prolog_success!(&mut wam, "clause(legs(I,6),Body).",
- [["I = _1","Body = insect(_1)"]]);
- assert_prolog_success!(&mut wam, "clause(legs(C,7),Body).",
- [["C = _1","Body = (_1,call(C))"]]);
- assert_prolog_success!(&mut wam, "clause(insect(I),T).",
- [["I = ant","T = true"],
- ["I = bee","T = true"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "clause(legs(I,6),Body).",
+ [["I = _1", "Body = insect(_1)"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "clause(legs(C,7),Body).",
+ [["C = _1", "Body = (_1,call(C))"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "clause(insect(I),T).",
+ [["I = ant", "T = true"], ["I = bee", "T = true"]]
+ );
assert_prolog_failure!(&mut wam, "clause(x,Body).");
- assert_prolog_success!(&mut wam, "catch(clause(_,_),error(instantiation_error,_),true).");
- assert_prolog_success!(&mut wam, "catch(clause(4,_),error(type_error(callable,4),_),true).");
- assert_prolog_success!(&mut wam, "catch(clause(elk(N),_),error(permission_error(access,private_procedure,elk/1),_),true).");
- assert_prolog_success!(&mut wam, "catch(clause(atom(N),_),error(permission_error(access,private_procedure,atom/1),_),true).");
+ assert_prolog_success!(
+ &mut wam,
+ "catch(clause(_,_),error(instantiation_error,_),true)."
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(clause(4,_),error(type_error(callable,4),_),true)."
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(clause(elk(N),_),error(permission_error(access,private_procedure,elk/1),_),true)."
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(clause(atom(N),_),error(permission_error(access,private_procedure,atom/1),_),true)."
+ );
assert_prolog_success!(&mut wam, "asserta(legs(octopus,8)).");
assert_prolog_success!(&mut wam, "asserta( (legs(A,4) :- animal(A)) ).");
assert_prolog_success!(&mut wam, "asserta( (foo(X) :- X,call(X)) ).");
- assert_prolog_success!(&mut wam, "catch(asserta(_),error(instantiation_error,_),true).");
+ assert_prolog_success!(
+ &mut wam,
+ "catch(asserta(_),error(instantiation_error,_),true)."
+ );
assert_prolog_failure!(&mut wam, "asserta(_).");
- assert_prolog_success!(&mut wam, "catch(asserta(4),error(type_error(callable,4),_),true).");
+ assert_prolog_success!(
+ &mut wam,
+ "catch(asserta(4),error(type_error(callable,4),_),true)."
+ );
assert_prolog_failure!(&mut wam, "asserta(4).");
- assert_prolog_success!(&mut wam, "catch(asserta( (foo :- 4) ),error(type_error(callable,4),_),true).");
+ assert_prolog_success!(
+ &mut wam,
+ "catch(asserta( (foo :- 4) ),error(type_error(callable,4),_),true)."
+ );
assert_prolog_failure!(&mut wam, "asserta( (foo :- 4) ).");
assert_prolog_success!(&mut wam, "catch(asserta( (atom(_) :- true) ),error(permission_error(modify,static_procedure,atom/1),_),true).");
assert_prolog_failure!(&mut wam, "asserta( (atom(_) :- true) ).");
- submit(&mut wam, "
+ submit(
+ &mut wam,
+ "
:- dynamic(cat/0).
cat.
:- dynamic(insect/1).
insect(ant).
-insect(bee).");
+insect(bee).",
+ );
assert_prolog_success!(&mut wam, "assertz(legs(octopus,8)).");
assert_prolog_success!(&mut wam, "assertz( (legs(A,4) :- animal(A)) ).");
assert_prolog_success!(&mut wam, "assertz( (foo(X) :- X,call(X)) ).");
- assert_prolog_success!(&mut wam, "catch(assertz(_),error(instantiation_error,_),true).");
+ assert_prolog_success!(
+ &mut wam,
+ "catch(assertz(_),error(instantiation_error,_),true)."
+ );
assert_prolog_failure!(&mut wam, "assertz(_).");
- assert_prolog_success!(&mut wam, "catch(assertz(4),error(type_error(callable,4),_),true).");
+ assert_prolog_success!(
+ &mut wam,
+ "catch(assertz(4),error(type_error(callable,4),_),true)."
+ );
assert_prolog_failure!(&mut wam, "assertz(4).");
- assert_prolog_success!(&mut wam, "catch(assertz( (foo :- 4) ),error(type_error(callable,4),_),true).");
+ assert_prolog_success!(
+ &mut wam,
+ "catch(assertz( (foo :- 4) ),error(type_error(callable,4),_),true)."
+ );
assert_prolog_failure!(&mut wam, "assertz( (foo :- 4) ).");
assert_prolog_success!(&mut wam, "catch(assertz( (atom(_) :- true) ),error(permission_error(modify,static_procedure,atom/1),_),true).");
assert_prolog_failure!(&mut wam, "assertz( (atom(_) :- true) ).");
- submit(&mut wam, "
+ submit(
+ &mut wam,
+ "
:- dynamic(legs/2).
legs(A,4) :- animal(A).
legs(octopus,8).
:- dynamic(foo/1).
foo(X) :- call(X),call(X).
-foo(X) :- call(X) -> call(X).");
+foo(X) :- call(X) -> call(X).",
+ );
assert_prolog_success!(&mut wam, "retract(legs(octopus,8)).");
assert_prolog_failure!(&mut wam, "retract(legs(spider,6)).");
- assert_prolog_success!(&mut wam, "retract( (legs(X,2) :- T) ).",
- [["X = _1","T = bird(_1)"]]);
- assert_prolog_success!(&mut wam, "retract( (legs(X,Y) :- Z) ).",
- [["X = _1","Y = 4","Z = animal(_1)"],
- ["X = _1","Y = 6","Z = insect(_1)"],
- ["X = spider","Y = 8","Z = true"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "retract( (legs(X,2) :- T) ).",
+ [["X = _1", "T = bird(_1)"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "retract( (legs(X,Y) :- Z) ).",
+ [
+ ["X = _1", "Y = 4", "Z = animal(_1)"],
+ ["X = _1", "Y = 6", "Z = insect(_1)"],
+ ["X = spider", "Y = 8", "Z = true"]
+ ]
+ );
assert_prolog_failure!(&mut wam, "retract( (legs(X,Y) :- Z) ).");
- assert_prolog_success!(&mut wam, "retract(insect(I)).",
- [["I = ant"],
- ["I = bee"]]);
- assert_prolog_success!(&mut wam, "retract(( foo(A) :- A,call(A) )).",
- [["A = call(A)"]]);
+ assert_prolog_success!(&mut wam, "retract(insect(I)).", [["I = ant"], ["I = bee"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "retract(( foo(A) :- A,call(A) )).",
+ [["A = call(A)"]]
+ );
assert_prolog_success!(&mut wam, "foo(atom(atom)).");
- assert_prolog_success!(&mut wam, "retract(( foo(C) :- A -> B )).",
- [["A = call(_1)","B = call(_1)","C = _1"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "retract(( foo(C) :- A -> B )).",
+ [["A = call(_1)", "B = call(_1)", "C = _1"]]
+ );
assert_prolog_failure!(&mut wam, "retract( (X :- in_eec(Y)) ).");
- assert_prolog_success!(&mut wam, "catch(retract( (X :- in_eec(Y)) ),error(instantiation_error,_),true).");
+ assert_prolog_success!(
+ &mut wam,
+ "catch(retract( (X :- in_eec(Y)) ),error(instantiation_error,_),true)."
+ );
assert_prolog_failure!(&mut wam, "retract( (4 :- X) ).");
- assert_prolog_success!(&mut wam, "catch(retract( (4 :- X) ),error(type_error(callable,4),_),true).");
+ assert_prolog_success!(
+ &mut wam,
+ "catch(retract( (4 :- X) ),error(type_error(callable,4),_),true)."
+ );
assert_prolog_failure!(&mut wam, "retract( (atom(X) :- X == '[]') ).");
assert_prolog_success!(&mut wam, "catch(retract( (atom(X) :- X == '[]') ),error(permission_error(modify,static_procedure,atom/1),_),true).");
/* This example shows why machine::compile::localize_self_calls is necessary. */
-submit(&mut wam, "
+ submit(
+ &mut wam,
+ "
:- dynamic(p/1).
p(a).
p(b).
p(c) :- p(d).
-p(d).");
+p(d).",
+ );
- assert_prolog_success!(&mut wam, "p(X),retract(p(_)).",
- [["X = a"],
- ["X = a"],
- ["X = a"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "p(X),retract(p(_)).",
+ [["X = a"], ["X = a"], ["X = a"]]
+ );
- submit(&mut wam, "
+ submit(
+ &mut wam,
+ "
:- dynamic(foo/1).
foo(X) :- call(X),call(X).
-foo(X) :- call(X) -> call(X).");
+foo(X) :- call(X) -> call(X).",
+ );
assert_prolog_success!(&mut wam, "abolish(foo/2).");
assert_prolog_failure!(&mut wam, "abolish(foo/_).");
- assert_prolog_success!(&mut wam, "catch(abolish(foo/_),error(instantiation_error,abolish/1),true).");
+ assert_prolog_success!(
+ &mut wam,
+ "catch(abolish(foo/_),error(instantiation_error,abolish/1),true)."
+ );
assert_prolog_failure!(&mut wam, "abolish(foo).");
- assert_prolog_success!(&mut wam, "catch(abolish(foo),error(type_error(predicate_indicator,foo),abolish/1),true).");
+ assert_prolog_success!(
+ &mut wam,
+ "catch(abolish(foo),error(type_error(predicate_indicator,foo),abolish/1),true)."
+ );
assert_prolog_failure!(&mut wam, "abolish(foo(_)).");
- assert_prolog_success!(&mut wam, "catch(abolish(foo(_)),error(type_error(predicate_indicator,foo(_)),abolish/1),true).");
+ assert_prolog_success!(
+ &mut wam,
+ "catch(abolish(foo(_)),error(type_error(predicate_indicator,foo(_)),abolish/1),true)."
+ );
assert_prolog_failure!(&mut wam, "abolish(abolish/1).");
assert_prolog_success!(&mut wam, "catch(abolish(abolish/1),error(permission_error(modify,static_procedure,abolish/1),abolish/1),true).");
- assert_prolog_success!(&mut wam, "atom_length('enchanted evening',N).",
- [["N = 17"]]);
- assert_prolog_success!(&mut wam,r"atom_length('enchanted\
+ assert_prolog_success!(
+ &mut wam,
+ "atom_length('enchanted evening',N).",
+ [["N = 17"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ r"atom_length('enchanted\
evening',N).",
- [["N = 17"]]);
- assert_prolog_success!(&mut wam, "atom_length('',N).",
- [["N = 0"]]);
+ [["N = 17"]]
+ );
+ assert_prolog_success!(&mut wam, "atom_length('',N).", [["N = 0"]]);
assert_prolog_failure!(&mut wam, "atom_length('scarlet',5).");
- assert_prolog_success!(&mut wam, "catch((atom_length(Atom,4),false),error(instantiation_error,_),true).");
- assert_prolog_success!(&mut wam, "catch((atom_length(1.23,4),false),error(type_error(atom,1.23),_),true).");
- assert_prolog_success!(&mut wam, "catch((atom_length(atom,'4'),false),error(type_error(integer,'4'),_),true).");
+ assert_prolog_success!(
+ &mut wam,
+ "catch((atom_length(Atom,4),false),error(instantiation_error,_),true)."
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch((atom_length(1.23,4),false),error(type_error(atom,1.23),_),true)."
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch((atom_length(atom,'4'),false),error(type_error(integer,'4'),_),true)."
+ );
}
#[test]
-fn test_queries_on_setup_call_cleanup()
-{
+fn test_queries_on_setup_call_cleanup() {
let mut wam = Machine::new(readline::input_stream());
submit(&mut wam, ":- use_module('src/prolog/lib/non_iso.pl').");
-
+
// Test examples from the ISO Prolog page for setup_call_catch.
assert_prolog_failure!(&mut wam, "setup_call_cleanup(false, _, _).");
- assert_prolog_success!(&mut wam, "catch(setup_call_cleanup(true, throw(unthrown), _), error(instantiation_error, _), true).");
- assert_prolog_success!(&mut wam, "setup_call_cleanup(true, true, (true ; throw(x))).");
- assert_prolog_success!(&mut wam, "setup_call_cleanup(true, X = 1, X = 2).",
- [["X = 1"]]);
- assert_prolog_success!(&mut wam, "setup_call_cleanup(true, true, X = 2).",
- [["X = 2"]]);
- assert_prolog_success!(&mut wam, "catch(setup_call_cleanup(true, X=true, X), error(E, _), true).",
- [["E = instantiation_error", "X = _1"]]);
- assert_prolog_success!(&mut wam, "catch(setup_call_cleanup(X=throw(ex), true, X), E, true).",
- [["E = ex", "X = _3"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(setup_call_cleanup(true, throw(unthrown), _), error(instantiation_error, _), true)."
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "setup_call_cleanup(true, true, (true ; throw(x)))."
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "setup_call_cleanup(true, X = 1, X = 2).",
+ [["X = 1"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "setup_call_cleanup(true, true, X = 2).",
+ [["X = 2"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(setup_call_cleanup(true, X=true, X), error(E, _), true).",
+ [["E = instantiation_error", "X = _1"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(setup_call_cleanup(X=throw(ex), true, X), E, true).",
+ [["E = ex", "X = _3"]]
+ );
assert_prolog_success!(&mut wam, "setup_call_cleanup(true, true, false).");
- assert_prolog_success!(&mut wam, "setup_call_cleanup(S = 1, G = 2, C = 3).",
- [["S = 1", "G = 2", "C = 3"]]);
- assert_prolog_success!(&mut wam, "setup_call_cleanup((S=1;S=2), G=3, C=4).",
- [["S = 1", "G = 3", "C = 4"]]);
- assert_prolog_success!(&mut wam, "setup_call_cleanup(S=1, G=2, writeq(S+G)).",
- [["S = 1", "G = 2"]]);
- assert_prolog_success!(&mut wam, "setup_call_cleanup(S=1, (G=2;G=3), writeq(S+G)).",
- [["S = 1", "G = 2"],
- ["S = 1", "G = 3"]]);
- assert_prolog_success!(&mut wam, "setup_call_cleanup(S=1, G=2, writeq(S+G>A+B)), A=3, B=4.",
- [["S = 1", "G = 2", "A = 3", "B = 4"]]);
- assert_prolog_success!(&mut wam,
- "catch(setup_call_cleanup(S=1, (G=2;G=3,throw(x)), writeq(S+G)), E, true).",
- [["S = 1", "G = 2", "E = _26"], ["G = _4", "E = x", "S = _1"]]);
- assert_prolog_success!(&mut wam,
- "setup_call_cleanup(S=1, (G=2;G=3),writeq(S+G>B)), B=4, !.",
- [["S = 1", "B = 4", "G = 2"]]);
- assert_prolog_success!(&mut wam,
- "setup_call_cleanup(S=1,G=2,writeq(S+G>B)),B=3,!.",
- [["S = 1", "G = 2", "B = 3"]]);
- assert_prolog_success!(&mut wam,
- "setup_call_cleanup(S=1,(G=2;false),writeq(S+G>B)),B=3,!.",
- [["S = 1", "G = 2", "B = 3"]]);
- assert_prolog_success!(&mut wam,
- "setup_call_cleanup(S=1,(G=2;S=2),writeq(S+G>B)), B=3, !.",
- [["S = 1", "B = 3", "G = 2"]]);
- assert_prolog_failure!(&mut wam,
- "setup_call_cleanup(S=1,(G=2;G=3), writeq(S+G>B)), B=4, !, throw(x).");
+ assert_prolog_success!(
+ &mut wam,
+ "setup_call_cleanup(S = 1, G = 2, C = 3).",
+ [["S = 1", "G = 2", "C = 3"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "setup_call_cleanup((S=1;S=2), G=3, C=4).",
+ [["S = 1", "G = 3", "C = 4"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "setup_call_cleanup(S=1, G=2, writeq(S+G)).",
+ [["S = 1", "G = 2"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "setup_call_cleanup(S=1, (G=2;G=3), writeq(S+G)).",
+ [["S = 1", "G = 2"], ["S = 1", "G = 3"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "setup_call_cleanup(S=1, G=2, writeq(S+G>A+B)), A=3, B=4.",
+ [["S = 1", "G = 2", "A = 3", "B = 4"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(setup_call_cleanup(S=1, (G=2;G=3,throw(x)), writeq(S+G)), E, true).",
+ [["S = 1", "G = 2", "E = _26"], ["G = _4", "E = x", "S = _1"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "setup_call_cleanup(S=1, (G=2;G=3),writeq(S+G>B)), B=4, !.",
+ [["S = 1", "B = 4", "G = 2"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "setup_call_cleanup(S=1,G=2,writeq(S+G>B)),B=3,!.",
+ [["S = 1", "G = 2", "B = 3"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "setup_call_cleanup(S=1,(G=2;false),writeq(S+G>B)),B=3,!.",
+ [["S = 1", "G = 2", "B = 3"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "setup_call_cleanup(S=1,(G=2;S=2),writeq(S+G>B)), B=3, !.",
+ [["S = 1", "B = 3", "G = 2"]]
+ );
+ assert_prolog_failure!(
+ &mut wam,
+ "setup_call_cleanup(S=1,(G=2;G=3), writeq(S+G>B)), B=4, !, throw(x)."
+ );
- assert_prolog_success!(&mut wam,
- "catch(setup_call_cleanup(true,throw(goal),throw(cl)), Pat, true).",
- [["Pat = goal"]]);
- assert_prolog_success!(&mut wam,
- "catch(( setup_call_cleanup(true,(G=1;G=2),throw(cl)), throw(cont)), Pat, true).",
- [["Pat = cont", "G = _1"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "catch(setup_call_cleanup(true,throw(goal),throw(cl)), Pat, true).",
+ [["Pat = goal"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(( setup_call_cleanup(true,(G=1;G=2),throw(cl)), throw(cont)), Pat, true).",
+ [["Pat = cont", "G = _1"]]
+ );
// fails here.
assert_prolog_success!(&mut wam,
}
#[test]
-fn test_queries_on_call_with_inference_limit()
-{
+fn test_queries_on_call_with_inference_limit() {
let mut wam = Machine::new(readline::input_stream());
submit(&mut wam, ":- use_module('src/prolog/lib/non_iso.pl').");
-
- assert_prolog_success!(&mut wam, "call_with_inference_limit(throw(error), 0, R).",
- [["R = inference_limit_exceeded"]]);
- assert_prolog_success!(&mut wam, "catch(call_with_inference_limit(throw(error), 1, R), error, true).");
+
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(throw(error), 0, R).",
+ [["R = inference_limit_exceeded"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "catch(call_with_inference_limit(throw(error), 1, R), error, true)."
+ );
assert_prolog_failure!(&mut wam, "call_with_inference_limit(g(X), 5, R).");
submit(&mut wam, "g(1). g(2). g(3). g(4). g(5).");
- assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 5, R).",
- [["R = true", "X = 1"],
- ["R = true", "X = 2"],
- ["R = true", "X = 3"],
- ["R = true", "X = 4"],
- ["R = !", "X = 5"]]);
- assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 5, R), call(true).",
- [["R = true", "X = 1"],
- ["R = true", "X = 2"],
- ["R = true", "X = 3"],
- ["R = true", "X = 4"],
- ["R = !", "X = 5"]]);
- assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 2, R).",
- [["R = true", "X = 1"],
- ["R = true", "X = 2"],
- ["R = inference_limit_exceeded", "X = _1"]]);
- assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 3, R1),
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(g(X), 5, R).",
+ [
+ ["R = true", "X = 1"],
+ ["R = true", "X = 2"],
+ ["R = true", "X = 3"],
+ ["R = true", "X = 4"],
+ ["R = !", "X = 5"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(g(X), 5, R), call(true).",
+ [
+ ["R = true", "X = 1"],
+ ["R = true", "X = 2"],
+ ["R = true", "X = 3"],
+ ["R = true", "X = 4"],
+ ["R = !", "X = 5"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(g(X), 2, R).",
+ [
+ ["R = true", "X = 1"],
+ ["R = true", "X = 2"],
+ ["R = inference_limit_exceeded", "X = _1"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(g(X), 3, R1),
call_with_inference_limit(g(X), 5, R2).",
- [["X = 1", "R1 = true", "R2 = !"],
- ["X = 2", "R1 = true", "R2 = !"],
- ["X = 3", "R1 = true", "R2 = !"],
- ["X = 4", "R1 = true", "R2 = !"],
- ["X = 5", "R1 = !", "R2 = !"]]);
+ [
+ ["X = 1", "R1 = true", "R2 = !"],
+ ["X = 2", "R1 = true", "R2 = !"],
+ ["X = 3", "R1 = true", "R2 = !"],
+ ["X = 4", "R1 = true", "R2 = !"],
+ ["X = 5", "R1 = !", "R2 = !"]
+ ]
+ );
submit(&mut wam, "f(X) :- call_with_inference_limit(g(X), 5, _).");
- assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X), 7, R).",
- [["R = true", "X = 1"],
- ["R = true", "X = 2"],
- ["R = true", "X = 3"],
- ["R = true", "X = 4"],
- ["R = !", "X = 5"]]);
- assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X), 6, R).",
- [["R = true", "X = 1"],
- ["R = true", "X = 2"],
- ["R = true", "X = 3"],
- ["R = true", "X = 4"],
- ["R = inference_limit_exceeded", "X = _1"]]);
- assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X), 4, R).",
- [["R = true", "X = 1"],
- ["R = true", "X = 2"],
- ["R = inference_limit_exceeded", "X = _1"]]);
- assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X), 3, R).",
- [["R = true", "X = 1"],
- ["R = inference_limit_exceeded", "X = _1"]]);
- assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X), 2, R).",
- [["R = inference_limit_exceeded", "X = _1"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(f(X), 7, R).",
+ [
+ ["R = true", "X = 1"],
+ ["R = true", "X = 2"],
+ ["R = true", "X = 3"],
+ ["R = true", "X = 4"],
+ ["R = !", "X = 5"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(f(X), 6, R).",
+ [
+ ["R = true", "X = 1"],
+ ["R = true", "X = 2"],
+ ["R = true", "X = 3"],
+ ["R = true", "X = 4"],
+ ["R = inference_limit_exceeded", "X = _1"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(f(X), 4, R).",
+ [
+ ["R = true", "X = 1"],
+ ["R = true", "X = 2"],
+ ["R = inference_limit_exceeded", "X = _1"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(f(X), 3, R).",
+ [
+ ["R = true", "X = 1"],
+ ["R = inference_limit_exceeded", "X = _1"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(f(X), 2, R).",
+ [["R = inference_limit_exceeded", "X = _1"]]
+ );
submit(&mut wam, "e(X) :- call_with_inference_limit(f(X), 10, _).");
- assert_prolog_success!(&mut wam, "call_with_inference_limit(e(X), 10, R).",
- [["R = true", "X = 1"],
- ["R = true", "X = 2"],
- ["R = true", "X = 3"],
- ["R = true", "X = 4"],
- ["R = !", "X = 5"]]);
- assert_prolog_success!(&mut wam, "call_with_inference_limit(e(X), 8, R).",
- [["R = true", "X = 1"],
- ["R = true", "X = 2"],
- ["R = true", "X = 3"],
- ["R = true", "X = 4"],
- ["R = inference_limit_exceeded", "X = _1"]]);
- assert_prolog_success!(&mut wam, "call_with_inference_limit(e(X), 6, R).",
- [["R = true", "X = 1"],
- ["R = true", "X = 2"],
- ["R = inference_limit_exceeded", "X = _1"]]);
- assert_prolog_success!(&mut wam, "call_with_inference_limit(e(X), 5, R).",
- [["R = true", "X = 1"],
- ["R = inference_limit_exceeded", "X = _1"]]);
- assert_prolog_success!(&mut wam, "call_with_inference_limit(e(X), 4, R).",
- [["R = inference_limit_exceeded", "X = _1"]]);
-
- submit(&mut wam, "f(X, R) :- call_with_inference_limit(g(X), 5, R).");
-
- assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X, R), 4, S).",
- [["S = true", "X = 1", "R = true"],
- ["S = true", "X = 2", "R = true"],
- ["S = inference_limit_exceeded", "X = _1", "R = _2"]]);
- assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X, R), 8, R).",
- [["R = true", "X = 1"],
- ["R = true", "X = 2"],
- ["R = true", "X = 3"],
- ["R = true", "X = 4"],
- ["R = !", "X = 5"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(e(X), 10, R).",
+ [
+ ["R = true", "X = 1"],
+ ["R = true", "X = 2"],
+ ["R = true", "X = 3"],
+ ["R = true", "X = 4"],
+ ["R = !", "X = 5"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(e(X), 8, R).",
+ [
+ ["R = true", "X = 1"],
+ ["R = true", "X = 2"],
+ ["R = true", "X = 3"],
+ ["R = true", "X = 4"],
+ ["R = inference_limit_exceeded", "X = _1"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(e(X), 6, R).",
+ [
+ ["R = true", "X = 1"],
+ ["R = true", "X = 2"],
+ ["R = inference_limit_exceeded", "X = _1"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(e(X), 5, R).",
+ [
+ ["R = true", "X = 1"],
+ ["R = inference_limit_exceeded", "X = _1"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(e(X), 4, R).",
+ [["R = inference_limit_exceeded", "X = _1"]]
+ );
+
+ submit(
+ &mut wam,
+ "f(X, R) :- call_with_inference_limit(g(X), 5, R).",
+ );
+
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(f(X, R), 4, S).",
+ [
+ ["S = true", "X = 1", "R = true"],
+ ["S = true", "X = 2", "R = true"],
+ ["S = inference_limit_exceeded", "X = _1", "R = _2"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(f(X, R), 8, R).",
+ [
+ ["R = true", "X = 1"],
+ ["R = true", "X = 2"],
+ ["R = true", "X = 3"],
+ ["R = true", "X = 4"],
+ ["R = !", "X = 5"]
+ ]
+ );
submit(&mut wam, "g(1). g(2). g(3). g(4). g(5). g(6).");
- assert_prolog_success!(&mut wam, "call_with_inference_limit(f(X, R), 8, S).",
- [["R = true", "X = 1", "S = true"],
- ["R = true", "X = 2", "S = true"],
- ["R = true", "X = 3", "S = true"],
- ["R = true", "X = 4", "S = true"],
- ["R = true", "X = 5", "S = true"],
- ["R = inference_limit_exceeded", "S = !", "X = _1"]]);
- assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 2, R), call_with_inference_limit(g(X), 1, S).",
- [["R = true", "X = 1", "S = !"],
- ["R = true", "X = 2", "S = !"],
- ["R = true", "X = 3", "S = !"],
- ["R = true", "X = 4", "S = !"],
- ["R = true", "X = 5", "S = !"],
- ["R = !", "X = 6", "S = !"]]);
- assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 2, R), call_with_inference_limit(g(X), 1, R).",
- [["R = !", "X = 6"]]);
- assert_prolog_success!(&mut wam, "call_with_inference_limit(g(X), 1, R), call_with_inference_limit(g(X), 1, R).",
- [["R = inference_limit_exceeded", "X = _1"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(f(X, R), 8, S).",
+ [
+ ["R = true", "X = 1", "S = true"],
+ ["R = true", "X = 2", "S = true"],
+ ["R = true", "X = 3", "S = true"],
+ ["R = true", "X = 4", "S = true"],
+ ["R = true", "X = 5", "S = true"],
+ ["R = inference_limit_exceeded", "S = !", "X = _1"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(g(X), 2, R), call_with_inference_limit(g(X), 1, S).",
+ [
+ ["R = true", "X = 1", "S = !"],
+ ["R = true", "X = 2", "S = !"],
+ ["R = true", "X = 3", "S = !"],
+ ["R = true", "X = 4", "S = !"],
+ ["R = true", "X = 5", "S = !"],
+ ["R = !", "X = 6", "S = !"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(g(X), 2, R), call_with_inference_limit(g(X), 1, R).",
+ [["R = !", "X = 6"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "call_with_inference_limit(g(X), 1, R), call_with_inference_limit(g(X), 1, R).",
+ [["R = inference_limit_exceeded", "X = _1"]]
+ );
}
#[test]
-fn test_queries_on_dcgs()
-{
+fn test_queries_on_dcgs() {
let mut wam = Machine::new(readline::input_stream());
submit(&mut wam, ":- use_module('src/prolog/lib/dcgs.pl').");
// test case by YeGoblynQueene from hacker news.
- submit_code(&mut wam,
- " ability(destroy, X) --> destroy(X).
+ submit_code(
+ &mut wam,
+ " ability(destroy, X) --> destroy(X).
destroy(X) --> [destroy], target(X).
target(X) --> [target], permanent(X).
permanent(X) --> [creature], creature(X).
land('Mountain') --> [].
% etc permanents
sorcery('Duress') --> [].
- instant('Lightning Bolt') --> [].");
+ instant('Lightning Bolt') --> [].",
+ );
- assert_prolog_success!(&mut wam, "phrase(ability(destroy, X), P).",
- [["P = [destroy,target,creature]","X = 'Llanowar Elves'"],
- ["P = [destroy,target,artifact]","X = 'Ankh of Mishra'"],
- ["P = [destroy,target,land]","X = 'Mountain'"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "phrase(ability(destroy, X), P).",
+ [
+ ["P = [destroy,target,creature]", "X = 'Llanowar Elves'"],
+ ["P = [destroy,target,artifact]", "X = 'Ankh of Mishra'"],
+ ["P = [destroy,target,land]", "X = 'Mountain'"]
+ ]
+ );
}
#[test]
-fn test_queries_on_string_lists()
-{
+fn test_queries_on_string_lists() {
let mut wam = Machine::new(readline::input_stream());
submit(&mut wam, ":- use_module('src/prolog/lib/non_iso.pl').");
-
+
// double_quotes is chars by default.
assert_prolog_success!(&mut wam, "variant(\"\", []).");
assert_prolog_failure!(&mut wam, "\"\" == [].");
assert_prolog_success!(&mut wam, "\"koen\" = [k, o, e, n].");
assert_prolog_success!(&mut wam, "variant(\"koen\", [k, o, e, n]).");
assert_prolog_success!(&mut wam, "variant(\"koen\", \"koen\").");
- assert_prolog_success!(&mut wam, "\"koen\" = [k, o | X].",
- [["X = [e,n]"]]);
- assert_prolog_success!(&mut wam, "\"koen\" = [k, o | X], X = \"en\".",
- [["X = [e,n]"]]);
+ assert_prolog_success!(&mut wam, "\"koen\" = [k, o | X].", [["X = [e,n]"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "\"koen\" = [k, o | X], X = \"en\".",
+ [["X = [e,n]"]]
+ );
assert_prolog_failure!(&mut wam, "\"koen\" = [k, o | X], X == \"en\".");
- assert_prolog_success!(&mut wam, "\"koen\" = [k, o | X], variant(X, \"en\").",
- [["X = [e,n]"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "\"koen\" = [k, o | X], variant(X, \"en\").",
+ [["X = [e,n]"]]
+ );
assert_prolog_failure!(&mut wam, "X = \"abc\", Y = \"abc\", X == Y.");
- assert_prolog_failure!(&mut wam, "partial_string(\"abc\", X), partial_string(\"abc\", Y), X == Y.");
+ assert_prolog_failure!(
+ &mut wam,
+ "partial_string(\"abc\", X), partial_string(\"abc\", Y), X == Y."
+ );
assert_prolog_success!(&mut wam, "X = \"abc\", Y = \"abc\", variant(X, Y).");
- assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), partial_string(\"abc\", Y), variant(X, Y).");
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"abc\", X), partial_string(\"abc\", Y), variant(X, Y)."
+ );
submit(&mut wam, "matcher([a,b,c|X], ['d','e','f'|X]).");
assert_prolog_success!(&mut wam, "matcher(\"abcdef\", \"defdef\").");
assert_prolog_failure!(&mut wam, "matcher(\"abcdef\", \"defdff\").");
- assert_prolog_success!(&mut wam, "matcher([X, Y, Z | W], [A, B, C | W]).",
- [["A = d", "B = e", "C = f", "W = _1", "X = a", "Y = b", "Z = c"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "matcher([X, Y, Z | W], [A, B, C | W]).",
+ [["A = d", "B = e", "C = f", "W = _1", "X = a", "Y = b", "Z = c"]]
+ );
assert_prolog_failure!(&mut wam, "matcher([X, Y, Z | W], [X, B, C | W]).");
submit(&mut wam, "matcher([a,b,c|X], X).");
- assert_prolog_success!(&mut wam, "matcher(\"abcdef\", X), X = [d,e,f|Y], variant(Y, []), X = \"def\".",
- [["X = [d,e,f]", "Y = []"]]);
- assert_prolog_success!(&mut wam, "matcher(\"abcdef\", X), X = [d,e,f|Y], variant(Y, []), variant(X, \"def\").",
- [["X = [d,e,f]", "Y = []"]]);
- assert_prolog_success!(&mut wam, "X = ['a', 'b', 'c' | \"def\"].",
- [["X = [a,b,c,d,e,f]"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "matcher(\"abcdef\", X), X = [d,e,f|Y], variant(Y, []), X = \"def\".",
+ [["X = [d,e,f]", "Y = []"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "matcher(\"abcdef\", X), X = [d,e,f|Y], variant(Y, []), variant(X, \"def\").",
+ [["X = [d,e,f]", "Y = []"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "X = ['a', 'b', 'c' | \"def\"].",
+ [["X = [a,b,c,d,e,f]"]]
+ );
- assert_prolog_success!(&mut wam, "X = [a,b,c|\"abc\"].",
- [["X = [a,b,c,a,b,c]"]]);
+ assert_prolog_success!(&mut wam, "X = [a,b,c|\"abc\"].", [["X = [a,b,c,a,b,c]"]]);
assert_prolog_success!(&mut wam, "set_prolog_flag(double_quotes, atom).");
- assert_prolog_success!(&mut wam, "matcher(X, Y).",
- [["X = [a,b,c|_1]", "Y = _1"]]);
+ assert_prolog_success!(&mut wam, "matcher(X, Y).", [["X = [a,b,c|_1]", "Y = _1"]]);
assert_prolog_failure!(&mut wam, "matcher(\"abcdef\", Y).");
assert_prolog_success!(&mut wam, "set_prolog_flag(double_quotes, chars).");
- assert_prolog_success!(&mut wam, "X = \"abc\", X = ['a' | Y], set_prolog_flag(double_quotes, atom).",
- [["X = \"abc\"", "Y = \"bc\""]]);
+ assert_prolog_success!(
+ &mut wam,
+ "X = \"abc\", X = ['a' | Y], set_prolog_flag(double_quotes, atom).",
+ [["X = \"abc\"", "Y = \"bc\""]]
+ );
// partial strings.
assert_prolog_success!(&mut wam, "set_prolog_flag(double_quotes, chars).");
assert_prolog_failure!(&mut wam, "Y = 5, partial_string(\"abc\", Y).");
- assert_prolog_success!(&mut wam, "partial_string(\"abc\", X).",
- [["X = [a,b,c|_]"]]);
+ assert_prolog_success!(&mut wam, "partial_string(\"abc\", X).", [["X = [a,b,c|_]"]]);
- assert_prolog_failure!(&mut wam, "partial_string(\"abc\", X), partial_string(\"abc\", Y), matcher(X, V),
- matcher(Y, Z), V = Z.");
+ assert_prolog_failure!(
+ &mut wam,
+ "partial_string(\"abc\", X), partial_string(\"abc\", Y), matcher(X, V),
+ matcher(Y, Z), V = Z."
+ );
submit(&mut wam, "matcher([a, b, c | X], X).");
- assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y).",
- [["X = [a,b,c|_]", "Y = _"]]);
- assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), Y = \"def\".",
- [["X = [a,b,c,d,e,f]", "Y = [d,e,f]"]]);
- assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), \"def\" = Y.",
- [["X = [a,b,c,d,e,f]", "Y = [d,e,f]"]]);
-
- assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), partial_string(\"def\", Y).",
- [["X = [a,b,c,d,e,f|_]",
- "Y = [d,e,f|_]"]]);
- assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), partial_string(\"def\", Y),
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"abc\", X), matcher(X, Y).",
+ [["X = [a,b,c|_]", "Y = _"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"abc\", X), matcher(X, Y), Y = \"def\".",
+ [["X = [a,b,c,d,e,f]", "Y = [d,e,f]"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"abc\", X), matcher(X, Y), \"def\" = Y.",
+ [["X = [a,b,c,d,e,f]", "Y = [d,e,f]"]]
+ );
+
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"abc\", X), matcher(X, Y), partial_string(\"def\", Y).",
+ [["X = [a,b,c,d,e,f|_]", "Y = [d,e,f|_]"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"abc\", X), matcher(X, Y), partial_string(\"def\", Y),
Y = \"defghijkl\".",
- [["X = [a,b,c,d,e,f,g,h,i,j,k,l]",
- "Y = [d,e,f,g,h,i,j,k,l]"]]);
-
- assert_prolog_success!(&mut wam, "partial_string(\"abc\", X), matcher(X, Y), Y = [d, e, f | G].",
- [["X = [a,b,c,d,e,f|_]","Y = [d,e,f|_]","G = _"]]);
- assert_prolog_success!(&mut wam, "partial_string(\"abc\",X),matcher(X,Y),[d,e,f | G] = Y.",
- [["X = [a,b,c,d,e,f|_]","Y = [d,e,f|_]","G = _"]]);
- assert_prolog_success!(&mut wam, "partial_string(\"abc\",X),matcher(X,Y),Y = [d,e,f | G], G = \"ghi\".",
- [["X = [a,b,c,d,e,f,g,h,i]","Y = [d,e,f,g,h,i]","G = [g,h,i]"]]);
- assert_prolog_success!(&mut wam, "partial_string(\"abc\",X),matcher(X,Y),Y = [d,e,f | G],
+ [["X = [a,b,c,d,e,f,g,h,i,j,k,l]", "Y = [d,e,f,g,h,i,j,k,l]"]]
+ );
+
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"abc\", X), matcher(X, Y), Y = [d, e, f | G].",
+ [["X = [a,b,c,d,e,f|_]", "Y = [d,e,f|_]", "G = _"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"abc\",X),matcher(X,Y),[d,e,f | G] = Y.",
+ [["X = [a,b,c,d,e,f|_]", "Y = [d,e,f|_]", "G = _"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"abc\",X),matcher(X,Y),Y = [d,e,f | G], G = \"ghi\".",
+ [[
+ "X = [a,b,c,d,e,f,g,h,i]",
+ "Y = [d,e,f,g,h,i]",
+ "G = [g,h,i]"
+ ]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"abc\",X),matcher(X,Y),Y = [d,e,f | G],
is_partial_string(Y),G = \"ghi\".",
- [["X = [a,b,c,d,e,f,g,h,i]","Y = [d,e,f,g,h,i]","G = [g,h,i]"]]);
- assert_prolog_success!(&mut wam, "partial_string(\"abc\",X),matcher(X,Y),Y = [d,e,f | G],
+ [[
+ "X = [a,b,c,d,e,f,g,h,i]",
+ "Y = [d,e,f,g,h,i]",
+ "G = [g,h,i]"
+ ]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"abc\",X),matcher(X,Y),Y = [d,e,f | G],
is_partial_string(Y),is_partial_string(G),G = \"ghi\".",
- [["X = [a,b,c,d,e,f,g,h,i]","Y = [d,e,f,g,h,i]","G = [g,h,i]"]]);
- assert_prolog_success!(&mut wam, "partial_string(\"abc\",X),partial_string(\"ababc\",Y),Y = [a,b|Z],
+ [[
+ "X = [a,b,c,d,e,f,g,h,i]",
+ "Y = [d,e,f,g,h,i]",
+ "G = [g,h,i]"
+ ]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"abc\",X),partial_string(\"ababc\",Y),Y = [a,b|Z],
variant(X, Z).",
- [["X = [a,b,c|_]","Y = [a,b,a,b,c|_]","Z = [a,b,c|_]"]]);
- assert_prolog_failure!(&mut wam, "partial_string(\"abc\",X),partial_string(\"ababc\",Y),Y = [a,b|Z],
- X == Z.");
+ [["X = [a,b,c|_]", "Y = [a,b,a,b,c|_]", "Z = [a,b,c|_]"]]
+ );
+ assert_prolog_failure!(
+ &mut wam,
+ "partial_string(\"abc\",X),partial_string(\"ababc\",Y),Y = [a,b|Z],
+ X == Z."
+ );
assert_prolog_success!(&mut wam, "partial_string(\"abc\",X), X @> \"abc\".");
- assert_prolog_failure!(&mut wam, "partial_string(\"abc\",X), \\+ variant(X, \"abc\").");
+ assert_prolog_failure!(
+ &mut wam,
+ "partial_string(\"abc\",X), \\+ variant(X, \"abc\")."
+ );
assert_prolog_failure!(&mut wam, "partial_string(\"abc\",X), X @< \"abc\".");
- assert_prolog_success!(&mut wam, "partial_string(\"ab\",X),matcher(X,Y),Y = [a,b|V],
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"ab\",X),matcher(X,Y),Y = [a,b|V],
matcher(Y,Z),is_partial_string(Y).",
- [["V = [c|_]","X = [a,b,c,a,b,c|_]","Y = [a,b,c|_]","Z = _"]]);
- assert_prolog_success!(&mut wam, "partial_string(\"a\",X),matcher(X,Y).",
- [["X = [a,b,c|_]","Y = _"]]);
- assert_prolog_success!(&mut wam, "partial_string(\"a\",X),matcher(X,Y),is_partial_string(Y).",
- [["X = [a,b,c|_]","Y = _"]]);
- assert_prolog_success!(&mut wam, "partial_string(\"a\",X),matcher(X,Y),Y = \"def\".",
- [["X = [a,b,c,d,e,f]","Y = [d,e,f]"]]);
+ [["V = [c|_]", "X = [a,b,c,a,b,c|_]", "Y = [a,b,c|_]", "Z = _"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"a\",X),matcher(X,Y).",
+ [["X = [a,b,c|_]", "Y = _"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"a\",X),matcher(X,Y),is_partial_string(Y).",
+ [["X = [a,b,c|_]", "Y = _"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"a\",X),matcher(X,Y),Y = \"def\".",
+ [["X = [a,b,c,d,e,f]", "Y = [d,e,f]"]]
+ );
- submit(&mut wam, "matcher([a,b,c|X],X).
- matcher([a,b,d|X],X).");
+ submit(
+ &mut wam,
+ "matcher([a,b,c|X],X).
+ matcher([a,b,d|X],X).",
+ );
- assert_prolog_success!(&mut wam, "partial_string(\"ab\",X),matcher(X,Y).",
- [["X = [a,b,c|_]","Y = _"],
- ["X = [a,b,d|_]","Y = _"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"ab\",X),matcher(X,Y).",
+ [["X = [a,b,c|_]", "Y = _"], ["X = [a,b,d|_]", "Y = _"]]
+ );
- submit(&mut wam, "matcher([a,b,c,d|X],X).
- matcher([a,c,d|X],X).");
+ submit(
+ &mut wam,
+ "matcher([a,b,c,d|X],X).
+ matcher([a,c,d|X],X).",
+ );
- assert_prolog_success!(&mut wam, "partial_string(\"ab\",X),matcher(X,Y).",
- [["X = [a,b,c,d|_]","Y = _"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"ab\",X),matcher(X,Y).",
+ [["X = [a,b,c,d|_]", "Y = _"]]
+ );
- assert_prolog_success!(&mut wam, "partial_string(\"a\",X),matcher(X,Y).",
- [["X = [a,b,c,d|_]","Y = _"],
- ["X = [a,c,d|_]","Y = _"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"a\",X),matcher(X,Y).",
+ [["X = [a,b,c,d|_]", "Y = _"], ["X = [a,c,d|_]", "Y = _"]]
+ );
- submit(&mut wam, "matcher([a,b,c,d|X],X).
+ submit(
+ &mut wam,
+ "matcher([a,b,c,d|X],X).
matcher([a,c,d|X],X).
- matcher([a,e,f|X],X).");
-
- assert_prolog_success!(&mut wam, "partial_string(\"a\",X),matcher(X,Y).",
- [["X = [a,b,c,d|_]","Y = _"],
- ["X = [a,c,d|_]","Y = _"],
- ["X = [a,e,f|_]","Y = _"]]);
- assert_prolog_success!(&mut wam, "partial_string(\"a\",X),matcher(X,Y),Y = \" t\".",
- [["X = [a,b,c,d,' ',t]","Y = [' ',t]"],
- ["X = [a,c,d,' ',t]","Y = [' ',t]"],
- ["X = [a,e,f,' ',t]","Y = [' ',t]"]]);
-
- submit(&mut wam, "matcher([a,b,c|X],X) :- X = [].
- matcher([a,b,c|X],X).");
-
- assert_prolog_success!(&mut wam, "partial_string(\"abc\",X),matcher(X,Y).",
- [["X = [a,b,c]","Y = []"],
- ["X = [a,b,c|_]","Y = _"]]);
- assert_prolog_success!(&mut wam, "partial_string(\"a\",X),matcher(X,Y).",
- [["X = [a,b,c]","Y = []"],
- ["X = [a,b,c|_]","Y = _"]]);
-
- assert_prolog_failure!(&mut wam, "partial_string(\"abc\",X),partial_string(\"bc\",Y),X = [a|Y].");
-
- submit(&mut wam, "matcher([a|X],X) :- matcher2(X,_).
+ matcher([a,e,f|X],X).",
+ );
+
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"a\",X),matcher(X,Y).",
+ [
+ ["X = [a,b,c,d|_]", "Y = _"],
+ ["X = [a,c,d|_]", "Y = _"],
+ ["X = [a,e,f|_]", "Y = _"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"a\",X),matcher(X,Y),Y = \" t\".",
+ [
+ ["X = [a,b,c,d,' ',t]", "Y = [' ',t]"],
+ ["X = [a,c,d,' ',t]", "Y = [' ',t]"],
+ ["X = [a,e,f,' ',t]", "Y = [' ',t]"]
+ ]
+ );
+
+ submit(
+ &mut wam,
+ "matcher([a,b,c|X],X) :- X = [].
+ matcher([a,b,c|X],X).",
+ );
+
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"abc\",X),matcher(X,Y).",
+ [["X = [a,b,c]", "Y = []"], ["X = [a,b,c|_]", "Y = _"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"a\",X),matcher(X,Y).",
+ [["X = [a,b,c]", "Y = []"], ["X = [a,b,c|_]", "Y = _"]]
+ );
+
+ assert_prolog_failure!(
+ &mut wam,
+ "partial_string(\"abc\",X),partial_string(\"bc\",Y),X = [a|Y]."
+ );
+
+ submit(
+ &mut wam,
+ "matcher([a|X],X) :- matcher2(X,_).
matcher([b|X],X) :- matcher2(X,_).
matcher2([c|X],X).
- matcher2([d|X],X).");
-
- assert_prolog_success!(&mut wam, "partial_string(\"\",X),matcher(X,Y).",
- [["X = [a,c|_]","Y = [c|_]"],
- ["X = [a,d|_]","Y = [d|_]"],
- ["X = [b,c|_]","Y = [c|_]"],
- ["X = [b,d|_]","Y = [d|_]"]]);
- assert_prolog_success!(&mut wam, "partial_string(\"a\",X),matcher(X,Y).",
- [["X = [a,c|_]","Y = [c|_]"],
- ["X = [a,d|_]","Y = [d|_]"]]);
- assert_prolog_success!(&mut wam, "partial_string(\"b\",X),matcher(X,Y).",
- [["X = [b,c|_]","Y = [c|_]"],
- ["X = [b,d|_]","Y = [d|_]"]]);
- assert_prolog_success!(&mut wam, "partial_string(\"bc\",X),matcher(X,Y).",
- [["X = [b,c|_]","Y = [c|_]"]]);
-
- submit(&mut wam, "f(\"appendy jones\").
+ matcher2([d|X],X).",
+ );
+
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"\",X),matcher(X,Y).",
+ [
+ ["X = [a,c|_]", "Y = [c|_]"],
+ ["X = [a,d|_]", "Y = [d|_]"],
+ ["X = [b,c|_]", "Y = [c|_]"],
+ ["X = [b,d|_]", "Y = [d|_]"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"a\",X),matcher(X,Y).",
+ [["X = [a,c|_]", "Y = [c|_]"], ["X = [a,d|_]", "Y = [d|_]"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"b\",X),matcher(X,Y).",
+ [["X = [b,c|_]", "Y = [c|_]"], ["X = [b,d|_]", "Y = [d|_]"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"bc\",X),matcher(X,Y).",
+ [["X = [b,c|_]", "Y = [c|_]"]]
+ );
+
+ submit(
+ &mut wam,
+ "f(\"appendy jones\").
f(\"appendy smithers jones\").
- f(\"appendy o'toole\").");
+ f(\"appendy o'toole\").",
+ );
- assert_prolog_success!(&mut wam, "partial_string(\"appendy\",X),f(X).",
- [["X = [a,p,p,e,n,d,y,' ',j,o,n,e,s]"],
- ["X = [a,p,p,e,n,d,y,' ',s,m,i,t,h,e,r,s,' ',j,o,n,e,s]"],
- ["X = [a,p,p,e,n,d,y,' ',o,'\\'',t,o,o,l,e]"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"appendy\",X),f(X).",
+ [
+ ["X = [a,p,p,e,n,d,y,' ',j,o,n,e,s]"],
+ ["X = [a,p,p,e,n,d,y,' ',s,m,i,t,h,e,r,s,' ',j,o,n,e,s]"],
+ ["X = [a,p,p,e,n,d,y,' ',o,'\\'',t,o,o,l,e]"]
+ ]
+ );
- assert_prolog_success!(&mut wam, "partial_string(\"abc\",X),partial_string(\"abcdef\",X).",
- [["X = [a,b,c,d,e,f|_]"]]);
- assert_prolog_success!(&mut wam, "partial_string(\"abc\",X),partial_string(\"abcdef\",X),X = \"abcdef\".",
- [["X = [a,b,c,d,e,f]"]]);
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"abc\",X),partial_string(\"abcdef\",X).",
+ [["X = [a,b,c,d,e,f|_]"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "partial_string(\"abc\",X),partial_string(\"abcdef\",X),X = \"abcdef\".",
+ [["X = [a,b,c,d,e,f]"]]
+ );
}
#[test]
-fn test_queries_on_attributed_variables()
-{
+fn test_queries_on_attributed_variables() {
let mut wam = Machine::new(readline::input_stream());
- submit(&mut wam, "
+ submit(
+ &mut wam,
+ "
:- module(my_mod, []).
:- use_module('src/prolog/lib/atts.pl').
-:- attribute dif/1, frozen/1.");
+:- attribute dif/1, frozen/1.",
+ );
- assert_prolog_success!(&mut wam, "( put_atts(V, my_mod, dif(1)) ; put_atts(V, my_mod, dif(2)) ),
+ assert_prolog_success!(
+ &mut wam,
+ "( put_atts(V, my_mod, dif(1)) ; put_atts(V, my_mod, dif(2)) ),
get_atts(V, my_mod, L).",
- [["L = [dif(1)]", "V = _10"],
- ["L = [dif(2)]", "V = _10"]]);
+ [["L = [dif(1)]", "V = _10"], ["L = [dif(2)]", "V = _10"]]
+ );
- assert_prolog_success!(&mut wam, "put_atts(V, my_mod, frozen(a)),
+ assert_prolog_success!(
+ &mut wam,
+ "put_atts(V, my_mod, frozen(a)),
( put_atts(V, my_mod, dif(1))
; put_atts(V, my_mod, -frozen(a)), put_atts(V, my_mod, dif(2))
; put_atts(V, my_mod, dif(different)) ),
get_atts(V, my_mod, Ls).",
- [["Ls = [frozen(a),dif(1)]", "V = _10"],
- ["Ls = [dif(2)]", "V = _10"],
- ["Ls = [frozen(a),dif(different)]", "V = _10"]]);
+ [
+ ["Ls = [frozen(a),dif(1)]", "V = _10"],
+ ["Ls = [dif(2)]", "V = _10"],
+ ["Ls = [frozen(a),dif(different)]", "V = _10"]
+ ]
+ );
- assert_prolog_success!(&mut wam, "put_atts(V, my_mod, [dif(1), dif(2), frozen(a)]),
+ assert_prolog_success!(
+ &mut wam,
+ "put_atts(V, my_mod, [dif(1), dif(2), frozen(a)]),
( put_atts(V, my_mod, -dif(2)); put_atts(V, my_mod, -frozen(A)) ),
get_atts(V, my_mod, L).",
- [["A = _71", "L = [frozen(a)]", "V = _25"],
- ["A = _71", "L = [dif(2)]", "V = _25"]]);
- assert_prolog_success!(&mut wam, "put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
+ [
+ ["A = _71", "L = [frozen(a)]", "V = _25"],
+ ["A = _71", "L = [dif(2)]", "V = _25"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
( put_atts(V, my_mod, -dif(2)) ; put_atts(V, my_mod, -frozen(A)) ),
get_atts(V, my_mod, L).",
- [["A = _111", "L = [frozen(b)]", "V = _29"],
- ["A = _111", "L = [dif(2)]", "V = _29"]]);
- assert_prolog_success!(&mut wam, "put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
- get_atts(V, my_mod, -dif(1)).");
- assert_prolog_success!(&mut wam, "put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
- get_atts(V, my_mod, -dif(3)).");
- assert_prolog_success!(&mut wam, "put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
+ [
+ ["A = _111", "L = [frozen(b)]", "V = _29"],
+ ["A = _111", "L = [dif(2)]", "V = _29"]
+ ]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
+ get_atts(V, my_mod, -dif(1))."
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
+ get_atts(V, my_mod, -dif(3))."
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
get_atts(V, my_mod, dif(X)).",
- [["X = 2", "V = _29"]]);
- assert_prolog_success!(&mut wam, "put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
+ [["X = 2", "V = _29"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]),
put_atts(V, my_mod, -dif(A)), get_atts(V, my_mod, Ls).",
- [["A = _112", "Ls = [frozen(b)]", "V = _29"]]);
- assert_prolog_success!(&mut wam, "put_atts(V, my_mod, [dif(1), frozen(a), dif(2), frozen(b)]),
+ [["A = _112", "Ls = [frozen(b)]", "V = _29"]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "put_atts(V, my_mod, [dif(1), frozen(a), dif(2), frozen(b)]),
put_atts(V, my_mod, -dif(A)), get_atts(V, my_mod, Ls).",
- [["A = _114", "Ls = [frozen(b)]", "V = _29"]]);
+ [["A = _114", "Ls = [frozen(b)]", "V = _29"]]
+ );
- submit(&mut wam, ":- use_module('src/prolog/examples/minatotask.pl').");
+ submit(
+ &mut wam,
+ ":- use_module('src/prolog/examples/minatotask.pl').",
+ );
- assert_prolog_failure!(&mut wam, "ZDD = ( X -> b(true) ; ( Y -> b(true) ; b(false) ) ),
+ assert_prolog_failure!(
+ &mut wam,
+ "ZDD = ( X -> b(true) ; ( Y -> b(true) ; b(false) ) ),
Vs = [X,Y],
variables_set_zdd(Vs, ZDD),
- Vs = [1,1].");
- assert_prolog_success!(&mut wam, "ZDD = ( X -> b(true) ; ( Y -> b(true) ; b(false) ) ),
+ Vs = [1,1]."
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "ZDD = ( X -> b(true) ; ( Y -> b(true) ; b(false) ) ),
Vs = [X,Y],
variables_set_zdd(Vs, ZDD),
X = 1.",
- [["X = 1", "Y = 0", "Vs = [1,0]", "ZDD = (1->b(true);0->b(true);b(false))"]]);
- assert_prolog_success!(&mut wam, "ZDD = ( X -> b(true) ; ( Y -> b(true) ; b(false) ) ),
+ [[
+ "X = 1",
+ "Y = 0",
+ "Vs = [1,0]",
+ "ZDD = (1->b(true);0->b(true);b(false))"
+ ]]
+ );
+ assert_prolog_success!(
+ &mut wam,
+ "ZDD = ( X -> b(true) ; ( Y -> b(true) ; b(false) ) ),
Vs = [X,Y],
variables_set_zdd(Vs, ZDD),
X = 0.",
- [["Vs = [0,_58]", "X = 0", "Y = _58", "ZDD = (0->b(true);_58->b(true);b(false))"]]);
+ [[
+ "Vs = [0,_58]",
+ "X = 0",
+ "Y = _58",
+ "ZDD = (0->b(true);_58->b(true);b(false))"
+ ]]
+ );
}