#[derive(Clone)]
pub enum TokenOrRedirect {
Atom(ClauseName),
+ BarAsOp,
Op(ClauseName, SharedOpDesc),
NumberedVar(String),
CompositeRedirect(DirectedOp),
fn format_prefix_op_with_space(&mut self, name: ClauseName, spec: SharedOpDesc) {
let op = DirectedOp::Left(name.clone(), spec);
- self.state_stack
- .push(TokenOrRedirect::CompositeRedirect(op));
+ self.state_stack.push(TokenOrRedirect::CompositeRedirect(op));
self.state_stack.push(TokenOrRedirect::Space);
self.state_stack.push(TokenOrRedirect::Atom(name));
}
let left_directed_op = DirectedOp::Left(name.clone(), spec.clone());
let right_directed_op = DirectedOp::Right(name.clone(), spec.clone());
- self.state_stack
- .push(TokenOrRedirect::CompositeRedirect(left_directed_op));
- self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
- self.state_stack
- .push(TokenOrRedirect::CompositeRedirect(right_directed_op));
+ self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
+ self.state_stack.push(TokenOrRedirect::BarAsOp);
+ self.state_stack.push(TokenOrRedirect::CompositeRedirect(right_directed_op));
}
fn format_curly_braces(&mut self) {
if let Some(loc_data) = self.state_stack.pop() {
match loc_data {
TokenOrRedirect::Atom(atom) => self.print_atom(&atom),
+ TokenOrRedirect::BarAsOp => self.append_str(" | "),
TokenOrRedirect::Op(atom, _) => self.print_op(atom.as_str()),
TokenOrRedirect::NumberedVar(num_var) => self.append_str(num_var.as_str()),
TokenOrRedirect::CompositeRedirect(op) => {
#[derive(Clone)]
pub(super) enum HeapPtr {
HeapCell(usize),
- PStrLocation(usize, usize),
- String(usize, Rc<String>),
+ PStrChar(usize, usize),
+ PStrTail(usize, usize),
+ StringChar(usize, Rc<String>),
+ StringTail(usize, Rc<String>),
}
impl HeapPtr {
#[inline]
pub(super)
- fn as_addr(&self) -> Addr {
+ fn read(&self, heap: &Heap) -> Addr {
match self {
- &HeapPtr::HeapCell(h) => Addr::HeapCell(h),
- &HeapPtr::PStrLocation(h, n) => Addr::PStrLocation(h, n),
- &HeapPtr::String(n, ref s) => Addr::Con(Constant::String(n, s.clone())),
+ &HeapPtr::HeapCell(h) =>
+ Addr::HeapCell(h),
+ &HeapPtr::PStrChar(h, n) =>
+ if let HeapCellValue::PartialString(ref pstr) = &heap[h] {
+ let s = pstr.block_as_str();
+
+ if let Some(c) = s[n ..].chars().next() {
+ Addr::Con(Constant::Char(c))
+ } else {
+ Addr::PStrTail(h, n)
+ }
+ } else {
+ unreachable!()
+ },
+ &HeapPtr::PStrTail(h, n) =>
+ Addr::PStrTail(h, n),
+ &HeapPtr::StringChar(n, ref s) =>
+ if let Some(c) = s[n ..].chars().next() {
+ Addr::Con(Constant::Char(c))
+ } else {
+ Addr::Con(Constant::EmptyList)
+ },
+ &HeapPtr::StringTail(n, ref s) =>
+ Addr::Con(Constant::String(n, s.clone())),
}
}
}
HeapPtr::HeapCell(ref mut h) => {
*h += rhs;
}
- HeapPtr::PStrLocation(h, n) => {
+ HeapPtr::PStrChar(h, n) | HeapPtr::PStrTail(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();
}
+
+ self.s = HeapPtr::PStrTail(*h, *n);
}
_ => {
unreachable!()
}
}
}
- HeapPtr::String(ref mut n, ref s) => {
+ HeapPtr::StringChar(n, s) | HeapPtr::StringTail(n, s) => {
for c in s[*n ..].chars().take(rhs) {
*n += c.len_utf8();
}
+
+ self.s = HeapPtr::StringTail(*n, s.clone());
}
}
}
match self.flags.double_quotes {
DoubleQuotes::Chars | DoubleQuotes::Codes
if s.len() > n => {
- self.s = HeapPtr::String(n, s);
+ self.s = HeapPtr::StringChar(n, s);
self.mode = MachineMode::Read;
}
_ => {
}
},
Addr::PStrLocation(h, n) => {
- self.s = HeapPtr::PStrLocation(h, n);
+ self.s = HeapPtr::PStrChar(h, n);
self.mode = MachineMode::Read;
}
addr @ Addr::AttrVar(_)
&FactInstruction::UnifyConstant(ref c) => {
match self.mode {
MachineMode::Read => {
- let addr = self.s.as_addr();
+ let addr = self.s.read(&self.heap);
self.write_constant_to_var(addr, c.clone());
}
MachineMode::Write => {
}
&FactInstruction::UnifyVariable(reg) => {
match self.mode {
- MachineMode::Read => self[reg] = self.s.as_addr(),
+ MachineMode::Read => self[reg] = self.s.read(&self.heap),
MachineMode::Write => {
let h = self.heap.h();
match self.mode {
MachineMode::Read => {
let reg_addr = self[reg].clone();
- self.unify(reg_addr, self.s.as_addr());
+ self.unify(reg_addr, self.s.read(&self.heap));
}
MachineMode::Write => {
let addr = self.deref(self[reg].clone());
match self.mode {
MachineMode::Read => {
let reg_addr = self[reg].clone();
- self.unify(reg_addr, self.s.as_addr());
+ self.unify(reg_addr, self.s.read(&self.heap));
}
MachineMode::Write => {
let heap_val = self.store(self[reg].clone());