fix additional tests, make better use of existing code (#2293)
This commit is contained in:
@@ -173,6 +173,98 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
|
|||||||
let mut pstr_iter1 = HeapPStrIter::new(&machine_st.heap, s1);
|
let mut pstr_iter1 = HeapPStrIter::new(&machine_st.heap, s1);
|
||||||
let mut pstr_iter2 = HeapPStrIter::new(&machine_st.heap, s1 + 1);
|
let mut pstr_iter2 = HeapPStrIter::new(&machine_st.heap, s1 + 1);
|
||||||
|
|
||||||
|
fn unify_sequence(
|
||||||
|
machine_st: &mut MachineState,
|
||||||
|
iter: PStrIteratee,
|
||||||
|
source_cell: HeapCellValue,
|
||||||
|
) -> bool {
|
||||||
|
match iter {
|
||||||
|
PStrIteratee::Char(focus, _) => {
|
||||||
|
machine_st.pdl.push(machine_st.heap[focus]);
|
||||||
|
machine_st.pdl.push(source_cell);
|
||||||
|
}
|
||||||
|
PStrIteratee::PStrSegment(focus, _, n) => {
|
||||||
|
read_heap_cell!(machine_st.heap[focus],
|
||||||
|
(HeapCellValueTag::CStr | HeapCellValueTag::PStr, pstr_atom) => {
|
||||||
|
if focus < machine_st.heap.len() - 2 {
|
||||||
|
machine_st.heap.pop();
|
||||||
|
machine_st.heap.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if n == 0 {
|
||||||
|
let target_cell = match machine_st.heap[focus].get_tag() {
|
||||||
|
HeapCellValueTag::CStr => {
|
||||||
|
atom_as_cstr_cell!(pstr_atom)
|
||||||
|
}
|
||||||
|
HeapCellValueTag::PStr => {
|
||||||
|
pstr_loc_as_cell!(focus)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
machine_st.pdl.push(target_cell);
|
||||||
|
machine_st.pdl.push(source_cell);
|
||||||
|
} else {
|
||||||
|
let h_len = machine_st.heap.len();
|
||||||
|
|
||||||
|
machine_st.heap.push(pstr_offset_as_cell!(focus));
|
||||||
|
machine_st.heap.push(fixnum_as_cell!(
|
||||||
|
Fixnum::build_with(n as i64)
|
||||||
|
));
|
||||||
|
|
||||||
|
machine_st.pdl.push(pstr_loc_as_cell!(h_len));
|
||||||
|
machine_st.pdl.push(source_cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::PStrOffset, pstr_loc) => {
|
||||||
|
let n0 = cell_as_fixnum!(machine_st.heap[focus+1])
|
||||||
|
.get_num() as usize;
|
||||||
|
|
||||||
|
if pstr_loc < machine_st.heap.len() - 2 {
|
||||||
|
machine_st.heap.pop();
|
||||||
|
machine_st.heap.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if n == n0 {
|
||||||
|
machine_st.pdl.push(pstr_loc_as_cell!(focus));
|
||||||
|
machine_st.pdl.push(source_cell);
|
||||||
|
} else {
|
||||||
|
let h_len = machine_st.heap.len();
|
||||||
|
|
||||||
|
machine_st.heap.push(pstr_offset_as_cell!(pstr_loc));
|
||||||
|
machine_st.heap.push(fixnum_as_cell!(
|
||||||
|
Fixnum::build_with(n as i64)
|
||||||
|
));
|
||||||
|
|
||||||
|
machine_st.pdl.push(pstr_loc_as_cell!(h_len));
|
||||||
|
machine_st.pdl.push(source_cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if focus < machine_st.heap.len() - 2 {
|
||||||
|
machine_st.heap.pop();
|
||||||
|
machine_st.heap.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
machine_st.pdl.push(machine_st.heap[focus]);
|
||||||
|
machine_st.pdl.push(source_cell);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
match compare_pstr_prefixes(&mut pstr_iter1, &mut pstr_iter2) {
|
match compare_pstr_prefixes(&mut pstr_iter1, &mut pstr_iter2) {
|
||||||
PStrCmpResult::Ordered(Ordering::Equal) => {}
|
PStrCmpResult::Ordered(Ordering::Equal) => {}
|
||||||
PStrCmpResult::Ordered(Ordering::Less) => {
|
PStrCmpResult::Ordered(Ordering::Less) => {
|
||||||
@@ -230,118 +322,13 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::CStr | HeapCellValueTag::PStrLoc) => {
|
(HeapCellValueTag::CStr | HeapCellValueTag::PStrLoc) => {
|
||||||
machine_st.pdl.push(focus);
|
unify_sequence(machine_st, chars_iter.item.unwrap(), focus);
|
||||||
|
|
||||||
match chars_iter.item.unwrap() {
|
|
||||||
PStrIteratee::Char(focus, _) |
|
|
||||||
PStrIteratee::PStrSegment(focus, _, 0) => {
|
|
||||||
machine_st.pdl.push(machine_st.heap[focus]);
|
|
||||||
|
|
||||||
machine_st.heap.pop();
|
|
||||||
machine_st.heap.pop();
|
|
||||||
}
|
|
||||||
PStrIteratee::PStrSegment(focus, _, n) => {
|
|
||||||
let segment = machine_st.heap[focus];
|
|
||||||
|
|
||||||
machine_st.heap.pop();
|
|
||||||
machine_st.heap.pop();
|
|
||||||
|
|
||||||
let h = machine_st.heap.len();
|
|
||||||
|
|
||||||
machine_st.pdl.push(pstr_loc_as_cell!(h+1));
|
|
||||||
|
|
||||||
machine_st.heap.push(segment);
|
|
||||||
machine_st.heap.push(pstr_offset_as_cell!(h));
|
|
||||||
machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(n as i64)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
|
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
|
||||||
match chars_iter.item.unwrap() {
|
if unify_sequence(machine_st, chars_iter.item.unwrap(), heap_loc_as_cell!(h)) {
|
||||||
PStrIteratee::Char(focus, _) => {
|
|
||||||
machine_st.pdl.push(machine_st.heap[focus]);
|
|
||||||
machine_st.pdl.push(heap_loc_as_cell!(h));
|
|
||||||
}
|
|
||||||
PStrIteratee::PStrSegment(focus, _, n) => {
|
|
||||||
read_heap_cell!(machine_st.heap[focus],
|
|
||||||
(HeapCellValueTag::CStr | HeapCellValueTag::PStr, pstr_atom) => {
|
|
||||||
if focus < machine_st.heap.len() - 2 {
|
|
||||||
machine_st.heap.pop();
|
|
||||||
machine_st.heap.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if n == 0 {
|
|
||||||
let target_cell = match machine_st.heap[focus].get_tag() {
|
|
||||||
HeapCellValueTag::CStr => {
|
|
||||||
atom_as_cstr_cell!(pstr_atom)
|
|
||||||
}
|
|
||||||
HeapCellValueTag::PStr => {
|
|
||||||
pstr_loc_as_cell!(focus)
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
machine_st.pdl.push(target_cell);
|
|
||||||
machine_st.pdl.push(heap_loc_as_cell!(h));
|
|
||||||
} else {
|
|
||||||
let h_len = machine_st.heap.len();
|
|
||||||
|
|
||||||
machine_st.heap.push(pstr_offset_as_cell!(focus));
|
|
||||||
machine_st.heap.push(fixnum_as_cell!(
|
|
||||||
Fixnum::build_with(n as i64)
|
|
||||||
));
|
|
||||||
|
|
||||||
machine_st.pdl.push(pstr_loc_as_cell!(h_len));
|
|
||||||
machine_st.pdl.push(heap_loc_as_cell!(h));
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::PStrOffset, pstr_loc) => {
|
|
||||||
let n0 = cell_as_fixnum!(machine_st.heap[focus+1])
|
|
||||||
.get_num() as usize;
|
|
||||||
|
|
||||||
if pstr_loc < machine_st.heap.len() - 2 {
|
|
||||||
machine_st.heap.pop();
|
|
||||||
machine_st.heap.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if n == n0 {
|
|
||||||
machine_st.pdl.push(pstr_loc_as_cell!(focus));
|
|
||||||
machine_st.pdl.push(heap_loc_as_cell!(h));
|
|
||||||
} else {
|
|
||||||
let h_len = machine_st.heap.len();
|
|
||||||
|
|
||||||
machine_st.heap.push(pstr_offset_as_cell!(pstr_loc));
|
|
||||||
machine_st.heap.push(fixnum_as_cell!(
|
|
||||||
Fixnum::build_with(n as i64)
|
|
||||||
));
|
|
||||||
|
|
||||||
machine_st.pdl.push(pstr_loc_as_cell!(h_len));
|
|
||||||
machine_st.pdl.push(heap_loc_as_cell!(h));
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if focus < machine_st.heap.len() - 2 {
|
|
||||||
machine_st.heap.pop();
|
|
||||||
machine_st.heap.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
machine_st.pdl.push(machine_st.heap[focus]);
|
|
||||||
machine_st.pdl.push(heap_loc_as_cell!(h));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break 'outer;
|
break 'outer;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user