pub(crate)
fn new() -> Self {
MachineState {
- s: 0,
+ s: HeapPtr::default(),
p: CodePtr::default(),
b: 0,
b0: 0,
pub(crate)
fn with_small_heap() -> Self {
MachineState {
- s: 0,
+ s: HeapPtr::default(),
p: CodePtr::default(),
b: 0,
b0: 0,
}
}
+ fn increment_s_ptr(&mut self, rhs: usize) {
+ match &mut self.s {
+ HeapPtr::HeapCell(ref mut h) => {
+ *h += rhs;
+ }
+ HeapPtr::PStrLocation(h, n) => {
+ match &self.heap[*h] {
+ HeapCellValue::PartialString(ref pstr) => {
+ let s = pstr.block_as_str();
+
+ for c in s[*n ..].chars().take(rhs) {
+ *n += c.len_utf8();
+ }
+ }
+ _ => {
+ unreachable!()
+ }
+ }
+ }
+ HeapPtr::String(ref mut n, ref s) => {
+ for c in s[*n ..].chars().take(rhs) {
+ *n += c.len_utf8();
+ }
+ }
+ }
+ }
+
pub(super)
fn unwind_trail(&mut self, a1: usize, a2: usize) {
// the sequence is reversed to respect the chronology of trail
};
}
- fn get_char_list(&mut self, offset: usize, s: Rc<String>)
- {
- if let Some(c) = s[offset ..].chars().next() {
- let h = self.heap.h();
-
- self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::Char(c))));
- self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::String(
- offset + c.len_utf8(),
- s,
- ))));
-
- self.s = h;
- self.mode = MachineMode::Read;
- }
- }
-
- fn get_partial_string_list(&mut self, pstr_h: usize, offset: usize)
- {
- let (c, pstr_tail) =
- if let HeapCellValue::PartialString(ref pstr) = &self.heap[pstr_h] {
- let s = pstr.block_as_str();
-
- if let Some(c) = s[offset ..].chars().next() {
- (c, Addr::PStrTail(pstr_h, offset + c.len_utf8()))
- } else {
- unreachable!()
- }
- } else {
- unreachable!()
- };
-
- self.s = self.heap.h();
-
- self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::Char(c))));
- self.heap.push(HeapCellValue::Addr(pstr_tail));
-
- self.mode = MachineMode::Read;
- }
-
pub(super)
fn execute_fact_instr(&mut self, instr: &FactInstruction) {
match instr {
match self.flags.double_quotes {
DoubleQuotes::Chars | DoubleQuotes::Codes
if s.len() > n => {
- self.get_char_list(n, s)
+ self.s = HeapPtr::String(n, s);
+ self.mode = MachineMode::Read;
}
_ => {
self.fail = true
}
},
Addr::PStrLocation(h, n) => {
- self.get_partial_string_list(h, n)
+ self.s = HeapPtr::PStrLocation(h, n);
+ self.mode = MachineMode::Read;
}
addr @ Addr::AttrVar(_)
| addr @ Addr::StackCell(..)
self.mode = MachineMode::Write;
}
Addr::Lis(a) => {
- self.s = a;
+ self.s = HeapPtr::HeapCell(a);
self.mode = MachineMode::Read;
}
_ => self.fail = true,
if let &HeapCellValue::NamedStr(narity, ref s, _) = result {
if narity == arity && ct.name() == *s {
- self.s = a + 1;
+ self.s = HeapPtr::HeapCell(a + 1);
self.mode = MachineMode::Read;
} else {
self.fail = true;
&FactInstruction::UnifyConstant(ref c) => {
match self.mode {
MachineMode::Read => {
- let addr = Addr::HeapCell(self.s);
+ let addr = self.s.as_addr();
self.write_constant_to_var(addr, c.clone());
}
MachineMode::Write => {
}
};
- self.s += 1;
+ self.increment_s_ptr(1);
}
&FactInstruction::UnifyVariable(reg) => {
match self.mode {
- MachineMode::Read => self[reg] = self.heap[self.s].as_addr(self.s),
+ MachineMode::Read => self[reg] = self.s.as_addr(),
MachineMode::Write => {
let h = self.heap.h();
}
};
- self.s += 1;
+ self.increment_s_ptr(1);
}
&FactInstruction::UnifyLocalValue(reg) => {
- let s = self.s;
-
match self.mode {
MachineMode::Read => {
let reg_addr = self[reg].clone();
- self.unify(reg_addr, Addr::HeapCell(s));
+ self.unify(reg_addr, self.s.as_addr());
}
MachineMode::Write => {
let addr = self.deref(self[reg].clone());
let val = self.heap[hc].clone();
self.heap.push(val);
- self.s += 1;
+ self.increment_s_ptr(1);
return;
}
}
};
- self.s += 1;
+ self.increment_s_ptr(1);
}
&FactInstruction::UnifyValue(reg) => {
- let s = self.s;
-
match self.mode {
MachineMode::Read => {
let reg_addr = self[reg].clone();
- self.unify(reg_addr, Addr::HeapCell(s));
+ self.unify(reg_addr, self.s.as_addr());
}
MachineMode::Write => {
let heap_val = self.store(self[reg].clone());
}
};
- self.s += 1;
+ self.increment_s_ptr(1);
}
&FactInstruction::UnifyVoid(n) => {
match self.mode {
- MachineMode::Read => self.s += n,
+ MachineMode::Read => self.increment_s_ptr(n),
MachineMode::Write => {
let h = self.heap.h();
&QueryInstruction::PutStructure(ref ct, arity, reg) => {
let h = self.heap.h();
- self.heap
- .push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec()));
+ self.heap.push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec()));
self[reg] = Addr::Str(h);
}
&QueryInstruction::PutUnsafeValue(n, arg) => {
let e = self.e;
- let addr = self.deref(Addr::StackCell(e, n));
+ let addr = self.store(self.deref(Addr::StackCell(e, n)));
if addr.is_protected(e) {
- self.registers[arg] = self.store(addr);
+ self.registers[arg] = addr;
} else {
let h = self.heap.h();
self.e = 0;
self.b = 0;
self.b0 = 0;
- self.s = 0;
+ self.s = HeapPtr::default();
self.tr = 0;
self.p = CodePtr::default();
self.cp = LocalCodePtr::default();