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()) {
|
||||
if entry.is_dir() {
|
||||
if let Some(file_name) = entry.file_name() {
|
||||
let new_prefix =
|
||||
prefix.to_owned() + file_name.to_str().unwrap() + "/";
|
||||
let new_prefix = prefix.to_owned() + file_name.to_str().unwrap() + "/";
|
||||
find_prolog_files(libraries, &new_prefix, &entry);
|
||||
}
|
||||
} else if entry.is_file() {
|
||||
let ext = std::ffi::OsStr::new("pl");
|
||||
if entry.extension() == Some(ext) {
|
||||
let contain =
|
||||
String::from_utf8(fs::read(&entry).unwrap()).unwrap();
|
||||
let contain = String::from_utf8(fs::read(&entry).unwrap()).unwrap();
|
||||
let name = entry.file_stem().unwrap().to_str().unwrap();
|
||||
|
||||
let line = format!(
|
||||
@@ -47,7 +45,7 @@ fn main() {
|
||||
|
||||
libraries
|
||||
.write_all(
|
||||
b"ref_thread_local! {
|
||||
b"ref_thread_local::ref_thread_local! {
|
||||
pub static managed LIBRARIES: IndexMap<&'static str, &'static str> = {
|
||||
let mut m = IndexMap::new();\n",
|
||||
)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::temp_v;
|
||||
|
||||
use crate::fixtures::*;
|
||||
use crate::forms::*;
|
||||
@@ -14,8 +15,13 @@ pub trait Allocator<'a> {
|
||||
fn mark_anon_var<Target>(&mut self, _: Level, _: GenContext, _: &mut Vec<Target>)
|
||||
where
|
||||
Target: CompilationTarget<'a>;
|
||||
fn mark_non_var<Target>(&mut self, _: Level, _: GenContext, _: &'a Cell<RegType>, _: &mut Vec<Target>)
|
||||
where
|
||||
fn mark_non_var<Target>(
|
||||
&mut self,
|
||||
_: Level,
|
||||
_: GenContext,
|
||||
_: &'a Cell<RegType>,
|
||||
_: &mut Vec<Target>,
|
||||
) where
|
||||
Target: CompilationTarget<'a>;
|
||||
fn mark_reserved_var<Target>(
|
||||
&mut self,
|
||||
@@ -28,8 +34,14 @@ pub trait Allocator<'a> {
|
||||
_: bool,
|
||||
) where
|
||||
Target: CompilationTarget<'a>;
|
||||
fn mark_var<Target>(&mut self, _: Rc<Var>, _: Level, _: &'a Cell<VarReg>, _: GenContext, _: &mut Vec<Target>)
|
||||
where
|
||||
fn mark_var<Target>(
|
||||
&mut self,
|
||||
_: Rc<Var>,
|
||||
_: Level,
|
||||
_: &'a Cell<VarReg>,
|
||||
_: GenContext,
|
||||
_: &mut Vec<Target>,
|
||||
) where
|
||||
Target: CompilationTarget<'a>;
|
||||
|
||||
fn reset(&mut self);
|
||||
@@ -47,7 +59,7 @@ pub trait Allocator<'a> {
|
||||
fn drain_var_data(
|
||||
&mut self,
|
||||
vs: VariableFixtures<'a>,
|
||||
num_of_chunks: usize
|
||||
num_of_chunks: usize,
|
||||
) -> VariableFixtures<'a> {
|
||||
let mut perm_vs = VariableFixtures::new();
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::{atom, clause_name};
|
||||
|
||||
use crate::clause_types::*;
|
||||
use crate::fixtures::*;
|
||||
@@ -267,9 +268,7 @@ impl<'a> ArithmeticEvaluator<'a> {
|
||||
|
||||
fn push_constant(&mut self, c: &Constant) -> Result<(), ArithmeticError> {
|
||||
match c {
|
||||
&Constant::Fixnum(n) => self
|
||||
.interm
|
||||
.push(ArithmeticTerm::Number(Number::Fixnum(n))),
|
||||
&Constant::Fixnum(n) => self.interm.push(ArithmeticTerm::Number(Number::Fixnum(n))),
|
||||
&Constant::Integer(ref n) => self
|
||||
.interm
|
||||
.push(ArithmeticTerm::Number(Number::Integer(n.clone()))),
|
||||
@@ -326,17 +325,11 @@ impl<'a> ArithmeticEvaluator<'a> {
|
||||
// integer division rounding function -- 9.1.3.1.
|
||||
pub fn rnd_i<'a>(n: &'a Number) -> RefOrOwned<'a, Number> {
|
||||
match n {
|
||||
&Number::Integer(_) => {
|
||||
RefOrOwned::Borrowed(n)
|
||||
}
|
||||
&Number::Float(OrderedFloat(f)) => {
|
||||
RefOrOwned::Owned(Number::from(
|
||||
Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0))
|
||||
))
|
||||
}
|
||||
&Number::Fixnum(n) => {
|
||||
RefOrOwned::Owned(Number::from(n))
|
||||
}
|
||||
&Number::Integer(_) => RefOrOwned::Borrowed(n),
|
||||
&Number::Float(OrderedFloat(f)) => RefOrOwned::Owned(Number::from(
|
||||
Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0)),
|
||||
)),
|
||||
&Number::Fixnum(n) => RefOrOwned::Owned(Number::from(n)),
|
||||
&Number::Rational(ref r) => {
|
||||
let r_ref = r.fract_floor_ref();
|
||||
let (mut fract, mut floor) = (Rational::new(), Integer::new());
|
||||
@@ -432,31 +425,31 @@ impl Add<Number> for Number {
|
||||
Number::from(Integer::from(n1) + Integer::from(n2))
|
||||
})
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Integer(n2)) |
|
||||
(Number::Integer(n2), Number::Fixnum(n1)) => {
|
||||
(Number::Fixnum(n1), Number::Integer(n2))
|
||||
| (Number::Integer(n2), Number::Fixnum(n1)) => {
|
||||
Ok(Number::from(Integer::from(n1) + &*n2))
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Rational(n2)) |
|
||||
(Number::Rational(n2), Number::Fixnum(n1)) => {
|
||||
(Number::Fixnum(n1), Number::Rational(n2))
|
||||
| (Number::Rational(n2), Number::Fixnum(n1)) => {
|
||||
Ok(Number::from(Rational::from(n1) + &*n2))
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) |
|
||||
(Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
|
||||
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2)))
|
||||
| (Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
|
||||
Ok(Number::Float(add_f(float_fn_to_f(n1)?, n2)?))
|
||||
}
|
||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||
Ok(Number::from(Integer::from(&*n1) + &*n2)) // add_i
|
||||
}
|
||||
(Number::Integer(n1), Number::Float(OrderedFloat(n2)))
|
||||
| (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
|
||||
| (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
|
||||
Ok(Number::Float(add_f(float_i_to_f(&n1)?, n2)?))
|
||||
}
|
||||
(Number::Integer(n1), Number::Rational(n2))
|
||||
| (Number::Rational(n2), Number::Integer(n1)) => {
|
||||
| (Number::Rational(n2), Number::Integer(n1)) => {
|
||||
Ok(Number::from(Rational::from(&*n1) + &*n2))
|
||||
}
|
||||
(Number::Rational(n1), Number::Float(OrderedFloat(n2)))
|
||||
| (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => {
|
||||
| (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => {
|
||||
Ok(Number::Float(add_f(float_r_to_f(&n1)?, n2)?))
|
||||
}
|
||||
(Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => {
|
||||
@@ -474,12 +467,13 @@ impl Neg for Number {
|
||||
|
||||
fn neg(self) -> Self::Output {
|
||||
match self {
|
||||
Number::Fixnum(n) =>
|
||||
Number::Fixnum(n) => {
|
||||
if let Some(n) = n.checked_neg() {
|
||||
Number::Fixnum(n)
|
||||
} else {
|
||||
Number::from(-Integer::from(n))
|
||||
}
|
||||
}
|
||||
Number::Integer(n) => Number::Integer(Rc::new(-Integer::from(&*n))),
|
||||
Number::Float(OrderedFloat(f)) => Number::Float(OrderedFloat(-f)),
|
||||
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::Fixnum(n1), Number::Integer(n2)) |
|
||||
(Number::Integer(n2), Number::Fixnum(n1)) => {
|
||||
(Number::Fixnum(n1), Number::Integer(n2))
|
||||
| (Number::Integer(n2), Number::Fixnum(n1)) => {
|
||||
Ok(Number::from(Integer::from(n1) * &*n2))
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Rational(n2)) |
|
||||
(Number::Rational(n2), Number::Fixnum(n1)) => {
|
||||
(Number::Fixnum(n1), Number::Rational(n2))
|
||||
| (Number::Rational(n2), Number::Fixnum(n1)) => {
|
||||
Ok(Number::from(Rational::from(n1) * &*n2))
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) |
|
||||
(Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
|
||||
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2)))
|
||||
| (Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
|
||||
Ok(Number::Float(mul_f(float_fn_to_f(n1)?, n2)?))
|
||||
}
|
||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||
@@ -549,72 +543,50 @@ impl Div<Number> for Number {
|
||||
|
||||
fn div(self, rhs: Number) -> Self::Output {
|
||||
match (self, rhs) {
|
||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||
Ok(Number::Float(div_f(
|
||||
float_fn_to_f(n1)?,
|
||||
float_fn_to_f(n2)?,
|
||||
)?))
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||
Ok(Number::Float(div_f(
|
||||
float_fn_to_f(n1)?,
|
||||
float_i_to_f(&n2)?,
|
||||
)?))
|
||||
}
|
||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
||||
Ok(Number::Float(div_f(
|
||||
float_i_to_f(&n1)?,
|
||||
float_fn_to_f(n2)?,
|
||||
)?))
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Rational(n2)) => {
|
||||
Ok(Number::Float(div_f(
|
||||
float_fn_to_f(n1)?,
|
||||
float_r_to_f(&n2)?,
|
||||
)?))
|
||||
}
|
||||
(Number::Rational(n1), Number::Fixnum(n2)) => {
|
||||
Ok(Number::Float(div_f(
|
||||
float_r_to_f(&n1)?,
|
||||
float_fn_to_f(n2)?,
|
||||
)?))
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => Ok(Number::Float(div_f(
|
||||
float_fn_to_f(n1)?,
|
||||
float_fn_to_f(n2)?,
|
||||
)?)),
|
||||
(Number::Fixnum(n1), Number::Integer(n2)) => Ok(Number::Float(div_f(
|
||||
float_fn_to_f(n1)?,
|
||||
float_i_to_f(&n2)?,
|
||||
)?)),
|
||||
(Number::Integer(n1), Number::Fixnum(n2)) => Ok(Number::Float(div_f(
|
||||
float_i_to_f(&n1)?,
|
||||
float_fn_to_f(n2)?,
|
||||
)?)),
|
||||
(Number::Fixnum(n1), Number::Rational(n2)) => Ok(Number::Float(div_f(
|
||||
float_fn_to_f(n1)?,
|
||||
float_r_to_f(&n2)?,
|
||||
)?)),
|
||||
(Number::Rational(n1), Number::Fixnum(n2)) => Ok(Number::Float(div_f(
|
||||
float_r_to_f(&n1)?,
|
||||
float_fn_to_f(n2)?,
|
||||
)?)),
|
||||
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) => {
|
||||
Ok(Number::Float(div_f(
|
||||
float_fn_to_f(n1)?,
|
||||
n2,
|
||||
)?))
|
||||
Ok(Number::Float(div_f(float_fn_to_f(n1)?, n2)?))
|
||||
}
|
||||
(Number::Float(OrderedFloat(n1)), Number::Fixnum(n2)) => {
|
||||
Ok(Number::Float(div_f(
|
||||
n1,
|
||||
float_fn_to_f(n2)?,
|
||||
)?))
|
||||
}
|
||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||
Ok(Number::Float(div_f(
|
||||
float_i_to_f(&n1)?,
|
||||
float_i_to_f(&n2)?,
|
||||
)?))
|
||||
Ok(Number::Float(div_f(n1, float_fn_to_f(n2)?)?))
|
||||
}
|
||||
(Number::Integer(n1), Number::Integer(n2)) => Ok(Number::Float(div_f(
|
||||
float_i_to_f(&n1)?,
|
||||
float_i_to_f(&n2)?,
|
||||
)?)),
|
||||
(Number::Integer(n1), Number::Float(OrderedFloat(n2))) => {
|
||||
Ok(Number::Float(div_f(float_i_to_f(&n1)?, n2)?))
|
||||
}
|
||||
(Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
|
||||
Ok(Number::Float(div_f(n2, float_i_to_f(&n1)?)?))
|
||||
}
|
||||
(Number::Integer(n1), Number::Rational(n2)) => {
|
||||
Ok(Number::Float(div_f(
|
||||
float_i_to_f(&n1)?,
|
||||
float_r_to_f(&n2)?,
|
||||
)?))
|
||||
}
|
||||
(Number::Rational(n2), Number::Integer(n1)) => {
|
||||
Ok(Number::Float(div_f(
|
||||
float_r_to_f(&n2)?,
|
||||
float_i_to_f(&n1)?,
|
||||
)?))
|
||||
}
|
||||
(Number::Integer(n1), Number::Rational(n2)) => Ok(Number::Float(div_f(
|
||||
float_i_to_f(&n1)?,
|
||||
float_r_to_f(&n2)?,
|
||||
)?)),
|
||||
(Number::Rational(n2), Number::Integer(n1)) => Ok(Number::Float(div_f(
|
||||
float_r_to_f(&n2)?,
|
||||
float_i_to_f(&n1)?,
|
||||
)?)),
|
||||
(Number::Rational(n1), Number::Float(OrderedFloat(n2))) => {
|
||||
Ok(Number::Float(div_f(float_r_to_f(&n1)?, n2)?))
|
||||
}
|
||||
@@ -727,12 +699,8 @@ impl<'a> TryFrom<(Addr, &'a Heap)> for Number {
|
||||
|
||||
fn try_from((addr, heap): (Addr, &'a Heap)) -> Result<Number, Self::Error> {
|
||||
match addr {
|
||||
Addr::Fixnum(n) => {
|
||||
Ok(Number::from(n))
|
||||
}
|
||||
Addr::Float(n) => {
|
||||
Ok(Number::Float(n))
|
||||
}
|
||||
Addr::Fixnum(n) => Ok(Number::from(n)),
|
||||
Addr::Float(n) => Ok(Number::Float(n)),
|
||||
Addr::Usize(n) => {
|
||||
if let Ok(n) = isize::try_from(n) {
|
||||
Ok(Number::from(n))
|
||||
@@ -740,12 +708,8 @@ impl<'a> TryFrom<(Addr, &'a Heap)> for Number {
|
||||
Ok(Number::from(Integer::from(n)))
|
||||
}
|
||||
}
|
||||
Addr::Con(h) => {
|
||||
Number::try_from(&heap[h])
|
||||
}
|
||||
_ => {
|
||||
Err(())
|
||||
}
|
||||
Addr::Con(h) => Number::try_from(&heap[h]),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -755,35 +719,21 @@ impl<'a> TryFrom<&'a HeapCellValue> for Number {
|
||||
|
||||
fn try_from(value: &'a HeapCellValue) -> Result<Number, Self::Error> {
|
||||
match value {
|
||||
HeapCellValue::Addr(addr) => {
|
||||
match addr {
|
||||
&Addr::Fixnum(n) => {
|
||||
HeapCellValue::Addr(addr) => match addr {
|
||||
&Addr::Fixnum(n) => Ok(Number::from(n)),
|
||||
&Addr::Float(n) => Ok(Number::Float(n)),
|
||||
&Addr::Usize(n) => {
|
||||
if let Ok(n) = isize::try_from(n) {
|
||||
Ok(Number::from(n))
|
||||
}
|
||||
&Addr::Float(n) => {
|
||||
Ok(Number::Float(n))
|
||||
}
|
||||
&Addr::Usize(n) => {
|
||||
if let Ok(n) = isize::try_from(n) {
|
||||
Ok(Number::from(n))
|
||||
} else {
|
||||
Ok(Number::from(Integer::from(n)))
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
Err(())
|
||||
} else {
|
||||
Ok(Number::from(Integer::from(n)))
|
||||
}
|
||||
}
|
||||
}
|
||||
HeapCellValue::Integer(n) => {
|
||||
Ok(Number::Integer(n.clone()))
|
||||
}
|
||||
HeapCellValue::Rational(n) => {
|
||||
Ok(Number::Rational(n.clone()))
|
||||
}
|
||||
_ => {
|
||||
Err(())
|
||||
}
|
||||
_ => 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::{clause_name, temp_v};
|
||||
|
||||
use crate::forms::Number;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::rug::rand::RandState;
|
||||
|
||||
use crate::ref_thread_local::RefThreadLocal;
|
||||
use crate::ref_thread_local::{ref_thread_local, RefThreadLocal};
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
@@ -322,7 +323,9 @@ impl SystemClauseType {
|
||||
&SystemClauseType::ClearAttributeGoals => clause_name!("$clear_attribute_goals"),
|
||||
&SystemClauseType::CloneAttributeGoals => clause_name!("$clone_attribute_goals"),
|
||||
&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::CurrentInput => clause_name!("$current_input"),
|
||||
&SystemClauseType::CurrentHostname => clause_name!("$current_hostname"),
|
||||
@@ -337,58 +340,70 @@ impl SystemClauseType {
|
||||
&SystemClauseType::WorkingDirectory => clause_name!("$working_directory"),
|
||||
&SystemClauseType::PathCanonical => clause_name!("$path_canonical"),
|
||||
&SystemClauseType::FileTime => clause_name!("$file_time"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate) =>
|
||||
clause_name!("$add_dynamic_predicate"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause) =>
|
||||
clause_name!("$add_goal_expansion_clause"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause) =>
|
||||
clause_name!("$add_term_expansion_clause"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable) =>
|
||||
clause_name!("$clause_to_evacuable"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::ConcludeLoad) =>
|
||||
clause_name!("$conclude_load"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::DeclareModule) =>
|
||||
clause_name!("$declare_module"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary) =>
|
||||
clause_name!("$load_compiled_library"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload) =>
|
||||
clause_name!("$push_load_state_payload"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::Asserta) =>
|
||||
clause_name!("$asserta"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::Assertz) =>
|
||||
clause_name!("$assertz"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::Retract) =>
|
||||
clause_name!("$retract_clause"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::UseModule) =>
|
||||
clause_name!("$use_module"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::PushLoadContext) =>
|
||||
clause_name!("$push_load_context"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::PopLoadContext) =>
|
||||
clause_name!("$pop_load_context"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload) =>
|
||||
clause_name!("$pop_load_state_payload"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextSource) =>
|
||||
clause_name!("$prolog_lc_source"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextFile) =>
|
||||
clause_name!("$prolog_lc_file"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory) =>
|
||||
clause_name!("$prolog_lc_dir"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextModule) =>
|
||||
clause_name!("$prolog_lc_module"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextStream) =>
|
||||
clause_name!("$prolog_lc_stream"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty) =>
|
||||
clause_name!("$cpp_meta_predicate_property"),
|
||||
&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::REPL(REPLCodePtr::AddDynamicPredicate) => {
|
||||
clause_name!("$add_dynamic_predicate")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause) => {
|
||||
clause_name!("$add_goal_expansion_clause")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause) => {
|
||||
clause_name!("$add_term_expansion_clause")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable) => {
|
||||
clause_name!("$clause_to_evacuable")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::ConcludeLoad) => clause_name!("$conclude_load"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::DeclareModule) => clause_name!("$declare_module"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary) => {
|
||||
clause_name!("$load_compiled_library")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload) => {
|
||||
clause_name!("$push_load_state_payload")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::Asserta) => clause_name!("$asserta"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::Assertz) => clause_name!("$assertz"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::Retract) => clause_name!("$retract_clause"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::PushLoadContext) => {
|
||||
clause_name!("$push_load_context")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::PopLoadContext) => {
|
||||
clause_name!("$pop_load_context")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload) => {
|
||||
clause_name!("$pop_load_state_payload")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextSource) => {
|
||||
clause_name!("$prolog_lc_source")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextFile) => {
|
||||
clause_name!("$prolog_lc_file")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory) => {
|
||||
clause_name!("$prolog_lc_dir")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextModule) => {
|
||||
clause_name!("$prolog_lc_module")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextStream) => {
|
||||
clause_name!("$prolog_lc_stream")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty) => {
|
||||
clause_name!("$cpp_meta_predicate_property")
|
||||
}
|
||||
&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::CopyToLiftedHeap => clause_name!("$copy_to_lh"),
|
||||
&SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"),
|
||||
@@ -397,8 +412,9 @@ impl SystemClauseType {
|
||||
&SystemClauseType::EnqueueAttributeGoal => clause_name!("$enqueue_attribute_goal"),
|
||||
&SystemClauseType::EnqueueAttributedVar => clause_name!("$enqueue_attr_var"),
|
||||
&SystemClauseType::FetchGlobalVar => clause_name!("$fetch_global_var"),
|
||||
&SystemClauseType::FetchGlobalVarWithOffset =>
|
||||
clause_name!("$fetch_global_var_with_offset"),
|
||||
&SystemClauseType::FetchGlobalVarWithOffset => {
|
||||
clause_name!("$fetch_global_var_with_offset")
|
||||
}
|
||||
&SystemClauseType::FirstStream => clause_name!("$first_stream"),
|
||||
&SystemClauseType::FlushOutput => clause_name!("$flush_output"),
|
||||
&SystemClauseType::GetByte => clause_name!("$get_byte"),
|
||||
@@ -424,13 +440,13 @@ impl SystemClauseType {
|
||||
clause_name!("$get_lh_from_offset_diff")
|
||||
}
|
||||
&SystemClauseType::GetBValue => clause_name!("$get_b_value"),
|
||||
// &SystemClauseType::GetClause => clause_name!("$get_clause"),
|
||||
// &SystemClauseType::GetClause => clause_name!("$get_clause"),
|
||||
&SystemClauseType::GetNextDBRef => clause_name!("$get_next_db_ref"),
|
||||
&SystemClauseType::GetNextOpDBRef => clause_name!("$get_next_op_db_ref"),
|
||||
&SystemClauseType::LookupDBRef => clause_name!("$lookup_db_ref"),
|
||||
&SystemClauseType::LookupOpDBRef => clause_name!("$lookup_op_db_ref"),
|
||||
&SystemClauseType::GetDoubleQuotes => clause_name!("$get_double_quotes"),
|
||||
// &SystemClauseType::GetModuleClause => clause_name!("$get_module_clause"),
|
||||
// &SystemClauseType::GetModuleClause => clause_name!("$get_module_clause"),
|
||||
&SystemClauseType::GetSCCCleaner => clause_name!("$get_scc_cleaner"),
|
||||
&SystemClauseType::Halt => clause_name!("$halt"),
|
||||
&SystemClauseType::HeadIsDynamic => clause_name!("$head_is_dynamic"),
|
||||
@@ -455,7 +471,7 @@ impl SystemClauseType {
|
||||
// &SystemClauseType::ModuleAssertDynamicPredicateToBack => {
|
||||
// clause_name!("$module_assertz")
|
||||
// }
|
||||
// &SystemClauseType::ModuleHeadIsDynamic => clause_name!("$module_head_is_dynamic"),
|
||||
// &SystemClauseType::ModuleHeadIsDynamic => clause_name!("$module_head_is_dynamic"),
|
||||
&SystemClauseType::ModuleExists => clause_name!("$module_exists"),
|
||||
&SystemClauseType::NextStream => clause_name!("$next_stream"),
|
||||
&SystemClauseType::NoSuchPredicate => clause_name!("$no_such_predicate"),
|
||||
@@ -507,7 +523,9 @@ impl SystemClauseType {
|
||||
&SystemClauseType::ReadTerm => clause_name!("$read_term"),
|
||||
&SystemClauseType::ReadTermFromChars => clause_name!("$read_term_from_chars"),
|
||||
&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::ResetContinuationMarker => clause_name!("$reset_cont_marker"),
|
||||
&SystemClauseType::ReturnFromVerifyAttr => clause_name!("$return_from_verify_attr"),
|
||||
@@ -521,7 +539,9 @@ impl SystemClauseType {
|
||||
&SystemClauseType::SocketServerAccept => clause_name!("$socket_server_accept"),
|
||||
&SystemClauseType::SocketServerClose => clause_name!("$socket_server_close"),
|
||||
&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::TruncateLiftedHeapTo => clause_name!("$truncate_lh_to"),
|
||||
&SystemClauseType::UnifyWithOccursCheck => clause_name!("$unify_with_occurs_check"),
|
||||
@@ -542,7 +562,9 @@ impl SystemClauseType {
|
||||
&SystemClauseType::Ed25519Sign => clause_name!("$ed25519_sign"),
|
||||
&SystemClauseType::Ed25519Verify => clause_name!("$ed25519_verify"),
|
||||
&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::LoadHTML => clause_name!("$load_html"),
|
||||
&SystemClauseType::LoadXML => clause_name!("$load_xml"),
|
||||
@@ -556,14 +578,16 @@ impl SystemClauseType {
|
||||
|
||||
pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
|
||||
match (name, arity) {
|
||||
("$abolish_clause", 3) =>
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::AbolishClause)),
|
||||
("$add_dynamic_predicate", 3) =>
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate)),
|
||||
("$add_goal_expansion_clause", 4) =>
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause)),
|
||||
("$add_term_expansion_clause", 3) =>
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause)),
|
||||
("$abolish_clause", 3) => Some(SystemClauseType::REPL(REPLCodePtr::AbolishClause)),
|
||||
("$add_dynamic_predicate", 3) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate))
|
||||
}
|
||||
("$add_goal_expansion_clause", 4) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause))
|
||||
}
|
||||
("$add_term_expansion_clause", 3) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause))
|
||||
}
|
||||
("$atom_chars", 2) => Some(SystemClauseType::AtomChars),
|
||||
("$atom_codes", 2) => Some(SystemClauseType::AtomCodes),
|
||||
("$atom_length", 2) => Some(SystemClauseType::AtomLength),
|
||||
@@ -602,7 +626,9 @@ impl SystemClauseType {
|
||||
("$peek_code", 2) => Some(SystemClauseType::PeekCode),
|
||||
("$is_partial_string", 1) => Some(SystemClauseType::IsPartialString),
|
||||
("$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_char", 2) => Some(SystemClauseType::GetChar),
|
||||
("$get_n_chars", 3) => Some(SystemClauseType::GetNChars),
|
||||
@@ -611,18 +637,10 @@ impl SystemClauseType {
|
||||
("$points_to_cont_reset_marker", 1) => {
|
||||
Some(SystemClauseType::PointsToContinuationResetMarker)
|
||||
}
|
||||
("$put_byte", 2) => {
|
||||
Some(SystemClauseType::PutByte)
|
||||
}
|
||||
("$put_char", 2) => {
|
||||
Some(SystemClauseType::PutChar)
|
||||
}
|
||||
("$put_chars", 2) => {
|
||||
Some(SystemClauseType::PutChars)
|
||||
}
|
||||
("$put_code", 2) => {
|
||||
Some(SystemClauseType::PutCode)
|
||||
}
|
||||
("$put_byte", 2) => Some(SystemClauseType::PutByte),
|
||||
("$put_char", 2) => Some(SystemClauseType::PutChar),
|
||||
("$put_chars", 2) => Some(SystemClauseType::PutChars),
|
||||
("$put_code", 2) => Some(SystemClauseType::PutCode),
|
||||
("$reset_attr_var_state", 0) => Some(SystemClauseType::ResetAttrVarState),
|
||||
("$truncate_if_no_lh_growth", 1) => {
|
||||
Some(SystemClauseType::TruncateIfNoLiftedHeapGrowth)
|
||||
@@ -691,7 +709,9 @@ impl SystemClauseType {
|
||||
("$socket_server_accept", 7) => Some(SystemClauseType::SocketServerAccept),
|
||||
("$socket_server_close", 1) => Some(SystemClauseType::SocketServerClose),
|
||||
("$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_variables", 2) => Some(SystemClauseType::TermVariables),
|
||||
("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
|
||||
@@ -708,12 +728,18 @@ impl SystemClauseType {
|
||||
("$working_directory", 2) => Some(SystemClauseType::WorkingDirectory),
|
||||
("$path_canonical", 2) => Some(SystemClauseType::PathCanonical),
|
||||
("$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)),
|
||||
("$use_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)),
|
||||
("$declare_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DeclareModule)),
|
||||
("$load_compiled_library", 2) => Some(SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary)),
|
||||
("$push_load_state_payload", 1) => Some(SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload)),
|
||||
("$load_compiled_library", 2) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary))
|
||||
}
|
||||
("$push_load_state_payload", 1) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload))
|
||||
}
|
||||
("$asserta", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Asserta)),
|
||||
("$assertz", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Assertz)),
|
||||
("$retract_clause", 4) => Some(SystemClauseType::REPL(REPLCodePtr::Retract)),
|
||||
@@ -742,18 +768,38 @@ impl SystemClauseType {
|
||||
("$chars_base64", 4) => Some(SystemClauseType::CharsBase64),
|
||||
("$load_library_as_stream", 3) => Some(SystemClauseType::LoadLibraryAsStream),
|
||||
("$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)),
|
||||
("$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_dir", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory)),
|
||||
("$prolog_lc_module", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextModule)),
|
||||
("$prolog_lc_stream", 1) => 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)),
|
||||
("$prolog_lc_dir", 1) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory))
|
||||
}
|
||||
("$prolog_lc_module", 1) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::LoadContextModule))
|
||||
}
|
||||
("$prolog_lc_stream", 1) => {
|
||||
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,
|
||||
}
|
||||
}
|
||||
@@ -832,10 +878,10 @@ impl ClauseType {
|
||||
match self {
|
||||
&ClauseType::Op(_, ref spec, _) => Some(spec.clone()),
|
||||
&ClauseType::Inlined(InlinedClauseType::CompareNumber(..))
|
||||
| &ClauseType::BuiltIn(BuiltInClauseType::Is(..))
|
||||
| &ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(_))
|
||||
| &ClauseType::BuiltIn(BuiltInClauseType::NotEq)
|
||||
| &ClauseType::BuiltIn(BuiltInClauseType::Eq) => Some(SharedOpDesc::new(700, XFX)),
|
||||
| &ClauseType::BuiltIn(BuiltInClauseType::Is(..))
|
||||
| &ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(_))
|
||||
| &ClauseType::BuiltIn(BuiltInClauseType::NotEq)
|
||||
| &ClauseType::BuiltIn(BuiltInClauseType::Eq) => Some(SharedOpDesc::new(700, XFX)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
189
src/codegen.rs
189
src/codegen.rs
@@ -1,6 +1,7 @@
|
||||
/// Code generation to WAM-like instructions.
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::tabled_rc::TabledData;
|
||||
use crate::prolog_parser_rebis::{perm_v, temp_v};
|
||||
|
||||
use crate::allocator::*;
|
||||
use crate::arithmetic::*;
|
||||
@@ -66,18 +67,14 @@ impl<'a> ConjunctInfo<'a> {
|
||||
self.has_deep_cut as usize
|
||||
}
|
||||
|
||||
fn mark_unsafe_vars(
|
||||
&self,
|
||||
mut unsafe_var_marker: UnsafeVarMarker,
|
||||
code: &mut Code,
|
||||
) {
|
||||
fn mark_unsafe_vars(&self, mut unsafe_var_marker: UnsafeVarMarker, code: &mut Code) {
|
||||
if code.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut code_index = 0;
|
||||
|
||||
for phase in 0 .. {
|
||||
for phase in 0.. {
|
||||
while let Line::Query(ref query_instr) = &code[code_index] {
|
||||
if !unsafe_var_marker.mark_safe_vars(query_instr) {
|
||||
unsafe_var_marker.mark_phase(query_instr, phase);
|
||||
@@ -95,7 +92,7 @@ impl<'a> ConjunctInfo<'a> {
|
||||
|
||||
code_index = 0;
|
||||
|
||||
for phase in 0 .. {
|
||||
for phase in 0.. {
|
||||
while let Line::Query(ref mut query_instr) = &mut code[code_index] {
|
||||
unsafe_var_marker.mark_unsafe_vars(query_instr, phase);
|
||||
code_index += 1;
|
||||
@@ -173,7 +170,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
code: &mut Code,
|
||||
) -> RegType {
|
||||
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() {
|
||||
code.extend(target.into_iter().map(Line::Query));
|
||||
@@ -191,9 +189,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
code: &mut Code,
|
||||
) -> RegType {
|
||||
match self.marker.bindings().get(&name) {
|
||||
Some(&VarData::Temp(_, t, _)) if t != 0 => {
|
||||
RegType::Temp(t)
|
||||
}
|
||||
Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t),
|
||||
Some(&VarData::Perm(p)) if p != 0 => {
|
||||
if let GenContext::Last(_) = term_loc {
|
||||
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)
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
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>,
|
||||
) {
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
&Term::Cons(ref cell, _, _) | &Term::Clause(ref cell, _, _, _) => {
|
||||
self.marker.mark_non_var(Level::Deep, term_loc, cell, target);
|
||||
self.marker
|
||||
.mark_non_var(Level::Deep, term_loc, cell, target);
|
||||
target.push(Target::clause_arg_to_instr(cell.get()));
|
||||
}
|
||||
&Term::Constant(_, ref constant) => {
|
||||
@@ -264,7 +260,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
};
|
||||
}
|
||||
|
||||
fn compile_target<Target, Iter>(
|
||||
fn compile_target<Target, Iter>(
|
||||
&mut self,
|
||||
iter: Iter,
|
||||
term_loc: GenContext,
|
||||
@@ -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) => {
|
||||
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() {
|
||||
for (i, chunked_term) in chunked_terms.iter().enumerate() {
|
||||
let term_loc = match chunked_term {
|
||||
&ChunkedTerm::HeadClause(..) =>
|
||||
GenContext::Head,
|
||||
&ChunkedTerm::HeadClause(..) => GenContext::Head,
|
||||
&ChunkedTerm::BodyTerm(_) => {
|
||||
if i < chunked_terms.len() - 1 {
|
||||
GenContext::Mid(chunk_num)
|
||||
@@ -391,8 +387,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
&QueryTerm::Clause(_, ref ct, ref terms, false) => {
|
||||
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) => {
|
||||
*last_call = true;
|
||||
}
|
||||
&mut ControlInstruction::Proceed => {
|
||||
}
|
||||
&mut ControlInstruction::Proceed => {}
|
||||
_ => {
|
||||
dealloc_index += 1;
|
||||
}
|
||||
@@ -416,8 +410,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
Some(&mut Line::Cut(CutInstruction::Cut(_))) => {
|
||||
dealloc_index += 1;
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
dealloc_index
|
||||
@@ -437,23 +430,17 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
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 at_1 =
|
||||
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)
|
||||
)
|
||||
} else {
|
||||
at_1.unwrap_or(interm!(1))
|
||||
};
|
||||
let at_1 = 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))
|
||||
} else {
|
||||
at_1.unwrap_or(interm!(1))
|
||||
};
|
||||
|
||||
let at_2 =
|
||||
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)
|
||||
)
|
||||
} else {
|
||||
at_2.unwrap_or(interm!(2))
|
||||
};
|
||||
let at_2 = 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))
|
||||
} else {
|
||||
at_2.unwrap_or(interm!(2))
|
||||
};
|
||||
|
||||
code.append(&mut lcode);
|
||||
code.append(&mut rcode);
|
||||
@@ -461,9 +448,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
code.push(compare_number_instr!(cmp, at_1, at_2));
|
||||
}
|
||||
&InlinedClauseType::IsAtom(..) => match terms[0].as_ref() {
|
||||
&Term::Constant(_, Constant::Char(_)) |
|
||||
&Term::Constant(_, Constant::EmptyList) |
|
||||
&Term::Constant(_, Constant::Atom(..)) => {
|
||||
&Term::Constant(_, Constant::Char(_))
|
||||
| &Term::Constant(_, Constant::EmptyList)
|
||||
| &Term::Constant(_, Constant::Atom(..)) => {
|
||||
code.push(succeed!());
|
||||
}
|
||||
&Term::Var(ref vr, ref name) => {
|
||||
@@ -528,11 +515,11 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
}
|
||||
},
|
||||
&InlinedClauseType::IsNumber(..) => match terms[0].as_ref() {
|
||||
&Term::Constant(_, Constant::Float(_)) |
|
||||
&Term::Constant(_, Constant::Rational(_)) |
|
||||
&Term::Constant(_, Constant::Integer(_)) |
|
||||
&Term::Constant(_, Constant::Fixnum(_)) |
|
||||
&Term::Constant(_, Constant::Usize(_)) => {
|
||||
&Term::Constant(_, Constant::Float(_))
|
||||
| &Term::Constant(_, Constant::Rational(_))
|
||||
| &Term::Constant(_, Constant::Integer(_))
|
||||
| &Term::Constant(_, Constant::Fixnum(_))
|
||||
| &Term::Constant(_, Constant::Usize(_)) => {
|
||||
code.push(succeed!());
|
||||
}
|
||||
&Term::Var(ref vr, ref name) => {
|
||||
@@ -558,9 +545,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
}
|
||||
},
|
||||
&InlinedClauseType::IsInteger(..) => match terms[0].as_ref() {
|
||||
&Term::Constant(_, Constant::Integer(_)) |
|
||||
&Term::Constant(_, Constant::Fixnum(_)) |
|
||||
&Term::Constant(_, Constant::Usize(_)) => {
|
||||
&Term::Constant(_, Constant::Integer(_))
|
||||
| &Term::Constant(_, Constant::Fixnum(_))
|
||||
| &Term::Constant(_, Constant::Usize(_)) => {
|
||||
code.push(succeed!());
|
||||
}
|
||||
&Term::Var(ref vr, ref name) => {
|
||||
@@ -615,14 +602,15 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
&Term::Var(ref vr, ref name) => {
|
||||
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() {
|
||||
code.extend(target.into_iter().map(Line::Query));
|
||||
}
|
||||
}
|
||||
&Term::Constant(_, ref c @ Constant::Integer(_)) |
|
||||
&Term::Constant(_, ref c @ Constant::Fixnum(_)) => {
|
||||
&Term::Constant(_, ref c @ Constant::Integer(_))
|
||||
| &Term::Constant(_, ref c @ Constant::Fixnum(_)) => {
|
||||
code.push(Line::Query(put_constant!(
|
||||
Level::Shallow,
|
||||
c.clone(),
|
||||
@@ -655,14 +643,11 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
}
|
||||
}
|
||||
|
||||
let at =
|
||||
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)
|
||||
)
|
||||
} else {
|
||||
at.unwrap_or(interm!(1))
|
||||
};
|
||||
let at = 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))
|
||||
} else {
|
||||
at.unwrap_or(interm!(1))
|
||||
};
|
||||
|
||||
Ok(if use_default_call_policy {
|
||||
code.push(is_call_by_default!(temp_v!(1), at));
|
||||
@@ -721,24 +706,18 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
&QueryTerm::GetLevelAndUnify(ref cell, ref var) => {
|
||||
self.compile_get_level_and_unify(code, cell, var.clone(), term_loc)
|
||||
}
|
||||
&QueryTerm::UnblockedCut(ref cell) => {
|
||||
self.compile_unblocked_cut(code, cell)
|
||||
}
|
||||
&QueryTerm::BlockedCut => {
|
||||
code.push(if chunk_num == 0 {
|
||||
Line::Cut(CutInstruction::NeckCut)
|
||||
} else {
|
||||
Line::Cut(CutInstruction::Cut(perm_v!(1)))
|
||||
})
|
||||
}
|
||||
&QueryTerm::UnblockedCut(ref cell) => self.compile_unblocked_cut(code, cell),
|
||||
&QueryTerm::BlockedCut => code.push(if chunk_num == 0 {
|
||||
Line::Cut(CutInstruction::NeckCut)
|
||||
} else {
|
||||
Line::Cut(CutInstruction::Cut(perm_v!(1)))
|
||||
}),
|
||||
&QueryTerm::Clause(
|
||||
_,
|
||||
ClauseType::BuiltIn(BuiltInClauseType::Is(..)),
|
||||
ref terms,
|
||||
use_default_call_policy,
|
||||
) => {
|
||||
self.compile_is_call(terms, code, term_loc, use_default_call_policy)?
|
||||
}
|
||||
) => self.compile_is_call(terms, code, term_loc, use_default_call_policy)?,
|
||||
&QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) => {
|
||||
self.compile_inlined(ct, terms, term_loc, code)?
|
||||
}
|
||||
@@ -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.
|
||||
match toc {
|
||||
&QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => code.push(proceed!()),
|
||||
@@ -786,7 +770,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
if conjunct_info.allocates() {
|
||||
let offset = self.global_jmp_by_locs_offset;
|
||||
|
||||
if let Some(jmp_by_offset) = self.jmp_by_locs[offset ..].last_mut() {
|
||||
if let Some(jmp_by_offset) = self.jmp_by_locs[offset..].last_mut() {
|
||||
if *jmp_by_offset == dealloc_index {
|
||||
*jmp_by_offset += 1;
|
||||
}
|
||||
@@ -905,32 +889,32 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
self.add_conditional_call(code, term, num_perm_vars_left);
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn compile_query(&mut self, query: &'a Vec<QueryTerm>) -> Result<Code, CompilationError> {
|
||||
let iter = ChunkedIterator::from_term_sequence(query);
|
||||
let conjunct_info = self.collect_var_data(iter);
|
||||
/*
|
||||
pub fn compile_query(&mut self, query: &'a Vec<QueryTerm>) -> Result<Code, CompilationError> {
|
||||
let iter = ChunkedIterator::from_term_sequence(query);
|
||||
let conjunct_info = self.collect_var_data(iter);
|
||||
|
||||
let mut code = Vec::new();
|
||||
self.compile_seq_prelude(&conjunct_info, &mut code);
|
||||
let mut code = Vec::new();
|
||||
self.compile_seq_prelude(&conjunct_info, &mut code);
|
||||
|
||||
let iter = ChunkedIterator::from_term_sequence(query);
|
||||
self.compile_seq(iter, &conjunct_info, &mut code, true)?;
|
||||
let iter = ChunkedIterator::from_term_sequence(query);
|
||||
self.compile_seq(iter, &conjunct_info, &mut code, true)?;
|
||||
|
||||
conjunct_info.mark_unsafe_vars(UnsafeVarMarker::new(), &mut code);
|
||||
conjunct_info.mark_unsafe_vars(UnsafeVarMarker::new(), &mut code);
|
||||
|
||||
if let Some(query_term) = query.last() {
|
||||
Self::compile_cleanup(&mut code, &conjunct_info, query_term);
|
||||
if let Some(query_term) = query.last() {
|
||||
Self::compile_cleanup(&mut code, &conjunct_info, query_term);
|
||||
}
|
||||
|
||||
Ok(code)
|
||||
}
|
||||
|
||||
Ok(code)
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
||||
#[inline]
|
||||
fn increment_jmp_by_locs_by(&mut self, incr: usize) {
|
||||
let offset = self.global_jmp_by_locs_offset;
|
||||
|
||||
for loc in &mut self.jmp_by_locs[offset ..] {
|
||||
for loc in &mut self.jmp_by_locs[offset..] {
|
||||
*loc += incr;
|
||||
}
|
||||
}
|
||||
@@ -1077,7 +1061,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
|
||||
if skip_stub_try_me_else {
|
||||
// skip the TryMeElse(0) also.
|
||||
self.increment_jmp_by_locs_by(2);
|
||||
self.increment_jmp_by_locs_by(2);
|
||||
} else {
|
||||
self.increment_jmp_by_locs_by(1);
|
||||
}
|
||||
@@ -1105,7 +1089,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
|
||||
for (l, r) in split_pred {
|
||||
let skel_lower_bound = self.skeleton.clauses.len();
|
||||
let code_segment = self.compile_pred_subseq(&clauses[l .. r], optimal_index)?;
|
||||
let code_segment = self.compile_pred_subseq(&clauses[l..r], optimal_index)?;
|
||||
let clause_start_offset = code.len();
|
||||
|
||||
if multi_seq {
|
||||
@@ -1123,11 +1107,10 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
if self.is_extensible {
|
||||
let segment_is_indexed = to_indexing_line(&code_segment[0]).is_some();
|
||||
|
||||
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_start_offset + 2 * (segment_is_indexed as usize);
|
||||
clause_index_info.opt_arg_index_key +=
|
||||
clause_start_offset + 1;
|
||||
clause_index_info.opt_arg_index_key += clause_start_offset + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::indexmap::IndexMap;
|
||||
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::temp_v;
|
||||
|
||||
use crate::allocator::*;
|
||||
use crate::fixtures::*;
|
||||
@@ -293,9 +294,7 @@ impl<'a> Allocator<'a> for DebrayAllocator {
|
||||
|
||||
(pr, true)
|
||||
}
|
||||
r => {
|
||||
(r, false)
|
||||
}
|
||||
r => (r, false),
|
||||
};
|
||||
|
||||
self.mark_reserved_var(var, lvl, cell, term_loc, target, r, is_new_var);
|
||||
|
||||
144
src/forms.rs
144
src/forms.rs
@@ -1,5 +1,6 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::parser::OpDesc;
|
||||
use crate::prolog_parser_rebis::{clause_name, is_infix, is_postfix};
|
||||
|
||||
use crate::clause_types::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
@@ -36,7 +37,7 @@ pub enum TopLevel {
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum AppendOrPrepend {
|
||||
Append,
|
||||
Prepend
|
||||
Prepend,
|
||||
}
|
||||
|
||||
impl AppendOrPrepend {
|
||||
@@ -115,12 +116,8 @@ impl ListingSource {
|
||||
pub trait ClauseInfo {
|
||||
fn is_consistent(&self, clauses: &Vec<PredicateClause>) -> bool {
|
||||
match clauses.first() {
|
||||
Some(cl) => {
|
||||
self.name() == cl.name() && self.arity() == cl.arity()
|
||||
}
|
||||
None => {
|
||||
true
|
||||
}
|
||||
Some(cl) => self.name() == cl.name() && self.arity() == cl.arity(),
|
||||
None => true,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,38 +137,25 @@ impl ClauseInfo for Term {
|
||||
_ => Some(clause_name!(":-")),
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
Some(name.clone())
|
||||
}
|
||||
_ => Some(name.clone()),
|
||||
}
|
||||
}
|
||||
Term::Constant(_, Constant::Atom(ref name, _)) => {
|
||||
Some(name.clone())
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
Term::Constant(_, Constant::Atom(ref name, _)) => Some(name.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn arity(&self) -> usize {
|
||||
match self {
|
||||
Term::Clause(_, ref name, ref terms, _) =>
|
||||
match name.as_str() {
|
||||
":-" => {
|
||||
match terms.len() {
|
||||
1 => 0,
|
||||
2 => terms[0].arity(),
|
||||
_ => terms.len(),
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
terms.len()
|
||||
}
|
||||
Term::Clause(_, ref name, ref terms, _) => match name.as_str() {
|
||||
":-" => match terms.len() {
|
||||
1 => 0,
|
||||
2 => terms[0].arity(),
|
||||
_ => terms.len(),
|
||||
},
|
||||
_ => {
|
||||
0
|
||||
}
|
||||
_ => terms.len(),
|
||||
},
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,23 +173,15 @@ impl ClauseInfo for Rule {
|
||||
impl ClauseInfo for PredicateClause {
|
||||
fn name(&self) -> Option<ClauseName> {
|
||||
match self {
|
||||
&PredicateClause::Fact(ref term, ..) => {
|
||||
term.name()
|
||||
}
|
||||
&PredicateClause::Rule(ref rule, ..) => {
|
||||
rule.name()
|
||||
}
|
||||
&PredicateClause::Fact(ref term, ..) => term.name(),
|
||||
&PredicateClause::Rule(ref rule, ..) => rule.name(),
|
||||
}
|
||||
}
|
||||
|
||||
fn arity(&self) -> usize {
|
||||
match self {
|
||||
&PredicateClause::Fact(ref term, ..) => {
|
||||
term.arity()
|
||||
}
|
||||
&PredicateClause::Rule(ref rule, ..) => {
|
||||
rule.arity()
|
||||
}
|
||||
&PredicateClause::Fact(ref term, ..) => term.arity(),
|
||||
&PredicateClause::Rule(ref rule, ..) => rule.arity(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -222,11 +198,9 @@ impl PredicateClause {
|
||||
// TODO: add this to `Term` in `prolog_parser` like `first_arg`.
|
||||
pub fn args(&self) -> Option<&[Box<Term>]> {
|
||||
match *self {
|
||||
PredicateClause::Fact(ref term, ..) => {
|
||||
match term {
|
||||
Term::Clause(_, _, args, _) => Some(&args),
|
||||
_ => None,
|
||||
}
|
||||
PredicateClause::Fact(ref term, ..) => match term {
|
||||
Term::Clause(_, _, args, _) => Some(&args),
|
||||
_ => None,
|
||||
},
|
||||
PredicateClause::Rule(ref rule, ..) => {
|
||||
if rule.head.1.is_empty() {
|
||||
@@ -240,14 +214,11 @@ impl PredicateClause {
|
||||
|
||||
pub fn arity(&self) -> usize {
|
||||
match self {
|
||||
&PredicateClause::Fact(ref term, ..) => {
|
||||
term.arity()
|
||||
}
|
||||
&PredicateClause::Fact(ref term, ..) => term.arity(),
|
||||
&PredicateClause::Rule(ref rule, ..) => {
|
||||
if rule.head.0.as_str() == ":" && rule.head.1.len() == 2 {
|
||||
match (rule.head.1)[0].as_ref() {
|
||||
&Term::Constant(_, Constant::Atom(..)) => {
|
||||
}
|
||||
&Term::Constant(_, Constant::Atom(..)) => {}
|
||||
_ => {
|
||||
return 2;
|
||||
}
|
||||
@@ -321,7 +292,7 @@ pub enum Declaration {
|
||||
pub struct OpDecl {
|
||||
pub prec: usize,
|
||||
pub spec: Specifier,
|
||||
pub name: ClauseName
|
||||
pub name: ClauseName,
|
||||
}
|
||||
|
||||
impl OpDecl {
|
||||
@@ -345,7 +316,7 @@ impl OpDecl {
|
||||
XFY | XFX | YFX => Fixity::In,
|
||||
XF | YF => Fixity::Post,
|
||||
FX | FY => Fixity::Pre,
|
||||
_ => unreachable!()
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,12 +327,12 @@ impl OpDecl {
|
||||
Some(cell) => {
|
||||
return Some(cell.shared_op_desc().replace((self.prec, self.spec)));
|
||||
}
|
||||
None => {
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
op_dir.insert(key, OpDirValue::new(self.spec, self.prec))
|
||||
.map(|op_dir_value| op_dir_value.shared_op_desc().get())
|
||||
op_dir
|
||||
.insert(key, OpDirValue::new(self.spec, self.prec))
|
||||
.map(|op_dir_value| op_dir_value.shared_op_desc().get())
|
||||
}
|
||||
|
||||
pub fn submit(
|
||||
@@ -419,11 +390,7 @@ pub fn fetch_op_spec_from_existing(
|
||||
spec.or_else(|| fetch_op_spec(name, arity, op_dir))
|
||||
}
|
||||
|
||||
pub fn fetch_op_spec(
|
||||
name: ClauseName,
|
||||
arity: usize,
|
||||
op_dir: &OpDir,
|
||||
) -> Option<SharedOpDesc> {
|
||||
pub fn fetch_op_spec(name: ClauseName, arity: usize, op_dir: &OpDir) -> Option<SharedOpDesc> {
|
||||
match arity {
|
||||
2 => op_dir
|
||||
.get(&(name, Fixity::In))
|
||||
@@ -451,9 +418,7 @@ pub fn fetch_op_spec(
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -499,7 +464,6 @@ impl Module {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Number {
|
||||
Float(OrderedFloat<f64>),
|
||||
@@ -559,7 +523,6 @@ impl Into<HeapCellValue> for Number {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Number {
|
||||
#[inline]
|
||||
pub fn is_positive(&self) -> bool {
|
||||
@@ -594,12 +557,13 @@ impl Number {
|
||||
#[inline]
|
||||
pub fn abs(self) -> Self {
|
||||
match self {
|
||||
Number::Fixnum(n) =>
|
||||
Number::Fixnum(n) => {
|
||||
if let Some(n) = n.checked_abs() {
|
||||
Number::from(n)
|
||||
} else {
|
||||
Number::from(Integer::from(n).abs())
|
||||
}
|
||||
}
|
||||
Number::Integer(n) => Number::from(Integer::from(n.abs_ref())),
|
||||
Number::Float(f) => Number::Float(OrderedFloat(f.abs())),
|
||||
Number::Rational(r) => Number::from(Rational::from(r.abs_ref())),
|
||||
@@ -624,15 +588,13 @@ impl OptArgIndexKey {
|
||||
#[inline]
|
||||
pub fn arg_num(&self) -> usize {
|
||||
match &self {
|
||||
OptArgIndexKey::Constant(arg_num, ..) |
|
||||
OptArgIndexKey::Structure(arg_num, ..) |
|
||||
OptArgIndexKey::List(arg_num, _) => {
|
||||
OptArgIndexKey::Constant(arg_num, ..)
|
||||
| OptArgIndexKey::Structure(arg_num, ..)
|
||||
| OptArgIndexKey::List(arg_num, _) => {
|
||||
// these are always at least 1.
|
||||
*arg_num
|
||||
}
|
||||
OptArgIndexKey::None => {
|
||||
0
|
||||
}
|
||||
OptArgIndexKey::None => 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -644,27 +606,22 @@ impl OptArgIndexKey {
|
||||
#[inline]
|
||||
pub fn switch_on_term_loc(&self) -> Option<usize> {
|
||||
match &self {
|
||||
OptArgIndexKey::Constant(_, loc, ..) |
|
||||
OptArgIndexKey::Structure(_, loc, ..) |
|
||||
OptArgIndexKey::List(_, loc) => {
|
||||
Some(*loc)
|
||||
}
|
||||
OptArgIndexKey::None => {
|
||||
None
|
||||
}
|
||||
OptArgIndexKey::Constant(_, loc, ..)
|
||||
| OptArgIndexKey::Structure(_, loc, ..)
|
||||
| OptArgIndexKey::List(_, loc) => Some(*loc),
|
||||
OptArgIndexKey::None => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_switch_on_term_loc(&mut self, value: usize) {
|
||||
match self {
|
||||
OptArgIndexKey::Constant(_, ref mut loc, ..) |
|
||||
OptArgIndexKey::Structure(_, ref mut loc, ..) |
|
||||
OptArgIndexKey::List(_, ref mut loc) => {
|
||||
OptArgIndexKey::Constant(_, ref mut loc, ..)
|
||||
| OptArgIndexKey::Structure(_, ref mut loc, ..)
|
||||
| OptArgIndexKey::List(_, ref mut loc) => {
|
||||
*loc = value;
|
||||
}
|
||||
OptArgIndexKey::None => {
|
||||
}
|
||||
OptArgIndexKey::None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -673,13 +630,12 @@ impl AddAssign<usize> for OptArgIndexKey {
|
||||
#[inline]
|
||||
fn add_assign(&mut self, n: usize) {
|
||||
match self {
|
||||
OptArgIndexKey::Constant(_, ref mut o, ..) |
|
||||
OptArgIndexKey::List(_, ref mut o) |
|
||||
OptArgIndexKey::Structure(_, ref mut o, ..) => {
|
||||
OptArgIndexKey::Constant(_, ref mut o, ..)
|
||||
| OptArgIndexKey::List(_, ref mut o)
|
||||
| OptArgIndexKey::Structure(_, ref mut o, ..) => {
|
||||
*o += n;
|
||||
}
|
||||
OptArgIndexKey::None => {
|
||||
}
|
||||
OptArgIndexKey::None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
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::forms::*;
|
||||
@@ -14,7 +20,7 @@ use crate::indexmap::{IndexMap, IndexSet};
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::convert::TryFrom;
|
||||
use std::iter::{FromIterator, once};
|
||||
use std::iter::{once, FromIterator};
|
||||
use std::net::{IpAddr, TcpListener};
|
||||
use std::ops::{Range, RangeFrom};
|
||||
use std::rc::Rc;
|
||||
@@ -99,10 +105,7 @@ impl<'a> HCPreOrderIterator<'a> {
|
||||
None => return false,
|
||||
};
|
||||
|
||||
let mut parent_spec = DirectedOp::Left(
|
||||
clause_name!("-"),
|
||||
SharedOpDesc::new(200, FY),
|
||||
);
|
||||
let mut parent_spec = DirectedOp::Left(clause_name!("-"), SharedOpDesc::new(200, FY));
|
||||
|
||||
loop {
|
||||
match self.machine_st.store(self.machine_st.deref(addr)) {
|
||||
@@ -154,12 +157,13 @@ fn char_to_string(is_quoted: bool, c: char) -> String {
|
||||
'\u{07}' if is_quoted => "\\a".to_string(), // UTF-8 alert
|
||||
'"' if is_quoted => "\\\"".to_string(),
|
||||
'\\' if is_quoted => "\\\\".to_string(),
|
||||
'\'' | '\n' | '\r' | '\t' | '\u{0b}' | '\u{0c}' | '\u{08}' | '\u{07}' | '"' | '\\' =>
|
||||
c.to_string(),
|
||||
'\u{a0}' ..= '\u{d6}' => c.to_string(),
|
||||
'\u{d8}' ..= '\u{f6}' => c.to_string(),
|
||||
'\u{f8}' ..= '\u{74f}' => c.to_string(),
|
||||
'\x20' ..= '\x7e' => c.to_string(),
|
||||
'\'' | '\n' | '\r' | '\t' | '\u{0b}' | '\u{0c}' | '\u{08}' | '\u{07}' | '"' | '\\' => {
|
||||
c.to_string()
|
||||
}
|
||||
'\u{a0}'..='\u{d6}' => c.to_string(),
|
||||
'\u{d8}'..='\u{f6}' => c.to_string(),
|
||||
'\u{f8}'..='\u{74f}' => c.to_string(),
|
||||
'\x20'..='\x7e' => c.to_string(),
|
||||
_ => format!("\\x{:x}\\", c as u32),
|
||||
}
|
||||
}
|
||||
@@ -271,25 +275,13 @@ fn is_numbered_var(ct: &ClauseType, arity: usize) -> bool {
|
||||
#[inline]
|
||||
fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp>) -> bool {
|
||||
if let Some(ref op) = op {
|
||||
op.is_negative_sign() &&
|
||||
iter.leftmost_leaf_has_property(|addr, heap| {
|
||||
match Number::try_from((addr, heap)) {
|
||||
Ok(Number::Fixnum(n)) => {
|
||||
n > 0
|
||||
}
|
||||
Ok(Number::Float(f)) => {
|
||||
f > OrderedFloat(0f64)
|
||||
}
|
||||
Ok(Number::Integer(n)) => {
|
||||
&*n > &0
|
||||
}
|
||||
Ok(Number::Rational(n)) => {
|
||||
&*n > &0
|
||||
}
|
||||
_ => {
|
||||
false
|
||||
}
|
||||
}
|
||||
op.is_negative_sign()
|
||||
&& iter.leftmost_leaf_has_property(|addr, heap| match Number::try_from((addr, heap)) {
|
||||
Ok(Number::Fixnum(n)) => n > 0,
|
||||
Ok(Number::Float(f)) => f > OrderedFloat(0f64),
|
||||
Ok(Number::Integer(n)) => &*n > &0,
|
||||
Ok(Number::Rational(n)) => &*n > &0,
|
||||
_ => false,
|
||||
})
|
||||
} else {
|
||||
false
|
||||
@@ -298,8 +290,8 @@ fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp
|
||||
|
||||
fn numbervar(n: Integer) -> Var {
|
||||
static CHAR_CODES: [char; 26] = [
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
|
||||
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
];
|
||||
|
||||
let i = n.mod_u(26) as usize;
|
||||
@@ -332,9 +324,7 @@ impl MachineState {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -446,8 +436,7 @@ fn non_quoted_graphic_token<Iter: Iterator<Item = char>>(mut iter: Iter, c: char
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn non_quoted_token<Iter: Iterator<Item = char>>(mut iter: Iter) -> bool {
|
||||
pub(super) fn non_quoted_token<Iter: Iterator<Item = char>>(mut iter: Iter) -> bool {
|
||||
if let Some(c) = iter.next() {
|
||||
if small_letter_char!(c) {
|
||||
iter.all(|c| alpha_numeric_char!(c))
|
||||
@@ -505,37 +494,37 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
max_depth: 0,
|
||||
}
|
||||
}
|
||||
/*
|
||||
pub fn from_heap_locs(
|
||||
machine_st: &'a MachineState,
|
||||
op_dir: &'a OpDir,
|
||||
output: Outputter,
|
||||
) -> Self {
|
||||
let mut printer = Self::new(machine_st, op_dir, output);
|
||||
/*
|
||||
pub fn from_heap_locs(
|
||||
machine_st: &'a MachineState,
|
||||
op_dir: &'a OpDir,
|
||||
output: Outputter,
|
||||
) -> Self {
|
||||
let mut printer = Self::new(machine_st, op_dir, output);
|
||||
|
||||
printer.toplevel_spec = Some(DirectedOp::Right(
|
||||
clause_name!("="),
|
||||
SharedOpDesc::new(700, XFX),
|
||||
));
|
||||
printer.toplevel_spec = Some(DirectedOp::Right(
|
||||
clause_name!("="),
|
||||
SharedOpDesc::new(700, XFX),
|
||||
));
|
||||
|
||||
printer.heap_locs = reverse_heap_locs(machine_st);
|
||||
printer.heap_locs = reverse_heap_locs(machine_st);
|
||||
|
||||
printer
|
||||
}
|
||||
*/
|
||||
/*
|
||||
pub fn drop_toplevel_spec(&mut self) {
|
||||
self.toplevel_spec = None;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
#[inline]
|
||||
pub fn see_all_locs(&mut self) {
|
||||
for key in self.heap_locs.keys().cloned() {
|
||||
self.printed_vars.insert(key);
|
||||
printer
|
||||
}
|
||||
}
|
||||
*/
|
||||
*/
|
||||
/*
|
||||
pub fn drop_toplevel_spec(&mut self) {
|
||||
self.toplevel_spec = None;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
#[inline]
|
||||
pub fn see_all_locs(&mut self) {
|
||||
for key in self.heap_locs.keys().cloned() {
|
||||
self.printed_vars.insert(key);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#[inline]
|
||||
fn ambiguity_check(&self, atom: &str) -> bool {
|
||||
@@ -555,7 +544,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
iter.stack().pop();
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -579,7 +569,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
if self.check_max_depth(&mut max_depth) {
|
||||
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));
|
||||
|
||||
return;
|
||||
@@ -587,7 +578,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|
||||
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));
|
||||
} else {
|
||||
match ct.name().as_str() {
|
||||
@@ -602,9 +596,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
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::Atom(clause_name!("...")));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -612,11 +608,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
|
||||
let right_directed_op = DirectedOp::Right(ct.name(), spec.clone());
|
||||
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::CompositeRedirect(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::CompositeRedirect(max_depth, right_directed_op));
|
||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(
|
||||
max_depth,
|
||||
right_directed_op,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -626,15 +626,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
mut max_depth: usize,
|
||||
arity: usize,
|
||||
name: ClauseName,
|
||||
) -> bool
|
||||
{
|
||||
) -> bool {
|
||||
if self.check_max_depth(&mut max_depth) {
|
||||
for _ in 0 .. arity {
|
||||
for _ in 0..arity {
|
||||
iter.stack().pop();
|
||||
}
|
||||
|
||||
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::Atom(name));
|
||||
@@ -644,8 +644,9 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::Close);
|
||||
|
||||
for _ in 0 .. arity {
|
||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||
for _ in 0..arity {
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||
self.state_stack.push(TokenOrRedirect::Comma);
|
||||
}
|
||||
|
||||
@@ -662,12 +663,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
iter: &mut HCPreOrderIterator,
|
||||
mut max_depth: usize,
|
||||
name: ClauseName,
|
||||
spec: SharedOpDesc)
|
||||
{
|
||||
spec: SharedOpDesc,
|
||||
) {
|
||||
if self.check_max_depth(&mut max_depth) {
|
||||
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::Atom(name));
|
||||
|
||||
@@ -676,7 +678,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|
||||
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::Atom(name));
|
||||
}
|
||||
@@ -687,14 +690,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
mut max_depth: usize,
|
||||
name: ClauseName,
|
||||
spec: SharedOpDesc,
|
||||
)
|
||||
{
|
||||
) {
|
||||
if self.check_max_depth(&mut max_depth) {
|
||||
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::Atom(clause_name!("...")));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -702,25 +706,32 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
let left_directed_op = DirectedOp::Left(name.clone(), spec.clone());
|
||||
let right_directed_op = DirectedOp::Right(name.clone(), spec.clone());
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(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::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) {
|
||||
iter.stack().pop();
|
||||
|
||||
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);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
true
|
||||
@@ -795,18 +806,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
}
|
||||
|
||||
match addr {
|
||||
Addr::Lis(h) | Addr::Str(h) => {
|
||||
Some(format!("{}", h))
|
||||
}
|
||||
Addr::Lis(h) | Addr::Str(h) => Some(format!("{}", h)),
|
||||
_ => {
|
||||
if let Some(r) = addr.as_var() {
|
||||
match r {
|
||||
Ref::StackCell(fr, sc) => {
|
||||
Some(format!("_s_{}_{}", fr, sc))
|
||||
}
|
||||
Ref::HeapCell(h) | Ref::AttrVar(h) => {
|
||||
Some(format!("_{}", h))
|
||||
}
|
||||
Ref::StackCell(fr, sc) => Some(format!("_s_{}_{}", fr, sc)),
|
||||
Ref::HeapCell(h) | Ref::AttrVar(h) => Some(format!("_{}", h)),
|
||||
}
|
||||
} else {
|
||||
None
|
||||
@@ -818,8 +823,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
fn record_children_as_non_cyclic(&mut self, addr: &Addr) {
|
||||
match addr {
|
||||
&Addr::Lis(l) => {
|
||||
let c1 = self.machine_st.store(self.machine_st.deref(Addr::HeapCell(l)));
|
||||
let c2 = self.machine_st.store(self.machine_st.deref(Addr::HeapCell(l + 1)));
|
||||
let c1 = self
|
||||
.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) {
|
||||
self.non_cyclic_terms.insert(c);
|
||||
@@ -830,18 +839,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
}
|
||||
}
|
||||
&Addr::Str(s) => {
|
||||
let arity =
|
||||
match &self.machine_st.heap[s] {
|
||||
HeapCellValue::NamedStr(arity, ..) => {
|
||||
arity
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
};
|
||||
let arity = match &self.machine_st.heap[s] {
|
||||
HeapCellValue::NamedStr(arity, ..) => arity,
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
};
|
||||
|
||||
for i in 1 .. arity + 1 {
|
||||
let c = self.machine_st.store(self.machine_st.deref(Addr::HeapCell(s + i)));
|
||||
for i in 1..arity + 1 {
|
||||
let c = self
|
||||
.machine_st
|
||||
.store(self.machine_st.deref(Addr::HeapCell(s + i)));
|
||||
|
||||
if let Some(c) = functor_location(&c) {
|
||||
self.non_cyclic_terms.insert(c);
|
||||
@@ -856,15 +864,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
self.non_cyclic_terms.insert(c);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_for_seen(
|
||||
&mut self,
|
||||
iter: &mut HCPreOrderIterator,
|
||||
) -> Option<Addr> {
|
||||
fn check_for_seen(&mut self, iter: &mut HCPreOrderIterator) -> Option<Addr> {
|
||||
iter.stack().last().cloned().and_then(|addr| {
|
||||
let addr = self.machine_st.store(self.machine_st.deref(addr));
|
||||
|
||||
@@ -889,9 +893,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
}
|
||||
None => {
|
||||
let offset = match functor_location(&addr) {
|
||||
Some(offset) => {
|
||||
offset
|
||||
}
|
||||
Some(offset) => offset,
|
||||
None => {
|
||||
return iter.next();
|
||||
}
|
||||
@@ -1036,19 +1038,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|
||||
let rdiv_ct = clause_name!("rdiv");
|
||||
|
||||
let left_directed_op =
|
||||
if spec.prec() > 0 {
|
||||
Some(DirectedOp::Left(rdiv_ct.clone(), spec.clone()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let left_directed_op = if spec.prec() > 0 {
|
||||
Some(DirectedOp::Left(rdiv_ct.clone(), spec.clone()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let right_directed_op =
|
||||
if spec.prec() > 0 {
|
||||
Some(DirectedOp::Right(rdiv_ct.clone(), spec.clone()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let right_directed_op = if spec.prec() > 0 {
|
||||
Some(DirectedOp::Right(rdiv_ct.clone(), spec.clone()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if spec.prec() > 0 {
|
||||
self.state_stack.push(TokenOrRedirect::Number(
|
||||
@@ -1056,10 +1056,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
left_directed_op,
|
||||
));
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::Op(
|
||||
rdiv_ct,
|
||||
spec.clone(),
|
||||
));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::Op(rdiv_ct, spec.clone()));
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::Number(
|
||||
Number::from(r.numer()),
|
||||
@@ -1068,17 +1066,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
} else {
|
||||
self.state_stack.push(TokenOrRedirect::Close);
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::Number(
|
||||
Number::from(r.denom()),
|
||||
None,
|
||||
));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::Number(Number::from(r.denom()), None));
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::Comma);
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::Number(
|
||||
Number::from(r.numer()),
|
||||
None,
|
||||
));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::Number(Number::from(r.numer()), None));
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::Open);
|
||||
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)) {
|
||||
let c = char_to_string(false, c);
|
||||
|
||||
@@ -1120,46 +1113,37 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
fn print_proper_string(&mut self, buf: String, max_depth: usize) {
|
||||
self.push_char('"');
|
||||
|
||||
let buf =
|
||||
if max_depth == 0 {
|
||||
String::from_iter(buf.chars().map(|c| {
|
||||
char_to_string(self.quoted, c)
|
||||
}))
|
||||
} else {
|
||||
let mut char_count = 0;
|
||||
let mut buf =
|
||||
String::from_iter(buf.chars().take(max_depth).map(|c| {
|
||||
char_count += 1;
|
||||
char_to_string(self.quoted, c)
|
||||
}));
|
||||
let buf = if max_depth == 0 {
|
||||
String::from_iter(buf.chars().map(|c| char_to_string(self.quoted, c)))
|
||||
} else {
|
||||
let mut char_count = 0;
|
||||
let mut buf = String::from_iter(buf.chars().take(max_depth).map(|c| {
|
||||
char_count += 1;
|
||||
char_to_string(self.quoted, c)
|
||||
}));
|
||||
|
||||
if char_count == max_depth {
|
||||
buf += " ...";
|
||||
}
|
||||
if char_count == max_depth {
|
||||
buf += " ...";
|
||||
}
|
||||
|
||||
buf
|
||||
};
|
||||
buf
|
||||
};
|
||||
|
||||
self.append_str(&buf);
|
||||
self.push_char('"');
|
||||
}
|
||||
|
||||
fn print_list_like(
|
||||
&mut self,
|
||||
iter: &mut HCPreOrderIterator,
|
||||
addr: Addr,
|
||||
mut max_depth: usize,
|
||||
) {
|
||||
fn print_list_like(&mut self, iter: &mut HCPreOrderIterator, addr: Addr, mut max_depth: usize) {
|
||||
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!("...")));
|
||||
return;
|
||||
}
|
||||
|
||||
let mut heap_pstr_iter =
|
||||
self.machine_st.heap_pstr_iter(addr);
|
||||
let mut heap_pstr_iter = self.machine_st.heap_pstr_iter(addr);
|
||||
|
||||
let buf = heap_pstr_iter.to_string();
|
||||
|
||||
@@ -1184,12 +1168,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|
||||
let buf_len = buf.len();
|
||||
|
||||
let buf_iter: Box<dyn Iterator<Item=char>> =
|
||||
if self.max_depth == 0 {
|
||||
Box::new(buf.chars())
|
||||
} else {
|
||||
Box::new(buf.chars().take(max_depth))
|
||||
};
|
||||
let buf_iter: Box<dyn Iterator<Item = char>> = if self.max_depth == 0 {
|
||||
Box::new(buf.chars())
|
||||
} else {
|
||||
Box::new(buf.chars().take(max_depth))
|
||||
};
|
||||
|
||||
let mut byte_len = 0;
|
||||
|
||||
@@ -1207,14 +1190,16 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
byte_len += c.len_utf8();
|
||||
}
|
||||
|
||||
for _ in 0 .. char_count {
|
||||
for _ in 0..char_count {
|
||||
self.state_stack.push(TokenOrRedirect::Close);
|
||||
}
|
||||
|
||||
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 {
|
||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||
iter.stack().push(end_addr);
|
||||
}
|
||||
} else {
|
||||
@@ -1232,15 +1217,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
byte_len += c.len_utf8();
|
||||
}
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::CloseList(Rc::new(
|
||||
Cell::new((switch, 0))
|
||||
)));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::CloseList(Rc::new(Cell::new((switch, 0)))));
|
||||
|
||||
if self.max_depth > 0 && buf_len > byte_len {
|
||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||
} else {
|
||||
self.outputter.truncate(self.outputter.len() - ','.len_utf8());
|
||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||
} else {
|
||||
self.outputter
|
||||
.truncate(self.outputter.len() - ','.len_utf8());
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||
|
||||
iter.stack().push(end_addr);
|
||||
}
|
||||
@@ -1268,8 +1255,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|
||||
let cell = Rc::new(Cell::new((true, 0)));
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::CloseList(cell.clone()));
|
||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::CloseList(cell.clone()));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||
self.state_stack.push(TokenOrRedirect::OpenList(cell));
|
||||
|
||||
return;
|
||||
@@ -1277,11 +1266,14 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|
||||
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::FunctorRedirect(max_depth));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::OpenList(cell));
|
||||
}
|
||||
@@ -1298,23 +1290,24 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
max_depth: usize,
|
||||
) {
|
||||
let add_brackets = if !self.ignore_ops {
|
||||
negated_operand || if let Some(ref op) = op {
|
||||
if self.numbervars && arity == 1 && name.as_str() == "$VAR" {
|
||||
!iter.immediate_leaf_has_property(|addr, heap| {
|
||||
match heap.index_addr(&addr).as_ref() {
|
||||
&HeapCellValue::Integer(ref n) => &**n >= &0,
|
||||
&HeapCellValue::Addr(Addr::Fixnum(n)) => n >= 0,
|
||||
&HeapCellValue::Addr(Addr::Float(f)) => f >= OrderedFloat(0f64),
|
||||
&HeapCellValue::Rational(ref r) => &**r >= &0,
|
||||
_ => false
|
||||
}
|
||||
}) && needs_bracketing(&spec, op)
|
||||
negated_operand
|
||||
|| if let Some(ref op) = op {
|
||||
if self.numbervars && arity == 1 && name.as_str() == "$VAR" {
|
||||
!iter.immediate_leaf_has_property(|addr, heap| {
|
||||
match heap.index_addr(&addr).as_ref() {
|
||||
&HeapCellValue::Integer(ref n) => &**n >= &0,
|
||||
&HeapCellValue::Addr(Addr::Fixnum(n)) => n >= 0,
|
||||
&HeapCellValue::Addr(Addr::Float(f)) => f >= OrderedFloat(0f64),
|
||||
&HeapCellValue::Rational(ref r) => &**r >= &0,
|
||||
_ => false,
|
||||
}
|
||||
}) && needs_bracketing(&spec, op)
|
||||
} else {
|
||||
needs_bracketing(&spec, op)
|
||||
}
|
||||
} else {
|
||||
needs_bracketing(&spec, op)
|
||||
is_functor_redirect && spec.prec() >= 1000
|
||||
}
|
||||
} else {
|
||||
is_functor_redirect && spec.prec() >= 1000
|
||||
}
|
||||
} else {
|
||||
false
|
||||
};
|
||||
@@ -1344,15 +1337,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
tcp_listener: &TcpListener,
|
||||
max_depth: usize,
|
||||
) {
|
||||
let (ip, port) =
|
||||
if let Some(addr) = tcp_listener.local_addr().ok() {
|
||||
(addr.ip(), Number::from(addr.port() as isize))
|
||||
} else {
|
||||
let disconnected_atom = clause_name!("$disconnected_tcp_listener");
|
||||
self.state_stack.push(TokenOrRedirect::Atom(disconnected_atom));
|
||||
let (ip, port) = if let Some(addr) = tcp_listener.local_addr().ok() {
|
||||
(addr.ip(), Number::from(addr.port() as isize))
|
||||
} else {
|
||||
let disconnected_atom = clause_name!("$disconnected_tcp_listener");
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::Atom(disconnected_atom));
|
||||
|
||||
return;
|
||||
};
|
||||
return;
|
||||
};
|
||||
|
||||
if self.format_struct(iter, max_depth, 1, clause_name!("$tcp_listener")) {
|
||||
let atom = self.state_stack.pop().unwrap();
|
||||
@@ -1369,22 +1362,16 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
}
|
||||
}
|
||||
|
||||
fn print_stream(
|
||||
&mut self,
|
||||
iter: &mut HCPreOrderIterator,
|
||||
stream: &Stream,
|
||||
max_depth: usize,
|
||||
) {
|
||||
fn print_stream(&mut self, iter: &mut HCPreOrderIterator, stream: &Stream, max_depth: usize) {
|
||||
if let Some(alias) = &stream.options.alias {
|
||||
self.print_atom(alias);
|
||||
} else {
|
||||
if self.format_struct(iter, max_depth, 1, clause_name!("$stream")) {
|
||||
let atom =
|
||||
if stream.is_stdout() || stream.is_stdin() {
|
||||
TokenOrRedirect::Atom(clause_name!("user"))
|
||||
} else {
|
||||
TokenOrRedirect::RawPtr(stream.as_ptr())
|
||||
};
|
||||
let atom = if stream.is_stdout() || stream.is_stdin() {
|
||||
TokenOrRedirect::Atom(clause_name!("user"))
|
||||
} else {
|
||||
TokenOrRedirect::RawPtr(stream.as_ptr())
|
||||
};
|
||||
|
||||
let stream_root = self.state_stack.pop().unwrap();
|
||||
|
||||
@@ -1414,7 +1401,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|
||||
match self.machine_st.heap.index_addr(&addr).as_ref() {
|
||||
&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 {
|
||||
self.handle_op_as_struct(
|
||||
|
||||
474
src/indexing.rs
474
src/indexing.rs
@@ -1,4 +1,5 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::clause_name;
|
||||
use crate::prolog_parser_rebis::tabled_rc::*;
|
||||
|
||||
use crate::forms::*;
|
||||
@@ -43,14 +44,10 @@ impl OptArgIndexKey {
|
||||
#[inline]
|
||||
fn has_key_type(&self, key_type: OptArgIndexKeyType) -> bool {
|
||||
match (self, key_type) {
|
||||
(OptArgIndexKey::Constant(..), OptArgIndexKeyType::Constant) |
|
||||
(OptArgIndexKey::Structure(..), OptArgIndexKeyType::Structure) |
|
||||
(OptArgIndexKey::List(..), OptArgIndexKeyType::List) => {
|
||||
true
|
||||
}
|
||||
_ => {
|
||||
false
|
||||
}
|
||||
(OptArgIndexKey::Constant(..), OptArgIndexKeyType::Constant)
|
||||
| (OptArgIndexKey::Structure(..), OptArgIndexKeyType::Structure)
|
||||
| (OptArgIndexKey::List(..), OptArgIndexKeyType::List) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,16 +90,20 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
indexing_code: &'a mut Vec<IndexingLine>,
|
||||
append_or_prepend: AppendOrPrepend,
|
||||
) -> 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) {
|
||||
let constant_key =
|
||||
search_skeleton_for_first_key_type(
|
||||
self.skeleton,
|
||||
OptArgIndexKeyType::Constant,
|
||||
self.append_or_prepend,
|
||||
);
|
||||
fn internalize_constant(&mut self, constant_ptr: IndexingCodePtr) {
|
||||
let constant_key = search_skeleton_for_first_key_type(
|
||||
self.skeleton,
|
||||
OptArgIndexKeyType::Constant,
|
||||
self.append_or_prepend,
|
||||
);
|
||||
|
||||
let mut constants = IndexMap::new();
|
||||
|
||||
@@ -117,7 +118,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
|
||||
if let IndexingCodePtr::Internal(_) = constant_ptr {
|
||||
self.indexing_code.push(IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnConstant(constants)
|
||||
IndexingInstruction::SwitchOnConstant(constants),
|
||||
));
|
||||
|
||||
let last_index = self.indexing_code.len() - 1;
|
||||
@@ -126,34 +127,39 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
self.offset = self.indexing_code.len();
|
||||
|
||||
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)
|
||||
{
|
||||
let third_level_index =
|
||||
if self.append_or_prepend.is_append() {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(external),
|
||||
IndexedChoiceInstruction::Trust(index)
|
||||
]
|
||||
} else {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(index),
|
||||
IndexedChoiceInstruction::Trust(external)
|
||||
]
|
||||
};
|
||||
fn add_indexed_choice_for_constant(
|
||||
&mut self,
|
||||
external: usize,
|
||||
constant: Constant,
|
||||
index: usize,
|
||||
) {
|
||||
let third_level_index = if self.append_or_prepend.is_append() {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(external),
|
||||
IndexedChoiceInstruction::Trust(index)
|
||||
]
|
||||
} else {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(index),
|
||||
IndexedChoiceInstruction::Trust(external)
|
||||
]
|
||||
};
|
||||
|
||||
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] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnConstant(ref mut constants)
|
||||
) => {
|
||||
constants.insert(constant, IndexingCodePtr::Internal(indexing_code_len - self.offset));
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(ref mut constants)) => {
|
||||
constants.insert(
|
||||
constant,
|
||||
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
@@ -164,10 +170,11 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
fn extend_indexed_choice(&mut self, index: usize) {
|
||||
match &mut self.indexing_code[self.offset] {
|
||||
IndexingLine::IndexedChoice(ref mut indexed_choice_instrs)
|
||||
if self.append_or_prepend.is_append() => {
|
||||
uncap_choice_seq_with_trust(indexed_choice_instrs);
|
||||
indexed_choice_instrs.push_back(IndexedChoiceInstruction::Trust(index));
|
||||
}
|
||||
if self.append_or_prepend.is_append() =>
|
||||
{
|
||||
uncap_choice_seq_with_trust(indexed_choice_instrs);
|
||||
indexed_choice_instrs.push_back(IndexedChoiceInstruction::Trust(index));
|
||||
}
|
||||
IndexingLine::IndexedChoice(ref mut indexed_choice_instrs) => {
|
||||
uncap_choice_seq_with_try(indexed_choice_instrs);
|
||||
indexed_choice_instrs.push_front(IndexedChoiceInstruction::Try(index));
|
||||
@@ -188,9 +195,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
let indexing_code_len = self.indexing_code.len();
|
||||
|
||||
match &mut self.indexing_code[self.offset] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
|
||||
match *c {
|
||||
IndexingCodePtr::Fail => {
|
||||
*c = IndexingCodePtr::External(index);
|
||||
@@ -203,7 +208,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
*c = IndexingCodePtr::Internal(indexing_code_len);
|
||||
|
||||
self.indexing_code.push(IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnConstant(constants)
|
||||
IndexingInstruction::SwitchOnConstant(constants),
|
||||
));
|
||||
|
||||
self.offset = indexing_code_len;
|
||||
@@ -213,12 +218,11 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnConstant(constants)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(constants)) => {
|
||||
match constants.get(&overlapping_constant).cloned() {
|
||||
None | Some(IndexingCodePtr::Fail) => {
|
||||
constants.insert(overlapping_constant, IndexingCodePtr::External(index));
|
||||
constants
|
||||
.insert(overlapping_constant, IndexingCodePtr::External(index));
|
||||
}
|
||||
Some(IndexingCodePtr::External(o)) => {
|
||||
self.add_indexed_choice_for_constant(o, overlapping_constant, index);
|
||||
@@ -232,9 +236,9 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
break;
|
||||
}
|
||||
IndexingLine::IndexedChoice(_) => {
|
||||
self.internalize_constant(
|
||||
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
||||
);
|
||||
self.internalize_constant(IndexingCodePtr::Internal(
|
||||
indexing_code_len - self.offset,
|
||||
));
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
@@ -248,9 +252,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
let indexing_code_len = self.indexing_code.len();
|
||||
|
||||
match &mut self.indexing_code[self.offset] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
|
||||
match *c {
|
||||
IndexingCodePtr::Fail => {
|
||||
*c = IndexingCodePtr::External(index);
|
||||
@@ -265,9 +267,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnConstant(constants)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(constants)) => {
|
||||
match constants.get(&constant).cloned() {
|
||||
None | Some(IndexingCodePtr::Fail) => {
|
||||
constants.insert(constant, IndexingCodePtr::External(index));
|
||||
@@ -284,9 +284,9 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
break;
|
||||
}
|
||||
IndexingLine::IndexedChoice(_) => {
|
||||
self.internalize_constant(
|
||||
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
||||
);
|
||||
self.internalize_constant(IndexingCodePtr::Internal(
|
||||
indexing_code_len - self.offset,
|
||||
));
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
@@ -295,13 +295,12 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn internalize_structure(&mut self, structure_ptr: IndexingCodePtr) {
|
||||
let structure_key =
|
||||
search_skeleton_for_first_key_type(
|
||||
self.skeleton,
|
||||
OptArgIndexKeyType::Structure,
|
||||
self.append_or_prepend,
|
||||
);
|
||||
fn internalize_structure(&mut self, structure_ptr: IndexingCodePtr) {
|
||||
let structure_key = search_skeleton_for_first_key_type(
|
||||
self.skeleton,
|
||||
OptArgIndexKeyType::Structure,
|
||||
self.append_or_prepend,
|
||||
);
|
||||
|
||||
let mut structures = IndexMap::new();
|
||||
|
||||
@@ -316,7 +315,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
|
||||
if let IndexingCodePtr::Internal(_) = structure_ptr {
|
||||
self.indexing_code.push(IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnStructure(structures)
|
||||
IndexingInstruction::SwitchOnStructure(structures),
|
||||
));
|
||||
|
||||
let last_index = self.indexing_code.len() - 1;
|
||||
@@ -325,34 +324,39 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
self.offset = self.indexing_code.len();
|
||||
|
||||
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)
|
||||
{
|
||||
let third_level_index =
|
||||
if self.append_or_prepend.is_append() {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(external),
|
||||
IndexedChoiceInstruction::Trust(index)
|
||||
]
|
||||
} else {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(index),
|
||||
IndexedChoiceInstruction::Trust(external)
|
||||
]
|
||||
};
|
||||
fn add_indexed_choice_for_structure(
|
||||
&mut self,
|
||||
external: usize,
|
||||
key: PredicateKey,
|
||||
index: usize,
|
||||
) {
|
||||
let third_level_index = if self.append_or_prepend.is_append() {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(external),
|
||||
IndexedChoiceInstruction::Trust(index)
|
||||
]
|
||||
} else {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(index),
|
||||
IndexedChoiceInstruction::Trust(external)
|
||||
]
|
||||
};
|
||||
|
||||
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] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnStructure(ref mut structures)
|
||||
) => {
|
||||
structures.insert(key, IndexingCodePtr::Internal(indexing_code_len - self.offset));
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref mut structures)) => {
|
||||
structures.insert(
|
||||
key,
|
||||
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
@@ -365,26 +369,26 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
let indexing_code_len = self.indexing_code.len();
|
||||
|
||||
match &mut self.indexing_code[self.offset] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)
|
||||
) => {
|
||||
match *s {
|
||||
IndexingCodePtr::Fail => {
|
||||
*s = IndexingCodePtr::External(index);
|
||||
break;
|
||||
}
|
||||
IndexingCodePtr::External(o) => {
|
||||
*s = IndexingCodePtr::Internal(indexing_code_len - self.offset);
|
||||
self.internalize_structure(IndexingCodePtr::External(o));
|
||||
}
|
||||
IndexingCodePtr::Internal(o) => {
|
||||
self.offset += o;
|
||||
}
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
ref mut s,
|
||||
)) => match *s {
|
||||
IndexingCodePtr::Fail => {
|
||||
*s = IndexingCodePtr::External(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnStructure(structures)
|
||||
) => {
|
||||
IndexingCodePtr::External(o) => {
|
||||
*s = IndexingCodePtr::Internal(indexing_code_len - self.offset);
|
||||
self.internalize_structure(IndexingCodePtr::External(o));
|
||||
}
|
||||
IndexingCodePtr::Internal(o) => {
|
||||
self.offset += o;
|
||||
}
|
||||
},
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(structures)) => {
|
||||
match structures.get(&key).cloned() {
|
||||
None | Some(IndexingCodePtr::Fail) => {
|
||||
structures.insert(key, IndexingCodePtr::External(index));
|
||||
@@ -404,9 +408,9 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
// replace this value, at self.offset, with
|
||||
// SwitchOnStructures, and swap this IndexedChoice
|
||||
// vector to the end of self.indexing_code.
|
||||
self.internalize_structure(
|
||||
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
||||
);
|
||||
self.internalize_structure(IndexingCodePtr::Internal(
|
||||
indexing_code_len - self.offset,
|
||||
));
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
@@ -419,9 +423,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
let indexing_code_len = self.indexing_code.len();
|
||||
|
||||
match &mut self.indexing_code[self.offset] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)) => {
|
||||
match *l {
|
||||
IndexingCodePtr::Fail => {
|
||||
*l = IndexingCodePtr::External(index);
|
||||
@@ -429,22 +431,20 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
IndexingCodePtr::External(o) => {
|
||||
*l = IndexingCodePtr::Internal(indexing_code_len - self.offset);
|
||||
|
||||
let third_level_index =
|
||||
if self.append_or_prepend.is_append() {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(o),
|
||||
IndexedChoiceInstruction::Trust(index)
|
||||
]
|
||||
} else {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(index),
|
||||
IndexedChoiceInstruction::Trust(o)
|
||||
]
|
||||
};
|
||||
let third_level_index = if self.append_or_prepend.is_append() {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(o),
|
||||
IndexedChoiceInstruction::Trust(index)
|
||||
]
|
||||
} else {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(index),
|
||||
IndexedChoiceInstruction::Trust(o)
|
||||
]
|
||||
};
|
||||
|
||||
self.indexing_code.push(
|
||||
IndexingLine::IndexedChoice(third_level_index),
|
||||
);
|
||||
self.indexing_code
|
||||
.push(IndexingLine::IndexedChoice(third_level_index));
|
||||
}
|
||||
IndexingCodePtr::Internal(o) => {
|
||||
self.offset += o;
|
||||
@@ -462,24 +462,16 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
pub fn merge_clause_index(
|
||||
target_indexing_code: &mut Vec<IndexingLine>,
|
||||
skeleton: &mut [ClauseIndexInfo], // the clause to be merged is the last element in the skeleton.
|
||||
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,
|
||||
) {
|
||||
let opt_arg_index_key =
|
||||
match append_or_prepend {
|
||||
AppendOrPrepend::Append => {
|
||||
skeleton.last_mut().unwrap().opt_arg_index_key.take()
|
||||
}
|
||||
AppendOrPrepend::Prepend => {
|
||||
skeleton.first_mut().unwrap().opt_arg_index_key.take()
|
||||
}
|
||||
};
|
||||
let opt_arg_index_key = match append_or_prepend {
|
||||
AppendOrPrepend::Append => 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(
|
||||
skeleton,
|
||||
target_indexing_code,
|
||||
append_or_prepend,
|
||||
);
|
||||
let mut merging_ptr =
|
||||
IndexingCodeMergingPtr::new(skeleton, target_indexing_code, append_or_prepend);
|
||||
|
||||
match &opt_arg_index_key {
|
||||
OptArgIndexKey::Constant(_, index_loc, ref constant, ref overlapping_constants) => {
|
||||
@@ -488,7 +480,9 @@ pub fn merge_clause_index(
|
||||
|
||||
for overlapping_constant in overlapping_constants {
|
||||
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]
|
||||
fn remove_instruction_with_offset(
|
||||
code: &mut SliceDeque<IndexedChoiceInstruction>,
|
||||
offset: usize,
|
||||
) {
|
||||
fn remove_instruction_with_offset(code: &mut SliceDeque<IndexedChoiceInstruction>, offset: usize) {
|
||||
for (index, line) in code.iter().enumerate() {
|
||||
if offset == line.offset() {
|
||||
code.remove(index);
|
||||
@@ -537,9 +528,7 @@ pub fn remove_constant_indices(
|
||||
let iter = once(constant).chain(overlapping_constants.iter());
|
||||
|
||||
match &mut indexing_code[index] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
|
||||
match *c {
|
||||
IndexingCodePtr::External(_) => {
|
||||
*c = IndexingCodePtr::Fail;
|
||||
@@ -560,12 +549,13 @@ pub fn remove_constant_indices(
|
||||
|
||||
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 {
|
||||
match &mut indexing_code[index] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnConstant(ref mut constants)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(
|
||||
ref mut constants,
|
||||
)) => {
|
||||
constants_index = index;
|
||||
|
||||
match constants.get(constant).cloned() {
|
||||
@@ -586,18 +576,21 @@ pub fn remove_constant_indices(
|
||||
|
||||
if indexed_choice_instrs.len() == 1 {
|
||||
let ext = IndexingCodePtr::External(
|
||||
indexed_choice_instrs.pop_back().unwrap().offset()
|
||||
indexed_choice_instrs.pop_back().unwrap().offset(),
|
||||
);
|
||||
|
||||
match &mut indexing_code[constants_index] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||
_,
|
||||
_,
|
||||
ref mut c,
|
||||
..,
|
||||
)) => {
|
||||
*c = ext;
|
||||
}
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnConstant(ref mut constants)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(
|
||||
ref mut constants,
|
||||
)) => {
|
||||
constants.insert(constant.clone(), ext);
|
||||
}
|
||||
_ => {
|
||||
@@ -616,13 +609,11 @@ pub fn remove_constant_indices(
|
||||
}
|
||||
|
||||
match &indexing_code[constants_index] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnConstant(ref constants)
|
||||
) if constants.is_empty() => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(ref constants))
|
||||
if constants.is_empty() =>
|
||||
{
|
||||
match &mut indexing_code[0] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
|
||||
*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;
|
||||
|
||||
match &mut indexing_code[index] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)) => {
|
||||
match *s {
|
||||
IndexingCodePtr::External(_) => {
|
||||
*s = IndexingCodePtr::Fail;
|
||||
@@ -669,9 +657,7 @@ pub fn remove_structure_index(
|
||||
|
||||
loop {
|
||||
match &mut indexing_code[index] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnStructure(ref mut structures)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref mut structures)) => {
|
||||
structures_index = index;
|
||||
|
||||
match structures.get(&(name.clone(), arity)).cloned() {
|
||||
@@ -692,18 +678,22 @@ pub fn remove_structure_index(
|
||||
|
||||
if indexed_choice_instrs.len() == 1 {
|
||||
let ext = IndexingCodePtr::External(
|
||||
indexed_choice_instrs.pop_back().unwrap().offset()
|
||||
indexed_choice_instrs.pop_back().unwrap().offset(),
|
||||
);
|
||||
|
||||
match &mut indexing_code[structures_index] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
ref mut s,
|
||||
)) => {
|
||||
*s = ext;
|
||||
}
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnStructure(ref mut structures)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(
|
||||
ref mut structures,
|
||||
)) => {
|
||||
structures.insert((name.clone(), arity), ext);
|
||||
}
|
||||
_ => {
|
||||
@@ -721,13 +711,17 @@ pub fn remove_structure_index(
|
||||
}
|
||||
|
||||
match &indexing_code[structures_index] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnStructure(ref structures)
|
||||
) if structures.is_empty() => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref structures))
|
||||
if structures.is_empty() =>
|
||||
{
|
||||
match &mut indexing_code[0] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
ref mut s,
|
||||
)) => {
|
||||
*s = IndexingCodePtr::Fail;
|
||||
}
|
||||
_ => {
|
||||
@@ -735,21 +729,15 @@ pub fn remove_structure_index(
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove_list_index(
|
||||
indexing_code: &mut Vec<IndexingLine>,
|
||||
offset: usize,
|
||||
) {
|
||||
pub fn remove_list_index(indexing_code: &mut Vec<IndexingLine>, offset: usize) {
|
||||
let mut index = 0;
|
||||
|
||||
match &mut indexing_code[index] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)) => {
|
||||
match *l {
|
||||
IndexingCodePtr::External(_) => {
|
||||
*l = IndexingCodePtr::Fail;
|
||||
@@ -773,14 +761,17 @@ pub fn remove_list_index(
|
||||
remove_instruction_with_offset(indexed_choice_instrs, offset);
|
||||
|
||||
if indexed_choice_instrs.len() == 1 {
|
||||
let ext = IndexingCodePtr::External(
|
||||
indexed_choice_instrs.pop_back().unwrap().offset()
|
||||
);
|
||||
let ext =
|
||||
IndexingCodePtr::External(indexed_choice_instrs.pop_back().unwrap().offset());
|
||||
|
||||
match &mut indexing_code[0] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
ref mut l,
|
||||
_,
|
||||
)) => {
|
||||
*l = ext;
|
||||
}
|
||||
_ => {
|
||||
@@ -836,8 +827,7 @@ pub fn remove_index(
|
||||
fn second_level_index<IndexKey: Eq + Hash>(
|
||||
indices: IndexMap<IndexKey, SliceDeque<IndexedChoiceInstruction>>,
|
||||
prelude: &mut SliceDeque<IndexingLine>,
|
||||
) -> IndexMap<IndexKey, IndexingCodePtr>
|
||||
{
|
||||
) -> IndexMap<IndexKey, IndexingCodePtr> {
|
||||
let mut index_locs = IndexMap::new();
|
||||
|
||||
for (key, mut code) in indices.into_iter() {
|
||||
@@ -868,10 +858,11 @@ fn switch_on<IndexKey: Eq + Hash>(
|
||||
|
||||
IndexingCodePtr::Internal(1)
|
||||
} else {
|
||||
index.into_iter()
|
||||
.next()
|
||||
.map(|(_, v)| v)
|
||||
.unwrap_or(IndexingCodePtr::Fail)
|
||||
index
|
||||
.into_iter()
|
||||
.next()
|
||||
.map(|(_, v)| v)
|
||||
.unwrap_or(IndexingCodePtr::Fail)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -884,9 +875,10 @@ fn switch_on_list(
|
||||
prelude.push_back(IndexingLine::from(lists));
|
||||
IndexingCodePtr::Internal(1)
|
||||
} else {
|
||||
lists.first()
|
||||
.map(|i| IndexingCodePtr::External(i.offset()))
|
||||
.unwrap_or(IndexingCodePtr::Fail)
|
||||
lists
|
||||
.first()
|
||||
.map(|i| IndexingCodePtr::External(i.offset()))
|
||||
.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
|
||||
@@ -1001,7 +992,7 @@ impl CodeOffsets {
|
||||
constants: IndexMap::new(),
|
||||
lists: sdeq![],
|
||||
structures: IndexMap::new(),
|
||||
optimal_index
|
||||
optimal_index,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1011,20 +1002,15 @@ impl CodeOffsets {
|
||||
}
|
||||
|
||||
fn index_constant(&mut self, constant: &Constant, index: usize) -> Vec<Constant> {
|
||||
let overlapping_constants =
|
||||
constant_key_alternatives(constant, self.atom_tbl.clone());
|
||||
let overlapping_constants = constant_key_alternatives(constant, self.atom_tbl.clone());
|
||||
|
||||
let code = self.constants
|
||||
.entry(constant.clone())
|
||||
.or_insert(sdeq![]);
|
||||
let code = self.constants.entry(constant.clone()).or_insert(sdeq![]);
|
||||
|
||||
let is_initial_index = code.is_empty();
|
||||
code.push_back(compute_index(is_initial_index, index));
|
||||
|
||||
for constant in &overlapping_constants {
|
||||
let code = self.constants
|
||||
.entry(constant.clone())
|
||||
.or_insert(sdeq![]);
|
||||
let code = self.constants.entry(constant.clone()).or_insert(sdeq![]);
|
||||
|
||||
let is_initial_index = code.is_empty();
|
||||
let index = compute_index(is_initial_index, index);
|
||||
@@ -1062,25 +1048,21 @@ impl CodeOffsets {
|
||||
self.index_structure(name, terms.len(), index);
|
||||
}
|
||||
&Term::Cons(..) | &Term::Constant(_, Constant::String(_)) => {
|
||||
clause_index_info.opt_arg_index_key =
|
||||
OptArgIndexKey::List(self.optimal_index, 0);
|
||||
clause_index_info.opt_arg_index_key = OptArgIndexKey::List(self.optimal_index, 0);
|
||||
|
||||
self.index_list(index);
|
||||
}
|
||||
&Term::Constant(_, ref constant) => {
|
||||
let overlapping_constants =
|
||||
self.index_constant(constant, index);
|
||||
let overlapping_constants = self.index_constant(constant, index);
|
||||
|
||||
clause_index_info.opt_arg_index_key =
|
||||
OptArgIndexKey::Constant(
|
||||
self.optimal_index,
|
||||
0,
|
||||
constant.clone(),
|
||||
overlapping_constants,
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
clause_index_info.opt_arg_index_key = OptArgIndexKey::Constant(
|
||||
self.optimal_index,
|
||||
0,
|
||||
constant.clone(),
|
||||
overlapping_constants,
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1117,8 +1099,7 @@ impl CodeOffsets {
|
||||
IndexingCodePtr::Internal(ref mut i) => {
|
||||
*i += con_loc.is_internal() as usize;
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
match &mut lst_loc {
|
||||
@@ -1126,15 +1107,18 @@ impl CodeOffsets {
|
||||
*i += con_loc.is_internal() as usize;
|
||||
*i += str_loc.is_internal() as usize;
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
let var_offset = 1 + skip_stub_try_me_else as usize;
|
||||
|
||||
prelude.push_front(IndexingLine::from(
|
||||
IndexingInstruction::SwitchOnTerm(self.optimal_index, var_offset, con_loc, lst_loc, str_loc)
|
||||
));
|
||||
prelude.push_front(IndexingLine::from(IndexingInstruction::SwitchOnTerm(
|
||||
self.optimal_index,
|
||||
var_offset,
|
||||
con_loc,
|
||||
lst_loc,
|
||||
str_loc,
|
||||
)));
|
||||
|
||||
prelude.into_iter().collect()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::clause_name;
|
||||
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
@@ -34,9 +35,7 @@ impl Level {
|
||||
impl ArithmeticTerm {
|
||||
fn into_functor(&self) -> MachineStub {
|
||||
match self {
|
||||
&ArithmeticTerm::Reg(r) => {
|
||||
reg_type_into_functor(r)
|
||||
}
|
||||
&ArithmeticTerm::Reg(r) => reg_type_into_functor(r),
|
||||
&ArithmeticTerm::Interm(i) => {
|
||||
functor!("intermediate", [integer(i)])
|
||||
}
|
||||
@@ -185,16 +184,11 @@ impl Line {
|
||||
|
||||
pub fn enqueue_functors(&self, mut h: usize, functors: &mut Vec<MachineStub>) {
|
||||
match self {
|
||||
&Line::Arithmetic(ref arith_instr) =>
|
||||
functors.push(arith_instr.to_functor(h)),
|
||||
&Line::Choice(ref choice_instr) =>
|
||||
functors.push(choice_instr.to_functor()),
|
||||
&Line::Control(ref control_instr) =>
|
||||
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::Arithmetic(ref arith_instr) => functors.push(arith_instr.to_functor(h)),
|
||||
&Line::Choice(ref choice_instr) => functors.push(choice_instr.to_functor()),
|
||||
&Line::Control(ref control_instr) => 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) => {
|
||||
for indexing_instr in indexing_instrs {
|
||||
match indexing_instr {
|
||||
@@ -213,10 +207,10 @@ impl Line {
|
||||
}
|
||||
}
|
||||
}
|
||||
&Line::IndexedChoice(ref indexed_choice_instr) =>
|
||||
functors.push(indexed_choice_instr.to_functor()),
|
||||
&Line::Query(ref query_instr) =>
|
||||
functors.push(query_instr.to_functor(h)),
|
||||
&Line::IndexedChoice(ref indexed_choice_instr) => {
|
||||
functors.push(indexed_choice_instr.to_functor())
|
||||
}
|
||||
&Line::Query(ref query_instr) => functors.push(query_instr.to_functor(h)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,24 +218,16 @@ impl Line {
|
||||
#[inline]
|
||||
pub fn to_indexing_line_mut(line: &mut Line) -> Option<&mut Vec<IndexingLine>> {
|
||||
match line {
|
||||
Line::IndexingCode(ref mut indexing_code) => {
|
||||
Some(indexing_code)
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
Line::IndexingCode(ref mut indexing_code) => Some(indexing_code),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_indexing_line(line: &Line) -> Option<&Vec<IndexingLine>> {
|
||||
match line {
|
||||
Line::IndexingCode(ref indexing_code) => {
|
||||
Some(indexing_code)
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
Line::IndexingCode(ref indexing_code) => Some(indexing_code),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,11 +282,7 @@ fn arith_instr_unary_functor(
|
||||
) -> MachineStub {
|
||||
let at_stub = at.into_functor();
|
||||
|
||||
functor!(
|
||||
name,
|
||||
[aux(h, 0), integer(t)],
|
||||
[at_stub]
|
||||
)
|
||||
functor!(name, [aux(h, 0), integer(t)], [at_stub])
|
||||
}
|
||||
|
||||
fn arith_instr_bin_functor(
|
||||
@@ -383,39 +365,17 @@ impl ArithmeticInstruction {
|
||||
&ArithmeticInstruction::Gcd(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, "gcd", at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::Sign(ref 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::Tan(ref at, t) => {
|
||||
arith_instr_unary_functor(h, "tan", at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Log(ref at, t) => {
|
||||
arith_instr_unary_functor(h, "log", at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Exp(ref at, t) => {
|
||||
arith_instr_unary_functor(h, "exp", at, t)
|
||||
}
|
||||
&ArithmeticInstruction::ACos(ref at, t) => {
|
||||
arith_instr_unary_functor(h, "acos", at, t)
|
||||
}
|
||||
&ArithmeticInstruction::ASin(ref at, t) => {
|
||||
arith_instr_unary_functor(h, "asin", at, t)
|
||||
}
|
||||
&ArithmeticInstruction::ATan(ref at, t) => {
|
||||
arith_instr_unary_functor(h, "atan", at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Sqrt(ref at, t) => {
|
||||
arith_instr_unary_functor(h, "sqrt", at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Abs(ref at, t) => {
|
||||
arith_instr_unary_functor(h, "abs", at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Sign(ref 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::Tan(ref at, t) => arith_instr_unary_functor(h, "tan", at, t),
|
||||
&ArithmeticInstruction::Log(ref at, t) => arith_instr_unary_functor(h, "log", at, t),
|
||||
&ArithmeticInstruction::Exp(ref at, t) => arith_instr_unary_functor(h, "exp", at, t),
|
||||
&ArithmeticInstruction::ACos(ref at, t) => arith_instr_unary_functor(h, "acos", at, t),
|
||||
&ArithmeticInstruction::ASin(ref at, t) => arith_instr_unary_functor(h, "asin", at, t),
|
||||
&ArithmeticInstruction::ATan(ref at, t) => arith_instr_unary_functor(h, "atan", at, t),
|
||||
&ArithmeticInstruction::Sqrt(ref at, t) => arith_instr_unary_functor(h, "sqrt", at, t),
|
||||
&ArithmeticInstruction::Abs(ref at, t) => arith_instr_unary_functor(h, "abs", at, t),
|
||||
&ArithmeticInstruction::Float(ref at, t) => {
|
||||
arith_instr_unary_functor(h, "float", at, t)
|
||||
}
|
||||
@@ -431,12 +391,8 @@ impl ArithmeticInstruction {
|
||||
&ArithmeticInstruction::Floor(ref at, t) => {
|
||||
arith_instr_unary_functor(h, "floor", at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Neg(ref at, t) => {
|
||||
arith_instr_unary_functor(h, "-", at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Plus(ref at, t) => {
|
||||
arith_instr_unary_functor(h, "+", at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Neg(ref at, t) => arith_instr_unary_functor(h, "-", at, t),
|
||||
&ArithmeticInstruction::Plus(ref at, t) => arith_instr_unary_functor(h, "+", at, t),
|
||||
&ArithmeticInstruction::BitwiseComplement(ref at, t) => {
|
||||
arith_instr_unary_functor(h, "\\", at, t)
|
||||
}
|
||||
@@ -451,21 +407,18 @@ pub enum ControlInstruction {
|
||||
CallClause(ClauseType, usize, usize, bool, bool),
|
||||
Deallocate,
|
||||
JmpBy(usize, usize, usize, bool), // arity, global_offset, perm_vars after threshold, last call.
|
||||
RevJmpBy(usize), // notice the lack of context change as in
|
||||
// JmpBy. RevJmpBy is used only to patch extensible
|
||||
// predicates together.
|
||||
RevJmpBy(usize), // notice the lack of context change as in
|
||||
// JmpBy. RevJmpBy is used only to patch extensible
|
||||
// predicates together.
|
||||
Proceed,
|
||||
}
|
||||
|
||||
impl ControlInstruction {
|
||||
pub fn perm_vars(&self) -> Option<usize> {
|
||||
match self {
|
||||
ControlInstruction::CallClause(_, _, num_cells, ..) =>
|
||||
Some(*num_cells),
|
||||
ControlInstruction::JmpBy(_, _, num_cells, ..) =>
|
||||
Some(*num_cells),
|
||||
_ =>
|
||||
None
|
||||
ControlInstruction::CallClause(_, _, num_cells, ..) => Some(*num_cells),
|
||||
ControlInstruction::JmpBy(_, _, num_cells, ..) => Some(*num_cells),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -500,7 +453,13 @@ impl ControlInstruction {
|
||||
#[derive(Debug)]
|
||||
pub enum IndexingInstruction {
|
||||
// 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>),
|
||||
SwitchOnStructure(IndexMap<(ClauseName, usize), IndexingCodePtr>),
|
||||
}
|
||||
@@ -511,11 +470,13 @@ impl IndexingInstruction {
|
||||
&IndexingInstruction::SwitchOnTerm(arg, vars, constants, lists, structures) => {
|
||||
functor!(
|
||||
"switch_on_term",
|
||||
[integer(arg),
|
||||
integer(vars),
|
||||
indexing_code_ptr(h, constants),
|
||||
indexing_code_ptr(h, lists),
|
||||
indexing_code_ptr(h, structures)]
|
||||
[
|
||||
integer(arg),
|
||||
integer(vars),
|
||||
indexing_code_ptr(h, constants),
|
||||
indexing_code_ptr(h, lists),
|
||||
indexing_code_ptr(h, structures)
|
||||
]
|
||||
)
|
||||
}
|
||||
&IndexingInstruction::SwitchOnConstant(ref constants) => {
|
||||
@@ -528,15 +489,14 @@ impl IndexingInstruction {
|
||||
let key_value_pair = functor!(
|
||||
":",
|
||||
SharedOpDesc::new(600, XFY),
|
||||
[constant(c),
|
||||
indexing_code_ptr(h + 3, *ptr)]
|
||||
[constant(c), 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::Str(h + 3)));
|
||||
key_value_list_stub.push(HeapCellValue::Addr(
|
||||
Addr::HeapCell(h + 3 + key_value_pair.len())
|
||||
));
|
||||
key_value_list_stub.push(HeapCellValue::Addr(Addr::HeapCell(
|
||||
h + 3 + key_value_pair.len(),
|
||||
)));
|
||||
|
||||
h += key_value_pair.len() + 3;
|
||||
key_value_list_stub.extend(key_value_pair.into_iter());
|
||||
@@ -560,23 +520,21 @@ impl IndexingInstruction {
|
||||
let predicate_indicator_stub = functor!(
|
||||
"/",
|
||||
SharedOpDesc::new(400, YFX),
|
||||
[clause_name(name.clone()),
|
||||
integer(*arity)]
|
||||
[clause_name(name.clone()), integer(*arity)]
|
||||
);
|
||||
|
||||
let key_value_pair = functor!(
|
||||
":",
|
||||
SharedOpDesc::new(600, XFY),
|
||||
[aux(h + 3, 0),
|
||||
indexing_code_ptr(h + 3, *ptr)],
|
||||
[aux(h + 3, 0), indexing_code_ptr(h + 3, *ptr)],
|
||||
[predicate_indicator_stub]
|
||||
);
|
||||
|
||||
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::HeapCell(h + 3 + key_value_pair.len())
|
||||
));
|
||||
key_value_list_stub.push(HeapCellValue::Addr(Addr::HeapCell(
|
||||
h + 3 + key_value_pair.len(),
|
||||
)));
|
||||
|
||||
h += key_value_pair.len() + 3;
|
||||
key_value_list_stub.extend(key_value_pair.into_iter());
|
||||
@@ -614,7 +572,7 @@ impl FactInstruction {
|
||||
match self {
|
||||
&FactInstruction::GetConstant(lvl, ref c, r) => {
|
||||
let lvl_stub = lvl.into_functor();
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"get_constant",
|
||||
@@ -624,17 +582,13 @@ impl FactInstruction {
|
||||
}
|
||||
&FactInstruction::GetList(lvl, r) => {
|
||||
let lvl_stub = lvl.into_functor();
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"get_list",
|
||||
[aux(h, 0), aux(h, 1)],
|
||||
[lvl_stub, rt_stub]
|
||||
)
|
||||
functor!("get_list", [aux(h, 0), aux(h, 1)], [lvl_stub, rt_stub])
|
||||
}
|
||||
&FactInstruction::GetPartialString(lvl, ref s, r, has_tail) => {
|
||||
let lvl_stub = lvl.into_functor();
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"get_partial_string",
|
||||
@@ -654,20 +608,12 @@ impl FactInstruction {
|
||||
&FactInstruction::GetValue(r, arg) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"get_value",
|
||||
[aux(h, 0), integer(arg)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("get_value", [aux(h, 0), integer(arg)], [rt_stub])
|
||||
}
|
||||
&FactInstruction::GetVariable(r, arg) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"get_variable",
|
||||
[aux(h, 0), integer(arg)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("get_variable", [aux(h, 0), integer(arg)], [rt_stub])
|
||||
}
|
||||
&FactInstruction::UnifyConstant(ref c) => {
|
||||
functor!("unify_constant", [constant(h, c)], [])
|
||||
@@ -675,29 +621,17 @@ impl FactInstruction {
|
||||
&FactInstruction::UnifyLocalValue(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"unify_local_value",
|
||||
[aux(h, 0)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("unify_local_value", [aux(h, 0)], [rt_stub])
|
||||
}
|
||||
&FactInstruction::UnifyVariable(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"unify_variable",
|
||||
[aux(h, 0)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("unify_variable", [aux(h, 0)], [rt_stub])
|
||||
}
|
||||
&FactInstruction::UnifyValue(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"unify_value",
|
||||
[aux(h, 0)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("unify_value", [aux(h, 0)], [rt_stub])
|
||||
}
|
||||
&FactInstruction::UnifyVoid(vars) => {
|
||||
functor!("unify_void", [integer(vars)])
|
||||
@@ -726,13 +660,12 @@ pub enum QueryInstruction {
|
||||
impl QueryInstruction {
|
||||
pub fn to_functor(&self, h: usize) -> MachineStub {
|
||||
match self {
|
||||
&QueryInstruction::PutUnsafeValue(norm, arg) => functor!(
|
||||
"put_unsafe_value",
|
||||
[integer(norm), integer(arg)]
|
||||
),
|
||||
&QueryInstruction::PutUnsafeValue(norm, arg) => {
|
||||
functor!("put_unsafe_value", [integer(norm), integer(arg)])
|
||||
}
|
||||
&QueryInstruction::PutConstant(lvl, ref c, r) => {
|
||||
let lvl_stub = lvl.into_functor();
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"put_constant",
|
||||
@@ -742,17 +675,13 @@ impl QueryInstruction {
|
||||
}
|
||||
&QueryInstruction::PutList(lvl, r) => {
|
||||
let lvl_stub = lvl.into_functor();
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"put_list",
|
||||
[aux(h, 0), aux(h, 1)],
|
||||
[lvl_stub, rt_stub]
|
||||
)
|
||||
functor!("put_list", [aux(h, 0), aux(h, 1)], [lvl_stub, rt_stub])
|
||||
}
|
||||
&QueryInstruction::PutPartialString(lvl, ref s, r, has_tail) => {
|
||||
let lvl_stub = lvl.into_functor();
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"put_partial_string",
|
||||
@@ -772,29 +701,17 @@ impl QueryInstruction {
|
||||
&QueryInstruction::PutValue(r, arg) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"put_value",
|
||||
[aux(h, 0), integer(arg)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("put_value", [aux(h, 0), integer(arg)], [rt_stub])
|
||||
}
|
||||
&QueryInstruction::GetVariable(r, arg) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"get_variable",
|
||||
[aux(h, 0), integer(arg)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("get_variable", [aux(h, 0), integer(arg)], [rt_stub])
|
||||
}
|
||||
&QueryInstruction::PutVariable(r, arg) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"put_variable",
|
||||
[aux(h, 0), integer(arg)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("put_variable", [aux(h, 0), integer(arg)], [rt_stub])
|
||||
}
|
||||
&QueryInstruction::SetConstant(ref c) => {
|
||||
functor!("set_constant", [constant(h, c)], [])
|
||||
@@ -802,29 +719,17 @@ impl QueryInstruction {
|
||||
&QueryInstruction::SetLocalValue(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"set_local_value",
|
||||
[aux(h, 0)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("set_local_value", [aux(h, 0)], [rt_stub])
|
||||
}
|
||||
&QueryInstruction::SetVariable(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"set_variable",
|
||||
[aux(h, 0)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("set_variable", [aux(h, 0)], [rt_stub])
|
||||
}
|
||||
&QueryInstruction::SetValue(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"set_value",
|
||||
[aux(h, 0)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("set_value", [aux(h, 0)], [rt_stub])
|
||||
}
|
||||
&QueryInstruction::SetVoid(vars) => {
|
||||
functor!("set_void", [integer(vars)])
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::rc_atom;
|
||||
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
@@ -25,11 +26,11 @@ impl<'a> TermRef<'a> {
|
||||
pub fn level(self) -> Level {
|
||||
match self {
|
||||
TermRef::AnonVar(lvl)
|
||||
| TermRef::Cons(lvl, ..)
|
||||
| TermRef::Constant(lvl, ..)
|
||||
| TermRef::Var(lvl, ..)
|
||||
| TermRef::Clause(lvl, ..) => lvl,
|
||||
| TermRef::PartialString(lvl, ..) => lvl,
|
||||
| TermRef::Cons(lvl, ..)
|
||||
| TermRef::Constant(lvl, ..)
|
||||
| TermRef::Var(lvl, ..)
|
||||
| TermRef::Clause(lvl, ..) => lvl,
|
||||
TermRef::PartialString(lvl, ..) => lvl,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,23 +52,16 @@ pub enum TermIterState<'a> {
|
||||
Var(Level, &'a Cell<VarReg>, Rc<Var>),
|
||||
}
|
||||
|
||||
fn is_partial_string<'a>(
|
||||
head: &'a Term,
|
||||
mut tail: &'a Term,
|
||||
) -> Option<(String, Option<&'a Term>)>
|
||||
{
|
||||
let mut string =
|
||||
match head {
|
||||
&Term::Constant(_, Constant::Atom(ref atom, _)) if atom.is_char() => {
|
||||
atom.as_str().chars().next().unwrap().to_string()
|
||||
}
|
||||
&Term::Constant(_, Constant::Char(c)) => {
|
||||
c.to_string()
|
||||
}
|
||||
_ => {
|
||||
return None;
|
||||
}
|
||||
};
|
||||
fn is_partial_string<'a>(head: &'a Term, mut tail: &'a Term) -> Option<(String, Option<&'a Term>)> {
|
||||
let mut string = match head {
|
||||
&Term::Constant(_, Constant::Atom(ref atom, _)) if atom.is_char() => {
|
||||
atom.as_str().chars().next().unwrap().to_string()
|
||||
}
|
||||
&Term::Constant(_, Constant::Char(c)) => c.to_string(),
|
||||
_ => {
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
while let Term::Cons(_, ref head, ref succ) = tail {
|
||||
match head.as_ref() {
|
||||
@@ -105,9 +99,7 @@ fn is_partial_string<'a>(
|
||||
impl<'a> TermIterState<'a> {
|
||||
pub fn subterm_to_state(lvl: Level, term: &'a Term) -> TermIterState<'a> {
|
||||
match term {
|
||||
&Term::AnonVar => {
|
||||
TermIterState::AnonVar(lvl)
|
||||
}
|
||||
&Term::AnonVar => TermIterState::AnonVar(lvl),
|
||||
&Term::Clause(ref cell, ref name, ref subterms, ref spec) => {
|
||||
let ct = if let Some(spec) = spec {
|
||||
ClauseType::Op(name.clone(), spec.clone(), CodeIndex::default())
|
||||
@@ -120,12 +112,8 @@ impl<'a> TermIterState<'a> {
|
||||
&Term::Cons(ref cell, ref head, ref tail) => {
|
||||
TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref())
|
||||
}
|
||||
&Term::Constant(ref cell, ref constant) => {
|
||||
TermIterState::Constant(lvl, cell, constant)
|
||||
}
|
||||
&Term::Var(ref cell, ref var) => {
|
||||
TermIterState::Var(lvl, cell, var.clone())
|
||||
}
|
||||
&Term::Constant(ref cell, ref constant) => TermIterState::Constant(lvl, cell, constant),
|
||||
&Term::Var(ref cell, ref var) => TermIterState::Var(lvl, cell, var.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,8 +163,7 @@ impl<'a> QueryIterator<'a> {
|
||||
state_stack: vec![],
|
||||
}
|
||||
}
|
||||
&Term::Var(ref cell, ref var) =>
|
||||
TermIterState::Var(Level::Root, cell, (*var).clone()),
|
||||
&Term::Var(ref cell, ref var) => TermIterState::Var(Level::Root, cell, (*var).clone()),
|
||||
};
|
||||
|
||||
QueryIterator {
|
||||
@@ -265,18 +252,15 @@ impl<'a> Iterator for QueryIterator<'a> {
|
||||
}
|
||||
TermIterState::InitialCons(lvl, cell, head, tail) => {
|
||||
if let Some((string, tail)) = is_partial_string(head, tail) {
|
||||
self.state_stack.push(TermIterState::PartialString(
|
||||
lvl,
|
||||
cell,
|
||||
string,
|
||||
tail,
|
||||
));
|
||||
self.state_stack
|
||||
.push(TermIterState::PartialString(lvl, cell, string, tail));
|
||||
|
||||
if let Some(tail) = tail {
|
||||
self.push_subterm(lvl.child_level(), tail);
|
||||
}
|
||||
} 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(), head);
|
||||
@@ -309,7 +293,8 @@ pub struct FactIterator<'a> {
|
||||
|
||||
impl<'a> FactIterator<'a> {
|
||||
fn push_subterm(&mut self, lvl: Level, term: &'a Term) {
|
||||
self.state_queue.push_back(TermIterState::subterm_to_state(lvl, term));
|
||||
self.state_queue
|
||||
.push_back(TermIterState::subterm_to_state(lvl, term));
|
||||
}
|
||||
|
||||
pub fn from_rule_head_clause(terms: &'a Vec<Box<Term>>) -> Self {
|
||||
@@ -393,8 +378,7 @@ impl<'a> Iterator for FactIterator<'a> {
|
||||
TermIterState::Var(lvl, cell, var) => {
|
||||
return Some(TermRef::Var(lvl, cell, var));
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -481,16 +465,16 @@ impl<'a> ChunkedIterator<'a> {
|
||||
}
|
||||
}))
|
||||
}
|
||||
/*
|
||||
pub fn from_term_sequence(terms: &'a [QueryTerm]) -> Self {
|
||||
ChunkedIterator {
|
||||
chunk_num: 0,
|
||||
iter: Box::new(terms.iter().map(|t| ChunkedTerm::BodyTerm(t))),
|
||||
deep_cut_encountered: false,
|
||||
cut_var_in_head: false,
|
||||
/*
|
||||
pub fn from_term_sequence(terms: &'a [QueryTerm]) -> Self {
|
||||
ChunkedIterator {
|
||||
chunk_num: 0,
|
||||
iter: Box::new(terms.iter().map(|t| ChunkedTerm::BodyTerm(t))),
|
||||
deep_cut_encountered: false,
|
||||
cut_var_in_head: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
*/
|
||||
pub fn from_rule_body(p1: &'a QueryTerm, clauses: &'a Vec<QueryTerm>) -> Self {
|
||||
let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1)));
|
||||
let iter = inner_iter.chain(clauses.iter().map(|t| ChunkedTerm::BodyTerm(t)));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::divrem::*;
|
||||
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::clause_name;
|
||||
|
||||
use crate::arithmetic::*;
|
||||
use crate::clause_types::*;
|
||||
@@ -19,19 +20,16 @@ use std::rc::Rc;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! try_numeric_result {
|
||||
($s: ident, $e: expr, $caller: expr) => (
|
||||
($s: ident, $e: expr, $caller: expr) => {
|
||||
match $e {
|
||||
Ok(val) => {
|
||||
Ok(val)
|
||||
}
|
||||
Ok(val) => Ok(val),
|
||||
Err(e) => {
|
||||
let caller_copy =
|
||||
$caller.iter().map(|v| v.context_free_clone()).collect();
|
||||
let caller_copy = $caller.iter().map(|v| v.context_free_clone()).collect();
|
||||
|
||||
Err($s.error_form(MachineError::evaluation_error(e), caller_copy))
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
fn isize_gcd(n1: isize, n2: isize) -> Option<isize> {
|
||||
@@ -83,52 +81,29 @@ fn isize_gcd(n1: isize, n2: isize) -> Option<isize> {
|
||||
}
|
||||
|
||||
impl MachineState {
|
||||
pub(crate)
|
||||
fn get_number(&mut self, at: &ArithmeticTerm) -> Result<Number, MachineStub> {
|
||||
pub(crate) fn get_number(&mut self, at: &ArithmeticTerm) -> Result<Number, MachineStub> {
|
||||
match at {
|
||||
&ArithmeticTerm::Reg(r) => {
|
||||
self.arith_eval_by_metacall(r)
|
||||
}
|
||||
&ArithmeticTerm::Interm(i) => Ok(mem::replace(
|
||||
&mut self.interms[i - 1],
|
||||
Number::Fixnum(0),
|
||||
)),
|
||||
&ArithmeticTerm::Number(ref n) => {
|
||||
Ok(n.clone())
|
||||
&ArithmeticTerm::Reg(r) => self.arith_eval_by_metacall(r),
|
||||
&ArithmeticTerm::Interm(i) => {
|
||||
Ok(mem::replace(&mut self.interms[i - 1], Number::Fixnum(0)))
|
||||
}
|
||||
&ArithmeticTerm::Number(ref n) => Ok(n.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn rational_from_number(
|
||||
&self,
|
||||
n: Number,
|
||||
) -> Result<Rc<Rational>, MachineError> {
|
||||
pub(super) fn rational_from_number(&self, n: Number) -> Result<Rc<Rational>, MachineError> {
|
||||
match n {
|
||||
Number::Fixnum(n) => {
|
||||
Ok(Rc::new(Rational::from(n)))
|
||||
}
|
||||
Number::Rational(r) => {
|
||||
Ok(r)
|
||||
}
|
||||
Number::Float(OrderedFloat(f)) => {
|
||||
match Rational::from_f64(f) {
|
||||
Some(r) => {
|
||||
Ok(Rc::new(r))
|
||||
}
|
||||
None => {
|
||||
Err(MachineError::instantiation_error())
|
||||
}
|
||||
}
|
||||
}
|
||||
Number::Integer(n) => {
|
||||
Ok(Rc::new(Rational::from(&*n)))
|
||||
}
|
||||
Number::Fixnum(n) => Ok(Rc::new(Rational::from(n))),
|
||||
Number::Rational(r) => Ok(r),
|
||||
Number::Float(OrderedFloat(f)) => match Rational::from_f64(f) {
|
||||
Some(r) => Ok(Rc::new(r)),
|
||||
None => Err(MachineError::instantiation_error()),
|
||||
},
|
||||
Number::Integer(n) => Ok(Rc::new(Rational::from(&*n))),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn get_rational(
|
||||
pub(crate) fn get_rational(
|
||||
&mut self,
|
||||
at: &ArithmeticTerm,
|
||||
caller: MachineStub,
|
||||
@@ -137,12 +112,11 @@ impl MachineState {
|
||||
|
||||
match self.rational_from_number(n) {
|
||||
Ok(r) => Ok((r, caller)),
|
||||
Err(e) => Err(self.error_form(e, caller))
|
||||
Err(e) => Err(self.error_form(e, caller)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn arith_eval_by_metacall(&self, r: RegType) -> Result<Number, MachineStub> {
|
||||
pub(crate) fn arith_eval_by_metacall(&self, r: RegType) -> Result<Number, MachineStub> {
|
||||
let caller = MachineError::functor_stub(clause_name!("is"), 2);
|
||||
let mut interms: Vec<Number> = Vec::with_capacity(64);
|
||||
|
||||
@@ -163,9 +137,8 @@ impl MachineState {
|
||||
"min" => interms.push(self.min(a1, a2)?),
|
||||
"rdiv" => {
|
||||
let r1 = self.rational_from_number(a1);
|
||||
let r2 = r1.and_then(|r1| {
|
||||
self.rational_from_number(a2).map(|r2| (r1, r2))
|
||||
});
|
||||
let r2 =
|
||||
r1.and_then(|r1| self.rational_from_number(a2).map(|r2| (r1, r2)));
|
||||
|
||||
match r2 {
|
||||
Ok((r1, r2)) => {
|
||||
@@ -242,18 +215,12 @@ impl MachineState {
|
||||
&HeapCellValue::Addr(Addr::Fixnum(n)) => {
|
||||
interms.push(Number::Fixnum(n));
|
||||
}
|
||||
&HeapCellValue::Addr(Addr::Float(n)) => {
|
||||
interms.push(Number::Float(n))
|
||||
}
|
||||
&HeapCellValue::Integer(ref n) => {
|
||||
interms.push(Number::Integer(n.clone()))
|
||||
}
|
||||
&HeapCellValue::Addr(Addr::Float(n)) => interms.push(Number::Float(n)),
|
||||
&HeapCellValue::Integer(ref n) => interms.push(Number::Integer(n.clone())),
|
||||
&HeapCellValue::Addr(Addr::Usize(n)) => {
|
||||
interms.push(Number::Integer(Rc::new(Integer::from(n))));
|
||||
}
|
||||
&HeapCellValue::Rational(ref n) => {
|
||||
interms.push(Number::Rational(n.clone()))
|
||||
}
|
||||
&HeapCellValue::Rational(ref n) => interms.push(Number::Rational(n.clone())),
|
||||
&HeapCellValue::Atom(ref name, _) if name.as_str() == "pi" => {
|
||||
interms.push(Number::Float(OrderedFloat(f64::consts::PI)))
|
||||
}
|
||||
@@ -282,10 +249,7 @@ impl MachineState {
|
||||
));
|
||||
}
|
||||
&HeapCellValue::Addr(addr) if addr.is_ref() => {
|
||||
return Err(self.error_form(
|
||||
MachineError::instantiation_error(),
|
||||
caller,
|
||||
));
|
||||
return Err(self.error_form(MachineError::instantiation_error(), caller));
|
||||
}
|
||||
val => {
|
||||
return Err(self.type_error(
|
||||
@@ -301,8 +265,7 @@ impl MachineState {
|
||||
Ok(interms.pop().unwrap())
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn rdiv(&self, r1: Rc<Rational>, r2: Rc<Rational>) -> Result<Rational, MachineStub> {
|
||||
pub(crate) fn rdiv(&self, r1: Rc<Rational>, r2: Rc<Rational>) -> Result<Rational, MachineStub> {
|
||||
if &*r2 == &0 {
|
||||
let stub = MachineError::functor_stub(clause_name!("(rdiv)"), 2);
|
||||
Err(self.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||
@@ -311,27 +274,21 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn int_floor_div(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
pub(crate) fn int_floor_div(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
let stub = MachineError::functor_stub(clause_name!("(div)"), 2);
|
||||
let modulus = self.modulus(n1.clone(), n2.clone())?;
|
||||
|
||||
self.idiv(try_numeric_result!(self, n1 - modulus, stub)?, n2)
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn idiv(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
pub(crate) fn idiv(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
match (n1, n2) {
|
||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||
if n2 == 0 {
|
||||
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
|
||||
|
||||
Err(self.error_form(
|
||||
MachineError::evaluation_error(
|
||||
EvalError::ZeroDivisor
|
||||
),
|
||||
stub,
|
||||
))
|
||||
Err(self
|
||||
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||
} else {
|
||||
if let Some(result) = n1.checked_div(n2) {
|
||||
Ok(Number::from(result))
|
||||
@@ -347,12 +304,8 @@ impl MachineState {
|
||||
if &*n2 == &0 {
|
||||
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
|
||||
|
||||
Err(self.error_form(
|
||||
MachineError::evaluation_error(
|
||||
EvalError::ZeroDivisor
|
||||
),
|
||||
stub,
|
||||
))
|
||||
Err(self
|
||||
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||
} else {
|
||||
Ok(Number::from(Integer::from(n1) / &*n2))
|
||||
}
|
||||
@@ -361,12 +314,8 @@ impl MachineState {
|
||||
if n1 == 0 {
|
||||
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
|
||||
|
||||
Err(self.error_form(
|
||||
MachineError::evaluation_error(
|
||||
EvalError::ZeroDivisor
|
||||
),
|
||||
stub,
|
||||
))
|
||||
Err(self
|
||||
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||
} else {
|
||||
Ok(Number::from(&*n2 / Integer::from(n1)))
|
||||
}
|
||||
@@ -375,25 +324,19 @@ impl MachineState {
|
||||
if &*n2 == &0 {
|
||||
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
|
||||
|
||||
Err(self.error_form(
|
||||
MachineError::evaluation_error(
|
||||
EvalError::ZeroDivisor
|
||||
),
|
||||
stub,
|
||||
))
|
||||
Err(self
|
||||
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||
} else {
|
||||
Ok(Number::from(<(Integer, Integer)>::from(n1.div_rem_ref(&*n2)).0))
|
||||
Ok(Number::from(
|
||||
<(Integer, Integer)>::from(n1.div_rem_ref(&*n2)).0,
|
||||
))
|
||||
}
|
||||
}
|
||||
(Number::Fixnum(_), n2) | (Number::Integer(_), n2) => {
|
||||
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
|
||||
|
||||
Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Integer,
|
||||
n2,
|
||||
),
|
||||
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
|
||||
stub,
|
||||
))
|
||||
}
|
||||
@@ -401,19 +344,14 @@ impl MachineState {
|
||||
let stub = MachineError::functor_stub(clause_name!("(//)"), 2);
|
||||
|
||||
Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Integer,
|
||||
n1,
|
||||
),
|
||||
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
|
||||
stub,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn div(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
pub(crate) fn div(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
let stub = MachineError::functor_stub(clause_name!("(/)"), 2);
|
||||
|
||||
if n2.is_zero() {
|
||||
@@ -423,8 +361,7 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn atan2(&self, n1: Number, n2: Number) -> Result<f64, MachineStub> {
|
||||
pub(crate) fn atan2(&self, n1: Number, n2: Number) -> Result<f64, MachineStub> {
|
||||
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
||||
|
||||
if n1.is_zero() && n2.is_zero() {
|
||||
@@ -437,8 +374,7 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn int_pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
pub(crate) fn int_pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
if n1.is_zero() && n2.is_negative() {
|
||||
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
||||
return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub));
|
||||
@@ -451,11 +387,7 @@ impl MachineState {
|
||||
let stub = MachineError::functor_stub(clause_name!("^"), 2);
|
||||
|
||||
Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Float,
|
||||
n
|
||||
),
|
||||
MachineError::type_error(self.heap.h(), ValidType::Float, n),
|
||||
stub,
|
||||
))
|
||||
} else {
|
||||
@@ -477,11 +409,7 @@ impl MachineState {
|
||||
let stub = MachineError::functor_stub(clause_name!("^"), 2);
|
||||
|
||||
Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Float,
|
||||
n
|
||||
),
|
||||
MachineError::type_error(self.heap.h(), ValidType::Float, n),
|
||||
stub,
|
||||
))
|
||||
} else {
|
||||
@@ -495,11 +423,7 @@ impl MachineState {
|
||||
let stub = MachineError::functor_stub(clause_name!("^"), 2);
|
||||
|
||||
Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Float,
|
||||
n
|
||||
),
|
||||
MachineError::type_error(self.heap.h(), ValidType::Float, n),
|
||||
stub,
|
||||
))
|
||||
} else {
|
||||
@@ -513,11 +437,7 @@ impl MachineState {
|
||||
let stub = MachineError::functor_stub(clause_name!("^"), 2);
|
||||
|
||||
Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Float,
|
||||
n
|
||||
),
|
||||
MachineError::type_error(self.heap.h(), ValidType::Float, n),
|
||||
stub,
|
||||
))
|
||||
} else {
|
||||
@@ -548,8 +468,7 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn gcd(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
pub(crate) fn gcd(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
match (n1, n2) {
|
||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||
if let Some(result) = isize_gcd(n1, n2) {
|
||||
@@ -558,8 +477,8 @@ impl MachineState {
|
||||
Ok(Number::from(Integer::from(n1).gcd(&Integer::from(n2))))
|
||||
}
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Integer(n2)) |
|
||||
(Number::Integer(n2), Number::Fixnum(n1)) => {
|
||||
(Number::Fixnum(n1), Number::Integer(n2))
|
||||
| (Number::Integer(n2), Number::Fixnum(n1)) => {
|
||||
let n1 = Integer::from(n1);
|
||||
Ok(Number::from(Integer::from(n2.gcd_ref(&n1))))
|
||||
}
|
||||
@@ -571,11 +490,7 @@ impl MachineState {
|
||||
let stub = MachineError::functor_stub(clause_name!("gcd"), 2);
|
||||
|
||||
Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Integer,
|
||||
n
|
||||
),
|
||||
MachineError::type_error(self.heap.h(), ValidType::Integer, n),
|
||||
stub,
|
||||
))
|
||||
}
|
||||
@@ -584,19 +499,14 @@ impl MachineState {
|
||||
let stub = MachineError::functor_stub(clause_name!("gcd"), 2);
|
||||
|
||||
Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Integer,
|
||||
n,
|
||||
),
|
||||
MachineError::type_error(self.heap.h(), ValidType::Integer, n),
|
||||
stub,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn float_pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
pub(crate) fn float_pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
let f1 = result_f(&n1, rnd_f);
|
||||
let f2 = result_f(&n2, rnd_f);
|
||||
|
||||
@@ -612,8 +522,12 @@ impl MachineState {
|
||||
)?)))
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn pow(&self, n1: Number, n2: Number, culprit: &'static str) -> Result<Number, MachineStub> {
|
||||
pub(crate) fn pow(
|
||||
&self,
|
||||
n1: Number,
|
||||
n2: Number,
|
||||
culprit: &'static str,
|
||||
) -> Result<Number, MachineStub> {
|
||||
if n2.is_negative() && n1.is_zero() {
|
||||
let stub = MachineError::functor_stub(clause_name!(culprit), 2);
|
||||
return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub));
|
||||
@@ -623,8 +537,11 @@ impl MachineState {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn unary_float_fn_template<FloatFn>(&self, n1: Number, f: FloatFn) -> Result<f64, MachineStub>
|
||||
pub(crate) fn unary_float_fn_template<FloatFn>(
|
||||
&self,
|
||||
n1: Number,
|
||||
f: FloatFn,
|
||||
) -> Result<f64, MachineStub>
|
||||
where
|
||||
FloatFn: Fn(f64) -> f64,
|
||||
{
|
||||
@@ -637,56 +554,47 @@ impl MachineState {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn sin(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||
pub(crate) fn sin(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||
self.unary_float_fn_template(n1, |f| f.sin())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn cos(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||
pub(crate) fn cos(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||
self.unary_float_fn_template(n1, |f| f.cos())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn tan(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||
pub(crate) fn tan(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||
self.unary_float_fn_template(n1, |f| f.tan())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn log(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||
pub(crate) fn log(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||
self.unary_float_fn_template(n1, |f| f.log(f64::consts::E))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn exp(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||
pub(crate) fn exp(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||
self.unary_float_fn_template(n1, |f| f.exp())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn asin(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||
pub(crate) fn asin(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||
self.unary_float_fn_template(n1, |f| f.asin())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn acos(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||
pub(crate) fn acos(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||
self.unary_float_fn_template(n1, |f| f.acos())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn atan(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||
pub(crate) fn atan(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||
self.unary_float_fn_template(n1, |f| f.atan())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn sqrt(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||
pub(crate) fn sqrt(&self, n1: Number) -> Result<f64, MachineStub> {
|
||||
if n1.is_negative() {
|
||||
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
||||
return Err(self.error_form(MachineError::evaluation_error(EvalError::Undefined), stub));
|
||||
@@ -696,27 +604,23 @@ impl MachineState {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn float(&self, n: Number) -> Result<f64, MachineStub> {
|
||||
pub(crate) fn float(&self, n: Number) -> Result<f64, MachineStub> {
|
||||
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
||||
try_numeric_result!(self, result_f(&n, rnd_f), stub)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn floor(&self, n1: Number) -> Number {
|
||||
pub(crate) fn floor(&self, n1: Number) -> Number {
|
||||
rnd_i(&n1).to_owned()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn ceiling(&self, n1: Number) -> Number {
|
||||
pub(crate) fn ceiling(&self, n1: Number) -> Number {
|
||||
-self.floor(-n1)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn truncate(&self, n: Number) -> Number {
|
||||
pub(crate) fn truncate(&self, n: Number) -> Number {
|
||||
if n.is_negative() {
|
||||
-self.floor(n.abs())
|
||||
} else {
|
||||
@@ -724,8 +628,7 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn round(&self, n: Number) -> Result<Number, MachineStub> {
|
||||
pub(crate) fn round(&self, n: Number) -> Result<Number, MachineStub> {
|
||||
let stub = MachineError::functor_stub(clause_name!("is"), 2);
|
||||
|
||||
let result = n + Number::Float(OrderedFloat(0.5f64));
|
||||
@@ -734,8 +637,7 @@ impl MachineState {
|
||||
Ok(self.floor(result))
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn shr(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
pub(crate) fn shr(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
let stub = MachineError::functor_stub(clause_name!("(>>)"), 2);
|
||||
|
||||
match (n1, n2) {
|
||||
@@ -756,38 +658,26 @@ impl MachineState {
|
||||
_ => Ok(Number::from(n1 >> u32::max_value())),
|
||||
}
|
||||
}
|
||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
||||
match u32::try_from(n2) {
|
||||
Ok(n2) => Ok(Number::from(Integer::from(&*n1 >> n2))),
|
||||
_ => Ok(Number::from(Integer::from(&*n1 >> u32::max_value()))),
|
||||
}
|
||||
}
|
||||
(Number::Integer(n1), Number::Integer(n2)) =>
|
||||
match n2.to_u32() {
|
||||
Some(n2) => Ok(Number::from(Integer::from(&*n1 >> n2))),
|
||||
_ => Ok(Number::from(Integer::from(&*n1 >> u32::max_value()))),
|
||||
},
|
||||
(Number::Integer(n1), Number::Fixnum(n2)) => match u32::try_from(n2) {
|
||||
Ok(n2) => Ok(Number::from(Integer::from(&*n1 >> n2))),
|
||||
_ => Ok(Number::from(Integer::from(&*n1 >> u32::max_value()))),
|
||||
},
|
||||
(Number::Integer(n1), Number::Integer(n2)) => match n2.to_u32() {
|
||||
Some(n2) => Ok(Number::from(Integer::from(&*n1 >> n2))),
|
||||
_ => Ok(Number::from(Integer::from(&*n1 >> u32::max_value()))),
|
||||
},
|
||||
(Number::Integer(_), n2) => Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Integer,
|
||||
n2,
|
||||
),
|
||||
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
|
||||
stub,
|
||||
)),
|
||||
(n1, _) => Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Integer,
|
||||
n1,
|
||||
),
|
||||
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
|
||||
stub,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn shl(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
pub(crate) fn shl(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
let stub = MachineError::functor_stub(clause_name!("(<<)"), 2);
|
||||
|
||||
match (n1, n2) {
|
||||
@@ -808,263 +698,181 @@ impl MachineState {
|
||||
_ => Ok(Number::from(n1 << u32::max_value())),
|
||||
}
|
||||
}
|
||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
||||
match u32::try_from(n2) {
|
||||
Ok(n2) => Ok(Number::from(Integer::from(&*n1 << n2))),
|
||||
_ => Ok(Number::from(Integer::from(&*n1 << u32::max_value()))),
|
||||
}
|
||||
}
|
||||
(Number::Integer(n1), Number::Fixnum(n2)) => match u32::try_from(n2) {
|
||||
Ok(n2) => Ok(Number::from(Integer::from(&*n1 << n2))),
|
||||
_ => Ok(Number::from(Integer::from(&*n1 << u32::max_value()))),
|
||||
},
|
||||
(Number::Integer(n1), Number::Integer(n2)) => match n2.to_u32() {
|
||||
Some(n2) => Ok(Number::from(Integer::from(&*n1 << n2))),
|
||||
_ => Ok(Number::from(Integer::from(&*n1 << u32::max_value()))),
|
||||
},
|
||||
(Number::Integer(_), n2) => Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Integer,
|
||||
n2,
|
||||
),
|
||||
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
|
||||
stub,
|
||||
)),
|
||||
(n1, _) => Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Integer,
|
||||
n1,
|
||||
),
|
||||
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
|
||||
stub,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn bitwise_complement(&self, n1: Number) -> Result<Number, MachineStub> {
|
||||
pub(crate) fn bitwise_complement(&self, n1: Number) -> Result<Number, MachineStub> {
|
||||
let stub = MachineError::functor_stub(clause_name!("(\\)"), 2);
|
||||
|
||||
match n1 {
|
||||
Number::Fixnum(n) => Ok(Number::Fixnum(!n)),
|
||||
Number::Integer(n1) => Ok(Number::from(Integer::from(!&*n1))),
|
||||
_ => Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Integer,
|
||||
n1,
|
||||
),
|
||||
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
|
||||
stub,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn xor(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
pub(crate) fn xor(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
let stub = MachineError::functor_stub(clause_name!("(xor)"), 2);
|
||||
|
||||
match (n1, n2) {
|
||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||
Ok(Number::from(n1 ^ n2))
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => Ok(Number::from(n1 ^ n2)),
|
||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||
let n1 = Integer::from(n1);
|
||||
Ok(Number::from(n1 ^ &*n2))
|
||||
}
|
||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
||||
Ok(Number::from(&*n1 ^ Integer::from(n2)))
|
||||
}
|
||||
(Number::Integer(n1), Number::Fixnum(n2)) => Ok(Number::from(&*n1 ^ Integer::from(n2))),
|
||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||
Ok(Number::from(Integer::from(&*n1 ^ &*n2)))
|
||||
}
|
||||
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => {
|
||||
Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Integer,
|
||||
n2
|
||||
),
|
||||
stub,
|
||||
))
|
||||
}
|
||||
(n1, _) => {
|
||||
Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Integer,
|
||||
n1
|
||||
),
|
||||
stub,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn and(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
let stub = MachineError::functor_stub(clause_name!("(/\\)"), 2);
|
||||
|
||||
match (n1, n2) {
|
||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||
Ok(Number::from(n1 & n2))
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||
let n1 = Integer::from(n1);
|
||||
Ok(Number::from(n1 & &*n2))
|
||||
}
|
||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
||||
Ok(Number::from(&*n1 & Integer::from(n2)))
|
||||
}
|
||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||
Ok(Number::from(Integer::from(&*n1 & &*n2)))
|
||||
}
|
||||
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => {
|
||||
Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Integer,
|
||||
n2,
|
||||
),
|
||||
stub,
|
||||
))
|
||||
}
|
||||
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => Err(self.error_form(
|
||||
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
|
||||
stub,
|
||||
)),
|
||||
(n1, _) => Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Integer,
|
||||
n1,
|
||||
),
|
||||
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
|
||||
stub,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn or(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
pub(crate) fn and(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
let stub = MachineError::functor_stub(clause_name!("(/\\)"), 2);
|
||||
|
||||
match (n1, n2) {
|
||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => Ok(Number::from(n1 & n2)),
|
||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||
let n1 = Integer::from(n1);
|
||||
Ok(Number::from(n1 & &*n2))
|
||||
}
|
||||
(Number::Integer(n1), Number::Fixnum(n2)) => Ok(Number::from(&*n1 & Integer::from(n2))),
|
||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||
Ok(Number::from(Integer::from(&*n1 & &*n2)))
|
||||
}
|
||||
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => Err(self.error_form(
|
||||
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
|
||||
stub,
|
||||
)),
|
||||
(n1, _) => Err(self.error_form(
|
||||
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
|
||||
stub,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn or(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
let stub = MachineError::functor_stub(clause_name!("(\\/)"), 2);
|
||||
|
||||
match (n1, n2) {
|
||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||
Ok(Number::from(n1 | n2))
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => Ok(Number::from(n1 | n2)),
|
||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||
let n1 = Integer::from(n1);
|
||||
Ok(Number::from(n1 | &*n2))
|
||||
}
|
||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
||||
Ok(Number::from(&*n1 | Integer::from(n2)))
|
||||
}
|
||||
(Number::Integer(n1), Number::Fixnum(n2)) => Ok(Number::from(&*n1 | Integer::from(n2))),
|
||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||
Ok(Number::from(Integer::from(&*n1 | &*n2)))
|
||||
}
|
||||
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => {
|
||||
Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Integer,
|
||||
n2,
|
||||
),
|
||||
stub,
|
||||
))
|
||||
}
|
||||
(n1, _) => {
|
||||
Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Integer,
|
||||
n1
|
||||
),
|
||||
stub,
|
||||
))
|
||||
}
|
||||
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => Err(self.error_form(
|
||||
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
|
||||
stub,
|
||||
)),
|
||||
(n1, _) => Err(self.error_form(
|
||||
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
|
||||
stub,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn modulus(&self, x: Number, y: Number) -> Result<Number, MachineStub> {
|
||||
pub(crate) fn modulus(&self, x: Number, y: Number) -> Result<Number, MachineStub> {
|
||||
let stub = MachineError::functor_stub(clause_name!("(mod)"), 2);
|
||||
|
||||
match (x, y) {
|
||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||
if n2 == 0 {
|
||||
Err(self.error_form(
|
||||
MachineError::evaluation_error(EvalError::ZeroDivisor),
|
||||
stub,
|
||||
))
|
||||
Err(self
|
||||
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||
} else {
|
||||
Ok(Number::from(n1.rem_floor(n2)))
|
||||
}
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||
if &*n2 == &0 {
|
||||
Err(self.error_form(
|
||||
MachineError::evaluation_error(EvalError::ZeroDivisor),
|
||||
stub,
|
||||
))
|
||||
Err(self
|
||||
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||
} else {
|
||||
let n1 = Integer::from(n1);
|
||||
Ok(Number::from(<(Integer, Integer)>::from(n1.div_rem_floor_ref(&*n2)).1))
|
||||
Ok(Number::from(
|
||||
<(Integer, Integer)>::from(n1.div_rem_floor_ref(&*n2)).1,
|
||||
))
|
||||
}
|
||||
}
|
||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
||||
if n2 == 0 {
|
||||
Err(self.error_form(
|
||||
MachineError::evaluation_error(EvalError::ZeroDivisor),
|
||||
stub,
|
||||
))
|
||||
Err(self
|
||||
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||
} else {
|
||||
let n2 = Integer::from(n2);
|
||||
Ok(Number::from(<(Integer, Integer)>::from(n1.div_rem_floor_ref(&n2)).1))
|
||||
Ok(Number::from(
|
||||
<(Integer, Integer)>::from(n1.div_rem_floor_ref(&n2)).1,
|
||||
))
|
||||
}
|
||||
}
|
||||
(Number::Integer(x), Number::Integer(y)) => {
|
||||
if &*y == &0 {
|
||||
Err(self.error_form(
|
||||
MachineError::evaluation_error(EvalError::ZeroDivisor),
|
||||
stub,
|
||||
))
|
||||
Err(self
|
||||
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||
} else {
|
||||
Ok(Number::from(<(Integer, Integer)>::from(x.div_rem_floor_ref(&*y)).1))
|
||||
Ok(Number::from(
|
||||
<(Integer, Integer)>::from(x.div_rem_floor_ref(&*y)).1,
|
||||
))
|
||||
}
|
||||
}
|
||||
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => {
|
||||
Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Integer,
|
||||
n2,
|
||||
),
|
||||
stub,
|
||||
))
|
||||
}
|
||||
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => Err(self.error_form(
|
||||
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
|
||||
stub,
|
||||
)),
|
||||
(n1, _) => Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Integer,
|
||||
n1,
|
||||
),
|
||||
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
|
||||
stub,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn remainder(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
pub(crate) fn remainder(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
let stub = MachineError::functor_stub(clause_name!("(rem)"), 2);
|
||||
|
||||
match (n1, n2) {
|
||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||
if n2 == 0 {
|
||||
Err(self.error_form(
|
||||
MachineError::evaluation_error(EvalError::ZeroDivisor),
|
||||
stub,
|
||||
))
|
||||
Err(self
|
||||
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||
} else {
|
||||
Ok(Number::from(n1 % n2))
|
||||
}
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||
if &*n2 == &0 {
|
||||
Err(self.error_form(
|
||||
MachineError::evaluation_error(EvalError::ZeroDivisor),
|
||||
stub,
|
||||
))
|
||||
Err(self
|
||||
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||
} else {
|
||||
let n1 = Integer::from(n1);
|
||||
Ok(Number::from(n1 % &*n2))
|
||||
@@ -1072,10 +880,8 @@ impl MachineState {
|
||||
}
|
||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
||||
if n2 == 0 {
|
||||
Err(self.error_form(
|
||||
MachineError::evaluation_error(EvalError::ZeroDivisor),
|
||||
stub,
|
||||
))
|
||||
Err(self
|
||||
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||
} else {
|
||||
let n2 = Integer::from(n2);
|
||||
Ok(Number::from(&*n1 % n2))
|
||||
@@ -1083,37 +889,24 @@ impl MachineState {
|
||||
}
|
||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||
if &*n2 == &0 {
|
||||
Err(self.error_form(
|
||||
MachineError::evaluation_error(EvalError::ZeroDivisor),
|
||||
stub,
|
||||
))
|
||||
Err(self
|
||||
.error_form(MachineError::evaluation_error(EvalError::ZeroDivisor), stub))
|
||||
} else {
|
||||
Ok(Number::from(Integer::from(&*n1 % &*n2)))
|
||||
}
|
||||
}
|
||||
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => {
|
||||
Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Integer,
|
||||
n2,
|
||||
),
|
||||
stub,
|
||||
))
|
||||
}
|
||||
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => Err(self.error_form(
|
||||
MachineError::type_error(self.heap.h(), ValidType::Integer, n2),
|
||||
stub,
|
||||
)),
|
||||
(n1, _) => Err(self.error_form(
|
||||
MachineError::type_error(
|
||||
self.heap.h(),
|
||||
ValidType::Integer,
|
||||
n1,
|
||||
),
|
||||
MachineError::type_error(self.heap.h(), ValidType::Integer, n1),
|
||||
stub,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn max(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
pub(crate) fn max(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
match (n1, n2) {
|
||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||
if n1 > n2 {
|
||||
@@ -1154,8 +947,7 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn min(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
pub(crate) fn min(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||
match (n1, n2) {
|
||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||
if n1 < n2 {
|
||||
@@ -1196,8 +988,7 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn sign(&self, n: Number) -> Number {
|
||||
pub(crate) fn sign(&self, n: Number) -> Number {
|
||||
if n.is_positive() {
|
||||
Number::from(1)
|
||||
} else if n.is_negative() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::heap_iter::*;
|
||||
use crate::machine::*;
|
||||
use crate::prolog_parser_rebis::temp_v;
|
||||
|
||||
use crate::indexmap::IndexSet;
|
||||
|
||||
@@ -20,8 +21,7 @@ pub(super) struct AttrVarInitializer {
|
||||
}
|
||||
|
||||
impl AttrVarInitializer {
|
||||
pub(super)
|
||||
fn new(verify_attrs_loc: usize, project_attrs_loc: usize) -> Self {
|
||||
pub(super) fn new(verify_attrs_loc: usize, project_attrs_loc: usize) -> Self {
|
||||
AttrVarInitializer {
|
||||
attribute_goals: vec![],
|
||||
attr_var_queue: vec![],
|
||||
@@ -34,24 +34,21 @@ impl AttrVarInitializer {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn reset(&mut self) {
|
||||
self.attribute_goals.clear();
|
||||
pub(super) fn reset(&mut self) {
|
||||
self.attribute_goals.clear();
|
||||
self.attr_var_queue.clear();
|
||||
self.bindings.clear();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn backtrack(&mut self, queue_b: usize, bindings_b: usize) {
|
||||
pub(super) fn backtrack(&mut self, queue_b: usize, bindings_b: usize) {
|
||||
self.attr_var_queue.truncate(queue_b);
|
||||
self.bindings.truncate(bindings_b);
|
||||
}
|
||||
}
|
||||
|
||||
impl MachineState {
|
||||
pub(super)
|
||||
fn push_attr_var_binding(&mut self, h: usize, addr: Addr) {
|
||||
pub(super) fn push_attr_var_binding(&mut self, h: usize, addr: Addr) {
|
||||
if self.attr_var_init.bindings.is_empty() {
|
||||
self.attr_var_init.instigating_p = self.p.local();
|
||||
|
||||
@@ -79,7 +76,7 @@ impl MachineState {
|
||||
let iter = self
|
||||
.attr_var_init
|
||||
.bindings
|
||||
.drain(0 ..)
|
||||
.drain(0..)
|
||||
.map(|(_, addr)| HeapCellValue::Addr(addr));
|
||||
|
||||
let value_list_addr = Addr::HeapCell(self.heap.to_list(iter));
|
||||
@@ -97,8 +94,7 @@ impl MachineState {
|
||||
self[temp_v!(2)] = value_list_addr;
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn gather_attr_vars_created_since(&self, b: usize) -> IntoIter<Addr> {
|
||||
pub(super) fn gather_attr_vars_created_since(&self, b: usize) -> IntoIter<Addr> {
|
||||
let mut attr_vars: Vec<_> = self.attr_var_init.attr_var_queue[b..]
|
||||
.iter()
|
||||
.filter_map(|h| match self.store(self.deref(Addr::HeapCell(*h))) {
|
||||
@@ -107,29 +103,25 @@ impl MachineState {
|
||||
})
|
||||
.collect();
|
||||
|
||||
attr_vars.sort_unstable_by(|a1, a2| {
|
||||
self.compare_term_test(a1, a2).unwrap_or(Ordering::Less)
|
||||
});
|
||||
attr_vars
|
||||
.sort_unstable_by(|a1, a2| self.compare_term_test(a1, a2).unwrap_or(Ordering::Less));
|
||||
|
||||
self.term_dedup(&mut attr_vars);
|
||||
attr_vars.into_iter()
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn verify_attr_interrupt(&mut self, p: usize) {
|
||||
pub(super) fn verify_attr_interrupt(&mut self, p: usize) {
|
||||
self.allocate(self.num_of_args + 2);
|
||||
|
||||
let e = self.e;
|
||||
self.stack.index_and_frame_mut(e).prelude.interrupt_cp = self.attr_var_init.cp;
|
||||
|
||||
for i in 1 .. self.num_of_args + 1 {
|
||||
for i in 1..self.num_of_args + 1 {
|
||||
self.stack.index_and_frame_mut(e)[i] = self[RegType::Temp(i)];
|
||||
}
|
||||
|
||||
self.stack.index_and_frame_mut(e)[self.num_of_args + 1] =
|
||||
Addr::CutPoint(self.b0);
|
||||
self.stack.index_and_frame_mut(e)[self.num_of_args + 2] =
|
||||
Addr::Usize(self.num_of_args);
|
||||
self.stack.index_and_frame_mut(e)[self.num_of_args + 1] = Addr::CutPoint(self.b0);
|
||||
self.stack.index_and_frame_mut(e)[self.num_of_args + 2] = Addr::Usize(self.num_of_args);
|
||||
|
||||
self.verify_attributes();
|
||||
|
||||
@@ -138,9 +130,8 @@ impl MachineState {
|
||||
self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn attr_vars_of_term(&self, addr: Addr) -> Vec<Addr> {
|
||||
let mut seen_set = IndexSet::new();
|
||||
pub(super) fn attr_vars_of_term(&self, addr: Addr) -> Vec<Addr> {
|
||||
let mut seen_set = IndexSet::new();
|
||||
let mut seen_vars = vec![];
|
||||
|
||||
let mut iter = self.acyclic_pre_order_iter(addr);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,8 @@
|
||||
use crate::machine::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::term_stream::*;
|
||||
use crate::machine::*;
|
||||
use crate::prolog_parser_rebis::clause_name;
|
||||
|
||||
use crate::machine::term_stream::*;
|
||||
use indexmap::IndexSet;
|
||||
|
||||
use crate::ref_thread_local::RefThreadLocal;
|
||||
@@ -19,37 +20,35 @@ pub(super) struct LoadState<'a> {
|
||||
pub(super) wam: &'a mut Machine,
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn set_code_index(
|
||||
pub(super) fn set_code_index(
|
||||
retraction_info: &mut RetractionInfo,
|
||||
compilation_target: &CompilationTarget,
|
||||
key: PredicateKey,
|
||||
code_index: &CodeIndex,
|
||||
code_ptr: IndexPtr,
|
||||
) {
|
||||
let record =
|
||||
match compilation_target {
|
||||
CompilationTarget::User => {
|
||||
if IndexPtr::Undefined == code_index.get() {
|
||||
code_index.set(code_ptr);
|
||||
RetractionRecord::AddedUserPredicate(key)
|
||||
} else {
|
||||
// TODO: emit warning about overwriting previous record
|
||||
let replaced = code_index.replace(code_ptr);
|
||||
RetractionRecord::ReplacedUserPredicate(key, replaced)
|
||||
}
|
||||
let record = match compilation_target {
|
||||
CompilationTarget::User => {
|
||||
if IndexPtr::Undefined == code_index.get() {
|
||||
code_index.set(code_ptr);
|
||||
RetractionRecord::AddedUserPredicate(key)
|
||||
} else {
|
||||
// TODO: emit warning about overwriting previous record
|
||||
let replaced = code_index.replace(code_ptr);
|
||||
RetractionRecord::ReplacedUserPredicate(key, replaced)
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
if IndexPtr::Undefined == code_index.get() {
|
||||
code_index.set(code_ptr);
|
||||
RetractionRecord::AddedModulePredicate(module_name.clone(), key)
|
||||
} else {
|
||||
// TODO: emit warning about overwriting previous record
|
||||
let replaced = code_index.replace(code_ptr);
|
||||
RetractionRecord::ReplacedModulePredicate(module_name.clone(), key, replaced)
|
||||
}
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
if IndexPtr::Undefined == code_index.get() {
|
||||
code_index.set(code_ptr);
|
||||
RetractionRecord::AddedModulePredicate(module_name.clone(), key)
|
||||
} else {
|
||||
// TODO: emit warning about overwriting previous record
|
||||
let replaced = code_index.replace(code_ptr);
|
||||
RetractionRecord::ReplacedModulePredicate(module_name.clone(), key, replaced)
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
retraction_info.push_record(record);
|
||||
}
|
||||
@@ -71,16 +70,16 @@ fn add_op_decl_as_module_export(
|
||||
|
||||
match op_decl.insert_into_op_dir(wam_op_dir) {
|
||||
Some((prec, spec)) => {
|
||||
retraction_info.push_record(
|
||||
RetractionRecord::ReplacedUserOp(op_decl.clone(), prec, spec)
|
||||
);
|
||||
retraction_info.push_record(RetractionRecord::ReplacedUserOp(
|
||||
op_decl.clone(),
|
||||
prec,
|
||||
spec,
|
||||
));
|
||||
|
||||
module_op_exports.push((op_decl.clone(), Some((prec, spec))));
|
||||
}
|
||||
None => {
|
||||
retraction_info.push_record(
|
||||
RetractionRecord::AddedUserOp(op_decl.clone())
|
||||
);
|
||||
retraction_info.push_record(RetractionRecord::AddedUserOp(op_decl.clone()));
|
||||
|
||||
module_op_exports.push((op_decl.clone(), None));
|
||||
}
|
||||
@@ -89,49 +88,45 @@ fn add_op_decl_as_module_export(
|
||||
add_op_decl(retraction_info, compilation_target, module_op_dir, op_decl);
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn add_op_decl(
|
||||
pub(super) fn add_op_decl(
|
||||
retraction_info: &mut RetractionInfo,
|
||||
compilation_target: &CompilationTarget,
|
||||
op_dir: &mut OpDir,
|
||||
op_decl: &OpDecl,
|
||||
) {
|
||||
match op_decl.insert_into_op_dir(op_dir) {
|
||||
Some((prec, spec)) => {
|
||||
match &compilation_target {
|
||||
CompilationTarget::User => {
|
||||
retraction_info.push_record(
|
||||
RetractionRecord::ReplacedUserOp(op_decl.clone(), prec, spec),
|
||||
);
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
retraction_info.push_record(
|
||||
RetractionRecord::ReplacedModuleOp(
|
||||
module_name.clone(), op_decl.clone(), prec, spec,
|
||||
),
|
||||
);
|
||||
}
|
||||
Some((prec, spec)) => match &compilation_target {
|
||||
CompilationTarget::User => {
|
||||
retraction_info.push_record(RetractionRecord::ReplacedUserOp(
|
||||
op_decl.clone(),
|
||||
prec,
|
||||
spec,
|
||||
));
|
||||
}
|
||||
}
|
||||
None => {
|
||||
match &compilation_target {
|
||||
CompilationTarget::User => {
|
||||
retraction_info.push_record(
|
||||
RetractionRecord::AddedUserOp(op_decl.clone()),
|
||||
);
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
retraction_info.push_record(
|
||||
RetractionRecord::AddedModuleOp(module_name.clone(), op_decl.clone()),
|
||||
);
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
retraction_info.push_record(RetractionRecord::ReplacedModuleOp(
|
||||
module_name.clone(),
|
||||
op_decl.clone(),
|
||||
prec,
|
||||
spec,
|
||||
));
|
||||
}
|
||||
}
|
||||
},
|
||||
None => match &compilation_target {
|
||||
CompilationTarget::User => {
|
||||
retraction_info.push_record(RetractionRecord::AddedUserOp(op_decl.clone()));
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
retraction_info.push_record(RetractionRecord::AddedModuleOp(
|
||||
module_name.clone(),
|
||||
op_decl.clone(),
|
||||
));
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn import_module_exports(
|
||||
pub(super) fn import_module_exports(
|
||||
retraction_info: &mut RetractionInfo,
|
||||
compilation_target: &CompilationTarget,
|
||||
imported_module: &Module,
|
||||
@@ -166,12 +161,7 @@ fn import_module_exports(
|
||||
}
|
||||
}
|
||||
ModuleExport::OpDecl(ref op_decl) => {
|
||||
add_op_decl(
|
||||
retraction_info,
|
||||
compilation_target,
|
||||
op_dir,
|
||||
op_decl,
|
||||
);
|
||||
add_op_decl(retraction_info, compilation_target, op_dir, op_decl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,7 +175,7 @@ fn import_module_exports_into_module(
|
||||
op_dir: &mut OpDir,
|
||||
meta_predicates: &mut MetaPredicateDir,
|
||||
wam_op_dir: &mut OpDir,
|
||||
module_op_exports: &mut ModuleOpExports
|
||||
module_op_exports: &mut ModuleOpExports,
|
||||
) {
|
||||
for export in imported_module.module_decl.exports.iter() {
|
||||
match export {
|
||||
@@ -227,7 +217,6 @@ fn import_module_exports_into_module(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn import_qualified_module_exports(
|
||||
retraction_info: &mut RetractionInfo,
|
||||
compilation_target: &CompilationTarget,
|
||||
@@ -263,12 +252,7 @@ fn import_qualified_module_exports(
|
||||
}
|
||||
}
|
||||
ModuleExport::OpDecl(ref op_decl) => {
|
||||
add_op_decl(
|
||||
retraction_info,
|
||||
compilation_target,
|
||||
op_dir,
|
||||
op_decl,
|
||||
);
|
||||
add_op_decl(retraction_info, compilation_target, op_dir, op_decl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -326,29 +310,28 @@ fn import_qualified_module_exports_into_module(
|
||||
|
||||
impl<'a> LoadState<'a> {
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn increment_clause_assert_margin(&mut self, incr: usize) {
|
||||
pub(super) fn increment_clause_assert_margin(&mut self, incr: usize) {
|
||||
match &self.compilation_target {
|
||||
CompilationTarget::User => {
|
||||
}
|
||||
CompilationTarget::User => {}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::IncreasedClauseAssertMargin(
|
||||
self.retraction_info
|
||||
.push_record(RetractionRecord::IncreasedClauseAssertMargin(
|
||||
module_name.clone(),
|
||||
incr,
|
||||
),
|
||||
);
|
||||
));
|
||||
|
||||
self.wam.indices.modules.get_mut(module_name)
|
||||
self.wam
|
||||
.indices
|
||||
.modules
|
||||
.get_mut(module_name)
|
||||
.map(|module| module.clause_assert_margin += incr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn remove_module_op_exports(&mut self) {
|
||||
for (mut op_decl, record) in self.module_op_exports.drain(0 ..) {
|
||||
pub(super) fn remove_module_op_exports(&mut self) {
|
||||
for (mut op_decl, record) in self.module_op_exports.drain(0..) {
|
||||
op_decl.remove(&mut self.wam.indices.op_dir);
|
||||
|
||||
if let Some((prec, spec)) = record {
|
||||
@@ -365,26 +348,28 @@ impl<'a> LoadState<'a> {
|
||||
key: PredicateKey,
|
||||
) -> CodeIndex {
|
||||
match self.wam.indices.modules.get_mut(&module_name) {
|
||||
Some(ref mut module) => {
|
||||
module.code_dir
|
||||
.entry(key)
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||
.clone()
|
||||
}
|
||||
Some(ref mut module) => module
|
||||
.code_dir
|
||||
.entry(key)
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||
.clone(),
|
||||
None => {
|
||||
let mut module = Module::new(
|
||||
ModuleDecl { name: module_name.clone(), exports: vec![] },
|
||||
ModuleDecl {
|
||||
name: module_name.clone(),
|
||||
exports: vec![],
|
||||
},
|
||||
ListingSource::DynamicallyGenerated,
|
||||
);
|
||||
|
||||
let code_index = module.code_dir
|
||||
let code_index = module
|
||||
.code_dir
|
||||
.entry(key)
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||
.clone();
|
||||
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::AddedModule(module_name.clone()),
|
||||
);
|
||||
self.retraction_info
|
||||
.push_record(RetractionRecord::AddedModule(module_name.clone()));
|
||||
|
||||
self.wam.indices.modules.insert(module_name, module);
|
||||
code_index
|
||||
@@ -392,29 +377,31 @@ impl<'a> LoadState<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn get_or_insert_code_index(&mut self, key: PredicateKey) -> CodeIndex {
|
||||
pub(super) fn get_or_insert_code_index(&mut self, key: PredicateKey) -> CodeIndex {
|
||||
match self.compilation_target.clone() {
|
||||
CompilationTarget::User => {
|
||||
self.wam.indices.code_dir
|
||||
.entry(key)
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||
.clone()
|
||||
}
|
||||
CompilationTarget::User => self
|
||||
.wam
|
||||
.indices
|
||||
.code_dir
|
||||
.entry(key)
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||
.clone(),
|
||||
CompilationTarget::Module(module_name) => {
|
||||
self.get_or_insert_local_code_index(module_name, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn get_or_insert_qualified_code_index(
|
||||
pub(super) fn get_or_insert_qualified_code_index(
|
||||
&mut self,
|
||||
module_name: ClauseName,
|
||||
key: PredicateKey,
|
||||
) -> CodeIndex {
|
||||
if module_name.as_str() == "user" {
|
||||
return self.wam.indices.code_dir
|
||||
return self
|
||||
.wam
|
||||
.indices
|
||||
.code_dir
|
||||
.entry(key)
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||
.clone();
|
||||
@@ -424,15 +411,20 @@ impl<'a> LoadState<'a> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn add_extensible_predicate(&mut self, key: PredicateKey, skeleton: PredicateSkeleton) {
|
||||
pub(super) fn add_extensible_predicate(
|
||||
&mut self,
|
||||
key: PredicateKey,
|
||||
skeleton: PredicateSkeleton,
|
||||
) {
|
||||
match &self.compilation_target {
|
||||
CompilationTarget::User => {
|
||||
self.wam.indices.extensible_predicates.insert(key.clone(), skeleton);
|
||||
self.wam
|
||||
.indices
|
||||
.extensible_predicates
|
||||
.insert(key.clone(), skeleton);
|
||||
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::AddedUserExtensiblePredicate(key),
|
||||
);
|
||||
self.retraction_info
|
||||
.push_record(RetractionRecord::AddedUserExtensiblePredicate(key));
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
if let Some(module) = self.wam.indices.modules.get_mut(module_name) {
|
||||
@@ -448,8 +440,7 @@ impl<'a> LoadState<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn add_op_decl(&mut self, op_decl: &OpDecl) {
|
||||
pub(super) fn add_op_decl(&mut self, op_decl: &OpDecl) {
|
||||
match &self.compilation_target {
|
||||
CompilationTarget::User => {
|
||||
add_op_decl(
|
||||
@@ -479,8 +470,7 @@ impl<'a> LoadState<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn get_clause_type(
|
||||
pub(super) fn get_clause_type(
|
||||
&mut self,
|
||||
name: ClauseName,
|
||||
arity: usize,
|
||||
@@ -495,14 +485,11 @@ impl<'a> LoadState<'a> {
|
||||
let idx = self.get_or_insert_code_index((name.clone(), arity));
|
||||
ClauseType::Op(name, fixity, idx)
|
||||
}
|
||||
ct => {
|
||||
ct
|
||||
}
|
||||
ct => ct,
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn get_qualified_clause_type(
|
||||
pub(super) fn get_qualified_clause_type(
|
||||
&mut self,
|
||||
module_name: ClauseName,
|
||||
name: ClauseName,
|
||||
@@ -522,14 +509,11 @@ impl<'a> LoadState<'a> {
|
||||
|
||||
ClauseType::Op(name, fixity, idx)
|
||||
}
|
||||
ct => {
|
||||
ct
|
||||
}
|
||||
ct => ct,
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn add_meta_predicate_record(
|
||||
pub(super) fn add_meta_predicate_record(
|
||||
&mut self,
|
||||
module_name: ClauseName,
|
||||
name: ClauseName,
|
||||
@@ -540,20 +524,26 @@ impl<'a> LoadState<'a> {
|
||||
|
||||
match module_name.as_str() {
|
||||
"user" => {
|
||||
match self.wam.indices.meta_predicates.insert(key.clone(), meta_specs) {
|
||||
match self
|
||||
.wam
|
||||
.indices
|
||||
.meta_predicates
|
||||
.insert(key.clone(), meta_specs)
|
||||
{
|
||||
Some(old_meta_specs) => {
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::ReplacedMetaPredicate(
|
||||
module_name.clone(), key.0, old_meta_specs,
|
||||
),
|
||||
);
|
||||
self.retraction_info
|
||||
.push_record(RetractionRecord::ReplacedMetaPredicate(
|
||||
module_name.clone(),
|
||||
key.0,
|
||||
old_meta_specs,
|
||||
));
|
||||
}
|
||||
None => {
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::AddedMetaPredicate(
|
||||
module_name.clone(), key,
|
||||
)
|
||||
);
|
||||
self.retraction_info
|
||||
.push_record(RetractionRecord::AddedMetaPredicate(
|
||||
module_name.clone(),
|
||||
key,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -564,15 +554,15 @@ impl<'a> LoadState<'a> {
|
||||
Some(old_meta_specs) => {
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::ReplacedMetaPredicate(
|
||||
module_name.clone(), key.0, old_meta_specs,
|
||||
module_name.clone(),
|
||||
key.0,
|
||||
old_meta_specs,
|
||||
),
|
||||
);
|
||||
}
|
||||
None => {
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::AddedMetaPredicate(
|
||||
module_name.clone(), key,
|
||||
)
|
||||
RetractionRecord::AddedMetaPredicate(module_name.clone(), key),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -588,15 +578,14 @@ impl<'a> LoadState<'a> {
|
||||
|
||||
module.meta_predicates.insert(key.clone(), meta_specs);
|
||||
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::AddedMetaPredicate(
|
||||
module_name.clone(), key,
|
||||
)
|
||||
);
|
||||
self.retraction_info
|
||||
.push_record(RetractionRecord::AddedMetaPredicate(
|
||||
module_name.clone(),
|
||||
key,
|
||||
));
|
||||
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::AddedModule(module_name.clone()),
|
||||
);
|
||||
self.retraction_info
|
||||
.push_record(RetractionRecord::AddedModule(module_name.clone()));
|
||||
|
||||
self.wam.indices.modules.insert(module_name, module);
|
||||
}
|
||||
@@ -623,32 +612,29 @@ impl<'a> LoadState<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn add_module(&mut self, module_decl: ModuleDecl, listing_src: ListingSource) {
|
||||
pub(crate) fn add_module(&mut self, module_decl: ModuleDecl, listing_src: ListingSource) {
|
||||
let module_name = module_decl.name.clone();
|
||||
|
||||
let mut module =
|
||||
match self.wam.indices.modules.remove(&module_name) {
|
||||
Some(mut module) => {
|
||||
let old_module_decl = mem::replace(&mut module.module_decl, module_decl);
|
||||
let mut module = match self.wam.indices.modules.remove(&module_name) {
|
||||
Some(mut module) => {
|
||||
let old_module_decl = mem::replace(&mut module.module_decl, module_decl);
|
||||
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::ReplacedModule(
|
||||
old_module_decl, listing_src.clone(),
|
||||
),
|
||||
);
|
||||
self.retraction_info
|
||||
.push_record(RetractionRecord::ReplacedModule(
|
||||
old_module_decl,
|
||||
listing_src.clone(),
|
||||
));
|
||||
|
||||
module.listing_src = listing_src;
|
||||
module
|
||||
}
|
||||
None => {
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::AddedModule(module_name.clone()),
|
||||
);
|
||||
module.listing_src = listing_src;
|
||||
module
|
||||
}
|
||||
None => {
|
||||
self.retraction_info
|
||||
.push_record(RetractionRecord::AddedModule(module_name.clone()));
|
||||
|
||||
Module::new(module_decl, listing_src)
|
||||
}
|
||||
};
|
||||
Module::new(module_decl, listing_src)
|
||||
}
|
||||
};
|
||||
|
||||
self.import_builtins_in_module(
|
||||
&mut module.code_dir,
|
||||
@@ -676,8 +662,7 @@ impl<'a> LoadState<'a> {
|
||||
self.wam.indices.modules.insert(module_name, module);
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn import_module(&mut self, module_name: ClauseName) -> Result<(), SessionError> {
|
||||
pub(super) fn import_module(&mut self, module_name: ClauseName) -> Result<(), SessionError> {
|
||||
if let Some(module) = self.wam.indices.modules.remove(&module_name) {
|
||||
match &self.compilation_target {
|
||||
CompilationTarget::User => {
|
||||
@@ -717,7 +702,9 @@ impl<'a> LoadState<'a> {
|
||||
self.wam.indices.modules.insert(module_name, module);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(SessionError::ExistenceError(ExistenceError::Module(module_name)))
|
||||
Err(SessionError::ExistenceError(ExistenceError::Module(
|
||||
module_name,
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -765,41 +752,41 @@ impl<'a> LoadState<'a> {
|
||||
self.wam.indices.modules.insert(module_name, module);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(SessionError::ExistenceError(ExistenceError::Module(module_name)))
|
||||
Err(SessionError::ExistenceError(ExistenceError::Module(
|
||||
module_name,
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn use_module(&mut self, module_src: ModuleSource) -> Result<(), SessionError> {
|
||||
let (stream, listing_src) =
|
||||
match module_src {
|
||||
ModuleSource::File(filename) => {
|
||||
let mut path_buf = PathBuf::from(filename.as_str());
|
||||
path_buf.set_extension("pl");
|
||||
let file = File::open(&path_buf)?;
|
||||
pub(crate) fn use_module(&mut self, module_src: ModuleSource) -> Result<(), SessionError> {
|
||||
let (stream, listing_src) = match module_src {
|
||||
ModuleSource::File(filename) => {
|
||||
let mut path_buf = PathBuf::from(filename.as_str());
|
||||
path_buf.set_extension("pl");
|
||||
let file = File::open(&path_buf)?;
|
||||
|
||||
(Stream::from_file_as_input(filename.clone(), file),
|
||||
ListingSource::File(filename, path_buf))
|
||||
}
|
||||
ModuleSource::Library(library) => {
|
||||
match LIBRARIES.borrow().get(library.as_str()) {
|
||||
Some(code) => {
|
||||
if let Some(ref module) = self.wam.indices.modules.get(&library) {
|
||||
if let ListingSource::DynamicallyGenerated = &module.listing_src {
|
||||
(Stream::from(*code), ListingSource::User)
|
||||
} else {
|
||||
return self.import_module(library);
|
||||
}
|
||||
} else {
|
||||
(Stream::from(*code), ListingSource::User)
|
||||
}
|
||||
}
|
||||
None => {
|
||||
(
|
||||
Stream::from_file_as_input(filename.clone(), file),
|
||||
ListingSource::File(filename, path_buf),
|
||||
)
|
||||
}
|
||||
ModuleSource::Library(library) => match LIBRARIES.borrow().get(library.as_str()) {
|
||||
Some(code) => {
|
||||
if let Some(ref module) = self.wam.indices.modules.get(&library) {
|
||||
if let ListingSource::DynamicallyGenerated = &module.listing_src {
|
||||
(Stream::from(*code), ListingSource::User)
|
||||
} else {
|
||||
return self.import_module(library);
|
||||
}
|
||||
} else {
|
||||
(Stream::from(*code), ListingSource::User)
|
||||
}
|
||||
}
|
||||
};
|
||||
None => {
|
||||
return self.import_module(library);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
let compilation_target = {
|
||||
let stream = &mut parsing_stream(stream)?;
|
||||
@@ -820,43 +807,39 @@ impl<'a> LoadState<'a> {
|
||||
// nothing to do.
|
||||
Ok(())
|
||||
}
|
||||
CompilationTarget::Module(module_name) => {
|
||||
self.import_module(module_name)
|
||||
}
|
||||
CompilationTarget::Module(module_name) => self.import_module(module_name),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn use_qualified_module(
|
||||
pub(crate) fn use_qualified_module(
|
||||
&mut self,
|
||||
module_src: ModuleSource,
|
||||
exports: IndexSet<ModuleExport>,
|
||||
) -> Result<(), SessionError> {
|
||||
let (stream, listing_src) =
|
||||
match module_src {
|
||||
ModuleSource::File(filename) => {
|
||||
let mut path_buf = PathBuf::from(filename.as_str());
|
||||
path_buf.set_extension("pl");
|
||||
let file = File::open(&path_buf)?;
|
||||
let (stream, listing_src) = match module_src {
|
||||
ModuleSource::File(filename) => {
|
||||
let mut path_buf = PathBuf::from(filename.as_str());
|
||||
path_buf.set_extension("pl");
|
||||
let file = File::open(&path_buf)?;
|
||||
|
||||
(Stream::from_file_as_input(filename.clone(), file),
|
||||
ListingSource::File(filename, path_buf))
|
||||
}
|
||||
ModuleSource::Library(library) => {
|
||||
match LIBRARIES.borrow().get(library.as_str()) {
|
||||
Some(code) => {
|
||||
if self.wam.indices.modules.contains_key(&library) {
|
||||
return self.import_qualified_module(library, exports);
|
||||
} else {
|
||||
(Stream::from(*code), ListingSource::User)
|
||||
}
|
||||
}
|
||||
None => {
|
||||
return self.import_qualified_module(library, exports);
|
||||
}
|
||||
(
|
||||
Stream::from_file_as_input(filename.clone(), file),
|
||||
ListingSource::File(filename, path_buf),
|
||||
)
|
||||
}
|
||||
ModuleSource::Library(library) => match LIBRARIES.borrow().get(library.as_str()) {
|
||||
Some(code) => {
|
||||
if self.wam.indices.modules.contains_key(&library) {
|
||||
return self.import_qualified_module(library, exports);
|
||||
} else {
|
||||
(Stream::from(*code), ListingSource::User)
|
||||
}
|
||||
}
|
||||
};
|
||||
None => {
|
||||
return self.import_qualified_module(library, exports);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
let compilation_target = {
|
||||
let stream = &mut parsing_stream(stream)?;
|
||||
@@ -884,12 +867,9 @@ impl<'a> LoadState<'a> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn composite_op_dir(&self) -> CompositeOpDir {
|
||||
pub(super) fn composite_op_dir(&self) -> CompositeOpDir {
|
||||
match &self.compilation_target {
|
||||
CompilationTarget::User => {
|
||||
CompositeOpDir::new(&self.wam.indices.op_dir, None)
|
||||
}
|
||||
CompilationTarget::User => CompositeOpDir::new(&self.wam.indices.op_dir, None),
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
match self.wam.indices.modules.get(module_name) {
|
||||
Some(ref module) => {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,5 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::{clause_name, temp_v};
|
||||
|
||||
use crate::forms::{ModuleSource, Number}; //, PredicateKey};
|
||||
use crate::machine::heap::*;
|
||||
@@ -23,74 +24,59 @@ pub(crate) struct MachineError {
|
||||
from: ErrorProvenance,
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
trait TypeError {
|
||||
pub(crate) trait TypeError {
|
||||
fn type_error(self, h: usize, valid_type: ValidType) -> MachineError;
|
||||
}
|
||||
|
||||
impl TypeError for Addr {
|
||||
fn type_error(self, _: usize, valid_type: ValidType) -> MachineError {
|
||||
let stub = functor!(
|
||||
"type_error",
|
||||
[atom(valid_type.as_str()), addr(self)]
|
||||
);
|
||||
let stub = functor!("type_error", [atom(valid_type.as_str()), addr(self)]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeError for HeapCellValue {
|
||||
fn type_error(self, _: usize, valid_type: ValidType) -> MachineError {
|
||||
let stub = functor!(
|
||||
"type_error",
|
||||
[atom(valid_type.as_str()), value(self)]
|
||||
);
|
||||
let stub = functor!("type_error", [atom(valid_type.as_str()), value(self)]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeError for MachineStub {
|
||||
fn type_error(self, h: usize, valid_type: ValidType) -> MachineError {
|
||||
let stub = functor!(
|
||||
"type_error",
|
||||
[atom(valid_type.as_str()), aux(h, 0)],
|
||||
[self]
|
||||
);
|
||||
let stub = functor!("type_error", [atom(valid_type.as_str()), aux(h, 0)], [self]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Constructed
|
||||
from: ErrorProvenance::Constructed,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeError for Number {
|
||||
fn type_error(self, _h: usize, valid_type: ValidType) -> MachineError {
|
||||
let stub = functor!(
|
||||
"type_error",
|
||||
[atom(valid_type.as_str()), number(self)]
|
||||
);
|
||||
let stub = functor!("type_error", [atom(valid_type.as_str()), number(self)]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
trait PermissionError {
|
||||
pub(crate) trait PermissionError {
|
||||
fn permission_error(self, h: usize, index_str: &'static str, perm: Permission) -> MachineError;
|
||||
}
|
||||
|
||||
@@ -104,7 +90,7 @@ impl PermissionError for Addr {
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,22 +106,18 @@ impl PermissionError for MachineStub {
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Constructed
|
||||
from: ErrorProvenance::Constructed,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
trait DomainError {
|
||||
pub(super) trait DomainError {
|
||||
fn domain_error(self, error: DomainErrorType) -> MachineError;
|
||||
}
|
||||
|
||||
impl DomainError for Addr {
|
||||
fn domain_error(self, error: DomainErrorType) -> MachineError {
|
||||
let stub = functor!(
|
||||
"domain_error",
|
||||
[atom(error.as_str()), addr(self)]
|
||||
);
|
||||
let stub = functor!("domain_error", [atom(error.as_str()), addr(self)]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
@@ -147,10 +129,7 @@ impl DomainError for Addr {
|
||||
|
||||
impl DomainError for Number {
|
||||
fn domain_error(self, error: DomainErrorType) -> MachineError {
|
||||
let stub = functor!(
|
||||
"domain_error",
|
||||
[atom(error.as_str()), number(self)]
|
||||
);
|
||||
let stub = functor!("domain_error", [atom(error.as_str()), number(self)]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
@@ -161,8 +140,7 @@ impl DomainError for Number {
|
||||
}
|
||||
|
||||
impl MachineError {
|
||||
pub(super)
|
||||
fn functor_stub(name: ClauseName, arity: usize) -> MachineStub {
|
||||
pub(super) fn functor_stub(name: ClauseName, arity: usize) -> MachineStub {
|
||||
functor!(
|
||||
"/",
|
||||
SharedOpDesc::new(400, YFX),
|
||||
@@ -171,8 +149,7 @@ impl MachineError {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn interrupt_error() -> Self {
|
||||
pub(super) fn interrupt_error() -> Self {
|
||||
let stub = functor!("$interrupt_thrown");
|
||||
|
||||
MachineError {
|
||||
@@ -182,8 +159,7 @@ impl MachineError {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn evaluation_error(eval_error: EvalError) -> Self {
|
||||
pub(super) fn evaluation_error(eval_error: EvalError) -> Self {
|
||||
let stub = functor!("evaluation_error", [atom(eval_error.as_str())]);
|
||||
|
||||
MachineError {
|
||||
@@ -193,13 +169,11 @@ impl MachineError {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn type_error<T: TypeError>(h: usize, valid_type: ValidType, culprit: T) -> Self {
|
||||
pub(super) fn type_error<T: TypeError>(h: usize, valid_type: ValidType, culprit: T) -> Self {
|
||||
culprit.type_error(h, valid_type)
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn module_resolution_error(
|
||||
pub(super) fn module_resolution_error(
|
||||
h: usize,
|
||||
mod_name: ClauseName,
|
||||
name: ClauseName,
|
||||
@@ -218,11 +192,7 @@ impl MachineError {
|
||||
[res_stub]
|
||||
);
|
||||
|
||||
let stub = functor!(
|
||||
"evaluation_error",
|
||||
[aux(h, 0)],
|
||||
[ind_stub]
|
||||
);
|
||||
let stub = functor!("evaluation_error", [aux(h, 0)], [ind_stub]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
@@ -231,14 +201,10 @@ impl MachineError {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn existence_error(h: usize, err: ExistenceError) -> Self {
|
||||
pub(super) fn existence_error(h: usize, err: ExistenceError) -> Self {
|
||||
match err {
|
||||
ExistenceError::Module(name) => {
|
||||
let stub = functor!(
|
||||
"existence_error",
|
||||
[atom("source_sink"), clause_name(name)]
|
||||
);
|
||||
let stub = functor!("existence_error", [atom("source_sink"), clause_name(name)]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
@@ -253,11 +219,7 @@ impl MachineError {
|
||||
[clause_name(name), integer(arity)]
|
||||
);
|
||||
|
||||
let stub = functor!(
|
||||
"existence_error",
|
||||
[atom("procedure"), aux(h, 0)],
|
||||
[culprit]
|
||||
);
|
||||
let stub = functor!("existence_error", [atom("procedure"), aux(h, 0)], [culprit]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
@@ -281,10 +243,7 @@ impl MachineError {
|
||||
}
|
||||
}
|
||||
ExistenceError::SourceSink(culprit) => {
|
||||
let stub = functor!(
|
||||
"existence_error",
|
||||
[atom("source_sink"), addr(culprit)]
|
||||
);
|
||||
let stub = functor!("existence_error", [atom("source_sink"), addr(culprit)]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
@@ -293,10 +252,7 @@ impl MachineError {
|
||||
}
|
||||
}
|
||||
ExistenceError::Stream(culprit) => {
|
||||
let stub = functor!(
|
||||
"existence_error",
|
||||
[atom("stream"), addr(culprit)]
|
||||
);
|
||||
let stub = functor!("existence_error", [atom("stream"), addr(culprit)]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
@@ -307,25 +263,18 @@ impl MachineError {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn permission_error<T: PermissionError>(
|
||||
pub(super) fn permission_error<T: PermissionError>(
|
||||
h: usize,
|
||||
err: Permission,
|
||||
index_str: &'static str,
|
||||
culprit: T,
|
||||
) -> Self {
|
||||
culprit.permission_error(
|
||||
h,
|
||||
index_str,
|
||||
err,
|
||||
)
|
||||
culprit.permission_error(h, index_str, err)
|
||||
}
|
||||
|
||||
fn arithmetic_error(h: usize, err: ArithmeticError) -> Self {
|
||||
match err {
|
||||
ArithmeticError::UninstantiatedVar => {
|
||||
Self::instantiation_error()
|
||||
}
|
||||
ArithmeticError::UninstantiatedVar => Self::instantiation_error(),
|
||||
ArithmeticError::NonEvaluableFunctor(name, arity) => {
|
||||
let culprit = functor!(
|
||||
"/",
|
||||
@@ -339,13 +288,11 @@ impl MachineError {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn domain_error<T: DomainError>(error: DomainErrorType, culprit: T) -> Self {
|
||||
pub(super) fn domain_error<T: DomainError>(error: DomainErrorType, culprit: T) -> Self {
|
||||
culprit.domain_error(error)
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn instantiation_error() -> Self {
|
||||
pub(super) fn instantiation_error() -> Self {
|
||||
let stub = functor!("instantiation_error");
|
||||
|
||||
MachineError {
|
||||
@@ -355,8 +302,7 @@ impl MachineError {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn session_error(h: usize, err: SessionError) -> Self {
|
||||
pub(super) fn session_error(h: usize, err: SessionError) -> Self {
|
||||
match err {
|
||||
// SessionError::CannotOverwriteBuiltIn(pred_str) |
|
||||
/*
|
||||
@@ -369,9 +315,7 @@ impl MachineError {
|
||||
)
|
||||
}
|
||||
*/
|
||||
SessionError::ExistenceError(err) => {
|
||||
Self::existence_error(h, err)
|
||||
}
|
||||
SessionError::ExistenceError(err) => Self::existence_error(h, err),
|
||||
// SessionError::InvalidFileName(filename) => {
|
||||
// Self::existence_error(h, ExistenceError::Module(filename))
|
||||
// }
|
||||
@@ -385,46 +329,32 @@ impl MachineError {
|
||||
)
|
||||
}
|
||||
*/
|
||||
SessionError::ModuleCannotImportSelf(module_name) => {
|
||||
Self::permission_error(
|
||||
h,
|
||||
Permission::Modify,
|
||||
"module",
|
||||
functor!("module_cannot_import_self", [clause_name(module_name)]),
|
||||
)
|
||||
}
|
||||
SessionError::NamelessEntry => {
|
||||
Self::permission_error(
|
||||
h,
|
||||
Permission::Create,
|
||||
"static_procedure",
|
||||
functor!("nameless_procedure")
|
||||
)
|
||||
}
|
||||
SessionError::ModuleCannotImportSelf(module_name) => Self::permission_error(
|
||||
h,
|
||||
Permission::Modify,
|
||||
"module",
|
||||
functor!("module_cannot_import_self", [clause_name(module_name)]),
|
||||
),
|
||||
SessionError::NamelessEntry => Self::permission_error(
|
||||
h,
|
||||
Permission::Create,
|
||||
"static_procedure",
|
||||
functor!("nameless_procedure"),
|
||||
),
|
||||
SessionError::OpIsInfixAndPostFix(op) => {
|
||||
Self::permission_error(
|
||||
h,
|
||||
Permission::Create,
|
||||
"operator",
|
||||
functor!(clause_name(op)),
|
||||
)
|
||||
}
|
||||
SessionError::CompilationError(err) => {
|
||||
Self::syntax_error(h, err)
|
||||
}
|
||||
SessionError::QueryCannotBeDefinedAsFact => {
|
||||
Self::permission_error(
|
||||
h,
|
||||
Permission::Create,
|
||||
"static_procedure",
|
||||
functor!("query_cannot_be_defined_as_fact")
|
||||
)
|
||||
Self::permission_error(h, Permission::Create, "operator", functor!(clause_name(op)))
|
||||
}
|
||||
SessionError::CompilationError(err) => Self::syntax_error(h, err),
|
||||
SessionError::QueryCannotBeDefinedAsFact => Self::permission_error(
|
||||
h,
|
||||
Permission::Create,
|
||||
"static_procedure",
|
||||
functor!("query_cannot_be_defined_as_fact"),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn syntax_error<E: Into<CompilationError>>(h: usize, err: E) -> Self {
|
||||
pub(super) fn syntax_error<E: Into<CompilationError>>(h: usize, err: E) -> Self {
|
||||
let err = err.into();
|
||||
|
||||
if let CompilationError::Arithmetic(err) = err {
|
||||
@@ -434,11 +364,7 @@ impl MachineError {
|
||||
let location = err.line_and_col_num();
|
||||
let stub = err.as_functor(h);
|
||||
|
||||
let stub = functor!(
|
||||
"syntax_error",
|
||||
[aux(h, 0)],
|
||||
[stub]
|
||||
);
|
||||
let stub = functor!("syntax_error", [aux(h, 0)], [stub]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
@@ -447,8 +373,7 @@ impl MachineError {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn representation_error(flag: RepFlag) -> Self {
|
||||
pub(super) fn representation_error(flag: RepFlag) -> Self {
|
||||
let stub = functor!("representation_error", [atom(flag.as_str())]);
|
||||
|
||||
MachineError {
|
||||
@@ -515,56 +440,39 @@ impl From<ParserError> for CompilationError {
|
||||
impl CompilationError {
|
||||
pub fn line_and_col_num(&self) -> Option<(usize, usize)> {
|
||||
match self {
|
||||
&CompilationError::ParserError(ref err) =>
|
||||
err.line_and_col_num(),
|
||||
_ =>
|
||||
None
|
||||
&CompilationError::ParserError(ref err) => err.line_and_col_num(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_functor(&self, _h: usize) -> MachineStub {
|
||||
match self {
|
||||
&CompilationError::Arithmetic(..) =>
|
||||
functor!("arithmetic_error"),
|
||||
&CompilationError::Arithmetic(..) => functor!("arithmetic_error"),
|
||||
// &CompilationError::BadPendingByte =>
|
||||
// functor!("bad_pending_byte"),
|
||||
&CompilationError::CannotParseCyclicTerm =>
|
||||
functor!("cannot_parse_cyclic_term"),
|
||||
&CompilationError::CannotParseCyclicTerm => functor!("cannot_parse_cyclic_term"),
|
||||
// &CompilationError::ExpandedTermsListNotAList =>
|
||||
// functor!("expanded_terms_list_is_not_a_list"),
|
||||
&CompilationError::ExpectedRel =>
|
||||
functor!("expected_relation"),
|
||||
&CompilationError::ExpectedRel => functor!("expected_relation"),
|
||||
// &CompilationError::ExpectedTopLevelTerm =>
|
||||
// functor!("expected_atom_or_cons_or_clause"),
|
||||
&CompilationError::InadmissibleFact =>
|
||||
functor!("inadmissible_fact"),
|
||||
&CompilationError::InadmissibleQueryTerm =>
|
||||
functor!("inadmissible_query_term"),
|
||||
&CompilationError::InconsistentEntry =>
|
||||
functor!("inconsistent_entry"),
|
||||
&CompilationError::InadmissibleFact => functor!("inadmissible_fact"),
|
||||
&CompilationError::InadmissibleQueryTerm => functor!("inadmissible_query_term"),
|
||||
&CompilationError::InconsistentEntry => functor!("inconsistent_entry"),
|
||||
// &CompilationError::InvalidDoubleQuotesDecl =>
|
||||
// functor!("invalid_double_quotes_declaration"),
|
||||
// &CompilationError::InvalidHook =>
|
||||
// functor!("invalid_hook"),
|
||||
&CompilationError::InvalidMetaPredicateDecl =>
|
||||
functor!("invalid_meta_predicate_decl"),
|
||||
&CompilationError::InvalidModuleDecl =>
|
||||
functor!("invalid_module_declaration"),
|
||||
&CompilationError::InvalidModuleExport =>
|
||||
functor!("invalid_module_export"),
|
||||
&CompilationError::InvalidModuleResolution(ref module_name) =>
|
||||
functor!(
|
||||
"no_such_module",
|
||||
[clause_name(module_name.clone())]
|
||||
),
|
||||
&CompilationError::InvalidRuleHead =>
|
||||
functor!("invalid_head_of_rule"),
|
||||
&CompilationError::InvalidUseModuleDecl =>
|
||||
functor!("invalid_use_module_declaration"),
|
||||
&CompilationError::ParserError(ref err) =>
|
||||
functor!(err.as_str()),
|
||||
&CompilationError::UnreadableTerm =>
|
||||
functor!("unreadable_term"),
|
||||
&CompilationError::InvalidMetaPredicateDecl => functor!("invalid_meta_predicate_decl"),
|
||||
&CompilationError::InvalidModuleDecl => functor!("invalid_module_declaration"),
|
||||
&CompilationError::InvalidModuleExport => functor!("invalid_module_export"),
|
||||
&CompilationError::InvalidModuleResolution(ref module_name) => {
|
||||
functor!("no_such_module", [clause_name(module_name.clone())])
|
||||
}
|
||||
&CompilationError::InvalidRuleHead => functor!("invalid_head_of_rule"),
|
||||
&CompilationError::InvalidUseModuleDecl => functor!("invalid_use_module_declaration"),
|
||||
&CompilationError::ParserError(ref err) => functor!(err.as_str()),
|
||||
&CompilationError::UnreadableTerm => functor!("unreadable_term"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -715,16 +623,15 @@ impl EvalError {
|
||||
pub(super) enum CycleSearchResult {
|
||||
EmptyList,
|
||||
NotList,
|
||||
PartialList(usize, Ref), // the list length (up to max), and an offset into the heap.
|
||||
ProperList(usize), // the list length.
|
||||
PartialList(usize, Ref), // the list length (up to max), and an offset into the heap.
|
||||
ProperList(usize), // the list length.
|
||||
PStrLocation(usize, usize, usize), // the list length (up to max), the heap offset, byte offset into the string.
|
||||
UntouchedList(usize), // the address of an uniterated Addr::Lis(address).
|
||||
}
|
||||
|
||||
impl MachineState {
|
||||
// see 8.4.3 of Draft Technical Corrigendum 2.
|
||||
pub(super)
|
||||
fn check_sort_errors(&self) -> CallResult {
|
||||
pub(super) fn check_sort_errors(&self) -> CallResult {
|
||||
let stub = MachineError::functor_stub(clause_name!("sort"), 2);
|
||||
let list = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||
let sorted = self.store(self.deref(self[temp_v!(2)].clone()));
|
||||
@@ -734,7 +641,9 @@ impl MachineState {
|
||||
return Err(self.error_form(MachineError::instantiation_error(), stub))
|
||||
}
|
||||
CycleSearchResult::NotList => {
|
||||
return Err(self.error_form(MachineError::type_error(0, ValidType::List, list), stub))
|
||||
return Err(
|
||||
self.error_form(MachineError::type_error(0, ValidType::List, list), stub)
|
||||
)
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
@@ -766,7 +675,8 @@ impl MachineState {
|
||||
new_l = l;
|
||||
}
|
||||
HeapCellValue::NamedStr(2, ref name, Some(_))
|
||||
if name.as_str() == "-" => {
|
||||
if name.as_str() == "-" =>
|
||||
{
|
||||
break;
|
||||
}
|
||||
HeapCellValue::Addr(Addr::HeapCell(_)) => {
|
||||
@@ -793,11 +703,10 @@ impl MachineState {
|
||||
}
|
||||
|
||||
// see 8.4.4 of Draft Technical Corrigendum 2.
|
||||
pub(super)
|
||||
fn check_keysort_errors(&self) -> CallResult {
|
||||
pub(super) fn check_keysort_errors(&self) -> CallResult {
|
||||
let stub = MachineError::functor_stub(clause_name!("keysort"), 2);
|
||||
|
||||
let pairs = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||
let pairs = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||
let sorted = self.store(self.deref(self[temp_v!(2)].clone()));
|
||||
|
||||
match self.detect_cycles(pairs.clone()) {
|
||||
@@ -814,8 +723,7 @@ impl MachineState {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn type_error<T: TypeError>(
|
||||
pub(crate) fn type_error<T: TypeError>(
|
||||
&self,
|
||||
valid_type: ValidType,
|
||||
culprit: T,
|
||||
@@ -823,33 +731,25 @@ impl MachineState {
|
||||
arity: usize,
|
||||
) -> MachineStub {
|
||||
let stub = MachineError::functor_stub(caller, arity);
|
||||
let err = MachineError::type_error(
|
||||
self.heap.h(),
|
||||
valid_type,
|
||||
culprit,
|
||||
);
|
||||
let err = MachineError::type_error(self.heap.h(), valid_type, culprit);
|
||||
|
||||
return self.error_form(err, stub);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn representation_error(
|
||||
pub(crate) fn representation_error(
|
||||
&self,
|
||||
rep_flag: RepFlag,
|
||||
caller: ClauseName,
|
||||
arity: usize,
|
||||
) -> MachineStub {
|
||||
let stub = MachineError::functor_stub(caller, arity);
|
||||
let err = MachineError::representation_error(
|
||||
rep_flag,
|
||||
);
|
||||
let err = MachineError::representation_error(rep_flag);
|
||||
|
||||
return self.error_form(err, stub);
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn error_form(&self, err: MachineError, src: MachineStub) -> MachineStub {
|
||||
pub(super) fn error_form(&self, err: MachineError, src: MachineStub) -> MachineStub {
|
||||
let location = err.location;
|
||||
let err_len = err.len();
|
||||
|
||||
@@ -874,8 +774,7 @@ impl MachineState {
|
||||
stub
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn throw_exception(&mut self, err: MachineStub) {
|
||||
pub(super) fn throw_exception(&mut self, err: MachineStub) {
|
||||
let h = self.heap.h();
|
||||
|
||||
self.ball.boundary = 0;
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::clause_name;
|
||||
|
||||
use crate::clause_types::*;
|
||||
use crate::fixtures::*;
|
||||
use crate::forms::*;
|
||||
use crate::machine::CompilationTarget;
|
||||
use crate::instructions::*;
|
||||
use crate::machine::code_repo::CodeRepo;
|
||||
use crate::machine::Ball;
|
||||
use crate::machine::heap::*;
|
||||
use crate::machine::machine_state::*;
|
||||
use crate::machine::partial_string::*;
|
||||
use crate::machine::raw_block::RawBlockTraits;
|
||||
use crate::machine::streams::Stream;
|
||||
use crate::machine::term_stream::LoadStatePayload;
|
||||
use crate::instructions::*;
|
||||
use crate::machine::Ball;
|
||||
use crate::machine::CompilationTarget;
|
||||
use crate::ordered_float::OrderedFloat;
|
||||
use crate::rug::{Integer, Rational};
|
||||
|
||||
@@ -96,20 +97,14 @@ impl Ord for Ref {
|
||||
fn cmp(&self, other: &Ref) -> Ordering {
|
||||
match (self, other) {
|
||||
(Ref::AttrVar(h1), Ref::AttrVar(h2))
|
||||
| (Ref::HeapCell(h1), Ref::HeapCell(h2))
|
||||
| (Ref::HeapCell(h1), Ref::AttrVar(h2))
|
||||
| (Ref::AttrVar(h1), Ref::HeapCell(h2)) => {
|
||||
h1.cmp(&h2)
|
||||
}
|
||||
| (Ref::HeapCell(h1), Ref::HeapCell(h2))
|
||||
| (Ref::HeapCell(h1), Ref::AttrVar(h2))
|
||||
| (Ref::AttrVar(h1), Ref::HeapCell(h2)) => h1.cmp(&h2),
|
||||
(Ref::StackCell(fr1, sc1), Ref::StackCell(fr2, sc2)) => {
|
||||
fr1.cmp(&fr2).then_with(|| sc1.cmp(&sc2))
|
||||
}
|
||||
(Ref::StackCell(..), _) => {
|
||||
Ordering::Greater
|
||||
}
|
||||
(_, Ref::StackCell(..)) => {
|
||||
Ordering::Less
|
||||
}
|
||||
(Ref::StackCell(..), _) => Ordering::Greater,
|
||||
(_, Ref::StackCell(..)) => Ordering::Less,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,35 +119,23 @@ impl PartialEq<Ref> for Addr {
|
||||
impl PartialOrd<Ref> for Addr {
|
||||
fn partial_cmp(&self, r: &Ref) -> Option<Ordering> {
|
||||
match self {
|
||||
&Addr::StackCell(fr, sc) => {
|
||||
match *r {
|
||||
Ref::AttrVar(_) | Ref::HeapCell(_) => {
|
||||
&Addr::StackCell(fr, sc) => match *r {
|
||||
Ref::AttrVar(_) | Ref::HeapCell(_) => Some(Ordering::Greater),
|
||||
Ref::StackCell(fr1, sc1) => {
|
||||
if fr1 < fr || (fr1 == fr && sc1 < sc) {
|
||||
Some(Ordering::Greater)
|
||||
}
|
||||
Ref::StackCell(fr1, sc1) => {
|
||||
if fr1 < fr || (fr1 == fr && sc1 < sc) {
|
||||
Some(Ordering::Greater)
|
||||
} else if fr1 == fr && sc1 == sc {
|
||||
Some(Ordering::Equal)
|
||||
} else {
|
||||
Some(Ordering::Less)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&Addr::HeapCell(h) | &Addr::AttrVar(h) => {
|
||||
match r {
|
||||
Ref::StackCell(..) => {
|
||||
} else if fr1 == fr && sc1 == sc {
|
||||
Some(Ordering::Equal)
|
||||
} else {
|
||||
Some(Ordering::Less)
|
||||
}
|
||||
Ref::AttrVar(h1) | Ref::HeapCell(h1) => {
|
||||
h.partial_cmp(h1)
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
},
|
||||
&Addr::HeapCell(h) | &Addr::AttrVar(h) => match r {
|
||||
Ref::StackCell(..) => Some(Ordering::Less),
|
||||
Ref::AttrVar(h1) | Ref::HeapCell(h1) => h.partial_cmp(h1),
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,26 +144,21 @@ impl Addr {
|
||||
#[inline]
|
||||
pub fn is_heap_bound(&self) -> bool {
|
||||
match self {
|
||||
Addr::Char(_) | Addr::EmptyList |
|
||||
Addr::CutPoint(_) | Addr::Usize(_) | Addr::Fixnum(_) |
|
||||
Addr::Float(_) => {
|
||||
false
|
||||
}
|
||||
_ => {
|
||||
true
|
||||
}
|
||||
Addr::Char(_)
|
||||
| Addr::EmptyList
|
||||
| Addr::CutPoint(_)
|
||||
| Addr::Usize(_)
|
||||
| Addr::Fixnum(_)
|
||||
| Addr::Float(_) => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_ref(&self) -> bool {
|
||||
match self {
|
||||
Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::AttrVar(_) => {
|
||||
true
|
||||
}
|
||||
_ => {
|
||||
false
|
||||
}
|
||||
Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::AttrVar(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,92 +172,54 @@ impl Addr {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn order_category(&self, heap: &Heap) -> Option<TermOrderCategory> {
|
||||
pub(super) fn order_category(&self, heap: &Heap) -> Option<TermOrderCategory> {
|
||||
match Number::try_from((*self, heap)) {
|
||||
Ok(Number::Integer(_)) | Ok(Number::Fixnum(_)) | Ok(Number::Rational(_)) => {
|
||||
Some(TermOrderCategory::Integer)
|
||||
}
|
||||
Ok(Number::Float(_)) => {
|
||||
Some(TermOrderCategory::FloatingPoint)
|
||||
}
|
||||
_ => {
|
||||
match self {
|
||||
Addr::HeapCell(_) | Addr::AttrVar(_) | Addr::StackCell(..) => {
|
||||
Some(TermOrderCategory::Variable)
|
||||
}
|
||||
Addr::Float(_) => {
|
||||
Some(TermOrderCategory::FloatingPoint)
|
||||
}
|
||||
&Addr::Con(h) => {
|
||||
match &heap[h] {
|
||||
HeapCellValue::Atom(..) => {
|
||||
Some(TermOrderCategory::Atom)
|
||||
}
|
||||
HeapCellValue::DBRef(_) => {
|
||||
None
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
Addr::Char(_) | Addr::EmptyList => {
|
||||
Some(TermOrderCategory::Atom)
|
||||
}
|
||||
Addr::Fixnum(_) | Addr::Usize(_) => {
|
||||
Some(TermOrderCategory::Integer)
|
||||
}
|
||||
Addr::Lis(_) | Addr::PStrLocation(..) | Addr::Str(_) => {
|
||||
Some(TermOrderCategory::Compound)
|
||||
}
|
||||
Addr::CutPoint(_) | Addr::LoadStatePayload(_) | Addr::Stream(_) | Addr::TcpListener(_) => {
|
||||
None
|
||||
}
|
||||
Ok(Number::Float(_)) => Some(TermOrderCategory::FloatingPoint),
|
||||
_ => match self {
|
||||
Addr::HeapCell(_) | Addr::AttrVar(_) | Addr::StackCell(..) => {
|
||||
Some(TermOrderCategory::Variable)
|
||||
}
|
||||
}
|
||||
Addr::Float(_) => Some(TermOrderCategory::FloatingPoint),
|
||||
&Addr::Con(h) => match &heap[h] {
|
||||
HeapCellValue::Atom(..) => Some(TermOrderCategory::Atom),
|
||||
HeapCellValue::DBRef(_) => None,
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
},
|
||||
Addr::Char(_) | Addr::EmptyList => Some(TermOrderCategory::Atom),
|
||||
Addr::Fixnum(_) | Addr::Usize(_) => Some(TermOrderCategory::Integer),
|
||||
Addr::Lis(_) | Addr::PStrLocation(..) | Addr::Str(_) => {
|
||||
Some(TermOrderCategory::Compound)
|
||||
}
|
||||
Addr::CutPoint(_)
|
||||
| Addr::LoadStatePayload(_)
|
||||
| Addr::Stream(_)
|
||||
| Addr::TcpListener(_) => None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_constant_index(&self, machine_st: &MachineState) -> Option<Constant> {
|
||||
match self {
|
||||
&Addr::Char(c) => {
|
||||
Some(Constant::Char(c))
|
||||
}
|
||||
&Addr::Con(h) => {
|
||||
match &machine_st.heap[h] {
|
||||
&HeapCellValue::Atom(ref name, _) if name.is_char() => {
|
||||
Some(Constant::Char(name.as_str().chars().next().unwrap()))
|
||||
}
|
||||
&HeapCellValue::Atom(ref name, _) => {
|
||||
Some(Constant::Atom(name.clone(), None))
|
||||
}
|
||||
&HeapCellValue::Integer(ref n) => {
|
||||
Some(Constant::Integer(n.clone()))
|
||||
}
|
||||
&HeapCellValue::Rational(ref n) => {
|
||||
Some(Constant::Rational(n.clone()))
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
&Addr::Char(c) => Some(Constant::Char(c)),
|
||||
&Addr::Con(h) => match &machine_st.heap[h] {
|
||||
&HeapCellValue::Atom(ref name, _) if name.is_char() => {
|
||||
Some(Constant::Char(name.as_str().chars().next().unwrap()))
|
||||
}
|
||||
}
|
||||
&Addr::EmptyList => {
|
||||
Some(Constant::EmptyList)
|
||||
}
|
||||
&Addr::Fixnum(n) => {
|
||||
Some(Constant::Fixnum(n))
|
||||
}
|
||||
&Addr::Float(f) => {
|
||||
Some(Constant::Float(f))
|
||||
}
|
||||
&Addr::Usize(n) => {
|
||||
Some(Constant::Usize(n))
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
&HeapCellValue::Atom(ref name, _) => Some(Constant::Atom(name.clone(), None)),
|
||||
&HeapCellValue::Integer(ref n) => Some(Constant::Integer(n.clone())),
|
||||
&HeapCellValue::Rational(ref n) => Some(Constant::Rational(n.clone())),
|
||||
_ => None,
|
||||
},
|
||||
&Addr::EmptyList => Some(Constant::EmptyList),
|
||||
&Addr::Fixnum(n) => Some(Constant::Fixnum(n)),
|
||||
&Addr::Float(f) => Some(Constant::Float(f)),
|
||||
&Addr::Usize(n) => Some(Constant::Usize(n)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,61 +323,37 @@ impl HeapCellValue {
|
||||
#[inline]
|
||||
pub fn as_addr(&self, focus: usize) -> Addr {
|
||||
match self {
|
||||
HeapCellValue::Addr(ref a) => {
|
||||
*a
|
||||
}
|
||||
HeapCellValue::Atom(..) | HeapCellValue::DBRef(..) | HeapCellValue::Integer(..) |
|
||||
HeapCellValue::Rational(..) => {
|
||||
Addr::Con(focus)
|
||||
}
|
||||
HeapCellValue::LoadStatePayload(_) => {
|
||||
Addr::LoadStatePayload(focus)
|
||||
}
|
||||
HeapCellValue::NamedStr(_, _, _) => {
|
||||
Addr::Str(focus)
|
||||
}
|
||||
HeapCellValue::PartialString(..) => {
|
||||
Addr::PStrLocation(focus, 0)
|
||||
}
|
||||
HeapCellValue::Stream(_) => {
|
||||
Addr::Stream(focus)
|
||||
}
|
||||
HeapCellValue::TcpListener(_) => {
|
||||
Addr::TcpListener(focus)
|
||||
}
|
||||
HeapCellValue::Addr(ref a) => *a,
|
||||
HeapCellValue::Atom(..)
|
||||
| HeapCellValue::DBRef(..)
|
||||
| HeapCellValue::Integer(..)
|
||||
| HeapCellValue::Rational(..) => Addr::Con(focus),
|
||||
HeapCellValue::LoadStatePayload(_) => Addr::LoadStatePayload(focus),
|
||||
HeapCellValue::NamedStr(_, _, _) => Addr::Str(focus),
|
||||
HeapCellValue::PartialString(..) => Addr::PStrLocation(focus, 0),
|
||||
HeapCellValue::Stream(_) => Addr::Stream(focus),
|
||||
HeapCellValue::TcpListener(_) => Addr::TcpListener(focus),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn context_free_clone(&self) -> HeapCellValue {
|
||||
match self {
|
||||
&HeapCellValue::Addr(addr) => {
|
||||
HeapCellValue::Addr(addr)
|
||||
}
|
||||
&HeapCellValue::Atom(ref name, ref op) => {
|
||||
HeapCellValue::Atom(name.clone(), op.clone())
|
||||
}
|
||||
&HeapCellValue::DBRef(ref db_ref) => {
|
||||
HeapCellValue::DBRef(db_ref.clone())
|
||||
}
|
||||
&HeapCellValue::Integer(ref n) => {
|
||||
HeapCellValue::Integer(n.clone())
|
||||
}
|
||||
&HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr),
|
||||
&HeapCellValue::Atom(ref name, ref op) => HeapCellValue::Atom(name.clone(), op.clone()),
|
||||
&HeapCellValue::DBRef(ref db_ref) => HeapCellValue::DBRef(db_ref.clone()),
|
||||
&HeapCellValue::Integer(ref n) => HeapCellValue::Integer(n.clone()),
|
||||
&HeapCellValue::LoadStatePayload(_) => {
|
||||
HeapCellValue::Atom(clause_name!("$live_term_stream"), None)
|
||||
}
|
||||
&HeapCellValue::NamedStr(arity, ref name, ref op) => {
|
||||
HeapCellValue::NamedStr(arity, name.clone(), op.clone())
|
||||
}
|
||||
&HeapCellValue::Rational(ref r) => {
|
||||
HeapCellValue::Rational(r.clone())
|
||||
}
|
||||
&HeapCellValue::Rational(ref r) => HeapCellValue::Rational(r.clone()),
|
||||
&HeapCellValue::PartialString(ref pstr, has_tail) => {
|
||||
HeapCellValue::PartialString(pstr.clone(), has_tail)
|
||||
}
|
||||
&HeapCellValue::Stream(ref stream) => {
|
||||
HeapCellValue::Stream(stream.clone())
|
||||
}
|
||||
&HeapCellValue::Stream(ref stream) => HeapCellValue::Stream(stream.clone()),
|
||||
&HeapCellValue::TcpListener(_) => {
|
||||
HeapCellValue::Atom(clause_name!("$tcp_listener"), None)
|
||||
}
|
||||
@@ -473,8 +389,7 @@ impl Deref for CodeIndex {
|
||||
|
||||
impl CodeIndex {
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn new(ptr: IndexPtr) -> Self {
|
||||
pub(super) fn new(ptr: IndexPtr) -> Self {
|
||||
CodeIndex(Rc::new(Cell::new(ptr)))
|
||||
}
|
||||
|
||||
@@ -482,7 +397,7 @@ impl CodeIndex {
|
||||
pub fn is_undefined(&self) -> bool {
|
||||
match self.0.get() {
|
||||
IndexPtr::Undefined => true, // | &IndexPtr::DynamicUndefined => true,
|
||||
_ => false
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,7 +451,7 @@ pub enum CodePtr {
|
||||
CallN(usize, LocalCodePtr, bool), // arity, local, last call.
|
||||
Local(LocalCodePtr),
|
||||
// DynamicTransaction(DynamicTransactionType, LocalCodePtr), // the type of transaction, the return pointer.
|
||||
REPL(REPLCodePtr, LocalCodePtr), // the REPL code, the return pointer.
|
||||
REPL(REPLCodePtr, LocalCodePtr), // the REPL code, the return pointer.
|
||||
VerifyAttrInterrupt(usize), // location of the verify attribute interrupt code in the CodeDir.
|
||||
}
|
||||
|
||||
@@ -544,10 +459,10 @@ impl CodePtr {
|
||||
pub fn local(&self) -> LocalCodePtr {
|
||||
match self {
|
||||
&CodePtr::BuiltInClause(_, ref local)
|
||||
| &CodePtr::CallN(_, ref local, _)
|
||||
| &CodePtr::Local(ref local) => local.clone(),
|
||||
| &CodePtr::CallN(_, ref local, _)
|
||||
| &CodePtr::Local(ref local) => local.clone(),
|
||||
&CodePtr::VerifyAttrInterrupt(p) => LocalCodePtr::DirEntry(p),
|
||||
&CodePtr::REPL(_, p) => p // | &CodePtr::DynamicTransaction(_, p) => p,
|
||||
&CodePtr::REPL(_, p) => p, // | &CodePtr::DynamicTransaction(_, p) => p,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -566,12 +481,11 @@ pub enum LocalCodePtr {
|
||||
DirEntry(usize), // offset
|
||||
Halt,
|
||||
IndexingBuf(usize, usize, usize), // DirEntry offset, first internal offset, second internal offset
|
||||
// TopLevel(usize, usize), // chunk_num, offset
|
||||
// TopLevel(usize, usize), // chunk_num, offset
|
||||
}
|
||||
|
||||
impl LocalCodePtr {
|
||||
pub(crate)
|
||||
fn assign_if_local(&mut self, cp: CodePtr) {
|
||||
pub(crate) fn assign_if_local(&mut self, cp: CodePtr) {
|
||||
match cp {
|
||||
CodePtr::Local(local) => *self = local,
|
||||
_ => {}
|
||||
@@ -579,8 +493,7 @@ impl LocalCodePtr {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn abs_loc(&self) -> usize {
|
||||
pub(crate) fn abs_loc(&self) -> usize {
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(ref p) => *p,
|
||||
LocalCodePtr::IndexingBuf(ref p, ..) => *p,
|
||||
@@ -588,35 +501,28 @@ impl LocalCodePtr {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn is_reset_cont_marker(&self, code_repo: &CodeRepo, last_call: bool) -> bool {
|
||||
pub(crate) fn is_reset_cont_marker(&self, code_repo: &CodeRepo, last_call: bool) -> bool {
|
||||
match code_repo.lookup_instr(last_call, &CodePtr::Local(*self)) {
|
||||
Some(line) => {
|
||||
match line.as_ref() {
|
||||
Line::Control(ControlInstruction::CallClause(ref ct, ..)) => {
|
||||
if let ClauseType::System(SystemClauseType::ResetContinuationMarker) = *ct {
|
||||
return true;
|
||||
}
|
||||
Some(line) => match line.as_ref() {
|
||||
Line::Control(ControlInstruction::CallClause(ref ct, ..)) => {
|
||||
if let ClauseType::System(SystemClauseType::ResetContinuationMarker) = *ct {
|
||||
return true;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn as_functor<T: RawBlockTraits>(&self, heap: &mut HeapTemplate<T>) -> Addr {
|
||||
pub(crate) fn as_functor<T: RawBlockTraits>(&self, heap: &mut HeapTemplate<T>) -> Addr {
|
||||
let addr = Addr::HeapCell(heap.h());
|
||||
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(p) => {
|
||||
heap.append(functor!(
|
||||
"dir_entry",
|
||||
[integer(*p)]
|
||||
));
|
||||
heap.append(functor!("dir_entry", [integer(*p)]));
|
||||
}
|
||||
LocalCodePtr::Halt => {
|
||||
heap.append(functor!("halt"));
|
||||
@@ -658,7 +564,7 @@ impl PartialOrd<CodePtr> for CodePtr {
|
||||
impl PartialOrd<LocalCodePtr> for LocalCodePtr {
|
||||
fn partial_cmp(&self, other: &LocalCodePtr) -> Option<Ordering> {
|
||||
match (self, other) {
|
||||
(&LocalCodePtr::DirEntry(p1), &LocalCodePtr::DirEntry(ref p2)) |
|
||||
(&LocalCodePtr::DirEntry(p1), &LocalCodePtr::DirEntry(ref p2)) |
|
||||
(&LocalCodePtr::TopLevel(_, p1), &LocalCodePtr::TopLevel(_, ref p2)) => {
|
||||
p1.partial_cmp(p2)
|
||||
}
|
||||
@@ -693,12 +599,9 @@ impl Add<usize> for LocalCodePtr {
|
||||
#[inline]
|
||||
fn add(self, rhs: usize) -> Self::Output {
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(p) =>
|
||||
LocalCodePtr::DirEntry(p + rhs),
|
||||
LocalCodePtr::Halt =>
|
||||
unreachable!(),
|
||||
LocalCodePtr::IndexingBuf(p, o, i) =>
|
||||
LocalCodePtr::IndexingBuf(p, o, i + rhs),
|
||||
LocalCodePtr::DirEntry(p) => LocalCodePtr::DirEntry(p + rhs),
|
||||
LocalCodePtr::Halt => unreachable!(),
|
||||
LocalCodePtr::IndexingBuf(p, o, i) => LocalCodePtr::IndexingBuf(p, o, i + rhs),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -709,12 +612,11 @@ impl Sub<usize> for LocalCodePtr {
|
||||
#[inline]
|
||||
fn sub(self, rhs: usize) -> Self::Output {
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(p) =>
|
||||
p.checked_sub(rhs).map(LocalCodePtr::DirEntry),
|
||||
LocalCodePtr::Halt =>
|
||||
unreachable!(),
|
||||
LocalCodePtr::IndexingBuf(p, o, i) =>
|
||||
i.checked_sub(rhs).map(|r| LocalCodePtr::IndexingBuf(p, o, r)),
|
||||
LocalCodePtr::DirEntry(p) => p.checked_sub(rhs).map(LocalCodePtr::DirEntry),
|
||||
LocalCodePtr::Halt => unreachable!(),
|
||||
LocalCodePtr::IndexingBuf(p, o, i) => i
|
||||
.checked_sub(rhs)
|
||||
.map(|r| LocalCodePtr::IndexingBuf(p, o, r)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -723,15 +625,12 @@ impl SubAssign<usize> for LocalCodePtr {
|
||||
#[inline]
|
||||
fn sub_assign(&mut self, rhs: usize) {
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(ref mut p) =>
|
||||
*p -= rhs,
|
||||
LocalCodePtr::Halt | LocalCodePtr::IndexingBuf(..) =>
|
||||
unreachable!(),
|
||||
LocalCodePtr::DirEntry(ref mut p) => *p -= rhs,
|
||||
LocalCodePtr::Halt | LocalCodePtr::IndexingBuf(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl AddAssign<usize> for LocalCodePtr {
|
||||
#[inline]
|
||||
fn add_assign(&mut self, rhs: usize) {
|
||||
@@ -749,14 +648,12 @@ impl Add<usize> for CodePtr {
|
||||
|
||||
fn add(self, rhs: usize) -> Self::Output {
|
||||
match self {
|
||||
p @ CodePtr::REPL(..) |
|
||||
p @ CodePtr::VerifyAttrInterrupt(_) => { // |
|
||||
// p @ CodePtr::DynamicTransaction(..) => {
|
||||
p @ CodePtr::REPL(..) | p @ CodePtr::VerifyAttrInterrupt(_) => {
|
||||
// |
|
||||
// p @ CodePtr::DynamicTransaction(..) => {
|
||||
p
|
||||
}
|
||||
CodePtr::Local(local) => {
|
||||
CodePtr::Local(local + rhs)
|
||||
}
|
||||
CodePtr::Local(local) => CodePtr::Local(local + rhs),
|
||||
CodePtr::BuiltInClause(_, local) | CodePtr::CallN(_, local, _) => {
|
||||
CodePtr::Local(local + rhs)
|
||||
}
|
||||
@@ -784,7 +681,6 @@ impl SubAssign<usize> for CodePtr {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub type HeapVarDict = IndexMap<Rc<Var>, Addr>;
|
||||
pub type AllocVarDict = IndexMap<Rc<Var>, VarData>;
|
||||
|
||||
@@ -830,23 +726,17 @@ impl IndexStore {
|
||||
key: &PredicateKey,
|
||||
) -> Option<&mut PredicateSkeleton> {
|
||||
match (key.0.as_str(), key.1) {
|
||||
("term_expansion", 2) => {
|
||||
self.extensible_predicates.get_mut(key)
|
||||
}
|
||||
_ => {
|
||||
match compilation_target {
|
||||
CompilationTarget::User => {
|
||||
self.extensible_predicates.get_mut(key)
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
if let Some(module) = self.modules.get_mut(module_name) {
|
||||
module.extensible_predicates.get_mut(key)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
("term_expansion", 2) => self.extensible_predicates.get_mut(key),
|
||||
_ => match compilation_target {
|
||||
CompilationTarget::User => self.extensible_predicates.get_mut(key),
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
if let Some(module) = self.modules.get_mut(module_name) {
|
||||
module.extensible_predicates.get_mut(key)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -858,19 +748,17 @@ impl IndexStore {
|
||||
match (key.0.as_str(), key.1) {
|
||||
("term_expansion", 2) => {
|
||||
self.extensible_predicates.remove(key);
|
||||
},
|
||||
_ => {
|
||||
match compilation_target {
|
||||
CompilationTarget::User => {
|
||||
self.extensible_predicates.remove(key);
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
if let Some(module) = self.modules.get_mut(module_name) {
|
||||
module.extensible_predicates.remove(key);
|
||||
}
|
||||
}
|
||||
_ => match compilation_target {
|
||||
CompilationTarget::User => {
|
||||
self.extensible_predicates.remove(key);
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
if let Some(module) = self.modules.get_mut(module_name) {
|
||||
module.extensible_predicates.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -883,15 +771,9 @@ impl IndexStore {
|
||||
) -> Option<CodeIndex> {
|
||||
if module.as_str() == "user" {
|
||||
match ClauseType::from(name, arity, op_spec) {
|
||||
ClauseType::Named(name, arity, _) => {
|
||||
self.code_dir.get(&(name, arity)).cloned()
|
||||
}
|
||||
ClauseType::Op(name, spec, ..) => {
|
||||
self.code_dir.get(&(name, spec.arity())).cloned()
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
ClauseType::Named(name, arity, _) => self.code_dir.get(&(name, arity)).cloned(),
|
||||
ClauseType::Op(name, spec, ..) => self.code_dir.get(&(name, spec.arity())).cloned(),
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
self.modules.get(&module).and_then(|module| {
|
||||
@@ -902,9 +784,7 @@ impl IndexStore {
|
||||
ClauseType::Op(name, spec, ..) => {
|
||||
module.code_dir.get(&(name, spec.arity())).cloned()
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -917,44 +797,32 @@ impl IndexStore {
|
||||
compilation_target: &CompilationTarget,
|
||||
) -> Option<&Vec<MetaSpec>> {
|
||||
match compilation_target {
|
||||
CompilationTarget::User => {
|
||||
self.meta_predicates.get(&(name, arity))
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
match self.modules.get(module_name) {
|
||||
Some(ref module) => {
|
||||
module.meta_predicates.get(&(name.clone(), arity))
|
||||
.or_else(|| {
|
||||
self.meta_predicates.get(&(name, arity))
|
||||
})
|
||||
}
|
||||
None => {
|
||||
self.meta_predicates.get(&(name, arity))
|
||||
}
|
||||
}
|
||||
}
|
||||
CompilationTarget::User => self.meta_predicates.get(&(name, arity)),
|
||||
CompilationTarget::Module(ref module_name) => match self.modules.get(module_name) {
|
||||
Some(ref module) => module
|
||||
.meta_predicates
|
||||
.get(&(name.clone(), arity))
|
||||
.or_else(|| self.meta_predicates.get(&(name, arity))),
|
||||
None => self.meta_predicates.get(&(name, arity)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_dynamic_predicate(&self, module_name: ClauseName, key: PredicateKey) -> bool {
|
||||
match module_name.as_str() {
|
||||
"user" => {
|
||||
self.extensible_predicates.get(&key)
|
||||
"user" => self
|
||||
.extensible_predicates
|
||||
.get(&key)
|
||||
.map(|skeleton| skeleton.is_dynamic)
|
||||
.unwrap_or(false),
|
||||
_ => match self.modules.get(&module_name) {
|
||||
Some(ref module) => module
|
||||
.extensible_predicates
|
||||
.get(&key)
|
||||
.map(|skeleton| skeleton.is_dynamic)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
_ => {
|
||||
match self.modules.get(&module_name) {
|
||||
Some(ref module) => {
|
||||
module.extensible_predicates.get(&key)
|
||||
.map(|skeleton| skeleton.is_dynamic)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
None => {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
.unwrap_or(false),
|
||||
None => false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -963,8 +831,7 @@ impl IndexStore {
|
||||
IndexStore::default()
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn get_cleaner_sites(&self) -> (usize, usize) {
|
||||
pub(super) fn get_cleaner_sites(&self) -> (usize, usize) {
|
||||
let r_w_h = clause_name!("run_cleaners_with_handling");
|
||||
let r_wo_h = clause_name!("run_cleaners_without_handling");
|
||||
let iso_ext = clause_name!("iso_ext");
|
||||
@@ -996,10 +863,8 @@ pub enum RefOrOwned<'a, T: 'a> {
|
||||
impl<'a, T: 'a + fmt::Debug> fmt::Debug for RefOrOwned<'a, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
&RefOrOwned::Borrowed(ref borrowed) =>
|
||||
write!(f, "Borrowed({:?})", borrowed),
|
||||
&RefOrOwned::Owned(ref owned) =>
|
||||
write!(f, "Owned({:?})", owned),
|
||||
&RefOrOwned::Borrowed(ref borrowed) => write!(f, "Borrowed({:?})", borrowed),
|
||||
&RefOrOwned::Owned(ref owned) => write!(f, "Owned({:?})", owned),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1012,7 +877,9 @@ impl<'a, T> RefOrOwned<'a, T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_owned(self) -> T where T: Clone
|
||||
pub fn to_owned(self) -> T
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
match self {
|
||||
RefOrOwned::Borrowed(item) => item.clone(),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::tabled_rc::*;
|
||||
use crate::prolog_parser_rebis::{clause_name, temp_v};
|
||||
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
@@ -14,7 +15,9 @@ use crate::machine::stack::*;
|
||||
use crate::machine::streams::*;
|
||||
use crate::rug::Integer;
|
||||
|
||||
use crate::downcast::Any;
|
||||
use crate::downcast::{
|
||||
downcast, downcast_methods, downcast_methods_core, downcast_methods_std, impl_downcast, Any,
|
||||
};
|
||||
|
||||
use crate::indexmap::IndexMap;
|
||||
|
||||
@@ -32,33 +35,26 @@ pub struct Ball {
|
||||
}
|
||||
|
||||
impl Ball {
|
||||
pub(super)
|
||||
fn new() -> Self {
|
||||
pub(super) fn new() -> Self {
|
||||
Ball {
|
||||
boundary: 0,
|
||||
stub: Heap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn reset(&mut self) {
|
||||
pub(super) fn reset(&mut self) {
|
||||
self.boundary = 0;
|
||||
self.stub.clear();
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn copy_and_align(&self, h: usize) -> Heap {
|
||||
pub(super) fn copy_and_align(&self, h: usize) -> Heap {
|
||||
let diff = self.boundary as i64 - h as i64;
|
||||
let mut stub = Heap::new();
|
||||
|
||||
for heap_value in self.stub.iter_from(0) {
|
||||
stub.push(match heap_value {
|
||||
&HeapCellValue::Addr(addr) => {
|
||||
HeapCellValue::Addr(addr - diff)
|
||||
}
|
||||
heap_value => {
|
||||
heap_value.context_free_clone()
|
||||
}
|
||||
&HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr - diff),
|
||||
heap_value => heap_value.context_free_clone(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -123,11 +119,7 @@ pub(super) struct CopyBallTerm<'a> {
|
||||
}
|
||||
|
||||
impl<'a> CopyBallTerm<'a> {
|
||||
pub(super) fn new(
|
||||
stack: &'a mut Stack,
|
||||
heap: &'a mut Heap,
|
||||
stub: &'a mut Heap,
|
||||
) -> Self {
|
||||
pub(super) fn new(stack: &'a mut Stack, heap: &'a mut Heap, stub: &'a mut Heap) -> Self {
|
||||
let hb = heap.h();
|
||||
|
||||
CopyBallTerm {
|
||||
@@ -182,12 +174,8 @@ impl<'a> CopierTarget for CopyBallTerm<'a> {
|
||||
let index = h - self.heap_boundary;
|
||||
self.stub[index].as_addr(h)
|
||||
}
|
||||
Addr::StackCell(fr, sc) => {
|
||||
self.stack.index_and_frame(fr)[sc]
|
||||
}
|
||||
addr => {
|
||||
addr
|
||||
}
|
||||
Addr::StackCell(fr, sc) => self.stack.index_and_frame(fr)[sc],
|
||||
addr => addr,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,9 +214,7 @@ impl Index<RegType> for MachineState {
|
||||
impl IndexMut<RegType> for MachineState {
|
||||
fn index_mut(&mut self, reg: RegType) -> &mut Self::Output {
|
||||
match reg {
|
||||
RegType::Temp(temp) => {
|
||||
&mut self.registers[temp]
|
||||
}
|
||||
RegType::Temp(temp) => &mut self.registers[temp],
|
||||
RegType::Perm(perm) => {
|
||||
let e = self.e;
|
||||
|
||||
@@ -255,15 +241,12 @@ pub(super) enum HeapPtr {
|
||||
|
||||
impl HeapPtr {
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn read(&self, heap: &Heap) -> Addr {
|
||||
pub(super) fn read(&self, heap: &Heap) -> Addr {
|
||||
match self {
|
||||
&HeapPtr::HeapCell(h) => {
|
||||
Addr::HeapCell(h)
|
||||
}
|
||||
&HeapPtr::HeapCell(h) => Addr::HeapCell(h),
|
||||
&HeapPtr::PStrChar(h, n) => {
|
||||
if let &HeapCellValue::PartialString(ref pstr, has_tail) = &heap[h] {
|
||||
if let Some(c) = pstr.range_from(n ..).next() {
|
||||
if let Some(c) = pstr.range_from(n..).next() {
|
||||
Addr::Char(c)
|
||||
} else if has_tail {
|
||||
Addr::HeapCell(h + 1)
|
||||
@@ -274,9 +257,7 @@ impl HeapPtr {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
&HeapPtr::PStrLocation(h, n) => {
|
||||
Addr::PStrLocation(h, n)
|
||||
}
|
||||
&HeapPtr::PStrLocation(h, n) => Addr::PStrLocation(h, n),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,16 +294,11 @@ pub struct MachineState {
|
||||
pub(super) last_call: bool,
|
||||
pub(crate) heap_locs: HeapVarDict,
|
||||
pub(crate) flags: MachineFlags,
|
||||
pub(crate) at_end_of_expansion: bool
|
||||
pub(crate) at_end_of_expansion: bool,
|
||||
}
|
||||
|
||||
impl MachineState {
|
||||
pub(crate)
|
||||
fn read_term(
|
||||
&mut self,
|
||||
mut stream: Stream,
|
||||
indices: &mut IndexStore,
|
||||
) -> CallResult {
|
||||
pub(crate) fn read_term(&mut self, mut stream: Stream, indices: &mut IndexStore) -> CallResult {
|
||||
self.check_stream_properties(
|
||||
&mut stream,
|
||||
StreamType::Text,
|
||||
@@ -342,11 +318,7 @@ impl MachineState {
|
||||
let mut orig_stream = stream.clone();
|
||||
|
||||
loop {
|
||||
match self.read(
|
||||
stream.clone(),
|
||||
self.atom_tbl.clone(),
|
||||
&indices.op_dir,
|
||||
) {
|
||||
match self.read(stream.clone(), self.atom_tbl.clone(), &indices.op_dir) {
|
||||
Ok(term_write_result) => {
|
||||
let term = self[temp_v!(2)];
|
||||
self.unify(Addr::HeapCell(term_write_result.heap_loc), term);
|
||||
@@ -363,7 +335,8 @@ impl MachineState {
|
||||
let h = self.heap.h();
|
||||
let spec = fetch_atom_op_spec(clause_name!("="), None, &indices.op_dir);
|
||||
|
||||
self.heap.push(HeapCellValue::NamedStr(2, clause_name!("="), spec));
|
||||
self.heap
|
||||
.push(HeapCellValue::NamedStr(2, clause_name!("="), spec));
|
||||
self.heap.push(HeapCellValue::Atom(var_atom, None));
|
||||
self.heap.push(HeapCellValue::Addr(binding));
|
||||
|
||||
@@ -406,8 +379,7 @@ impl MachineState {
|
||||
}
|
||||
|
||||
let vars_addr = self[temp_v!(4)];
|
||||
let vars_offset =
|
||||
Addr::HeapCell(self.heap.to_list(var_list.into_iter()));
|
||||
let vars_offset = Addr::HeapCell(self.heap.to_list(var_list.into_iter()));
|
||||
|
||||
self.unify(vars_offset, vars_addr);
|
||||
|
||||
@@ -427,7 +399,7 @@ impl MachineState {
|
||||
self[temp_v!(2)],
|
||||
&mut orig_stream,
|
||||
clause_name!("read_term"),
|
||||
3
|
||||
3,
|
||||
)?;
|
||||
|
||||
if orig_stream.options.eof_action == EOFAction::Reset {
|
||||
@@ -448,12 +420,10 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn write_term<'a>(
|
||||
pub(crate) fn write_term<'a>(
|
||||
&'a self,
|
||||
op_dir: &'a OpDir,
|
||||
) -> Result<Option<HCPrinter<'a, PrinterOutputter>>, MachineStub>
|
||||
{
|
||||
) -> Result<Option<HCPrinter<'a, PrinterOutputter>>, MachineStub> {
|
||||
let ignore_ops = self.store(self.deref(self[temp_v!(3)]));
|
||||
let numbervars = self.store(self.deref(self[temp_v!(4)]));
|
||||
let quoted = self.store(self.deref(self[temp_v!(5)]));
|
||||
@@ -462,7 +432,7 @@ impl MachineState {
|
||||
let mut printer = HCPrinter::new(&self, op_dir, PrinterOutputter::new());
|
||||
|
||||
if let &Addr::Con(h) = &ignore_ops {
|
||||
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
|
||||
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
|
||||
printer.ignore_ops = name.as_str() == "true";
|
||||
} else {
|
||||
unreachable!()
|
||||
@@ -470,7 +440,7 @@ impl MachineState {
|
||||
}
|
||||
|
||||
if let &Addr::Con(h) = &numbervars {
|
||||
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
|
||||
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
|
||||
printer.numbervars = name.as_str() == "true";
|
||||
} else {
|
||||
unreachable!()
|
||||
@@ -478,7 +448,7 @@ impl MachineState {
|
||||
}
|
||||
|
||||
if let &Addr::Con(h) = "ed {
|
||||
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
|
||||
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
|
||||
printer.quoted = name.as_str() == "true";
|
||||
} else {
|
||||
unreachable!()
|
||||
@@ -514,9 +484,7 @@ impl MachineState {
|
||||
for addr in addrs {
|
||||
match addr {
|
||||
Addr::Str(s) => match &self.heap[s] {
|
||||
&HeapCellValue::NamedStr(2, ref name, _)
|
||||
if name.as_str() == "=" =>
|
||||
{
|
||||
&HeapCellValue::NamedStr(2, ref name, _) if name.as_str() == "=" => {
|
||||
let atom = self.heap[s + 1].as_addr(s + 1);
|
||||
let var = self.heap[s + 2].as_addr(s + 2);
|
||||
|
||||
@@ -540,11 +508,9 @@ impl MachineState {
|
||||
|
||||
var_names.insert(var, atom);
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -558,8 +524,7 @@ impl MachineState {
|
||||
Ok(Some(printer))
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn throw_undefined_error(&mut self, name: ClauseName, arity: usize) -> MachineStub {
|
||||
pub(super) fn throw_undefined_error(&mut self, name: ClauseName, arity: usize) -> MachineStub {
|
||||
let stub = MachineError::functor_stub(name.clone(), arity);
|
||||
let h = self.heap.h();
|
||||
let key = ExistenceError::Procedure(name, arity);
|
||||
@@ -568,13 +533,11 @@ impl MachineState {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn heap_pstr_iter<'a>(&'a self, focus: Addr) -> HeapPStrIter<'a> {
|
||||
pub(crate) fn heap_pstr_iter<'a>(&'a self, focus: Addr) -> HeapPStrIter<'a> {
|
||||
HeapPStrIter::new(self, focus)
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn try_char_list(&self, addrs: Vec<Addr>) -> Result<String, MachineError> {
|
||||
pub(super) fn try_char_list(&self, addrs: Vec<Addr>) -> Result<String, MachineError> {
|
||||
let mut chars = String::new();
|
||||
let mut iter = addrs.iter();
|
||||
|
||||
@@ -594,55 +557,46 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
let h = self.heap.h();
|
||||
|
||||
return Err(
|
||||
MachineError::type_error(h, ValidType::Character, addr)
|
||||
);
|
||||
return Err(MachineError::type_error(h, ValidType::Character, addr));
|
||||
}
|
||||
|
||||
Ok(chars)
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn read_predicate_key(&self, name: Addr, arity: Addr) -> (ClauseName, usize) {
|
||||
pub(super) fn read_predicate_key(&self, name: Addr, arity: Addr) -> (ClauseName, usize) {
|
||||
let predicate_name = atom_from!(self, self.store(self.deref(name)));
|
||||
let arity = self.store(self.deref(arity));
|
||||
|
||||
let arity =
|
||||
match Number::try_from((arity, &self.heap)) {
|
||||
Ok(Number::Integer(n)) if &*n >= &0 && &*n <= &MAX_ARITY =>
|
||||
n.to_usize().unwrap(),
|
||||
Ok(Number::Fixnum(n)) if n >= 0 && n <= MAX_ARITY as isize =>
|
||||
usize::try_from(n).unwrap(),
|
||||
_ =>
|
||||
unreachable!()
|
||||
};
|
||||
let arity = match Number::try_from((arity, &self.heap)) {
|
||||
Ok(Number::Integer(n)) if &*n >= &0 && &*n <= &MAX_ARITY => n.to_usize().unwrap(),
|
||||
Ok(Number::Fixnum(n)) if n >= 0 && n <= MAX_ARITY as isize => {
|
||||
usize::try_from(n).unwrap()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
(predicate_name, arity)
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn call_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
||||
pub(super) fn call_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
||||
self.cp.assign_if_local(self.p.clone() + 1);
|
||||
self.num_of_args = arity;
|
||||
self.b0 = self.b;
|
||||
self.p = CodePtr::Local(p);
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn execute_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
||||
pub(super) fn execute_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
||||
self.num_of_args = arity;
|
||||
self.b0 = self.b;
|
||||
self.p = CodePtr::Local(p);
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn module_lookup(
|
||||
pub(super) fn module_lookup(
|
||||
&mut self,
|
||||
indices: &IndexStore,
|
||||
call_policy: &mut Box<dyn CallPolicy>,
|
||||
@@ -687,10 +641,15 @@ pub(crate) type CallResult = Result<(), Vec<HeapCellValue>>;
|
||||
pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
||||
let b = machine_st.b;
|
||||
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
|
||||
let n = machine_st
|
||||
.stack
|
||||
.index_or_frame(b)
|
||||
.prelude
|
||||
.univ_prelude
|
||||
.num_cells;
|
||||
|
||||
for i in 1 .. n + 1 {
|
||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
|
||||
for i in 1..n + 1 {
|
||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
||||
}
|
||||
|
||||
machine_st.num_of_args = n;
|
||||
@@ -706,17 +665,24 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||
|
||||
machine_st.trail.truncate(machine_st.tr);
|
||||
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
||||
machine_st
|
||||
.heap
|
||||
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
||||
|
||||
let attr_var_init_queue_b =
|
||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
||||
let attr_var_init_bindings_b =
|
||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
|
||||
let attr_var_init_queue_b = machine_st
|
||||
.stack
|
||||
.index_or_frame(b)
|
||||
.prelude
|
||||
.attr_var_init_queue_b;
|
||||
let attr_var_init_bindings_b = machine_st
|
||||
.stack
|
||||
.index_or_frame(b)
|
||||
.prelude
|
||||
.attr_var_init_bindings_b;
|
||||
|
||||
machine_st.attr_var_init.backtrack(
|
||||
attr_var_init_queue_b,
|
||||
attr_var_init_bindings_b,
|
||||
);
|
||||
machine_st
|
||||
.attr_var_init
|
||||
.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
|
||||
|
||||
machine_st.hb = machine_st.heap.h();
|
||||
machine_st.p += 1;
|
||||
@@ -726,10 +692,15 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
|
||||
fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
||||
let b = machine_st.b;
|
||||
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
|
||||
let n = machine_st
|
||||
.stack
|
||||
.index_or_frame(b)
|
||||
.prelude
|
||||
.univ_prelude
|
||||
.num_cells;
|
||||
|
||||
for i in 1 .. n + 1 {
|
||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
|
||||
for i in 1..n + 1 {
|
||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
||||
}
|
||||
|
||||
machine_st.num_of_args = n;
|
||||
@@ -745,14 +716,24 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||
|
||||
machine_st.trail.truncate(machine_st.tr);
|
||||
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
||||
machine_st
|
||||
.heap
|
||||
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
||||
|
||||
let attr_var_init_queue_b =
|
||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
||||
let attr_var_init_bindings_b =
|
||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
|
||||
let attr_var_init_queue_b = machine_st
|
||||
.stack
|
||||
.index_or_frame(b)
|
||||
.prelude
|
||||
.attr_var_init_queue_b;
|
||||
let attr_var_init_bindings_b = machine_st
|
||||
.stack
|
||||
.index_or_frame(b)
|
||||
.prelude
|
||||
.attr_var_init_bindings_b;
|
||||
|
||||
machine_st.attr_var_init.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
|
||||
machine_st
|
||||
.attr_var_init
|
||||
.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
|
||||
|
||||
machine_st.hb = machine_st.heap.h();
|
||||
machine_st.p = CodePtr::Local(dir_entry!(machine_st.p.local().abs_loc() + offset));
|
||||
@@ -762,10 +743,15 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
|
||||
fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
||||
let b = machine_st.b;
|
||||
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
|
||||
let n = machine_st
|
||||
.stack
|
||||
.index_or_frame(b)
|
||||
.prelude
|
||||
.univ_prelude
|
||||
.num_cells;
|
||||
|
||||
for i in 1 .. n + 1 {
|
||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
|
||||
for i in 1..n + 1 {
|
||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
||||
}
|
||||
|
||||
machine_st.num_of_args = n;
|
||||
@@ -779,17 +765,24 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||
|
||||
machine_st.trail.truncate(machine_st.tr);
|
||||
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
||||
machine_st
|
||||
.heap
|
||||
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
||||
|
||||
let attr_var_init_queue_b =
|
||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
||||
let attr_var_init_bindings_b =
|
||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
|
||||
let attr_var_init_queue_b = machine_st
|
||||
.stack
|
||||
.index_or_frame(b)
|
||||
.prelude
|
||||
.attr_var_init_queue_b;
|
||||
let attr_var_init_bindings_b = machine_st
|
||||
.stack
|
||||
.index_or_frame(b)
|
||||
.prelude
|
||||
.attr_var_init_bindings_b;
|
||||
|
||||
machine_st.attr_var_init.backtrack(
|
||||
attr_var_init_queue_b,
|
||||
attr_var_init_bindings_b,
|
||||
);
|
||||
machine_st
|
||||
.attr_var_init
|
||||
.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
|
||||
|
||||
machine_st.b = machine_st.stack.index_or_frame(b).prelude.b;
|
||||
machine_st.stack.truncate(b);
|
||||
@@ -802,10 +795,15 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
|
||||
fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult {
|
||||
let b = machine_st.b;
|
||||
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
|
||||
let n = machine_st
|
||||
.stack
|
||||
.index_or_frame(b)
|
||||
.prelude
|
||||
.univ_prelude
|
||||
.num_cells;
|
||||
|
||||
for i in 1 .. n + 1 {
|
||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
|
||||
for i in 1..n + 1 {
|
||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
||||
}
|
||||
|
||||
machine_st.num_of_args = n;
|
||||
@@ -819,17 +817,24 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||
|
||||
machine_st.trail.truncate(machine_st.tr);
|
||||
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
||||
machine_st
|
||||
.heap
|
||||
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
||||
|
||||
let attr_var_init_queue_b =
|
||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
||||
let attr_var_init_bindings_b =
|
||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
|
||||
let attr_var_init_queue_b = machine_st
|
||||
.stack
|
||||
.index_or_frame(b)
|
||||
.prelude
|
||||
.attr_var_init_queue_b;
|
||||
let attr_var_init_bindings_b = machine_st
|
||||
.stack
|
||||
.index_or_frame(b)
|
||||
.prelude
|
||||
.attr_var_init_bindings_b;
|
||||
|
||||
machine_st.attr_var_init.backtrack(
|
||||
attr_var_init_queue_b,
|
||||
attr_var_init_bindings_b,
|
||||
);
|
||||
machine_st
|
||||
.attr_var_init
|
||||
.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
|
||||
|
||||
machine_st.b = machine_st.stack.index_or_frame(b).prelude.b;
|
||||
machine_st.stack.truncate(b);
|
||||
@@ -928,13 +933,13 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
Addr::Con(h) if machine_st.heap.atom_at(h) => {
|
||||
if let HeapCellValue::Atom(ref atom, _) = &machine_st.heap[h] {
|
||||
match atom.as_str() {
|
||||
">" | "<" | "=" => {
|
||||
}
|
||||
">" | "<" | "=" => {}
|
||||
_ => {
|
||||
let stub =
|
||||
MachineError::functor_stub(clause_name!("compare"), 3);
|
||||
|
||||
let err = MachineError::domain_error(DomainErrorType::Order, a1);
|
||||
let err =
|
||||
MachineError::domain_error(DomainErrorType::Order, a1);
|
||||
return Err(machine_st.error_form(err, stub));
|
||||
}
|
||||
}
|
||||
@@ -948,8 +953,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
let err = MachineError::type_error(h, ValidType::Atom, a1);
|
||||
return Err(machine_st.error_form(err, stub));
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let atom = match machine_st.compare_term_test(&a2, &a3) {
|
||||
@@ -998,9 +1002,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
let addr = machine_st[temp_v!(1)];
|
||||
let eof = clause_name!("end_of_file".to_string(), machine_st.atom_tbl);
|
||||
|
||||
let atom = machine_st.heap.to_unifiable(
|
||||
HeapCellValue::Atom(eof, None)
|
||||
);
|
||||
let atom = machine_st.heap.to_unifiable(HeapCellValue::Atom(eof, None));
|
||||
|
||||
machine_st.unify(addr, atom);
|
||||
}
|
||||
@@ -1056,7 +1058,9 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
let mut list = machine_st.try_from_list(temp_v!(1), stub)?;
|
||||
|
||||
list.sort_unstable_by(|a1, a2| {
|
||||
machine_st.compare_term_test(a1, a2).unwrap_or(Ordering::Less)
|
||||
machine_st
|
||||
.compare_term_test(a1, a2)
|
||||
.unwrap_or(Ordering::Less)
|
||||
});
|
||||
|
||||
machine_st.term_dedup(&mut list);
|
||||
@@ -1081,7 +1085,9 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
}
|
||||
|
||||
key_pairs.sort_by(|a1, a2| {
|
||||
machine_st.compare_term_test(&a1.0, &a2.0).unwrap_or(Ordering::Less)
|
||||
machine_st
|
||||
.compare_term_test(&a1.0, &a2.0)
|
||||
.unwrap_or(Ordering::Less)
|
||||
});
|
||||
|
||||
let key_pairs = key_pairs.into_iter().map(|kp| kp.1);
|
||||
@@ -1155,11 +1161,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
let stub = MachineError::functor_stub(clause_name!("call"), arity + 1);
|
||||
|
||||
return Err(machine_st.error_form(
|
||||
MachineError::type_error(
|
||||
machine_st.heap.h(),
|
||||
ValidType::Callable,
|
||||
name
|
||||
),
|
||||
MachineError::type_error(machine_st.heap.h(), ValidType::Callable, name),
|
||||
stub,
|
||||
));
|
||||
}
|
||||
@@ -1200,7 +1202,8 @@ impl CallPolicy for CWILCallPolicy {
|
||||
arity: usize,
|
||||
idx: &CodeIndex,
|
||||
) -> CallResult {
|
||||
self.prev_policy.context_call(machine_st, name, arity, idx)?;//, indices)?;
|
||||
self.prev_policy
|
||||
.context_call(machine_st, name, arity, idx)?; //, indices)?;
|
||||
self.increment(machine_st)
|
||||
}
|
||||
|
||||
@@ -1239,7 +1242,7 @@ impl CallPolicy for CWILCallPolicy {
|
||||
code_dir,
|
||||
op_dir,
|
||||
current_input_stream,
|
||||
current_output_stream
|
||||
current_output_stream,
|
||||
)?;
|
||||
|
||||
self.increment(machine_st)
|
||||
@@ -1283,8 +1286,7 @@ pub(crate) struct CWILCallPolicy {
|
||||
}
|
||||
|
||||
impl CWILCallPolicy {
|
||||
pub(crate)
|
||||
fn new_in_place(policy: &mut Box<dyn CallPolicy>) {
|
||||
pub(crate) fn new_in_place(policy: &mut Box<dyn CallPolicy>) {
|
||||
let mut prev_policy: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {});
|
||||
mem::swap(&mut prev_policy, policy);
|
||||
|
||||
@@ -1319,8 +1321,7 @@ impl CWILCallPolicy {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn add_limit(&mut self, mut limit: Integer, b: usize) -> &Integer {
|
||||
pub(crate) fn add_limit(&mut self, mut limit: Integer, b: usize) -> &Integer {
|
||||
limit += &self.count;
|
||||
|
||||
match self.limits.last().cloned() {
|
||||
@@ -1331,8 +1332,7 @@ impl CWILCallPolicy {
|
||||
&self.count
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn remove_limit(&mut self, b: usize) -> &Integer {
|
||||
pub(crate) fn remove_limit(&mut self, b: usize) -> &Integer {
|
||||
if let Some((_, bp)) = self.limits.last().cloned() {
|
||||
if bp == b {
|
||||
self.limits.pop();
|
||||
@@ -1342,13 +1342,11 @@ impl CWILCallPolicy {
|
||||
&self.count
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn is_empty(&self) -> bool {
|
||||
pub(crate) fn is_empty(&self) -> bool {
|
||||
self.limits.is_empty()
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn into_inner(&mut self) -> Box<dyn CallPolicy> {
|
||||
pub(crate) fn into_inner(&mut self) -> Box<dyn CallPolicy> {
|
||||
let mut new_inner: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {});
|
||||
mem::swap(&mut self.prev_policy, &mut new_inner);
|
||||
new_inner
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,8 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::tabled_rc::*;
|
||||
use crate::prolog_parser_rebis::{clause_name, temp_v};
|
||||
|
||||
use crate::lazy_static::lazy_static;
|
||||
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
@@ -34,8 +37,8 @@ mod machine_state_impl;
|
||||
mod system_calls;
|
||||
|
||||
//use crate::machine::attributed_variables::*;
|
||||
use crate::machine::compile::*;
|
||||
use crate::machine::code_repo::*;
|
||||
use crate::machine::compile::*;
|
||||
// use crate::machine::loader::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
@@ -45,6 +48,7 @@ use crate::machine::streams::*;
|
||||
use crate::indexmap::IndexMap;
|
||||
|
||||
//use std::convert::TryFrom;
|
||||
use prolog_parser_rebis::ast::ClauseName;
|
||||
use std::fs::File;
|
||||
use std::mem;
|
||||
use std::path::PathBuf;
|
||||
@@ -162,18 +166,13 @@ impl Machine {
|
||||
}
|
||||
|
||||
fn load_file(&mut self, path: String, stream: Stream) {
|
||||
self.machine_st[temp_v!(1)] = Addr::Stream(
|
||||
self.machine_st.heap.push(HeapCellValue::Stream(
|
||||
stream,
|
||||
))
|
||||
);
|
||||
self.machine_st[temp_v!(1)] =
|
||||
Addr::Stream(self.machine_st.heap.push(HeapCellValue::Stream(stream)));
|
||||
|
||||
self.machine_st[temp_v!(2)] = Addr::Con(
|
||||
self.machine_st.heap.push(HeapCellValue::Atom(
|
||||
clause_name!(path, self.machine_st.atom_tbl),
|
||||
None,
|
||||
))
|
||||
);
|
||||
self.machine_st[temp_v!(2)] = Addr::Con(self.machine_st.heap.push(HeapCellValue::Atom(
|
||||
clause_name!(path, self.machine_st.atom_tbl),
|
||||
None,
|
||||
)));
|
||||
|
||||
self.run_module_predicate(clause_name!("loader"), (clause_name!("file_load"), 2));
|
||||
}
|
||||
@@ -206,11 +205,9 @@ impl Machine {
|
||||
bootstrapping_compile(
|
||||
Stream::from(include_str!("attributed_variables.pl")),
|
||||
self,
|
||||
ListingSource::from_file_and_path(
|
||||
clause_name!("attributed_variables"),
|
||||
path_buf,
|
||||
),
|
||||
).unwrap();
|
||||
ListingSource::from_file_and_path(clause_name!("attributed_variables"), path_buf),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut path_buf = current_dir();
|
||||
path_buf.push("machine/project_attributes.pl");
|
||||
@@ -218,11 +215,9 @@ impl Machine {
|
||||
bootstrapping_compile(
|
||||
Stream::from(include_str!("project_attributes.pl")),
|
||||
self,
|
||||
ListingSource::from_file_and_path(
|
||||
clause_name!("project_attributes"),
|
||||
path_buf,
|
||||
),
|
||||
).unwrap();
|
||||
ListingSource::from_file_and_path(clause_name!("project_attributes"), path_buf),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if let Some(module) = self.indices.modules.get(&clause_name!("$atts")) {
|
||||
if let Some(code_index) = module.code_dir.get(&(clause_name!("driver"), 2)) {
|
||||
@@ -255,12 +250,13 @@ impl Machine {
|
||||
|
||||
fn configure_modules(&mut self) {
|
||||
fn update_call_n_indices(loader: &Module, target_module: &mut Module) {
|
||||
for arity in 1 .. 66 {
|
||||
for arity in 1..66 {
|
||||
let key = (clause_name!("call"), arity);
|
||||
|
||||
match loader.code_dir.get(&key) {
|
||||
Some(src_code_index) => {
|
||||
let target_code_index = target_module.code_dir
|
||||
let target_code_index = target_module
|
||||
.code_dir
|
||||
.entry(key.clone())
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined));
|
||||
|
||||
@@ -289,10 +285,11 @@ impl Machine {
|
||||
builtins.module_decl.exports.push(export.clone());
|
||||
}
|
||||
|
||||
for arity in 10 .. 66 {
|
||||
builtins.module_decl.exports.push(
|
||||
ModuleExport::PredicateKey((clause_name!("call"), arity)),
|
||||
);
|
||||
for arity in 10..66 {
|
||||
builtins
|
||||
.module_decl
|
||||
.exports
|
||||
.push(ModuleExport::PredicateKey((clause_name!("call"), arity)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,8 +303,7 @@ impl Machine {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(user_input: Stream, user_output: Stream) -> Self
|
||||
{
|
||||
pub fn new(user_input: Stream, user_output: Stream) -> Self {
|
||||
use crate::ref_thread_local::RefThreadLocal;
|
||||
|
||||
let mut wam = Machine {
|
||||
@@ -333,16 +329,15 @@ impl Machine {
|
||||
clause_name!("ops_and_meta_predicates.pl"),
|
||||
lib_path.clone(),
|
||||
),
|
||||
).unwrap();
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
bootstrapping_compile(
|
||||
Stream::from(LIBRARIES.borrow()["builtins"]),
|
||||
&mut wam,
|
||||
ListingSource::from_file_and_path(
|
||||
clause_name!("builtins.pl"),
|
||||
lib_path.clone(),
|
||||
),
|
||||
).unwrap();
|
||||
ListingSource::from_file_and_path(clause_name!("builtins.pl"), lib_path.clone()),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if let Some(builtins) = wam.indices.modules.get(&clause_name!("builtins")) {
|
||||
load_module(
|
||||
@@ -361,11 +356,9 @@ impl Machine {
|
||||
bootstrapping_compile(
|
||||
Stream::from(include_str!("../loader.pl")),
|
||||
&mut wam,
|
||||
ListingSource::from_file_and_path(
|
||||
clause_name!("loader.pl"),
|
||||
lib_path.clone(),
|
||||
),
|
||||
).unwrap();
|
||||
ListingSource::from_file_and_path(clause_name!("loader.pl"), lib_path.clone()),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
wam.configure_modules();
|
||||
|
||||
@@ -391,25 +384,19 @@ impl Machine {
|
||||
pub fn configure_streams(&mut self) {
|
||||
self.user_input.options.alias = Some(clause_name!("user_input"));
|
||||
|
||||
self.indices.stream_aliases.insert(
|
||||
clause_name!("user_input"),
|
||||
self.user_input.clone(),
|
||||
);
|
||||
self.indices
|
||||
.stream_aliases
|
||||
.insert(clause_name!("user_input"), self.user_input.clone());
|
||||
|
||||
self.indices.streams.insert(
|
||||
self.user_input.clone()
|
||||
);
|
||||
self.indices.streams.insert(self.user_input.clone());
|
||||
|
||||
self.user_output.options.alias = Some(clause_name!("user_output"));
|
||||
|
||||
self.indices.stream_aliases.insert(
|
||||
clause_name!("user_output"),
|
||||
self.user_output.clone(),
|
||||
);
|
||||
self.indices
|
||||
.stream_aliases
|
||||
.insert(clause_name!("user_output"), self.user_output.clone());
|
||||
|
||||
self.indices.streams.insert(
|
||||
self.user_output.clone()
|
||||
);
|
||||
self.indices.streams.insert(self.user_output.clone());
|
||||
}
|
||||
|
||||
fn throw_session_error(&mut self, err: SessionError, key: PredicateKey) {
|
||||
@@ -508,8 +495,7 @@ impl Machine {
|
||||
self.machine_st.p = CodePtr::Local(p);
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn run_query(&mut self) {
|
||||
pub(super) fn run_query(&mut self) {
|
||||
while !self.machine_st.p.is_halt() {
|
||||
self.machine_st.query_stepper(
|
||||
&mut self.indices,
|
||||
@@ -546,26 +532,22 @@ impl MachineState {
|
||||
user_output: &mut Stream,
|
||||
) {
|
||||
match instr {
|
||||
&Line::Arithmetic(ref arith_instr) => {
|
||||
self.execute_arith_instr(arith_instr)
|
||||
}
|
||||
&Line::Arithmetic(ref arith_instr) => self.execute_arith_instr(arith_instr),
|
||||
&Line::Choice(ref choice_instr) => {
|
||||
self.execute_choice_instr(choice_instr, &mut policies.call_policy)
|
||||
}
|
||||
&Line::Cut(ref cut_instr) => {
|
||||
self.execute_cut_instr(cut_instr, &mut policies.cut_policy)
|
||||
}
|
||||
&Line::Control(ref control_instr) => {
|
||||
self.execute_ctrl_instr(
|
||||
indices,
|
||||
code_repo,
|
||||
&mut policies.call_policy,
|
||||
&mut policies.cut_policy,
|
||||
user_input,
|
||||
user_output,
|
||||
control_instr,
|
||||
)
|
||||
}
|
||||
&Line::Control(ref control_instr) => self.execute_ctrl_instr(
|
||||
indices,
|
||||
code_repo,
|
||||
&mut policies.call_policy,
|
||||
&mut policies.cut_policy,
|
||||
user_input,
|
||||
user_output,
|
||||
control_instr,
|
||||
),
|
||||
&Line::Fact(ref fact_instr) => {
|
||||
self.execute_fact_instr(&fact_instr);
|
||||
self.p += 1;
|
||||
@@ -617,15 +599,13 @@ impl MachineState {
|
||||
|
||||
fn check_machine_index(&mut self, code_repo: &CodeRepo) -> bool {
|
||||
match self.p {
|
||||
CodePtr::Local(LocalCodePtr::DirEntry(p)) |
|
||||
CodePtr::Local(LocalCodePtr::IndexingBuf(p, ..))
|
||||
if p < code_repo.code.len() => {
|
||||
}
|
||||
CodePtr::Local(LocalCodePtr::DirEntry(p))
|
||||
| CodePtr::Local(LocalCodePtr::IndexingBuf(p, ..))
|
||||
if p < code_repo.code.len() => {}
|
||||
CodePtr::Local(LocalCodePtr::Halt) | CodePtr::REPL(..) => {
|
||||
return false;
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
true
|
||||
@@ -689,13 +669,7 @@ impl MachineState {
|
||||
user_output: &mut Stream,
|
||||
) {
|
||||
loop {
|
||||
self.execute_instr(
|
||||
indices,
|
||||
policies,
|
||||
code_repo,
|
||||
user_input,
|
||||
user_output,
|
||||
);
|
||||
self.execute_instr(indices, policies, code_repo, user_input, user_output);
|
||||
|
||||
if self.fail {
|
||||
self.backtrack();
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::tabled_rc::*;
|
||||
use crate::prolog_parser_rebis::{atom, clause_name, rc_atom};
|
||||
|
||||
use crate::forms::*;
|
||||
use crate::iterators::*;
|
||||
use crate::machine::*;
|
||||
use crate::machine::load_state::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::*;
|
||||
|
||||
use crate::indexmap::IndexSet;
|
||||
|
||||
@@ -85,27 +86,24 @@ fn setup_op_decl(
|
||||
to_op_decl(prec, spec.as_str(), name)
|
||||
}
|
||||
|
||||
fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, CompilationError>
|
||||
{
|
||||
fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, CompilationError> {
|
||||
match term {
|
||||
Term::Clause(_, ref slash, ref mut terms, Some(_))
|
||||
if (slash.as_str() == "/" || slash.as_str() == "//") && terms.len() == 2 =>
|
||||
{
|
||||
let arity = *terms.pop().unwrap();
|
||||
let name = *terms.pop().unwrap();
|
||||
let name = *terms.pop().unwrap();
|
||||
|
||||
let arity = arity
|
||||
.to_constant()
|
||||
.and_then(|c| {
|
||||
match c {
|
||||
Constant::Integer(n) => n.to_usize(),
|
||||
Constant::Fixnum(n) => usize::try_from(n).ok(),
|
||||
_ => None
|
||||
}
|
||||
.and_then(|c| match c {
|
||||
Constant::Integer(n) => n.to_usize(),
|
||||
Constant::Fixnum(n) => usize::try_from(n).ok(),
|
||||
_ => None,
|
||||
})
|
||||
.ok_or(CompilationError::InvalidModuleExport)?;
|
||||
|
||||
let name = name
|
||||
let name = name
|
||||
.to_constant()
|
||||
.and_then(|c| c.to_atom())
|
||||
.ok_or(CompilationError::InvalidModuleExport)?;
|
||||
@@ -116,9 +114,7 @@ fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, Compilatio
|
||||
Ok((name, arity + 2))
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
Err(CompilationError::InvalidModuleExport)
|
||||
}
|
||||
_ => Err(CompilationError::InvalidModuleExport),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,10 +151,7 @@ fn setup_module_export(
|
||||
.or_else(|_| {
|
||||
if let Term::Clause(_, name, terms, _) = term {
|
||||
if terms.len() == 3 && name.as_str() == "op" {
|
||||
Ok(ModuleExport::OpDecl(setup_op_decl(
|
||||
terms,
|
||||
atom_tbl
|
||||
)?))
|
||||
Ok(ModuleExport::OpDecl(setup_op_decl(terms, atom_tbl)?))
|
||||
} else {
|
||||
Err(CompilationError::InvalidModuleDecl)
|
||||
}
|
||||
@@ -168,8 +161,7 @@ fn setup_module_export(
|
||||
})
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn setup_module_export_list(
|
||||
pub(super) fn setup_module_export_list(
|
||||
mut export_list: Term,
|
||||
atom_tbl: TabledData<Atom>,
|
||||
) -> Result<Vec<ModuleExport>, CompilationError> {
|
||||
@@ -218,8 +210,7 @@ fn setup_use_module_decl(mut terms: Vec<Box<Term>>) -> Result<ModuleSource, Comp
|
||||
.map(|c| ModuleSource::Library(c))
|
||||
.ok_or(CompilationError::InvalidUseModuleDecl)
|
||||
}
|
||||
Term::Constant(_, Constant::Atom(ref name, _)) =>
|
||||
Ok(ModuleSource::File(name.clone())),
|
||||
Term::Constant(_, Constant::Atom(ref name, _)) => Ok(ModuleSource::File(name.clone())),
|
||||
_ => Err(CompilationError::InvalidUseModuleDecl),
|
||||
}
|
||||
}
|
||||
@@ -271,12 +262,8 @@ fn setup_qualified_import(
|
||||
.map(|c| ModuleSource::Library(c))
|
||||
.ok_or(CompilationError::InvalidUseModuleDecl)
|
||||
}
|
||||
Term::Constant(_, Constant::Atom(ref name, _)) => {
|
||||
Ok(ModuleSource::File(name.clone()))
|
||||
}
|
||||
_ => {
|
||||
Err(CompilationError::InvalidUseModuleDecl)
|
||||
}
|
||||
Term::Constant(_, Constant::Atom(ref name, _)) => Ok(ModuleSource::File(name.clone())),
|
||||
_ => Err(CompilationError::InvalidUseModuleDecl),
|
||||
}?;
|
||||
|
||||
let mut exports = IndexSet::new();
|
||||
@@ -334,8 +321,7 @@ fn setup_qualified_import(
|
||||
fn setup_meta_predicate<'a>(
|
||||
mut terms: Vec<Box<Term>>,
|
||||
load_state: &LoadState<'a>,
|
||||
) -> Result<(ClauseName, ClauseName, Vec<MetaSpec>), CompilationError>
|
||||
{
|
||||
) -> Result<(ClauseName, ClauseName, Vec<MetaSpec>), CompilationError> {
|
||||
fn get_name_and_meta_specs(
|
||||
name: ClauseName,
|
||||
terms: &mut [Box<Term>],
|
||||
@@ -345,26 +331,23 @@ fn setup_meta_predicate<'a>(
|
||||
for meta_spec in terms.into_iter() {
|
||||
match &**meta_spec {
|
||||
Term::Constant(_, Constant::Atom(meta_spec, _)) => {
|
||||
let meta_spec =
|
||||
match meta_spec.as_str() {
|
||||
"+" => MetaSpec::Plus,
|
||||
"-" => MetaSpec::Minus,
|
||||
"?" => MetaSpec::Either,
|
||||
_ => return Err(CompilationError::InvalidMetaPredicateDecl),
|
||||
};
|
||||
let meta_spec = match meta_spec.as_str() {
|
||||
"+" => MetaSpec::Plus,
|
||||
"-" => MetaSpec::Minus,
|
||||
"?" => MetaSpec::Either,
|
||||
_ => return Err(CompilationError::InvalidMetaPredicateDecl),
|
||||
};
|
||||
|
||||
meta_specs.push(meta_spec);
|
||||
}
|
||||
Term::Constant(_, Constant::Fixnum(n)) => {
|
||||
match usize::try_from(*n) {
|
||||
Ok(n) if n <= MAX_ARITY => {
|
||||
meta_specs.push(MetaSpec::RequiresExpansionWithArgument(n));
|
||||
}
|
||||
_ => {
|
||||
return Err(CompilationError::InvalidMetaPredicateDecl);
|
||||
}
|
||||
Term::Constant(_, Constant::Fixnum(n)) => match usize::try_from(*n) {
|
||||
Ok(n) if n <= MAX_ARITY => {
|
||||
meta_specs.push(MetaSpec::RequiresExpansionWithArgument(n));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(CompilationError::InvalidMetaPredicateDecl);
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
return Err(CompilationError::InvalidMetaPredicateDecl);
|
||||
}
|
||||
@@ -375,42 +358,35 @@ fn setup_meta_predicate<'a>(
|
||||
}
|
||||
|
||||
match *terms.pop().unwrap() {
|
||||
Term::Clause(_, name, mut terms, _)
|
||||
if name.as_str() == ":" && terms.len() == 2 => {
|
||||
let spec = *terms.pop().unwrap();
|
||||
let module_name = *terms.pop().unwrap();
|
||||
Term::Clause(_, name, mut terms, _) if name.as_str() == ":" && terms.len() == 2 => {
|
||||
let spec = *terms.pop().unwrap();
|
||||
let module_name = *terms.pop().unwrap();
|
||||
|
||||
match module_name {
|
||||
Term::Constant(_, Constant::Atom(module_name, _)) => {
|
||||
match spec {
|
||||
Term::Clause(_, name, mut terms, _) => {
|
||||
let (name, meta_specs) =
|
||||
get_name_and_meta_specs(name, &mut terms)?;
|
||||
match module_name {
|
||||
Term::Constant(_, Constant::Atom(module_name, _)) => match spec {
|
||||
Term::Clause(_, name, mut terms, _) => {
|
||||
let (name, meta_specs) = get_name_and_meta_specs(name, &mut terms)?;
|
||||
|
||||
Ok((module_name, name, meta_specs))
|
||||
}
|
||||
_ => {
|
||||
Err(CompilationError::InvalidMetaPredicateDecl)
|
||||
}
|
||||
}
|
||||
Ok((module_name, name, meta_specs))
|
||||
}
|
||||
_ => {
|
||||
Err(CompilationError::InvalidMetaPredicateDecl)
|
||||
}
|
||||
}
|
||||
_ => Err(CompilationError::InvalidMetaPredicateDecl),
|
||||
},
|
||||
_ => Err(CompilationError::InvalidMetaPredicateDecl),
|
||||
}
|
||||
}
|
||||
Term::Clause(_, name, mut terms, _) => {
|
||||
let (name, meta_specs) = get_name_and_meta_specs(name, &mut terms)?;
|
||||
Ok((load_state.compilation_target.module_name(), name, meta_specs))
|
||||
}
|
||||
_ => {
|
||||
Err(CompilationError::InvalidMetaPredicateDecl)
|
||||
Ok((
|
||||
load_state.compilation_target.module_name(),
|
||||
name,
|
||||
meta_specs,
|
||||
))
|
||||
}
|
||||
_ => Err(CompilationError::InvalidMetaPredicateDecl),
|
||||
}
|
||||
}
|
||||
|
||||
fn merge_clauses(tls: &mut VecDeque<TopLevel>) -> Result<TopLevel, CompilationError>
|
||||
{
|
||||
fn merge_clauses(tls: &mut VecDeque<TopLevel>) -> Result<TopLevel, CompilationError> {
|
||||
let mut clauses = vec![];
|
||||
|
||||
while let Some(tl) = tls.pop_front() {
|
||||
@@ -432,9 +408,7 @@ fn merge_clauses(tls: &mut VecDeque<TopLevel>) -> Result<TopLevel, CompilationEr
|
||||
let clause = PredicateClause::Rule(rule);
|
||||
clauses.push(clause);
|
||||
}
|
||||
TopLevel::Predicate(predicate) => {
|
||||
clauses.extend(predicate.into_iter())
|
||||
}
|
||||
TopLevel::Predicate(predicate) => clauses.extend(predicate.into_iter()),
|
||||
_ => {
|
||||
tls.push_front(tl);
|
||||
break;
|
||||
@@ -506,8 +480,8 @@ fn check_for_internal_if_then(terms: &mut Vec<Term>) {
|
||||
|
||||
conq_terms.push_front(Term::Constant(
|
||||
Cell::default(),
|
||||
Constant::Atom(clause_name!("blocked_!"), None))
|
||||
);
|
||||
Constant::Atom(clause_name!("blocked_!"), None),
|
||||
));
|
||||
|
||||
while let Some(term) = pre_cut_terms.pop_back() {
|
||||
conq_terms.push_front(term);
|
||||
@@ -531,38 +505,29 @@ fn setup_declaration<'a>(
|
||||
let atom_tbl = load_state.wam.machine_st.atom_tbl.clone();
|
||||
|
||||
match term {
|
||||
Term::Clause(_, name, mut terms, _) =>
|
||||
match (name.as_str(), terms.len()) {
|
||||
("dynamic", 1) => {
|
||||
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
|
||||
Ok(Declaration::Dynamic(name, arity))
|
||||
}
|
||||
("module", 2) =>
|
||||
Ok(Declaration::Module(setup_module_decl(terms, atom_tbl)?)),
|
||||
("op", 3) =>
|
||||
Ok(Declaration::Op(setup_op_decl(terms, atom_tbl)?)),
|
||||
("non_counted_backtracking", 1) => {
|
||||
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
|
||||
Ok(Declaration::NonCountedBacktracking(name, arity))
|
||||
}
|
||||
("use_module", 1) => {
|
||||
Ok(Declaration::UseModule(setup_use_module_decl(terms)?))
|
||||
}
|
||||
("use_module", 2) => {
|
||||
let (name, exports) = setup_qualified_import(terms, atom_tbl)?;
|
||||
Ok(Declaration::UseQualifiedModule(name, exports))
|
||||
}
|
||||
("meta_predicate", 1) => {
|
||||
let (module_name, name, meta_specs) = setup_meta_predicate(terms, load_state)?;
|
||||
Ok(Declaration::MetaPredicate(module_name, name, meta_specs))
|
||||
}
|
||||
_ => {
|
||||
Err(CompilationError::InconsistentEntry)
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
Err(CompilationError::InconsistentEntry)
|
||||
}
|
||||
Term::Clause(_, name, mut terms, _) => match (name.as_str(), terms.len()) {
|
||||
("dynamic", 1) => {
|
||||
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
|
||||
Ok(Declaration::Dynamic(name, arity))
|
||||
}
|
||||
("module", 2) => Ok(Declaration::Module(setup_module_decl(terms, atom_tbl)?)),
|
||||
("op", 3) => Ok(Declaration::Op(setup_op_decl(terms, atom_tbl)?)),
|
||||
("non_counted_backtracking", 1) => {
|
||||
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
|
||||
Ok(Declaration::NonCountedBacktracking(name, arity))
|
||||
}
|
||||
("use_module", 1) => Ok(Declaration::UseModule(setup_use_module_decl(terms)?)),
|
||||
("use_module", 2) => {
|
||||
let (name, exports) = setup_qualified_import(terms, atom_tbl)?;
|
||||
Ok(Declaration::UseQualifiedModule(name, exports))
|
||||
}
|
||||
("meta_predicate", 1) => {
|
||||
let (module_name, name, meta_specs) = setup_meta_predicate(terms, load_state)?;
|
||||
Ok(Declaration::MetaPredicate(module_name, name, meta_specs))
|
||||
}
|
||||
_ => Err(CompilationError::InconsistentEntry),
|
||||
},
|
||||
_ => Err(CompilationError::InconsistentEntry),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -596,8 +561,7 @@ pub(crate) struct Preprocessor {
|
||||
}
|
||||
|
||||
impl Preprocessor {
|
||||
pub(super)
|
||||
fn new(flags: MachineFlags) -> Self {
|
||||
pub(super) fn new(flags: MachineFlags) -> Self {
|
||||
Preprocessor {
|
||||
flags,
|
||||
queue: VecDeque::new(),
|
||||
@@ -606,12 +570,8 @@ impl Preprocessor {
|
||||
|
||||
fn setup_fact(&mut self, term: Term) -> Result<Term, CompilationError> {
|
||||
match term {
|
||||
Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) => {
|
||||
Ok(term)
|
||||
}
|
||||
_ => {
|
||||
Err(CompilationError::InadmissibleFact)
|
||||
}
|
||||
Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) => Ok(term),
|
||||
_ => Err(CompilationError::InadmissibleFact),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -712,109 +672,97 @@ impl Preprocessor {
|
||||
Ok(clause_to_query_term(load_state, name, vec![], fixity))
|
||||
}
|
||||
}
|
||||
Term::Constant(_, Constant::Char('!')) => {
|
||||
Ok(QueryTerm::BlockedCut)
|
||||
}
|
||||
Term::Constant(_, Constant::Char('!')) => Ok(QueryTerm::BlockedCut),
|
||||
Term::Var(_, ref v) if v.as_str() == "!" => {
|
||||
Ok(QueryTerm::UnblockedCut(Cell::default()))
|
||||
}
|
||||
Term::Clause(r, name, mut terms, fixity) => {
|
||||
match (name.as_str(), terms.len()) {
|
||||
(";", 2) => {
|
||||
let term = Term::Clause(r, name.clone(), terms, fixity);
|
||||
Term::Clause(r, name, mut terms, fixity) => match (name.as_str(), terms.len()) {
|
||||
(";", 2) => {
|
||||
let term = Term::Clause(r, name.clone(), terms, fixity);
|
||||
|
||||
let (stub, clauses) = self.fabricate_disjunct(term);
|
||||
self.queue.push_back(clauses);
|
||||
let (stub, clauses) = self.fabricate_disjunct(term);
|
||||
self.queue.push_back(clauses);
|
||||
|
||||
Ok(QueryTerm::Jump(stub))
|
||||
}
|
||||
("->", 2) => {
|
||||
let conq = *terms.pop().unwrap();
|
||||
let prec = *terms.pop().unwrap();
|
||||
Ok(QueryTerm::Jump(stub))
|
||||
}
|
||||
("->", 2) => {
|
||||
let conq = *terms.pop().unwrap();
|
||||
let prec = *terms.pop().unwrap();
|
||||
|
||||
let (stub, clauses) = self.fabricate_if_then(prec, conq);
|
||||
self.queue.push_back(clauses);
|
||||
let (stub, clauses) = self.fabricate_if_then(prec, conq);
|
||||
self.queue.push_back(clauses);
|
||||
|
||||
Ok(QueryTerm::Jump(stub))
|
||||
}
|
||||
("\\+", 1) => {
|
||||
terms.push(Box::new(Term::Constant(
|
||||
Cell::default(),
|
||||
Constant::Atom(clause_name!("$fail"), None)
|
||||
)));
|
||||
Ok(QueryTerm::Jump(stub))
|
||||
}
|
||||
("\\+", 1) => {
|
||||
terms.push(Box::new(Term::Constant(
|
||||
Cell::default(),
|
||||
Constant::Atom(clause_name!("$fail"), None),
|
||||
)));
|
||||
|
||||
let conq = Term::Constant(
|
||||
Cell::default(),
|
||||
Constant::Atom(clause_name!("true"), None)
|
||||
);
|
||||
let conq =
|
||||
Term::Constant(Cell::default(), Constant::Atom(clause_name!("true"), None));
|
||||
|
||||
let prec = Term::Clause(Cell::default(), clause_name!("->"), terms, None);
|
||||
let terms = vec![Box::new(prec), Box::new(conq)];
|
||||
let prec = Term::Clause(Cell::default(), clause_name!("->"), terms, None);
|
||||
let terms = vec![Box::new(prec), Box::new(conq)];
|
||||
|
||||
let term = Term::Clause(Cell::default(), clause_name!(";"), terms, None);
|
||||
let (stub, clauses) = self.fabricate_disjunct(term);
|
||||
let term = Term::Clause(Cell::default(), clause_name!(";"), terms, None);
|
||||
let (stub, clauses) = self.fabricate_disjunct(term);
|
||||
|
||||
debug_assert!(clauses.len() > 0);
|
||||
self.queue.push_back(clauses);
|
||||
debug_assert!(clauses.len() > 0);
|
||||
self.queue.push_back(clauses);
|
||||
|
||||
Ok(QueryTerm::Jump(stub))
|
||||
}
|
||||
("$get_level", 1) => {
|
||||
if let Term::Var(_, ref var) = *terms[0] {
|
||||
Ok(QueryTerm::GetLevelAndUnify(Cell::default(), var.clone()))
|
||||
} else {
|
||||
Err(CompilationError::InadmissibleQueryTerm)
|
||||
}
|
||||
}
|
||||
(":", 2) => {
|
||||
let predicate_name = *terms.pop().unwrap();
|
||||
let module_name = *terms.pop().unwrap();
|
||||
|
||||
match (module_name, predicate_name) {
|
||||
(Term::Constant(_, Constant::Atom(module_name, _)),
|
||||
Term::Constant(_, Constant::Atom(predicate_name, fixity))) => {
|
||||
Ok(qualified_clause_to_query_term(
|
||||
load_state,
|
||||
module_name,
|
||||
predicate_name,
|
||||
vec![],
|
||||
fixity,
|
||||
))
|
||||
}
|
||||
(Term::Constant(_, Constant::Atom(module_name, _)),
|
||||
Term::Clause(_, name, terms, fixity)) => {
|
||||
Ok(qualified_clause_to_query_term(
|
||||
load_state,
|
||||
module_name,
|
||||
name,
|
||||
terms,
|
||||
fixity,
|
||||
))
|
||||
}
|
||||
(module_name, predicate_name) => {
|
||||
terms.push(Box::new(module_name));
|
||||
terms.push(Box::new(predicate_name));
|
||||
|
||||
Ok(clause_to_query_term(load_state, name, terms, fixity))
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
Ok(clause_to_query_term(load_state, name, terms, fixity))
|
||||
Ok(QueryTerm::Jump(stub))
|
||||
}
|
||||
("$get_level", 1) => {
|
||||
if let Term::Var(_, ref var) = *terms[0] {
|
||||
Ok(QueryTerm::GetLevelAndUnify(Cell::default(), var.clone()))
|
||||
} else {
|
||||
Err(CompilationError::InadmissibleQueryTerm)
|
||||
}
|
||||
}
|
||||
}
|
||||
Term::Var(..) => {
|
||||
Ok(QueryTerm::Clause(
|
||||
Cell::default(),
|
||||
ClauseType::CallN,
|
||||
vec![Box::new(term)],
|
||||
false,
|
||||
))
|
||||
}
|
||||
_ => {
|
||||
Err(CompilationError::InadmissibleQueryTerm)
|
||||
}
|
||||
(":", 2) => {
|
||||
let predicate_name = *terms.pop().unwrap();
|
||||
let module_name = *terms.pop().unwrap();
|
||||
|
||||
match (module_name, predicate_name) {
|
||||
(
|
||||
Term::Constant(_, Constant::Atom(module_name, _)),
|
||||
Term::Constant(_, Constant::Atom(predicate_name, fixity)),
|
||||
) => Ok(qualified_clause_to_query_term(
|
||||
load_state,
|
||||
module_name,
|
||||
predicate_name,
|
||||
vec![],
|
||||
fixity,
|
||||
)),
|
||||
(
|
||||
Term::Constant(_, Constant::Atom(module_name, _)),
|
||||
Term::Clause(_, name, terms, fixity),
|
||||
) => Ok(qualified_clause_to_query_term(
|
||||
load_state,
|
||||
module_name,
|
||||
name,
|
||||
terms,
|
||||
fixity,
|
||||
)),
|
||||
(module_name, predicate_name) => {
|
||||
terms.push(Box::new(module_name));
|
||||
terms.push(Box::new(predicate_name));
|
||||
|
||||
Ok(clause_to_query_term(load_state, name, terms, fixity))
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => Ok(clause_to_query_term(load_state, name, terms, fixity)),
|
||||
},
|
||||
Term::Var(..) => Ok(QueryTerm::Clause(
|
||||
Cell::default(),
|
||||
ClauseType::CallN,
|
||||
vec![Box::new(term)],
|
||||
false,
|
||||
)),
|
||||
_ => Err(CompilationError::InadmissibleQueryTerm),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -835,9 +783,7 @@ impl Preprocessor {
|
||||
self.to_query_term(load_state, Term::Clause(r, name, subterms, fixity))
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
self.to_query_term(load_state, term)
|
||||
}
|
||||
_ => self.to_query_term(load_state, term),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -884,30 +830,23 @@ impl Preprocessor {
|
||||
mut terms: Vec<Box<Term>>,
|
||||
cut_context: CutContext,
|
||||
) -> Result<Rule, CompilationError> {
|
||||
let post_head_terms: Vec<_> = terms.drain(1 ..).collect();
|
||||
let post_head_terms: Vec<_> = terms.drain(1..).collect();
|
||||
|
||||
let mut query_terms =
|
||||
self.setup_query(load_state, post_head_terms, cut_context)?;
|
||||
let mut query_terms = self.setup_query(load_state, post_head_terms, cut_context)?;
|
||||
|
||||
let clauses = query_terms.drain(1 ..).collect();
|
||||
let clauses = query_terms.drain(1..).collect();
|
||||
let qt = query_terms.pop().unwrap();
|
||||
|
||||
match *terms.pop().unwrap() {
|
||||
Term::Clause(_, name, terms, _) => {
|
||||
Ok(Rule {
|
||||
head: (name, terms, qt),
|
||||
clauses,
|
||||
})
|
||||
}
|
||||
Term::Constant(_, Constant::Atom(name, _)) => {
|
||||
Ok(Rule {
|
||||
head: (name, vec![], qt),
|
||||
clauses,
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
Err(CompilationError::InvalidRuleHead)
|
||||
}
|
||||
Term::Clause(_, name, terms, _) => Ok(Rule {
|
||||
head: (name, terms, qt),
|
||||
clauses,
|
||||
}),
|
||||
Term::Constant(_, Constant::Atom(name, _)) => Ok(Rule {
|
||||
head: (name, vec![], qt),
|
||||
clauses,
|
||||
}),
|
||||
_ => Err(CompilationError::InvalidRuleHead),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -917,11 +856,14 @@ impl Preprocessor {
|
||||
terms: Vec<Box<Term>>,
|
||||
cut_context: CutContext,
|
||||
) -> Result<TopLevel, CompilationError> {
|
||||
Ok(TopLevel::Query(self.setup_query(load_state, terms, cut_context)?))
|
||||
Ok(TopLevel::Query(self.setup_query(
|
||||
load_state,
|
||||
terms,
|
||||
cut_context,
|
||||
)?))
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn try_term_to_tl<'a>(
|
||||
pub(super) fn try_term_to_tl<'a>(
|
||||
&mut self,
|
||||
load_state: &mut LoadState<'a>,
|
||||
term: Term,
|
||||
@@ -944,9 +886,7 @@ impl Preprocessor {
|
||||
Ok(TopLevel::Fact(self.setup_fact(term)?))
|
||||
}
|
||||
}
|
||||
term => {
|
||||
Ok(TopLevel::Fact(self.setup_fact(term)?))
|
||||
}
|
||||
term => Ok(TopLevel::Fact(self.setup_fact(term)?)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -965,21 +905,18 @@ impl Preprocessor {
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn parse_queue<'a>(
|
||||
pub(super) fn parse_queue<'a>(
|
||||
&mut self,
|
||||
load_state: &mut LoadState<'a>,
|
||||
) -> Result<VecDeque<TopLevel>, CompilationError> {
|
||||
let mut queue = VecDeque::new();
|
||||
|
||||
while let Some(terms) = self.queue.pop_front() {
|
||||
let clauses = merge_clauses(
|
||||
&mut self.try_terms_to_tls(
|
||||
load_state,
|
||||
terms,
|
||||
CutContext::HasCutVariable,
|
||||
)?
|
||||
)?;
|
||||
let clauses = merge_clauses(&mut self.try_terms_to_tls(
|
||||
load_state,
|
||||
terms,
|
||||
CutContext::HasCutVariable,
|
||||
)?)?;
|
||||
|
||||
queue.push_back(clauses);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
63
src/main.rs
63
src/main.rs
@@ -1,43 +1,35 @@
|
||||
extern crate blake2;
|
||||
extern crate chrono;
|
||||
extern crate cpu_time;
|
||||
extern crate crossterm;
|
||||
extern crate divrem;
|
||||
#[macro_use]
|
||||
extern crate downcast;
|
||||
extern crate git_version;
|
||||
extern crate hostname;
|
||||
extern crate indexmap;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate libc;
|
||||
extern crate native_tls;
|
||||
extern crate nix;
|
||||
extern crate openssl;
|
||||
extern crate ordered_float;
|
||||
#[macro_use]
|
||||
extern crate prolog_parser_rebis;
|
||||
#[macro_use]
|
||||
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 blake2;
|
||||
use chrono;
|
||||
use cpu_time;
|
||||
use crossterm;
|
||||
use divrem;
|
||||
use downcast;
|
||||
use git_version;
|
||||
use indexmap;
|
||||
use lazy_static;
|
||||
use native_tls;
|
||||
use nix::sys::signal;
|
||||
use openssl;
|
||||
use ordered_float;
|
||||
use prolog_parser_rebis;
|
||||
use ref_thread_local;
|
||||
use ring;
|
||||
use ripemd160;
|
||||
use rustyline;
|
||||
use sha3;
|
||||
use 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]
|
||||
mod macros;
|
||||
mod allocator;
|
||||
mod arithmetic;
|
||||
mod machine;
|
||||
mod codegen;
|
||||
mod clause_types;
|
||||
mod codegen;
|
||||
mod debray_allocator;
|
||||
mod fixtures;
|
||||
mod forms;
|
||||
@@ -46,17 +38,18 @@ mod heap_print;
|
||||
mod indexing;
|
||||
mod instructions;
|
||||
mod iterators;
|
||||
mod machine;
|
||||
mod read;
|
||||
mod targets;
|
||||
mod write;
|
||||
|
||||
use machine::*;
|
||||
use machine::streams::*;
|
||||
use machine::*;
|
||||
use read::*;
|
||||
|
||||
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();
|
||||
if signal == signal::Signal::SIGINT {
|
||||
INTERRUPT.store(true, Ordering::Relaxed);
|
||||
|
||||
Reference in New Issue
Block a user