DeleteFromAttributedVarList,
#[strum_discriminants(strum(props(Arity = "1", Name = "$delete_all_attributes_from_var")))]
DeleteAllAttributesFromVar,
+ #[strum_discriminants(strum(props(Arity = "2", Name = "$term_attributed_variables_without_attrs")))]
+ TermAttributedVariablesWithoutAttrs,
REPL(REPLCodePtr),
}
&Instruction::CallPutToAttributedVarList(_) |
&Instruction::CallDeleteFromAttributedVarList(_) |
&Instruction::CallDeleteAllAttributesFromVar(_) |
+ &Instruction::CallTermAttributedVariablesWithoutAttrs(_) |
&Instruction::CallFetchGlobalVar(_) |
&Instruction::CallFirstStream(_) |
&Instruction::CallFlushOutput(_) |
&Instruction::ExecutePutToAttributedVarList(_) |
&Instruction::ExecuteDeleteFromAttributedVarList(_) |
&Instruction::ExecuteDeleteAllAttributesFromVar(_) |
+ &Instruction::ExecuteTermAttributedVariablesWithoutAttrs(_) |
&Instruction::ExecuteFetchGlobalVar(_) |
&Instruction::ExecuteFirstStream(_) |
&Instruction::ExecuteFlushOutput(_) |
call_residue_vars(Goal, Vars) :-
'$get_attr_var_queue_delim'(B),
call(Goal),
- '$get_attr_var_queue_beyond'(B, Vars).
+ '$get_attr_var_queue_beyond'(B, AttrVars),
+ '$project_atts':copy_term(AttrVars, AttrVars, Gs),
+ '$term_attributed_variables_without_attrs'(Gs, Vars).
term_attributed_variables(Term, Vars) :-
'$term_attributed_variables'(Term, Vars).
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
}
&Instruction::CallTermVariables(_) => {
- self.term_variables();
+ self.term_variables(|value| value.is_var());
step_or_fail!(self, self.machine_st.p += 1);
}
&Instruction::ExecuteTermVariables(_) => {
- self.term_variables();
+ self.term_variables(|value| value.is_var());
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
}
&Instruction::CallTermVariablesUnderMaxDepth(_) => {
self.delete_all_attributes_from_var();
self.machine_st.p = self.machine_st.cp;
}
+ &Instruction::CallTermAttributedVariablesWithoutAttrs(_) => {
+ self.term_variables(|value| value.is_attr_var());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteTermAttributedVariablesWithoutAttrs(_) => {
+ self.term_variables(|value| value.is_attr_var());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
}
}
}
#[inline]
- pub(crate) fn variable_set<S: BuildHasher>(
+ pub(crate) fn filter_cell_set<S: BuildHasher>(
&mut self,
seen_set: &mut IndexSet<HeapCellValue, S>,
value: HeapCellValue,
+ filter_fn: impl Fn(HeapCellValue) -> bool,
) {
let mut iter = stackful_preorder_iter(&mut self.heap, value);
while let Some(value) = iter.next() {
let value = unmark_cell_bits!(value);
- if value.is_var() {
+ if filter_fn(value) {
let value = unmark_cell_bits!(heap_bound_store(
iter.heap,
heap_bound_deref(iter.heap, value)
));
- if value.is_var() {
+ if filter_fn(value) {
seen_set.insert(value);
}
}
// complete_partial_goal prior to goal_expansion.
let mut supp_vars = IndexSet::with_hasher(FxBuildHasher::default());
- self.machine_st.variable_set(&mut supp_vars, self.machine_st.registers[2]);
+ self.machine_st.filter_cell_set(
+ &mut supp_vars,
+ self.machine_st.registers[2],
+ |value| value.is_var(),
+ );
struct GoalAnalysisResult {
is_simple_goal: bool,
// fill expanded_vars with variables of the partial
// goal pre-completion by complete_partial_goal.
for idx in s + 1 .. s + arity - supp_vars.len() + 1 {
- self.machine_st.variable_set(&mut expanded_vars, self.machine_st.heap[idx]);
+ self.machine_st.filter_cell_set(
+ &mut expanded_vars,
+ self.machine_st.heap[idx],
+ |value| value.is_var(),
+ );
}
let is_simple_goal = if arity >= supp_vars.len() {
if self.machine_st.heap[match_site + 1].get_tag() == HeapCellValueTag::Lis {
let prev_tail_value = self.machine_st.heap[match_site + 1].get_value();
+
self.machine_st.heap[prev_tail].set_value(prev_tail_value);
+ self.machine_st.attr_var_init.attr_var_queue.push(attr_var_list - 1);
} else {
self.machine_st.heap[prev_tail] = heap_loc_as_cell!(prev_tail);
}
self.machine_st.heap.push(str_loc_as_cell!(h+1));
self.machine_st.heap.extend(functor!(atom!(":"), [cell(module), cell(attr)]));
+ self.machine_st.attr_var_init.attr_var_queue.push(attr_var_list - 1);
+
match self.match_attribute(self.machine_st.heap[attr_var_list], module, attr) {
Some(AttrListMatch { match_site, .. }) => {
let (match_site, l) = match match_site {
self.machine_st.heap.push(heap_loc_as_cell!(h));
self.machine_st.heap.push(heap_loc_as_cell!(h+5));
- self.machine_st.attr_var_init.attr_var_queue.push(attr_var_list - 1);
self.machine_st.trail(TrailRef::AttrVarListLink(attr_var_list, attr_var_list));
}
}
}
#[inline(always)]
- pub(crate) fn term_variables(&mut self) {
+ pub(crate) fn term_variables(&mut self, filter_fn: impl Fn(HeapCellValue) -> bool) {
let stored_v = self.deref_register(1);
let a2 = self.deref_register(2);
let mut seen_set = IndexSet::with_hasher(FxBuildHasher::default());
- self.machine_st.variable_set(&mut seen_set, stored_v);
+ self.machine_st.filter_cell_set(&mut seen_set, stored_v, filter_fn);
let outcome = heap_loc_as_cell!(
iter_to_heap_list(&mut self.machine_st.heap, seen_set.into_iter())