fix current_predicate/1 (#1761)
This commit is contained in:
@@ -306,10 +306,10 @@ enum SystemClauseType {
|
|||||||
GetBValue,
|
GetBValue,
|
||||||
#[strum_discriminants(strum(props(Arity = "3", Name = "$get_cont_chunk")))]
|
#[strum_discriminants(strum(props(Arity = "3", Name = "$get_cont_chunk")))]
|
||||||
GetContinuationChunk,
|
GetContinuationChunk,
|
||||||
#[strum_discriminants(strum(props(Arity = "4", Name = "$get_next_db_ref")))]
|
|
||||||
GetNextDBRef,
|
|
||||||
#[strum_discriminants(strum(props(Arity = "7", Name = "$get_next_op_db_ref")))]
|
#[strum_discriminants(strum(props(Arity = "7", Name = "$get_next_op_db_ref")))]
|
||||||
GetNextOpDBRef,
|
GetNextOpDBRef,
|
||||||
|
#[strum_discriminants(strum(props(Arity = "2", Name = "$lookup_db_ref")))]
|
||||||
|
LookupDBRef,
|
||||||
#[strum_discriminants(strum(props(Arity = "1", Name = "$is_partial_string")))]
|
#[strum_discriminants(strum(props(Arity = "1", Name = "$is_partial_string")))]
|
||||||
IsPartialString,
|
IsPartialString,
|
||||||
#[strum_discriminants(strum(props(Arity = "1", Name = "$halt")))]
|
#[strum_discriminants(strum(props(Arity = "1", Name = "$halt")))]
|
||||||
@@ -578,6 +578,8 @@ enum SystemClauseType {
|
|||||||
DeleteAllAttributesFromVar,
|
DeleteAllAttributesFromVar,
|
||||||
#[strum_discriminants(strum(props(Arity = "1", Name = "$unattributed_var")))]
|
#[strum_discriminants(strum(props(Arity = "1", Name = "$unattributed_var")))]
|
||||||
UnattributedVar,
|
UnattributedVar,
|
||||||
|
#[strum_discriminants(strum(props(Arity = "3", Name = "$get_db_refs")))]
|
||||||
|
GetDBRefs,
|
||||||
REPL(REPLCodePtr),
|
REPL(REPLCodePtr),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1641,6 +1643,7 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
&Instruction::CallDeleteFromAttributedVarList(_) |
|
&Instruction::CallDeleteFromAttributedVarList(_) |
|
||||||
&Instruction::CallDeleteAllAttributesFromVar(_) |
|
&Instruction::CallDeleteAllAttributesFromVar(_) |
|
||||||
&Instruction::CallUnattributedVar(_) |
|
&Instruction::CallUnattributedVar(_) |
|
||||||
|
&Instruction::CallGetDBRefs(_) |
|
||||||
&Instruction::CallFetchGlobalVar(_) |
|
&Instruction::CallFetchGlobalVar(_) |
|
||||||
&Instruction::CallFirstStream(_) |
|
&Instruction::CallFirstStream(_) |
|
||||||
&Instruction::CallFlushOutput(_) |
|
&Instruction::CallFlushOutput(_) |
|
||||||
@@ -1656,8 +1659,8 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
&Instruction::CallGetAttrVarQueueBeyond(_) |
|
&Instruction::CallGetAttrVarQueueBeyond(_) |
|
||||||
&Instruction::CallGetBValue(_) |
|
&Instruction::CallGetBValue(_) |
|
||||||
&Instruction::CallGetContinuationChunk(_) |
|
&Instruction::CallGetContinuationChunk(_) |
|
||||||
&Instruction::CallGetNextDBRef(_) |
|
|
||||||
&Instruction::CallGetNextOpDBRef(_) |
|
&Instruction::CallGetNextOpDBRef(_) |
|
||||||
|
&Instruction::CallLookupDBRef(_) |
|
||||||
&Instruction::CallIsPartialString(_) |
|
&Instruction::CallIsPartialString(_) |
|
||||||
&Instruction::CallHalt(_) |
|
&Instruction::CallHalt(_) |
|
||||||
&Instruction::CallGetLiftedHeapFromOffset(_) |
|
&Instruction::CallGetLiftedHeapFromOffset(_) |
|
||||||
@@ -1862,6 +1865,7 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
&Instruction::ExecuteDeleteFromAttributedVarList(_) |
|
&Instruction::ExecuteDeleteFromAttributedVarList(_) |
|
||||||
&Instruction::ExecuteDeleteAllAttributesFromVar(_) |
|
&Instruction::ExecuteDeleteAllAttributesFromVar(_) |
|
||||||
&Instruction::ExecuteUnattributedVar(_) |
|
&Instruction::ExecuteUnattributedVar(_) |
|
||||||
|
&Instruction::ExecuteGetDBRefs(_) |
|
||||||
&Instruction::ExecuteFetchGlobalVar(_) |
|
&Instruction::ExecuteFetchGlobalVar(_) |
|
||||||
&Instruction::ExecuteFirstStream(_) |
|
&Instruction::ExecuteFirstStream(_) |
|
||||||
&Instruction::ExecuteFlushOutput(_) |
|
&Instruction::ExecuteFlushOutput(_) |
|
||||||
@@ -1877,8 +1881,8 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
&Instruction::ExecuteGetAttrVarQueueBeyond(_) |
|
&Instruction::ExecuteGetAttrVarQueueBeyond(_) |
|
||||||
&Instruction::ExecuteGetBValue(_) |
|
&Instruction::ExecuteGetBValue(_) |
|
||||||
&Instruction::ExecuteGetContinuationChunk(_) |
|
&Instruction::ExecuteGetContinuationChunk(_) |
|
||||||
&Instruction::ExecuteGetNextDBRef(_) |
|
|
||||||
&Instruction::ExecuteGetNextOpDBRef(_) |
|
&Instruction::ExecuteGetNextOpDBRef(_) |
|
||||||
|
&Instruction::ExecuteLookupDBRef(_) |
|
||||||
&Instruction::ExecuteIsPartialString(_) |
|
&Instruction::ExecuteIsPartialString(_) |
|
||||||
&Instruction::ExecuteHalt(_) |
|
&Instruction::ExecuteHalt(_) |
|
||||||
&Instruction::ExecuteGetLiftedHeapFromOffset(_) |
|
&Instruction::ExecuteGetLiftedHeapFromOffset(_) |
|
||||||
|
|||||||
@@ -1205,7 +1205,6 @@ module_abolish(Pred, Module) :-
|
|||||||
; throw(error(type_error(predicate_indicator, Module:Pred), abolish/1))
|
; throw(error(type_error(predicate_indicator, Module:Pred), abolish/1))
|
||||||
).
|
).
|
||||||
|
|
||||||
|
|
||||||
:- meta_predicate abolish(:).
|
:- meta_predicate abolish(:).
|
||||||
|
|
||||||
%% abolish(Pred).
|
%% abolish(Pred).
|
||||||
@@ -1246,13 +1245,6 @@ abolish(Pred) :-
|
|||||||
; throw(error(type_error(predicate_indicator, Pred), abolish/1))
|
; throw(error(type_error(predicate_indicator, Pred), abolish/1))
|
||||||
).
|
).
|
||||||
|
|
||||||
|
|
||||||
'$iterate_db_refs'(Name, Arity, Name/Arity). % :-
|
|
||||||
% '$lookup_db_ref'(Ref, Name, Arity).
|
|
||||||
'$iterate_db_refs'(RName, RArity, Name/Arity) :-
|
|
||||||
'$get_next_db_ref'(RName, RArity, RRName, RRArity),
|
|
||||||
'$iterate_db_refs'(RRName, RRArity, Name/Arity).
|
|
||||||
|
|
||||||
%% current_predicate(Pred).
|
%% current_predicate(Pred).
|
||||||
%
|
%
|
||||||
% Pred must satisfy: `Pred = Name/Arity`.
|
% Pred must satisfy: `Pred = Name/Arity`.
|
||||||
@@ -1260,27 +1252,28 @@ abolish(Pred) :-
|
|||||||
% It can be used to check for existence of a predicate or to enumerate all loaded predicates
|
% It can be used to check for existence of a predicate or to enumerate all loaded predicates
|
||||||
current_predicate(Pred) :-
|
current_predicate(Pred) :-
|
||||||
( var(Pred) ->
|
( var(Pred) ->
|
||||||
'$get_next_db_ref'(RN, RA, _, _),
|
'$get_db_refs'(_, _, PIs),
|
||||||
'$iterate_db_refs'(RN, RA, Pred)
|
lists:member(Pred, PIs)
|
||||||
; Pred \= _/_ ->
|
; Pred = Name/Arity ->
|
||||||
throw(error(type_error(predicate_indicator, Pred), current_predicate/1))
|
( ( nonvar(Name), \+ atom(Name)
|
||||||
; Pred = Name/Arity,
|
; nonvar(Arity), \+ integer(Arity)
|
||||||
( nonvar(Name), \+ atom(Name)
|
; integer(Arity), Arity < 0
|
||||||
; nonvar(Arity), \+ integer(Arity)
|
) ->
|
||||||
; integer(Arity), Arity < 0
|
throw(error(type_error(predicate_indicator, Pred), current_predicate/1))
|
||||||
) ->
|
; nonvar(Name),
|
||||||
throw(error(type_error(predicate_indicator, Pred), current_predicate/1))
|
nonvar(Arity) ->
|
||||||
; '$get_next_db_ref'(RN, RA, _, _),
|
'$lookup_db_ref'(Name, Arity)
|
||||||
'$iterate_db_refs'(RN, RA, Pred)
|
; '$get_db_refs'(Name, Arity, PIs),
|
||||||
|
lists:member(Pred, PIs)
|
||||||
|
)
|
||||||
|
; throw(error(type_error(predicate_indicator, Pred), current_predicate/1))
|
||||||
).
|
).
|
||||||
|
|
||||||
|
|
||||||
'$iterate_op_db_refs'(RPriority, RSpec, ROp, _, RPriority, RSpec, ROp).
|
'$iterate_op_db_refs'(RPriority, RSpec, ROp, _, RPriority, RSpec, ROp).
|
||||||
'$iterate_op_db_refs'(RPriority, RSpec, ROp, OssifiedOpDir, Priority, Spec, Op) :-
|
'$iterate_op_db_refs'(RPriority, RSpec, ROp, OssifiedOpDir, Priority, Spec, Op) :-
|
||||||
'$get_next_op_db_ref'(RPriority, RSpec, ROp, OssifiedOpDir, RRPriority, RRSpec, RROp),
|
'$get_next_op_db_ref'(RPriority, RSpec, ROp, OssifiedOpDir, RRPriority, RRSpec, RROp),
|
||||||
'$iterate_op_db_refs'(RRPriority, RRSpec, RROp, OssifiedOpDir, Priority, Spec, Op).
|
'$iterate_op_db_refs'(RRPriority, RRSpec, RROp, OssifiedOpDir, Priority, Spec, Op).
|
||||||
|
|
||||||
|
|
||||||
can_be_op_priority(Priority) :- var(Priority).
|
can_be_op_priority(Priority) :- var(Priority).
|
||||||
can_be_op_priority(Priority) :- op_priority(Priority).
|
can_be_op_priority(Priority) :- op_priority(Priority).
|
||||||
|
|
||||||
|
|||||||
@@ -3720,12 +3720,12 @@ impl Machine {
|
|||||||
self.get_continuation_chunk();
|
self.get_continuation_chunk();
|
||||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
}
|
}
|
||||||
&Instruction::CallGetNextDBRef(_) => {
|
&Instruction::CallLookupDBRef(_) => {
|
||||||
self.get_next_db_ref();
|
self.lookup_db_ref();
|
||||||
step_or_fail!(self, self.machine_st.p += 1);
|
step_or_fail!(self, self.machine_st.p += 1);
|
||||||
}
|
}
|
||||||
&Instruction::ExecuteGetNextDBRef(_) => {
|
&Instruction::ExecuteLookupDBRef(_) => {
|
||||||
self.get_next_db_ref();
|
self.lookup_db_ref();
|
||||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
}
|
}
|
||||||
&Instruction::CallGetNextOpDBRef(_) => {
|
&Instruction::CallGetNextOpDBRef(_) => {
|
||||||
@@ -5255,6 +5255,14 @@ impl Machine {
|
|||||||
self.machine_st.unattributed_var();
|
self.machine_st.unattributed_var();
|
||||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
}
|
}
|
||||||
|
&Instruction::CallGetDBRefs(_) => {
|
||||||
|
self.get_db_refs();
|
||||||
|
step_or_fail!(self, self.machine_st.p += 1);
|
||||||
|
}
|
||||||
|
&Instruction::ExecuteGetDBRefs(_) => {
|
||||||
|
self.get_db_refs();
|
||||||
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3660,44 +3660,74 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn get_next_db_ref(&mut self) {
|
pub(crate) fn lookup_db_ref(&mut self) {
|
||||||
let a1 = self.deref_register(1);
|
let name = cell_as_atom!(self.deref_register(1));
|
||||||
|
let arity = cell_as_fixnum!(self.deref_register(2)).get_num() as usize;
|
||||||
|
|
||||||
if let Some(name_var) = a1.as_var() {
|
if self.indices.code_dir.get(&(name, arity)).is_none() {
|
||||||
let mut iter = self.indices.code_dir.iter();
|
self.machine_st.fail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while let Some(((name, arity), _)) = iter.next() {
|
#[inline(always)]
|
||||||
let arity_var = self.machine_st.deref(self.machine_st.registers[2])
|
pub(crate) fn get_db_refs(&mut self) {
|
||||||
.as_var().unwrap();
|
let name_match: fn(Atom, Atom) -> bool;
|
||||||
|
let arity_match: fn(usize, usize) -> bool;
|
||||||
|
|
||||||
self.machine_st.bind(name_var, atom_as_cell!(name));
|
let atom = self.deref_register(1);
|
||||||
self.machine_st.bind(arity_var, fixnum_as_cell!(Fixnum::build_with(*arity as i64)));
|
|
||||||
|
|
||||||
|
let pred_atom = if atom.is_var() {
|
||||||
|
name_match = |_, _| true;
|
||||||
|
atom!("")
|
||||||
|
} else {
|
||||||
|
name_match = |atom_1, atom_2| atom_1 == atom_2;
|
||||||
|
cell_as_atom!(atom)
|
||||||
|
};
|
||||||
|
|
||||||
|
let arity = self.deref_register(2);
|
||||||
|
|
||||||
|
let pred_arity = if arity.is_var() {
|
||||||
|
arity_match = |_, _| true;
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
arity_match = |arity_1, arity_2| arity_1 == arity_2;
|
||||||
|
|
||||||
|
let arity = match Number::try_from(arity) {
|
||||||
|
Ok(Number::Fixnum(n)) => Some(n.get_num() as usize),
|
||||||
|
Ok(Number::Integer(n)) => n.to_usize(),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(arity) = arity {
|
||||||
|
arity
|
||||||
|
} else {
|
||||||
|
self.machine_st.fail = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
self.machine_st.fail = true;
|
let h = self.machine_st.heap.len();
|
||||||
} else if a1.get_tag() == HeapCellValueTag::Atom {
|
let mut num_functors = 0;
|
||||||
let name = cell_as_atom!(a1);
|
|
||||||
let arity = cell_as_fixnum!(self.deref_register(2)).get_num() as usize;
|
|
||||||
|
|
||||||
match self.machine_st.get_next_db_ref(&self.indices, &DBRef::NamedPred(name, arity)) {
|
for (name, arity) in self.indices.code_dir.keys() {
|
||||||
Some(DBRef::NamedPred(name, arity)) => {
|
if name_match(pred_atom, *name) && arity_match(pred_arity, *arity) {
|
||||||
let atom_var = self.machine_st.deref(self.machine_st.registers[3])
|
self.machine_st.heap.extend(
|
||||||
.as_var().unwrap();
|
functor!(atom!("/"), [cell(atom_as_cell!(name)), fixnum(*arity)]),
|
||||||
|
);
|
||||||
|
|
||||||
let arity_var = self.machine_st.deref(self.machine_st.registers[4])
|
num_functors += 1;
|
||||||
.as_var().unwrap();
|
|
||||||
|
|
||||||
self.machine_st.bind(atom_var, atom_as_cell!(name));
|
|
||||||
self.machine_st.bind(arity_var, fixnum_as_cell!(Fixnum::build_with(arity as i64)));
|
|
||||||
}
|
|
||||||
Some(DBRef::Op(..)) | None => {
|
|
||||||
self.machine_st.fail = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if num_functors > 0 {
|
||||||
|
let h = iter_to_heap_list(
|
||||||
|
&mut self.machine_st.heap,
|
||||||
|
(0 .. num_functors).map(|i| str_loc_as_cell!(h + 3 * i)),
|
||||||
|
);
|
||||||
|
|
||||||
|
unify!(self.machine_st, heap_loc_as_cell!(h), self.machine_st.registers[3]);
|
||||||
} else {
|
} else {
|
||||||
self.machine_st.fail = true;
|
unify!(self.machine_st, empty_list_as_cell!(), self.machine_st.registers[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user