don't read into the heap while incrementing self.s (#1233, #1245)

This commit is contained in:
Mark Thom
2022-01-24 18:47:53 -07:00
parent e6c4ecfc10
commit a562793fce
5 changed files with 71 additions and 78 deletions

View File

@@ -11,7 +11,7 @@
*/ */
:- module(least_time, [find_min_time/2, :- module(least_time, [find_min_time/2,
write_time_nl/1]). write_time_nl/1]).
:- use_module(library(dcgs)). :- use_module(library(dcgs)).
@@ -27,10 +27,10 @@ valid_time([H1,H2,M1,M2], T) :-
memberd_t(M2, [0,1,2,3,4,5,6,7,8,9], TM2), memberd_t(M2, [0,1,2,3,4,5,6,7,8,9], TM2),
( maplist(=(true), [TH1, TH2, TM1, TM2]) -> ( maplist(=(true), [TH1, TH2, TM1, TM2]) ->
( H1 =:= 2 -> ( H1 =:= 2 ->
( H2 =< 3 -> ( H2 =< 3 ->
T = true T = true
; T = false ; T = false
) )
; T = true ; T = true
) )
; T = false ; T = false

View File

@@ -2769,6 +2769,7 @@ impl Machine {
let (h, n) = pstr_loc_and_offset(&self.machine_st.heap, h); let (h, n) = pstr_loc_and_offset(&self.machine_st.heap, h);
self.machine_st.s = HeapPtr::PStrChar(h, n.get_num() as usize); self.machine_st.s = HeapPtr::PStrChar(h, n.get_num() as usize);
self.machine_st.s_offset = 0;
self.machine_st.mode = MachineMode::Read; self.machine_st.mode = MachineMode::Read;
} }
(HeapCellValueTag::CStr) => { (HeapCellValueTag::CStr) => {
@@ -2776,10 +2777,12 @@ impl Machine {
self.machine_st.heap.push(store_v); self.machine_st.heap.push(store_v);
self.machine_st.s = HeapPtr::PStrChar(h, 0); self.machine_st.s = HeapPtr::PStrChar(h, 0);
self.machine_st.s_offset = 0;
self.machine_st.mode = MachineMode::Read; self.machine_st.mode = MachineMode::Read;
} }
(HeapCellValueTag::Lis, l) => { (HeapCellValueTag::Lis, l) => {
self.machine_st.s = HeapPtr::HeapCell(l); self.machine_st.s = HeapPtr::HeapCell(l);
self.machine_st.s_offset = 0;
self.machine_st.mode = MachineMode::Read; self.machine_st.mode = MachineMode::Read;
} }
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var | HeapCellValueTag::StackVar) => { (HeapCellValueTag::AttrVar | HeapCellValueTag::Var | HeapCellValueTag::StackVar) => {
@@ -2827,6 +2830,7 @@ impl Machine {
(HeapCellValueTag::Atom, (result_name, result_arity)) => { (HeapCellValueTag::Atom, (result_name, result_arity)) => {
if arity == result_arity && name == result_name { if arity == result_arity && name == result_name {
self.machine_st.s = HeapPtr::HeapCell(a + 1); self.machine_st.s = HeapPtr::HeapCell(a + 1);
self.machine_st.s_offset = 0;
self.machine_st.mode = MachineMode::Read; self.machine_st.mode = MachineMode::Read;
} else { } else {
self.machine_st.backtrack(); self.machine_st.backtrack();
@@ -2883,7 +2887,7 @@ impl Machine {
self.machine_st.backtrack(); self.machine_st.backtrack();
continue; continue;
} else { } else {
self.machine_st.increment_s_ptr(1); self.machine_st.s_offset += 1;
} }
} }
MachineMode::Write => { MachineMode::Write => {
@@ -2905,7 +2909,7 @@ impl Machine {
self.machine_st.backtrack(); self.machine_st.backtrack();
continue; continue;
} else { } else {
self.machine_st.increment_s_ptr(1); self.machine_st.s_offset += 1;
} }
} }
MachineMode::Write => { MachineMode::Write => {
@@ -2917,7 +2921,7 @@ impl Machine {
let value = self.machine_st.heap[hc]; let value = self.machine_st.heap[hc];
self.machine_st.heap.push(value); self.machine_st.heap.push(value);
self.machine_st.increment_s_ptr(1); self.machine_st.s_offset += 1;
} }
_ => { _ => {
self.machine_st.heap.push(heap_loc_as_cell!(h)); self.machine_st.heap.push(heap_loc_as_cell!(h));
@@ -2937,7 +2941,7 @@ impl Machine {
match self.machine_st.mode { match self.machine_st.mode {
MachineMode::Read => { MachineMode::Read => {
self.machine_st[reg] = self.machine_st.read_s(); self.machine_st[reg] = self.machine_st.read_s();
self.machine_st.increment_s_ptr(1); self.machine_st.s_offset += 1;
} }
MachineMode::Write => { MachineMode::Write => {
let h = self.machine_st.heap.len(); let h = self.machine_st.heap.len();
@@ -2961,7 +2965,7 @@ impl Machine {
self.machine_st.backtrack(); self.machine_st.backtrack();
continue; continue;
} else { } else {
self.machine_st.increment_s_ptr(1); self.machine_st.s_offset += 1;
} }
} }
MachineMode::Write => { MachineMode::Write => {
@@ -2988,7 +2992,7 @@ impl Machine {
&Instruction::UnifyVoid(n) => { &Instruction::UnifyVoid(n) => {
match self.machine_st.mode { match self.machine_st.mode {
MachineMode::Read => { MachineMode::Read => {
self.machine_st.increment_s_ptr(n); self.machine_st.s_offset += n;
} }
MachineMode::Write => { MachineMode::Write => {
let h = self.machine_st.heap.len(); let h = self.machine_st.heap.len();

View File

@@ -55,6 +55,7 @@ pub struct MachineState {
pub arena: Arena, pub arena: Arena,
pub(super) pdl: Vec<HeapCellValue>, pub(super) pdl: Vec<HeapCellValue>,
pub(super) s: HeapPtr, pub(super) s: HeapPtr,
pub(super) s_offset: usize,
pub(super) p: usize, pub(super) p: usize,
pub(super) oip: u32, // first internal code ptr pub(super) oip: u32, // first internal code ptr
pub(super) iip : u32, // second internal code ptr pub(super) iip : u32, // second internal code ptr

View File

@@ -28,6 +28,7 @@ impl MachineState {
atom_tbl: AtomTable::new(), atom_tbl: AtomTable::new(),
pdl: Vec::with_capacity(1024), pdl: Vec::with_capacity(1024),
s: HeapPtr::default(), s: HeapPtr::default(),
s_offset: 0,
p: 0, p: 0,
oip: 0, oip: 0,
iip: 0, iip: 0,
@@ -77,6 +78,7 @@ impl MachineState {
) )
} }
#[inline]
pub fn deref(&self, mut addr: HeapCellValue) -> HeapCellValue { pub fn deref(&self, mut addr: HeapCellValue) -> HeapCellValue {
loop { loop {
let value = self.store(addr); let value = self.store(addr);
@@ -1390,28 +1392,25 @@ impl MachineState {
} }
pub(crate) fn read_s(&mut self) -> HeapCellValue { pub(crate) fn read_s(&mut self) -> HeapCellValue {
match &self.s { match &mut self.s {
&HeapPtr::HeapCell(h) => self.deref(self.heap[h]), &mut HeapPtr::HeapCell(h) => self.deref(self.heap[h + self.s_offset]),
&HeapPtr::PStrChar(h, n) => { &mut HeapPtr::PStrChar(h, n) if self.s_offset == 0 => {
read_heap_cell!(self.heap[h], read_heap_cell!(self.heap[h],
(HeapCellValueTag::PStr, pstr_atom) => { (HeapCellValueTag::PStr, pstr_atom) => {
let pstr = PartialString::from(pstr_atom); let pstr = PartialString::from(pstr_atom);
if let Some(c) = pstr.as_str_from(n).chars().next() { if let Some(c) = pstr.as_str_from(n).chars().next() {
char_as_cell!(c) char_as_cell!(c)
} else { // if has_tail { } else {
self.deref(self.heap[h+1]) // heap_loc_as_cell!(h+1) self.deref(self.heap[h+1])
} }
// } else {
// empty_list_as_cell!()
// }
} }
(HeapCellValueTag::CStr, cstr_atom) => { (HeapCellValueTag::CStr, cstr_atom) => {
let pstr = PartialString::from(cstr_atom); let pstr = PartialString::from(cstr_atom);
if let Some(c) = pstr.as_str_from(n).chars().next() { if let Some(c) = pstr.as_str_from(n).chars().next() {
char_as_cell!(c) char_as_cell!(c)
} else { // if has_tail { } else {
empty_list_as_cell!() empty_list_as_cell!()
} }
} }
@@ -1420,14 +1419,25 @@ impl MachineState {
} }
) )
} }
&HeapPtr::PStrLocation(h, n) => { &mut HeapPtr::PStrChar(h, ref mut n) |
&mut HeapPtr::PStrLocation(h, ref mut n) => {
read_heap_cell!(self.heap[h], read_heap_cell!(self.heap[h],
(HeapCellValueTag::PStr, pstr_atom) => { (HeapCellValueTag::PStr, pstr_atom) => {
if n < pstr_atom.len() { let pstr = PartialString::from(pstr_atom);
let n_offset: usize = pstr.as_str_from(*n)
.chars()
.take(self.s_offset)
.map(|c| c.len_utf8())
.sum();
self.s_offset = 0;
*n += n_offset;
if *n < pstr_atom.len() {
let h_len = self.heap.len(); let h_len = self.heap.len();
self.heap.push(pstr_offset_as_cell!(h)); self.heap.push(pstr_offset_as_cell!(h));
self.heap.push(fixnum_as_cell!(Fixnum::build_with(n as i64))); self.heap.push(fixnum_as_cell!(Fixnum::build_with(*n as i64)));
pstr_loc_as_cell!(h_len) pstr_loc_as_cell!(h_len)
} else { } else {
@@ -1435,11 +1445,21 @@ impl MachineState {
} }
} }
(HeapCellValueTag::CStr, cstr_atom) => { (HeapCellValueTag::CStr, cstr_atom) => {
if n < cstr_atom.len() { let pstr = PartialString::from(cstr_atom);
let n_offset: usize = pstr.as_str_from(*n)
.chars()
.take(self.s_offset)
.map(|c| c.len_utf8())
.sum();
self.s_offset = 0;
*n += n_offset;
if *n < cstr_atom.len() {
let h_len = self.heap.len(); let h_len = self.heap.len();
self.heap.push(pstr_offset_as_cell!(h)); self.heap.push(pstr_offset_as_cell!(h));
self.heap.push(fixnum_as_cell!(Fixnum::build_with(n as i64))); self.heap.push(fixnum_as_cell!(Fixnum::build_with(*n as i64)));
pstr_loc_as_cell!(h_len) pstr_loc_as_cell!(h_len)
} else { } else {
@@ -1821,30 +1841,6 @@ impl MachineState {
Some(Ordering::Equal) Some(Ordering::Equal)
} }
pub(crate) fn increment_s_ptr(&mut self, rhs: usize) {
match &mut self.s {
HeapPtr::HeapCell(ref mut h) => {
*h += rhs;
}
&mut HeapPtr::PStrChar(h, ref mut n) | &mut HeapPtr::PStrLocation(h, ref mut n) => {
read_heap_cell!(self.heap[h],
(HeapCellValueTag::PStr | HeapCellValueTag::CStr, pstr_atom) => {
let pstr = PartialString::from(pstr_atom);
for c in pstr.as_str_from(*n).chars().take(rhs) {
*n += c.len_utf8();
}
self.s = HeapPtr::PStrLocation(h, *n);
}
_ => {
unreachable!()
}
)
}
}
}
pub fn match_partial_string(&mut self, value: HeapCellValue, string: Atom, has_tail: bool) { pub fn match_partial_string(&mut self, value: HeapCellValue, string: Atom, has_tail: bool) {
let h = self.heap.len(); let h = self.heap.len();
self.heap.push(value); self.heap.push(value);
@@ -1860,23 +1856,35 @@ impl MachineState {
(HeapCellValueTag::PStr | HeapCellValueTag::CStr, pstr_atom) => { (HeapCellValueTag::PStr | HeapCellValueTag::CStr, pstr_atom) => {
if has_tail { if has_tail {
self.s = HeapPtr::PStrLocation(focus, offset); self.s = HeapPtr::PStrLocation(focus, offset);
self.s_offset = 0;
self.mode = MachineMode::Read; self.mode = MachineMode::Read;
} else if offset == pstr_atom.len() { } else if offset == pstr_atom.len() {
let focus_addr = heap_pstr_iter.focus; let focus = heap_pstr_iter.focus;
unify!(self, focus_addr, empty_list_as_cell!()); unify!(self, focus, empty_list_as_cell!());
} else { } else {
self.fail = true; self.fail = true;
} }
} }
(HeapCellValueTag::PStrLoc | HeapCellValueTag::PStrOffset, h) => { (HeapCellValueTag::PStrLoc | HeapCellValueTag::PStrOffset, h) => {
if has_tail { let (focus, _) = pstr_loc_and_offset(&self.heap, h);
let (h, _) = pstr_loc_and_offset(&self.heap, h); let pstr_atom = read_heap_cell!(self.heap[focus],
(HeapCellValueTag::CStr | HeapCellValueTag::PStr, pstr_atom) => {
pstr_atom
}
_ => {
unreachable!()
}
);
self.s = HeapPtr::PStrLocation(h, offset); if has_tail {
self.s = HeapPtr::PStrLocation(focus, offset);
self.s_offset = 0;
self.mode = MachineMode::Read; self.mode = MachineMode::Read;
} else if offset == pstr_atom.len() {
let focus = heap_pstr_iter.focus;
unify!(self, focus, empty_list_as_cell!());
} else { } else {
let end_cell = heap_pstr_iter.focus; self.fail = true;
self.fail = end_cell != empty_list_as_cell!();
} }
} }
_ => { _ => {
@@ -1884,6 +1892,7 @@ impl MachineState {
if has_tail { if has_tail {
self.s = HeapPtr::HeapCell(focus); self.s = HeapPtr::HeapCell(focus);
self.s_offset = 0;
self.mode = MachineMode::Read; self.mode = MachineMode::Read;
} else { } else {
let focus = heap_pstr_iter.focus; let focus = heap_pstr_iter.focus;
@@ -1900,6 +1909,7 @@ impl MachineState {
let target_cell = if has_tail { let target_cell = if has_tail {
self.s = HeapPtr::HeapCell(h + 1); self.s = HeapPtr::HeapCell(h + 1);
self.s_offset = 0;
self.mode = MachineMode::Read; self.mode = MachineMode::Read;
put_partial_string( put_partial_string(

View File

@@ -499,28 +499,6 @@ impl<'a> Iterator for PStrCharsIter<'a> {
} }
} }
/*
if !self.iter.at_string_terminator() {
// at a cycle. emit the final character.
match self.iter.step(self.iter.brent_st.hare) {
Some(PStrIterStep { iteratee: PStrIteratee::Char(_, c), .. }) => {
self.iter.focus = empty_list_as_cell!();
return Some(c);
}
Some(PStrIterStep { iteratee: PStrIteratee::PStrSegment(_, pstr_atom, _), .. }) => {
self.iter.focus = empty_list_as_cell!();
let c = PartialString::from(pstr_atom).as_str_from(0).chars().next().unwrap();
return Some(c);
}
_ => {
self.iter.focus = empty_list_as_cell!();
return None;
}
}
}
*/
None None
} }
} }