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:
8
build.rs
8
build.rs
@@ -15,15 +15,13 @@ fn find_prolog_files(libraries: &mut File, prefix: &str, current_dir: &Path) {
|
|||||||
for entry in entries.filter_map(Result::ok).map(|e| e.path()) {
|
for entry in entries.filter_map(Result::ok).map(|e| e.path()) {
|
||||||
if entry.is_dir() {
|
if entry.is_dir() {
|
||||||
if let Some(file_name) = entry.file_name() {
|
if let Some(file_name) = entry.file_name() {
|
||||||
let new_prefix =
|
let new_prefix = prefix.to_owned() + file_name.to_str().unwrap() + "/";
|
||||||
prefix.to_owned() + file_name.to_str().unwrap() + "/";
|
|
||||||
find_prolog_files(libraries, &new_prefix, &entry);
|
find_prolog_files(libraries, &new_prefix, &entry);
|
||||||
}
|
}
|
||||||
} else if entry.is_file() {
|
} else if entry.is_file() {
|
||||||
let ext = std::ffi::OsStr::new("pl");
|
let ext = std::ffi::OsStr::new("pl");
|
||||||
if entry.extension() == Some(ext) {
|
if entry.extension() == Some(ext) {
|
||||||
let contain =
|
let contain = String::from_utf8(fs::read(&entry).unwrap()).unwrap();
|
||||||
String::from_utf8(fs::read(&entry).unwrap()).unwrap();
|
|
||||||
let name = entry.file_stem().unwrap().to_str().unwrap();
|
let name = entry.file_stem().unwrap().to_str().unwrap();
|
||||||
|
|
||||||
let line = format!(
|
let line = format!(
|
||||||
@@ -47,7 +45,7 @@ fn main() {
|
|||||||
|
|
||||||
libraries
|
libraries
|
||||||
.write_all(
|
.write_all(
|
||||||
b"ref_thread_local! {
|
b"ref_thread_local::ref_thread_local! {
|
||||||
pub static managed LIBRARIES: IndexMap<&'static str, &'static str> = {
|
pub static managed LIBRARIES: IndexMap<&'static str, &'static str> = {
|
||||||
let mut m = IndexMap::new();\n",
|
let mut m = IndexMap::new();\n",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use crate::prolog_parser_rebis::ast::*;
|
||||||
|
use crate::prolog_parser_rebis::temp_v;
|
||||||
|
|
||||||
use crate::fixtures::*;
|
use crate::fixtures::*;
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
@@ -14,8 +15,13 @@ pub trait Allocator<'a> {
|
|||||||
fn mark_anon_var<Target>(&mut self, _: Level, _: GenContext, _: &mut Vec<Target>)
|
fn mark_anon_var<Target>(&mut self, _: Level, _: GenContext, _: &mut Vec<Target>)
|
||||||
where
|
where
|
||||||
Target: CompilationTarget<'a>;
|
Target: CompilationTarget<'a>;
|
||||||
fn mark_non_var<Target>(&mut self, _: Level, _: GenContext, _: &'a Cell<RegType>, _: &mut Vec<Target>)
|
fn mark_non_var<Target>(
|
||||||
where
|
&mut self,
|
||||||
|
_: Level,
|
||||||
|
_: GenContext,
|
||||||
|
_: &'a Cell<RegType>,
|
||||||
|
_: &mut Vec<Target>,
|
||||||
|
) where
|
||||||
Target: CompilationTarget<'a>;
|
Target: CompilationTarget<'a>;
|
||||||
fn mark_reserved_var<Target>(
|
fn mark_reserved_var<Target>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -28,8 +34,14 @@ pub trait Allocator<'a> {
|
|||||||
_: bool,
|
_: bool,
|
||||||
) where
|
) where
|
||||||
Target: CompilationTarget<'a>;
|
Target: CompilationTarget<'a>;
|
||||||
fn mark_var<Target>(&mut self, _: Rc<Var>, _: Level, _: &'a Cell<VarReg>, _: GenContext, _: &mut Vec<Target>)
|
fn mark_var<Target>(
|
||||||
where
|
&mut self,
|
||||||
|
_: Rc<Var>,
|
||||||
|
_: Level,
|
||||||
|
_: &'a Cell<VarReg>,
|
||||||
|
_: GenContext,
|
||||||
|
_: &mut Vec<Target>,
|
||||||
|
) where
|
||||||
Target: CompilationTarget<'a>;
|
Target: CompilationTarget<'a>;
|
||||||
|
|
||||||
fn reset(&mut self);
|
fn reset(&mut self);
|
||||||
@@ -47,7 +59,7 @@ pub trait Allocator<'a> {
|
|||||||
fn drain_var_data(
|
fn drain_var_data(
|
||||||
&mut self,
|
&mut self,
|
||||||
vs: VariableFixtures<'a>,
|
vs: VariableFixtures<'a>,
|
||||||
num_of_chunks: usize
|
num_of_chunks: usize,
|
||||||
) -> VariableFixtures<'a> {
|
) -> VariableFixtures<'a> {
|
||||||
let mut perm_vs = VariableFixtures::new();
|
let mut perm_vs = VariableFixtures::new();
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use crate::prolog_parser_rebis::ast::*;
|
||||||
|
use crate::prolog_parser_rebis::{atom, clause_name};
|
||||||
|
|
||||||
use crate::clause_types::*;
|
use crate::clause_types::*;
|
||||||
use crate::fixtures::*;
|
use crate::fixtures::*;
|
||||||
@@ -267,9 +268,7 @@ impl<'a> ArithmeticEvaluator<'a> {
|
|||||||
|
|
||||||
fn push_constant(&mut self, c: &Constant) -> Result<(), ArithmeticError> {
|
fn push_constant(&mut self, c: &Constant) -> Result<(), ArithmeticError> {
|
||||||
match c {
|
match c {
|
||||||
&Constant::Fixnum(n) => self
|
&Constant::Fixnum(n) => self.interm.push(ArithmeticTerm::Number(Number::Fixnum(n))),
|
||||||
.interm
|
|
||||||
.push(ArithmeticTerm::Number(Number::Fixnum(n))),
|
|
||||||
&Constant::Integer(ref n) => self
|
&Constant::Integer(ref n) => self
|
||||||
.interm
|
.interm
|
||||||
.push(ArithmeticTerm::Number(Number::Integer(n.clone()))),
|
.push(ArithmeticTerm::Number(Number::Integer(n.clone()))),
|
||||||
@@ -326,17 +325,11 @@ impl<'a> ArithmeticEvaluator<'a> {
|
|||||||
// integer division rounding function -- 9.1.3.1.
|
// integer division rounding function -- 9.1.3.1.
|
||||||
pub fn rnd_i<'a>(n: &'a Number) -> RefOrOwned<'a, Number> {
|
pub fn rnd_i<'a>(n: &'a Number) -> RefOrOwned<'a, Number> {
|
||||||
match n {
|
match n {
|
||||||
&Number::Integer(_) => {
|
&Number::Integer(_) => RefOrOwned::Borrowed(n),
|
||||||
RefOrOwned::Borrowed(n)
|
&Number::Float(OrderedFloat(f)) => RefOrOwned::Owned(Number::from(
|
||||||
}
|
Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0)),
|
||||||
&Number::Float(OrderedFloat(f)) => {
|
)),
|
||||||
RefOrOwned::Owned(Number::from(
|
&Number::Fixnum(n) => RefOrOwned::Owned(Number::from(n)),
|
||||||
Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0))
|
|
||||||
))
|
|
||||||
}
|
|
||||||
&Number::Fixnum(n) => {
|
|
||||||
RefOrOwned::Owned(Number::from(n))
|
|
||||||
}
|
|
||||||
&Number::Rational(ref r) => {
|
&Number::Rational(ref r) => {
|
||||||
let r_ref = r.fract_floor_ref();
|
let r_ref = r.fract_floor_ref();
|
||||||
let (mut fract, mut floor) = (Rational::new(), Integer::new());
|
let (mut fract, mut floor) = (Rational::new(), Integer::new());
|
||||||
@@ -432,16 +425,16 @@ impl Add<Number> for Number {
|
|||||||
Number::from(Integer::from(n1) + Integer::from(n2))
|
Number::from(Integer::from(n1) + Integer::from(n2))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Integer(n2)) |
|
(Number::Fixnum(n1), Number::Integer(n2))
|
||||||
(Number::Integer(n2), Number::Fixnum(n1)) => {
|
| (Number::Integer(n2), Number::Fixnum(n1)) => {
|
||||||
Ok(Number::from(Integer::from(n1) + &*n2))
|
Ok(Number::from(Integer::from(n1) + &*n2))
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Rational(n2)) |
|
(Number::Fixnum(n1), Number::Rational(n2))
|
||||||
(Number::Rational(n2), Number::Fixnum(n1)) => {
|
| (Number::Rational(n2), Number::Fixnum(n1)) => {
|
||||||
Ok(Number::from(Rational::from(n1) + &*n2))
|
Ok(Number::from(Rational::from(n1) + &*n2))
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) |
|
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2)))
|
||||||
(Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
|
| (Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
|
||||||
Ok(Number::Float(add_f(float_fn_to_f(n1)?, n2)?))
|
Ok(Number::Float(add_f(float_fn_to_f(n1)?, n2)?))
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||||
@@ -474,12 +467,13 @@ impl Neg for Number {
|
|||||||
|
|
||||||
fn neg(self) -> Self::Output {
|
fn neg(self) -> Self::Output {
|
||||||
match self {
|
match self {
|
||||||
Number::Fixnum(n) =>
|
Number::Fixnum(n) => {
|
||||||
if let Some(n) = n.checked_neg() {
|
if let Some(n) = n.checked_neg() {
|
||||||
Number::Fixnum(n)
|
Number::Fixnum(n)
|
||||||
} else {
|
} else {
|
||||||
Number::from(-Integer::from(n))
|
Number::from(-Integer::from(n))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Number::Integer(n) => Number::Integer(Rc::new(-Integer::from(&*n))),
|
Number::Integer(n) => Number::Integer(Rc::new(-Integer::from(&*n))),
|
||||||
Number::Float(OrderedFloat(f)) => Number::Float(OrderedFloat(-f)),
|
Number::Float(OrderedFloat(f)) => Number::Float(OrderedFloat(-f)),
|
||||||
Number::Rational(r) => Number::Rational(Rc::new(-Rational::from(&*r))),
|
Number::Rational(r) => Number::Rational(Rc::new(-Rational::from(&*r))),
|
||||||
@@ -507,16 +501,16 @@ impl Mul<Number> for Number {
|
|||||||
Number::from(Integer::from(n1) * Integer::from(n2))
|
Number::from(Integer::from(n1) * Integer::from(n2))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Integer(n2)) |
|
(Number::Fixnum(n1), Number::Integer(n2))
|
||||||
(Number::Integer(n2), Number::Fixnum(n1)) => {
|
| (Number::Integer(n2), Number::Fixnum(n1)) => {
|
||||||
Ok(Number::from(Integer::from(n1) * &*n2))
|
Ok(Number::from(Integer::from(n1) * &*n2))
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Rational(n2)) |
|
(Number::Fixnum(n1), Number::Rational(n2))
|
||||||
(Number::Rational(n2), Number::Fixnum(n1)) => {
|
| (Number::Rational(n2), Number::Fixnum(n1)) => {
|
||||||
Ok(Number::from(Rational::from(n1) * &*n2))
|
Ok(Number::from(Rational::from(n1) * &*n2))
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) |
|
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2)))
|
||||||
(Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
|
| (Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
|
||||||
Ok(Number::Float(mul_f(float_fn_to_f(n1)?, n2)?))
|
Ok(Number::Float(mul_f(float_fn_to_f(n1)?, n2)?))
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||||
@@ -549,72 +543,50 @@ impl Div<Number> for Number {
|
|||||||
|
|
||||||
fn div(self, rhs: Number) -> Self::Output {
|
fn div(self, rhs: Number) -> Self::Output {
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
(Number::Fixnum(n1), Number::Fixnum(n2)) => Ok(Number::Float(div_f(
|
||||||
Ok(Number::Float(div_f(
|
|
||||||
float_fn_to_f(n1)?,
|
float_fn_to_f(n1)?,
|
||||||
float_fn_to_f(n2)?,
|
float_fn_to_f(n2)?,
|
||||||
)?))
|
)?)),
|
||||||
}
|
(Number::Fixnum(n1), Number::Integer(n2)) => Ok(Number::Float(div_f(
|
||||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
|
||||||
Ok(Number::Float(div_f(
|
|
||||||
float_fn_to_f(n1)?,
|
float_fn_to_f(n1)?,
|
||||||
float_i_to_f(&n2)?,
|
float_i_to_f(&n2)?,
|
||||||
)?))
|
)?)),
|
||||||
}
|
(Number::Integer(n1), Number::Fixnum(n2)) => Ok(Number::Float(div_f(
|
||||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
|
||||||
Ok(Number::Float(div_f(
|
|
||||||
float_i_to_f(&n1)?,
|
float_i_to_f(&n1)?,
|
||||||
float_fn_to_f(n2)?,
|
float_fn_to_f(n2)?,
|
||||||
)?))
|
)?)),
|
||||||
}
|
(Number::Fixnum(n1), Number::Rational(n2)) => Ok(Number::Float(div_f(
|
||||||
(Number::Fixnum(n1), Number::Rational(n2)) => {
|
|
||||||
Ok(Number::Float(div_f(
|
|
||||||
float_fn_to_f(n1)?,
|
float_fn_to_f(n1)?,
|
||||||
float_r_to_f(&n2)?,
|
float_r_to_f(&n2)?,
|
||||||
)?))
|
)?)),
|
||||||
}
|
(Number::Rational(n1), Number::Fixnum(n2)) => Ok(Number::Float(div_f(
|
||||||
(Number::Rational(n1), Number::Fixnum(n2)) => {
|
|
||||||
Ok(Number::Float(div_f(
|
|
||||||
float_r_to_f(&n1)?,
|
float_r_to_f(&n1)?,
|
||||||
float_fn_to_f(n2)?,
|
float_fn_to_f(n2)?,
|
||||||
)?))
|
)?)),
|
||||||
}
|
|
||||||
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) => {
|
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) => {
|
||||||
Ok(Number::Float(div_f(
|
Ok(Number::Float(div_f(float_fn_to_f(n1)?, n2)?))
|
||||||
float_fn_to_f(n1)?,
|
|
||||||
n2,
|
|
||||||
)?))
|
|
||||||
}
|
}
|
||||||
(Number::Float(OrderedFloat(n1)), Number::Fixnum(n2)) => {
|
(Number::Float(OrderedFloat(n1)), Number::Fixnum(n2)) => {
|
||||||
Ok(Number::Float(div_f(
|
Ok(Number::Float(div_f(n1, float_fn_to_f(n2)?)?))
|
||||||
n1,
|
|
||||||
float_fn_to_f(n2)?,
|
|
||||||
)?))
|
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
(Number::Integer(n1), Number::Integer(n2)) => Ok(Number::Float(div_f(
|
||||||
Ok(Number::Float(div_f(
|
|
||||||
float_i_to_f(&n1)?,
|
float_i_to_f(&n1)?,
|
||||||
float_i_to_f(&n2)?,
|
float_i_to_f(&n2)?,
|
||||||
)?))
|
)?)),
|
||||||
}
|
|
||||||
(Number::Integer(n1), Number::Float(OrderedFloat(n2))) => {
|
(Number::Integer(n1), Number::Float(OrderedFloat(n2))) => {
|
||||||
Ok(Number::Float(div_f(float_i_to_f(&n1)?, n2)?))
|
Ok(Number::Float(div_f(float_i_to_f(&n1)?, n2)?))
|
||||||
}
|
}
|
||||||
(Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
|
(Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
|
||||||
Ok(Number::Float(div_f(n2, float_i_to_f(&n1)?)?))
|
Ok(Number::Float(div_f(n2, float_i_to_f(&n1)?)?))
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Rational(n2)) => {
|
(Number::Integer(n1), Number::Rational(n2)) => Ok(Number::Float(div_f(
|
||||||
Ok(Number::Float(div_f(
|
|
||||||
float_i_to_f(&n1)?,
|
float_i_to_f(&n1)?,
|
||||||
float_r_to_f(&n2)?,
|
float_r_to_f(&n2)?,
|
||||||
)?))
|
)?)),
|
||||||
}
|
(Number::Rational(n2), Number::Integer(n1)) => Ok(Number::Float(div_f(
|
||||||
(Number::Rational(n2), Number::Integer(n1)) => {
|
|
||||||
Ok(Number::Float(div_f(
|
|
||||||
float_r_to_f(&n2)?,
|
float_r_to_f(&n2)?,
|
||||||
float_i_to_f(&n1)?,
|
float_i_to_f(&n1)?,
|
||||||
)?))
|
)?)),
|
||||||
}
|
|
||||||
(Number::Rational(n1), Number::Float(OrderedFloat(n2))) => {
|
(Number::Rational(n1), Number::Float(OrderedFloat(n2))) => {
|
||||||
Ok(Number::Float(div_f(float_r_to_f(&n1)?, n2)?))
|
Ok(Number::Float(div_f(float_r_to_f(&n1)?, n2)?))
|
||||||
}
|
}
|
||||||
@@ -727,12 +699,8 @@ impl<'a> TryFrom<(Addr, &'a Heap)> for Number {
|
|||||||
|
|
||||||
fn try_from((addr, heap): (Addr, &'a Heap)) -> Result<Number, Self::Error> {
|
fn try_from((addr, heap): (Addr, &'a Heap)) -> Result<Number, Self::Error> {
|
||||||
match addr {
|
match addr {
|
||||||
Addr::Fixnum(n) => {
|
Addr::Fixnum(n) => Ok(Number::from(n)),
|
||||||
Ok(Number::from(n))
|
Addr::Float(n) => Ok(Number::Float(n)),
|
||||||
}
|
|
||||||
Addr::Float(n) => {
|
|
||||||
Ok(Number::Float(n))
|
|
||||||
}
|
|
||||||
Addr::Usize(n) => {
|
Addr::Usize(n) => {
|
||||||
if let Ok(n) = isize::try_from(n) {
|
if let Ok(n) = isize::try_from(n) {
|
||||||
Ok(Number::from(n))
|
Ok(Number::from(n))
|
||||||
@@ -740,12 +708,8 @@ impl<'a> TryFrom<(Addr, &'a Heap)> for Number {
|
|||||||
Ok(Number::from(Integer::from(n)))
|
Ok(Number::from(Integer::from(n)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Addr::Con(h) => {
|
Addr::Con(h) => Number::try_from(&heap[h]),
|
||||||
Number::try_from(&heap[h])
|
_ => Err(()),
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -755,14 +719,9 @@ impl<'a> TryFrom<&'a HeapCellValue> for Number {
|
|||||||
|
|
||||||
fn try_from(value: &'a HeapCellValue) -> Result<Number, Self::Error> {
|
fn try_from(value: &'a HeapCellValue) -> Result<Number, Self::Error> {
|
||||||
match value {
|
match value {
|
||||||
HeapCellValue::Addr(addr) => {
|
HeapCellValue::Addr(addr) => match addr {
|
||||||
match addr {
|
&Addr::Fixnum(n) => Ok(Number::from(n)),
|
||||||
&Addr::Fixnum(n) => {
|
&Addr::Float(n) => Ok(Number::Float(n)),
|
||||||
Ok(Number::from(n))
|
|
||||||
}
|
|
||||||
&Addr::Float(n) => {
|
|
||||||
Ok(Number::Float(n))
|
|
||||||
}
|
|
||||||
&Addr::Usize(n) => {
|
&Addr::Usize(n) => {
|
||||||
if let Ok(n) = isize::try_from(n) {
|
if let Ok(n) = isize::try_from(n) {
|
||||||
Ok(Number::from(n))
|
Ok(Number::from(n))
|
||||||
@@ -770,20 +729,11 @@ impl<'a> TryFrom<&'a HeapCellValue> for Number {
|
|||||||
Ok(Number::from(Integer::from(n)))
|
Ok(Number::from(Integer::from(n)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => Err(()),
|
||||||
Err(())
|
},
|
||||||
}
|
HeapCellValue::Integer(n) => Ok(Number::Integer(n.clone())),
|
||||||
}
|
HeapCellValue::Rational(n) => Ok(Number::Rational(n.clone())),
|
||||||
}
|
_ => Err(()),
|
||||||
HeapCellValue::Integer(n) => {
|
|
||||||
Ok(Number::Integer(n.clone()))
|
|
||||||
}
|
|
||||||
HeapCellValue::Rational(n) => {
|
|
||||||
Ok(Number::Rational(n.clone()))
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use crate::prolog_parser_rebis::ast::*;
|
||||||
|
use crate::prolog_parser_rebis::{clause_name, temp_v};
|
||||||
|
|
||||||
use crate::forms::Number;
|
use crate::forms::Number;
|
||||||
use crate::machine::machine_indices::*;
|
use crate::machine::machine_indices::*;
|
||||||
use crate::rug::rand::RandState;
|
use crate::rug::rand::RandState;
|
||||||
|
|
||||||
use crate::ref_thread_local::RefThreadLocal;
|
use crate::ref_thread_local::{ref_thread_local, RefThreadLocal};
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
@@ -322,7 +323,9 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::ClearAttributeGoals => clause_name!("$clear_attribute_goals"),
|
&SystemClauseType::ClearAttributeGoals => clause_name!("$clear_attribute_goals"),
|
||||||
&SystemClauseType::CloneAttributeGoals => clause_name!("$clone_attribute_goals"),
|
&SystemClauseType::CloneAttributeGoals => clause_name!("$clone_attribute_goals"),
|
||||||
&SystemClauseType::CodesToNumber => clause_name!("$codes_to_number"),
|
&SystemClauseType::CodesToNumber => clause_name!("$codes_to_number"),
|
||||||
&SystemClauseType::CopyTermWithoutAttrVars => clause_name!("$copy_term_without_attr_vars"),
|
&SystemClauseType::CopyTermWithoutAttrVars => {
|
||||||
|
clause_name!("$copy_term_without_attr_vars")
|
||||||
|
}
|
||||||
&SystemClauseType::CreatePartialString => clause_name!("$create_partial_string"),
|
&SystemClauseType::CreatePartialString => clause_name!("$create_partial_string"),
|
||||||
&SystemClauseType::CurrentInput => clause_name!("$current_input"),
|
&SystemClauseType::CurrentInput => clause_name!("$current_input"),
|
||||||
&SystemClauseType::CurrentHostname => clause_name!("$current_hostname"),
|
&SystemClauseType::CurrentHostname => clause_name!("$current_hostname"),
|
||||||
@@ -337,58 +340,70 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::WorkingDirectory => clause_name!("$working_directory"),
|
&SystemClauseType::WorkingDirectory => clause_name!("$working_directory"),
|
||||||
&SystemClauseType::PathCanonical => clause_name!("$path_canonical"),
|
&SystemClauseType::PathCanonical => clause_name!("$path_canonical"),
|
||||||
&SystemClauseType::FileTime => clause_name!("$file_time"),
|
&SystemClauseType::FileTime => clause_name!("$file_time"),
|
||||||
&SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate) =>
|
&SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate) => {
|
||||||
clause_name!("$add_dynamic_predicate"),
|
clause_name!("$add_dynamic_predicate")
|
||||||
&SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause) =>
|
}
|
||||||
clause_name!("$add_goal_expansion_clause"),
|
&SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause) => {
|
||||||
&SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause) =>
|
clause_name!("$add_goal_expansion_clause")
|
||||||
clause_name!("$add_term_expansion_clause"),
|
}
|
||||||
&SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable) =>
|
&SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause) => {
|
||||||
clause_name!("$clause_to_evacuable"),
|
clause_name!("$add_term_expansion_clause")
|
||||||
&SystemClauseType::REPL(REPLCodePtr::ConcludeLoad) =>
|
}
|
||||||
clause_name!("$conclude_load"),
|
&SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable) => {
|
||||||
&SystemClauseType::REPL(REPLCodePtr::DeclareModule) =>
|
clause_name!("$clause_to_evacuable")
|
||||||
clause_name!("$declare_module"),
|
}
|
||||||
&SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary) =>
|
&SystemClauseType::REPL(REPLCodePtr::ConcludeLoad) => clause_name!("$conclude_load"),
|
||||||
clause_name!("$load_compiled_library"),
|
&SystemClauseType::REPL(REPLCodePtr::DeclareModule) => clause_name!("$declare_module"),
|
||||||
&SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload) =>
|
&SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary) => {
|
||||||
clause_name!("$push_load_state_payload"),
|
clause_name!("$load_compiled_library")
|
||||||
&SystemClauseType::REPL(REPLCodePtr::Asserta) =>
|
}
|
||||||
clause_name!("$asserta"),
|
&SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload) => {
|
||||||
&SystemClauseType::REPL(REPLCodePtr::Assertz) =>
|
clause_name!("$push_load_state_payload")
|
||||||
clause_name!("$assertz"),
|
}
|
||||||
&SystemClauseType::REPL(REPLCodePtr::Retract) =>
|
&SystemClauseType::REPL(REPLCodePtr::Asserta) => clause_name!("$asserta"),
|
||||||
clause_name!("$retract_clause"),
|
&SystemClauseType::REPL(REPLCodePtr::Assertz) => clause_name!("$assertz"),
|
||||||
&SystemClauseType::REPL(REPLCodePtr::UseModule) =>
|
&SystemClauseType::REPL(REPLCodePtr::Retract) => clause_name!("$retract_clause"),
|
||||||
clause_name!("$use_module"),
|
&SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"),
|
||||||
&SystemClauseType::REPL(REPLCodePtr::PushLoadContext) =>
|
&SystemClauseType::REPL(REPLCodePtr::PushLoadContext) => {
|
||||||
clause_name!("$push_load_context"),
|
clause_name!("$push_load_context")
|
||||||
&SystemClauseType::REPL(REPLCodePtr::PopLoadContext) =>
|
}
|
||||||
clause_name!("$pop_load_context"),
|
&SystemClauseType::REPL(REPLCodePtr::PopLoadContext) => {
|
||||||
&SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload) =>
|
clause_name!("$pop_load_context")
|
||||||
clause_name!("$pop_load_state_payload"),
|
}
|
||||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextSource) =>
|
&SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload) => {
|
||||||
clause_name!("$prolog_lc_source"),
|
clause_name!("$pop_load_state_payload")
|
||||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextFile) =>
|
}
|
||||||
clause_name!("$prolog_lc_file"),
|
&SystemClauseType::REPL(REPLCodePtr::LoadContextSource) => {
|
||||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory) =>
|
clause_name!("$prolog_lc_source")
|
||||||
clause_name!("$prolog_lc_dir"),
|
}
|
||||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextModule) =>
|
&SystemClauseType::REPL(REPLCodePtr::LoadContextFile) => {
|
||||||
clause_name!("$prolog_lc_module"),
|
clause_name!("$prolog_lc_file")
|
||||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextStream) =>
|
}
|
||||||
clause_name!("$prolog_lc_stream"),
|
&SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory) => {
|
||||||
&SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty) =>
|
clause_name!("$prolog_lc_dir")
|
||||||
clause_name!("$cpp_meta_predicate_property"),
|
}
|
||||||
&SystemClauseType::REPL(REPLCodePtr::BuiltInProperty) =>
|
&SystemClauseType::REPL(REPLCodePtr::LoadContextModule) => {
|
||||||
clause_name!("$cpp_built_in_property"),
|
clause_name!("$prolog_lc_module")
|
||||||
&SystemClauseType::REPL(REPLCodePtr::DynamicProperty) =>
|
}
|
||||||
clause_name!("$cpp_dynamic_property"),
|
&SystemClauseType::REPL(REPLCodePtr::LoadContextStream) => {
|
||||||
&SystemClauseType::REPL(REPLCodePtr::MultifileProperty) =>
|
clause_name!("$prolog_lc_stream")
|
||||||
clause_name!("$cpp_multifile_property"),
|
}
|
||||||
&SystemClauseType::REPL(REPLCodePtr::DiscontiguousProperty) =>
|
&SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty) => {
|
||||||
clause_name!("$cpp_discontiguous_property"),
|
clause_name!("$cpp_meta_predicate_property")
|
||||||
&SystemClauseType::REPL(REPLCodePtr::AbolishClause) =>
|
}
|
||||||
clause_name!("$abolish_clause"),
|
&SystemClauseType::REPL(REPLCodePtr::BuiltInProperty) => {
|
||||||
|
clause_name!("$cpp_built_in_property")
|
||||||
|
}
|
||||||
|
&SystemClauseType::REPL(REPLCodePtr::DynamicProperty) => {
|
||||||
|
clause_name!("$cpp_dynamic_property")
|
||||||
|
}
|
||||||
|
&SystemClauseType::REPL(REPLCodePtr::MultifileProperty) => {
|
||||||
|
clause_name!("$cpp_multifile_property")
|
||||||
|
}
|
||||||
|
&SystemClauseType::REPL(REPLCodePtr::DiscontiguousProperty) => {
|
||||||
|
clause_name!("$cpp_discontiguous_property")
|
||||||
|
}
|
||||||
|
&SystemClauseType::REPL(REPLCodePtr::AbolishClause) => clause_name!("$abolish_clause"),
|
||||||
&SystemClauseType::Close => clause_name!("$close"),
|
&SystemClauseType::Close => clause_name!("$close"),
|
||||||
&SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"),
|
&SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"),
|
||||||
&SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"),
|
&SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"),
|
||||||
@@ -397,8 +412,9 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::EnqueueAttributeGoal => clause_name!("$enqueue_attribute_goal"),
|
&SystemClauseType::EnqueueAttributeGoal => clause_name!("$enqueue_attribute_goal"),
|
||||||
&SystemClauseType::EnqueueAttributedVar => clause_name!("$enqueue_attr_var"),
|
&SystemClauseType::EnqueueAttributedVar => clause_name!("$enqueue_attr_var"),
|
||||||
&SystemClauseType::FetchGlobalVar => clause_name!("$fetch_global_var"),
|
&SystemClauseType::FetchGlobalVar => clause_name!("$fetch_global_var"),
|
||||||
&SystemClauseType::FetchGlobalVarWithOffset =>
|
&SystemClauseType::FetchGlobalVarWithOffset => {
|
||||||
clause_name!("$fetch_global_var_with_offset"),
|
clause_name!("$fetch_global_var_with_offset")
|
||||||
|
}
|
||||||
&SystemClauseType::FirstStream => clause_name!("$first_stream"),
|
&SystemClauseType::FirstStream => clause_name!("$first_stream"),
|
||||||
&SystemClauseType::FlushOutput => clause_name!("$flush_output"),
|
&SystemClauseType::FlushOutput => clause_name!("$flush_output"),
|
||||||
&SystemClauseType::GetByte => clause_name!("$get_byte"),
|
&SystemClauseType::GetByte => clause_name!("$get_byte"),
|
||||||
@@ -507,7 +523,9 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::ReadTerm => clause_name!("$read_term"),
|
&SystemClauseType::ReadTerm => clause_name!("$read_term"),
|
||||||
&SystemClauseType::ReadTermFromChars => clause_name!("$read_term_from_chars"),
|
&SystemClauseType::ReadTermFromChars => clause_name!("$read_term_from_chars"),
|
||||||
&SystemClauseType::ResetGlobalVarAtKey => clause_name!("$reset_global_var_at_key"),
|
&SystemClauseType::ResetGlobalVarAtKey => clause_name!("$reset_global_var_at_key"),
|
||||||
&SystemClauseType::ResetGlobalVarAtOffset => clause_name!("$reset_global_var_at_offset"),
|
&SystemClauseType::ResetGlobalVarAtOffset => {
|
||||||
|
clause_name!("$reset_global_var_at_offset")
|
||||||
|
}
|
||||||
&SystemClauseType::ResetBlock => clause_name!("$reset_block"),
|
&SystemClauseType::ResetBlock => clause_name!("$reset_block"),
|
||||||
&SystemClauseType::ResetContinuationMarker => clause_name!("$reset_cont_marker"),
|
&SystemClauseType::ResetContinuationMarker => clause_name!("$reset_cont_marker"),
|
||||||
&SystemClauseType::ReturnFromVerifyAttr => clause_name!("$return_from_verify_attr"),
|
&SystemClauseType::ReturnFromVerifyAttr => clause_name!("$return_from_verify_attr"),
|
||||||
@@ -521,7 +539,9 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::SocketServerAccept => clause_name!("$socket_server_accept"),
|
&SystemClauseType::SocketServerAccept => clause_name!("$socket_server_accept"),
|
||||||
&SystemClauseType::SocketServerClose => clause_name!("$socket_server_close"),
|
&SystemClauseType::SocketServerClose => clause_name!("$socket_server_close"),
|
||||||
&SystemClauseType::Succeed => clause_name!("$succeed"),
|
&SystemClauseType::Succeed => clause_name!("$succeed"),
|
||||||
&SystemClauseType::TermAttributedVariables => clause_name!("$term_attributed_variables"),
|
&SystemClauseType::TermAttributedVariables => {
|
||||||
|
clause_name!("$term_attributed_variables")
|
||||||
|
}
|
||||||
&SystemClauseType::TermVariables => clause_name!("$term_variables"),
|
&SystemClauseType::TermVariables => clause_name!("$term_variables"),
|
||||||
&SystemClauseType::TruncateLiftedHeapTo => clause_name!("$truncate_lh_to"),
|
&SystemClauseType::TruncateLiftedHeapTo => clause_name!("$truncate_lh_to"),
|
||||||
&SystemClauseType::UnifyWithOccursCheck => clause_name!("$unify_with_occurs_check"),
|
&SystemClauseType::UnifyWithOccursCheck => clause_name!("$unify_with_occurs_check"),
|
||||||
@@ -542,7 +562,9 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::Ed25519Sign => clause_name!("$ed25519_sign"),
|
&SystemClauseType::Ed25519Sign => clause_name!("$ed25519_sign"),
|
||||||
&SystemClauseType::Ed25519Verify => clause_name!("$ed25519_verify"),
|
&SystemClauseType::Ed25519Verify => clause_name!("$ed25519_verify"),
|
||||||
&SystemClauseType::Ed25519NewKeyPair => clause_name!("$ed25519_new_keypair"),
|
&SystemClauseType::Ed25519NewKeyPair => clause_name!("$ed25519_new_keypair"),
|
||||||
&SystemClauseType::Ed25519KeyPairPublicKey => clause_name!("$ed25519_keypair_public_key"),
|
&SystemClauseType::Ed25519KeyPairPublicKey => {
|
||||||
|
clause_name!("$ed25519_keypair_public_key")
|
||||||
|
}
|
||||||
&SystemClauseType::Curve25519ScalarMult => clause_name!("$curve25519_scalar_mult"),
|
&SystemClauseType::Curve25519ScalarMult => clause_name!("$curve25519_scalar_mult"),
|
||||||
&SystemClauseType::LoadHTML => clause_name!("$load_html"),
|
&SystemClauseType::LoadHTML => clause_name!("$load_html"),
|
||||||
&SystemClauseType::LoadXML => clause_name!("$load_xml"),
|
&SystemClauseType::LoadXML => clause_name!("$load_xml"),
|
||||||
@@ -556,14 +578,16 @@ impl SystemClauseType {
|
|||||||
|
|
||||||
pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
|
pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
|
||||||
match (name, arity) {
|
match (name, arity) {
|
||||||
("$abolish_clause", 3) =>
|
("$abolish_clause", 3) => Some(SystemClauseType::REPL(REPLCodePtr::AbolishClause)),
|
||||||
Some(SystemClauseType::REPL(REPLCodePtr::AbolishClause)),
|
("$add_dynamic_predicate", 3) => {
|
||||||
("$add_dynamic_predicate", 3) =>
|
Some(SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate))
|
||||||
Some(SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate)),
|
}
|
||||||
("$add_goal_expansion_clause", 4) =>
|
("$add_goal_expansion_clause", 4) => {
|
||||||
Some(SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause)),
|
Some(SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause))
|
||||||
("$add_term_expansion_clause", 3) =>
|
}
|
||||||
Some(SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause)),
|
("$add_term_expansion_clause", 3) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause))
|
||||||
|
}
|
||||||
("$atom_chars", 2) => Some(SystemClauseType::AtomChars),
|
("$atom_chars", 2) => Some(SystemClauseType::AtomChars),
|
||||||
("$atom_codes", 2) => Some(SystemClauseType::AtomCodes),
|
("$atom_codes", 2) => Some(SystemClauseType::AtomCodes),
|
||||||
("$atom_length", 2) => Some(SystemClauseType::AtomLength),
|
("$atom_length", 2) => Some(SystemClauseType::AtomLength),
|
||||||
@@ -602,7 +626,9 @@ impl SystemClauseType {
|
|||||||
("$peek_code", 2) => Some(SystemClauseType::PeekCode),
|
("$peek_code", 2) => Some(SystemClauseType::PeekCode),
|
||||||
("$is_partial_string", 1) => Some(SystemClauseType::IsPartialString),
|
("$is_partial_string", 1) => Some(SystemClauseType::IsPartialString),
|
||||||
("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar),
|
("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar),
|
||||||
("$fetch_global_var_with_offset", 3) => Some(SystemClauseType::FetchGlobalVarWithOffset),
|
("$fetch_global_var_with_offset", 3) => {
|
||||||
|
Some(SystemClauseType::FetchGlobalVarWithOffset)
|
||||||
|
}
|
||||||
("$get_byte", 2) => Some(SystemClauseType::GetByte),
|
("$get_byte", 2) => Some(SystemClauseType::GetByte),
|
||||||
("$get_char", 2) => Some(SystemClauseType::GetChar),
|
("$get_char", 2) => Some(SystemClauseType::GetChar),
|
||||||
("$get_n_chars", 3) => Some(SystemClauseType::GetNChars),
|
("$get_n_chars", 3) => Some(SystemClauseType::GetNChars),
|
||||||
@@ -611,18 +637,10 @@ impl SystemClauseType {
|
|||||||
("$points_to_cont_reset_marker", 1) => {
|
("$points_to_cont_reset_marker", 1) => {
|
||||||
Some(SystemClauseType::PointsToContinuationResetMarker)
|
Some(SystemClauseType::PointsToContinuationResetMarker)
|
||||||
}
|
}
|
||||||
("$put_byte", 2) => {
|
("$put_byte", 2) => Some(SystemClauseType::PutByte),
|
||||||
Some(SystemClauseType::PutByte)
|
("$put_char", 2) => Some(SystemClauseType::PutChar),
|
||||||
}
|
("$put_chars", 2) => Some(SystemClauseType::PutChars),
|
||||||
("$put_char", 2) => {
|
("$put_code", 2) => Some(SystemClauseType::PutCode),
|
||||||
Some(SystemClauseType::PutChar)
|
|
||||||
}
|
|
||||||
("$put_chars", 2) => {
|
|
||||||
Some(SystemClauseType::PutChars)
|
|
||||||
}
|
|
||||||
("$put_code", 2) => {
|
|
||||||
Some(SystemClauseType::PutCode)
|
|
||||||
}
|
|
||||||
("$reset_attr_var_state", 0) => Some(SystemClauseType::ResetAttrVarState),
|
("$reset_attr_var_state", 0) => Some(SystemClauseType::ResetAttrVarState),
|
||||||
("$truncate_if_no_lh_growth", 1) => {
|
("$truncate_if_no_lh_growth", 1) => {
|
||||||
Some(SystemClauseType::TruncateIfNoLiftedHeapGrowth)
|
Some(SystemClauseType::TruncateIfNoLiftedHeapGrowth)
|
||||||
@@ -691,7 +709,9 @@ impl SystemClauseType {
|
|||||||
("$socket_server_accept", 7) => Some(SystemClauseType::SocketServerAccept),
|
("$socket_server_accept", 7) => Some(SystemClauseType::SocketServerAccept),
|
||||||
("$socket_server_close", 1) => Some(SystemClauseType::SocketServerClose),
|
("$socket_server_close", 1) => Some(SystemClauseType::SocketServerClose),
|
||||||
("$store_global_var", 2) => Some(SystemClauseType::StoreGlobalVar),
|
("$store_global_var", 2) => Some(SystemClauseType::StoreGlobalVar),
|
||||||
("$store_global_var_with_offset", 2) => Some(SystemClauseType::StoreGlobalVarWithOffset),
|
("$store_global_var_with_offset", 2) => {
|
||||||
|
Some(SystemClauseType::StoreGlobalVarWithOffset)
|
||||||
|
}
|
||||||
("$term_attributed_variables", 2) => Some(SystemClauseType::TermAttributedVariables),
|
("$term_attributed_variables", 2) => Some(SystemClauseType::TermAttributedVariables),
|
||||||
("$term_variables", 2) => Some(SystemClauseType::TermVariables),
|
("$term_variables", 2) => Some(SystemClauseType::TermVariables),
|
||||||
("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
|
("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
|
||||||
@@ -708,12 +728,18 @@ impl SystemClauseType {
|
|||||||
("$working_directory", 2) => Some(SystemClauseType::WorkingDirectory),
|
("$working_directory", 2) => Some(SystemClauseType::WorkingDirectory),
|
||||||
("$path_canonical", 2) => Some(SystemClauseType::PathCanonical),
|
("$path_canonical", 2) => Some(SystemClauseType::PathCanonical),
|
||||||
("$file_time", 3) => Some(SystemClauseType::FileTime),
|
("$file_time", 3) => Some(SystemClauseType::FileTime),
|
||||||
("$clause_to_evacuable", 3) => Some(SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable)),
|
("$clause_to_evacuable", 3) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable))
|
||||||
|
}
|
||||||
("$conclude_load", 1) => Some(SystemClauseType::REPL(REPLCodePtr::ConcludeLoad)),
|
("$conclude_load", 1) => Some(SystemClauseType::REPL(REPLCodePtr::ConcludeLoad)),
|
||||||
("$use_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)),
|
("$use_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)),
|
||||||
("$declare_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DeclareModule)),
|
("$declare_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DeclareModule)),
|
||||||
("$load_compiled_library", 2) => Some(SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary)),
|
("$load_compiled_library", 2) => {
|
||||||
("$push_load_state_payload", 1) => Some(SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload)),
|
Some(SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary))
|
||||||
|
}
|
||||||
|
("$push_load_state_payload", 1) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload))
|
||||||
|
}
|
||||||
("$asserta", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Asserta)),
|
("$asserta", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Asserta)),
|
||||||
("$assertz", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Assertz)),
|
("$assertz", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Assertz)),
|
||||||
("$retract_clause", 4) => Some(SystemClauseType::REPL(REPLCodePtr::Retract)),
|
("$retract_clause", 4) => Some(SystemClauseType::REPL(REPLCodePtr::Retract)),
|
||||||
@@ -742,18 +768,38 @@ impl SystemClauseType {
|
|||||||
("$chars_base64", 4) => Some(SystemClauseType::CharsBase64),
|
("$chars_base64", 4) => Some(SystemClauseType::CharsBase64),
|
||||||
("$load_library_as_stream", 3) => Some(SystemClauseType::LoadLibraryAsStream),
|
("$load_library_as_stream", 3) => Some(SystemClauseType::LoadLibraryAsStream),
|
||||||
("$push_load_context", 2) => Some(SystemClauseType::REPL(REPLCodePtr::PushLoadContext)),
|
("$push_load_context", 2) => Some(SystemClauseType::REPL(REPLCodePtr::PushLoadContext)),
|
||||||
("$pop_load_state_payload", 1) => Some(SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload)),
|
("$pop_load_state_payload", 1) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload))
|
||||||
|
}
|
||||||
("$pop_load_context", 0) => Some(SystemClauseType::REPL(REPLCodePtr::PopLoadContext)),
|
("$pop_load_context", 0) => Some(SystemClauseType::REPL(REPLCodePtr::PopLoadContext)),
|
||||||
("$prolog_lc_source", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextSource)),
|
("$prolog_lc_source", 1) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::LoadContextSource))
|
||||||
|
}
|
||||||
("$prolog_lc_file", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextFile)),
|
("$prolog_lc_file", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextFile)),
|
||||||
("$prolog_lc_dir", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory)),
|
("$prolog_lc_dir", 1) => {
|
||||||
("$prolog_lc_module", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextModule)),
|
Some(SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory))
|
||||||
("$prolog_lc_stream", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextStream)),
|
}
|
||||||
("$cpp_meta_predicate_property", 4) => Some(SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty)),
|
("$prolog_lc_module", 1) => {
|
||||||
("$cpp_built_in_property", 2) => Some(SystemClauseType::REPL(REPLCodePtr::BuiltInProperty)),
|
Some(SystemClauseType::REPL(REPLCodePtr::LoadContextModule))
|
||||||
("$cpp_dynamic_property", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DynamicProperty)),
|
}
|
||||||
("$cpp_multifile_property", 3) => Some(SystemClauseType::REPL(REPLCodePtr::MultifileProperty)),
|
("$prolog_lc_stream", 1) => {
|
||||||
("$cpp_discontiguous_property", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DiscontiguousProperty)),
|
Some(SystemClauseType::REPL(REPLCodePtr::LoadContextStream))
|
||||||
|
}
|
||||||
|
("$cpp_meta_predicate_property", 4) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty))
|
||||||
|
}
|
||||||
|
("$cpp_built_in_property", 2) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::BuiltInProperty))
|
||||||
|
}
|
||||||
|
("$cpp_dynamic_property", 3) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::DynamicProperty))
|
||||||
|
}
|
||||||
|
("$cpp_multifile_property", 3) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::MultifileProperty))
|
||||||
|
}
|
||||||
|
("$cpp_discontiguous_property", 3) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::DiscontiguousProperty))
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
119
src/codegen.rs
119
src/codegen.rs
@@ -1,6 +1,7 @@
|
|||||||
/// Code generation to WAM-like instructions.
|
/// Code generation to WAM-like instructions.
|
||||||
use crate::prolog_parser_rebis::ast::*;
|
use crate::prolog_parser_rebis::ast::*;
|
||||||
use crate::prolog_parser_rebis::tabled_rc::TabledData;
|
use crate::prolog_parser_rebis::tabled_rc::TabledData;
|
||||||
|
use crate::prolog_parser_rebis::{perm_v, temp_v};
|
||||||
|
|
||||||
use crate::allocator::*;
|
use crate::allocator::*;
|
||||||
use crate::arithmetic::*;
|
use crate::arithmetic::*;
|
||||||
@@ -66,11 +67,7 @@ impl<'a> ConjunctInfo<'a> {
|
|||||||
self.has_deep_cut as usize
|
self.has_deep_cut as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mark_unsafe_vars(
|
fn mark_unsafe_vars(&self, mut unsafe_var_marker: UnsafeVarMarker, code: &mut Code) {
|
||||||
&self,
|
|
||||||
mut unsafe_var_marker: UnsafeVarMarker,
|
|
||||||
code: &mut Code,
|
|
||||||
) {
|
|
||||||
if code.is_empty() {
|
if code.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -173,7 +170,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
code: &mut Code,
|
code: &mut Code,
|
||||||
) -> RegType {
|
) -> RegType {
|
||||||
let mut target = Vec::new();
|
let mut target = Vec::new();
|
||||||
self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target);
|
self.marker
|
||||||
|
.mark_var(name, Level::Shallow, vr, term_loc, &mut target);
|
||||||
|
|
||||||
if !target.is_empty() {
|
if !target.is_empty() {
|
||||||
code.extend(target.into_iter().map(Line::Query));
|
code.extend(target.into_iter().map(Line::Query));
|
||||||
@@ -191,9 +189,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
code: &mut Code,
|
code: &mut Code,
|
||||||
) -> RegType {
|
) -> RegType {
|
||||||
match self.marker.bindings().get(&name) {
|
match self.marker.bindings().get(&name) {
|
||||||
Some(&VarData::Temp(_, t, _)) if t != 0 => {
|
Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t),
|
||||||
RegType::Temp(t)
|
|
||||||
}
|
|
||||||
Some(&VarData::Perm(p)) if p != 0 => {
|
Some(&VarData::Perm(p)) if p != 0 => {
|
||||||
if let GenContext::Last(_) = term_loc {
|
if let GenContext::Last(_) = term_loc {
|
||||||
self.mark_var_in_non_callable(name.clone(), term_loc, vr, code);
|
self.mark_var_in_non_callable(name.clone(), term_loc, vr, code);
|
||||||
@@ -202,9 +198,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
RegType::Perm(p)
|
RegType::Perm(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => self.mark_var_in_non_callable(name, term_loc, vr, code),
|
||||||
self.mark_var_in_non_callable(name, term_loc, vr, code)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +225,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
target: &mut Vec<Target>,
|
target: &mut Vec<Target>,
|
||||||
) {
|
) {
|
||||||
if is_exposed || self.get_var_count(var.as_ref()) > 1 {
|
if is_exposed || self.get_var_count(var.as_ref()) > 1 {
|
||||||
self.marker.mark_var(var.clone(), Level::Deep, cell, term_loc, target);
|
self.marker
|
||||||
|
.mark_var(var.clone(), Level::Deep, cell, term_loc, target);
|
||||||
} else {
|
} else {
|
||||||
Self::add_or_increment_void_instr(target);
|
Self::add_or_increment_void_instr(target);
|
||||||
}
|
}
|
||||||
@@ -252,7 +247,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
Self::add_or_increment_void_instr(target);
|
Self::add_or_increment_void_instr(target);
|
||||||
}
|
}
|
||||||
&Term::Cons(ref cell, _, _) | &Term::Clause(ref cell, _, _, _) => {
|
&Term::Cons(ref cell, _, _) | &Term::Clause(ref cell, _, _, _) => {
|
||||||
self.marker.mark_non_var(Level::Deep, term_loc, cell, target);
|
self.marker
|
||||||
|
.mark_non_var(Level::Deep, term_loc, cell, target);
|
||||||
target.push(Target::clause_arg_to_instr(cell.get()));
|
target.push(Target::clause_arg_to_instr(cell.get()));
|
||||||
}
|
}
|
||||||
&Term::Constant(_, ref constant) => {
|
&Term::Constant(_, ref constant) => {
|
||||||
@@ -334,13 +330,14 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.marker.mark_var(var.clone(), lvl, cell, term_loc, &mut target);
|
self.marker
|
||||||
|
.mark_var(var.clone(), lvl, cell, term_loc, &mut target);
|
||||||
}
|
}
|
||||||
TermRef::Var(lvl @ Level::Shallow, cell, var) => {
|
TermRef::Var(lvl @ Level::Shallow, cell, var) => {
|
||||||
self.marker.mark_var(var.clone(), lvl, cell, term_loc, &mut target);
|
self.marker
|
||||||
}
|
.mark_var(var.clone(), lvl, cell, term_loc, &mut target);
|
||||||
_ => {
|
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,8 +350,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
while let Some((chunk_num, lt_arity, chunked_terms)) = iter.next() {
|
while let Some((chunk_num, lt_arity, chunked_terms)) = iter.next() {
|
||||||
for (i, chunked_term) in chunked_terms.iter().enumerate() {
|
for (i, chunked_term) in chunked_terms.iter().enumerate() {
|
||||||
let term_loc = match chunked_term {
|
let term_loc = match chunked_term {
|
||||||
&ChunkedTerm::HeadClause(..) =>
|
&ChunkedTerm::HeadClause(..) => GenContext::Head,
|
||||||
GenContext::Head,
|
|
||||||
&ChunkedTerm::BodyTerm(_) => {
|
&ChunkedTerm::BodyTerm(_) => {
|
||||||
if i < chunked_terms.len() - 1 {
|
if i < chunked_terms.len() - 1 {
|
||||||
GenContext::Mid(chunk_num)
|
GenContext::Mid(chunk_num)
|
||||||
@@ -391,8 +387,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
&QueryTerm::Clause(_, ref ct, ref terms, false) => {
|
&QueryTerm::Clause(_, ref ct, ref terms, false) => {
|
||||||
code.push(call_clause!(ct.clone(), terms.len(), pvs));
|
code.push(call_clause!(ct.clone(), terms.len(), pvs));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,8 +402,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
&mut ControlInstruction::JmpBy(_, _, _, ref mut last_call) => {
|
&mut ControlInstruction::JmpBy(_, _, _, ref mut last_call) => {
|
||||||
*last_call = true;
|
*last_call = true;
|
||||||
}
|
}
|
||||||
&mut ControlInstruction::Proceed => {
|
&mut ControlInstruction::Proceed => {}
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
dealloc_index += 1;
|
dealloc_index += 1;
|
||||||
}
|
}
|
||||||
@@ -416,8 +410,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
Some(&mut Line::Cut(CutInstruction::Cut(_))) => {
|
Some(&mut Line::Cut(CutInstruction::Cut(_))) => {
|
||||||
dealloc_index += 1;
|
dealloc_index += 1;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
dealloc_index
|
dealloc_index
|
||||||
@@ -437,20 +430,14 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
let (mut lcode, at_1) = self.call_arith_eval(terms[0].as_ref(), 1)?;
|
let (mut lcode, at_1) = self.call_arith_eval(terms[0].as_ref(), 1)?;
|
||||||
let (mut rcode, at_2) = self.call_arith_eval(terms[1].as_ref(), 2)?;
|
let (mut rcode, at_2) = self.call_arith_eval(terms[1].as_ref(), 2)?;
|
||||||
|
|
||||||
let at_1 =
|
let at_1 = if let &Term::Var(ref vr, ref name) = terms[0].as_ref() {
|
||||||
if let &Term::Var(ref vr, ref name) = terms[0].as_ref() {
|
ArithmeticTerm::Reg(self.mark_non_callable(name.clone(), 1, term_loc, vr, code))
|
||||||
ArithmeticTerm::Reg(
|
|
||||||
self.mark_non_callable(name.clone(), 1, term_loc, vr, code)
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
at_1.unwrap_or(interm!(1))
|
at_1.unwrap_or(interm!(1))
|
||||||
};
|
};
|
||||||
|
|
||||||
let at_2 =
|
let at_2 = if let &Term::Var(ref vr, ref name) = terms[1].as_ref() {
|
||||||
if let &Term::Var(ref vr, ref name) = terms[1].as_ref() {
|
ArithmeticTerm::Reg(self.mark_non_callable(name.clone(), 2, term_loc, vr, code))
|
||||||
ArithmeticTerm::Reg(
|
|
||||||
self.mark_non_callable(name.clone(), 2, term_loc, vr, code)
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
at_2.unwrap_or(interm!(2))
|
at_2.unwrap_or(interm!(2))
|
||||||
};
|
};
|
||||||
@@ -461,9 +448,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
code.push(compare_number_instr!(cmp, at_1, at_2));
|
code.push(compare_number_instr!(cmp, at_1, at_2));
|
||||||
}
|
}
|
||||||
&InlinedClauseType::IsAtom(..) => match terms[0].as_ref() {
|
&InlinedClauseType::IsAtom(..) => match terms[0].as_ref() {
|
||||||
&Term::Constant(_, Constant::Char(_)) |
|
&Term::Constant(_, Constant::Char(_))
|
||||||
&Term::Constant(_, Constant::EmptyList) |
|
| &Term::Constant(_, Constant::EmptyList)
|
||||||
&Term::Constant(_, Constant::Atom(..)) => {
|
| &Term::Constant(_, Constant::Atom(..)) => {
|
||||||
code.push(succeed!());
|
code.push(succeed!());
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
@@ -528,11 +515,11 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsNumber(..) => match terms[0].as_ref() {
|
&InlinedClauseType::IsNumber(..) => match terms[0].as_ref() {
|
||||||
&Term::Constant(_, Constant::Float(_)) |
|
&Term::Constant(_, Constant::Float(_))
|
||||||
&Term::Constant(_, Constant::Rational(_)) |
|
| &Term::Constant(_, Constant::Rational(_))
|
||||||
&Term::Constant(_, Constant::Integer(_)) |
|
| &Term::Constant(_, Constant::Integer(_))
|
||||||
&Term::Constant(_, Constant::Fixnum(_)) |
|
| &Term::Constant(_, Constant::Fixnum(_))
|
||||||
&Term::Constant(_, Constant::Usize(_)) => {
|
| &Term::Constant(_, Constant::Usize(_)) => {
|
||||||
code.push(succeed!());
|
code.push(succeed!());
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
@@ -558,9 +545,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsInteger(..) => match terms[0].as_ref() {
|
&InlinedClauseType::IsInteger(..) => match terms[0].as_ref() {
|
||||||
&Term::Constant(_, Constant::Integer(_)) |
|
&Term::Constant(_, Constant::Integer(_))
|
||||||
&Term::Constant(_, Constant::Fixnum(_)) |
|
| &Term::Constant(_, Constant::Fixnum(_))
|
||||||
&Term::Constant(_, Constant::Usize(_)) => {
|
| &Term::Constant(_, Constant::Usize(_)) => {
|
||||||
code.push(succeed!());
|
code.push(succeed!());
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
@@ -615,14 +602,15 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
let mut target = vec![];
|
let mut target = vec![];
|
||||||
|
|
||||||
self.marker.mark_var(name.clone(), Level::Shallow, vr, term_loc, &mut target);
|
self.marker
|
||||||
|
.mark_var(name.clone(), Level::Shallow, vr, term_loc, &mut target);
|
||||||
|
|
||||||
if !target.is_empty() {
|
if !target.is_empty() {
|
||||||
code.extend(target.into_iter().map(Line::Query));
|
code.extend(target.into_iter().map(Line::Query));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Term::Constant(_, ref c @ Constant::Integer(_)) |
|
&Term::Constant(_, ref c @ Constant::Integer(_))
|
||||||
&Term::Constant(_, ref c @ Constant::Fixnum(_)) => {
|
| &Term::Constant(_, ref c @ Constant::Fixnum(_)) => {
|
||||||
code.push(Line::Query(put_constant!(
|
code.push(Line::Query(put_constant!(
|
||||||
Level::Shallow,
|
Level::Shallow,
|
||||||
c.clone(),
|
c.clone(),
|
||||||
@@ -655,11 +643,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let at =
|
let at = if let &Term::Var(ref vr, ref name) = terms[1].as_ref() {
|
||||||
if let &Term::Var(ref vr, ref name) = terms[1].as_ref() {
|
ArithmeticTerm::Reg(self.mark_non_callable(name.clone(), 2, term_loc, vr, code))
|
||||||
ArithmeticTerm::Reg(
|
|
||||||
self.mark_non_callable(name.clone(), 2, term_loc, vr, code)
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
at.unwrap_or(interm!(1))
|
at.unwrap_or(interm!(1))
|
||||||
};
|
};
|
||||||
@@ -721,24 +706,18 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
&QueryTerm::GetLevelAndUnify(ref cell, ref var) => {
|
&QueryTerm::GetLevelAndUnify(ref cell, ref var) => {
|
||||||
self.compile_get_level_and_unify(code, cell, var.clone(), term_loc)
|
self.compile_get_level_and_unify(code, cell, var.clone(), term_loc)
|
||||||
}
|
}
|
||||||
&QueryTerm::UnblockedCut(ref cell) => {
|
&QueryTerm::UnblockedCut(ref cell) => self.compile_unblocked_cut(code, cell),
|
||||||
self.compile_unblocked_cut(code, cell)
|
&QueryTerm::BlockedCut => code.push(if chunk_num == 0 {
|
||||||
}
|
|
||||||
&QueryTerm::BlockedCut => {
|
|
||||||
code.push(if chunk_num == 0 {
|
|
||||||
Line::Cut(CutInstruction::NeckCut)
|
Line::Cut(CutInstruction::NeckCut)
|
||||||
} else {
|
} else {
|
||||||
Line::Cut(CutInstruction::Cut(perm_v!(1)))
|
Line::Cut(CutInstruction::Cut(perm_v!(1)))
|
||||||
})
|
}),
|
||||||
}
|
|
||||||
&QueryTerm::Clause(
|
&QueryTerm::Clause(
|
||||||
_,
|
_,
|
||||||
ClauseType::BuiltIn(BuiltInClauseType::Is(..)),
|
ClauseType::BuiltIn(BuiltInClauseType::Is(..)),
|
||||||
ref terms,
|
ref terms,
|
||||||
use_default_call_policy,
|
use_default_call_policy,
|
||||||
) => {
|
) => self.compile_is_call(terms, code, term_loc, use_default_call_policy)?,
|
||||||
self.compile_is_call(terms, code, term_loc, use_default_call_policy)?
|
|
||||||
}
|
|
||||||
&QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) => {
|
&QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) => {
|
||||||
self.compile_inlined(ct, terms, term_loc, code)?
|
self.compile_inlined(ct, terms, term_loc, code)?
|
||||||
}
|
}
|
||||||
@@ -772,7 +751,12 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_cleanup(&mut self, code: &mut Code, conjunct_info: &ConjunctInfo, toc: &'a QueryTerm) {
|
fn compile_cleanup(
|
||||||
|
&mut self,
|
||||||
|
code: &mut Code,
|
||||||
|
conjunct_info: &ConjunctInfo,
|
||||||
|
toc: &'a QueryTerm,
|
||||||
|
) {
|
||||||
// add a proceed to bookend any trailing cuts.
|
// add a proceed to bookend any trailing cuts.
|
||||||
match toc {
|
match toc {
|
||||||
&QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => code.push(proceed!()),
|
&QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => code.push(proceed!()),
|
||||||
@@ -1126,8 +1110,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
for clause_index_info in self.skeleton.clauses[skel_lower_bound..].iter_mut() {
|
for clause_index_info in self.skeleton.clauses[skel_lower_bound..].iter_mut() {
|
||||||
clause_index_info.clause_start +=
|
clause_index_info.clause_start +=
|
||||||
clause_start_offset + 2 * (segment_is_indexed as usize);
|
clause_start_offset + 2 * (segment_is_indexed as usize);
|
||||||
clause_index_info.opt_arg_index_key +=
|
clause_index_info.opt_arg_index_key += clause_start_offset + 1;
|
||||||
clause_start_offset + 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use crate::indexmap::IndexMap;
|
use crate::indexmap::IndexMap;
|
||||||
|
|
||||||
use crate::prolog_parser_rebis::ast::*;
|
use crate::prolog_parser_rebis::ast::*;
|
||||||
|
use crate::prolog_parser_rebis::temp_v;
|
||||||
|
|
||||||
use crate::allocator::*;
|
use crate::allocator::*;
|
||||||
use crate::fixtures::*;
|
use crate::fixtures::*;
|
||||||
@@ -293,9 +294,7 @@ impl<'a> Allocator<'a> for DebrayAllocator {
|
|||||||
|
|
||||||
(pr, true)
|
(pr, true)
|
||||||
}
|
}
|
||||||
r => {
|
r => (r, false),
|
||||||
(r, false)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.mark_reserved_var(var, lvl, cell, term_loc, target, r, is_new_var);
|
self.mark_reserved_var(var, lvl, cell, term_loc, target, r, is_new_var);
|
||||||
|
|||||||
132
src/forms.rs
132
src/forms.rs
@@ -1,5 +1,6 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use crate::prolog_parser_rebis::ast::*;
|
||||||
use crate::prolog_parser_rebis::parser::OpDesc;
|
use crate::prolog_parser_rebis::parser::OpDesc;
|
||||||
|
use crate::prolog_parser_rebis::{clause_name, is_infix, is_postfix};
|
||||||
|
|
||||||
use crate::clause_types::*;
|
use crate::clause_types::*;
|
||||||
use crate::machine::machine_errors::*;
|
use crate::machine::machine_errors::*;
|
||||||
@@ -36,7 +37,7 @@ pub enum TopLevel {
|
|||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum AppendOrPrepend {
|
pub enum AppendOrPrepend {
|
||||||
Append,
|
Append,
|
||||||
Prepend
|
Prepend,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppendOrPrepend {
|
impl AppendOrPrepend {
|
||||||
@@ -115,12 +116,8 @@ impl ListingSource {
|
|||||||
pub trait ClauseInfo {
|
pub trait ClauseInfo {
|
||||||
fn is_consistent(&self, clauses: &Vec<PredicateClause>) -> bool {
|
fn is_consistent(&self, clauses: &Vec<PredicateClause>) -> bool {
|
||||||
match clauses.first() {
|
match clauses.first() {
|
||||||
Some(cl) => {
|
Some(cl) => self.name() == cl.name() && self.arity() == cl.arity(),
|
||||||
self.name() == cl.name() && self.arity() == cl.arity()
|
None => true,
|
||||||
}
|
|
||||||
None => {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,38 +137,25 @@ impl ClauseInfo for Term {
|
|||||||
_ => Some(clause_name!(":-")),
|
_ => Some(clause_name!(":-")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => Some(name.clone()),
|
||||||
Some(name.clone())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
Term::Constant(_, Constant::Atom(ref name, _)) => Some(name.clone()),
|
||||||
Term::Constant(_, Constant::Atom(ref name, _)) => {
|
_ => None,
|
||||||
Some(name.clone())
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arity(&self) -> usize {
|
fn arity(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
Term::Clause(_, ref name, ref terms, _) =>
|
Term::Clause(_, ref name, ref terms, _) => match name.as_str() {
|
||||||
match name.as_str() {
|
":-" => match terms.len() {
|
||||||
":-" => {
|
|
||||||
match terms.len() {
|
|
||||||
1 => 0,
|
1 => 0,
|
||||||
2 => terms[0].arity(),
|
2 => terms[0].arity(),
|
||||||
_ => terms.len(),
|
_ => terms.len(),
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
terms.len()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
_ => {
|
_ => terms.len(),
|
||||||
0
|
},
|
||||||
}
|
_ => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,23 +173,15 @@ impl ClauseInfo for Rule {
|
|||||||
impl ClauseInfo for PredicateClause {
|
impl ClauseInfo for PredicateClause {
|
||||||
fn name(&self) -> Option<ClauseName> {
|
fn name(&self) -> Option<ClauseName> {
|
||||||
match self {
|
match self {
|
||||||
&PredicateClause::Fact(ref term, ..) => {
|
&PredicateClause::Fact(ref term, ..) => term.name(),
|
||||||
term.name()
|
&PredicateClause::Rule(ref rule, ..) => rule.name(),
|
||||||
}
|
|
||||||
&PredicateClause::Rule(ref rule, ..) => {
|
|
||||||
rule.name()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arity(&self) -> usize {
|
fn arity(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
&PredicateClause::Fact(ref term, ..) => {
|
&PredicateClause::Fact(ref term, ..) => term.arity(),
|
||||||
term.arity()
|
&PredicateClause::Rule(ref rule, ..) => rule.arity(),
|
||||||
}
|
|
||||||
&PredicateClause::Rule(ref rule, ..) => {
|
|
||||||
rule.arity()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,11 +198,9 @@ impl PredicateClause {
|
|||||||
// TODO: add this to `Term` in `prolog_parser` like `first_arg`.
|
// TODO: add this to `Term` in `prolog_parser` like `first_arg`.
|
||||||
pub fn args(&self) -> Option<&[Box<Term>]> {
|
pub fn args(&self) -> Option<&[Box<Term>]> {
|
||||||
match *self {
|
match *self {
|
||||||
PredicateClause::Fact(ref term, ..) => {
|
PredicateClause::Fact(ref term, ..) => match term {
|
||||||
match term {
|
|
||||||
Term::Clause(_, _, args, _) => Some(&args),
|
Term::Clause(_, _, args, _) => Some(&args),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
|
||||||
},
|
},
|
||||||
PredicateClause::Rule(ref rule, ..) => {
|
PredicateClause::Rule(ref rule, ..) => {
|
||||||
if rule.head.1.is_empty() {
|
if rule.head.1.is_empty() {
|
||||||
@@ -240,14 +214,11 @@ impl PredicateClause {
|
|||||||
|
|
||||||
pub fn arity(&self) -> usize {
|
pub fn arity(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
&PredicateClause::Fact(ref term, ..) => {
|
&PredicateClause::Fact(ref term, ..) => term.arity(),
|
||||||
term.arity()
|
|
||||||
}
|
|
||||||
&PredicateClause::Rule(ref rule, ..) => {
|
&PredicateClause::Rule(ref rule, ..) => {
|
||||||
if rule.head.0.as_str() == ":" && rule.head.1.len() == 2 {
|
if rule.head.0.as_str() == ":" && rule.head.1.len() == 2 {
|
||||||
match (rule.head.1)[0].as_ref() {
|
match (rule.head.1)[0].as_ref() {
|
||||||
&Term::Constant(_, Constant::Atom(..)) => {
|
&Term::Constant(_, Constant::Atom(..)) => {}
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
@@ -321,7 +292,7 @@ pub enum Declaration {
|
|||||||
pub struct OpDecl {
|
pub struct OpDecl {
|
||||||
pub prec: usize,
|
pub prec: usize,
|
||||||
pub spec: Specifier,
|
pub spec: Specifier,
|
||||||
pub name: ClauseName
|
pub name: ClauseName,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OpDecl {
|
impl OpDecl {
|
||||||
@@ -345,7 +316,7 @@ impl OpDecl {
|
|||||||
XFY | XFX | YFX => Fixity::In,
|
XFY | XFX | YFX => Fixity::In,
|
||||||
XF | YF => Fixity::Post,
|
XF | YF => Fixity::Post,
|
||||||
FX | FY => Fixity::Pre,
|
FX | FY => Fixity::Pre,
|
||||||
_ => unreachable!()
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,11 +327,11 @@ impl OpDecl {
|
|||||||
Some(cell) => {
|
Some(cell) => {
|
||||||
return Some(cell.shared_op_desc().replace((self.prec, self.spec)));
|
return Some(cell.shared_op_desc().replace((self.prec, self.spec)));
|
||||||
}
|
}
|
||||||
None => {
|
None => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
op_dir.insert(key, OpDirValue::new(self.spec, self.prec))
|
op_dir
|
||||||
|
.insert(key, OpDirValue::new(self.spec, self.prec))
|
||||||
.map(|op_dir_value| op_dir_value.shared_op_desc().get())
|
.map(|op_dir_value| op_dir_value.shared_op_desc().get())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,11 +390,7 @@ pub fn fetch_op_spec_from_existing(
|
|||||||
spec.or_else(|| fetch_op_spec(name, arity, op_dir))
|
spec.or_else(|| fetch_op_spec(name, arity, op_dir))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fetch_op_spec(
|
pub fn fetch_op_spec(name: ClauseName, arity: usize, op_dir: &OpDir) -> Option<SharedOpDesc> {
|
||||||
name: ClauseName,
|
|
||||||
arity: usize,
|
|
||||||
op_dir: &OpDir,
|
|
||||||
) -> Option<SharedOpDesc> {
|
|
||||||
match arity {
|
match arity {
|
||||||
2 => op_dir
|
2 => op_dir
|
||||||
.get(&(name, Fixity::In))
|
.get(&(name, Fixity::In))
|
||||||
@@ -451,9 +418,7 @@ pub fn fetch_op_spec(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => {
|
_ => None,
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,7 +464,6 @@ impl Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Number {
|
pub enum Number {
|
||||||
Float(OrderedFloat<f64>),
|
Float(OrderedFloat<f64>),
|
||||||
@@ -559,7 +523,6 @@ impl Into<HeapCellValue> for Number {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Number {
|
impl Number {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_positive(&self) -> bool {
|
pub fn is_positive(&self) -> bool {
|
||||||
@@ -594,12 +557,13 @@ impl Number {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn abs(self) -> Self {
|
pub fn abs(self) -> Self {
|
||||||
match self {
|
match self {
|
||||||
Number::Fixnum(n) =>
|
Number::Fixnum(n) => {
|
||||||
if let Some(n) = n.checked_abs() {
|
if let Some(n) = n.checked_abs() {
|
||||||
Number::from(n)
|
Number::from(n)
|
||||||
} else {
|
} else {
|
||||||
Number::from(Integer::from(n).abs())
|
Number::from(Integer::from(n).abs())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Number::Integer(n) => Number::from(Integer::from(n.abs_ref())),
|
Number::Integer(n) => Number::from(Integer::from(n.abs_ref())),
|
||||||
Number::Float(f) => Number::Float(OrderedFloat(f.abs())),
|
Number::Float(f) => Number::Float(OrderedFloat(f.abs())),
|
||||||
Number::Rational(r) => Number::from(Rational::from(r.abs_ref())),
|
Number::Rational(r) => Number::from(Rational::from(r.abs_ref())),
|
||||||
@@ -624,15 +588,13 @@ impl OptArgIndexKey {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn arg_num(&self) -> usize {
|
pub fn arg_num(&self) -> usize {
|
||||||
match &self {
|
match &self {
|
||||||
OptArgIndexKey::Constant(arg_num, ..) |
|
OptArgIndexKey::Constant(arg_num, ..)
|
||||||
OptArgIndexKey::Structure(arg_num, ..) |
|
| OptArgIndexKey::Structure(arg_num, ..)
|
||||||
OptArgIndexKey::List(arg_num, _) => {
|
| OptArgIndexKey::List(arg_num, _) => {
|
||||||
// these are always at least 1.
|
// these are always at least 1.
|
||||||
*arg_num
|
*arg_num
|
||||||
}
|
}
|
||||||
OptArgIndexKey::None => {
|
OptArgIndexKey::None => 0,
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -644,27 +606,22 @@ impl OptArgIndexKey {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn switch_on_term_loc(&self) -> Option<usize> {
|
pub fn switch_on_term_loc(&self) -> Option<usize> {
|
||||||
match &self {
|
match &self {
|
||||||
OptArgIndexKey::Constant(_, loc, ..) |
|
OptArgIndexKey::Constant(_, loc, ..)
|
||||||
OptArgIndexKey::Structure(_, loc, ..) |
|
| OptArgIndexKey::Structure(_, loc, ..)
|
||||||
OptArgIndexKey::List(_, loc) => {
|
| OptArgIndexKey::List(_, loc) => Some(*loc),
|
||||||
Some(*loc)
|
OptArgIndexKey::None => None,
|
||||||
}
|
|
||||||
OptArgIndexKey::None => {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_switch_on_term_loc(&mut self, value: usize) {
|
pub fn set_switch_on_term_loc(&mut self, value: usize) {
|
||||||
match self {
|
match self {
|
||||||
OptArgIndexKey::Constant(_, ref mut loc, ..) |
|
OptArgIndexKey::Constant(_, ref mut loc, ..)
|
||||||
OptArgIndexKey::Structure(_, ref mut loc, ..) |
|
| OptArgIndexKey::Structure(_, ref mut loc, ..)
|
||||||
OptArgIndexKey::List(_, ref mut loc) => {
|
| OptArgIndexKey::List(_, ref mut loc) => {
|
||||||
*loc = value;
|
*loc = value;
|
||||||
}
|
}
|
||||||
OptArgIndexKey::None => {
|
OptArgIndexKey::None => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -673,13 +630,12 @@ impl AddAssign<usize> for OptArgIndexKey {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn add_assign(&mut self, n: usize) {
|
fn add_assign(&mut self, n: usize) {
|
||||||
match self {
|
match self {
|
||||||
OptArgIndexKey::Constant(_, ref mut o, ..) |
|
OptArgIndexKey::Constant(_, ref mut o, ..)
|
||||||
OptArgIndexKey::List(_, ref mut o) |
|
| OptArgIndexKey::List(_, ref mut o)
|
||||||
OptArgIndexKey::Structure(_, ref mut o, ..) => {
|
| OptArgIndexKey::Structure(_, ref mut o, ..) => {
|
||||||
*o += n;
|
*o += n;
|
||||||
}
|
}
|
||||||
OptArgIndexKey::None => {
|
OptArgIndexKey::None => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use crate::prolog_parser_rebis::ast::*;
|
||||||
|
use crate::prolog_parser_rebis::{
|
||||||
|
alpha_char, alpha_numeric_char, backslash_char, capital_letter_char, char_class, clause_name,
|
||||||
|
cut_char, decimal_digit_char, graphic_char, graphic_token_char, is_fx, is_infix, is_postfix,
|
||||||
|
is_prefix, is_xf, is_xfx, is_xfy, is_yfx, semicolon_char, sign_char, single_quote_char,
|
||||||
|
small_letter_char, solo_char, variable_indicator_char,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::clause_types::*;
|
use crate::clause_types::*;
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
@@ -14,7 +20,7 @@ use crate::indexmap::{IndexMap, IndexSet};
|
|||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::iter::{FromIterator, once};
|
use std::iter::{once, FromIterator};
|
||||||
use std::net::{IpAddr, TcpListener};
|
use std::net::{IpAddr, TcpListener};
|
||||||
use std::ops::{Range, RangeFrom};
|
use std::ops::{Range, RangeFrom};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@@ -99,10 +105,7 @@ impl<'a> HCPreOrderIterator<'a> {
|
|||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut parent_spec = DirectedOp::Left(
|
let mut parent_spec = DirectedOp::Left(clause_name!("-"), SharedOpDesc::new(200, FY));
|
||||||
clause_name!("-"),
|
|
||||||
SharedOpDesc::new(200, FY),
|
|
||||||
);
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match self.machine_st.store(self.machine_st.deref(addr)) {
|
match self.machine_st.store(self.machine_st.deref(addr)) {
|
||||||
@@ -154,8 +157,9 @@ fn char_to_string(is_quoted: bool, c: char) -> String {
|
|||||||
'\u{07}' if is_quoted => "\\a".to_string(), // UTF-8 alert
|
'\u{07}' if is_quoted => "\\a".to_string(), // UTF-8 alert
|
||||||
'"' if is_quoted => "\\\"".to_string(),
|
'"' if is_quoted => "\\\"".to_string(),
|
||||||
'\\' if is_quoted => "\\\\".to_string(),
|
'\\' if is_quoted => "\\\\".to_string(),
|
||||||
'\'' | '\n' | '\r' | '\t' | '\u{0b}' | '\u{0c}' | '\u{08}' | '\u{07}' | '"' | '\\' =>
|
'\'' | '\n' | '\r' | '\t' | '\u{0b}' | '\u{0c}' | '\u{08}' | '\u{07}' | '"' | '\\' => {
|
||||||
c.to_string(),
|
c.to_string()
|
||||||
|
}
|
||||||
'\u{a0}'..='\u{d6}' => c.to_string(),
|
'\u{a0}'..='\u{d6}' => c.to_string(),
|
||||||
'\u{d8}'..='\u{f6}' => c.to_string(),
|
'\u{d8}'..='\u{f6}' => c.to_string(),
|
||||||
'\u{f8}'..='\u{74f}' => c.to_string(),
|
'\u{f8}'..='\u{74f}' => c.to_string(),
|
||||||
@@ -271,25 +275,13 @@ fn is_numbered_var(ct: &ClauseType, arity: usize) -> bool {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp>) -> bool {
|
fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp>) -> bool {
|
||||||
if let Some(ref op) = op {
|
if let Some(ref op) = op {
|
||||||
op.is_negative_sign() &&
|
op.is_negative_sign()
|
||||||
iter.leftmost_leaf_has_property(|addr, heap| {
|
&& iter.leftmost_leaf_has_property(|addr, heap| match Number::try_from((addr, heap)) {
|
||||||
match Number::try_from((addr, heap)) {
|
Ok(Number::Fixnum(n)) => n > 0,
|
||||||
Ok(Number::Fixnum(n)) => {
|
Ok(Number::Float(f)) => f > OrderedFloat(0f64),
|
||||||
n > 0
|
Ok(Number::Integer(n)) => &*n > &0,
|
||||||
}
|
Ok(Number::Rational(n)) => &*n > &0,
|
||||||
Ok(Number::Float(f)) => {
|
_ => false,
|
||||||
f > OrderedFloat(0f64)
|
|
||||||
}
|
|
||||||
Ok(Number::Integer(n)) => {
|
|
||||||
&*n > &0
|
|
||||||
}
|
|
||||||
Ok(Number::Rational(n)) => {
|
|
||||||
&*n > &0
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@@ -298,8 +290,8 @@ fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp
|
|||||||
|
|
||||||
fn numbervar(n: Integer) -> Var {
|
fn numbervar(n: Integer) -> Var {
|
||||||
static CHAR_CODES: [char; 26] = [
|
static CHAR_CODES: [char; 26] = [
|
||||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
|
||||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||||
];
|
];
|
||||||
|
|
||||||
let i = n.mod_u(26) as usize;
|
let i = n.mod_u(26) as usize;
|
||||||
@@ -332,9 +324,7 @@ impl MachineState {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => None,
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -446,8 +436,7 @@ fn non_quoted_graphic_token<Iter: Iterator<Item = char>>(mut iter: Iter, c: char
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn non_quoted_token<Iter: Iterator<Item = char>>(mut iter: Iter) -> bool {
|
||||||
fn non_quoted_token<Iter: Iterator<Item = char>>(mut iter: Iter) -> bool {
|
|
||||||
if let Some(c) = iter.next() {
|
if let Some(c) = iter.next() {
|
||||||
if small_letter_char!(c) {
|
if small_letter_char!(c) {
|
||||||
iter.all(|c| alpha_numeric_char!(c))
|
iter.all(|c| alpha_numeric_char!(c))
|
||||||
@@ -555,7 +544,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -579,7 +569,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
if self.check_max_depth(&mut max_depth) {
|
if self.check_max_depth(&mut max_depth) {
|
||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -587,7 +578,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
|
let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, left_directed_op));
|
self.state_stack.push(TokenOrRedirect::CompositeRedirect(
|
||||||
|
max_depth,
|
||||||
|
left_directed_op,
|
||||||
|
));
|
||||||
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
||||||
} else {
|
} else {
|
||||||
match ct.name().as_str() {
|
match ct.name().as_str() {
|
||||||
@@ -602,9 +596,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -612,11 +608,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
|
let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
|
||||||
let right_directed_op = DirectedOp::Right(ct.name(), spec.clone());
|
let right_directed_op = DirectedOp::Right(ct.name(), spec.clone());
|
||||||
|
|
||||||
self.state_stack
|
self.state_stack.push(TokenOrRedirect::CompositeRedirect(
|
||||||
.push(TokenOrRedirect::CompositeRedirect(max_depth, left_directed_op));
|
max_depth,
|
||||||
|
left_directed_op,
|
||||||
|
));
|
||||||
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
||||||
self.state_stack
|
self.state_stack.push(TokenOrRedirect::CompositeRedirect(
|
||||||
.push(TokenOrRedirect::CompositeRedirect(max_depth, right_directed_op));
|
max_depth,
|
||||||
|
right_directed_op,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,15 +626,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
mut max_depth: usize,
|
mut max_depth: usize,
|
||||||
arity: usize,
|
arity: usize,
|
||||||
name: ClauseName,
|
name: ClauseName,
|
||||||
) -> bool
|
) -> bool {
|
||||||
{
|
|
||||||
if self.check_max_depth(&mut max_depth) {
|
if self.check_max_depth(&mut max_depth) {
|
||||||
for _ in 0..arity {
|
for _ in 0..arity {
|
||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Close);
|
self.state_stack.push(TokenOrRedirect::Close);
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
self.state_stack.push(TokenOrRedirect::Open);
|
self.state_stack.push(TokenOrRedirect::Open);
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(name));
|
self.state_stack.push(TokenOrRedirect::Atom(name));
|
||||||
@@ -645,7 +645,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
self.state_stack.push(TokenOrRedirect::Close);
|
self.state_stack.push(TokenOrRedirect::Close);
|
||||||
|
|
||||||
for _ in 0..arity {
|
for _ in 0..arity {
|
||||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||||
self.state_stack.push(TokenOrRedirect::Comma);
|
self.state_stack.push(TokenOrRedirect::Comma);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -662,12 +663,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
iter: &mut HCPreOrderIterator,
|
iter: &mut HCPreOrderIterator,
|
||||||
mut max_depth: usize,
|
mut max_depth: usize,
|
||||||
name: ClauseName,
|
name: ClauseName,
|
||||||
spec: SharedOpDesc)
|
spec: SharedOpDesc,
|
||||||
{
|
) {
|
||||||
if self.check_max_depth(&mut max_depth) {
|
if self.check_max_depth(&mut max_depth) {
|
||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
self.state_stack.push(TokenOrRedirect::Space);
|
self.state_stack.push(TokenOrRedirect::Space);
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(name));
|
self.state_stack.push(TokenOrRedirect::Atom(name));
|
||||||
|
|
||||||
@@ -676,7 +678,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
let op = DirectedOp::Left(name.clone(), spec);
|
let op = DirectedOp::Left(name.clone(), spec);
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, op));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::CompositeRedirect(max_depth, op));
|
||||||
self.state_stack.push(TokenOrRedirect::Space);
|
self.state_stack.push(TokenOrRedirect::Space);
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(name));
|
self.state_stack.push(TokenOrRedirect::Atom(name));
|
||||||
}
|
}
|
||||||
@@ -687,14 +690,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
mut max_depth: usize,
|
mut max_depth: usize,
|
||||||
name: ClauseName,
|
name: ClauseName,
|
||||||
spec: SharedOpDesc,
|
spec: SharedOpDesc,
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
if self.check_max_depth(&mut max_depth) {
|
if self.check_max_depth(&mut max_depth) {
|
||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
self.state_stack.push(TokenOrRedirect::BarAsOp);
|
self.state_stack.push(TokenOrRedirect::BarAsOp);
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -702,25 +706,32 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
let left_directed_op = DirectedOp::Left(name.clone(), spec.clone());
|
let left_directed_op = DirectedOp::Left(name.clone(), spec.clone());
|
||||||
let right_directed_op = DirectedOp::Right(name.clone(), spec.clone());
|
let right_directed_op = DirectedOp::Right(name.clone(), spec.clone());
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, left_directed_op));
|
self.state_stack.push(TokenOrRedirect::CompositeRedirect(
|
||||||
|
max_depth,
|
||||||
|
left_directed_op,
|
||||||
|
));
|
||||||
self.state_stack.push(TokenOrRedirect::BarAsOp);
|
self.state_stack.push(TokenOrRedirect::BarAsOp);
|
||||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, right_directed_op));
|
self.state_stack.push(TokenOrRedirect::CompositeRedirect(
|
||||||
|
max_depth,
|
||||||
|
right_directed_op,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format_curly_braces(&mut self, iter: &mut HCPreOrderIterator, mut max_depth: usize) -> bool
|
fn format_curly_braces(&mut self, iter: &mut HCPreOrderIterator, mut max_depth: usize) -> bool {
|
||||||
{
|
|
||||||
if self.check_max_depth(&mut max_depth) {
|
if self.check_max_depth(&mut max_depth) {
|
||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::RightCurly);
|
self.state_stack.push(TokenOrRedirect::RightCurly);
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
self.state_stack.push(TokenOrRedirect::LeftCurly);
|
self.state_stack.push(TokenOrRedirect::LeftCurly);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::RightCurly);
|
self.state_stack.push(TokenOrRedirect::RightCurly);
|
||||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||||
self.state_stack.push(TokenOrRedirect::LeftCurly);
|
self.state_stack.push(TokenOrRedirect::LeftCurly);
|
||||||
|
|
||||||
true
|
true
|
||||||
@@ -795,18 +806,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match addr {
|
match addr {
|
||||||
Addr::Lis(h) | Addr::Str(h) => {
|
Addr::Lis(h) | Addr::Str(h) => Some(format!("{}", h)),
|
||||||
Some(format!("{}", h))
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
if let Some(r) = addr.as_var() {
|
if let Some(r) = addr.as_var() {
|
||||||
match r {
|
match r {
|
||||||
Ref::StackCell(fr, sc) => {
|
Ref::StackCell(fr, sc) => Some(format!("_s_{}_{}", fr, sc)),
|
||||||
Some(format!("_s_{}_{}", fr, sc))
|
Ref::HeapCell(h) | Ref::AttrVar(h) => Some(format!("_{}", h)),
|
||||||
}
|
|
||||||
Ref::HeapCell(h) | Ref::AttrVar(h) => {
|
|
||||||
Some(format!("_{}", h))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -818,8 +823,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
fn record_children_as_non_cyclic(&mut self, addr: &Addr) {
|
fn record_children_as_non_cyclic(&mut self, addr: &Addr) {
|
||||||
match addr {
|
match addr {
|
||||||
&Addr::Lis(l) => {
|
&Addr::Lis(l) => {
|
||||||
let c1 = self.machine_st.store(self.machine_st.deref(Addr::HeapCell(l)));
|
let c1 = self
|
||||||
let c2 = self.machine_st.store(self.machine_st.deref(Addr::HeapCell(l + 1)));
|
.machine_st
|
||||||
|
.store(self.machine_st.deref(Addr::HeapCell(l)));
|
||||||
|
let c2 = self
|
||||||
|
.machine_st
|
||||||
|
.store(self.machine_st.deref(Addr::HeapCell(l + 1)));
|
||||||
|
|
||||||
if let Some(c) = functor_location(&c1) {
|
if let Some(c) = functor_location(&c1) {
|
||||||
self.non_cyclic_terms.insert(c);
|
self.non_cyclic_terms.insert(c);
|
||||||
@@ -830,18 +839,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Addr::Str(s) => {
|
&Addr::Str(s) => {
|
||||||
let arity =
|
let arity = match &self.machine_st.heap[s] {
|
||||||
match &self.machine_st.heap[s] {
|
HeapCellValue::NamedStr(arity, ..) => arity,
|
||||||
HeapCellValue::NamedStr(arity, ..) => {
|
|
||||||
arity
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for i in 1..arity + 1 {
|
for i in 1..arity + 1 {
|
||||||
let c = self.machine_st.store(self.machine_st.deref(Addr::HeapCell(s + i)));
|
let c = self
|
||||||
|
.machine_st
|
||||||
|
.store(self.machine_st.deref(Addr::HeapCell(s + i)));
|
||||||
|
|
||||||
if let Some(c) = functor_location(&c) {
|
if let Some(c) = functor_location(&c) {
|
||||||
self.non_cyclic_terms.insert(c);
|
self.non_cyclic_terms.insert(c);
|
||||||
@@ -856,15 +864,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
self.non_cyclic_terms.insert(c);
|
self.non_cyclic_terms.insert(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_for_seen(
|
fn check_for_seen(&mut self, iter: &mut HCPreOrderIterator) -> Option<Addr> {
|
||||||
&mut self,
|
|
||||||
iter: &mut HCPreOrderIterator,
|
|
||||||
) -> Option<Addr> {
|
|
||||||
iter.stack().last().cloned().and_then(|addr| {
|
iter.stack().last().cloned().and_then(|addr| {
|
||||||
let addr = self.machine_st.store(self.machine_st.deref(addr));
|
let addr = self.machine_st.store(self.machine_st.deref(addr));
|
||||||
|
|
||||||
@@ -889,9 +893,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let offset = match functor_location(&addr) {
|
let offset = match functor_location(&addr) {
|
||||||
Some(offset) => {
|
Some(offset) => offset,
|
||||||
offset
|
|
||||||
}
|
|
||||||
None => {
|
None => {
|
||||||
return iter.next();
|
return iter.next();
|
||||||
}
|
}
|
||||||
@@ -1036,15 +1038,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
let rdiv_ct = clause_name!("rdiv");
|
let rdiv_ct = clause_name!("rdiv");
|
||||||
|
|
||||||
let left_directed_op =
|
let left_directed_op = if spec.prec() > 0 {
|
||||||
if spec.prec() > 0 {
|
|
||||||
Some(DirectedOp::Left(rdiv_ct.clone(), spec.clone()))
|
Some(DirectedOp::Left(rdiv_ct.clone(), spec.clone()))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let right_directed_op =
|
let right_directed_op = if spec.prec() > 0 {
|
||||||
if spec.prec() > 0 {
|
|
||||||
Some(DirectedOp::Right(rdiv_ct.clone(), spec.clone()))
|
Some(DirectedOp::Right(rdiv_ct.clone(), spec.clone()))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -1056,10 +1056,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
left_directed_op,
|
left_directed_op,
|
||||||
));
|
));
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Op(
|
self.state_stack
|
||||||
rdiv_ct,
|
.push(TokenOrRedirect::Op(rdiv_ct, spec.clone()));
|
||||||
spec.clone(),
|
|
||||||
));
|
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Number(
|
self.state_stack.push(TokenOrRedirect::Number(
|
||||||
Number::from(r.numer()),
|
Number::from(r.numer()),
|
||||||
@@ -1068,17 +1066,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
} else {
|
} else {
|
||||||
self.state_stack.push(TokenOrRedirect::Close);
|
self.state_stack.push(TokenOrRedirect::Close);
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Number(
|
self.state_stack
|
||||||
Number::from(r.denom()),
|
.push(TokenOrRedirect::Number(Number::from(r.denom()), None));
|
||||||
None,
|
|
||||||
));
|
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Comma);
|
self.state_stack.push(TokenOrRedirect::Comma);
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Number(
|
self.state_stack
|
||||||
Number::from(r.numer()),
|
.push(TokenOrRedirect::Number(Number::from(r.numer()), None));
|
||||||
None,
|
|
||||||
));
|
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Open);
|
self.state_stack.push(TokenOrRedirect::Open);
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(rdiv_ct));
|
self.state_stack.push(TokenOrRedirect::Atom(rdiv_ct));
|
||||||
@@ -1092,8 +1086,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_char(&mut self, is_quoted: bool, c: char)
|
fn print_char(&mut self, is_quoted: bool, c: char) {
|
||||||
{
|
|
||||||
if non_quoted_token(once(c)) {
|
if non_quoted_token(once(c)) {
|
||||||
let c = char_to_string(false, c);
|
let c = char_to_string(false, c);
|
||||||
|
|
||||||
@@ -1120,15 +1113,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
fn print_proper_string(&mut self, buf: String, max_depth: usize) {
|
fn print_proper_string(&mut self, buf: String, max_depth: usize) {
|
||||||
self.push_char('"');
|
self.push_char('"');
|
||||||
|
|
||||||
let buf =
|
let buf = if max_depth == 0 {
|
||||||
if max_depth == 0 {
|
String::from_iter(buf.chars().map(|c| char_to_string(self.quoted, c)))
|
||||||
String::from_iter(buf.chars().map(|c| {
|
|
||||||
char_to_string(self.quoted, c)
|
|
||||||
}))
|
|
||||||
} else {
|
} else {
|
||||||
let mut char_count = 0;
|
let mut char_count = 0;
|
||||||
let mut buf =
|
let mut buf = String::from_iter(buf.chars().take(max_depth).map(|c| {
|
||||||
String::from_iter(buf.chars().take(max_depth).map(|c| {
|
|
||||||
char_count += 1;
|
char_count += 1;
|
||||||
char_to_string(self.quoted, c)
|
char_to_string(self.quoted, c)
|
||||||
}));
|
}));
|
||||||
@@ -1144,22 +1133,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
self.push_char('"');
|
self.push_char('"');
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_list_like(
|
fn print_list_like(&mut self, iter: &mut HCPreOrderIterator, addr: Addr, mut max_depth: usize) {
|
||||||
&mut self,
|
|
||||||
iter: &mut HCPreOrderIterator,
|
|
||||||
addr: Addr,
|
|
||||||
mut max_depth: usize,
|
|
||||||
) {
|
|
||||||
if self.check_max_depth(&mut max_depth) {
|
if self.check_max_depth(&mut max_depth) {
|
||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut heap_pstr_iter =
|
let mut heap_pstr_iter = self.machine_st.heap_pstr_iter(addr);
|
||||||
self.machine_st.heap_pstr_iter(addr);
|
|
||||||
|
|
||||||
let buf = heap_pstr_iter.to_string();
|
let buf = heap_pstr_iter.to_string();
|
||||||
|
|
||||||
@@ -1184,8 +1168,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
let buf_len = buf.len();
|
let buf_len = buf.len();
|
||||||
|
|
||||||
let buf_iter: Box<dyn Iterator<Item=char>> =
|
let buf_iter: Box<dyn Iterator<Item = char>> = if self.max_depth == 0 {
|
||||||
if self.max_depth == 0 {
|
|
||||||
Box::new(buf.chars())
|
Box::new(buf.chars())
|
||||||
} else {
|
} else {
|
||||||
Box::new(buf.chars().take(max_depth))
|
Box::new(buf.chars().take(max_depth))
|
||||||
@@ -1212,9 +1195,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.max_depth > 0 && buf_len > byte_len {
|
if self.max_depth > 0 && buf_len > byte_len {
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
} else {
|
} else {
|
||||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||||
iter.stack().push(end_addr);
|
iter.stack().push(end_addr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1232,15 +1217,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
byte_len += c.len_utf8();
|
byte_len += c.len_utf8();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::CloseList(Rc::new(
|
self.state_stack
|
||||||
Cell::new((switch, 0))
|
.push(TokenOrRedirect::CloseList(Rc::new(Cell::new((switch, 0)))));
|
||||||
)));
|
|
||||||
|
|
||||||
if self.max_depth > 0 && buf_len > byte_len {
|
if self.max_depth > 0 && buf_len > byte_len {
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
} else {
|
} else {
|
||||||
self.outputter.truncate(self.outputter.len() - ','.len_utf8());
|
self.outputter
|
||||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
.truncate(self.outputter.len() - ','.len_utf8());
|
||||||
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||||
|
|
||||||
iter.stack().push(end_addr);
|
iter.stack().push(end_addr);
|
||||||
}
|
}
|
||||||
@@ -1268,8 +1255,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
let cell = Rc::new(Cell::new((true, 0)));
|
let cell = Rc::new(Cell::new((true, 0)));
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::CloseList(cell.clone()));
|
self.state_stack
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
.push(TokenOrRedirect::CloseList(cell.clone()));
|
||||||
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
self.state_stack.push(TokenOrRedirect::OpenList(cell));
|
self.state_stack.push(TokenOrRedirect::OpenList(cell));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -1277,11 +1266,14 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
let cell = Rc::new(Cell::new((true, max_depth)));
|
let cell = Rc::new(Cell::new((true, max_depth)));
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::CloseList(cell.clone()));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::CloseList(cell.clone()));
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||||
self.state_stack.push(TokenOrRedirect::HeadTailSeparator); // bar
|
self.state_stack.push(TokenOrRedirect::HeadTailSeparator); // bar
|
||||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::OpenList(cell));
|
self.state_stack.push(TokenOrRedirect::OpenList(cell));
|
||||||
}
|
}
|
||||||
@@ -1298,7 +1290,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
max_depth: usize,
|
max_depth: usize,
|
||||||
) {
|
) {
|
||||||
let add_brackets = if !self.ignore_ops {
|
let add_brackets = if !self.ignore_ops {
|
||||||
negated_operand || if let Some(ref op) = op {
|
negated_operand
|
||||||
|
|| if let Some(ref op) = op {
|
||||||
if self.numbervars && arity == 1 && name.as_str() == "$VAR" {
|
if self.numbervars && arity == 1 && name.as_str() == "$VAR" {
|
||||||
!iter.immediate_leaf_has_property(|addr, heap| {
|
!iter.immediate_leaf_has_property(|addr, heap| {
|
||||||
match heap.index_addr(&addr).as_ref() {
|
match heap.index_addr(&addr).as_ref() {
|
||||||
@@ -1306,7 +1299,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
&HeapCellValue::Addr(Addr::Fixnum(n)) => n >= 0,
|
&HeapCellValue::Addr(Addr::Fixnum(n)) => n >= 0,
|
||||||
&HeapCellValue::Addr(Addr::Float(f)) => f >= OrderedFloat(0f64),
|
&HeapCellValue::Addr(Addr::Float(f)) => f >= OrderedFloat(0f64),
|
||||||
&HeapCellValue::Rational(ref r) => &**r >= &0,
|
&HeapCellValue::Rational(ref r) => &**r >= &0,
|
||||||
_ => false
|
_ => false,
|
||||||
}
|
}
|
||||||
}) && needs_bracketing(&spec, op)
|
}) && needs_bracketing(&spec, op)
|
||||||
} else {
|
} else {
|
||||||
@@ -1344,12 +1337,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
tcp_listener: &TcpListener,
|
tcp_listener: &TcpListener,
|
||||||
max_depth: usize,
|
max_depth: usize,
|
||||||
) {
|
) {
|
||||||
let (ip, port) =
|
let (ip, port) = if let Some(addr) = tcp_listener.local_addr().ok() {
|
||||||
if let Some(addr) = tcp_listener.local_addr().ok() {
|
|
||||||
(addr.ip(), Number::from(addr.port() as isize))
|
(addr.ip(), Number::from(addr.port() as isize))
|
||||||
} else {
|
} else {
|
||||||
let disconnected_atom = clause_name!("$disconnected_tcp_listener");
|
let disconnected_atom = clause_name!("$disconnected_tcp_listener");
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(disconnected_atom));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(disconnected_atom));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@@ -1369,18 +1362,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_stream(
|
fn print_stream(&mut self, iter: &mut HCPreOrderIterator, stream: &Stream, max_depth: usize) {
|
||||||
&mut self,
|
|
||||||
iter: &mut HCPreOrderIterator,
|
|
||||||
stream: &Stream,
|
|
||||||
max_depth: usize,
|
|
||||||
) {
|
|
||||||
if let Some(alias) = &stream.options.alias {
|
if let Some(alias) = &stream.options.alias {
|
||||||
self.print_atom(alias);
|
self.print_atom(alias);
|
||||||
} else {
|
} else {
|
||||||
if self.format_struct(iter, max_depth, 1, clause_name!("$stream")) {
|
if self.format_struct(iter, max_depth, 1, clause_name!("$stream")) {
|
||||||
let atom =
|
let atom = if stream.is_stdout() || stream.is_stdin() {
|
||||||
if stream.is_stdout() || stream.is_stdin() {
|
|
||||||
TokenOrRedirect::Atom(clause_name!("user"))
|
TokenOrRedirect::Atom(clause_name!("user"))
|
||||||
} else {
|
} else {
|
||||||
TokenOrRedirect::RawPtr(stream.as_ptr())
|
TokenOrRedirect::RawPtr(stream.as_ptr())
|
||||||
@@ -1414,7 +1401,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
match self.machine_st.heap.index_addr(&addr).as_ref() {
|
match self.machine_st.heap.index_addr(&addr).as_ref() {
|
||||||
&HeapCellValue::NamedStr(arity, ref name, ref spec) => {
|
&HeapCellValue::NamedStr(arity, ref name, ref spec) => {
|
||||||
let spec = fetch_op_spec_from_existing(name.clone(), arity, spec.clone(), self.op_dir);
|
let spec =
|
||||||
|
fetch_op_spec_from_existing(name.clone(), arity, spec.clone(), self.op_dir);
|
||||||
|
|
||||||
if let Some(spec) = spec {
|
if let Some(spec) = spec {
|
||||||
self.handle_op_as_struct(
|
self.handle_op_as_struct(
|
||||||
|
|||||||
344
src/indexing.rs
344
src/indexing.rs
@@ -1,4 +1,5 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use crate::prolog_parser_rebis::ast::*;
|
||||||
|
use crate::prolog_parser_rebis::clause_name;
|
||||||
use crate::prolog_parser_rebis::tabled_rc::*;
|
use crate::prolog_parser_rebis::tabled_rc::*;
|
||||||
|
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
@@ -43,14 +44,10 @@ impl OptArgIndexKey {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn has_key_type(&self, key_type: OptArgIndexKeyType) -> bool {
|
fn has_key_type(&self, key_type: OptArgIndexKeyType) -> bool {
|
||||||
match (self, key_type) {
|
match (self, key_type) {
|
||||||
(OptArgIndexKey::Constant(..), OptArgIndexKeyType::Constant) |
|
(OptArgIndexKey::Constant(..), OptArgIndexKeyType::Constant)
|
||||||
(OptArgIndexKey::Structure(..), OptArgIndexKeyType::Structure) |
|
| (OptArgIndexKey::Structure(..), OptArgIndexKeyType::Structure)
|
||||||
(OptArgIndexKey::List(..), OptArgIndexKeyType::List) => {
|
| (OptArgIndexKey::List(..), OptArgIndexKeyType::List) => true,
|
||||||
true
|
_ => false,
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,12 +90,16 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
indexing_code: &'a mut Vec<IndexingLine>,
|
indexing_code: &'a mut Vec<IndexingLine>,
|
||||||
append_or_prepend: AppendOrPrepend,
|
append_or_prepend: AppendOrPrepend,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self { skeleton, indexing_code, offset: 0, append_or_prepend }
|
Self {
|
||||||
|
skeleton,
|
||||||
|
indexing_code,
|
||||||
|
offset: 0,
|
||||||
|
append_or_prepend,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn internalize_constant(&mut self, constant_ptr: IndexingCodePtr) {
|
fn internalize_constant(&mut self, constant_ptr: IndexingCodePtr) {
|
||||||
let constant_key =
|
let constant_key = search_skeleton_for_first_key_type(
|
||||||
search_skeleton_for_first_key_type(
|
|
||||||
self.skeleton,
|
self.skeleton,
|
||||||
OptArgIndexKeyType::Constant,
|
OptArgIndexKeyType::Constant,
|
||||||
self.append_or_prepend,
|
self.append_or_prepend,
|
||||||
@@ -117,7 +118,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
|
|
||||||
if let IndexingCodePtr::Internal(_) = constant_ptr {
|
if let IndexingCodePtr::Internal(_) = constant_ptr {
|
||||||
self.indexing_code.push(IndexingLine::Indexing(
|
self.indexing_code.push(IndexingLine::Indexing(
|
||||||
IndexingInstruction::SwitchOnConstant(constants)
|
IndexingInstruction::SwitchOnConstant(constants),
|
||||||
));
|
));
|
||||||
|
|
||||||
let last_index = self.indexing_code.len() - 1;
|
let last_index = self.indexing_code.len() - 1;
|
||||||
@@ -126,15 +127,18 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
self.offset = self.indexing_code.len();
|
self.offset = self.indexing_code.len();
|
||||||
|
|
||||||
self.indexing_code.push(IndexingLine::Indexing(
|
self.indexing_code.push(IndexingLine::Indexing(
|
||||||
IndexingInstruction::SwitchOnConstant(constants)
|
IndexingInstruction::SwitchOnConstant(constants),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_indexed_choice_for_constant(&mut self, external: usize, constant: Constant, index: usize)
|
fn add_indexed_choice_for_constant(
|
||||||
{
|
&mut self,
|
||||||
let third_level_index =
|
external: usize,
|
||||||
if self.append_or_prepend.is_append() {
|
constant: Constant,
|
||||||
|
index: usize,
|
||||||
|
) {
|
||||||
|
let third_level_index = if self.append_or_prepend.is_append() {
|
||||||
sdeq![
|
sdeq![
|
||||||
IndexedChoiceInstruction::Try(external),
|
IndexedChoiceInstruction::Try(external),
|
||||||
IndexedChoiceInstruction::Trust(index)
|
IndexedChoiceInstruction::Trust(index)
|
||||||
@@ -147,13 +151,15 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let indexing_code_len = self.indexing_code.len();
|
let indexing_code_len = self.indexing_code.len();
|
||||||
self.indexing_code.push(IndexingLine::IndexedChoice(third_level_index));
|
self.indexing_code
|
||||||
|
.push(IndexingLine::IndexedChoice(third_level_index));
|
||||||
|
|
||||||
match &mut self.indexing_code[self.offset] {
|
match &mut self.indexing_code[self.offset] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(ref mut constants)) => {
|
||||||
IndexingInstruction::SwitchOnConstant(ref mut constants)
|
constants.insert(
|
||||||
) => {
|
constant,
|
||||||
constants.insert(constant, IndexingCodePtr::Internal(indexing_code_len - self.offset));
|
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -164,7 +170,8 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
fn extend_indexed_choice(&mut self, index: usize) {
|
fn extend_indexed_choice(&mut self, index: usize) {
|
||||||
match &mut self.indexing_code[self.offset] {
|
match &mut self.indexing_code[self.offset] {
|
||||||
IndexingLine::IndexedChoice(ref mut indexed_choice_instrs)
|
IndexingLine::IndexedChoice(ref mut indexed_choice_instrs)
|
||||||
if self.append_or_prepend.is_append() => {
|
if self.append_or_prepend.is_append() =>
|
||||||
|
{
|
||||||
uncap_choice_seq_with_trust(indexed_choice_instrs);
|
uncap_choice_seq_with_trust(indexed_choice_instrs);
|
||||||
indexed_choice_instrs.push_back(IndexedChoiceInstruction::Trust(index));
|
indexed_choice_instrs.push_back(IndexedChoiceInstruction::Trust(index));
|
||||||
}
|
}
|
||||||
@@ -188,9 +195,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
let indexing_code_len = self.indexing_code.len();
|
let indexing_code_len = self.indexing_code.len();
|
||||||
|
|
||||||
match &mut self.indexing_code[self.offset] {
|
match &mut self.indexing_code[self.offset] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
|
||||||
) => {
|
|
||||||
match *c {
|
match *c {
|
||||||
IndexingCodePtr::Fail => {
|
IndexingCodePtr::Fail => {
|
||||||
*c = IndexingCodePtr::External(index);
|
*c = IndexingCodePtr::External(index);
|
||||||
@@ -203,7 +208,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
*c = IndexingCodePtr::Internal(indexing_code_len);
|
*c = IndexingCodePtr::Internal(indexing_code_len);
|
||||||
|
|
||||||
self.indexing_code.push(IndexingLine::Indexing(
|
self.indexing_code.push(IndexingLine::Indexing(
|
||||||
IndexingInstruction::SwitchOnConstant(constants)
|
IndexingInstruction::SwitchOnConstant(constants),
|
||||||
));
|
));
|
||||||
|
|
||||||
self.offset = indexing_code_len;
|
self.offset = indexing_code_len;
|
||||||
@@ -213,12 +218,11 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(constants)) => {
|
||||||
IndexingInstruction::SwitchOnConstant(constants)
|
|
||||||
) => {
|
|
||||||
match constants.get(&overlapping_constant).cloned() {
|
match constants.get(&overlapping_constant).cloned() {
|
||||||
None | Some(IndexingCodePtr::Fail) => {
|
None | Some(IndexingCodePtr::Fail) => {
|
||||||
constants.insert(overlapping_constant, IndexingCodePtr::External(index));
|
constants
|
||||||
|
.insert(overlapping_constant, IndexingCodePtr::External(index));
|
||||||
}
|
}
|
||||||
Some(IndexingCodePtr::External(o)) => {
|
Some(IndexingCodePtr::External(o)) => {
|
||||||
self.add_indexed_choice_for_constant(o, overlapping_constant, index);
|
self.add_indexed_choice_for_constant(o, overlapping_constant, index);
|
||||||
@@ -232,9 +236,9 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
IndexingLine::IndexedChoice(_) => {
|
IndexingLine::IndexedChoice(_) => {
|
||||||
self.internalize_constant(
|
self.internalize_constant(IndexingCodePtr::Internal(
|
||||||
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
indexing_code_len - self.offset,
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -248,9 +252,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
let indexing_code_len = self.indexing_code.len();
|
let indexing_code_len = self.indexing_code.len();
|
||||||
|
|
||||||
match &mut self.indexing_code[self.offset] {
|
match &mut self.indexing_code[self.offset] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
|
||||||
) => {
|
|
||||||
match *c {
|
match *c {
|
||||||
IndexingCodePtr::Fail => {
|
IndexingCodePtr::Fail => {
|
||||||
*c = IndexingCodePtr::External(index);
|
*c = IndexingCodePtr::External(index);
|
||||||
@@ -265,9 +267,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(constants)) => {
|
||||||
IndexingInstruction::SwitchOnConstant(constants)
|
|
||||||
) => {
|
|
||||||
match constants.get(&constant).cloned() {
|
match constants.get(&constant).cloned() {
|
||||||
None | Some(IndexingCodePtr::Fail) => {
|
None | Some(IndexingCodePtr::Fail) => {
|
||||||
constants.insert(constant, IndexingCodePtr::External(index));
|
constants.insert(constant, IndexingCodePtr::External(index));
|
||||||
@@ -284,9 +284,9 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
IndexingLine::IndexedChoice(_) => {
|
IndexingLine::IndexedChoice(_) => {
|
||||||
self.internalize_constant(
|
self.internalize_constant(IndexingCodePtr::Internal(
|
||||||
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
indexing_code_len - self.offset,
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -296,8 +296,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn internalize_structure(&mut self, structure_ptr: IndexingCodePtr) {
|
fn internalize_structure(&mut self, structure_ptr: IndexingCodePtr) {
|
||||||
let structure_key =
|
let structure_key = search_skeleton_for_first_key_type(
|
||||||
search_skeleton_for_first_key_type(
|
|
||||||
self.skeleton,
|
self.skeleton,
|
||||||
OptArgIndexKeyType::Structure,
|
OptArgIndexKeyType::Structure,
|
||||||
self.append_or_prepend,
|
self.append_or_prepend,
|
||||||
@@ -316,7 +315,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
|
|
||||||
if let IndexingCodePtr::Internal(_) = structure_ptr {
|
if let IndexingCodePtr::Internal(_) = structure_ptr {
|
||||||
self.indexing_code.push(IndexingLine::Indexing(
|
self.indexing_code.push(IndexingLine::Indexing(
|
||||||
IndexingInstruction::SwitchOnStructure(structures)
|
IndexingInstruction::SwitchOnStructure(structures),
|
||||||
));
|
));
|
||||||
|
|
||||||
let last_index = self.indexing_code.len() - 1;
|
let last_index = self.indexing_code.len() - 1;
|
||||||
@@ -325,15 +324,18 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
self.offset = self.indexing_code.len();
|
self.offset = self.indexing_code.len();
|
||||||
|
|
||||||
self.indexing_code.push(IndexingLine::Indexing(
|
self.indexing_code.push(IndexingLine::Indexing(
|
||||||
IndexingInstruction::SwitchOnStructure(structures)
|
IndexingInstruction::SwitchOnStructure(structures),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_indexed_choice_for_structure(&mut self, external: usize, key: PredicateKey, index: usize)
|
fn add_indexed_choice_for_structure(
|
||||||
{
|
&mut self,
|
||||||
let third_level_index =
|
external: usize,
|
||||||
if self.append_or_prepend.is_append() {
|
key: PredicateKey,
|
||||||
|
index: usize,
|
||||||
|
) {
|
||||||
|
let third_level_index = if self.append_or_prepend.is_append() {
|
||||||
sdeq![
|
sdeq![
|
||||||
IndexedChoiceInstruction::Try(external),
|
IndexedChoiceInstruction::Try(external),
|
||||||
IndexedChoiceInstruction::Trust(index)
|
IndexedChoiceInstruction::Trust(index)
|
||||||
@@ -346,13 +348,15 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let indexing_code_len = self.indexing_code.len();
|
let indexing_code_len = self.indexing_code.len();
|
||||||
self.indexing_code.push(IndexingLine::IndexedChoice(third_level_index));
|
self.indexing_code
|
||||||
|
.push(IndexingLine::IndexedChoice(third_level_index));
|
||||||
|
|
||||||
match &mut self.indexing_code[self.offset] {
|
match &mut self.indexing_code[self.offset] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref mut structures)) => {
|
||||||
IndexingInstruction::SwitchOnStructure(ref mut structures)
|
structures.insert(
|
||||||
) => {
|
key,
|
||||||
structures.insert(key, IndexingCodePtr::Internal(indexing_code_len - self.offset));
|
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -365,10 +369,13 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
let indexing_code_len = self.indexing_code.len();
|
let indexing_code_len = self.indexing_code.len();
|
||||||
|
|
||||||
match &mut self.indexing_code[self.offset] {
|
match &mut self.indexing_code[self.offset] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)
|
_,
|
||||||
) => {
|
_,
|
||||||
match *s {
|
_,
|
||||||
|
_,
|
||||||
|
ref mut s,
|
||||||
|
)) => match *s {
|
||||||
IndexingCodePtr::Fail => {
|
IndexingCodePtr::Fail => {
|
||||||
*s = IndexingCodePtr::External(index);
|
*s = IndexingCodePtr::External(index);
|
||||||
break;
|
break;
|
||||||
@@ -380,11 +387,8 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
IndexingCodePtr::Internal(o) => {
|
IndexingCodePtr::Internal(o) => {
|
||||||
self.offset += o;
|
self.offset += o;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(structures)) => {
|
||||||
IndexingLine::Indexing(
|
|
||||||
IndexingInstruction::SwitchOnStructure(structures)
|
|
||||||
) => {
|
|
||||||
match structures.get(&key).cloned() {
|
match structures.get(&key).cloned() {
|
||||||
None | Some(IndexingCodePtr::Fail) => {
|
None | Some(IndexingCodePtr::Fail) => {
|
||||||
structures.insert(key, IndexingCodePtr::External(index));
|
structures.insert(key, IndexingCodePtr::External(index));
|
||||||
@@ -404,9 +408,9 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
// replace this value, at self.offset, with
|
// replace this value, at self.offset, with
|
||||||
// SwitchOnStructures, and swap this IndexedChoice
|
// SwitchOnStructures, and swap this IndexedChoice
|
||||||
// vector to the end of self.indexing_code.
|
// vector to the end of self.indexing_code.
|
||||||
self.internalize_structure(
|
self.internalize_structure(IndexingCodePtr::Internal(
|
||||||
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
indexing_code_len - self.offset,
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -419,9 +423,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
let indexing_code_len = self.indexing_code.len();
|
let indexing_code_len = self.indexing_code.len();
|
||||||
|
|
||||||
match &mut self.indexing_code[self.offset] {
|
match &mut self.indexing_code[self.offset] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)) => {
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)
|
|
||||||
) => {
|
|
||||||
match *l {
|
match *l {
|
||||||
IndexingCodePtr::Fail => {
|
IndexingCodePtr::Fail => {
|
||||||
*l = IndexingCodePtr::External(index);
|
*l = IndexingCodePtr::External(index);
|
||||||
@@ -429,8 +431,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
IndexingCodePtr::External(o) => {
|
IndexingCodePtr::External(o) => {
|
||||||
*l = IndexingCodePtr::Internal(indexing_code_len - self.offset);
|
*l = IndexingCodePtr::Internal(indexing_code_len - self.offset);
|
||||||
|
|
||||||
let third_level_index =
|
let third_level_index = if self.append_or_prepend.is_append() {
|
||||||
if self.append_or_prepend.is_append() {
|
|
||||||
sdeq![
|
sdeq![
|
||||||
IndexedChoiceInstruction::Try(o),
|
IndexedChoiceInstruction::Try(o),
|
||||||
IndexedChoiceInstruction::Trust(index)
|
IndexedChoiceInstruction::Trust(index)
|
||||||
@@ -442,9 +443,8 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
self.indexing_code.push(
|
self.indexing_code
|
||||||
IndexingLine::IndexedChoice(third_level_index),
|
.push(IndexingLine::IndexedChoice(third_level_index));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
IndexingCodePtr::Internal(o) => {
|
IndexingCodePtr::Internal(o) => {
|
||||||
self.offset += o;
|
self.offset += o;
|
||||||
@@ -465,21 +465,13 @@ pub fn merge_clause_index(
|
|||||||
new_clause_loc: usize, // the absolute location of the new clause in the code vector.
|
new_clause_loc: usize, // the absolute location of the new clause in the code vector.
|
||||||
append_or_prepend: AppendOrPrepend,
|
append_or_prepend: AppendOrPrepend,
|
||||||
) {
|
) {
|
||||||
let opt_arg_index_key =
|
let opt_arg_index_key = match append_or_prepend {
|
||||||
match append_or_prepend {
|
AppendOrPrepend::Append => skeleton.last_mut().unwrap().opt_arg_index_key.take(),
|
||||||
AppendOrPrepend::Append => {
|
AppendOrPrepend::Prepend => skeleton.first_mut().unwrap().opt_arg_index_key.take(),
|
||||||
skeleton.last_mut().unwrap().opt_arg_index_key.take()
|
|
||||||
}
|
|
||||||
AppendOrPrepend::Prepend => {
|
|
||||||
skeleton.first_mut().unwrap().opt_arg_index_key.take()
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut merging_ptr = IndexingCodeMergingPtr::new(
|
let mut merging_ptr =
|
||||||
skeleton,
|
IndexingCodeMergingPtr::new(skeleton, target_indexing_code, append_or_prepend);
|
||||||
target_indexing_code,
|
|
||||||
append_or_prepend,
|
|
||||||
);
|
|
||||||
|
|
||||||
match &opt_arg_index_key {
|
match &opt_arg_index_key {
|
||||||
OptArgIndexKey::Constant(_, index_loc, ref constant, ref overlapping_constants) => {
|
OptArgIndexKey::Constant(_, index_loc, ref constant, ref overlapping_constants) => {
|
||||||
@@ -488,7 +480,9 @@ pub fn merge_clause_index(
|
|||||||
|
|
||||||
for overlapping_constant in overlapping_constants {
|
for overlapping_constant in overlapping_constants {
|
||||||
merging_ptr.index_overlapping_constant(
|
merging_ptr.index_overlapping_constant(
|
||||||
constant, overlapping_constant.clone(), offset,
|
constant,
|
||||||
|
overlapping_constant.clone(),
|
||||||
|
offset,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -514,10 +508,7 @@ pub fn merge_clause_index(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn remove_instruction_with_offset(
|
fn remove_instruction_with_offset(code: &mut SliceDeque<IndexedChoiceInstruction>, offset: usize) {
|
||||||
code: &mut SliceDeque<IndexedChoiceInstruction>,
|
|
||||||
offset: usize,
|
|
||||||
) {
|
|
||||||
for (index, line) in code.iter().enumerate() {
|
for (index, line) in code.iter().enumerate() {
|
||||||
if offset == line.offset() {
|
if offset == line.offset() {
|
||||||
code.remove(index);
|
code.remove(index);
|
||||||
@@ -537,9 +528,7 @@ pub fn remove_constant_indices(
|
|||||||
let iter = once(constant).chain(overlapping_constants.iter());
|
let iter = once(constant).chain(overlapping_constants.iter());
|
||||||
|
|
||||||
match &mut indexing_code[index] {
|
match &mut indexing_code[index] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
|
||||||
) => {
|
|
||||||
match *c {
|
match *c {
|
||||||
IndexingCodePtr::External(_) => {
|
IndexingCodePtr::External(_) => {
|
||||||
*c = IndexingCodePtr::Fail;
|
*c = IndexingCodePtr::Fail;
|
||||||
@@ -560,12 +549,13 @@ pub fn remove_constant_indices(
|
|||||||
|
|
||||||
let mut constants_index = 0;
|
let mut constants_index = 0;
|
||||||
|
|
||||||
for constant in iter { // (constant, index_loc) in iter.zip(index_locs.iter()) {
|
for constant in iter {
|
||||||
|
// (constant, index_loc) in iter.zip(index_locs.iter()) {
|
||||||
loop {
|
loop {
|
||||||
match &mut indexing_code[index] {
|
match &mut indexing_code[index] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(
|
||||||
IndexingInstruction::SwitchOnConstant(ref mut constants)
|
ref mut constants,
|
||||||
) => {
|
)) => {
|
||||||
constants_index = index;
|
constants_index = index;
|
||||||
|
|
||||||
match constants.get(constant).cloned() {
|
match constants.get(constant).cloned() {
|
||||||
@@ -586,18 +576,21 @@ pub fn remove_constant_indices(
|
|||||||
|
|
||||||
if indexed_choice_instrs.len() == 1 {
|
if indexed_choice_instrs.len() == 1 {
|
||||||
let ext = IndexingCodePtr::External(
|
let ext = IndexingCodePtr::External(
|
||||||
indexed_choice_instrs.pop_back().unwrap().offset()
|
indexed_choice_instrs.pop_back().unwrap().offset(),
|
||||||
);
|
);
|
||||||
|
|
||||||
match &mut indexing_code[constants_index] {
|
match &mut indexing_code[constants_index] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
_,
|
||||||
) => {
|
_,
|
||||||
|
ref mut c,
|
||||||
|
..,
|
||||||
|
)) => {
|
||||||
*c = ext;
|
*c = ext;
|
||||||
}
|
}
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(
|
||||||
IndexingInstruction::SwitchOnConstant(ref mut constants)
|
ref mut constants,
|
||||||
) => {
|
)) => {
|
||||||
constants.insert(constant.clone(), ext);
|
constants.insert(constant.clone(), ext);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -616,13 +609,11 @@ pub fn remove_constant_indices(
|
|||||||
}
|
}
|
||||||
|
|
||||||
match &indexing_code[constants_index] {
|
match &indexing_code[constants_index] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(ref constants))
|
||||||
IndexingInstruction::SwitchOnConstant(ref constants)
|
if constants.is_empty() =>
|
||||||
) if constants.is_empty() => {
|
{
|
||||||
match &mut indexing_code[0] {
|
match &mut indexing_code[0] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
|
||||||
) => {
|
|
||||||
*c = IndexingCodePtr::Fail;
|
*c = IndexingCodePtr::Fail;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -630,8 +621,7 @@ pub fn remove_constant_indices(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -644,9 +634,7 @@ pub fn remove_structure_index(
|
|||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
|
|
||||||
match &mut indexing_code[index] {
|
match &mut indexing_code[index] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)) => {
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)
|
|
||||||
) => {
|
|
||||||
match *s {
|
match *s {
|
||||||
IndexingCodePtr::External(_) => {
|
IndexingCodePtr::External(_) => {
|
||||||
*s = IndexingCodePtr::Fail;
|
*s = IndexingCodePtr::Fail;
|
||||||
@@ -669,9 +657,7 @@ pub fn remove_structure_index(
|
|||||||
|
|
||||||
loop {
|
loop {
|
||||||
match &mut indexing_code[index] {
|
match &mut indexing_code[index] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref mut structures)) => {
|
||||||
IndexingInstruction::SwitchOnStructure(ref mut structures)
|
|
||||||
) => {
|
|
||||||
structures_index = index;
|
structures_index = index;
|
||||||
|
|
||||||
match structures.get(&(name.clone(), arity)).cloned() {
|
match structures.get(&(name.clone(), arity)).cloned() {
|
||||||
@@ -692,18 +678,22 @@ pub fn remove_structure_index(
|
|||||||
|
|
||||||
if indexed_choice_instrs.len() == 1 {
|
if indexed_choice_instrs.len() == 1 {
|
||||||
let ext = IndexingCodePtr::External(
|
let ext = IndexingCodePtr::External(
|
||||||
indexed_choice_instrs.pop_back().unwrap().offset()
|
indexed_choice_instrs.pop_back().unwrap().offset(),
|
||||||
);
|
);
|
||||||
|
|
||||||
match &mut indexing_code[structures_index] {
|
match &mut indexing_code[structures_index] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)
|
_,
|
||||||
) => {
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
ref mut s,
|
||||||
|
)) => {
|
||||||
*s = ext;
|
*s = ext;
|
||||||
}
|
}
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(
|
||||||
IndexingInstruction::SwitchOnStructure(ref mut structures)
|
ref mut structures,
|
||||||
) => {
|
)) => {
|
||||||
structures.insert((name.clone(), arity), ext);
|
structures.insert((name.clone(), arity), ext);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -721,13 +711,17 @@ pub fn remove_structure_index(
|
|||||||
}
|
}
|
||||||
|
|
||||||
match &indexing_code[structures_index] {
|
match &indexing_code[structures_index] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref structures))
|
||||||
IndexingInstruction::SwitchOnStructure(ref structures)
|
if structures.is_empty() =>
|
||||||
) if structures.is_empty() => {
|
{
|
||||||
match &mut indexing_code[0] {
|
match &mut indexing_code[0] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)
|
_,
|
||||||
) => {
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
ref mut s,
|
||||||
|
)) => {
|
||||||
*s = IndexingCodePtr::Fail;
|
*s = IndexingCodePtr::Fail;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -735,21 +729,15 @@ pub fn remove_structure_index(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_list_index(
|
pub fn remove_list_index(indexing_code: &mut Vec<IndexingLine>, offset: usize) {
|
||||||
indexing_code: &mut Vec<IndexingLine>,
|
|
||||||
offset: usize,
|
|
||||||
) {
|
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
|
|
||||||
match &mut indexing_code[index] {
|
match &mut indexing_code[index] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)) => {
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)
|
|
||||||
) => {
|
|
||||||
match *l {
|
match *l {
|
||||||
IndexingCodePtr::External(_) => {
|
IndexingCodePtr::External(_) => {
|
||||||
*l = IndexingCodePtr::Fail;
|
*l = IndexingCodePtr::Fail;
|
||||||
@@ -773,14 +761,17 @@ pub fn remove_list_index(
|
|||||||
remove_instruction_with_offset(indexed_choice_instrs, offset);
|
remove_instruction_with_offset(indexed_choice_instrs, offset);
|
||||||
|
|
||||||
if indexed_choice_instrs.len() == 1 {
|
if indexed_choice_instrs.len() == 1 {
|
||||||
let ext = IndexingCodePtr::External(
|
let ext =
|
||||||
indexed_choice_instrs.pop_back().unwrap().offset()
|
IndexingCodePtr::External(indexed_choice_instrs.pop_back().unwrap().offset());
|
||||||
);
|
|
||||||
|
|
||||||
match &mut indexing_code[0] {
|
match &mut indexing_code[0] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)
|
_,
|
||||||
) => {
|
_,
|
||||||
|
_,
|
||||||
|
ref mut l,
|
||||||
|
_,
|
||||||
|
)) => {
|
||||||
*l = ext;
|
*l = ext;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -836,8 +827,7 @@ pub fn remove_index(
|
|||||||
fn second_level_index<IndexKey: Eq + Hash>(
|
fn second_level_index<IndexKey: Eq + Hash>(
|
||||||
indices: IndexMap<IndexKey, SliceDeque<IndexedChoiceInstruction>>,
|
indices: IndexMap<IndexKey, SliceDeque<IndexedChoiceInstruction>>,
|
||||||
prelude: &mut SliceDeque<IndexingLine>,
|
prelude: &mut SliceDeque<IndexingLine>,
|
||||||
) -> IndexMap<IndexKey, IndexingCodePtr>
|
) -> IndexMap<IndexKey, IndexingCodePtr> {
|
||||||
{
|
|
||||||
let mut index_locs = IndexMap::new();
|
let mut index_locs = IndexMap::new();
|
||||||
|
|
||||||
for (key, mut code) in indices.into_iter() {
|
for (key, mut code) in indices.into_iter() {
|
||||||
@@ -868,7 +858,8 @@ fn switch_on<IndexKey: Eq + Hash>(
|
|||||||
|
|
||||||
IndexingCodePtr::Internal(1)
|
IndexingCodePtr::Internal(1)
|
||||||
} else {
|
} else {
|
||||||
index.into_iter()
|
index
|
||||||
|
.into_iter()
|
||||||
.next()
|
.next()
|
||||||
.map(|(_, v)| v)
|
.map(|(_, v)| v)
|
||||||
.unwrap_or(IndexingCodePtr::Fail)
|
.unwrap_or(IndexingCodePtr::Fail)
|
||||||
@@ -884,7 +875,8 @@ fn switch_on_list(
|
|||||||
prelude.push_back(IndexingLine::from(lists));
|
prelude.push_back(IndexingLine::from(lists));
|
||||||
IndexingCodePtr::Internal(1)
|
IndexingCodePtr::Internal(1)
|
||||||
} else {
|
} else {
|
||||||
lists.first()
|
lists
|
||||||
|
.first()
|
||||||
.map(|i| IndexingCodePtr::External(i.offset()))
|
.map(|i| IndexingCodePtr::External(i.offset()))
|
||||||
.unwrap_or(IndexingCodePtr::Fail)
|
.unwrap_or(IndexingCodePtr::Fail)
|
||||||
}
|
}
|
||||||
@@ -978,8 +970,7 @@ pub fn constant_key_alternatives(constant: &Constant, atom_tbl: TabledData<Atom>
|
|||||||
constants.push(Constant::Fixnum(n));
|
constants.push(Constant::Fixnum(n));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constants
|
constants
|
||||||
@@ -1001,7 +992,7 @@ impl CodeOffsets {
|
|||||||
constants: IndexMap::new(),
|
constants: IndexMap::new(),
|
||||||
lists: sdeq![],
|
lists: sdeq![],
|
||||||
structures: IndexMap::new(),
|
structures: IndexMap::new(),
|
||||||
optimal_index
|
optimal_index,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1011,20 +1002,15 @@ impl CodeOffsets {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn index_constant(&mut self, constant: &Constant, index: usize) -> Vec<Constant> {
|
fn index_constant(&mut self, constant: &Constant, index: usize) -> Vec<Constant> {
|
||||||
let overlapping_constants =
|
let overlapping_constants = constant_key_alternatives(constant, self.atom_tbl.clone());
|
||||||
constant_key_alternatives(constant, self.atom_tbl.clone());
|
|
||||||
|
|
||||||
let code = self.constants
|
let code = self.constants.entry(constant.clone()).or_insert(sdeq![]);
|
||||||
.entry(constant.clone())
|
|
||||||
.or_insert(sdeq![]);
|
|
||||||
|
|
||||||
let is_initial_index = code.is_empty();
|
let is_initial_index = code.is_empty();
|
||||||
code.push_back(compute_index(is_initial_index, index));
|
code.push_back(compute_index(is_initial_index, index));
|
||||||
|
|
||||||
for constant in &overlapping_constants {
|
for constant in &overlapping_constants {
|
||||||
let code = self.constants
|
let code = self.constants.entry(constant.clone()).or_insert(sdeq![]);
|
||||||
.entry(constant.clone())
|
|
||||||
.or_insert(sdeq![]);
|
|
||||||
|
|
||||||
let is_initial_index = code.is_empty();
|
let is_initial_index = code.is_empty();
|
||||||
let index = compute_index(is_initial_index, index);
|
let index = compute_index(is_initial_index, index);
|
||||||
@@ -1062,25 +1048,21 @@ impl CodeOffsets {
|
|||||||
self.index_structure(name, terms.len(), index);
|
self.index_structure(name, terms.len(), index);
|
||||||
}
|
}
|
||||||
&Term::Cons(..) | &Term::Constant(_, Constant::String(_)) => {
|
&Term::Cons(..) | &Term::Constant(_, Constant::String(_)) => {
|
||||||
clause_index_info.opt_arg_index_key =
|
clause_index_info.opt_arg_index_key = OptArgIndexKey::List(self.optimal_index, 0);
|
||||||
OptArgIndexKey::List(self.optimal_index, 0);
|
|
||||||
|
|
||||||
self.index_list(index);
|
self.index_list(index);
|
||||||
}
|
}
|
||||||
&Term::Constant(_, ref constant) => {
|
&Term::Constant(_, ref constant) => {
|
||||||
let overlapping_constants =
|
let overlapping_constants = self.index_constant(constant, index);
|
||||||
self.index_constant(constant, index);
|
|
||||||
|
|
||||||
clause_index_info.opt_arg_index_key =
|
clause_index_info.opt_arg_index_key = OptArgIndexKey::Constant(
|
||||||
OptArgIndexKey::Constant(
|
|
||||||
self.optimal_index,
|
self.optimal_index,
|
||||||
0,
|
0,
|
||||||
constant.clone(),
|
constant.clone(),
|
||||||
overlapping_constants,
|
overlapping_constants,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1117,8 +1099,7 @@ impl CodeOffsets {
|
|||||||
IndexingCodePtr::Internal(ref mut i) => {
|
IndexingCodePtr::Internal(ref mut i) => {
|
||||||
*i += con_loc.is_internal() as usize;
|
*i += con_loc.is_internal() as usize;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match &mut lst_loc {
|
match &mut lst_loc {
|
||||||
@@ -1126,15 +1107,18 @@ impl CodeOffsets {
|
|||||||
*i += con_loc.is_internal() as usize;
|
*i += con_loc.is_internal() as usize;
|
||||||
*i += str_loc.is_internal() as usize;
|
*i += str_loc.is_internal() as usize;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let var_offset = 1 + skip_stub_try_me_else as usize;
|
let var_offset = 1 + skip_stub_try_me_else as usize;
|
||||||
|
|
||||||
prelude.push_front(IndexingLine::from(
|
prelude.push_front(IndexingLine::from(IndexingInstruction::SwitchOnTerm(
|
||||||
IndexingInstruction::SwitchOnTerm(self.optimal_index, var_offset, con_loc, lst_loc, str_loc)
|
self.optimal_index,
|
||||||
));
|
var_offset,
|
||||||
|
con_loc,
|
||||||
|
lst_loc,
|
||||||
|
str_loc,
|
||||||
|
)));
|
||||||
|
|
||||||
prelude.into_iter().collect()
|
prelude.into_iter().collect()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use crate::prolog_parser_rebis::ast::*;
|
||||||
|
use crate::prolog_parser_rebis::clause_name;
|
||||||
|
|
||||||
use crate::clause_types::*;
|
use crate::clause_types::*;
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
@@ -34,9 +35,7 @@ impl Level {
|
|||||||
impl ArithmeticTerm {
|
impl ArithmeticTerm {
|
||||||
fn into_functor(&self) -> MachineStub {
|
fn into_functor(&self) -> MachineStub {
|
||||||
match self {
|
match self {
|
||||||
&ArithmeticTerm::Reg(r) => {
|
&ArithmeticTerm::Reg(r) => reg_type_into_functor(r),
|
||||||
reg_type_into_functor(r)
|
|
||||||
}
|
|
||||||
&ArithmeticTerm::Interm(i) => {
|
&ArithmeticTerm::Interm(i) => {
|
||||||
functor!("intermediate", [integer(i)])
|
functor!("intermediate", [integer(i)])
|
||||||
}
|
}
|
||||||
@@ -185,16 +184,11 @@ impl Line {
|
|||||||
|
|
||||||
pub fn enqueue_functors(&self, mut h: usize, functors: &mut Vec<MachineStub>) {
|
pub fn enqueue_functors(&self, mut h: usize, functors: &mut Vec<MachineStub>) {
|
||||||
match self {
|
match self {
|
||||||
&Line::Arithmetic(ref arith_instr) =>
|
&Line::Arithmetic(ref arith_instr) => functors.push(arith_instr.to_functor(h)),
|
||||||
functors.push(arith_instr.to_functor(h)),
|
&Line::Choice(ref choice_instr) => functors.push(choice_instr.to_functor()),
|
||||||
&Line::Choice(ref choice_instr) =>
|
&Line::Control(ref control_instr) => functors.push(control_instr.to_functor()),
|
||||||
functors.push(choice_instr.to_functor()),
|
&Line::Cut(ref cut_instr) => functors.push(cut_instr.to_functor(h)),
|
||||||
&Line::Control(ref control_instr) =>
|
&Line::Fact(ref fact_instr) => functors.push(fact_instr.to_functor(h)),
|
||||||
functors.push(control_instr.to_functor()),
|
|
||||||
&Line::Cut(ref cut_instr) =>
|
|
||||||
functors.push(cut_instr.to_functor(h)),
|
|
||||||
&Line::Fact(ref fact_instr) =>
|
|
||||||
functors.push(fact_instr.to_functor(h)),
|
|
||||||
&Line::IndexingCode(ref indexing_instrs) => {
|
&Line::IndexingCode(ref indexing_instrs) => {
|
||||||
for indexing_instr in indexing_instrs {
|
for indexing_instr in indexing_instrs {
|
||||||
match indexing_instr {
|
match indexing_instr {
|
||||||
@@ -213,10 +207,10 @@ impl Line {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Line::IndexedChoice(ref indexed_choice_instr) =>
|
&Line::IndexedChoice(ref indexed_choice_instr) => {
|
||||||
functors.push(indexed_choice_instr.to_functor()),
|
functors.push(indexed_choice_instr.to_functor())
|
||||||
&Line::Query(ref query_instr) =>
|
}
|
||||||
functors.push(query_instr.to_functor(h)),
|
&Line::Query(ref query_instr) => functors.push(query_instr.to_functor(h)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,24 +218,16 @@ impl Line {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_indexing_line_mut(line: &mut Line) -> Option<&mut Vec<IndexingLine>> {
|
pub fn to_indexing_line_mut(line: &mut Line) -> Option<&mut Vec<IndexingLine>> {
|
||||||
match line {
|
match line {
|
||||||
Line::IndexingCode(ref mut indexing_code) => {
|
Line::IndexingCode(ref mut indexing_code) => Some(indexing_code),
|
||||||
Some(indexing_code)
|
_ => None,
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_indexing_line(line: &Line) -> Option<&Vec<IndexingLine>> {
|
pub fn to_indexing_line(line: &Line) -> Option<&Vec<IndexingLine>> {
|
||||||
match line {
|
match line {
|
||||||
Line::IndexingCode(ref indexing_code) => {
|
Line::IndexingCode(ref indexing_code) => Some(indexing_code),
|
||||||
Some(indexing_code)
|
_ => None,
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,11 +282,7 @@ fn arith_instr_unary_functor(
|
|||||||
) -> MachineStub {
|
) -> MachineStub {
|
||||||
let at_stub = at.into_functor();
|
let at_stub = at.into_functor();
|
||||||
|
|
||||||
functor!(
|
functor!(name, [aux(h, 0), integer(t)], [at_stub])
|
||||||
name,
|
|
||||||
[aux(h, 0), integer(t)],
|
|
||||||
[at_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arith_instr_bin_functor(
|
fn arith_instr_bin_functor(
|
||||||
@@ -383,39 +365,17 @@ impl ArithmeticInstruction {
|
|||||||
&ArithmeticInstruction::Gcd(ref at_1, ref at_2, t) => {
|
&ArithmeticInstruction::Gcd(ref at_1, ref at_2, t) => {
|
||||||
arith_instr_bin_functor(h, "gcd", at_1, at_2, t)
|
arith_instr_bin_functor(h, "gcd", at_1, at_2, t)
|
||||||
}
|
}
|
||||||
&ArithmeticInstruction::Sign(ref at, t) => {
|
&ArithmeticInstruction::Sign(ref at, t) => arith_instr_unary_functor(h, "sign", at, t),
|
||||||
arith_instr_unary_functor(h, "sign", at, t)
|
&ArithmeticInstruction::Cos(ref at, t) => arith_instr_unary_functor(h, "cos", at, t),
|
||||||
}
|
&ArithmeticInstruction::Sin(ref at, t) => arith_instr_unary_functor(h, "sin", at, t),
|
||||||
&ArithmeticInstruction::Cos(ref at, t) => {
|
&ArithmeticInstruction::Tan(ref at, t) => arith_instr_unary_functor(h, "tan", at, t),
|
||||||
arith_instr_unary_functor(h, "cos", at, t)
|
&ArithmeticInstruction::Log(ref at, t) => arith_instr_unary_functor(h, "log", at, t),
|
||||||
}
|
&ArithmeticInstruction::Exp(ref at, t) => arith_instr_unary_functor(h, "exp", at, t),
|
||||||
&ArithmeticInstruction::Sin(ref at, t) => {
|
&ArithmeticInstruction::ACos(ref at, t) => arith_instr_unary_functor(h, "acos", at, t),
|
||||||
arith_instr_unary_functor(h, "sin", at, t)
|
&ArithmeticInstruction::ASin(ref at, t) => arith_instr_unary_functor(h, "asin", at, t),
|
||||||
}
|
&ArithmeticInstruction::ATan(ref at, t) => arith_instr_unary_functor(h, "atan", at, t),
|
||||||
&ArithmeticInstruction::Tan(ref at, t) => {
|
&ArithmeticInstruction::Sqrt(ref at, t) => arith_instr_unary_functor(h, "sqrt", at, t),
|
||||||
arith_instr_unary_functor(h, "tan", at, t)
|
&ArithmeticInstruction::Abs(ref at, t) => arith_instr_unary_functor(h, "abs", at, t),
|
||||||
}
|
|
||||||
&ArithmeticInstruction::Log(ref at, t) => {
|
|
||||||
arith_instr_unary_functor(h, "log", at, t)
|
|
||||||
}
|
|
||||||
&ArithmeticInstruction::Exp(ref at, t) => {
|
|
||||||
arith_instr_unary_functor(h, "exp", at, t)
|
|
||||||
}
|
|
||||||
&ArithmeticInstruction::ACos(ref at, t) => {
|
|
||||||
arith_instr_unary_functor(h, "acos", at, t)
|
|
||||||
}
|
|
||||||
&ArithmeticInstruction::ASin(ref at, t) => {
|
|
||||||
arith_instr_unary_functor(h, "asin", at, t)
|
|
||||||
}
|
|
||||||
&ArithmeticInstruction::ATan(ref at, t) => {
|
|
||||||
arith_instr_unary_functor(h, "atan", at, t)
|
|
||||||
}
|
|
||||||
&ArithmeticInstruction::Sqrt(ref at, t) => {
|
|
||||||
arith_instr_unary_functor(h, "sqrt", at, t)
|
|
||||||
}
|
|
||||||
&ArithmeticInstruction::Abs(ref at, t) => {
|
|
||||||
arith_instr_unary_functor(h, "abs", at, t)
|
|
||||||
}
|
|
||||||
&ArithmeticInstruction::Float(ref at, t) => {
|
&ArithmeticInstruction::Float(ref at, t) => {
|
||||||
arith_instr_unary_functor(h, "float", at, t)
|
arith_instr_unary_functor(h, "float", at, t)
|
||||||
}
|
}
|
||||||
@@ -431,12 +391,8 @@ impl ArithmeticInstruction {
|
|||||||
&ArithmeticInstruction::Floor(ref at, t) => {
|
&ArithmeticInstruction::Floor(ref at, t) => {
|
||||||
arith_instr_unary_functor(h, "floor", at, t)
|
arith_instr_unary_functor(h, "floor", at, t)
|
||||||
}
|
}
|
||||||
&ArithmeticInstruction::Neg(ref at, t) => {
|
&ArithmeticInstruction::Neg(ref at, t) => arith_instr_unary_functor(h, "-", at, t),
|
||||||
arith_instr_unary_functor(h, "-", at, t)
|
&ArithmeticInstruction::Plus(ref at, t) => arith_instr_unary_functor(h, "+", at, t),
|
||||||
}
|
|
||||||
&ArithmeticInstruction::Plus(ref at, t) => {
|
|
||||||
arith_instr_unary_functor(h, "+", at, t)
|
|
||||||
}
|
|
||||||
&ArithmeticInstruction::BitwiseComplement(ref at, t) => {
|
&ArithmeticInstruction::BitwiseComplement(ref at, t) => {
|
||||||
arith_instr_unary_functor(h, "\\", at, t)
|
arith_instr_unary_functor(h, "\\", at, t)
|
||||||
}
|
}
|
||||||
@@ -460,12 +416,9 @@ pub enum ControlInstruction {
|
|||||||
impl ControlInstruction {
|
impl ControlInstruction {
|
||||||
pub fn perm_vars(&self) -> Option<usize> {
|
pub fn perm_vars(&self) -> Option<usize> {
|
||||||
match self {
|
match self {
|
||||||
ControlInstruction::CallClause(_, _, num_cells, ..) =>
|
ControlInstruction::CallClause(_, _, num_cells, ..) => Some(*num_cells),
|
||||||
Some(*num_cells),
|
ControlInstruction::JmpBy(_, _, num_cells, ..) => Some(*num_cells),
|
||||||
ControlInstruction::JmpBy(_, _, num_cells, ..) =>
|
_ => None,
|
||||||
Some(*num_cells),
|
|
||||||
_ =>
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -500,7 +453,13 @@ impl ControlInstruction {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum IndexingInstruction {
|
pub enum IndexingInstruction {
|
||||||
// The first index is the optimal argument being indexed.
|
// The first index is the optimal argument being indexed.
|
||||||
SwitchOnTerm(usize, usize, IndexingCodePtr, IndexingCodePtr, IndexingCodePtr),
|
SwitchOnTerm(
|
||||||
|
usize,
|
||||||
|
usize,
|
||||||
|
IndexingCodePtr,
|
||||||
|
IndexingCodePtr,
|
||||||
|
IndexingCodePtr,
|
||||||
|
),
|
||||||
SwitchOnConstant(IndexMap<Constant, IndexingCodePtr>),
|
SwitchOnConstant(IndexMap<Constant, IndexingCodePtr>),
|
||||||
SwitchOnStructure(IndexMap<(ClauseName, usize), IndexingCodePtr>),
|
SwitchOnStructure(IndexMap<(ClauseName, usize), IndexingCodePtr>),
|
||||||
}
|
}
|
||||||
@@ -511,11 +470,13 @@ impl IndexingInstruction {
|
|||||||
&IndexingInstruction::SwitchOnTerm(arg, vars, constants, lists, structures) => {
|
&IndexingInstruction::SwitchOnTerm(arg, vars, constants, lists, structures) => {
|
||||||
functor!(
|
functor!(
|
||||||
"switch_on_term",
|
"switch_on_term",
|
||||||
[integer(arg),
|
[
|
||||||
|
integer(arg),
|
||||||
integer(vars),
|
integer(vars),
|
||||||
indexing_code_ptr(h, constants),
|
indexing_code_ptr(h, constants),
|
||||||
indexing_code_ptr(h, lists),
|
indexing_code_ptr(h, lists),
|
||||||
indexing_code_ptr(h, structures)]
|
indexing_code_ptr(h, structures)
|
||||||
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
&IndexingInstruction::SwitchOnConstant(ref constants) => {
|
&IndexingInstruction::SwitchOnConstant(ref constants) => {
|
||||||
@@ -528,15 +489,14 @@ impl IndexingInstruction {
|
|||||||
let key_value_pair = functor!(
|
let key_value_pair = functor!(
|
||||||
":",
|
":",
|
||||||
SharedOpDesc::new(600, XFY),
|
SharedOpDesc::new(600, XFY),
|
||||||
[constant(c),
|
[constant(c), indexing_code_ptr(h + 3, *ptr)]
|
||||||
indexing_code_ptr(h + 3, *ptr)]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
key_value_list_stub.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
|
key_value_list_stub.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
|
||||||
key_value_list_stub.push(HeapCellValue::Addr(Addr::Str(h + 3)));
|
key_value_list_stub.push(HeapCellValue::Addr(Addr::Str(h + 3)));
|
||||||
key_value_list_stub.push(HeapCellValue::Addr(
|
key_value_list_stub.push(HeapCellValue::Addr(Addr::HeapCell(
|
||||||
Addr::HeapCell(h + 3 + key_value_pair.len())
|
h + 3 + key_value_pair.len(),
|
||||||
));
|
)));
|
||||||
|
|
||||||
h += key_value_pair.len() + 3;
|
h += key_value_pair.len() + 3;
|
||||||
key_value_list_stub.extend(key_value_pair.into_iter());
|
key_value_list_stub.extend(key_value_pair.into_iter());
|
||||||
@@ -560,23 +520,21 @@ impl IndexingInstruction {
|
|||||||
let predicate_indicator_stub = functor!(
|
let predicate_indicator_stub = functor!(
|
||||||
"/",
|
"/",
|
||||||
SharedOpDesc::new(400, YFX),
|
SharedOpDesc::new(400, YFX),
|
||||||
[clause_name(name.clone()),
|
[clause_name(name.clone()), integer(*arity)]
|
||||||
integer(*arity)]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let key_value_pair = functor!(
|
let key_value_pair = functor!(
|
||||||
":",
|
":",
|
||||||
SharedOpDesc::new(600, XFY),
|
SharedOpDesc::new(600, XFY),
|
||||||
[aux(h + 3, 0),
|
[aux(h + 3, 0), indexing_code_ptr(h + 3, *ptr)],
|
||||||
indexing_code_ptr(h + 3, *ptr)],
|
|
||||||
[predicate_indicator_stub]
|
[predicate_indicator_stub]
|
||||||
);
|
);
|
||||||
|
|
||||||
key_value_list_stub.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
|
key_value_list_stub.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
|
||||||
key_value_list_stub.push(HeapCellValue::Addr(Addr::Str(h + 3)));
|
key_value_list_stub.push(HeapCellValue::Addr(Addr::Str(h + 3)));
|
||||||
key_value_list_stub.push(HeapCellValue::Addr(
|
key_value_list_stub.push(HeapCellValue::Addr(Addr::HeapCell(
|
||||||
Addr::HeapCell(h + 3 + key_value_pair.len())
|
h + 3 + key_value_pair.len(),
|
||||||
));
|
)));
|
||||||
|
|
||||||
h += key_value_pair.len() + 3;
|
h += key_value_pair.len() + 3;
|
||||||
key_value_list_stub.extend(key_value_pair.into_iter());
|
key_value_list_stub.extend(key_value_pair.into_iter());
|
||||||
@@ -626,11 +584,7 @@ impl FactInstruction {
|
|||||||
let lvl_stub = lvl.into_functor();
|
let lvl_stub = lvl.into_functor();
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("get_list", [aux(h, 0), aux(h, 1)], [lvl_stub, rt_stub])
|
||||||
"get_list",
|
|
||||||
[aux(h, 0), aux(h, 1)],
|
|
||||||
[lvl_stub, rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&FactInstruction::GetPartialString(lvl, ref s, r, has_tail) => {
|
&FactInstruction::GetPartialString(lvl, ref s, r, has_tail) => {
|
||||||
let lvl_stub = lvl.into_functor();
|
let lvl_stub = lvl.into_functor();
|
||||||
@@ -654,20 +608,12 @@ impl FactInstruction {
|
|||||||
&FactInstruction::GetValue(r, arg) => {
|
&FactInstruction::GetValue(r, arg) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("get_value", [aux(h, 0), integer(arg)], [rt_stub])
|
||||||
"get_value",
|
|
||||||
[aux(h, 0), integer(arg)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&FactInstruction::GetVariable(r, arg) => {
|
&FactInstruction::GetVariable(r, arg) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("get_variable", [aux(h, 0), integer(arg)], [rt_stub])
|
||||||
"get_variable",
|
|
||||||
[aux(h, 0), integer(arg)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&FactInstruction::UnifyConstant(ref c) => {
|
&FactInstruction::UnifyConstant(ref c) => {
|
||||||
functor!("unify_constant", [constant(h, c)], [])
|
functor!("unify_constant", [constant(h, c)], [])
|
||||||
@@ -675,29 +621,17 @@ impl FactInstruction {
|
|||||||
&FactInstruction::UnifyLocalValue(r) => {
|
&FactInstruction::UnifyLocalValue(r) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("unify_local_value", [aux(h, 0)], [rt_stub])
|
||||||
"unify_local_value",
|
|
||||||
[aux(h, 0)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&FactInstruction::UnifyVariable(r) => {
|
&FactInstruction::UnifyVariable(r) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("unify_variable", [aux(h, 0)], [rt_stub])
|
||||||
"unify_variable",
|
|
||||||
[aux(h, 0)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&FactInstruction::UnifyValue(r) => {
|
&FactInstruction::UnifyValue(r) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("unify_value", [aux(h, 0)], [rt_stub])
|
||||||
"unify_value",
|
|
||||||
[aux(h, 0)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&FactInstruction::UnifyVoid(vars) => {
|
&FactInstruction::UnifyVoid(vars) => {
|
||||||
functor!("unify_void", [integer(vars)])
|
functor!("unify_void", [integer(vars)])
|
||||||
@@ -726,10 +660,9 @@ pub enum QueryInstruction {
|
|||||||
impl QueryInstruction {
|
impl QueryInstruction {
|
||||||
pub fn to_functor(&self, h: usize) -> MachineStub {
|
pub fn to_functor(&self, h: usize) -> MachineStub {
|
||||||
match self {
|
match self {
|
||||||
&QueryInstruction::PutUnsafeValue(norm, arg) => functor!(
|
&QueryInstruction::PutUnsafeValue(norm, arg) => {
|
||||||
"put_unsafe_value",
|
functor!("put_unsafe_value", [integer(norm), integer(arg)])
|
||||||
[integer(norm), integer(arg)]
|
}
|
||||||
),
|
|
||||||
&QueryInstruction::PutConstant(lvl, ref c, r) => {
|
&QueryInstruction::PutConstant(lvl, ref c, r) => {
|
||||||
let lvl_stub = lvl.into_functor();
|
let lvl_stub = lvl.into_functor();
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
@@ -744,11 +677,7 @@ impl QueryInstruction {
|
|||||||
let lvl_stub = lvl.into_functor();
|
let lvl_stub = lvl.into_functor();
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("put_list", [aux(h, 0), aux(h, 1)], [lvl_stub, rt_stub])
|
||||||
"put_list",
|
|
||||||
[aux(h, 0), aux(h, 1)],
|
|
||||||
[lvl_stub, rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&QueryInstruction::PutPartialString(lvl, ref s, r, has_tail) => {
|
&QueryInstruction::PutPartialString(lvl, ref s, r, has_tail) => {
|
||||||
let lvl_stub = lvl.into_functor();
|
let lvl_stub = lvl.into_functor();
|
||||||
@@ -772,29 +701,17 @@ impl QueryInstruction {
|
|||||||
&QueryInstruction::PutValue(r, arg) => {
|
&QueryInstruction::PutValue(r, arg) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("put_value", [aux(h, 0), integer(arg)], [rt_stub])
|
||||||
"put_value",
|
|
||||||
[aux(h, 0), integer(arg)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&QueryInstruction::GetVariable(r, arg) => {
|
&QueryInstruction::GetVariable(r, arg) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("get_variable", [aux(h, 0), integer(arg)], [rt_stub])
|
||||||
"get_variable",
|
|
||||||
[aux(h, 0), integer(arg)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&QueryInstruction::PutVariable(r, arg) => {
|
&QueryInstruction::PutVariable(r, arg) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("put_variable", [aux(h, 0), integer(arg)], [rt_stub])
|
||||||
"put_variable",
|
|
||||||
[aux(h, 0), integer(arg)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&QueryInstruction::SetConstant(ref c) => {
|
&QueryInstruction::SetConstant(ref c) => {
|
||||||
functor!("set_constant", [constant(h, c)], [])
|
functor!("set_constant", [constant(h, c)], [])
|
||||||
@@ -802,29 +719,17 @@ impl QueryInstruction {
|
|||||||
&QueryInstruction::SetLocalValue(r) => {
|
&QueryInstruction::SetLocalValue(r) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("set_local_value", [aux(h, 0)], [rt_stub])
|
||||||
"set_local_value",
|
|
||||||
[aux(h, 0)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&QueryInstruction::SetVariable(r) => {
|
&QueryInstruction::SetVariable(r) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("set_variable", [aux(h, 0)], [rt_stub])
|
||||||
"set_variable",
|
|
||||||
[aux(h, 0)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&QueryInstruction::SetValue(r) => {
|
&QueryInstruction::SetValue(r) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("set_value", [aux(h, 0)], [rt_stub])
|
||||||
"set_value",
|
|
||||||
[aux(h, 0)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&QueryInstruction::SetVoid(vars) => {
|
&QueryInstruction::SetVoid(vars) => {
|
||||||
functor!("set_void", [integer(vars)])
|
functor!("set_void", [integer(vars)])
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use crate::prolog_parser_rebis::ast::*;
|
||||||
|
use crate::prolog_parser_rebis::rc_atom;
|
||||||
|
|
||||||
use crate::clause_types::*;
|
use crate::clause_types::*;
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
@@ -29,7 +30,7 @@ impl<'a> TermRef<'a> {
|
|||||||
| TermRef::Constant(lvl, ..)
|
| TermRef::Constant(lvl, ..)
|
||||||
| TermRef::Var(lvl, ..)
|
| TermRef::Var(lvl, ..)
|
||||||
| TermRef::Clause(lvl, ..) => lvl,
|
| TermRef::Clause(lvl, ..) => lvl,
|
||||||
| TermRef::PartialString(lvl, ..) => lvl,
|
TermRef::PartialString(lvl, ..) => lvl,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -51,19 +52,12 @@ pub enum TermIterState<'a> {
|
|||||||
Var(Level, &'a Cell<VarReg>, Rc<Var>),
|
Var(Level, &'a Cell<VarReg>, Rc<Var>),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_partial_string<'a>(
|
fn is_partial_string<'a>(head: &'a Term, mut tail: &'a Term) -> Option<(String, Option<&'a Term>)> {
|
||||||
head: &'a Term,
|
let mut string = match head {
|
||||||
mut tail: &'a Term,
|
|
||||||
) -> Option<(String, Option<&'a Term>)>
|
|
||||||
{
|
|
||||||
let mut string =
|
|
||||||
match head {
|
|
||||||
&Term::Constant(_, Constant::Atom(ref atom, _)) if atom.is_char() => {
|
&Term::Constant(_, Constant::Atom(ref atom, _)) if atom.is_char() => {
|
||||||
atom.as_str().chars().next().unwrap().to_string()
|
atom.as_str().chars().next().unwrap().to_string()
|
||||||
}
|
}
|
||||||
&Term::Constant(_, Constant::Char(c)) => {
|
&Term::Constant(_, Constant::Char(c)) => c.to_string(),
|
||||||
c.to_string()
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@@ -105,9 +99,7 @@ fn is_partial_string<'a>(
|
|||||||
impl<'a> TermIterState<'a> {
|
impl<'a> TermIterState<'a> {
|
||||||
pub fn subterm_to_state(lvl: Level, term: &'a Term) -> TermIterState<'a> {
|
pub fn subterm_to_state(lvl: Level, term: &'a Term) -> TermIterState<'a> {
|
||||||
match term {
|
match term {
|
||||||
&Term::AnonVar => {
|
&Term::AnonVar => TermIterState::AnonVar(lvl),
|
||||||
TermIterState::AnonVar(lvl)
|
|
||||||
}
|
|
||||||
&Term::Clause(ref cell, ref name, ref subterms, ref spec) => {
|
&Term::Clause(ref cell, ref name, ref subterms, ref spec) => {
|
||||||
let ct = if let Some(spec) = spec {
|
let ct = if let Some(spec) = spec {
|
||||||
ClauseType::Op(name.clone(), spec.clone(), CodeIndex::default())
|
ClauseType::Op(name.clone(), spec.clone(), CodeIndex::default())
|
||||||
@@ -120,12 +112,8 @@ impl<'a> TermIterState<'a> {
|
|||||||
&Term::Cons(ref cell, ref head, ref tail) => {
|
&Term::Cons(ref cell, ref head, ref tail) => {
|
||||||
TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref())
|
TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref())
|
||||||
}
|
}
|
||||||
&Term::Constant(ref cell, ref constant) => {
|
&Term::Constant(ref cell, ref constant) => TermIterState::Constant(lvl, cell, constant),
|
||||||
TermIterState::Constant(lvl, cell, constant)
|
&Term::Var(ref cell, ref var) => TermIterState::Var(lvl, cell, var.clone()),
|
||||||
}
|
|
||||||
&Term::Var(ref cell, ref var) => {
|
|
||||||
TermIterState::Var(lvl, cell, var.clone())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,8 +163,7 @@ impl<'a> QueryIterator<'a> {
|
|||||||
state_stack: vec![],
|
state_stack: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Term::Var(ref cell, ref var) =>
|
&Term::Var(ref cell, ref var) => TermIterState::Var(Level::Root, cell, (*var).clone()),
|
||||||
TermIterState::Var(Level::Root, cell, (*var).clone()),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QueryIterator {
|
QueryIterator {
|
||||||
@@ -265,18 +252,15 @@ impl<'a> Iterator for QueryIterator<'a> {
|
|||||||
}
|
}
|
||||||
TermIterState::InitialCons(lvl, cell, head, tail) => {
|
TermIterState::InitialCons(lvl, cell, head, tail) => {
|
||||||
if let Some((string, tail)) = is_partial_string(head, tail) {
|
if let Some((string, tail)) = is_partial_string(head, tail) {
|
||||||
self.state_stack.push(TermIterState::PartialString(
|
self.state_stack
|
||||||
lvl,
|
.push(TermIterState::PartialString(lvl, cell, string, tail));
|
||||||
cell,
|
|
||||||
string,
|
|
||||||
tail,
|
|
||||||
));
|
|
||||||
|
|
||||||
if let Some(tail) = tail {
|
if let Some(tail) = tail {
|
||||||
self.push_subterm(lvl.child_level(), tail);
|
self.push_subterm(lvl.child_level(), tail);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.state_stack.push(TermIterState::FinalCons(lvl, cell, head, tail));
|
self.state_stack
|
||||||
|
.push(TermIterState::FinalCons(lvl, cell, head, tail));
|
||||||
|
|
||||||
self.push_subterm(lvl.child_level(), tail);
|
self.push_subterm(lvl.child_level(), tail);
|
||||||
self.push_subterm(lvl.child_level(), head);
|
self.push_subterm(lvl.child_level(), head);
|
||||||
@@ -309,7 +293,8 @@ pub struct FactIterator<'a> {
|
|||||||
|
|
||||||
impl<'a> FactIterator<'a> {
|
impl<'a> FactIterator<'a> {
|
||||||
fn push_subterm(&mut self, lvl: Level, term: &'a Term) {
|
fn push_subterm(&mut self, lvl: Level, term: &'a Term) {
|
||||||
self.state_queue.push_back(TermIterState::subterm_to_state(lvl, term));
|
self.state_queue
|
||||||
|
.push_back(TermIterState::subterm_to_state(lvl, term));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_rule_head_clause(terms: &'a Vec<Box<Term>>) -> Self {
|
pub fn from_rule_head_clause(terms: &'a Vec<Box<Term>>) -> Self {
|
||||||
@@ -393,8 +378,7 @@ impl<'a> Iterator for FactIterator<'a> {
|
|||||||
TermIterState::Var(lvl, cell, var) => {
|
TermIterState::Var(lvl, cell, var) => {
|
||||||
return Some(TermRef::Var(lvl, cell, var));
|
return Some(TermRef::Var(lvl, cell, var));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use crate::divrem::*;
|
use crate::divrem::*;
|
||||||
|
|
||||||
use crate::prolog_parser_rebis::ast::*;
|
use crate::prolog_parser_rebis::ast::*;
|
||||||
|
use crate::prolog_parser_rebis::clause_name;
|
||||||
|
|
||||||
use crate::arithmetic::*;
|
use crate::arithmetic::*;
|
||||||
use crate::clause_types::*;
|
use crate::clause_types::*;
|
||||||
@@ -19,19 +20,16 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! try_numeric_result {
|
macro_rules! try_numeric_result {
|
||||||
($s: ident, $e: expr, $caller: expr) => (
|
($s: ident, $e: expr, $caller: expr) => {
|
||||||
match $e {
|
match $e {
|
||||||
Ok(val) => {
|
Ok(val) => Ok(val),
|
||||||
Ok(val)
|
|
||||||
}
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let caller_copy =
|
let caller_copy = $caller.iter().map(|v| v.context_free_clone()).collect();
|
||||||
$caller.iter().map(|v| v.context_free_clone()).collect();
|
|
||||||
|
|
||||||
Err($s.error_form(MachineError::evaluation_error(e), caller_copy))
|
Err($s.error_form(MachineError::evaluation_error(e), caller_copy))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn isize_gcd(n1: isize, n2: isize) -> Option<isize> {
|
fn isize_gcd(n1: isize, n2: isize) -> Option<isize> {
|
||||||
@@ -83,52 +81,29 @@ fn isize_gcd(n1: isize, n2: isize) -> Option<isize> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MachineState {
|
impl MachineState {
|
||||||
pub(crate)
|
pub(crate) fn get_number(&mut self, at: &ArithmeticTerm) -> Result<Number, MachineStub> {
|
||||||
fn get_number(&mut self, at: &ArithmeticTerm) -> Result<Number, MachineStub> {
|
|
||||||
match at {
|
match at {
|
||||||
&ArithmeticTerm::Reg(r) => {
|
&ArithmeticTerm::Reg(r) => self.arith_eval_by_metacall(r),
|
||||||
self.arith_eval_by_metacall(r)
|
&ArithmeticTerm::Interm(i) => {
|
||||||
}
|
Ok(mem::replace(&mut self.interms[i - 1], Number::Fixnum(0)))
|
||||||
&ArithmeticTerm::Interm(i) => Ok(mem::replace(
|
|
||||||
&mut self.interms[i - 1],
|
|
||||||
Number::Fixnum(0),
|
|
||||||
)),
|
|
||||||
&ArithmeticTerm::Number(ref n) => {
|
|
||||||
Ok(n.clone())
|
|
||||||
}
|
}
|
||||||
|
&ArithmeticTerm::Number(ref n) => Ok(n.clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn rational_from_number(&self, n: Number) -> Result<Rc<Rational>, MachineError> {
|
||||||
fn rational_from_number(
|
|
||||||
&self,
|
|
||||||
n: Number,
|
|
||||||
) -> Result<Rc<Rational>, MachineError> {
|
|
||||||
match n {
|
match n {
|
||||||
Number::Fixnum(n) => {
|
Number::Fixnum(n) => Ok(Rc::new(Rational::from(n))),
|
||||||
Ok(Rc::new(Rational::from(n)))
|
Number::Rational(r) => Ok(r),
|
||||||
}
|
Number::Float(OrderedFloat(f)) => match Rational::from_f64(f) {
|
||||||
Number::Rational(r) => {
|
Some(r) => Ok(Rc::new(r)),
|
||||||
Ok(r)
|
None => Err(MachineError::instantiation_error()),
|
||||||
}
|
},
|
||||||
Number::Float(OrderedFloat(f)) => {
|
Number::Integer(n) => Ok(Rc::new(Rational::from(&*n))),
|
||||||
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)
|
pub(crate) fn get_rational(
|
||||||
fn get_rational(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
at: &ArithmeticTerm,
|
at: &ArithmeticTerm,
|
||||||
caller: MachineStub,
|
caller: MachineStub,
|
||||||
@@ -137,12 +112,11 @@ impl MachineState {
|
|||||||
|
|
||||||
match self.rational_from_number(n) {
|
match self.rational_from_number(n) {
|
||||||
Ok(r) => Ok((r, caller)),
|
Ok(r) => Ok((r, caller)),
|
||||||
Err(e) => Err(self.error_form(e, caller))
|
Err(e) => Err(self.error_form(e, caller)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn arith_eval_by_metacall(&self, r: RegType) -> Result<Number, MachineStub> {
|
||||||
fn arith_eval_by_metacall(&self, r: RegType) -> Result<Number, MachineStub> {
|
|
||||||
let caller = MachineError::functor_stub(clause_name!("is"), 2);
|
let caller = MachineError::functor_stub(clause_name!("is"), 2);
|
||||||
let mut interms: Vec<Number> = Vec::with_capacity(64);
|
let mut interms: Vec<Number> = Vec::with_capacity(64);
|
||||||
|
|
||||||
@@ -163,9 +137,8 @@ impl MachineState {
|
|||||||
"min" => interms.push(self.min(a1, a2)?),
|
"min" => interms.push(self.min(a1, a2)?),
|
||||||
"rdiv" => {
|
"rdiv" => {
|
||||||
let r1 = self.rational_from_number(a1);
|
let r1 = self.rational_from_number(a1);
|
||||||
let r2 = r1.and_then(|r1| {
|
let r2 =
|
||||||
self.rational_from_number(a2).map(|r2| (r1, r2))
|
r1.and_then(|r1| self.rational_from_number(a2).map(|r2| (r1, r2)));
|
||||||
});
|
|
||||||
|
|
||||||
match r2 {
|
match r2 {
|
||||||
Ok((r1, r2)) => {
|
Ok((r1, r2)) => {
|
||||||
@@ -242,18 +215,12 @@ impl MachineState {
|
|||||||
&HeapCellValue::Addr(Addr::Fixnum(n)) => {
|
&HeapCellValue::Addr(Addr::Fixnum(n)) => {
|
||||||
interms.push(Number::Fixnum(n));
|
interms.push(Number::Fixnum(n));
|
||||||
}
|
}
|
||||||
&HeapCellValue::Addr(Addr::Float(n)) => {
|
&HeapCellValue::Addr(Addr::Float(n)) => interms.push(Number::Float(n)),
|
||||||
interms.push(Number::Float(n))
|
&HeapCellValue::Integer(ref n) => interms.push(Number::Integer(n.clone())),
|
||||||
}
|
|
||||||
&HeapCellValue::Integer(ref n) => {
|
|
||||||
interms.push(Number::Integer(n.clone()))
|
|
||||||
}
|
|
||||||
&HeapCellValue::Addr(Addr::Usize(n)) => {
|
&HeapCellValue::Addr(Addr::Usize(n)) => {
|
||||||
interms.push(Number::Integer(Rc::new(Integer::from(n))));
|
interms.push(Number::Integer(Rc::new(Integer::from(n))));
|
||||||
}
|
}
|
||||||
&HeapCellValue::Rational(ref n) => {
|
&HeapCellValue::Rational(ref n) => interms.push(Number::Rational(n.clone())),
|
||||||
interms.push(Number::Rational(n.clone()))
|
|
||||||
}
|
|
||||||
&HeapCellValue::Atom(ref name, _) if name.as_str() == "pi" => {
|
&HeapCellValue::Atom(ref name, _) if name.as_str() == "pi" => {
|
||||||
interms.push(Number::Float(OrderedFloat(f64::consts::PI)))
|
interms.push(Number::Float(OrderedFloat(f64::consts::PI)))
|
||||||
}
|
}
|
||||||
@@ -282,10 +249,7 @@ impl MachineState {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
&HeapCellValue::Addr(addr) if addr.is_ref() => {
|
&HeapCellValue::Addr(addr) if addr.is_ref() => {
|
||||||
return Err(self.error_form(
|
return Err(self.error_form(MachineError::instantiation_error(), caller));
|
||||||
MachineError::instantiation_error(),
|
|
||||||
caller,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
val => {
|
val => {
|
||||||
return Err(self.type_error(
|
return Err(self.type_error(
|
||||||
@@ -301,8 +265,7 @@ impl MachineState {
|
|||||||
Ok(interms.pop().unwrap())
|
Ok(interms.pop().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn rdiv(&self, r1: Rc<Rational>, r2: Rc<Rational>) -> Result<Rational, MachineStub> {
|
||||||
fn rdiv(&self, r1: Rc<Rational>, r2: Rc<Rational>) -> Result<Rational, MachineStub> {
|
|
||||||
if &*r2 == &0 {
|
if &*r2 == &0 {
|
||||||
let stub = MachineError::functor_stub(clause_name!("(rdiv)"), 2);
|
let stub = MachineError::functor_stub(clause_name!("(rdiv)"), 2);
|
||||||
Err(self.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
Err(self.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||||
@@ -311,27 +274,21 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn int_floor_div(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||||
fn int_floor_div(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
|
||||||
let stub = MachineError::functor_stub(clause_name!("(div)"), 2);
|
let stub = MachineError::functor_stub(clause_name!("(div)"), 2);
|
||||||
let modulus = self.modulus(n1.clone(), n2.clone())?;
|
let modulus = self.modulus(n1.clone(), n2.clone())?;
|
||||||
|
|
||||||
self.idiv(try_numeric_result!(self, n1 - modulus, stub)?, n2)
|
self.idiv(try_numeric_result!(self, n1 - modulus, stub)?, n2)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn idiv(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||||
fn idiv(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
|
||||||
match (n1, n2) {
|
match (n1, n2) {
|
||||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||||
if n2 == 0 {
|
if n2 == 0 {
|
||||||
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
|
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
|
||||||
|
|
||||||
Err(self.error_form(
|
Err(self
|
||||||
MachineError::evaluation_error(
|
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||||
EvalError::ZeroDivisor
|
|
||||||
),
|
|
||||||
stub,
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
if let Some(result) = n1.checked_div(n2) {
|
if let Some(result) = n1.checked_div(n2) {
|
||||||
Ok(Number::from(result))
|
Ok(Number::from(result))
|
||||||
@@ -347,12 +304,8 @@ impl MachineState {
|
|||||||
if &*n2 == &0 {
|
if &*n2 == &0 {
|
||||||
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
|
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
|
||||||
|
|
||||||
Err(self.error_form(
|
Err(self
|
||||||
MachineError::evaluation_error(
|
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||||
EvalError::ZeroDivisor
|
|
||||||
),
|
|
||||||
stub,
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(Number::from(Integer::from(n1) / &*n2))
|
Ok(Number::from(Integer::from(n1) / &*n2))
|
||||||
}
|
}
|
||||||
@@ -361,12 +314,8 @@ impl MachineState {
|
|||||||
if n1 == 0 {
|
if n1 == 0 {
|
||||||
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
|
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
|
||||||
|
|
||||||
Err(self.error_form(
|
Err(self
|
||||||
MachineError::evaluation_error(
|
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||||
EvalError::ZeroDivisor
|
|
||||||
),
|
|
||||||
stub,
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(Number::from(&*n2 / Integer::from(n1)))
|
Ok(Number::from(&*n2 / Integer::from(n1)))
|
||||||
}
|
}
|
||||||
@@ -375,25 +324,19 @@ impl MachineState {
|
|||||||
if &*n2 == &0 {
|
if &*n2 == &0 {
|
||||||
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
|
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
|
||||||
|
|
||||||
Err(self.error_form(
|
Err(self
|
||||||
MachineError::evaluation_error(
|
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||||
EvalError::ZeroDivisor
|
|
||||||
),
|
|
||||||
stub,
|
|
||||||
))
|
|
||||||
} else {
|
} 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) => {
|
(Number::Fixnum(_), n2) | (Number::Integer(_), n2) => {
|
||||||
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
|
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
|
||||||
|
|
||||||
Err(self.error_form(
|
Err(self.error_form(
|
||||||
MachineError::type_error(
|
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Integer,
|
|
||||||
n2,
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -401,19 +344,14 @@ impl MachineState {
|
|||||||
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
|
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
|
||||||
|
|
||||||
Err(self.error_form(
|
Err(self.error_form(
|
||||||
MachineError::type_error(
|
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Integer,
|
|
||||||
n1,
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn div(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||||
fn div(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
|
||||||
let stub = MachineError::functor_stub(clause_name!("(/)"), 2);
|
let stub = MachineError::functor_stub(clause_name!("(/)"), 2);
|
||||||
|
|
||||||
if n2.is_zero() {
|
if n2.is_zero() {
|
||||||
@@ -423,8 +361,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn atan2(&self, n1: Number, n2: Number) -> Result<f64, MachineStub> {
|
||||||
fn atan2(&self, n1: Number, n2: Number) -> Result<f64, MachineStub> {
|
|
||||||
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
||||||
|
|
||||||
if n1.is_zero() && n2.is_zero() {
|
if n1.is_zero() && n2.is_zero() {
|
||||||
@@ -437,8 +374,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn int_pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||||
fn int_pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
|
||||||
if n1.is_zero() && n2.is_negative() {
|
if n1.is_zero() && n2.is_negative() {
|
||||||
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
||||||
return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub));
|
return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub));
|
||||||
@@ -451,11 +387,7 @@ impl MachineState {
|
|||||||
let stub = MachineError::functor_stub(clause_name!("^"), 2);
|
let stub = MachineError::functor_stub(clause_name!("^"), 2);
|
||||||
|
|
||||||
Err(self.error_form(
|
Err(self.error_form(
|
||||||
MachineError::type_error(
|
MachineError::type_error(self.heap.h(), ValidType::Float, n),
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Float,
|
|
||||||
n
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
@@ -477,11 +409,7 @@ impl MachineState {
|
|||||||
let stub = MachineError::functor_stub(clause_name!("^"), 2);
|
let stub = MachineError::functor_stub(clause_name!("^"), 2);
|
||||||
|
|
||||||
Err(self.error_form(
|
Err(self.error_form(
|
||||||
MachineError::type_error(
|
MachineError::type_error(self.heap.h(), ValidType::Float, n),
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Float,
|
|
||||||
n
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
@@ -495,11 +423,7 @@ impl MachineState {
|
|||||||
let stub = MachineError::functor_stub(clause_name!("^"), 2);
|
let stub = MachineError::functor_stub(clause_name!("^"), 2);
|
||||||
|
|
||||||
Err(self.error_form(
|
Err(self.error_form(
|
||||||
MachineError::type_error(
|
MachineError::type_error(self.heap.h(), ValidType::Float, n),
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Float,
|
|
||||||
n
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
@@ -513,11 +437,7 @@ impl MachineState {
|
|||||||
let stub = MachineError::functor_stub(clause_name!("^"), 2);
|
let stub = MachineError::functor_stub(clause_name!("^"), 2);
|
||||||
|
|
||||||
Err(self.error_form(
|
Err(self.error_form(
|
||||||
MachineError::type_error(
|
MachineError::type_error(self.heap.h(), ValidType::Float, n),
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Float,
|
|
||||||
n
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
@@ -548,8 +468,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn gcd(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||||
fn gcd(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
|
||||||
match (n1, n2) {
|
match (n1, n2) {
|
||||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||||
if let Some(result) = isize_gcd(n1, 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))))
|
Ok(Number::from(Integer::from(n1).gcd(&Integer::from(n2))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Integer(n2)) |
|
(Number::Fixnum(n1), Number::Integer(n2))
|
||||||
(Number::Integer(n2), Number::Fixnum(n1)) => {
|
| (Number::Integer(n2), Number::Fixnum(n1)) => {
|
||||||
let n1 = Integer::from(n1);
|
let n1 = Integer::from(n1);
|
||||||
Ok(Number::from(Integer::from(n2.gcd_ref(&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);
|
let stub = MachineError::functor_stub(clause_name!("gcd"), 2);
|
||||||
|
|
||||||
Err(self.error_form(
|
Err(self.error_form(
|
||||||
MachineError::type_error(
|
MachineError::type_error(self.heap.h(), ValidType::Integer, n),
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Integer,
|
|
||||||
n
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -584,19 +499,14 @@ impl MachineState {
|
|||||||
let stub = MachineError::functor_stub(clause_name!("gcd"), 2);
|
let stub = MachineError::functor_stub(clause_name!("gcd"), 2);
|
||||||
|
|
||||||
Err(self.error_form(
|
Err(self.error_form(
|
||||||
MachineError::type_error(
|
MachineError::type_error(self.heap.h(), ValidType::Integer, n),
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Integer,
|
|
||||||
n,
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn float_pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||||
fn float_pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
|
||||||
let f1 = result_f(&n1, rnd_f);
|
let f1 = result_f(&n1, rnd_f);
|
||||||
let f2 = result_f(&n2, rnd_f);
|
let f2 = result_f(&n2, rnd_f);
|
||||||
|
|
||||||
@@ -612,8 +522,12 @@ impl MachineState {
|
|||||||
)?)))
|
)?)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn pow(
|
||||||
fn pow(&self, n1: Number, n2: Number, culprit: &'static str) -> Result<Number, MachineStub> {
|
&self,
|
||||||
|
n1: Number,
|
||||||
|
n2: Number,
|
||||||
|
culprit: &'static str,
|
||||||
|
) -> Result<Number, MachineStub> {
|
||||||
if n2.is_negative() && n1.is_zero() {
|
if n2.is_negative() && n1.is_zero() {
|
||||||
let stub = MachineError::functor_stub(clause_name!(culprit), 2);
|
let stub = MachineError::functor_stub(clause_name!(culprit), 2);
|
||||||
return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub));
|
return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub));
|
||||||
@@ -623,8 +537,11 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn unary_float_fn_template<FloatFn>(
|
||||||
fn unary_float_fn_template<FloatFn>(&self, n1: Number, f: FloatFn) -> Result<f64, MachineStub>
|
&self,
|
||||||
|
n1: Number,
|
||||||
|
f: FloatFn,
|
||||||
|
) -> Result<f64, MachineStub>
|
||||||
where
|
where
|
||||||
FloatFn: Fn(f64) -> f64,
|
FloatFn: Fn(f64) -> f64,
|
||||||
{
|
{
|
||||||
@@ -637,56 +554,47 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn sin(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||||
fn sin(&self, n1: Number) -> Result<f64, MachineStub> {
|
|
||||||
self.unary_float_fn_template(n1, |f| f.sin())
|
self.unary_float_fn_template(n1, |f| f.sin())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn cos(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||||
fn cos(&self, n1: Number) -> Result<f64, MachineStub> {
|
|
||||||
self.unary_float_fn_template(n1, |f| f.cos())
|
self.unary_float_fn_template(n1, |f| f.cos())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn tan(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||||
fn tan(&self, n1: Number) -> Result<f64, MachineStub> {
|
|
||||||
self.unary_float_fn_template(n1, |f| f.tan())
|
self.unary_float_fn_template(n1, |f| f.tan())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn log(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||||
fn log(&self, n1: Number) -> Result<f64, MachineStub> {
|
|
||||||
self.unary_float_fn_template(n1, |f| f.log(f64::consts::E))
|
self.unary_float_fn_template(n1, |f| f.log(f64::consts::E))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn exp(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||||
fn exp(&self, n1: Number) -> Result<f64, MachineStub> {
|
|
||||||
self.unary_float_fn_template(n1, |f| f.exp())
|
self.unary_float_fn_template(n1, |f| f.exp())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn asin(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||||
fn asin(&self, n1: Number) -> Result<f64, MachineStub> {
|
|
||||||
self.unary_float_fn_template(n1, |f| f.asin())
|
self.unary_float_fn_template(n1, |f| f.asin())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn acos(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||||
fn acos(&self, n1: Number) -> Result<f64, MachineStub> {
|
|
||||||
self.unary_float_fn_template(n1, |f| f.acos())
|
self.unary_float_fn_template(n1, |f| f.acos())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn atan(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||||
fn atan(&self, n1: Number) -> Result<f64, MachineStub> {
|
|
||||||
self.unary_float_fn_template(n1, |f| f.atan())
|
self.unary_float_fn_template(n1, |f| f.atan())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn sqrt(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||||
fn sqrt(&self, n1: Number) -> Result<f64, MachineStub> {
|
|
||||||
if n1.is_negative() {
|
if n1.is_negative() {
|
||||||
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
||||||
return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub));
|
return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub));
|
||||||
@@ -696,27 +604,23 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn float(&self, n: Number) -> Result<f64, MachineStub> {
|
||||||
fn float(&self, n: Number) -> Result<f64, MachineStub> {
|
|
||||||
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
||||||
try_numeric_result!(self, result_f(&n, rnd_f), stub)
|
try_numeric_result!(self, result_f(&n, rnd_f), stub)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn floor(&self, n1: Number) -> Number {
|
||||||
fn floor(&self, n1: Number) -> Number {
|
|
||||||
rnd_i(&n1).to_owned()
|
rnd_i(&n1).to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn ceiling(&self, n1: Number) -> Number {
|
||||||
fn ceiling(&self, n1: Number) -> Number {
|
|
||||||
-self.floor(-n1)
|
-self.floor(-n1)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn truncate(&self, n: Number) -> Number {
|
||||||
fn truncate(&self, n: Number) -> Number {
|
|
||||||
if n.is_negative() {
|
if n.is_negative() {
|
||||||
-self.floor(n.abs())
|
-self.floor(n.abs())
|
||||||
} else {
|
} else {
|
||||||
@@ -724,8 +628,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn round(&self, n: Number) -> Result<Number, MachineStub> {
|
||||||
fn round(&self, n: Number) -> Result<Number, MachineStub> {
|
|
||||||
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
||||||
|
|
||||||
let result = n + Number::Float(OrderedFloat(0.5f64));
|
let result = n + Number::Float(OrderedFloat(0.5f64));
|
||||||
@@ -734,8 +637,7 @@ impl MachineState {
|
|||||||
Ok(self.floor(result))
|
Ok(self.floor(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn shr(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||||
fn shr(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
|
||||||
let stub = MachineError::functor_stub(clause_name!("(>>)"), 2);
|
let stub = MachineError::functor_stub(clause_name!("(>>)"), 2);
|
||||||
|
|
||||||
match (n1, n2) {
|
match (n1, n2) {
|
||||||
@@ -756,38 +658,26 @@ impl MachineState {
|
|||||||
_ => Ok(Number::from(n1 >> u32::max_value())),
|
_ => Ok(Number::from(n1 >> u32::max_value())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
(Number::Integer(n1), Number::Fixnum(n2)) => match u32::try_from(n2) {
|
||||||
match u32::try_from(n2) {
|
|
||||||
Ok(n2) => Ok(Number::from(Integer::from(&*n1 >> n2))),
|
Ok(n2) => Ok(Number::from(Integer::from(&*n1 >> n2))),
|
||||||
_ => Ok(Number::from(Integer::from(&*n1 >> u32::max_value()))),
|
_ => Ok(Number::from(Integer::from(&*n1 >> u32::max_value()))),
|
||||||
}
|
},
|
||||||
}
|
(Number::Integer(n1), Number::Integer(n2)) => match n2.to_u32() {
|
||||||
(Number::Integer(n1), Number::Integer(n2)) =>
|
|
||||||
match n2.to_u32() {
|
|
||||||
Some(n2) => Ok(Number::from(Integer::from(&*n1 >> n2))),
|
Some(n2) => Ok(Number::from(Integer::from(&*n1 >> n2))),
|
||||||
_ => Ok(Number::from(Integer::from(&*n1 >> u32::max_value()))),
|
_ => Ok(Number::from(Integer::from(&*n1 >> u32::max_value()))),
|
||||||
},
|
},
|
||||||
(Number::Integer(_), n2) => Err(self.error_form(
|
(Number::Integer(_), n2) => Err(self.error_form(
|
||||||
MachineError::type_error(
|
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Integer,
|
|
||||||
n2,
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
)),
|
)),
|
||||||
(n1, _) => Err(self.error_form(
|
(n1, _) => Err(self.error_form(
|
||||||
MachineError::type_error(
|
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Integer,
|
|
||||||
n1,
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn shl(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||||
fn shl(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
|
||||||
let stub = MachineError::functor_stub(clause_name!("(<<)"), 2);
|
let stub = MachineError::functor_stub(clause_name!("(<<)"), 2);
|
||||||
|
|
||||||
match (n1, n2) {
|
match (n1, n2) {
|
||||||
@@ -808,263 +698,181 @@ impl MachineState {
|
|||||||
_ => Ok(Number::from(n1 << u32::max_value())),
|
_ => Ok(Number::from(n1 << u32::max_value())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
(Number::Integer(n1), Number::Fixnum(n2)) => match u32::try_from(n2) {
|
||||||
match u32::try_from(n2) {
|
|
||||||
Ok(n2) => Ok(Number::from(Integer::from(&*n1 << n2))),
|
Ok(n2) => Ok(Number::from(Integer::from(&*n1 << n2))),
|
||||||
_ => Ok(Number::from(Integer::from(&*n1 << u32::max_value()))),
|
_ => Ok(Number::from(Integer::from(&*n1 << u32::max_value()))),
|
||||||
}
|
},
|
||||||
}
|
|
||||||
(Number::Integer(n1), Number::Integer(n2)) => match n2.to_u32() {
|
(Number::Integer(n1), Number::Integer(n2)) => match n2.to_u32() {
|
||||||
Some(n2) => Ok(Number::from(Integer::from(&*n1 << n2))),
|
Some(n2) => Ok(Number::from(Integer::from(&*n1 << n2))),
|
||||||
_ => Ok(Number::from(Integer::from(&*n1 << u32::max_value()))),
|
_ => Ok(Number::from(Integer::from(&*n1 << u32::max_value()))),
|
||||||
},
|
},
|
||||||
(Number::Integer(_), n2) => Err(self.error_form(
|
(Number::Integer(_), n2) => Err(self.error_form(
|
||||||
MachineError::type_error(
|
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Integer,
|
|
||||||
n2,
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
)),
|
)),
|
||||||
(n1, _) => Err(self.error_form(
|
(n1, _) => Err(self.error_form(
|
||||||
MachineError::type_error(
|
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Integer,
|
|
||||||
n1,
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn bitwise_complement(&self, n1: Number) -> Result<Number, MachineStub> {
|
||||||
fn bitwise_complement(&self, n1: Number) -> Result<Number, MachineStub> {
|
|
||||||
let stub = MachineError::functor_stub(clause_name!("(\\)"), 2);
|
let stub = MachineError::functor_stub(clause_name!("(\\)"), 2);
|
||||||
|
|
||||||
match n1 {
|
match n1 {
|
||||||
Number::Fixnum(n) => Ok(Number::Fixnum(!n)),
|
Number::Fixnum(n) => Ok(Number::Fixnum(!n)),
|
||||||
Number::Integer(n1) => Ok(Number::from(Integer::from(!&*n1))),
|
Number::Integer(n1) => Ok(Number::from(Integer::from(!&*n1))),
|
||||||
_ => Err(self.error_form(
|
_ => Err(self.error_form(
|
||||||
MachineError::type_error(
|
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Integer,
|
|
||||||
n1,
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn xor(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||||
fn xor(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
|
||||||
let stub = MachineError::functor_stub(clause_name!("(xor)"), 2);
|
let stub = MachineError::functor_stub(clause_name!("(xor)"), 2);
|
||||||
|
|
||||||
match (n1, n2) {
|
match (n1, n2) {
|
||||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
(Number::Fixnum(n1), Number::Fixnum(n2)) => Ok(Number::from(n1 ^ n2)),
|
||||||
Ok(Number::from(n1 ^ n2))
|
|
||||||
}
|
|
||||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||||
let n1 = Integer::from(n1);
|
let n1 = Integer::from(n1);
|
||||||
Ok(Number::from(n1 ^ &*n2))
|
Ok(Number::from(n1 ^ &*n2))
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
(Number::Integer(n1), Number::Fixnum(n2)) => Ok(Number::from(&*n1 ^ Integer::from(n2))),
|
||||||
Ok(Number::from(&*n1 ^ Integer::from(n2)))
|
|
||||||
}
|
|
||||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||||
Ok(Number::from(Integer::from(&*n1 ^ &*n2)))
|
Ok(Number::from(Integer::from(&*n1 ^ &*n2)))
|
||||||
}
|
}
|
||||||
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => {
|
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => Err(self.error_form(
|
||||||
Err(self.error_form(
|
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
|
||||||
MachineError::type_error(
|
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Integer,
|
|
||||||
n2
|
|
||||||
),
|
|
||||||
stub,
|
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,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
(n1, _) => Err(self.error_form(
|
(n1, _) => Err(self.error_form(
|
||||||
MachineError::type_error(
|
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Integer,
|
|
||||||
n1,
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn and(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||||
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::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);
|
let stub = MachineError::functor_stub(clause_name!("(\\/)"), 2);
|
||||||
|
|
||||||
match (n1, n2) {
|
match (n1, n2) {
|
||||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
(Number::Fixnum(n1), Number::Fixnum(n2)) => Ok(Number::from(n1 | n2)),
|
||||||
Ok(Number::from(n1 | n2))
|
|
||||||
}
|
|
||||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||||
let n1 = Integer::from(n1);
|
let n1 = Integer::from(n1);
|
||||||
Ok(Number::from(n1 | &*n2))
|
Ok(Number::from(n1 | &*n2))
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
(Number::Integer(n1), Number::Fixnum(n2)) => Ok(Number::from(&*n1 | Integer::from(n2))),
|
||||||
Ok(Number::from(&*n1 | Integer::from(n2)))
|
|
||||||
}
|
|
||||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||||
Ok(Number::from(Integer::from(&*n1 | &*n2)))
|
Ok(Number::from(Integer::from(&*n1 | &*n2)))
|
||||||
}
|
}
|
||||||
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => {
|
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => Err(self.error_form(
|
||||||
Err(self.error_form(
|
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
|
||||||
MachineError::type_error(
|
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Integer,
|
|
||||||
n2,
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
))
|
)),
|
||||||
}
|
(n1, _) => Err(self.error_form(
|
||||||
(n1, _) => {
|
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
|
||||||
Err(self.error_form(
|
|
||||||
MachineError::type_error(
|
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Integer,
|
|
||||||
n1
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
))
|
)),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn modulus(&self, x: Number, y: Number) -> Result<Number, MachineStub> {
|
||||||
fn modulus(&self, x: Number, y: Number) -> Result<Number, MachineStub> {
|
|
||||||
let stub = MachineError::functor_stub(clause_name!("(mod)"), 2);
|
let stub = MachineError::functor_stub(clause_name!("(mod)"), 2);
|
||||||
|
|
||||||
match (x, y) {
|
match (x, y) {
|
||||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||||
if n2 == 0 {
|
if n2 == 0 {
|
||||||
Err(self.error_form(
|
Err(self
|
||||||
MachineError::evaluation_error(EvalError::ZeroDivisor),
|
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||||
stub,
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(Number::from(n1.rem_floor(n2)))
|
Ok(Number::from(n1.rem_floor(n2)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||||
if &*n2 == &0 {
|
if &*n2 == &0 {
|
||||||
Err(self.error_form(
|
Err(self
|
||||||
MachineError::evaluation_error(EvalError::ZeroDivisor),
|
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||||
stub,
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
let n1 = Integer::from(n1);
|
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)) => {
|
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
||||||
if n2 == 0 {
|
if n2 == 0 {
|
||||||
Err(self.error_form(
|
Err(self
|
||||||
MachineError::evaluation_error(EvalError::ZeroDivisor),
|
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||||
stub,
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
let n2 = Integer::from(n2);
|
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)) => {
|
(Number::Integer(x), Number::Integer(y)) => {
|
||||||
if &*y == &0 {
|
if &*y == &0 {
|
||||||
Err(self.error_form(
|
Err(self
|
||||||
MachineError::evaluation_error(EvalError::ZeroDivisor),
|
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||||
stub,
|
|
||||||
))
|
|
||||||
} else {
|
} 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(
|
(n1, _) => Err(self.error_form(
|
||||||
MachineError::type_error(
|
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Integer,
|
|
||||||
n1,
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn remainder(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||||
fn remainder(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
|
||||||
let stub = MachineError::functor_stub(clause_name!("(rem)"), 2);
|
let stub = MachineError::functor_stub(clause_name!("(rem)"), 2);
|
||||||
|
|
||||||
match (n1, n2) {
|
match (n1, n2) {
|
||||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||||
if n2 == 0 {
|
if n2 == 0 {
|
||||||
Err(self.error_form(
|
Err(self
|
||||||
MachineError::evaluation_error(EvalError::ZeroDivisor),
|
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||||
stub,
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(Number::from(n1 % n2))
|
Ok(Number::from(n1 % n2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||||
if &*n2 == &0 {
|
if &*n2 == &0 {
|
||||||
Err(self.error_form(
|
Err(self
|
||||||
MachineError::evaluation_error(EvalError::ZeroDivisor),
|
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||||
stub,
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
let n1 = Integer::from(n1);
|
let n1 = Integer::from(n1);
|
||||||
Ok(Number::from(n1 % &*n2))
|
Ok(Number::from(n1 % &*n2))
|
||||||
@@ -1072,10 +880,8 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
||||||
if n2 == 0 {
|
if n2 == 0 {
|
||||||
Err(self.error_form(
|
Err(self
|
||||||
MachineError::evaluation_error(EvalError::ZeroDivisor),
|
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||||
stub,
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
let n2 = Integer::from(n2);
|
let n2 = Integer::from(n2);
|
||||||
Ok(Number::from(&*n1 % n2))
|
Ok(Number::from(&*n1 % n2))
|
||||||
@@ -1083,37 +889,24 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||||
if &*n2 == &0 {
|
if &*n2 == &0 {
|
||||||
Err(self.error_form(
|
Err(self
|
||||||
MachineError::evaluation_error(EvalError::ZeroDivisor),
|
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||||
stub,
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(Number::from(Integer::from(&*n1 % &*n2)))
|
Ok(Number::from(Integer::from(&*n1 % &*n2)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => {
|
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => Err(self.error_form(
|
||||||
Err(self.error_form(
|
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
|
||||||
MachineError::type_error(
|
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Integer,
|
|
||||||
n2,
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
))
|
)),
|
||||||
}
|
|
||||||
(n1, _) => Err(self.error_form(
|
(n1, _) => Err(self.error_form(
|
||||||
MachineError::type_error(
|
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
|
||||||
self.heap.h(),
|
|
||||||
ValidType::Integer,
|
|
||||||
n1,
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn max(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||||
fn max(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
|
||||||
match (n1, n2) {
|
match (n1, n2) {
|
||||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||||
if n1 > n2 {
|
if n1 > n2 {
|
||||||
@@ -1154,8 +947,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn min(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||||
fn min(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
|
||||||
match (n1, n2) {
|
match (n1, n2) {
|
||||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||||
if n1 < n2 {
|
if n1 < n2 {
|
||||||
@@ -1196,8 +988,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn sign(&self, n: Number) -> Number {
|
||||||
fn sign(&self, n: Number) -> Number {
|
|
||||||
if n.is_positive() {
|
if n.is_positive() {
|
||||||
Number::from(1)
|
Number::from(1)
|
||||||
} else if n.is_negative() {
|
} else if n.is_negative() {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::heap_iter::*;
|
use crate::heap_iter::*;
|
||||||
use crate::machine::*;
|
use crate::machine::*;
|
||||||
|
use crate::prolog_parser_rebis::temp_v;
|
||||||
|
|
||||||
use crate::indexmap::IndexSet;
|
use crate::indexmap::IndexSet;
|
||||||
|
|
||||||
@@ -20,8 +21,7 @@ pub(super) struct AttrVarInitializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AttrVarInitializer {
|
impl AttrVarInitializer {
|
||||||
pub(super)
|
pub(super) fn new(verify_attrs_loc: usize, project_attrs_loc: usize) -> Self {
|
||||||
fn new(verify_attrs_loc: usize, project_attrs_loc: usize) -> Self {
|
|
||||||
AttrVarInitializer {
|
AttrVarInitializer {
|
||||||
attribute_goals: vec![],
|
attribute_goals: vec![],
|
||||||
attr_var_queue: vec![],
|
attr_var_queue: vec![],
|
||||||
@@ -34,24 +34,21 @@ impl AttrVarInitializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn reset(&mut self) {
|
||||||
fn reset(&mut self) {
|
|
||||||
self.attribute_goals.clear();
|
self.attribute_goals.clear();
|
||||||
self.attr_var_queue.clear();
|
self.attr_var_queue.clear();
|
||||||
self.bindings.clear();
|
self.bindings.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn backtrack(&mut self, queue_b: usize, bindings_b: usize) {
|
||||||
fn backtrack(&mut self, queue_b: usize, bindings_b: usize) {
|
|
||||||
self.attr_var_queue.truncate(queue_b);
|
self.attr_var_queue.truncate(queue_b);
|
||||||
self.bindings.truncate(bindings_b);
|
self.bindings.truncate(bindings_b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MachineState {
|
impl MachineState {
|
||||||
pub(super)
|
pub(super) fn push_attr_var_binding(&mut self, h: usize, addr: Addr) {
|
||||||
fn push_attr_var_binding(&mut self, h: usize, addr: Addr) {
|
|
||||||
if self.attr_var_init.bindings.is_empty() {
|
if self.attr_var_init.bindings.is_empty() {
|
||||||
self.attr_var_init.instigating_p = self.p.local();
|
self.attr_var_init.instigating_p = self.p.local();
|
||||||
|
|
||||||
@@ -97,8 +94,7 @@ impl MachineState {
|
|||||||
self[temp_v!(2)] = value_list_addr;
|
self[temp_v!(2)] = value_list_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn gather_attr_vars_created_since(&self, b: usize) -> IntoIter<Addr> {
|
||||||
fn gather_attr_vars_created_since(&self, b: usize) -> IntoIter<Addr> {
|
|
||||||
let mut attr_vars: Vec<_> = self.attr_var_init.attr_var_queue[b..]
|
let mut attr_vars: Vec<_> = self.attr_var_init.attr_var_queue[b..]
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|h| match self.store(self.deref(Addr::HeapCell(*h))) {
|
.filter_map(|h| match self.store(self.deref(Addr::HeapCell(*h))) {
|
||||||
@@ -107,16 +103,14 @@ impl MachineState {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
attr_vars.sort_unstable_by(|a1, a2| {
|
attr_vars
|
||||||
self.compare_term_test(a1, a2).unwrap_or(Ordering::Less)
|
.sort_unstable_by(|a1, a2| self.compare_term_test(a1, a2).unwrap_or(Ordering::Less));
|
||||||
});
|
|
||||||
|
|
||||||
self.term_dedup(&mut attr_vars);
|
self.term_dedup(&mut attr_vars);
|
||||||
attr_vars.into_iter()
|
attr_vars.into_iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn verify_attr_interrupt(&mut self, p: usize) {
|
||||||
fn verify_attr_interrupt(&mut self, p: usize) {
|
|
||||||
self.allocate(self.num_of_args + 2);
|
self.allocate(self.num_of_args + 2);
|
||||||
|
|
||||||
let e = self.e;
|
let e = self.e;
|
||||||
@@ -126,10 +120,8 @@ impl MachineState {
|
|||||||
self.stack.index_and_frame_mut(e)[i] = self[RegType::Temp(i)];
|
self.stack.index_and_frame_mut(e)[i] = self[RegType::Temp(i)];
|
||||||
}
|
}
|
||||||
|
|
||||||
self.stack.index_and_frame_mut(e)[self.num_of_args + 1] =
|
self.stack.index_and_frame_mut(e)[self.num_of_args + 1] = Addr::CutPoint(self.b0);
|
||||||
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 + 2] =
|
|
||||||
Addr::Usize(self.num_of_args);
|
|
||||||
|
|
||||||
self.verify_attributes();
|
self.verify_attributes();
|
||||||
|
|
||||||
@@ -138,8 +130,7 @@ impl MachineState {
|
|||||||
self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
|
self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn attr_vars_of_term(&self, addr: Addr) -> Vec<Addr> {
|
||||||
fn attr_vars_of_term(&self, addr: Addr) -> Vec<Addr> {
|
|
||||||
let mut seen_set = IndexSet::new();
|
let mut seen_set = IndexSet::new();
|
||||||
let mut seen_vars = vec![];
|
let mut seen_vars = vec![];
|
||||||
|
|
||||||
|
|||||||
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::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 indexmap::IndexSet;
|
||||||
|
|
||||||
use crate::ref_thread_local::RefThreadLocal;
|
use crate::ref_thread_local::RefThreadLocal;
|
||||||
@@ -19,16 +20,14 @@ pub(super) struct LoadState<'a> {
|
|||||||
pub(super) wam: &'a mut Machine,
|
pub(super) wam: &'a mut Machine,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn set_code_index(
|
||||||
fn set_code_index(
|
|
||||||
retraction_info: &mut RetractionInfo,
|
retraction_info: &mut RetractionInfo,
|
||||||
compilation_target: &CompilationTarget,
|
compilation_target: &CompilationTarget,
|
||||||
key: PredicateKey,
|
key: PredicateKey,
|
||||||
code_index: &CodeIndex,
|
code_index: &CodeIndex,
|
||||||
code_ptr: IndexPtr,
|
code_ptr: IndexPtr,
|
||||||
) {
|
) {
|
||||||
let record =
|
let record = match compilation_target {
|
||||||
match compilation_target {
|
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => {
|
||||||
if IndexPtr::Undefined == code_index.get() {
|
if IndexPtr::Undefined == code_index.get() {
|
||||||
code_index.set(code_ptr);
|
code_index.set(code_ptr);
|
||||||
@@ -71,16 +70,16 @@ fn add_op_decl_as_module_export(
|
|||||||
|
|
||||||
match op_decl.insert_into_op_dir(wam_op_dir) {
|
match op_decl.insert_into_op_dir(wam_op_dir) {
|
||||||
Some((prec, spec)) => {
|
Some((prec, spec)) => {
|
||||||
retraction_info.push_record(
|
retraction_info.push_record(RetractionRecord::ReplacedUserOp(
|
||||||
RetractionRecord::ReplacedUserOp(op_decl.clone(), prec, spec)
|
op_decl.clone(),
|
||||||
);
|
prec,
|
||||||
|
spec,
|
||||||
|
));
|
||||||
|
|
||||||
module_op_exports.push((op_decl.clone(), Some((prec, spec))));
|
module_op_exports.push((op_decl.clone(), Some((prec, spec))));
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
retraction_info.push_record(
|
retraction_info.push_record(RetractionRecord::AddedUserOp(op_decl.clone()));
|
||||||
RetractionRecord::AddedUserOp(op_decl.clone())
|
|
||||||
);
|
|
||||||
|
|
||||||
module_op_exports.push((op_decl.clone(), None));
|
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);
|
add_op_decl(retraction_info, compilation_target, module_op_dir, op_decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn add_op_decl(
|
||||||
fn add_op_decl(
|
|
||||||
retraction_info: &mut RetractionInfo,
|
retraction_info: &mut RetractionInfo,
|
||||||
compilation_target: &CompilationTarget,
|
compilation_target: &CompilationTarget,
|
||||||
op_dir: &mut OpDir,
|
op_dir: &mut OpDir,
|
||||||
op_decl: &OpDecl,
|
op_decl: &OpDecl,
|
||||||
) {
|
) {
|
||||||
match op_decl.insert_into_op_dir(op_dir) {
|
match op_decl.insert_into_op_dir(op_dir) {
|
||||||
Some((prec, spec)) => {
|
Some((prec, spec)) => match &compilation_target {
|
||||||
match &compilation_target {
|
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => {
|
||||||
retraction_info.push_record(
|
retraction_info.push_record(RetractionRecord::ReplacedUserOp(
|
||||||
RetractionRecord::ReplacedUserOp(op_decl.clone(), prec, spec),
|
op_decl.clone(),
|
||||||
);
|
prec,
|
||||||
|
spec,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
CompilationTarget::Module(ref module_name) => {
|
CompilationTarget::Module(ref module_name) => {
|
||||||
retraction_info.push_record(
|
retraction_info.push_record(RetractionRecord::ReplacedModuleOp(
|
||||||
RetractionRecord::ReplacedModuleOp(
|
module_name.clone(),
|
||||||
module_name.clone(), op_decl.clone(), prec, spec,
|
op_decl.clone(),
|
||||||
),
|
prec,
|
||||||
);
|
spec,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
None => match &compilation_target {
|
||||||
None => {
|
|
||||||
match &compilation_target {
|
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => {
|
||||||
retraction_info.push_record(
|
retraction_info.push_record(RetractionRecord::AddedUserOp(op_decl.clone()));
|
||||||
RetractionRecord::AddedUserOp(op_decl.clone()),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
CompilationTarget::Module(ref module_name) => {
|
CompilationTarget::Module(ref module_name) => {
|
||||||
retraction_info.push_record(
|
retraction_info.push_record(RetractionRecord::AddedModuleOp(
|
||||||
RetractionRecord::AddedModuleOp(module_name.clone(), op_decl.clone()),
|
module_name.clone(),
|
||||||
);
|
op_decl.clone(),
|
||||||
}
|
));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn import_module_exports(
|
||||||
fn import_module_exports(
|
|
||||||
retraction_info: &mut RetractionInfo,
|
retraction_info: &mut RetractionInfo,
|
||||||
compilation_target: &CompilationTarget,
|
compilation_target: &CompilationTarget,
|
||||||
imported_module: &Module,
|
imported_module: &Module,
|
||||||
@@ -166,12 +161,7 @@ fn import_module_exports(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ModuleExport::OpDecl(ref op_decl) => {
|
ModuleExport::OpDecl(ref op_decl) => {
|
||||||
add_op_decl(
|
add_op_decl(retraction_info, compilation_target, op_dir, op_decl);
|
||||||
retraction_info,
|
|
||||||
compilation_target,
|
|
||||||
op_dir,
|
|
||||||
op_decl,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,7 +175,7 @@ fn import_module_exports_into_module(
|
|||||||
op_dir: &mut OpDir,
|
op_dir: &mut OpDir,
|
||||||
meta_predicates: &mut MetaPredicateDir,
|
meta_predicates: &mut MetaPredicateDir,
|
||||||
wam_op_dir: &mut OpDir,
|
wam_op_dir: &mut OpDir,
|
||||||
module_op_exports: &mut ModuleOpExports
|
module_op_exports: &mut ModuleOpExports,
|
||||||
) {
|
) {
|
||||||
for export in imported_module.module_decl.exports.iter() {
|
for export in imported_module.module_decl.exports.iter() {
|
||||||
match export {
|
match export {
|
||||||
@@ -227,7 +217,6 @@ fn import_module_exports_into_module(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn import_qualified_module_exports(
|
fn import_qualified_module_exports(
|
||||||
retraction_info: &mut RetractionInfo,
|
retraction_info: &mut RetractionInfo,
|
||||||
compilation_target: &CompilationTarget,
|
compilation_target: &CompilationTarget,
|
||||||
@@ -263,12 +252,7 @@ fn import_qualified_module_exports(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ModuleExport::OpDecl(ref op_decl) => {
|
ModuleExport::OpDecl(ref op_decl) => {
|
||||||
add_op_decl(
|
add_op_decl(retraction_info, compilation_target, op_dir, op_decl);
|
||||||
retraction_info,
|
|
||||||
compilation_target,
|
|
||||||
op_dir,
|
|
||||||
op_decl,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -326,28 +310,27 @@ fn import_qualified_module_exports_into_module(
|
|||||||
|
|
||||||
impl<'a> LoadState<'a> {
|
impl<'a> LoadState<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn increment_clause_assert_margin(&mut self, incr: usize) {
|
||||||
fn increment_clause_assert_margin(&mut self, incr: usize) {
|
|
||||||
match &self.compilation_target {
|
match &self.compilation_target {
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => {}
|
||||||
}
|
|
||||||
CompilationTarget::Module(ref module_name) => {
|
CompilationTarget::Module(ref module_name) => {
|
||||||
self.retraction_info.push_record(
|
self.retraction_info
|
||||||
RetractionRecord::IncreasedClauseAssertMargin(
|
.push_record(RetractionRecord::IncreasedClauseAssertMargin(
|
||||||
module_name.clone(),
|
module_name.clone(),
|
||||||
incr,
|
incr,
|
||||||
),
|
));
|
||||||
);
|
|
||||||
|
|
||||||
self.wam.indices.modules.get_mut(module_name)
|
self.wam
|
||||||
|
.indices
|
||||||
|
.modules
|
||||||
|
.get_mut(module_name)
|
||||||
.map(|module| module.clause_assert_margin += incr);
|
.map(|module| module.clause_assert_margin += incr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn remove_module_op_exports(&mut self) {
|
||||||
fn remove_module_op_exports(&mut self) {
|
|
||||||
for (mut op_decl, record) in self.module_op_exports.drain(0..) {
|
for (mut op_decl, record) in self.module_op_exports.drain(0..) {
|
||||||
op_decl.remove(&mut self.wam.indices.op_dir);
|
op_decl.remove(&mut self.wam.indices.op_dir);
|
||||||
|
|
||||||
@@ -365,26 +348,28 @@ impl<'a> LoadState<'a> {
|
|||||||
key: PredicateKey,
|
key: PredicateKey,
|
||||||
) -> CodeIndex {
|
) -> CodeIndex {
|
||||||
match self.wam.indices.modules.get_mut(&module_name) {
|
match self.wam.indices.modules.get_mut(&module_name) {
|
||||||
Some(ref mut module) => {
|
Some(ref mut module) => module
|
||||||
module.code_dir
|
.code_dir
|
||||||
.entry(key)
|
.entry(key)
|
||||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||||
.clone()
|
.clone(),
|
||||||
}
|
|
||||||
None => {
|
None => {
|
||||||
let mut module = Module::new(
|
let mut module = Module::new(
|
||||||
ModuleDecl { name: module_name.clone(), exports: vec![] },
|
ModuleDecl {
|
||||||
|
name: module_name.clone(),
|
||||||
|
exports: vec![],
|
||||||
|
},
|
||||||
ListingSource::DynamicallyGenerated,
|
ListingSource::DynamicallyGenerated,
|
||||||
);
|
);
|
||||||
|
|
||||||
let code_index = module.code_dir
|
let code_index = module
|
||||||
|
.code_dir
|
||||||
.entry(key)
|
.entry(key)
|
||||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
self.retraction_info.push_record(
|
self.retraction_info
|
||||||
RetractionRecord::AddedModule(module_name.clone()),
|
.push_record(RetractionRecord::AddedModule(module_name.clone()));
|
||||||
);
|
|
||||||
|
|
||||||
self.wam.indices.modules.insert(module_name, module);
|
self.wam.indices.modules.insert(module_name, module);
|
||||||
code_index
|
code_index
|
||||||
@@ -392,29 +377,31 @@ impl<'a> LoadState<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn get_or_insert_code_index(&mut self, key: PredicateKey) -> CodeIndex {
|
||||||
fn get_or_insert_code_index(&mut self, key: PredicateKey) -> CodeIndex {
|
|
||||||
match self.compilation_target.clone() {
|
match self.compilation_target.clone() {
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => self
|
||||||
self.wam.indices.code_dir
|
.wam
|
||||||
|
.indices
|
||||||
|
.code_dir
|
||||||
.entry(key)
|
.entry(key)
|
||||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||||
.clone()
|
.clone(),
|
||||||
}
|
|
||||||
CompilationTarget::Module(module_name) => {
|
CompilationTarget::Module(module_name) => {
|
||||||
self.get_or_insert_local_code_index(module_name, key)
|
self.get_or_insert_local_code_index(module_name, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn get_or_insert_qualified_code_index(
|
||||||
fn get_or_insert_qualified_code_index(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
module_name: ClauseName,
|
module_name: ClauseName,
|
||||||
key: PredicateKey,
|
key: PredicateKey,
|
||||||
) -> CodeIndex {
|
) -> CodeIndex {
|
||||||
if module_name.as_str() == "user" {
|
if module_name.as_str() == "user" {
|
||||||
return self.wam.indices.code_dir
|
return self
|
||||||
|
.wam
|
||||||
|
.indices
|
||||||
|
.code_dir
|
||||||
.entry(key)
|
.entry(key)
|
||||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||||
.clone();
|
.clone();
|
||||||
@@ -424,15 +411,20 @@ impl<'a> LoadState<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn add_extensible_predicate(
|
||||||
fn add_extensible_predicate(&mut self, key: PredicateKey, skeleton: PredicateSkeleton) {
|
&mut self,
|
||||||
|
key: PredicateKey,
|
||||||
|
skeleton: PredicateSkeleton,
|
||||||
|
) {
|
||||||
match &self.compilation_target {
|
match &self.compilation_target {
|
||||||
CompilationTarget::User => {
|
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(
|
self.retraction_info
|
||||||
RetractionRecord::AddedUserExtensiblePredicate(key),
|
.push_record(RetractionRecord::AddedUserExtensiblePredicate(key));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
CompilationTarget::Module(ref module_name) => {
|
CompilationTarget::Module(ref module_name) => {
|
||||||
if let Some(module) = self.wam.indices.modules.get_mut(module_name) {
|
if let Some(module) = self.wam.indices.modules.get_mut(module_name) {
|
||||||
@@ -448,8 +440,7 @@ impl<'a> LoadState<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn add_op_decl(&mut self, op_decl: &OpDecl) {
|
||||||
fn add_op_decl(&mut self, op_decl: &OpDecl) {
|
|
||||||
match &self.compilation_target {
|
match &self.compilation_target {
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => {
|
||||||
add_op_decl(
|
add_op_decl(
|
||||||
@@ -479,8 +470,7 @@ impl<'a> LoadState<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn get_clause_type(
|
||||||
fn get_clause_type(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
name: ClauseName,
|
name: ClauseName,
|
||||||
arity: usize,
|
arity: usize,
|
||||||
@@ -495,14 +485,11 @@ impl<'a> LoadState<'a> {
|
|||||||
let idx = self.get_or_insert_code_index((name.clone(), arity));
|
let idx = self.get_or_insert_code_index((name.clone(), arity));
|
||||||
ClauseType::Op(name, fixity, idx)
|
ClauseType::Op(name, fixity, idx)
|
||||||
}
|
}
|
||||||
ct => {
|
ct => ct,
|
||||||
ct
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn get_qualified_clause_type(
|
||||||
fn get_qualified_clause_type(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
module_name: ClauseName,
|
module_name: ClauseName,
|
||||||
name: ClauseName,
|
name: ClauseName,
|
||||||
@@ -522,14 +509,11 @@ impl<'a> LoadState<'a> {
|
|||||||
|
|
||||||
ClauseType::Op(name, fixity, idx)
|
ClauseType::Op(name, fixity, idx)
|
||||||
}
|
}
|
||||||
ct => {
|
ct => ct,
|
||||||
ct
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn add_meta_predicate_record(
|
||||||
fn add_meta_predicate_record(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
module_name: ClauseName,
|
module_name: ClauseName,
|
||||||
name: ClauseName,
|
name: ClauseName,
|
||||||
@@ -540,20 +524,26 @@ impl<'a> LoadState<'a> {
|
|||||||
|
|
||||||
match module_name.as_str() {
|
match module_name.as_str() {
|
||||||
"user" => {
|
"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) => {
|
Some(old_meta_specs) => {
|
||||||
self.retraction_info.push_record(
|
self.retraction_info
|
||||||
RetractionRecord::ReplacedMetaPredicate(
|
.push_record(RetractionRecord::ReplacedMetaPredicate(
|
||||||
module_name.clone(), key.0, old_meta_specs,
|
module_name.clone(),
|
||||||
),
|
key.0,
|
||||||
);
|
old_meta_specs,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.retraction_info.push_record(
|
self.retraction_info
|
||||||
RetractionRecord::AddedMetaPredicate(
|
.push_record(RetractionRecord::AddedMetaPredicate(
|
||||||
module_name.clone(), key,
|
module_name.clone(),
|
||||||
)
|
key,
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -564,15 +554,15 @@ impl<'a> LoadState<'a> {
|
|||||||
Some(old_meta_specs) => {
|
Some(old_meta_specs) => {
|
||||||
self.retraction_info.push_record(
|
self.retraction_info.push_record(
|
||||||
RetractionRecord::ReplacedMetaPredicate(
|
RetractionRecord::ReplacedMetaPredicate(
|
||||||
module_name.clone(), key.0, old_meta_specs,
|
module_name.clone(),
|
||||||
|
key.0,
|
||||||
|
old_meta_specs,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.retraction_info.push_record(
|
self.retraction_info.push_record(
|
||||||
RetractionRecord::AddedMetaPredicate(
|
RetractionRecord::AddedMetaPredicate(module_name.clone(), key),
|
||||||
module_name.clone(), key,
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -588,15 +578,14 @@ impl<'a> LoadState<'a> {
|
|||||||
|
|
||||||
module.meta_predicates.insert(key.clone(), meta_specs);
|
module.meta_predicates.insert(key.clone(), meta_specs);
|
||||||
|
|
||||||
self.retraction_info.push_record(
|
self.retraction_info
|
||||||
RetractionRecord::AddedMetaPredicate(
|
.push_record(RetractionRecord::AddedMetaPredicate(
|
||||||
module_name.clone(), key,
|
module_name.clone(),
|
||||||
)
|
key,
|
||||||
);
|
));
|
||||||
|
|
||||||
self.retraction_info.push_record(
|
self.retraction_info
|
||||||
RetractionRecord::AddedModule(module_name.clone()),
|
.push_record(RetractionRecord::AddedModule(module_name.clone()));
|
||||||
);
|
|
||||||
|
|
||||||
self.wam.indices.modules.insert(module_name, module);
|
self.wam.indices.modules.insert(module_name, module);
|
||||||
}
|
}
|
||||||
@@ -623,28 +612,25 @@ impl<'a> LoadState<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn add_module(&mut self, module_decl: ModuleDecl, listing_src: ListingSource) {
|
||||||
fn add_module(&mut self, module_decl: ModuleDecl, listing_src: ListingSource) {
|
|
||||||
let module_name = module_decl.name.clone();
|
let module_name = module_decl.name.clone();
|
||||||
|
|
||||||
let mut module =
|
let mut module = match self.wam.indices.modules.remove(&module_name) {
|
||||||
match self.wam.indices.modules.remove(&module_name) {
|
|
||||||
Some(mut module) => {
|
Some(mut module) => {
|
||||||
let old_module_decl = mem::replace(&mut module.module_decl, module_decl);
|
let old_module_decl = mem::replace(&mut module.module_decl, module_decl);
|
||||||
|
|
||||||
self.retraction_info.push_record(
|
self.retraction_info
|
||||||
RetractionRecord::ReplacedModule(
|
.push_record(RetractionRecord::ReplacedModule(
|
||||||
old_module_decl, listing_src.clone(),
|
old_module_decl,
|
||||||
),
|
listing_src.clone(),
|
||||||
);
|
));
|
||||||
|
|
||||||
module.listing_src = listing_src;
|
module.listing_src = listing_src;
|
||||||
module
|
module
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.retraction_info.push_record(
|
self.retraction_info
|
||||||
RetractionRecord::AddedModule(module_name.clone()),
|
.push_record(RetractionRecord::AddedModule(module_name.clone()));
|
||||||
);
|
|
||||||
|
|
||||||
Module::new(module_decl, listing_src)
|
Module::new(module_decl, listing_src)
|
||||||
}
|
}
|
||||||
@@ -676,8 +662,7 @@ impl<'a> LoadState<'a> {
|
|||||||
self.wam.indices.modules.insert(module_name, module);
|
self.wam.indices.modules.insert(module_name, module);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn import_module(&mut self, module_name: ClauseName) -> Result<(), SessionError> {
|
||||||
fn import_module(&mut self, module_name: ClauseName) -> Result<(), SessionError> {
|
|
||||||
if let Some(module) = self.wam.indices.modules.remove(&module_name) {
|
if let Some(module) = self.wam.indices.modules.remove(&module_name) {
|
||||||
match &self.compilation_target {
|
match &self.compilation_target {
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => {
|
||||||
@@ -717,7 +702,9 @@ impl<'a> LoadState<'a> {
|
|||||||
self.wam.indices.modules.insert(module_name, module);
|
self.wam.indices.modules.insert(module_name, module);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(SessionError::ExistenceError(ExistenceError::Module(module_name)))
|
Err(SessionError::ExistenceError(ExistenceError::Module(
|
||||||
|
module_name,
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -765,24 +752,25 @@ impl<'a> LoadState<'a> {
|
|||||||
self.wam.indices.modules.insert(module_name, module);
|
self.wam.indices.modules.insert(module_name, module);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(SessionError::ExistenceError(ExistenceError::Module(module_name)))
|
Err(SessionError::ExistenceError(ExistenceError::Module(
|
||||||
|
module_name,
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn use_module(&mut self, module_src: ModuleSource) -> Result<(), SessionError> {
|
||||||
fn use_module(&mut self, module_src: ModuleSource) -> Result<(), SessionError> {
|
let (stream, listing_src) = match module_src {
|
||||||
let (stream, listing_src) =
|
|
||||||
match module_src {
|
|
||||||
ModuleSource::File(filename) => {
|
ModuleSource::File(filename) => {
|
||||||
let mut path_buf = PathBuf::from(filename.as_str());
|
let mut path_buf = PathBuf::from(filename.as_str());
|
||||||
path_buf.set_extension("pl");
|
path_buf.set_extension("pl");
|
||||||
let file = File::open(&path_buf)?;
|
let file = File::open(&path_buf)?;
|
||||||
|
|
||||||
(Stream::from_file_as_input(filename.clone(), file),
|
(
|
||||||
ListingSource::File(filename, path_buf))
|
Stream::from_file_as_input(filename.clone(), file),
|
||||||
|
ListingSource::File(filename, path_buf),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
ModuleSource::Library(library) => {
|
ModuleSource::Library(library) => match LIBRARIES.borrow().get(library.as_str()) {
|
||||||
match LIBRARIES.borrow().get(library.as_str()) {
|
|
||||||
Some(code) => {
|
Some(code) => {
|
||||||
if let Some(ref module) = self.wam.indices.modules.get(&library) {
|
if let Some(ref module) = self.wam.indices.modules.get(&library) {
|
||||||
if let ListingSource::DynamicallyGenerated = &module.listing_src {
|
if let ListingSource::DynamicallyGenerated = &module.listing_src {
|
||||||
@@ -797,8 +785,7 @@ impl<'a> LoadState<'a> {
|
|||||||
None => {
|
None => {
|
||||||
return self.import_module(library);
|
return self.import_module(library);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let compilation_target = {
|
let compilation_target = {
|
||||||
@@ -820,30 +807,27 @@ impl<'a> LoadState<'a> {
|
|||||||
// nothing to do.
|
// nothing to do.
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
CompilationTarget::Module(module_name) => {
|
CompilationTarget::Module(module_name) => self.import_module(module_name),
|
||||||
self.import_module(module_name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn use_qualified_module(
|
||||||
fn use_qualified_module(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
module_src: ModuleSource,
|
module_src: ModuleSource,
|
||||||
exports: IndexSet<ModuleExport>,
|
exports: IndexSet<ModuleExport>,
|
||||||
) -> Result<(), SessionError> {
|
) -> Result<(), SessionError> {
|
||||||
let (stream, listing_src) =
|
let (stream, listing_src) = match module_src {
|
||||||
match module_src {
|
|
||||||
ModuleSource::File(filename) => {
|
ModuleSource::File(filename) => {
|
||||||
let mut path_buf = PathBuf::from(filename.as_str());
|
let mut path_buf = PathBuf::from(filename.as_str());
|
||||||
path_buf.set_extension("pl");
|
path_buf.set_extension("pl");
|
||||||
let file = File::open(&path_buf)?;
|
let file = File::open(&path_buf)?;
|
||||||
|
|
||||||
(Stream::from_file_as_input(filename.clone(), file),
|
(
|
||||||
ListingSource::File(filename, path_buf))
|
Stream::from_file_as_input(filename.clone(), file),
|
||||||
|
ListingSource::File(filename, path_buf),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
ModuleSource::Library(library) => {
|
ModuleSource::Library(library) => match LIBRARIES.borrow().get(library.as_str()) {
|
||||||
match LIBRARIES.borrow().get(library.as_str()) {
|
|
||||||
Some(code) => {
|
Some(code) => {
|
||||||
if self.wam.indices.modules.contains_key(&library) {
|
if self.wam.indices.modules.contains_key(&library) {
|
||||||
return self.import_qualified_module(library, exports);
|
return self.import_qualified_module(library, exports);
|
||||||
@@ -854,8 +838,7 @@ impl<'a> LoadState<'a> {
|
|||||||
None => {
|
None => {
|
||||||
return self.import_qualified_module(library, exports);
|
return self.import_qualified_module(library, exports);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let compilation_target = {
|
let compilation_target = {
|
||||||
@@ -884,12 +867,9 @@ impl<'a> LoadState<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn composite_op_dir(&self) -> CompositeOpDir {
|
||||||
fn composite_op_dir(&self) -> CompositeOpDir {
|
|
||||||
match &self.compilation_target {
|
match &self.compilation_target {
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => CompositeOpDir::new(&self.wam.indices.op_dir, None),
|
||||||
CompositeOpDir::new(&self.wam.indices.op_dir, None)
|
|
||||||
}
|
|
||||||
CompilationTarget::Module(ref module_name) => {
|
CompilationTarget::Module(ref module_name) => {
|
||||||
match self.wam.indices.modules.get(module_name) {
|
match self.wam.indices.modules.get(module_name) {
|
||||||
Some(ref module) => {
|
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::ast::*;
|
||||||
|
use crate::prolog_parser_rebis::{clause_name, temp_v};
|
||||||
|
|
||||||
use crate::forms::{ModuleSource, Number}; //, PredicateKey};
|
use crate::forms::{ModuleSource, Number}; //, PredicateKey};
|
||||||
use crate::machine::heap::*;
|
use crate::machine::heap::*;
|
||||||
@@ -23,74 +24,59 @@ pub(crate) struct MachineError {
|
|||||||
from: ErrorProvenance,
|
from: ErrorProvenance,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) trait TypeError {
|
||||||
trait TypeError {
|
|
||||||
fn type_error(self, h: usize, valid_type: ValidType) -> MachineError;
|
fn type_error(self, h: usize, valid_type: ValidType) -> MachineError;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeError for Addr {
|
impl TypeError for Addr {
|
||||||
fn type_error(self, _: usize, valid_type: ValidType) -> MachineError {
|
fn type_error(self, _: usize, valid_type: ValidType) -> MachineError {
|
||||||
let stub = functor!(
|
let stub = functor!("type_error", [atom(valid_type.as_str()), addr(self)]);
|
||||||
"type_error",
|
|
||||||
[atom(valid_type.as_str()), addr(self)]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
location: None,
|
location: None,
|
||||||
from: ErrorProvenance::Received
|
from: ErrorProvenance::Received,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeError for HeapCellValue {
|
impl TypeError for HeapCellValue {
|
||||||
fn type_error(self, _: usize, valid_type: ValidType) -> MachineError {
|
fn type_error(self, _: usize, valid_type: ValidType) -> MachineError {
|
||||||
let stub = functor!(
|
let stub = functor!("type_error", [atom(valid_type.as_str()), value(self)]);
|
||||||
"type_error",
|
|
||||||
[atom(valid_type.as_str()), value(self)]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
location: None,
|
location: None,
|
||||||
from: ErrorProvenance::Received
|
from: ErrorProvenance::Received,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeError for MachineStub {
|
impl TypeError for MachineStub {
|
||||||
fn type_error(self, h: usize, valid_type: ValidType) -> MachineError {
|
fn type_error(self, h: usize, valid_type: ValidType) -> MachineError {
|
||||||
let stub = functor!(
|
let stub = functor!("type_error", [atom(valid_type.as_str()), aux(h, 0)], [self]);
|
||||||
"type_error",
|
|
||||||
[atom(valid_type.as_str()), aux(h, 0)],
|
|
||||||
[self]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
location: None,
|
location: None,
|
||||||
from: ErrorProvenance::Constructed
|
from: ErrorProvenance::Constructed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeError for Number {
|
impl TypeError for Number {
|
||||||
fn type_error(self, _h: usize, valid_type: ValidType) -> MachineError {
|
fn type_error(self, _h: usize, valid_type: ValidType) -> MachineError {
|
||||||
let stub = functor!(
|
let stub = functor!("type_error", [atom(valid_type.as_str()), number(self)]);
|
||||||
"type_error",
|
|
||||||
[atom(valid_type.as_str()), number(self)]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
location: None,
|
location: None,
|
||||||
from: ErrorProvenance::Received
|
from: ErrorProvenance::Received,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) trait PermissionError {
|
||||||
trait PermissionError {
|
|
||||||
fn permission_error(self, h: usize, index_str: &'static str, perm: Permission) -> MachineError;
|
fn permission_error(self, h: usize, index_str: &'static str, perm: Permission) -> MachineError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +90,7 @@ impl PermissionError for Addr {
|
|||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
location: None,
|
location: None,
|
||||||
from: ErrorProvenance::Received
|
from: ErrorProvenance::Received,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,22 +106,18 @@ impl PermissionError for MachineStub {
|
|||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
location: None,
|
location: None,
|
||||||
from: ErrorProvenance::Constructed
|
from: ErrorProvenance::Constructed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) trait DomainError {
|
||||||
trait DomainError {
|
|
||||||
fn domain_error(self, error: DomainErrorType) -> MachineError;
|
fn domain_error(self, error: DomainErrorType) -> MachineError;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DomainError for Addr {
|
impl DomainError for Addr {
|
||||||
fn domain_error(self, error: DomainErrorType) -> MachineError {
|
fn domain_error(self, error: DomainErrorType) -> MachineError {
|
||||||
let stub = functor!(
|
let stub = functor!("domain_error", [atom(error.as_str()), addr(self)]);
|
||||||
"domain_error",
|
|
||||||
[atom(error.as_str()), addr(self)]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -147,10 +129,7 @@ impl DomainError for Addr {
|
|||||||
|
|
||||||
impl DomainError for Number {
|
impl DomainError for Number {
|
||||||
fn domain_error(self, error: DomainErrorType) -> MachineError {
|
fn domain_error(self, error: DomainErrorType) -> MachineError {
|
||||||
let stub = functor!(
|
let stub = functor!("domain_error", [atom(error.as_str()), number(self)]);
|
||||||
"domain_error",
|
|
||||||
[atom(error.as_str()), number(self)]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -161,8 +140,7 @@ impl DomainError for Number {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MachineError {
|
impl MachineError {
|
||||||
pub(super)
|
pub(super) fn functor_stub(name: ClauseName, arity: usize) -> MachineStub {
|
||||||
fn functor_stub(name: ClauseName, arity: usize) -> MachineStub {
|
|
||||||
functor!(
|
functor!(
|
||||||
"/",
|
"/",
|
||||||
SharedOpDesc::new(400, YFX),
|
SharedOpDesc::new(400, YFX),
|
||||||
@@ -171,8 +149,7 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn interrupt_error() -> Self {
|
||||||
fn interrupt_error() -> Self {
|
|
||||||
let stub = functor!("$interrupt_thrown");
|
let stub = functor!("$interrupt_thrown");
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
@@ -182,8 +159,7 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn evaluation_error(eval_error: EvalError) -> Self {
|
||||||
fn evaluation_error(eval_error: EvalError) -> Self {
|
|
||||||
let stub = functor!("evaluation_error", [atom(eval_error.as_str())]);
|
let stub = functor!("evaluation_error", [atom(eval_error.as_str())]);
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
@@ -193,13 +169,11 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn type_error<T: TypeError>(h: usize, valid_type: ValidType, culprit: T) -> Self {
|
||||||
fn type_error<T: TypeError>(h: usize, valid_type: ValidType, culprit: T) -> Self {
|
|
||||||
culprit.type_error(h, valid_type)
|
culprit.type_error(h, valid_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn module_resolution_error(
|
||||||
fn module_resolution_error(
|
|
||||||
h: usize,
|
h: usize,
|
||||||
mod_name: ClauseName,
|
mod_name: ClauseName,
|
||||||
name: ClauseName,
|
name: ClauseName,
|
||||||
@@ -218,11 +192,7 @@ impl MachineError {
|
|||||||
[res_stub]
|
[res_stub]
|
||||||
);
|
);
|
||||||
|
|
||||||
let stub = functor!(
|
let stub = functor!("evaluation_error", [aux(h, 0)], [ind_stub]);
|
||||||
"evaluation_error",
|
|
||||||
[aux(h, 0)],
|
|
||||||
[ind_stub]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -231,14 +201,10 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn existence_error(h: usize, err: ExistenceError) -> Self {
|
||||||
fn existence_error(h: usize, err: ExistenceError) -> Self {
|
|
||||||
match err {
|
match err {
|
||||||
ExistenceError::Module(name) => {
|
ExistenceError::Module(name) => {
|
||||||
let stub = functor!(
|
let stub = functor!("existence_error", [atom("source_sink"), clause_name(name)]);
|
||||||
"existence_error",
|
|
||||||
[atom("source_sink"), clause_name(name)]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -253,11 +219,7 @@ impl MachineError {
|
|||||||
[clause_name(name), integer(arity)]
|
[clause_name(name), integer(arity)]
|
||||||
);
|
);
|
||||||
|
|
||||||
let stub = functor!(
|
let stub = functor!("existence_error", [atom("procedure"), aux(h, 0)], [culprit]);
|
||||||
"existence_error",
|
|
||||||
[atom("procedure"), aux(h, 0)],
|
|
||||||
[culprit]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -281,10 +243,7 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExistenceError::SourceSink(culprit) => {
|
ExistenceError::SourceSink(culprit) => {
|
||||||
let stub = functor!(
|
let stub = functor!("existence_error", [atom("source_sink"), addr(culprit)]);
|
||||||
"existence_error",
|
|
||||||
[atom("source_sink"), addr(culprit)]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -293,10 +252,7 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExistenceError::Stream(culprit) => {
|
ExistenceError::Stream(culprit) => {
|
||||||
let stub = functor!(
|
let stub = functor!("existence_error", [atom("stream"), addr(culprit)]);
|
||||||
"existence_error",
|
|
||||||
[atom("stream"), addr(culprit)]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -307,25 +263,18 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn permission_error<T: PermissionError>(
|
||||||
fn permission_error<T: PermissionError>(
|
|
||||||
h: usize,
|
h: usize,
|
||||||
err: Permission,
|
err: Permission,
|
||||||
index_str: &'static str,
|
index_str: &'static str,
|
||||||
culprit: T,
|
culprit: T,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
culprit.permission_error(
|
culprit.permission_error(h, index_str, err)
|
||||||
h,
|
|
||||||
index_str,
|
|
||||||
err,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arithmetic_error(h: usize, err: ArithmeticError) -> Self {
|
fn arithmetic_error(h: usize, err: ArithmeticError) -> Self {
|
||||||
match err {
|
match err {
|
||||||
ArithmeticError::UninstantiatedVar => {
|
ArithmeticError::UninstantiatedVar => Self::instantiation_error(),
|
||||||
Self::instantiation_error()
|
|
||||||
}
|
|
||||||
ArithmeticError::NonEvaluableFunctor(name, arity) => {
|
ArithmeticError::NonEvaluableFunctor(name, arity) => {
|
||||||
let culprit = functor!(
|
let culprit = functor!(
|
||||||
"/",
|
"/",
|
||||||
@@ -339,13 +288,11 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn domain_error<T: DomainError>(error: DomainErrorType, culprit: T) -> Self {
|
||||||
fn domain_error<T: DomainError>(error: DomainErrorType, culprit: T) -> Self {
|
|
||||||
culprit.domain_error(error)
|
culprit.domain_error(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn instantiation_error() -> Self {
|
||||||
fn instantiation_error() -> Self {
|
|
||||||
let stub = functor!("instantiation_error");
|
let stub = functor!("instantiation_error");
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
@@ -355,8 +302,7 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn session_error(h: usize, err: SessionError) -> Self {
|
||||||
fn session_error(h: usize, err: SessionError) -> Self {
|
|
||||||
match err {
|
match err {
|
||||||
// SessionError::CannotOverwriteBuiltIn(pred_str) |
|
// SessionError::CannotOverwriteBuiltIn(pred_str) |
|
||||||
/*
|
/*
|
||||||
@@ -369,9 +315,7 @@ impl MachineError {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
SessionError::ExistenceError(err) => {
|
SessionError::ExistenceError(err) => Self::existence_error(h, err),
|
||||||
Self::existence_error(h, err)
|
|
||||||
}
|
|
||||||
// SessionError::InvalidFileName(filename) => {
|
// SessionError::InvalidFileName(filename) => {
|
||||||
// Self::existence_error(h, ExistenceError::Module(filename))
|
// Self::existence_error(h, ExistenceError::Module(filename))
|
||||||
// }
|
// }
|
||||||
@@ -385,46 +329,32 @@ impl MachineError {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
SessionError::ModuleCannotImportSelf(module_name) => {
|
SessionError::ModuleCannotImportSelf(module_name) => Self::permission_error(
|
||||||
Self::permission_error(
|
|
||||||
h,
|
h,
|
||||||
Permission::Modify,
|
Permission::Modify,
|
||||||
"module",
|
"module",
|
||||||
functor!("module_cannot_import_self", [clause_name(module_name)]),
|
functor!("module_cannot_import_self", [clause_name(module_name)]),
|
||||||
)
|
),
|
||||||
}
|
SessionError::NamelessEntry => Self::permission_error(
|
||||||
SessionError::NamelessEntry => {
|
|
||||||
Self::permission_error(
|
|
||||||
h,
|
h,
|
||||||
Permission::Create,
|
Permission::Create,
|
||||||
"static_procedure",
|
"static_procedure",
|
||||||
functor!("nameless_procedure")
|
functor!("nameless_procedure"),
|
||||||
)
|
),
|
||||||
}
|
|
||||||
SessionError::OpIsInfixAndPostFix(op) => {
|
SessionError::OpIsInfixAndPostFix(op) => {
|
||||||
Self::permission_error(
|
Self::permission_error(h, Permission::Create, "operator", functor!(clause_name(op)))
|
||||||
h,
|
|
||||||
Permission::Create,
|
|
||||||
"operator",
|
|
||||||
functor!(clause_name(op)),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
SessionError::CompilationError(err) => {
|
SessionError::CompilationError(err) => Self::syntax_error(h, err),
|
||||||
Self::syntax_error(h, err)
|
SessionError::QueryCannotBeDefinedAsFact => Self::permission_error(
|
||||||
}
|
|
||||||
SessionError::QueryCannotBeDefinedAsFact => {
|
|
||||||
Self::permission_error(
|
|
||||||
h,
|
h,
|
||||||
Permission::Create,
|
Permission::Create,
|
||||||
"static_procedure",
|
"static_procedure",
|
||||||
functor!("query_cannot_be_defined_as_fact")
|
functor!("query_cannot_be_defined_as_fact"),
|
||||||
)
|
),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn syntax_error<E: Into<CompilationError>>(h: usize, err: E) -> Self {
|
||||||
fn syntax_error<E: Into<CompilationError>>(h: usize, err: E) -> Self {
|
|
||||||
let err = err.into();
|
let err = err.into();
|
||||||
|
|
||||||
if let CompilationError::Arithmetic(err) = err {
|
if let CompilationError::Arithmetic(err) = err {
|
||||||
@@ -434,11 +364,7 @@ impl MachineError {
|
|||||||
let location = err.line_and_col_num();
|
let location = err.line_and_col_num();
|
||||||
let stub = err.as_functor(h);
|
let stub = err.as_functor(h);
|
||||||
|
|
||||||
let stub = functor!(
|
let stub = functor!("syntax_error", [aux(h, 0)], [stub]);
|
||||||
"syntax_error",
|
|
||||||
[aux(h, 0)],
|
|
||||||
[stub]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -447,8 +373,7 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn representation_error(flag: RepFlag) -> Self {
|
||||||
fn representation_error(flag: RepFlag) -> Self {
|
|
||||||
let stub = functor!("representation_error", [atom(flag.as_str())]);
|
let stub = functor!("representation_error", [atom(flag.as_str())]);
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
@@ -515,56 +440,39 @@ impl From<ParserError> for CompilationError {
|
|||||||
impl CompilationError {
|
impl CompilationError {
|
||||||
pub fn line_and_col_num(&self) -> Option<(usize, usize)> {
|
pub fn line_and_col_num(&self) -> Option<(usize, usize)> {
|
||||||
match self {
|
match self {
|
||||||
&CompilationError::ParserError(ref err) =>
|
&CompilationError::ParserError(ref err) => err.line_and_col_num(),
|
||||||
err.line_and_col_num(),
|
_ => None,
|
||||||
_ =>
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_functor(&self, _h: usize) -> MachineStub {
|
pub fn as_functor(&self, _h: usize) -> MachineStub {
|
||||||
match self {
|
match self {
|
||||||
&CompilationError::Arithmetic(..) =>
|
&CompilationError::Arithmetic(..) => functor!("arithmetic_error"),
|
||||||
functor!("arithmetic_error"),
|
|
||||||
// &CompilationError::BadPendingByte =>
|
// &CompilationError::BadPendingByte =>
|
||||||
// functor!("bad_pending_byte"),
|
// functor!("bad_pending_byte"),
|
||||||
&CompilationError::CannotParseCyclicTerm =>
|
&CompilationError::CannotParseCyclicTerm => functor!("cannot_parse_cyclic_term"),
|
||||||
functor!("cannot_parse_cyclic_term"),
|
|
||||||
// &CompilationError::ExpandedTermsListNotAList =>
|
// &CompilationError::ExpandedTermsListNotAList =>
|
||||||
// functor!("expanded_terms_list_is_not_a_list"),
|
// functor!("expanded_terms_list_is_not_a_list"),
|
||||||
&CompilationError::ExpectedRel =>
|
&CompilationError::ExpectedRel => functor!("expected_relation"),
|
||||||
functor!("expected_relation"),
|
|
||||||
// &CompilationError::ExpectedTopLevelTerm =>
|
// &CompilationError::ExpectedTopLevelTerm =>
|
||||||
// functor!("expected_atom_or_cons_or_clause"),
|
// functor!("expected_atom_or_cons_or_clause"),
|
||||||
&CompilationError::InadmissibleFact =>
|
&CompilationError::InadmissibleFact => functor!("inadmissible_fact"),
|
||||||
functor!("inadmissible_fact"),
|
&CompilationError::InadmissibleQueryTerm => functor!("inadmissible_query_term"),
|
||||||
&CompilationError::InadmissibleQueryTerm =>
|
&CompilationError::InconsistentEntry => functor!("inconsistent_entry"),
|
||||||
functor!("inadmissible_query_term"),
|
|
||||||
&CompilationError::InconsistentEntry =>
|
|
||||||
functor!("inconsistent_entry"),
|
|
||||||
// &CompilationError::InvalidDoubleQuotesDecl =>
|
// &CompilationError::InvalidDoubleQuotesDecl =>
|
||||||
// functor!("invalid_double_quotes_declaration"),
|
// functor!("invalid_double_quotes_declaration"),
|
||||||
// &CompilationError::InvalidHook =>
|
// &CompilationError::InvalidHook =>
|
||||||
// functor!("invalid_hook"),
|
// functor!("invalid_hook"),
|
||||||
&CompilationError::InvalidMetaPredicateDecl =>
|
&CompilationError::InvalidMetaPredicateDecl => functor!("invalid_meta_predicate_decl"),
|
||||||
functor!("invalid_meta_predicate_decl"),
|
&CompilationError::InvalidModuleDecl => functor!("invalid_module_declaration"),
|
||||||
&CompilationError::InvalidModuleDecl =>
|
&CompilationError::InvalidModuleExport => functor!("invalid_module_export"),
|
||||||
functor!("invalid_module_declaration"),
|
&CompilationError::InvalidModuleResolution(ref module_name) => {
|
||||||
&CompilationError::InvalidModuleExport =>
|
functor!("no_such_module", [clause_name(module_name.clone())])
|
||||||
functor!("invalid_module_export"),
|
}
|
||||||
&CompilationError::InvalidModuleResolution(ref module_name) =>
|
&CompilationError::InvalidRuleHead => functor!("invalid_head_of_rule"),
|
||||||
functor!(
|
&CompilationError::InvalidUseModuleDecl => functor!("invalid_use_module_declaration"),
|
||||||
"no_such_module",
|
&CompilationError::ParserError(ref err) => functor!(err.as_str()),
|
||||||
[clause_name(module_name.clone())]
|
&CompilationError::UnreadableTerm => functor!("unreadable_term"),
|
||||||
),
|
|
||||||
&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"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -723,8 +631,7 @@ pub(super) enum CycleSearchResult {
|
|||||||
|
|
||||||
impl MachineState {
|
impl MachineState {
|
||||||
// see 8.4.3 of Draft Technical Corrigendum 2.
|
// see 8.4.3 of Draft Technical Corrigendum 2.
|
||||||
pub(super)
|
pub(super) fn check_sort_errors(&self) -> CallResult {
|
||||||
fn check_sort_errors(&self) -> CallResult {
|
|
||||||
let stub = MachineError::functor_stub(clause_name!("sort"), 2);
|
let stub = MachineError::functor_stub(clause_name!("sort"), 2);
|
||||||
let list = self.store(self.deref(self[temp_v!(1)].clone()));
|
let list = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||||
let sorted = self.store(self.deref(self[temp_v!(2)].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))
|
return Err(self.error_form(MachineError::instantiation_error(), stub))
|
||||||
}
|
}
|
||||||
CycleSearchResult::NotList => {
|
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;
|
new_l = l;
|
||||||
}
|
}
|
||||||
HeapCellValue::NamedStr(2, ref name, Some(_))
|
HeapCellValue::NamedStr(2, ref name, Some(_))
|
||||||
if name.as_str() == "-" => {
|
if name.as_str() == "-" =>
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
HeapCellValue::Addr(Addr::HeapCell(_)) => {
|
HeapCellValue::Addr(Addr::HeapCell(_)) => {
|
||||||
@@ -793,8 +703,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// see 8.4.4 of Draft Technical Corrigendum 2.
|
// see 8.4.4 of Draft Technical Corrigendum 2.
|
||||||
pub(super)
|
pub(super) fn check_keysort_errors(&self) -> CallResult {
|
||||||
fn check_keysort_errors(&self) -> CallResult {
|
|
||||||
let stub = MachineError::functor_stub(clause_name!("keysort"), 2);
|
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()));
|
||||||
@@ -814,8 +723,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn type_error<T: TypeError>(
|
||||||
fn type_error<T: TypeError>(
|
|
||||||
&self,
|
&self,
|
||||||
valid_type: ValidType,
|
valid_type: ValidType,
|
||||||
culprit: T,
|
culprit: T,
|
||||||
@@ -823,33 +731,25 @@ impl MachineState {
|
|||||||
arity: usize,
|
arity: usize,
|
||||||
) -> MachineStub {
|
) -> MachineStub {
|
||||||
let stub = MachineError::functor_stub(caller, arity);
|
let stub = MachineError::functor_stub(caller, arity);
|
||||||
let err = MachineError::type_error(
|
let err = MachineError::type_error(self.heap.h(), valid_type, culprit);
|
||||||
self.heap.h(),
|
|
||||||
valid_type,
|
|
||||||
culprit,
|
|
||||||
);
|
|
||||||
|
|
||||||
return self.error_form(err, stub);
|
return self.error_form(err, stub);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn representation_error(
|
||||||
fn representation_error(
|
|
||||||
&self,
|
&self,
|
||||||
rep_flag: RepFlag,
|
rep_flag: RepFlag,
|
||||||
caller: ClauseName,
|
caller: ClauseName,
|
||||||
arity: usize,
|
arity: usize,
|
||||||
) -> MachineStub {
|
) -> MachineStub {
|
||||||
let stub = MachineError::functor_stub(caller, arity);
|
let stub = MachineError::functor_stub(caller, arity);
|
||||||
let err = MachineError::representation_error(
|
let err = MachineError::representation_error(rep_flag);
|
||||||
rep_flag,
|
|
||||||
);
|
|
||||||
|
|
||||||
return self.error_form(err, stub);
|
return self.error_form(err, stub);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn error_form(&self, err: MachineError, src: MachineStub) -> MachineStub {
|
||||||
fn error_form(&self, err: MachineError, src: MachineStub) -> MachineStub {
|
|
||||||
let location = err.location;
|
let location = err.location;
|
||||||
let err_len = err.len();
|
let err_len = err.len();
|
||||||
|
|
||||||
@@ -874,8 +774,7 @@ impl MachineState {
|
|||||||
stub
|
stub
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn throw_exception(&mut self, err: MachineStub) {
|
||||||
fn throw_exception(&mut self, err: MachineStub) {
|
|
||||||
let h = self.heap.h();
|
let h = self.heap.h();
|
||||||
|
|
||||||
self.ball.boundary = 0;
|
self.ball.boundary = 0;
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use crate::prolog_parser_rebis::ast::*;
|
||||||
|
use crate::prolog_parser_rebis::clause_name;
|
||||||
|
|
||||||
use crate::clause_types::*;
|
use crate::clause_types::*;
|
||||||
use crate::fixtures::*;
|
use crate::fixtures::*;
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
use crate::machine::CompilationTarget;
|
use crate::instructions::*;
|
||||||
use crate::machine::code_repo::CodeRepo;
|
use crate::machine::code_repo::CodeRepo;
|
||||||
use crate::machine::Ball;
|
|
||||||
use crate::machine::heap::*;
|
use crate::machine::heap::*;
|
||||||
use crate::machine::machine_state::*;
|
use crate::machine::machine_state::*;
|
||||||
use crate::machine::partial_string::*;
|
use crate::machine::partial_string::*;
|
||||||
use crate::machine::raw_block::RawBlockTraits;
|
use crate::machine::raw_block::RawBlockTraits;
|
||||||
use crate::machine::streams::Stream;
|
use crate::machine::streams::Stream;
|
||||||
use crate::machine::term_stream::LoadStatePayload;
|
use crate::machine::term_stream::LoadStatePayload;
|
||||||
use crate::instructions::*;
|
use crate::machine::Ball;
|
||||||
|
use crate::machine::CompilationTarget;
|
||||||
use crate::ordered_float::OrderedFloat;
|
use crate::ordered_float::OrderedFloat;
|
||||||
use crate::rug::{Integer, Rational};
|
use crate::rug::{Integer, Rational};
|
||||||
|
|
||||||
@@ -98,18 +99,12 @@ impl Ord for Ref {
|
|||||||
(Ref::AttrVar(h1), Ref::AttrVar(h2))
|
(Ref::AttrVar(h1), Ref::AttrVar(h2))
|
||||||
| (Ref::HeapCell(h1), Ref::HeapCell(h2))
|
| (Ref::HeapCell(h1), Ref::HeapCell(h2))
|
||||||
| (Ref::HeapCell(h1), Ref::AttrVar(h2))
|
| (Ref::HeapCell(h1), Ref::AttrVar(h2))
|
||||||
| (Ref::AttrVar(h1), Ref::HeapCell(h2)) => {
|
| (Ref::AttrVar(h1), Ref::HeapCell(h2)) => h1.cmp(&h2),
|
||||||
h1.cmp(&h2)
|
|
||||||
}
|
|
||||||
(Ref::StackCell(fr1, sc1), Ref::StackCell(fr2, sc2)) => {
|
(Ref::StackCell(fr1, sc1), Ref::StackCell(fr2, sc2)) => {
|
||||||
fr1.cmp(&fr2).then_with(|| sc1.cmp(&sc2))
|
fr1.cmp(&fr2).then_with(|| sc1.cmp(&sc2))
|
||||||
}
|
}
|
||||||
(Ref::StackCell(..), _) => {
|
(Ref::StackCell(..), _) => Ordering::Greater,
|
||||||
Ordering::Greater
|
(_, Ref::StackCell(..)) => Ordering::Less,
|
||||||
}
|
|
||||||
(_, Ref::StackCell(..)) => {
|
|
||||||
Ordering::Less
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,11 +119,8 @@ impl PartialEq<Ref> for Addr {
|
|||||||
impl PartialOrd<Ref> for Addr {
|
impl PartialOrd<Ref> for Addr {
|
||||||
fn partial_cmp(&self, r: &Ref) -> Option<Ordering> {
|
fn partial_cmp(&self, r: &Ref) -> Option<Ordering> {
|
||||||
match self {
|
match self {
|
||||||
&Addr::StackCell(fr, sc) => {
|
&Addr::StackCell(fr, sc) => match *r {
|
||||||
match *r {
|
Ref::AttrVar(_) | Ref::HeapCell(_) => Some(Ordering::Greater),
|
||||||
Ref::AttrVar(_) | Ref::HeapCell(_) => {
|
|
||||||
Some(Ordering::Greater)
|
|
||||||
}
|
|
||||||
Ref::StackCell(fr1, sc1) => {
|
Ref::StackCell(fr1, sc1) => {
|
||||||
if fr1 < fr || (fr1 == fr && sc1 < sc) {
|
if fr1 < fr || (fr1 == fr && sc1 < sc) {
|
||||||
Some(Ordering::Greater)
|
Some(Ordering::Greater)
|
||||||
@@ -138,21 +130,12 @@ impl PartialOrd<Ref> for Addr {
|
|||||||
Some(Ordering::Less)
|
Some(Ordering::Less)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
&Addr::HeapCell(h) | &Addr::AttrVar(h) => match r {
|
||||||
&Addr::HeapCell(h) | &Addr::AttrVar(h) => {
|
Ref::StackCell(..) => Some(Ordering::Less),
|
||||||
match r {
|
Ref::AttrVar(h1) | Ref::HeapCell(h1) => h.partial_cmp(h1),
|
||||||
Ref::StackCell(..) => {
|
},
|
||||||
Some(Ordering::Less)
|
_ => None,
|
||||||
}
|
|
||||||
Ref::AttrVar(h1) | Ref::HeapCell(h1) => {
|
|
||||||
h.partial_cmp(h1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,26 +144,21 @@ impl Addr {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_heap_bound(&self) -> bool {
|
pub fn is_heap_bound(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Addr::Char(_) | Addr::EmptyList |
|
Addr::Char(_)
|
||||||
Addr::CutPoint(_) | Addr::Usize(_) | Addr::Fixnum(_) |
|
| Addr::EmptyList
|
||||||
Addr::Float(_) => {
|
| Addr::CutPoint(_)
|
||||||
false
|
| Addr::Usize(_)
|
||||||
}
|
| Addr::Fixnum(_)
|
||||||
_ => {
|
| Addr::Float(_) => false,
|
||||||
true
|
_ => true,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_ref(&self) -> bool {
|
pub fn is_ref(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::AttrVar(_) => {
|
Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::AttrVar(_) => true,
|
||||||
true
|
_ => false,
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,92 +172,54 @@ impl Addr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn order_category(&self, heap: &Heap) -> Option<TermOrderCategory> {
|
||||||
fn order_category(&self, heap: &Heap) -> Option<TermOrderCategory> {
|
|
||||||
match Number::try_from((*self, heap)) {
|
match Number::try_from((*self, heap)) {
|
||||||
Ok(Number::Integer(_)) | Ok(Number::Fixnum(_)) | Ok(Number::Rational(_)) => {
|
Ok(Number::Integer(_)) | Ok(Number::Fixnum(_)) | Ok(Number::Rational(_)) => {
|
||||||
Some(TermOrderCategory::Integer)
|
Some(TermOrderCategory::Integer)
|
||||||
}
|
}
|
||||||
Ok(Number::Float(_)) => {
|
Ok(Number::Float(_)) => Some(TermOrderCategory::FloatingPoint),
|
||||||
Some(TermOrderCategory::FloatingPoint)
|
_ => match self {
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
match self {
|
|
||||||
Addr::HeapCell(_) | Addr::AttrVar(_) | Addr::StackCell(..) => {
|
Addr::HeapCell(_) | Addr::AttrVar(_) | Addr::StackCell(..) => {
|
||||||
Some(TermOrderCategory::Variable)
|
Some(TermOrderCategory::Variable)
|
||||||
}
|
}
|
||||||
Addr::Float(_) => {
|
Addr::Float(_) => Some(TermOrderCategory::FloatingPoint),
|
||||||
Some(TermOrderCategory::FloatingPoint)
|
&Addr::Con(h) => match &heap[h] {
|
||||||
}
|
HeapCellValue::Atom(..) => Some(TermOrderCategory::Atom),
|
||||||
&Addr::Con(h) => {
|
HeapCellValue::DBRef(_) => None,
|
||||||
match &heap[h] {
|
|
||||||
HeapCellValue::Atom(..) => {
|
|
||||||
Some(TermOrderCategory::Atom)
|
|
||||||
}
|
|
||||||
HeapCellValue::DBRef(_) => {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
Addr::Char(_) | Addr::EmptyList => Some(TermOrderCategory::Atom),
|
||||||
Addr::Char(_) | Addr::EmptyList => {
|
Addr::Fixnum(_) | Addr::Usize(_) => Some(TermOrderCategory::Integer),
|
||||||
Some(TermOrderCategory::Atom)
|
|
||||||
}
|
|
||||||
Addr::Fixnum(_) | Addr::Usize(_) => {
|
|
||||||
Some(TermOrderCategory::Integer)
|
|
||||||
}
|
|
||||||
Addr::Lis(_) | Addr::PStrLocation(..) | Addr::Str(_) => {
|
Addr::Lis(_) | Addr::PStrLocation(..) | Addr::Str(_) => {
|
||||||
Some(TermOrderCategory::Compound)
|
Some(TermOrderCategory::Compound)
|
||||||
}
|
}
|
||||||
Addr::CutPoint(_) | Addr::LoadStatePayload(_) | Addr::Stream(_) | Addr::TcpListener(_) => {
|
Addr::CutPoint(_)
|
||||||
None
|
| Addr::LoadStatePayload(_)
|
||||||
}
|
| Addr::Stream(_)
|
||||||
}
|
| Addr::TcpListener(_) => None,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_constant_index(&self, machine_st: &MachineState) -> Option<Constant> {
|
pub fn as_constant_index(&self, machine_st: &MachineState) -> Option<Constant> {
|
||||||
match self {
|
match self {
|
||||||
&Addr::Char(c) => {
|
&Addr::Char(c) => Some(Constant::Char(c)),
|
||||||
Some(Constant::Char(c))
|
&Addr::Con(h) => match &machine_st.heap[h] {
|
||||||
}
|
|
||||||
&Addr::Con(h) => {
|
|
||||||
match &machine_st.heap[h] {
|
|
||||||
&HeapCellValue::Atom(ref name, _) if name.is_char() => {
|
&HeapCellValue::Atom(ref name, _) if name.is_char() => {
|
||||||
Some(Constant::Char(name.as_str().chars().next().unwrap()))
|
Some(Constant::Char(name.as_str().chars().next().unwrap()))
|
||||||
}
|
}
|
||||||
&HeapCellValue::Atom(ref name, _) => {
|
&HeapCellValue::Atom(ref name, _) => Some(Constant::Atom(name.clone(), None)),
|
||||||
Some(Constant::Atom(name.clone(), None))
|
&HeapCellValue::Integer(ref n) => Some(Constant::Integer(n.clone())),
|
||||||
}
|
&HeapCellValue::Rational(ref n) => Some(Constant::Rational(n.clone())),
|
||||||
&HeapCellValue::Integer(ref n) => {
|
_ => None,
|
||||||
Some(Constant::Integer(n.clone()))
|
},
|
||||||
}
|
&Addr::EmptyList => Some(Constant::EmptyList),
|
||||||
&HeapCellValue::Rational(ref n) => {
|
&Addr::Fixnum(n) => Some(Constant::Fixnum(n)),
|
||||||
Some(Constant::Rational(n.clone()))
|
&Addr::Float(f) => Some(Constant::Float(f)),
|
||||||
}
|
&Addr::Usize(n) => Some(Constant::Usize(n)),
|
||||||
_ => {
|
_ => None,
|
||||||
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]
|
#[inline]
|
||||||
pub fn as_addr(&self, focus: usize) -> Addr {
|
pub fn as_addr(&self, focus: usize) -> Addr {
|
||||||
match self {
|
match self {
|
||||||
HeapCellValue::Addr(ref a) => {
|
HeapCellValue::Addr(ref a) => *a,
|
||||||
*a
|
HeapCellValue::Atom(..)
|
||||||
}
|
| HeapCellValue::DBRef(..)
|
||||||
HeapCellValue::Atom(..) | HeapCellValue::DBRef(..) | HeapCellValue::Integer(..) |
|
| HeapCellValue::Integer(..)
|
||||||
HeapCellValue::Rational(..) => {
|
| HeapCellValue::Rational(..) => Addr::Con(focus),
|
||||||
Addr::Con(focus)
|
HeapCellValue::LoadStatePayload(_) => Addr::LoadStatePayload(focus),
|
||||||
}
|
HeapCellValue::NamedStr(_, _, _) => Addr::Str(focus),
|
||||||
HeapCellValue::LoadStatePayload(_) => {
|
HeapCellValue::PartialString(..) => Addr::PStrLocation(focus, 0),
|
||||||
Addr::LoadStatePayload(focus)
|
HeapCellValue::Stream(_) => Addr::Stream(focus),
|
||||||
}
|
HeapCellValue::TcpListener(_) => Addr::TcpListener(focus),
|
||||||
HeapCellValue::NamedStr(_, _, _) => {
|
|
||||||
Addr::Str(focus)
|
|
||||||
}
|
|
||||||
HeapCellValue::PartialString(..) => {
|
|
||||||
Addr::PStrLocation(focus, 0)
|
|
||||||
}
|
|
||||||
HeapCellValue::Stream(_) => {
|
|
||||||
Addr::Stream(focus)
|
|
||||||
}
|
|
||||||
HeapCellValue::TcpListener(_) => {
|
|
||||||
Addr::TcpListener(focus)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn context_free_clone(&self) -> HeapCellValue {
|
pub fn context_free_clone(&self) -> HeapCellValue {
|
||||||
match self {
|
match self {
|
||||||
&HeapCellValue::Addr(addr) => {
|
&HeapCellValue::Addr(addr) => 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::Atom(ref name, ref op) => {
|
&HeapCellValue::Integer(ref n) => HeapCellValue::Integer(n.clone()),
|
||||||
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::LoadStatePayload(_) => {
|
||||||
HeapCellValue::Atom(clause_name!("$live_term_stream"), None)
|
HeapCellValue::Atom(clause_name!("$live_term_stream"), None)
|
||||||
}
|
}
|
||||||
&HeapCellValue::NamedStr(arity, ref name, ref op) => {
|
&HeapCellValue::NamedStr(arity, ref name, ref op) => {
|
||||||
HeapCellValue::NamedStr(arity, name.clone(), op.clone())
|
HeapCellValue::NamedStr(arity, name.clone(), op.clone())
|
||||||
}
|
}
|
||||||
&HeapCellValue::Rational(ref r) => {
|
&HeapCellValue::Rational(ref r) => HeapCellValue::Rational(r.clone()),
|
||||||
HeapCellValue::Rational(r.clone())
|
|
||||||
}
|
|
||||||
&HeapCellValue::PartialString(ref pstr, has_tail) => {
|
&HeapCellValue::PartialString(ref pstr, has_tail) => {
|
||||||
HeapCellValue::PartialString(pstr.clone(), has_tail)
|
HeapCellValue::PartialString(pstr.clone(), has_tail)
|
||||||
}
|
}
|
||||||
&HeapCellValue::Stream(ref stream) => {
|
&HeapCellValue::Stream(ref stream) => HeapCellValue::Stream(stream.clone()),
|
||||||
HeapCellValue::Stream(stream.clone())
|
|
||||||
}
|
|
||||||
&HeapCellValue::TcpListener(_) => {
|
&HeapCellValue::TcpListener(_) => {
|
||||||
HeapCellValue::Atom(clause_name!("$tcp_listener"), None)
|
HeapCellValue::Atom(clause_name!("$tcp_listener"), None)
|
||||||
}
|
}
|
||||||
@@ -473,8 +389,7 @@ impl Deref for CodeIndex {
|
|||||||
|
|
||||||
impl CodeIndex {
|
impl CodeIndex {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn new(ptr: IndexPtr) -> Self {
|
||||||
fn new(ptr: IndexPtr) -> Self {
|
|
||||||
CodeIndex(Rc::new(Cell::new(ptr)))
|
CodeIndex(Rc::new(Cell::new(ptr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -482,7 +397,7 @@ impl CodeIndex {
|
|||||||
pub fn is_undefined(&self) -> bool {
|
pub fn is_undefined(&self) -> bool {
|
||||||
match self.0.get() {
|
match self.0.get() {
|
||||||
IndexPtr::Undefined => true, // | &IndexPtr::DynamicUndefined => true,
|
IndexPtr::Undefined => true, // | &IndexPtr::DynamicUndefined => true,
|
||||||
_ => false
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -547,7 +462,7 @@ impl CodePtr {
|
|||||||
| &CodePtr::CallN(_, ref local, _)
|
| &CodePtr::CallN(_, ref local, _)
|
||||||
| &CodePtr::Local(ref local) => local.clone(),
|
| &CodePtr::Local(ref local) => local.clone(),
|
||||||
&CodePtr::VerifyAttrInterrupt(p) => LocalCodePtr::DirEntry(p),
|
&CodePtr::VerifyAttrInterrupt(p) => LocalCodePtr::DirEntry(p),
|
||||||
&CodePtr::REPL(_, p) => p // | &CodePtr::DynamicTransaction(_, p) => p,
|
&CodePtr::REPL(_, p) => p, // | &CodePtr::DynamicTransaction(_, p) => p,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -570,8 +485,7 @@ pub enum LocalCodePtr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LocalCodePtr {
|
impl LocalCodePtr {
|
||||||
pub(crate)
|
pub(crate) fn assign_if_local(&mut self, cp: CodePtr) {
|
||||||
fn assign_if_local(&mut self, cp: CodePtr) {
|
|
||||||
match cp {
|
match cp {
|
||||||
CodePtr::Local(local) => *self = local,
|
CodePtr::Local(local) => *self = local,
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -579,8 +493,7 @@ impl LocalCodePtr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn abs_loc(&self) -> usize {
|
||||||
fn abs_loc(&self) -> usize {
|
|
||||||
match self {
|
match self {
|
||||||
LocalCodePtr::DirEntry(ref p) => *p,
|
LocalCodePtr::DirEntry(ref p) => *p,
|
||||||
LocalCodePtr::IndexingBuf(ref p, ..) => *p,
|
LocalCodePtr::IndexingBuf(ref p, ..) => *p,
|
||||||
@@ -588,35 +501,28 @@ impl LocalCodePtr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn is_reset_cont_marker(&self, code_repo: &CodeRepo, last_call: bool) -> bool {
|
||||||
fn is_reset_cont_marker(&self, code_repo: &CodeRepo, last_call: bool) -> bool {
|
|
||||||
match code_repo.lookup_instr(last_call, &CodePtr::Local(*self)) {
|
match code_repo.lookup_instr(last_call, &CodePtr::Local(*self)) {
|
||||||
Some(line) => {
|
Some(line) => match line.as_ref() {
|
||||||
match line.as_ref() {
|
|
||||||
Line::Control(ControlInstruction::CallClause(ref ct, ..)) => {
|
Line::Control(ControlInstruction::CallClause(ref ct, ..)) => {
|
||||||
if let ClauseType::System(SystemClauseType::ResetContinuationMarker) = *ct {
|
if let ClauseType::System(SystemClauseType::ResetContinuationMarker) = *ct {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn as_functor<T: RawBlockTraits>(&self, heap: &mut HeapTemplate<T>) -> Addr {
|
||||||
fn as_functor<T: RawBlockTraits>(&self, heap: &mut HeapTemplate<T>) -> Addr {
|
|
||||||
let addr = Addr::HeapCell(heap.h());
|
let addr = Addr::HeapCell(heap.h());
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
LocalCodePtr::DirEntry(p) => {
|
LocalCodePtr::DirEntry(p) => {
|
||||||
heap.append(functor!(
|
heap.append(functor!("dir_entry", [integer(*p)]));
|
||||||
"dir_entry",
|
|
||||||
[integer(*p)]
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
LocalCodePtr::Halt => {
|
LocalCodePtr::Halt => {
|
||||||
heap.append(functor!("halt"));
|
heap.append(functor!("halt"));
|
||||||
@@ -693,12 +599,9 @@ impl Add<usize> for LocalCodePtr {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn add(self, rhs: usize) -> Self::Output {
|
fn add(self, rhs: usize) -> Self::Output {
|
||||||
match self {
|
match self {
|
||||||
LocalCodePtr::DirEntry(p) =>
|
LocalCodePtr::DirEntry(p) => LocalCodePtr::DirEntry(p + rhs),
|
||||||
LocalCodePtr::DirEntry(p + rhs),
|
LocalCodePtr::Halt => unreachable!(),
|
||||||
LocalCodePtr::Halt =>
|
LocalCodePtr::IndexingBuf(p, o, i) => LocalCodePtr::IndexingBuf(p, o, i + rhs),
|
||||||
unreachable!(),
|
|
||||||
LocalCodePtr::IndexingBuf(p, o, i) =>
|
|
||||||
LocalCodePtr::IndexingBuf(p, o, i + rhs),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -709,12 +612,11 @@ impl Sub<usize> for LocalCodePtr {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn sub(self, rhs: usize) -> Self::Output {
|
fn sub(self, rhs: usize) -> Self::Output {
|
||||||
match self {
|
match self {
|
||||||
LocalCodePtr::DirEntry(p) =>
|
LocalCodePtr::DirEntry(p) => p.checked_sub(rhs).map(LocalCodePtr::DirEntry),
|
||||||
p.checked_sub(rhs).map(LocalCodePtr::DirEntry),
|
LocalCodePtr::Halt => unreachable!(),
|
||||||
LocalCodePtr::Halt =>
|
LocalCodePtr::IndexingBuf(p, o, i) => i
|
||||||
unreachable!(),
|
.checked_sub(rhs)
|
||||||
LocalCodePtr::IndexingBuf(p, o, i) =>
|
.map(|r| LocalCodePtr::IndexingBuf(p, o, r)),
|
||||||
i.checked_sub(rhs).map(|r| LocalCodePtr::IndexingBuf(p, o, r)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -723,15 +625,12 @@ impl SubAssign<usize> for LocalCodePtr {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn sub_assign(&mut self, rhs: usize) {
|
fn sub_assign(&mut self, rhs: usize) {
|
||||||
match self {
|
match self {
|
||||||
LocalCodePtr::DirEntry(ref mut p) =>
|
LocalCodePtr::DirEntry(ref mut p) => *p -= rhs,
|
||||||
*p -= rhs,
|
LocalCodePtr::Halt | LocalCodePtr::IndexingBuf(..) => unreachable!(),
|
||||||
LocalCodePtr::Halt | LocalCodePtr::IndexingBuf(..) =>
|
|
||||||
unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl AddAssign<usize> for LocalCodePtr {
|
impl AddAssign<usize> for LocalCodePtr {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add_assign(&mut self, rhs: usize) {
|
fn add_assign(&mut self, rhs: usize) {
|
||||||
@@ -749,14 +648,12 @@ impl Add<usize> for CodePtr {
|
|||||||
|
|
||||||
fn add(self, rhs: usize) -> Self::Output {
|
fn add(self, rhs: usize) -> Self::Output {
|
||||||
match self {
|
match self {
|
||||||
p @ CodePtr::REPL(..) |
|
p @ CodePtr::REPL(..) | p @ CodePtr::VerifyAttrInterrupt(_) => {
|
||||||
p @ CodePtr::VerifyAttrInterrupt(_) => { // |
|
// |
|
||||||
// p @ CodePtr::DynamicTransaction(..) => {
|
// p @ CodePtr::DynamicTransaction(..) => {
|
||||||
p
|
p
|
||||||
}
|
}
|
||||||
CodePtr::Local(local) => {
|
CodePtr::Local(local) => CodePtr::Local(local + rhs),
|
||||||
CodePtr::Local(local + rhs)
|
|
||||||
}
|
|
||||||
CodePtr::BuiltInClause(_, local) | CodePtr::CallN(_, local, _) => {
|
CodePtr::BuiltInClause(_, local) | CodePtr::CallN(_, local, _) => {
|
||||||
CodePtr::Local(local + rhs)
|
CodePtr::Local(local + rhs)
|
||||||
}
|
}
|
||||||
@@ -784,7 +681,6 @@ impl SubAssign<usize> for CodePtr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub type HeapVarDict = IndexMap<Rc<Var>, Addr>;
|
pub type HeapVarDict = IndexMap<Rc<Var>, Addr>;
|
||||||
pub type AllocVarDict = IndexMap<Rc<Var>, VarData>;
|
pub type AllocVarDict = IndexMap<Rc<Var>, VarData>;
|
||||||
|
|
||||||
@@ -830,14 +726,9 @@ impl IndexStore {
|
|||||||
key: &PredicateKey,
|
key: &PredicateKey,
|
||||||
) -> Option<&mut PredicateSkeleton> {
|
) -> Option<&mut PredicateSkeleton> {
|
||||||
match (key.0.as_str(), key.1) {
|
match (key.0.as_str(), key.1) {
|
||||||
("term_expansion", 2) => {
|
("term_expansion", 2) => self.extensible_predicates.get_mut(key),
|
||||||
self.extensible_predicates.get_mut(key)
|
_ => match compilation_target {
|
||||||
}
|
CompilationTarget::User => self.extensible_predicates.get_mut(key),
|
||||||
_ => {
|
|
||||||
match compilation_target {
|
|
||||||
CompilationTarget::User => {
|
|
||||||
self.extensible_predicates.get_mut(key)
|
|
||||||
}
|
|
||||||
CompilationTarget::Module(ref module_name) => {
|
CompilationTarget::Module(ref module_name) => {
|
||||||
if let Some(module) = self.modules.get_mut(module_name) {
|
if let Some(module) = self.modules.get_mut(module_name) {
|
||||||
module.extensible_predicates.get_mut(key)
|
module.extensible_predicates.get_mut(key)
|
||||||
@@ -845,8 +736,7 @@ impl IndexStore {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -858,9 +748,8 @@ impl IndexStore {
|
|||||||
match (key.0.as_str(), key.1) {
|
match (key.0.as_str(), key.1) {
|
||||||
("term_expansion", 2) => {
|
("term_expansion", 2) => {
|
||||||
self.extensible_predicates.remove(key);
|
self.extensible_predicates.remove(key);
|
||||||
},
|
}
|
||||||
_ => {
|
_ => match compilation_target {
|
||||||
match compilation_target {
|
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => {
|
||||||
self.extensible_predicates.remove(key);
|
self.extensible_predicates.remove(key);
|
||||||
}
|
}
|
||||||
@@ -869,8 +758,7 @@ impl IndexStore {
|
|||||||
module.extensible_predicates.remove(key);
|
module.extensible_predicates.remove(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -883,15 +771,9 @@ impl IndexStore {
|
|||||||
) -> Option<CodeIndex> {
|
) -> Option<CodeIndex> {
|
||||||
if module.as_str() == "user" {
|
if module.as_str() == "user" {
|
||||||
match ClauseType::from(name, arity, op_spec) {
|
match ClauseType::from(name, arity, op_spec) {
|
||||||
ClauseType::Named(name, arity, _) => {
|
ClauseType::Named(name, arity, _) => self.code_dir.get(&(name, arity)).cloned(),
|
||||||
self.code_dir.get(&(name, arity)).cloned()
|
ClauseType::Op(name, spec, ..) => self.code_dir.get(&(name, spec.arity())).cloned(),
|
||||||
}
|
_ => None,
|
||||||
ClauseType::Op(name, spec, ..) => {
|
|
||||||
self.code_dir.get(&(name, spec.arity())).cloned()
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.modules.get(&module).and_then(|module| {
|
self.modules.get(&module).and_then(|module| {
|
||||||
@@ -902,9 +784,7 @@ impl IndexStore {
|
|||||||
ClauseType::Op(name, spec, ..) => {
|
ClauseType::Op(name, spec, ..) => {
|
||||||
module.code_dir.get(&(name, spec.arity())).cloned()
|
module.code_dir.get(&(name, spec.arity())).cloned()
|
||||||
}
|
}
|
||||||
_ => {
|
_ => None,
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -917,44 +797,32 @@ impl IndexStore {
|
|||||||
compilation_target: &CompilationTarget,
|
compilation_target: &CompilationTarget,
|
||||||
) -> Option<&Vec<MetaSpec>> {
|
) -> Option<&Vec<MetaSpec>> {
|
||||||
match compilation_target {
|
match compilation_target {
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => self.meta_predicates.get(&(name, arity)),
|
||||||
self.meta_predicates.get(&(name, arity))
|
CompilationTarget::Module(ref module_name) => match self.modules.get(module_name) {
|
||||||
}
|
Some(ref module) => module
|
||||||
CompilationTarget::Module(ref module_name) => {
|
.meta_predicates
|
||||||
match self.modules.get(module_name) {
|
.get(&(name.clone(), arity))
|
||||||
Some(ref module) => {
|
.or_else(|| self.meta_predicates.get(&(name, arity))),
|
||||||
module.meta_predicates.get(&(name.clone(), arity))
|
None => self.meta_predicates.get(&(name, 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 {
|
pub fn is_dynamic_predicate(&self, module_name: ClauseName, key: PredicateKey) -> bool {
|
||||||
match module_name.as_str() {
|
match module_name.as_str() {
|
||||||
"user" => {
|
"user" => self
|
||||||
self.extensible_predicates.get(&key)
|
.extensible_predicates
|
||||||
|
.get(&key)
|
||||||
.map(|skeleton| skeleton.is_dynamic)
|
.map(|skeleton| skeleton.is_dynamic)
|
||||||
.unwrap_or(false)
|
.unwrap_or(false),
|
||||||
}
|
_ => match self.modules.get(&module_name) {
|
||||||
_ => {
|
Some(ref module) => module
|
||||||
match self.modules.get(&module_name) {
|
.extensible_predicates
|
||||||
Some(ref module) => {
|
.get(&key)
|
||||||
module.extensible_predicates.get(&key)
|
|
||||||
.map(|skeleton| skeleton.is_dynamic)
|
.map(|skeleton| skeleton.is_dynamic)
|
||||||
.unwrap_or(false)
|
.unwrap_or(false),
|
||||||
}
|
None => false,
|
||||||
None => {
|
},
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -963,8 +831,7 @@ impl IndexStore {
|
|||||||
IndexStore::default()
|
IndexStore::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn get_cleaner_sites(&self) -> (usize, usize) {
|
||||||
fn get_cleaner_sites(&self) -> (usize, usize) {
|
|
||||||
let r_w_h = clause_name!("run_cleaners_with_handling");
|
let r_w_h = clause_name!("run_cleaners_with_handling");
|
||||||
let r_wo_h = clause_name!("run_cleaners_without_handling");
|
let r_wo_h = clause_name!("run_cleaners_without_handling");
|
||||||
let iso_ext = clause_name!("iso_ext");
|
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> {
|
impl<'a, T: 'a + fmt::Debug> fmt::Debug for RefOrOwned<'a, T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
&RefOrOwned::Borrowed(ref borrowed) =>
|
&RefOrOwned::Borrowed(ref borrowed) => write!(f, "Borrowed({:?})", borrowed),
|
||||||
write!(f, "Borrowed({:?})", borrowed),
|
&RefOrOwned::Owned(ref owned) => write!(f, "Owned({:?})", owned),
|
||||||
&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 {
|
match self {
|
||||||
RefOrOwned::Borrowed(item) => item.clone(),
|
RefOrOwned::Borrowed(item) => item.clone(),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use crate::prolog_parser_rebis::ast::*;
|
||||||
use crate::prolog_parser_rebis::tabled_rc::*;
|
use crate::prolog_parser_rebis::tabled_rc::*;
|
||||||
|
use crate::prolog_parser_rebis::{clause_name, temp_v};
|
||||||
|
|
||||||
use crate::clause_types::*;
|
use crate::clause_types::*;
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
@@ -14,7 +15,9 @@ use crate::machine::stack::*;
|
|||||||
use crate::machine::streams::*;
|
use crate::machine::streams::*;
|
||||||
use crate::rug::Integer;
|
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;
|
use crate::indexmap::IndexMap;
|
||||||
|
|
||||||
@@ -32,33 +35,26 @@ pub struct Ball {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Ball {
|
impl Ball {
|
||||||
pub(super)
|
pub(super) fn new() -> Self {
|
||||||
fn new() -> Self {
|
|
||||||
Ball {
|
Ball {
|
||||||
boundary: 0,
|
boundary: 0,
|
||||||
stub: Heap::new(),
|
stub: Heap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn reset(&mut self) {
|
||||||
fn reset(&mut self) {
|
|
||||||
self.boundary = 0;
|
self.boundary = 0;
|
||||||
self.stub.clear();
|
self.stub.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn copy_and_align(&self, h: usize) -> Heap {
|
||||||
fn copy_and_align(&self, h: usize) -> Heap {
|
|
||||||
let diff = self.boundary as i64 - h as i64;
|
let diff = self.boundary as i64 - h as i64;
|
||||||
let mut stub = Heap::new();
|
let mut stub = Heap::new();
|
||||||
|
|
||||||
for heap_value in self.stub.iter_from(0) {
|
for heap_value in self.stub.iter_from(0) {
|
||||||
stub.push(match heap_value {
|
stub.push(match heap_value {
|
||||||
&HeapCellValue::Addr(addr) => {
|
&HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr - diff),
|
||||||
HeapCellValue::Addr(addr - diff)
|
heap_value => heap_value.context_free_clone(),
|
||||||
}
|
|
||||||
heap_value => {
|
|
||||||
heap_value.context_free_clone()
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,11 +119,7 @@ pub(super) struct CopyBallTerm<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CopyBallTerm<'a> {
|
impl<'a> CopyBallTerm<'a> {
|
||||||
pub(super) fn new(
|
pub(super) fn new(stack: &'a mut Stack, heap: &'a mut Heap, stub: &'a mut Heap) -> Self {
|
||||||
stack: &'a mut Stack,
|
|
||||||
heap: &'a mut Heap,
|
|
||||||
stub: &'a mut Heap,
|
|
||||||
) -> Self {
|
|
||||||
let hb = heap.h();
|
let hb = heap.h();
|
||||||
|
|
||||||
CopyBallTerm {
|
CopyBallTerm {
|
||||||
@@ -182,12 +174,8 @@ impl<'a> CopierTarget for CopyBallTerm<'a> {
|
|||||||
let index = h - self.heap_boundary;
|
let index = h - self.heap_boundary;
|
||||||
self.stub[index].as_addr(h)
|
self.stub[index].as_addr(h)
|
||||||
}
|
}
|
||||||
Addr::StackCell(fr, sc) => {
|
Addr::StackCell(fr, sc) => self.stack.index_and_frame(fr)[sc],
|
||||||
self.stack.index_and_frame(fr)[sc]
|
addr => addr,
|
||||||
}
|
|
||||||
addr => {
|
|
||||||
addr
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,9 +214,7 @@ impl Index<RegType> for MachineState {
|
|||||||
impl IndexMut<RegType> for MachineState {
|
impl IndexMut<RegType> for MachineState {
|
||||||
fn index_mut(&mut self, reg: RegType) -> &mut Self::Output {
|
fn index_mut(&mut self, reg: RegType) -> &mut Self::Output {
|
||||||
match reg {
|
match reg {
|
||||||
RegType::Temp(temp) => {
|
RegType::Temp(temp) => &mut self.registers[temp],
|
||||||
&mut self.registers[temp]
|
|
||||||
}
|
|
||||||
RegType::Perm(perm) => {
|
RegType::Perm(perm) => {
|
||||||
let e = self.e;
|
let e = self.e;
|
||||||
|
|
||||||
@@ -255,12 +241,9 @@ pub(super) enum HeapPtr {
|
|||||||
|
|
||||||
impl HeapPtr {
|
impl HeapPtr {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn read(&self, heap: &Heap) -> Addr {
|
||||||
fn read(&self, heap: &Heap) -> Addr {
|
|
||||||
match self {
|
match self {
|
||||||
&HeapPtr::HeapCell(h) => {
|
&HeapPtr::HeapCell(h) => Addr::HeapCell(h),
|
||||||
Addr::HeapCell(h)
|
|
||||||
}
|
|
||||||
&HeapPtr::PStrChar(h, n) => {
|
&HeapPtr::PStrChar(h, n) => {
|
||||||
if let &HeapCellValue::PartialString(ref pstr, has_tail) = &heap[h] {
|
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() {
|
||||||
@@ -274,9 +257,7 @@ impl HeapPtr {
|
|||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&HeapPtr::PStrLocation(h, n) => {
|
&HeapPtr::PStrLocation(h, n) => Addr::PStrLocation(h, n),
|
||||||
Addr::PStrLocation(h, n)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -313,16 +294,11 @@ pub struct MachineState {
|
|||||||
pub(super) last_call: bool,
|
pub(super) last_call: bool,
|
||||||
pub(crate) heap_locs: HeapVarDict,
|
pub(crate) heap_locs: HeapVarDict,
|
||||||
pub(crate) flags: MachineFlags,
|
pub(crate) flags: MachineFlags,
|
||||||
pub(crate) at_end_of_expansion: bool
|
pub(crate) at_end_of_expansion: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MachineState {
|
impl MachineState {
|
||||||
pub(crate)
|
pub(crate) fn read_term(&mut self, mut stream: Stream, indices: &mut IndexStore) -> CallResult {
|
||||||
fn read_term(
|
|
||||||
&mut self,
|
|
||||||
mut stream: Stream,
|
|
||||||
indices: &mut IndexStore,
|
|
||||||
) -> CallResult {
|
|
||||||
self.check_stream_properties(
|
self.check_stream_properties(
|
||||||
&mut stream,
|
&mut stream,
|
||||||
StreamType::Text,
|
StreamType::Text,
|
||||||
@@ -342,11 +318,7 @@ impl MachineState {
|
|||||||
let mut orig_stream = stream.clone();
|
let mut orig_stream = stream.clone();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match self.read(
|
match self.read(stream.clone(), self.atom_tbl.clone(), &indices.op_dir) {
|
||||||
stream.clone(),
|
|
||||||
self.atom_tbl.clone(),
|
|
||||||
&indices.op_dir,
|
|
||||||
) {
|
|
||||||
Ok(term_write_result) => {
|
Ok(term_write_result) => {
|
||||||
let term = self[temp_v!(2)];
|
let term = self[temp_v!(2)];
|
||||||
self.unify(Addr::HeapCell(term_write_result.heap_loc), term);
|
self.unify(Addr::HeapCell(term_write_result.heap_loc), term);
|
||||||
@@ -363,7 +335,8 @@ impl MachineState {
|
|||||||
let h = self.heap.h();
|
let h = self.heap.h();
|
||||||
let spec = fetch_atom_op_spec(clause_name!("="), None, &indices.op_dir);
|
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::Atom(var_atom, None));
|
||||||
self.heap.push(HeapCellValue::Addr(binding));
|
self.heap.push(HeapCellValue::Addr(binding));
|
||||||
|
|
||||||
@@ -406,8 +379,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let vars_addr = self[temp_v!(4)];
|
let vars_addr = self[temp_v!(4)];
|
||||||
let vars_offset =
|
let vars_offset = Addr::HeapCell(self.heap.to_list(var_list.into_iter()));
|
||||||
Addr::HeapCell(self.heap.to_list(var_list.into_iter()));
|
|
||||||
|
|
||||||
self.unify(vars_offset, vars_addr);
|
self.unify(vars_offset, vars_addr);
|
||||||
|
|
||||||
@@ -427,7 +399,7 @@ impl MachineState {
|
|||||||
self[temp_v!(2)],
|
self[temp_v!(2)],
|
||||||
&mut orig_stream,
|
&mut orig_stream,
|
||||||
clause_name!("read_term"),
|
clause_name!("read_term"),
|
||||||
3
|
3,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if orig_stream.options.eof_action == EOFAction::Reset {
|
if orig_stream.options.eof_action == EOFAction::Reset {
|
||||||
@@ -448,12 +420,10 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn write_term<'a>(
|
||||||
fn write_term<'a>(
|
|
||||||
&'a self,
|
&'a self,
|
||||||
op_dir: &'a OpDir,
|
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 ignore_ops = self.store(self.deref(self[temp_v!(3)]));
|
||||||
let numbervars = self.store(self.deref(self[temp_v!(4)]));
|
let numbervars = self.store(self.deref(self[temp_v!(4)]));
|
||||||
let quoted = self.store(self.deref(self[temp_v!(5)]));
|
let quoted = self.store(self.deref(self[temp_v!(5)]));
|
||||||
@@ -514,9 +484,7 @@ impl MachineState {
|
|||||||
for addr in addrs {
|
for addr in addrs {
|
||||||
match addr {
|
match addr {
|
||||||
Addr::Str(s) => match &self.heap[s] {
|
Addr::Str(s) => match &self.heap[s] {
|
||||||
&HeapCellValue::NamedStr(2, ref name, _)
|
&HeapCellValue::NamedStr(2, ref name, _) if name.as_str() == "=" => {
|
||||||
if name.as_str() == "=" =>
|
|
||||||
{
|
|
||||||
let atom = self.heap[s + 1].as_addr(s + 1);
|
let atom = self.heap[s + 1].as_addr(s + 1);
|
||||||
let var = self.heap[s + 2].as_addr(s + 2);
|
let var = self.heap[s + 2].as_addr(s + 2);
|
||||||
|
|
||||||
@@ -540,11 +508,9 @@ impl MachineState {
|
|||||||
|
|
||||||
var_names.insert(var, atom);
|
var_names.insert(var, atom);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -558,8 +524,7 @@ impl MachineState {
|
|||||||
Ok(Some(printer))
|
Ok(Some(printer))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn throw_undefined_error(&mut self, name: ClauseName, arity: usize) -> MachineStub {
|
||||||
fn throw_undefined_error(&mut self, name: ClauseName, arity: usize) -> MachineStub {
|
|
||||||
let stub = MachineError::functor_stub(name.clone(), arity);
|
let stub = MachineError::functor_stub(name.clone(), arity);
|
||||||
let h = self.heap.h();
|
let h = self.heap.h();
|
||||||
let key = ExistenceError::Procedure(name, arity);
|
let key = ExistenceError::Procedure(name, arity);
|
||||||
@@ -568,13 +533,11 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn heap_pstr_iter<'a>(&'a self, focus: Addr) -> HeapPStrIter<'a> {
|
||||||
fn heap_pstr_iter<'a>(&'a self, focus: Addr) -> HeapPStrIter<'a> {
|
|
||||||
HeapPStrIter::new(self, focus)
|
HeapPStrIter::new(self, focus)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn try_char_list(&self, addrs: Vec<Addr>) -> Result<String, MachineError> {
|
||||||
fn try_char_list(&self, addrs: Vec<Addr>) -> Result<String, MachineError> {
|
|
||||||
let mut chars = String::new();
|
let mut chars = String::new();
|
||||||
let mut iter = addrs.iter();
|
let mut iter = addrs.iter();
|
||||||
|
|
||||||
@@ -594,55 +557,46 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let h = self.heap.h();
|
let h = self.heap.h();
|
||||||
|
|
||||||
return Err(
|
return Err(MachineError::type_error(h, ValidType::Character, addr));
|
||||||
MachineError::type_error(h, ValidType::Character, addr)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(chars)
|
Ok(chars)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn read_predicate_key(&self, name: Addr, arity: Addr) -> (ClauseName, usize) {
|
||||||
fn read_predicate_key(&self, name: Addr, arity: Addr) -> (ClauseName, usize) {
|
|
||||||
let predicate_name = atom_from!(self, self.store(self.deref(name)));
|
let predicate_name = atom_from!(self, self.store(self.deref(name)));
|
||||||
let arity = self.store(self.deref(arity));
|
let arity = self.store(self.deref(arity));
|
||||||
|
|
||||||
let arity =
|
let arity = match Number::try_from((arity, &self.heap)) {
|
||||||
match Number::try_from((arity, &self.heap)) {
|
Ok(Number::Integer(n)) if &*n >= &0 && &*n <= &MAX_ARITY => n.to_usize().unwrap(),
|
||||||
Ok(Number::Integer(n)) if &*n >= &0 && &*n <= &MAX_ARITY =>
|
Ok(Number::Fixnum(n)) if n >= 0 && n <= MAX_ARITY as isize => {
|
||||||
n.to_usize().unwrap(),
|
usize::try_from(n).unwrap()
|
||||||
Ok(Number::Fixnum(n)) if n >= 0 && n <= MAX_ARITY as isize =>
|
}
|
||||||
usize::try_from(n).unwrap(),
|
_ => unreachable!(),
|
||||||
_ =>
|
|
||||||
unreachable!()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
(predicate_name, arity)
|
(predicate_name, arity)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn call_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
||||||
fn call_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
|
||||||
self.cp.assign_if_local(self.p.clone() + 1);
|
self.cp.assign_if_local(self.p.clone() + 1);
|
||||||
self.num_of_args = arity;
|
self.num_of_args = arity;
|
||||||
self.b0 = self.b;
|
self.b0 = self.b;
|
||||||
self.p = CodePtr::Local(p);
|
self.p = CodePtr::Local(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn execute_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
||||||
fn execute_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
|
||||||
self.num_of_args = arity;
|
self.num_of_args = arity;
|
||||||
self.b0 = self.b;
|
self.b0 = self.b;
|
||||||
self.p = CodePtr::Local(p);
|
self.p = CodePtr::Local(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn module_lookup(
|
||||||
fn module_lookup(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
indices: &IndexStore,
|
indices: &IndexStore,
|
||||||
call_policy: &mut Box<dyn CallPolicy>,
|
call_policy: &mut Box<dyn CallPolicy>,
|
||||||
@@ -687,7 +641,12 @@ pub(crate) type CallResult = Result<(), Vec<HeapCellValue>>;
|
|||||||
pub(crate) trait CallPolicy: Any + fmt::Debug {
|
pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||||
fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
||||||
let b = machine_st.b;
|
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 {
|
for i in 1..n + 1 {
|
||||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
||||||
@@ -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.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||||
|
|
||||||
machine_st.trail.truncate(machine_st.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 =
|
let attr_var_init_queue_b = machine_st
|
||||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
.stack
|
||||||
let attr_var_init_bindings_b =
|
.index_or_frame(b)
|
||||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_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(
|
machine_st
|
||||||
attr_var_init_queue_b,
|
.attr_var_init
|
||||||
attr_var_init_bindings_b,
|
.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
|
||||||
);
|
|
||||||
|
|
||||||
machine_st.hb = machine_st.heap.h();
|
machine_st.hb = machine_st.heap.h();
|
||||||
machine_st.p += 1;
|
machine_st.p += 1;
|
||||||
@@ -726,7 +692,12 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
|
|
||||||
fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
||||||
let b = machine_st.b;
|
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 {
|
for i in 1..n + 1 {
|
||||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
||||||
@@ -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.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||||
|
|
||||||
machine_st.trail.truncate(machine_st.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 =
|
let attr_var_init_queue_b = machine_st
|
||||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
.stack
|
||||||
let attr_var_init_bindings_b =
|
.index_or_frame(b)
|
||||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_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.hb = machine_st.heap.h();
|
||||||
machine_st.p = CodePtr::Local(dir_entry!(machine_st.p.local().abs_loc() + offset));
|
machine_st.p = CodePtr::Local(dir_entry!(machine_st.p.local().abs_loc() + offset));
|
||||||
@@ -762,7 +743,12 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
|
|
||||||
fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
||||||
let b = machine_st.b;
|
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 {
|
for i in 1..n + 1 {
|
||||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
||||||
@@ -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.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||||
|
|
||||||
machine_st.trail.truncate(machine_st.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 =
|
let attr_var_init_queue_b = machine_st
|
||||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
.stack
|
||||||
let attr_var_init_bindings_b =
|
.index_or_frame(b)
|
||||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_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(
|
machine_st
|
||||||
attr_var_init_queue_b,
|
.attr_var_init
|
||||||
attr_var_init_bindings_b,
|
.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.b = machine_st.stack.index_or_frame(b).prelude.b;
|
||||||
machine_st.stack.truncate(b);
|
machine_st.stack.truncate(b);
|
||||||
@@ -802,7 +795,12 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
|
|
||||||
fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult {
|
fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult {
|
||||||
let b = machine_st.b;
|
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 {
|
for i in 1..n + 1 {
|
||||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
||||||
@@ -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.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||||
|
|
||||||
machine_st.trail.truncate(machine_st.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 =
|
let attr_var_init_queue_b = machine_st
|
||||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
.stack
|
||||||
let attr_var_init_bindings_b =
|
.index_or_frame(b)
|
||||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_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(
|
machine_st
|
||||||
attr_var_init_queue_b,
|
.attr_var_init
|
||||||
attr_var_init_bindings_b,
|
.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.b = machine_st.stack.index_or_frame(b).prelude.b;
|
||||||
machine_st.stack.truncate(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) => {
|
Addr::Con(h) if machine_st.heap.atom_at(h) => {
|
||||||
if let HeapCellValue::Atom(ref atom, _) = &machine_st.heap[h] {
|
if let HeapCellValue::Atom(ref atom, _) = &machine_st.heap[h] {
|
||||||
match atom.as_str() {
|
match atom.as_str() {
|
||||||
">" | "<" | "=" => {
|
">" | "<" | "=" => {}
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
let stub =
|
let stub =
|
||||||
MachineError::functor_stub(clause_name!("compare"), 3);
|
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));
|
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);
|
let err = MachineError::type_error(h, ValidType::Atom, a1);
|
||||||
return Err(machine_st.error_form(err, stub));
|
return Err(machine_st.error_form(err, stub));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let atom = match machine_st.compare_term_test(&a2, &a3) {
|
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 addr = machine_st[temp_v!(1)];
|
||||||
let eof = clause_name!("end_of_file".to_string(), machine_st.atom_tbl);
|
let eof = clause_name!("end_of_file".to_string(), machine_st.atom_tbl);
|
||||||
|
|
||||||
let atom = machine_st.heap.to_unifiable(
|
let atom = machine_st.heap.to_unifiable(HeapCellValue::Atom(eof, None));
|
||||||
HeapCellValue::Atom(eof, None)
|
|
||||||
);
|
|
||||||
|
|
||||||
machine_st.unify(addr, atom);
|
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)?;
|
let mut list = machine_st.try_from_list(temp_v!(1), stub)?;
|
||||||
|
|
||||||
list.sort_unstable_by(|a1, a2| {
|
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);
|
machine_st.term_dedup(&mut list);
|
||||||
@@ -1081,7 +1085,9 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
}
|
}
|
||||||
|
|
||||||
key_pairs.sort_by(|a1, a2| {
|
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);
|
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);
|
let stub = MachineError::functor_stub(clause_name!("call"), arity + 1);
|
||||||
|
|
||||||
return Err(machine_st.error_form(
|
return Err(machine_st.error_form(
|
||||||
MachineError::type_error(
|
MachineError::type_error(machine_st.heap.h(), ValidType::Callable, name),
|
||||||
machine_st.heap.h(),
|
|
||||||
ValidType::Callable,
|
|
||||||
name
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -1200,7 +1202,8 @@ impl CallPolicy for CWILCallPolicy {
|
|||||||
arity: usize,
|
arity: usize,
|
||||||
idx: &CodeIndex,
|
idx: &CodeIndex,
|
||||||
) -> CallResult {
|
) -> 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)
|
self.increment(machine_st)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1239,7 +1242,7 @@ impl CallPolicy for CWILCallPolicy {
|
|||||||
code_dir,
|
code_dir,
|
||||||
op_dir,
|
op_dir,
|
||||||
current_input_stream,
|
current_input_stream,
|
||||||
current_output_stream
|
current_output_stream,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.increment(machine_st)
|
self.increment(machine_st)
|
||||||
@@ -1283,8 +1286,7 @@ pub(crate) struct CWILCallPolicy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CWILCallPolicy {
|
impl CWILCallPolicy {
|
||||||
pub(crate)
|
pub(crate) fn new_in_place(policy: &mut Box<dyn CallPolicy>) {
|
||||||
fn new_in_place(policy: &mut Box<dyn CallPolicy>) {
|
|
||||||
let mut prev_policy: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {});
|
let mut prev_policy: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {});
|
||||||
mem::swap(&mut prev_policy, policy);
|
mem::swap(&mut prev_policy, policy);
|
||||||
|
|
||||||
@@ -1319,8 +1321,7 @@ impl CWILCallPolicy {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn add_limit(&mut self, mut limit: Integer, b: usize) -> &Integer {
|
||||||
fn add_limit(&mut self, mut limit: Integer, b: usize) -> &Integer {
|
|
||||||
limit += &self.count;
|
limit += &self.count;
|
||||||
|
|
||||||
match self.limits.last().cloned() {
|
match self.limits.last().cloned() {
|
||||||
@@ -1331,8 +1332,7 @@ impl CWILCallPolicy {
|
|||||||
&self.count
|
&self.count
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn remove_limit(&mut self, b: usize) -> &Integer {
|
||||||
fn remove_limit(&mut self, b: usize) -> &Integer {
|
|
||||||
if let Some((_, bp)) = self.limits.last().cloned() {
|
if let Some((_, bp)) = self.limits.last().cloned() {
|
||||||
if bp == b {
|
if bp == b {
|
||||||
self.limits.pop();
|
self.limits.pop();
|
||||||
@@ -1342,13 +1342,11 @@ impl CWILCallPolicy {
|
|||||||
&self.count
|
&self.count
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn is_empty(&self) -> bool {
|
||||||
fn is_empty(&self) -> bool {
|
|
||||||
self.limits.is_empty()
|
self.limits.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn into_inner(&mut self) -> Box<dyn CallPolicy> {
|
||||||
fn into_inner(&mut self) -> Box<dyn CallPolicy> {
|
|
||||||
let mut new_inner: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {});
|
let mut new_inner: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {});
|
||||||
mem::swap(&mut self.prev_policy, &mut new_inner);
|
mem::swap(&mut self.prev_policy, &mut new_inner);
|
||||||
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::ast::*;
|
||||||
use crate::prolog_parser_rebis::tabled_rc::*;
|
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::clause_types::*;
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
@@ -34,8 +37,8 @@ mod machine_state_impl;
|
|||||||
mod system_calls;
|
mod system_calls;
|
||||||
|
|
||||||
//use crate::machine::attributed_variables::*;
|
//use crate::machine::attributed_variables::*;
|
||||||
use crate::machine::compile::*;
|
|
||||||
use crate::machine::code_repo::*;
|
use crate::machine::code_repo::*;
|
||||||
|
use crate::machine::compile::*;
|
||||||
// use crate::machine::loader::*;
|
// use crate::machine::loader::*;
|
||||||
use crate::machine::machine_errors::*;
|
use crate::machine::machine_errors::*;
|
||||||
use crate::machine::machine_indices::*;
|
use crate::machine::machine_indices::*;
|
||||||
@@ -45,6 +48,7 @@ use crate::machine::streams::*;
|
|||||||
use crate::indexmap::IndexMap;
|
use crate::indexmap::IndexMap;
|
||||||
|
|
||||||
//use std::convert::TryFrom;
|
//use std::convert::TryFrom;
|
||||||
|
use prolog_parser_rebis::ast::ClauseName;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@@ -162,18 +166,13 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn load_file(&mut self, path: String, stream: Stream) {
|
fn load_file(&mut self, path: String, stream: Stream) {
|
||||||
self.machine_st[temp_v!(1)] = Addr::Stream(
|
self.machine_st[temp_v!(1)] =
|
||||||
self.machine_st.heap.push(HeapCellValue::Stream(
|
Addr::Stream(self.machine_st.heap.push(HeapCellValue::Stream(stream)));
|
||||||
stream,
|
|
||||||
))
|
|
||||||
);
|
|
||||||
|
|
||||||
self.machine_st[temp_v!(2)] = Addr::Con(
|
self.machine_st[temp_v!(2)] = Addr::Con(self.machine_st.heap.push(HeapCellValue::Atom(
|
||||||
self.machine_st.heap.push(HeapCellValue::Atom(
|
|
||||||
clause_name!(path, self.machine_st.atom_tbl),
|
clause_name!(path, self.machine_st.atom_tbl),
|
||||||
None,
|
None,
|
||||||
))
|
)));
|
||||||
);
|
|
||||||
|
|
||||||
self.run_module_predicate(clause_name!("loader"), (clause_name!("file_load"), 2));
|
self.run_module_predicate(clause_name!("loader"), (clause_name!("file_load"), 2));
|
||||||
}
|
}
|
||||||
@@ -206,11 +205,9 @@ impl Machine {
|
|||||||
bootstrapping_compile(
|
bootstrapping_compile(
|
||||||
Stream::from(include_str!("attributed_variables.pl")),
|
Stream::from(include_str!("attributed_variables.pl")),
|
||||||
self,
|
self,
|
||||||
ListingSource::from_file_and_path(
|
ListingSource::from_file_and_path(clause_name!("attributed_variables"), path_buf),
|
||||||
clause_name!("attributed_variables"),
|
)
|
||||||
path_buf,
|
.unwrap();
|
||||||
),
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
let mut path_buf = current_dir();
|
let mut path_buf = current_dir();
|
||||||
path_buf.push("machine/project_attributes.pl");
|
path_buf.push("machine/project_attributes.pl");
|
||||||
@@ -218,11 +215,9 @@ impl Machine {
|
|||||||
bootstrapping_compile(
|
bootstrapping_compile(
|
||||||
Stream::from(include_str!("project_attributes.pl")),
|
Stream::from(include_str!("project_attributes.pl")),
|
||||||
self,
|
self,
|
||||||
ListingSource::from_file_and_path(
|
ListingSource::from_file_and_path(clause_name!("project_attributes"), path_buf),
|
||||||
clause_name!("project_attributes"),
|
)
|
||||||
path_buf,
|
.unwrap();
|
||||||
),
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
if let Some(module) = self.indices.modules.get(&clause_name!("$atts")) {
|
if let Some(module) = self.indices.modules.get(&clause_name!("$atts")) {
|
||||||
if let Some(code_index) = module.code_dir.get(&(clause_name!("driver"), 2)) {
|
if let Some(code_index) = module.code_dir.get(&(clause_name!("driver"), 2)) {
|
||||||
@@ -260,7 +255,8 @@ impl Machine {
|
|||||||
|
|
||||||
match loader.code_dir.get(&key) {
|
match loader.code_dir.get(&key) {
|
||||||
Some(src_code_index) => {
|
Some(src_code_index) => {
|
||||||
let target_code_index = target_module.code_dir
|
let target_code_index = target_module
|
||||||
|
.code_dir
|
||||||
.entry(key.clone())
|
.entry(key.clone())
|
||||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined));
|
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined));
|
||||||
|
|
||||||
@@ -290,9 +286,10 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for arity in 10..66 {
|
for arity in 10..66 {
|
||||||
builtins.module_decl.exports.push(
|
builtins
|
||||||
ModuleExport::PredicateKey((clause_name!("call"), arity)),
|
.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;
|
use crate::ref_thread_local::RefThreadLocal;
|
||||||
|
|
||||||
let mut wam = Machine {
|
let mut wam = Machine {
|
||||||
@@ -333,16 +329,15 @@ impl Machine {
|
|||||||
clause_name!("ops_and_meta_predicates.pl"),
|
clause_name!("ops_and_meta_predicates.pl"),
|
||||||
lib_path.clone(),
|
lib_path.clone(),
|
||||||
),
|
),
|
||||||
).unwrap();
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
bootstrapping_compile(
|
bootstrapping_compile(
|
||||||
Stream::from(LIBRARIES.borrow()["builtins"]),
|
Stream::from(LIBRARIES.borrow()["builtins"]),
|
||||||
&mut wam,
|
&mut wam,
|
||||||
ListingSource::from_file_and_path(
|
ListingSource::from_file_and_path(clause_name!("builtins.pl"), lib_path.clone()),
|
||||||
clause_name!("builtins.pl"),
|
)
|
||||||
lib_path.clone(),
|
.unwrap();
|
||||||
),
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
if let Some(builtins) = wam.indices.modules.get(&clause_name!("builtins")) {
|
if let Some(builtins) = wam.indices.modules.get(&clause_name!("builtins")) {
|
||||||
load_module(
|
load_module(
|
||||||
@@ -361,11 +356,9 @@ impl Machine {
|
|||||||
bootstrapping_compile(
|
bootstrapping_compile(
|
||||||
Stream::from(include_str!("../loader.pl")),
|
Stream::from(include_str!("../loader.pl")),
|
||||||
&mut wam,
|
&mut wam,
|
||||||
ListingSource::from_file_and_path(
|
ListingSource::from_file_and_path(clause_name!("loader.pl"), lib_path.clone()),
|
||||||
clause_name!("loader.pl"),
|
)
|
||||||
lib_path.clone(),
|
.unwrap();
|
||||||
),
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
wam.configure_modules();
|
wam.configure_modules();
|
||||||
|
|
||||||
@@ -391,25 +384,19 @@ impl Machine {
|
|||||||
pub fn configure_streams(&mut self) {
|
pub fn configure_streams(&mut self) {
|
||||||
self.user_input.options.alias = Some(clause_name!("user_input"));
|
self.user_input.options.alias = Some(clause_name!("user_input"));
|
||||||
|
|
||||||
self.indices.stream_aliases.insert(
|
self.indices
|
||||||
clause_name!("user_input"),
|
.stream_aliases
|
||||||
self.user_input.clone(),
|
.insert(clause_name!("user_input"), self.user_input.clone());
|
||||||
);
|
|
||||||
|
|
||||||
self.indices.streams.insert(
|
self.indices.streams.insert(self.user_input.clone());
|
||||||
self.user_input.clone()
|
|
||||||
);
|
|
||||||
|
|
||||||
self.user_output.options.alias = Some(clause_name!("user_output"));
|
self.user_output.options.alias = Some(clause_name!("user_output"));
|
||||||
|
|
||||||
self.indices.stream_aliases.insert(
|
self.indices
|
||||||
clause_name!("user_output"),
|
.stream_aliases
|
||||||
self.user_output.clone(),
|
.insert(clause_name!("user_output"), self.user_output.clone());
|
||||||
);
|
|
||||||
|
|
||||||
self.indices.streams.insert(
|
self.indices.streams.insert(self.user_output.clone());
|
||||||
self.user_output.clone()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn throw_session_error(&mut self, err: SessionError, key: PredicateKey) {
|
fn throw_session_error(&mut self, err: SessionError, key: PredicateKey) {
|
||||||
@@ -508,8 +495,7 @@ impl Machine {
|
|||||||
self.machine_st.p = CodePtr::Local(p);
|
self.machine_st.p = CodePtr::Local(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn run_query(&mut self) {
|
||||||
fn run_query(&mut self) {
|
|
||||||
while !self.machine_st.p.is_halt() {
|
while !self.machine_st.p.is_halt() {
|
||||||
self.machine_st.query_stepper(
|
self.machine_st.query_stepper(
|
||||||
&mut self.indices,
|
&mut self.indices,
|
||||||
@@ -546,17 +532,14 @@ impl MachineState {
|
|||||||
user_output: &mut Stream,
|
user_output: &mut Stream,
|
||||||
) {
|
) {
|
||||||
match instr {
|
match instr {
|
||||||
&Line::Arithmetic(ref arith_instr) => {
|
&Line::Arithmetic(ref arith_instr) => self.execute_arith_instr(arith_instr),
|
||||||
self.execute_arith_instr(arith_instr)
|
|
||||||
}
|
|
||||||
&Line::Choice(ref choice_instr) => {
|
&Line::Choice(ref choice_instr) => {
|
||||||
self.execute_choice_instr(choice_instr, &mut policies.call_policy)
|
self.execute_choice_instr(choice_instr, &mut policies.call_policy)
|
||||||
}
|
}
|
||||||
&Line::Cut(ref cut_instr) => {
|
&Line::Cut(ref cut_instr) => {
|
||||||
self.execute_cut_instr(cut_instr, &mut policies.cut_policy)
|
self.execute_cut_instr(cut_instr, &mut policies.cut_policy)
|
||||||
}
|
}
|
||||||
&Line::Control(ref control_instr) => {
|
&Line::Control(ref control_instr) => self.execute_ctrl_instr(
|
||||||
self.execute_ctrl_instr(
|
|
||||||
indices,
|
indices,
|
||||||
code_repo,
|
code_repo,
|
||||||
&mut policies.call_policy,
|
&mut policies.call_policy,
|
||||||
@@ -564,8 +547,7 @@ impl MachineState {
|
|||||||
user_input,
|
user_input,
|
||||||
user_output,
|
user_output,
|
||||||
control_instr,
|
control_instr,
|
||||||
)
|
),
|
||||||
}
|
|
||||||
&Line::Fact(ref fact_instr) => {
|
&Line::Fact(ref fact_instr) => {
|
||||||
self.execute_fact_instr(&fact_instr);
|
self.execute_fact_instr(&fact_instr);
|
||||||
self.p += 1;
|
self.p += 1;
|
||||||
@@ -617,15 +599,13 @@ impl MachineState {
|
|||||||
|
|
||||||
fn check_machine_index(&mut self, code_repo: &CodeRepo) -> bool {
|
fn check_machine_index(&mut self, code_repo: &CodeRepo) -> bool {
|
||||||
match self.p {
|
match self.p {
|
||||||
CodePtr::Local(LocalCodePtr::DirEntry(p)) |
|
CodePtr::Local(LocalCodePtr::DirEntry(p))
|
||||||
CodePtr::Local(LocalCodePtr::IndexingBuf(p, ..))
|
| CodePtr::Local(LocalCodePtr::IndexingBuf(p, ..))
|
||||||
if p < code_repo.code.len() => {
|
if p < code_repo.code.len() => {}
|
||||||
}
|
|
||||||
CodePtr::Local(LocalCodePtr::Halt) | CodePtr::REPL(..) => {
|
CodePtr::Local(LocalCodePtr::Halt) | CodePtr::REPL(..) => {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
true
|
||||||
@@ -689,13 +669,7 @@ impl MachineState {
|
|||||||
user_output: &mut Stream,
|
user_output: &mut Stream,
|
||||||
) {
|
) {
|
||||||
loop {
|
loop {
|
||||||
self.execute_instr(
|
self.execute_instr(indices, policies, code_repo, user_input, user_output);
|
||||||
indices,
|
|
||||||
policies,
|
|
||||||
code_repo,
|
|
||||||
user_input,
|
|
||||||
user_output,
|
|
||||||
);
|
|
||||||
|
|
||||||
if self.fail {
|
if self.fail {
|
||||||
self.backtrack();
|
self.backtrack();
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use crate::prolog_parser_rebis::ast::*;
|
||||||
use crate::prolog_parser_rebis::tabled_rc::*;
|
use crate::prolog_parser_rebis::tabled_rc::*;
|
||||||
|
use crate::prolog_parser_rebis::{atom, clause_name, rc_atom};
|
||||||
|
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
use crate::iterators::*;
|
use crate::iterators::*;
|
||||||
use crate::machine::*;
|
|
||||||
use crate::machine::load_state::*;
|
use crate::machine::load_state::*;
|
||||||
use crate::machine::machine_errors::*;
|
use crate::machine::machine_errors::*;
|
||||||
|
use crate::machine::*;
|
||||||
|
|
||||||
use crate::indexmap::IndexSet;
|
use crate::indexmap::IndexSet;
|
||||||
|
|
||||||
@@ -85,8 +86,7 @@ fn setup_op_decl(
|
|||||||
to_op_decl(prec, spec.as_str(), name)
|
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 {
|
match term {
|
||||||
Term::Clause(_, ref slash, ref mut terms, Some(_))
|
Term::Clause(_, ref slash, ref mut terms, Some(_))
|
||||||
if (slash.as_str() == "/" || slash.as_str() == "//") && terms.len() == 2 =>
|
if (slash.as_str() == "/" || slash.as_str() == "//") && terms.len() == 2 =>
|
||||||
@@ -96,12 +96,10 @@ fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, Compilatio
|
|||||||
|
|
||||||
let arity = arity
|
let arity = arity
|
||||||
.to_constant()
|
.to_constant()
|
||||||
.and_then(|c| {
|
.and_then(|c| match c {
|
||||||
match c {
|
|
||||||
Constant::Integer(n) => n.to_usize(),
|
Constant::Integer(n) => n.to_usize(),
|
||||||
Constant::Fixnum(n) => usize::try_from(n).ok(),
|
Constant::Fixnum(n) => usize::try_from(n).ok(),
|
||||||
_ => None
|
_ => None,
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.ok_or(CompilationError::InvalidModuleExport)?;
|
.ok_or(CompilationError::InvalidModuleExport)?;
|
||||||
|
|
||||||
@@ -116,9 +114,7 @@ fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, Compilatio
|
|||||||
Ok((name, arity + 2))
|
Ok((name, arity + 2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => Err(CompilationError::InvalidModuleExport),
|
||||||
Err(CompilationError::InvalidModuleExport)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,10 +151,7 @@ fn setup_module_export(
|
|||||||
.or_else(|_| {
|
.or_else(|_| {
|
||||||
if let Term::Clause(_, name, terms, _) = term {
|
if let Term::Clause(_, name, terms, _) = term {
|
||||||
if terms.len() == 3 && name.as_str() == "op" {
|
if terms.len() == 3 && name.as_str() == "op" {
|
||||||
Ok(ModuleExport::OpDecl(setup_op_decl(
|
Ok(ModuleExport::OpDecl(setup_op_decl(terms, atom_tbl)?))
|
||||||
terms,
|
|
||||||
atom_tbl
|
|
||||||
)?))
|
|
||||||
} else {
|
} else {
|
||||||
Err(CompilationError::InvalidModuleDecl)
|
Err(CompilationError::InvalidModuleDecl)
|
||||||
}
|
}
|
||||||
@@ -168,8 +161,7 @@ fn setup_module_export(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn setup_module_export_list(
|
||||||
fn setup_module_export_list(
|
|
||||||
mut export_list: Term,
|
mut export_list: Term,
|
||||||
atom_tbl: TabledData<Atom>,
|
atom_tbl: TabledData<Atom>,
|
||||||
) -> Result<Vec<ModuleExport>, CompilationError> {
|
) -> 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))
|
.map(|c| ModuleSource::Library(c))
|
||||||
.ok_or(CompilationError::InvalidUseModuleDecl)
|
.ok_or(CompilationError::InvalidUseModuleDecl)
|
||||||
}
|
}
|
||||||
Term::Constant(_, Constant::Atom(ref name, _)) =>
|
Term::Constant(_, Constant::Atom(ref name, _)) => Ok(ModuleSource::File(name.clone())),
|
||||||
Ok(ModuleSource::File(name.clone())),
|
|
||||||
_ => Err(CompilationError::InvalidUseModuleDecl),
|
_ => Err(CompilationError::InvalidUseModuleDecl),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -271,12 +262,8 @@ fn setup_qualified_import(
|
|||||||
.map(|c| ModuleSource::Library(c))
|
.map(|c| ModuleSource::Library(c))
|
||||||
.ok_or(CompilationError::InvalidUseModuleDecl)
|
.ok_or(CompilationError::InvalidUseModuleDecl)
|
||||||
}
|
}
|
||||||
Term::Constant(_, Constant::Atom(ref name, _)) => {
|
Term::Constant(_, Constant::Atom(ref name, _)) => Ok(ModuleSource::File(name.clone())),
|
||||||
Ok(ModuleSource::File(name.clone()))
|
_ => Err(CompilationError::InvalidUseModuleDecl),
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
Err(CompilationError::InvalidUseModuleDecl)
|
|
||||||
}
|
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
let mut exports = IndexSet::new();
|
let mut exports = IndexSet::new();
|
||||||
@@ -334,8 +321,7 @@ fn setup_qualified_import(
|
|||||||
fn setup_meta_predicate<'a>(
|
fn setup_meta_predicate<'a>(
|
||||||
mut terms: Vec<Box<Term>>,
|
mut terms: Vec<Box<Term>>,
|
||||||
load_state: &LoadState<'a>,
|
load_state: &LoadState<'a>,
|
||||||
) -> Result<(ClauseName, ClauseName, Vec<MetaSpec>), CompilationError>
|
) -> Result<(ClauseName, ClauseName, Vec<MetaSpec>), CompilationError> {
|
||||||
{
|
|
||||||
fn get_name_and_meta_specs(
|
fn get_name_and_meta_specs(
|
||||||
name: ClauseName,
|
name: ClauseName,
|
||||||
terms: &mut [Box<Term>],
|
terms: &mut [Box<Term>],
|
||||||
@@ -345,8 +331,7 @@ fn setup_meta_predicate<'a>(
|
|||||||
for meta_spec in terms.into_iter() {
|
for meta_spec in terms.into_iter() {
|
||||||
match &**meta_spec {
|
match &**meta_spec {
|
||||||
Term::Constant(_, Constant::Atom(meta_spec, _)) => {
|
Term::Constant(_, Constant::Atom(meta_spec, _)) => {
|
||||||
let meta_spec =
|
let meta_spec = match meta_spec.as_str() {
|
||||||
match meta_spec.as_str() {
|
|
||||||
"+" => MetaSpec::Plus,
|
"+" => MetaSpec::Plus,
|
||||||
"-" => MetaSpec::Minus,
|
"-" => MetaSpec::Minus,
|
||||||
"?" => MetaSpec::Either,
|
"?" => MetaSpec::Either,
|
||||||
@@ -355,16 +340,14 @@ fn setup_meta_predicate<'a>(
|
|||||||
|
|
||||||
meta_specs.push(meta_spec);
|
meta_specs.push(meta_spec);
|
||||||
}
|
}
|
||||||
Term::Constant(_, Constant::Fixnum(n)) => {
|
Term::Constant(_, Constant::Fixnum(n)) => match usize::try_from(*n) {
|
||||||
match usize::try_from(*n) {
|
|
||||||
Ok(n) if n <= MAX_ARITY => {
|
Ok(n) if n <= MAX_ARITY => {
|
||||||
meta_specs.push(MetaSpec::RequiresExpansionWithArgument(n));
|
meta_specs.push(MetaSpec::RequiresExpansionWithArgument(n));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(CompilationError::InvalidMetaPredicateDecl);
|
return Err(CompilationError::InvalidMetaPredicateDecl);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
return Err(CompilationError::InvalidMetaPredicateDecl);
|
return Err(CompilationError::InvalidMetaPredicateDecl);
|
||||||
}
|
}
|
||||||
@@ -375,42 +358,35 @@ fn setup_meta_predicate<'a>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
match *terms.pop().unwrap() {
|
match *terms.pop().unwrap() {
|
||||||
Term::Clause(_, name, mut terms, _)
|
Term::Clause(_, name, mut terms, _) if name.as_str() == ":" && terms.len() == 2 => {
|
||||||
if name.as_str() == ":" && terms.len() == 2 => {
|
|
||||||
let spec = *terms.pop().unwrap();
|
let spec = *terms.pop().unwrap();
|
||||||
let module_name = *terms.pop().unwrap();
|
let module_name = *terms.pop().unwrap();
|
||||||
|
|
||||||
match module_name {
|
match module_name {
|
||||||
Term::Constant(_, Constant::Atom(module_name, _)) => {
|
Term::Constant(_, Constant::Atom(module_name, _)) => match spec {
|
||||||
match spec {
|
|
||||||
Term::Clause(_, name, mut terms, _) => {
|
Term::Clause(_, name, mut terms, _) => {
|
||||||
let (name, meta_specs) =
|
let (name, meta_specs) = get_name_and_meta_specs(name, &mut terms)?;
|
||||||
get_name_and_meta_specs(name, &mut terms)?;
|
|
||||||
|
|
||||||
Ok((module_name, name, meta_specs))
|
Ok((module_name, name, meta_specs))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => Err(CompilationError::InvalidMetaPredicateDecl),
|
||||||
Err(CompilationError::InvalidMetaPredicateDecl)
|
},
|
||||||
}
|
_ => Err(CompilationError::InvalidMetaPredicateDecl),
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
Err(CompilationError::InvalidMetaPredicateDecl)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Term::Clause(_, name, mut terms, _) => {
|
Term::Clause(_, name, mut terms, _) => {
|
||||||
let (name, meta_specs) = get_name_and_meta_specs(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))
|
Ok((
|
||||||
}
|
load_state.compilation_target.module_name(),
|
||||||
_ => {
|
name,
|
||||||
Err(CompilationError::InvalidMetaPredicateDecl)
|
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![];
|
let mut clauses = vec![];
|
||||||
|
|
||||||
while let Some(tl) = tls.pop_front() {
|
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);
|
let clause = PredicateClause::Rule(rule);
|
||||||
clauses.push(clause);
|
clauses.push(clause);
|
||||||
}
|
}
|
||||||
TopLevel::Predicate(predicate) => {
|
TopLevel::Predicate(predicate) => clauses.extend(predicate.into_iter()),
|
||||||
clauses.extend(predicate.into_iter())
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
tls.push_front(tl);
|
tls.push_front(tl);
|
||||||
break;
|
break;
|
||||||
@@ -506,8 +480,8 @@ fn check_for_internal_if_then(terms: &mut Vec<Term>) {
|
|||||||
|
|
||||||
conq_terms.push_front(Term::Constant(
|
conq_terms.push_front(Term::Constant(
|
||||||
Cell::default(),
|
Cell::default(),
|
||||||
Constant::Atom(clause_name!("blocked_!"), None))
|
Constant::Atom(clause_name!("blocked_!"), None),
|
||||||
);
|
));
|
||||||
|
|
||||||
while let Some(term) = pre_cut_terms.pop_back() {
|
while let Some(term) = pre_cut_terms.pop_back() {
|
||||||
conq_terms.push_front(term);
|
conq_terms.push_front(term);
|
||||||
@@ -531,23 +505,18 @@ fn setup_declaration<'a>(
|
|||||||
let atom_tbl = load_state.wam.machine_st.atom_tbl.clone();
|
let atom_tbl = load_state.wam.machine_st.atom_tbl.clone();
|
||||||
|
|
||||||
match term {
|
match term {
|
||||||
Term::Clause(_, name, mut terms, _) =>
|
Term::Clause(_, name, mut terms, _) => match (name.as_str(), terms.len()) {
|
||||||
match (name.as_str(), terms.len()) {
|
|
||||||
("dynamic", 1) => {
|
("dynamic", 1) => {
|
||||||
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
|
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
|
||||||
Ok(Declaration::Dynamic(name, arity))
|
Ok(Declaration::Dynamic(name, arity))
|
||||||
}
|
}
|
||||||
("module", 2) =>
|
("module", 2) => Ok(Declaration::Module(setup_module_decl(terms, atom_tbl)?)),
|
||||||
Ok(Declaration::Module(setup_module_decl(terms, atom_tbl)?)),
|
("op", 3) => Ok(Declaration::Op(setup_op_decl(terms, atom_tbl)?)),
|
||||||
("op", 3) =>
|
|
||||||
Ok(Declaration::Op(setup_op_decl(terms, atom_tbl)?)),
|
|
||||||
("non_counted_backtracking", 1) => {
|
("non_counted_backtracking", 1) => {
|
||||||
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
|
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
|
||||||
Ok(Declaration::NonCountedBacktracking(name, arity))
|
Ok(Declaration::NonCountedBacktracking(name, arity))
|
||||||
}
|
}
|
||||||
("use_module", 1) => {
|
("use_module", 1) => Ok(Declaration::UseModule(setup_use_module_decl(terms)?)),
|
||||||
Ok(Declaration::UseModule(setup_use_module_decl(terms)?))
|
|
||||||
}
|
|
||||||
("use_module", 2) => {
|
("use_module", 2) => {
|
||||||
let (name, exports) = setup_qualified_import(terms, atom_tbl)?;
|
let (name, exports) = setup_qualified_import(terms, atom_tbl)?;
|
||||||
Ok(Declaration::UseQualifiedModule(name, exports))
|
Ok(Declaration::UseQualifiedModule(name, exports))
|
||||||
@@ -556,13 +525,9 @@ fn setup_declaration<'a>(
|
|||||||
let (module_name, name, meta_specs) = setup_meta_predicate(terms, load_state)?;
|
let (module_name, name, meta_specs) = setup_meta_predicate(terms, load_state)?;
|
||||||
Ok(Declaration::MetaPredicate(module_name, name, meta_specs))
|
Ok(Declaration::MetaPredicate(module_name, name, meta_specs))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => Err(CompilationError::InconsistentEntry),
|
||||||
Err(CompilationError::InconsistentEntry)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
_ => {
|
_ => Err(CompilationError::InconsistentEntry),
|
||||||
Err(CompilationError::InconsistentEntry)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,8 +561,7 @@ pub(crate) struct Preprocessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Preprocessor {
|
impl Preprocessor {
|
||||||
pub(super)
|
pub(super) fn new(flags: MachineFlags) -> Self {
|
||||||
fn new(flags: MachineFlags) -> Self {
|
|
||||||
Preprocessor {
|
Preprocessor {
|
||||||
flags,
|
flags,
|
||||||
queue: VecDeque::new(),
|
queue: VecDeque::new(),
|
||||||
@@ -606,12 +570,8 @@ impl Preprocessor {
|
|||||||
|
|
||||||
fn setup_fact(&mut self, term: Term) -> Result<Term, CompilationError> {
|
fn setup_fact(&mut self, term: Term) -> Result<Term, CompilationError> {
|
||||||
match term {
|
match term {
|
||||||
Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) => {
|
Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) => Ok(term),
|
||||||
Ok(term)
|
_ => Err(CompilationError::InadmissibleFact),
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
Err(CompilationError::InadmissibleFact)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -712,14 +672,11 @@ impl Preprocessor {
|
|||||||
Ok(clause_to_query_term(load_state, name, vec![], fixity))
|
Ok(clause_to_query_term(load_state, name, vec![], fixity))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Term::Constant(_, Constant::Char('!')) => {
|
Term::Constant(_, Constant::Char('!')) => Ok(QueryTerm::BlockedCut),
|
||||||
Ok(QueryTerm::BlockedCut)
|
|
||||||
}
|
|
||||||
Term::Var(_, ref v) if v.as_str() == "!" => {
|
Term::Var(_, ref v) if v.as_str() == "!" => {
|
||||||
Ok(QueryTerm::UnblockedCut(Cell::default()))
|
Ok(QueryTerm::UnblockedCut(Cell::default()))
|
||||||
}
|
}
|
||||||
Term::Clause(r, name, mut terms, fixity) => {
|
Term::Clause(r, name, mut terms, fixity) => match (name.as_str(), terms.len()) {
|
||||||
match (name.as_str(), terms.len()) {
|
|
||||||
(";", 2) => {
|
(";", 2) => {
|
||||||
let term = Term::Clause(r, name.clone(), terms, fixity);
|
let term = Term::Clause(r, name.clone(), terms, fixity);
|
||||||
|
|
||||||
@@ -740,13 +697,11 @@ impl Preprocessor {
|
|||||||
("\\+", 1) => {
|
("\\+", 1) => {
|
||||||
terms.push(Box::new(Term::Constant(
|
terms.push(Box::new(Term::Constant(
|
||||||
Cell::default(),
|
Cell::default(),
|
||||||
Constant::Atom(clause_name!("$fail"), None)
|
Constant::Atom(clause_name!("$fail"), None),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
let conq = Term::Constant(
|
let conq =
|
||||||
Cell::default(),
|
Term::Constant(Cell::default(), Constant::Atom(clause_name!("true"), None));
|
||||||
Constant::Atom(clause_name!("true"), None)
|
|
||||||
);
|
|
||||||
|
|
||||||
let prec = Term::Clause(Cell::default(), clause_name!("->"), terms, None);
|
let prec = Term::Clause(Cell::default(), clause_name!("->"), terms, None);
|
||||||
let terms = vec![Box::new(prec), Box::new(conq)];
|
let terms = vec![Box::new(prec), Box::new(conq)];
|
||||||
@@ -771,26 +726,26 @@ impl Preprocessor {
|
|||||||
let module_name = *terms.pop().unwrap();
|
let module_name = *terms.pop().unwrap();
|
||||||
|
|
||||||
match (module_name, predicate_name) {
|
match (module_name, predicate_name) {
|
||||||
(Term::Constant(_, Constant::Atom(module_name, _)),
|
(
|
||||||
Term::Constant(_, Constant::Atom(predicate_name, fixity))) => {
|
Term::Constant(_, Constant::Atom(module_name, _)),
|
||||||
Ok(qualified_clause_to_query_term(
|
Term::Constant(_, Constant::Atom(predicate_name, fixity)),
|
||||||
|
) => Ok(qualified_clause_to_query_term(
|
||||||
load_state,
|
load_state,
|
||||||
module_name,
|
module_name,
|
||||||
predicate_name,
|
predicate_name,
|
||||||
vec![],
|
vec![],
|
||||||
fixity,
|
fixity,
|
||||||
))
|
)),
|
||||||
}
|
(
|
||||||
(Term::Constant(_, Constant::Atom(module_name, _)),
|
Term::Constant(_, Constant::Atom(module_name, _)),
|
||||||
Term::Clause(_, name, terms, fixity)) => {
|
Term::Clause(_, name, terms, fixity),
|
||||||
Ok(qualified_clause_to_query_term(
|
) => Ok(qualified_clause_to_query_term(
|
||||||
load_state,
|
load_state,
|
||||||
module_name,
|
module_name,
|
||||||
name,
|
name,
|
||||||
terms,
|
terms,
|
||||||
fixity,
|
fixity,
|
||||||
))
|
)),
|
||||||
}
|
|
||||||
(module_name, predicate_name) => {
|
(module_name, predicate_name) => {
|
||||||
terms.push(Box::new(module_name));
|
terms.push(Box::new(module_name));
|
||||||
terms.push(Box::new(predicate_name));
|
terms.push(Box::new(predicate_name));
|
||||||
@@ -799,22 +754,15 @@ impl Preprocessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => 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(
|
||||||
}
|
|
||||||
}
|
|
||||||
Term::Var(..) => {
|
|
||||||
Ok(QueryTerm::Clause(
|
|
||||||
Cell::default(),
|
Cell::default(),
|
||||||
ClauseType::CallN,
|
ClauseType::CallN,
|
||||||
vec![Box::new(term)],
|
vec![Box::new(term)],
|
||||||
false,
|
false,
|
||||||
))
|
)),
|
||||||
}
|
_ => Err(CompilationError::InadmissibleQueryTerm),
|
||||||
_ => {
|
|
||||||
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::Clause(r, name, subterms, fixity))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => self.to_query_term(load_state, term),
|
||||||
self.to_query_term(load_state, term)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -886,28 +832,21 @@ impl Preprocessor {
|
|||||||
) -> Result<Rule, CompilationError> {
|
) -> 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 =
|
let mut query_terms = self.setup_query(load_state, post_head_terms, cut_context)?;
|
||||||
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();
|
let qt = query_terms.pop().unwrap();
|
||||||
|
|
||||||
match *terms.pop().unwrap() {
|
match *terms.pop().unwrap() {
|
||||||
Term::Clause(_, name, terms, _) => {
|
Term::Clause(_, name, terms, _) => Ok(Rule {
|
||||||
Ok(Rule {
|
|
||||||
head: (name, terms, qt),
|
head: (name, terms, qt),
|
||||||
clauses,
|
clauses,
|
||||||
})
|
}),
|
||||||
}
|
Term::Constant(_, Constant::Atom(name, _)) => Ok(Rule {
|
||||||
Term::Constant(_, Constant::Atom(name, _)) => {
|
|
||||||
Ok(Rule {
|
|
||||||
head: (name, vec![], qt),
|
head: (name, vec![], qt),
|
||||||
clauses,
|
clauses,
|
||||||
})
|
}),
|
||||||
}
|
_ => Err(CompilationError::InvalidRuleHead),
|
||||||
_ => {
|
|
||||||
Err(CompilationError::InvalidRuleHead)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -917,11 +856,14 @@ impl Preprocessor {
|
|||||||
terms: Vec<Box<Term>>,
|
terms: Vec<Box<Term>>,
|
||||||
cut_context: CutContext,
|
cut_context: CutContext,
|
||||||
) -> Result<TopLevel, CompilationError> {
|
) -> 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)
|
pub(super) fn try_term_to_tl<'a>(
|
||||||
fn try_term_to_tl<'a>(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
load_state: &mut LoadState<'a>,
|
load_state: &mut LoadState<'a>,
|
||||||
term: Term,
|
term: Term,
|
||||||
@@ -944,9 +886,7 @@ impl Preprocessor {
|
|||||||
Ok(TopLevel::Fact(self.setup_fact(term)?))
|
Ok(TopLevel::Fact(self.setup_fact(term)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
term => {
|
term => Ok(TopLevel::Fact(self.setup_fact(term)?)),
|
||||||
Ok(TopLevel::Fact(self.setup_fact(term)?))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -965,21 +905,18 @@ impl Preprocessor {
|
|||||||
Ok(results)
|
Ok(results)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn parse_queue<'a>(
|
||||||
fn parse_queue<'a>(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
load_state: &mut LoadState<'a>,
|
load_state: &mut LoadState<'a>,
|
||||||
) -> Result<VecDeque<TopLevel>, CompilationError> {
|
) -> Result<VecDeque<TopLevel>, CompilationError> {
|
||||||
let mut queue = VecDeque::new();
|
let mut queue = VecDeque::new();
|
||||||
|
|
||||||
while let Some(terms) = self.queue.pop_front() {
|
while let Some(terms) = self.queue.pop_front() {
|
||||||
let clauses = merge_clauses(
|
let clauses = merge_clauses(&mut self.try_terms_to_tls(
|
||||||
&mut self.try_terms_to_tls(
|
|
||||||
load_state,
|
load_state,
|
||||||
terms,
|
terms,
|
||||||
CutContext::HasCutVariable,
|
CutContext::HasCutVariable,
|
||||||
)?
|
)?)?;
|
||||||
)?;
|
|
||||||
|
|
||||||
queue.push_back(clauses);
|
queue.push_back(clauses);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
63
src/main.rs
63
src/main.rs
@@ -1,43 +1,35 @@
|
|||||||
extern crate blake2;
|
use blake2;
|
||||||
extern crate chrono;
|
use chrono;
|
||||||
extern crate cpu_time;
|
use cpu_time;
|
||||||
extern crate crossterm;
|
use crossterm;
|
||||||
extern crate divrem;
|
use divrem;
|
||||||
#[macro_use]
|
use downcast;
|
||||||
extern crate downcast;
|
use git_version;
|
||||||
extern crate git_version;
|
use indexmap;
|
||||||
extern crate hostname;
|
use lazy_static;
|
||||||
extern crate indexmap;
|
use native_tls;
|
||||||
#[macro_use]
|
use nix::sys::signal;
|
||||||
extern crate lazy_static;
|
use openssl;
|
||||||
extern crate libc;
|
use ordered_float;
|
||||||
extern crate native_tls;
|
use prolog_parser_rebis;
|
||||||
extern crate nix;
|
use ref_thread_local;
|
||||||
extern crate openssl;
|
use ring;
|
||||||
extern crate ordered_float;
|
use ripemd160;
|
||||||
#[macro_use]
|
use rustyline;
|
||||||
extern crate prolog_parser_rebis;
|
use sha3;
|
||||||
#[macro_use]
|
use unicode_reader;
|
||||||
extern crate ref_thread_local;
|
|
||||||
extern crate ring;
|
|
||||||
extern crate ripemd160;
|
|
||||||
#[cfg(feature = "rug")]
|
|
||||||
extern crate rug;
|
|
||||||
#[cfg(feature = "num-rug-adapter")]
|
|
||||||
extern crate num_rug_adapter as rug;
|
|
||||||
extern crate rustyline;
|
|
||||||
extern crate sha3;
|
|
||||||
extern crate unicode_reader;
|
|
||||||
|
|
||||||
use crate::nix::sys::signal;
|
#[cfg(feature = "num-rug-adapter")]
|
||||||
|
use num_rug_adapter as rug;
|
||||||
|
#[cfg(feature = "rug")]
|
||||||
|
use rug;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
mod allocator;
|
mod allocator;
|
||||||
mod arithmetic;
|
mod arithmetic;
|
||||||
mod machine;
|
|
||||||
mod codegen;
|
|
||||||
mod clause_types;
|
mod clause_types;
|
||||||
|
mod codegen;
|
||||||
mod debray_allocator;
|
mod debray_allocator;
|
||||||
mod fixtures;
|
mod fixtures;
|
||||||
mod forms;
|
mod forms;
|
||||||
@@ -46,17 +38,18 @@ mod heap_print;
|
|||||||
mod indexing;
|
mod indexing;
|
||||||
mod instructions;
|
mod instructions;
|
||||||
mod iterators;
|
mod iterators;
|
||||||
|
mod machine;
|
||||||
mod read;
|
mod read;
|
||||||
mod targets;
|
mod targets;
|
||||||
mod write;
|
mod write;
|
||||||
|
|
||||||
use machine::*;
|
|
||||||
use machine::streams::*;
|
use machine::streams::*;
|
||||||
|
use machine::*;
|
||||||
use read::*;
|
use read::*;
|
||||||
|
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
extern fn handle_sigint(signal: libc::c_int) {
|
extern "C" fn handle_sigint(signal: libc::c_int) {
|
||||||
let signal = signal::Signal::from_c_int(signal).unwrap();
|
let signal = signal::Signal::from_c_int(signal).unwrap();
|
||||||
if signal == signal::Signal::SIGINT {
|
if signal == signal::Signal::SIGINT {
|
||||||
INTERRUPT.store(true, Ordering::Relaxed);
|
INTERRUPT.store(true, Ordering::Relaxed);
|
||||||
|
|||||||
Reference in New Issue
Block a user