GetClauseP,
#[strum_discriminants(strum(props(Arity = "6", Name = "$invoke_clause_at_p")))]
InvokeClauseAtP,
+ #[strum_discriminants(strum(props(Arity = "2", Name = "$get_from_attr_list")))]
+ GetFromAttributedVarList,
REPL(REPLCodePtr),
}
&Instruction::CallIsExpandedOrInlined(_) |
&Instruction::CallGetClauseP(_) |
&Instruction::CallInvokeClauseAtP(_) |
+ &Instruction::CallGetFromAttributedVarList(_) |
&Instruction::CallEnqueueAttributedVar(_) |
&Instruction::CallFetchGlobalVar(_) |
&Instruction::CallFirstStream(_) |
&Instruction::ExecuteIsExpandedOrInlined(_) |
&Instruction::ExecuteGetClauseP(_) |
&Instruction::ExecuteInvokeClauseAtP(_) |
+ &Instruction::ExecuteGetFromAttributedVarList(_) |
&Instruction::ExecuteEnqueueAttributedVar(_) |
&Instruction::ExecuteFetchGlobalVar(_) |
&Instruction::ExecuteFirstStream(_) |
'$get_attr'(V, Attr) :-
'$get_attr_list'(V, Ls),
nonvar(Ls),
- '$get_from_list'(Ls, V, Attr).
+ '$get_from_attr_list'(Ls, Attr).
+/*
'$get_from_list'([L|Ls], V, Attr) :-
nonvar(L),
( L \= Attr ->
'$get_from_list'(Ls, V, Attr)
; L = Attr
).
+*/
'$put_attr'(V, Attr) :-
'$get_attr_list'(V, Ls),
self.machine_st.execute_at_index(2, p);
}
+ &Instruction::CallGetFromAttributedVarList(_) => {
+ self.get_from_attributed_variable_list();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetFromAttributedVarList(_) => {
+ self.get_from_attributed_variable_list();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
}
}
self.machine_st.bind(Ref::heap_cell(attr_var_list), list_addr);
}
+ #[inline(always)]
+ pub(crate) fn get_from_attributed_variable_list(&mut self) {
+ let mut attrs_list = self.deref_register(1);
+ let attr = self.deref_register(2);
+
+ let (name, arity) = match self.machine_st.name_and_arity_from_heap(attr) {
+ Some(key) => key,
+ None => {
+ self.machine_st.fail = true;
+ return;
+ }
+ };
+
+ while let HeapCellValueTag::Lis = attrs_list.get_tag() {
+ let mut list_head = self.machine_st.heap[attrs_list.get_value()];
+
+ loop {
+ read_heap_cell!(list_head,
+ (HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
+ if list_head != self.machine_st.heap[h] {
+ list_head = self.machine_st.heap[h];
+ } else {
+ self.machine_st.fail = true;
+ return;
+ }
+ }
+ (HeapCellValueTag::Str | HeapCellValueTag::Atom) => {
+ let (t_name, t_arity) = self.machine_st
+ .name_and_arity_from_heap(list_head)
+ .unwrap();
+
+ if name == t_name && arity == t_arity {
+ let old_tr = self.machine_st.tr;
+
+ unify!(self.machine_st, list_head, attr);
+
+ if self.machine_st.fail {
+ let curr_tr = self.machine_st.trail.len();
+
+ self.unwind_trail(old_tr, curr_tr);
+ self.machine_st.tr = old_tr;
+
+ self.machine_st.pdl.clear();
+ self.machine_st.fail = false;
+ } else {
+ return;
+ }
+ }
+
+ break;
+ }
+ _ => {
+ break;
+ }
+ );
+ }
+
+ attrs_list = self.machine_st.store(
+ self.machine_st.deref(self.machine_st.heap[attrs_list.get_value()+1])
+ );
+ }
+
+ self.machine_st.fail = true;
+ }
+
#[inline(always)]
pub(crate) fn get_attr_var_queue_delimiter(&mut self) {
let addr = self.deref_register(1);