remove extern crate declaration and fix outfall (macros now need to be imported into scope)

using use declarations in main.rs so that use paths don't need to be updated as well, this will be done in a later commit
This commit is contained in:
Skgland
2021-02-06 19:21:24 +01:00
parent 3f950490f9
commit b53ef148a0
25 changed files with 5815 additions and 7507 deletions

View File

@@ -1,6 +1,7 @@
use crate::divrem::*;
use crate::prolog_parser_rebis::ast::*;
use crate::prolog_parser_rebis::clause_name;
use crate::arithmetic::*;
use crate::clause_types::*;
@@ -19,19 +20,16 @@ use std::rc::Rc;
#[macro_export]
macro_rules! try_numeric_result {
($s: ident, $e: expr, $caller: expr) => (
($s: ident, $e: expr, $caller: expr) => {
match $e {
Ok(val) => {
Ok(val)
}
Ok(val) => Ok(val),
Err(e) => {
let caller_copy =
$caller.iter().map(|v| v.context_free_clone()).collect();
let caller_copy = $caller.iter().map(|v| v.context_free_clone()).collect();
Err($s.error_form(MachineError::evaluation_error(e), caller_copy))
}
}
);
};
}
fn isize_gcd(n1: isize, n2: isize) -> Option<isize> {
@@ -83,52 +81,29 @@ fn isize_gcd(n1: isize, n2: isize) -> Option<isize> {
}
impl MachineState {
pub(crate)
fn get_number(&mut self, at: &ArithmeticTerm) -> Result<Number, MachineStub> {
pub(crate) 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::Fixnum(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::Fixnum(0)))
}
&ArithmeticTerm::Number(ref n) => Ok(n.clone()),
}
}
pub(super)
fn rational_from_number(
&self,
n: Number,
) -> Result<Rc<Rational>, MachineError> {
pub(super) fn rational_from_number(&self, n: Number) -> Result<Rc<Rational>, MachineError> {
match n {
Number::Fixnum(n) => {
Ok(Rc::new(Rational::from(n)))
}
Number::Rational(r) => {
Ok(r)
}
Number::Float(OrderedFloat(f)) => {
match Rational::from_f64(f) {
Some(r) => {
Ok(Rc::new(r))
}
None => {
Err(MachineError::instantiation_error())
}
}
}
Number::Integer(n) => {
Ok(Rc::new(Rational::from(&*n)))
}
Number::Fixnum(n) => Ok(Rc::new(Rational::from(n))),
Number::Rational(r) => Ok(r),
Number::Float(OrderedFloat(f)) => match Rational::from_f64(f) {
Some(r) => Ok(Rc::new(r)),
None => Err(MachineError::instantiation_error()),
},
Number::Integer(n) => Ok(Rc::new(Rational::from(&*n))),
}
}
pub(crate)
fn get_rational(
pub(crate) fn get_rational(
&mut self,
at: &ArithmeticTerm,
caller: MachineStub,
@@ -137,12 +112,11 @@ impl MachineState {
match self.rational_from_number(n) {
Ok(r) => Ok((r, caller)),
Err(e) => Err(self.error_form(e, caller))
Err(e) => Err(self.error_form(e, caller)),
}
}
pub(crate)
fn arith_eval_by_metacall(&self, r: RegType) -> Result<Number, MachineStub> {
pub(crate) fn arith_eval_by_metacall(&self, r: RegType) -> Result<Number, MachineStub> {
let caller = MachineError::functor_stub(clause_name!("is"), 2);
let mut interms: Vec<Number> = Vec::with_capacity(64);
@@ -163,9 +137,8 @@ impl MachineState {
"min" => interms.push(self.min(a1, a2)?),
"rdiv" => {
let r1 = self.rational_from_number(a1);
let r2 = r1.and_then(|r1| {
self.rational_from_number(a2).map(|r2| (r1, r2))
});
let r2 =
r1.and_then(|r1| self.rational_from_number(a2).map(|r2| (r1, r2)));
match r2 {
Ok((r1, r2)) => {
@@ -242,18 +215,12 @@ impl MachineState {
&HeapCellValue::Addr(Addr::Fixnum(n)) => {
interms.push(Number::Fixnum(n));
}
&HeapCellValue::Addr(Addr::Float(n)) => {
interms.push(Number::Float(n))
}
&HeapCellValue::Integer(ref n) => {
interms.push(Number::Integer(n.clone()))
}
&HeapCellValue::Addr(Addr::Float(n)) => interms.push(Number::Float(n)),
&HeapCellValue::Integer(ref n) => interms.push(Number::Integer(n.clone())),
&HeapCellValue::Addr(Addr::Usize(n)) => {
interms.push(Number::Integer(Rc::new(Integer::from(n))));
}
&HeapCellValue::Rational(ref n) => {
interms.push(Number::Rational(n.clone()))
}
&HeapCellValue::Rational(ref n) => interms.push(Number::Rational(n.clone())),
&HeapCellValue::Atom(ref name, _) if name.as_str() == "pi" => {
interms.push(Number::Float(OrderedFloat(f64::consts::PI)))
}
@@ -282,10 +249,7 @@ impl MachineState {
));
}
&HeapCellValue::Addr(addr) if addr.is_ref() => {
return Err(self.error_form(
MachineError::instantiation_error(),
caller,
));
return Err(self.error_form(MachineError::instantiation_error(), caller));
}
val => {
return Err(self.type_error(
@@ -301,8 +265,7 @@ impl MachineState {
Ok(interms.pop().unwrap())
}
pub(crate)
fn rdiv(&self, r1: Rc<Rational>, r2: Rc<Rational>) -> Result<Rational, MachineStub> {
pub(crate) fn rdiv(&self, r1: Rc<Rational>, r2: Rc<Rational>) -> Result<Rational, MachineStub> {
if &*r2 == &0 {
let stub = MachineError::functor_stub(clause_name!("(rdiv)"), 2);
Err(self.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
@@ -311,27 +274,21 @@ impl MachineState {
}
}
pub(crate)
fn int_floor_div(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
pub(crate) fn int_floor_div(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(div)"), 2);
let modulus = self.modulus(n1.clone(), n2.clone())?;
self.idiv(try_numeric_result!(self, n1 - modulus, stub)?, n2)
}
pub(crate)
fn idiv(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
pub(crate) fn idiv(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
match (n1, n2) {
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
if n2 == 0 {
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
Err(self.error_form(
MachineError::evaluation_error(
EvalError::ZeroDivisor
),
stub,
))
Err(self
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
} else {
if let Some(result) = n1.checked_div(n2) {
Ok(Number::from(result))
@@ -347,12 +304,8 @@ impl MachineState {
if &*n2 == &0 {
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
Err(self.error_form(
MachineError::evaluation_error(
EvalError::ZeroDivisor
),
stub,
))
Err(self
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
} else {
Ok(Number::from(Integer::from(n1) / &*n2))
}
@@ -361,12 +314,8 @@ impl MachineState {
if n1 == 0 {
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
Err(self.error_form(
MachineError::evaluation_error(
EvalError::ZeroDivisor
),
stub,
))
Err(self
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
} else {
Ok(Number::from(&*n2 / Integer::from(n1)))
}
@@ -375,25 +324,19 @@ impl MachineState {
if &*n2 == &0 {
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
Err(self.error_form(
MachineError::evaluation_error(
EvalError::ZeroDivisor
),
stub,
))
Err(self
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
} else {
Ok(Number::from(<(Integer, Integer)>::from(n1.div_rem_ref(&*n2)).0))
Ok(Number::from(
<(Integer, Integer)>::from(n1.div_rem_ref(&*n2)).0,
))
}
}
(Number::Fixnum(_), n2) | (Number::Integer(_), n2) => {
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Integer,
n2,
),
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
stub,
))
}
@@ -401,19 +344,14 @@ impl MachineState {
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Integer,
n1,
),
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
stub,
))
}
}
}
pub(crate)
fn div(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
pub(crate) fn div(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(/)"), 2);
if n2.is_zero() {
@@ -423,8 +361,7 @@ impl MachineState {
}
}
pub(crate)
fn atan2(&self, n1: Number, n2: Number) -> Result<f64, MachineStub> {
pub(crate) 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() {
@@ -437,8 +374,7 @@ impl MachineState {
}
}
pub(crate)
fn int_pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
pub(crate) 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));
@@ -451,11 +387,7 @@ impl MachineState {
let stub = MachineError::functor_stub(clause_name!("^"), 2);
Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Float,
n
),
MachineError::type_error(self.heap.h(), ValidType::Float, n),
stub,
))
} else {
@@ -477,11 +409,7 @@ impl MachineState {
let stub = MachineError::functor_stub(clause_name!("^"), 2);
Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Float,
n
),
MachineError::type_error(self.heap.h(), ValidType::Float, n),
stub,
))
} else {
@@ -495,11 +423,7 @@ impl MachineState {
let stub = MachineError::functor_stub(clause_name!("^"), 2);
Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Float,
n
),
MachineError::type_error(self.heap.h(), ValidType::Float, n),
stub,
))
} else {
@@ -513,11 +437,7 @@ impl MachineState {
let stub = MachineError::functor_stub(clause_name!("^"), 2);
Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Float,
n
),
MachineError::type_error(self.heap.h(), ValidType::Float, n),
stub,
))
} else {
@@ -548,8 +468,7 @@ impl MachineState {
}
}
pub(crate)
fn gcd(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
pub(crate) fn gcd(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
match (n1, n2) {
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
if let Some(result) = isize_gcd(n1, n2) {
@@ -558,8 +477,8 @@ impl MachineState {
Ok(Number::from(Integer::from(n1).gcd(&Integer::from(n2))))
}
}
(Number::Fixnum(n1), Number::Integer(n2)) |
(Number::Integer(n2), Number::Fixnum(n1)) => {
(Number::Fixnum(n1), Number::Integer(n2))
| (Number::Integer(n2), Number::Fixnum(n1)) => {
let n1 = Integer::from(n1);
Ok(Number::from(Integer::from(n2.gcd_ref(&n1))))
}
@@ -571,11 +490,7 @@ impl MachineState {
let stub = MachineError::functor_stub(clause_name!("gcd"), 2);
Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Integer,
n
),
MachineError::type_error(self.heap.h(), ValidType::Integer, n),
stub,
))
}
@@ -584,19 +499,14 @@ impl MachineState {
let stub = MachineError::functor_stub(clause_name!("gcd"), 2);
Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Integer,
n,
),
MachineError::type_error(self.heap.h(), ValidType::Integer, n),
stub,
))
}
}
}
pub(crate)
fn float_pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
pub(crate) 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);
@@ -612,8 +522,12 @@ impl MachineState {
)?)))
}
pub(crate)
fn pow(&self, n1: Number, n2: Number, culprit: &'static str) -> Result<Number, MachineStub> {
pub(crate) fn pow(
&self,
n1: Number,
n2: Number,
culprit: &'static str,
) -> Result<Number, MachineStub> {
if n2.is_negative() && n1.is_zero() {
let stub = MachineError::functor_stub(clause_name!(culprit), 2);
return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub));
@@ -623,8 +537,11 @@ impl MachineState {
}
#[inline]
pub(crate)
fn unary_float_fn_template<FloatFn>(&self, n1: Number, f: FloatFn) -> Result<f64, MachineStub>
pub(crate) fn unary_float_fn_template<FloatFn>(
&self,
n1: Number,
f: FloatFn,
) -> Result<f64, MachineStub>
where
FloatFn: Fn(f64) -> f64,
{
@@ -637,56 +554,47 @@ impl MachineState {
}
#[inline]
pub(crate)
fn sin(&self, n1: Number) -> Result<f64, MachineStub> {
pub(crate) fn sin(&self, n1: Number) -> Result<f64, MachineStub> {
self.unary_float_fn_template(n1, |f| f.sin())
}
#[inline]
pub(crate)
fn cos(&self, n1: Number) -> Result<f64, MachineStub> {
pub(crate) fn cos(&self, n1: Number) -> Result<f64, MachineStub> {
self.unary_float_fn_template(n1, |f| f.cos())
}
#[inline]
pub(crate)
fn tan(&self, n1: Number) -> Result<f64, MachineStub> {
pub(crate) fn tan(&self, n1: Number) -> Result<f64, MachineStub> {
self.unary_float_fn_template(n1, |f| f.tan())
}
#[inline]
pub(crate)
fn log(&self, n1: Number) -> Result<f64, MachineStub> {
pub(crate) fn log(&self, n1: Number) -> Result<f64, MachineStub> {
self.unary_float_fn_template(n1, |f| f.log(f64::consts::E))
}
#[inline]
pub(crate)
fn exp(&self, n1: Number) -> Result<f64, MachineStub> {
pub(crate) fn exp(&self, n1: Number) -> Result<f64, MachineStub> {
self.unary_float_fn_template(n1, |f| f.exp())
}
#[inline]
pub(crate)
fn asin(&self, n1: Number) -> Result<f64, MachineStub> {
pub(crate) fn asin(&self, n1: Number) -> Result<f64, MachineStub> {
self.unary_float_fn_template(n1, |f| f.asin())
}
#[inline]
pub(crate)
fn acos(&self, n1: Number) -> Result<f64, MachineStub> {
pub(crate) fn acos(&self, n1: Number) -> Result<f64, MachineStub> {
self.unary_float_fn_template(n1, |f| f.acos())
}
#[inline]
pub(crate)
fn atan(&self, n1: Number) -> Result<f64, MachineStub> {
pub(crate) fn atan(&self, n1: Number) -> Result<f64, MachineStub> {
self.unary_float_fn_template(n1, |f| f.atan())
}
#[inline]
pub(crate)
fn sqrt(&self, n1: Number) -> Result<f64, MachineStub> {
pub(crate) 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));
@@ -696,27 +604,23 @@ impl MachineState {
}
#[inline]
pub(crate)
fn float(&self, n: Number) -> Result<f64, MachineStub> {
pub(crate) 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)
}
#[inline]
pub(crate)
fn floor(&self, n1: Number) -> Number {
pub(crate) fn floor(&self, n1: Number) -> Number {
rnd_i(&n1).to_owned()
}
#[inline]
pub(crate)
fn ceiling(&self, n1: Number) -> Number {
pub(crate) fn ceiling(&self, n1: Number) -> Number {
-self.floor(-n1)
}
#[inline]
pub(crate)
fn truncate(&self, n: Number) -> Number {
pub(crate) fn truncate(&self, n: Number) -> Number {
if n.is_negative() {
-self.floor(n.abs())
} else {
@@ -724,8 +628,7 @@ impl MachineState {
}
}
pub(crate)
fn round(&self, n: Number) -> Result<Number, MachineStub> {
pub(crate) fn round(&self, n: Number) -> Result<Number, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("is"), 2);
let result = n + Number::Float(OrderedFloat(0.5f64));
@@ -734,8 +637,7 @@ impl MachineState {
Ok(self.floor(result))
}
pub(crate)
fn shr(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
pub(crate) fn shr(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(>>)"), 2);
match (n1, n2) {
@@ -756,38 +658,26 @@ impl MachineState {
_ => Ok(Number::from(n1 >> u32::max_value())),
}
}
(Number::Integer(n1), Number::Fixnum(n2)) => {
match u32::try_from(n2) {
Ok(n2) => Ok(Number::from(Integer::from(&*n1 >> n2))),
_ => Ok(Number::from(Integer::from(&*n1 >> u32::max_value()))),
}
}
(Number::Integer(n1), Number::Integer(n2)) =>
match n2.to_u32() {
Some(n2) => Ok(Number::from(Integer::from(&*n1 >> n2))),
_ => Ok(Number::from(Integer::from(&*n1 >> u32::max_value()))),
},
(Number::Integer(n1), Number::Fixnum(n2)) => match u32::try_from(n2) {
Ok(n2) => Ok(Number::from(Integer::from(&*n1 >> n2))),
_ => Ok(Number::from(Integer::from(&*n1 >> u32::max_value()))),
},
(Number::Integer(n1), Number::Integer(n2)) => match n2.to_u32() {
Some(n2) => Ok(Number::from(Integer::from(&*n1 >> n2))),
_ => Ok(Number::from(Integer::from(&*n1 >> u32::max_value()))),
},
(Number::Integer(_), n2) => Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Integer,
n2,
),
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
stub,
)),
(n1, _) => Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Integer,
n1,
),
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
stub,
)),
}
}
pub(crate)
fn shl(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
pub(crate) fn shl(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(<<)"), 2);
match (n1, n2) {
@@ -808,263 +698,181 @@ impl MachineState {
_ => Ok(Number::from(n1 << u32::max_value())),
}
}
(Number::Integer(n1), Number::Fixnum(n2)) => {
match u32::try_from(n2) {
Ok(n2) => Ok(Number::from(Integer::from(&*n1 << n2))),
_ => Ok(Number::from(Integer::from(&*n1 << u32::max_value()))),
}
}
(Number::Integer(n1), Number::Fixnum(n2)) => match u32::try_from(n2) {
Ok(n2) => Ok(Number::from(Integer::from(&*n1 << n2))),
_ => Ok(Number::from(Integer::from(&*n1 << u32::max_value()))),
},
(Number::Integer(n1), Number::Integer(n2)) => match n2.to_u32() {
Some(n2) => Ok(Number::from(Integer::from(&*n1 << n2))),
_ => Ok(Number::from(Integer::from(&*n1 << u32::max_value()))),
},
(Number::Integer(_), n2) => Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Integer,
n2,
),
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
stub,
)),
(n1, _) => Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Integer,
n1,
),
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
stub,
)),
}
}
pub(crate)
fn bitwise_complement(&self, n1: Number) -> Result<Number, MachineStub> {
pub(crate) fn bitwise_complement(&self, n1: Number) -> Result<Number, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(\\)"), 2);
match n1 {
Number::Fixnum(n) => Ok(Number::Fixnum(!n)),
Number::Integer(n1) => Ok(Number::from(Integer::from(!&*n1))),
_ => Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Integer,
n1,
),
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
stub,
)),
}
}
pub(crate)
fn xor(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
pub(crate) fn xor(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(xor)"), 2);
match (n1, n2) {
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
Ok(Number::from(n1 ^ n2))
}
(Number::Fixnum(n1), Number::Fixnum(n2)) => Ok(Number::from(n1 ^ n2)),
(Number::Fixnum(n1), Number::Integer(n2)) => {
let n1 = Integer::from(n1);
Ok(Number::from(n1 ^ &*n2))
}
(Number::Integer(n1), Number::Fixnum(n2)) => {
Ok(Number::from(&*n1 ^ Integer::from(n2)))
}
(Number::Integer(n1), Number::Fixnum(n2)) => Ok(Number::from(&*n1 ^ Integer::from(n2))),
(Number::Integer(n1), Number::Integer(n2)) => {
Ok(Number::from(Integer::from(&*n1 ^ &*n2)))
}
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => {
Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Integer,
n2
),
stub,
))
}
(n1, _) => {
Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Integer,
n1
),
stub,
))
}
}
}
pub(crate)
fn and(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(/\\)"), 2);
match (n1, n2) {
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
Ok(Number::from(n1 & n2))
}
(Number::Fixnum(n1), Number::Integer(n2)) => {
let n1 = Integer::from(n1);
Ok(Number::from(n1 & &*n2))
}
(Number::Integer(n1), Number::Fixnum(n2)) => {
Ok(Number::from(&*n1 & Integer::from(n2)))
}
(Number::Integer(n1), Number::Integer(n2)) => {
Ok(Number::from(Integer::from(&*n1 & &*n2)))
}
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => {
Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Integer,
n2,
),
stub,
))
}
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => Err(self.error_form(
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
stub,
)),
(n1, _) => Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Integer,
n1,
),
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
stub,
)),
}
}
pub(crate)
fn or(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
pub(crate) fn and(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(/\\)"), 2);
match (n1, n2) {
(Number::Fixnum(n1), Number::Fixnum(n2)) => Ok(Number::from(n1 & n2)),
(Number::Fixnum(n1), Number::Integer(n2)) => {
let n1 = Integer::from(n1);
Ok(Number::from(n1 & &*n2))
}
(Number::Integer(n1), Number::Fixnum(n2)) => Ok(Number::from(&*n1 & Integer::from(n2))),
(Number::Integer(n1), Number::Integer(n2)) => {
Ok(Number::from(Integer::from(&*n1 & &*n2)))
}
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => Err(self.error_form(
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
stub,
)),
(n1, _) => Err(self.error_form(
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
stub,
)),
}
}
pub(crate) fn or(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(\\/)"), 2);
match (n1, n2) {
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
Ok(Number::from(n1 | n2))
}
(Number::Fixnum(n1), Number::Fixnum(n2)) => Ok(Number::from(n1 | n2)),
(Number::Fixnum(n1), Number::Integer(n2)) => {
let n1 = Integer::from(n1);
Ok(Number::from(n1 | &*n2))
}
(Number::Integer(n1), Number::Fixnum(n2)) => {
Ok(Number::from(&*n1 | Integer::from(n2)))
}
(Number::Integer(n1), Number::Fixnum(n2)) => Ok(Number::from(&*n1 | Integer::from(n2))),
(Number::Integer(n1), Number::Integer(n2)) => {
Ok(Number::from(Integer::from(&*n1 | &*n2)))
}
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => {
Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Integer,
n2,
),
stub,
))
}
(n1, _) => {
Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Integer,
n1
),
stub,
))
}
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => Err(self.error_form(
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
stub,
)),
(n1, _) => Err(self.error_form(
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
stub,
)),
}
}
pub(crate)
fn modulus(&self, x: Number, y: Number) -> Result<Number, MachineStub> {
pub(crate) fn modulus(&self, x: Number, y: Number) -> Result<Number, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(mod)"), 2);
match (x, y) {
(Number::Fixnum(n1), Number::Fixnum(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(Number::from(n1.rem_floor(n2)))
}
}
(Number::Fixnum(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 {
let n1 = Integer::from(n1);
Ok(Number::from(<(Integer, Integer)>::from(n1.div_rem_floor_ref(&*n2)).1))
Ok(Number::from(
<(Integer, Integer)>::from(n1.div_rem_floor_ref(&*n2)).1,
))
}
}
(Number::Integer(n1), Number::Fixnum(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 {
let n2 = Integer::from(n2);
Ok(Number::from(<(Integer, Integer)>::from(n1.div_rem_floor_ref(&n2)).1))
Ok(Number::from(
<(Integer, Integer)>::from(n1.div_rem_floor_ref(&n2)).1,
))
}
}
(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(Number::from(<(Integer, Integer)>::from(x.div_rem_floor_ref(&*y)).1))
Ok(Number::from(
<(Integer, Integer)>::from(x.div_rem_floor_ref(&*y)).1,
))
}
}
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => {
Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Integer,
n2,
),
stub,
))
}
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => Err(self.error_form(
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
stub,
)),
(n1, _) => Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Integer,
n1,
),
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
stub,
)),
}
}
pub(crate)
fn remainder(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
pub(crate) fn remainder(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
let stub = MachineError::functor_stub(clause_name!("(rem)"), 2);
match (n1, n2) {
(Number::Fixnum(n1), Number::Fixnum(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(Number::from(n1 % n2))
}
}
(Number::Fixnum(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 {
let n1 = Integer::from(n1);
Ok(Number::from(n1 % &*n2))
@@ -1072,10 +880,8 @@ impl MachineState {
}
(Number::Integer(n1), Number::Fixnum(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 {
let n2 = Integer::from(n2);
Ok(Number::from(&*n1 % n2))
@@ -1083,37 +889,24 @@ impl MachineState {
}
(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(Number::from(Integer::from(&*n1 % &*n2)))
}
}
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => {
Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Integer,
n2,
),
stub,
))
}
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => Err(self.error_form(
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
stub,
)),
(n1, _) => Err(self.error_form(
MachineError::type_error(
self.heap.h(),
ValidType::Integer,
n1,
),
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
stub,
)),
}
}
pub(crate)
fn max(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
pub(crate) fn max(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
match (n1, n2) {
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
if n1 > n2 {
@@ -1154,8 +947,7 @@ impl MachineState {
}
}
pub(crate)
fn min(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
pub(crate) fn min(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
match (n1, n2) {
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
if n1 < n2 {
@@ -1196,8 +988,7 @@ impl MachineState {
}
}
pub(crate)
fn sign(&self, n: Number) -> Number {
pub(crate) fn sign(&self, n: Number) -> Number {
if n.is_positive() {
Number::from(1)
} else if n.is_negative() {

View File

@@ -1,5 +1,6 @@
use crate::heap_iter::*;
use crate::machine::*;
use crate::prolog_parser_rebis::temp_v;
use crate::indexmap::IndexSet;
@@ -20,8 +21,7 @@ pub(super) struct AttrVarInitializer {
}
impl AttrVarInitializer {
pub(super)
fn new(verify_attrs_loc: usize, project_attrs_loc: usize) -> Self {
pub(super) fn new(verify_attrs_loc: usize, project_attrs_loc: usize) -> Self {
AttrVarInitializer {
attribute_goals: vec![],
attr_var_queue: vec![],
@@ -34,24 +34,21 @@ impl AttrVarInitializer {
}
#[inline]
pub(super)
fn reset(&mut self) {
self.attribute_goals.clear();
pub(super) fn reset(&mut self) {
self.attribute_goals.clear();
self.attr_var_queue.clear();
self.bindings.clear();
}
#[inline]
pub(super)
fn backtrack(&mut self, queue_b: usize, bindings_b: usize) {
pub(super) fn backtrack(&mut self, queue_b: usize, bindings_b: usize) {
self.attr_var_queue.truncate(queue_b);
self.bindings.truncate(bindings_b);
}
}
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.instigating_p = self.p.local();
@@ -79,7 +76,7 @@ impl MachineState {
let iter = self
.attr_var_init
.bindings
.drain(0 ..)
.drain(0..)
.map(|(_, addr)| HeapCellValue::Addr(addr));
let value_list_addr = Addr::HeapCell(self.heap.to_list(iter));
@@ -97,8 +94,7 @@ impl MachineState {
self[temp_v!(2)] = value_list_addr;
}
pub(super)
fn gather_attr_vars_created_since(&self, b: usize) -> IntoIter<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))) {
@@ -107,29 +103,25 @@ impl MachineState {
})
.collect();
attr_vars.sort_unstable_by(|a1, a2| {
self.compare_term_test(a1, a2).unwrap_or(Ordering::Less)
});
attr_vars
.sort_unstable_by(|a1, a2| self.compare_term_test(a1, a2).unwrap_or(Ordering::Less));
self.term_dedup(&mut attr_vars);
attr_vars.into_iter()
}
pub(super)
fn verify_attr_interrupt(&mut self, p: usize) {
pub(super) fn verify_attr_interrupt(&mut self, p: usize) {
self.allocate(self.num_of_args + 2);
let e = self.e;
self.stack.index_and_frame_mut(e).prelude.interrupt_cp = self.attr_var_init.cp;
for i in 1 .. self.num_of_args + 1 {
for i in 1..self.num_of_args + 1 {
self.stack.index_and_frame_mut(e)[i] = self[RegType::Temp(i)];
}
self.stack.index_and_frame_mut(e)[self.num_of_args + 1] =
Addr::CutPoint(self.b0);
self.stack.index_and_frame_mut(e)[self.num_of_args + 2] =
Addr::Usize(self.num_of_args);
self.stack.index_and_frame_mut(e)[self.num_of_args + 1] = Addr::CutPoint(self.b0);
self.stack.index_and_frame_mut(e)[self.num_of_args + 2] = Addr::Usize(self.num_of_args);
self.verify_attributes();
@@ -138,9 +130,8 @@ impl MachineState {
self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
}
pub(super)
fn attr_vars_of_term(&self, addr: Addr) -> Vec<Addr> {
let mut seen_set = IndexSet::new();
pub(super) fn attr_vars_of_term(&self, addr: Addr) -> Vec<Addr> {
let mut seen_set = IndexSet::new();
let mut seen_vars = vec![];
let mut iter = self.acyclic_pre_order_iter(addr);

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,8 @@
use crate::machine::*;
use crate::machine::machine_indices::*;
use crate::machine::term_stream::*;
use crate::machine::*;
use crate::prolog_parser_rebis::clause_name;
use crate::machine::term_stream::*;
use indexmap::IndexSet;
use crate::ref_thread_local::RefThreadLocal;
@@ -19,37 +20,35 @@ pub(super) struct LoadState<'a> {
pub(super) wam: &'a mut Machine,
}
pub(super)
fn set_code_index(
pub(super) fn set_code_index(
retraction_info: &mut RetractionInfo,
compilation_target: &CompilationTarget,
key: PredicateKey,
code_index: &CodeIndex,
code_ptr: IndexPtr,
) {
let record =
match compilation_target {
CompilationTarget::User => {
if IndexPtr::Undefined == code_index.get() {
code_index.set(code_ptr);
RetractionRecord::AddedUserPredicate(key)
} else {
// TODO: emit warning about overwriting previous record
let replaced = code_index.replace(code_ptr);
RetractionRecord::ReplacedUserPredicate(key, replaced)
}
let record = match compilation_target {
CompilationTarget::User => {
if IndexPtr::Undefined == code_index.get() {
code_index.set(code_ptr);
RetractionRecord::AddedUserPredicate(key)
} else {
// TODO: emit warning about overwriting previous record
let replaced = code_index.replace(code_ptr);
RetractionRecord::ReplacedUserPredicate(key, replaced)
}
CompilationTarget::Module(ref module_name) => {
if IndexPtr::Undefined == code_index.get() {
code_index.set(code_ptr);
RetractionRecord::AddedModulePredicate(module_name.clone(), key)
} else {
// TODO: emit warning about overwriting previous record
let replaced = code_index.replace(code_ptr);
RetractionRecord::ReplacedModulePredicate(module_name.clone(), key, replaced)
}
}
CompilationTarget::Module(ref module_name) => {
if IndexPtr::Undefined == code_index.get() {
code_index.set(code_ptr);
RetractionRecord::AddedModulePredicate(module_name.clone(), key)
} else {
// TODO: emit warning about overwriting previous record
let replaced = code_index.replace(code_ptr);
RetractionRecord::ReplacedModulePredicate(module_name.clone(), key, replaced)
}
};
}
};
retraction_info.push_record(record);
}
@@ -71,16 +70,16 @@ fn add_op_decl_as_module_export(
match op_decl.insert_into_op_dir(wam_op_dir) {
Some((prec, spec)) => {
retraction_info.push_record(
RetractionRecord::ReplacedUserOp(op_decl.clone(), prec, spec)
);
retraction_info.push_record(RetractionRecord::ReplacedUserOp(
op_decl.clone(),
prec,
spec,
));
module_op_exports.push((op_decl.clone(), Some((prec, spec))));
}
None => {
retraction_info.push_record(
RetractionRecord::AddedUserOp(op_decl.clone())
);
retraction_info.push_record(RetractionRecord::AddedUserOp(op_decl.clone()));
module_op_exports.push((op_decl.clone(), None));
}
@@ -89,49 +88,45 @@ fn add_op_decl_as_module_export(
add_op_decl(retraction_info, compilation_target, module_op_dir, op_decl);
}
pub(super)
fn add_op_decl(
pub(super) fn add_op_decl(
retraction_info: &mut RetractionInfo,
compilation_target: &CompilationTarget,
op_dir: &mut OpDir,
op_decl: &OpDecl,
) {
match op_decl.insert_into_op_dir(op_dir) {
Some((prec, spec)) => {
match &compilation_target {
CompilationTarget::User => {
retraction_info.push_record(
RetractionRecord::ReplacedUserOp(op_decl.clone(), prec, spec),
);
}
CompilationTarget::Module(ref module_name) => {
retraction_info.push_record(
RetractionRecord::ReplacedModuleOp(
module_name.clone(), op_decl.clone(), prec, spec,
),
);
}
Some((prec, spec)) => match &compilation_target {
CompilationTarget::User => {
retraction_info.push_record(RetractionRecord::ReplacedUserOp(
op_decl.clone(),
prec,
spec,
));
}
}
None => {
match &compilation_target {
CompilationTarget::User => {
retraction_info.push_record(
RetractionRecord::AddedUserOp(op_decl.clone()),
);
}
CompilationTarget::Module(ref module_name) => {
retraction_info.push_record(
RetractionRecord::AddedModuleOp(module_name.clone(), op_decl.clone()),
);
}
CompilationTarget::Module(ref module_name) => {
retraction_info.push_record(RetractionRecord::ReplacedModuleOp(
module_name.clone(),
op_decl.clone(),
prec,
spec,
));
}
}
},
None => match &compilation_target {
CompilationTarget::User => {
retraction_info.push_record(RetractionRecord::AddedUserOp(op_decl.clone()));
}
CompilationTarget::Module(ref module_name) => {
retraction_info.push_record(RetractionRecord::AddedModuleOp(
module_name.clone(),
op_decl.clone(),
));
}
},
}
}
pub(super)
fn import_module_exports(
pub(super) fn import_module_exports(
retraction_info: &mut RetractionInfo,
compilation_target: &CompilationTarget,
imported_module: &Module,
@@ -166,12 +161,7 @@ fn import_module_exports(
}
}
ModuleExport::OpDecl(ref op_decl) => {
add_op_decl(
retraction_info,
compilation_target,
op_dir,
op_decl,
);
add_op_decl(retraction_info, compilation_target, op_dir, op_decl);
}
}
}
@@ -185,7 +175,7 @@ fn import_module_exports_into_module(
op_dir: &mut OpDir,
meta_predicates: &mut MetaPredicateDir,
wam_op_dir: &mut OpDir,
module_op_exports: &mut ModuleOpExports
module_op_exports: &mut ModuleOpExports,
) {
for export in imported_module.module_decl.exports.iter() {
match export {
@@ -227,7 +217,6 @@ fn import_module_exports_into_module(
}
}
fn import_qualified_module_exports(
retraction_info: &mut RetractionInfo,
compilation_target: &CompilationTarget,
@@ -263,12 +252,7 @@ fn import_qualified_module_exports(
}
}
ModuleExport::OpDecl(ref op_decl) => {
add_op_decl(
retraction_info,
compilation_target,
op_dir,
op_decl,
);
add_op_decl(retraction_info, compilation_target, op_dir, op_decl);
}
}
}
@@ -326,29 +310,28 @@ fn import_qualified_module_exports_into_module(
impl<'a> LoadState<'a> {
#[inline]
pub(super)
fn increment_clause_assert_margin(&mut self, incr: usize) {
pub(super) fn increment_clause_assert_margin(&mut self, incr: usize) {
match &self.compilation_target {
CompilationTarget::User => {
}
CompilationTarget::User => {}
CompilationTarget::Module(ref module_name) => {
self.retraction_info.push_record(
RetractionRecord::IncreasedClauseAssertMargin(
self.retraction_info
.push_record(RetractionRecord::IncreasedClauseAssertMargin(
module_name.clone(),
incr,
),
);
));
self.wam.indices.modules.get_mut(module_name)
self.wam
.indices
.modules
.get_mut(module_name)
.map(|module| module.clause_assert_margin += incr);
}
}
}
#[inline]
pub(super)
fn remove_module_op_exports(&mut self) {
for (mut op_decl, record) in self.module_op_exports.drain(0 ..) {
pub(super) fn remove_module_op_exports(&mut self) {
for (mut op_decl, record) in self.module_op_exports.drain(0..) {
op_decl.remove(&mut self.wam.indices.op_dir);
if let Some((prec, spec)) = record {
@@ -365,26 +348,28 @@ impl<'a> LoadState<'a> {
key: PredicateKey,
) -> CodeIndex {
match self.wam.indices.modules.get_mut(&module_name) {
Some(ref mut module) => {
module.code_dir
.entry(key)
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
.clone()
}
Some(ref mut module) => module
.code_dir
.entry(key)
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
.clone(),
None => {
let mut module = Module::new(
ModuleDecl { name: module_name.clone(), exports: vec![] },
ModuleDecl {
name: module_name.clone(),
exports: vec![],
},
ListingSource::DynamicallyGenerated,
);
let code_index = module.code_dir
let code_index = module
.code_dir
.entry(key)
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
.clone();
self.retraction_info.push_record(
RetractionRecord::AddedModule(module_name.clone()),
);
self.retraction_info
.push_record(RetractionRecord::AddedModule(module_name.clone()));
self.wam.indices.modules.insert(module_name, module);
code_index
@@ -392,29 +377,31 @@ impl<'a> LoadState<'a> {
}
}
pub(super)
fn get_or_insert_code_index(&mut self, key: PredicateKey) -> CodeIndex {
pub(super) fn get_or_insert_code_index(&mut self, key: PredicateKey) -> CodeIndex {
match self.compilation_target.clone() {
CompilationTarget::User => {
self.wam.indices.code_dir
.entry(key)
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
.clone()
}
CompilationTarget::User => self
.wam
.indices
.code_dir
.entry(key)
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
.clone(),
CompilationTarget::Module(module_name) => {
self.get_or_insert_local_code_index(module_name, key)
}
}
}
pub(super)
fn get_or_insert_qualified_code_index(
pub(super) fn get_or_insert_qualified_code_index(
&mut self,
module_name: ClauseName,
key: PredicateKey,
) -> CodeIndex {
if module_name.as_str() == "user" {
return self.wam.indices.code_dir
return self
.wam
.indices
.code_dir
.entry(key)
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
.clone();
@@ -424,15 +411,20 @@ impl<'a> LoadState<'a> {
}
#[inline]
pub(super)
fn add_extensible_predicate(&mut self, key: PredicateKey, skeleton: PredicateSkeleton) {
pub(super) fn add_extensible_predicate(
&mut self,
key: PredicateKey,
skeleton: PredicateSkeleton,
) {
match &self.compilation_target {
CompilationTarget::User => {
self.wam.indices.extensible_predicates.insert(key.clone(), skeleton);
self.wam
.indices
.extensible_predicates
.insert(key.clone(), skeleton);
self.retraction_info.push_record(
RetractionRecord::AddedUserExtensiblePredicate(key),
);
self.retraction_info
.push_record(RetractionRecord::AddedUserExtensiblePredicate(key));
}
CompilationTarget::Module(ref module_name) => {
if let Some(module) = self.wam.indices.modules.get_mut(module_name) {
@@ -448,8 +440,7 @@ impl<'a> LoadState<'a> {
}
}
pub(super)
fn add_op_decl(&mut self, op_decl: &OpDecl) {
pub(super) fn add_op_decl(&mut self, op_decl: &OpDecl) {
match &self.compilation_target {
CompilationTarget::User => {
add_op_decl(
@@ -479,8 +470,7 @@ impl<'a> LoadState<'a> {
}
}
pub(super)
fn get_clause_type(
pub(super) fn get_clause_type(
&mut self,
name: ClauseName,
arity: usize,
@@ -495,14 +485,11 @@ impl<'a> LoadState<'a> {
let idx = self.get_or_insert_code_index((name.clone(), arity));
ClauseType::Op(name, fixity, idx)
}
ct => {
ct
}
ct => ct,
}
}
pub(super)
fn get_qualified_clause_type(
pub(super) fn get_qualified_clause_type(
&mut self,
module_name: ClauseName,
name: ClauseName,
@@ -522,14 +509,11 @@ impl<'a> LoadState<'a> {
ClauseType::Op(name, fixity, idx)
}
ct => {
ct
}
ct => ct,
}
}
pub(super)
fn add_meta_predicate_record(
pub(super) fn add_meta_predicate_record(
&mut self,
module_name: ClauseName,
name: ClauseName,
@@ -540,20 +524,26 @@ impl<'a> LoadState<'a> {
match module_name.as_str() {
"user" => {
match self.wam.indices.meta_predicates.insert(key.clone(), meta_specs) {
match self
.wam
.indices
.meta_predicates
.insert(key.clone(), meta_specs)
{
Some(old_meta_specs) => {
self.retraction_info.push_record(
RetractionRecord::ReplacedMetaPredicate(
module_name.clone(), key.0, old_meta_specs,
),
);
self.retraction_info
.push_record(RetractionRecord::ReplacedMetaPredicate(
module_name.clone(),
key.0,
old_meta_specs,
));
}
None => {
self.retraction_info.push_record(
RetractionRecord::AddedMetaPredicate(
module_name.clone(), key,
)
);
self.retraction_info
.push_record(RetractionRecord::AddedMetaPredicate(
module_name.clone(),
key,
));
}
}
}
@@ -564,15 +554,15 @@ impl<'a> LoadState<'a> {
Some(old_meta_specs) => {
self.retraction_info.push_record(
RetractionRecord::ReplacedMetaPredicate(
module_name.clone(), key.0, old_meta_specs,
module_name.clone(),
key.0,
old_meta_specs,
),
);
}
None => {
self.retraction_info.push_record(
RetractionRecord::AddedMetaPredicate(
module_name.clone(), key,
)
RetractionRecord::AddedMetaPredicate(module_name.clone(), key),
);
}
}
@@ -588,15 +578,14 @@ impl<'a> LoadState<'a> {
module.meta_predicates.insert(key.clone(), meta_specs);
self.retraction_info.push_record(
RetractionRecord::AddedMetaPredicate(
module_name.clone(), key,
)
);
self.retraction_info
.push_record(RetractionRecord::AddedMetaPredicate(
module_name.clone(),
key,
));
self.retraction_info.push_record(
RetractionRecord::AddedModule(module_name.clone()),
);
self.retraction_info
.push_record(RetractionRecord::AddedModule(module_name.clone()));
self.wam.indices.modules.insert(module_name, module);
}
@@ -623,32 +612,29 @@ impl<'a> LoadState<'a> {
}
}
pub(crate)
fn add_module(&mut self, module_decl: ModuleDecl, listing_src: ListingSource) {
pub(crate) fn add_module(&mut self, module_decl: ModuleDecl, listing_src: ListingSource) {
let module_name = module_decl.name.clone();
let mut module =
match self.wam.indices.modules.remove(&module_name) {
Some(mut module) => {
let old_module_decl = mem::replace(&mut module.module_decl, module_decl);
let mut module = match self.wam.indices.modules.remove(&module_name) {
Some(mut module) => {
let old_module_decl = mem::replace(&mut module.module_decl, module_decl);
self.retraction_info.push_record(
RetractionRecord::ReplacedModule(
old_module_decl, listing_src.clone(),
),
);
self.retraction_info
.push_record(RetractionRecord::ReplacedModule(
old_module_decl,
listing_src.clone(),
));
module.listing_src = listing_src;
module
}
None => {
self.retraction_info.push_record(
RetractionRecord::AddedModule(module_name.clone()),
);
module.listing_src = listing_src;
module
}
None => {
self.retraction_info
.push_record(RetractionRecord::AddedModule(module_name.clone()));
Module::new(module_decl, listing_src)
}
};
Module::new(module_decl, listing_src)
}
};
self.import_builtins_in_module(
&mut module.code_dir,
@@ -676,8 +662,7 @@ impl<'a> LoadState<'a> {
self.wam.indices.modules.insert(module_name, module);
}
pub(super)
fn import_module(&mut self, module_name: ClauseName) -> Result<(), SessionError> {
pub(super) fn import_module(&mut self, module_name: ClauseName) -> Result<(), SessionError> {
if let Some(module) = self.wam.indices.modules.remove(&module_name) {
match &self.compilation_target {
CompilationTarget::User => {
@@ -717,7 +702,9 @@ impl<'a> LoadState<'a> {
self.wam.indices.modules.insert(module_name, module);
Ok(())
} else {
Err(SessionError::ExistenceError(ExistenceError::Module(module_name)))
Err(SessionError::ExistenceError(ExistenceError::Module(
module_name,
)))
}
}
@@ -765,41 +752,41 @@ impl<'a> LoadState<'a> {
self.wam.indices.modules.insert(module_name, module);
Ok(())
} else {
Err(SessionError::ExistenceError(ExistenceError::Module(module_name)))
Err(SessionError::ExistenceError(ExistenceError::Module(
module_name,
)))
}
}
pub(crate)
fn use_module(&mut self, module_src: ModuleSource) -> Result<(), SessionError> {
let (stream, listing_src) =
match module_src {
ModuleSource::File(filename) => {
let mut path_buf = PathBuf::from(filename.as_str());
path_buf.set_extension("pl");
let file = File::open(&path_buf)?;
pub(crate) fn use_module(&mut self, module_src: ModuleSource) -> Result<(), SessionError> {
let (stream, listing_src) = match module_src {
ModuleSource::File(filename) => {
let mut path_buf = PathBuf::from(filename.as_str());
path_buf.set_extension("pl");
let file = File::open(&path_buf)?;
(Stream::from_file_as_input(filename.clone(), file),
ListingSource::File(filename, path_buf))
}
ModuleSource::Library(library) => {
match LIBRARIES.borrow().get(library.as_str()) {
Some(code) => {
if let Some(ref module) = self.wam.indices.modules.get(&library) {
if let ListingSource::DynamicallyGenerated = &module.listing_src {
(Stream::from(*code), ListingSource::User)
} else {
return self.import_module(library);
}
} else {
(Stream::from(*code), ListingSource::User)
}
}
None => {
(
Stream::from_file_as_input(filename.clone(), file),
ListingSource::File(filename, path_buf),
)
}
ModuleSource::Library(library) => match LIBRARIES.borrow().get(library.as_str()) {
Some(code) => {
if let Some(ref module) = self.wam.indices.modules.get(&library) {
if let ListingSource::DynamicallyGenerated = &module.listing_src {
(Stream::from(*code), ListingSource::User)
} else {
return self.import_module(library);
}
} else {
(Stream::from(*code), ListingSource::User)
}
}
};
None => {
return self.import_module(library);
}
},
};
let compilation_target = {
let stream = &mut parsing_stream(stream)?;
@@ -820,43 +807,39 @@ impl<'a> LoadState<'a> {
// nothing to do.
Ok(())
}
CompilationTarget::Module(module_name) => {
self.import_module(module_name)
}
CompilationTarget::Module(module_name) => self.import_module(module_name),
}
}
pub(crate)
fn use_qualified_module(
pub(crate) fn use_qualified_module(
&mut self,
module_src: ModuleSource,
exports: IndexSet<ModuleExport>,
) -> Result<(), SessionError> {
let (stream, listing_src) =
match module_src {
ModuleSource::File(filename) => {
let mut path_buf = PathBuf::from(filename.as_str());
path_buf.set_extension("pl");
let file = File::open(&path_buf)?;
let (stream, listing_src) = match module_src {
ModuleSource::File(filename) => {
let mut path_buf = PathBuf::from(filename.as_str());
path_buf.set_extension("pl");
let file = File::open(&path_buf)?;
(Stream::from_file_as_input(filename.clone(), file),
ListingSource::File(filename, path_buf))
}
ModuleSource::Library(library) => {
match LIBRARIES.borrow().get(library.as_str()) {
Some(code) => {
if self.wam.indices.modules.contains_key(&library) {
return self.import_qualified_module(library, exports);
} else {
(Stream::from(*code), ListingSource::User)
}
}
None => {
return self.import_qualified_module(library, exports);
}
(
Stream::from_file_as_input(filename.clone(), file),
ListingSource::File(filename, path_buf),
)
}
ModuleSource::Library(library) => match LIBRARIES.borrow().get(library.as_str()) {
Some(code) => {
if self.wam.indices.modules.contains_key(&library) {
return self.import_qualified_module(library, exports);
} else {
(Stream::from(*code), ListingSource::User)
}
}
};
None => {
return self.import_qualified_module(library, exports);
}
},
};
let compilation_target = {
let stream = &mut parsing_stream(stream)?;
@@ -884,12 +867,9 @@ impl<'a> LoadState<'a> {
}
#[inline]
pub(super)
fn composite_op_dir(&self) -> CompositeOpDir {
pub(super) fn composite_op_dir(&self) -> CompositeOpDir {
match &self.compilation_target {
CompilationTarget::User => {
CompositeOpDir::new(&self.wam.indices.op_dir, None)
}
CompilationTarget::User => CompositeOpDir::new(&self.wam.indices.op_dir, None),
CompilationTarget::Module(ref module_name) => {
match self.wam.indices.modules.get(module_name) {
Some(ref module) => {

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
use crate::prolog_parser_rebis::ast::*;
use crate::prolog_parser_rebis::{clause_name, temp_v};
use crate::forms::{ModuleSource, Number}; //, PredicateKey};
use crate::machine::heap::*;
@@ -23,74 +24,59 @@ pub(crate) struct MachineError {
from: ErrorProvenance,
}
pub(crate)
trait TypeError {
pub(crate) trait TypeError {
fn type_error(self, h: usize, valid_type: ValidType) -> MachineError;
}
impl TypeError for Addr {
fn type_error(self, _: usize, valid_type: ValidType) -> MachineError {
let stub = functor!(
"type_error",
[atom(valid_type.as_str()), addr(self)]
);
let stub = functor!("type_error", [atom(valid_type.as_str()), addr(self)]);
MachineError {
stub,
location: None,
from: ErrorProvenance::Received
from: ErrorProvenance::Received,
}
}
}
impl TypeError for HeapCellValue {
fn type_error(self, _: usize, valid_type: ValidType) -> MachineError {
let stub = functor!(
"type_error",
[atom(valid_type.as_str()), value(self)]
);
let stub = functor!("type_error", [atom(valid_type.as_str()), value(self)]);
MachineError {
stub,
location: None,
from: ErrorProvenance::Received
from: ErrorProvenance::Received,
}
}
}
impl TypeError for MachineStub {
fn type_error(self, h: usize, valid_type: ValidType) -> MachineError {
let stub = functor!(
"type_error",
[atom(valid_type.as_str()), aux(h, 0)],
[self]
);
let stub = functor!("type_error", [atom(valid_type.as_str()), aux(h, 0)], [self]);
MachineError {
stub,
location: None,
from: ErrorProvenance::Constructed
from: ErrorProvenance::Constructed,
}
}
}
impl TypeError for Number {
fn type_error(self, _h: usize, valid_type: ValidType) -> MachineError {
let stub = functor!(
"type_error",
[atom(valid_type.as_str()), number(self)]
);
let stub = functor!("type_error", [atom(valid_type.as_str()), number(self)]);
MachineError {
stub,
location: None,
from: ErrorProvenance::Received
from: ErrorProvenance::Received,
}
}
}
pub(crate)
trait PermissionError {
pub(crate) trait PermissionError {
fn permission_error(self, h: usize, index_str: &'static str, perm: Permission) -> MachineError;
}
@@ -104,7 +90,7 @@ impl PermissionError for Addr {
MachineError {
stub,
location: None,
from: ErrorProvenance::Received
from: ErrorProvenance::Received,
}
}
}
@@ -120,22 +106,18 @@ impl PermissionError for MachineStub {
MachineError {
stub,
location: None,
from: ErrorProvenance::Constructed
from: ErrorProvenance::Constructed,
}
}
}
pub(super)
trait DomainError {
pub(super) trait DomainError {
fn domain_error(self, error: DomainErrorType) -> MachineError;
}
impl DomainError for Addr {
fn domain_error(self, error: DomainErrorType) -> MachineError {
let stub = functor!(
"domain_error",
[atom(error.as_str()), addr(self)]
);
let stub = functor!("domain_error", [atom(error.as_str()), addr(self)]);
MachineError {
stub,
@@ -147,10 +129,7 @@ impl DomainError for Addr {
impl DomainError for Number {
fn domain_error(self, error: DomainErrorType) -> MachineError {
let stub = functor!(
"domain_error",
[atom(error.as_str()), number(self)]
);
let stub = functor!("domain_error", [atom(error.as_str()), number(self)]);
MachineError {
stub,
@@ -161,8 +140,7 @@ impl DomainError for Number {
}
impl MachineError {
pub(super)
fn functor_stub(name: ClauseName, arity: usize) -> MachineStub {
pub(super) fn functor_stub(name: ClauseName, arity: usize) -> MachineStub {
functor!(
"/",
SharedOpDesc::new(400, YFX),
@@ -171,8 +149,7 @@ impl MachineError {
}
#[inline]
pub(super)
fn interrupt_error() -> Self {
pub(super) fn interrupt_error() -> Self {
let stub = functor!("$interrupt_thrown");
MachineError {
@@ -182,8 +159,7 @@ impl MachineError {
}
}
pub(super)
fn evaluation_error(eval_error: EvalError) -> Self {
pub(super) fn evaluation_error(eval_error: EvalError) -> Self {
let stub = functor!("evaluation_error", [atom(eval_error.as_str())]);
MachineError {
@@ -193,13 +169,11 @@ impl MachineError {
}
}
pub(super)
fn type_error<T: TypeError>(h: usize, valid_type: ValidType, culprit: T) -> Self {
pub(super) fn type_error<T: TypeError>(h: usize, valid_type: ValidType, culprit: T) -> Self {
culprit.type_error(h, valid_type)
}
pub(super)
fn module_resolution_error(
pub(super) fn module_resolution_error(
h: usize,
mod_name: ClauseName,
name: ClauseName,
@@ -218,11 +192,7 @@ impl MachineError {
[res_stub]
);
let stub = functor!(
"evaluation_error",
[aux(h, 0)],
[ind_stub]
);
let stub = functor!("evaluation_error", [aux(h, 0)], [ind_stub]);
MachineError {
stub,
@@ -231,14 +201,10 @@ impl MachineError {
}
}
pub(super)
fn existence_error(h: usize, err: ExistenceError) -> Self {
pub(super) fn existence_error(h: usize, err: ExistenceError) -> Self {
match err {
ExistenceError::Module(name) => {
let stub = functor!(
"existence_error",
[atom("source_sink"), clause_name(name)]
);
let stub = functor!("existence_error", [atom("source_sink"), clause_name(name)]);
MachineError {
stub,
@@ -253,11 +219,7 @@ impl MachineError {
[clause_name(name), integer(arity)]
);
let stub = functor!(
"existence_error",
[atom("procedure"), aux(h, 0)],
[culprit]
);
let stub = functor!("existence_error", [atom("procedure"), aux(h, 0)], [culprit]);
MachineError {
stub,
@@ -281,10 +243,7 @@ impl MachineError {
}
}
ExistenceError::SourceSink(culprit) => {
let stub = functor!(
"existence_error",
[atom("source_sink"), addr(culprit)]
);
let stub = functor!("existence_error", [atom("source_sink"), addr(culprit)]);
MachineError {
stub,
@@ -293,10 +252,7 @@ impl MachineError {
}
}
ExistenceError::Stream(culprit) => {
let stub = functor!(
"existence_error",
[atom("stream"), addr(culprit)]
);
let stub = functor!("existence_error", [atom("stream"), addr(culprit)]);
MachineError {
stub,
@@ -307,25 +263,18 @@ impl MachineError {
}
}
pub(super)
fn permission_error<T: PermissionError>(
pub(super) fn permission_error<T: PermissionError>(
h: usize,
err: Permission,
index_str: &'static str,
culprit: T,
) -> Self {
culprit.permission_error(
h,
index_str,
err,
)
culprit.permission_error(h, index_str, err)
}
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 culprit = functor!(
"/",
@@ -339,13 +288,11 @@ impl MachineError {
}
#[inline]
pub(super)
fn domain_error<T: DomainError>(error: DomainErrorType, culprit: T) -> Self {
pub(super) fn domain_error<T: DomainError>(error: DomainErrorType, culprit: T) -> Self {
culprit.domain_error(error)
}
pub(super)
fn instantiation_error() -> Self {
pub(super) fn instantiation_error() -> Self {
let stub = functor!("instantiation_error");
MachineError {
@@ -355,8 +302,7 @@ impl MachineError {
}
}
pub(super)
fn session_error(h: usize, err: SessionError) -> Self {
pub(super) fn session_error(h: usize, err: SessionError) -> Self {
match err {
// SessionError::CannotOverwriteBuiltIn(pred_str) |
/*
@@ -369,9 +315,7 @@ impl MachineError {
)
}
*/
SessionError::ExistenceError(err) => {
Self::existence_error(h, err)
}
SessionError::ExistenceError(err) => Self::existence_error(h, err),
// SessionError::InvalidFileName(filename) => {
// Self::existence_error(h, ExistenceError::Module(filename))
// }
@@ -385,46 +329,32 @@ impl MachineError {
)
}
*/
SessionError::ModuleCannotImportSelf(module_name) => {
Self::permission_error(
h,
Permission::Modify,
"module",
functor!("module_cannot_import_self", [clause_name(module_name)]),
)
}
SessionError::NamelessEntry => {
Self::permission_error(
h,
Permission::Create,
"static_procedure",
functor!("nameless_procedure")
)
}
SessionError::ModuleCannotImportSelf(module_name) => Self::permission_error(
h,
Permission::Modify,
"module",
functor!("module_cannot_import_self", [clause_name(module_name)]),
),
SessionError::NamelessEntry => Self::permission_error(
h,
Permission::Create,
"static_procedure",
functor!("nameless_procedure"),
),
SessionError::OpIsInfixAndPostFix(op) => {
Self::permission_error(
h,
Permission::Create,
"operator",
functor!(clause_name(op)),
)
}
SessionError::CompilationError(err) => {
Self::syntax_error(h, err)
}
SessionError::QueryCannotBeDefinedAsFact => {
Self::permission_error(
h,
Permission::Create,
"static_procedure",
functor!("query_cannot_be_defined_as_fact")
)
Self::permission_error(h, Permission::Create, "operator", functor!(clause_name(op)))
}
SessionError::CompilationError(err) => Self::syntax_error(h, err),
SessionError::QueryCannotBeDefinedAsFact => Self::permission_error(
h,
Permission::Create,
"static_procedure",
functor!("query_cannot_be_defined_as_fact"),
),
}
}
pub(super)
fn syntax_error<E: Into<CompilationError>>(h: usize, err: E) -> Self {
pub(super) fn syntax_error<E: Into<CompilationError>>(h: usize, err: E) -> Self {
let err = err.into();
if let CompilationError::Arithmetic(err) = err {
@@ -434,11 +364,7 @@ impl MachineError {
let location = err.line_and_col_num();
let stub = err.as_functor(h);
let stub = functor!(
"syntax_error",
[aux(h, 0)],
[stub]
);
let stub = functor!("syntax_error", [aux(h, 0)], [stub]);
MachineError {
stub,
@@ -447,8 +373,7 @@ impl MachineError {
}
}
pub(super)
fn representation_error(flag: RepFlag) -> Self {
pub(super) fn representation_error(flag: RepFlag) -> Self {
let stub = functor!("representation_error", [atom(flag.as_str())]);
MachineError {
@@ -515,56 +440,39 @@ impl From<ParserError> for CompilationError {
impl CompilationError {
pub fn line_and_col_num(&self) -> Option<(usize, usize)> {
match self {
&CompilationError::ParserError(ref err) =>
err.line_and_col_num(),
_ =>
None
&CompilationError::ParserError(ref err) => err.line_and_col_num(),
_ => None,
}
}
pub fn as_functor(&self, _h: usize) -> MachineStub {
match self {
&CompilationError::Arithmetic(..) =>
functor!("arithmetic_error"),
&CompilationError::Arithmetic(..) => functor!("arithmetic_error"),
// &CompilationError::BadPendingByte =>
// functor!("bad_pending_byte"),
&CompilationError::CannotParseCyclicTerm =>
functor!("cannot_parse_cyclic_term"),
&CompilationError::CannotParseCyclicTerm => functor!("cannot_parse_cyclic_term"),
// &CompilationError::ExpandedTermsListNotAList =>
// functor!("expanded_terms_list_is_not_a_list"),
&CompilationError::ExpectedRel =>
functor!("expected_relation"),
&CompilationError::ExpectedRel => functor!("expected_relation"),
// &CompilationError::ExpectedTopLevelTerm =>
// functor!("expected_atom_or_cons_or_clause"),
&CompilationError::InadmissibleFact =>
functor!("inadmissible_fact"),
&CompilationError::InadmissibleQueryTerm =>
functor!("inadmissible_query_term"),
&CompilationError::InconsistentEntry =>
functor!("inconsistent_entry"),
&CompilationError::InadmissibleFact => functor!("inadmissible_fact"),
&CompilationError::InadmissibleQueryTerm => functor!("inadmissible_query_term"),
&CompilationError::InconsistentEntry => functor!("inconsistent_entry"),
// &CompilationError::InvalidDoubleQuotesDecl =>
// functor!("invalid_double_quotes_declaration"),
// &CompilationError::InvalidHook =>
// functor!("invalid_hook"),
&CompilationError::InvalidMetaPredicateDecl =>
functor!("invalid_meta_predicate_decl"),
&CompilationError::InvalidModuleDecl =>
functor!("invalid_module_declaration"),
&CompilationError::InvalidModuleExport =>
functor!("invalid_module_export"),
&CompilationError::InvalidModuleResolution(ref module_name) =>
functor!(
"no_such_module",
[clause_name(module_name.clone())]
),
&CompilationError::InvalidRuleHead =>
functor!("invalid_head_of_rule"),
&CompilationError::InvalidUseModuleDecl =>
functor!("invalid_use_module_declaration"),
&CompilationError::ParserError(ref err) =>
functor!(err.as_str()),
&CompilationError::UnreadableTerm =>
functor!("unreadable_term"),
&CompilationError::InvalidMetaPredicateDecl => functor!("invalid_meta_predicate_decl"),
&CompilationError::InvalidModuleDecl => functor!("invalid_module_declaration"),
&CompilationError::InvalidModuleExport => functor!("invalid_module_export"),
&CompilationError::InvalidModuleResolution(ref module_name) => {
functor!("no_such_module", [clause_name(module_name.clone())])
}
&CompilationError::InvalidRuleHead => functor!("invalid_head_of_rule"),
&CompilationError::InvalidUseModuleDecl => functor!("invalid_use_module_declaration"),
&CompilationError::ParserError(ref err) => functor!(err.as_str()),
&CompilationError::UnreadableTerm => functor!("unreadable_term"),
}
}
}
@@ -715,16 +623,15 @@ impl EvalError {
pub(super) enum CycleSearchResult {
EmptyList,
NotList,
PartialList(usize, Ref), // the list length (up to max), and an offset into the heap.
ProperList(usize), // the list length.
PartialList(usize, Ref), // the list length (up to max), and an offset into the heap.
ProperList(usize), // the list length.
PStrLocation(usize, usize, usize), // the list length (up to max), the heap offset, byte offset into the string.
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 {
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 sorted = self.store(self.deref(self[temp_v!(2)].clone()));
@@ -734,7 +641,9 @@ impl MachineState {
return Err(self.error_form(MachineError::instantiation_error(), stub))
}
CycleSearchResult::NotList => {
return Err(self.error_form(MachineError::type_error(0, ValidType::List, list), stub))
return Err(
self.error_form(MachineError::type_error(0, ValidType::List, list), stub)
)
}
_ => {}
};
@@ -766,7 +675,8 @@ impl MachineState {
new_l = l;
}
HeapCellValue::NamedStr(2, ref name, Some(_))
if name.as_str() == "-" => {
if name.as_str() == "-" =>
{
break;
}
HeapCellValue::Addr(Addr::HeapCell(_)) => {
@@ -793,11 +703,10 @@ impl MachineState {
}
// see 8.4.4 of Draft Technical Corrigendum 2.
pub(super)
fn check_keysort_errors(&self) -> CallResult {
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 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()) {
@@ -814,8 +723,7 @@ impl MachineState {
}
#[inline]
pub(crate)
fn type_error<T: TypeError>(
pub(crate) fn type_error<T: TypeError>(
&self,
valid_type: ValidType,
culprit: T,
@@ -823,33 +731,25 @@ impl MachineState {
arity: usize,
) -> MachineStub {
let stub = MachineError::functor_stub(caller, arity);
let err = MachineError::type_error(
self.heap.h(),
valid_type,
culprit,
);
let err = MachineError::type_error(self.heap.h(), valid_type, culprit);
return self.error_form(err, stub);
}
#[inline]
pub(crate)
fn representation_error(
pub(crate) fn representation_error(
&self,
rep_flag: RepFlag,
caller: ClauseName,
arity: usize,
) -> MachineStub {
let stub = MachineError::functor_stub(caller, arity);
let err = MachineError::representation_error(
rep_flag,
);
let err = MachineError::representation_error(rep_flag);
return self.error_form(err, stub);
}
pub(super)
fn error_form(&self, err: MachineError, src: MachineStub) -> MachineStub {
pub(super) fn error_form(&self, err: MachineError, src: MachineStub) -> MachineStub {
let location = err.location;
let err_len = err.len();
@@ -874,8 +774,7 @@ impl MachineState {
stub
}
pub(super)
fn throw_exception(&mut self, err: MachineStub) {
pub(super) fn throw_exception(&mut self, err: MachineStub) {
let h = self.heap.h();
self.ball.boundary = 0;

View File

@@ -1,18 +1,19 @@
use crate::prolog_parser_rebis::ast::*;
use crate::prolog_parser_rebis::clause_name;
use crate::clause_types::*;
use crate::fixtures::*;
use crate::forms::*;
use crate::machine::CompilationTarget;
use crate::instructions::*;
use crate::machine::code_repo::CodeRepo;
use crate::machine::Ball;
use crate::machine::heap::*;
use crate::machine::machine_state::*;
use crate::machine::partial_string::*;
use crate::machine::raw_block::RawBlockTraits;
use crate::machine::streams::Stream;
use crate::machine::term_stream::LoadStatePayload;
use crate::instructions::*;
use crate::machine::Ball;
use crate::machine::CompilationTarget;
use crate::ordered_float::OrderedFloat;
use crate::rug::{Integer, Rational};
@@ -96,20 +97,14 @@ impl Ord for Ref {
fn cmp(&self, other: &Ref) -> Ordering {
match (self, other) {
(Ref::AttrVar(h1), Ref::AttrVar(h2))
| (Ref::HeapCell(h1), Ref::HeapCell(h2))
| (Ref::HeapCell(h1), Ref::AttrVar(h2))
| (Ref::AttrVar(h1), Ref::HeapCell(h2)) => {
h1.cmp(&h2)
}
| (Ref::HeapCell(h1), Ref::HeapCell(h2))
| (Ref::HeapCell(h1), Ref::AttrVar(h2))
| (Ref::AttrVar(h1), Ref::HeapCell(h2)) => h1.cmp(&h2),
(Ref::StackCell(fr1, sc1), Ref::StackCell(fr2, sc2)) => {
fr1.cmp(&fr2).then_with(|| sc1.cmp(&sc2))
}
(Ref::StackCell(..), _) => {
Ordering::Greater
}
(_, Ref::StackCell(..)) => {
Ordering::Less
}
(Ref::StackCell(..), _) => Ordering::Greater,
(_, Ref::StackCell(..)) => Ordering::Less,
}
}
}
@@ -124,35 +119,23 @@ impl PartialEq<Ref> for Addr {
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(_) => {
&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)
}
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(..) => {
} else if fr1 == fr && sc1 == sc {
Some(Ordering::Equal)
} else {
Some(Ordering::Less)
}
Ref::AttrVar(h1) | Ref::HeapCell(h1) => {
h.partial_cmp(h1)
}
}
}
_ => {
None
}
},
&Addr::HeapCell(h) | &Addr::AttrVar(h) => match r {
Ref::StackCell(..) => Some(Ordering::Less),
Ref::AttrVar(h1) | Ref::HeapCell(h1) => h.partial_cmp(h1),
},
_ => None,
}
}
}
@@ -161,26 +144,21 @@ impl Addr {
#[inline]
pub fn is_heap_bound(&self) -> bool {
match self {
Addr::Char(_) | Addr::EmptyList |
Addr::CutPoint(_) | Addr::Usize(_) | Addr::Fixnum(_) |
Addr::Float(_) => {
false
}
_ => {
true
}
Addr::Char(_)
| Addr::EmptyList
| Addr::CutPoint(_)
| Addr::Usize(_)
| Addr::Fixnum(_)
| Addr::Float(_) => false,
_ => true,
}
}
#[inline]
pub fn is_ref(&self) -> bool {
match self {
Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::AttrVar(_) => {
true
}
_ => {
false
}
Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::AttrVar(_) => true,
_ => false,
}
}
@@ -194,92 +172,54 @@ impl Addr {
}
}
pub(super)
fn order_category(&self, heap: &Heap) -> Option<TermOrderCategory> {
pub(super) fn order_category(&self, heap: &Heap) -> Option<TermOrderCategory> {
match Number::try_from((*self, heap)) {
Ok(Number::Integer(_)) | Ok(Number::Fixnum(_)) | Ok(Number::Rational(_)) => {
Some(TermOrderCategory::Integer)
}
Ok(Number::Float(_)) => {
Some(TermOrderCategory::FloatingPoint)
}
_ => {
match self {
Addr::HeapCell(_) | Addr::AttrVar(_) | Addr::StackCell(..) => {
Some(TermOrderCategory::Variable)
}
Addr::Float(_) => {
Some(TermOrderCategory::FloatingPoint)
}
&Addr::Con(h) => {
match &heap[h] {
HeapCellValue::Atom(..) => {
Some(TermOrderCategory::Atom)
}
HeapCellValue::DBRef(_) => {
None
}
_ => {
unreachable!()
}
}
}
Addr::Char(_) | Addr::EmptyList => {
Some(TermOrderCategory::Atom)
}
Addr::Fixnum(_) | Addr::Usize(_) => {
Some(TermOrderCategory::Integer)
}
Addr::Lis(_) | Addr::PStrLocation(..) | Addr::Str(_) => {
Some(TermOrderCategory::Compound)
}
Addr::CutPoint(_) | Addr::LoadStatePayload(_) | Addr::Stream(_) | Addr::TcpListener(_) => {
None
}
Ok(Number::Float(_)) => Some(TermOrderCategory::FloatingPoint),
_ => match self {
Addr::HeapCell(_) | Addr::AttrVar(_) | Addr::StackCell(..) => {
Some(TermOrderCategory::Variable)
}
}
Addr::Float(_) => Some(TermOrderCategory::FloatingPoint),
&Addr::Con(h) => match &heap[h] {
HeapCellValue::Atom(..) => Some(TermOrderCategory::Atom),
HeapCellValue::DBRef(_) => None,
_ => {
unreachable!()
}
},
Addr::Char(_) | Addr::EmptyList => Some(TermOrderCategory::Atom),
Addr::Fixnum(_) | Addr::Usize(_) => Some(TermOrderCategory::Integer),
Addr::Lis(_) | Addr::PStrLocation(..) | Addr::Str(_) => {
Some(TermOrderCategory::Compound)
}
Addr::CutPoint(_)
| Addr::LoadStatePayload(_)
| Addr::Stream(_)
| Addr::TcpListener(_) => None,
},
}
}
pub fn as_constant_index(&self, machine_st: &MachineState) -> Option<Constant> {
match self {
&Addr::Char(c) => {
Some(Constant::Char(c))
}
&Addr::Con(h) => {
match &machine_st.heap[h] {
&HeapCellValue::Atom(ref name, _) if name.is_char() => {
Some(Constant::Char(name.as_str().chars().next().unwrap()))
}
&HeapCellValue::Atom(ref name, _) => {
Some(Constant::Atom(name.clone(), None))
}
&HeapCellValue::Integer(ref n) => {
Some(Constant::Integer(n.clone()))
}
&HeapCellValue::Rational(ref n) => {
Some(Constant::Rational(n.clone()))
}
_ => {
None
}
&Addr::Char(c) => Some(Constant::Char(c)),
&Addr::Con(h) => match &machine_st.heap[h] {
&HeapCellValue::Atom(ref name, _) if name.is_char() => {
Some(Constant::Char(name.as_str().chars().next().unwrap()))
}
}
&Addr::EmptyList => {
Some(Constant::EmptyList)
}
&Addr::Fixnum(n) => {
Some(Constant::Fixnum(n))
}
&Addr::Float(f) => {
Some(Constant::Float(f))
}
&Addr::Usize(n) => {
Some(Constant::Usize(n))
}
_ => {
None
}
&HeapCellValue::Atom(ref name, _) => Some(Constant::Atom(name.clone(), None)),
&HeapCellValue::Integer(ref n) => Some(Constant::Integer(n.clone())),
&HeapCellValue::Rational(ref n) => Some(Constant::Rational(n.clone())),
_ => None,
},
&Addr::EmptyList => Some(Constant::EmptyList),
&Addr::Fixnum(n) => Some(Constant::Fixnum(n)),
&Addr::Float(f) => Some(Constant::Float(f)),
&Addr::Usize(n) => Some(Constant::Usize(n)),
_ => None,
}
}
@@ -383,61 +323,37 @@ impl HeapCellValue {
#[inline]
pub fn as_addr(&self, focus: usize) -> Addr {
match self {
HeapCellValue::Addr(ref a) => {
*a
}
HeapCellValue::Atom(..) | HeapCellValue::DBRef(..) | HeapCellValue::Integer(..) |
HeapCellValue::Rational(..) => {
Addr::Con(focus)
}
HeapCellValue::LoadStatePayload(_) => {
Addr::LoadStatePayload(focus)
}
HeapCellValue::NamedStr(_, _, _) => {
Addr::Str(focus)
}
HeapCellValue::PartialString(..) => {
Addr::PStrLocation(focus, 0)
}
HeapCellValue::Stream(_) => {
Addr::Stream(focus)
}
HeapCellValue::TcpListener(_) => {
Addr::TcpListener(focus)
}
HeapCellValue::Addr(ref a) => *a,
HeapCellValue::Atom(..)
| HeapCellValue::DBRef(..)
| HeapCellValue::Integer(..)
| HeapCellValue::Rational(..) => Addr::Con(focus),
HeapCellValue::LoadStatePayload(_) => Addr::LoadStatePayload(focus),
HeapCellValue::NamedStr(_, _, _) => Addr::Str(focus),
HeapCellValue::PartialString(..) => Addr::PStrLocation(focus, 0),
HeapCellValue::Stream(_) => Addr::Stream(focus),
HeapCellValue::TcpListener(_) => Addr::TcpListener(focus),
}
}
#[inline]
pub fn context_free_clone(&self) -> HeapCellValue {
match self {
&HeapCellValue::Addr(addr) => {
HeapCellValue::Addr(addr)
}
&HeapCellValue::Atom(ref name, ref op) => {
HeapCellValue::Atom(name.clone(), op.clone())
}
&HeapCellValue::DBRef(ref db_ref) => {
HeapCellValue::DBRef(db_ref.clone())
}
&HeapCellValue::Integer(ref n) => {
HeapCellValue::Integer(n.clone())
}
&HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr),
&HeapCellValue::Atom(ref name, ref op) => HeapCellValue::Atom(name.clone(), op.clone()),
&HeapCellValue::DBRef(ref db_ref) => HeapCellValue::DBRef(db_ref.clone()),
&HeapCellValue::Integer(ref n) => HeapCellValue::Integer(n.clone()),
&HeapCellValue::LoadStatePayload(_) => {
HeapCellValue::Atom(clause_name!("$live_term_stream"), None)
}
&HeapCellValue::NamedStr(arity, ref name, ref op) => {
HeapCellValue::NamedStr(arity, name.clone(), op.clone())
}
&HeapCellValue::Rational(ref r) => {
HeapCellValue::Rational(r.clone())
}
&HeapCellValue::Rational(ref r) => HeapCellValue::Rational(r.clone()),
&HeapCellValue::PartialString(ref pstr, has_tail) => {
HeapCellValue::PartialString(pstr.clone(), has_tail)
}
&HeapCellValue::Stream(ref stream) => {
HeapCellValue::Stream(stream.clone())
}
&HeapCellValue::Stream(ref stream) => HeapCellValue::Stream(stream.clone()),
&HeapCellValue::TcpListener(_) => {
HeapCellValue::Atom(clause_name!("$tcp_listener"), None)
}
@@ -473,8 +389,7 @@ impl Deref for CodeIndex {
impl CodeIndex {
#[inline]
pub(super)
fn new(ptr: IndexPtr) -> Self {
pub(super) fn new(ptr: IndexPtr) -> Self {
CodeIndex(Rc::new(Cell::new(ptr)))
}
@@ -482,7 +397,7 @@ impl CodeIndex {
pub fn is_undefined(&self) -> bool {
match self.0.get() {
IndexPtr::Undefined => true, // | &IndexPtr::DynamicUndefined => true,
_ => false
_ => false,
}
}
@@ -536,7 +451,7 @@ pub enum CodePtr {
CallN(usize, LocalCodePtr, bool), // arity, local, last call.
Local(LocalCodePtr),
// DynamicTransaction(DynamicTransactionType, LocalCodePtr), // the type of transaction, the return pointer.
REPL(REPLCodePtr, LocalCodePtr), // the REPL code, the return pointer.
REPL(REPLCodePtr, LocalCodePtr), // the REPL code, the return pointer.
VerifyAttrInterrupt(usize), // location of the verify attribute interrupt code in the CodeDir.
}
@@ -544,10 +459,10 @@ 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) => p // | &CodePtr::DynamicTransaction(_, p) => p,
&CodePtr::REPL(_, p) => p, // | &CodePtr::DynamicTransaction(_, p) => p,
}
}
@@ -566,12 +481,11 @@ pub enum LocalCodePtr {
DirEntry(usize), // offset
Halt,
IndexingBuf(usize, usize, usize), // DirEntry offset, first internal offset, second internal offset
// TopLevel(usize, usize), // chunk_num, offset
// TopLevel(usize, usize), // chunk_num, offset
}
impl LocalCodePtr {
pub(crate)
fn assign_if_local(&mut self, cp: CodePtr) {
pub(crate) fn assign_if_local(&mut self, cp: CodePtr) {
match cp {
CodePtr::Local(local) => *self = local,
_ => {}
@@ -579,8 +493,7 @@ impl LocalCodePtr {
}
#[inline]
pub(crate)
fn abs_loc(&self) -> usize {
pub(crate) fn abs_loc(&self) -> usize {
match self {
LocalCodePtr::DirEntry(ref p) => *p,
LocalCodePtr::IndexingBuf(ref p, ..) => *p,
@@ -588,35 +501,28 @@ impl LocalCodePtr {
}
}
pub(crate)
fn is_reset_cont_marker(&self, code_repo: &CodeRepo, last_call: bool) -> bool {
pub(crate) fn is_reset_cont_marker(&self, code_repo: &CodeRepo, last_call: bool) -> bool {
match code_repo.lookup_instr(last_call, &CodePtr::Local(*self)) {
Some(line) => {
match line.as_ref() {
Line::Control(ControlInstruction::CallClause(ref ct, ..)) => {
if let ClauseType::System(SystemClauseType::ResetContinuationMarker) = *ct {
return true;
}
Some(line) => match line.as_ref() {
Line::Control(ControlInstruction::CallClause(ref ct, ..)) => {
if let ClauseType::System(SystemClauseType::ResetContinuationMarker) = *ct {
return true;
}
_ => {}
}
}
_ => {}
},
None => {}
}
false
}
pub(crate)
fn as_functor<T: RawBlockTraits>(&self, heap: &mut HeapTemplate<T>) -> Addr {
pub(crate) fn as_functor<T: RawBlockTraits>(&self, heap: &mut HeapTemplate<T>) -> Addr {
let addr = Addr::HeapCell(heap.h());
match self {
LocalCodePtr::DirEntry(p) => {
heap.append(functor!(
"dir_entry",
[integer(*p)]
));
heap.append(functor!("dir_entry", [integer(*p)]));
}
LocalCodePtr::Halt => {
heap.append(functor!("halt"));
@@ -658,7 +564,7 @@ impl PartialOrd<CodePtr> for CodePtr {
impl PartialOrd<LocalCodePtr> for LocalCodePtr {
fn partial_cmp(&self, other: &LocalCodePtr) -> Option<Ordering> {
match (self, other) {
(&LocalCodePtr::DirEntry(p1), &LocalCodePtr::DirEntry(ref p2)) |
(&LocalCodePtr::DirEntry(p1), &LocalCodePtr::DirEntry(ref p2)) |
(&LocalCodePtr::TopLevel(_, p1), &LocalCodePtr::TopLevel(_, ref p2)) => {
p1.partial_cmp(p2)
}
@@ -693,12 +599,9 @@ impl Add<usize> for LocalCodePtr {
#[inline]
fn add(self, rhs: usize) -> Self::Output {
match self {
LocalCodePtr::DirEntry(p) =>
LocalCodePtr::DirEntry(p + rhs),
LocalCodePtr::Halt =>
unreachable!(),
LocalCodePtr::IndexingBuf(p, o, i) =>
LocalCodePtr::IndexingBuf(p, o, i + rhs),
LocalCodePtr::DirEntry(p) => LocalCodePtr::DirEntry(p + rhs),
LocalCodePtr::Halt => unreachable!(),
LocalCodePtr::IndexingBuf(p, o, i) => LocalCodePtr::IndexingBuf(p, o, i + rhs),
}
}
}
@@ -709,12 +612,11 @@ impl Sub<usize> for LocalCodePtr {
#[inline]
fn sub(self, rhs: usize) -> Self::Output {
match self {
LocalCodePtr::DirEntry(p) =>
p.checked_sub(rhs).map(LocalCodePtr::DirEntry),
LocalCodePtr::Halt =>
unreachable!(),
LocalCodePtr::IndexingBuf(p, o, i) =>
i.checked_sub(rhs).map(|r| LocalCodePtr::IndexingBuf(p, o, r)),
LocalCodePtr::DirEntry(p) => p.checked_sub(rhs).map(LocalCodePtr::DirEntry),
LocalCodePtr::Halt => unreachable!(),
LocalCodePtr::IndexingBuf(p, o, i) => i
.checked_sub(rhs)
.map(|r| LocalCodePtr::IndexingBuf(p, o, r)),
}
}
}
@@ -723,15 +625,12 @@ impl SubAssign<usize> for LocalCodePtr {
#[inline]
fn sub_assign(&mut self, rhs: usize) {
match self {
LocalCodePtr::DirEntry(ref mut p) =>
*p -= rhs,
LocalCodePtr::Halt | LocalCodePtr::IndexingBuf(..) =>
unreachable!(),
LocalCodePtr::DirEntry(ref mut p) => *p -= rhs,
LocalCodePtr::Halt | LocalCodePtr::IndexingBuf(..) => unreachable!(),
}
}
}
impl AddAssign<usize> for LocalCodePtr {
#[inline]
fn add_assign(&mut self, rhs: usize) {
@@ -749,14 +648,12 @@ impl Add<usize> for CodePtr {
fn add(self, rhs: usize) -> Self::Output {
match self {
p @ CodePtr::REPL(..) |
p @ CodePtr::VerifyAttrInterrupt(_) => { // |
// p @ CodePtr::DynamicTransaction(..) => {
p @ CodePtr::REPL(..) | p @ CodePtr::VerifyAttrInterrupt(_) => {
// |
// p @ CodePtr::DynamicTransaction(..) => {
p
}
CodePtr::Local(local) => {
CodePtr::Local(local + rhs)
}
CodePtr::Local(local) => CodePtr::Local(local + rhs),
CodePtr::BuiltInClause(_, local) | CodePtr::CallN(_, local, _) => {
CodePtr::Local(local + rhs)
}
@@ -784,7 +681,6 @@ impl SubAssign<usize> for CodePtr {
}
}
pub type HeapVarDict = IndexMap<Rc<Var>, Addr>;
pub type AllocVarDict = IndexMap<Rc<Var>, VarData>;
@@ -830,23 +726,17 @@ impl IndexStore {
key: &PredicateKey,
) -> Option<&mut PredicateSkeleton> {
match (key.0.as_str(), key.1) {
("term_expansion", 2) => {
self.extensible_predicates.get_mut(key)
}
_ => {
match compilation_target {
CompilationTarget::User => {
self.extensible_predicates.get_mut(key)
}
CompilationTarget::Module(ref module_name) => {
if let Some(module) = self.modules.get_mut(module_name) {
module.extensible_predicates.get_mut(key)
} else {
None
}
("term_expansion", 2) => self.extensible_predicates.get_mut(key),
_ => match compilation_target {
CompilationTarget::User => self.extensible_predicates.get_mut(key),
CompilationTarget::Module(ref module_name) => {
if let Some(module) = self.modules.get_mut(module_name) {
module.extensible_predicates.get_mut(key)
} else {
None
}
}
}
},
}
}
@@ -858,19 +748,17 @@ impl IndexStore {
match (key.0.as_str(), key.1) {
("term_expansion", 2) => {
self.extensible_predicates.remove(key);
},
_ => {
match compilation_target {
CompilationTarget::User => {
self.extensible_predicates.remove(key);
}
CompilationTarget::Module(ref module_name) => {
if let Some(module) = self.modules.get_mut(module_name) {
module.extensible_predicates.remove(key);
}
}
_ => match compilation_target {
CompilationTarget::User => {
self.extensible_predicates.remove(key);
}
CompilationTarget::Module(ref module_name) => {
if let Some(module) = self.modules.get_mut(module_name) {
module.extensible_predicates.remove(key);
}
}
}
},
}
}
@@ -883,15 +771,9 @@ impl IndexStore {
) -> Option<CodeIndex> {
if module.as_str() == "user" {
match ClauseType::from(name, arity, op_spec) {
ClauseType::Named(name, arity, _) => {
self.code_dir.get(&(name, arity)).cloned()
}
ClauseType::Op(name, spec, ..) => {
self.code_dir.get(&(name, spec.arity())).cloned()
}
_ => {
None
}
ClauseType::Named(name, arity, _) => self.code_dir.get(&(name, arity)).cloned(),
ClauseType::Op(name, spec, ..) => self.code_dir.get(&(name, spec.arity())).cloned(),
_ => None,
}
} else {
self.modules.get(&module).and_then(|module| {
@@ -902,9 +784,7 @@ impl IndexStore {
ClauseType::Op(name, spec, ..) => {
module.code_dir.get(&(name, spec.arity())).cloned()
}
_ => {
None
}
_ => None,
}
})
}
@@ -917,44 +797,32 @@ impl IndexStore {
compilation_target: &CompilationTarget,
) -> Option<&Vec<MetaSpec>> {
match compilation_target {
CompilationTarget::User => {
self.meta_predicates.get(&(name, arity))
}
CompilationTarget::Module(ref module_name) => {
match self.modules.get(module_name) {
Some(ref module) => {
module.meta_predicates.get(&(name.clone(), arity))
.or_else(|| {
self.meta_predicates.get(&(name, arity))
})
}
None => {
self.meta_predicates.get(&(name, arity))
}
}
}
CompilationTarget::User => self.meta_predicates.get(&(name, arity)),
CompilationTarget::Module(ref module_name) => match self.modules.get(module_name) {
Some(ref module) => module
.meta_predicates
.get(&(name.clone(), arity))
.or_else(|| self.meta_predicates.get(&(name, arity))),
None => self.meta_predicates.get(&(name, arity)),
},
}
}
pub fn is_dynamic_predicate(&self, module_name: ClauseName, key: PredicateKey) -> bool {
match module_name.as_str() {
"user" => {
self.extensible_predicates.get(&key)
"user" => self
.extensible_predicates
.get(&key)
.map(|skeleton| skeleton.is_dynamic)
.unwrap_or(false),
_ => match self.modules.get(&module_name) {
Some(ref module) => module
.extensible_predicates
.get(&key)
.map(|skeleton| skeleton.is_dynamic)
.unwrap_or(false)
}
_ => {
match self.modules.get(&module_name) {
Some(ref module) => {
module.extensible_predicates.get(&key)
.map(|skeleton| skeleton.is_dynamic)
.unwrap_or(false)
}
None => {
false
}
}
}
.unwrap_or(false),
None => false,
},
}
}
@@ -963,8 +831,7 @@ impl IndexStore {
IndexStore::default()
}
pub(super)
fn get_cleaner_sites(&self) -> (usize, usize) {
pub(super) fn get_cleaner_sites(&self) -> (usize, usize) {
let r_w_h = clause_name!("run_cleaners_with_handling");
let r_wo_h = clause_name!("run_cleaners_without_handling");
let iso_ext = clause_name!("iso_ext");
@@ -996,10 +863,8 @@ pub enum RefOrOwned<'a, T: 'a> {
impl<'a, T: 'a + fmt::Debug> fmt::Debug for RefOrOwned<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&RefOrOwned::Borrowed(ref borrowed) =>
write!(f, "Borrowed({:?})", borrowed),
&RefOrOwned::Owned(ref owned) =>
write!(f, "Owned({:?})", owned),
&RefOrOwned::Borrowed(ref borrowed) => write!(f, "Borrowed({:?})", borrowed),
&RefOrOwned::Owned(ref owned) => write!(f, "Owned({:?})", owned),
}
}
}
@@ -1012,7 +877,9 @@ impl<'a, T> RefOrOwned<'a, T> {
}
}
pub fn to_owned(self) -> T where T: Clone
pub fn to_owned(self) -> T
where
T: Clone,
{
match self {
RefOrOwned::Borrowed(item) => item.clone(),

View File

@@ -1,5 +1,6 @@
use crate::prolog_parser_rebis::ast::*;
use crate::prolog_parser_rebis::tabled_rc::*;
use crate::prolog_parser_rebis::{clause_name, temp_v};
use crate::clause_types::*;
use crate::forms::*;
@@ -14,7 +15,9 @@ use crate::machine::stack::*;
use crate::machine::streams::*;
use crate::rug::Integer;
use crate::downcast::Any;
use crate::downcast::{
downcast, downcast_methods, downcast_methods_core, downcast_methods_std, impl_downcast, Any,
};
use crate::indexmap::IndexMap;
@@ -32,33 +35,26 @@ pub struct Ball {
}
impl Ball {
pub(super)
fn new() -> Self {
pub(super) fn new() -> Self {
Ball {
boundary: 0,
stub: Heap::new(),
}
}
pub(super)
fn reset(&mut self) {
pub(super) fn reset(&mut self) {
self.boundary = 0;
self.stub.clear();
}
pub(super)
fn copy_and_align(&self, h: usize) -> Heap {
pub(super) fn copy_and_align(&self, h: usize) -> Heap {
let diff = self.boundary as i64 - h as i64;
let mut stub = Heap::new();
for heap_value in self.stub.iter_from(0) {
stub.push(match heap_value {
&HeapCellValue::Addr(addr) => {
HeapCellValue::Addr(addr - diff)
}
heap_value => {
heap_value.context_free_clone()
}
&HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr - diff),
heap_value => heap_value.context_free_clone(),
});
}
@@ -123,11 +119,7 @@ pub(super) struct CopyBallTerm<'a> {
}
impl<'a> CopyBallTerm<'a> {
pub(super) fn new(
stack: &'a mut Stack,
heap: &'a mut Heap,
stub: &'a mut Heap,
) -> Self {
pub(super) fn new(stack: &'a mut Stack, heap: &'a mut Heap, stub: &'a mut Heap) -> Self {
let hb = heap.h();
CopyBallTerm {
@@ -182,12 +174,8 @@ impl<'a> CopierTarget for CopyBallTerm<'a> {
let index = h - self.heap_boundary;
self.stub[index].as_addr(h)
}
Addr::StackCell(fr, sc) => {
self.stack.index_and_frame(fr)[sc]
}
addr => {
addr
}
Addr::StackCell(fr, sc) => self.stack.index_and_frame(fr)[sc],
addr => addr,
}
}
@@ -226,9 +214,7 @@ impl Index<RegType> for MachineState {
impl IndexMut<RegType> for MachineState {
fn index_mut(&mut self, reg: RegType) -> &mut Self::Output {
match reg {
RegType::Temp(temp) => {
&mut self.registers[temp]
}
RegType::Temp(temp) => &mut self.registers[temp],
RegType::Perm(perm) => {
let e = self.e;
@@ -255,15 +241,12 @@ pub(super) enum HeapPtr {
impl HeapPtr {
#[inline]
pub(super)
fn read(&self, heap: &Heap) -> Addr {
pub(super) fn read(&self, heap: &Heap) -> Addr {
match self {
&HeapPtr::HeapCell(h) => {
Addr::HeapCell(h)
}
&HeapPtr::HeapCell(h) => Addr::HeapCell(h),
&HeapPtr::PStrChar(h, n) => {
if let &HeapCellValue::PartialString(ref pstr, has_tail) = &heap[h] {
if let Some(c) = pstr.range_from(n ..).next() {
if let Some(c) = pstr.range_from(n..).next() {
Addr::Char(c)
} else if has_tail {
Addr::HeapCell(h + 1)
@@ -274,9 +257,7 @@ impl HeapPtr {
unreachable!()
}
}
&HeapPtr::PStrLocation(h, n) => {
Addr::PStrLocation(h, n)
}
&HeapPtr::PStrLocation(h, n) => Addr::PStrLocation(h, n),
}
}
}
@@ -313,16 +294,11 @@ pub struct MachineState {
pub(super) last_call: bool,
pub(crate) heap_locs: HeapVarDict,
pub(crate) flags: MachineFlags,
pub(crate) at_end_of_expansion: bool
pub(crate) at_end_of_expansion: bool,
}
impl MachineState {
pub(crate)
fn read_term(
&mut self,
mut stream: Stream,
indices: &mut IndexStore,
) -> CallResult {
pub(crate) fn read_term(&mut self, mut stream: Stream, indices: &mut IndexStore) -> CallResult {
self.check_stream_properties(
&mut stream,
StreamType::Text,
@@ -342,11 +318,7 @@ impl MachineState {
let mut orig_stream = stream.clone();
loop {
match self.read(
stream.clone(),
self.atom_tbl.clone(),
&indices.op_dir,
) {
match self.read(stream.clone(), self.atom_tbl.clone(), &indices.op_dir) {
Ok(term_write_result) => {
let term = self[temp_v!(2)];
self.unify(Addr::HeapCell(term_write_result.heap_loc), term);
@@ -363,7 +335,8 @@ impl MachineState {
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::Atom(var_atom, None));
self.heap.push(HeapCellValue::Addr(binding));
@@ -406,8 +379,7 @@ impl MachineState {
}
let vars_addr = self[temp_v!(4)];
let vars_offset =
Addr::HeapCell(self.heap.to_list(var_list.into_iter()));
let vars_offset = Addr::HeapCell(self.heap.to_list(var_list.into_iter()));
self.unify(vars_offset, vars_addr);
@@ -427,7 +399,7 @@ impl MachineState {
self[temp_v!(2)],
&mut orig_stream,
clause_name!("read_term"),
3
3,
)?;
if orig_stream.options.eof_action == EOFAction::Reset {
@@ -448,12 +420,10 @@ impl MachineState {
}
}
pub(crate)
fn write_term<'a>(
pub(crate) fn write_term<'a>(
&'a self,
op_dir: &'a OpDir,
) -> Result<Option<HCPrinter<'a, PrinterOutputter>>, MachineStub>
{
) -> Result<Option<HCPrinter<'a, PrinterOutputter>>, MachineStub> {
let ignore_ops = self.store(self.deref(self[temp_v!(3)]));
let numbervars = self.store(self.deref(self[temp_v!(4)]));
let quoted = self.store(self.deref(self[temp_v!(5)]));
@@ -462,7 +432,7 @@ impl MachineState {
let mut printer = HCPrinter::new(&self, op_dir, PrinterOutputter::new());
if let &Addr::Con(h) = &ignore_ops {
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
printer.ignore_ops = name.as_str() == "true";
} else {
unreachable!()
@@ -470,7 +440,7 @@ impl MachineState {
}
if let &Addr::Con(h) = &numbervars {
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
printer.numbervars = name.as_str() == "true";
} else {
unreachable!()
@@ -478,7 +448,7 @@ impl MachineState {
}
if let &Addr::Con(h) = &quoted {
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
printer.quoted = name.as_str() == "true";
} else {
unreachable!()
@@ -514,9 +484,7 @@ impl MachineState {
for addr in addrs {
match addr {
Addr::Str(s) => match &self.heap[s] {
&HeapCellValue::NamedStr(2, ref name, _)
if name.as_str() == "=" =>
{
&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);
@@ -540,11 +508,9 @@ impl MachineState {
var_names.insert(var, atom);
}
_ => {
}
_ => {}
},
_ => {
}
_ => {}
}
}
@@ -558,8 +524,7 @@ impl MachineState {
Ok(Some(printer))
}
pub(super)
fn throw_undefined_error(&mut self, name: ClauseName, arity: usize) -> MachineStub {
pub(super) fn throw_undefined_error(&mut self, name: ClauseName, arity: usize) -> MachineStub {
let stub = MachineError::functor_stub(name.clone(), arity);
let h = self.heap.h();
let key = ExistenceError::Procedure(name, arity);
@@ -568,13 +533,11 @@ impl MachineState {
}
#[inline]
pub(crate)
fn heap_pstr_iter<'a>(&'a self, focus: Addr) -> HeapPStrIter<'a> {
pub(crate) fn heap_pstr_iter<'a>(&'a self, focus: Addr) -> HeapPStrIter<'a> {
HeapPStrIter::new(self, focus)
}
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();
@@ -594,55 +557,46 @@ impl MachineState {
}
}
}
_ => {
}
_ => {}
};
let h = self.heap.h();
return Err(
MachineError::type_error(h, ValidType::Character, addr)
);
return Err(MachineError::type_error(h, ValidType::Character, addr));
}
Ok(chars)
}
pub(super)
fn read_predicate_key(&self, name: Addr, arity: Addr) -> (ClauseName, usize) {
pub(super) fn read_predicate_key(&self, name: Addr, arity: Addr) -> (ClauseName, usize) {
let predicate_name = atom_from!(self, self.store(self.deref(name)));
let arity = self.store(self.deref(arity));
let arity =
match Number::try_from((arity, &self.heap)) {
Ok(Number::Integer(n)) if &*n >= &0 && &*n <= &MAX_ARITY =>
n.to_usize().unwrap(),
Ok(Number::Fixnum(n)) if n >= 0 && n <= MAX_ARITY as isize =>
usize::try_from(n).unwrap(),
_ =>
unreachable!()
};
let arity = match Number::try_from((arity, &self.heap)) {
Ok(Number::Integer(n)) if &*n >= &0 && &*n <= &MAX_ARITY => n.to_usize().unwrap(),
Ok(Number::Fixnum(n)) if n >= 0 && n <= MAX_ARITY as isize => {
usize::try_from(n).unwrap()
}
_ => unreachable!(),
};
(predicate_name, arity)
}
pub(super)
fn call_at_index(&mut self, arity: usize, p: LocalCodePtr) {
pub(super) fn call_at_index(&mut self, arity: usize, p: LocalCodePtr) {
self.cp.assign_if_local(self.p.clone() + 1);
self.num_of_args = arity;
self.b0 = self.b;
self.p = CodePtr::Local(p);
}
pub(super)
fn execute_at_index(&mut self, arity: usize, p: LocalCodePtr) {
pub(super) fn execute_at_index(&mut self, arity: usize, p: LocalCodePtr) {
self.num_of_args = arity;
self.b0 = self.b;
self.p = CodePtr::Local(p);
}
pub(super)
fn module_lookup(
pub(super) fn module_lookup(
&mut self,
indices: &IndexStore,
call_policy: &mut Box<dyn CallPolicy>,
@@ -687,10 +641,15 @@ pub(crate) type CallResult = Result<(), Vec<HeapCellValue>>;
pub(crate) trait CallPolicy: Any + fmt::Debug {
fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
let b = machine_st.b;
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
let n = machine_st
.stack
.index_or_frame(b)
.prelude
.univ_prelude
.num_cells;
for i in 1 .. n + 1 {
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
for i in 1..n + 1 {
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
}
machine_st.num_of_args = n;
@@ -706,17 +665,24 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
machine_st.trail.truncate(machine_st.tr);
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
machine_st
.heap
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
let attr_var_init_queue_b =
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
let attr_var_init_bindings_b =
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
let attr_var_init_queue_b = machine_st
.stack
.index_or_frame(b)
.prelude
.attr_var_init_queue_b;
let attr_var_init_bindings_b = machine_st
.stack
.index_or_frame(b)
.prelude
.attr_var_init_bindings_b;
machine_st.attr_var_init.backtrack(
attr_var_init_queue_b,
attr_var_init_bindings_b,
);
machine_st
.attr_var_init
.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
machine_st.hb = machine_st.heap.h();
machine_st.p += 1;
@@ -726,10 +692,15 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
let b = machine_st.b;
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
let n = machine_st
.stack
.index_or_frame(b)
.prelude
.univ_prelude
.num_cells;
for i in 1 .. n + 1 {
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
for i in 1..n + 1 {
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
}
machine_st.num_of_args = n;
@@ -745,14 +716,24 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
machine_st.trail.truncate(machine_st.tr);
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
machine_st
.heap
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
let attr_var_init_queue_b =
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
let attr_var_init_bindings_b =
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
let attr_var_init_queue_b = machine_st
.stack
.index_or_frame(b)
.prelude
.attr_var_init_queue_b;
let attr_var_init_bindings_b = machine_st
.stack
.index_or_frame(b)
.prelude
.attr_var_init_bindings_b;
machine_st.attr_var_init.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
machine_st
.attr_var_init
.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
machine_st.hb = machine_st.heap.h();
machine_st.p = CodePtr::Local(dir_entry!(machine_st.p.local().abs_loc() + offset));
@@ -762,10 +743,15 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
let b = machine_st.b;
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
let n = machine_st
.stack
.index_or_frame(b)
.prelude
.univ_prelude
.num_cells;
for i in 1 .. n + 1 {
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
for i in 1..n + 1 {
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
}
machine_st.num_of_args = n;
@@ -779,17 +765,24 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
machine_st.trail.truncate(machine_st.tr);
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
machine_st
.heap
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
let attr_var_init_queue_b =
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
let attr_var_init_bindings_b =
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
let attr_var_init_queue_b = machine_st
.stack
.index_or_frame(b)
.prelude
.attr_var_init_queue_b;
let attr_var_init_bindings_b = machine_st
.stack
.index_or_frame(b)
.prelude
.attr_var_init_bindings_b;
machine_st.attr_var_init.backtrack(
attr_var_init_queue_b,
attr_var_init_bindings_b,
);
machine_st
.attr_var_init
.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
machine_st.b = machine_st.stack.index_or_frame(b).prelude.b;
machine_st.stack.truncate(b);
@@ -802,10 +795,15 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult {
let b = machine_st.b;
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
let n = machine_st
.stack
.index_or_frame(b)
.prelude
.univ_prelude
.num_cells;
for i in 1 .. n + 1 {
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
for i in 1..n + 1 {
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
}
machine_st.num_of_args = n;
@@ -819,17 +817,24 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
machine_st.trail.truncate(machine_st.tr);
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
machine_st
.heap
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
let attr_var_init_queue_b =
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
let attr_var_init_bindings_b =
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
let attr_var_init_queue_b = machine_st
.stack
.index_or_frame(b)
.prelude
.attr_var_init_queue_b;
let attr_var_init_bindings_b = machine_st
.stack
.index_or_frame(b)
.prelude
.attr_var_init_bindings_b;
machine_st.attr_var_init.backtrack(
attr_var_init_queue_b,
attr_var_init_bindings_b,
);
machine_st
.attr_var_init
.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
machine_st.b = machine_st.stack.index_or_frame(b).prelude.b;
machine_st.stack.truncate(b);
@@ -928,13 +933,13 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
Addr::Con(h) if machine_st.heap.atom_at(h) => {
if let HeapCellValue::Atom(ref atom, _) = &machine_st.heap[h] {
match atom.as_str() {
">" | "<" | "=" => {
}
">" | "<" | "=" => {}
_ => {
let stub =
MachineError::functor_stub(clause_name!("compare"), 3);
let err = MachineError::domain_error(DomainErrorType::Order, a1);
let err =
MachineError::domain_error(DomainErrorType::Order, a1);
return Err(machine_st.error_form(err, stub));
}
}
@@ -948,8 +953,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
let err = MachineError::type_error(h, ValidType::Atom, a1);
return Err(machine_st.error_form(err, stub));
}
_ => {
}
_ => {}
}
let atom = match machine_st.compare_term_test(&a2, &a3) {
@@ -998,9 +1002,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
let addr = machine_st[temp_v!(1)];
let eof = clause_name!("end_of_file".to_string(), machine_st.atom_tbl);
let atom = machine_st.heap.to_unifiable(
HeapCellValue::Atom(eof, None)
);
let atom = machine_st.heap.to_unifiable(HeapCellValue::Atom(eof, None));
machine_st.unify(addr, atom);
}
@@ -1056,7 +1058,9 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
let mut list = machine_st.try_from_list(temp_v!(1), stub)?;
list.sort_unstable_by(|a1, a2| {
machine_st.compare_term_test(a1, a2).unwrap_or(Ordering::Less)
machine_st
.compare_term_test(a1, a2)
.unwrap_or(Ordering::Less)
});
machine_st.term_dedup(&mut list);
@@ -1081,7 +1085,9 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
}
key_pairs.sort_by(|a1, a2| {
machine_st.compare_term_test(&a1.0, &a2.0).unwrap_or(Ordering::Less)
machine_st
.compare_term_test(&a1.0, &a2.0)
.unwrap_or(Ordering::Less)
});
let key_pairs = key_pairs.into_iter().map(|kp| kp.1);
@@ -1155,11 +1161,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
let stub = MachineError::functor_stub(clause_name!("call"), arity + 1);
return Err(machine_st.error_form(
MachineError::type_error(
machine_st.heap.h(),
ValidType::Callable,
name
),
MachineError::type_error(machine_st.heap.h(), ValidType::Callable, name),
stub,
));
}
@@ -1200,7 +1202,8 @@ impl CallPolicy for CWILCallPolicy {
arity: usize,
idx: &CodeIndex,
) -> CallResult {
self.prev_policy.context_call(machine_st, name, arity, idx)?;//, indices)?;
self.prev_policy
.context_call(machine_st, name, arity, idx)?; //, indices)?;
self.increment(machine_st)
}
@@ -1239,7 +1242,7 @@ impl CallPolicy for CWILCallPolicy {
code_dir,
op_dir,
current_input_stream,
current_output_stream
current_output_stream,
)?;
self.increment(machine_st)
@@ -1283,8 +1286,7 @@ pub(crate) struct CWILCallPolicy {
}
impl CWILCallPolicy {
pub(crate)
fn new_in_place(policy: &mut Box<dyn CallPolicy>) {
pub(crate) fn new_in_place(policy: &mut Box<dyn CallPolicy>) {
let mut prev_policy: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {});
mem::swap(&mut prev_policy, policy);
@@ -1319,8 +1321,7 @@ impl CWILCallPolicy {
Ok(())
}
pub(crate)
fn add_limit(&mut self, mut limit: Integer, b: usize) -> &Integer {
pub(crate) fn add_limit(&mut self, mut limit: Integer, b: usize) -> &Integer {
limit += &self.count;
match self.limits.last().cloned() {
@@ -1331,8 +1332,7 @@ impl CWILCallPolicy {
&self.count
}
pub(crate)
fn remove_limit(&mut self, b: usize) -> &Integer {
pub(crate) fn remove_limit(&mut self, b: usize) -> &Integer {
if let Some((_, bp)) = self.limits.last().cloned() {
if bp == b {
self.limits.pop();
@@ -1342,13 +1342,11 @@ impl CWILCallPolicy {
&self.count
}
pub(crate)
fn is_empty(&self) -> bool {
pub(crate) fn is_empty(&self) -> bool {
self.limits.is_empty()
}
pub(crate)
fn into_inner(&mut self) -> Box<dyn CallPolicy> {
pub(crate) fn into_inner(&mut self) -> Box<dyn CallPolicy> {
let mut new_inner: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {});
mem::swap(&mut self.prev_policy, &mut new_inner);
new_inner

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,8 @@
use crate::prolog_parser_rebis::ast::*;
use crate::prolog_parser_rebis::tabled_rc::*;
use crate::prolog_parser_rebis::{clause_name, temp_v};
use crate::lazy_static::lazy_static;
use crate::clause_types::*;
use crate::forms::*;
@@ -34,8 +37,8 @@ mod machine_state_impl;
mod system_calls;
//use crate::machine::attributed_variables::*;
use crate::machine::compile::*;
use crate::machine::code_repo::*;
use crate::machine::compile::*;
// use crate::machine::loader::*;
use crate::machine::machine_errors::*;
use crate::machine::machine_indices::*;
@@ -45,6 +48,7 @@ use crate::machine::streams::*;
use crate::indexmap::IndexMap;
//use std::convert::TryFrom;
use prolog_parser_rebis::ast::ClauseName;
use std::fs::File;
use std::mem;
use std::path::PathBuf;
@@ -162,18 +166,13 @@ impl Machine {
}
fn load_file(&mut self, path: String, stream: Stream) {
self.machine_st[temp_v!(1)] = Addr::Stream(
self.machine_st.heap.push(HeapCellValue::Stream(
stream,
))
);
self.machine_st[temp_v!(1)] =
Addr::Stream(self.machine_st.heap.push(HeapCellValue::Stream(stream)));
self.machine_st[temp_v!(2)] = Addr::Con(
self.machine_st.heap.push(HeapCellValue::Atom(
clause_name!(path, self.machine_st.atom_tbl),
None,
))
);
self.machine_st[temp_v!(2)] = Addr::Con(self.machine_st.heap.push(HeapCellValue::Atom(
clause_name!(path, self.machine_st.atom_tbl),
None,
)));
self.run_module_predicate(clause_name!("loader"), (clause_name!("file_load"), 2));
}
@@ -206,11 +205,9 @@ impl Machine {
bootstrapping_compile(
Stream::from(include_str!("attributed_variables.pl")),
self,
ListingSource::from_file_and_path(
clause_name!("attributed_variables"),
path_buf,
),
).unwrap();
ListingSource::from_file_and_path(clause_name!("attributed_variables"), path_buf),
)
.unwrap();
let mut path_buf = current_dir();
path_buf.push("machine/project_attributes.pl");
@@ -218,11 +215,9 @@ impl Machine {
bootstrapping_compile(
Stream::from(include_str!("project_attributes.pl")),
self,
ListingSource::from_file_and_path(
clause_name!("project_attributes"),
path_buf,
),
).unwrap();
ListingSource::from_file_and_path(clause_name!("project_attributes"), path_buf),
)
.unwrap();
if let Some(module) = self.indices.modules.get(&clause_name!("$atts")) {
if let Some(code_index) = module.code_dir.get(&(clause_name!("driver"), 2)) {
@@ -255,12 +250,13 @@ impl Machine {
fn configure_modules(&mut self) {
fn update_call_n_indices(loader: &Module, target_module: &mut Module) {
for arity in 1 .. 66 {
for arity in 1..66 {
let key = (clause_name!("call"), arity);
match loader.code_dir.get(&key) {
Some(src_code_index) => {
let target_code_index = target_module.code_dir
let target_code_index = target_module
.code_dir
.entry(key.clone())
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined));
@@ -289,10 +285,11 @@ impl Machine {
builtins.module_decl.exports.push(export.clone());
}
for arity in 10 .. 66 {
builtins.module_decl.exports.push(
ModuleExport::PredicateKey((clause_name!("call"), arity)),
);
for arity in 10..66 {
builtins
.module_decl
.exports
.push(ModuleExport::PredicateKey((clause_name!("call"), arity)));
}
}
@@ -306,8 +303,7 @@ impl Machine {
}
}
pub fn new(user_input: Stream, user_output: Stream) -> Self
{
pub fn new(user_input: Stream, user_output: Stream) -> Self {
use crate::ref_thread_local::RefThreadLocal;
let mut wam = Machine {
@@ -333,16 +329,15 @@ impl Machine {
clause_name!("ops_and_meta_predicates.pl"),
lib_path.clone(),
),
).unwrap();
)
.unwrap();
bootstrapping_compile(
Stream::from(LIBRARIES.borrow()["builtins"]),
&mut wam,
ListingSource::from_file_and_path(
clause_name!("builtins.pl"),
lib_path.clone(),
),
).unwrap();
ListingSource::from_file_and_path(clause_name!("builtins.pl"), lib_path.clone()),
)
.unwrap();
if let Some(builtins) = wam.indices.modules.get(&clause_name!("builtins")) {
load_module(
@@ -361,11 +356,9 @@ impl Machine {
bootstrapping_compile(
Stream::from(include_str!("../loader.pl")),
&mut wam,
ListingSource::from_file_and_path(
clause_name!("loader.pl"),
lib_path.clone(),
),
).unwrap();
ListingSource::from_file_and_path(clause_name!("loader.pl"), lib_path.clone()),
)
.unwrap();
wam.configure_modules();
@@ -391,25 +384,19 @@ impl Machine {
pub fn configure_streams(&mut self) {
self.user_input.options.alias = Some(clause_name!("user_input"));
self.indices.stream_aliases.insert(
clause_name!("user_input"),
self.user_input.clone(),
);
self.indices
.stream_aliases
.insert(clause_name!("user_input"), self.user_input.clone());
self.indices.streams.insert(
self.user_input.clone()
);
self.indices.streams.insert(self.user_input.clone());
self.user_output.options.alias = Some(clause_name!("user_output"));
self.indices.stream_aliases.insert(
clause_name!("user_output"),
self.user_output.clone(),
);
self.indices
.stream_aliases
.insert(clause_name!("user_output"), self.user_output.clone());
self.indices.streams.insert(
self.user_output.clone()
);
self.indices.streams.insert(self.user_output.clone());
}
fn throw_session_error(&mut self, err: SessionError, key: PredicateKey) {
@@ -508,8 +495,7 @@ impl Machine {
self.machine_st.p = CodePtr::Local(p);
}
pub(super)
fn run_query(&mut self) {
pub(super) fn run_query(&mut self) {
while !self.machine_st.p.is_halt() {
self.machine_st.query_stepper(
&mut self.indices,
@@ -546,26 +532,22 @@ impl MachineState {
user_output: &mut Stream,
) {
match instr {
&Line::Arithmetic(ref arith_instr) => {
self.execute_arith_instr(arith_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,
user_input,
user_output,
control_instr,
)
}
&Line::Control(ref control_instr) => self.execute_ctrl_instr(
indices,
code_repo,
&mut policies.call_policy,
&mut policies.cut_policy,
user_input,
user_output,
control_instr,
),
&Line::Fact(ref fact_instr) => {
self.execute_fact_instr(&fact_instr);
self.p += 1;
@@ -617,15 +599,13 @@ impl MachineState {
fn check_machine_index(&mut self, code_repo: &CodeRepo) -> bool {
match self.p {
CodePtr::Local(LocalCodePtr::DirEntry(p)) |
CodePtr::Local(LocalCodePtr::IndexingBuf(p, ..))
if p < code_repo.code.len() => {
}
CodePtr::Local(LocalCodePtr::DirEntry(p))
| CodePtr::Local(LocalCodePtr::IndexingBuf(p, ..))
if p < code_repo.code.len() => {}
CodePtr::Local(LocalCodePtr::Halt) | CodePtr::REPL(..) => {
return false;
}
_ => {
}
_ => {}
}
true
@@ -689,13 +669,7 @@ impl MachineState {
user_output: &mut Stream,
) {
loop {
self.execute_instr(
indices,
policies,
code_repo,
user_input,
user_output,
);
self.execute_instr(indices, policies, code_repo, user_input, user_output);
if self.fail {
self.backtrack();

View File

@@ -1,11 +1,12 @@
use crate::prolog_parser_rebis::ast::*;
use crate::prolog_parser_rebis::tabled_rc::*;
use crate::prolog_parser_rebis::{atom, clause_name, rc_atom};
use crate::forms::*;
use crate::iterators::*;
use crate::machine::*;
use crate::machine::load_state::*;
use crate::machine::machine_errors::*;
use crate::machine::*;
use crate::indexmap::IndexSet;
@@ -85,27 +86,24 @@ fn setup_op_decl(
to_op_decl(prec, spec.as_str(), name)
}
fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, CompilationError>
{
fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, CompilationError> {
match term {
Term::Clause(_, ref slash, ref mut terms, Some(_))
if (slash.as_str() == "/" || slash.as_str() == "//") && terms.len() == 2 =>
{
let arity = *terms.pop().unwrap();
let name = *terms.pop().unwrap();
let name = *terms.pop().unwrap();
let arity = arity
.to_constant()
.and_then(|c| {
match c {
Constant::Integer(n) => n.to_usize(),
Constant::Fixnum(n) => usize::try_from(n).ok(),
_ => None
}
.and_then(|c| match c {
Constant::Integer(n) => n.to_usize(),
Constant::Fixnum(n) => usize::try_from(n).ok(),
_ => None,
})
.ok_or(CompilationError::InvalidModuleExport)?;
let name = name
let name = name
.to_constant()
.and_then(|c| c.to_atom())
.ok_or(CompilationError::InvalidModuleExport)?;
@@ -116,9 +114,7 @@ fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, Compilatio
Ok((name, arity + 2))
}
}
_ => {
Err(CompilationError::InvalidModuleExport)
}
_ => Err(CompilationError::InvalidModuleExport),
}
}
@@ -155,10 +151,7 @@ fn setup_module_export(
.or_else(|_| {
if let Term::Clause(_, name, terms, _) = term {
if terms.len() == 3 && name.as_str() == "op" {
Ok(ModuleExport::OpDecl(setup_op_decl(
terms,
atom_tbl
)?))
Ok(ModuleExport::OpDecl(setup_op_decl(terms, atom_tbl)?))
} else {
Err(CompilationError::InvalidModuleDecl)
}
@@ -168,8 +161,7 @@ fn setup_module_export(
})
}
pub(super)
fn setup_module_export_list(
pub(super) fn setup_module_export_list(
mut export_list: Term,
atom_tbl: TabledData<Atom>,
) -> Result<Vec<ModuleExport>, CompilationError> {
@@ -218,8 +210,7 @@ fn setup_use_module_decl(mut terms: Vec<Box<Term>>) -> Result<ModuleSource, Comp
.map(|c| ModuleSource::Library(c))
.ok_or(CompilationError::InvalidUseModuleDecl)
}
Term::Constant(_, Constant::Atom(ref name, _)) =>
Ok(ModuleSource::File(name.clone())),
Term::Constant(_, Constant::Atom(ref name, _)) => Ok(ModuleSource::File(name.clone())),
_ => Err(CompilationError::InvalidUseModuleDecl),
}
}
@@ -271,12 +262,8 @@ fn setup_qualified_import(
.map(|c| ModuleSource::Library(c))
.ok_or(CompilationError::InvalidUseModuleDecl)
}
Term::Constant(_, Constant::Atom(ref name, _)) => {
Ok(ModuleSource::File(name.clone()))
}
_ => {
Err(CompilationError::InvalidUseModuleDecl)
}
Term::Constant(_, Constant::Atom(ref name, _)) => Ok(ModuleSource::File(name.clone())),
_ => Err(CompilationError::InvalidUseModuleDecl),
}?;
let mut exports = IndexSet::new();
@@ -334,8 +321,7 @@ fn setup_qualified_import(
fn setup_meta_predicate<'a>(
mut terms: Vec<Box<Term>>,
load_state: &LoadState<'a>,
) -> Result<(ClauseName, ClauseName, Vec<MetaSpec>), CompilationError>
{
) -> Result<(ClauseName, ClauseName, Vec<MetaSpec>), CompilationError> {
fn get_name_and_meta_specs(
name: ClauseName,
terms: &mut [Box<Term>],
@@ -345,26 +331,23 @@ fn setup_meta_predicate<'a>(
for meta_spec in terms.into_iter() {
match &**meta_spec {
Term::Constant(_, Constant::Atom(meta_spec, _)) => {
let meta_spec =
match meta_spec.as_str() {
"+" => MetaSpec::Plus,
"-" => MetaSpec::Minus,
"?" => MetaSpec::Either,
_ => return Err(CompilationError::InvalidMetaPredicateDecl),
};
let meta_spec = match meta_spec.as_str() {
"+" => MetaSpec::Plus,
"-" => MetaSpec::Minus,
"?" => MetaSpec::Either,
_ => return Err(CompilationError::InvalidMetaPredicateDecl),
};
meta_specs.push(meta_spec);
}
Term::Constant(_, Constant::Fixnum(n)) => {
match usize::try_from(*n) {
Ok(n) if n <= MAX_ARITY => {
meta_specs.push(MetaSpec::RequiresExpansionWithArgument(n));
}
_ => {
return Err(CompilationError::InvalidMetaPredicateDecl);
}
Term::Constant(_, Constant::Fixnum(n)) => match usize::try_from(*n) {
Ok(n) if n <= MAX_ARITY => {
meta_specs.push(MetaSpec::RequiresExpansionWithArgument(n));
}
}
_ => {
return Err(CompilationError::InvalidMetaPredicateDecl);
}
},
_ => {
return Err(CompilationError::InvalidMetaPredicateDecl);
}
@@ -375,42 +358,35 @@ fn setup_meta_predicate<'a>(
}
match *terms.pop().unwrap() {
Term::Clause(_, name, mut terms, _)
if name.as_str() == ":" && terms.len() == 2 => {
let spec = *terms.pop().unwrap();
let module_name = *terms.pop().unwrap();
Term::Clause(_, name, mut terms, _) if name.as_str() == ":" && terms.len() == 2 => {
let spec = *terms.pop().unwrap();
let module_name = *terms.pop().unwrap();
match module_name {
Term::Constant(_, Constant::Atom(module_name, _)) => {
match spec {
Term::Clause(_, name, mut terms, _) => {
let (name, meta_specs) =
get_name_and_meta_specs(name, &mut terms)?;
match module_name {
Term::Constant(_, Constant::Atom(module_name, _)) => match spec {
Term::Clause(_, name, mut terms, _) => {
let (name, meta_specs) = get_name_and_meta_specs(name, &mut terms)?;
Ok((module_name, name, meta_specs))
}
_ => {
Err(CompilationError::InvalidMetaPredicateDecl)
}
}
Ok((module_name, name, meta_specs))
}
_ => {
Err(CompilationError::InvalidMetaPredicateDecl)
}
}
_ => Err(CompilationError::InvalidMetaPredicateDecl),
},
_ => Err(CompilationError::InvalidMetaPredicateDecl),
}
}
Term::Clause(_, name, mut terms, _) => {
let (name, meta_specs) = get_name_and_meta_specs(name, &mut terms)?;
Ok((load_state.compilation_target.module_name(), name, meta_specs))
}
_ => {
Err(CompilationError::InvalidMetaPredicateDecl)
Ok((
load_state.compilation_target.module_name(),
name,
meta_specs,
))
}
_ => Err(CompilationError::InvalidMetaPredicateDecl),
}
}
fn merge_clauses(tls: &mut VecDeque<TopLevel>) -> Result<TopLevel, CompilationError>
{
fn merge_clauses(tls: &mut VecDeque<TopLevel>) -> Result<TopLevel, CompilationError> {
let mut clauses = vec![];
while let Some(tl) = tls.pop_front() {
@@ -432,9 +408,7 @@ fn merge_clauses(tls: &mut VecDeque<TopLevel>) -> Result<TopLevel, CompilationEr
let clause = PredicateClause::Rule(rule);
clauses.push(clause);
}
TopLevel::Predicate(predicate) => {
clauses.extend(predicate.into_iter())
}
TopLevel::Predicate(predicate) => clauses.extend(predicate.into_iter()),
_ => {
tls.push_front(tl);
break;
@@ -506,8 +480,8 @@ fn check_for_internal_if_then(terms: &mut Vec<Term>) {
conq_terms.push_front(Term::Constant(
Cell::default(),
Constant::Atom(clause_name!("blocked_!"), None))
);
Constant::Atom(clause_name!("blocked_!"), None),
));
while let Some(term) = pre_cut_terms.pop_back() {
conq_terms.push_front(term);
@@ -531,38 +505,29 @@ fn setup_declaration<'a>(
let atom_tbl = load_state.wam.machine_st.atom_tbl.clone();
match term {
Term::Clause(_, name, mut terms, _) =>
match (name.as_str(), terms.len()) {
("dynamic", 1) => {
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
Ok(Declaration::Dynamic(name, arity))
}
("module", 2) =>
Ok(Declaration::Module(setup_module_decl(terms, atom_tbl)?)),
("op", 3) =>
Ok(Declaration::Op(setup_op_decl(terms, atom_tbl)?)),
("non_counted_backtracking", 1) => {
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
Ok(Declaration::NonCountedBacktracking(name, arity))
}
("use_module", 1) => {
Ok(Declaration::UseModule(setup_use_module_decl(terms)?))
}
("use_module", 2) => {
let (name, exports) = setup_qualified_import(terms, atom_tbl)?;
Ok(Declaration::UseQualifiedModule(name, exports))
}
("meta_predicate", 1) => {
let (module_name, name, meta_specs) = setup_meta_predicate(terms, load_state)?;
Ok(Declaration::MetaPredicate(module_name, name, meta_specs))
}
_ => {
Err(CompilationError::InconsistentEntry)
}
},
_ => {
Err(CompilationError::InconsistentEntry)
}
Term::Clause(_, name, mut terms, _) => match (name.as_str(), terms.len()) {
("dynamic", 1) => {
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
Ok(Declaration::Dynamic(name, arity))
}
("module", 2) => Ok(Declaration::Module(setup_module_decl(terms, atom_tbl)?)),
("op", 3) => Ok(Declaration::Op(setup_op_decl(terms, atom_tbl)?)),
("non_counted_backtracking", 1) => {
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
Ok(Declaration::NonCountedBacktracking(name, arity))
}
("use_module", 1) => Ok(Declaration::UseModule(setup_use_module_decl(terms)?)),
("use_module", 2) => {
let (name, exports) = setup_qualified_import(terms, atom_tbl)?;
Ok(Declaration::UseQualifiedModule(name, exports))
}
("meta_predicate", 1) => {
let (module_name, name, meta_specs) = setup_meta_predicate(terms, load_state)?;
Ok(Declaration::MetaPredicate(module_name, name, meta_specs))
}
_ => Err(CompilationError::InconsistentEntry),
},
_ => Err(CompilationError::InconsistentEntry),
}
}
@@ -596,8 +561,7 @@ pub(crate) struct Preprocessor {
}
impl Preprocessor {
pub(super)
fn new(flags: MachineFlags) -> Self {
pub(super) fn new(flags: MachineFlags) -> Self {
Preprocessor {
flags,
queue: VecDeque::new(),
@@ -606,12 +570,8 @@ impl Preprocessor {
fn setup_fact(&mut self, term: Term) -> Result<Term, CompilationError> {
match term {
Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) => {
Ok(term)
}
_ => {
Err(CompilationError::InadmissibleFact)
}
Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) => Ok(term),
_ => Err(CompilationError::InadmissibleFact),
}
}
@@ -712,109 +672,97 @@ impl Preprocessor {
Ok(clause_to_query_term(load_state, name, vec![], fixity))
}
}
Term::Constant(_, Constant::Char('!')) => {
Ok(QueryTerm::BlockedCut)
}
Term::Constant(_, Constant::Char('!')) => Ok(QueryTerm::BlockedCut),
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);
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);
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();
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);
let (stub, clauses) = self.fabricate_if_then(prec, conq);
self.queue.push_back(clauses);
Ok(QueryTerm::Jump(stub))
}
("\\+", 1) => {
terms.push(Box::new(Term::Constant(
Cell::default(),
Constant::Atom(clause_name!("$fail"), None)
)));
Ok(QueryTerm::Jump(stub))
}
("\\+", 1) => {
terms.push(Box::new(Term::Constant(
Cell::default(),
Constant::Atom(clause_name!("$fail"), None),
)));
let conq = Term::Constant(
Cell::default(),
Constant::Atom(clause_name!("true"), None)
);
let conq =
Term::Constant(Cell::default(), Constant::Atom(clause_name!("true"), None));
let prec = Term::Clause(Cell::default(), clause_name!("->"), terms, None);
let terms = vec![Box::new(prec), Box::new(conq)];
let prec = Term::Clause(Cell::default(), clause_name!("->"), terms, None);
let terms = vec![Box::new(prec), Box::new(conq)];
let term = Term::Clause(Cell::default(), clause_name!(";"), terms, None);
let (stub, clauses) = self.fabricate_disjunct(term);
let term = Term::Clause(Cell::default(), clause_name!(";"), terms, None);
let (stub, clauses) = self.fabricate_disjunct(term);
debug_assert!(clauses.len() > 0);
self.queue.push_back(clauses);
debug_assert!(clauses.len() > 0);
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(CompilationError::InadmissibleQueryTerm)
}
}
(":", 2) => {
let predicate_name = *terms.pop().unwrap();
let module_name = *terms.pop().unwrap();
match (module_name, predicate_name) {
(Term::Constant(_, Constant::Atom(module_name, _)),
Term::Constant(_, Constant::Atom(predicate_name, fixity))) => {
Ok(qualified_clause_to_query_term(
load_state,
module_name,
predicate_name,
vec![],
fixity,
))
}
(Term::Constant(_, Constant::Atom(module_name, _)),
Term::Clause(_, name, terms, fixity)) => {
Ok(qualified_clause_to_query_term(
load_state,
module_name,
name,
terms,
fixity,
))
}
(module_name, predicate_name) => {
terms.push(Box::new(module_name));
terms.push(Box::new(predicate_name));
Ok(clause_to_query_term(load_state, name, terms, fixity))
}
}
}
_ => {
Ok(clause_to_query_term(load_state, name, terms, fixity))
Ok(QueryTerm::Jump(stub))
}
("$get_level", 1) => {
if let Term::Var(_, ref var) = *terms[0] {
Ok(QueryTerm::GetLevelAndUnify(Cell::default(), var.clone()))
} else {
Err(CompilationError::InadmissibleQueryTerm)
}
}
}
Term::Var(..) => {
Ok(QueryTerm::Clause(
Cell::default(),
ClauseType::CallN,
vec![Box::new(term)],
false,
))
}
_ => {
Err(CompilationError::InadmissibleQueryTerm)
}
(":", 2) => {
let predicate_name = *terms.pop().unwrap();
let module_name = *terms.pop().unwrap();
match (module_name, predicate_name) {
(
Term::Constant(_, Constant::Atom(module_name, _)),
Term::Constant(_, Constant::Atom(predicate_name, fixity)),
) => Ok(qualified_clause_to_query_term(
load_state,
module_name,
predicate_name,
vec![],
fixity,
)),
(
Term::Constant(_, Constant::Atom(module_name, _)),
Term::Clause(_, name, terms, fixity),
) => Ok(qualified_clause_to_query_term(
load_state,
module_name,
name,
terms,
fixity,
)),
(module_name, predicate_name) => {
terms.push(Box::new(module_name));
terms.push(Box::new(predicate_name));
Ok(clause_to_query_term(load_state, name, terms, fixity))
}
}
}
_ => Ok(clause_to_query_term(load_state, name, terms, fixity)),
},
Term::Var(..) => Ok(QueryTerm::Clause(
Cell::default(),
ClauseType::CallN,
vec![Box::new(term)],
false,
)),
_ => Err(CompilationError::InadmissibleQueryTerm),
}
}
@@ -835,9 +783,7 @@ impl Preprocessor {
self.to_query_term(load_state, Term::Clause(r, name, subterms, fixity))
}
}
_ => {
self.to_query_term(load_state, term)
}
_ => self.to_query_term(load_state, term),
}
}
@@ -884,30 +830,23 @@ impl Preprocessor {
mut terms: Vec<Box<Term>>,
cut_context: CutContext,
) -> Result<Rule, CompilationError> {
let post_head_terms: Vec<_> = terms.drain(1 ..).collect();
let post_head_terms: Vec<_> = terms.drain(1..).collect();
let mut query_terms =
self.setup_query(load_state, post_head_terms, cut_context)?;
let mut query_terms = self.setup_query(load_state, post_head_terms, cut_context)?;
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(CompilationError::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(CompilationError::InvalidRuleHead),
}
}
@@ -917,11 +856,14 @@ impl Preprocessor {
terms: Vec<Box<Term>>,
cut_context: CutContext,
) -> Result<TopLevel, CompilationError> {
Ok(TopLevel::Query(self.setup_query(load_state, terms, cut_context)?))
Ok(TopLevel::Query(self.setup_query(
load_state,
terms,
cut_context,
)?))
}
pub(super)
fn try_term_to_tl<'a>(
pub(super) fn try_term_to_tl<'a>(
&mut self,
load_state: &mut LoadState<'a>,
term: Term,
@@ -944,9 +886,7 @@ impl Preprocessor {
Ok(TopLevel::Fact(self.setup_fact(term)?))
}
}
term => {
Ok(TopLevel::Fact(self.setup_fact(term)?))
}
term => Ok(TopLevel::Fact(self.setup_fact(term)?)),
}
}
@@ -965,21 +905,18 @@ impl Preprocessor {
Ok(results)
}
pub(super)
fn parse_queue<'a>(
pub(super) fn parse_queue<'a>(
&mut self,
load_state: &mut LoadState<'a>,
) -> Result<VecDeque<TopLevel>, CompilationError> {
let mut queue = VecDeque::new();
while let Some(terms) = self.queue.pop_front() {
let clauses = merge_clauses(
&mut self.try_terms_to_tls(
load_state,
terms,
CutContext::HasCutVariable,
)?
)?;
let clauses = merge_clauses(&mut self.try_terms_to_tls(
load_state,
terms,
CutContext::HasCutVariable,
)?)?;
queue.push_back(clauses);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff