harmonize partial strings with complete strings (#276), make Addr a copyable type
This commit is contained in:
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -445,6 +445,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "prolog_parser"
|
name = "prolog_parser"
|
||||||
version = "0.8.48"
|
version = "0.8.48"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lexical 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lexical 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-rug-adapter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-rug-adapter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -579,7 +580,7 @@ dependencies = [
|
|||||||
"nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-rug-adapter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-rug-adapter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"prolog_parser 0.8.48",
|
"prolog_parser 0.8.48 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rug 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rug 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustyline 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustyline 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -790,6 +791,7 @@ dependencies = [
|
|||||||
"checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc"
|
"checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc"
|
||||||
"checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1"
|
"checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1"
|
||||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||||
|
"checksum prolog_parser 0.8.48 (registry+https://github.com/rust-lang/crates.io-index)" = "301d67e5905691f8d5dc5f08c8c6e12cf849a12bea779af8b5221c35b89faf95"
|
||||||
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||||
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||||
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||||
|
|||||||
@@ -25,10 +25,7 @@ libc = "0.2.62"
|
|||||||
nix = "0.15.0"
|
nix = "0.15.0"
|
||||||
num-rug-adapter = { optional = true, version = "0.1.1" }
|
num-rug-adapter = { optional = true, version = "0.1.1" }
|
||||||
ordered-float = "0.5.0"
|
ordered-float = "0.5.0"
|
||||||
prolog_parser = { version = "0.8.48", path = "../prolog_parser", default-features = false }
|
prolog_parser = { version = "0.8.48", default-features = false }
|
||||||
ref_thread_local = "0.0.0"
|
ref_thread_local = "0.0.0"
|
||||||
rug = { version = "1.4.0", optional = true }
|
rug = { version = "1.4.0", optional = true }
|
||||||
rustyline = "6.0.0"
|
rustyline = "6.0.0"
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
debug = true
|
|
||||||
@@ -282,9 +282,9 @@ impl ClauseConsistency for Rule {
|
|||||||
fn name_and_module(&self) -> Option<(ClauseName, ClauseName)> {
|
fn name_and_module(&self) -> Option<(ClauseName, ClauseName)> {
|
||||||
Some((self.head.0.owning_module(), self.head.0.clone()))
|
Some((self.head.0.owning_module(), self.head.0.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arity(&self) -> usize {
|
fn arity(&self) -> usize {
|
||||||
self.head.1.len()
|
self.head.1.len()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,7 +597,7 @@ impl Into<HeapCellValue> for Number {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Number {
|
impl Number {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_positive(&self) -> bool {
|
pub fn is_positive(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ impl<'a> HCPreOrderIterator<'a> {
|
|||||||
&HeapCellValue::Addr(a) => {
|
&HeapCellValue::Addr(a) => {
|
||||||
self.follow(a)
|
self.follow(a)
|
||||||
}
|
}
|
||||||
HeapCellValue::PartialString(_) => {
|
HeapCellValue::PartialString(..) => {
|
||||||
self.follow(Addr::PStrLocation(h, 0))
|
self.follow(Addr::PStrLocation(h, 0))
|
||||||
}
|
}
|
||||||
HeapCellValue::Atom(..) | HeapCellValue::DBRef(_)
|
HeapCellValue::Atom(..) | HeapCellValue::DBRef(_)
|
||||||
@@ -64,17 +64,19 @@ impl<'a> HCPreOrderIterator<'a> {
|
|||||||
da
|
da
|
||||||
}
|
}
|
||||||
Addr::PStrLocation(h, n) => {
|
Addr::PStrLocation(h, n) => {
|
||||||
if let HeapCellValue::PartialString(ref pstr) = &self.machine_st.heap[h] {
|
if let &HeapCellValue::PartialString(ref pstr, has_tail) = &self.machine_st.heap[h] {
|
||||||
if let Some(c) = pstr.range_from(n ..).next() {
|
if let Some(c) = pstr.range_from(n ..).next() {
|
||||||
if !pstr.at_end(n + c.len_utf8()) {
|
if !pstr.at_end(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 if has_tail {
|
||||||
self.state_stack.push(Addr::HeapCell(h + 1));
|
self.state_stack.push(Addr::HeapCell(h + 1));
|
||||||
|
} else {
|
||||||
|
self.state_stack.push(Addr::EmptyList);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.state_stack.push(Addr::Char(c));
|
self.state_stack.push(Addr::Char(c));
|
||||||
} else {
|
} else if has_tail {
|
||||||
unreachable!()
|
return self.follow(Addr::HeapCell(h + 1));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -86,8 +88,19 @@ impl<'a> HCPreOrderIterator<'a> {
|
|||||||
self.follow_heap(s) // record terms of structure.
|
self.follow_heap(s) // record terms of structure.
|
||||||
}
|
}
|
||||||
Addr::Con(h) => {
|
Addr::Con(h) => {
|
||||||
if let HeapCellValue::PartialString(_) = &self.machine_st.heap[h] {
|
if let &HeapCellValue::PartialString(ref pstr, has_tail) = &self.machine_st.heap[h] {
|
||||||
self.state_stack.push(Addr::HeapCell(h + 1));
|
if !self.machine_st.flags.double_quotes.is_atom() {
|
||||||
|
return if let Some(c) = pstr.range_from(0 ..).next() {
|
||||||
|
self.state_stack.push(Addr::PStrLocation(h, c.len_utf8()));
|
||||||
|
self.state_stack.push(Addr::Char(c));
|
||||||
|
|
||||||
|
Addr::PStrLocation(h, 0)
|
||||||
|
} else if has_tail {
|
||||||
|
self.follow(Addr::HeapCell(h + 1))
|
||||||
|
} else {
|
||||||
|
Addr::EmptyList
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr::Con(h)
|
Addr::Con(h)
|
||||||
@@ -157,11 +170,18 @@ impl<'a> Iterator for HCPostOrderIterator<'a> {
|
|||||||
self.parent_stack.push((2, Addr::Lis(a)));
|
self.parent_stack.push((2, Addr::Lis(a)));
|
||||||
}
|
}
|
||||||
&HeapCellValue::Addr(Addr::PStrLocation(h, n)) => {
|
&HeapCellValue::Addr(Addr::PStrLocation(h, n)) => {
|
||||||
if let HeapCellValue::PartialString(ref pstr) = &self.machine_st.heap[h] {
|
match &self.machine_st.heap[h] {
|
||||||
let c = pstr.range_from(n ..).next().unwrap();
|
&HeapCellValue::PartialString(ref pstr, _) => {
|
||||||
self.parent_stack.push((2, Addr::PStrLocation(h, n + c.len_utf8())));
|
let c = pstr.range_from(n ..).next().unwrap();
|
||||||
} else {
|
let next_n = n + c.len_utf8();
|
||||||
unreachable!()
|
|
||||||
|
if !pstr.at_end(next_n) {
|
||||||
|
self.parent_stack.push((2, Addr::PStrLocation(h, next_n)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|||||||
@@ -184,16 +184,16 @@ pub trait HCValueOutputter {
|
|||||||
type Output;
|
type Output;
|
||||||
|
|
||||||
fn new() -> Self;
|
fn new() -> Self;
|
||||||
fn push_char(&mut self, _: char);
|
fn push_char(&mut self, c: char);
|
||||||
fn append(&mut self, _: &str);
|
fn append(&mut self, s: &str);
|
||||||
fn begin_new_var(&mut self);
|
fn begin_new_var(&mut self);
|
||||||
fn insert(&mut self, _: usize, _: char);
|
fn insert(&mut self, index: usize, c: char);
|
||||||
fn result(self) -> Self::Output;
|
fn result(self) -> Self::Output;
|
||||||
fn ends_with(&self, _: &str) -> bool;
|
fn ends_with(&self, s: &str) -> bool;
|
||||||
fn len(&self) -> usize;
|
fn len(&self) -> usize;
|
||||||
fn truncate(&mut self, _: usize);
|
fn truncate(&mut self, len: usize);
|
||||||
fn range(&self, _: Range<usize>) -> &str;
|
fn range(&self, range: Range<usize>) -> &str;
|
||||||
fn range_from(&self, _: RangeFrom<usize>) -> &str;
|
fn range_from(&self, range: RangeFrom<usize>) -> &str;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PrinterOutputter {
|
pub struct PrinterOutputter {
|
||||||
@@ -1022,130 +1022,149 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_string_as_str(
|
|
||||||
&mut self,
|
|
||||||
mut h: usize,
|
|
||||||
mut offset: usize,
|
|
||||||
quoted: bool,
|
|
||||||
) {
|
|
||||||
self.push_char('"');
|
|
||||||
|
|
||||||
while let HeapCellValue::PartialString(ref pstr) = &self.machine_st.heap[h] {
|
|
||||||
let atom = String::from_iter(pstr.range_from(offset ..).map(|c| {
|
|
||||||
char_to_string(quoted, c)
|
|
||||||
}));
|
|
||||||
|
|
||||||
self.append_str(&atom);
|
|
||||||
|
|
||||||
h += 2;
|
|
||||||
offset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.push_char('"');
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print_string(
|
fn print_string(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
iter: &mut HCPreOrderIterator,
|
||||||
mut max_depth: usize,
|
mut max_depth: usize,
|
||||||
mut h: usize,
|
h: usize,
|
||||||
mut offset: usize,
|
n: usize,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if !self.machine_st.machine_flags().double_quotes.is_atom() {
|
iter.stack().pop();
|
||||||
if self.check_max_depth(&mut max_depth) {
|
iter.stack().pop();
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
|
||||||
|
if self.check_max_depth(&mut max_depth) {
|
||||||
|
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut heap_pstr_iter =
|
||||||
|
self.machine_st.heap_pstr_iter(Addr::PStrLocation(h, n));
|
||||||
|
|
||||||
|
let mut buf = String::new();
|
||||||
|
|
||||||
|
while let Some(Some(c)) = heap_pstr_iter.next() {
|
||||||
|
buf.push(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
let end_addr =
|
||||||
|
if let &HeapCellValue::PartialString(_, has_tail) = &self.machine_st.heap[h] {
|
||||||
|
if has_tail {
|
||||||
|
self.machine_st.store(self.machine_st.deref(heap_pstr_iter.focus()))
|
||||||
|
} else {
|
||||||
|
Addr::EmptyList
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Addr::EmptyList = end_addr {
|
||||||
|
if !self.machine_st.flags.double_quotes.is_codes() {
|
||||||
|
self.push_char('"');
|
||||||
|
|
||||||
|
let buf =
|
||||||
|
if max_depth == 0 {
|
||||||
|
String::from_iter(buf.chars().map(|c| {
|
||||||
|
char_to_string(self.quoted, c)
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
let mut char_count = 0;
|
||||||
|
let mut buf =
|
||||||
|
String::from_iter(buf.chars().take(max_depth).map(|c| {
|
||||||
|
char_count += 1;
|
||||||
|
char_to_string(self.quoted, c)
|
||||||
|
}));
|
||||||
|
|
||||||
|
if char_count == max_depth {
|
||||||
|
buf += " ...";
|
||||||
|
}
|
||||||
|
|
||||||
|
buf
|
||||||
|
};
|
||||||
|
|
||||||
|
self.append_str(&buf);
|
||||||
|
self.push_char('"');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
while let HeapCellValue::PartialString(ref pstr) = &self.machine_st.heap[h] {
|
|
||||||
if pstr.at_end(offset) && !self.at_cdr("") {
|
|
||||||
if let HeapCellValue::Addr(Addr::EmptyList) = &self.machine_st.heap[h+1] {
|
|
||||||
self.append_str("[]");
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
h += 2;
|
|
||||||
offset = 0;
|
|
||||||
}
|
|
||||||
} else if self.ignore_ops {
|
|
||||||
let iter: Box<dyn Iterator<Item=char>> =
|
|
||||||
if self.max_depth == 0 {
|
|
||||||
Box::new(pstr.range_from(offset ..))
|
|
||||||
} else {
|
|
||||||
Box::new(pstr.range_from(offset ..).take(max_depth))
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut char_count = 0;
|
let buf_len = buf.len();
|
||||||
let mut byte_len = 0;
|
|
||||||
|
|
||||||
for c in iter {
|
let buf_iter: Box<dyn Iterator<Item=char>> =
|
||||||
self.print_char(self.quoted, '.');
|
if self.max_depth == 0 {
|
||||||
self.push_char('(');
|
Box::new(buf.chars())
|
||||||
|
} else {
|
||||||
|
Box::new(buf.chars().take(max_depth))
|
||||||
|
};
|
||||||
|
|
||||||
self.print_char(self.quoted, c);
|
let mut byte_len = 0;
|
||||||
self.push_char(',');
|
|
||||||
|
|
||||||
char_count += 1;
|
let char_printer = |printer: &mut Self, c| {
|
||||||
byte_len += c.len_utf8();
|
if printer.machine_st.flags.double_quotes.is_codes() {
|
||||||
}
|
let s = (c as u32).to_string();
|
||||||
|
|
||||||
let mut at_end = false;
|
push_space_if_amb!(printer, &s, {
|
||||||
|
printer.append_str(&s);
|
||||||
if self.max_depth > 0 && !pstr.at_end(offset + byte_len) {
|
});
|
||||||
self.append_str("...");
|
} else {
|
||||||
at_end = true;
|
printer.print_char(printer.quoted, c);
|
||||||
} else {
|
}
|
||||||
if let HeapCellValue::Addr(Addr::EmptyList) = &self.machine_st.heap[h+1] {
|
};
|
||||||
self.append_str("[]");
|
|
||||||
at_end = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _ in 0 .. char_count {
|
if self.ignore_ops {
|
||||||
self.push_char(')');
|
let mut char_count = 0;
|
||||||
}
|
|
||||||
|
|
||||||
if at_end {
|
for c in buf_iter {
|
||||||
break;
|
self.push_char('.');
|
||||||
}
|
self.push_char('(');
|
||||||
|
|
||||||
max_depth -= char_count;
|
char_printer(self, c);
|
||||||
} else {
|
self.push_char(',');
|
||||||
self.push_char('[');
|
|
||||||
|
|
||||||
let iter: Box<dyn Iterator<Item=char>> =
|
char_count += 1;
|
||||||
if self.max_depth == 0 {
|
byte_len += c.len_utf8();
|
||||||
Box::new(pstr.range_from(offset ..))
|
}
|
||||||
} else {
|
|
||||||
Box::new(pstr.range_from(offset ..).take(max_depth))
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut byte_len = 0;
|
for _ in 0 .. char_count {
|
||||||
let mut char_count = 0;
|
self.state_stack.push(TokenOrRedirect::Close);
|
||||||
|
}
|
||||||
|
|
||||||
for c in iter {
|
if self.max_depth > 0 && buf_len > byte_len {
|
||||||
self.print_char(false, c);
|
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
self.push_char(',');
|
} else {
|
||||||
|
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||||
byte_len += c.len_utf8();
|
iter.stack().push(end_addr);
|
||||||
char_count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.max_depth > 0 && !pstr.at_end(offset + byte_len) {
|
|
||||||
self.append_str("...|...]");
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
self.outputter.truncate(self.outputter.len() - ','.len_utf8());
|
|
||||||
self.push_char(']');
|
|
||||||
}
|
|
||||||
|
|
||||||
max_depth -= char_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
h += 2;
|
|
||||||
offset = 0;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.print_string_as_str(h, 0, self.quoted);
|
let switch = if !self.at_cdr(",") {
|
||||||
|
self.push_char('[');
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
for c in buf_iter {
|
||||||
|
char_printer(self, c);
|
||||||
|
self.push_char(',');
|
||||||
|
|
||||||
|
byte_len += c.len_utf8();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.state_stack.push(TokenOrRedirect::CloseList(Rc::new(
|
||||||
|
Cell::new((switch, 0))
|
||||||
|
)));
|
||||||
|
|
||||||
|
if self.max_depth > 0 && buf_len > byte_len {
|
||||||
|
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
|
} else {
|
||||||
|
self.outputter.truncate(self.outputter.len() - ','.len_utf8());
|
||||||
|
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||||
|
|
||||||
|
iter.stack().push(end_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1250,7 +1269,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
Some(addr) => addr,
|
Some(addr) => addr,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
match self.machine_st.heap.index_addr(&addr).as_ref() {
|
match self.machine_st.heap.index_addr(&addr).as_ref() {
|
||||||
&HeapCellValue::NamedStr(arity, ref name, ref spec) => {
|
&HeapCellValue::NamedStr(arity, ref name, ref spec) => {
|
||||||
let spec = fetch_op_spec(name.clone(), arity, spec.clone(), self.op_dir);
|
let spec = fetch_op_spec(name.clone(), arity, spec.clone(), self.op_dir);
|
||||||
@@ -1320,23 +1339,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
&HeapCellValue::Addr(Addr::Usize(u)) => {
|
&HeapCellValue::Addr(Addr::Usize(u)) => {
|
||||||
self.append_str(&format!("{}", u));
|
self.append_str(&format!("{}", u));
|
||||||
}
|
}
|
||||||
&HeapCellValue::Addr(Addr::PStrLocation(..))
|
|
||||||
if !self.machine_st.flags.double_quotes.is_atom() => {
|
|
||||||
if self.ignore_ops {
|
|
||||||
self.format_struct(iter, max_depth, 2, clause_name!("."));
|
|
||||||
} else {
|
|
||||||
self.push_list(iter, max_depth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&HeapCellValue::Addr(Addr::PStrLocation(h, n)) => {
|
&HeapCellValue::Addr(Addr::PStrLocation(h, n)) => {
|
||||||
if let HeapCellValue::PartialString(_) = &self.machine_st.heap[h] {
|
self.print_string(iter, max_depth, h, n);
|
||||||
self.print_string(max_depth, h, n);
|
|
||||||
|
|
||||||
iter.stack().pop();
|
|
||||||
iter.stack().pop();
|
|
||||||
} else {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
&HeapCellValue::Addr(Addr::Lis(_)) => {
|
&HeapCellValue::Addr(Addr::Lis(_)) => {
|
||||||
if self.ignore_ops {
|
if self.ignore_ops {
|
||||||
@@ -1358,21 +1362,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
&HeapCellValue::Rational(ref n) => {
|
&HeapCellValue::Rational(ref n) => {
|
||||||
self.print_number(Number::Rational(n.clone()), &op);
|
self.print_number(Number::Rational(n.clone()), &op);
|
||||||
}
|
}
|
||||||
&HeapCellValue::PartialString(_)
|
|
||||||
if self.print_strings_as_strs => {
|
|
||||||
if let Addr::Con(h) = addr {
|
|
||||||
self.print_string_as_str(h, 0, true);
|
|
||||||
} else {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&HeapCellValue::PartialString(_) => {
|
|
||||||
if let Addr::Con(h) = addr {
|
|
||||||
self.print_string(max_depth, h, 0);
|
|
||||||
} else {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&HeapCellValue::Stream(ref stream) => {
|
&HeapCellValue::Stream(ref stream) => {
|
||||||
if let Some(alias) = &stream.options.alias {
|
if let Some(alias) = &stream.options.alias {
|
||||||
self.print_atom(alias);
|
self.print_atom(alias);
|
||||||
@@ -1385,6 +1374,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -482,7 +482,7 @@ impl FactInstruction {
|
|||||||
|
|
||||||
functor!(
|
functor!(
|
||||||
"get_constant",
|
"get_constant",
|
||||||
[aux(h, 0), constant(c), aux(h, 1)],
|
[aux(h, 0), constant(h, c), aux(h, 1)],
|
||||||
[lvl_stub, rt_stub]
|
[lvl_stub, rt_stub]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -524,7 +524,7 @@ impl FactInstruction {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
&FactInstruction::UnifyConstant(ref c) => {
|
&FactInstruction::UnifyConstant(ref c) => {
|
||||||
functor!("unify_constant", [constant(c)], [])
|
functor!("unify_constant", [constant(h, c)], [])
|
||||||
}
|
}
|
||||||
&FactInstruction::UnifyLocalValue(r) => {
|
&FactInstruction::UnifyLocalValue(r) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
@@ -589,7 +589,7 @@ impl QueryInstruction {
|
|||||||
|
|
||||||
functor!(
|
functor!(
|
||||||
"put_constant",
|
"put_constant",
|
||||||
[aux(h, 0), constant(c), aux(h, 1)],
|
[aux(h, 0), constant(h, c), aux(h, 1)],
|
||||||
[lvl_stub, rt_stub]
|
[lvl_stub, rt_stub]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -640,7 +640,7 @@ impl QueryInstruction {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
&QueryInstruction::SetConstant(ref c) => {
|
&QueryInstruction::SetConstant(ref c) => {
|
||||||
functor!("set_constant", [constant(c)], [])
|
functor!("set_constant", [constant(h, c)], [])
|
||||||
}
|
}
|
||||||
&QueryInstruction::SetLocalValue(r) => {
|
&QueryInstruction::SetLocalValue(r) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|||||||
@@ -132,11 +132,11 @@ put_attr(Name, Arity) -->
|
|||||||
'$put_attr'(V, Attr)),
|
'$put_attr'(V, Attr)),
|
||||||
(put_atts(V, Attr) :- !, functor(Attr, Head, Arity),
|
(put_atts(V, Attr) :- !, functor(Attr, Head, Arity),
|
||||||
functor(AttrForm, Head, Arity),
|
functor(AttrForm, Head, Arity),
|
||||||
'$get_attr_list'(V, Ls),
|
'$get_attr_list'(V, Ls),
|
||||||
'$del_attr'(Ls, V, AttrForm),
|
'$del_attr'(Ls, V, AttrForm),
|
||||||
'$put_attr'(V, Attr)),
|
'$put_attr'(V, Attr)),
|
||||||
(put_atts(V, -Attr) :- !, functor(Attr, _, _),
|
(put_atts(V, -Attr) :- !, functor(Attr, _, _),
|
||||||
'$get_attr_list'(V, Ls),
|
'$get_attr_list'(V, Ls),
|
||||||
'$del_attr'(Ls, V, Attr))].
|
'$del_attr'(Ls, V, Attr))].
|
||||||
|
|
||||||
get_attr(Name, Arity) -->
|
get_attr(Name, Arity) -->
|
||||||
@@ -158,4 +158,3 @@ call_residue_vars(Goal, Vars) :-
|
|||||||
'$get_attr_var_queue_delim'(B),
|
'$get_attr_var_queue_delim'(B),
|
||||||
call(Goal),
|
call(Goal),
|
||||||
'$get_attr_var_queue_beyond'(B, Vars).
|
'$get_attr_var_queue_beyond'(B, Vars).
|
||||||
|
|
||||||
|
|||||||
@@ -262,8 +262,11 @@ univ_errors(Term, List, N) :-
|
|||||||
Term =.. List :- '$call_with_default_policy'(univ_errors(Term, List, N)),
|
Term =.. List :- '$call_with_default_policy'(univ_errors(Term, List, N)),
|
||||||
'$call_with_default_policy'(univ_worker(Term, List, N)).
|
'$call_with_default_policy'(univ_worker(Term, List, N)).
|
||||||
|
|
||||||
|
|
||||||
:- non_counted_backtracking univ_worker/3.
|
:- non_counted_backtracking univ_worker/3.
|
||||||
univ_worker(Term, List, _) :- atomic(Term), !, '$call_with_default_policy'(List = [Term]).
|
|
||||||
|
univ_worker(Term, List, _) :-
|
||||||
|
atomic(Term), !, '$call_with_default_policy'(List = [Term]).
|
||||||
univ_worker(Term, [Name|Args], N) :-
|
univ_worker(Term, [Name|Args], N) :-
|
||||||
var(Term), !,
|
var(Term), !,
|
||||||
'$call_with_default_policy'(Arity is N-1),
|
'$call_with_default_policy'(Arity is N-1),
|
||||||
@@ -274,7 +277,9 @@ univ_worker(Term, List, _) :-
|
|||||||
'$call_with_default_policy'(get_args(Args, Term, 1, Arity)),
|
'$call_with_default_policy'(get_args(Args, Term, 1, Arity)),
|
||||||
'$call_with_default_policy'(List = [Name|Args]).
|
'$call_with_default_policy'(List = [Name|Args]).
|
||||||
|
|
||||||
|
|
||||||
:- non_counted_backtracking get_args/4.
|
:- non_counted_backtracking get_args/4.
|
||||||
|
|
||||||
get_args(Args, _, _, 0) :-
|
get_args(Args, _, _, 0) :-
|
||||||
!, '$call_with_default_policy'(Args = []).
|
!, '$call_with_default_policy'(Args = []).
|
||||||
get_args([Arg], Func, N, N) :-
|
get_args([Arg], Func, N, N) :-
|
||||||
@@ -287,19 +292,19 @@ get_args([Arg|Args], Func, I0, N) :-
|
|||||||
% write, write_canonical, writeq, write_term.
|
% write, write_canonical, writeq, write_term.
|
||||||
is_write_option(Functor) :-
|
is_write_option(Functor) :-
|
||||||
Functor =.. [Name, Arg],
|
Functor =.. [Name, Arg],
|
||||||
( Arg == true -> true
|
( Arg == true -> true
|
||||||
; Arg == false -> true
|
; Arg == false -> true
|
||||||
; Name == variable_names -> must_be_var_names_list(Arg)
|
; Name == variable_names -> must_be_var_names_list(Arg)
|
||||||
; Name == max_depth -> integer(Arg), Arg >= 0
|
; Name == max_depth -> integer(Arg), Arg >= 0
|
||||||
; var(Arg) -> throw(error(instantiation_error, write_term/2))
|
; var(Arg) -> throw(error(instantiation_error, write_term/2))
|
||||||
; throw(error(domain_error(write_option, Functor), write_term/2))
|
; throw(error(domain_error(write_option, Functor), write_term/2))
|
||||||
), % 8.14.2.3 e)
|
), % 8.14.2.3 e)
|
||||||
( Name == ignore_ops -> true
|
( Name == ignore_ops -> true
|
||||||
; Name == quoted -> true
|
; Name == quoted -> true
|
||||||
; Name == numbervars -> true
|
; Name == numbervars -> true
|
||||||
; Name == variable_names -> true
|
; Name == variable_names -> true
|
||||||
; Name == max_depth -> true
|
; Name == max_depth -> true
|
||||||
; throw(error(domain_error(write_option, Functor), write_term/2))
|
; throw(error(domain_error(write_option, Functor), write_term/2))
|
||||||
). % 8.14.2.3 e)
|
). % 8.14.2.3 e)
|
||||||
|
|
||||||
inst_member_or([X|Xs], Y, Z) :-
|
inst_member_or([X|Xs], Y, Z) :-
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
:- module(cont, [reset/3, shift/1]).
|
:- module(cont, [reset/3, shift/1]).
|
||||||
|
|
||||||
reset(Goal, Ball, Cont) :-
|
reset(Goal, Ball, Cont) :-
|
||||||
@@ -7,14 +6,14 @@ reset(Goal, Ball, Cont) :-
|
|||||||
'$bind_from_register'(Cont, 3),
|
'$bind_from_register'(Cont, 3),
|
||||||
'$bind_from_register'(Ball, 4).
|
'$bind_from_register'(Ball, 4).
|
||||||
|
|
||||||
shift(Term) :-
|
shift(Ball) :-
|
||||||
'$nextEP'(first, E, P),
|
'$nextEP'(first, E, P),
|
||||||
get_chunks(E, P, L),
|
get_chunks(E, P, L),
|
||||||
( L == [] ->
|
( L == [] ->
|
||||||
Cont = none
|
Cont = none
|
||||||
; Cont = cont(call_continuation(L))
|
; Cont = cont(call_continuation(L))
|
||||||
),
|
),
|
||||||
'$write_cont_and_term'(_, _, Cont, Term),
|
'$write_cont_and_term'(_, _, Cont, Ball),
|
||||||
'$unwind_environments'.
|
'$unwind_environments'.
|
||||||
|
|
||||||
get_chunks(E, P, L) :-
|
get_chunks(E, P, L) :-
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ activate(Wrapper,Worker,T) :-
|
|||||||
|
|
||||||
delim(Wrapper,Worker,Table) :-
|
delim(Wrapper,Worker,Table) :-
|
||||||
% debug(tabling, 'ACT: ~p on ~p', [Wrapper, Table]),
|
% debug(tabling, 'ACT: ~p on ~p', [Wrapper, Table]),
|
||||||
reset(Worker,SourceCall,Continuation),
|
reset(Worker,SourceCall,Continuation),
|
||||||
( Continuation == none, var(SourceCall) ->
|
( Continuation == none, var(SourceCall) ->
|
||||||
( add_answer(Table,Wrapper)
|
( add_answer(Table,Wrapper)
|
||||||
-> true %debug(tabling, 'ADD: ~p', [Wrapper])
|
-> true %debug(tabling, 'ADD: ~p', [Wrapper])
|
||||||
@@ -144,9 +144,9 @@ delim(Wrapper,Worker,Table) :-
|
|||||||
)
|
)
|
||||||
;
|
;
|
||||||
( Continuation = cont(Cont) ->
|
( Continuation = cont(Cont) ->
|
||||||
true
|
true
|
||||||
; Continuation = none ->
|
; Continuation = none ->
|
||||||
Cont = true
|
Cont = true
|
||||||
),
|
),
|
||||||
SourceCall = call_info(_,SourceTable),
|
SourceCall = call_info(_,SourceTable),
|
||||||
TargetCall = call_info(Wrapper,Table),
|
TargetCall = call_info(Wrapper,Table),
|
||||||
@@ -178,7 +178,7 @@ completion_step(SourceTableID) :-
|
|||||||
fail
|
fail
|
||||||
;
|
;
|
||||||
true
|
true
|
||||||
).
|
).
|
||||||
|
|
||||||
table_get_work(NBWorklistID,Answer,Dependency) :-
|
table_get_work(NBWorklistID,Answer,Dependency) :-
|
||||||
% get_worklist(Table, Worklist),
|
% get_worklist(Table, Worklist),
|
||||||
@@ -192,7 +192,7 @@ table_get_work(NBWorklistID,Answer,Dependency) :-
|
|||||||
table_get_work_(NBWorklistID,Answer,Dependency) :-
|
table_get_work_(NBWorklistID,Answer,Dependency) :-
|
||||||
worklist_do_all_work(NBWorklistID,Answer,Dependency0), % This will eventually fail
|
worklist_do_all_work(NBWorklistID,Answer,Dependency0), % This will eventually fail
|
||||||
copy_term(Dependency0,Dependency).
|
copy_term(Dependency0,Dependency).
|
||||||
|
|
||||||
table_get_work_(NBWorklistID,_Answer,_Dependency) :-
|
table_get_work_(NBWorklistID,_Answer,_Dependency) :-
|
||||||
bb_get(NBWorklistID, table_nb_worklist(Worklist)),
|
bb_get(NBWorklistID, table_nb_worklist(Worklist)),
|
||||||
unset_flag_executing_all_work(Worklist),
|
unset_flag_executing_all_work(Worklist),
|
||||||
|
|||||||
@@ -208,4 +208,3 @@ dll_get_reverse_contents_(List, Contents) :-
|
|||||||
dll_get_pointer_to_previous(List, Prev),
|
dll_get_pointer_to_previous(List, Prev),
|
||||||
dll_get_reverse_contents_(Prev, Rest)
|
dll_get_reverse_contents_(Prev, Rest)
|
||||||
).
|
).
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Ported to Scryer Prolog by Mark Thom (2019/2020).
|
/* Ported to Scryer Prolog by Mark Thom (2019/2020).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
:- module(global_worklist,
|
:- module(global_worklist,
|
||||||
@@ -21,7 +21,7 @@ put_new_global_worklist :-
|
|||||||
bb_b_put(table_global_worklist_initialized, [])
|
bb_b_put(table_global_worklist_initialized, [])
|
||||||
).
|
).
|
||||||
|
|
||||||
add_to_global_worklist(TableIdentifier) :-
|
add_to_global_worklist(TableIdentifier) :-
|
||||||
bb_get(table_global_worklist, TableGlobalWorklistFlag),
|
bb_get(table_global_worklist, TableGlobalWorklistFlag),
|
||||||
get_atts(TableGlobalWorklistFlag, table_global_worklist(L1)),
|
get_atts(TableGlobalWorklistFlag, table_global_worklist(L1)),
|
||||||
put_atts(TableGlobalWorklistFlag, table_global_worklist([TableIdentifier|L1])),
|
put_atts(TableGlobalWorklistFlag, table_global_worklist([TableIdentifier|L1])),
|
||||||
@@ -34,7 +34,7 @@ worklist_empty :-
|
|||||||
|
|
||||||
pop_worklist(TableIdentifier) :-
|
pop_worklist(TableIdentifier) :-
|
||||||
bb_get(table_global_worklist,TableGlobalWorklistFlag),
|
bb_get(table_global_worklist,TableGlobalWorklistFlag),
|
||||||
get_atts(TableGlobalWorklistFlag, table_global_worklist(L1)),
|
get_atts(TableGlobalWorklistFlag, table_global_worklist(L1)),
|
||||||
L1 = [TableIdentifier|L2],
|
L1 = [TableIdentifier|L2],
|
||||||
put_atts(TableGlobalWorklistFlag, table_global_worklist(L2)),
|
put_atts(TableGlobalWorklistFlag, table_global_worklist(L2)),
|
||||||
bb_put(table_global_worklist, TableGlobalWorklistFlag).
|
bb_put(table_global_worklist, TableGlobalWorklistFlag).
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ trie_insert_1_1_1(>,_V,_L,R,Assoc,FunctorData,Trie,First,Rest,Value) :-
|
|||||||
% Look in the right part of the assoc tree.
|
% Look in the right part of the assoc tree.
|
||||||
trie_insert_1_1(R,Assoc,FunctorData,Trie,First,Rest,Value).
|
trie_insert_1_1(R,Assoc,FunctorData,Trie,First,Rest,Value).
|
||||||
|
|
||||||
trie_insert_2(RegularTerm,Rest,Trie,Value) :-
|
trie_insert_2(RegularTerm,Rest,Trie,Value) :-
|
||||||
p_trie_arity_univ(RegularTerm,FunctorData,KList),
|
p_trie_arity_univ(RegularTerm,FunctorData,KList),
|
||||||
append(KList,Rest,KList2),
|
append(KList,Rest,KList2),
|
||||||
trie_insert_1(KList2,FunctorData,Trie,Value).
|
trie_insert_1(KList2,FunctorData,Trie,Value).
|
||||||
|
|||||||
@@ -175,6 +175,12 @@ impl MachineState {
|
|||||||
&HeapCellValue::Addr(Addr::Float(n)) => {
|
&HeapCellValue::Addr(Addr::Float(n)) => {
|
||||||
interms.push(Number::Float(n))
|
interms.push(Number::Float(n))
|
||||||
}
|
}
|
||||||
|
&HeapCellValue::Addr(Addr::Usize(n)) => {
|
||||||
|
interms.push(Number::Integer(Rc::new(Integer::from(n))));
|
||||||
|
}
|
||||||
|
&HeapCellValue::Addr(Addr::CharCode(n)) => {
|
||||||
|
interms.push(Number::Integer(Rc::new(Integer::from(n))));
|
||||||
|
}
|
||||||
&HeapCellValue::Rational(ref n) => {
|
&HeapCellValue::Rational(ref n) => {
|
||||||
interms.push(Number::Rational(n.clone()))
|
interms.push(Number::Rational(n.clone()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,13 +21,13 @@ call_verify_attributes(Attrs, _, _, []) :-
|
|||||||
call_verify_attributes([], _, _, []).
|
call_verify_attributes([], _, _, []).
|
||||||
call_verify_attributes([Attr|Attrs], Var, Value, ListOfGoalLists) :-
|
call_verify_attributes([Attr|Attrs], Var, Value, ListOfGoalLists) :-
|
||||||
gather_modules([Attr|Attrs], Modules0),
|
gather_modules([Attr|Attrs], Modules0),
|
||||||
sort(Modules0, Modules),
|
sort(Modules0, Modules),
|
||||||
verify_attrs(Modules, Var, Value, ListOfGoalLists).
|
verify_attrs(Modules, Var, Value, ListOfGoalLists).
|
||||||
|
|
||||||
verify_attrs([Module|Modules], Var, Value, [Goals|ListOfGoalLists]) :-
|
verify_attrs([Module|Modules], Var, Value, [Goals|ListOfGoalLists]) :-
|
||||||
catch(Module:verify_attributes(Var, Value, Goals),
|
catch(Module:verify_attributes(Var, Value, Goals),
|
||||||
error(evaluation_error((Module:verify_attributes)/3), verify_attributes/3),
|
error(evaluation_error((Module:verify_attributes)/3), verify_attributes/3),
|
||||||
Goals = []),
|
Goals = []),
|
||||||
verify_attrs(Modules, Var, Value, ListOfGoalLists).
|
verify_attrs(Modules, Var, Value, ListOfGoalLists).
|
||||||
verify_attrs([], _, _, []).
|
verify_attrs([], _, _, []).
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ pub(super) struct AttrVarInitializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AttrVarInitializer {
|
impl AttrVarInitializer {
|
||||||
pub(super) fn new(verify_attrs_loc: usize, project_attrs_loc: usize) -> Self {
|
pub(super)
|
||||||
|
fn new(verify_attrs_loc: usize, project_attrs_loc: usize) -> Self {
|
||||||
AttrVarInitializer {
|
AttrVarInitializer {
|
||||||
attribute_goals: vec![],
|
attribute_goals: vec![],
|
||||||
attr_var_queue: vec![],
|
attr_var_queue: vec![],
|
||||||
@@ -32,21 +33,24 @@ impl AttrVarInitializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super) fn reset(&mut self) {
|
pub(super)
|
||||||
self.attribute_goals.clear();
|
fn reset(&mut self) {
|
||||||
|
self.attribute_goals.clear();
|
||||||
self.attr_var_queue.clear();
|
self.attr_var_queue.clear();
|
||||||
self.bindings.clear();
|
self.bindings.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super) fn backtrack(&mut self, queue_b: usize, bindings_b: usize) {
|
pub(super)
|
||||||
|
fn backtrack(&mut self, queue_b: usize, bindings_b: usize) {
|
||||||
self.attr_var_queue.truncate(queue_b);
|
self.attr_var_queue.truncate(queue_b);
|
||||||
self.bindings.truncate(bindings_b);
|
self.bindings.truncate(bindings_b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MachineState {
|
impl MachineState {
|
||||||
pub(super) fn push_attr_var_binding(&mut self, h: usize, addr: Addr) {
|
pub(super)
|
||||||
|
fn push_attr_var_binding(&mut self, h: usize, addr: Addr) {
|
||||||
if self.attr_var_init.bindings.is_empty() {
|
if self.attr_var_init.bindings.is_empty() {
|
||||||
self.attr_var_init.instigating_p = self.p.local();
|
self.attr_var_init.instigating_p = self.p.local();
|
||||||
|
|
||||||
@@ -92,7 +96,8 @@ impl MachineState {
|
|||||||
self[temp_v!(2)] = value_list_addr;
|
self[temp_v!(2)] = value_list_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn gather_attr_vars_created_since(&self, b: usize) -> IntoIter<Addr> {
|
pub(super)
|
||||||
|
fn gather_attr_vars_created_since(&self, b: usize) -> IntoIter<Addr> {
|
||||||
let mut attr_vars: Vec<_> = self.attr_var_init.attr_var_queue[b..]
|
let mut attr_vars: Vec<_> = self.attr_var_init.attr_var_queue[b..]
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|h| match self.store(self.deref(Addr::HeapCell(*h))) {
|
.filter_map(|h| match self.store(self.deref(Addr::HeapCell(*h))) {
|
||||||
@@ -109,7 +114,8 @@ impl MachineState {
|
|||||||
attr_vars.into_iter()
|
attr_vars.into_iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn verify_attr_interrupt(&mut self, p: usize) {
|
pub(super)
|
||||||
|
fn verify_attr_interrupt(&mut self, p: usize) {
|
||||||
self.allocate(self.num_of_args + 2);
|
self.allocate(self.num_of_args + 2);
|
||||||
|
|
||||||
let e = self.e;
|
let e = self.e;
|
||||||
|
|||||||
@@ -33,13 +33,13 @@ struct CopyTermState<T: CopierTarget> {
|
|||||||
scan: usize,
|
scan: usize,
|
||||||
old_h: usize,
|
old_h: usize,
|
||||||
target: T,
|
target: T,
|
||||||
attr_var_policy: AttrVarPolicy
|
attr_var_policy: AttrVarPolicy,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: CopierTarget> CopyTermState<T> {
|
impl<T: CopierTarget> CopyTermState<T> {
|
||||||
fn new(target: T, attr_var_policy: AttrVarPolicy) -> Self {
|
fn new(target: T, attr_var_policy: AttrVarPolicy) -> Self {
|
||||||
CopyTermState {
|
CopyTermState {
|
||||||
trail: vec![],
|
trail: Trail::new(),
|
||||||
scan: 0,
|
scan: 0,
|
||||||
old_h: target.threshold(),
|
old_h: target.threshold(),
|
||||||
target,
|
target,
|
||||||
@@ -53,124 +53,86 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
&mut self.target[scan]
|
&mut self.target[scan]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copied_list(&mut self, addr: usize) -> bool {
|
|
||||||
match &self.target[addr] {
|
|
||||||
HeapCellValue::Addr(Addr::Lis(addr)) | HeapCellValue::Addr(Addr::HeapCell(addr)) => {
|
|
||||||
if *addr >= self.old_h {
|
|
||||||
*self.value_at_scan() = HeapCellValue::Addr(Addr::Lis(*addr));
|
|
||||||
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 let Addr::Lis(h) = self.target[addr + 1].as_addr(addr + 1) {
|
||||||
return;
|
if h >= self.old_h {
|
||||||
|
*self.value_at_scan() = HeapCellValue::Addr(Addr::Lis(h));
|
||||||
|
self.scan += 1;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let threshold = self.target.threshold();
|
let threshold = self.target.threshold();
|
||||||
|
|
||||||
*self.value_at_scan() = HeapCellValue::Addr(Addr::Lis(threshold));
|
*self.value_at_scan() = HeapCellValue::Addr(Addr::Lis(threshold));
|
||||||
|
|
||||||
let ra = self.target[addr].as_addr(threshold);
|
for i in 0 .. 2 {
|
||||||
let rd = self.target.store(self.target.deref(ra));
|
let hcv = self.target[addr + i].context_free_clone();
|
||||||
|
self.target.push(hcv);
|
||||||
|
}
|
||||||
|
|
||||||
self.target.push(HeapCellValue::Addr(ra));
|
let cdr = self.target.store(self.target.deref(Addr::HeapCell(addr + 1)));
|
||||||
|
|
||||||
let hcv = HeapCellValue::Addr(self.target[addr + 1].as_addr(addr + 1));
|
if let Addr::Lis(_) = cdr {
|
||||||
|
let tail_addr = self.target[addr + 1].as_addr(addr + 1);
|
||||||
|
|
||||||
self.target.push(hcv);
|
self.trail.push((
|
||||||
|
Ref::HeapCell(addr + 1),
|
||||||
|
HeapCellValue::Addr(tail_addr),
|
||||||
|
));
|
||||||
|
|
||||||
match rd {
|
self.target[addr + 1] = HeapCellValue::Addr(Addr::Lis(threshold));
|
||||||
Addr::AttrVar(h) | Addr::HeapCell(h)
|
}
|
||||||
if h >= self.old_h => {
|
|
||||||
self.target[threshold] = HeapCellValue::Addr(rd)
|
|
||||||
}
|
|
||||||
var @ Addr::AttrVar(_)
|
|
||||||
| var @ Addr::HeapCell(..)
|
|
||||||
| var @ Addr::StackCell(..) => {
|
|
||||||
if ra == rd {
|
|
||||||
self.reinstantiate_var(var, threshold);
|
|
||||||
|
|
||||||
if let AttrVarPolicy::StripAttributes = self.attr_var_policy {
|
|
||||||
self.trail.push((Ref::HeapCell(addr), HeapCellValue::Addr(ra)));
|
|
||||||
self.target[addr] = HeapCellValue::Addr(Addr::HeapCell(threshold));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.target[threshold] = HeapCellValue::Addr(ra);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
self.trail.push((
|
|
||||||
Ref::HeapCell(addr),
|
|
||||||
HeapCellValue::Addr(self.target[addr].as_addr(addr)),
|
|
||||||
));
|
|
||||||
|
|
||||||
self.target[addr] = HeapCellValue::Addr(Addr::Lis(threshold))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.scan += 1;
|
self.scan += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copied_partial_string(&mut self, addr: usize) -> bool {
|
fn copy_partial_string(&mut self, addr: usize, n: usize) {
|
||||||
if let &HeapCellValue::Addr(Addr::PStrLocation(h, n)) = &self.target[addr + 1] {
|
if let &HeapCellValue::Addr(Addr::PStrLocation(h, _)) = &self.target[addr] {
|
||||||
if h >= self.old_h {
|
if h >= self.old_h {
|
||||||
*self.value_at_scan() = HeapCellValue::Addr(Addr::PStrLocation(h, n));
|
*self.value_at_scan() = HeapCellValue::Addr(Addr::PStrLocation(h, n));
|
||||||
self.scan += 1;
|
self.scan += 1;
|
||||||
return true;
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn copy_partial_string(&mut self, addr: usize, n: usize) {
|
|
||||||
let threshold = self.target.threshold();
|
let threshold = self.target.threshold();
|
||||||
let tail_addr = self.target[addr + 1].as_addr(addr + 1);
|
|
||||||
|
|
||||||
let trail_item = mem::replace(
|
*self.value_at_scan() =
|
||||||
&mut self.target[addr + 1],
|
HeapCellValue::Addr(Addr::PStrLocation(threshold, 0));
|
||||||
HeapCellValue::Addr(Addr::PStrLocation(threshold, 0)),
|
|
||||||
);
|
|
||||||
|
|
||||||
self.trail.push((
|
self.scan += 1;
|
||||||
Ref::HeapCell(addr + 1),
|
|
||||||
trail_item,
|
|
||||||
));
|
|
||||||
|
|
||||||
let pstr =
|
let (pstr, has_tail) =
|
||||||
match &self.target[addr] {
|
match &self.target[addr] {
|
||||||
HeapCellValue::PartialString(ref pstr) => {
|
&HeapCellValue::PartialString(ref pstr, has_tail) => {
|
||||||
pstr.clone_from_offset(n)
|
(pstr.clone_from_offset(n), has_tail)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.target.push(HeapCellValue::PartialString(pstr));
|
self.target.push(HeapCellValue::PartialString(pstr, has_tail));
|
||||||
self.target.push(HeapCellValue::Addr(tail_addr));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn copy_partial_string_from(&mut self, addr: usize, n: usize) {
|
let replacement = HeapCellValue::Addr(Addr::PStrLocation(threshold, 0));
|
||||||
if self.copied_partial_string(addr) {
|
|
||||||
return;
|
let trail_item = mem::replace(
|
||||||
|
&mut self.target[addr],
|
||||||
|
replacement,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.trail.push((
|
||||||
|
Ref::HeapCell(addr),
|
||||||
|
trail_item,
|
||||||
|
));
|
||||||
|
|
||||||
|
if has_tail {
|
||||||
|
let tail_addr = self.target[addr + 1].as_addr(addr + 1);
|
||||||
|
self.target.push(HeapCellValue::Addr(tail_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
let threshold = self.target.threshold();
|
|
||||||
|
|
||||||
self.target[self.scan] =
|
|
||||||
HeapCellValue::Addr(Addr::PStrLocation(threshold, 0));
|
|
||||||
|
|
||||||
self.scan += 1;
|
|
||||||
|
|
||||||
self.copy_partial_string(addr, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reinstantiate_var(&mut self, addr: Addr, frontier: usize) {
|
fn reinstantiate_var(&mut self, addr: Addr, frontier: usize) {
|
||||||
@@ -178,6 +140,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
Addr::HeapCell(h) => {
|
Addr::HeapCell(h) => {
|
||||||
self.target[frontier] = HeapCellValue::Addr(Addr::HeapCell(frontier));
|
self.target[frontier] = HeapCellValue::Addr(Addr::HeapCell(frontier));
|
||||||
self.target[h] = HeapCellValue::Addr(Addr::HeapCell(frontier));
|
self.target[h] = HeapCellValue::Addr(Addr::HeapCell(frontier));
|
||||||
|
|
||||||
self.trail.push((
|
self.trail.push((
|
||||||
Ref::HeapCell(h),
|
Ref::HeapCell(h),
|
||||||
HeapCellValue::Addr(Addr::HeapCell(h)),
|
HeapCellValue::Addr(Addr::HeapCell(h)),
|
||||||
@@ -186,6 +149,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
Addr::StackCell(fr, sc) => {
|
Addr::StackCell(fr, sc) => {
|
||||||
self.target[frontier] = HeapCellValue::Addr(Addr::HeapCell(frontier));
|
self.target[frontier] = HeapCellValue::Addr(Addr::HeapCell(frontier));
|
||||||
self.target.stack().index_and_frame_mut(fr)[sc] = Addr::HeapCell(frontier);
|
self.target.stack().index_and_frame_mut(fr)[sc] = Addr::HeapCell(frontier);
|
||||||
|
|
||||||
self.trail.push((
|
self.trail.push((
|
||||||
Ref::StackCell(fr, sc),
|
Ref::StackCell(fr, sc),
|
||||||
HeapCellValue::Addr(Addr::StackCell(fr, sc)),
|
HeapCellValue::Addr(Addr::StackCell(fr, sc)),
|
||||||
@@ -199,7 +163,8 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.target[frontier] = HeapCellValue::Addr(Addr::HeapCell(threshold));
|
self.target[frontier] = HeapCellValue::Addr(Addr::HeapCell(threshold));
|
||||||
self.target[h] = HeapCellValue::Addr(Addr::HeapCell(threshold));
|
self.target[h] = HeapCellValue::Addr(Addr::HeapCell(frontier));
|
||||||
|
|
||||||
self.trail.push((
|
self.trail.push((
|
||||||
Ref::AttrVar(h),
|
Ref::AttrVar(h),
|
||||||
HeapCellValue::Addr(Addr::AttrVar(h)),
|
HeapCellValue::Addr(Addr::AttrVar(h)),
|
||||||
@@ -212,7 +177,9 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
self.target.push(list_val);
|
self.target.push(list_val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => unreachable!()
|
_ => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,17 +201,39 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn copy_stream(&mut self, addr: usize) {
|
||||||
|
let threshold = self.target.threshold();
|
||||||
|
|
||||||
|
let trail_item = mem::replace(
|
||||||
|
&mut self.target[addr],
|
||||||
|
HeapCellValue::Addr(Addr::Stream(threshold)),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.trail.push((
|
||||||
|
Ref::HeapCell(addr),
|
||||||
|
trail_item,
|
||||||
|
));
|
||||||
|
|
||||||
|
self.target.push(HeapCellValue::Stream(Stream::null_stream()));
|
||||||
|
|
||||||
|
self.scan += 1;
|
||||||
|
}
|
||||||
|
|
||||||
fn copy_structure(&mut self, addr: usize) {
|
fn copy_structure(&mut self, addr: usize) {
|
||||||
match self.target[addr].context_free_clone() {
|
match self.target[addr].context_free_clone() {
|
||||||
HeapCellValue::NamedStr(arity, name, fixity) => {
|
HeapCellValue::NamedStr(arity, name, fixity) => {
|
||||||
let threshold = self.target.threshold();
|
let threshold = self.target.threshold();
|
||||||
|
|
||||||
*self.value_at_scan() = HeapCellValue::Addr(Addr::Str(threshold));
|
*self.value_at_scan() = HeapCellValue::Addr(Addr::Str(threshold));
|
||||||
self.target[addr] = HeapCellValue::Addr(Addr::Str(threshold));
|
|
||||||
|
let trail_item = mem::replace(
|
||||||
|
&mut self.target[addr],
|
||||||
|
HeapCellValue::Addr(Addr::Str(threshold)),
|
||||||
|
);
|
||||||
|
|
||||||
self.trail.push((
|
self.trail.push((
|
||||||
Ref::HeapCell(addr),
|
Ref::HeapCell(addr),
|
||||||
HeapCellValue::NamedStr(arity, name.clone(), fixity.clone()),
|
trail_item,
|
||||||
));
|
));
|
||||||
|
|
||||||
self.target.push(HeapCellValue::NamedStr(arity, name, fixity));
|
self.target.push(HeapCellValue::NamedStr(arity, name, fixity));
|
||||||
@@ -257,7 +246,9 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
HeapCellValue::Addr(Addr::Str(addr)) => {
|
HeapCellValue::Addr(Addr::Str(addr)) => {
|
||||||
*self.value_at_scan() = HeapCellValue::Addr(Addr::Str(addr))
|
*self.value_at_scan() = HeapCellValue::Addr(Addr::Str(addr))
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.scan += 1;
|
self.scan += 1;
|
||||||
@@ -272,26 +263,30 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
&mut HeapCellValue::Addr(addr) => {
|
&mut HeapCellValue::Addr(addr) => {
|
||||||
match addr {
|
match addr {
|
||||||
Addr::Con(h) => {
|
Addr::Con(h) => {
|
||||||
self.target.push(self.target[h].context_free_clone());
|
let addr = self.target[h].as_addr(h);
|
||||||
self.scan += 1;
|
|
||||||
}
|
if addr == Addr::Con(h) {
|
||||||
Addr::Stream(_) => {
|
*self.value_at_scan() = self.target[h].context_free_clone();
|
||||||
self.target.push(HeapCellValue::Stream(Stream::null_stream()));
|
} else {
|
||||||
self.scan += 1;
|
*self.value_at_scan() = HeapCellValue::Addr(addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Addr::Lis(h) => {
|
Addr::Lis(h) => {
|
||||||
self.copy_list(h);
|
self.copy_list(h);
|
||||||
}
|
}
|
||||||
addr @ Addr::AttrVar(_)
|
addr @ Addr::AttrVar(_) |
|
||||||
| addr @ Addr::HeapCell(_)
|
addr @ Addr::HeapCell(_) |
|
||||||
| addr @ Addr::StackCell(..) => {
|
addr @ Addr::StackCell(..) => {
|
||||||
self.copy_var(addr);
|
self.copy_var(addr);
|
||||||
}
|
}
|
||||||
Addr::Str(addr) => {
|
Addr::Str(addr) => {
|
||||||
self.copy_structure(addr);
|
self.copy_structure(addr);
|
||||||
}
|
}
|
||||||
Addr::PStrLocation(addr, n) => {
|
Addr::PStrLocation(addr, n) => {
|
||||||
self.copy_partial_string_from(addr, n);
|
self.copy_partial_string(addr, n);
|
||||||
|
}
|
||||||
|
Addr::Stream(h) => {
|
||||||
|
self.copy_stream(h);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.scan += 1;
|
self.scan += 1;
|
||||||
|
|||||||
@@ -51,13 +51,19 @@ impl Machine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let arity = match self.machine_st.store(self.machine_st.deref(arity)) {
|
let arity = match self.machine_st.store(self.machine_st.deref(arity)) {
|
||||||
Addr::Con(h) =>
|
Addr::Con(h) => {
|
||||||
if let HeapCellValue::Integer(ref arity) = &self.machine_st.heap[h] {
|
if let HeapCellValue::Integer(ref arity) = &self.machine_st.heap[h] {
|
||||||
arity.to_usize().unwrap()
|
arity.to_usize().unwrap()
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
},
|
}
|
||||||
_ => unreachable!(),
|
}
|
||||||
|
Addr::Usize(n) => {
|
||||||
|
n
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
(name, arity)
|
(name, arity)
|
||||||
|
|||||||
@@ -39,12 +39,12 @@ impl<T: RawBlockTraits> Drop for HeapTemplate<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate)
|
||||||
struct HeapIntoIterator<T: RawBlockTraits> {
|
struct HeapIntoIter<T: RawBlockTraits> {
|
||||||
offset: usize,
|
offset: usize,
|
||||||
buf: RawBlock<T>,
|
buf: RawBlock<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RawBlockTraits> Drop for HeapIntoIterator<T> {
|
impl<T: RawBlockTraits> Drop for HeapIntoIter<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let mut heap =
|
let mut heap =
|
||||||
HeapTemplate { buf: self.buf.take(), _marker: PhantomData };
|
HeapTemplate { buf: self.buf.take(), _marker: PhantomData };
|
||||||
@@ -54,7 +54,7 @@ impl<T: RawBlockTraits> Drop for HeapIntoIterator<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RawBlockTraits> Iterator for HeapIntoIterator<T> {
|
impl<T: RawBlockTraits> Iterator for HeapIntoIter<T> {
|
||||||
type Item = HeapCellValue;
|
type Item = HeapCellValue;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
@@ -72,19 +72,19 @@ impl<T: RawBlockTraits> Iterator for HeapIntoIterator<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate)
|
||||||
struct HeapIterator<'a, T: RawBlockTraits> {
|
struct HeapIter<'a, T: RawBlockTraits> {
|
||||||
offset: usize,
|
offset: usize,
|
||||||
buf: &'a RawBlock<T>,
|
buf: &'a RawBlock<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: RawBlockTraits> HeapIterator<'a, T> {
|
impl<'a, T: RawBlockTraits> HeapIter<'a, T> {
|
||||||
pub(crate)
|
pub(crate)
|
||||||
fn new(buf: &'a RawBlock<T>, offset: usize) -> Self {
|
fn new(buf: &'a RawBlock<T>, offset: usize) -> Self {
|
||||||
HeapIterator { buf, offset }
|
HeapIter { buf, offset }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: RawBlockTraits> Iterator for HeapIterator<'a, T> {
|
impl<'a, T: RawBlockTraits> Iterator for HeapIter<'a, T> {
|
||||||
type Item = &'a HeapCellValue;
|
type Item = &'a HeapCellValue;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
@@ -101,20 +101,28 @@ impl<'a, T: RawBlockTraits> Iterator for HeapIterator<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub(crate)
|
pub(crate)
|
||||||
struct HeapIteratorMut<'a, T: RawBlockTraits> {
|
fn print_heap_terms<'a, I: Iterator<Item = &'a HeapCellValue>>(heap: I, h: usize) {
|
||||||
|
for (index, term) in heap.enumerate() {
|
||||||
|
println!("{} : {}", h + index, term);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate)
|
||||||
|
struct HeapIterMut<'a, T: RawBlockTraits> {
|
||||||
offset: usize,
|
offset: usize,
|
||||||
buf: &'a mut RawBlock<T>,
|
buf: &'a mut RawBlock<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: RawBlockTraits> HeapIteratorMut<'a, T> {
|
impl<'a, T: RawBlockTraits> HeapIterMut<'a, T> {
|
||||||
pub(crate)
|
pub(crate)
|
||||||
fn new(buf: &'a mut RawBlock<T>, offset: usize) -> Self {
|
fn new(buf: &'a mut RawBlock<T>, offset: usize) -> Self {
|
||||||
HeapIteratorMut { buf, offset }
|
HeapIterMut { buf, offset }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: RawBlockTraits> Iterator for HeapIteratorMut<'a, T> {
|
impl<'a, T: RawBlockTraits> Iterator for HeapIterMut<'a, T> {
|
||||||
type Item = &'a mut HeapCellValue;
|
type Item = &'a mut HeapCellValue;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
@@ -160,7 +168,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
&HeapCellValue::Rational(ref r) => {
|
&HeapCellValue::Rational(ref r) => {
|
||||||
HeapCellValue::Rational(r.clone())
|
HeapCellValue::Rational(r.clone())
|
||||||
}
|
}
|
||||||
&HeapCellValue::PartialString(_) => {
|
&HeapCellValue::PartialString(..) => {
|
||||||
HeapCellValue::Addr(Addr::PStrLocation(h, 0))
|
HeapCellValue::Addr(Addr::PStrLocation(h, 0))
|
||||||
}
|
}
|
||||||
&HeapCellValue::Stream(_) => {
|
&HeapCellValue::Stream(_) => {
|
||||||
@@ -169,6 +177,15 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn pop(&mut self) {
|
||||||
|
let h = self.h();
|
||||||
|
|
||||||
|
if h > 0 {
|
||||||
|
self.truncate(h - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate)
|
||||||
fn put_constant(&mut self, c: Constant) -> Addr {
|
fn put_constant(&mut self, c: Constant) -> Addr {
|
||||||
@@ -177,40 +194,45 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
Addr::Con(self.push(HeapCellValue::Atom(name, op)))
|
Addr::Con(self.push(HeapCellValue::Atom(name, op)))
|
||||||
}
|
}
|
||||||
Constant::Char(c) => {
|
Constant::Char(c) => {
|
||||||
self.push(HeapCellValue::Addr(Addr::Char(c)));
|
|
||||||
Addr::Char(c)
|
Addr::Char(c)
|
||||||
}
|
}
|
||||||
Constant::CharCode(c) => {
|
Constant::CharCode(c) => {
|
||||||
self.push(HeapCellValue::Addr(Addr::CharCode(c)));
|
|
||||||
Addr::CharCode(c)
|
Addr::CharCode(c)
|
||||||
}
|
}
|
||||||
Constant::CutPoint(cp) => {
|
|
||||||
self.push(HeapCellValue::Addr(Addr::CutPoint(cp)));
|
|
||||||
Addr::CutPoint(cp)
|
|
||||||
}
|
|
||||||
Constant::EmptyList => {
|
Constant::EmptyList => {
|
||||||
self.push(HeapCellValue::Addr(Addr::EmptyList));
|
|
||||||
Addr::EmptyList
|
Addr::EmptyList
|
||||||
}
|
}
|
||||||
Constant::Integer(n) => {
|
Constant::Integer(n) => {
|
||||||
Addr::Con(self.push(HeapCellValue::Integer(n)))
|
Addr::Con(self.push(HeapCellValue::Integer(n)))
|
||||||
}
|
}
|
||||||
Constant::Rational(r) => {
|
Constant::Rational(r) => {
|
||||||
Addr::Con(self.push(HeapCellValue::Rational(r)))
|
Addr::Con(self.push(HeapCellValue::Rational(r)))
|
||||||
}
|
}
|
||||||
Constant::Float(f) => {
|
Constant::Float(f) => {
|
||||||
self.push(HeapCellValue::Addr(Addr::Float(f)));
|
|
||||||
Addr::Float(f)
|
Addr::Float(f)
|
||||||
}
|
}
|
||||||
Constant::String(s) => {
|
Constant::String(s) => {
|
||||||
let addr = self.allocate_pstr(&s);
|
if s.is_empty() {
|
||||||
let h = self.h();
|
Addr::EmptyList
|
||||||
|
} else {
|
||||||
self[h - 1] = HeapCellValue::Addr(Addr::EmptyList);
|
let addr = self.allocate_pstr(&s);
|
||||||
addr
|
self.pop();
|
||||||
|
|
||||||
|
let h = self.h();
|
||||||
|
|
||||||
|
match &mut self[h - 1] {
|
||||||
|
&mut HeapCellValue::PartialString(_, ref mut has_tail) => {
|
||||||
|
*has_tail = false;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addr
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Constant::Usize(n) => {
|
Constant::Usize(n) => {
|
||||||
self.push(HeapCellValue::Addr(Addr::Usize(n)));
|
|
||||||
Addr::Usize(n)
|
Addr::Usize(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -239,7 +261,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate)
|
||||||
fn integer_at(&self, h: usize) -> bool {
|
fn integer_at(&self, h: usize) -> bool {
|
||||||
@@ -279,9 +301,12 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
val @ HeapCellValue::Stream(..) => {
|
val @ HeapCellValue::Stream(..) => {
|
||||||
Addr::Stream(self.push(val))
|
Addr::Stream(self.push(val))
|
||||||
}
|
}
|
||||||
val @ HeapCellValue::PartialString(_) => {
|
HeapCellValue::PartialString(pstr, has_tail) => {
|
||||||
let h = self.push(val);
|
let h = self.push(HeapCellValue::PartialString(pstr, has_tail));
|
||||||
self.push(HeapCellValue::Addr(Addr::EmptyList));
|
|
||||||
|
if has_tail {
|
||||||
|
self.push(HeapCellValue::Addr(Addr::EmptyList));
|
||||||
|
}
|
||||||
|
|
||||||
Addr::Con(h)
|
Addr::Con(h)
|
||||||
}
|
}
|
||||||
@@ -296,7 +321,8 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
let h = self.h();
|
let h = self.h();
|
||||||
|
|
||||||
self.push(HeapCellValue::PartialString(
|
self.push(HeapCellValue::PartialString(
|
||||||
PartialString::empty()
|
PartialString::empty(),
|
||||||
|
true,
|
||||||
));
|
));
|
||||||
|
|
||||||
self.push(HeapCellValue::Addr(
|
self.push(HeapCellValue::Addr(
|
||||||
@@ -343,7 +369,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.push(HeapCellValue::PartialString(pstr));
|
self.push(HeapCellValue::PartialString(pstr, true));
|
||||||
|
|
||||||
if rest_src != "" {
|
if rest_src != "" {
|
||||||
self.push(HeapCellValue::Addr(Addr::PStrLocation(h + 2, 0)));
|
self.push(HeapCellValue::Addr(Addr::PStrLocation(h + 2, 0)));
|
||||||
@@ -414,7 +440,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
self.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
|
self.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
|
||||||
self.push(value);
|
self.push(value);
|
||||||
|
|
||||||
h += mem::size_of::<HeapCellValue>() * 2;
|
h += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.push(HeapCellValue::Addr(Addr::EmptyList));
|
self.push(HeapCellValue::Addr(Addr::EmptyList));
|
||||||
@@ -424,18 +450,18 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
|
|
||||||
/* Create an iterator starting from the passed offset. */
|
/* Create an iterator starting from the passed offset. */
|
||||||
pub(crate)
|
pub(crate)
|
||||||
fn iter_from<'a>(&'a self, offset: usize) -> HeapIterator<'a, T> {
|
fn iter_from<'a>(&'a self, offset: usize) -> HeapIter<'a, T> {
|
||||||
HeapIterator::new(&self.buf, offset * mem::size_of::<HeapCellValue>())
|
HeapIter::new(&self.buf, offset * mem::size_of::<HeapCellValue>())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate)
|
||||||
fn iter_mut_from<'a>(&'a mut self, offset: usize) -> HeapIteratorMut<'a, T> {
|
fn iter_mut_from<'a>(&'a mut self, offset: usize) -> HeapIterMut<'a, T> {
|
||||||
HeapIteratorMut::new(&mut self.buf, offset * mem::size_of::<HeapCellValue>())
|
HeapIterMut::new(&mut self.buf, offset * mem::size_of::<HeapCellValue>())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate)
|
||||||
fn into_iter(mut self) -> HeapIntoIterator<T> {
|
fn into_iter(mut self) -> HeapIntoIter<T> {
|
||||||
HeapIntoIterator { buf: self.buf.take(), offset: 0 }
|
HeapIntoIter { buf: self.buf.take(), offset: 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate)
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ impl MachineError {
|
|||||||
SharedOpDesc::new(400, YFX),
|
SharedOpDesc::new(400, YFX),
|
||||||
[clause_name(name), integer(arity)]
|
[clause_name(name), integer(arity)]
|
||||||
);
|
);
|
||||||
|
|
||||||
let stub = functor!(
|
let stub = functor!(
|
||||||
"existence_error",
|
"existence_error",
|
||||||
[atom("procedure"), aux(h, 0)],
|
[atom("procedure"), aux(h, 0)],
|
||||||
@@ -286,7 +286,7 @@ impl MachineError {
|
|||||||
fn domain_error<T: DomainError>(error: DomainErrorType, culprit: T) -> Self {
|
fn domain_error<T: DomainError>(error: DomainErrorType, culprit: T) -> Self {
|
||||||
culprit.domain_error(error)
|
culprit.domain_error(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super)
|
||||||
fn instantiation_error() -> Self {
|
fn instantiation_error() -> Self {
|
||||||
let stub = functor!("instantiation_error");
|
let stub = functor!("instantiation_error");
|
||||||
@@ -352,7 +352,7 @@ impl MachineError {
|
|||||||
|
|
||||||
let location = err.line_and_col_num();
|
let location = err.line_and_col_num();
|
||||||
let stub = functor!(err.as_str());
|
let stub = functor!(err.as_str());
|
||||||
|
|
||||||
let stub = functor!(
|
let stub = functor!(
|
||||||
"syntax_error",
|
"syntax_error",
|
||||||
[aux(h, 0)],
|
[aux(h, 0)],
|
||||||
@@ -608,7 +608,7 @@ impl MachineState {
|
|||||||
pub(super)
|
pub(super)
|
||||||
fn check_keysort_errors(&self) -> CallResult {
|
fn check_keysort_errors(&self) -> CallResult {
|
||||||
let stub = MachineError::functor_stub(clause_name!("keysort"), 2);
|
let stub = MachineError::functor_stub(clause_name!("keysort"), 2);
|
||||||
|
|
||||||
let pairs = self.store(self.deref(self[temp_v!(1)].clone()));
|
let pairs = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||||
let sorted = self.store(self.deref(self[temp_v!(2)].clone()));
|
let sorted = self.store(self.deref(self[temp_v!(2)].clone()));
|
||||||
|
|
||||||
|
|||||||
@@ -152,6 +152,20 @@ impl PartialOrd<Ref> for Addr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Addr {
|
impl Addr {
|
||||||
|
#[inline]
|
||||||
|
pub fn is_heap_bound(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Addr::Char(_) | Addr::CharCode(_) | Addr::EmptyList
|
||||||
|
| Addr::CutPoint(_) | Addr::Usize(_) | Addr::Float(_) => {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn is_ref(&self) -> bool {
|
pub fn is_ref(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::AttrVar(_) => {
|
Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::AttrVar(_) => {
|
||||||
@@ -163,6 +177,7 @@ impl Addr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn as_var(&self) -> Option<Ref> {
|
pub fn as_var(&self) -> Option<Ref> {
|
||||||
match self {
|
match self {
|
||||||
&Addr::AttrVar(h) => Some(Ref::AttrVar(h)),
|
&Addr::AttrVar(h) => Some(Ref::AttrVar(h)),
|
||||||
@@ -173,7 +188,7 @@ impl Addr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super)
|
||||||
fn order_category(&self, heap: &Heap) -> Option<TermOrderCategory> {
|
fn order_category(&self, heap: &Heap) -> Option<TermOrderCategory> {
|
||||||
match self {
|
match self {
|
||||||
Addr::HeapCell(_) | Addr::AttrVar(_) | Addr::StackCell(..) => {
|
Addr::HeapCell(_) | Addr::AttrVar(_) | Addr::StackCell(..) => {
|
||||||
Some(TermOrderCategory::Variable)
|
Some(TermOrderCategory::Variable)
|
||||||
@@ -200,18 +215,21 @@ impl Addr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Addr::Char(_) | Addr::CharCode(_) | Addr::EmptyList => {
|
Addr::Char(_) | Addr::EmptyList => {
|
||||||
Some(TermOrderCategory::Atom)
|
Some(TermOrderCategory::Atom)
|
||||||
}
|
}
|
||||||
|
Addr::Usize(_) | Addr::CharCode(_) => {
|
||||||
|
Some(TermOrderCategory::Integer)
|
||||||
|
}
|
||||||
Addr::Lis(_) | Addr::PStrLocation(..) | Addr::Str(_) => {
|
Addr::Lis(_) | Addr::PStrLocation(..) | Addr::Str(_) => {
|
||||||
Some(TermOrderCategory::Compound)
|
Some(TermOrderCategory::Compound)
|
||||||
}
|
}
|
||||||
Addr::CutPoint(_) | Addr::Usize(_) | Addr::Stream(_) => {
|
Addr::CutPoint(_) | Addr::Stream(_) => {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_constant(&self, machine_st: &MachineState) -> Option<Constant> {
|
pub fn as_constant(&self, machine_st: &MachineState) -> Option<Constant> {
|
||||||
match self {
|
match self {
|
||||||
&Addr::Char(c) => {
|
&Addr::Char(c) => {
|
||||||
@@ -236,12 +254,30 @@ impl Addr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&Addr::EmptyList => {
|
||||||
|
Some(Constant::EmptyList)
|
||||||
|
}
|
||||||
&Addr::Float(f) => {
|
&Addr::Float(f) => {
|
||||||
Some(Constant::Float(f))
|
Some(Constant::Float(f))
|
||||||
}
|
}
|
||||||
&Addr::PStrLocation(h, n) => {
|
&Addr::PStrLocation(h, n) => {
|
||||||
machine_st.to_complete_string(h, n)
|
let mut heap_pstr_iter =
|
||||||
.map(|s| Constant::String(Rc::new(s)))
|
machine_st.heap_pstr_iter(Addr::PStrLocation(h, n));
|
||||||
|
|
||||||
|
let mut buf = String::new();
|
||||||
|
|
||||||
|
while let Some(Some(c)) = heap_pstr_iter.next() {
|
||||||
|
buf.push(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
let end_addr =
|
||||||
|
machine_st.store(machine_st.deref(heap_pstr_iter.focus()));
|
||||||
|
|
||||||
|
if let Addr::EmptyList = end_addr {
|
||||||
|
Some(Constant::String(Rc::new(buf)))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
None
|
None
|
||||||
@@ -262,6 +298,8 @@ impl Add<usize> for Addr {
|
|||||||
|
|
||||||
fn add(self, rhs: usize) -> Self::Output {
|
fn add(self, rhs: usize) -> Self::Output {
|
||||||
match self {
|
match self {
|
||||||
|
Addr::Stream(h) => Addr::Stream(h + rhs),
|
||||||
|
Addr::Con(h) => Addr::Con(h + rhs),
|
||||||
Addr::Lis(a) => Addr::Lis(a + rhs),
|
Addr::Lis(a) => Addr::Lis(a + rhs),
|
||||||
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),
|
||||||
@@ -278,6 +316,8 @@ impl Sub<i64> for Addr {
|
|||||||
fn sub(self, rhs: i64) -> Self::Output {
|
fn sub(self, rhs: i64) -> Self::Output {
|
||||||
if rhs < 0 {
|
if rhs < 0 {
|
||||||
match self {
|
match self {
|
||||||
|
Addr::Stream(h) => Addr::Stream(h + rhs.abs() as usize),
|
||||||
|
Addr::Con(h) => Addr::Con(h + rhs.abs() as usize),
|
||||||
Addr::Lis(a) => Addr::Lis(a + rhs.abs() as usize),
|
Addr::Lis(a) => Addr::Lis(a + rhs.abs() as usize),
|
||||||
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),
|
||||||
@@ -296,6 +336,8 @@ impl Sub<usize> for Addr {
|
|||||||
|
|
||||||
fn sub(self, rhs: usize) -> Self::Output {
|
fn sub(self, rhs: usize) -> Self::Output {
|
||||||
match self {
|
match self {
|
||||||
|
Addr::Stream(h) => Addr::Stream(h - rhs),
|
||||||
|
Addr::Con(h) => Addr::Con(h - rhs),
|
||||||
Addr::Lis(a) => Addr::Lis(a - rhs),
|
Addr::Lis(a) => Addr::Lis(a - rhs),
|
||||||
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),
|
||||||
@@ -331,8 +373,8 @@ pub enum HeapCellValue {
|
|||||||
DBRef(DBRef),
|
DBRef(DBRef),
|
||||||
Integer(Rc<Integer>),
|
Integer(Rc<Integer>),
|
||||||
NamedStr(usize, ClauseName, Option<SharedOpDesc>), // arity, name, precedence/Specifier if it has one.
|
NamedStr(usize, ClauseName, Option<SharedOpDesc>), // arity, name, precedence/Specifier if it has one.
|
||||||
Rational(Rc<Rational>),
|
Rational(Rc<Rational>),
|
||||||
PartialString(PartialString),
|
PartialString(PartialString, bool), // the partial string, a bool indicating whether it came from a Constant.
|
||||||
Stream(Stream),
|
Stream(Stream),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,7 +383,7 @@ impl HeapCellValue {
|
|||||||
pub fn as_addr(&self, focus: usize) -> Addr {
|
pub fn as_addr(&self, focus: usize) -> Addr {
|
||||||
match self {
|
match self {
|
||||||
HeapCellValue::Addr(ref a) => {
|
HeapCellValue::Addr(ref a) => {
|
||||||
a.clone()
|
*a
|
||||||
}
|
}
|
||||||
HeapCellValue::Atom(..) | HeapCellValue::DBRef(..) | HeapCellValue::Integer(..) |
|
HeapCellValue::Atom(..) | HeapCellValue::DBRef(..) | HeapCellValue::Integer(..) |
|
||||||
HeapCellValue::Rational(..) => {
|
HeapCellValue::Rational(..) => {
|
||||||
@@ -350,7 +392,7 @@ impl HeapCellValue {
|
|||||||
HeapCellValue::NamedStr(_, _, _) => {
|
HeapCellValue::NamedStr(_, _, _) => {
|
||||||
Addr::Str(focus)
|
Addr::Str(focus)
|
||||||
}
|
}
|
||||||
HeapCellValue::PartialString(_) => {
|
HeapCellValue::PartialString(..) => {
|
||||||
Addr::PStrLocation(focus, 0)
|
Addr::PStrLocation(focus, 0)
|
||||||
}
|
}
|
||||||
HeapCellValue::Stream(_) => {
|
HeapCellValue::Stream(_) => {
|
||||||
@@ -380,8 +422,8 @@ impl HeapCellValue {
|
|||||||
&HeapCellValue::Rational(ref r) => {
|
&HeapCellValue::Rational(ref r) => {
|
||||||
HeapCellValue::Rational(r.clone())
|
HeapCellValue::Rational(r.clone())
|
||||||
}
|
}
|
||||||
&HeapCellValue::PartialString(ref pstr) => {
|
&HeapCellValue::PartialString(ref pstr, has_tail) => {
|
||||||
HeapCellValue::PartialString(pstr.clone())
|
HeapCellValue::PartialString(pstr.clone(), has_tail)
|
||||||
}
|
}
|
||||||
&HeapCellValue::Stream(_) => {
|
&HeapCellValue::Stream(_) => {
|
||||||
HeapCellValue::Stream(Stream::null_stream())
|
HeapCellValue::Stream(Stream::null_stream())
|
||||||
|
|||||||
@@ -14,11 +14,105 @@ use crate::prolog::rug::Integer;
|
|||||||
|
|
||||||
use downcast::Any;
|
use downcast::Any;
|
||||||
|
|
||||||
|
use indexmap::IndexSet;
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::{Index, IndexMut};
|
use std::ops::{Index, IndexMut};
|
||||||
|
|
||||||
|
pub(crate)
|
||||||
|
struct HeapPStrIter<'a> {
|
||||||
|
focus: Addr,
|
||||||
|
machine_st: &'a MachineState,
|
||||||
|
seen: IndexSet<Addr>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> HeapPStrIter<'a> {
|
||||||
|
#[inline]
|
||||||
|
fn new(machine_st: &'a MachineState, focus: Addr) -> Self {
|
||||||
|
HeapPStrIter {
|
||||||
|
focus,
|
||||||
|
machine_st,
|
||||||
|
seen: IndexSet::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate)
|
||||||
|
fn focus(&'a self) -> Addr {
|
||||||
|
self.focus
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for HeapPStrIter<'a> {
|
||||||
|
type Item = Option<char>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let addr = self.machine_st.store(self.machine_st.deref(self.focus));
|
||||||
|
|
||||||
|
if !self.seen.contains(&addr) {
|
||||||
|
self.seen.insert(addr);
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
match addr {
|
||||||
|
Addr::PStrLocation(h, n) => {
|
||||||
|
if let &HeapCellValue::PartialString(ref pstr, _) = &self.machine_st.heap[h] {
|
||||||
|
if let Some(c) = pstr.range_from(n ..).next() {
|
||||||
|
self.focus = Addr::PStrLocation(h, n + c.len_utf8());
|
||||||
|
return Some(Some(c));
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Addr::Lis(l) => {
|
||||||
|
let addr = self.machine_st.store(self.machine_st.deref(Addr::HeapCell(l)));
|
||||||
|
|
||||||
|
if let Addr::Char(c) = addr {
|
||||||
|
self.focus = Addr::HeapCell(l + 1);
|
||||||
|
return Some(Some(c));
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Addr::EmptyList => {
|
||||||
|
self.focus = Addr::EmptyList;
|
||||||
|
return Some(None);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(super)
|
||||||
|
fn compare_pstr<'a>(
|
||||||
|
pstr_iter: HeapPStrIter<'a>,
|
||||||
|
mut c_iter: impl Iterator<Item = char>,
|
||||||
|
) -> bool {
|
||||||
|
for opt_c in pstr_iter {
|
||||||
|
match opt_c {
|
||||||
|
Some(_) => {
|
||||||
|
if opt_c != c_iter.next() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
return c_iter.next().is_none();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Ball {
|
pub struct Ball {
|
||||||
pub(super) boundary: usize,
|
pub(super) boundary: usize,
|
||||||
pub(super) stub: Heap,
|
pub(super) stub: Heap,
|
||||||
@@ -185,7 +279,7 @@ impl<'a> CopierTarget for CopyBallTerm<'a> {
|
|||||||
self.stub[index].as_addr(h)
|
self.stub[index].as_addr(h)
|
||||||
}
|
}
|
||||||
Addr::StackCell(fr, sc) => {
|
Addr::StackCell(fr, sc) => {
|
||||||
self.stack.index_and_frame(fr)[sc].clone()
|
self.stack.index_and_frame(fr)[sc]
|
||||||
}
|
}
|
||||||
addr => {
|
addr => {
|
||||||
addr
|
addr
|
||||||
@@ -195,7 +289,7 @@ impl<'a> CopierTarget for CopyBallTerm<'a> {
|
|||||||
|
|
||||||
fn deref(&self, mut addr: Addr) -> Addr {
|
fn deref(&self, mut addr: Addr) -> Addr {
|
||||||
loop {
|
loop {
|
||||||
let value = self.store(addr.clone());
|
let value = self.store(addr);
|
||||||
|
|
||||||
if value.is_ref() && value != addr {
|
if value.is_ref() && value != addr {
|
||||||
addr = value;
|
addr = value;
|
||||||
@@ -264,11 +358,13 @@ impl HeapPtr {
|
|||||||
Addr::HeapCell(h)
|
Addr::HeapCell(h)
|
||||||
}
|
}
|
||||||
&HeapPtr::PStrChar(h, n) => {
|
&HeapPtr::PStrChar(h, n) => {
|
||||||
if let HeapCellValue::PartialString(ref pstr) = &heap[h] {
|
if let &HeapCellValue::PartialString(ref pstr, has_tail) = &heap[h] {
|
||||||
if let Some(c) = pstr.range_from(n ..).next() {
|
if let Some(c) = pstr.range_from(n ..).next() {
|
||||||
Addr::Char(c)
|
Addr::Char(c)
|
||||||
} else {
|
} else if has_tail {
|
||||||
Addr::HeapCell(h + 1)
|
Addr::HeapCell(h + 1)
|
||||||
|
} else {
|
||||||
|
Addr::EmptyList
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -315,13 +411,19 @@ pub struct MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MachineState {
|
impl MachineState {
|
||||||
|
#[inline]
|
||||||
|
pub(crate)
|
||||||
|
fn heap_pstr_iter<'a>(&'a self, focus: Addr) -> HeapPStrIter<'a> {
|
||||||
|
HeapPStrIter::new(self, focus)
|
||||||
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super)
|
||||||
fn try_char_list(&self, addrs: Vec<Addr>) -> Result<String, MachineError> {
|
fn try_char_list(&self, addrs: Vec<Addr>) -> Result<String, MachineError> {
|
||||||
let mut chars = String::new();
|
let mut chars = String::new();
|
||||||
let mut iter = addrs.iter();
|
let mut iter = addrs.iter();
|
||||||
|
|
||||||
while let Some(addr) = iter.next() {
|
while let Some(addr) = iter.next() {
|
||||||
let addr = self.store(self.deref(addr.clone()));
|
let addr = self.store(self.deref(*addr));
|
||||||
|
|
||||||
match addr {
|
match addr {
|
||||||
Addr::Char(c) => {
|
Addr::Char(c) => {
|
||||||
@@ -480,7 +582,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
|
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
|
||||||
|
|
||||||
for i in 1 .. n + 1 {
|
for i in 1 .. n + 1 {
|
||||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1].clone();
|
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
machine_st.num_of_args = n;
|
machine_st.num_of_args = n;
|
||||||
@@ -519,7 +621,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
|
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
|
||||||
|
|
||||||
for i in 1 .. n + 1 {
|
for i in 1 .. n + 1 {
|
||||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1].clone();
|
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
machine_st.num_of_args = n;
|
machine_st.num_of_args = n;
|
||||||
@@ -555,7 +657,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
|
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
|
||||||
|
|
||||||
for i in 1 .. n + 1 {
|
for i in 1 .. n + 1 {
|
||||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1].clone();
|
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
machine_st.num_of_args = n;
|
machine_st.num_of_args = n;
|
||||||
@@ -595,7 +697,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
|
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
|
||||||
|
|
||||||
for i in 1 .. n + 1 {
|
for i in 1 .. n + 1 {
|
||||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1].clone();
|
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
machine_st.num_of_args = n;
|
machine_st.num_of_args = n;
|
||||||
@@ -717,7 +819,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
) -> CallResult {
|
) -> CallResult {
|
||||||
match ct {
|
match ct {
|
||||||
&BuiltInClauseType::AcyclicTerm => {
|
&BuiltInClauseType::AcyclicTerm => {
|
||||||
let addr = machine_st[temp_v!(1)].clone();
|
let addr = machine_st[temp_v!(1)];
|
||||||
machine_st.fail = machine_st.is_cyclic_term(addr);
|
machine_st.fail = machine_st.is_cyclic_term(addr);
|
||||||
return_from_clause!(machine_st.last_call, machine_st)
|
return_from_clause!(machine_st.last_call, machine_st)
|
||||||
}
|
}
|
||||||
@@ -726,9 +828,9 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
return_from_clause!(machine_st.last_call, machine_st)
|
return_from_clause!(machine_st.last_call, machine_st)
|
||||||
}
|
}
|
||||||
&BuiltInClauseType::Compare => {
|
&BuiltInClauseType::Compare => {
|
||||||
let a1 = machine_st[temp_v!(1)].clone();
|
let a1 = machine_st[temp_v!(1)];
|
||||||
let a2 = machine_st[temp_v!(2)].clone();
|
let a2 = machine_st[temp_v!(2)];
|
||||||
let a3 = machine_st[temp_v!(3)].clone();
|
let a3 = machine_st[temp_v!(3)];
|
||||||
|
|
||||||
let atom = match machine_st.compare_term_test(&a2, &a3) {
|
let atom = match machine_st.compare_term_test(&a2, &a3) {
|
||||||
Some(Ordering::Greater) => {
|
Some(Ordering::Greater) => {
|
||||||
@@ -769,7 +871,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
&indices.op_dir,
|
&indices.op_dir,
|
||||||
) {
|
) {
|
||||||
Ok(offset) => {
|
Ok(offset) => {
|
||||||
let addr = machine_st[temp_v!(1)].clone();
|
let addr = machine_st[temp_v!(1)];
|
||||||
machine_st.unify(addr, Addr::HeapCell(offset.heap_loc));
|
machine_st.unify(addr, Addr::HeapCell(offset.heap_loc));
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -789,8 +891,8 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
return_from_clause!(machine_st.last_call, machine_st)
|
return_from_clause!(machine_st.last_call, machine_st)
|
||||||
}
|
}
|
||||||
&BuiltInClauseType::Eq => {
|
&BuiltInClauseType::Eq => {
|
||||||
let a1 = machine_st[temp_v!(1)].clone();
|
let a1 = machine_st[temp_v!(1)];
|
||||||
let a2 = machine_st[temp_v!(2)].clone();
|
let a2 = machine_st[temp_v!(2)];
|
||||||
|
|
||||||
machine_st.fail = machine_st.eq_test(a1, a2);
|
machine_st.fail = machine_st.eq_test(a1, a2);
|
||||||
return_from_clause!(machine_st.last_call, machine_st)
|
return_from_clause!(machine_st.last_call, machine_st)
|
||||||
@@ -804,8 +906,8 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
return_from_clause!(machine_st.last_call, machine_st)
|
return_from_clause!(machine_st.last_call, machine_st)
|
||||||
}
|
}
|
||||||
&BuiltInClauseType::NotEq => {
|
&BuiltInClauseType::NotEq => {
|
||||||
let a1 = machine_st[temp_v!(1)].clone();
|
let a1 = machine_st[temp_v!(1)];
|
||||||
let a2 = machine_st[temp_v!(2)].clone();
|
let a2 = machine_st[temp_v!(2)];
|
||||||
|
|
||||||
machine_st.fail =
|
machine_st.fail =
|
||||||
if let Some(Ordering::Equal) = machine_st.compare_term_test(&a1, &a2) {
|
if let Some(Ordering::Equal) = machine_st.compare_term_test(&a1, &a2) {
|
||||||
@@ -830,7 +932,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
|
|
||||||
let heap_addr = Addr::HeapCell(machine_st.heap.to_list(list.into_iter()));
|
let heap_addr = Addr::HeapCell(machine_st.heap.to_list(list.into_iter()));
|
||||||
|
|
||||||
let r2 = machine_st[temp_v!(2)].clone();
|
let r2 = machine_st[temp_v!(2)];
|
||||||
machine_st.unify(r2, heap_addr);
|
machine_st.unify(r2, heap_addr);
|
||||||
|
|
||||||
return_from_clause!(machine_st.last_call, machine_st)
|
return_from_clause!(machine_st.last_call, machine_st)
|
||||||
@@ -854,13 +956,13 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
let key_pairs = key_pairs.into_iter().map(|kp| kp.1);
|
let key_pairs = key_pairs.into_iter().map(|kp| kp.1);
|
||||||
let heap_addr = Addr::HeapCell(machine_st.heap.to_list(key_pairs));
|
let heap_addr = Addr::HeapCell(machine_st.heap.to_list(key_pairs));
|
||||||
|
|
||||||
let r2 = machine_st[temp_v!(2)].clone();
|
let r2 = machine_st[temp_v!(2)];
|
||||||
machine_st.unify(r2, heap_addr);
|
machine_st.unify(r2, heap_addr);
|
||||||
|
|
||||||
return_from_clause!(machine_st.last_call, machine_st)
|
return_from_clause!(machine_st.last_call, machine_st)
|
||||||
}
|
}
|
||||||
&BuiltInClauseType::Is(r, ref at) => {
|
&BuiltInClauseType::Is(r, ref at) => {
|
||||||
let a1 = machine_st[r].clone();
|
let a1 = machine_st[r];
|
||||||
let n2 = machine_st.get_number(at)?;
|
let n2 = machine_st.get_number(at)?;
|
||||||
|
|
||||||
let n2 = Addr::Con(machine_st.heap.push(n2.into()));
|
let n2 = Addr::Con(machine_st.heap.push(n2.into()));
|
||||||
@@ -1142,13 +1244,13 @@ fn cut_body(machine_st: &mut MachineState, addr: &Addr) -> bool {
|
|||||||
pub(crate) struct DefaultCutPolicy {}
|
pub(crate) struct DefaultCutPolicy {}
|
||||||
|
|
||||||
pub(super) fn deref_cut(machine_st: &mut MachineState, r: RegType) {
|
pub(super) fn deref_cut(machine_st: &mut MachineState, r: RegType) {
|
||||||
let addr = machine_st.store(machine_st.deref(machine_st[r].clone()));
|
let addr = machine_st.store(machine_st.deref(machine_st[r]));
|
||||||
cut_body(machine_st, &addr);
|
cut_body(machine_st, &addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CutPolicy for DefaultCutPolicy {
|
impl CutPolicy for DefaultCutPolicy {
|
||||||
fn cut(&mut self, machine_st: &mut MachineState, r: RegType) -> bool {
|
fn cut(&mut self, machine_st: &mut MachineState, r: RegType) -> bool {
|
||||||
let addr = machine_st[r].clone();
|
let addr = machine_st[r];
|
||||||
cut_body(machine_st, &addr)
|
cut_body(machine_st, &addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1209,7 +1311,7 @@ impl CutPolicy for SCCCutPolicy {
|
|||||||
fn cut(&mut self, machine_st: &mut MachineState, r: RegType) -> bool {
|
fn cut(&mut self, machine_st: &mut MachineState, r: RegType) -> bool {
|
||||||
let b = machine_st.b;
|
let b = machine_st.b;
|
||||||
|
|
||||||
match machine_st[r].clone() {
|
match machine_st[r] {
|
||||||
Addr::Usize(b0) | Addr::CutPoint(b0) => {
|
Addr::Usize(b0) | Addr::CutPoint(b0) => {
|
||||||
if b > b0 {
|
if b > b0 {
|
||||||
machine_st.b = b0;
|
machine_st.b = b0;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,28 @@
|
|||||||
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use std::alloc;
|
use std::alloc;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::ops::{Range, RangeFrom};
|
use std::ops::RangeFrom;
|
||||||
|
use std::slice;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
pub struct PartialString {
|
pub struct PartialString {
|
||||||
buf: *const u8,
|
buf: *const u8,
|
||||||
|
len: usize,
|
||||||
|
_marker: PhantomData<[u8]>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for PartialString {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
let layout = alloc::Layout::from_size_align_unchecked(self.len, mem::align_of::<u8>());
|
||||||
|
alloc::dealloc(self.buf as *mut u8, layout);
|
||||||
|
|
||||||
|
self.buf = ptr::null();
|
||||||
|
self.len = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for PartialString {
|
impl Clone for PartialString {
|
||||||
@@ -47,54 +64,31 @@ impl Iterator for PStrIter {
|
|||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let b = ptr::read(self.buf);
|
let mut byte_count = 0;
|
||||||
|
|
||||||
if b == 0u8 {
|
for n in 0 .. mem::size_of::<char>() {
|
||||||
|
let b = ptr::read((self.buf as usize + n) as *const u8);
|
||||||
|
|
||||||
|
if b == 0u8 {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
byte_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if byte_count == 0 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let c = ptr::read(self.buf as *const char);
|
let slice = slice::from_raw_parts(self.buf, byte_count);
|
||||||
self.buf = self.buf.offset(c.len_utf8() as isize);
|
let s = str::from_utf8(slice).unwrap();
|
||||||
|
|
||||||
Some(c)
|
if let Some(c) = s.chars().next() {
|
||||||
}
|
self.buf = self.buf.offset(c.len_utf8() as isize);
|
||||||
}
|
Some(c)
|
||||||
}
|
} else {
|
||||||
|
None
|
||||||
pub struct PStrIterBounded {
|
|
||||||
buf: *const u8,
|
|
||||||
end: *const u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PStrIterBounded {
|
|
||||||
#[inline]
|
|
||||||
fn from(buf: *const u8, start: usize, end: usize) -> Self {
|
|
||||||
PStrIterBounded {
|
|
||||||
buf: (buf as usize + start) as *const _,
|
|
||||||
end: (buf as usize + end) as *const _,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Iterator for PStrIterBounded {
|
|
||||||
type Item = char;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
unsafe {
|
|
||||||
if self.buf >= self.end {
|
|
||||||
return None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let b = ptr::read(self.buf);
|
|
||||||
|
|
||||||
if b == 0u8 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let c = ptr::read(self.buf as *const char);
|
|
||||||
self.buf = self.buf.offset(c.len_utf8() as isize);
|
|
||||||
|
|
||||||
Some(c)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,6 +99,8 @@ impl PartialString {
|
|||||||
fn new(src: &str) -> Option<(Self, &str)> {
|
fn new(src: &str) -> Option<(Self, &str)> {
|
||||||
let pstr = PartialString {
|
let pstr = PartialString {
|
||||||
buf: ptr::null_mut(),
|
buf: ptr::null_mut(),
|
||||||
|
len: 0,
|
||||||
|
_marker: PhantomData,
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -116,7 +112,9 @@ impl PartialString {
|
|||||||
pub(super)
|
pub(super)
|
||||||
fn empty() -> Self {
|
fn empty() -> Self {
|
||||||
PartialString {
|
PartialString {
|
||||||
buf: "\u{0}".as_bytes()[0] as *const _,
|
buf: &"\u{0}".as_bytes()[0] as *const _,
|
||||||
|
len: '\u{0}'.len_utf8(),
|
||||||
|
_marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,11 +126,12 @@ impl PartialString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let layout = alloc::Layout::from_size_align_unchecked(
|
let layout = alloc::Layout::from_size_align_unchecked(
|
||||||
src.len() + '\u{0}'.len_utf8(),
|
terminator_idx + '\u{0}'.len_utf8(),
|
||||||
mem::align_of::<u8>(),
|
mem::align_of::<u8>(),
|
||||||
);
|
);
|
||||||
|
|
||||||
self.buf = alloc::alloc(layout) as *const _;
|
self.buf = alloc::alloc(layout) as *const _;
|
||||||
|
self.len = terminator_idx + '\u{0}'.len_utf8();
|
||||||
|
|
||||||
ptr::copy(
|
ptr::copy(
|
||||||
src.as_ptr(),
|
src.as_ptr(),
|
||||||
@@ -149,24 +148,17 @@ impl PartialString {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub(crate)
|
|
||||||
fn iter(&self) -> PStrIter {
|
|
||||||
PStrIter {
|
|
||||||
buf: self.buf,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super)
|
pub(super)
|
||||||
fn clone_from_offset(&self, n: usize) -> Self {
|
fn clone_from_offset(&self, n: usize) -> Self {
|
||||||
|
let len = if self.len > n { self.len - n } else { 0 };
|
||||||
|
|
||||||
let mut pstr = PartialString {
|
let mut pstr = PartialString {
|
||||||
buf: ptr::null_mut(),
|
buf: ptr::null_mut(),
|
||||||
|
len: len + '\u{0}'.len_utf8(),
|
||||||
|
_marker: PhantomData,
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let len = scan_for_terminator(self.range_from(0 ..));
|
|
||||||
let len = if len > n { len - n } else { 0 };
|
|
||||||
|
|
||||||
let layout = alloc::Layout::from_size_align_unchecked(
|
let layout = alloc::Layout::from_size_align_unchecked(
|
||||||
len + '\u{0}'.len_utf8(),
|
len + '\u{0}'.len_utf8(),
|
||||||
mem::align_of::<u8>(),
|
mem::align_of::<u8>(),
|
||||||
@@ -199,11 +191,6 @@ impl PartialString {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn range(&self, index: Range<usize>) -> PStrIterBounded {
|
|
||||||
PStrIterBounded::from(self.buf, index.start, index.end)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn range_from(&self, index: RangeFrom<usize>) -> PStrIter {
|
pub fn range_from(&self, index: RangeFrom<usize>) -> PStrIter {
|
||||||
PStrIter::from(self.buf, index.start)
|
PStrIter::from(self.buf, index.start)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use std::mem;
|
|||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
pub(crate) trait RawBlockTraits {
|
pub(crate) trait RawBlockTraits {
|
||||||
fn init_size() -> usize;
|
fn init_size() -> usize;
|
||||||
fn align() -> usize;
|
fn align() -> usize;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -36,20 +36,6 @@ impl<T: RawBlockTraits> RawBlock<T> {
|
|||||||
block
|
block
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
|
||||||
fn with_capacity(cap: usize) -> Self {
|
|
||||||
let mut block = RawBlock { size: 0,
|
|
||||||
base: ptr::null(),
|
|
||||||
top: ptr::null(),
|
|
||||||
_marker: PhantomData };
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
block.init_at_size(cap);
|
|
||||||
}
|
|
||||||
|
|
||||||
block
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn init_at_size(&mut self, cap: usize) {
|
unsafe fn init_at_size(&mut self, cap: usize) {
|
||||||
let layout = alloc::Layout::from_size_align_unchecked(cap, T::align());
|
let layout = alloc::Layout::from_size_align_unchecked(cap, T::align());
|
||||||
|
|
||||||
@@ -86,7 +72,6 @@ impl<T: RawBlockTraits> RawBlock<T> {
|
|||||||
mem::replace(self, Self::empty_block())
|
mem::replace(self, Self::empty_block())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn free_space(&self) -> usize {
|
fn free_space(&self) -> usize {
|
||||||
debug_assert!(self.top >= self.base,
|
debug_assert!(self.top >= self.base,
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ impl Drop for Stack {
|
|||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct FramePrelude {
|
pub struct FramePrelude {
|
||||||
is_or_frame: u8,
|
|
||||||
pub num_cells: usize,
|
pub num_cells: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +61,6 @@ pub struct AndFramePrelude {
|
|||||||
|
|
||||||
pub struct AndFrame {
|
pub struct AndFrame {
|
||||||
pub prelude: AndFramePrelude,
|
pub prelude: AndFramePrelude,
|
||||||
_marker: PhantomData<Addr>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AndFrame {
|
impl AndFrame {
|
||||||
@@ -89,8 +87,6 @@ impl Index<usize> for AndFrame {
|
|||||||
|
|
||||||
impl IndexMut<usize> for AndFrame {
|
impl IndexMut<usize> for AndFrame {
|
||||||
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
||||||
debug_assert!(self.prelude.univ_prelude.is_or_frame == 0);
|
|
||||||
|
|
||||||
let prelude_offset = prelude_size::<AndFramePrelude>();
|
let prelude_offset = prelude_size::<AndFramePrelude>();
|
||||||
let index_offset = (index - 1) * mem::size_of::<Addr>();
|
let index_offset = (index - 1) * mem::size_of::<Addr>();
|
||||||
|
|
||||||
@@ -103,24 +99,6 @@ impl IndexMut<usize> for AndFrame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for AndFrame {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
let prelude_offset = prelude_size::<AndFramePrelude>();
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let ptr = mem::transmute::<&mut AndFrame, *const u8>(self);
|
|
||||||
let ptr = ptr as usize + prelude_offset;
|
|
||||||
|
|
||||||
for idx in 0 .. self.prelude.univ_prelude.num_cells {
|
|
||||||
let index_offset = idx * mem::size_of::<Addr>();
|
|
||||||
let ptr = (ptr + index_offset) as *mut Addr;
|
|
||||||
|
|
||||||
ptr::drop_in_place(ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct OrFramePrelude {
|
pub struct OrFramePrelude {
|
||||||
pub univ_prelude: FramePrelude,
|
pub univ_prelude: FramePrelude,
|
||||||
pub e: usize,
|
pub e: usize,
|
||||||
@@ -137,7 +115,6 @@ pub struct OrFramePrelude {
|
|||||||
|
|
||||||
pub struct OrFrame {
|
pub struct OrFrame {
|
||||||
pub prelude: OrFramePrelude,
|
pub prelude: OrFramePrelude,
|
||||||
_marker: PhantomData<Addr>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Index<usize> for OrFrame {
|
impl Index<usize> for OrFrame {
|
||||||
@@ -145,8 +122,6 @@ impl Index<usize> for OrFrame {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index(&self, index: usize) -> &Self::Output {
|
fn index(&self, index: usize) -> &Self::Output {
|
||||||
debug_assert!(self.prelude.univ_prelude.is_or_frame == 1);
|
|
||||||
|
|
||||||
let prelude_offset = prelude_size::<OrFramePrelude>();
|
let prelude_offset = prelude_size::<OrFramePrelude>();
|
||||||
let index_offset = index * mem::size_of::<Addr>();
|
let index_offset = index * mem::size_of::<Addr>();
|
||||||
|
|
||||||
@@ -162,8 +137,6 @@ impl Index<usize> for OrFrame {
|
|||||||
impl IndexMut<usize> for OrFrame {
|
impl IndexMut<usize> for OrFrame {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
||||||
debug_assert!(self.prelude.univ_prelude.is_or_frame == 1);
|
|
||||||
|
|
||||||
let prelude_offset = prelude_size::<OrFramePrelude>();
|
let prelude_offset = prelude_size::<OrFramePrelude>();
|
||||||
let index_offset = index * mem::size_of::<Addr>();
|
let index_offset = index * mem::size_of::<Addr>();
|
||||||
|
|
||||||
@@ -176,24 +149,6 @@ impl IndexMut<usize> for OrFrame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for OrFrame {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
let prelude_offset = prelude_size::<OrFramePrelude>();
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let ptr = mem::transmute::<&mut OrFrame, *const u8>(self);
|
|
||||||
let ptr = ptr as usize + prelude_offset;
|
|
||||||
|
|
||||||
for idx in 0 .. self.prelude.univ_prelude.num_cells {
|
|
||||||
let index_offset = idx * mem::size_of::<Addr>();
|
|
||||||
let ptr = (ptr + index_offset) as *mut Addr;
|
|
||||||
|
|
||||||
ptr::drop_in_place(ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OrFrame {
|
impl OrFrame {
|
||||||
pub fn size_of(num_cells: usize) -> usize {
|
pub fn size_of(num_cells: usize) -> usize {
|
||||||
prelude_size::<OrFramePrelude>() + num_cells * mem::size_of::<Addr>()
|
prelude_size::<OrFramePrelude>() + num_cells * mem::size_of::<Addr>()
|
||||||
@@ -217,8 +172,6 @@ impl Stack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let and_frame = &mut *(self.buf.top as *mut AndFrame);
|
let and_frame = &mut *(self.buf.top as *mut AndFrame);
|
||||||
|
|
||||||
and_frame.prelude.univ_prelude.is_or_frame = 0;
|
|
||||||
and_frame.prelude.univ_prelude.num_cells = num_cells;
|
and_frame.prelude.univ_prelude.num_cells = num_cells;
|
||||||
|
|
||||||
let e = self.buf.top as usize - self.buf.base as usize;
|
let e = self.buf.top as usize - self.buf.base as usize;
|
||||||
@@ -240,8 +193,6 @@ impl Stack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let or_frame = &mut *(self.buf.top as *mut OrFrame);
|
let or_frame = &mut *(self.buf.top as *mut OrFrame);
|
||||||
|
|
||||||
or_frame.prelude.univ_prelude.is_or_frame = 1;
|
|
||||||
or_frame.prelude.univ_prelude.num_cells = num_cells;
|
or_frame.prelude.univ_prelude.num_cells = num_cells;
|
||||||
|
|
||||||
let b = self.buf.top as usize - self.buf.base as usize;
|
let b = self.buf.top as usize - self.buf.base as usize;
|
||||||
@@ -287,6 +238,7 @@ impl Stack {
|
|||||||
Stack { buf: self.buf.take(), _marker: PhantomData }
|
Stack { buf: self.buf.take(), _marker: PhantomData }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn truncate(&mut self, b: usize) {
|
pub fn truncate(&mut self, b: usize) {
|
||||||
if b == 0 {
|
if b == 0 {
|
||||||
self.inner_truncate(mem::align_of::<Addr>());
|
self.inner_truncate(mem::align_of::<Addr>());
|
||||||
@@ -295,40 +247,12 @@ impl Stack {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn inner_truncate(&mut self, b: usize) {
|
fn inner_truncate(&mut self, b: usize) {
|
||||||
let mut b = b + self.buf.base as usize;
|
let base = b + self.buf.base as usize;
|
||||||
let base = b;
|
|
||||||
|
|
||||||
unsafe {
|
if base < self.buf.top as usize {
|
||||||
while b as *const _ < self.buf.top {
|
self.buf.top = base as *const _;
|
||||||
let univ_prelude = ptr::read(b as *const FramePrelude);
|
|
||||||
|
|
||||||
let offset = if univ_prelude.is_or_frame == 0 {
|
|
||||||
let frame_ptr = b as *mut AndFrame;
|
|
||||||
let frame = &mut *frame_ptr;
|
|
||||||
let size_of_frame = AndFrame::size_of(frame.prelude.univ_prelude.num_cells);
|
|
||||||
|
|
||||||
ptr::drop_in_place(frame_ptr);
|
|
||||||
|
|
||||||
b + size_of_frame
|
|
||||||
} else {
|
|
||||||
debug_assert!(univ_prelude.is_or_frame == 1);
|
|
||||||
|
|
||||||
let frame_ptr = b as *mut OrFrame;
|
|
||||||
let frame = &mut *frame_ptr;
|
|
||||||
let size_of_frame = OrFrame::size_of(frame.prelude.univ_prelude.num_cells);
|
|
||||||
|
|
||||||
ptr::drop_in_place(frame_ptr);
|
|
||||||
|
|
||||||
b + size_of_frame
|
|
||||||
};
|
|
||||||
|
|
||||||
b = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
if base < self.buf.top as usize {
|
|
||||||
self.buf.top = base as *const _;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ struct BrentAlgState {
|
|||||||
impl BrentAlgState {
|
impl BrentAlgState {
|
||||||
fn new(hare: Addr) -> Self {
|
fn new(hare: Addr) -> Self {
|
||||||
BrentAlgState {
|
BrentAlgState {
|
||||||
hare: hare.clone(),
|
hare: hare,
|
||||||
tortoise: hare,
|
tortoise: hare,
|
||||||
power: 2,
|
power: 2,
|
||||||
steps: 0,
|
steps: 0,
|
||||||
@@ -89,7 +89,7 @@ impl BrentAlgState {
|
|||||||
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 {
|
||||||
self.tortoise = self.hare.clone();
|
self.tortoise = self.hare;
|
||||||
self.power <<= 1;
|
self.power <<= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
Addr::PStrLocation(h, n) => {
|
Addr::PStrLocation(h, n) => {
|
||||||
match &self.heap[h] {
|
match &self.heap[h] {
|
||||||
HeapCellValue::PartialString(ref pstr) => {
|
HeapCellValue::PartialString(ref pstr, _) => {
|
||||||
if let Some(c) = pstr.range_from(n ..).next() {
|
if let Some(c) = pstr.range_from(n ..).next() {
|
||||||
brent_st.step(Addr::PStrLocation(h, n + c.len_utf8()))
|
brent_st.step(Addr::PStrLocation(h, n + c.len_utf8()))
|
||||||
} else {
|
} else {
|
||||||
@@ -184,7 +184,7 @@ impl MachineState {
|
|||||||
return CycleSearchResult::EmptyList;
|
return CycleSearchResult::EmptyList;
|
||||||
}
|
}
|
||||||
Addr::Con(h) if max_steps > 0 => {
|
Addr::Con(h) if max_steps > 0 => {
|
||||||
if let HeapCellValue::PartialString(_) = &self.heap[h] {
|
if let HeapCellValue::PartialString(..) = &self.heap[h] {
|
||||||
if !self.flags.double_quotes.is_atom() {
|
if !self.flags.double_quotes.is_atom() {
|
||||||
Addr::PStrLocation(h, 0)
|
Addr::PStrLocation(h, 0)
|
||||||
} else {
|
} else {
|
||||||
@@ -195,7 +195,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Addr::Con(h) => {
|
Addr::Con(h) => {
|
||||||
if let HeapCellValue::PartialString(_) = &self.heap[h] {
|
if let HeapCellValue::PartialString(..) = &self.heap[h] {
|
||||||
if !self.flags.double_quotes.is_atom() {
|
if !self.flags.double_quotes.is_atom() {
|
||||||
return CycleSearchResult::UntouchedList(h);
|
return CycleSearchResult::UntouchedList(h);
|
||||||
}
|
}
|
||||||
@@ -235,7 +235,7 @@ impl MachineState {
|
|||||||
Addr::PStrLocation(h, n)
|
Addr::PStrLocation(h, n)
|
||||||
}
|
}
|
||||||
Addr::Con(h) => {
|
Addr::Con(h) => {
|
||||||
if let HeapCellValue::PartialString(_) = &self.heap[h] {
|
if let HeapCellValue::PartialString(..) = &self.heap[h] {
|
||||||
if !self.flags.double_quotes.is_atom() {
|
if !self.flags.double_quotes.is_atom() {
|
||||||
Addr::PStrLocation(h, 0)
|
Addr::PStrLocation(h, 0)
|
||||||
} else {
|
} else {
|
||||||
@@ -425,7 +425,7 @@ impl MachineState {
|
|||||||
&indices.op_dir,
|
&indices.op_dir,
|
||||||
) {
|
) {
|
||||||
Ok(term_write_result) => {
|
Ok(term_write_result) => {
|
||||||
let a1 = self[temp_v!(1)].clone();
|
let a1 = self[temp_v!(1)];
|
||||||
self.unify(Addr::HeapCell(term_write_result.heap_loc), a1);
|
self.unify(Addr::HeapCell(term_write_result.heap_loc), a1);
|
||||||
|
|
||||||
if self.fail {
|
if self.fail {
|
||||||
@@ -447,7 +447,7 @@ impl MachineState {
|
|||||||
list_of_var_eqs.push(Addr::Str(h));
|
list_of_var_eqs.push(Addr::Str(h));
|
||||||
}
|
}
|
||||||
|
|
||||||
let a2 = self[temp_v!(2)].clone();
|
let a2 = self[temp_v!(2)];
|
||||||
let list_offset =
|
let list_offset =
|
||||||
Addr::HeapCell(self.heap.to_list(list_of_var_eqs.into_iter()));
|
Addr::HeapCell(self.heap.to_list(list_of_var_eqs.into_iter()));
|
||||||
|
|
||||||
@@ -475,7 +475,7 @@ impl MachineState {
|
|||||||
self.block = self.b;
|
self.block = self.b;
|
||||||
|
|
||||||
let c = Constant::Usize(self.block);
|
let c = Constant::Usize(self.block);
|
||||||
let addr = self[r].clone();
|
let addr = self[r];
|
||||||
|
|
||||||
self.write_constant_to_var(addr, &c);
|
self.write_constant_to_var(addr, &c);
|
||||||
self.block
|
self.block
|
||||||
@@ -513,7 +513,7 @@ impl MachineState {
|
|||||||
where
|
where
|
||||||
AddrConstr: Fn(usize) -> Addr,
|
AddrConstr: Fn(usize) -> Addr,
|
||||||
{
|
{
|
||||||
match self.store(self.deref(self[temp_v!(1)].clone())) {
|
match self.store(self.deref(self[temp_v!(1)])) {
|
||||||
Addr::Usize(lh_offset) => {
|
Addr::Usize(lh_offset) => {
|
||||||
if lh_offset >= self.lifted_heap.h() {
|
if lh_offset >= self.lifted_heap.h() {
|
||||||
self.lifted_heap.truncate(lh_offset);
|
self.lifted_heap.truncate(lh_offset);
|
||||||
@@ -542,7 +542,7 @@ impl MachineState {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let a2 = self[temp_v!(2)].clone();
|
let a2 = self[temp_v!(2)];
|
||||||
|
|
||||||
if let Some(r) = a2.as_var() {
|
if let Some(r) = a2.as_var() {
|
||||||
let spec = get_clause_spec(
|
let spec = get_clause_spec(
|
||||||
@@ -578,7 +578,7 @@ impl MachineState {
|
|||||||
|
|
||||||
match op_dir.range(key..).skip(1).next() {
|
match op_dir.range(key..).skip(1).next() {
|
||||||
Some((OrderedOpDirKey(name, _), (priority, spec))) => {
|
Some((OrderedOpDirKey(name, _), (priority, spec))) => {
|
||||||
let a2 = self[temp_v!(2)].clone();
|
let a2 = self[temp_v!(2)];
|
||||||
|
|
||||||
if let Some(r) = a2.as_var() {
|
if let Some(r) = a2.as_var() {
|
||||||
let addr = self.heap.to_unifiable(
|
let addr = self.heap.to_unifiable(
|
||||||
@@ -627,7 +627,7 @@ impl MachineState {
|
|||||||
indices: &IndexStore,
|
indices: &IndexStore,
|
||||||
stub: MachineStub,
|
stub: MachineStub,
|
||||||
) -> CallResult {
|
) -> CallResult {
|
||||||
let nx = self[temp_v!(2)].clone();
|
let nx = self[temp_v!(2)];
|
||||||
|
|
||||||
if let Some(c) = string.chars().last() {
|
if let Some(c) = string.chars().last() {
|
||||||
if layout_char!(c) {
|
if layout_char!(c) {
|
||||||
@@ -696,7 +696,7 @@ impl MachineState {
|
|||||||
self.term_dedup(&mut attr_goals);
|
self.term_dedup(&mut attr_goals);
|
||||||
|
|
||||||
let attr_goals = Addr::HeapCell(self.heap.to_list(attr_goals.into_iter()));
|
let attr_goals = Addr::HeapCell(self.heap.to_list(attr_goals.into_iter()));
|
||||||
let target = self[temp_v!(1)].clone();
|
let target = self[temp_v!(1)];
|
||||||
|
|
||||||
self.unify(attr_goals, target);
|
self.unify(attr_goals, target);
|
||||||
}
|
}
|
||||||
@@ -773,7 +773,7 @@ impl MachineState {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
&SystemClauseType::BindFromRegister => {
|
&SystemClauseType::BindFromRegister => {
|
||||||
let reg = self.store(self.deref(self[temp_v!(2)].clone()));
|
let reg = self.store(self.deref(self[temp_v!(2)]));
|
||||||
let n = match reg {
|
let n = match reg {
|
||||||
Addr::Con(h) =>
|
Addr::Con(h) =>
|
||||||
if let HeapCellValue::Integer(ref n) = &self.heap[h] {
|
if let HeapCellValue::Integer(ref n) = &self.heap[h] {
|
||||||
@@ -781,13 +781,15 @@ impl MachineState {
|
|||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
_ => unreachable!()
|
_ => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(n) = n {
|
if let Some(n) = n {
|
||||||
if n <= MAX_ARITY {
|
if n <= MAX_ARITY {
|
||||||
let target = self[temp_v!(n)].clone();
|
let target = self[temp_v!(n)];
|
||||||
let addr = self[temp_v!(1)].clone();
|
let addr = self[temp_v!(1)];
|
||||||
|
|
||||||
self.unify(addr, target);
|
self.unify(addr, target);
|
||||||
return return_from_clause!(self.last_call, self);
|
return return_from_clause!(self.last_call, self);
|
||||||
@@ -843,7 +845,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
&SystemClauseType::CurrentOutput => {
|
&SystemClauseType::CurrentOutput => {
|
||||||
let addr = self.store(self.deref(self[temp_v!(1)].clone()));
|
let addr = self.store(self.deref(self[temp_v!(1)]));
|
||||||
let stream = current_output_stream.clone();
|
let stream = current_output_stream.clone();
|
||||||
|
|
||||||
match addr {
|
match addr {
|
||||||
@@ -879,7 +881,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
&SystemClauseType::AtomChars => {
|
&SystemClauseType::AtomChars => {
|
||||||
let a1 = self[temp_v!(1)].clone();
|
let a1 = self[temp_v!(1)];
|
||||||
|
|
||||||
match self.store(self.deref(a1)) {
|
match self.store(self.deref(a1)) {
|
||||||
Addr::Char(c) => {
|
Addr::Char(c) => {
|
||||||
@@ -890,7 +892,7 @@ impl MachineState {
|
|||||||
self.unify(a2, list_of_chars);
|
self.unify(a2, list_of_chars);
|
||||||
}
|
}
|
||||||
Addr::Con(h) if self.heap.atom_at(h) => {
|
Addr::Con(h) if self.heap.atom_at(h) => {
|
||||||
if let HeapCellValue::Atom(name, _) = self.heap.clone(h) {
|
if let HeapCellValue::Atom(name, _) = self.heap.clone(h) {
|
||||||
let iter = name.as_str().chars().map(|c| Addr::Char(c));
|
let iter = name.as_str().chars().map(|c| Addr::Char(c));
|
||||||
let list_of_chars = Addr::HeapCell(self.heap.to_list(iter));
|
let list_of_chars = Addr::HeapCell(self.heap.to_list(iter));
|
||||||
|
|
||||||
@@ -910,7 +912,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Addr::EmptyList => {
|
Addr::EmptyList => {
|
||||||
let a2 = self[temp_v!(2)].clone();
|
let a2 = self[temp_v!(2)];
|
||||||
let chars = vec![
|
let chars = vec![
|
||||||
Addr::Char('['),
|
Addr::Char('['),
|
||||||
Addr::Char(']'),
|
Addr::Char(']'),
|
||||||
@@ -954,14 +956,14 @@ impl MachineState {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
&SystemClauseType::AtomCodes => {
|
&SystemClauseType::AtomCodes => {
|
||||||
let a1 = self[temp_v!(1)].clone();
|
let a1 = self[temp_v!(1)];
|
||||||
|
|
||||||
match self.store(self.deref(a1)) {
|
match self.store(self.deref(a1)) {
|
||||||
Addr::Char(c) => {
|
Addr::Char(c) => {
|
||||||
let iter = once(Addr::CharCode(c as u32));
|
let iter = once(Addr::CharCode(c as u32));
|
||||||
let list_of_codes = Addr::HeapCell(self.heap.to_list(iter));
|
let list_of_codes = Addr::HeapCell(self.heap.to_list(iter));
|
||||||
|
|
||||||
let a2 = self[temp_v!(2)].clone();
|
let a2 = self[temp_v!(2)];
|
||||||
self.unify(a2, list_of_codes);
|
self.unify(a2, list_of_codes);
|
||||||
}
|
}
|
||||||
Addr::Con(h) if self.heap.atom_at(h) => {
|
Addr::Con(h) if self.heap.atom_at(h) => {
|
||||||
@@ -1005,7 +1007,7 @@ impl MachineState {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let list_of_codes = Addr::HeapCell(self.heap.to_list(chars.into_iter()));
|
let list_of_codes = Addr::HeapCell(self.heap.to_list(chars.into_iter()));
|
||||||
let a2 = self[temp_v!(2)].clone();
|
let a2 = self[temp_v!(2)];
|
||||||
|
|
||||||
self.unify(a2, list_of_codes);
|
self.unify(a2, list_of_codes);
|
||||||
}
|
}
|
||||||
@@ -1170,7 +1172,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
&SystemClauseType::IsPartialString => {
|
&SystemClauseType::IsPartialString => {
|
||||||
let pstr = self.store(self.deref(self[temp_v!(1)].clone()));
|
let pstr = self.store(self.deref(self[temp_v!(1)]));
|
||||||
|
|
||||||
match pstr {
|
match pstr {
|
||||||
Addr::PStrLocation(..) => {
|
Addr::PStrLocation(..) => {
|
||||||
@@ -1289,7 +1291,7 @@ impl MachineState {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
&SystemClauseType::LiftedHeapLength => {
|
&SystemClauseType::LiftedHeapLength => {
|
||||||
let a1 = self[temp_v!(1)].clone();
|
let a1 = self[temp_v!(1)];
|
||||||
let lh_len = Addr::Usize(self.lifted_heap.h());
|
let lh_len = Addr::Usize(self.lifted_heap.h());
|
||||||
|
|
||||||
self.unify(a1, lh_len);
|
self.unify(a1, lh_len);
|
||||||
@@ -1350,7 +1352,7 @@ impl MachineState {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
&SystemClauseType::CheckCutPoint => {
|
&SystemClauseType::CheckCutPoint => {
|
||||||
let addr = self.store(self.deref(self[temp_v!(1)].clone()));
|
let addr = self.store(self.deref(self[temp_v!(1)]));
|
||||||
|
|
||||||
match addr {
|
match addr {
|
||||||
Addr::Usize(old_b) | Addr::CutPoint(old_b) => {
|
Addr::Usize(old_b) | Addr::CutPoint(old_b) => {
|
||||||
@@ -1400,7 +1402,7 @@ impl MachineState {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
&SystemClauseType::FetchGlobalVarWithOffset => {
|
&SystemClauseType::FetchGlobalVarWithOffset => {
|
||||||
let key = self[temp_v!(1)].clone();
|
let key = self[temp_v!(1)];
|
||||||
|
|
||||||
let key = match self.store(self.deref(key)) {
|
let key = match self.store(self.deref(key)) {
|
||||||
Addr::Con(h) if self.heap.atom_at(h) => {
|
Addr::Con(h) if self.heap.atom_at(h) => {
|
||||||
@@ -1428,7 +1430,7 @@ impl MachineState {
|
|||||||
*offset = Some(h);
|
*offset = Some(h);
|
||||||
}
|
}
|
||||||
Some((_, Some(h))) => {
|
Some((_, Some(h))) => {
|
||||||
let offset = self[temp_v!(3)].clone();
|
let offset = self[temp_v!(3)];
|
||||||
|
|
||||||
self.unify(offset, Addr::Usize(*h));
|
self.unify(offset, Addr::Usize(*h));
|
||||||
|
|
||||||
@@ -1445,7 +1447,7 @@ impl MachineState {
|
|||||||
let mut iter = parsing_stream(current_input_stream.clone());
|
let mut iter = parsing_stream(current_input_stream.clone());
|
||||||
let result = iter.next();
|
let result = iter.next();
|
||||||
|
|
||||||
let a1 = self[temp_v!(1)].clone();
|
let a1 = self[temp_v!(1)];
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Some(Ok(b)) => {
|
Some(Ok(b)) => {
|
||||||
@@ -1559,7 +1561,7 @@ impl MachineState {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
&SystemClauseType::HeadIsDynamic => {
|
&SystemClauseType::HeadIsDynamic => {
|
||||||
let head = self[temp_v!(1)].clone();
|
let head = self[temp_v!(1)];
|
||||||
|
|
||||||
self.fail = !match self.store(self.deref(head)) {
|
self.fail = !match self.store(self.deref(head)) {
|
||||||
Addr::Str(s) => match &self.heap[s] {
|
Addr::Str(s) => match &self.heap[s] {
|
||||||
@@ -1595,7 +1597,7 @@ impl MachineState {
|
|||||||
for addr in self.lifted_heap.iter_mut_from(old_threshold + 1) {
|
for addr in self.lifted_heap.iter_mut_from(old_threshold + 1) {
|
||||||
match addr {
|
match addr {
|
||||||
HeapCellValue::Addr(ref mut addr) => {
|
HeapCellValue::Addr(ref mut addr) => {
|
||||||
*addr -= self.heap.h() + lh_offset
|
*addr -= self.heap.h() + lh_offset;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@@ -2094,7 +2096,7 @@ impl MachineState {
|
|||||||
let iter = self.gather_attr_vars_created_since(b);
|
let iter = self.gather_attr_vars_created_since(b);
|
||||||
|
|
||||||
let var_list_addr = Addr::HeapCell(self.heap.to_list(iter));
|
let var_list_addr = Addr::HeapCell(self.heap.to_list(iter));
|
||||||
let list_addr = self[temp_v!(2)].clone();
|
let list_addr = self[temp_v!(2)];
|
||||||
|
|
||||||
self.unify(var_list_addr, list_addr);
|
self.unify(var_list_addr, list_addr);
|
||||||
} else {
|
} else {
|
||||||
@@ -2416,7 +2418,7 @@ impl MachineState {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
let target = self[temp_v!(1)].clone();
|
let target = self[temp_v!(1)];
|
||||||
|
|
||||||
self.unify(target, module);
|
self.unify(target, module);
|
||||||
}
|
}
|
||||||
@@ -2885,7 +2887,7 @@ impl MachineState {
|
|||||||
ContinueResult::PrintWithMaxDepth => 'p',
|
ContinueResult::PrintWithMaxDepth => 'p',
|
||||||
};
|
};
|
||||||
|
|
||||||
let target = self[temp_v!(1)];
|
let target = self[temp_v!(1)];
|
||||||
self.unify(Addr::Char(c), target);
|
self.unify(Addr::Char(c), target);
|
||||||
}
|
}
|
||||||
&SystemClauseType::NextEP => {
|
&SystemClauseType::NextEP => {
|
||||||
@@ -3008,12 +3010,12 @@ impl MachineState {
|
|||||||
self.reset_block(addr);
|
self.reset_block(addr);
|
||||||
}
|
}
|
||||||
&SystemClauseType::ResetContinuationMarker => {
|
&SystemClauseType::ResetContinuationMarker => {
|
||||||
let h = self.heap.h();
|
|
||||||
|
|
||||||
self[temp_v!(3)] = self.heap.to_unifiable(
|
self[temp_v!(3)] = self.heap.to_unifiable(
|
||||||
HeapCellValue::Atom(clause_name!("none"), None)
|
HeapCellValue::Atom(clause_name!("none"), None)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let h = self.heap.h();
|
||||||
|
|
||||||
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
|
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
|
||||||
self[temp_v!(4)] = Addr::HeapCell(h);
|
self[temp_v!(4)] = Addr::HeapCell(h);
|
||||||
}
|
}
|
||||||
@@ -3079,7 +3081,7 @@ impl MachineState {
|
|||||||
let mut ball = Ball::new();
|
let mut ball = Ball::new();
|
||||||
|
|
||||||
ball.boundary = self.heap.h();
|
ball.boundary = self.heap.h();
|
||||||
|
|
||||||
copy_term(
|
copy_term(
|
||||||
CopyBallTerm::new(&mut self.stack, &mut self.heap, &mut ball.stub),
|
CopyBallTerm::new(&mut self.stack, &mut self.heap, &mut ball.stub),
|
||||||
value,
|
value,
|
||||||
@@ -3238,7 +3240,7 @@ impl MachineState {
|
|||||||
h,
|
h,
|
||||||
ExistenceError::Procedure(name, arity),
|
ExistenceError::Procedure(name, arity),
|
||||||
);
|
);
|
||||||
|
|
||||||
let err = self.error_form(err, stub);
|
let err = self.error_form(err, stub);
|
||||||
|
|
||||||
self.throw_exception(err);
|
self.throw_exception(err);
|
||||||
@@ -3262,7 +3264,7 @@ impl MachineState {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let listing = Addr::HeapCell(self.heap.to_list(functors.into_iter()));
|
let listing = Addr::HeapCell(self.heap.to_list(functors.into_iter()));
|
||||||
let listing_var = self[temp_v!(3)].clone();
|
let listing_var = self[temp_v!(3)];
|
||||||
|
|
||||||
self.unify(listing, listing_var);
|
self.unify(listing, listing_var);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ impl<'a> TermStream<'a> {
|
|||||||
|
|
||||||
while let Some(term) = self.stack.pop() {
|
while let Some(term) = self.stack.pop() {
|
||||||
match machine_st.try_expand_term(self.wam, &term, CompileTimeHook::TermExpansion) {
|
match machine_st.try_expand_term(self.wam, &term, CompileTimeHook::TermExpansion) {
|
||||||
Some(term_string) => {
|
Some(term_string) => {
|
||||||
let term = self.parse_expansion_output(term_string.as_str(), op_dir)?;
|
let term = self.parse_expansion_output(term_string.as_str(), op_dir)?;
|
||||||
self.enqueue_term(term)?;
|
self.enqueue_term(term)?;
|
||||||
}
|
}
|
||||||
@@ -247,7 +247,7 @@ impl<'a> TermStream<'a> {
|
|||||||
|
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_term(&mut self, op_dir: &OpDir) -> Result<Term, ParserError> {
|
pub fn read_term(&mut self, op_dir: &OpDir) -> Result<Term, ParserError> {
|
||||||
loop {
|
loop {
|
||||||
if let Some(term) = self.stack.pop() {
|
if let Some(term) = self.stack.pop() {
|
||||||
@@ -304,7 +304,8 @@ impl<'a> TermStream<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MachineState {
|
impl MachineState {
|
||||||
pub(super) fn print_with_locs(&self, addr: Addr, op_dir: &OpDir) -> PrinterOutputter {
|
pub(super)
|
||||||
|
fn print_with_locs(&self, addr: Addr, op_dir: &OpDir) -> PrinterOutputter {
|
||||||
let output = PrinterOutputter::new();
|
let output = PrinterOutputter::new();
|
||||||
let mut printer = HCPrinter::from_heap_locs(&self, op_dir, output);
|
let mut printer = HCPrinter::from_heap_locs(&self, op_dir, output);
|
||||||
let mut max_var_length = 0;
|
let mut max_var_length = 0;
|
||||||
@@ -315,12 +316,14 @@ impl MachineState {
|
|||||||
|
|
||||||
printer.quoted = true;
|
printer.quoted = true;
|
||||||
printer.numbervars = true;
|
printer.numbervars = true;
|
||||||
|
|
||||||
// the purpose of the offset is to avoid clashes with variable names that might
|
// the purpose of the offset is to avoid clashes with variable
|
||||||
// occur after the addresses in the expanded term are substituted with the variable
|
// names that might occur after the addresses in the expanded
|
||||||
// names in the pre-expansion term. This formula ensures that all generated "numbervars"-
|
// term are substituted with the variable names in the
|
||||||
// style variable names will be longer than the keys of the var_dict, and therefore
|
// pre-expansion term. This formula ensures that all generated
|
||||||
// not equal to any of them.
|
// "numbervars"- style variable names will be longer than the
|
||||||
|
// keys of the var_dict, and therefore not equal to any of
|
||||||
|
// them.
|
||||||
printer.numbervars_offset = Integer::from(10).pow(max_var_length as u32) * 26;
|
printer.numbervars_offset = Integer::from(10).pow(max_var_length as u32) * 26;
|
||||||
printer.print_strings_as_strs = true;
|
printer.print_strings_as_strs = true;
|
||||||
printer.drop_toplevel_spec();
|
printer.drop_toplevel_spec();
|
||||||
@@ -334,8 +337,8 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// reset the machine, but keep the heap contents as they were.
|
// reset the machine, but keep the heap contents as they were.
|
||||||
// this prevents clashes between underscored variable names
|
// this prevents clashes between underscored variable names in the
|
||||||
// in the same query.
|
// same query.
|
||||||
fn reset_with_heap_preservation(&mut self) {
|
fn reset_with_heap_preservation(&mut self) {
|
||||||
let heap = self.heap.take();
|
let heap = self.heap.take();
|
||||||
self.reset();
|
self.reset();
|
||||||
@@ -359,7 +362,9 @@ impl MachineState {
|
|||||||
wam.code_repo.cached_query = code;
|
wam.code_repo.cached_query = code;
|
||||||
|
|
||||||
self.cp = LocalCodePtr::TopLevel(0, 0);
|
self.cp = LocalCodePtr::TopLevel(0, 0);
|
||||||
|
|
||||||
self.at_end_of_expansion = false;
|
self.at_end_of_expansion = false;
|
||||||
|
self.flags.double_quotes = DoubleQuotes::Chars;
|
||||||
|
|
||||||
self.query_stepper(
|
self.query_stepper(
|
||||||
&mut wam.indices,
|
&mut wam.indices,
|
||||||
|
|||||||
@@ -112,16 +112,6 @@ macro_rules! functor_term {
|
|||||||
(number($e:expr), $arity:expr, $aux_lens:expr, $addendum:ident) => (
|
(number($e:expr), $arity:expr, $aux_lens:expr, $addendum:ident) => (
|
||||||
$e.into()
|
$e.into()
|
||||||
);
|
);
|
||||||
/*
|
|
||||||
(string($s:expr), $arity:expr, $aux_lens:expr, $addendum: ident) => ({
|
|
||||||
let len: usize = $aux_lens.iter().sum();
|
|
||||||
let h = len + $arity + 1 + $addendum.h();
|
|
||||||
|
|
||||||
$addendum.allocate_pstr(&$s);
|
|
||||||
|
|
||||||
HeapCell::PStrLocation(h, 0)
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
(integer($e:expr), $arity:expr, $aux_lens:expr, $addendum: ident) => (
|
(integer($e:expr), $arity:expr, $aux_lens:expr, $addendum: ident) => (
|
||||||
HeapCellValue::Integer(Rc::new(Integer::from($e)))
|
HeapCellValue::Integer(Rc::new(Integer::from($e)))
|
||||||
);
|
);
|
||||||
@@ -148,9 +138,6 @@ macro_rules! from_constant {
|
|||||||
&Constant::CharCode(c) => {
|
&Constant::CharCode(c) => {
|
||||||
HeapCellValue::Addr(Addr::CharCode(c))
|
HeapCellValue::Addr(Addr::CharCode(c))
|
||||||
}
|
}
|
||||||
&Constant::CutPoint(cp) => {
|
|
||||||
HeapCellValue::Addr(Addr::CutPoint(cp))
|
|
||||||
}
|
|
||||||
&Constant::Integer(ref n) => {
|
&Constant::Integer(ref n) => {
|
||||||
HeapCellValue::Integer(n.clone())
|
HeapCellValue::Integer(n.clone())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,7 +153,8 @@ pub struct TermWriteResult {
|
|||||||
pub(crate) var_dict: HeapVarDict,
|
pub(crate) var_dict: HeapVarDict,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) -> TermWriteResult {
|
pub(crate)
|
||||||
|
fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) -> TermWriteResult {
|
||||||
let heap_loc = machine_st.heap.h();
|
let heap_loc = machine_st.heap.h();
|
||||||
|
|
||||||
let mut queue = SubtermDeque::new();
|
let mut queue = SubtermDeque::new();
|
||||||
@@ -188,13 +189,13 @@ pub(crate) fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) ->
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&TermRef::AnonVar(Level::Root) | &TermRef::Constant(Level::Root, ..) => {
|
&TermRef::AnonVar(Level::Root) | &TermRef::Constant(Level::Root, ..)
|
||||||
let value = HeapCellValue::Addr(term.as_addr(&mut machine_st.heap, h));
|
| &TermRef::Var(Level::Root, ..) => {
|
||||||
machine_st.heap.push(value);
|
let addr = term.as_addr(&mut machine_st.heap, h);
|
||||||
}
|
|
||||||
&TermRef::Var(Level::Root, ..) => {
|
if !addr.is_heap_bound() {
|
||||||
let value = HeapCellValue::Addr(term.as_addr(&mut machine_st.heap, h));
|
machine_st.heap.push(HeapCellValue::Addr(addr));
|
||||||
machine_st.heap.push(value);
|
}
|
||||||
}
|
}
|
||||||
&TermRef::AnonVar(_) => {
|
&TermRef::AnonVar(_) => {
|
||||||
if let Some((arity, site_h)) = queue.pop_front() {
|
if let Some((arity, site_h)) = queue.pop_front() {
|
||||||
|
|||||||
@@ -43,7 +43,6 @@
|
|||||||
).
|
).
|
||||||
|
|
||||||
'$submit_query_and_print_results'(Term0, VarList) :-
|
'$submit_query_and_print_results'(Term0, VarList) :-
|
||||||
write('oh brother'), nl,
|
|
||||||
( expand_goals(Term0, Term) -> true
|
( expand_goals(Term0, Term) -> true
|
||||||
; Term0 = Term
|
; Term0 = Term
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -158,8 +158,10 @@ impl fmt::Display for HeapCellValue {
|
|||||||
&HeapCellValue::NamedStr(arity, ref name, None) => {
|
&HeapCellValue::NamedStr(arity, ref name, None) => {
|
||||||
write!(f, "{}/{}", name.as_str(), arity)
|
write!(f, "{}/{}", name.as_str(), arity)
|
||||||
}
|
}
|
||||||
&HeapCellValue::PartialString(ref pstr) => {
|
&HeapCellValue::PartialString(ref pstr, has_tail) => {
|
||||||
write!(f, "pstr ( buf: 0x{:x} )", (pstr as *const _) as usize)
|
write!(f, "pstr ( buf: 0x{:x}, has_tail({}) )",
|
||||||
|
(pstr as *const _) as usize,
|
||||||
|
has_tail)
|
||||||
}
|
}
|
||||||
&HeapCellValue::Stream(ref stream) => {
|
&HeapCellValue::Stream(ref stream) => {
|
||||||
write!(f, "$stream({})", stream.as_ptr() as usize)
|
write!(f, "$stream({})", stream.as_ptr() as usize)
|
||||||
|
|||||||
@@ -23,6 +23,6 @@ test_queries_on_facts :-
|
|||||||
retract(p(_,_,_)),
|
retract(p(_,_,_)),
|
||||||
assertz(p(Z, h(Z, W), f(W))),
|
assertz(p(Z, h(Z, W), f(W))),
|
||||||
p(f(f(a)), h(f(f(a)), f(a)), f(f(a))),
|
p(f(f(a)), h(f(f(a)), f(a)), f(f(a))),
|
||||||
retract(p(Z, h(Z, W), f(W))).
|
retract(p(Z, h(Z, W), f(W))).[
|
||||||
|
|
||||||
:- initialization(test_queries_on_facts).
|
:- initialization(test_queries_on_facts).
|
||||||
|
|||||||
Reference in New Issue
Block a user