remove Addr::PStrTail (#276)
This commit is contained in:
@@ -89,7 +89,7 @@ impl<'a> HCPreOrderIterator<'a> {
|
|||||||
if pstr.len() > n + c.len_utf8() {
|
if pstr.len() > n + c.len_utf8() {
|
||||||
self.state_stack.push(Addr::PStrLocation(h, n + c.len_utf8()));
|
self.state_stack.push(Addr::PStrLocation(h, n + c.len_utf8()));
|
||||||
} else {
|
} else {
|
||||||
self.state_stack.push(Addr::PStrTail(h, n + c.len_utf8()));
|
self.state_stack.push(Addr::HeapCell(h + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.state_stack.push(Addr::Con(Constant::Char(c)));
|
self.state_stack.push(Addr::Con(Constant::Char(c)));
|
||||||
@@ -102,7 +102,7 @@ impl<'a> HCPreOrderIterator<'a> {
|
|||||||
|
|
||||||
Addr::PStrLocation(h, n)
|
Addr::PStrLocation(h, n)
|
||||||
}
|
}
|
||||||
Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::PStrTail(..) => {
|
Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => {
|
||||||
da
|
da
|
||||||
}
|
}
|
||||||
Addr::Str(s) => {
|
Addr::Str(s) => {
|
||||||
@@ -130,20 +130,6 @@ impl<'a> Iterator for HCPreOrderIterator<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Addr::PStrTail(h, n) => {
|
|
||||||
match &self.machine_st.heap[h] {
|
|
||||||
HeapCellValue::PartialString(ref pstr) => {
|
|
||||||
if pstr.len() > n {
|
|
||||||
HeapCellValue::Addr(Addr::PStrLocation(h, n))
|
|
||||||
} else {
|
|
||||||
HeapCellValue::Addr(pstr.tail_addr().clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Addr::StackCell(fr, sc) => {
|
Addr::StackCell(fr, sc) => {
|
||||||
HeapCellValue::Addr(self.machine_st.stack.index_and_frame(fr)[sc].clone())
|
HeapCellValue::Addr(self.machine_st.stack.index_and_frame(fr)[sc].clone())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -437,7 +437,7 @@ fn functor_location(addr: &Addr) -> Option<usize> {
|
|||||||
Some(match addr {
|
Some(match addr {
|
||||||
&Addr::Lis(l) => l,
|
&Addr::Lis(l) => l,
|
||||||
&Addr::Str(s) => s,
|
&Addr::Str(s) => s,
|
||||||
&Addr::PStrLocation(h, _) | &Addr::PStrTail(h, _) => h,
|
&Addr::PStrLocation(h, _) => h,
|
||||||
_ => {
|
_ => {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@@ -763,7 +763,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
Ref::StackCell(fr, sc) => {
|
Ref::StackCell(fr, sc) => {
|
||||||
Some(format!("_s_{}_{}", fr, sc))
|
Some(format!("_s_{}_{}", fr, sc))
|
||||||
}
|
}
|
||||||
Ref::HeapCell(h) | Ref::AttrVar(h) | Ref::PStrTail(h, _) => {
|
Ref::HeapCell(h) | Ref::AttrVar(h) => {
|
||||||
Some(format!("_{}", h))
|
Some(format!("_{}", h))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -807,12 +807,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Addr::PStrLocation(h, _) | &Addr::PStrTail(h, _) => {
|
&Addr::PStrLocation(h, _) => {
|
||||||
let tail = match &self.machine_st.heap[h] {
|
let tail = self.machine_st.heap[h + 1].as_addr(h + 1);
|
||||||
&HeapCellValue::PartialString(ref pstr) => pstr.tail_addr().clone(),
|
|
||||||
_ => unreachable!()
|
|
||||||
};
|
|
||||||
|
|
||||||
let tail = self.machine_st.store(self.machine_st.deref(tail));
|
let tail = self.machine_st.store(self.machine_st.deref(tail));
|
||||||
|
|
||||||
if let Some(c) = functor_location(&tail) {
|
if let Some(c) = functor_location(&tail) {
|
||||||
|
|||||||
@@ -65,20 +65,6 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copied_partial_string(&mut self, addr: usize) -> bool {
|
|
||||||
if let HeapCellValue::PartialString(ref pstr) = &self.target[addr] {
|
|
||||||
if let Addr::PStrLocation(h, n) = pstr.tail_addr() {
|
|
||||||
if *h >= self.old_h {
|
|
||||||
*self.value_at_scan() = HeapCellValue::Addr(Addr::PStrLocation(*h, *n));
|
|
||||||
self.scan += 1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn copy_list(&mut self, addr: usize) {
|
fn copy_list(&mut self, addr: usize) {
|
||||||
if self.copied_list(addr) {
|
if self.copied_list(addr) {
|
||||||
return;
|
return;
|
||||||
@@ -98,14 +84,13 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
self.target.push(hcv);
|
self.target.push(hcv);
|
||||||
|
|
||||||
match rd.clone() {
|
match rd.clone() {
|
||||||
Addr::AttrVar(h) | Addr::HeapCell(h) | Addr::PStrTail(h, _)
|
Addr::AttrVar(h) | Addr::HeapCell(h)
|
||||||
if h >= self.old_h => {
|
if h >= self.old_h => {
|
||||||
self.target[threshold] = HeapCellValue::Addr(rd)
|
self.target[threshold] = HeapCellValue::Addr(rd)
|
||||||
}
|
}
|
||||||
var @ Addr::AttrVar(_)
|
var @ Addr::AttrVar(_)
|
||||||
| var @ Addr::HeapCell(..)
|
| var @ Addr::HeapCell(..)
|
||||||
| var @ Addr::StackCell(..)
|
| var @ Addr::StackCell(..) => {
|
||||||
| var @ Addr::PStrTail(..) => {
|
|
||||||
if ra == rd {
|
if ra == rd {
|
||||||
self.reinstantiate_var(var, threshold);
|
self.reinstantiate_var(var, threshold);
|
||||||
|
|
||||||
@@ -130,57 +115,44 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
self.scan += 1;
|
self.scan += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn copied_partial_string(&mut self, addr: usize) -> bool {
|
||||||
|
if let &HeapCellValue::Addr(Addr::PStrLocation(h, n)) = &self.target[addr + 1] {
|
||||||
|
if h >= self.old_h {
|
||||||
|
*self.value_at_scan() = HeapCellValue::Addr(Addr::PStrLocation(h, n));
|
||||||
|
self.scan += 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
fn copy_partial_string(&mut self, addr: usize, n: usize) {
|
fn copy_partial_string(&mut self, addr: usize, n: usize) {
|
||||||
let threshold = self.target.threshold();
|
let threshold = self.target.threshold();
|
||||||
|
|
||||||
let tail_addr =
|
|
||||||
match &self.target[addr] {
|
|
||||||
HeapCellValue::PartialString(ref pstr) => {
|
|
||||||
self.trail.push((
|
self.trail.push((
|
||||||
Ref::PStrTail(addr, 0),
|
Ref::HeapCell(addr + 1),
|
||||||
HeapCellValue::Addr(pstr.tail.clone()),
|
self.target[addr + 1].clone(),
|
||||||
));
|
));
|
||||||
|
|
||||||
self.target.store(self.target.deref(pstr.tail.clone()))
|
let tail_addr = self.target[addr + 1].as_addr(addr + 1);
|
||||||
}
|
|
||||||
_ => {
|
self.target[addr + 1] = HeapCellValue::Addr(
|
||||||
unreachable!()
|
Addr::PStrLocation(threshold, 0)
|
||||||
}
|
);
|
||||||
};
|
|
||||||
|
|
||||||
let pstr =
|
let pstr =
|
||||||
match &mut self.target[addr] {
|
match &self.target[addr] {
|
||||||
HeapCellValue::PartialString(ref mut pstr) => {
|
HeapCellValue::PartialString(ref pstr) => {
|
||||||
let mut new_pstr = pstr.clone_from_offset(n);
|
pstr.clone_from_offset(n)
|
||||||
|
|
||||||
if let Addr::PStrTail(h, n) = &tail_addr {
|
|
||||||
new_pstr.tail = if *h == addr {
|
|
||||||
Addr::PStrTail(threshold, *n)
|
|
||||||
} else {
|
|
||||||
Addr::HeapCell(threshold + 1)
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
new_pstr.tail = Addr::HeapCell(threshold + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
pstr.tail = Addr::PStrLocation(threshold, 0);
|
|
||||||
new_pstr
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match tail_addr {
|
|
||||||
Addr::PStrTail(h, _) if h == addr => {
|
|
||||||
self.target.push(HeapCellValue::PartialString(pstr));
|
self.target.push(HeapCellValue::PartialString(pstr));
|
||||||
}
|
self.target.push(HeapCellValue::Addr(tail_addr));
|
||||||
addr => {
|
|
||||||
self.target.push(HeapCellValue::PartialString(pstr));
|
|
||||||
self.target.push(HeapCellValue::Addr(addr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy_partial_string_from(&mut self, addr: usize, n: usize) {
|
fn copy_partial_string_from(&mut self, addr: usize, n: usize) {
|
||||||
@@ -216,22 +188,6 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
HeapCellValue::Addr(Addr::StackCell(fr, sc)),
|
HeapCellValue::Addr(Addr::StackCell(fr, sc)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Addr::PStrTail(h, n) => {
|
|
||||||
match &mut self.target[h] {
|
|
||||||
HeapCellValue::PartialString(ref mut pstr) => {
|
|
||||||
pstr.tail = Addr::PStrTail(frontier, n);
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.target[frontier] = HeapCellValue::Addr(Addr::PStrTail(frontier, n));
|
|
||||||
self.trail.push((
|
|
||||||
Ref::PStrTail(h, n),
|
|
||||||
HeapCellValue::Addr(Addr::PStrTail(h, n))
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Addr::AttrVar(h) => {
|
Addr::AttrVar(h) => {
|
||||||
let threshold = if let AttrVarPolicy::DeepCopy = self.attr_var_policy {
|
let threshold = if let AttrVarPolicy::DeepCopy = self.attr_var_policy {
|
||||||
self.target.threshold()
|
self.target.threshold()
|
||||||
@@ -320,8 +276,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
}
|
}
|
||||||
addr @ Addr::AttrVar(_)
|
addr @ Addr::AttrVar(_)
|
||||||
| addr @ Addr::HeapCell(_)
|
| addr @ Addr::HeapCell(_)
|
||||||
| addr @ Addr::StackCell(..)
|
| addr @ Addr::StackCell(..) => {
|
||||||
| addr @ Addr::PStrTail(..) => {
|
|
||||||
self.copy_var(addr);
|
self.copy_var(addr);
|
||||||
}
|
}
|
||||||
Addr::Str(addr) => {
|
Addr::Str(addr) => {
|
||||||
@@ -349,10 +304,6 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
match r {
|
match r {
|
||||||
Ref::AttrVar(h) | Ref::HeapCell(h) =>
|
Ref::AttrVar(h) | Ref::HeapCell(h) =>
|
||||||
self.target[h] = value,
|
self.target[h] = value,
|
||||||
Ref::PStrTail(h, _) =>
|
|
||||||
if let HeapCellValue::PartialString(ref mut pstr) = &mut self.target[h] {
|
|
||||||
pstr.tail = value.as_addr(0);
|
|
||||||
},
|
|
||||||
Ref::StackCell(fr, sc) =>
|
Ref::StackCell(fr, sc) =>
|
||||||
self.target.stack().index_and_frame_mut(fr)[sc] = value.as_addr(0),
|
self.target.stack().index_and_frame_mut(fr)[sc] = value.as_addr(0),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -158,17 +158,8 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
return if orig_h == self.h() {
|
return if orig_h == self.h() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let prev_h = self.h() - 1;
|
let tail_h = self.h() - 1;
|
||||||
|
self[tail_h] = HeapCellValue::Addr(Addr::HeapCell(tail_h));
|
||||||
match &mut self[prev_h] {
|
|
||||||
HeapCellValue::PartialString(ref mut pstr) => {
|
|
||||||
let s = pstr.block_as_str();
|
|
||||||
pstr.tail = Addr::PStrTail(prev_h, s.len());
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(Addr::PStrLocation(orig_h, 0))
|
Some(Addr::PStrLocation(orig_h, 0))
|
||||||
};
|
};
|
||||||
@@ -176,8 +167,8 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
|
|
||||||
let h = self.h();
|
let h = self.h();
|
||||||
|
|
||||||
let (mut pstr, rest_src) =
|
let (pstr, rest_src) =
|
||||||
match PartialString::new(src, h) {
|
match PartialString::new(src) {
|
||||||
Some(tuple) => {
|
Some(tuple) => {
|
||||||
tuple
|
tuple
|
||||||
}
|
}
|
||||||
@@ -188,44 +179,19 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
} else if orig_h == h {
|
} else if orig_h == h {
|
||||||
return None;
|
return None;
|
||||||
} else {
|
} else {
|
||||||
let prev_h = h - 1;
|
self[h - 1] = HeapCellValue::Addr(Addr::HeapCell(h - 1));
|
||||||
|
|
||||||
match &mut self[prev_h] {
|
|
||||||
HeapCellValue::PartialString(ref mut pstr) => {
|
|
||||||
let s = pstr.block_as_str();
|
|
||||||
pstr.tail = Addr::PStrTail(prev_h, s.len());
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Some(Addr::PStrLocation(orig_h, 0));
|
return Some(Addr::PStrLocation(orig_h, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_top = unsafe {
|
self.push(HeapCellValue::PartialString(pstr));
|
||||||
self.buf.new_block(mem::size_of::<HeapCellValue>())
|
|
||||||
};
|
|
||||||
|
|
||||||
if rest_src != "" {
|
if rest_src != "" {
|
||||||
pstr.tail = Addr::PStrLocation(h+1, 0);
|
self.push(HeapCellValue::Addr(Addr::PStrLocation(h + 2, 0)));
|
||||||
src = rest_src;
|
src = rest_src;
|
||||||
} else {
|
} else {
|
||||||
pstr.tail = Addr::PStrTail(h, src.len());
|
self.push(HeapCellValue::Addr(Addr::HeapCell(h + 1)));
|
||||||
}
|
|
||||||
|
|
||||||
unsafe{
|
|
||||||
ptr::write(
|
|
||||||
self.buf.top as *mut _,
|
|
||||||
HeapCellValue::PartialString(pstr),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.buf.top = new_top;
|
|
||||||
|
|
||||||
if rest_src == "" {
|
|
||||||
return Some(Addr::PStrLocation(orig_h, 0));
|
return Some(Addr::PStrLocation(orig_h, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -432,7 +432,6 @@ pub(super) enum CycleSearchResult {
|
|||||||
CompleteString(usize, Rc<String>), // the string length (in bytes), the string.
|
CompleteString(usize, Rc<String>), // the string length (in bytes), the string.
|
||||||
UntouchedString(usize, Rc<String>), // the cut off, past which is the untouched string.
|
UntouchedString(usize, Rc<String>), // the cut off, past which is the untouched string.
|
||||||
PStrLocation(usize, usize, usize), // the list length (up to max), the heap offset, byte offset into the string.
|
PStrLocation(usize, usize, usize), // the list length (up to max), the heap offset, byte offset into the string.
|
||||||
PStrTail(usize, usize, usize), // the list length (up to max), the heap offset, byte offset into the string.
|
|
||||||
UntouchedList(usize), // the address of an uniterated Addr::Lis(address).
|
UntouchedList(usize), // the address of an uniterated Addr::Lis(address).
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ pub enum Addr {
|
|||||||
StackCell(usize, usize),
|
StackCell(usize, usize),
|
||||||
Str(usize),
|
Str(usize),
|
||||||
PStrLocation(usize, usize), // location of pstr in heap, offset into string in bytes.
|
PStrLocation(usize, usize), // location of pstr in heap, offset into string in bytes.
|
||||||
PStrTail(usize, usize), // location of pstr in heap, offset into string in bytes.
|
|
||||||
Stream(Stream),
|
Stream(Stream),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +57,6 @@ pub enum Ref {
|
|||||||
AttrVar(usize),
|
AttrVar(usize),
|
||||||
HeapCell(usize),
|
HeapCell(usize),
|
||||||
StackCell(usize, usize),
|
StackCell(usize, usize),
|
||||||
PStrTail(usize, usize),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ref {
|
impl Ref {
|
||||||
@@ -67,7 +65,6 @@ impl Ref {
|
|||||||
Ref::AttrVar(h) => Addr::AttrVar(h),
|
Ref::AttrVar(h) => Addr::AttrVar(h),
|
||||||
Ref::HeapCell(h) => Addr::HeapCell(h),
|
Ref::HeapCell(h) => Addr::HeapCell(h),
|
||||||
Ref::StackCell(fr, sc) => Addr::StackCell(fr, sc),
|
Ref::StackCell(fr, sc) => Addr::StackCell(fr, sc),
|
||||||
Ref::PStrTail(h, n) => Addr::PStrTail(h, n),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,7 +81,7 @@ impl PartialOrd<Ref> for Addr {
|
|||||||
match self {
|
match self {
|
||||||
&Addr::StackCell(fr, sc) => {
|
&Addr::StackCell(fr, sc) => {
|
||||||
match *r {
|
match *r {
|
||||||
Ref::AttrVar(_) | Ref::HeapCell(_) | Ref::PStrTail(..) => {
|
Ref::AttrVar(_) | Ref::HeapCell(_) => {
|
||||||
Some(Ordering::Greater)
|
Some(Ordering::Greater)
|
||||||
}
|
}
|
||||||
Ref::StackCell(fr1, sc1) => {
|
Ref::StackCell(fr1, sc1) => {
|
||||||
@@ -106,22 +103,6 @@ impl PartialOrd<Ref> for Addr {
|
|||||||
Ref::AttrVar(h1) | Ref::HeapCell(h1) => {
|
Ref::AttrVar(h1) | Ref::HeapCell(h1) => {
|
||||||
h.partial_cmp(h1)
|
h.partial_cmp(h1)
|
||||||
}
|
}
|
||||||
Ref::PStrTail(h1, _) => {
|
|
||||||
h.partial_cmp(h1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&Addr::PStrTail(h, n) => {
|
|
||||||
match r {
|
|
||||||
Ref::StackCell(..) => {
|
|
||||||
Some(Ordering::Less)
|
|
||||||
}
|
|
||||||
Ref::AttrVar(h1) | Ref::HeapCell(h1) => {
|
|
||||||
h.partial_cmp(h1)
|
|
||||||
}
|
|
||||||
Ref::PStrTail(h1, n1) => {
|
|
||||||
Some(h.cmp(h1).then_with(|| n.cmp(n1)))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -134,7 +115,7 @@ impl PartialOrd<Ref> for Addr {
|
|||||||
impl Addr {
|
impl Addr {
|
||||||
pub fn is_ref(&self) -> bool {
|
pub fn is_ref(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::AttrVar(_) | Addr::PStrTail(..) => {
|
Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::AttrVar(_) => {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -148,7 +129,6 @@ impl Addr {
|
|||||||
&Addr::AttrVar(h) => Some(Ref::AttrVar(h)),
|
&Addr::AttrVar(h) => Some(Ref::AttrVar(h)),
|
||||||
&Addr::HeapCell(h) => Some(Ref::HeapCell(h)),
|
&Addr::HeapCell(h) => Some(Ref::HeapCell(h)),
|
||||||
&Addr::StackCell(fr, sc) => Some(Ref::StackCell(fr, sc)),
|
&Addr::StackCell(fr, sc) => Some(Ref::StackCell(fr, sc)),
|
||||||
&Addr::PStrTail(h, n) => Some(Ref::PStrTail(h, n)),
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,7 +151,6 @@ impl Add<usize> for Addr {
|
|||||||
Addr::HeapCell(h) => Addr::HeapCell(h + rhs),
|
Addr::HeapCell(h) => Addr::HeapCell(h + rhs),
|
||||||
Addr::Str(s) => Addr::Str(s + rhs),
|
Addr::Str(s) => Addr::Str(s + rhs),
|
||||||
Addr::PStrLocation(h, n) => Addr::PStrLocation(h + rhs, n),
|
Addr::PStrLocation(h, n) => Addr::PStrLocation(h + rhs, n),
|
||||||
Addr::PStrTail(h, n) => Addr::PStrTail(h + rhs, n),
|
|
||||||
_ => self,
|
_ => self,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,7 +166,6 @@ impl Sub<i64> for Addr {
|
|||||||
Addr::AttrVar(h) => Addr::AttrVar(h + rhs.abs() as usize),
|
Addr::AttrVar(h) => Addr::AttrVar(h + rhs.abs() as usize),
|
||||||
Addr::HeapCell(h) => Addr::HeapCell(h + rhs.abs() as usize),
|
Addr::HeapCell(h) => Addr::HeapCell(h + rhs.abs() as usize),
|
||||||
Addr::Str(s) => Addr::Str(s + rhs.abs() as usize),
|
Addr::Str(s) => Addr::Str(s + rhs.abs() as usize),
|
||||||
Addr::PStrTail(h, n) => Addr::PStrTail(h + rhs.abs() as usize, n),
|
|
||||||
Addr::PStrLocation(h, n) => Addr::PStrLocation(h + rhs.abs() as usize, n),
|
Addr::PStrLocation(h, n) => Addr::PStrLocation(h + rhs.abs() as usize, n),
|
||||||
_ => self,
|
_ => self,
|
||||||
}
|
}
|
||||||
@@ -206,7 +184,6 @@ impl Sub<usize> for Addr {
|
|||||||
Addr::AttrVar(h) => Addr::AttrVar(h - rhs),
|
Addr::AttrVar(h) => Addr::AttrVar(h - rhs),
|
||||||
Addr::HeapCell(h) => Addr::HeapCell(h - rhs),
|
Addr::HeapCell(h) => Addr::HeapCell(h - rhs),
|
||||||
Addr::Str(s) => Addr::Str(s - rhs),
|
Addr::Str(s) => Addr::Str(s - rhs),
|
||||||
Addr::PStrTail(h, n) => Addr::PStrTail(h - rhs, n),
|
|
||||||
Addr::PStrLocation(h, n) => Addr::PStrLocation(h - rhs, n),
|
Addr::PStrLocation(h, n) => Addr::PStrLocation(h - rhs, n),
|
||||||
_ => self,
|
_ => self,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,13 +58,12 @@ impl Ball {
|
|||||||
|
|
||||||
for heap_value in self.stub.iter_from(0) {
|
for heap_value in self.stub.iter_from(0) {
|
||||||
stub.push(match heap_value {
|
stub.push(match heap_value {
|
||||||
HeapCellValue::Addr(ref addr) => HeapCellValue::Addr(addr.clone() - diff),
|
HeapCellValue::Addr(ref addr) => {
|
||||||
HeapCellValue::PartialString(ref pstr) => {
|
HeapCellValue::Addr(addr.clone() - diff)
|
||||||
let mut new_pstr = pstr.clone();
|
}
|
||||||
new_pstr.tail = pstr.tail.clone() - diff;
|
heap_value => {
|
||||||
HeapCellValue::PartialString(new_pstr)
|
heap_value.clone()
|
||||||
}
|
}
|
||||||
heap_value => heap_value.clone(),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,9 +249,9 @@ pub(super) enum MachineMode {
|
|||||||
pub(super) enum HeapPtr {
|
pub(super) enum HeapPtr {
|
||||||
HeapCell(usize),
|
HeapCell(usize),
|
||||||
PStrChar(usize, usize),
|
PStrChar(usize, usize),
|
||||||
PStrTail(usize, usize),
|
PStrLocation(usize, usize),
|
||||||
StringChar(usize, Rc<String>),
|
StringChar(usize, Rc<String>),
|
||||||
StringTail(usize, Rc<String>),
|
StringLocation(usize, Rc<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HeapPtr {
|
impl HeapPtr {
|
||||||
@@ -269,20 +268,20 @@ impl HeapPtr {
|
|||||||
if let Some(c) = s[n ..].chars().next() {
|
if let Some(c) = s[n ..].chars().next() {
|
||||||
Addr::Con(Constant::Char(c))
|
Addr::Con(Constant::Char(c))
|
||||||
} else {
|
} else {
|
||||||
Addr::PStrTail(h, n)
|
Addr::HeapCell(h + 1)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
},
|
},
|
||||||
&HeapPtr::PStrTail(h, n) =>
|
&HeapPtr::PStrLocation(h, n) =>
|
||||||
Addr::PStrTail(h, n),
|
Addr::PStrLocation(h, n),
|
||||||
&HeapPtr::StringChar(n, ref s) =>
|
&HeapPtr::StringChar(n, ref s) =>
|
||||||
if let Some(c) = s[n ..].chars().next() {
|
if let Some(c) = s[n ..].chars().next() {
|
||||||
Addr::Con(Constant::Char(c))
|
Addr::Con(Constant::Char(c))
|
||||||
} else {
|
} else {
|
||||||
Addr::Con(Constant::EmptyList)
|
Addr::Con(Constant::EmptyList)
|
||||||
},
|
},
|
||||||
&HeapPtr::StringTail(n, ref s) =>
|
&HeapPtr::StringLocation(n, ref s) =>
|
||||||
Addr::Con(Constant::String(n, s.clone())),
|
Addr::Con(Constant::String(n, s.clone())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,12 +130,12 @@ impl MachineState {
|
|||||||
Addr::StackCell(fr, sc) => {
|
Addr::StackCell(fr, sc) => {
|
||||||
self.stack.index_and_frame(fr)[sc].clone()
|
self.stack.index_and_frame(fr)[sc].clone()
|
||||||
}
|
}
|
||||||
Addr::PStrTail(h, n) => {
|
Addr::PStrLocation(h, n) => {
|
||||||
if let HeapCellValue::PartialString(ref pstr) = &self.heap[h] {
|
if let HeapCellValue::PartialString(ref pstr) = &self.heap[h] {
|
||||||
if pstr.len() > n {
|
if pstr.len() > n {
|
||||||
Addr::PStrLocation(h, n)
|
Addr::PStrLocation(h, n)
|
||||||
} else {
|
} else {
|
||||||
pstr.tail.clone()
|
Addr::HeapCell(h + 1)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -179,20 +179,6 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bind_pstr_tail(&mut self, h: usize, t2: Addr) {
|
|
||||||
let pstr_len = match &mut self.heap[h] {
|
|
||||||
HeapCellValue::PartialString(ref mut pstr) => {
|
|
||||||
pstr.tail = t2;
|
|
||||||
pstr.len()
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.trail(TrailRef::from(Ref::PStrTail(h, pstr_len)));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super)
|
pub(super)
|
||||||
fn bind(&mut self, r1: Ref, a2: Addr) {
|
fn bind(&mut self, r1: Ref, a2: Addr) {
|
||||||
let t1 = self.store(r1.as_addr());
|
let t1 = self.store(r1.as_addr());
|
||||||
@@ -209,9 +195,6 @@ impl MachineState {
|
|||||||
Ref::AttrVar(h) => {
|
Ref::AttrVar(h) => {
|
||||||
return self.bind_attr_var(h, t2);
|
return self.bind_attr_var(h, t2);
|
||||||
}
|
}
|
||||||
Ref::PStrTail(h, _) => {
|
|
||||||
return self.bind_pstr_tail(h, t2);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.trail(TrailRef::from(r1));
|
self.trail(TrailRef::from(r1));
|
||||||
@@ -228,9 +211,6 @@ impl MachineState {
|
|||||||
Some(Ref::AttrVar(h)) => {
|
Some(Ref::AttrVar(h)) => {
|
||||||
self.bind_attr_var(h, t1);
|
self.bind_attr_var(h, t1);
|
||||||
}
|
}
|
||||||
Some(Ref::PStrTail(h, _)) => {
|
|
||||||
self.bind_pstr_tail(h, t1);
|
|
||||||
}
|
|
||||||
None => {
|
None => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -308,9 +288,6 @@ impl MachineState {
|
|||||||
(Addr::StackCell(fr, sc), addr) | (addr, Addr::StackCell(fr, sc)) => {
|
(Addr::StackCell(fr, sc), addr) | (addr, Addr::StackCell(fr, sc)) => {
|
||||||
self.bind_with_occurs_check(Ref::StackCell(fr, sc), addr)
|
self.bind_with_occurs_check(Ref::StackCell(fr, sc), addr)
|
||||||
}
|
}
|
||||||
(Addr::PStrTail(h, n), addr) | (addr, Addr::PStrTail(h, n)) => {
|
|
||||||
self.bind_with_occurs_check(Ref::PStrTail(h, n), addr);
|
|
||||||
}
|
|
||||||
(Addr::Lis(a1), Addr::Str(a2)) | (Addr::Str(a2), Addr::Lis(a1)) => {
|
(Addr::Lis(a1), Addr::Str(a2)) | (Addr::Str(a2), Addr::Lis(a1)) => {
|
||||||
if let &HeapCellValue::NamedStr(n2, ref f2, _) = &self.heap[a2] {
|
if let &HeapCellValue::NamedStr(n2, ref f2, _) = &self.heap[a2] {
|
||||||
if f2.as_str() == "." && n2 == 2 {
|
if f2.as_str() == "." && n2 == 2 {
|
||||||
@@ -352,7 +329,7 @@ impl MachineState {
|
|||||||
let s = pstr.block_as_str();
|
let s = pstr.block_as_str();
|
||||||
|
|
||||||
if let Some(c) = s[n ..].chars().next() {
|
if let Some(c) = s[n ..].chars().next() {
|
||||||
pdl.push(Addr::PStrTail(h, n + c.len_utf8()));
|
pdl.push(Addr::PStrLocation(h, n + c.len_utf8()));
|
||||||
pdl.push(Addr::HeapCell(l + 1));
|
pdl.push(Addr::HeapCell(l + 1));
|
||||||
|
|
||||||
pdl.push(Addr::Con(Constant::Char(c)));
|
pdl.push(Addr::Con(Constant::Char(c)));
|
||||||
@@ -366,16 +343,21 @@ impl MachineState {
|
|||||||
if let HeapCellValue::PartialString(ref pstr) = &self.heap[h] {
|
if let HeapCellValue::PartialString(ref pstr) = &self.heap[h] {
|
||||||
let pstr_s = pstr.block_as_str();
|
let pstr_s = pstr.block_as_str();
|
||||||
|
|
||||||
if let Some(c) = pstr_s[n ..].chars().next() {
|
let pstr_len = pstr_s[n ..].len();
|
||||||
if let Some(c1) = s[n1 ..].chars().next() {
|
let s_len = s[n1 ..].len();
|
||||||
if c == c1 {
|
let m_len = std::cmp::min(s_len, pstr_len);
|
||||||
pdl.push(Addr::Con(Constant::String(n1 + c.len_utf8(), s)));
|
|
||||||
pdl.push(Addr::PStrTail(h, n + c.len_utf8()));
|
if pstr_s[n .. n + m_len] == s[n1 .. n1 + m_len] {
|
||||||
|
if s_len <= pstr_len {
|
||||||
|
pdl.push(Addr::Con(Constant::EmptyList));
|
||||||
|
pdl.push(Addr::PStrLocation(h, n + m_len));
|
||||||
|
} else {
|
||||||
|
pdl.push(Addr::Con(Constant::String(n1 + m_len, s)));
|
||||||
|
pdl.push(Addr::HeapCell(h + 1));
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.fail = true;
|
self.fail = true;
|
||||||
break;
|
break;
|
||||||
@@ -387,16 +369,21 @@ impl MachineState {
|
|||||||
let pstr_s1 = pstr1.block_as_str();
|
let pstr_s1 = pstr1.block_as_str();
|
||||||
let pstr_s2 = pstr2.block_as_str();
|
let pstr_s2 = pstr2.block_as_str();
|
||||||
|
|
||||||
if let Some(c1) = pstr_s1[n1 ..].chars().next() {
|
let pstr_s1_len = pstr_s1[n1 ..].len();
|
||||||
if let Some(c2) = pstr_s2[n2 ..].chars().next() {
|
let pstr_s2_len = pstr_s2[n2 ..].len();
|
||||||
if c1 == c2 {
|
let m_len = std::cmp::min(pstr_s1_len, pstr_s2_len);
|
||||||
pdl.push(Addr::PStrTail(h1, n1 + c1.len_utf8()));
|
|
||||||
pdl.push(Addr::PStrTail(h2, n2 + c2.len_utf8()));
|
if pstr_s1[n1 .. n1 + m_len] == pstr_s2[n2 .. n2 + m_len] {
|
||||||
|
if pstr_s1_len <= pstr_s2_len {
|
||||||
|
pdl.push(Addr::HeapCell(h1 + 1));
|
||||||
|
pdl.push(Addr::PStrLocation(h2, n2 + m_len));
|
||||||
|
} else {
|
||||||
|
pdl.push(Addr::HeapCell(h2 + 1));
|
||||||
|
pdl.push(Addr::PStrLocation(h1, n1 + m_len));
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.fail = true;
|
self.fail = true;
|
||||||
break;
|
break;
|
||||||
@@ -472,9 +459,6 @@ impl MachineState {
|
|||||||
(Addr::StackCell(fr, sc), addr) | (addr, Addr::StackCell(fr, sc)) => {
|
(Addr::StackCell(fr, sc), addr) | (addr, Addr::StackCell(fr, sc)) => {
|
||||||
self.bind(Ref::StackCell(fr, sc), addr);
|
self.bind(Ref::StackCell(fr, sc), addr);
|
||||||
}
|
}
|
||||||
(Addr::PStrTail(h, n), addr) | (addr, Addr::PStrTail(h, n)) => {
|
|
||||||
self.bind(Ref::PStrTail(h, n), addr);
|
|
||||||
}
|
|
||||||
(Addr::Lis(a1), Addr::Str(a2)) | (Addr::Str(a2), Addr::Lis(a1)) => {
|
(Addr::Lis(a1), Addr::Str(a2)) | (Addr::Str(a2), Addr::Lis(a1)) => {
|
||||||
if let &HeapCellValue::NamedStr(n2, ref f2, _) = &self.heap[a2] {
|
if let &HeapCellValue::NamedStr(n2, ref f2, _) = &self.heap[a2] {
|
||||||
if f2.as_str() == "." && n2 == 2 {
|
if f2.as_str() == "." && n2 == 2 {
|
||||||
@@ -515,7 +499,7 @@ impl MachineState {
|
|||||||
let s = pstr.block_as_str();
|
let s = pstr.block_as_str();
|
||||||
|
|
||||||
if let Some(c) = s[n ..].chars().next() {
|
if let Some(c) = s[n ..].chars().next() {
|
||||||
pdl.push(Addr::PStrTail(h, n + c.len_utf8()));
|
pdl.push(Addr::PStrLocation(h, n + c.len_utf8()));
|
||||||
pdl.push(Addr::HeapCell(l + 1));
|
pdl.push(Addr::HeapCell(l + 1));
|
||||||
|
|
||||||
pdl.push(Addr::Con(Constant::Char(c)));
|
pdl.push(Addr::Con(Constant::Char(c)));
|
||||||
@@ -529,16 +513,21 @@ impl MachineState {
|
|||||||
if let HeapCellValue::PartialString(ref pstr) = &self.heap[h] {
|
if let HeapCellValue::PartialString(ref pstr) = &self.heap[h] {
|
||||||
let pstr_s = pstr.block_as_str();
|
let pstr_s = pstr.block_as_str();
|
||||||
|
|
||||||
if let Some(c) = pstr_s[n ..].chars().next() {
|
let pstr_len = pstr_s[n ..].len();
|
||||||
if let Some(c1) = s[n1 ..].chars().next() {
|
let s_len = s[n1 ..].len();
|
||||||
if c == c1 {
|
let m_len = std::cmp::min(s_len, pstr_len);
|
||||||
pdl.push(Addr::Con(Constant::String(n1 + c.len_utf8(), s)));
|
|
||||||
pdl.push(Addr::PStrTail(h, n + c.len_utf8()));
|
if pstr_s[n .. n + m_len] == s[n1 .. n1 + m_len] {
|
||||||
|
if s_len <= pstr_len {
|
||||||
|
pdl.push(Addr::Con(Constant::EmptyList));
|
||||||
|
pdl.push(Addr::PStrLocation(h, n + m_len));
|
||||||
|
} else {
|
||||||
|
pdl.push(Addr::Con(Constant::String(n1 + m_len, s)));
|
||||||
|
pdl.push(Addr::HeapCell(h + 1));
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.fail = true;
|
self.fail = true;
|
||||||
break;
|
break;
|
||||||
@@ -550,16 +539,21 @@ impl MachineState {
|
|||||||
let pstr_s1 = pstr1.block_as_str();
|
let pstr_s1 = pstr1.block_as_str();
|
||||||
let pstr_s2 = pstr2.block_as_str();
|
let pstr_s2 = pstr2.block_as_str();
|
||||||
|
|
||||||
if let Some(c1) = pstr_s1[n1 ..].chars().next() {
|
let pstr_s1_len = pstr_s1[n1 ..].len();
|
||||||
if let Some(c2) = pstr_s2[n2 ..].chars().next() {
|
let pstr_s2_len = pstr_s2[n2 ..].len();
|
||||||
if c1 == c2 {
|
let m_len = std::cmp::min(pstr_s1_len, pstr_s2_len);
|
||||||
pdl.push(Addr::PStrTail(h1, n1 + c1.len_utf8()));
|
|
||||||
pdl.push(Addr::PStrTail(h2, n2 + c2.len_utf8()));
|
if pstr_s1[n1 .. n1 + m_len] == pstr_s2[n2 .. n2 + m_len] {
|
||||||
|
if pstr_s1_len <= pstr_s2_len {
|
||||||
|
pdl.push(Addr::HeapCell(h1 + 1));
|
||||||
|
pdl.push(Addr::PStrLocation(h2, n2 + m_len));
|
||||||
|
} else {
|
||||||
|
pdl.push(Addr::HeapCell(h2 + 1));
|
||||||
|
pdl.push(Addr::PStrLocation(h1, n1 + m_len));
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.fail = true;
|
self.fail = true;
|
||||||
break;
|
break;
|
||||||
@@ -618,12 +612,6 @@ impl MachineState {
|
|||||||
self.tr += 1;
|
self.tr += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TrailRef::Ref(Ref::PStrTail(h, n)) => {
|
|
||||||
if h < self.hb {
|
|
||||||
self.trail.push(TrailRef::Ref(Ref::PStrTail(h, n)));
|
|
||||||
self.tr += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TrailRef::AttrVarHeapLink(h) => {
|
TrailRef::AttrVarHeapLink(h) => {
|
||||||
if h < self.hb {
|
if h < self.hb {
|
||||||
self.trail.push(TrailRef::AttrVarHeapLink(h));
|
self.trail.push(TrailRef::AttrVarHeapLink(h));
|
||||||
@@ -650,7 +638,7 @@ impl MachineState {
|
|||||||
HeapPtr::HeapCell(ref mut h) => {
|
HeapPtr::HeapCell(ref mut h) => {
|
||||||
*h += rhs;
|
*h += rhs;
|
||||||
}
|
}
|
||||||
HeapPtr::PStrChar(h, n) | HeapPtr::PStrTail(h, n) => {
|
HeapPtr::PStrChar(h, n) | HeapPtr::PStrLocation(h, n) => {
|
||||||
match &self.heap[*h] {
|
match &self.heap[*h] {
|
||||||
HeapCellValue::PartialString(ref pstr) => {
|
HeapCellValue::PartialString(ref pstr) => {
|
||||||
let s = pstr.block_as_str();
|
let s = pstr.block_as_str();
|
||||||
@@ -659,19 +647,19 @@ impl MachineState {
|
|||||||
*n += c.len_utf8();
|
*n += c.len_utf8();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.s = HeapPtr::PStrTail(*h, *n);
|
self.s = HeapPtr::PStrLocation(*h, *n);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HeapPtr::StringChar(n, s) | HeapPtr::StringTail(n, s) => {
|
HeapPtr::StringChar(n, s) | HeapPtr::StringLocation(n, s) => {
|
||||||
for c in s[*n ..].chars().take(rhs) {
|
for c in s[*n ..].chars().take(rhs) {
|
||||||
*n += c.len_utf8();
|
*n += c.len_utf8();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.s = HeapPtr::StringTail(*n, s.clone());
|
self.s = HeapPtr::StringLocation(*n, s.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -692,14 +680,6 @@ impl MachineState {
|
|||||||
TrailRef::Ref(Ref::StackCell(fr, sc)) => {
|
TrailRef::Ref(Ref::StackCell(fr, sc)) => {
|
||||||
self.stack.index_and_frame_mut(fr)[sc] = Addr::StackCell(fr, sc)
|
self.stack.index_and_frame_mut(fr)[sc] = Addr::StackCell(fr, sc)
|
||||||
}
|
}
|
||||||
TrailRef::Ref(Ref::PStrTail(h, n)) => {
|
|
||||||
if let HeapCellValue::PartialString(ref mut pstr) = &mut self.heap[h] {
|
|
||||||
pstr.truncate(n);
|
|
||||||
pstr.tail = Addr::PStrTail(h, n);
|
|
||||||
|
|
||||||
self.tr += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TrailRef::AttrVarHeapLink(h) => {
|
TrailRef::AttrVarHeapLink(h) => {
|
||||||
self.heap[h] = HeapCellValue::Addr(Addr::HeapCell(h));
|
self.heap[h] = HeapCellValue::Addr(Addr::HeapCell(h));
|
||||||
}
|
}
|
||||||
@@ -724,7 +704,6 @@ impl MachineState {
|
|||||||
match self.trail[i] {
|
match self.trail[i] {
|
||||||
TrailRef::Ref(Ref::AttrVar(tr_i))
|
TrailRef::Ref(Ref::AttrVar(tr_i))
|
||||||
| TrailRef::Ref(Ref::HeapCell(tr_i))
|
| TrailRef::Ref(Ref::HeapCell(tr_i))
|
||||||
| TrailRef::Ref(Ref::PStrTail(tr_i, _))
|
|
||||||
| TrailRef::AttrVarHeapLink(tr_i)
|
| TrailRef::AttrVarHeapLink(tr_i)
|
||||||
| TrailRef::AttrVarListLink(tr_i, _) => {
|
| TrailRef::AttrVarListLink(tr_i, _) => {
|
||||||
if tr_i >= hb {
|
if tr_i >= hb {
|
||||||
@@ -1623,8 +1602,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
addr @ Addr::AttrVar(_)
|
addr @ Addr::AttrVar(_)
|
||||||
| addr @ Addr::StackCell(..)
|
| addr @ Addr::StackCell(..)
|
||||||
| addr @ Addr::HeapCell(_)
|
| addr @ Addr::HeapCell(_) => {
|
||||||
| addr @ Addr::PStrTail(..) => {
|
|
||||||
let h = self.heap.h();
|
let h = self.heap.h();
|
||||||
|
|
||||||
self.heap.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
|
self.heap.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
|
||||||
@@ -1768,8 +1746,7 @@ impl MachineState {
|
|||||||
|
|
||||||
let offset = match addr {
|
let offset = match addr {
|
||||||
Addr::HeapCell(_) | Addr::StackCell(..)
|
Addr::HeapCell(_) | Addr::StackCell(..)
|
||||||
| Addr::AttrVar(..) | Addr::PStrTail(..)
|
| Addr::AttrVar(..) | Addr::Stream(_) => {
|
||||||
| Addr::Stream(_) => {
|
|
||||||
v
|
v
|
||||||
}
|
}
|
||||||
Addr::Con(Constant::String(n, ref s)) => {
|
Addr::Con(Constant::String(n, ref s)) => {
|
||||||
@@ -2042,7 +2019,7 @@ impl MachineState {
|
|||||||
let n = self.store(self.deref(self[temp_v!(1)].clone()));
|
let n = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||||
|
|
||||||
match n {
|
match n {
|
||||||
Addr::HeapCell(_) | Addr::StackCell(..) | Addr::PStrTail(..) =>
|
Addr::HeapCell(_) | Addr::StackCell(..) =>
|
||||||
// 8.5.2.3 a)
|
// 8.5.2.3 a)
|
||||||
{
|
{
|
||||||
return Err(self.error_form(MachineError::instantiation_error(), stub))
|
return Err(self.error_form(MachineError::instantiation_error(), stub))
|
||||||
@@ -2067,7 +2044,7 @@ impl MachineState {
|
|||||||
let term = self.store(self.deref(self[temp_v!(2)].clone()));
|
let term = self.store(self.deref(self[temp_v!(2)].clone()));
|
||||||
|
|
||||||
match term {
|
match term {
|
||||||
Addr::HeapCell(_) | Addr::StackCell(..) | Addr::PStrTail(..) =>
|
Addr::HeapCell(_) | Addr::StackCell(..) =>
|
||||||
// 8.5.2.3 b)
|
// 8.5.2.3 b)
|
||||||
{
|
{
|
||||||
return Err(self.error_form(MachineError::instantiation_error(), stub))
|
return Err(self.error_form(MachineError::instantiation_error(), stub))
|
||||||
@@ -2102,7 +2079,7 @@ impl MachineState {
|
|||||||
if n == 1 {
|
if n == 1 {
|
||||||
Addr::Con(Constant::Char(c))
|
Addr::Con(Constant::Char(c))
|
||||||
} else {
|
} else {
|
||||||
Addr::PStrTail(h, offset + c.len_utf8())
|
Addr::PStrLocation(h, offset + c.len_utf8())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -2137,15 +2114,20 @@ impl MachineState {
|
|||||||
_ =>
|
_ =>
|
||||||
// 8.5.2.3 d)
|
// 8.5.2.3 d)
|
||||||
{
|
{
|
||||||
return Err(self
|
return Err(self.error_form(
|
||||||
.error_form(MachineError::type_error(ValidType::Compound, term), stub))
|
MachineError::type_error(ValidType::Compound, term),
|
||||||
|
stub,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ =>
|
_ =>
|
||||||
// 8.5.2.3 c)
|
// 8.5.2.3 c)
|
||||||
{
|
{
|
||||||
return Err(self.error_form(MachineError::type_error(ValidType::Integer, n), stub))
|
return Err(self.error_form(
|
||||||
|
MachineError::type_error(ValidType::Integer, n),
|
||||||
|
stub,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2247,32 +2229,8 @@ impl MachineState {
|
|||||||
| (
|
| (
|
||||||
HeapCellValue::Addr(Addr::PStrLocation(..)),
|
HeapCellValue::Addr(Addr::PStrLocation(..)),
|
||||||
HeapCellValue::Addr(Addr::PStrLocation(..)),
|
HeapCellValue::Addr(Addr::PStrLocation(..)),
|
||||||
)
|
|
||||||
| (
|
|
||||||
HeapCellValue::Addr(Addr::PStrTail(..)),
|
|
||||||
HeapCellValue::Addr(Addr::PStrTail(..)),
|
|
||||||
) => {
|
) => {
|
||||||
}
|
}
|
||||||
(
|
|
||||||
HeapCellValue::Addr(Addr::PStrLocation(h1, _)),
|
|
||||||
HeapCellValue::Addr(Addr::PStrTail(h2, _)),
|
|
||||||
) => {
|
|
||||||
return if h1 == h2 {
|
|
||||||
Ordering::Less
|
|
||||||
} else {
|
|
||||||
h1.cmp(&h2)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
(
|
|
||||||
HeapCellValue::Addr(Addr::PStrTail(h2, _)),
|
|
||||||
HeapCellValue::Addr(Addr::PStrLocation(h1, _)),
|
|
||||||
) => {
|
|
||||||
return if h1 == h2 {
|
|
||||||
Ordering::Greater
|
|
||||||
} else {
|
|
||||||
h2.cmp(&h1)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
(
|
(
|
||||||
HeapCellValue::Addr(Addr::PStrLocation(..)),
|
HeapCellValue::Addr(Addr::PStrLocation(..)),
|
||||||
HeapCellValue::Addr(Addr::Con(Constant::String(..))),
|
HeapCellValue::Addr(Addr::Con(Constant::String(..))),
|
||||||
@@ -2359,29 +2317,8 @@ impl MachineState {
|
|||||||
return hc1.cmp(&hc2);
|
return hc1.cmp(&hc2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(
|
|
||||||
HeapCellValue::Addr(Addr::PStrTail(hc1, _)),
|
|
||||||
HeapCellValue::Addr(Addr::HeapCell(hc2)),
|
|
||||||
)
|
|
||||||
| (
|
|
||||||
HeapCellValue::Addr(Addr::HeapCell(hc1)),
|
|
||||||
HeapCellValue::Addr(Addr::PStrTail(hc2, _)),
|
|
||||||
)
|
|
||||||
| (
|
|
||||||
HeapCellValue::Addr(Addr::PStrTail(hc1, _)),
|
|
||||||
HeapCellValue::Addr(Addr::AttrVar(hc2)),
|
|
||||||
)
|
|
||||||
| (
|
|
||||||
HeapCellValue::Addr(Addr::AttrVar(hc1)),
|
|
||||||
HeapCellValue::Addr(Addr::PStrTail(hc2, _)),
|
|
||||||
) => {
|
|
||||||
if hc1 != hc2 {
|
|
||||||
return hc1.cmp(&hc2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(HeapCellValue::Addr(Addr::HeapCell(_)), _)
|
(HeapCellValue::Addr(Addr::HeapCell(_)), _)
|
||||||
| (HeapCellValue::Addr(Addr::AttrVar(_)), _)
|
| (HeapCellValue::Addr(Addr::AttrVar(_)), _) => {
|
||||||
| (HeapCellValue::Addr(Addr::PStrTail(..)), _) => {
|
|
||||||
return Ordering::Less;
|
return Ordering::Less;
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
@@ -2400,10 +2337,6 @@ impl MachineState {
|
|||||||
HeapCellValue::Addr(Addr::StackCell(..)),
|
HeapCellValue::Addr(Addr::StackCell(..)),
|
||||||
HeapCellValue::Addr(Addr::HeapCell(_)),
|
HeapCellValue::Addr(Addr::HeapCell(_)),
|
||||||
)
|
)
|
||||||
| (
|
|
||||||
HeapCellValue::Addr(Addr::StackCell(..)),
|
|
||||||
HeapCellValue::Addr(Addr::PStrTail(..)),
|
|
||||||
)
|
|
||||||
| (
|
| (
|
||||||
HeapCellValue::Addr(Addr::StackCell(..)),
|
HeapCellValue::Addr(Addr::StackCell(..)),
|
||||||
HeapCellValue::Addr(Addr::AttrVar(_)),
|
HeapCellValue::Addr(Addr::AttrVar(_)),
|
||||||
@@ -2420,11 +2353,7 @@ impl MachineState {
|
|||||||
| (
|
| (
|
||||||
HeapCellValue::Addr(Addr::Con(Constant::Integer(..))),
|
HeapCellValue::Addr(Addr::Con(Constant::Integer(..))),
|
||||||
HeapCellValue::Addr(Addr::AttrVar(_)),
|
HeapCellValue::Addr(Addr::AttrVar(_)),
|
||||||
)
|
) => {
|
||||||
| (
|
|
||||||
HeapCellValue::Addr(Addr::Con(Constant::Integer(..))),
|
|
||||||
HeapCellValue::Addr(Addr::PStrTail(..)),
|
|
||||||
)=> {
|
|
||||||
return Ordering::Greater;
|
return Ordering::Greater;
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
@@ -2441,7 +2370,9 @@ impl MachineState {
|
|||||||
return n1.cmp(&n2);
|
return n1.cmp(&n2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(HeapCellValue::Addr(Addr::Con(Constant::Integer(_))), _) => return Ordering::Less,
|
(HeapCellValue::Addr(Addr::Con(Constant::Integer(_))), _) => {
|
||||||
|
return Ordering::Less;
|
||||||
|
}
|
||||||
(
|
(
|
||||||
HeapCellValue::Addr(Addr::Con(Constant::Float(..))),
|
HeapCellValue::Addr(Addr::Con(Constant::Float(..))),
|
||||||
HeapCellValue::Addr(Addr::HeapCell(_)),
|
HeapCellValue::Addr(Addr::HeapCell(_)),
|
||||||
@@ -2449,10 +2380,6 @@ impl MachineState {
|
|||||||
| (
|
| (
|
||||||
HeapCellValue::Addr(Addr::Con(Constant::Float(..))),
|
HeapCellValue::Addr(Addr::Con(Constant::Float(..))),
|
||||||
HeapCellValue::Addr(Addr::AttrVar(_)),
|
HeapCellValue::Addr(Addr::AttrVar(_)),
|
||||||
)
|
|
||||||
| (
|
|
||||||
HeapCellValue::Addr(Addr::Con(Constant::Float(..))),
|
|
||||||
HeapCellValue::Addr(Addr::PStrTail(..)),
|
|
||||||
) => {
|
) => {
|
||||||
return Ordering::Greater;
|
return Ordering::Greater;
|
||||||
}
|
}
|
||||||
@@ -2478,10 +2405,6 @@ impl MachineState {
|
|||||||
| (
|
| (
|
||||||
HeapCellValue::Addr(Addr::Con(Constant::Rational(..))),
|
HeapCellValue::Addr(Addr::Con(Constant::Rational(..))),
|
||||||
HeapCellValue::Addr(Addr::AttrVar(_)),
|
HeapCellValue::Addr(Addr::AttrVar(_)),
|
||||||
)
|
|
||||||
| (
|
|
||||||
HeapCellValue::Addr(Addr::Con(Constant::Rational(..))),
|
|
||||||
HeapCellValue::Addr(Addr::PStrTail(..)),
|
|
||||||
) => {
|
) => {
|
||||||
return Ordering::Greater;
|
return Ordering::Greater;
|
||||||
}
|
}
|
||||||
@@ -2509,10 +2432,6 @@ impl MachineState {
|
|||||||
| (
|
| (
|
||||||
HeapCellValue::Addr(Addr::Con(Constant::String(..))),
|
HeapCellValue::Addr(Addr::Con(Constant::String(..))),
|
||||||
HeapCellValue::Addr(Addr::AttrVar(_)),
|
HeapCellValue::Addr(Addr::AttrVar(_)),
|
||||||
)
|
|
||||||
| (
|
|
||||||
HeapCellValue::Addr(Addr::Con(Constant::String(..))),
|
|
||||||
HeapCellValue::Addr(Addr::PStrTail(..)),
|
|
||||||
) => {
|
) => {
|
||||||
return Ordering::Greater;
|
return Ordering::Greater;
|
||||||
}
|
}
|
||||||
@@ -2561,10 +2480,6 @@ impl MachineState {
|
|||||||
HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
|
HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
|
||||||
HeapCellValue::Addr(Addr::StackCell(..)),
|
HeapCellValue::Addr(Addr::StackCell(..)),
|
||||||
) => return Ordering::Greater,
|
) => return Ordering::Greater,
|
||||||
(
|
|
||||||
HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
|
|
||||||
HeapCellValue::Addr(Addr::PStrTail(..)),
|
|
||||||
) => return Ordering::Greater,
|
|
||||||
(
|
(
|
||||||
HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
|
HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
|
||||||
HeapCellValue::Addr(Addr::Con(Constant::Float(_))),
|
HeapCellValue::Addr(Addr::Con(Constant::Float(_))),
|
||||||
@@ -2616,8 +2531,12 @@ impl MachineState {
|
|||||||
return n.as_str().cmp(".");
|
return n.as_str().cmp(".");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(HeapCellValue::NamedStr(..), _) => return Ordering::Greater,
|
(HeapCellValue::NamedStr(..), _) => {
|
||||||
(HeapCellValue::Addr(Addr::Lis(_)), _) => return Ordering::Greater,
|
return Ordering::Greater;
|
||||||
|
}
|
||||||
|
(HeapCellValue::Addr(Addr::Lis(_)), _) => {
|
||||||
|
return Ordering::Greater;
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2711,7 +2630,7 @@ impl MachineState {
|
|||||||
let d = self.store(self.deref(self[r1].clone()));
|
let d = self.store(self.deref(self[r1].clone()));
|
||||||
|
|
||||||
match d {
|
match d {
|
||||||
Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(..) | Addr::PStrTail(..) => {
|
Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(..) => {
|
||||||
self.fail = true;
|
self.fail = true;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -2723,7 +2642,7 @@ impl MachineState {
|
|||||||
let d = self.store(self.deref(self[r1].clone()));
|
let d = self.store(self.deref(self[r1].clone()));
|
||||||
|
|
||||||
match d {
|
match d {
|
||||||
Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::PStrTail(..) => {
|
Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => {
|
||||||
self.p += 1;
|
self.p += 1;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -2809,7 +2728,7 @@ impl MachineState {
|
|||||||
let shared_op_desc = fetch_op_spec(clause_name!("."), 2, None, &indices.op_dir);
|
let shared_op_desc = fetch_op_spec(clause_name!("."), 2, None, &indices.op_dir);
|
||||||
self.try_functor_compound_case(clause_name!("."), 2, shared_op_desc)
|
self.try_functor_compound_case(clause_name!("."), 2, shared_op_desc)
|
||||||
}
|
}
|
||||||
Addr::AttrVar(..) | Addr::HeapCell(_) | Addr::StackCell(..) | Addr::PStrTail(..) => {
|
Addr::AttrVar(..) | Addr::HeapCell(_) | Addr::StackCell(..) => {
|
||||||
let name = self.store(self.deref(self[temp_v!(2)].clone()));
|
let name = self.store(self.deref(self[temp_v!(2)].clone()));
|
||||||
let arity = self.store(self.deref(self[temp_v!(3)].clone()));
|
let arity = self.store(self.deref(self[temp_v!(3)].clone()));
|
||||||
|
|
||||||
@@ -2911,9 +2830,12 @@ impl MachineState {
|
|||||||
Addr::Lis(l) => {
|
Addr::Lis(l) => {
|
||||||
self.try_from_inner_list(vec![], l, caller, a1)
|
self.try_from_inner_list(vec![], l, caller, a1)
|
||||||
}
|
}
|
||||||
Addr::Con(Constant::String(n, ref s)) if !self.flags.double_quotes.is_atom() => {
|
Addr::Con(Constant::String(n, ref s))
|
||||||
|
if !self.flags.double_quotes.is_atom() => {
|
||||||
if s.len() > n {
|
if s.len() > n {
|
||||||
Ok(Vec::from_iter(s[n ..].chars().map(|c| Addr::Con(Constant::Char(c)))))
|
Ok(Vec::from_iter(s[n ..].chars().map(|c| {
|
||||||
|
Addr::Con(Constant::Char(c))
|
||||||
|
})))
|
||||||
} else {
|
} else {
|
||||||
Ok(vec![])
|
Ok(vec![])
|
||||||
}
|
}
|
||||||
@@ -2921,7 +2843,7 @@ impl MachineState {
|
|||||||
Addr::PStrLocation(h, n) => {
|
Addr::PStrLocation(h, n) => {
|
||||||
self.try_from_partial_string(vec![], h, n, caller, a1)
|
self.try_from_partial_string(vec![], h, n, caller, a1)
|
||||||
}
|
}
|
||||||
Addr::HeapCell(_) | Addr::StackCell(..) | Addr::PStrTail(..) => {
|
Addr::HeapCell(_) | Addr::StackCell(..) => {
|
||||||
Err(self.error_form(MachineError::instantiation_error(), caller))
|
Err(self.error_form(MachineError::instantiation_error(), caller))
|
||||||
}
|
}
|
||||||
Addr::Con(Constant::EmptyList) => {
|
Addr::Con(Constant::EmptyList) => {
|
||||||
@@ -3002,7 +2924,9 @@ impl MachineState {
|
|||||||
|
|
||||||
chars.extend(s[n ..].chars().map(|c| Addr::Con(Constant::Char(c))));
|
chars.extend(s[n ..].chars().map(|c| Addr::Con(Constant::Char(c))));
|
||||||
|
|
||||||
match self.store(self.deref(pstr.tail.clone())) {
|
let tail = self.heap[h + 1].as_addr(h + 1);
|
||||||
|
|
||||||
|
match self.store(self.deref(tail)) {
|
||||||
Addr::Con(Constant::EmptyList) => {
|
Addr::Con(Constant::EmptyList) => {
|
||||||
return Ok(chars);
|
return Ok(chars);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use crate::prolog::machine::machine_indices::*;
|
|
||||||
use crate::prolog::machine::raw_block::*;
|
use crate::prolog::machine::raw_block::*;
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
@@ -22,7 +21,6 @@ impl RawBlockTraits for PartialStringTraits {
|
|||||||
|
|
||||||
pub struct PartialString {
|
pub struct PartialString {
|
||||||
pub(super) buf: RawBlock<PartialStringTraits>,
|
pub(super) buf: RawBlock<PartialStringTraits>,
|
||||||
pub(super) tail: Addr,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for PartialString {
|
impl Clone for PartialString {
|
||||||
@@ -55,10 +53,9 @@ fn scan_for_terminator(src: &str) -> usize {
|
|||||||
|
|
||||||
impl PartialString {
|
impl PartialString {
|
||||||
pub(super)
|
pub(super)
|
||||||
fn new(src: &str, h: usize) -> Option<(Self, &str)> {
|
fn new(src: &str) -> Option<(Self, &str)> {
|
||||||
let pstr = PartialString {
|
let pstr = PartialString {
|
||||||
buf: RawBlock::with_capacity(src.len() + '\u{0}'.len_utf8()),
|
buf: RawBlock::with_capacity(src.len() + '\u{0}'.len_utf8()),
|
||||||
tail: Addr::PStrTail(h, 0),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -91,14 +88,10 @@ impl PartialString {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ordinarily cloning of heap cell values is done in copy_term,
|
|
||||||
* so we rely on it to set the tail correctly. here it's set to PStrTail(0, 0),
|
|
||||||
* because we don't know its heap location. */
|
|
||||||
pub(super)
|
pub(super)
|
||||||
fn clone_from_offset(&self, n: usize) -> Self {
|
fn clone_from_offset(&self, n: usize) -> Self {
|
||||||
let mut pstr = PartialString {
|
let mut pstr = PartialString {
|
||||||
buf: RawBlock::with_capacity(self.len() + '\u{0}'.len_utf8()),
|
buf: RawBlock::with_capacity(self.len() + '\u{0}'.len_utf8()),
|
||||||
tail: Addr::PStrTail(0, 0),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -140,22 +133,8 @@ impl PartialString {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub(crate)
|
|
||||||
fn tail_addr(&self) -> &Addr {
|
|
||||||
&self.tail
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.buf.top as usize - self.buf.base as usize
|
self.buf.top as usize - self.buf.base as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn truncate(&mut self, len: usize) {
|
|
||||||
if (len + self.buf.base as usize) < self.buf.top as usize {
|
|
||||||
self.buf.top = (len + self.buf.base as usize) as *const _;
|
|
||||||
self.write_terminator_at(len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,10 +83,8 @@ impl BrentAlgState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn step(&mut self, hare: Addr) -> Option<CycleSearchResult> {
|
#[inline]
|
||||||
self.hare = hare;
|
fn conclude_or_move_tortoise(&mut self) -> Option<CycleSearchResult> {
|
||||||
self.steps += 1;
|
|
||||||
|
|
||||||
if self.tortoise == self.hare {
|
if self.tortoise == self.hare {
|
||||||
return Some(CycleSearchResult::NotList);
|
return Some(CycleSearchResult::NotList);
|
||||||
} else if self.steps == self.power {
|
} else if self.steps == self.power {
|
||||||
@@ -94,10 +92,17 @@ impl BrentAlgState {
|
|||||||
self.power <<= 1;
|
self.power <<= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn step(&mut self, hare: Addr) -> Option<CycleSearchResult> {
|
||||||
|
self.hare = hare;
|
||||||
|
self.steps += 1;
|
||||||
|
|
||||||
|
self.conclude_or_move_tortoise()
|
||||||
|
}
|
||||||
|
|
||||||
fn to_result(self) -> CycleSearchResult {
|
fn to_result(self) -> CycleSearchResult {
|
||||||
match self.hare {
|
match self.hare {
|
||||||
addr @ Addr::HeapCell(_) | addr @ Addr::StackCell(..) | addr @ Addr::AttrVar(_) => {
|
addr @ Addr::HeapCell(_) | addr @ Addr::StackCell(..) | addr @ Addr::AttrVar(_) => {
|
||||||
@@ -106,9 +111,6 @@ impl BrentAlgState {
|
|||||||
Addr::PStrLocation(h, n) => {
|
Addr::PStrLocation(h, n) => {
|
||||||
CycleSearchResult::PStrLocation(self.steps, h, n)
|
CycleSearchResult::PStrLocation(self.steps, h, n)
|
||||||
}
|
}
|
||||||
Addr::PStrTail(h, n) => {
|
|
||||||
CycleSearchResult::PStrTail(self.steps, h, n)
|
|
||||||
}
|
|
||||||
Addr::Con(Constant::EmptyList) => {
|
Addr::Con(Constant::EmptyList) => {
|
||||||
CycleSearchResult::ProperList(self.steps)
|
CycleSearchResult::ProperList(self.steps)
|
||||||
}
|
}
|
||||||
@@ -146,16 +148,13 @@ impl MachineState {
|
|||||||
Some(CycleSearchResult::CompleteString(s.len(), s))
|
Some(CycleSearchResult::CompleteString(s.len(), s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Addr::PStrTail(h, n) => {
|
|
||||||
Some(CycleSearchResult::PStrTail(brent_st.steps, h, n))
|
|
||||||
}
|
|
||||||
Addr::PStrLocation(h, n) => {
|
Addr::PStrLocation(h, n) => {
|
||||||
match &self.heap[h] {
|
match &self.heap[h] {
|
||||||
HeapCellValue::PartialString(ref pstr) => {
|
HeapCellValue::PartialString(ref pstr) => {
|
||||||
let s = pstr.block_as_str();
|
let s = pstr.block_as_str();
|
||||||
|
|
||||||
if let Some(c) = s[n ..].chars().next() {
|
if let Some(c) = s[n ..].chars().next() {
|
||||||
brent_st.step(Addr::PStrTail(h, n + c.len_utf8()))
|
brent_st.step(Addr::PStrLocation(h, n + c.len_utf8()))
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
@@ -189,9 +188,6 @@ impl MachineState {
|
|||||||
Addr::PStrLocation(h, _) => {
|
Addr::PStrLocation(h, _) => {
|
||||||
return CycleSearchResult::UntouchedList(h);
|
return CycleSearchResult::UntouchedList(h);
|
||||||
}
|
}
|
||||||
Addr::PStrTail(h, n) => {
|
|
||||||
return CycleSearchResult::PStrTail(0, h, n);
|
|
||||||
}
|
|
||||||
Addr::Con(Constant::EmptyList) => {
|
Addr::Con(Constant::EmptyList) => {
|
||||||
return CycleSearchResult::EmptyList;
|
return CycleSearchResult::EmptyList;
|
||||||
}
|
}
|
||||||
@@ -251,9 +247,6 @@ impl MachineState {
|
|||||||
Addr::PStrLocation(h, n) => {
|
Addr::PStrLocation(h, n) => {
|
||||||
Addr::PStrLocation(h, n)
|
Addr::PStrLocation(h, n)
|
||||||
}
|
}
|
||||||
Addr::PStrTail(h, n) => {
|
|
||||||
return CycleSearchResult::PStrTail(0, h, n);
|
|
||||||
}
|
|
||||||
Addr::Con(Constant::String(0, ref s)) if !self.flags.double_quotes.is_atom() => {
|
Addr::Con(Constant::String(0, ref s)) if !self.flags.double_quotes.is_atom() => {
|
||||||
return CycleSearchResult::CompleteString(s.len(), s.clone());
|
return CycleSearchResult::CompleteString(s.len(), s.clone());
|
||||||
}
|
}
|
||||||
@@ -316,9 +309,6 @@ impl MachineState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match search_result {
|
match search_result {
|
||||||
CycleSearchResult::PStrTail(steps, h, n) => {
|
|
||||||
self.finalize_skip_max_list(steps, Addr::PStrTail(h, n));
|
|
||||||
}
|
|
||||||
CycleSearchResult::PStrLocation(steps, h, n) => {
|
CycleSearchResult::PStrLocation(steps, h, n) => {
|
||||||
self.finalize_skip_max_list(steps, Addr::PStrLocation(h, n));
|
self.finalize_skip_max_list(steps, Addr::PStrLocation(h, n));
|
||||||
}
|
}
|
||||||
@@ -1062,14 +1052,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let pstr_tail = match &self.heap[h] {
|
let pstr_tail = self.heap[h + 1].as_addr(h + 1);
|
||||||
HeapCellValue::PartialString(ref pstr) => {
|
|
||||||
pstr.tail_addr().clone()
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.unify(self[temp_v!(2)].clone(), pstr);
|
self.unify(self[temp_v!(2)].clone(), pstr);
|
||||||
|
|
||||||
@@ -1093,13 +1076,9 @@ impl MachineState {
|
|||||||
|
|
||||||
match pstr {
|
match pstr {
|
||||||
Addr::PStrLocation(h, _) => {
|
Addr::PStrLocation(h, _) => {
|
||||||
let tail = if let HeapCellValue::PartialString(ref pstr) = &self.heap[h] {
|
let tail = self.heap[h + 1].as_addr(h + 1);
|
||||||
pstr.tail.clone()
|
|
||||||
} else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
|
|
||||||
let target = self[temp_v!(2)].clone();
|
let target = self[temp_v!(2)].clone();
|
||||||
|
|
||||||
self.unify(tail, target);
|
self.unify(tail, target);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -1406,9 +1385,6 @@ impl MachineState {
|
|||||||
HeapCellValue::Addr(ref mut addr) => {
|
HeapCellValue::Addr(ref mut addr) => {
|
||||||
*addr -= self.heap.h() + lh_offset
|
*addr -= self.heap.h() + lh_offset
|
||||||
}
|
}
|
||||||
HeapCellValue::PartialString(ref mut pstr) => {
|
|
||||||
pstr.tail -= self.heap.h() + lh_offset;
|
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1872,8 +1848,7 @@ impl MachineState {
|
|||||||
self.heap.push(HeapCellValue::Addr(addr.clone() + h));
|
self.heap.push(HeapCellValue::Addr(addr.clone() + h));
|
||||||
}
|
}
|
||||||
HeapCellValue::PartialString(ref pstr) => {
|
HeapCellValue::PartialString(ref pstr) => {
|
||||||
let mut new_pstr = pstr.clone();
|
let new_pstr = pstr.clone();
|
||||||
new_pstr.tail = pstr.tail.clone() + h;
|
|
||||||
self.heap.push(HeapCellValue::PartialString(new_pstr));
|
self.heap.push(HeapCellValue::PartialString(new_pstr));
|
||||||
}
|
}
|
||||||
value => {
|
value => {
|
||||||
@@ -1922,8 +1897,7 @@ impl MachineState {
|
|||||||
self.heap.push(HeapCellValue::Addr(addr.clone() + h))
|
self.heap.push(HeapCellValue::Addr(addr.clone() + h))
|
||||||
}
|
}
|
||||||
HeapCellValue::PartialString(ref pstr) => {
|
HeapCellValue::PartialString(ref pstr) => {
|
||||||
let mut new_pstr = pstr.clone();
|
let new_pstr = pstr.clone();
|
||||||
new_pstr.tail = pstr.tail.clone() + h;
|
|
||||||
self.heap.push(HeapCellValue::PartialString(new_pstr));
|
self.heap.push(HeapCellValue::PartialString(new_pstr));
|
||||||
}
|
}
|
||||||
value => {
|
value => {
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ impl fmt::Display for HeapCellValue {
|
|||||||
write!(f, "{}/{}", name.as_str(), arity)
|
write!(f, "{}/{}", name.as_str(), arity)
|
||||||
}
|
}
|
||||||
&HeapCellValue::PartialString(ref pstr) => {
|
&HeapCellValue::PartialString(ref pstr) => {
|
||||||
write!(f, "pstr ( buf: {}, tail: {} )", pstr.block_as_str(), pstr.tail_addr())
|
write!(f, "pstr ( buf: {} )", pstr.block_as_str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,7 +183,6 @@ impl fmt::Display for Addr {
|
|||||||
&Addr::StackCell(fr, sc) => write!(f, "Addr::StackCell({}, {})", fr, sc),
|
&Addr::StackCell(fr, sc) => write!(f, "Addr::StackCell({}, {})", fr, sc),
|
||||||
&Addr::Str(s) => write!(f, "Addr::Str({})", s),
|
&Addr::Str(s) => write!(f, "Addr::Str({})", s),
|
||||||
&Addr::PStrLocation(h, n) => write!(f, "Addr::PStrLocation({}, {})", h, n),
|
&Addr::PStrLocation(h, n) => write!(f, "Addr::PStrLocation({}, {})", h, n),
|
||||||
&Addr::PStrTail(h, n) => write!(f, "Addr::PStrTail({}, {})", h, n),
|
|
||||||
&Addr::Stream(ref stream) => write!(f, "Addr::Stream({})", stream.as_ptr() as usize),
|
&Addr::Stream(ref stream) => write!(f, "Addr::Stream({})", stream.as_ptr() as usize),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user