add db refs
This commit is contained in:
@@ -86,7 +86,7 @@ pub enum InlinedClauseType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ref_thread_local! {
|
ref_thread_local! {
|
||||||
static managed CLAUSE_TYPE_FORMS: BTreeMap<(&'static str, usize), ClauseType> = {
|
pub static managed CLAUSE_TYPE_FORMS: BTreeMap<(&'static str, usize), ClauseType> = {
|
||||||
let mut m = BTreeMap::new();
|
let mut m = BTreeMap::new();
|
||||||
|
|
||||||
let r1 = temp_v!(1);
|
let r1 = temp_v!(1);
|
||||||
@@ -180,8 +180,9 @@ pub enum SystemClauseType {
|
|||||||
GetAttrVarQueueBeyond,
|
GetAttrVarQueueBeyond,
|
||||||
GetBValue,
|
GetBValue,
|
||||||
GetClause,
|
GetClause,
|
||||||
GetCurrentPredicateList,
|
|
||||||
GetModuleClause,
|
GetModuleClause,
|
||||||
|
GetNextDBRef,
|
||||||
|
LookupDBRef,
|
||||||
Halt,
|
Halt,
|
||||||
ModuleHeadIsDynamic,
|
ModuleHeadIsDynamic,
|
||||||
GetLiftedHeapFromOffset,
|
GetLiftedHeapFromOffset,
|
||||||
@@ -251,9 +252,10 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::GetAttrVarQueueBeyond => clause_name!("$get_attr_var_queue_beyond"),
|
&SystemClauseType::GetAttrVarQueueBeyond => clause_name!("$get_attr_var_queue_beyond"),
|
||||||
&SystemClauseType::GetLiftedHeapFromOffset => clause_name!("$get_lh_from_offset"),
|
&SystemClauseType::GetLiftedHeapFromOffset => clause_name!("$get_lh_from_offset"),
|
||||||
&SystemClauseType::GetLiftedHeapFromOffsetDiff => clause_name!("$get_lh_from_offset_diff"),
|
&SystemClauseType::GetLiftedHeapFromOffsetDiff => clause_name!("$get_lh_from_offset_diff"),
|
||||||
&SystemClauseType::GetCurrentPredicateList => clause_name!("$get_current_predicate_list"),
|
|
||||||
&SystemClauseType::GetBValue => clause_name!("$get_b_value"),
|
&SystemClauseType::GetBValue => clause_name!("$get_b_value"),
|
||||||
&SystemClauseType::GetClause => clause_name!("$get_clause"),
|
&SystemClauseType::GetClause => clause_name!("$get_clause"),
|
||||||
|
&SystemClauseType::GetNextDBRef => clause_name!("$get_next_db_ref"),
|
||||||
|
&SystemClauseType::LookupDBRef => clause_name!("$lookup_db_ref"),
|
||||||
&SystemClauseType::GetDoubleQuotes => clause_name!("$get_double_quotes"),
|
&SystemClauseType::GetDoubleQuotes => clause_name!("$get_double_quotes"),
|
||||||
&SystemClauseType::GetModuleClause => clause_name!("$get_module_clause"),
|
&SystemClauseType::GetModuleClause => clause_name!("$get_module_clause"),
|
||||||
&SystemClauseType::GetSCCCleaner => clause_name!("$get_scc_cleaner"),
|
&SystemClauseType::GetSCCCleaner => clause_name!("$get_scc_cleaner"),
|
||||||
@@ -309,6 +311,8 @@ impl SystemClauseType {
|
|||||||
("$copy_to_lh", 2) => Some(SystemClauseType::CopyToLiftedHeap),
|
("$copy_to_lh", 2) => Some(SystemClauseType::CopyToLiftedHeap),
|
||||||
("$del_attr_non_head", 1) => Some(SystemClauseType::DeleteAttribute),
|
("$del_attr_non_head", 1) => Some(SystemClauseType::DeleteAttribute),
|
||||||
("$del_attr_head", 1) => Some(SystemClauseType::DeleteHeadAttribute),
|
("$del_attr_head", 1) => Some(SystemClauseType::DeleteHeadAttribute),
|
||||||
|
("$get_next_db_ref", 2) => Some(SystemClauseType::GetNextDBRef),
|
||||||
|
("$lookup_db_ref", 3) => Some(SystemClauseType::LookupDBRef),
|
||||||
("$module_call", 2) => Some(SystemClauseType::DynamicModuleResolution),
|
("$module_call", 2) => Some(SystemClauseType::DynamicModuleResolution),
|
||||||
("$enqueue_attribute_goal", 1) => Some(SystemClauseType::EnqueueAttributeGoal),
|
("$enqueue_attribute_goal", 1) => Some(SystemClauseType::EnqueueAttributeGoal),
|
||||||
("$enqueue_attr_var", 1) => Some(SystemClauseType::EnqueueAttributedVar),
|
("$enqueue_attr_var", 1) => Some(SystemClauseType::EnqueueAttributedVar),
|
||||||
@@ -321,7 +325,6 @@ impl SystemClauseType {
|
|||||||
("$get_b_value", 1) => Some(SystemClauseType::GetBValue),
|
("$get_b_value", 1) => Some(SystemClauseType::GetBValue),
|
||||||
("$get_clause", 2) => Some(SystemClauseType::GetClause),
|
("$get_clause", 2) => Some(SystemClauseType::GetClause),
|
||||||
("$get_module_clause", 3) => Some(SystemClauseType::GetModuleClause),
|
("$get_module_clause", 3) => Some(SystemClauseType::GetModuleClause),
|
||||||
("$get_current_predicate_list", 1) => Some(SystemClauseType::GetCurrentPredicateList),
|
|
||||||
("$get_lh_from_offset", 2) => Some(SystemClauseType::GetLiftedHeapFromOffset),
|
("$get_lh_from_offset", 2) => Some(SystemClauseType::GetLiftedHeapFromOffset),
|
||||||
("$get_lh_from_offset_diff", 3) => Some(SystemClauseType::GetLiftedHeapFromOffsetDiff),
|
("$get_lh_from_offset_diff", 3) => Some(SystemClauseType::GetLiftedHeapFromOffsetDiff),
|
||||||
("$get_double_quotes", 1) => Some(SystemClauseType::GetDoubleQuotes),
|
("$get_double_quotes", 1) => Some(SystemClauseType::GetDoubleQuotes),
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ impl<'a> HCPreOrderIterator<'a> {
|
|||||||
{
|
{
|
||||||
let da = self.machine_st.store(self.machine_st.deref(addr));
|
let da = self.machine_st.store(self.machine_st.deref(addr));
|
||||||
|
|
||||||
match da {
|
match da {
|
||||||
Addr::Con(Constant::String(ref s))
|
Addr::Con(Constant::String(ref s))
|
||||||
if self.machine_st.machine_flags().double_quotes.is_chars() => {
|
if self.machine_st.machine_flags().double_quotes.is_chars() => {
|
||||||
if let Some(c) = s.head() {
|
if let Some(c) = s.head() {
|
||||||
@@ -59,7 +59,7 @@ impl<'a> HCPreOrderIterator<'a> {
|
|||||||
|
|
||||||
Addr::Con(Constant::String(s.clone()))
|
Addr::Con(Constant::String(s.clone()))
|
||||||
},
|
},
|
||||||
Addr::Con(_) => da,
|
Addr::Con(_) | Addr::DBRef(_) => da,
|
||||||
Addr::Lis(a) => {
|
Addr::Lis(a) => {
|
||||||
self.state_stack.push(Addr::HeapCell(a + 1));
|
self.state_stack.push(Addr::HeapCell(a + 1));
|
||||||
self.state_stack.push(Addr::HeapCell(a));
|
self.state_stack.push(Addr::HeapCell(a));
|
||||||
|
|||||||
@@ -682,58 +682,20 @@ abolish(Pred) :-
|
|||||||
; throw(error(type_error(predicate_indicator, Pred), abolish/1))
|
; throw(error(type_error(predicate_indicator, Pred), abolish/1))
|
||||||
).
|
).
|
||||||
|
|
||||||
match_builtins(acyclic_term, 1).
|
'$iterate_db_refs'(Ref, Name/Arity) :-
|
||||||
match_builtins(arg, 3).
|
'$lookup_db_ref'(Ref, Name, Arity).
|
||||||
match_builtins(compare, 3).
|
'$iterate_db_refs'(Ref, Name/Arity) :-
|
||||||
match_builtins(cyclic_term, 1).
|
'$get_next_db_ref'(Ref, NextRef),
|
||||||
match_builtins(@>, 2).
|
'$iterate_db_refs'(NextRef, Name/Arity).
|
||||||
match_builtins(@<, 2).
|
|
||||||
match_builtins(@>=, 2).
|
|
||||||
match_builtins(@=<, 2).
|
|
||||||
match_builtins(\=@=, 2).
|
|
||||||
match_builtins(=@=, 2).
|
|
||||||
match_builtins(copy_term, 2).
|
|
||||||
match_builtins(==, 2).
|
|
||||||
match_builtins(functor, 3).
|
|
||||||
match_builtins(ground, 1).
|
|
||||||
match_builtins(is, 2).
|
|
||||||
match_builtins(keysort, 2).
|
|
||||||
match_builtins(nl, 0).
|
|
||||||
match_builtins(\==, 2).
|
|
||||||
match_builtins(is_partial_string, 1).
|
|
||||||
match_builtins(partial_string, 2).
|
|
||||||
match_builtins(read, 1).
|
|
||||||
match_builtins(sort, 2).
|
|
||||||
match_builtins(>, 2).
|
|
||||||
match_builtins(<, 2).
|
|
||||||
match_builtins(>=, 2).
|
|
||||||
match_builtins(=<, 2).
|
|
||||||
match_builtins(=\=, 2).
|
|
||||||
match_builtins(=:=, 2).
|
|
||||||
match_builtins(atom, 1).
|
|
||||||
match_builtins(atomic, 1).
|
|
||||||
match_builtins(compound, 1).
|
|
||||||
match_builtins(integer, 1).
|
|
||||||
match_builtins(rational, 1).
|
|
||||||
match_builtins(string, 1).
|
|
||||||
match_builtins(float, 1).
|
|
||||||
match_builtins(nonvar, 1).
|
|
||||||
match_builtins(var, 1).
|
|
||||||
match_builtins(call, N) :-
|
|
||||||
max_arity(Max),
|
|
||||||
between:between(0, Max, N).
|
|
||||||
|
|
||||||
'$iterate_predicate_list'([Name/Arity|Preds], Name/Arity).
|
|
||||||
'$iterate_predicate_list'([_|Preds], Pred) :-
|
|
||||||
'$iterate_predicate_list'(Preds, Pred).
|
|
||||||
'$iterate_predicate_list'([], Name/Arity) :-
|
|
||||||
match_builtins(Name, Arity).
|
|
||||||
|
|
||||||
current_predicate(Pred) :-
|
current_predicate(Pred) :-
|
||||||
( nonvar(Pred), Pred \= _ / _
|
( nonvar(Pred), Pred \= _ / _
|
||||||
-> throw(error(type_error(predicate_indicator,Pred), current_predicate/1))
|
-> throw(error(type_error(predicate_indicator, Pred), current_predicate/1))
|
||||||
; '$get_current_predicate_list'(Ls),
|
; '$get_next_db_ref'(Ref, _),
|
||||||
'$iterate_predicate_list'(Ls, Pred)
|
'$iterate_db_refs'(Ref, Pred)
|
||||||
|
; Pred = call/N,
|
||||||
|
max_arity(Max),
|
||||||
|
between:between(0, Max, N)
|
||||||
).
|
).
|
||||||
|
|
||||||
bb_put(Key, Value) :- atom(Key), !, '$store_global_var'(Key, Value).
|
bb_put(Key, Value) :- atom(Key), !, '$store_global_var'(Key, Value).
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
self.copy_var(addr),
|
self.copy_var(addr),
|
||||||
Addr::Str(addr) =>
|
Addr::Str(addr) =>
|
||||||
self.copy_structure(addr),
|
self.copy_structure(addr),
|
||||||
Addr::Con(_) =>
|
Addr::Con(_) | Addr::DBRef(_) =>
|
||||||
self.scan += 1
|
self.scan += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,15 +7,22 @@ use prolog::forms::*;
|
|||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::{BTreeMap, HashMap, VecDeque};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::{Add, AddAssign, Sub, SubAssign};
|
use std::ops::{Add, AddAssign, Sub, SubAssign};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum DBRef {
|
||||||
|
BuiltInPred(ClauseName, usize),
|
||||||
|
NamedPred(ClauseName, usize)
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum Addr {
|
pub enum Addr {
|
||||||
AttrVar(usize),
|
AttrVar(usize),
|
||||||
Con(Constant),
|
Con(Constant),
|
||||||
|
DBRef(DBRef),
|
||||||
Lis(usize),
|
Lis(usize),
|
||||||
HeapCell(usize),
|
HeapCell(usize),
|
||||||
StackCell(usize, usize),
|
StackCell(usize, usize),
|
||||||
@@ -502,7 +509,7 @@ impl IndexStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type CodeDir = HashMap<PredicateKey, CodeIndex>;
|
pub type CodeDir = BTreeMap<PredicateKey, CodeIndex>;
|
||||||
pub type TermDir = HashMap<PredicateKey, (Predicate, VecDeque<TopLevel>)>;
|
pub type TermDir = HashMap<PredicateKey, (Predicate, VecDeque<TopLevel>)>;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
|
#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
|
||||||
|
|||||||
@@ -628,7 +628,7 @@ impl MachineState {
|
|||||||
"+" => interms.push(a1 + a2),
|
"+" => interms.push(a1 + a2),
|
||||||
"-" => interms.push(a1 - a2),
|
"-" => interms.push(a1 - a2),
|
||||||
"*" => interms.push(a1 * a2),
|
"*" => interms.push(a1 * a2),
|
||||||
"/" => interms.push(self.div(a1, a2)?),
|
"/" => interms.push(self.div(a1, a2)?),
|
||||||
"**" => interms.push(self.pow(a1, a2)?),
|
"**" => interms.push(self.pow(a1, a2)?),
|
||||||
"max" => interms.push(self.max(a1, a2)?),
|
"max" => interms.push(self.max(a1, a2)?),
|
||||||
"rdiv" => {
|
"rdiv" => {
|
||||||
@@ -850,10 +850,10 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn max(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
fn max(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> {
|
||||||
Ok(max(n1, n2))
|
Ok(max(n1, n2))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remainder(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, MachineStub>
|
fn remainder(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, MachineStub>
|
||||||
{
|
{
|
||||||
let stub = MachineError::functor_stub(clause_name!("(rem)"), 2);
|
let stub = MachineError::functor_stub(clause_name!("(rem)"), 2);
|
||||||
@@ -923,7 +923,7 @@ impl MachineState {
|
|||||||
let n2 = try_or_fail!(self, self.get_number(a2));
|
let n2 = try_or_fail!(self, self.get_number(a2));
|
||||||
|
|
||||||
self.interms[t - 1] = try_or_fail!(self, self.max(n1, n2));
|
self.interms[t - 1] = try_or_fail!(self, self.max(n1, n2));
|
||||||
self.p += 1;
|
self.p += 1;
|
||||||
},
|
},
|
||||||
&ArithmeticInstruction::Pow(ref a1, ref a2, t) => {
|
&ArithmeticInstruction::Pow(ref a1, ref a2, t) => {
|
||||||
let n1 = try_or_fail!(self, self.get_number(a1));
|
let n1 = try_or_fail!(self, self.get_number(a1));
|
||||||
@@ -1208,6 +1208,10 @@ impl MachineState {
|
|||||||
Addr::Con(_) => c,
|
Addr::Con(_) => c,
|
||||||
Addr::Lis(_) => l,
|
Addr::Lis(_) => l,
|
||||||
Addr::Str(_) => s,
|
Addr::Str(_) => s,
|
||||||
|
Addr::DBRef(_) => {
|
||||||
|
self.fail = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match offset {
|
match offset {
|
||||||
@@ -1885,6 +1889,8 @@ impl MachineState {
|
|||||||
let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
|
let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||||
|
|
||||||
match a1.clone() {
|
match a1.clone() {
|
||||||
|
Addr::DBRef(_) =>
|
||||||
|
self.fail = true,
|
||||||
Addr::Con(_) =>
|
Addr::Con(_) =>
|
||||||
self.try_functor_unify_components(a1, Addr::Con(integer!(0))),
|
self.try_functor_unify_components(a1, Addr::Con(integer!(0))),
|
||||||
Addr::Str(o) =>
|
Addr::Str(o) =>
|
||||||
@@ -2223,7 +2229,7 @@ impl MachineState {
|
|||||||
try_or_fail!(self, call_policy.compile_hook(self, hook)),
|
try_or_fail!(self, call_policy.compile_hook(self, hook)),
|
||||||
&ClauseType::Inlined(ref ct) => {
|
&ClauseType::Inlined(ref ct) => {
|
||||||
self.execute_inlined(ct);
|
self.execute_inlined(ct);
|
||||||
|
|
||||||
if lco {
|
if lco {
|
||||||
self.p = CodePtr::Local(self.cp);
|
self.p = CodePtr::Local(self.cp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,11 @@ use prolog::machine::copier::*;
|
|||||||
use prolog::machine::machine_errors::*;
|
use prolog::machine::machine_errors::*;
|
||||||
use prolog::machine::machine_indices::*;
|
use prolog::machine::machine_indices::*;
|
||||||
use prolog::machine::machine_state::*;
|
use prolog::machine::machine_state::*;
|
||||||
use prolog::num::{ToPrimitive, Zero};
|
use prolog::num::{FromPrimitive, ToPrimitive, Zero};
|
||||||
use prolog::num::bigint::{BigInt};
|
use prolog::num::bigint::{BigInt};
|
||||||
|
|
||||||
|
use ref_thread_local::RefThreadLocal;
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::io::{stdout, Write};
|
use std::io::{stdout, Write};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
@@ -213,6 +215,57 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_next_db_ref(&mut self, db_ref: &DBRef, code_dir: &CodeDir) {
|
||||||
|
match db_ref {
|
||||||
|
&DBRef::BuiltInPred(ref name, arity) => {
|
||||||
|
let key = (name.as_str(), arity);
|
||||||
|
|
||||||
|
match CLAUSE_TYPE_FORMS.borrow().range(&key ..).skip(1).next() {
|
||||||
|
Some(((_, arity), ct)) => {
|
||||||
|
let a2 = self[temp_v!(2)].clone();
|
||||||
|
|
||||||
|
if let Some(r) = a2.as_var() {
|
||||||
|
self.bind(r, Addr::DBRef(DBRef::BuiltInPred(ct.name(), *arity)));
|
||||||
|
} else {
|
||||||
|
self.fail = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None =>
|
||||||
|
match code_dir.iter().next() {
|
||||||
|
Some(((ref name, arity), _)) => {
|
||||||
|
let a2 = self[temp_v!(2)].clone();
|
||||||
|
|
||||||
|
if let Some(r) = a2.as_var() {
|
||||||
|
self.bind(r, Addr::DBRef(DBRef::NamedPred(name.clone(), *arity)));
|
||||||
|
} else {
|
||||||
|
self.fail = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
self.fail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
&DBRef::NamedPred(ref name, arity) => {
|
||||||
|
let key = (name.clone(), arity);
|
||||||
|
|
||||||
|
match code_dir.range(key ..).skip(1).next() {
|
||||||
|
Some(((name, arity), _)) => {
|
||||||
|
let a2 = self[temp_v!(2)].clone();
|
||||||
|
|
||||||
|
if let Some(r) = a2.as_var() {
|
||||||
|
self.bind(r, Addr::DBRef(DBRef::NamedPred(name.clone(), *arity)));
|
||||||
|
} else {
|
||||||
|
self.fail = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => self.fail = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn system_call(&mut self,
|
pub(super) fn system_call(&mut self,
|
||||||
ct: &SystemClauseType,
|
ct: &SystemClauseType,
|
||||||
indices: &mut IndexStore,
|
indices: &mut IndexStore,
|
||||||
@@ -462,27 +515,53 @@ impl MachineState {
|
|||||||
self.p = CodePtr::Local(LocalCodePtr::UserTermExpansion(0));
|
self.p = CodePtr::Local(LocalCodePtr::UserTermExpansion(0));
|
||||||
return Ok(());
|
return Ok(());
|
||||||
},
|
},
|
||||||
&SystemClauseType::GetCurrentPredicateList => {
|
&SystemClauseType::GetNextDBRef => {
|
||||||
let mut addrs = vec![];
|
let a1 = self[temp_v!(1)].clone();
|
||||||
|
|
||||||
for ((name, arity), idx) in indices.code_dir.iter() {
|
match self.store(self.deref(a1)) {
|
||||||
if idx.is_undefined() {
|
addr @ Addr::HeapCell(_)
|
||||||
continue;
|
| addr @ Addr::StackCell(..)
|
||||||
|
| addr @ Addr::AttrVar(_) =>
|
||||||
|
match CLAUSE_TYPE_FORMS.borrow().iter().next() {
|
||||||
|
Some(((_, arity), ct)) => {
|
||||||
|
let db_ref = DBRef::BuiltInPred(ct.name(), *arity);
|
||||||
|
let r = addr.as_var().unwrap();
|
||||||
|
|
||||||
|
self.bind(r, Addr::DBRef(db_ref));
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
self.fail = true;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Addr::DBRef(ref db_ref) =>
|
||||||
|
self.get_next_db_ref(db_ref, &indices.code_dir),
|
||||||
|
_ => {
|
||||||
|
self.fail = true;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
&SystemClauseType::LookupDBRef => {
|
||||||
|
let a1 = self[temp_v!(1)].clone();
|
||||||
|
|
||||||
let h = self.heap.h;
|
match self.store(self.deref(a1)) {
|
||||||
|
Addr::DBRef(db_ref) =>
|
||||||
|
match db_ref {
|
||||||
|
DBRef::BuiltInPred(name, arity) | DBRef::NamedPred(name, arity) => {
|
||||||
|
let a2 = self[temp_v!(2)].clone();
|
||||||
|
let a3 = self[temp_v!(3)].clone();
|
||||||
|
|
||||||
self.heap.push(HeapCellValue::NamedStr(2, clause_name!("/"), Some((400, YFX))));
|
let arity = Number::Integer(Rc::new(BigInt::from_usize(arity).unwrap()));
|
||||||
self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::Atom(name.clone(), None))));
|
|
||||||
self.heap.push(heap_integer!(*arity));
|
|
||||||
|
|
||||||
addrs.push(Addr::Str(h));
|
self.unify(a2, Addr::Con(Constant::Atom(name, None)));
|
||||||
|
|
||||||
|
if !self.fail {
|
||||||
|
self.unify(a3, Addr::Con(Constant::Number(arity)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => self.fail = true
|
||||||
}
|
}
|
||||||
|
|
||||||
let list_addr = Addr::HeapCell(self.heap.to_list(addrs.into_iter()));
|
|
||||||
let target_addr = self[temp_v!(1)].clone();
|
|
||||||
|
|
||||||
self.unify(list_addr, target_addr);
|
|
||||||
},
|
},
|
||||||
&SystemClauseType::TruncateIfNoLiftedHeapGrowthDiff =>
|
&SystemClauseType::TruncateIfNoLiftedHeapGrowthDiff =>
|
||||||
self.truncate_if_no_lifted_heap_diff(|h| Addr::HeapCell(h)),
|
self.truncate_if_no_lifted_heap_diff(|h| Addr::HeapCell(h)),
|
||||||
|
|||||||
@@ -159,10 +159,20 @@ impl fmt::Display for HeapCellValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for DBRef {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
&DBRef::BuiltInPred(ref name, arity) => write!(f, "db_ref:builtin:{}/{}", name, arity),
|
||||||
|
&DBRef::NamedPred(ref name, arity) => write!(f, "db_ref:named:{}/{}", name, arity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for Addr {
|
impl fmt::Display for Addr {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
&Addr::Con(ref c) => write!(f, "Addr::Con({})", c),
|
&Addr::Con(ref c) => write!(f, "Addr::Con({})", c),
|
||||||
|
&Addr::DBRef(ref db_ref) => write!(f, "Addr::DBRef({})", db_ref),
|
||||||
&Addr::Lis(l) => write!(f, "Addr::Lis({})", l),
|
&Addr::Lis(l) => write!(f, "Addr::Lis({})", l),
|
||||||
&Addr::AttrVar(h) => write!(f, "Addr::AttrVar({})", h),
|
&Addr::AttrVar(h) => write!(f, "Addr::AttrVar({})", h),
|
||||||
&Addr::HeapCell(h) => write!(f, "Addr::HeapCell({})", h),
|
&Addr::HeapCell(h) => write!(f, "Addr::HeapCell({})", h),
|
||||||
|
|||||||
Reference in New Issue
Block a user