fix comparisons to partial string tails (#1420)

This commit is contained in:
Mark Thom
2022-04-14 22:14:23 -06:00
parent 7595ec16e5
commit 05c14d5780
3 changed files with 63 additions and 56 deletions

View File

@@ -1545,7 +1545,7 @@ impl MachineState {
} }
} else { } else {
self.pdl.clear(); self.pdl.clear();
return Some(Ordering::Greater); return Some(n1.chars().next().cmp(&Some(c2)));
} }
} }
_ => { _ => {
@@ -1563,7 +1563,7 @@ impl MachineState {
} }
} else { } else {
self.pdl.clear(); self.pdl.clear();
return Some(Ordering::Less); return Some(Some(c1).cmp(&n2.chars().next()));
} }
} }
(HeapCellValueTag::Char, c2) => { (HeapCellValueTag::Char, c2) => {
@@ -1583,41 +1583,61 @@ impl MachineState {
) )
} }
Some(TermOrderCategory::Compound) => { Some(TermOrderCategory::Compound) => {
fn stalled_pstr_iter_handler( fn stalled_pstr_iter_comparator(
string_iter: HeapPStrIter, iteratee: PStrIteratee,
stalled_iter: HeapPStrIter, iter2: HeapPStrIter,
pdl: &mut Vec<HeapCellValue>, pdl: &mut Vec<HeapCellValue>,
) -> Option<Ordering> { ) -> Option<Ordering> {
let l = read_heap_cell!(stalled_iter.focus, let compound = Some(TermOrderCategory::Compound);
(HeapCellValueTag::Str, s) => {
let (name, arity) = cell_as_atom_cell!(stalled_iter.heap[s])
.get_name_and_arity();
if !(name == atom!(".") && arity == 2) { if iter2.focus.order_category() != compound {
pdl.clear(); Some(compound.cmp(&iter2.focus.order_category()))
return Some((atom!("."),2).cmp(&(name,arity))); } else {
let c1 = match iteratee {
PStrIteratee::Char(_, c) => c,
PStrIteratee::PStrSegment(focus, pstr_atom, n) => {
let pstr = PartialString::from(pstr_atom);
match pstr.as_str_from(n).chars().next() {
Some(c) => c,
None => {
pdl.push(iter2.focus);
// iter2 is continuable, so it
// has a tail in the heap at
// focus+1.
pdl.push(iter2.heap[focus+1]);
return None;
}
}
} }
};
s+1 read_heap_cell!(iter2.focus,
} (HeapCellValueTag::Lis, l) => {
(HeapCellValueTag::Lis, l) => { pdl.push(iter2.heap[l]);
l pdl.push(char_as_cell!(c1));
}
_ => {
unreachable!()
}
);
let c2 = stalled_iter.heap[l]; None
let c1 = match string_iter.chars().next() { }
Some(c) => char_as_cell!(c), (HeapCellValueTag::Str, s) => {
None => string_iter.focus, let (name, arity) = cell_as_atom_cell!(iter2.heap[s])
}; .get_name_and_arity();
pdl.push(c2); if name == atom!(".") && arity == 2 {
pdl.push(c1); pdl.push(iter2.heap[s+1]);
pdl.push(char_as_cell!(c1));
None None
} else {
Some((2, atom!(".")).cmp(&(arity, name)))
}
}
_ => {
unreachable!()
}
)
}
} }
fn pstr_comparator( fn pstr_comparator(
@@ -1631,33 +1651,21 @@ impl MachineState {
match compare_pstr_prefixes(&mut iter1, &mut iter2) { match compare_pstr_prefixes(&mut iter1, &mut iter2) {
PStrCmpResult::Ordered(ordering) => Some(ordering), PStrCmpResult::Ordered(ordering) => Some(ordering),
_ => { PStrCmpResult::FirstIterContinuable(iteratee) => {
if iter1.num_steps() == 0 && iter2.num_steps() == 0 { stalled_pstr_iter_comparator(iteratee, iter2, pdl)
return read_heap_cell!(iter2.focus, }
(HeapCellValueTag::CStr | HeapCellValueTag::PStrLoc) => { PStrCmpResult::SecondIterContinuable(iteratee) => {
let result = stalled_pstr_iter_handler(iter2, iter1, pdl); let result = stalled_pstr_iter_comparator(iteratee, iter1, pdl);
if let Some(ordering) = result { if let Some(ordering) = result {
Some(ordering.reverse()) Some(ordering.reverse())
} else { } else {
let pdl_len = pdl.len(); let pdl_len = pdl.len();
pdl.swap(pdl_len - 2, pdl_len - 1); pdl.swap(pdl_len - 2, pdl_len - 1);
result result
}
}
(HeapCellValueTag::Atom, (name, arity)) => {
if name == atom!("[]") && arity == 0 {
return Some(Ordering::Greater);
} else {
stalled_pstr_iter_handler(iter1, iter2, pdl)
}
}
_ => {
stalled_pstr_iter_handler(iter1, iter2, pdl)
}
);
} }
}
PStrCmpResult::Unordered => {
pdl.push(iter2.focus); pdl.push(iter2.focus);
pdl.push(iter1.focus); pdl.push(iter1.focus);

View File

@@ -542,7 +542,6 @@ pub fn compare_pstr_prefixes<'a>(
#[inline(always)] #[inline(always)]
fn step(iter: &mut HeapPStrIter, hare: usize) -> Option<PStrIterStep> { fn step(iter: &mut HeapPStrIter, hare: usize) -> Option<PStrIterStep> {
let result = iter.step(hare); let result = iter.step(hare);
iter.focus = iter.heap[hare]; iter.focus = iter.heap[hare];
if iter.focus.is_string_terminator(iter.heap) { if iter.focus.is_string_terminator(iter.heap) {

View File

@@ -592,7 +592,7 @@ impl HeapCellValue {
}) })
} }
HeapCellValueTag::Lis | HeapCellValueTag::PStrLoc | HeapCellValueTag::Lis | HeapCellValueTag::PStrLoc |
HeapCellValueTag::CStr | HeapCellValueTag::Str => { HeapCellValueTag::CStr | HeapCellValueTag::Str => {
Some(TermOrderCategory::Compound) Some(TermOrderCategory::Compound)
} }
_ => { _ => {