fix comparisons to partial string tails (#1420)
This commit is contained in:
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|||||||
Reference in New Issue
Block a user