port '$get_from_list' to '$get_from_attr_list' in Rust

This commit is contained in:
Mark Thom
2023-02-06 01:23:29 -07:00
parent 2fcec4fff9
commit 9454d670c7
4 changed files with 80 additions and 1 deletions

View File

@@ -34,8 +34,9 @@
'$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 ->
@@ -43,6 +44,7 @@
'$get_from_list'(Ls, V, Attr)
; L = Attr
).
*/
'$put_attr'(V, Attr) :-
'$get_attr_list'(V, Ls),

View File

@@ -5207,6 +5207,14 @@ impl Machine {
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);
}
}
}

View File

@@ -4328,6 +4328,71 @@ impl Machine {
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);