harmonize partial strings with complete strings (#276), make Addr a copyable type

This commit is contained in:
Mark Thom
2020-04-03 10:22:46 -06:00
parent cac76d4739
commit 141f3bcec3
33 changed files with 1229 additions and 885 deletions

4
Cargo.lock generated
View File

@@ -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"

View File

@@ -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

View File

@@ -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 {

View File

@@ -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!()
}
} }
} }
_ => { _ => {

View File

@@ -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!()
} }
} }
} }

View File

@@ -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);

View File

@@ -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).

View File

@@ -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) :-

View File

@@ -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) :-

View File

@@ -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),

View File

@@ -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)
). ).

View File

@@ -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).

View File

@@ -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).

View File

@@ -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()))
} }

View File

@@ -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([], _, _, []).

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)

View File

@@ -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)

View File

@@ -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()));

View File

@@ -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())

View File

@@ -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

View File

@@ -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)

View File

@@ -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,

View File

@@ -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 _;
}
} }
} }

View File

@@ -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);
} }

View File

@@ -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,

View File

@@ -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())
} }

View File

@@ -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() {

View File

@@ -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
), ),

View File

@@ -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)

View File

@@ -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).