port '$get_from_list' to '$get_from_attr_list' in Rust
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user