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

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

View File

@@ -15,15 +15,13 @@ fn find_prolog_files(libraries: &mut File, prefix: &str, current_dir: &Path) {
for entry in entries.filter_map(Result::ok).map(|e| e.path()) { for entry in entries.filter_map(Result::ok).map(|e| e.path()) {
if entry.is_dir() { if entry.is_dir() {
if let Some(file_name) = entry.file_name() { if let Some(file_name) = entry.file_name() {
let new_prefix = let new_prefix = prefix.to_owned() + file_name.to_str().unwrap() + "/";
prefix.to_owned() + file_name.to_str().unwrap() + "/";
find_prolog_files(libraries, &new_prefix, &entry); find_prolog_files(libraries, &new_prefix, &entry);
} }
} else if entry.is_file() { } else if entry.is_file() {
let ext = std::ffi::OsStr::new("pl"); let ext = std::ffi::OsStr::new("pl");
if entry.extension() == Some(ext) { if entry.extension() == Some(ext) {
let contain = let contain = String::from_utf8(fs::read(&entry).unwrap()).unwrap();
String::from_utf8(fs::read(&entry).unwrap()).unwrap();
let name = entry.file_stem().unwrap().to_str().unwrap(); let name = entry.file_stem().unwrap().to_str().unwrap();
let line = format!( let line = format!(
@@ -47,7 +45,7 @@ fn main() {
libraries libraries
.write_all( .write_all(
b"ref_thread_local! { b"ref_thread_local::ref_thread_local! {
pub static managed LIBRARIES: IndexMap<&'static str, &'static str> = { pub static managed LIBRARIES: IndexMap<&'static str, &'static str> = {
let mut m = IndexMap::new();\n", let mut m = IndexMap::new();\n",
) )

View File

@@ -1,4 +1,5 @@
use crate::prolog_parser_rebis::ast::*; use crate::prolog_parser_rebis::ast::*;
use crate::prolog_parser_rebis::temp_v;
use crate::fixtures::*; use crate::fixtures::*;
use crate::forms::*; use crate::forms::*;
@@ -14,8 +15,13 @@ pub trait Allocator<'a> {
fn mark_anon_var<Target>(&mut self, _: Level, _: GenContext, _: &mut Vec<Target>) fn mark_anon_var<Target>(&mut self, _: Level, _: GenContext, _: &mut Vec<Target>)
where where
Target: CompilationTarget<'a>; Target: CompilationTarget<'a>;
fn mark_non_var<Target>(&mut self, _: Level, _: GenContext, _: &'a Cell<RegType>, _: &mut Vec<Target>) fn mark_non_var<Target>(
where &mut self,
_: Level,
_: GenContext,
_: &'a Cell<RegType>,
_: &mut Vec<Target>,
) where
Target: CompilationTarget<'a>; Target: CompilationTarget<'a>;
fn mark_reserved_var<Target>( fn mark_reserved_var<Target>(
&mut self, &mut self,
@@ -28,8 +34,14 @@ pub trait Allocator<'a> {
_: bool, _: bool,
) where ) where
Target: CompilationTarget<'a>; Target: CompilationTarget<'a>;
fn mark_var<Target>(&mut self, _: Rc<Var>, _: Level, _: &'a Cell<VarReg>, _: GenContext, _: &mut Vec<Target>) fn mark_var<Target>(
where &mut self,
_: Rc<Var>,
_: Level,
_: &'a Cell<VarReg>,
_: GenContext,
_: &mut Vec<Target>,
) where
Target: CompilationTarget<'a>; Target: CompilationTarget<'a>;
fn reset(&mut self); fn reset(&mut self);
@@ -47,7 +59,7 @@ pub trait Allocator<'a> {
fn drain_var_data( fn drain_var_data(
&mut self, &mut self,
vs: VariableFixtures<'a>, vs: VariableFixtures<'a>,
num_of_chunks: usize num_of_chunks: usize,
) -> VariableFixtures<'a> { ) -> VariableFixtures<'a> {
let mut perm_vs = VariableFixtures::new(); let mut perm_vs = VariableFixtures::new();

View File

@@ -1,4 +1,5 @@
use crate::prolog_parser_rebis::ast::*; use crate::prolog_parser_rebis::ast::*;
use crate::prolog_parser_rebis::{atom, clause_name};
use crate::clause_types::*; use crate::clause_types::*;
use crate::fixtures::*; use crate::fixtures::*;
@@ -267,9 +268,7 @@ impl<'a> ArithmeticEvaluator<'a> {
fn push_constant(&mut self, c: &Constant) -> Result<(), ArithmeticError> { fn push_constant(&mut self, c: &Constant) -> Result<(), ArithmeticError> {
match c { match c {
&Constant::Fixnum(n) => self &Constant::Fixnum(n) => self.interm.push(ArithmeticTerm::Number(Number::Fixnum(n))),
.interm
.push(ArithmeticTerm::Number(Number::Fixnum(n))),
&Constant::Integer(ref n) => self &Constant::Integer(ref n) => self
.interm .interm
.push(ArithmeticTerm::Number(Number::Integer(n.clone()))), .push(ArithmeticTerm::Number(Number::Integer(n.clone()))),
@@ -326,17 +325,11 @@ impl<'a> ArithmeticEvaluator<'a> {
// integer division rounding function -- 9.1.3.1. // integer division rounding function -- 9.1.3.1.
pub fn rnd_i<'a>(n: &'a Number) -> RefOrOwned<'a, Number> { pub fn rnd_i<'a>(n: &'a Number) -> RefOrOwned<'a, Number> {
match n { match n {
&Number::Integer(_) => { &Number::Integer(_) => RefOrOwned::Borrowed(n),
RefOrOwned::Borrowed(n) &Number::Float(OrderedFloat(f)) => RefOrOwned::Owned(Number::from(
} Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0)),
&Number::Float(OrderedFloat(f)) => { )),
RefOrOwned::Owned(Number::from( &Number::Fixnum(n) => RefOrOwned::Owned(Number::from(n)),
Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0))
))
}
&Number::Fixnum(n) => {
RefOrOwned::Owned(Number::from(n))
}
&Number::Rational(ref r) => { &Number::Rational(ref r) => {
let r_ref = r.fract_floor_ref(); let r_ref = r.fract_floor_ref();
let (mut fract, mut floor) = (Rational::new(), Integer::new()); let (mut fract, mut floor) = (Rational::new(), Integer::new());
@@ -432,31 +425,31 @@ impl Add<Number> for Number {
Number::from(Integer::from(n1) + Integer::from(n2)) Number::from(Integer::from(n1) + Integer::from(n2))
}) })
} }
(Number::Fixnum(n1), Number::Integer(n2)) | (Number::Fixnum(n1), Number::Integer(n2))
(Number::Integer(n2), Number::Fixnum(n1)) => { | (Number::Integer(n2), Number::Fixnum(n1)) => {
Ok(Number::from(Integer::from(n1) + &*n2)) Ok(Number::from(Integer::from(n1) + &*n2))
} }
(Number::Fixnum(n1), Number::Rational(n2)) | (Number::Fixnum(n1), Number::Rational(n2))
(Number::Rational(n2), Number::Fixnum(n1)) => { | (Number::Rational(n2), Number::Fixnum(n1)) => {
Ok(Number::from(Rational::from(n1) + &*n2)) Ok(Number::from(Rational::from(n1) + &*n2))
} }
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) | (Number::Fixnum(n1), Number::Float(OrderedFloat(n2)))
(Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => { | (Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
Ok(Number::Float(add_f(float_fn_to_f(n1)?, n2)?)) Ok(Number::Float(add_f(float_fn_to_f(n1)?, n2)?))
} }
(Number::Integer(n1), Number::Integer(n2)) => { (Number::Integer(n1), Number::Integer(n2)) => {
Ok(Number::from(Integer::from(&*n1) + &*n2)) // add_i Ok(Number::from(Integer::from(&*n1) + &*n2)) // add_i
} }
(Number::Integer(n1), Number::Float(OrderedFloat(n2))) (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)?)) Ok(Number::Float(add_f(float_i_to_f(&n1)?, n2)?))
} }
(Number::Integer(n1), Number::Rational(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)) Ok(Number::from(Rational::from(&*n1) + &*n2))
} }
(Number::Rational(n1), Number::Float(OrderedFloat(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)?)) Ok(Number::Float(add_f(float_r_to_f(&n1)?, n2)?))
} }
(Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => { (Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => {
@@ -474,12 +467,13 @@ impl Neg for Number {
fn neg(self) -> Self::Output { fn neg(self) -> Self::Output {
match self { match self {
Number::Fixnum(n) => Number::Fixnum(n) => {
if let Some(n) = n.checked_neg() { if let Some(n) = n.checked_neg() {
Number::Fixnum(n) Number::Fixnum(n)
} else { } else {
Number::from(-Integer::from(n)) Number::from(-Integer::from(n))
} }
}
Number::Integer(n) => Number::Integer(Rc::new(-Integer::from(&*n))), Number::Integer(n) => Number::Integer(Rc::new(-Integer::from(&*n))),
Number::Float(OrderedFloat(f)) => Number::Float(OrderedFloat(-f)), Number::Float(OrderedFloat(f)) => Number::Float(OrderedFloat(-f)),
Number::Rational(r) => Number::Rational(Rc::new(-Rational::from(&*r))), Number::Rational(r) => Number::Rational(Rc::new(-Rational::from(&*r))),
@@ -507,16 +501,16 @@ impl Mul<Number> for Number {
Number::from(Integer::from(n1) * Integer::from(n2)) Number::from(Integer::from(n1) * Integer::from(n2))
}) })
} }
(Number::Fixnum(n1), Number::Integer(n2)) | (Number::Fixnum(n1), Number::Integer(n2))
(Number::Integer(n2), Number::Fixnum(n1)) => { | (Number::Integer(n2), Number::Fixnum(n1)) => {
Ok(Number::from(Integer::from(n1) * &*n2)) Ok(Number::from(Integer::from(n1) * &*n2))
} }
(Number::Fixnum(n1), Number::Rational(n2)) | (Number::Fixnum(n1), Number::Rational(n2))
(Number::Rational(n2), Number::Fixnum(n1)) => { | (Number::Rational(n2), Number::Fixnum(n1)) => {
Ok(Number::from(Rational::from(n1) * &*n2)) Ok(Number::from(Rational::from(n1) * &*n2))
} }
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) | (Number::Fixnum(n1), Number::Float(OrderedFloat(n2)))
(Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => { | (Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
Ok(Number::Float(mul_f(float_fn_to_f(n1)?, n2)?)) Ok(Number::Float(mul_f(float_fn_to_f(n1)?, n2)?))
} }
(Number::Integer(n1), Number::Integer(n2)) => { (Number::Integer(n1), Number::Integer(n2)) => {
@@ -549,72 +543,50 @@ impl Div<Number> for Number {
fn div(self, rhs: Number) -> Self::Output { fn div(self, rhs: Number) -> Self::Output {
match (self, rhs) { match (self, rhs) {
(Number::Fixnum(n1), Number::Fixnum(n2)) => { (Number::Fixnum(n1), Number::Fixnum(n2)) => Ok(Number::Float(div_f(
Ok(Number::Float(div_f( float_fn_to_f(n1)?,
float_fn_to_f(n1)?, float_fn_to_f(n2)?,
float_fn_to_f(n2)?, )?)),
)?)) (Number::Fixnum(n1), Number::Integer(n2)) => Ok(Number::Float(div_f(
} float_fn_to_f(n1)?,
(Number::Fixnum(n1), Number::Integer(n2)) => { float_i_to_f(&n2)?,
Ok(Number::Float(div_f( )?)),
float_fn_to_f(n1)?, (Number::Integer(n1), Number::Fixnum(n2)) => Ok(Number::Float(div_f(
float_i_to_f(&n2)?, float_i_to_f(&n1)?,
)?)) float_fn_to_f(n2)?,
} )?)),
(Number::Integer(n1), Number::Fixnum(n2)) => { (Number::Fixnum(n1), Number::Rational(n2)) => Ok(Number::Float(div_f(
Ok(Number::Float(div_f( float_fn_to_f(n1)?,
float_i_to_f(&n1)?, float_r_to_f(&n2)?,
float_fn_to_f(n2)?, )?)),
)?)) (Number::Rational(n1), Number::Fixnum(n2)) => Ok(Number::Float(div_f(
} float_r_to_f(&n1)?,
(Number::Fixnum(n1), Number::Rational(n2)) => { float_fn_to_f(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))) => { (Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) => {
Ok(Number::Float(div_f( Ok(Number::Float(div_f(float_fn_to_f(n1)?, n2)?))
float_fn_to_f(n1)?,
n2,
)?))
} }
(Number::Float(OrderedFloat(n1)), Number::Fixnum(n2)) => { (Number::Float(OrderedFloat(n1)), Number::Fixnum(n2)) => {
Ok(Number::Float(div_f( Ok(Number::Float(div_f(n1, float_fn_to_f(n2)?)?))
n1,
float_fn_to_f(n2)?,
)?))
}
(Number::Integer(n1), Number::Integer(n2)) => {
Ok(Number::Float(div_f(
float_i_to_f(&n1)?,
float_i_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))) => { (Number::Integer(n1), Number::Float(OrderedFloat(n2))) => {
Ok(Number::Float(div_f(float_i_to_f(&n1)?, n2)?)) Ok(Number::Float(div_f(float_i_to_f(&n1)?, n2)?))
} }
(Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => { (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
Ok(Number::Float(div_f(n2, float_i_to_f(&n1)?)?)) Ok(Number::Float(div_f(n2, float_i_to_f(&n1)?)?))
} }
(Number::Integer(n1), Number::Rational(n2)) => { (Number::Integer(n1), Number::Rational(n2)) => Ok(Number::Float(div_f(
Ok(Number::Float(div_f( float_i_to_f(&n1)?,
float_i_to_f(&n1)?, float_r_to_f(&n2)?,
float_r_to_f(&n2)?, )?)),
)?)) (Number::Rational(n2), Number::Integer(n1)) => Ok(Number::Float(div_f(
} float_r_to_f(&n2)?,
(Number::Rational(n2), Number::Integer(n1)) => { float_i_to_f(&n1)?,
Ok(Number::Float(div_f( )?)),
float_r_to_f(&n2)?,
float_i_to_f(&n1)?,
)?))
}
(Number::Rational(n1), Number::Float(OrderedFloat(n2))) => { (Number::Rational(n1), Number::Float(OrderedFloat(n2))) => {
Ok(Number::Float(div_f(float_r_to_f(&n1)?, n2)?)) Ok(Number::Float(div_f(float_r_to_f(&n1)?, n2)?))
} }
@@ -727,12 +699,8 @@ impl<'a> TryFrom<(Addr, &'a Heap)> for Number {
fn try_from((addr, heap): (Addr, &'a Heap)) -> Result<Number, Self::Error> { fn try_from((addr, heap): (Addr, &'a Heap)) -> Result<Number, Self::Error> {
match addr { match addr {
Addr::Fixnum(n) => { Addr::Fixnum(n) => Ok(Number::from(n)),
Ok(Number::from(n)) Addr::Float(n) => Ok(Number::Float(n)),
}
Addr::Float(n) => {
Ok(Number::Float(n))
}
Addr::Usize(n) => { Addr::Usize(n) => {
if let Ok(n) = isize::try_from(n) { if let Ok(n) = isize::try_from(n) {
Ok(Number::from(n)) Ok(Number::from(n))
@@ -740,12 +708,8 @@ impl<'a> TryFrom<(Addr, &'a Heap)> for Number {
Ok(Number::from(Integer::from(n))) Ok(Number::from(Integer::from(n)))
} }
} }
Addr::Con(h) => { Addr::Con(h) => Number::try_from(&heap[h]),
Number::try_from(&heap[h]) _ => Err(()),
}
_ => {
Err(())
}
} }
} }
} }
@@ -755,35 +719,21 @@ impl<'a> TryFrom<&'a HeapCellValue> for Number {
fn try_from(value: &'a HeapCellValue) -> Result<Number, Self::Error> { fn try_from(value: &'a HeapCellValue) -> Result<Number, Self::Error> {
match value { match value {
HeapCellValue::Addr(addr) => { HeapCellValue::Addr(addr) => match addr {
match addr { &Addr::Fixnum(n) => Ok(Number::from(n)),
&Addr::Fixnum(n) => { &Addr::Float(n) => Ok(Number::Float(n)),
&Addr::Usize(n) => {
if let Ok(n) = isize::try_from(n) {
Ok(Number::from(n)) Ok(Number::from(n))
} } else {
&Addr::Float(n) => { Ok(Number::from(Integer::from(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(())
} }
} }
} _ => Err(()),
HeapCellValue::Integer(n) => { },
Ok(Number::Integer(n.clone())) HeapCellValue::Integer(n) => Ok(Number::Integer(n.clone())),
} HeapCellValue::Rational(n) => Ok(Number::Rational(n.clone())),
HeapCellValue::Rational(n) => { _ => Err(()),
Ok(Number::Rational(n.clone()))
}
_ => {
Err(())
}
} }
} }
} }

View File

@@ -1,10 +1,11 @@
use crate::prolog_parser_rebis::ast::*; use crate::prolog_parser_rebis::ast::*;
use crate::prolog_parser_rebis::{clause_name, temp_v};
use crate::forms::Number; use crate::forms::Number;
use crate::machine::machine_indices::*; use crate::machine::machine_indices::*;
use crate::rug::rand::RandState; use crate::rug::rand::RandState;
use crate::ref_thread_local::RefThreadLocal; use crate::ref_thread_local::{ref_thread_local, RefThreadLocal};
use std::collections::BTreeMap; use std::collections::BTreeMap;
@@ -322,7 +323,9 @@ impl SystemClauseType {
&SystemClauseType::ClearAttributeGoals => clause_name!("$clear_attribute_goals"), &SystemClauseType::ClearAttributeGoals => clause_name!("$clear_attribute_goals"),
&SystemClauseType::CloneAttributeGoals => clause_name!("$clone_attribute_goals"), &SystemClauseType::CloneAttributeGoals => clause_name!("$clone_attribute_goals"),
&SystemClauseType::CodesToNumber => clause_name!("$codes_to_number"), &SystemClauseType::CodesToNumber => clause_name!("$codes_to_number"),
&SystemClauseType::CopyTermWithoutAttrVars => clause_name!("$copy_term_without_attr_vars"), &SystemClauseType::CopyTermWithoutAttrVars => {
clause_name!("$copy_term_without_attr_vars")
}
&SystemClauseType::CreatePartialString => clause_name!("$create_partial_string"), &SystemClauseType::CreatePartialString => clause_name!("$create_partial_string"),
&SystemClauseType::CurrentInput => clause_name!("$current_input"), &SystemClauseType::CurrentInput => clause_name!("$current_input"),
&SystemClauseType::CurrentHostname => clause_name!("$current_hostname"), &SystemClauseType::CurrentHostname => clause_name!("$current_hostname"),
@@ -337,58 +340,70 @@ impl SystemClauseType {
&SystemClauseType::WorkingDirectory => clause_name!("$working_directory"), &SystemClauseType::WorkingDirectory => clause_name!("$working_directory"),
&SystemClauseType::PathCanonical => clause_name!("$path_canonical"), &SystemClauseType::PathCanonical => clause_name!("$path_canonical"),
&SystemClauseType::FileTime => clause_name!("$file_time"), &SystemClauseType::FileTime => clause_name!("$file_time"),
&SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate) => &SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate) => {
clause_name!("$add_dynamic_predicate"), clause_name!("$add_dynamic_predicate")
&SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause) => }
clause_name!("$add_goal_expansion_clause"), &SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause) => {
&SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause) => clause_name!("$add_goal_expansion_clause")
clause_name!("$add_term_expansion_clause"), }
&SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable) => &SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause) => {
clause_name!("$clause_to_evacuable"), clause_name!("$add_term_expansion_clause")
&SystemClauseType::REPL(REPLCodePtr::ConcludeLoad) => }
clause_name!("$conclude_load"), &SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable) => {
&SystemClauseType::REPL(REPLCodePtr::DeclareModule) => clause_name!("$clause_to_evacuable")
clause_name!("$declare_module"), }
&SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary) => &SystemClauseType::REPL(REPLCodePtr::ConcludeLoad) => clause_name!("$conclude_load"),
clause_name!("$load_compiled_library"), &SystemClauseType::REPL(REPLCodePtr::DeclareModule) => clause_name!("$declare_module"),
&SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload) => &SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary) => {
clause_name!("$push_load_state_payload"), clause_name!("$load_compiled_library")
&SystemClauseType::REPL(REPLCodePtr::Asserta) => }
clause_name!("$asserta"), &SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload) => {
&SystemClauseType::REPL(REPLCodePtr::Assertz) => clause_name!("$push_load_state_payload")
clause_name!("$assertz"), }
&SystemClauseType::REPL(REPLCodePtr::Retract) => &SystemClauseType::REPL(REPLCodePtr::Asserta) => clause_name!("$asserta"),
clause_name!("$retract_clause"), &SystemClauseType::REPL(REPLCodePtr::Assertz) => clause_name!("$assertz"),
&SystemClauseType::REPL(REPLCodePtr::UseModule) => &SystemClauseType::REPL(REPLCodePtr::Retract) => clause_name!("$retract_clause"),
clause_name!("$use_module"), &SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"),
&SystemClauseType::REPL(REPLCodePtr::PushLoadContext) => &SystemClauseType::REPL(REPLCodePtr::PushLoadContext) => {
clause_name!("$push_load_context"), clause_name!("$push_load_context")
&SystemClauseType::REPL(REPLCodePtr::PopLoadContext) => }
clause_name!("$pop_load_context"), &SystemClauseType::REPL(REPLCodePtr::PopLoadContext) => {
&SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload) => clause_name!("$pop_load_context")
clause_name!("$pop_load_state_payload"), }
&SystemClauseType::REPL(REPLCodePtr::LoadContextSource) => &SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload) => {
clause_name!("$prolog_lc_source"), clause_name!("$pop_load_state_payload")
&SystemClauseType::REPL(REPLCodePtr::LoadContextFile) => }
clause_name!("$prolog_lc_file"), &SystemClauseType::REPL(REPLCodePtr::LoadContextSource) => {
&SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory) => clause_name!("$prolog_lc_source")
clause_name!("$prolog_lc_dir"), }
&SystemClauseType::REPL(REPLCodePtr::LoadContextModule) => &SystemClauseType::REPL(REPLCodePtr::LoadContextFile) => {
clause_name!("$prolog_lc_module"), clause_name!("$prolog_lc_file")
&SystemClauseType::REPL(REPLCodePtr::LoadContextStream) => }
clause_name!("$prolog_lc_stream"), &SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory) => {
&SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty) => clause_name!("$prolog_lc_dir")
clause_name!("$cpp_meta_predicate_property"), }
&SystemClauseType::REPL(REPLCodePtr::BuiltInProperty) => &SystemClauseType::REPL(REPLCodePtr::LoadContextModule) => {
clause_name!("$cpp_built_in_property"), clause_name!("$prolog_lc_module")
&SystemClauseType::REPL(REPLCodePtr::DynamicProperty) => }
clause_name!("$cpp_dynamic_property"), &SystemClauseType::REPL(REPLCodePtr::LoadContextStream) => {
&SystemClauseType::REPL(REPLCodePtr::MultifileProperty) => clause_name!("$prolog_lc_stream")
clause_name!("$cpp_multifile_property"), }
&SystemClauseType::REPL(REPLCodePtr::DiscontiguousProperty) => &SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty) => {
clause_name!("$cpp_discontiguous_property"), clause_name!("$cpp_meta_predicate_property")
&SystemClauseType::REPL(REPLCodePtr::AbolishClause) => }
clause_name!("$abolish_clause"), &SystemClauseType::REPL(REPLCodePtr::BuiltInProperty) => {
clause_name!("$cpp_built_in_property")
}
&SystemClauseType::REPL(REPLCodePtr::DynamicProperty) => {
clause_name!("$cpp_dynamic_property")
}
&SystemClauseType::REPL(REPLCodePtr::MultifileProperty) => {
clause_name!("$cpp_multifile_property")
}
&SystemClauseType::REPL(REPLCodePtr::DiscontiguousProperty) => {
clause_name!("$cpp_discontiguous_property")
}
&SystemClauseType::REPL(REPLCodePtr::AbolishClause) => clause_name!("$abolish_clause"),
&SystemClauseType::Close => clause_name!("$close"), &SystemClauseType::Close => clause_name!("$close"),
&SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"), &SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"),
&SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"), &SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"),
@@ -397,8 +412,9 @@ impl SystemClauseType {
&SystemClauseType::EnqueueAttributeGoal => clause_name!("$enqueue_attribute_goal"), &SystemClauseType::EnqueueAttributeGoal => clause_name!("$enqueue_attribute_goal"),
&SystemClauseType::EnqueueAttributedVar => clause_name!("$enqueue_attr_var"), &SystemClauseType::EnqueueAttributedVar => clause_name!("$enqueue_attr_var"),
&SystemClauseType::FetchGlobalVar => clause_name!("$fetch_global_var"), &SystemClauseType::FetchGlobalVar => clause_name!("$fetch_global_var"),
&SystemClauseType::FetchGlobalVarWithOffset => &SystemClauseType::FetchGlobalVarWithOffset => {
clause_name!("$fetch_global_var_with_offset"), clause_name!("$fetch_global_var_with_offset")
}
&SystemClauseType::FirstStream => clause_name!("$first_stream"), &SystemClauseType::FirstStream => clause_name!("$first_stream"),
&SystemClauseType::FlushOutput => clause_name!("$flush_output"), &SystemClauseType::FlushOutput => clause_name!("$flush_output"),
&SystemClauseType::GetByte => clause_name!("$get_byte"), &SystemClauseType::GetByte => clause_name!("$get_byte"),
@@ -424,13 +440,13 @@ impl SystemClauseType {
clause_name!("$get_lh_from_offset_diff") clause_name!("$get_lh_from_offset_diff")
} }
&SystemClauseType::GetBValue => clause_name!("$get_b_value"), &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::GetNextDBRef => clause_name!("$get_next_db_ref"),
&SystemClauseType::GetNextOpDBRef => clause_name!("$get_next_op_db_ref"), &SystemClauseType::GetNextOpDBRef => clause_name!("$get_next_op_db_ref"),
&SystemClauseType::LookupDBRef => clause_name!("$lookup_db_ref"), &SystemClauseType::LookupDBRef => clause_name!("$lookup_db_ref"),
&SystemClauseType::LookupOpDBRef => clause_name!("$lookup_op_db_ref"), &SystemClauseType::LookupOpDBRef => clause_name!("$lookup_op_db_ref"),
&SystemClauseType::GetDoubleQuotes => clause_name!("$get_double_quotes"), &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::GetSCCCleaner => clause_name!("$get_scc_cleaner"),
&SystemClauseType::Halt => clause_name!("$halt"), &SystemClauseType::Halt => clause_name!("$halt"),
&SystemClauseType::HeadIsDynamic => clause_name!("$head_is_dynamic"), &SystemClauseType::HeadIsDynamic => clause_name!("$head_is_dynamic"),
@@ -455,7 +471,7 @@ impl SystemClauseType {
// &SystemClauseType::ModuleAssertDynamicPredicateToBack => { // &SystemClauseType::ModuleAssertDynamicPredicateToBack => {
// clause_name!("$module_assertz") // 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::ModuleExists => clause_name!("$module_exists"),
&SystemClauseType::NextStream => clause_name!("$next_stream"), &SystemClauseType::NextStream => clause_name!("$next_stream"),
&SystemClauseType::NoSuchPredicate => clause_name!("$no_such_predicate"), &SystemClauseType::NoSuchPredicate => clause_name!("$no_such_predicate"),
@@ -507,7 +523,9 @@ impl SystemClauseType {
&SystemClauseType::ReadTerm => clause_name!("$read_term"), &SystemClauseType::ReadTerm => clause_name!("$read_term"),
&SystemClauseType::ReadTermFromChars => clause_name!("$read_term_from_chars"), &SystemClauseType::ReadTermFromChars => clause_name!("$read_term_from_chars"),
&SystemClauseType::ResetGlobalVarAtKey => clause_name!("$reset_global_var_at_key"), &SystemClauseType::ResetGlobalVarAtKey => clause_name!("$reset_global_var_at_key"),
&SystemClauseType::ResetGlobalVarAtOffset => clause_name!("$reset_global_var_at_offset"), &SystemClauseType::ResetGlobalVarAtOffset => {
clause_name!("$reset_global_var_at_offset")
}
&SystemClauseType::ResetBlock => clause_name!("$reset_block"), &SystemClauseType::ResetBlock => clause_name!("$reset_block"),
&SystemClauseType::ResetContinuationMarker => clause_name!("$reset_cont_marker"), &SystemClauseType::ResetContinuationMarker => clause_name!("$reset_cont_marker"),
&SystemClauseType::ReturnFromVerifyAttr => clause_name!("$return_from_verify_attr"), &SystemClauseType::ReturnFromVerifyAttr => clause_name!("$return_from_verify_attr"),
@@ -521,7 +539,9 @@ impl SystemClauseType {
&SystemClauseType::SocketServerAccept => clause_name!("$socket_server_accept"), &SystemClauseType::SocketServerAccept => clause_name!("$socket_server_accept"),
&SystemClauseType::SocketServerClose => clause_name!("$socket_server_close"), &SystemClauseType::SocketServerClose => clause_name!("$socket_server_close"),
&SystemClauseType::Succeed => clause_name!("$succeed"), &SystemClauseType::Succeed => clause_name!("$succeed"),
&SystemClauseType::TermAttributedVariables => clause_name!("$term_attributed_variables"), &SystemClauseType::TermAttributedVariables => {
clause_name!("$term_attributed_variables")
}
&SystemClauseType::TermVariables => clause_name!("$term_variables"), &SystemClauseType::TermVariables => clause_name!("$term_variables"),
&SystemClauseType::TruncateLiftedHeapTo => clause_name!("$truncate_lh_to"), &SystemClauseType::TruncateLiftedHeapTo => clause_name!("$truncate_lh_to"),
&SystemClauseType::UnifyWithOccursCheck => clause_name!("$unify_with_occurs_check"), &SystemClauseType::UnifyWithOccursCheck => clause_name!("$unify_with_occurs_check"),
@@ -542,7 +562,9 @@ impl SystemClauseType {
&SystemClauseType::Ed25519Sign => clause_name!("$ed25519_sign"), &SystemClauseType::Ed25519Sign => clause_name!("$ed25519_sign"),
&SystemClauseType::Ed25519Verify => clause_name!("$ed25519_verify"), &SystemClauseType::Ed25519Verify => clause_name!("$ed25519_verify"),
&SystemClauseType::Ed25519NewKeyPair => clause_name!("$ed25519_new_keypair"), &SystemClauseType::Ed25519NewKeyPair => clause_name!("$ed25519_new_keypair"),
&SystemClauseType::Ed25519KeyPairPublicKey => clause_name!("$ed25519_keypair_public_key"), &SystemClauseType::Ed25519KeyPairPublicKey => {
clause_name!("$ed25519_keypair_public_key")
}
&SystemClauseType::Curve25519ScalarMult => clause_name!("$curve25519_scalar_mult"), &SystemClauseType::Curve25519ScalarMult => clause_name!("$curve25519_scalar_mult"),
&SystemClauseType::LoadHTML => clause_name!("$load_html"), &SystemClauseType::LoadHTML => clause_name!("$load_html"),
&SystemClauseType::LoadXML => clause_name!("$load_xml"), &SystemClauseType::LoadXML => clause_name!("$load_xml"),
@@ -556,14 +578,16 @@ impl SystemClauseType {
pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> { pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
match (name, arity) { match (name, arity) {
("$abolish_clause", 3) => ("$abolish_clause", 3) => Some(SystemClauseType::REPL(REPLCodePtr::AbolishClause)),
Some(SystemClauseType::REPL(REPLCodePtr::AbolishClause)), ("$add_dynamic_predicate", 3) => {
("$add_dynamic_predicate", 3) => Some(SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate))
Some(SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate)), }
("$add_goal_expansion_clause", 4) => ("$add_goal_expansion_clause", 4) => {
Some(SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause)), Some(SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause))
("$add_term_expansion_clause", 3) => }
Some(SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause)), ("$add_term_expansion_clause", 3) => {
Some(SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause))
}
("$atom_chars", 2) => Some(SystemClauseType::AtomChars), ("$atom_chars", 2) => Some(SystemClauseType::AtomChars),
("$atom_codes", 2) => Some(SystemClauseType::AtomCodes), ("$atom_codes", 2) => Some(SystemClauseType::AtomCodes),
("$atom_length", 2) => Some(SystemClauseType::AtomLength), ("$atom_length", 2) => Some(SystemClauseType::AtomLength),
@@ -602,7 +626,9 @@ impl SystemClauseType {
("$peek_code", 2) => Some(SystemClauseType::PeekCode), ("$peek_code", 2) => Some(SystemClauseType::PeekCode),
("$is_partial_string", 1) => Some(SystemClauseType::IsPartialString), ("$is_partial_string", 1) => Some(SystemClauseType::IsPartialString),
("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar), ("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar),
("$fetch_global_var_with_offset", 3) => Some(SystemClauseType::FetchGlobalVarWithOffset), ("$fetch_global_var_with_offset", 3) => {
Some(SystemClauseType::FetchGlobalVarWithOffset)
}
("$get_byte", 2) => Some(SystemClauseType::GetByte), ("$get_byte", 2) => Some(SystemClauseType::GetByte),
("$get_char", 2) => Some(SystemClauseType::GetChar), ("$get_char", 2) => Some(SystemClauseType::GetChar),
("$get_n_chars", 3) => Some(SystemClauseType::GetNChars), ("$get_n_chars", 3) => Some(SystemClauseType::GetNChars),
@@ -611,18 +637,10 @@ impl SystemClauseType {
("$points_to_cont_reset_marker", 1) => { ("$points_to_cont_reset_marker", 1) => {
Some(SystemClauseType::PointsToContinuationResetMarker) Some(SystemClauseType::PointsToContinuationResetMarker)
} }
("$put_byte", 2) => { ("$put_byte", 2) => Some(SystemClauseType::PutByte),
Some(SystemClauseType::PutByte) ("$put_char", 2) => Some(SystemClauseType::PutChar),
} ("$put_chars", 2) => Some(SystemClauseType::PutChars),
("$put_char", 2) => { ("$put_code", 2) => Some(SystemClauseType::PutCode),
Some(SystemClauseType::PutChar)
}
("$put_chars", 2) => {
Some(SystemClauseType::PutChars)
}
("$put_code", 2) => {
Some(SystemClauseType::PutCode)
}
("$reset_attr_var_state", 0) => Some(SystemClauseType::ResetAttrVarState), ("$reset_attr_var_state", 0) => Some(SystemClauseType::ResetAttrVarState),
("$truncate_if_no_lh_growth", 1) => { ("$truncate_if_no_lh_growth", 1) => {
Some(SystemClauseType::TruncateIfNoLiftedHeapGrowth) Some(SystemClauseType::TruncateIfNoLiftedHeapGrowth)
@@ -691,7 +709,9 @@ impl SystemClauseType {
("$socket_server_accept", 7) => Some(SystemClauseType::SocketServerAccept), ("$socket_server_accept", 7) => Some(SystemClauseType::SocketServerAccept),
("$socket_server_close", 1) => Some(SystemClauseType::SocketServerClose), ("$socket_server_close", 1) => Some(SystemClauseType::SocketServerClose),
("$store_global_var", 2) => Some(SystemClauseType::StoreGlobalVar), ("$store_global_var", 2) => Some(SystemClauseType::StoreGlobalVar),
("$store_global_var_with_offset", 2) => Some(SystemClauseType::StoreGlobalVarWithOffset), ("$store_global_var_with_offset", 2) => {
Some(SystemClauseType::StoreGlobalVarWithOffset)
}
("$term_attributed_variables", 2) => Some(SystemClauseType::TermAttributedVariables), ("$term_attributed_variables", 2) => Some(SystemClauseType::TermAttributedVariables),
("$term_variables", 2) => Some(SystemClauseType::TermVariables), ("$term_variables", 2) => Some(SystemClauseType::TermVariables),
("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo), ("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
@@ -708,12 +728,18 @@ impl SystemClauseType {
("$working_directory", 2) => Some(SystemClauseType::WorkingDirectory), ("$working_directory", 2) => Some(SystemClauseType::WorkingDirectory),
("$path_canonical", 2) => Some(SystemClauseType::PathCanonical), ("$path_canonical", 2) => Some(SystemClauseType::PathCanonical),
("$file_time", 3) => Some(SystemClauseType::FileTime), ("$file_time", 3) => Some(SystemClauseType::FileTime),
("$clause_to_evacuable", 3) => Some(SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable)), ("$clause_to_evacuable", 3) => {
Some(SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable))
}
("$conclude_load", 1) => Some(SystemClauseType::REPL(REPLCodePtr::ConcludeLoad)), ("$conclude_load", 1) => Some(SystemClauseType::REPL(REPLCodePtr::ConcludeLoad)),
("$use_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)), ("$use_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)),
("$declare_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DeclareModule)), ("$declare_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DeclareModule)),
("$load_compiled_library", 2) => Some(SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary)), ("$load_compiled_library", 2) => {
("$push_load_state_payload", 1) => Some(SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload)), Some(SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary))
}
("$push_load_state_payload", 1) => {
Some(SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload))
}
("$asserta", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Asserta)), ("$asserta", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Asserta)),
("$assertz", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Assertz)), ("$assertz", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Assertz)),
("$retract_clause", 4) => Some(SystemClauseType::REPL(REPLCodePtr::Retract)), ("$retract_clause", 4) => Some(SystemClauseType::REPL(REPLCodePtr::Retract)),
@@ -742,18 +768,38 @@ impl SystemClauseType {
("$chars_base64", 4) => Some(SystemClauseType::CharsBase64), ("$chars_base64", 4) => Some(SystemClauseType::CharsBase64),
("$load_library_as_stream", 3) => Some(SystemClauseType::LoadLibraryAsStream), ("$load_library_as_stream", 3) => Some(SystemClauseType::LoadLibraryAsStream),
("$push_load_context", 2) => Some(SystemClauseType::REPL(REPLCodePtr::PushLoadContext)), ("$push_load_context", 2) => Some(SystemClauseType::REPL(REPLCodePtr::PushLoadContext)),
("$pop_load_state_payload", 1) => Some(SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload)), ("$pop_load_state_payload", 1) => {
Some(SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload))
}
("$pop_load_context", 0) => Some(SystemClauseType::REPL(REPLCodePtr::PopLoadContext)), ("$pop_load_context", 0) => Some(SystemClauseType::REPL(REPLCodePtr::PopLoadContext)),
("$prolog_lc_source", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextSource)), ("$prolog_lc_source", 1) => {
Some(SystemClauseType::REPL(REPLCodePtr::LoadContextSource))
}
("$prolog_lc_file", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextFile)), ("$prolog_lc_file", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextFile)),
("$prolog_lc_dir", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory)), ("$prolog_lc_dir", 1) => {
("$prolog_lc_module", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextModule)), Some(SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory))
("$prolog_lc_stream", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextStream)), }
("$cpp_meta_predicate_property", 4) => Some(SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty)), ("$prolog_lc_module", 1) => {
("$cpp_built_in_property", 2) => Some(SystemClauseType::REPL(REPLCodePtr::BuiltInProperty)), Some(SystemClauseType::REPL(REPLCodePtr::LoadContextModule))
("$cpp_dynamic_property", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DynamicProperty)), }
("$cpp_multifile_property", 3) => Some(SystemClauseType::REPL(REPLCodePtr::MultifileProperty)), ("$prolog_lc_stream", 1) => {
("$cpp_discontiguous_property", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DiscontiguousProperty)), Some(SystemClauseType::REPL(REPLCodePtr::LoadContextStream))
}
("$cpp_meta_predicate_property", 4) => {
Some(SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty))
}
("$cpp_built_in_property", 2) => {
Some(SystemClauseType::REPL(REPLCodePtr::BuiltInProperty))
}
("$cpp_dynamic_property", 3) => {
Some(SystemClauseType::REPL(REPLCodePtr::DynamicProperty))
}
("$cpp_multifile_property", 3) => {
Some(SystemClauseType::REPL(REPLCodePtr::MultifileProperty))
}
("$cpp_discontiguous_property", 3) => {
Some(SystemClauseType::REPL(REPLCodePtr::DiscontiguousProperty))
}
_ => None, _ => None,
} }
} }
@@ -832,10 +878,10 @@ impl ClauseType {
match self { match self {
&ClauseType::Op(_, ref spec, _) => Some(spec.clone()), &ClauseType::Op(_, ref spec, _) => Some(spec.clone()),
&ClauseType::Inlined(InlinedClauseType::CompareNumber(..)) &ClauseType::Inlined(InlinedClauseType::CompareNumber(..))
| &ClauseType::BuiltIn(BuiltInClauseType::Is(..)) | &ClauseType::BuiltIn(BuiltInClauseType::Is(..))
| &ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(_)) | &ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(_))
| &ClauseType::BuiltIn(BuiltInClauseType::NotEq) | &ClauseType::BuiltIn(BuiltInClauseType::NotEq)
| &ClauseType::BuiltIn(BuiltInClauseType::Eq) => Some(SharedOpDesc::new(700, XFX)), | &ClauseType::BuiltIn(BuiltInClauseType::Eq) => Some(SharedOpDesc::new(700, XFX)),
_ => None, _ => None,
} }
} }

