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:
@@ -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() {
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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) = "ed {
|
||||
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
@@ -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();
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user