correct handling of strings and partial strings as lists, print bar operator with surrounding spaces (#274)
This commit is contained in:
@@ -157,6 +157,7 @@ fn char_to_string(c: char) -> String {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum TokenOrRedirect {
|
pub enum TokenOrRedirect {
|
||||||
Atom(ClauseName),
|
Atom(ClauseName),
|
||||||
|
BarAsOp,
|
||||||
Op(ClauseName, SharedOpDesc),
|
Op(ClauseName, SharedOpDesc),
|
||||||
NumberedVar(String),
|
NumberedVar(String),
|
||||||
CompositeRedirect(DirectedOp),
|
CompositeRedirect(DirectedOp),
|
||||||
@@ -531,8 +532,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
fn format_prefix_op_with_space(&mut self, name: ClauseName, spec: SharedOpDesc) {
|
fn format_prefix_op_with_space(&mut self, name: ClauseName, spec: SharedOpDesc) {
|
||||||
let op = DirectedOp::Left(name.clone(), spec);
|
let op = DirectedOp::Left(name.clone(), spec);
|
||||||
|
|
||||||
self.state_stack
|
self.state_stack.push(TokenOrRedirect::CompositeRedirect(op));
|
||||||
.push(TokenOrRedirect::CompositeRedirect(op));
|
|
||||||
self.state_stack.push(TokenOrRedirect::Space);
|
self.state_stack.push(TokenOrRedirect::Space);
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(name));
|
self.state_stack.push(TokenOrRedirect::Atom(name));
|
||||||
}
|
}
|
||||||
@@ -541,11 +541,9 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
let left_directed_op = DirectedOp::Left(name.clone(), spec.clone());
|
let left_directed_op = DirectedOp::Left(name.clone(), spec.clone());
|
||||||
let right_directed_op = DirectedOp::Right(name.clone(), spec.clone());
|
let right_directed_op = DirectedOp::Right(name.clone(), spec.clone());
|
||||||
|
|
||||||
self.state_stack
|
self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
|
||||||
.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
|
self.state_stack.push(TokenOrRedirect::BarAsOp);
|
||||||
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
|
self.state_stack.push(TokenOrRedirect::CompositeRedirect(right_directed_op));
|
||||||
self.state_stack
|
|
||||||
.push(TokenOrRedirect::CompositeRedirect(right_directed_op));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format_curly_braces(&mut self) {
|
fn format_curly_braces(&mut self) {
|
||||||
@@ -994,6 +992,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
if let Some(loc_data) = self.state_stack.pop() {
|
if let Some(loc_data) = self.state_stack.pop() {
|
||||||
match loc_data {
|
match loc_data {
|
||||||
TokenOrRedirect::Atom(atom) => self.print_atom(&atom),
|
TokenOrRedirect::Atom(atom) => self.print_atom(&atom),
|
||||||
|
TokenOrRedirect::BarAsOp => self.append_str(" | "),
|
||||||
TokenOrRedirect::Op(atom, _) => self.print_op(atom.as_str()),
|
TokenOrRedirect::Op(atom, _) => self.print_op(atom.as_str()),
|
||||||
TokenOrRedirect::NumberedVar(num_var) => self.append_str(num_var.as_str()),
|
TokenOrRedirect::NumberedVar(num_var) => self.append_str(num_var.as_str()),
|
||||||
TokenOrRedirect::CompositeRedirect(op) => {
|
TokenOrRedirect::CompositeRedirect(op) => {
|
||||||
|
|||||||
@@ -249,18 +249,41 @@ pub(super) enum MachineMode {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(super) enum HeapPtr {
|
pub(super) enum HeapPtr {
|
||||||
HeapCell(usize),
|
HeapCell(usize),
|
||||||
PStrLocation(usize, usize),
|
PStrChar(usize, usize),
|
||||||
String(usize, Rc<String>),
|
PStrTail(usize, usize),
|
||||||
|
StringChar(usize, Rc<String>),
|
||||||
|
StringTail(usize, Rc<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HeapPtr {
|
impl HeapPtr {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super)
|
||||||
fn as_addr(&self) -> Addr {
|
fn read(&self, heap: &Heap) -> Addr {
|
||||||
match self {
|
match self {
|
||||||
&HeapPtr::HeapCell(h) => Addr::HeapCell(h),
|
&HeapPtr::HeapCell(h) =>
|
||||||
&HeapPtr::PStrLocation(h, n) => Addr::PStrLocation(h, n),
|
Addr::HeapCell(h),
|
||||||
&HeapPtr::String(n, ref s) => Addr::Con(Constant::String(n, s.clone())),
|
&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())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -650,7 +650,7 @@ impl MachineState {
|
|||||||
HeapPtr::HeapCell(ref mut h) => {
|
HeapPtr::HeapCell(ref mut h) => {
|
||||||
*h += rhs;
|
*h += rhs;
|
||||||
}
|
}
|
||||||
HeapPtr::PStrLocation(h, n) => {
|
HeapPtr::PStrChar(h, n) | HeapPtr::PStrTail(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();
|
||||||
@@ -658,16 +658,20 @@ impl MachineState {
|
|||||||
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::PStrTail(*h, *n);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HeapPtr::String(ref mut n, ref s) => {
|
HeapPtr::StringChar(n, s) | HeapPtr::StringTail(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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1606,7 +1610,7 @@ impl MachineState {
|
|||||||
match self.flags.double_quotes {
|
match self.flags.double_quotes {
|
||||||
DoubleQuotes::Chars | DoubleQuotes::Codes
|
DoubleQuotes::Chars | DoubleQuotes::Codes
|
||||||
if s.len() > n => {
|
if s.len() > n => {
|
||||||
self.s = HeapPtr::String(n, s);
|
self.s = HeapPtr::StringChar(n, s);
|
||||||
self.mode = MachineMode::Read;
|
self.mode = MachineMode::Read;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -1614,7 +1618,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Addr::PStrLocation(h, n) => {
|
Addr::PStrLocation(h, n) => {
|
||||||
self.s = HeapPtr::PStrLocation(h, n);
|
self.s = HeapPtr::PStrChar(h, n);
|
||||||
self.mode = MachineMode::Read;
|
self.mode = MachineMode::Read;
|
||||||
}
|
}
|
||||||
addr @ Addr::AttrVar(_)
|
addr @ Addr::AttrVar(_)
|
||||||
@@ -1675,7 +1679,7 @@ impl MachineState {
|
|||||||
&FactInstruction::UnifyConstant(ref c) => {
|
&FactInstruction::UnifyConstant(ref c) => {
|
||||||
match self.mode {
|
match self.mode {
|
||||||
MachineMode::Read => {
|
MachineMode::Read => {
|
||||||
let addr = self.s.as_addr();
|
let addr = self.s.read(&self.heap);
|
||||||
self.write_constant_to_var(addr, c.clone());
|
self.write_constant_to_var(addr, c.clone());
|
||||||
}
|
}
|
||||||
MachineMode::Write => {
|
MachineMode::Write => {
|
||||||
@@ -1687,7 +1691,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
&FactInstruction::UnifyVariable(reg) => {
|
&FactInstruction::UnifyVariable(reg) => {
|
||||||
match self.mode {
|
match self.mode {
|
||||||
MachineMode::Read => self[reg] = self.s.as_addr(),
|
MachineMode::Read => self[reg] = self.s.read(&self.heap),
|
||||||
MachineMode::Write => {
|
MachineMode::Write => {
|
||||||
let h = self.heap.h();
|
let h = self.heap.h();
|
||||||
|
|
||||||
@@ -1702,7 +1706,7 @@ impl MachineState {
|
|||||||
match self.mode {
|
match self.mode {
|
||||||
MachineMode::Read => {
|
MachineMode::Read => {
|
||||||
let reg_addr = self[reg].clone();
|
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 => {
|
MachineMode::Write => {
|
||||||
let addr = self.deref(self[reg].clone());
|
let addr = self.deref(self[reg].clone());
|
||||||
@@ -1730,7 +1734,7 @@ impl MachineState {
|
|||||||
match self.mode {
|
match self.mode {
|
||||||
MachineMode::Read => {
|
MachineMode::Read => {
|
||||||
let reg_addr = self[reg].clone();
|
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 => {
|
MachineMode::Write => {
|
||||||
let heap_val = self.store(self[reg].clone());
|
let heap_val = self.store(self[reg].clone());
|
||||||
|
|||||||
Reference in New Issue
Block a user