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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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