View File

@@ -1,6 +1,7 @@
/// Code generation to WAM-like instructions. /// Code generation to WAM-like instructions.
use crate::prolog_parser_rebis::ast::*; use crate::prolog_parser_rebis::ast::*;
use crate::prolog_parser_rebis::tabled_rc::TabledData; use crate::prolog_parser_rebis::tabled_rc::TabledData;
use crate::prolog_parser_rebis::{perm_v, temp_v};
use crate::allocator::*; use crate::allocator::*;
use crate::arithmetic::*; use crate::arithmetic::*;
@@ -66,18 +67,14 @@ impl<'a> ConjunctInfo<'a> {
self.has_deep_cut as usize self.has_deep_cut as usize
} }
fn mark_unsafe_vars( fn mark_unsafe_vars(&self, mut unsafe_var_marker: UnsafeVarMarker, code: &mut Code) {
&self,
mut unsafe_var_marker: UnsafeVarMarker,
code: &mut Code,
) {
if code.is_empty() { if code.is_empty() {
return; return;
} }
let mut code_index = 0; let mut code_index = 0;
for phase in 0 .. { for phase in 0.. {
while let Line::Query(ref query_instr) = &code[code_index] { while let Line::Query(ref query_instr) = &code[code_index] {
if !unsafe_var_marker.mark_safe_vars(query_instr) { if !unsafe_var_marker.mark_safe_vars(query_instr) {
unsafe_var_marker.mark_phase(query_instr, phase); unsafe_var_marker.mark_phase(query_instr, phase);
@@ -95,7 +92,7 @@ impl<'a> ConjunctInfo<'a> {
code_index = 0; code_index = 0;
for phase in 0 .. { for phase in 0.. {
while let Line::Query(ref mut query_instr) = &mut code[code_index] { while let Line::Query(ref mut query_instr) = &mut code[code_index] {
unsafe_var_marker.mark_unsafe_vars(query_instr, phase); unsafe_var_marker.mark_unsafe_vars(query_instr, phase);
code_index += 1; code_index += 1;
@@ -173,7 +170,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
code: &mut Code, code: &mut Code,
) -> RegType { ) -> RegType {
let mut target = Vec::new(); let mut target = Vec::new();
self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target); self.marker
.mark_var(name, Level::Shallow, vr, term_loc, &mut target);
if !target.is_empty() { if !target.is_empty() {
code.extend(target.into_iter().map(Line::Query)); code.extend(target.into_iter().map(Line::Query));
@@ -191,9 +189,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
code: &mut Code, code: &mut Code,
) -> RegType { ) -> RegType {
match self.marker.bindings().get(&name) { match self.marker.bindings().get(&name) {
Some(&VarData::Temp(_, t, _)) if t != 0 => { Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t),
RegType::Temp(t)
}
Some(&VarData::Perm(p)) if p != 0 => { Some(&VarData::Perm(p)) if p != 0 => {
if let GenContext::Last(_) = term_loc { if let GenContext::Last(_) = term_loc {
self.mark_var_in_non_callable(name.clone(), term_loc, vr, code); self.mark_var_in_non_callable(name.clone(), term_loc, vr, code);
@@ -202,9 +198,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
RegType::Perm(p) RegType::Perm(p)
} }
} }
_ => { _ => self.mark_var_in_non_callable(name, term_loc, vr, code),
self.mark_var_in_non_callable(name, term_loc, vr, code)
}
} }
} }
@@ -231,7 +225,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
target: &mut Vec<Target>, target: &mut Vec<Target>,
) { ) {
if is_exposed || self.get_var_count(var.as_ref()) > 1 { if is_exposed || self.get_var_count(var.as_ref()) > 1 {
self.marker.mark_var(var.clone(), Level::Deep, cell, term_loc, target); self.marker
.mark_var(var.clone(), Level::Deep, cell, term_loc, target);
} else { } else {
Self::add_or_increment_void_instr(target); Self::add_or_increment_void_instr(target);
} }
@@ -252,7 +247,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
Self::add_or_increment_void_instr(target); Self::add_or_increment_void_instr(target);
} }
&Term::Cons(ref cell, _, _) | &Term::Clause(ref cell, _, _, _) => { &Term::Cons(ref cell, _, _) | &Term::Clause(ref cell, _, _, _) => {
self.marker.mark_non_var(Level::Deep, term_loc, cell, target); self.marker
.mark_non_var(Level::Deep, term_loc, cell, target);
target.push(Target::clause_arg_to_instr(cell.get())); target.push(Target::clause_arg_to_instr(cell.get()));
} }
&Term::Constant(_, ref constant) => { &Term::Constant(_, ref constant) => {
@@ -264,7 +260,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
}; };
} }
fn compile_target<Target, Iter>( fn compile_target<Target, Iter>(
&mut self, &mut self,
iter: Iter, iter: Iter,
term_loc: GenContext, 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) => { TermRef::Var(lvl @ Level::Shallow, cell, var) => {
self.marker.mark_var(var.clone(), lvl, cell, term_loc, &mut target); self.marker
} .mark_var(var.clone(), lvl, cell, term_loc, &mut target);
_ => {
} }
_ => {}
}; };
} }
@@ -353,8 +350,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
while let Some((chunk_num, lt_arity, chunked_terms)) = iter.next() { while let Some((chunk_num, lt_arity, chunked_terms)) = iter.next() {
for (i, chunked_term) in chunked_terms.iter().enumerate() { for (i, chunked_term) in chunked_terms.iter().enumerate() {
let term_loc = match chunked_term { let term_loc = match chunked_term {
&ChunkedTerm::HeadClause(..) => &ChunkedTerm::HeadClause(..) => GenContext::Head,
GenContext::Head,
&ChunkedTerm::BodyTerm(_) => { &ChunkedTerm::BodyTerm(_) => {
if i < chunked_terms.len() - 1 { if i < chunked_terms.len() - 1 {
GenContext::Mid(chunk_num) GenContext::Mid(chunk_num)
@@ -391,8 +387,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
&QueryTerm::Clause(_, ref ct, ref terms, false) => { &QueryTerm::Clause(_, ref ct, ref terms, false) => {
code.push(call_clause!(ct.clone(), terms.len(), pvs)); code.push(call_clause!(ct.clone(), terms.len(), pvs));
} }
_ => { _ => {}
}
} }
} }
@@ -407,8 +402,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
&mut ControlInstruction::JmpBy(_, _, _, ref mut last_call) => { &mut ControlInstruction::JmpBy(_, _, _, ref mut last_call) => {
*last_call = true; *last_call = true;
} }
&mut ControlInstruction::Proceed => { &mut ControlInstruction::Proceed => {}
}
_ => { _ => {
dealloc_index += 1; dealloc_index += 1;
} }
@@ -416,8 +410,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
Some(&mut Line::Cut(CutInstruction::Cut(_))) => { Some(&mut Line::Cut(CutInstruction::Cut(_))) => {
dealloc_index += 1; dealloc_index += 1;
} }
_ => { _ => {}
}
}; };
dealloc_index dealloc_index
@@ -437,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 lcode, at_1) = self.call_arith_eval(terms[0].as_ref(), 1)?;
let (mut rcode, at_2) = self.call_arith_eval(terms[1].as_ref(), 2)?; let (mut rcode, at_2) = self.call_arith_eval(terms[1].as_ref(), 2)?;
let at_1 = let at_1 = if let &Term::Var(ref vr, ref name) = terms[0].as_ref() {
if let &Term::Var(ref vr, ref name) = terms[0].as_ref() { ArithmeticTerm::Reg(self.mark_non_callable(name.clone(), 1, term_loc, vr, code))
ArithmeticTerm::Reg( } else {
self.mark_non_callable(name.clone(), 1, term_loc, vr, code) at_1.unwrap_or(interm!(1))
) };
} else {
at_1.unwrap_or(interm!(1))
};
let at_2 = let at_2 = if let &Term::Var(ref vr, ref name) = terms[1].as_ref() {
if let &Term::Var(ref vr, ref name) = terms[1].as_ref() { ArithmeticTerm::Reg(self.mark_non_callable(name.clone(), 2, term_loc, vr, code))
ArithmeticTerm::Reg( } else {
self.mark_non_callable(name.clone(), 2, term_loc, vr, code) at_2.unwrap_or(interm!(2))
) };
} else {
at_2.unwrap_or(interm!(2))
};
code.append(&mut lcode); code.append(&mut lcode);
code.append(&mut rcode); 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)); code.push(compare_number_instr!(cmp, at_1, at_2));
} }
&InlinedClauseType::IsAtom(..) => match terms[0].as_ref() { &InlinedClauseType::IsAtom(..) => match terms[0].as_ref() {
&Term::Constant(_, Constant::Char(_)) | &Term::Constant(_, Constant::Char(_))
&Term::Constant(_, Constant::EmptyList) | | &Term::Constant(_, Constant::EmptyList)
&Term::Constant(_, Constant::Atom(..)) => { | &Term::Constant(_, Constant::Atom(..)) => {
code.push(succeed!()); code.push(succeed!());
} }
&Term::Var(ref vr, ref name) => { &Term::Var(ref vr, ref name) => {
@@ -528,11 +515,11 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
} }
}, },
&InlinedClauseType::IsNumber(..) => match terms[0].as_ref() { &InlinedClauseType::IsNumber(..) => match terms[0].as_ref() {
&Term::Constant(_, Constant::Float(_)) | &Term::Constant(_, Constant::Float(_))
&Term::Constant(_, Constant::Rational(_)) | | &Term::Constant(_, Constant::Rational(_))
&Term::Constant(_, Constant::Integer(_)) | | &Term::Constant(_, Constant::Integer(_))
&Term::Constant(_, Constant::Fixnum(_)) | | &Term::Constant(_, Constant::Fixnum(_))
&Term::Constant(_, Constant::Usize(_)) => { | &Term::Constant(_, Constant::Usize(_)) => {
code.push(succeed!()); code.push(succeed!());
} }
&Term::Var(ref vr, ref name) => { &Term::Var(ref vr, ref name) => {
@@ -558,9 +545,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
} }
}, },
&InlinedClauseType::IsInteger(..) => match terms[0].as_ref() { &InlinedClauseType::IsInteger(..) => match terms[0].as_ref() {
&Term::Constant(_, Constant::Integer(_)) | &Term::Constant(_, Constant::Integer(_))
&Term::Constant(_, Constant::Fixnum(_)) | | &Term::Constant(_, Constant::Fixnum(_))
&Term::Constant(_, Constant::Usize(_)) => { | &Term::Constant(_, Constant::Usize(_)) => {
code.push(succeed!()); code.push(succeed!());
} }
&Term::Var(ref vr, ref name) => { &Term::Var(ref vr, ref name) => {
@@ -615,14 +602,15 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
&Term::Var(ref vr, ref name) => { &Term::Var(ref vr, ref name) => {
let mut target = vec![]; let mut target = vec![];
self.marker.mark_var(name.clone(), Level::Shallow, vr, term_loc, &mut target); self.marker
.mark_var(name.clone(), Level::Shallow, vr, term_loc, &mut target);
if !target.is_empty() { if !target.is_empty() {
code.extend(target.into_iter().map(Line::Query)); code.extend(target.into_iter().map(Line::Query));
} }
} }
&Term::Constant(_, ref c @ Constant::Integer(_)) | &Term::Constant(_, ref c @ Constant::Integer(_))
&Term::Constant(_, ref c @ Constant::Fixnum(_)) => { | &Term::Constant(_, ref c @ Constant::Fixnum(_)) => {
code.push(Line::Query(put_constant!( code.push(Line::Query(put_constant!(
Level::Shallow, Level::Shallow,
c.clone(), c.clone(),
@@ -655,14 +643,11 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
} }
} }
let at = let at = if let &Term::Var(ref vr, ref name) = terms[1].as_ref() {
if let &Term::Var(ref vr, ref name) = terms[1].as_ref() { ArithmeticTerm::Reg(self.mark_non_callable(name.clone(), 2, term_loc, vr, code))
ArithmeticTerm::Reg( } else {
self.mark_non_callable(name.clone(), 2, term_loc, vr, code) at.unwrap_or(interm!(1))
) };
} else {
at.unwrap_or(interm!(1))
};
Ok(if use_default_call_policy { Ok(if use_default_call_policy {
code.push(is_call_by_default!(temp_v!(1), at)); 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) => { &QueryTerm::GetLevelAndUnify(ref cell, ref var) => {
self.compile_get_level_and_unify(code, cell, var.clone(), term_loc) self.compile_get_level_and_unify(code, cell, var.clone(), term_loc)
} }
&QueryTerm::UnblockedCut(ref cell) => { &QueryTerm::UnblockedCut(ref cell) => self.compile_unblocked_cut(code, cell),
self.compile_unblocked_cut(code, cell) &QueryTerm::BlockedCut => code.push(if chunk_num == 0 {
} Line::Cut(CutInstruction::NeckCut)
&QueryTerm::BlockedCut => { } else {
code.push(if chunk_num == 0 { Line::Cut(CutInstruction::Cut(perm_v!(1)))
Line::Cut(CutInstruction::NeckCut) }),
} else {
Line::Cut(CutInstruction::Cut(perm_v!(1)))
})
}
&QueryTerm::Clause( &QueryTerm::Clause(
_, _,
ClauseType::BuiltIn(BuiltInClauseType::Is(..)), ClauseType::BuiltIn(BuiltInClauseType::Is(..)),
ref terms, ref terms,
use_default_call_policy, use_default_call_policy,
) => { ) => self.compile_is_call(terms, code, term_loc, use_default_call_policy)?,
self.compile_is_call(terms, code, term_loc, use_default_call_policy)?
}
&QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) => { &QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) => {
self.compile_inlined(ct, terms, term_loc, code)? self.compile_inlined(ct, terms, term_loc, code)?
} }
@@ -772,7 +751,12 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
} }
} }
fn compile_cleanup(&mut self, code: &mut Code, conjunct_info: &ConjunctInfo, toc: &'a QueryTerm) { fn compile_cleanup(
&mut self,
code: &mut Code,
conjunct_info: &ConjunctInfo,
toc: &'a QueryTerm,
) {
// add a proceed to bookend any trailing cuts. // add a proceed to bookend any trailing cuts.
match toc { match toc {
&QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => code.push(proceed!()), &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => code.push(proceed!()),
@@ -786,7 +770,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
if conjunct_info.allocates() { if conjunct_info.allocates() {
let offset = self.global_jmp_by_locs_offset; 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 { if *jmp_by_offset == dealloc_index {
*jmp_by_offset += 1; *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); self.add_conditional_call(code, term, num_perm_vars_left);
} }
/* /*
pub fn compile_query(&mut self, query: &'a Vec<QueryTerm>) -> Result<Code, CompilationError> { pub fn compile_query(&mut self, query: &'a Vec<QueryTerm>) -> Result<Code, CompilationError> {
let iter = ChunkedIterator::from_term_sequence(query); let iter = ChunkedIterator::from_term_sequence(query);
let conjunct_info = self.collect_var_data(iter); let conjunct_info = self.collect_var_data(iter);
let mut code = Vec::new(); let mut code = Vec::new();
self.compile_seq_prelude(&conjunct_info, &mut code); self.compile_seq_prelude(&conjunct_info, &mut code);
let iter = ChunkedIterator::from_term_sequence(query); let iter = ChunkedIterator::from_term_sequence(query);
self.compile_seq(iter, &conjunct_info, &mut code, true)?; 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() { if let Some(query_term) = query.last() {
Self::compile_cleanup(&mut code, &conjunct_info, query_term); Self::compile_cleanup(&mut code, &conjunct_info, query_term);
}
Ok(code)
} }
*/
Ok(code)
}
*/
#[inline] #[inline]
fn increment_jmp_by_locs_by(&mut self, incr: usize) { fn increment_jmp_by_locs_by(&mut self, incr: usize) {
let offset = self.global_jmp_by_locs_offset; 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; *loc += incr;
} }
} }
@@ -1077,7 +1061,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
if skip_stub_try_me_else { if skip_stub_try_me_else {
// skip the TryMeElse(0) also. // skip the TryMeElse(0) also.
self.increment_jmp_by_locs_by(2); self.increment_jmp_by_locs_by(2);
} else { } else {
self.increment_jmp_by_locs_by(1); self.increment_jmp_by_locs_by(1);
} }
@@ -1105,7 +1089,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
for (l, r) in split_pred { for (l, r) in split_pred {
let skel_lower_bound = self.skeleton.clauses.len(); 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(); let clause_start_offset = code.len();
if multi_seq { if multi_seq {
@@ -1123,11 +1107,10 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
if self.is_extensible { if self.is_extensible {
let segment_is_indexed = to_indexing_line(&code_segment[0]).is_some(); 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_index_info.clause_start +=
clause_start_offset + 2 * (segment_is_indexed as usize); clause_start_offset + 2 * (segment_is_indexed as usize);
clause_index_info.opt_arg_index_key += clause_index_info.opt_arg_index_key += clause_start_offset + 1;
clause_start_offset + 1;
} }
} }

View File

@@ -1,6 +1,7 @@
use crate::indexmap::IndexMap; use crate::indexmap::IndexMap;
use crate::prolog_parser_rebis::ast::*; use crate::prolog_parser_rebis::ast::*;
use crate::prolog_parser_rebis::temp_v;
use crate::allocator::*; use crate::allocator::*;
use crate::fixtures::*; use crate::fixtures::*;
@@ -293,9 +294,7 @@ impl<'a> Allocator<'a> for DebrayAllocator {
(pr, true) (pr, true)
} }
r => { r => (r, false),
(r, false)
}
}; };
self.mark_reserved_var(var, lvl, cell, term_loc, target, r, is_new_var); self.mark_reserved_var(var, lvl, cell, term_loc, target, r, is_new_var);

View File

@@ -1,5 +1,6 @@
use crate::prolog_parser_rebis::ast::*; use crate::prolog_parser_rebis::ast::*;
use crate::prolog_parser_rebis::parser::OpDesc; use crate::prolog_parser_rebis::parser::OpDesc;
use crate::prolog_parser_rebis::{clause_name, is_infix, is_postfix};
use crate::clause_types::*; use crate::clause_types::*;
use crate::machine::machine_errors::*; use crate::machine::machine_errors::*;
@@ -36,7 +37,7 @@ pub enum TopLevel {
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum AppendOrPrepend { pub enum AppendOrPrepend {
Append, Append,
Prepend Prepend,
} }
impl AppendOrPrepend { impl AppendOrPrepend {
@@ -115,12 +116,8 @@ impl ListingSource {
pub trait ClauseInfo { pub trait ClauseInfo {
fn is_consistent(&self, clauses: &Vec<PredicateClause>) -> bool { fn is_consistent(&self, clauses: &Vec<PredicateClause>) -> bool {
match clauses.first() { match clauses.first() {
Some(cl) => { Some(cl) => self.name() == cl.name() && self.arity() == cl.arity(),
self.name() == cl.name() && self.arity() == cl.arity() None => true,
}
None => {
true
}
} }
} }
@@ -140,38 +137,25 @@ impl ClauseInfo for Term {
_ => Some(clause_name!(":-")), _ => Some(clause_name!(":-")),
} }
} }
_ => { _ => Some(name.clone()),
Some(name.clone())
}
} }
} }
Term::Constant(_, Constant::Atom(ref name, _)) => { Term::Constant(_, Constant::Atom(ref name, _)) => Some(name.clone()),
Some(name.clone()) _ => None,
}
_ => {
None
}
} }
} }
fn arity(&self) -> usize { fn arity(&self) -> usize {
match self { match self {
Term::Clause(_, ref name, ref terms, _) => Term::Clause(_, ref name, ref terms, _) => match name.as_str() {
match name.as_str() { ":-" => match terms.len() {
":-" => { 1 => 0,
match terms.len() { 2 => terms[0].arity(),
1 => 0, _ => terms.len(),
2 => terms[0].arity(),
_ => terms.len(),
}
}
_ => {
terms.len()
}
}, },
_ => { _ => terms.len(),
0 },
} _ => 0,
} }
} }
} }
@@ -189,23 +173,15 @@ impl ClauseInfo for Rule {
impl ClauseInfo for PredicateClause { impl ClauseInfo for PredicateClause {
fn name(&self) -> Option<ClauseName> { fn name(&self) -> Option<ClauseName> {
match self { match self {
&PredicateClause::Fact(ref term, ..) => { &PredicateClause::Fact(ref term, ..) => term.name(),
term.name() &PredicateClause::Rule(ref rule, ..) => rule.name(),
}
&PredicateClause::Rule(ref rule, ..) => {
rule.name()
}
} }
} }
fn arity(&self) -> usize { fn arity(&self) -> usize {
match self { match self {
&PredicateClause::Fact(ref term, ..) => { &PredicateClause::Fact(ref term, ..) => term.arity(),
term.arity() &PredicateClause::Rule(ref rule, ..) => rule.arity(),
}
&PredicateClause::Rule(ref rule, ..) => {
rule.arity()
}
} }
} }
} }
@@ -222,11 +198,9 @@ impl PredicateClause {
// TODO: add this to `Term` in `prolog_parser` like `first_arg`. // TODO: add this to `Term` in `prolog_parser` like `first_arg`.
pub fn args(&self) -> Option<&[Box<Term>]> { pub fn args(&self) -> Option<&[Box<Term>]> {
match *self { match *self {
PredicateClause::Fact(ref term, ..) => { PredicateClause::Fact(ref term, ..) => match term {
match term { Term::Clause(_, _, args, _) => Some(&args),
Term::Clause(_, _, args, _) => Some(&args), _ => None,
_ => None,
}
}, },
PredicateClause::Rule(ref rule, ..) => { PredicateClause::Rule(ref rule, ..) => {
if rule.head.1.is_empty() { if rule.head.1.is_empty() {
@@ -240,14 +214,11 @@ impl PredicateClause {
pub fn arity(&self) -> usize { pub fn arity(&self) -> usize {
match self { match self {
&PredicateClause::Fact(ref term, ..) => { &PredicateClause::Fact(ref term, ..) => term.arity(),
term.arity()
}
&PredicateClause::Rule(ref rule, ..) => { &PredicateClause::Rule(ref rule, ..) => {
if rule.head.0.as_str() == ":" && rule.head.1.len() == 2 { if rule.head.0.as_str() == ":" && rule.head.1.len() == 2 {
match (rule.head.1)[0].as_ref() { match (rule.head.1)[0].as_ref() {
&Term::Constant(_, Constant::Atom(..)) => { &Term::Constant(_, Constant::Atom(..)) => {}
}
_ => { _ => {
return 2; return 2;
} }
@@ -321,7 +292,7 @@ pub enum Declaration {
pub struct OpDecl { pub struct OpDecl {
pub prec: usize, pub prec: usize,
pub spec: Specifier, pub spec: Specifier,
pub name: ClauseName pub name: ClauseName,
} }
impl OpDecl { impl OpDecl {
@@ -345,7 +316,7 @@ impl OpDecl {
XFY | XFX | YFX => Fixity::In, XFY | XFX | YFX => Fixity::In,
XF | YF => Fixity::Post, XF | YF => Fixity::Post,
FX | FY => Fixity::Pre, FX | FY => Fixity::Pre,
_ => unreachable!() _ => unreachable!(),
} }
} }
@@ -356,12 +327,12 @@ impl OpDecl {
Some(cell) => { Some(cell) => {
return Some(cell.shared_op_desc().replace((self.prec, self.spec))); return Some(cell.shared_op_desc().replace((self.prec, self.spec)));
} }
None => { None => {}
}
} }
op_dir.insert(key, OpDirValue::new(self.spec, self.prec)) op_dir
.map(|op_dir_value| op_dir_value.shared_op_desc().get()) .insert(key, OpDirValue::new(self.spec, self.prec))
.map(|op_dir_value| op_dir_value.shared_op_desc().get())
} }
pub fn submit( pub fn submit(
@@ -419,11 +390,7 @@ pub fn fetch_op_spec_from_existing(
spec.or_else(|| fetch_op_spec(name, arity, op_dir)) spec.or_else(|| fetch_op_spec(name, arity, op_dir))
} }
pub fn fetch_op_spec( pub fn fetch_op_spec(name: ClauseName, arity: usize, op_dir: &OpDir) -> Option<SharedOpDesc> {
name: ClauseName,
arity: usize,
op_dir: &OpDir,
) -> Option<SharedOpDesc> {
match arity { match arity {
2 => op_dir 2 => op_dir
.get(&(name, Fixity::In)) .get(&(name, Fixity::In))
@@ -451,9 +418,7 @@ pub fn fetch_op_spec(
} }
}) })
} }
_ => { _ => None,
None
}
} }
} }
@@ -499,7 +464,6 @@ impl Module {
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Number { pub enum Number {
Float(OrderedFloat<f64>), Float(OrderedFloat<f64>),
@@ -559,7 +523,6 @@ impl Into<HeapCellValue> for Number {
} }
} }
impl Number { impl Number {
#[inline] #[inline]
pub fn is_positive(&self) -> bool { pub fn is_positive(&self) -> bool {
@@ -594,12 +557,13 @@ impl Number {
#[inline] #[inline]
pub fn abs(self) -> Self { pub fn abs(self) -> Self {
match self { match self {
Number::Fixnum(n) => Number::Fixnum(n) => {
if let Some(n) = n.checked_abs() { if let Some(n) = n.checked_abs() {
Number::from(n) Number::from(n)
} else { } else {
Number::from(Integer::from(n).abs()) Number::from(Integer::from(n).abs())
} }
}
Number::Integer(n) => Number::from(Integer::from(n.abs_ref())), Number::Integer(n) => Number::from(Integer::from(n.abs_ref())),
Number::Float(f) => Number::Float(OrderedFloat(f.abs())), Number::Float(f) => Number::Float(OrderedFloat(f.abs())),
Number::Rational(r) => Number::from(Rational::from(r.abs_ref())), Number::Rational(r) => Number::from(Rational::from(r.abs_ref())),
@@ -624,15 +588,13 @@ impl OptArgIndexKey {
#[inline] #[inline]
pub fn arg_num(&self) -> usize { pub fn arg_num(&self) -> usize {
match &self { match &self {
OptArgIndexKey::Constant(arg_num, ..) | OptArgIndexKey::Constant(arg_num, ..)
OptArgIndexKey::Structure(arg_num, ..) | | OptArgIndexKey::Structure(arg_num, ..)
OptArgIndexKey::List(arg_num, _) => { | OptArgIndexKey::List(arg_num, _) => {
// these are always at least 1. // these are always at least 1.
*arg_num *arg_num
} }
OptArgIndexKey::None => { OptArgIndexKey::None => 0,
0
}
} }
} }
@@ -644,27 +606,22 @@ impl OptArgIndexKey {
#[inline] #[inline]
pub fn switch_on_term_loc(&self) -> Option<usize> { pub fn switch_on_term_loc(&self) -> Option<usize> {
match &self { match &self {
OptArgIndexKey::Constant(_, loc, ..) | OptArgIndexKey::Constant(_, loc, ..)
OptArgIndexKey::Structure(_, loc, ..) | | OptArgIndexKey::Structure(_, loc, ..)
OptArgIndexKey::List(_, loc) => { | OptArgIndexKey::List(_, loc) => Some(*loc),
Some(*loc) OptArgIndexKey::None => None,
}
OptArgIndexKey::None => {
None
}
} }
} }
#[inline] #[inline]
pub fn set_switch_on_term_loc(&mut self, value: usize) { pub fn set_switch_on_term_loc(&mut self, value: usize) {
match self { match self {
OptArgIndexKey::Constant(_, ref mut loc, ..) | OptArgIndexKey::Constant(_, ref mut loc, ..)
OptArgIndexKey::Structure(_, ref mut loc, ..) | | OptArgIndexKey::Structure(_, ref mut loc, ..)
OptArgIndexKey::List(_, ref mut loc) => { | OptArgIndexKey::List(_, ref mut loc) => {
*loc = value; *loc = value;
} }
OptArgIndexKey::None => { OptArgIndexKey::None => {}
}
} }
} }
} }
@@ -673,13 +630,12 @@ impl AddAssign<usize> for OptArgIndexKey {
#[inline] #[inline]
fn add_assign(&mut self, n: usize) { fn add_assign(&mut self, n: usize) {
match self { match self {
OptArgIndexKey::Constant(_, ref mut o, ..) | OptArgIndexKey::Constant(_, ref mut o, ..)
OptArgIndexKey::List(_, ref mut o) | | OptArgIndexKey::List(_, ref mut o)
OptArgIndexKey::Structure(_, ref mut o, ..) => { | OptArgIndexKey::Structure(_, ref mut o, ..) => {
*o += n; *o += n;
} }
OptArgIndexKey::None => { OptArgIndexKey::None => {}
}
} }
} }
} }

View File

@@ -1,4 +1,10 @@
use crate::prolog_parser_rebis::ast::*; use crate::prolog_parser_rebis::ast::*;
use crate::prolog_parser_rebis::{
alpha_char, alpha_numeric_char, backslash_char, capital_letter_char, char_class, clause_name,
cut_char, decimal_digit_char, graphic_char, graphic_token_char, is_fx, is_infix, is_postfix,
is_prefix, is_xf, is_xfx, is_xfy, is_yfx, semicolon_char, sign_char, single_quote_char,
small_letter_char, solo_char, variable_indicator_char,
};
use crate::clause_types::*; use crate::clause_types::*;
use crate::forms::*; use crate::forms::*;
@@ -14,7 +20,7 @@ use crate::indexmap::{IndexMap, IndexSet};
use std::cell::Cell; use std::cell::Cell;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::iter::{FromIterator, once}; use std::iter::{once, FromIterator};
use std::net::{IpAddr, TcpListener}; use std::net::{IpAddr, TcpListener};
use std::ops::{Range, RangeFrom}; use std::ops::{Range, RangeFrom};
use std::rc::Rc; use std::rc::Rc;
@@ -99,10 +105,7 @@ impl<'a> HCPreOrderIterator<'a> {
None => return false, None => return false,
}; };
let mut parent_spec = DirectedOp::Left( let mut parent_spec = DirectedOp::Left(clause_name!("-"), SharedOpDesc::new(200, FY));
clause_name!("-"),
SharedOpDesc::new(200, FY),
);
loop { loop {
match self.machine_st.store(self.machine_st.deref(addr)) { match self.machine_st.store(self.machine_st.deref(addr)) {
@@ -154,12 +157,13 @@ fn char_to_string(is_quoted: bool, c: char) -> String {
'\u{07}' if is_quoted => "\\a".to_string(), // UTF-8 alert '\u{07}' if is_quoted => "\\a".to_string(), // UTF-8 alert
'"' if is_quoted => "\\\"".to_string(), '"' if is_quoted => "\\\"".to_string(),
'\\' if is_quoted => "\\\\".to_string(), '\\' if is_quoted => "\\\\".to_string(),
'\'' | '\n' | '\r' | '\t' | '\u{0b}' | '\u{0c}' | '\u{08}' | '\u{07}' | '"' | '\\' => '\'' | '\n' | '\r' | '\t' | '\u{0b}' | '\u{0c}' | '\u{08}' | '\u{07}' | '"' | '\\' => {
c.to_string(), c.to_string()
'\u{a0}' ..= '\u{d6}' => c.to_string(), }
'\u{d8}' ..= '\u{f6}' => c.to_string(), '\u{a0}'..='\u{d6}' => c.to_string(),
'\u{f8}' ..= '\u{74f}' => c.to_string(), '\u{d8}'..='\u{f6}' => c.to_string(),
'\x20' ..= '\x7e' => c.to_string(), '\u{f8}'..='\u{74f}' => c.to_string(),
'\x20'..='\x7e' => c.to_string(),
_ => format!("\\x{:x}\\", c as u32), _ => format!("\\x{:x}\\", c as u32),
} }
} }
@@ -271,25 +275,13 @@ fn is_numbered_var(ct: &ClauseType, arity: usize) -> bool {
#[inline] #[inline]
fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp>) -> bool { fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp>) -> bool {
if let Some(ref op) = op { if let Some(ref op) = op {
op.is_negative_sign() && op.is_negative_sign()
iter.leftmost_leaf_has_property(|addr, heap| { && iter.leftmost_leaf_has_property(|addr, heap| match Number::try_from((addr, heap)) {
match Number::try_from((addr, heap)) { Ok(Number::Fixnum(n)) => n > 0,
Ok(Number::Fixnum(n)) => { Ok(Number::Float(f)) => f > OrderedFloat(0f64),
n > 0 Ok(Number::Integer(n)) => &*n > &0,
} Ok(Number::Rational(n)) => &*n > &0,
Ok(Number::Float(f)) => { _ => false,
f > OrderedFloat(0f64)
}
Ok(Number::Integer(n)) => {
&*n > &0
}
Ok(Number::Rational(n)) => {
&*n > &0
}
_ => {
false
}
}
}) })
} else { } else {
false false
@@ -298,8 +290,8 @@ fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp
fn numbervar(n: Integer) -> Var { fn numbervar(n: Integer) -> Var {
static CHAR_CODES: [char; 26] = [ static CHAR_CODES: [char; 26] = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
]; ];
let i = n.mod_u(26) as usize; let i = n.mod_u(26) as usize;
@@ -332,9 +324,7 @@ impl MachineState {
None None
} }
} }
_ => { _ => None,
None
}
} }
} }
} }
@@ -446,8 +436,7 @@ fn non_quoted_graphic_token<Iter: Iterator<Item = char>>(mut iter: Iter, c: char
} }
} }
pub(super) pub(super) fn non_quoted_token<Iter: Iterator<Item = char>>(mut iter: Iter) -> bool {
fn non_quoted_token<Iter: Iterator<Item = char>>(mut iter: Iter) -> bool {
if let Some(c) = iter.next() { if let Some(c) = iter.next() {
if small_letter_char!(c) { if small_letter_char!(c) {
iter.all(|c| alpha_numeric_char!(c)) iter.all(|c| alpha_numeric_char!(c))
@@ -505,37 +494,37 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
max_depth: 0, max_depth: 0,
} }
} }
/* /*
pub fn from_heap_locs( pub fn from_heap_locs(
machine_st: &'a MachineState, machine_st: &'a MachineState,
op_dir: &'a OpDir, op_dir: &'a OpDir,
output: Outputter, output: Outputter,
) -> Self { ) -> Self {
let mut printer = Self::new(machine_st, op_dir, output); let mut printer = Self::new(machine_st, op_dir, output);
printer.toplevel_spec = Some(DirectedOp::Right( printer.toplevel_spec = Some(DirectedOp::Right(
clause_name!("="), clause_name!("="),
SharedOpDesc::new(700, XFX), SharedOpDesc::new(700, XFX),
)); ));
printer.heap_locs = reverse_heap_locs(machine_st); printer.heap_locs = reverse_heap_locs(machine_st);
printer 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);
} }
} */
*/ /*
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] #[inline]
fn ambiguity_check(&self, atom: &str) -> bool { fn ambiguity_check(&self, atom: &str) -> bool {
@@ -555,7 +544,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
iter.stack().pop(); iter.stack().pop();
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec)); self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
return; return;
} }
@@ -579,7 +569,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
if self.check_max_depth(&mut max_depth) { if self.check_max_depth(&mut max_depth) {
iter.stack().pop(); iter.stack().pop();
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec)); self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
return; return;
@@ -587,7 +578,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let left_directed_op = DirectedOp::Left(ct.name(), spec.clone()); let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, left_directed_op)); self.state_stack.push(TokenOrRedirect::CompositeRedirect(
max_depth,
left_directed_op,
));
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec)); self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
} else { } else {
match ct.name().as_str() { match ct.name().as_str() {
@@ -602,9 +596,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
iter.stack().pop(); iter.stack().pop();
iter.stack().pop(); iter.stack().pop();
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec)); self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
return; return;
} }
@@ -612,11 +608,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let left_directed_op = DirectedOp::Left(ct.name(), spec.clone()); let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
let right_directed_op = DirectedOp::Right(ct.name(), spec.clone()); let right_directed_op = DirectedOp::Right(ct.name(), spec.clone());
self.state_stack self.state_stack.push(TokenOrRedirect::CompositeRedirect(
.push(TokenOrRedirect::CompositeRedirect(max_depth, left_directed_op)); max_depth,
left_directed_op,
));
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec)); self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
self.state_stack self.state_stack.push(TokenOrRedirect::CompositeRedirect(
.push(TokenOrRedirect::CompositeRedirect(max_depth, right_directed_op)); max_depth,
right_directed_op,
));
} }
} }
@@ -626,15 +626,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
mut max_depth: usize, mut max_depth: usize,
arity: usize, arity: usize,
name: ClauseName, name: ClauseName,
) -> bool ) -> bool {
{
if self.check_max_depth(&mut max_depth) { if self.check_max_depth(&mut max_depth) {
for _ in 0 .. arity { for _ in 0..arity {
iter.stack().pop(); iter.stack().pop();
} }
self.state_stack.push(TokenOrRedirect::Close); self.state_stack.push(TokenOrRedirect::Close);
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
self.state_stack.push(TokenOrRedirect::Open); self.state_stack.push(TokenOrRedirect::Open);
self.state_stack.push(TokenOrRedirect::Atom(name)); self.state_stack.push(TokenOrRedirect::Atom(name));
@@ -644,8 +644,9 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
self.state_stack.push(TokenOrRedirect::Close); self.state_stack.push(TokenOrRedirect::Close);
for _ in 0 .. arity { for _ in 0..arity {
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth)); self.state_stack
.push(TokenOrRedirect::FunctorRedirect(max_depth));
self.state_stack.push(TokenOrRedirect::Comma); self.state_stack.push(TokenOrRedirect::Comma);
} }
@@ -662,12 +663,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
iter: &mut HCPreOrderIterator, iter: &mut HCPreOrderIterator,
mut max_depth: usize, mut max_depth: usize,
name: ClauseName, name: ClauseName,
spec: SharedOpDesc) spec: SharedOpDesc,
{ ) {
if self.check_max_depth(&mut max_depth) { if self.check_max_depth(&mut max_depth) {
iter.stack().pop(); iter.stack().pop();
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
self.state_stack.push(TokenOrRedirect::Space); self.state_stack.push(TokenOrRedirect::Space);
self.state_stack.push(TokenOrRedirect::Atom(name)); self.state_stack.push(TokenOrRedirect::Atom(name));
@@ -676,7 +678,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let op = DirectedOp::Left(name.clone(), spec); let op = DirectedOp::Left(name.clone(), spec);
self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, op)); self.state_stack
.push(TokenOrRedirect::CompositeRedirect(max_depth, op));
self.state_stack.push(TokenOrRedirect::Space); self.state_stack.push(TokenOrRedirect::Space);
self.state_stack.push(TokenOrRedirect::Atom(name)); self.state_stack.push(TokenOrRedirect::Atom(name));
} }
@@ -687,14 +690,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
mut max_depth: usize, mut max_depth: usize,
name: ClauseName, name: ClauseName,
spec: SharedOpDesc, spec: SharedOpDesc,
) ) {
{
if self.check_max_depth(&mut max_depth) { if self.check_max_depth(&mut max_depth) {
iter.stack().pop(); iter.stack().pop();
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
self.state_stack.push(TokenOrRedirect::BarAsOp); self.state_stack.push(TokenOrRedirect::BarAsOp);
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
return; return;
} }
@@ -702,25 +706,32 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let left_directed_op = DirectedOp::Left(name.clone(), spec.clone()); let left_directed_op = DirectedOp::Left(name.clone(), spec.clone());
let right_directed_op = DirectedOp::Right(name.clone(), spec.clone()); let right_directed_op = DirectedOp::Right(name.clone(), spec.clone());
self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, left_directed_op)); self.state_stack.push(TokenOrRedirect::CompositeRedirect(
max_depth,
left_directed_op,
));
self.state_stack.push(TokenOrRedirect::BarAsOp); self.state_stack.push(TokenOrRedirect::BarAsOp);
self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, right_directed_op)); self.state_stack.push(TokenOrRedirect::CompositeRedirect(
max_depth,
right_directed_op,
));
} }
fn format_curly_braces(&mut self, iter: &mut HCPreOrderIterator, mut max_depth: usize) -> bool fn format_curly_braces(&mut self, iter: &mut HCPreOrderIterator, mut max_depth: usize) -> bool {
{
if self.check_max_depth(&mut max_depth) { if self.check_max_depth(&mut max_depth) {
iter.stack().pop(); iter.stack().pop();
self.state_stack.push(TokenOrRedirect::RightCurly); self.state_stack.push(TokenOrRedirect::RightCurly);
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
self.state_stack.push(TokenOrRedirect::LeftCurly); self.state_stack.push(TokenOrRedirect::LeftCurly);
return false; return false;
} }
self.state_stack.push(TokenOrRedirect::RightCurly); self.state_stack.push(TokenOrRedirect::RightCurly);
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth)); self.state_stack
.push(TokenOrRedirect::FunctorRedirect(max_depth));
self.state_stack.push(TokenOrRedirect::LeftCurly); self.state_stack.push(TokenOrRedirect::LeftCurly);
true true
@@ -795,18 +806,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
} }
match addr { match addr {
Addr::Lis(h) | Addr::Str(h) => { Addr::Lis(h) | Addr::Str(h) => Some(format!("{}", h)),
Some(format!("{}", h))
}
_ => { _ => {
if let Some(r) = addr.as_var() { if let Some(r) = addr.as_var() {
match r { match r {
Ref::StackCell(fr, sc) => { Ref::StackCell(fr, sc) => Some(format!("_s_{}_{}", fr, sc)),
Some(format!("_s_{}_{}", fr, sc)) Ref::HeapCell(h) | Ref::AttrVar(h) => Some(format!("_{}", h)),
}
Ref::HeapCell(h) | Ref::AttrVar(h) => {
Some(format!("_{}", h))
}
} }
} else { } else {
None None
@@ -818,8 +823,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
fn record_children_as_non_cyclic(&mut self, addr: &Addr) { fn record_children_as_non_cyclic(&mut self, addr: &Addr) {
match addr { match addr {
&Addr::Lis(l) => { &Addr::Lis(l) => {
let c1 = self.machine_st.store(self.machine_st.deref(Addr::HeapCell(l))); let c1 = self
let c2 = self.machine_st.store(self.machine_st.deref(Addr::HeapCell(l + 1))); .machine_st
.store(self.machine_st.deref(Addr::HeapCell(l)));
let c2 = self
.machine_st
.store(self.machine_st.deref(Addr::HeapCell(l + 1)));
if let Some(c) = functor_location(&c1) { if let Some(c) = functor_location(&c1) {
self.non_cyclic_terms.insert(c); self.non_cyclic_terms.insert(c);
@@ -830,18 +839,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
} }
} }
&Addr::Str(s) => { &Addr::Str(s) => {
let arity = let arity = match &self.machine_st.heap[s] {
match &self.machine_st.heap[s] { HeapCellValue::NamedStr(arity, ..) => arity,
HeapCellValue::NamedStr(arity, ..) => { _ => {
arity unreachable!()
} }
_ => { };
unreachable!()
}
};
for i in 1 .. arity + 1 { for i in 1..arity + 1 {
let c = self.machine_st.store(self.machine_st.deref(Addr::HeapCell(s + i))); let c = self
.machine_st
.store(self.machine_st.deref(Addr::HeapCell(s + i)));
if let Some(c) = functor_location(&c) { if let Some(c) = functor_location(&c) {
self.non_cyclic_terms.insert(c); self.non_cyclic_terms.insert(c);
@@ -856,15 +864,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
self.non_cyclic_terms.insert(c); self.non_cyclic_terms.insert(c);
} }
} }
_ => { _ => {}
}
} }
} }
fn check_for_seen( fn check_for_seen(&mut self, iter: &mut HCPreOrderIterator) -> Option<Addr> {
&mut self,
iter: &mut HCPreOrderIterator,
) -> Option<Addr> {
iter.stack().last().cloned().and_then(|addr| { iter.stack().last().cloned().and_then(|addr| {
let addr = self.machine_st.store(self.machine_st.deref(addr)); let addr = self.machine_st.store(self.machine_st.deref(addr));
@@ -889,9 +893,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
} }
None => { None => {
let offset = match functor_location(&addr) { let offset = match functor_location(&addr) {
Some(offset) => { Some(offset) => offset,
offset
}
None => { None => {
return iter.next(); return iter.next();
} }
@@ -1036,19 +1038,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let rdiv_ct = clause_name!("rdiv"); let rdiv_ct = clause_name!("rdiv");
let left_directed_op = let left_directed_op = if spec.prec() > 0 {
if spec.prec() > 0 { Some(DirectedOp::Left(rdiv_ct.clone(), spec.clone()))
Some(DirectedOp::Left(rdiv_ct.clone(), spec.clone())) } else {
} else { None
None };
};
let right_directed_op = let right_directed_op = if spec.prec() > 0 {
if spec.prec() > 0 { Some(DirectedOp::Right(rdiv_ct.clone(), spec.clone()))
Some(DirectedOp::Right(rdiv_ct.clone(), spec.clone())) } else {
} else { None
None };
};
if spec.prec() > 0 { if spec.prec() > 0 {
self.state_stack.push(TokenOrRedirect::Number( self.state_stack.push(TokenOrRedirect::Number(
@@ -1056,10 +1056,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
left_directed_op, left_directed_op,
)); ));
self.state_stack.push(TokenOrRedirect::Op( self.state_stack
rdiv_ct, .push(TokenOrRedirect::Op(rdiv_ct, spec.clone()));
spec.clone(),
));
self.state_stack.push(TokenOrRedirect::Number( self.state_stack.push(TokenOrRedirect::Number(
Number::from(r.numer()), Number::from(r.numer()),
@@ -1068,17 +1066,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
} else { } else {
self.state_stack.push(TokenOrRedirect::Close); self.state_stack.push(TokenOrRedirect::Close);
self.state_stack.push(TokenOrRedirect::Number( self.state_stack
Number::from(r.denom()), .push(TokenOrRedirect::Number(Number::from(r.denom()), None));
None,
));
self.state_stack.push(TokenOrRedirect::Comma); self.state_stack.push(TokenOrRedirect::Comma);
self.state_stack.push(TokenOrRedirect::Number( self.state_stack
Number::from(r.numer()), .push(TokenOrRedirect::Number(Number::from(r.numer()), None));
None,
));
self.state_stack.push(TokenOrRedirect::Open); self.state_stack.push(TokenOrRedirect::Open);
self.state_stack.push(TokenOrRedirect::Atom(rdiv_ct)); self.state_stack.push(TokenOrRedirect::Atom(rdiv_ct));
@@ -1092,8 +1086,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
} }
} }
fn print_char(&mut self, is_quoted: bool, c: char) fn print_char(&mut self, is_quoted: bool, c: char) {
{
if non_quoted_token(once(c)) { if non_quoted_token(once(c)) {
let c = char_to_string(false, c); let c = char_to_string(false, c);
@@ -1120,46 +1113,37 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
fn print_proper_string(&mut self, buf: String, max_depth: usize) { fn print_proper_string(&mut self, buf: String, max_depth: usize) {
self.push_char('"'); self.push_char('"');
let buf = let buf = if max_depth == 0 {
if max_depth == 0 { String::from_iter(buf.chars().map(|c| char_to_string(self.quoted, c)))
String::from_iter(buf.chars().map(|c| { } else {
char_to_string(self.quoted, c) let mut char_count = 0;
})) let mut buf = String::from_iter(buf.chars().take(max_depth).map(|c| {
} else { char_count += 1;
let mut char_count = 0; char_to_string(self.quoted, c)
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 { if char_count == max_depth {
buf += " ..."; buf += " ...";
} }
buf buf
}; };
self.append_str(&buf); self.append_str(&buf);
self.push_char('"'); self.push_char('"');
} }
fn print_list_like( fn print_list_like(&mut self, iter: &mut HCPreOrderIterator, addr: Addr, mut max_depth: usize) {
&mut self,
iter: &mut HCPreOrderIterator,
addr: Addr,
mut max_depth: usize,
) {
if self.check_max_depth(&mut max_depth) { if self.check_max_depth(&mut max_depth) {
iter.stack().pop(); iter.stack().pop();
iter.stack().pop(); iter.stack().pop();
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
return; return;
} }
let mut heap_pstr_iter = let mut heap_pstr_iter = self.machine_st.heap_pstr_iter(addr);
self.machine_st.heap_pstr_iter(addr);
let buf = heap_pstr_iter.to_string(); let buf = heap_pstr_iter.to_string();
@@ -1184,12 +1168,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let buf_len = buf.len(); let buf_len = buf.len();
let buf_iter: Box<dyn Iterator<Item=char>> = let buf_iter: Box<dyn Iterator<Item = char>> = if self.max_depth == 0 {
if self.max_depth == 0 { Box::new(buf.chars())
Box::new(buf.chars()) } else {
} else { Box::new(buf.chars().take(max_depth))
Box::new(buf.chars().take(max_depth)) };
};
let mut byte_len = 0; let mut byte_len = 0;
@@ -1207,14 +1190,16 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
byte_len += c.len_utf8(); byte_len += c.len_utf8();
} }
for _ in 0 .. char_count { for _ in 0..char_count {
self.state_stack.push(TokenOrRedirect::Close); self.state_stack.push(TokenOrRedirect::Close);
} }
if self.max_depth > 0 && buf_len > byte_len { if self.max_depth > 0 && buf_len > byte_len {
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
} else { } else {
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth)); self.state_stack
.push(TokenOrRedirect::FunctorRedirect(max_depth));
iter.stack().push(end_addr); iter.stack().push(end_addr);
} }
} else { } else {
@@ -1232,15 +1217,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
byte_len += c.len_utf8(); byte_len += c.len_utf8();
} }
self.state_stack.push(TokenOrRedirect::CloseList(Rc::new( self.state_stack
Cell::new((switch, 0)) .push(TokenOrRedirect::CloseList(Rc::new(Cell::new((switch, 0)))));
)));
if self.max_depth > 0 && buf_len > byte_len { if self.max_depth > 0 && buf_len > byte_len {
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
} else { .push(TokenOrRedirect::Atom(clause_name!("...")));
self.outputter.truncate(self.outputter.len() - ','.len_utf8()); } else {
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth)); self.outputter
.truncate(self.outputter.len() - ','.len_utf8());
self.state_stack
.push(TokenOrRedirect::FunctorRedirect(max_depth));
iter.stack().push(end_addr); iter.stack().push(end_addr);
} }
@@ -1268,8 +1255,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let cell = Rc::new(Cell::new((true, 0))); let cell = Rc::new(Cell::new((true, 0)));
self.state_stack.push(TokenOrRedirect::CloseList(cell.clone())); self.state_stack
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); .push(TokenOrRedirect::CloseList(cell.clone()));
self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
self.state_stack.push(TokenOrRedirect::OpenList(cell)); self.state_stack.push(TokenOrRedirect::OpenList(cell));
return; return;
@@ -1277,11 +1266,14 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let cell = Rc::new(Cell::new((true, max_depth))); let cell = Rc::new(Cell::new((true, max_depth)));
self.state_stack.push(TokenOrRedirect::CloseList(cell.clone())); self.state_stack
.push(TokenOrRedirect::CloseList(cell.clone()));
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth)); self.state_stack
.push(TokenOrRedirect::FunctorRedirect(max_depth));
self.state_stack.push(TokenOrRedirect::HeadTailSeparator); // bar self.state_stack.push(TokenOrRedirect::HeadTailSeparator); // bar
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth)); self.state_stack
.push(TokenOrRedirect::FunctorRedirect(max_depth));
self.state_stack.push(TokenOrRedirect::OpenList(cell)); self.state_stack.push(TokenOrRedirect::OpenList(cell));
} }
@@ -1298,23 +1290,24 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
max_depth: usize, max_depth: usize,
) { ) {
let add_brackets = if !self.ignore_ops { let add_brackets = if !self.ignore_ops {
negated_operand || if let Some(ref op) = op { negated_operand
if self.numbervars && arity == 1 && name.as_str() == "$VAR" { || if let Some(ref op) = op {
!iter.immediate_leaf_has_property(|addr, heap| { if self.numbervars && arity == 1 && name.as_str() == "$VAR" {
match heap.index_addr(&addr).as_ref() { !iter.immediate_leaf_has_property(|addr, heap| {
&HeapCellValue::Integer(ref n) => &**n >= &0, match heap.index_addr(&addr).as_ref() {
&HeapCellValue::Addr(Addr::Fixnum(n)) => n >= 0, &HeapCellValue::Integer(ref n) => &**n >= &0,
&HeapCellValue::Addr(Addr::Float(f)) => f >= OrderedFloat(0f64), &HeapCellValue::Addr(Addr::Fixnum(n)) => n >= 0,
&HeapCellValue::Rational(ref r) => &**r >= &0, &HeapCellValue::Addr(Addr::Float(f)) => f >= OrderedFloat(0f64),
_ => false &HeapCellValue::Rational(ref r) => &**r >= &0,
} _ => false,
}) && needs_bracketing(&spec, op) }
}) && needs_bracketing(&spec, op)
} else {
needs_bracketing(&spec, op)
}
} else { } else {
needs_bracketing(&spec, op) is_functor_redirect && spec.prec() >= 1000
} }
} else {
is_functor_redirect && spec.prec() >= 1000
}
} else { } else {
false false
}; };
@@ -1344,15 +1337,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
tcp_listener: &TcpListener, tcp_listener: &TcpListener,
max_depth: usize, max_depth: usize,
) { ) {
let (ip, port) = let (ip, port) = if let Some(addr) = tcp_listener.local_addr().ok() {
if let Some(addr) = tcp_listener.local_addr().ok() { (addr.ip(), Number::from(addr.port() as isize))
(addr.ip(), Number::from(addr.port() as isize)) } else {
} else { let disconnected_atom = clause_name!("$disconnected_tcp_listener");
let disconnected_atom = clause_name!("$disconnected_tcp_listener"); self.state_stack
self.state_stack.push(TokenOrRedirect::Atom(disconnected_atom)); .push(TokenOrRedirect::Atom(disconnected_atom));
return; return;
}; };
if self.format_struct(iter, max_depth, 1, clause_name!("$tcp_listener")) { if self.format_struct(iter, max_depth, 1, clause_name!("$tcp_listener")) {
let atom = self.state_stack.pop().unwrap(); let atom = self.state_stack.pop().unwrap();
@@ -1369,22 +1362,16 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
} }
} }
fn print_stream( fn print_stream(&mut self, iter: &mut HCPreOrderIterator, stream: &Stream, max_depth: usize) {
&mut self,
iter: &mut HCPreOrderIterator,
stream: &Stream,
max_depth: usize,
) {
if let Some(alias) = &stream.options.alias { if let Some(alias) = &stream.options.alias {
self.print_atom(alias); self.print_atom(alias);
} else { } else {
if self.format_struct(iter, max_depth, 1, clause_name!("$stream")) { if self.format_struct(iter, max_depth, 1, clause_name!("$stream")) {
let atom = let atom = if stream.is_stdout() || stream.is_stdin() {
if stream.is_stdout() || stream.is_stdin() { TokenOrRedirect::Atom(clause_name!("user"))
TokenOrRedirect::Atom(clause_name!("user")) } else {
} else { TokenOrRedirect::RawPtr(stream.as_ptr())
TokenOrRedirect::RawPtr(stream.as_ptr()) };
};
let stream_root = self.state_stack.pop().unwrap(); 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() { match self.machine_st.heap.index_addr(&addr).as_ref() {
&HeapCellValue::NamedStr(arity, ref name, ref spec) => { &HeapCellValue::NamedStr(arity, ref name, ref spec) => {
let spec = fetch_op_spec_from_existing(name.clone(), arity, spec.clone(), self.op_dir); let spec =
fetch_op_spec_from_existing(name.clone(), arity, spec.clone(), self.op_dir);
if let Some(spec) = spec { if let Some(spec) = spec {
self.handle_op_as_struct( self.handle_op_as_struct(

View File

@@ -1,4 +1,5 @@
use crate::prolog_parser_rebis::ast::*; use crate::prolog_parser_rebis::ast::*;
use crate::prolog_parser_rebis::clause_name;
use crate::prolog_parser_rebis::tabled_rc::*; use crate::prolog_parser_rebis::tabled_rc::*;
use crate::forms::*; use crate::forms::*;
@@ -43,14 +44,10 @@ impl OptArgIndexKey {
#[inline] #[inline]
fn has_key_type(&self, key_type: OptArgIndexKeyType) -> bool { fn has_key_type(&self, key_type: OptArgIndexKeyType) -> bool {
match (self, key_type) { match (self, key_type) {
(OptArgIndexKey::Constant(..), OptArgIndexKeyType::Constant) | (OptArgIndexKey::Constant(..), OptArgIndexKeyType::Constant)
(OptArgIndexKey::Structure(..), OptArgIndexKeyType::Structure) | | (OptArgIndexKey::Structure(..), OptArgIndexKeyType::Structure)
(OptArgIndexKey::List(..), OptArgIndexKeyType::List) => { | (OptArgIndexKey::List(..), OptArgIndexKeyType::List) => true,
true _ => false,
}
_ => {
false
}
} }
} }
} }
@@ -93,16 +90,20 @@ impl<'a> IndexingCodeMergingPtr<'a> {
indexing_code: &'a mut Vec<IndexingLine>, indexing_code: &'a mut Vec<IndexingLine>,
append_or_prepend: AppendOrPrepend, append_or_prepend: AppendOrPrepend,
) -> Self { ) -> Self {
Self { skeleton, indexing_code, offset: 0, append_or_prepend } Self {
skeleton,
indexing_code,
offset: 0,
append_or_prepend,
}
} }
fn internalize_constant(&mut self, constant_ptr: IndexingCodePtr) { fn internalize_constant(&mut self, constant_ptr: IndexingCodePtr) {
let constant_key = let constant_key = search_skeleton_for_first_key_type(
search_skeleton_for_first_key_type( self.skeleton,
self.skeleton, OptArgIndexKeyType::Constant,
OptArgIndexKeyType::Constant, self.append_or_prepend,
self.append_or_prepend, );
);
let mut constants = IndexMap::new(); let mut constants = IndexMap::new();
@@ -117,7 +118,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
if let IndexingCodePtr::Internal(_) = constant_ptr { if let IndexingCodePtr::Internal(_) = constant_ptr {
self.indexing_code.push(IndexingLine::Indexing( self.indexing_code.push(IndexingLine::Indexing(
IndexingInstruction::SwitchOnConstant(constants) IndexingInstruction::SwitchOnConstant(constants),
)); ));
let last_index = self.indexing_code.len() - 1; let last_index = self.indexing_code.len() - 1;
@@ -126,34 +127,39 @@ impl<'a> IndexingCodeMergingPtr<'a> {
self.offset = self.indexing_code.len(); self.offset = self.indexing_code.len();
self.indexing_code.push(IndexingLine::Indexing( self.indexing_code.push(IndexingLine::Indexing(
IndexingInstruction::SwitchOnConstant(constants) IndexingInstruction::SwitchOnConstant(constants),
)); ));
} }
} }
fn add_indexed_choice_for_constant(&mut self, external: usize, constant: Constant, index: usize) fn add_indexed_choice_for_constant(
{ &mut self,
let third_level_index = external: usize,
if self.append_or_prepend.is_append() { constant: Constant,
sdeq![ index: usize,
IndexedChoiceInstruction::Try(external), ) {
IndexedChoiceInstruction::Trust(index) let third_level_index = if self.append_or_prepend.is_append() {
] sdeq![
} else { IndexedChoiceInstruction::Try(external),
sdeq![ IndexedChoiceInstruction::Trust(index)
IndexedChoiceInstruction::Try(index), ]
IndexedChoiceInstruction::Trust(external) } else {
] sdeq![
}; IndexedChoiceInstruction::Try(index),
IndexedChoiceInstruction::Trust(external)
]
};
let indexing_code_len = self.indexing_code.len(); let indexing_code_len = self.indexing_code.len();
self.indexing_code.push(IndexingLine::IndexedChoice(third_level_index)); self.indexing_code
.push(IndexingLine::IndexedChoice(third_level_index));
match &mut self.indexing_code[self.offset] { match &mut self.indexing_code[self.offset] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(ref mut constants)) => {
IndexingInstruction::SwitchOnConstant(ref mut constants) constants.insert(
) => { constant,
constants.insert(constant, IndexingCodePtr::Internal(indexing_code_len - self.offset)); IndexingCodePtr::Internal(indexing_code_len - self.offset),
);
} }
_ => { _ => {
unreachable!() unreachable!()
@@ -164,10 +170,11 @@ impl<'a> IndexingCodeMergingPtr<'a> {
fn extend_indexed_choice(&mut self, index: usize) { fn extend_indexed_choice(&mut self, index: usize) {
match &mut self.indexing_code[self.offset] { match &mut self.indexing_code[self.offset] {
IndexingLine::IndexedChoice(ref mut indexed_choice_instrs) IndexingLine::IndexedChoice(ref mut indexed_choice_instrs)
if self.append_or_prepend.is_append() => { if self.append_or_prepend.is_append() =>
uncap_choice_seq_with_trust(indexed_choice_instrs); {
indexed_choice_instrs.push_back(IndexedChoiceInstruction::Trust(index)); uncap_choice_seq_with_trust(indexed_choice_instrs);
} indexed_choice_instrs.push_back(IndexedChoiceInstruction::Trust(index));
}
IndexingLine::IndexedChoice(ref mut indexed_choice_instrs) => { IndexingLine::IndexedChoice(ref mut indexed_choice_instrs) => {
uncap_choice_seq_with_try(indexed_choice_instrs); uncap_choice_seq_with_try(indexed_choice_instrs);
indexed_choice_instrs.push_front(IndexedChoiceInstruction::Try(index)); indexed_choice_instrs.push_front(IndexedChoiceInstruction::Try(index));
@@ -188,9 +195,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
let indexing_code_len = self.indexing_code.len(); let indexing_code_len = self.indexing_code.len();
match &mut self.indexing_code[self.offset] { match &mut self.indexing_code[self.offset] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
) => {
match *c { match *c {
IndexingCodePtr::Fail => { IndexingCodePtr::Fail => {
*c = IndexingCodePtr::External(index); *c = IndexingCodePtr::External(index);
@@ -203,7 +208,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
*c = IndexingCodePtr::Internal(indexing_code_len); *c = IndexingCodePtr::Internal(indexing_code_len);
self.indexing_code.push(IndexingLine::Indexing( self.indexing_code.push(IndexingLine::Indexing(
IndexingInstruction::SwitchOnConstant(constants) IndexingInstruction::SwitchOnConstant(constants),
)); ));
self.offset = indexing_code_len; self.offset = indexing_code_len;
@@ -213,12 +218,11 @@ impl<'a> IndexingCodeMergingPtr<'a> {
} }
} }
} }
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(constants)) => {
IndexingInstruction::SwitchOnConstant(constants)
) => {
match constants.get(&overlapping_constant).cloned() { match constants.get(&overlapping_constant).cloned() {
None | Some(IndexingCodePtr::Fail) => { None | Some(IndexingCodePtr::Fail) => {
constants.insert(overlapping_constant, IndexingCodePtr::External(index)); constants
.insert(overlapping_constant, IndexingCodePtr::External(index));
} }
Some(IndexingCodePtr::External(o)) => { Some(IndexingCodePtr::External(o)) => {
self.add_indexed_choice_for_constant(o, overlapping_constant, index); self.add_indexed_choice_for_constant(o, overlapping_constant, index);
@@ -232,9 +236,9 @@ impl<'a> IndexingCodeMergingPtr<'a> {
break; break;
} }
IndexingLine::IndexedChoice(_) => { IndexingLine::IndexedChoice(_) => {
self.internalize_constant( self.internalize_constant(IndexingCodePtr::Internal(
IndexingCodePtr::Internal(indexing_code_len - self.offset), indexing_code_len - self.offset,
); ));
} }
_ => { _ => {
unreachable!() unreachable!()
@@ -248,9 +252,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
let indexing_code_len = self.indexing_code.len(); let indexing_code_len = self.indexing_code.len();
match &mut self.indexing_code[self.offset] { match &mut self.indexing_code[self.offset] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
) => {
match *c { match *c {
IndexingCodePtr::Fail => { IndexingCodePtr::Fail => {
*c = IndexingCodePtr::External(index); *c = IndexingCodePtr::External(index);
@@ -265,9 +267,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
} }
} }
} }
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(constants)) => {
IndexingInstruction::SwitchOnConstant(constants)
) => {
match constants.get(&constant).cloned() { match constants.get(&constant).cloned() {
None | Some(IndexingCodePtr::Fail) => { None | Some(IndexingCodePtr::Fail) => {
constants.insert(constant, IndexingCodePtr::External(index)); constants.insert(constant, IndexingCodePtr::External(index));
@@ -284,9 +284,9 @@ impl<'a> IndexingCodeMergingPtr<'a> {
break; break;
} }
IndexingLine::IndexedChoice(_) => { IndexingLine::IndexedChoice(_) => {
self.internalize_constant( self.internalize_constant(IndexingCodePtr::Internal(
IndexingCodePtr::Internal(indexing_code_len - self.offset), indexing_code_len - self.offset,
); ));
} }
_ => { _ => {
unreachable!() unreachable!()
@@ -295,13 +295,12 @@ impl<'a> IndexingCodeMergingPtr<'a> {
} }
} }
fn internalize_structure(&mut self, structure_ptr: IndexingCodePtr) { fn internalize_structure(&mut self, structure_ptr: IndexingCodePtr) {
let structure_key = let structure_key = search_skeleton_for_first_key_type(
search_skeleton_for_first_key_type( self.skeleton,
self.skeleton, OptArgIndexKeyType::Structure,
OptArgIndexKeyType::Structure, self.append_or_prepend,
self.append_or_prepend, );
);
let mut structures = IndexMap::new(); let mut structures = IndexMap::new();
@@ -316,7 +315,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
if let IndexingCodePtr::Internal(_) = structure_ptr { if let IndexingCodePtr::Internal(_) = structure_ptr {
self.indexing_code.push(IndexingLine::Indexing( self.indexing_code.push(IndexingLine::Indexing(
IndexingInstruction::SwitchOnStructure(structures) IndexingInstruction::SwitchOnStructure(structures),
)); ));
let last_index = self.indexing_code.len() - 1; let last_index = self.indexing_code.len() - 1;
@@ -325,34 +324,39 @@ impl<'a> IndexingCodeMergingPtr<'a> {
self.offset = self.indexing_code.len(); self.offset = self.indexing_code.len();
self.indexing_code.push(IndexingLine::Indexing( self.indexing_code.push(IndexingLine::Indexing(
IndexingInstruction::SwitchOnStructure(structures) IndexingInstruction::SwitchOnStructure(structures),
)); ));
} }
} }
fn add_indexed_choice_for_structure(&mut self, external: usize, key: PredicateKey, index: usize) fn add_indexed_choice_for_structure(
{ &mut self,
let third_level_index = external: usize,
if self.append_or_prepend.is_append() { key: PredicateKey,
sdeq![ index: usize,
IndexedChoiceInstruction::Try(external), ) {
IndexedChoiceInstruction::Trust(index) let third_level_index = if self.append_or_prepend.is_append() {
] sdeq![
} else { IndexedChoiceInstruction::Try(external),
sdeq![ IndexedChoiceInstruction::Trust(index)
IndexedChoiceInstruction::Try(index), ]
IndexedChoiceInstruction::Trust(external) } else {
] sdeq![
}; IndexedChoiceInstruction::Try(index),
IndexedChoiceInstruction::Trust(external)
]
};
let indexing_code_len = self.indexing_code.len(); let indexing_code_len = self.indexing_code.len();
self.indexing_code.push(IndexingLine::IndexedChoice(third_level_index)); self.indexing_code
.push(IndexingLine::IndexedChoice(third_level_index));
match &mut self.indexing_code[self.offset] { match &mut self.indexing_code[self.offset] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref mut structures)) => {
IndexingInstruction::SwitchOnStructure(ref mut structures) structures.insert(
) => { key,
structures.insert(key, IndexingCodePtr::Internal(indexing_code_len - self.offset)); IndexingCodePtr::Internal(indexing_code_len - self.offset),
);
} }
_ => { _ => {
unreachable!() unreachable!()
@@ -365,26 +369,26 @@ impl<'a> IndexingCodeMergingPtr<'a> {
let indexing_code_len = self.indexing_code.len(); let indexing_code_len = self.indexing_code.len();
match &mut self.indexing_code[self.offset] { match &mut self.indexing_code[self.offset] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s) _,
) => { _,
match *s { _,
IndexingCodePtr::Fail => { _,
*s = IndexingCodePtr::External(index); ref mut s,
break; )) => match *s {
} IndexingCodePtr::Fail => {
IndexingCodePtr::External(o) => { *s = IndexingCodePtr::External(index);
*s = IndexingCodePtr::Internal(indexing_code_len - self.offset); break;
self.internalize_structure(IndexingCodePtr::External(o));
}
IndexingCodePtr::Internal(o) => {
self.offset += o;
}
} }
} IndexingCodePtr::External(o) => {
IndexingLine::Indexing( *s = IndexingCodePtr::Internal(indexing_code_len - self.offset);
IndexingInstruction::SwitchOnStructure(structures) self.internalize_structure(IndexingCodePtr::External(o));
) => { }
IndexingCodePtr::Internal(o) => {
self.offset += o;
}
},
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(structures)) => {
match structures.get(&key).cloned() { match structures.get(&key).cloned() {
None | Some(IndexingCodePtr::Fail) => { None | Some(IndexingCodePtr::Fail) => {
structures.insert(key, IndexingCodePtr::External(index)); structures.insert(key, IndexingCodePtr::External(index));
@@ -404,9 +408,9 @@ impl<'a> IndexingCodeMergingPtr<'a> {
// replace this value, at self.offset, with // replace this value, at self.offset, with
// SwitchOnStructures, and swap this IndexedChoice // SwitchOnStructures, and swap this IndexedChoice
// vector to the end of self.indexing_code. // vector to the end of self.indexing_code.
self.internalize_structure( self.internalize_structure(IndexingCodePtr::Internal(
IndexingCodePtr::Internal(indexing_code_len - self.offset), indexing_code_len - self.offset,
); ));
} }
_ => { _ => {
unreachable!() unreachable!()
@@ -419,9 +423,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
let indexing_code_len = self.indexing_code.len(); let indexing_code_len = self.indexing_code.len();
match &mut self.indexing_code[self.offset] { match &mut self.indexing_code[self.offset] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)) => {
IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)
) => {
match *l { match *l {
IndexingCodePtr::Fail => { IndexingCodePtr::Fail => {
*l = IndexingCodePtr::External(index); *l = IndexingCodePtr::External(index);
@@ -429,22 +431,20 @@ impl<'a> IndexingCodeMergingPtr<'a> {
IndexingCodePtr::External(o) => { IndexingCodePtr::External(o) => {
*l = IndexingCodePtr::Internal(indexing_code_len - self.offset); *l = IndexingCodePtr::Internal(indexing_code_len - self.offset);
let third_level_index = let third_level_index = if self.append_or_prepend.is_append() {
if self.append_or_prepend.is_append() { sdeq![
sdeq![ IndexedChoiceInstruction::Try(o),
IndexedChoiceInstruction::Try(o), IndexedChoiceInstruction::Trust(index)
IndexedChoiceInstruction::Trust(index) ]
] } else {
} else { sdeq![
sdeq![ IndexedChoiceInstruction::Try(index),
IndexedChoiceInstruction::Try(index), IndexedChoiceInstruction::Trust(o)
IndexedChoiceInstruction::Trust(o) ]
] };
};
self.indexing_code.push( self.indexing_code
IndexingLine::IndexedChoice(third_level_index), .push(IndexingLine::IndexedChoice(third_level_index));
);
} }
IndexingCodePtr::Internal(o) => { IndexingCodePtr::Internal(o) => {
self.offset += o; self.offset += o;
@@ -462,24 +462,16 @@ impl<'a> IndexingCodeMergingPtr<'a> {
pub fn merge_clause_index( pub fn merge_clause_index(
target_indexing_code: &mut Vec<IndexingLine>, target_indexing_code: &mut Vec<IndexingLine>,
skeleton: &mut [ClauseIndexInfo], // the clause to be merged is the last element in the skeleton. 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, append_or_prepend: AppendOrPrepend,
) { ) {
let opt_arg_index_key = let opt_arg_index_key = match append_or_prepend {
match append_or_prepend { AppendOrPrepend::Append => skeleton.last_mut().unwrap().opt_arg_index_key.take(),
AppendOrPrepend::Append => { AppendOrPrepend::Prepend => skeleton.first_mut().unwrap().opt_arg_index_key.take(),
skeleton.last_mut().unwrap().opt_arg_index_key.take() };
}
AppendOrPrepend::Prepend => {
skeleton.first_mut().unwrap().opt_arg_index_key.take()
}
};
let mut merging_ptr = IndexingCodeMergingPtr::new( let mut merging_ptr =
skeleton, IndexingCodeMergingPtr::new(skeleton, target_indexing_code, append_or_prepend);
target_indexing_code,
append_or_prepend,
);
match &opt_arg_index_key { match &opt_arg_index_key {
OptArgIndexKey::Constant(_, index_loc, ref constant, ref overlapping_constants) => { OptArgIndexKey::Constant(_, index_loc, ref constant, ref overlapping_constants) => {
@@ -488,7 +480,9 @@ pub fn merge_clause_index(
for overlapping_constant in overlapping_constants { for overlapping_constant in overlapping_constants {
merging_ptr.index_overlapping_constant( merging_ptr.index_overlapping_constant(
constant, overlapping_constant.clone(), offset, constant,
overlapping_constant.clone(),
offset,
); );
} }
} }
@@ -514,10 +508,7 @@ pub fn merge_clause_index(
} }
#[inline] #[inline]
fn remove_instruction_with_offset( fn remove_instruction_with_offset(code: &mut SliceDeque<IndexedChoiceInstruction>, offset: usize) {
code: &mut SliceDeque<IndexedChoiceInstruction>,
offset: usize,
) {
for (index, line) in code.iter().enumerate() { for (index, line) in code.iter().enumerate() {
if offset == line.offset() { if offset == line.offset() {
code.remove(index); code.remove(index);
@@ -537,9 +528,7 @@ pub fn remove_constant_indices(
let iter = once(constant).chain(overlapping_constants.iter()); let iter = once(constant).chain(overlapping_constants.iter());
match &mut indexing_code[index] { match &mut indexing_code[index] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
) => {
match *c { match *c {
IndexingCodePtr::External(_) => { IndexingCodePtr::External(_) => {
*c = IndexingCodePtr::Fail; *c = IndexingCodePtr::Fail;
@@ -560,12 +549,13 @@ pub fn remove_constant_indices(
let mut constants_index = 0; let mut constants_index = 0;
for constant in iter { // (constant, index_loc) in iter.zip(index_locs.iter()) { for constant in iter {
// (constant, index_loc) in iter.zip(index_locs.iter()) {
loop { loop {
match &mut indexing_code[index] { match &mut indexing_code[index] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(
IndexingInstruction::SwitchOnConstant(ref mut constants) ref mut constants,
) => { )) => {
constants_index = index; constants_index = index;
match constants.get(constant).cloned() { match constants.get(constant).cloned() {
@@ -586,18 +576,21 @@ pub fn remove_constant_indices(
if indexed_choice_instrs.len() == 1 { if indexed_choice_instrs.len() == 1 {
let ext = IndexingCodePtr::External( let ext = IndexingCodePtr::External(
indexed_choice_instrs.pop_back().unwrap().offset() indexed_choice_instrs.pop_back().unwrap().offset(),
); );
match &mut indexing_code[constants_index] { match &mut indexing_code[constants_index] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..) _,
) => { _,
ref mut c,
..,
)) => {
*c = ext; *c = ext;
} }
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(
IndexingInstruction::SwitchOnConstant(ref mut constants) ref mut constants,
) => { )) => {
constants.insert(constant.clone(), ext); constants.insert(constant.clone(), ext);
} }
_ => { _ => {
@@ -616,13 +609,11 @@ pub fn remove_constant_indices(
} }
match &indexing_code[constants_index] { match &indexing_code[constants_index] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(ref constants))
IndexingInstruction::SwitchOnConstant(ref constants) if constants.is_empty() =>
) if constants.is_empty() => { {
match &mut indexing_code[0] { match &mut indexing_code[0] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
) => {
*c = IndexingCodePtr::Fail; *c = IndexingCodePtr::Fail;
} }
_ => { _ => {
@@ -630,8 +621,7 @@ pub fn remove_constant_indices(
} }
} }
} }
_ => { _ => {}
}
} }
} }
@@ -644,9 +634,7 @@ pub fn remove_structure_index(
let mut index = 0; let mut index = 0;
match &mut indexing_code[index] { match &mut indexing_code[index] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)) => {
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)
) => {
match *s { match *s {
IndexingCodePtr::External(_) => { IndexingCodePtr::External(_) => {
*s = IndexingCodePtr::Fail; *s = IndexingCodePtr::Fail;
@@ -669,9 +657,7 @@ pub fn remove_structure_index(
loop { loop {
match &mut indexing_code[index] { match &mut indexing_code[index] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref mut structures)) => {
IndexingInstruction::SwitchOnStructure(ref mut structures)
) => {
structures_index = index; structures_index = index;
match structures.get(&(name.clone(), arity)).cloned() { match structures.get(&(name.clone(), arity)).cloned() {
@@ -692,18 +678,22 @@ pub fn remove_structure_index(
if indexed_choice_instrs.len() == 1 { if indexed_choice_instrs.len() == 1 {
let ext = IndexingCodePtr::External( let ext = IndexingCodePtr::External(
indexed_choice_instrs.pop_back().unwrap().offset() indexed_choice_instrs.pop_back().unwrap().offset(),
); );
match &mut indexing_code[structures_index] { match &mut indexing_code[structures_index] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s) _,
) => { _,
_,
_,
ref mut s,
)) => {
*s = ext; *s = ext;
} }
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(
IndexingInstruction::SwitchOnStructure(ref mut structures) ref mut structures,
) => { )) => {
structures.insert((name.clone(), arity), ext); structures.insert((name.clone(), arity), ext);
} }
_ => { _ => {
@@ -721,13 +711,17 @@ pub fn remove_structure_index(
} }
match &indexing_code[structures_index] { match &indexing_code[structures_index] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref structures))
IndexingInstruction::SwitchOnStructure(ref structures) if structures.is_empty() =>
) if structures.is_empty() => { {
match &mut indexing_code[0] { match &mut indexing_code[0] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s) _,
) => { _,
_,
_,
ref mut s,
)) => {
*s = IndexingCodePtr::Fail; *s = IndexingCodePtr::Fail;
} }
_ => { _ => {
@@ -735,21 +729,15 @@ pub fn remove_structure_index(
} }
} }
} }
_ => { _ => {}
}
} }
} }
pub fn remove_list_index( pub fn remove_list_index(indexing_code: &mut Vec<IndexingLine>, offset: usize) {
indexing_code: &mut Vec<IndexingLine>,
offset: usize,
) {
let mut index = 0; let mut index = 0;
match &mut indexing_code[index] { match &mut indexing_code[index] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)) => {
IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)
) => {
match *l { match *l {
IndexingCodePtr::External(_) => { IndexingCodePtr::External(_) => {
*l = IndexingCodePtr::Fail; *l = IndexingCodePtr::Fail;
@@ -773,14 +761,17 @@ pub fn remove_list_index(
remove_instruction_with_offset(indexed_choice_instrs, offset); remove_instruction_with_offset(indexed_choice_instrs, offset);
if indexed_choice_instrs.len() == 1 { if indexed_choice_instrs.len() == 1 {
let ext = IndexingCodePtr::External( let ext =
indexed_choice_instrs.pop_back().unwrap().offset() IndexingCodePtr::External(indexed_choice_instrs.pop_back().unwrap().offset());
);
match &mut indexing_code[0] { match &mut indexing_code[0] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _) _,
) => { _,
_,
ref mut l,
_,
)) => {
*l = ext; *l = ext;
} }
_ => { _ => {
@@ -836,8 +827,7 @@ pub fn remove_index(
fn second_level_index<IndexKey: Eq + Hash>( fn second_level_index<IndexKey: Eq + Hash>(
indices: IndexMap<IndexKey, SliceDeque<IndexedChoiceInstruction>>, indices: IndexMap<IndexKey, SliceDeque<IndexedChoiceInstruction>>,
prelude: &mut SliceDeque<IndexingLine>, prelude: &mut SliceDeque<IndexingLine>,
) -> IndexMap<IndexKey, IndexingCodePtr> ) -> IndexMap<IndexKey, IndexingCodePtr> {
{
let mut index_locs = IndexMap::new(); let mut index_locs = IndexMap::new();
for (key, mut code) in indices.into_iter() { for (key, mut code) in indices.into_iter() {
@@ -868,10 +858,11 @@ fn switch_on<IndexKey: Eq + Hash>(
IndexingCodePtr::Internal(1) IndexingCodePtr::Internal(1)
} else { } else {
index.into_iter() index
.next() .into_iter()
.map(|(_, v)| v) .next()
.unwrap_or(IndexingCodePtr::Fail) .map(|(_, v)| v)
.unwrap_or(IndexingCodePtr::Fail)
} }
} }
@@ -884,9 +875,10 @@ fn switch_on_list(
prelude.push_back(IndexingLine::from(lists)); prelude.push_back(IndexingLine::from(lists));
IndexingCodePtr::Internal(1) IndexingCodePtr::Internal(1)
} else { } else {
lists.first() lists
.map(|i| IndexingCodePtr::External(i.offset())) .first()
.unwrap_or(IndexingCodePtr::Fail) .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.push(Constant::Fixnum(n));
} }
} }
_ => { _ => {}
}
} }
constants constants
@@ -1001,7 +992,7 @@ impl CodeOffsets {
constants: IndexMap::new(), constants: IndexMap::new(),
lists: sdeq![], lists: sdeq![],
structures: IndexMap::new(), structures: IndexMap::new(),
optimal_index optimal_index,
} }
} }
@@ -1011,20 +1002,15 @@ impl CodeOffsets {
} }
fn index_constant(&mut self, constant: &Constant, index: usize) -> Vec<Constant> { fn index_constant(&mut self, constant: &Constant, index: usize) -> Vec<Constant> {
let overlapping_constants = let overlapping_constants = constant_key_alternatives(constant, self.atom_tbl.clone());
constant_key_alternatives(constant, self.atom_tbl.clone());
let code = self.constants let code = self.constants.entry(constant.clone()).or_insert(sdeq![]);
.entry(constant.clone())
.or_insert(sdeq![]);
let is_initial_index = code.is_empty(); let is_initial_index = code.is_empty();
code.push_back(compute_index(is_initial_index, index)); code.push_back(compute_index(is_initial_index, index));
for constant in &overlapping_constants { for constant in &overlapping_constants {
let code = self.constants let code = self.constants.entry(constant.clone()).or_insert(sdeq![]);
.entry(constant.clone())
.or_insert(sdeq![]);
let is_initial_index = code.is_empty(); let is_initial_index = code.is_empty();
let index = compute_index(is_initial_index, index); let index = compute_index(is_initial_index, index);
@@ -1062,25 +1048,21 @@ impl CodeOffsets {
self.index_structure(name, terms.len(), index); self.index_structure(name, terms.len(), index);
} }
&Term::Cons(..) | &Term::Constant(_, Constant::String(_)) => { &Term::Cons(..) | &Term::Constant(_, Constant::String(_)) => {
clause_index_info.opt_arg_index_key = clause_index_info.opt_arg_index_key = OptArgIndexKey::List(self.optimal_index, 0);
OptArgIndexKey::List(self.optimal_index, 0);
self.index_list(index); self.index_list(index);
} }
&Term::Constant(_, ref constant) => { &Term::Constant(_, ref constant) => {
let overlapping_constants = let overlapping_constants = self.index_constant(constant, index);
self.index_constant(constant, index);
clause_index_info.opt_arg_index_key = clause_index_info.opt_arg_index_key = OptArgIndexKey::Constant(
OptArgIndexKey::Constant( self.optimal_index,
self.optimal_index, 0,
0, constant.clone(),
constant.clone(), overlapping_constants,
overlapping_constants, );
);
}
_ => {
} }
_ => {}
} }
} }
@@ -1117,8 +1099,7 @@ impl CodeOffsets {
IndexingCodePtr::Internal(ref mut i) => { IndexingCodePtr::Internal(ref mut i) => {
*i += con_loc.is_internal() as usize; *i += con_loc.is_internal() as usize;
} }
_ => { _ => {}
}
}; };
match &mut lst_loc { match &mut lst_loc {
@@ -1126,15 +1107,18 @@ impl CodeOffsets {
*i += con_loc.is_internal() as usize; *i += con_loc.is_internal() as usize;
*i += str_loc.is_internal() as usize; *i += str_loc.is_internal() as usize;
} }
_ => { _ => {}
}
}; };
let var_offset = 1 + skip_stub_try_me_else as usize; let var_offset = 1 + skip_stub_try_me_else as usize;
prelude.push_front(IndexingLine::from( prelude.push_front(IndexingLine::from(IndexingInstruction::SwitchOnTerm(
IndexingInstruction::SwitchOnTerm(self.optimal_index, var_offset, con_loc, lst_loc, str_loc) self.optimal_index,
)); var_offset,
con_loc,
lst_loc,
str_loc,
)));
prelude.into_iter().collect() prelude.into_iter().collect()
} }

View File

@@ -1,4 +1,5 @@
use crate::prolog_parser_rebis::ast::*; use crate::prolog_parser_rebis::ast::*;
use crate::prolog_parser_rebis::clause_name;
use crate::clause_types::*; use crate::clause_types::*;
use crate::forms::*; use crate::forms::*;
@@ -34,9 +35,7 @@ impl Level {
impl ArithmeticTerm { impl ArithmeticTerm {
fn into_functor(&self) -> MachineStub { fn into_functor(&self) -> MachineStub {
match self { match self {
&ArithmeticTerm::Reg(r) => { &ArithmeticTerm::Reg(r) => reg_type_into_functor(r),
reg_type_into_functor(r)
}
&ArithmeticTerm::Interm(i) => { &ArithmeticTerm::Interm(i) => {
functor!("intermediate", [integer(i)]) functor!("intermediate", [integer(i)])
} }
@@ -185,16 +184,11 @@ impl Line {
pub fn enqueue_functors(&self, mut h: usize, functors: &mut Vec<MachineStub>) { pub fn enqueue_functors(&self, mut h: usize, functors: &mut Vec<MachineStub>) {
match self { match self {
&Line::Arithmetic(ref arith_instr) => &Line::Arithmetic(ref arith_instr) => functors.push(arith_instr.to_functor(h)),
functors.push(arith_instr.to_functor(h)), &Line::Choice(ref choice_instr) => functors.push(choice_instr.to_functor()),
&Line::Choice(ref choice_instr) => &Line::Control(ref control_instr) => functors.push(control_instr.to_functor()),
functors.push(choice_instr.to_functor()), &Line::Cut(ref cut_instr) => functors.push(cut_instr.to_functor(h)),
&Line::Control(ref control_instr) => &Line::Fact(ref fact_instr) => functors.push(fact_instr.to_functor(h)),
functors.push(control_instr.to_functor()),
&Line::Cut(ref cut_instr) =>
functors.push(cut_instr.to_functor(h)),
&Line::Fact(ref fact_instr) =>
functors.push(fact_instr.to_functor(h)),
&Line::IndexingCode(ref indexing_instrs) => { &Line::IndexingCode(ref indexing_instrs) => {
for indexing_instr in indexing_instrs { for indexing_instr in indexing_instrs {
match indexing_instr { match indexing_instr {
@@ -213,10 +207,10 @@ impl Line {
} }
} }
} }
&Line::IndexedChoice(ref indexed_choice_instr) => &Line::IndexedChoice(ref indexed_choice_instr) => {
functors.push(indexed_choice_instr.to_functor()), functors.push(indexed_choice_instr.to_functor())
&Line::Query(ref query_instr) => }
functors.push(query_instr.to_functor(h)), &Line::Query(ref query_instr) => functors.push(query_instr.to_functor(h)),
} }
} }
} }
@@ -224,24 +218,16 @@ impl Line {
#[inline] #[inline]
pub fn to_indexing_line_mut(line: &mut Line) -> Option<&mut Vec<IndexingLine>> { pub fn to_indexing_line_mut(line: &mut Line) -> Option<&mut Vec<IndexingLine>> {
match line { match line {
Line::IndexingCode(ref mut indexing_code) => { Line::IndexingCode(ref mut indexing_code) => Some(indexing_code),
Some(indexing_code) _ => None,
}
_ => {
None
}
} }
} }
#[inline] #[inline]
pub fn to_indexing_line(line: &Line) -> Option<&Vec<IndexingLine>> { pub fn to_indexing_line(line: &Line) -> Option<&Vec<IndexingLine>> {
match line { match line {
Line::IndexingCode(ref indexing_code) => { Line::IndexingCode(ref indexing_code) => Some(indexing_code),
Some(indexing_code) _ => None,
}
_ => {
None
}
} }
} }
@@ -296,11 +282,7 @@ fn arith_instr_unary_functor(
) -> MachineStub { ) -> MachineStub {
let at_stub = at.into_functor(); let at_stub = at.into_functor();
functor!( functor!(name, [aux(h, 0), integer(t)], [at_stub])
name,
[aux(h, 0), integer(t)],
[at_stub]
)
} }
fn arith_instr_bin_functor( fn arith_instr_bin_functor(
@@ -383,39 +365,17 @@ impl ArithmeticInstruction {
&ArithmeticInstruction::Gcd(ref at_1, ref at_2, t) => { &ArithmeticInstruction::Gcd(ref at_1, ref at_2, t) => {
arith_instr_bin_functor(h, "gcd", at_1, at_2, t) arith_instr_bin_functor(h, "gcd", at_1, at_2, t)
} }
&ArithmeticInstruction::Sign(ref at, t) => { &ArithmeticInstruction::Sign(ref at, t) => arith_instr_unary_functor(h, "sign", at, t),
arith_instr_unary_functor(h, "sign", at, t) &ArithmeticInstruction::Cos(ref at, t) => arith_instr_unary_functor(h, "cos", at, t),
} &ArithmeticInstruction::Sin(ref at, t) => arith_instr_unary_functor(h, "sin", at, t),
&ArithmeticInstruction::Cos(ref at, t) => { &ArithmeticInstruction::Tan(ref at, t) => arith_instr_unary_functor(h, "tan", at, t),
arith_instr_unary_functor(h, "cos", at, t) &ArithmeticInstruction::Log(ref at, t) => arith_instr_unary_functor(h, "log", at, t),
} &ArithmeticInstruction::Exp(ref at, t) => arith_instr_unary_functor(h, "exp", at, t),
&ArithmeticInstruction::Sin(ref at, t) => { &ArithmeticInstruction::ACos(ref at, t) => arith_instr_unary_functor(h, "acos", at, t),
arith_instr_unary_functor(h, "sin", at, t) &ArithmeticInstruction::ASin(ref at, t) => arith_instr_unary_functor(h, "asin", at, t),
} &ArithmeticInstruction::ATan(ref at, t) => arith_instr_unary_functor(h, "atan", at, t),
&ArithmeticInstruction::Tan(ref at, t) => { &ArithmeticInstruction::Sqrt(ref at, t) => arith_instr_unary_functor(h, "sqrt", at, t),
arith_instr_unary_functor(h, "tan", at, t) &ArithmeticInstruction::Abs(ref at, t) => arith_instr_unary_functor(h, "abs", at, t),
}
&ArithmeticInstruction::Log(ref at, t) => {
arith_instr_unary_functor(h, "log", at, t)
}
&ArithmeticInstruction::Exp(ref at, t) => {
arith_instr_unary_functor(h, "exp", at, t)
}
&ArithmeticInstruction::ACos(ref at, t) => {
arith_instr_unary_functor(h, "acos", at, t)
}
&ArithmeticInstruction::ASin(ref at, t) => {
arith_instr_unary_functor(h, "asin", at, t)
}
&ArithmeticInstruction::ATan(ref at, t) => {
arith_instr_unary_functor(h, "atan", at, t)
}
&ArithmeticInstruction::Sqrt(ref at, t) => {
arith_instr_unary_functor(h, "sqrt", at, t)
}
&ArithmeticInstruction::Abs(ref at, t) => {
arith_instr_unary_functor(h, "abs", at, t)
}
&ArithmeticInstruction::Float(ref at, t) => { &ArithmeticInstruction::Float(ref at, t) => {
arith_instr_unary_functor(h, "float", at, t) arith_instr_unary_functor(h, "float", at, t)
} }
@@ -431,12 +391,8 @@ impl ArithmeticInstruction {
&ArithmeticInstruction::Floor(ref at, t) => { &ArithmeticInstruction::Floor(ref at, t) => {
arith_instr_unary_functor(h, "floor", at, t) arith_instr_unary_functor(h, "floor", at, t)
} }
&ArithmeticInstruction::Neg(ref at, t) => { &ArithmeticInstruction::Neg(ref at, t) => arith_instr_unary_functor(h, "-", at, t),
arith_instr_unary_functor(h, "-", at, t) &ArithmeticInstruction::Plus(ref at, t) => arith_instr_unary_functor(h, "+", at, t),
}
&ArithmeticInstruction::Plus(ref at, t) => {
arith_instr_unary_functor(h, "+", at, t)
}
&ArithmeticInstruction::BitwiseComplement(ref at, t) => { &ArithmeticInstruction::BitwiseComplement(ref at, t) => {
arith_instr_unary_functor(h, "\\", at, t) arith_instr_unary_functor(h, "\\", at, t)
} }
@@ -451,21 +407,18 @@ pub enum ControlInstruction {
CallClause(ClauseType, usize, usize, bool, bool), CallClause(ClauseType, usize, usize, bool, bool),
Deallocate, Deallocate,
JmpBy(usize, usize, usize, bool), // arity, global_offset, perm_vars after threshold, last call. JmpBy(usize, usize, usize, bool), // arity, global_offset, perm_vars after threshold, last call.
RevJmpBy(usize), // notice the lack of context change as in RevJmpBy(usize), // notice the lack of context change as in
// JmpBy. RevJmpBy is used only to patch extensible // JmpBy. RevJmpBy is used only to patch extensible
// predicates together. // predicates together.
Proceed, Proceed,
} }
impl ControlInstruction { impl ControlInstruction {
pub fn perm_vars(&self) -> Option<usize> { pub fn perm_vars(&self) -> Option<usize> {
match self { match self {
ControlInstruction::CallClause(_, _, num_cells, ..) => ControlInstruction::CallClause(_, _, num_cells, ..) => Some(*num_cells),
Some(*num_cells), ControlInstruction::JmpBy(_, _, num_cells, ..) => Some(*num_cells),
ControlInstruction::JmpBy(_, _, num_cells, ..) => _ => None,
Some(*num_cells),
_ =>
None
} }
} }
@@ -500,7 +453,13 @@ impl ControlInstruction {
#[derive(Debug)] #[derive(Debug)]
pub enum IndexingInstruction { pub enum IndexingInstruction {
// The first index is the optimal argument being indexed. // The first index is the optimal argument being indexed.
SwitchOnTerm(usize, usize, IndexingCodePtr, IndexingCodePtr, IndexingCodePtr), SwitchOnTerm(
usize,
usize,
IndexingCodePtr,
IndexingCodePtr,
IndexingCodePtr,
),
SwitchOnConstant(IndexMap<Constant, IndexingCodePtr>), SwitchOnConstant(IndexMap<Constant, IndexingCodePtr>),
SwitchOnStructure(IndexMap<(ClauseName, usize), IndexingCodePtr>), SwitchOnStructure(IndexMap<(ClauseName, usize), IndexingCodePtr>),
} }
@@ -511,11 +470,13 @@ impl IndexingInstruction {
&IndexingInstruction::SwitchOnTerm(arg, vars, constants, lists, structures) => { &IndexingInstruction::SwitchOnTerm(arg, vars, constants, lists, structures) => {
functor!( functor!(
"switch_on_term", "switch_on_term",
[integer(arg), [
integer(vars), integer(arg),
indexing_code_ptr(h, constants), integer(vars),
indexing_code_ptr(h, lists), indexing_code_ptr(h, constants),
indexing_code_ptr(h, structures)] indexing_code_ptr(h, lists),
indexing_code_ptr(h, structures)
]
) )
} }
&IndexingInstruction::SwitchOnConstant(ref constants) => { &IndexingInstruction::SwitchOnConstant(ref constants) => {
@@ -528,15 +489,14 @@ impl IndexingInstruction {
let key_value_pair = functor!( let key_value_pair = functor!(
":", ":",
SharedOpDesc::new(600, XFY), SharedOpDesc::new(600, XFY),
[constant(c), [constant(c), indexing_code_ptr(h + 3, *ptr)]
indexing_code_ptr(h + 3, *ptr)]
); );
key_value_list_stub.push(HeapCellValue::Addr(Addr::Lis(h + 1))); key_value_list_stub.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
key_value_list_stub.push(HeapCellValue::Addr(Addr::Str(h + 3))); key_value_list_stub.push(HeapCellValue::Addr(Addr::Str(h + 3)));
key_value_list_stub.push(HeapCellValue::Addr( key_value_list_stub.push(HeapCellValue::Addr(Addr::HeapCell(
Addr::HeapCell(h + 3 + key_value_pair.len()) h + 3 + key_value_pair.len(),
)); )));
h += key_value_pair.len() + 3; h += key_value_pair.len() + 3;
key_value_list_stub.extend(key_value_pair.into_iter()); key_value_list_stub.extend(key_value_pair.into_iter());
@@ -560,23 +520,21 @@ impl IndexingInstruction {
let predicate_indicator_stub = functor!( let predicate_indicator_stub = functor!(
"/", "/",
SharedOpDesc::new(400, YFX), SharedOpDesc::new(400, YFX),
[clause_name(name.clone()), [clause_name(name.clone()), integer(*arity)]
integer(*arity)]
); );
let key_value_pair = functor!( let key_value_pair = functor!(
":", ":",
SharedOpDesc::new(600, XFY), SharedOpDesc::new(600, XFY),
[aux(h + 3, 0), [aux(h + 3, 0), indexing_code_ptr(h + 3, *ptr)],
indexing_code_ptr(h + 3, *ptr)],
[predicate_indicator_stub] [predicate_indicator_stub]
); );
key_value_list_stub.push(HeapCellValue::Addr(Addr::Lis(h + 1))); key_value_list_stub.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
key_value_list_stub.push(HeapCellValue::Addr(Addr::Str(h + 3))); key_value_list_stub.push(HeapCellValue::Addr(Addr::Str(h + 3)));
key_value_list_stub.push(HeapCellValue::Addr( key_value_list_stub.push(HeapCellValue::Addr(Addr::HeapCell(
Addr::HeapCell(h + 3 + key_value_pair.len()) h + 3 + key_value_pair.len(),
)); )));
h += key_value_pair.len() + 3; h += key_value_pair.len() + 3;
key_value_list_stub.extend(key_value_pair.into_iter()); key_value_list_stub.extend(key_value_pair.into_iter());
@@ -614,7 +572,7 @@ impl FactInstruction {
match self { match self {
&FactInstruction::GetConstant(lvl, ref c, r) => { &FactInstruction::GetConstant(lvl, ref c, r) => {
let lvl_stub = lvl.into_functor(); let lvl_stub = lvl.into_functor();
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!(
"get_constant", "get_constant",
@@ -624,17 +582,13 @@ impl FactInstruction {
} }
&FactInstruction::GetList(lvl, r) => { &FactInstruction::GetList(lvl, r) => {
let lvl_stub = lvl.into_functor(); let lvl_stub = lvl.into_functor();
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("get_list", [aux(h, 0), aux(h, 1)], [lvl_stub, rt_stub])
"get_list",
[aux(h, 0), aux(h, 1)],
[lvl_stub, rt_stub]
)
} }
&FactInstruction::GetPartialString(lvl, ref s, r, has_tail) => { &FactInstruction::GetPartialString(lvl, ref s, r, has_tail) => {
let lvl_stub = lvl.into_functor(); let lvl_stub = lvl.into_functor();
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!(
"get_partial_string", "get_partial_string",
@@ -654,20 +608,12 @@ impl FactInstruction {
&FactInstruction::GetValue(r, arg) => { &FactInstruction::GetValue(r, arg) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("get_value", [aux(h, 0), integer(arg)], [rt_stub])
"get_value",
[aux(h, 0), integer(arg)],
[rt_stub]
)
} }
&FactInstruction::GetVariable(r, arg) => { &FactInstruction::GetVariable(r, arg) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("get_variable", [aux(h, 0), integer(arg)], [rt_stub])
"get_variable",
[aux(h, 0), integer(arg)],
[rt_stub]
)
} }
&FactInstruction::UnifyConstant(ref c) => { &FactInstruction::UnifyConstant(ref c) => {
functor!("unify_constant", [constant(h, c)], []) functor!("unify_constant", [constant(h, c)], [])
@@ -675,29 +621,17 @@ impl FactInstruction {
&FactInstruction::UnifyLocalValue(r) => { &FactInstruction::UnifyLocalValue(r) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("unify_local_value", [aux(h, 0)], [rt_stub])
"unify_local_value",
[aux(h, 0)],
[rt_stub]
)
} }
&FactInstruction::UnifyVariable(r) => { &FactInstruction::UnifyVariable(r) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("unify_variable", [aux(h, 0)], [rt_stub])
"unify_variable",
[aux(h, 0)],
[rt_stub]
)
} }
&FactInstruction::UnifyValue(r) => { &FactInstruction::UnifyValue(r) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("unify_value", [aux(h, 0)], [rt_stub])
"unify_value",
[aux(h, 0)],
[rt_stub]
)
} }
&FactInstruction::UnifyVoid(vars) => { &FactInstruction::UnifyVoid(vars) => {
functor!("unify_void", [integer(vars)]) functor!("unify_void", [integer(vars)])
@@ -726,13 +660,12 @@ pub enum QueryInstruction {
impl QueryInstruction { impl QueryInstruction {
pub fn to_functor(&self, h: usize) -> MachineStub { pub fn to_functor(&self, h: usize) -> MachineStub {
match self { match self {
&QueryInstruction::PutUnsafeValue(norm, arg) => functor!( &QueryInstruction::PutUnsafeValue(norm, arg) => {
"put_unsafe_value", functor!("put_unsafe_value", [integer(norm), integer(arg)])
[integer(norm), integer(arg)] }
),
&QueryInstruction::PutConstant(lvl, ref c, r) => { &QueryInstruction::PutConstant(lvl, ref c, r) => {
let lvl_stub = lvl.into_functor(); let lvl_stub = lvl.into_functor();
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!(
"put_constant", "put_constant",
@@ -742,17 +675,13 @@ impl QueryInstruction {
} }
&QueryInstruction::PutList(lvl, r) => { &QueryInstruction::PutList(lvl, r) => {
let lvl_stub = lvl.into_functor(); let lvl_stub = lvl.into_functor();
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("put_list", [aux(h, 0), aux(h, 1)], [lvl_stub, rt_stub])
"put_list",
[aux(h, 0), aux(h, 1)],
[lvl_stub, rt_stub]
)
} }
&QueryInstruction::PutPartialString(lvl, ref s, r, has_tail) => { &QueryInstruction::PutPartialString(lvl, ref s, r, has_tail) => {
let lvl_stub = lvl.into_functor(); let lvl_stub = lvl.into_functor();
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!(
"put_partial_string", "put_partial_string",
@@ -772,29 +701,17 @@ impl QueryInstruction {
&QueryInstruction::PutValue(r, arg) => { &QueryInstruction::PutValue(r, arg) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("put_value", [aux(h, 0), integer(arg)], [rt_stub])
"put_value",
[aux(h, 0), integer(arg)],
[rt_stub]
)
} }
&QueryInstruction::GetVariable(r, arg) => { &QueryInstruction::GetVariable(r, arg) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("get_variable", [aux(h, 0), integer(arg)], [rt_stub])
"get_variable",
[aux(h, 0), integer(arg)],
[rt_stub]
)
} }
&QueryInstruction::PutVariable(r, arg) => { &QueryInstruction::PutVariable(r, arg) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("put_variable", [aux(h, 0), integer(arg)], [rt_stub])
"put_variable",
[aux(h, 0), integer(arg)],
[rt_stub]
)
} }
&QueryInstruction::SetConstant(ref c) => { &QueryInstruction::SetConstant(ref c) => {
functor!("set_constant", [constant(h, c)], []) functor!("set_constant", [constant(h, c)], [])
@@ -802,29 +719,17 @@ impl QueryInstruction {
&QueryInstruction::SetLocalValue(r) => { &QueryInstruction::SetLocalValue(r) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("set_local_value", [aux(h, 0)], [rt_stub])
"set_local_value",
[aux(h, 0)],
[rt_stub]
)
} }
&QueryInstruction::SetVariable(r) => { &QueryInstruction::SetVariable(r) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("set_variable", [aux(h, 0)], [rt_stub])
"set_variable",
[aux(h, 0)],
[rt_stub]
)
} }
&QueryInstruction::SetValue(r) => { &QueryInstruction::SetValue(r) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("set_value", [aux(h, 0)], [rt_stub])
"set_value",
[aux(h, 0)],
[rt_stub]
)
} }
&QueryInstruction::SetVoid(vars) => { &QueryInstruction::SetVoid(vars) => {
functor!("set_void", [integer(vars)]) functor!("set_void", [integer(vars)])

View File

@@ -1,4 +1,5 @@
use crate::prolog_parser_rebis::ast::*; use crate::prolog_parser_rebis::ast::*;
use crate::prolog_parser_rebis::rc_atom;
use crate::clause_types::*; use crate::clause_types::*;
use crate::forms::*; use crate::forms::*;
@@ -25,11 +26,11 @@ impl<'a> TermRef<'a> {
pub fn level(self) -> Level { pub fn level(self) -> Level {
match self { match self {
TermRef::AnonVar(lvl) TermRef::AnonVar(lvl)
| TermRef::Cons(lvl, ..) | TermRef::Cons(lvl, ..)
| TermRef::Constant(lvl, ..) | TermRef::Constant(lvl, ..)
| TermRef::Var(lvl, ..) | TermRef::Var(lvl, ..)
| TermRef::Clause(lvl, ..) => lvl, | TermRef::Clause(lvl, ..) => lvl,
| TermRef::PartialString(lvl, ..) => lvl, TermRef::PartialString(lvl, ..) => lvl,
} }
} }
} }
@@ -51,23 +52,16 @@ pub enum TermIterState<'a> {
Var(Level, &'a Cell<VarReg>, Rc<Var>), Var(Level, &'a Cell<VarReg>, Rc<Var>),
} }
fn is_partial_string<'a>( fn is_partial_string<'a>(head: &'a Term, mut tail: &'a Term) -> Option<(String, Option<&'a Term>)> {
head: &'a Term, let mut string = match head {
mut tail: &'a Term, &Term::Constant(_, Constant::Atom(ref atom, _)) if atom.is_char() => {
) -> Option<(String, Option<&'a Term>)> atom.as_str().chars().next().unwrap().to_string()
{ }
let mut string = &Term::Constant(_, Constant::Char(c)) => c.to_string(),
match head { _ => {
&Term::Constant(_, Constant::Atom(ref atom, _)) if atom.is_char() => { return None;
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 { while let Term::Cons(_, ref head, ref succ) = tail {
match head.as_ref() { match head.as_ref() {
@@ -105,9 +99,7 @@ fn is_partial_string<'a>(
impl<'a> TermIterState<'a> { impl<'a> TermIterState<'a> {
pub fn subterm_to_state(lvl: Level, term: &'a Term) -> TermIterState<'a> { pub fn subterm_to_state(lvl: Level, term: &'a Term) -> TermIterState<'a> {
match term { match term {
&Term::AnonVar => { &Term::AnonVar => TermIterState::AnonVar(lvl),
TermIterState::AnonVar(lvl)
}
&Term::Clause(ref cell, ref name, ref subterms, ref spec) => { &Term::Clause(ref cell, ref name, ref subterms, ref spec) => {
let ct = if let Some(spec) = spec { let ct = if let Some(spec) = spec {
ClauseType::Op(name.clone(), spec.clone(), CodeIndex::default()) ClauseType::Op(name.clone(), spec.clone(), CodeIndex::default())
@@ -120,12 +112,8 @@ impl<'a> TermIterState<'a> {
&Term::Cons(ref cell, ref head, ref tail) => { &Term::Cons(ref cell, ref head, ref tail) => {
TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref()) TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref())
} }
&Term::Constant(ref cell, ref constant) => { &Term::Constant(ref cell, ref constant) => TermIterState::Constant(lvl, cell, constant),
TermIterState::Constant(lvl, cell, constant) &Term::Var(ref cell, ref var) => TermIterState::Var(lvl, cell, var.clone()),
}
&Term::Var(ref cell, ref var) => {
TermIterState::Var(lvl, cell, var.clone())
}
} }
} }
} }
@@ -175,8 +163,7 @@ impl<'a> QueryIterator<'a> {
state_stack: vec![], state_stack: vec![],
} }
} }
&Term::Var(ref cell, ref var) => &Term::Var(ref cell, ref var) => TermIterState::Var(Level::Root, cell, (*var).clone()),
TermIterState::Var(Level::Root, cell, (*var).clone()),
}; };
QueryIterator { QueryIterator {
@@ -265,18 +252,15 @@ impl<'a> Iterator for QueryIterator<'a> {
} }
TermIterState::InitialCons(lvl, cell, head, tail) => { TermIterState::InitialCons(lvl, cell, head, tail) => {
if let Some((string, tail)) = is_partial_string(head, tail) { if let Some((string, tail)) = is_partial_string(head, tail) {
self.state_stack.push(TermIterState::PartialString( self.state_stack
lvl, .push(TermIterState::PartialString(lvl, cell, string, tail));
cell,
string,
tail,
));
if let Some(tail) = tail { if let Some(tail) = tail {
self.push_subterm(lvl.child_level(), tail); self.push_subterm(lvl.child_level(), tail);
} }
} else { } else {
self.state_stack.push(TermIterState::FinalCons(lvl, cell, head, tail)); self.state_stack
.push(TermIterState::FinalCons(lvl, cell, head, tail));
self.push_subterm(lvl.child_level(), tail); self.push_subterm(lvl.child_level(), tail);
self.push_subterm(lvl.child_level(), head); self.push_subterm(lvl.child_level(), head);
@@ -309,7 +293,8 @@ pub struct FactIterator<'a> {
impl<'a> FactIterator<'a> { impl<'a> FactIterator<'a> {
fn push_subterm(&mut self, lvl: Level, term: &'a Term) { fn push_subterm(&mut self, lvl: Level, term: &'a Term) {
self.state_queue.push_back(TermIterState::subterm_to_state(lvl, term)); self.state_queue
.push_back(TermIterState::subterm_to_state(lvl, term));
} }
pub fn from_rule_head_clause(terms: &'a Vec<Box<Term>>) -> Self { pub fn from_rule_head_clause(terms: &'a Vec<Box<Term>>) -> Self {
@@ -393,8 +378,7 @@ impl<'a> Iterator for FactIterator<'a> {
TermIterState::Var(lvl, cell, var) => { TermIterState::Var(lvl, cell, var) => {
return Some(TermRef::Var(lvl, cell, var)); return Some(TermRef::Var(lvl, cell, var));
} }
_ => { _ => {}
}
} }
} }
@@ -481,16 +465,16 @@ impl<'a> ChunkedIterator<'a> {
} }
})) }))
} }
/* /*
pub fn from_term_sequence(terms: &'a [QueryTerm]) -> Self { pub fn from_term_sequence(terms: &'a [QueryTerm]) -> Self {
ChunkedIterator { ChunkedIterator {
chunk_num: 0, chunk_num: 0,
iter: Box::new(terms.iter().map(|t| ChunkedTerm::BodyTerm(t))), iter: Box::new(terms.iter().map(|t| ChunkedTerm::BodyTerm(t))),
deep_cut_encountered: false, deep_cut_encountered: false,
cut_var_in_head: false, cut_var_in_head: false,
}
} }
} */
*/
pub fn from_rule_body(p1: &'a QueryTerm, clauses: &'a Vec<QueryTerm>) -> Self { pub fn from_rule_body(p1: &'a QueryTerm, clauses: &'a Vec<QueryTerm>) -> Self {
let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1))); let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1)));
let iter = inner_iter.chain(clauses.iter().map(|t| ChunkedTerm::BodyTerm(t))); let iter = inner_iter.chain(clauses.iter().map(|t| ChunkedTerm::BodyTerm(t)));

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,43 +1,35 @@
extern crate blake2; use blake2;
extern crate chrono; use chrono;
extern crate cpu_time; use cpu_time;
extern crate crossterm; use crossterm;
extern crate divrem; use divrem;
#[macro_use] use downcast;
extern crate downcast; use git_version;
extern crate git_version; use indexmap;
extern crate hostname; use lazy_static;
extern crate indexmap; use native_tls;
#[macro_use] use nix::sys::signal;
extern crate lazy_static; use openssl;
extern crate libc; use ordered_float;
extern crate native_tls; use prolog_parser_rebis;
extern crate nix; use ref_thread_local;
extern crate openssl; use ring;
extern crate ordered_float; use ripemd160;
#[macro_use] use rustyline;
extern crate prolog_parser_rebis; use sha3;
#[macro_use] use unicode_reader;
extern crate ref_thread_local;
extern crate ring;
extern crate ripemd160;
#[cfg(feature = "rug")]
extern crate rug;
#[cfg(feature = "num-rug-adapter")]
extern crate num_rug_adapter as rug;
extern crate rustyline;
extern crate sha3;
extern crate unicode_reader;
use crate::nix::sys::signal; #[cfg(feature = "num-rug-adapter")]
use num_rug_adapter as rug;
#[cfg(feature = "rug")]
use rug;
#[macro_use] #[macro_use]
mod macros; mod macros;
mod allocator; mod allocator;
mod arithmetic; mod arithmetic;
mod machine;
mod codegen;
mod clause_types; mod clause_types;
mod codegen;
mod debray_allocator; mod debray_allocator;
mod fixtures; mod fixtures;
mod forms; mod forms;
@@ -46,17 +38,18 @@ mod heap_print;
mod indexing; mod indexing;
mod instructions; mod instructions;
mod iterators; mod iterators;
mod machine;
mod read; mod read;
mod targets; mod targets;
mod write; mod write;
use machine::*;
use machine::streams::*; use machine::streams::*;
use machine::*;
use read::*; use read::*;
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
extern fn handle_sigint(signal: libc::c_int) { extern "C" fn handle_sigint(signal: libc::c_int) {
let signal = signal::Signal::from_c_int(signal).unwrap(); let signal = signal::Signal::from_c_int(signal).unwrap();
if signal == signal::Signal::SIGINT { if signal == signal::Signal::SIGINT {
INTERRUPT.store(true, Ordering::Relaxed); INTERRUPT.store(true, Ordering::Relaxed);