add TrailRef type for trail
This commit is contained in:
@@ -821,6 +821,22 @@ impl Ref {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum TrailRef {
|
||||||
|
HeapCell(usize),
|
||||||
|
StackCell(usize, usize),
|
||||||
|
AttrVarLink(usize, Addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Ref> for TrailRef {
|
||||||
|
fn from(r: Ref) -> Self {
|
||||||
|
match r {
|
||||||
|
Ref::HeapCell(h) => TrailRef::HeapCell(h),
|
||||||
|
Ref::StackCell(fr, sc) => TrailRef::StackCell(fr, sc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub enum HeapCellValue {
|
pub enum HeapCellValue {
|
||||||
Addr(Addr),
|
Addr(Addr),
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ pub struct MachineState {
|
|||||||
pub(crate) and_stack: AndStack,
|
pub(crate) and_stack: AndStack,
|
||||||
pub(super) or_stack: OrStack,
|
pub(super) or_stack: OrStack,
|
||||||
pub(super) registers: Registers,
|
pub(super) registers: Registers,
|
||||||
pub(super) trail: Vec<Ref>,
|
pub(super) trail: Vec<TrailRef>,
|
||||||
pub(super) pstr_trail: Vec<(usize, StringList, usize)>, // b, String, trunc_pt
|
pub(super) pstr_trail: Vec<(usize, StringList, usize)>, // b, String, trunc_pt
|
||||||
pub(super) pstr_tr: usize,
|
pub(super) pstr_tr: usize,
|
||||||
pub(super) tr: usize,
|
pub(super) tr: usize,
|
||||||
|
|||||||
@@ -109,16 +109,16 @@ impl MachineState {
|
|||||||
self.heap[h] = HeapCellValue::Addr(t2)
|
self.heap[h] = HeapCellValue::Addr(t2)
|
||||||
};
|
};
|
||||||
|
|
||||||
self.trail(r1);
|
self.trail(TrailRef::from(r1));
|
||||||
} else {
|
} else {
|
||||||
match a2.as_var() {
|
match a2.as_var() {
|
||||||
Some(Ref::StackCell(fr, sc)) => {
|
Some(Ref::StackCell(fr, sc)) => {
|
||||||
self.and_stack[fr][sc] = t1;
|
self.and_stack[fr][sc] = t1;
|
||||||
self.trail(Ref::StackCell(fr, sc));
|
self.trail(TrailRef::StackCell(fr, sc));
|
||||||
},
|
},
|
||||||
Some(Ref::HeapCell(h)) => {
|
Some(Ref::HeapCell(h)) => {
|
||||||
self.heap[h] = HeapCellValue::Addr(t1);
|
self.heap[h] = HeapCellValue::Addr(t1);
|
||||||
self.trail(Ref::HeapCell(h));
|
self.trail(TrailRef::HeapCell(h));
|
||||||
},
|
},
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
@@ -347,14 +347,19 @@ impl MachineState {
|
|||||||
self.pstr_tr += 1;
|
self.pstr_tr += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trail(&mut self, r: Ref) {
|
fn trail(&mut self, r: TrailRef) {
|
||||||
match r {
|
match r {
|
||||||
Ref::HeapCell(hc) =>
|
TrailRef::HeapCell(h) =>
|
||||||
if hc < self.hb {
|
if h < self.hb {
|
||||||
self.trail.push(r);
|
self.trail.push(TrailRef::HeapCell(h));
|
||||||
self.tr += 1;
|
self.tr += 1;
|
||||||
},
|
},
|
||||||
Ref::StackCell(fr, _) => {
|
TrailRef::AttrVarLink(h, prev_addr) =>
|
||||||
|
if h < self.hb {
|
||||||
|
self.trail.push(TrailRef::AttrVarLink(h, prev_addr));
|
||||||
|
self.tr += 1;
|
||||||
|
},
|
||||||
|
TrailRef::StackCell(fr, sc) => {
|
||||||
let fr_gi = self.and_stack[fr].global_index;
|
let fr_gi = self.and_stack[fr].global_index;
|
||||||
let b_gi = if !self.or_stack.is_empty() {
|
let b_gi = if !self.or_stack.is_empty() {
|
||||||
if self.b > 0 {
|
if self.b > 0 {
|
||||||
@@ -368,7 +373,7 @@ impl MachineState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if fr_gi < b_gi {
|
if fr_gi < b_gi {
|
||||||
self.trail.push(r);
|
self.trail.push(TrailRef::StackCell(fr, sc));
|
||||||
self.tr += 1;
|
self.tr += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -376,12 +381,17 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn unwind_trail(&mut self, a1: usize, a2: usize) {
|
pub(super) fn unwind_trail(&mut self, a1: usize, a2: usize) {
|
||||||
for i in a1 .. a2 {
|
// the sequence is reversed to respect the chronology of trail
|
||||||
match self.trail[i] {
|
// additions, now that deleted attributes can be undeleted by
|
||||||
Ref::HeapCell(r) =>
|
// backtracking.
|
||||||
self.heap[r] = HeapCellValue::Addr(Addr::HeapCell(r)),
|
for i in (a1 .. a2).rev() {
|
||||||
Ref::StackCell(fr, sc) =>
|
match self.trail[i].clone() {
|
||||||
self.and_stack[fr][sc] = Addr::StackCell(fr, sc)
|
TrailRef::HeapCell(h) =>
|
||||||
|
self.heap[h] = HeapCellValue::Addr(Addr::HeapCell(h)),
|
||||||
|
TrailRef::StackCell(fr, sc) =>
|
||||||
|
self.and_stack[fr][sc] = Addr::StackCell(fr, sc),
|
||||||
|
TrailRef::AttrVarLink(h, prev_addr) =>
|
||||||
|
self.heap[h] = HeapCellValue::Addr(prev_addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -424,21 +434,21 @@ impl MachineState {
|
|||||||
let mut i = self.or_stack[b].tr;
|
let mut i = self.or_stack[b].tr;
|
||||||
|
|
||||||
while i < self.tr {
|
while i < self.tr {
|
||||||
let tr_i = self.trail[i];
|
let tr_i = self.trail[i].clone();
|
||||||
let hb = self.hb;
|
let hb = self.hb;
|
||||||
|
|
||||||
match tr_i {
|
match tr_i {
|
||||||
Ref::HeapCell(tr_i) =>
|
TrailRef::HeapCell(tr_i) | TrailRef::AttrVarLink(tr_i, _) =>
|
||||||
if tr_i < hb {
|
if tr_i < hb {
|
||||||
i += 1;
|
i += 1;
|
||||||
} else {
|
} else {
|
||||||
let tr = self.tr;
|
let tr = self.tr;
|
||||||
let val = self.trail[tr - 1];
|
let val = self.trail[tr - 1].clone();
|
||||||
self.trail[i] = val;
|
self.trail[i] = val;
|
||||||
self.trail.pop();
|
self.trail.pop();
|
||||||
self.tr -= 1;
|
self.tr -= 1;
|
||||||
},
|
},
|
||||||
Ref::StackCell(fr, _) => {
|
TrailRef::StackCell(fr, _) => {
|
||||||
let b = self.b - 1;
|
let b = self.b - 1;
|
||||||
let fr_gi = self.and_stack[fr].global_index;
|
let fr_gi = self.and_stack[fr].global_index;
|
||||||
let b_gi = if !self.or_stack.is_empty() {
|
let b_gi = if !self.or_stack.is_empty() {
|
||||||
@@ -451,7 +461,7 @@ impl MachineState {
|
|||||||
i += 1;
|
i += 1;
|
||||||
} else {
|
} else {
|
||||||
let tr = self.tr;
|
let tr = self.tr;
|
||||||
let val = self.trail[tr - 1];
|
let val = self.trail[tr - 1].clone();
|
||||||
self.trail[i] = val;
|
self.trail[i] = val;
|
||||||
self.trail.pop();
|
self.trail.pop();
|
||||||
self.tr -= 1;
|
self.tr -= 1;
|
||||||
@@ -474,11 +484,11 @@ impl MachineState {
|
|||||||
match self.store(self.deref(addr)) {
|
match self.store(self.deref(addr)) {
|
||||||
Addr::HeapCell(hc) => {
|
Addr::HeapCell(hc) => {
|
||||||
self.heap[hc] = HeapCellValue::Addr(Addr::Con(c.clone()));
|
self.heap[hc] = HeapCellValue::Addr(Addr::Con(c.clone()));
|
||||||
self.trail(Ref::HeapCell(hc));
|
self.trail(TrailRef::HeapCell(hc));
|
||||||
},
|
},
|
||||||
Addr::StackCell(fr, sc) => {
|
Addr::StackCell(fr, sc) => {
|
||||||
self.and_stack[fr][sc] = Addr::Con(c.clone());
|
self.and_stack[fr][sc] = Addr::Con(c.clone());
|
||||||
self.trail(Ref::StackCell(fr, sc));
|
self.trail(TrailRef::StackCell(fr, sc));
|
||||||
},
|
},
|
||||||
Addr::Con(Constant::String(ref mut s)) =>
|
Addr::Con(Constant::String(ref mut s)) =>
|
||||||
self.fail = match c {
|
self.fail = match c {
|
||||||
|
|||||||
Reference in New Issue
Block a user