harmonize partial strings with complete strings (#276), make Addr a copyable type
This commit is contained in:
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -445,6 +445,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "prolog_parser"
|
||||
version = "0.8.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"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)",
|
||||
@@ -579,7 +580,7 @@ dependencies = [
|
||||
"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)",
|
||||
"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)",
|
||||
"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)",
|
||||
@@ -790,6 +791,7 @@ dependencies = [
|
||||
"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 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 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"
|
||||
|
||||
@@ -25,10 +25,7 @@ libc = "0.2.62"
|
||||
nix = "0.15.0"
|
||||
num-rug-adapter = { optional = true, version = "0.1.1" }
|
||||
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"
|
||||
rug = { version = "1.4.0", optional = true }
|
||||
rustyline = "6.0.0"
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
@@ -37,7 +37,7 @@ impl<'a> HCPreOrderIterator<'a> {
|
||||
&HeapCellValue::Addr(a) => {
|
||||
self.follow(a)
|
||||
}
|
||||
HeapCellValue::PartialString(_) => {
|
||||
HeapCellValue::PartialString(..) => {
|
||||
self.follow(Addr::PStrLocation(h, 0))
|
||||
}
|
||||
HeapCellValue::Atom(..) | HeapCellValue::DBRef(_)
|
||||
@@ -64,17 +64,19 @@ impl<'a> HCPreOrderIterator<'a> {
|
||||
da
|
||||
}
|
||||
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 !pstr.at_end(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));
|
||||
} else {
|
||||
self.state_stack.push(Addr::EmptyList);
|
||||
}
|
||||
|
||||
self.state_stack.push(Addr::Char(c));
|
||||
} else {
|
||||
unreachable!()
|
||||
} else if has_tail {
|
||||
return self.follow(Addr::HeapCell(h + 1));
|
||||
}
|
||||
} else {
|
||||
unreachable!()
|
||||
@@ -86,8 +88,19 @@ impl<'a> HCPreOrderIterator<'a> {
|
||||
self.follow_heap(s) // record terms of structure.
|
||||
}
|
||||
Addr::Con(h) => {
|
||||
if let HeapCellValue::PartialString(_) = &self.machine_st.heap[h] {
|
||||
self.state_stack.push(Addr::HeapCell(h + 1));
|
||||
if let &HeapCellValue::PartialString(ref pstr, has_tail) = &self.machine_st.heap[h] {
|
||||
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)
|
||||
@@ -157,13 +170,20 @@ impl<'a> Iterator for HCPostOrderIterator<'a> {
|
||||
self.parent_stack.push((2, Addr::Lis(a)));
|
||||
}
|
||||
&HeapCellValue::Addr(Addr::PStrLocation(h, n)) => {
|
||||
if let HeapCellValue::PartialString(ref pstr) = &self.machine_st.heap[h] {
|
||||
match &self.machine_st.heap[h] {
|
||||
&HeapCellValue::PartialString(ref pstr, _) => {
|
||||
let c = pstr.range_from(n ..).next().unwrap();
|
||||
self.parent_stack.push((2, Addr::PStrLocation(h, n + c.len_utf8())));
|
||||
} else {
|
||||
let next_n = n + c.len_utf8();
|
||||
|
||||
if !pstr.at_end(next_n) {
|
||||
self.parent_stack.push((2, Addr::PStrLocation(h, next_n)));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Some(item);
|
||||
}
|
||||
|
||||
@@ -184,16 +184,16 @@ pub trait HCValueOutputter {
|
||||
type Output;
|
||||
|
||||
fn new() -> Self;
|
||||
fn push_char(&mut self, _: char);
|
||||
fn append(&mut self, _: &str);
|
||||
fn push_char(&mut self, c: char);
|
||||
fn append(&mut self, s: &str);
|
||||
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 ends_with(&self, _: &str) -> bool;
|
||||
fn ends_with(&self, s: &str) -> bool;
|
||||
fn len(&self) -> usize;
|
||||
fn truncate(&mut self, _: usize);
|
||||
fn range(&self, _: Range<usize>) -> &str;
|
||||
fn range_from(&self, _: RangeFrom<usize>) -> &str;
|
||||
fn truncate(&mut self, len: usize);
|
||||
fn range(&self, range: Range<usize>) -> &str;
|
||||
fn range_from(&self, range: RangeFrom<usize>) -> &str;
|
||||
}
|
||||
|
||||
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(
|
||||
&mut self,
|
||||
iter: &mut HCPreOrderIterator,
|
||||
mut max_depth: usize,
|
||||
mut h: usize,
|
||||
mut offset: usize,
|
||||
h: usize,
|
||||
n: usize,
|
||||
)
|
||||
{
|
||||
if !self.machine_st.machine_flags().double_quotes.is_atom() {
|
||||
iter.stack().pop();
|
||||
iter.stack().pop();
|
||||
|
||||
if self.check_max_depth(&mut max_depth) {
|
||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||
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;
|
||||
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);
|
||||
}
|
||||
} else if self.ignore_ops {
|
||||
let iter: Box<dyn Iterator<Item=char>> =
|
||||
if self.max_depth == 0 {
|
||||
Box::new(pstr.range_from(offset ..))
|
||||
|
||||
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 {
|
||||
Box::new(pstr.range_from(offset ..).take(max_depth))
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
let buf_len = buf.len();
|
||||
|
||||
let buf_iter: Box<dyn Iterator<Item=char>> =
|
||||
if self.max_depth == 0 {
|
||||
Box::new(buf.chars())
|
||||
} else {
|
||||
Box::new(buf.chars().take(max_depth))
|
||||
};
|
||||
|
||||
let mut byte_len = 0;
|
||||
|
||||
for c in iter {
|
||||
self.print_char(self.quoted, '.');
|
||||
let char_printer = |printer: &mut Self, c| {
|
||||
if printer.machine_st.flags.double_quotes.is_codes() {
|
||||
let s = (c as u32).to_string();
|
||||
|
||||
push_space_if_amb!(printer, &s, {
|
||||
printer.append_str(&s);
|
||||
});
|
||||
} else {
|
||||
printer.print_char(printer.quoted, c);
|
||||
}
|
||||
};
|
||||
|
||||
if self.ignore_ops {
|
||||
let mut char_count = 0;
|
||||
|
||||
for c in buf_iter {
|
||||
self.push_char('.');
|
||||
self.push_char('(');
|
||||
|
||||
self.print_char(self.quoted, c);
|
||||
char_printer(self, c);
|
||||
self.push_char(',');
|
||||
|
||||
char_count += 1;
|
||||
byte_len += c.len_utf8();
|
||||
}
|
||||
|
||||
let mut at_end = false;
|
||||
|
||||
if self.max_depth > 0 && !pstr.at_end(offset + byte_len) {
|
||||
self.append_str("...");
|
||||
at_end = true;
|
||||
} else {
|
||||
if let HeapCellValue::Addr(Addr::EmptyList) = &self.machine_st.heap[h+1] {
|
||||
self.append_str("[]");
|
||||
at_end = true;
|
||||
}
|
||||
}
|
||||
|
||||
for _ in 0 .. char_count {
|
||||
self.push_char(')');
|
||||
self.state_stack.push(TokenOrRedirect::Close);
|
||||
}
|
||||
|
||||
if at_end {
|
||||
break;
|
||||
}
|
||||
|
||||
max_depth -= char_count;
|
||||
if self.max_depth > 0 && buf_len > byte_len {
|
||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||
} else {
|
||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||
iter.stack().push(end_addr);
|
||||
}
|
||||
} else {
|
||||
let switch = if !self.at_cdr(",") {
|
||||
self.push_char('[');
|
||||
|
||||
let iter: Box<dyn Iterator<Item=char>> =
|
||||
if self.max_depth == 0 {
|
||||
Box::new(pstr.range_from(offset ..))
|
||||
true
|
||||
} else {
|
||||
Box::new(pstr.range_from(offset ..).take(max_depth))
|
||||
false
|
||||
};
|
||||
|
||||
let mut byte_len = 0;
|
||||
let mut char_count = 0;
|
||||
|
||||
for c in iter {
|
||||
self.print_char(false, c);
|
||||
for c in buf_iter {
|
||||
char_printer(self, c);
|
||||
self.push_char(',');
|
||||
|
||||
byte_len += c.len_utf8();
|
||||
char_count += 1;
|
||||
}
|
||||
|
||||
if self.max_depth > 0 && !pstr.at_end(offset + byte_len) {
|
||||
self.append_str("...|...]");
|
||||
break;
|
||||
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.push_char(']');
|
||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||
|
||||
iter.stack().push(end_addr);
|
||||
}
|
||||
|
||||
max_depth -= char_count;
|
||||
}
|
||||
|
||||
h += 2;
|
||||
offset = 0;
|
||||
}
|
||||
} else {
|
||||
self.print_string_as_str(h, 0, self.quoted);
|
||||
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1320,23 +1339,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
&HeapCellValue::Addr(Addr::Usize(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)) => {
|
||||
if let HeapCellValue::PartialString(_) = &self.machine_st.heap[h] {
|
||||
self.print_string(max_depth, h, n);
|
||||
|
||||
iter.stack().pop();
|
||||
iter.stack().pop();
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
self.print_string(iter, max_depth, h, n);
|
||||
}
|
||||
&HeapCellValue::Addr(Addr::Lis(_)) => {
|
||||
if self.ignore_ops {
|
||||
@@ -1358,21 +1362,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
&HeapCellValue::Rational(ref n) => {
|
||||
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) => {
|
||||
if let Some(alias) = &stream.options.alias {
|
||||
self.print_atom(alias);
|
||||
@@ -1385,6 +1374,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,7 +482,7 @@ impl FactInstruction {
|
||||
|
||||
functor!(
|
||||
"get_constant",
|
||||
[aux(h, 0), constant(c), aux(h, 1)],
|
||||
[aux(h, 0), constant(h, c), aux(h, 1)],
|
||||
[lvl_stub, rt_stub]
|
||||
)
|
||||
}
|
||||
@@ -524,7 +524,7 @@ impl FactInstruction {
|
||||
)
|
||||
}
|
||||
&FactInstruction::UnifyConstant(ref c) => {
|
||||
functor!("unify_constant", [constant(c)], [])
|
||||
functor!("unify_constant", [constant(h, c)], [])
|
||||
}
|
||||
&FactInstruction::UnifyLocalValue(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
@@ -589,7 +589,7 @@ impl QueryInstruction {
|
||||
|
||||
functor!(
|
||||
"put_constant",
|
||||
[aux(h, 0), constant(c), aux(h, 1)],
|
||||
[aux(h, 0), constant(h, c), aux(h, 1)],
|
||||
[lvl_stub, rt_stub]
|
||||
)
|
||||
}
|
||||
@@ -640,7 +640,7 @@ impl QueryInstruction {
|
||||
)
|
||||
}
|
||||
&QueryInstruction::SetConstant(ref c) => {
|
||||
functor!("set_constant", [constant(c)], [])
|
||||
functor!("set_constant", [constant(h, c)], [])
|
||||
}
|
||||
&QueryInstruction::SetLocalValue(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
@@ -158,4 +158,3 @@ call_residue_vars(Goal, Vars) :-
|
||||
'$get_attr_var_queue_delim'(B),
|
||||
call(Goal),
|
||||
'$get_attr_var_queue_beyond'(B, Vars).
|
||||
|
||||
|
||||
@@ -262,8 +262,11 @@ univ_errors(Term, List, N) :-
|
||||
Term =.. List :- '$call_with_default_policy'(univ_errors(Term, List, N)),
|
||||
'$call_with_default_policy'(univ_worker(Term, List, N)).
|
||||
|
||||
|
||||
:- 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) :-
|
||||
var(Term), !,
|
||||
'$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'(List = [Name|Args]).
|
||||
|
||||
|
||||
:- non_counted_backtracking get_args/4.
|
||||
|
||||
get_args(Args, _, _, 0) :-
|
||||
!, '$call_with_default_policy'(Args = []).
|
||||
get_args([Arg], Func, N, N) :-
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
:- module(cont, [reset/3, shift/1]).
|
||||
|
||||
reset(Goal, Ball, Cont) :-
|
||||
@@ -7,14 +6,14 @@ reset(Goal, Ball, Cont) :-
|
||||
'$bind_from_register'(Cont, 3),
|
||||
'$bind_from_register'(Ball, 4).
|
||||
|
||||
shift(Term) :-
|
||||
shift(Ball) :-
|
||||
'$nextEP'(first, E, P),
|
||||
get_chunks(E, P, L),
|
||||
( L == [] ->
|
||||
Cont = none
|
||||
; Cont = cont(call_continuation(L))
|
||||
),
|
||||
'$write_cont_and_term'(_, _, Cont, Term),
|
||||
'$write_cont_and_term'(_, _, Cont, Ball),
|
||||
'$unwind_environments'.
|
||||
|
||||
get_chunks(E, P, L) :-
|
||||
|
||||
@@ -208,4 +208,3 @@ dll_get_reverse_contents_(List, Contents) :-
|
||||
dll_get_pointer_to_previous(List, Prev),
|
||||
dll_get_reverse_contents_(Prev, Rest)
|
||||
).
|
||||
|
||||
|
||||
@@ -175,6 +175,12 @@ impl MachineState {
|
||||
&HeapCellValue::Addr(Addr::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) => {
|
||||
interms.push(Number::Rational(n.clone()))
|
||||
}
|
||||
|
||||
@@ -19,7 +19,8 @@ pub(super) struct 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 {
|
||||
attribute_goals: vec![],
|
||||
attr_var_queue: vec![],
|
||||
@@ -32,21 +33,24 @@ impl AttrVarInitializer {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn reset(&mut self) {
|
||||
pub(super)
|
||||
fn reset(&mut self) {
|
||||
self.attribute_goals.clear();
|
||||
self.attr_var_queue.clear();
|
||||
self.bindings.clear();
|
||||
}
|
||||
|
||||
#[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.bindings.truncate(bindings_b);
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
self.attr_var_init.instigating_p = self.p.local();
|
||||
|
||||
@@ -92,7 +96,8 @@ impl MachineState {
|
||||
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..]
|
||||
.iter()
|
||||
.filter_map(|h| match self.store(self.deref(Addr::HeapCell(*h))) {
|
||||
@@ -109,7 +114,8 @@ impl MachineState {
|
||||
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);
|
||||
|
||||
let e = self.e;
|
||||
|
||||
@@ -33,13 +33,13 @@ struct CopyTermState<T: CopierTarget> {
|
||||
scan: usize,
|
||||
old_h: usize,
|
||||
target: T,
|
||||
attr_var_policy: AttrVarPolicy
|
||||
attr_var_policy: AttrVarPolicy,
|
||||
}
|
||||
|
||||
impl<T: CopierTarget> CopyTermState<T> {
|
||||
fn new(target: T, attr_var_policy: AttrVarPolicy) -> Self {
|
||||
CopyTermState {
|
||||
trail: vec![],
|
||||
trail: Trail::new(),
|
||||
scan: 0,
|
||||
old_h: target.threshold(),
|
||||
target,
|
||||
@@ -53,124 +53,86 @@ impl<T: CopierTarget> CopyTermState<T> {
|
||||
&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) {
|
||||
if self.copied_list(addr) {
|
||||
if let Addr::Lis(h) = self.target[addr + 1].as_addr(addr + 1) {
|
||||
if h >= self.old_h {
|
||||
*self.value_at_scan() = HeapCellValue::Addr(Addr::Lis(h));
|
||||
self.scan += 1;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let threshold = self.target.threshold();
|
||||
|
||||
*self.value_at_scan() = HeapCellValue::Addr(Addr::Lis(threshold));
|
||||
|
||||
let ra = self.target[addr].as_addr(threshold);
|
||||
let rd = self.target.store(self.target.deref(ra));
|
||||
|
||||
self.target.push(HeapCellValue::Addr(ra));
|
||||
|
||||
let hcv = HeapCellValue::Addr(self.target[addr + 1].as_addr(addr + 1));
|
||||
|
||||
for i in 0 .. 2 {
|
||||
let hcv = self.target[addr + i].context_free_clone();
|
||||
self.target.push(hcv);
|
||||
|
||||
match rd {
|
||||
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;
|
||||
}
|
||||
|
||||
fn copied_partial_string(&mut self, addr: usize) -> bool {
|
||||
if let &HeapCellValue::Addr(Addr::PStrLocation(h, n)) = &self.target[addr + 1] {
|
||||
if h >= self.old_h {
|
||||
*self.value_at_scan() = HeapCellValue::Addr(Addr::PStrLocation(h, n));
|
||||
self.scan += 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
let cdr = self.target.store(self.target.deref(Addr::HeapCell(addr + 1)));
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn copy_partial_string(&mut self, addr: usize, n: usize) {
|
||||
let threshold = self.target.threshold();
|
||||
if let Addr::Lis(_) = cdr {
|
||||
let tail_addr = self.target[addr + 1].as_addr(addr + 1);
|
||||
|
||||
let trail_item = mem::replace(
|
||||
&mut self.target[addr + 1],
|
||||
HeapCellValue::Addr(Addr::PStrLocation(threshold, 0)),
|
||||
);
|
||||
|
||||
self.trail.push((
|
||||
Ref::HeapCell(addr + 1),
|
||||
trail_item,
|
||||
HeapCellValue::Addr(tail_addr),
|
||||
));
|
||||
|
||||
let pstr =
|
||||
self.target[addr + 1] = HeapCellValue::Addr(Addr::Lis(threshold));
|
||||
}
|
||||
|
||||
self.scan += 1;
|
||||
}
|
||||
|
||||
fn copy_partial_string(&mut self, addr: usize, n: usize) {
|
||||
if let &HeapCellValue::Addr(Addr::PStrLocation(h, _)) = &self.target[addr] {
|
||||
if h >= self.old_h {
|
||||
*self.value_at_scan() = HeapCellValue::Addr(Addr::PStrLocation(h, n));
|
||||
self.scan += 1;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let threshold = self.target.threshold();
|
||||
|
||||
*self.value_at_scan() =
|
||||
HeapCellValue::Addr(Addr::PStrLocation(threshold, 0));
|
||||
|
||||
self.scan += 1;
|
||||
|
||||
let (pstr, has_tail) =
|
||||
match &self.target[addr] {
|
||||
HeapCellValue::PartialString(ref pstr) => {
|
||||
pstr.clone_from_offset(n)
|
||||
&HeapCellValue::PartialString(ref pstr, has_tail) => {
|
||||
(pstr.clone_from_offset(n), has_tail)
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
};
|
||||
|
||||
self.target.push(HeapCellValue::PartialString(pstr));
|
||||
self.target.push(HeapCellValue::PartialString(pstr, has_tail));
|
||||
|
||||
let replacement = HeapCellValue::Addr(Addr::PStrLocation(threshold, 0));
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
fn copy_partial_string_from(&mut self, addr: usize, n: usize) {
|
||||
if self.copied_partial_string(addr) {
|
||||
return;
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -178,6 +140,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
||||
Addr::HeapCell(h) => {
|
||||
self.target[frontier] = HeapCellValue::Addr(Addr::HeapCell(frontier));
|
||||
self.target[h] = HeapCellValue::Addr(Addr::HeapCell(frontier));
|
||||
|
||||
self.trail.push((
|
||||
Ref::HeapCell(h),
|
||||
HeapCellValue::Addr(Addr::HeapCell(h)),
|
||||
@@ -186,6 +149,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
||||
Addr::StackCell(fr, sc) => {
|
||||
self.target[frontier] = HeapCellValue::Addr(Addr::HeapCell(frontier));
|
||||
self.target.stack().index_and_frame_mut(fr)[sc] = Addr::HeapCell(frontier);
|
||||
|
||||
self.trail.push((
|
||||
Ref::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[h] = HeapCellValue::Addr(Addr::HeapCell(threshold));
|
||||
self.target[h] = HeapCellValue::Addr(Addr::HeapCell(frontier));
|
||||
|
||||
self.trail.push((
|
||||
Ref::AttrVar(h),
|
||||
HeapCellValue::Addr(Addr::AttrVar(h)),
|
||||
@@ -212,7 +177,9 @@ impl<T: CopierTarget> CopyTermState<T> {
|
||||
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) {
|
||||
match self.target[addr].context_free_clone() {
|
||||
HeapCellValue::NamedStr(arity, name, fixity) => {
|
||||
let threshold = self.target.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((
|
||||
Ref::HeapCell(addr),
|
||||
HeapCellValue::NamedStr(arity, name.clone(), fixity.clone()),
|
||||
trail_item,
|
||||
));
|
||||
|
||||
self.target.push(HeapCellValue::NamedStr(arity, name, fixity));
|
||||
@@ -257,7 +246,9 @@ impl<T: CopierTarget> CopyTermState<T> {
|
||||
HeapCellValue::Addr(Addr::Str(addr)) => {
|
||||
*self.value_at_scan() = HeapCellValue::Addr(Addr::Str(addr))
|
||||
}
|
||||
_ => {}
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
self.scan += 1;
|
||||
@@ -272,26 +263,30 @@ impl<T: CopierTarget> CopyTermState<T> {
|
||||
&mut HeapCellValue::Addr(addr) => {
|
||||
match addr {
|
||||
Addr::Con(h) => {
|
||||
self.target.push(self.target[h].context_free_clone());
|
||||
self.scan += 1;
|
||||
let addr = self.target[h].as_addr(h);
|
||||
|
||||
if addr == Addr::Con(h) {
|
||||
*self.value_at_scan() = self.target[h].context_free_clone();
|
||||
} else {
|
||||
*self.value_at_scan() = HeapCellValue::Addr(addr);
|
||||
}
|
||||
Addr::Stream(_) => {
|
||||
self.target.push(HeapCellValue::Stream(Stream::null_stream()));
|
||||
self.scan += 1;
|
||||
}
|
||||
Addr::Lis(h) => {
|
||||
self.copy_list(h);
|
||||
}
|
||||
addr @ Addr::AttrVar(_)
|
||||
| addr @ Addr::HeapCell(_)
|
||||
| addr @ Addr::StackCell(..) => {
|
||||
addr @ Addr::AttrVar(_) |
|
||||
addr @ Addr::HeapCell(_) |
|
||||
addr @ Addr::StackCell(..) => {
|
||||
self.copy_var(addr);
|
||||
}
|
||||
Addr::Str(addr) => {
|
||||
self.copy_structure(addr);
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -51,13 +51,19 @@ impl Machine {
|
||||
};
|
||||
|
||||
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] {
|
||||
arity.to_usize().unwrap()
|
||||
} else {
|
||||
unreachable!()
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
Addr::Usize(n) => {
|
||||
n
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
};
|
||||
|
||||
(name, arity)
|
||||
|
||||
@@ -39,12 +39,12 @@ impl<T: RawBlockTraits> Drop for HeapTemplate<T> {
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
struct HeapIntoIterator<T: RawBlockTraits> {
|
||||
struct HeapIntoIter<T: RawBlockTraits> {
|
||||
offset: usize,
|
||||
buf: RawBlock<T>,
|
||||
}
|
||||
|
||||
impl<T: RawBlockTraits> Drop for HeapIntoIterator<T> {
|
||||
impl<T: RawBlockTraits> Drop for HeapIntoIter<T> {
|
||||
fn drop(&mut self) {
|
||||
let mut heap =
|
||||
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;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
@@ -72,19 +72,19 @@ impl<T: RawBlockTraits> Iterator for HeapIntoIterator<T> {
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
struct HeapIterator<'a, T: RawBlockTraits> {
|
||||
struct HeapIter<'a, T: RawBlockTraits> {
|
||||
offset: usize,
|
||||
buf: &'a RawBlock<T>,
|
||||
}
|
||||
|
||||
impl<'a, T: RawBlockTraits> HeapIterator<'a, T> {
|
||||
impl<'a, T: RawBlockTraits> HeapIter<'a, T> {
|
||||
pub(crate)
|
||||
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;
|
||||
|
||||
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)
|
||||
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,
|
||||
buf: &'a mut RawBlock<T>,
|
||||
}
|
||||
|
||||
impl<'a, T: RawBlockTraits> HeapIteratorMut<'a, T> {
|
||||
impl<'a, T: RawBlockTraits> HeapIterMut<'a, T> {
|
||||
pub(crate)
|
||||
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;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
@@ -160,7 +168,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
&HeapCellValue::Rational(ref r) => {
|
||||
HeapCellValue::Rational(r.clone())
|
||||
}
|
||||
&HeapCellValue::PartialString(_) => {
|
||||
&HeapCellValue::PartialString(..) => {
|
||||
HeapCellValue::Addr(Addr::PStrLocation(h, 0))
|
||||
}
|
||||
&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]
|
||||
pub(crate)
|
||||
fn put_constant(&mut self, c: Constant) -> Addr {
|
||||
@@ -177,19 +194,12 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
Addr::Con(self.push(HeapCellValue::Atom(name, op)))
|
||||
}
|
||||
Constant::Char(c) => {
|
||||
self.push(HeapCellValue::Addr(Addr::Char(c)));
|
||||
Addr::Char(c)
|
||||
}
|
||||
Constant::CharCode(c) => {
|
||||
self.push(HeapCellValue::Addr(Addr::CharCode(c)));
|
||||
Addr::CharCode(c)
|
||||
}
|
||||
Constant::CutPoint(cp) => {
|
||||
self.push(HeapCellValue::Addr(Addr::CutPoint(cp)));
|
||||
Addr::CutPoint(cp)
|
||||
}
|
||||
Constant::EmptyList => {
|
||||
self.push(HeapCellValue::Addr(Addr::EmptyList));
|
||||
Addr::EmptyList
|
||||
}
|
||||
Constant::Integer(n) => {
|
||||
@@ -199,18 +209,30 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
Addr::Con(self.push(HeapCellValue::Rational(r)))
|
||||
}
|
||||
Constant::Float(f) => {
|
||||
self.push(HeapCellValue::Addr(Addr::Float(f)));
|
||||
Addr::Float(f)
|
||||
}
|
||||
Constant::String(s) => {
|
||||
if s.is_empty() {
|
||||
Addr::EmptyList
|
||||
} else {
|
||||
let addr = self.allocate_pstr(&s);
|
||||
self.pop();
|
||||
|
||||
let h = self.h();
|
||||
|
||||
self[h - 1] = HeapCellValue::Addr(Addr::EmptyList);
|
||||
match &mut self[h - 1] {
|
||||
&mut HeapCellValue::PartialString(_, ref mut has_tail) => {
|
||||
*has_tail = false;
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
addr
|
||||
}
|
||||
}
|
||||
Constant::Usize(n) => {
|
||||
self.push(HeapCellValue::Addr(Addr::Usize(n)));
|
||||
Addr::Usize(n)
|
||||
}
|
||||
}
|
||||
@@ -279,9 +301,12 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
val @ HeapCellValue::Stream(..) => {
|
||||
Addr::Stream(self.push(val))
|
||||
}
|
||||
val @ HeapCellValue::PartialString(_) => {
|
||||
let h = self.push(val);
|
||||
HeapCellValue::PartialString(pstr, has_tail) => {
|
||||
let h = self.push(HeapCellValue::PartialString(pstr, has_tail));
|
||||
|
||||
if has_tail {
|
||||
self.push(HeapCellValue::Addr(Addr::EmptyList));
|
||||
}
|
||||
|
||||
Addr::Con(h)
|
||||
}
|
||||
@@ -296,7 +321,8 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
let h = self.h();
|
||||
|
||||
self.push(HeapCellValue::PartialString(
|
||||
PartialString::empty()
|
||||
PartialString::empty(),
|
||||
true,
|
||||
));
|
||||
|
||||
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 != "" {
|
||||
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(value);
|
||||
|
||||
h += mem::size_of::<HeapCellValue>() * 2;
|
||||
h += 2;
|
||||
}
|
||||
|
||||
self.push(HeapCellValue::Addr(Addr::EmptyList));
|
||||
@@ -424,18 +450,18 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
|
||||
/* Create an iterator starting from the passed offset. */
|
||||
pub(crate)
|
||||
fn iter_from<'a>(&'a self, offset: usize) -> HeapIterator<'a, T> {
|
||||
HeapIterator::new(&self.buf, offset * mem::size_of::<HeapCellValue>())
|
||||
fn iter_from<'a>(&'a self, offset: usize) -> HeapIter<'a, T> {
|
||||
HeapIter::new(&self.buf, offset * mem::size_of::<HeapCellValue>())
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn iter_mut_from<'a>(&'a mut self, offset: usize) -> HeapIteratorMut<'a, T> {
|
||||
HeapIteratorMut::new(&mut self.buf, offset * mem::size_of::<HeapCellValue>())
|
||||
fn iter_mut_from<'a>(&'a mut self, offset: usize) -> HeapIterMut<'a, T> {
|
||||
HeapIterMut::new(&mut self.buf, offset * mem::size_of::<HeapCellValue>())
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn into_iter(mut self) -> HeapIntoIterator<T> {
|
||||
HeapIntoIterator { buf: self.buf.take(), offset: 0 }
|
||||
fn into_iter(mut self) -> HeapIntoIter<T> {
|
||||
HeapIntoIter { buf: self.buf.take(), offset: 0 }
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
|
||||
@@ -152,6 +152,20 @@ impl PartialOrd<Ref> for 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 {
|
||||
match self {
|
||||
Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::AttrVar(_) => {
|
||||
@@ -163,6 +177,7 @@ impl Addr {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_var(&self) -> Option<Ref> {
|
||||
match self {
|
||||
&Addr::AttrVar(h) => Some(Ref::AttrVar(h)),
|
||||
@@ -200,13 +215,16 @@ impl Addr {
|
||||
}
|
||||
}
|
||||
}
|
||||
Addr::Char(_) | Addr::CharCode(_) | Addr::EmptyList => {
|
||||
Addr::Char(_) | Addr::EmptyList => {
|
||||
Some(TermOrderCategory::Atom)
|
||||
}
|
||||
Addr::Usize(_) | Addr::CharCode(_) => {
|
||||
Some(TermOrderCategory::Integer)
|
||||
}
|
||||
Addr::Lis(_) | Addr::PStrLocation(..) | Addr::Str(_) => {
|
||||
Some(TermOrderCategory::Compound)
|
||||
}
|
||||
Addr::CutPoint(_) | Addr::Usize(_) | Addr::Stream(_) => {
|
||||
Addr::CutPoint(_) | Addr::Stream(_) => {
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -236,12 +254,30 @@ impl Addr {
|
||||
}
|
||||
}
|
||||
}
|
||||
&Addr::EmptyList => {
|
||||
Some(Constant::EmptyList)
|
||||
}
|
||||
&Addr::Float(f) => {
|
||||
Some(Constant::Float(f))
|
||||
}
|
||||
&Addr::PStrLocation(h, n) => {
|
||||
machine_st.to_complete_string(h, n)
|
||||
.map(|s| Constant::String(Rc::new(s)))
|
||||
let mut heap_pstr_iter =
|
||||
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
|
||||
@@ -262,6 +298,8 @@ impl Add<usize> for Addr {
|
||||
|
||||
fn add(self, rhs: usize) -> Self::Output {
|
||||
match self {
|
||||
Addr::Stream(h) => Addr::Stream(h + rhs),
|
||||
Addr::Con(h) => Addr::Con(h + rhs),
|
||||
Addr::Lis(a) => Addr::Lis(a + rhs),
|
||||
Addr::AttrVar(h) => Addr::AttrVar(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 {
|
||||
if rhs < 0 {
|
||||
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::AttrVar(h) => Addr::AttrVar(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 {
|
||||
match self {
|
||||
Addr::Stream(h) => Addr::Stream(h - rhs),
|
||||
Addr::Con(h) => Addr::Con(h - rhs),
|
||||
Addr::Lis(a) => Addr::Lis(a - rhs),
|
||||
Addr::AttrVar(h) => Addr::AttrVar(h - rhs),
|
||||
Addr::HeapCell(h) => Addr::HeapCell(h - rhs),
|
||||
@@ -332,7 +374,7 @@ pub enum HeapCellValue {
|
||||
Integer(Rc<Integer>),
|
||||
NamedStr(usize, ClauseName, Option<SharedOpDesc>), // arity, name, precedence/Specifier if it has one.
|
||||
Rational(Rc<Rational>),
|
||||
PartialString(PartialString),
|
||||
PartialString(PartialString, bool), // the partial string, a bool indicating whether it came from a Constant.
|
||||
Stream(Stream),
|
||||
}
|
||||
|
||||
@@ -341,7 +383,7 @@ impl HeapCellValue {
|
||||
pub fn as_addr(&self, focus: usize) -> Addr {
|
||||
match self {
|
||||
HeapCellValue::Addr(ref a) => {
|
||||
a.clone()
|
||||
*a
|
||||
}
|
||||
HeapCellValue::Atom(..) | HeapCellValue::DBRef(..) | HeapCellValue::Integer(..) |
|
||||
HeapCellValue::Rational(..) => {
|
||||
@@ -350,7 +392,7 @@ impl HeapCellValue {
|
||||
HeapCellValue::NamedStr(_, _, _) => {
|
||||
Addr::Str(focus)
|
||||
}
|
||||
HeapCellValue::PartialString(_) => {
|
||||
HeapCellValue::PartialString(..) => {
|
||||
Addr::PStrLocation(focus, 0)
|
||||
}
|
||||
HeapCellValue::Stream(_) => {
|
||||
@@ -380,8 +422,8 @@ impl HeapCellValue {
|
||||
&HeapCellValue::Rational(ref r) => {
|
||||
HeapCellValue::Rational(r.clone())
|
||||
}
|
||||
&HeapCellValue::PartialString(ref pstr) => {
|
||||
HeapCellValue::PartialString(pstr.clone())
|
||||
&HeapCellValue::PartialString(ref pstr, has_tail) => {
|
||||
HeapCellValue::PartialString(pstr.clone(), has_tail)
|
||||
}
|
||||
&HeapCellValue::Stream(_) => {
|
||||
HeapCellValue::Stream(Stream::null_stream())
|
||||
|
||||
@@ -14,11 +14,105 @@ use crate::prolog::rug::Integer;
|
||||
|
||||
use downcast::Any;
|
||||
|
||||
use indexmap::IndexSet;
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::io::Write;
|
||||
use std::mem;
|
||||
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(super) boundary: usize,
|
||||
pub(super) stub: Heap,
|
||||
@@ -185,7 +279,7 @@ impl<'a> CopierTarget for CopyBallTerm<'a> {
|
||||
self.stub[index].as_addr(h)
|
||||
}
|
||||
Addr::StackCell(fr, sc) => {
|
||||
self.stack.index_and_frame(fr)[sc].clone()
|
||||
self.stack.index_and_frame(fr)[sc]
|
||||
}
|
||||
addr => {
|
||||
addr
|
||||
@@ -195,7 +289,7 @@ impl<'a> CopierTarget for CopyBallTerm<'a> {
|
||||
|
||||
fn deref(&self, mut addr: Addr) -> Addr {
|
||||
loop {
|
||||
let value = self.store(addr.clone());
|
||||
let value = self.store(addr);
|
||||
|
||||
if value.is_ref() && value != addr {
|
||||
addr = value;
|
||||
@@ -264,11 +358,13 @@ impl HeapPtr {
|
||||
Addr::HeapCell(h)
|
||||
}
|
||||
&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() {
|
||||
Addr::Char(c)
|
||||
} else {
|
||||
} else if has_tail {
|
||||
Addr::HeapCell(h + 1)
|
||||
} else {
|
||||
Addr::EmptyList
|
||||
}
|
||||
} else {
|
||||
unreachable!()
|
||||
@@ -315,13 +411,19 @@ pub struct MachineState {
|
||||
}
|
||||
|
||||
impl MachineState {
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn heap_pstr_iter<'a>(&'a self, focus: Addr) -> HeapPStrIter<'a> {
|
||||
HeapPStrIter::new(self, focus)
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn try_char_list(&self, addrs: Vec<Addr>) -> Result<String, MachineError> {
|
||||
let mut chars = String::new();
|
||||
let mut iter = addrs.iter();
|
||||
|
||||
while let Some(addr) = iter.next() {
|
||||
let addr = self.store(self.deref(addr.clone()));
|
||||
let addr = self.store(self.deref(*addr));
|
||||
|
||||
match addr {
|
||||
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;
|
||||
|
||||
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;
|
||||
@@ -519,7 +621,7 @@ pub(crate) trait CallPolicy: Any {
|
||||
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
|
||||
|
||||
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;
|
||||
@@ -555,7 +657,7 @@ pub(crate) trait CallPolicy: Any {
|
||||
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
|
||||
|
||||
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;
|
||||
@@ -595,7 +697,7 @@ pub(crate) trait CallPolicy: Any {
|
||||
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
|
||||
|
||||
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;
|
||||
@@ -717,7 +819,7 @@ pub(crate) trait CallPolicy: Any {
|
||||
) -> CallResult {
|
||||
match ct {
|
||||
&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);
|
||||
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)
|
||||
}
|
||||
&BuiltInClauseType::Compare => {
|
||||
let a1 = machine_st[temp_v!(1)].clone();
|
||||
let a2 = machine_st[temp_v!(2)].clone();
|
||||
let a3 = machine_st[temp_v!(3)].clone();
|
||||
let a1 = machine_st[temp_v!(1)];
|
||||
let a2 = machine_st[temp_v!(2)];
|
||||
let a3 = machine_st[temp_v!(3)];
|
||||
|
||||
let atom = match machine_st.compare_term_test(&a2, &a3) {
|
||||
Some(Ordering::Greater) => {
|
||||
@@ -769,7 +871,7 @@ pub(crate) trait CallPolicy: Any {
|
||||
&indices.op_dir,
|
||||
) {
|
||||
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));
|
||||
}
|
||||
Err(e) => {
|
||||
@@ -789,8 +891,8 @@ pub(crate) trait CallPolicy: Any {
|
||||
return_from_clause!(machine_st.last_call, machine_st)
|
||||
}
|
||||
&BuiltInClauseType::Eq => {
|
||||
let a1 = machine_st[temp_v!(1)].clone();
|
||||
let a2 = machine_st[temp_v!(2)].clone();
|
||||
let a1 = machine_st[temp_v!(1)];
|
||||
let a2 = machine_st[temp_v!(2)];
|
||||
|
||||
machine_st.fail = machine_st.eq_test(a1, a2);
|
||||
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)
|
||||
}
|
||||
&BuiltInClauseType::NotEq => {
|
||||
let a1 = machine_st[temp_v!(1)].clone();
|
||||
let a2 = machine_st[temp_v!(2)].clone();
|
||||
let a1 = machine_st[temp_v!(1)];
|
||||
let a2 = machine_st[temp_v!(2)];
|
||||
|
||||
machine_st.fail =
|
||||
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 r2 = machine_st[temp_v!(2)].clone();
|
||||
let r2 = machine_st[temp_v!(2)];
|
||||
machine_st.unify(r2, heap_addr);
|
||||
|
||||
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 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);
|
||||
|
||||
return_from_clause!(machine_st.last_call, machine_st)
|
||||
}
|
||||
&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 = 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(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);
|
||||
}
|
||||
|
||||
impl CutPolicy for DefaultCutPolicy {
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -1209,7 +1311,7 @@ impl CutPolicy for SCCCutPolicy {
|
||||
fn cut(&mut self, machine_st: &mut MachineState, r: RegType) -> bool {
|
||||
let b = machine_st.b;
|
||||
|
||||
match machine_st[r].clone() {
|
||||
match machine_st[r] {
|
||||
Addr::Usize(b0) | Addr::CutPoint(b0) => {
|
||||
if b > b0 {
|
||||
machine_st.b = b0;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,28 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use std::alloc;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use std::ops::{Range, RangeFrom};
|
||||
use std::ops::RangeFrom;
|
||||
use std::slice;
|
||||
use std::str;
|
||||
|
||||
pub struct PartialString {
|
||||
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 {
|
||||
@@ -47,56 +64,33 @@ impl Iterator for PStrIter {
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
unsafe {
|
||||
let b = ptr::read(self.buf);
|
||||
let mut byte_count = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
let c = ptr::read(self.buf as *const char);
|
||||
let slice = slice::from_raw_parts(self.buf, byte_count);
|
||||
let s = str::from_utf8(slice).unwrap();
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialString {
|
||||
@@ -105,6 +99,8 @@ impl PartialString {
|
||||
fn new(src: &str) -> Option<(Self, &str)> {
|
||||
let pstr = PartialString {
|
||||
buf: ptr::null_mut(),
|
||||
len: 0,
|
||||
_marker: PhantomData,
|
||||
};
|
||||
|
||||
unsafe {
|
||||
@@ -116,7 +112,9 @@ impl PartialString {
|
||||
pub(super)
|
||||
fn empty() -> Self {
|
||||
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(
|
||||
src.len() + '\u{0}'.len_utf8(),
|
||||
terminator_idx + '\u{0}'.len_utf8(),
|
||||
mem::align_of::<u8>(),
|
||||
);
|
||||
|
||||
self.buf = alloc::alloc(layout) as *const _;
|
||||
self.len = terminator_idx + '\u{0}'.len_utf8();
|
||||
|
||||
ptr::copy(
|
||||
src.as_ptr(),
|
||||
@@ -149,24 +148,17 @@ impl PartialString {
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn iter(&self) -> PStrIter {
|
||||
PStrIter {
|
||||
buf: self.buf,
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn clone_from_offset(&self, n: usize) -> Self {
|
||||
let len = if self.len > n { self.len - n } else { 0 };
|
||||
|
||||
let mut pstr = PartialString {
|
||||
buf: ptr::null_mut(),
|
||||
len: len + '\u{0}'.len_utf8(),
|
||||
_marker: PhantomData,
|
||||
};
|
||||
|
||||
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(
|
||||
len + '\u{0}'.len_utf8(),
|
||||
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]
|
||||
pub fn range_from(&self, index: RangeFrom<usize>) -> PStrIter {
|
||||
PStrIter::from(self.buf, index.start)
|
||||
|
||||
@@ -36,20 +36,6 @@ impl<T: RawBlockTraits> RawBlock<T> {
|
||||
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) {
|
||||
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())
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
fn free_space(&self) -> usize {
|
||||
debug_assert!(self.top >= self.base,
|
||||
|
||||
@@ -49,7 +49,6 @@ impl Drop for Stack {
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct FramePrelude {
|
||||
is_or_frame: u8,
|
||||
pub num_cells: usize,
|
||||
}
|
||||
|
||||
@@ -62,7 +61,6 @@ pub struct AndFramePrelude {
|
||||
|
||||
pub struct AndFrame {
|
||||
pub prelude: AndFramePrelude,
|
||||
_marker: PhantomData<Addr>,
|
||||
}
|
||||
|
||||
impl AndFrame {
|
||||
@@ -89,8 +87,6 @@ impl Index<usize> for AndFrame {
|
||||
|
||||
impl IndexMut<usize> for AndFrame {
|
||||
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 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 univ_prelude: FramePrelude,
|
||||
pub e: usize,
|
||||
@@ -137,7 +115,6 @@ pub struct OrFramePrelude {
|
||||
|
||||
pub struct OrFrame {
|
||||
pub prelude: OrFramePrelude,
|
||||
_marker: PhantomData<Addr>
|
||||
}
|
||||
|
||||
impl Index<usize> for OrFrame {
|
||||
@@ -145,8 +122,6 @@ impl Index<usize> for OrFrame {
|
||||
|
||||
#[inline]
|
||||
fn index(&self, index: usize) -> &Self::Output {
|
||||
debug_assert!(self.prelude.univ_prelude.is_or_frame == 1);
|
||||
|
||||
let prelude_offset = prelude_size::<OrFramePrelude>();
|
||||
let index_offset = index * mem::size_of::<Addr>();
|
||||
|
||||
@@ -162,8 +137,6 @@ impl Index<usize> for OrFrame {
|
||||
impl IndexMut<usize> for OrFrame {
|
||||
#[inline]
|
||||
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 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 {
|
||||
pub fn size_of(num_cells: usize) -> usize {
|
||||
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);
|
||||
|
||||
and_frame.prelude.univ_prelude.is_or_frame = 0;
|
||||
and_frame.prelude.univ_prelude.num_cells = num_cells;
|
||||
|
||||
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);
|
||||
|
||||
or_frame.prelude.univ_prelude.is_or_frame = 1;
|
||||
or_frame.prelude.univ_prelude.num_cells = num_cells;
|
||||
|
||||
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 }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn truncate(&mut self, b: usize) {
|
||||
if b == 0 {
|
||||
self.inner_truncate(mem::align_of::<Addr>());
|
||||
@@ -295,42 +247,14 @@ impl Stack {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inner_truncate(&mut self, b: usize) {
|
||||
let mut b = b + self.buf.base as usize;
|
||||
let base = b;
|
||||
|
||||
unsafe {
|
||||
while b as *const _ < self.buf.top {
|
||||
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;
|
||||
}
|
||||
let base = b + self.buf.base as usize;
|
||||
|
||||
if base < self.buf.top as usize {
|
||||
self.buf.top = base as *const _;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn drop_in_place(&mut self) {
|
||||
self.truncate(mem::align_of::<Addr>());
|
||||
|
||||
@@ -77,7 +77,7 @@ struct BrentAlgState {
|
||||
impl BrentAlgState {
|
||||
fn new(hare: Addr) -> Self {
|
||||
BrentAlgState {
|
||||
hare: hare.clone(),
|
||||
hare: hare,
|
||||
tortoise: hare,
|
||||
power: 2,
|
||||
steps: 0,
|
||||
@@ -89,7 +89,7 @@ impl BrentAlgState {
|
||||
if self.tortoise == self.hare {
|
||||
return Some(CycleSearchResult::NotList);
|
||||
} else if self.steps == self.power {
|
||||
self.tortoise = self.hare.clone();
|
||||
self.tortoise = self.hare;
|
||||
self.power <<= 1;
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ impl MachineState {
|
||||
}
|
||||
Addr::PStrLocation(h, n) => {
|
||||
match &self.heap[h] {
|
||||
HeapCellValue::PartialString(ref pstr) => {
|
||||
HeapCellValue::PartialString(ref pstr, _) => {
|
||||
if let Some(c) = pstr.range_from(n ..).next() {
|
||||
brent_st.step(Addr::PStrLocation(h, n + c.len_utf8()))
|
||||
} else {
|
||||
@@ -184,7 +184,7 @@ impl MachineState {
|
||||
return CycleSearchResult::EmptyList;
|
||||
}
|
||||
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() {
|
||||
Addr::PStrLocation(h, 0)
|
||||
} else {
|
||||
@@ -195,7 +195,7 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
Addr::Con(h) => {
|
||||
if let HeapCellValue::PartialString(_) = &self.heap[h] {
|
||||
if let HeapCellValue::PartialString(..) = &self.heap[h] {
|
||||
if !self.flags.double_quotes.is_atom() {
|
||||
return CycleSearchResult::UntouchedList(h);
|
||||
}
|
||||
@@ -235,7 +235,7 @@ impl MachineState {
|
||||
Addr::PStrLocation(h, n)
|
||||
}
|
||||
Addr::Con(h) => {
|
||||
if let HeapCellValue::PartialString(_) = &self.heap[h] {
|
||||
if let HeapCellValue::PartialString(..) = &self.heap[h] {
|
||||
if !self.flags.double_quotes.is_atom() {
|
||||
Addr::PStrLocation(h, 0)
|
||||
} else {
|
||||
@@ -425,7 +425,7 @@ impl MachineState {
|
||||
&indices.op_dir,
|
||||
) {
|
||||
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);
|
||||
|
||||
if self.fail {
|
||||
@@ -447,7 +447,7 @@ impl MachineState {
|
||||
list_of_var_eqs.push(Addr::Str(h));
|
||||
}
|
||||
|
||||
let a2 = self[temp_v!(2)].clone();
|
||||
let a2 = self[temp_v!(2)];
|
||||
let list_offset =
|
||||
Addr::HeapCell(self.heap.to_list(list_of_var_eqs.into_iter()));
|
||||
|
||||
@@ -475,7 +475,7 @@ impl MachineState {
|
||||
self.block = self.b;
|
||||
|
||||
let c = Constant::Usize(self.block);
|
||||
let addr = self[r].clone();
|
||||
let addr = self[r];
|
||||
|
||||
self.write_constant_to_var(addr, &c);
|
||||
self.block
|
||||
@@ -513,7 +513,7 @@ impl MachineState {
|
||||
where
|
||||
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) => {
|
||||
if lh_offset >= self.lifted_heap.h() {
|
||||
self.lifted_heap.truncate(lh_offset);
|
||||
@@ -542,7 +542,7 @@ impl MachineState {
|
||||
continue;
|
||||
}
|
||||
|
||||
let a2 = self[temp_v!(2)].clone();
|
||||
let a2 = self[temp_v!(2)];
|
||||
|
||||
if let Some(r) = a2.as_var() {
|
||||
let spec = get_clause_spec(
|
||||
@@ -578,7 +578,7 @@ impl MachineState {
|
||||
|
||||
match op_dir.range(key..).skip(1).next() {
|
||||
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() {
|
||||
let addr = self.heap.to_unifiable(
|
||||
@@ -627,7 +627,7 @@ impl MachineState {
|
||||
indices: &IndexStore,
|
||||
stub: MachineStub,
|
||||
) -> CallResult {
|
||||
let nx = self[temp_v!(2)].clone();
|
||||
let nx = self[temp_v!(2)];
|
||||
|
||||
if let Some(c) = string.chars().last() {
|
||||
if layout_char!(c) {
|
||||
@@ -696,7 +696,7 @@ impl MachineState {
|
||||
self.term_dedup(&mut attr_goals);
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -773,7 +773,7 @@ impl MachineState {
|
||||
return Ok(());
|
||||
}
|
||||
&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 {
|
||||
Addr::Con(h) =>
|
||||
if let HeapCellValue::Integer(ref n) = &self.heap[h] {
|
||||
@@ -781,13 +781,15 @@ impl MachineState {
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
_ => unreachable!()
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(n) = n {
|
||||
if n <= MAX_ARITY {
|
||||
let target = self[temp_v!(n)].clone();
|
||||
let addr = self[temp_v!(1)].clone();
|
||||
let target = self[temp_v!(n)];
|
||||
let addr = self[temp_v!(1)];
|
||||
|
||||
self.unify(addr, target);
|
||||
return return_from_clause!(self.last_call, self);
|
||||
@@ -843,7 +845,7 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
&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();
|
||||
|
||||
match addr {
|
||||
@@ -879,7 +881,7 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
&SystemClauseType::AtomChars => {
|
||||
let a1 = self[temp_v!(1)].clone();
|
||||
let a1 = self[temp_v!(1)];
|
||||
|
||||
match self.store(self.deref(a1)) {
|
||||
Addr::Char(c) => {
|
||||
@@ -910,7 +912,7 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
Addr::EmptyList => {
|
||||
let a2 = self[temp_v!(2)].clone();
|
||||
let a2 = self[temp_v!(2)];
|
||||
let chars = vec![
|
||||
Addr::Char('['),
|
||||
Addr::Char(']'),
|
||||
@@ -954,14 +956,14 @@ impl MachineState {
|
||||
};
|
||||
}
|
||||
&SystemClauseType::AtomCodes => {
|
||||
let a1 = self[temp_v!(1)].clone();
|
||||
let a1 = self[temp_v!(1)];
|
||||
|
||||
match self.store(self.deref(a1)) {
|
||||
Addr::Char(c) => {
|
||||
let iter = once(Addr::CharCode(c as u32));
|
||||
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);
|
||||
}
|
||||
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 a2 = self[temp_v!(2)].clone();
|
||||
let a2 = self[temp_v!(2)];
|
||||
|
||||
self.unify(a2, list_of_codes);
|
||||
}
|
||||
@@ -1170,7 +1172,7 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
&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 {
|
||||
Addr::PStrLocation(..) => {
|
||||
@@ -1289,7 +1291,7 @@ impl MachineState {
|
||||
return Ok(());
|
||||
}
|
||||
&SystemClauseType::LiftedHeapLength => {
|
||||
let a1 = self[temp_v!(1)].clone();
|
||||
let a1 = self[temp_v!(1)];
|
||||
let lh_len = Addr::Usize(self.lifted_heap.h());
|
||||
|
||||
self.unify(a1, lh_len);
|
||||
@@ -1350,7 +1352,7 @@ impl MachineState {
|
||||
};
|
||||
}
|
||||
&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 {
|
||||
Addr::Usize(old_b) | Addr::CutPoint(old_b) => {
|
||||
@@ -1400,7 +1402,7 @@ impl MachineState {
|
||||
};
|
||||
}
|
||||
&SystemClauseType::FetchGlobalVarWithOffset => {
|
||||
let key = self[temp_v!(1)].clone();
|
||||
let key = self[temp_v!(1)];
|
||||
|
||||
let key = match self.store(self.deref(key)) {
|
||||
Addr::Con(h) if self.heap.atom_at(h) => {
|
||||
@@ -1428,7 +1430,7 @@ impl MachineState {
|
||||
*offset = Some(h);
|
||||
}
|
||||
Some((_, Some(h))) => {
|
||||
let offset = self[temp_v!(3)].clone();
|
||||
let offset = self[temp_v!(3)];
|
||||
|
||||
self.unify(offset, Addr::Usize(*h));
|
||||
|
||||
@@ -1445,7 +1447,7 @@ impl MachineState {
|
||||
let mut iter = parsing_stream(current_input_stream.clone());
|
||||
let result = iter.next();
|
||||
|
||||
let a1 = self[temp_v!(1)].clone();
|
||||
let a1 = self[temp_v!(1)];
|
||||
|
||||
match result {
|
||||
Some(Ok(b)) => {
|
||||
@@ -1559,7 +1561,7 @@ impl MachineState {
|
||||
};
|
||||
}
|
||||
&SystemClauseType::HeadIsDynamic => {
|
||||
let head = self[temp_v!(1)].clone();
|
||||
let head = self[temp_v!(1)];
|
||||
|
||||
self.fail = !match self.store(self.deref(head)) {
|
||||
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) {
|
||||
match 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 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);
|
||||
} else {
|
||||
@@ -2416,7 +2418,7 @@ impl MachineState {
|
||||
),
|
||||
);
|
||||
|
||||
let target = self[temp_v!(1)].clone();
|
||||
let target = self[temp_v!(1)];
|
||||
|
||||
self.unify(target, module);
|
||||
}
|
||||
@@ -3008,12 +3010,12 @@ impl MachineState {
|
||||
self.reset_block(addr);
|
||||
}
|
||||
&SystemClauseType::ResetContinuationMarker => {
|
||||
let h = self.heap.h();
|
||||
|
||||
self[temp_v!(3)] = self.heap.to_unifiable(
|
||||
HeapCellValue::Atom(clause_name!("none"), None)
|
||||
);
|
||||
|
||||
let h = self.heap.h();
|
||||
|
||||
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
|
||||
self[temp_v!(4)] = Addr::HeapCell(h);
|
||||
}
|
||||
@@ -3262,7 +3264,7 @@ impl MachineState {
|
||||
);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -304,7 +304,8 @@ impl<'a> TermStream<'a> {
|
||||
}
|
||||
|
||||
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 mut printer = HCPrinter::from_heap_locs(&self, op_dir, output);
|
||||
let mut max_var_length = 0;
|
||||
@@ -316,11 +317,13 @@ impl MachineState {
|
||||
printer.quoted = true;
|
||||
printer.numbervars = true;
|
||||
|
||||
// the purpose of the offset is to avoid clashes with variable names that might
|
||||
// occur after the addresses in the expanded term are substituted with the variable
|
||||
// names in the pre-expansion term. This formula ensures that all generated "numbervars"-
|
||||
// style variable names will be longer than the keys of the var_dict, and therefore
|
||||
// not equal to any of them.
|
||||
// the purpose of the offset is to avoid clashes with variable
|
||||
// names that might occur after the addresses in the expanded
|
||||
// term are substituted with the variable names in the
|
||||
// pre-expansion term. This formula ensures that all generated
|
||||
// "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.print_strings_as_strs = true;
|
||||
printer.drop_toplevel_spec();
|
||||
@@ -334,8 +337,8 @@ impl MachineState {
|
||||
}
|
||||
|
||||
// reset the machine, but keep the heap contents as they were.
|
||||
// this prevents clashes between underscored variable names
|
||||
// in the same query.
|
||||
// this prevents clashes between underscored variable names in the
|
||||
// same query.
|
||||
fn reset_with_heap_preservation(&mut self) {
|
||||
let heap = self.heap.take();
|
||||
self.reset();
|
||||
@@ -359,7 +362,9 @@ impl MachineState {
|
||||
wam.code_repo.cached_query = code;
|
||||
|
||||
self.cp = LocalCodePtr::TopLevel(0, 0);
|
||||
|
||||
self.at_end_of_expansion = false;
|
||||
self.flags.double_quotes = DoubleQuotes::Chars;
|
||||
|
||||
self.query_stepper(
|
||||
&mut wam.indices,
|
||||
|
||||
@@ -112,16 +112,6 @@ macro_rules! functor_term {
|
||||
(number($e:expr), $arity:expr, $aux_lens:expr, $addendum:ident) => (
|
||||
$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) => (
|
||||
HeapCellValue::Integer(Rc::new(Integer::from($e)))
|
||||
);
|
||||
@@ -148,9 +138,6 @@ macro_rules! from_constant {
|
||||
&Constant::CharCode(c) => {
|
||||
HeapCellValue::Addr(Addr::CharCode(c))
|
||||
}
|
||||
&Constant::CutPoint(cp) => {
|
||||
HeapCellValue::Addr(Addr::CutPoint(cp))
|
||||
}
|
||||
&Constant::Integer(ref n) => {
|
||||
HeapCellValue::Integer(n.clone())
|
||||
}
|
||||
|
||||
@@ -153,7 +153,8 @@ pub struct TermWriteResult {
|
||||
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 mut queue = SubtermDeque::new();
|
||||
@@ -188,13 +189,13 @@ pub(crate) fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) ->
|
||||
continue;
|
||||
}
|
||||
}
|
||||
&TermRef::AnonVar(Level::Root) | &TermRef::Constant(Level::Root, ..) => {
|
||||
let value = HeapCellValue::Addr(term.as_addr(&mut machine_st.heap, h));
|
||||
machine_st.heap.push(value);
|
||||
&TermRef::AnonVar(Level::Root) | &TermRef::Constant(Level::Root, ..)
|
||||
| &TermRef::Var(Level::Root, ..) => {
|
||||
let addr = term.as_addr(&mut machine_st.heap, h);
|
||||
|
||||
if !addr.is_heap_bound() {
|
||||
machine_st.heap.push(HeapCellValue::Addr(addr));
|
||||
}
|
||||
&TermRef::Var(Level::Root, ..) => {
|
||||
let value = HeapCellValue::Addr(term.as_addr(&mut machine_st.heap, h));
|
||||
machine_st.heap.push(value);
|
||||
}
|
||||
&TermRef::AnonVar(_) => {
|
||||
if let Some((arity, site_h)) = queue.pop_front() {
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
).
|
||||
|
||||
'$submit_query_and_print_results'(Term0, VarList) :-
|
||||
write('oh brother'), nl,
|
||||
( expand_goals(Term0, Term) -> true
|
||||
; Term0 = Term
|
||||
),
|
||||
|
||||
@@ -158,8 +158,10 @@ impl fmt::Display for HeapCellValue {
|
||||
&HeapCellValue::NamedStr(arity, ref name, None) => {
|
||||
write!(f, "{}/{}", name.as_str(), arity)
|
||||
}
|
||||
&HeapCellValue::PartialString(ref pstr) => {
|
||||
write!(f, "pstr ( buf: 0x{:x} )", (pstr as *const _) as usize)
|
||||
&HeapCellValue::PartialString(ref pstr, has_tail) => {
|
||||
write!(f, "pstr ( buf: 0x{:x}, has_tail({}) )",
|
||||
(pstr as *const _) as usize,
|
||||
has_tail)
|
||||
}
|
||||
&HeapCellValue::Stream(ref stream) => {
|
||||
write!(f, "$stream({})", stream.as_ptr() as usize)
|
||||
|
||||
@@ -23,6 +23,6 @@ test_queries_on_facts :-
|
||||
retract(p(_,_,_)),
|
||||
assertz(p(Z, h(Z, W), f(W))),
|
||||
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).
|
||||
|
||||
Reference in New Issue
Block a user