remove pstr_vec
This commit is contained in:
@@ -89,7 +89,7 @@ const INLINED_ATOM_MAX_LEN: usize = 6;
|
|||||||
fn static_string_index(string: &str, index: usize) -> u64 {
|
fn static_string_index(string: &str, index: usize) -> u64 {
|
||||||
if 0 < string.len() && string.len() <= INLINED_ATOM_MAX_LEN {
|
if 0 < string.len() && string.len() <= INLINED_ATOM_MAX_LEN {
|
||||||
let mut string_buf: [u8; 8] = [0u8; 8];
|
let mut string_buf: [u8; 8] = [0u8; 8];
|
||||||
string_buf[.. string.len()].copy_from_slice(string.as_bytes());
|
string_buf[..string.len()].copy_from_slice(string.as_bytes());
|
||||||
(u64::from_le_bytes(string_buf) << 1) | 1
|
(u64::from_le_bytes(string_buf) << 1) | 1
|
||||||
} else {
|
} else {
|
||||||
(index << 1) as u64
|
(index << 1) as u64
|
||||||
@@ -165,22 +165,26 @@ pub fn index_static_strings(instruction_rs_path: &std::path::Path) -> TokenStrea
|
|||||||
let mut static_strs = vec![];
|
let mut static_strs = vec![];
|
||||||
let mut static_str_indices = vec![];
|
let mut static_str_indices = vec![];
|
||||||
|
|
||||||
let indices: Vec<u64> = visitor.static_strs.iter().map(|string| {
|
let indices: Vec<u64> = visitor
|
||||||
let index = static_string_index(string, static_strs.len());
|
.static_strs
|
||||||
|
.iter()
|
||||||
|
.map(|string| {
|
||||||
|
let index = static_string_index(string, static_strs.len());
|
||||||
|
|
||||||
static_str_keys.push(string);
|
static_str_keys.push(string);
|
||||||
|
|
||||||
if index & 1 == 1 {
|
if index & 1 == 1 {
|
||||||
index
|
index
|
||||||
} else {
|
} else {
|
||||||
static_str_indices.push(index);
|
static_str_indices.push(index);
|
||||||
static_strs.push(string);
|
static_strs.push(string);
|
||||||
index
|
index
|
||||||
}
|
}
|
||||||
}).collect();
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
let static_strs_len = static_strs.len(); // visitor.static_strs.len();
|
let static_strs_len = static_strs.len(); // visitor.static_strs.len();
|
||||||
//let static_strs: &Vec<_> = &visitor.static_strs.into_iter().collect();
|
//let static_strs: &Vec<_> = &visitor.static_strs.into_iter().collect();
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
static STRINGS: [&str; #static_strs_len] = [
|
static STRINGS: [&str; #static_strs_len] = [
|
||||||
|
|||||||
@@ -479,7 +479,6 @@ impl Div<Number> for Number {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl PartialEq for Number {
|
impl PartialEq for Number {
|
||||||
fn eq(&self, rhs: &Self) -> bool {
|
fn eq(&self, rhs: &Self) -> bool {
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
@@ -563,7 +562,6 @@ impl PartialOrd for Number {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Ord for Number {
|
impl Ord for Number {
|
||||||
fn cmp(&self, rhs: &Number) -> Ordering {
|
fn cmp(&self, rhs: &Number) -> Ordering {
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ impl AtomCell {
|
|||||||
debug_assert!(string.len() <= INLINED_ATOM_MAX_LEN);
|
debug_assert!(string.len() <= INLINED_ATOM_MAX_LEN);
|
||||||
|
|
||||||
let mut string_buf: [u8; 8] = [0u8; 8];
|
let mut string_buf: [u8; 8] = [0u8; 8];
|
||||||
string_buf[.. string.len()].copy_from_slice(string.as_bytes());
|
string_buf[..string.len()].copy_from_slice(string.as_bytes());
|
||||||
let encoding = u64::from_le_bytes(string_buf);
|
let encoding = u64::from_le_bytes(string_buf);
|
||||||
|
|
||||||
AtomCell::new()
|
AtomCell::new()
|
||||||
@@ -80,7 +80,7 @@ impl AtomCell {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_char_inlined(c: char) -> Self {
|
pub fn new_char_inlined(c: char) -> Self {
|
||||||
let mut char_buf = [0u8;8];
|
let mut char_buf = [0u8; 8];
|
||||||
c.encode_utf8(&mut char_buf);
|
c.encode_utf8(&mut char_buf);
|
||||||
|
|
||||||
let encoding = u64::from_le_bytes(char_buf);
|
let encoding = u64::from_le_bytes(char_buf);
|
||||||
@@ -109,7 +109,9 @@ impl AtomCell {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_name(self) -> Atom {
|
pub fn get_name(self) -> Atom {
|
||||||
Atom { index: (self.name() << 1) | self.is_inlined() as u64 }
|
Atom {
|
||||||
|
index: (self.name() << 1) | self.is_inlined() as u64,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -216,21 +218,22 @@ impl Hash for Atom {
|
|||||||
|
|
||||||
pub enum AtomString<'a> {
|
pub enum AtomString<'a> {
|
||||||
Static(&'a str),
|
Static(&'a str),
|
||||||
Inlined([u8;8]),
|
Inlined([u8; 8]),
|
||||||
Dynamic(AtomTableRef<str>),
|
Dynamic(AtomTableRef<str>),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inlined_to_str<'a>(bytes: &'a [u8;8]) -> &'a str {
|
fn inlined_to_str<'a>(bytes: &'a [u8; 8]) -> &'a str {
|
||||||
// allow the '\0\' atom to be represented as the 0-valued inlined atom
|
// allow the '\0\' atom to be represented as the 0-valued inlined atom
|
||||||
let slice_len = if bytes[0] == 0 {
|
let slice_len = if bytes[0] == 0 {
|
||||||
1
|
1
|
||||||
} else {
|
} else {
|
||||||
bytes.iter().position(|&b| b == 0u8).unwrap_or(INLINED_ATOM_MAX_LEN)
|
bytes
|
||||||
|
.iter()
|
||||||
|
.position(|&b| b == 0u8)
|
||||||
|
.unwrap_or(INLINED_ATOM_MAX_LEN)
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe { str::from_utf8_unchecked(&bytes[..slice_len]) }
|
||||||
str::from_utf8_unchecked(&bytes[..slice_len])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for AtomString<'_> {
|
impl std::fmt::Debug for AtomString<'_> {
|
||||||
|
|||||||
164
src/codegen.rs
164
src/codegen.rs
@@ -295,8 +295,10 @@ impl DebrayAllocator {
|
|||||||
self.mark_var::<QueryInstruction>(var_num, Level::Shallow, context, code);
|
self.mark_var::<QueryInstruction>(var_num, Level::Shallow, context, code);
|
||||||
temp_v!(arg)
|
temp_v!(arg)
|
||||||
} else {
|
} else {
|
||||||
if let VarAlloc::Perm { allocation: PermVarAllocation::Pending, .. } =
|
if let VarAlloc::Perm {
|
||||||
&self.var_data.records[var_num].allocation
|
allocation: PermVarAllocation::Pending,
|
||||||
|
..
|
||||||
|
} = &self.var_data.records[var_num].allocation
|
||||||
{
|
{
|
||||||
self.mark_var::<QueryInstruction>(var_num, Level::Shallow, context, code);
|
self.mark_var::<QueryInstruction>(var_num, Level::Shallow, context, code);
|
||||||
} else {
|
} else {
|
||||||
@@ -337,22 +339,16 @@ impl<'a> AddToFreeList<'a, QueryInstruction> for CodeGenerator {
|
|||||||
fn add_index_ptr<'a, Target: crate::targets::CompilationTarget<'a>>(
|
fn add_index_ptr<'a, Target: crate::targets::CompilationTarget<'a>>(
|
||||||
index_ptrs: &IndexMap<usize, CodeIndex, FxBuildHasher>,
|
index_ptrs: &IndexMap<usize, CodeIndex, FxBuildHasher>,
|
||||||
heap: &Heap,
|
heap: &Heap,
|
||||||
arity: usize,
|
|
||||||
heap_loc: usize,
|
heap_loc: usize,
|
||||||
) -> Option<Instruction> {
|
) -> Option<Instruction> {
|
||||||
match fetch_index_ptr(heap, arity, heap_loc) {
|
if let Some(index_ptr) = index_ptrs.get(&heap_loc) {
|
||||||
Some(index_ptr) => {
|
let subterm = HeapCellValue::from(*index_ptr);
|
||||||
|
return Some(Target::constant_subterm(subterm));
|
||||||
|
} else if !heap[heap_loc.saturating_sub(1)].get_mark_bit() {
|
||||||
|
if let Some(index_ptr) = fetch_index_ptr(heap, heap_loc) {
|
||||||
let subterm = HeapCellValue::from(index_ptr);
|
let subterm = HeapCellValue::from(index_ptr);
|
||||||
return Some(Target::constant_subterm(subterm));
|
return Some(Target::constant_subterm(subterm));
|
||||||
}
|
}
|
||||||
None => {
|
|
||||||
// if Level::Shallow == lvl {
|
|
||||||
if let Some(index_ptr) = index_ptrs.get(&heap_loc) {
|
|
||||||
let subterm = HeapCellValue::from(*index_ptr);
|
|
||||||
return Some(Target::constant_subterm(subterm));
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
@@ -495,23 +491,28 @@ impl CodeGenerator {
|
|||||||
let (heap_loc, _) = subterm_index(iter.deref(), heap_loc);
|
let (heap_loc, _) = subterm_index(iter.deref(), heap_loc);
|
||||||
|
|
||||||
if arity == 0 {
|
if arity == 0 {
|
||||||
if let Some(instr) = add_index_ptr::<Target>(index_ptrs, &iter, arity, heap_loc) {
|
if let Some(instr) = add_index_ptr::<Target>(index_ptrs, &iter, heap_loc) {
|
||||||
let r = self.marker.mark_non_var::<Target>(lvl, heap_loc, context, &mut target);
|
let r = self.marker.mark_non_var::<Target>(lvl, heap_loc, context, &mut target);
|
||||||
target.push_back(Target::to_structure(lvl, name, 0, r));
|
|
||||||
target.push_back(instr);
|
target.push_back(instr);
|
||||||
|
target.push_back(Target::to_structure(lvl, name, 0, r));
|
||||||
} else if lvl == Level::Shallow {
|
} else if lvl == Level::Shallow {
|
||||||
let r = self.marker.mark_non_var::<Target>(lvl, heap_loc, context, &mut target);
|
let r = self.marker.mark_non_var::<Target>(lvl, heap_loc, context, &mut target);
|
||||||
target.push_back(Target::to_constant(lvl, atom_as_cell!(name), r));
|
target.push_back(Target::to_constant(lvl, atom_as_cell!(name), r));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let r = self.marker.mark_non_var::<Target>(lvl, heap_loc, context, &mut target);
|
let r = self.marker.mark_non_var::<Target>(lvl, heap_loc, context, &mut target);
|
||||||
target.push_back(Target::to_structure(lvl, name, arity, r));
|
|
||||||
|
|
||||||
<CodeGenerator as AddToFreeList<'a, Target>>::add_term_to_free_list(
|
<CodeGenerator as AddToFreeList<'a, Target>>::add_term_to_free_list(
|
||||||
self,
|
self,
|
||||||
r,
|
r,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if let Some(instr) = add_index_ptr::<Target>(index_ptrs, &iter, heap_loc) {
|
||||||
|
target.push_back(instr);
|
||||||
|
}
|
||||||
|
|
||||||
|
target.push_back(Target::to_structure(lvl, name, arity, r));
|
||||||
|
|
||||||
let free_list_regs: Vec<_> = (heap_loc + 1 ..= heap_loc + arity)
|
let free_list_regs: Vec<_> = (heap_loc + 1 ..= heap_loc + arity)
|
||||||
.map(|subterm_loc| {
|
.map(|subterm_loc| {
|
||||||
let (subterm_loc, subterm) = subterm_index(iter.deref(), subterm_loc);
|
let (subterm_loc, subterm) = subterm_index(iter.deref(), subterm_loc);
|
||||||
@@ -522,10 +523,6 @@ impl CodeGenerator {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if let Some(instr) = add_index_ptr::<Target>(index_ptrs, &iter, arity, heap_loc) {
|
|
||||||
target.push_back(instr);
|
|
||||||
}
|
|
||||||
|
|
||||||
for r_opt in free_list_regs {
|
for r_opt in free_list_regs {
|
||||||
if let Some(r) = r_opt {
|
if let Some(r) = r_opt {
|
||||||
<CodeGenerator as AddToFreeList<'a, Target>>::add_subterm_to_free_list(
|
<CodeGenerator as AddToFreeList<'a, Target>>::add_subterm_to_free_list(
|
||||||
@@ -583,11 +580,11 @@ impl CodeGenerator {
|
|||||||
let heap_loc = iter.focus().value() as usize;
|
let heap_loc = iter.focus().value() as usize;
|
||||||
let (heap_loc, _) = subterm_index(iter.deref(), heap_loc);
|
let (heap_loc, _) = subterm_index(iter.deref(), heap_loc);
|
||||||
let r = self.marker.mark_non_var::<Target>(lvl, heap_loc, context, &mut target);
|
let r = self.marker.mark_non_var::<Target>(lvl, heap_loc, context, &mut target);
|
||||||
let (pstr_str, tail_loc) = iter.scan_slice_to_str(pstr_loc);
|
let HeapStringScan { string, tail_idx } = iter.scan_slice_to_str(pstr_loc);
|
||||||
|
|
||||||
target.push_back(Target::to_pstr(lvl, Rc::new(pstr_str.to_owned()), r));
|
target.push_back(Target::to_pstr(lvl, Rc::new(string.to_owned()), r));
|
||||||
|
|
||||||
let (tail_loc, tail) = subterm_index(iter.deref(), tail_loc);
|
let (tail_loc, tail) = subterm_index(iter.deref(), tail_idx);
|
||||||
self.subterm_to_instr::<Target>(
|
self.subterm_to_instr::<Target>(
|
||||||
tail, tail_loc, context, index_ptrs, &mut target,
|
tail, tail_loc, context, index_ptrs, &mut target,
|
||||||
);
|
);
|
||||||
@@ -676,12 +673,11 @@ impl CodeGenerator {
|
|||||||
&InlinedClauseType::CompareNumber(mut cmp) => {
|
&InlinedClauseType::CompareNumber(mut cmp) => {
|
||||||
self.marker.reset_arg(2);
|
self.marker.reset_arg(2);
|
||||||
|
|
||||||
let (mut lcode, at_1) =
|
let (mut lcode, at_1) = if let Some(r) = variable_marker(&mut self.marker) {
|
||||||
if let Some(r) = variable_marker(&mut self.marker) {
|
(CodeDeque::default(), Some(ArithmeticTerm::Reg(r)))
|
||||||
(CodeDeque::default(), Some(ArithmeticTerm::Reg(r)))
|
} else {
|
||||||
} else {
|
self.compile_arith_expr(terms, first_arg_loc, 1, context, 1)?
|
||||||
self.compile_arith_expr(terms, first_arg_loc, 1, context, 1)?
|
};
|
||||||
};
|
|
||||||
|
|
||||||
let (mut rcode, at_2) =
|
let (mut rcode, at_2) =
|
||||||
self.compile_arith_expr(terms, first_arg_loc + 1, 2, context, 2)?;
|
self.compile_arith_expr(terms, first_arg_loc + 1, 2, context, 2)?;
|
||||||
@@ -720,41 +716,41 @@ impl CodeGenerator {
|
|||||||
if let Some(r) = variable_marker(&mut self.marker) {
|
if let Some(r) = variable_marker(&mut self.marker) {
|
||||||
instr!("atomic", r)
|
instr!("atomic", r)
|
||||||
} else {
|
} else {
|
||||||
read_heap_cell!(first_arg,
|
read_heap_cell!(first_arg,
|
||||||
(HeapCellValueTag::Fixnum |
|
(HeapCellValueTag::Fixnum |
|
||||||
HeapCellValueTag::F64) => {
|
HeapCellValueTag::F64) => {
|
||||||
instr!("$succeed")
|
instr!("$succeed")
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Cons, cons_ptr) => {
|
(HeapCellValueTag::Cons, cons_ptr) => {
|
||||||
match cons_ptr.get_tag() {
|
match cons_ptr.get_tag() {
|
||||||
ArenaHeaderTag::Integer | ArenaHeaderTag::Rational => {
|
ArenaHeaderTag::Integer | ArenaHeaderTag::Rational => {
|
||||||
instr!("$succeed")
|
instr!("$succeed")
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
instr!("$fail")
|
instr!("$fail")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Atom, (_name, arity)) => {
|
(HeapCellValueTag::Atom, (_name, arity)) => {
|
||||||
if arity == 0 {
|
if arity == 0 {
|
||||||
instr!("$succeed")
|
instr!("$succeed")
|
||||||
} else {
|
} else {
|
||||||
instr!("$fail")
|
instr!("$fail")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Lis
|
(HeapCellValueTag::Lis
|
||||||
| HeapCellValueTag::Str
|
| HeapCellValueTag::Str
|
||||||
| HeapCellValueTag::PStrLoc) => {
|
| HeapCellValueTag::PStrLoc) => {
|
||||||
instr!("$fail")
|
instr!("$fail")
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if first_arg.is_constant() {
|
if first_arg.is_constant() {
|
||||||
instr!("$succeed")
|
instr!("$succeed")
|
||||||
} else {
|
} else {
|
||||||
instr!("$fail")
|
instr!("$fail")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InlinedClauseType::IsCompound(..) => {
|
InlinedClauseType::IsCompound(..) => {
|
||||||
@@ -860,7 +856,7 @@ impl CodeGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
InlinedClauseType::IsVar(..) => {
|
InlinedClauseType::IsVar(..) => {
|
||||||
self.marker.reset_arg(1);
|
self.marker.reset_arg(1);
|
||||||
|
|
||||||
@@ -871,7 +867,7 @@ impl CodeGenerator {
|
|||||||
} else {
|
} else {
|
||||||
instr!("$fail")
|
instr!("$fail")
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// inlined predicates are never counted, so this overrides nothing.
|
// inlined predicates are never counted, so this overrides nothing.
|
||||||
@@ -901,8 +897,7 @@ impl CodeGenerator {
|
|||||||
) -> Result<(), CompilationError> {
|
) -> Result<(), CompilationError> {
|
||||||
macro_rules! compile_expr {
|
macro_rules! compile_expr {
|
||||||
($self:expr, $terms:expr, $context:expr, $code:expr) => {{
|
($self:expr, $terms:expr, $context:expr, $code:expr) => {{
|
||||||
let (acode, at) =
|
let (acode, at) = $self.compile_arith_expr($terms, term_loc + 2, 1, $context, 2)?;
|
||||||
$self.compile_arith_expr($terms, term_loc + 2, 1, $context, 2)?;
|
|
||||||
$code.extend(acode.into_iter());
|
$code.extend(acode.into_iter());
|
||||||
at
|
at
|
||||||
}};
|
}};
|
||||||
@@ -1067,13 +1062,11 @@ impl CodeGenerator {
|
|||||||
code.push_back(instr!("deallocate"));
|
code.push_back(instr!("deallocate"));
|
||||||
}
|
}
|
||||||
|
|
||||||
code.push_back(
|
code.push_back(if self.marker.in_tail_position {
|
||||||
if self.marker.in_tail_position {
|
instr!("$succeed").into_execute()
|
||||||
instr!("$succeed").into_execute()
|
} else {
|
||||||
} else {
|
instr!("$succeed")
|
||||||
instr!("$succeed")
|
});
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
QueryTerm::Clause(clause) => {
|
QueryTerm::Clause(clause) => {
|
||||||
self.compile_query_line(
|
self.compile_query_line(
|
||||||
@@ -1145,7 +1138,10 @@ impl CodeGenerator {
|
|||||||
|
|
||||||
self.marker.var_data = var_data;
|
self.marker.var_data = var_data;
|
||||||
|
|
||||||
let term = FocusedHeapRefMut { heap, focus: *term_loc };
|
let term = FocusedHeapRefMut {
|
||||||
|
heap,
|
||||||
|
focus: *term_loc,
|
||||||
|
};
|
||||||
let mut code = VecDeque::new();
|
let mut code = VecDeque::new();
|
||||||
|
|
||||||
let head_loc = term.nth_arg(term.focus, 1).unwrap();
|
let head_loc = term.nth_arg(term.focus, 1).unwrap();
|
||||||
@@ -1216,11 +1212,7 @@ impl CodeGenerator {
|
|||||||
let mut stack = Stack::uninitialized();
|
let mut stack = Stack::uninitialized();
|
||||||
let iter = query_iterator::<true>(&mut term.heap, &mut stack, clause.term_loc());
|
let iter = query_iterator::<true>(&mut term.heap, &mut stack, clause.term_loc());
|
||||||
|
|
||||||
let query = self.compile_target::<QueryInstruction, _>(
|
let query = self.compile_target::<QueryInstruction, _>(iter, &clause.code_indices, context);
|
||||||
iter,
|
|
||||||
&clause.code_indices,
|
|
||||||
context,
|
|
||||||
);
|
|
||||||
|
|
||||||
code.extend(query);
|
code.extend(query);
|
||||||
self.add_call(code, clause.ct.to_instr(), clause.call_policy);
|
self.add_call(code, clause.ct.to_instr(), clause.call_policy);
|
||||||
@@ -1342,20 +1334,14 @@ impl CodeGenerator {
|
|||||||
skip_stub_try_me_else = !self.settings.is_dynamic();
|
skip_stub_try_me_else = !self.settings.is_dynamic();
|
||||||
}
|
}
|
||||||
|
|
||||||
let arg = clause.args(heap)
|
let arg = clause.args(heap).map(|r| heap[r.start() + optimal_index]);
|
||||||
.map(|r| heap[r.start() + optimal_index]);
|
|
||||||
|
|
||||||
if let Some(arg) = arg {
|
if let Some(arg) = arg {
|
||||||
let index = code.len();
|
let index = code.len();
|
||||||
|
|
||||||
if clauses_len > 1 || self.settings.is_extensible {
|
if clauses_len > 1 || self.settings.is_extensible {
|
||||||
let arg = heap_bound_store(heap, heap_bound_deref(heap, arg));
|
let arg = heap_bound_store(heap, heap_bound_deref(heap, arg));
|
||||||
code_offsets.index_term(
|
code_offsets.index_term(heap, arg, index, &mut clause_index_info);
|
||||||
heap,
|
|
||||||
arg,
|
|
||||||
index,
|
|
||||||
&mut clause_index_info,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -172,7 +172,9 @@ impl DebrayAllocator {
|
|||||||
|
|
||||||
for var_num in subsumed_hits {
|
for var_num in subsumed_hits {
|
||||||
match &mut self.var_data.records[var_num].allocation {
|
match &mut self.var_data.records[var_num].allocation {
|
||||||
VarAlloc::Perm { ref mut allocation, .. } => {
|
VarAlloc::Perm {
|
||||||
|
ref mut allocation, ..
|
||||||
|
} => {
|
||||||
if let PermVarAllocation::Done {
|
if let PermVarAllocation::Done {
|
||||||
shallow_safety,
|
shallow_safety,
|
||||||
deep_safety,
|
deep_safety,
|
||||||
@@ -233,7 +235,7 @@ impl DebrayAllocator {
|
|||||||
let num_occurrences = self.var_data.records[var_num].num_occurrences;
|
let num_occurrences = self.var_data.records[var_num].num_occurrences;
|
||||||
|
|
||||||
match &mut self.var_data.records[var_num].allocation {
|
match &mut self.var_data.records[var_num].allocation {
|
||||||
VarAlloc::Perm { allocation, ..} => {
|
VarAlloc::Perm { allocation, .. } => {
|
||||||
let shallow_safety = VarSafetyStatus::needed_if(
|
let shallow_safety = VarSafetyStatus::needed_if(
|
||||||
shallow_safety.contains(var_num),
|
shallow_safety.contains(var_num),
|
||||||
branch_designator,
|
branch_designator,
|
||||||
@@ -514,10 +516,12 @@ impl DebrayAllocator {
|
|||||||
self.perm_free_list.pop_front();
|
self.perm_free_list.pop_front();
|
||||||
|
|
||||||
match &mut self.var_data.records[var_num].allocation {
|
match &mut self.var_data.records[var_num].allocation {
|
||||||
VarAlloc::Perm { reg: p, allocation: PermVarAllocation::Pending }
|
VarAlloc::Perm {
|
||||||
if *p > 0 => {
|
reg: p,
|
||||||
return Some(std::mem::replace(p, 0));
|
allocation: PermVarAllocation::Pending,
|
||||||
}
|
} if *p > 0 => {
|
||||||
|
return Some(std::mem::replace(p, 0));
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -543,11 +547,12 @@ impl DebrayAllocator {
|
|||||||
|
|
||||||
match &mut self.var_data.records[var_num].allocation {
|
match &mut self.var_data.records[var_num].allocation {
|
||||||
VarAlloc::Perm {
|
VarAlloc::Perm {
|
||||||
allocation: PermVarAllocation::Done {
|
allocation:
|
||||||
deep_safety,
|
PermVarAllocation::Done {
|
||||||
shallow_safety,
|
deep_safety,
|
||||||
..
|
shallow_safety,
|
||||||
},
|
..
|
||||||
|
},
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
*deep_safety = VarSafetyStatus::unneeded(branch_designator);
|
*deep_safety = VarSafetyStatus::unneeded(branch_designator);
|
||||||
@@ -568,11 +573,12 @@ impl DebrayAllocator {
|
|||||||
|
|
||||||
match &mut self.var_data.records[var_num].allocation {
|
match &mut self.var_data.records[var_num].allocation {
|
||||||
VarAlloc::Perm {
|
VarAlloc::Perm {
|
||||||
allocation: PermVarAllocation::Done {
|
allocation:
|
||||||
deep_safety,
|
PermVarAllocation::Done {
|
||||||
shallow_safety,
|
deep_safety,
|
||||||
..
|
shallow_safety,
|
||||||
},
|
..
|
||||||
|
},
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
// GetVariable in head chunk is considered safe.
|
// GetVariable in head chunk is considered safe.
|
||||||
@@ -612,10 +618,11 @@ impl DebrayAllocator {
|
|||||||
|
|
||||||
match &mut self.var_data.records[var_num].allocation {
|
match &mut self.var_data.records[var_num].allocation {
|
||||||
VarAlloc::Perm {
|
VarAlloc::Perm {
|
||||||
allocation: PermVarAllocation::Done {
|
allocation:
|
||||||
ref mut shallow_safety,
|
PermVarAllocation::Done {
|
||||||
..
|
ref mut shallow_safety,
|
||||||
},
|
..
|
||||||
|
},
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if !self.in_tail_position
|
if !self.in_tail_position
|
||||||
@@ -648,10 +655,11 @@ impl DebrayAllocator {
|
|||||||
|
|
||||||
match &mut self.var_data.records[var_num].allocation {
|
match &mut self.var_data.records[var_num].allocation {
|
||||||
VarAlloc::Perm {
|
VarAlloc::Perm {
|
||||||
allocation: PermVarAllocation::Done {
|
allocation:
|
||||||
ref mut deep_safety,
|
PermVarAllocation::Done {
|
||||||
..
|
ref mut deep_safety,
|
||||||
},
|
..
|
||||||
|
},
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if self
|
if self
|
||||||
@@ -921,10 +929,7 @@ impl Allocator for DebrayAllocator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn reset_at_head(&mut self, heap: &mut Heap, head_loc: usize) {
|
fn reset_at_head(&mut self, heap: &mut Heap, head_loc: usize) {
|
||||||
let head_cell = heap_bound_store(
|
let head_cell = heap_bound_store(heap, heap_bound_deref(heap, heap_loc_as_cell!(head_loc)));
|
||||||
heap,
|
|
||||||
heap_bound_deref(heap, heap_loc_as_cell!(head_loc)),
|
|
||||||
);
|
|
||||||
|
|
||||||
read_heap_cell!(head_cell,
|
read_heap_cell!(head_cell,
|
||||||
(HeapCellValueTag::Str, s) => {
|
(HeapCellValueTag::Str, s) => {
|
||||||
@@ -933,7 +938,9 @@ impl Allocator for DebrayAllocator {
|
|||||||
self.reset_arg(arity);
|
self.reset_arg(arity);
|
||||||
self.arity = arity;
|
self.arity = arity;
|
||||||
|
|
||||||
for (idx, arg) in heap.splice(s+1 ..= s+arity).enumerate() {
|
for (c_idx, heap_idx) in (s+1 ..= s+arity).enumerate() {
|
||||||
|
let arg = heap[heap_idx];
|
||||||
|
|
||||||
if arg.is_var() {
|
if arg.is_var() {
|
||||||
let var = heap_bound_store(
|
let var = heap_bound_store(
|
||||||
heap,
|
heap,
|
||||||
@@ -953,11 +960,11 @@ impl Allocator for DebrayAllocator {
|
|||||||
let r = self.get_var_binding(var_num);
|
let r = self.get_var_binding(var_num);
|
||||||
|
|
||||||
if !r.is_perm() && r.reg_num() == 0 {
|
if !r.is_perm() && r.reg_num() == 0 {
|
||||||
self.in_use.insert(idx + 1);
|
self.in_use.insert(c_idx + 1);
|
||||||
self.shallow_temp_mappings.insert(idx + 1, var_num);
|
self.shallow_temp_mappings.insert(c_idx + 1, var_num);
|
||||||
self.var_data.records[var_num]
|
self.var_data.records[var_num]
|
||||||
.allocation
|
.allocation
|
||||||
.set_register(idx + 1);
|
.set_register(c_idx + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VarPtr::Anon => {}
|
VarPtr::Anon => {}
|
||||||
|
|||||||
18
src/forms.rs
18
src/forms.rs
@@ -1,7 +1,7 @@
|
|||||||
use crate::arena::*;
|
use crate::arena::*;
|
||||||
use crate::atom_table::*;
|
use crate::atom_table::*;
|
||||||
use crate::instructions::*;
|
|
||||||
use crate::functor_macro::*;
|
use crate::functor_macro::*;
|
||||||
|
use crate::instructions::*;
|
||||||
use crate::machine::disjuncts::VarData;
|
use crate::machine::disjuncts::VarData;
|
||||||
use crate::machine::heap::*;
|
use crate::machine::heap::*;
|
||||||
// use crate::machine::loader::PredicateQueue;
|
// use crate::machine::loader::PredicateQueue;
|
||||||
@@ -80,8 +80,8 @@ impl GenContext {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn chunk_type(&self) -> ChunkType {
|
pub fn chunk_type(&self) -> ChunkType {
|
||||||
match self {
|
match self {
|
||||||
GenContext::Head => ChunkType::Head,
|
GenContext::Head => ChunkType::Head,
|
||||||
GenContext::Mid(_) => ChunkType::Mid,
|
GenContext::Mid(_) => ChunkType::Mid,
|
||||||
GenContext::Last(_) => ChunkType::Last,
|
GenContext::Last(_) => ChunkType::Last,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,10 @@ impl ChunkType {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ChunkedTerms {
|
pub enum ChunkedTerms {
|
||||||
Branch(Vec<VecDeque<ChunkedTerms>>),
|
Branch(Vec<VecDeque<ChunkedTerms>>),
|
||||||
Chunk { chunk_num: usize, terms: VecDeque<QueryTerm> },
|
Chunk {
|
||||||
|
chunk_num: usize,
|
||||||
|
terms: VecDeque<QueryTerm>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -190,7 +193,8 @@ impl ChunkedTermVec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_gen_context(&self) -> GenContext {
|
pub fn current_gen_context(&self) -> GenContext {
|
||||||
self.current_chunk_type.to_gen_context(self.current_chunk_num)
|
self.current_chunk_type
|
||||||
|
.to_gen_context(self.current_chunk_num)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_chunk_term(&mut self, term: QueryTerm) {
|
pub fn push_chunk_term(&mut self, term: QueryTerm) {
|
||||||
@@ -290,9 +294,7 @@ pub fn clause_predicate_key(heap: &impl SizedHeap, term_loc: usize) -> Option<Pr
|
|||||||
let key_opt = term_predicate_key(heap, term_loc);
|
let key_opt = term_predicate_key(heap, term_loc);
|
||||||
|
|
||||||
if Some((atom!(":-"), 2)) == key_opt {
|
if Some((atom!(":-"), 2)) == key_opt {
|
||||||
term_nth_arg(heap, term_loc, 1).and_then(|arg_loc| {
|
term_nth_arg(heap, term_loc, 1).and_then(|arg_loc| term_predicate_key(heap, arg_loc))
|
||||||
term_predicate_key(heap, arg_loc)
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
key_opt
|
key_opt
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
//! A macro to construct functor terms ready to be written to the WAM
|
||||||
|
//! heap.
|
||||||
|
|
||||||
use crate::atom_table::*;
|
use crate::atom_table::*;
|
||||||
use crate::instructions::IndexingCodePtr;
|
use crate::instructions::IndexingCodePtr;
|
||||||
use crate::machine::heap::Heap;
|
use crate::machine::heap::Heap;
|
||||||
@@ -5,7 +8,7 @@ use crate::parser::ast::Fixnum;
|
|||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum FunctorElement {
|
pub(crate) enum FunctorElement {
|
||||||
AbsoluteCell(HeapCellValue),
|
AbsoluteCell(HeapCellValue),
|
||||||
Cell(HeapCellValue),
|
Cell(HeapCellValue),
|
||||||
InnerFunctor(u64, Vec<FunctorElement>),
|
InnerFunctor(u64, Vec<FunctorElement>),
|
||||||
@@ -190,19 +193,19 @@ pub(crate) fn variadic_functor(
|
|||||||
let num_items = key_value_pairs.len();
|
let num_items = key_value_pairs.len();
|
||||||
|
|
||||||
for (idx, _) in key_value_pairs.iter().enumerate() {
|
for (idx, _) in key_value_pairs.iter().enumerate() {
|
||||||
arg_vec.push(FunctorElement::Cell(str_loc_as_cell!(2 + num_items * 2 + idx)));
|
arg_vec.push(FunctorElement::Cell(str_loc_as_cell!(
|
||||||
|
2 + num_items * 2 + idx
|
||||||
|
)));
|
||||||
arg_vec.push(FunctorElement::Cell(list_loc_as_cell!(5 + idx)));
|
arg_vec.push(FunctorElement::Cell(list_loc_as_cell!(5 + idx)));
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_vec.pop();
|
arg_vec.pop();
|
||||||
arg_vec.push(FunctorElement::Cell(empty_list_as_cell!()));
|
arg_vec.push(FunctorElement::Cell(empty_list_as_cell!()));
|
||||||
|
|
||||||
arg_vec.extend(key_value_pairs
|
arg_vec.extend(key_value_pairs.into_iter().map(|kv_func| {
|
||||||
.into_iter()
|
let inner_functor_size = cell_index!(Heap::compute_functor_byte_size(&kv_func));
|
||||||
.map(|kv_func| {
|
FunctorElement::InnerFunctor(inner_functor_size as u64, kv_func)
|
||||||
let inner_functor_size = cell_index!(Heap::compute_functor_byte_size(&kv_func));
|
}));
|
||||||
FunctorElement::InnerFunctor(inner_functor_size as u64, kv_func)
|
|
||||||
}));
|
|
||||||
|
|
||||||
arg_vec
|
arg_vec
|
||||||
}
|
}
|
||||||
@@ -211,13 +214,15 @@ pub(crate) fn variadic_functor(
|
|||||||
#[allow(unused_parens)]
|
#[allow(unused_parens)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use FunctorElement::*;
|
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
|
use FunctorElement::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn basic_terms() {
|
fn basic_terms() {
|
||||||
let functor = functor!(atom!("first"), [atom_as_cell((atom!("a"))),
|
let functor = functor!(
|
||||||
char_as_cell('c')]);
|
atom!("first"),
|
||||||
|
[atom_as_cell((atom!("a"))), char_as_cell('c')]
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(functor.len(), 3);
|
assert_eq!(functor.len(), 3);
|
||||||
|
|
||||||
@@ -225,10 +230,14 @@ mod tests {
|
|||||||
assert_eq!(functor[1], Cell(atom_as_cell!(atom!("a"))));
|
assert_eq!(functor[1], Cell(atom_as_cell!(atom!("a"))));
|
||||||
assert_eq!(functor[2], Cell(char_as_cell!('c')));
|
assert_eq!(functor[2], Cell(char_as_cell!('c')));
|
||||||
|
|
||||||
let functor = functor!(atom!("second"), [atom_as_cell((atom!("a"))),
|
let functor = functor!(
|
||||||
functor((atom!("b")), [fixnum(1),
|
atom!("second"),
|
||||||
fixnum(2)]),
|
[
|
||||||
char_as_cell('c')]);
|
atom_as_cell((atom!("a"))),
|
||||||
|
functor((atom!("b")), [fixnum(1), fixnum(2)]),
|
||||||
|
char_as_cell('c')
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(functor.len(), 5);
|
assert_eq!(functor.len(), 5);
|
||||||
|
|
||||||
@@ -236,13 +245,20 @@ mod tests {
|
|||||||
assert_eq!(functor[1], Cell(atom_as_cell!(atom!("a"))));
|
assert_eq!(functor[1], Cell(atom_as_cell!(atom!("a"))));
|
||||||
assert_eq!(functor[2], Cell(str_loc_as_cell!(4)));
|
assert_eq!(functor[2], Cell(str_loc_as_cell!(4)));
|
||||||
assert_eq!(functor[3], Cell(char_as_cell!('c')));
|
assert_eq!(functor[3], Cell(char_as_cell!('c')));
|
||||||
assert_eq!(functor[4], InnerFunctor(3, functor!(atom!("b"), [fixnum(1),
|
assert_eq!(
|
||||||
fixnum(2)])));
|
functor[4],
|
||||||
|
InnerFunctor(3, functor!(atom!("b"), [fixnum(1), fixnum(2)]))
|
||||||
|
);
|
||||||
|
|
||||||
let functor = functor!(atom!("third"), [atom_as_cell((atom!("a"))),
|
let functor = functor!(
|
||||||
functor((atom!("b")), [fixnum(1), fixnum(2)]),
|
atom!("third"),
|
||||||
functor((atom!("c")), [fixnum(1), fixnum(2)]),
|
[
|
||||||
char_as_cell('c')]);
|
atom_as_cell((atom!("a"))),
|
||||||
|
functor((atom!("b")), [fixnum(1), fixnum(2)]),
|
||||||
|
functor((atom!("c")), [fixnum(1), fixnum(2)]),
|
||||||
|
char_as_cell('c')
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(functor.len(), 7);
|
assert_eq!(functor.len(), 7);
|
||||||
|
|
||||||
@@ -251,14 +267,25 @@ mod tests {
|
|||||||
assert_eq!(functor[2], Cell(str_loc_as_cell!(5)));
|
assert_eq!(functor[2], Cell(str_loc_as_cell!(5)));
|
||||||
assert_eq!(functor[3], Cell(str_loc_as_cell!(8)));
|
assert_eq!(functor[3], Cell(str_loc_as_cell!(8)));
|
||||||
assert_eq!(functor[4], Cell(char_as_cell!('c')));
|
assert_eq!(functor[4], Cell(char_as_cell!('c')));
|
||||||
assert_eq!(functor[5], InnerFunctor(3, functor!(atom!("b"), [fixnum(1), fixnum(2)])));
|
assert_eq!(
|
||||||
assert_eq!(functor[6], InnerFunctor(3, functor!(atom!("c"), [fixnum(1), fixnum(2)])));
|
functor[5],
|
||||||
|
InnerFunctor(3, functor!(atom!("b"), [fixnum(1), fixnum(2)]))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
functor[6],
|
||||||
|
InnerFunctor(3, functor!(atom!("c"), [fixnum(1), fixnum(2)]))
|
||||||
|
);
|
||||||
|
|
||||||
let functor = functor!(atom!("fourth"), [atom_as_cell((atom!("a"))),
|
let functor = functor!(
|
||||||
functor((atom!("b")), [fixnum(1), fixnum(2)]),
|
atom!("fourth"),
|
||||||
functor((atom!("c")), [fixnum(1)]),
|
[
|
||||||
functor((atom!("d")), [fixnum(453), fixnum(2)]),
|
atom_as_cell((atom!("a"))),
|
||||||
char_as_cell('c')]);
|
functor((atom!("b")), [fixnum(1), fixnum(2)]),
|
||||||
|
functor((atom!("c")), [fixnum(1)]),
|
||||||
|
functor((atom!("d")), [fixnum(453), fixnum(2)]),
|
||||||
|
char_as_cell('c')
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(functor.len(), 9);
|
assert_eq!(functor.len(), 9);
|
||||||
|
|
||||||
@@ -268,14 +295,26 @@ mod tests {
|
|||||||
assert_eq!(functor[3], Cell(str_loc_as_cell!(9)));
|
assert_eq!(functor[3], Cell(str_loc_as_cell!(9)));
|
||||||
assert_eq!(functor[4], Cell(str_loc_as_cell!(11)));
|
assert_eq!(functor[4], Cell(str_loc_as_cell!(11)));
|
||||||
assert_eq!(functor[5], Cell(char_as_cell!('c')));
|
assert_eq!(functor[5], Cell(char_as_cell!('c')));
|
||||||
assert_eq!(functor[6], InnerFunctor(3, functor!(atom!("b"), [fixnum(1), fixnum(2)])));
|
assert_eq!(
|
||||||
assert_eq!(functor[7], InnerFunctor(2, functor!(atom!("c"), [fixnum(1)])));
|
functor[6],
|
||||||
assert_eq!(functor[8], InnerFunctor(3, functor!(atom!("d"), [fixnum(453), fixnum(2)])));
|
InnerFunctor(3, functor!(atom!("b"), [fixnum(1), fixnum(2)]))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
functor[7],
|
||||||
|
InnerFunctor(2, functor!(atom!("c"), [fixnum(1)]))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
functor[8],
|
||||||
|
InnerFunctor(3, functor!(atom!("d"), [fixnum(453), fixnum(2)]))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn basic_terms_in_heap() {
|
fn basic_terms_in_heap() {
|
||||||
let functor = functor!(atom!("first"), [atom_as_cell((atom!("a"))), char_as_cell('b')]);
|
let functor = functor!(
|
||||||
|
atom!("first"),
|
||||||
|
[atom_as_cell((atom!("a"))), char_as_cell('b')]
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(functor.len(), 3);
|
assert_eq!(functor.len(), 3);
|
||||||
|
|
||||||
@@ -291,10 +330,15 @@ mod tests {
|
|||||||
|
|
||||||
heap.truncate(2);
|
heap.truncate(2);
|
||||||
|
|
||||||
let functor = functor!(atom!("second"), [atom_as_cell((atom!("a"))),
|
let functor = functor!(
|
||||||
functor((atom!("b")), [fixnum(1), fixnum(2)]),
|
atom!("second"),
|
||||||
functor((atom!("c")), [fixnum(1), fixnum(2)]),
|
[
|
||||||
char_as_cell('b')]);
|
atom_as_cell((atom!("a"))),
|
||||||
|
functor((atom!("b")), [fixnum(1), fixnum(2)]),
|
||||||
|
functor((atom!("c")), [fixnum(1), fixnum(2)]),
|
||||||
|
char_as_cell('b')
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(functor.len(), 7);
|
assert_eq!(functor.len(), 7);
|
||||||
|
|
||||||
@@ -318,14 +362,24 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn nested_functors() {
|
fn nested_functors() {
|
||||||
let functor = functor!(atom!("first"), [atom_as_cell((atom!("a"))),
|
let functor = functor!(
|
||||||
functor((atom!("d")), [fixnum(1),
|
atom!("first"),
|
||||||
functor((atom!("b")),
|
[
|
||||||
[atom_as_cell((atom!("c"))),
|
atom_as_cell((atom!("a"))),
|
||||||
char_as_cell('c')])]),
|
functor(
|
||||||
functor((atom!("e")), [fixnum(453),
|
(atom!("d")),
|
||||||
fixnum(2)]),
|
[
|
||||||
char_as_cell('b')]);
|
fixnum(1),
|
||||||
|
functor(
|
||||||
|
(atom!("b")),
|
||||||
|
[atom_as_cell((atom!("c"))), char_as_cell('c')]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
functor((atom!("e")), [fixnum(453), fixnum(2)]),
|
||||||
|
char_as_cell('b')
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(functor.len(), 7);
|
assert_eq!(functor.len(), 7);
|
||||||
|
|
||||||
@@ -334,24 +388,47 @@ mod tests {
|
|||||||
assert_eq!(functor[2], Cell(str_loc_as_cell!(5)));
|
assert_eq!(functor[2], Cell(str_loc_as_cell!(5)));
|
||||||
assert_eq!(functor[3], Cell(str_loc_as_cell!(11)));
|
assert_eq!(functor[3], Cell(str_loc_as_cell!(11)));
|
||||||
assert_eq!(functor[4], Cell(char_as_cell!('b')));
|
assert_eq!(functor[4], Cell(char_as_cell!('b')));
|
||||||
assert_eq!(functor[5], InnerFunctor(6, vec![Cell(atom_as_cell!(atom!("d"), 2)),
|
assert_eq!(
|
||||||
Cell(fixnum_as_cell!(Fixnum::build_with(1))),
|
functor[5],
|
||||||
Cell(str_loc_as_cell!(3)),
|
InnerFunctor(
|
||||||
InnerFunctor(3, functor!(atom!("b"), [atom_as_cell((atom!("c"))),
|
6,
|
||||||
char_as_cell('c')]))]));
|
vec![
|
||||||
assert_eq!(functor[6], InnerFunctor(3, functor!(atom!("e"), [fixnum(453),
|
Cell(atom_as_cell!(atom!("d"), 2)),
|
||||||
fixnum(2)])));
|
Cell(fixnum_as_cell!(Fixnum::build_with(1))),
|
||||||
|
Cell(str_loc_as_cell!(3)),
|
||||||
|
InnerFunctor(
|
||||||
|
3,
|
||||||
|
functor!(atom!("b"), [atom_as_cell((atom!("c"))), char_as_cell('c')])
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
functor[6],
|
||||||
|
InnerFunctor(3, functor!(atom!("e"), [fixnum(453), fixnum(2)]))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn nested_functors_in_heap() {
|
fn nested_functors_in_heap() {
|
||||||
let functor = functor!(atom!("first"), [atom_as_cell((atom!("a"))),
|
let functor = functor!(
|
||||||
functor((atom!("second")), [fixnum(1),
|
atom!("first"),
|
||||||
functor((atom!("third")), [atom_as_cell((atom!("b"))),
|
[
|
||||||
char_as_cell('c')])]),
|
atom_as_cell((atom!("a"))),
|
||||||
functor((atom!("fourth")), [fixnum(453), fixnum(2)]),
|
functor(
|
||||||
char_as_cell('b')]);
|
(atom!("second")),
|
||||||
|
[
|
||||||
|
fixnum(1),
|
||||||
|
functor(
|
||||||
|
(atom!("third")),
|
||||||
|
[atom_as_cell((atom!("b"))), char_as_cell('c')]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
functor((atom!("fourth")), [fixnum(453), fixnum(2)]),
|
||||||
|
char_as_cell('b')
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
let mut heap = Heap::new();
|
let mut heap = Heap::new();
|
||||||
let mut functor_writer = Heap::functor_writer(functor);
|
let mut functor_writer = Heap::functor_writer(functor);
|
||||||
@@ -392,33 +469,43 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(heap[0], atom_as_cell!(atom!("first"), 1));
|
assert_eq!(heap[0], atom_as_cell!(atom!("first"), 1));
|
||||||
assert_eq!(heap[1], pstr_loc_as_cell!(heap_index!(2)));
|
assert_eq!(heap[1], pstr_loc_as_cell!(heap_index!(2)));
|
||||||
assert_eq!(heap.slice_to_str(heap_index!(2), "a string".len()), "a string");
|
assert_eq!(
|
||||||
|
heap.slice_to_str(heap_index!(2), "a string".len()),
|
||||||
|
"a string"
|
||||||
|
);
|
||||||
assert_eq!(heap[4], empty_list_as_cell!());
|
assert_eq!(heap[4], empty_list_as_cell!());
|
||||||
|
|
||||||
heap.truncate(0);
|
heap.truncate(0);
|
||||||
|
|
||||||
let functor = functor!(atom!("second"), [string((String::from("a stuttered\0 string")))]);
|
let functor = functor!(
|
||||||
|
atom!("second"),
|
||||||
|
[string((String::from("a stuttered\0 string")))]
|
||||||
|
);
|
||||||
|
|
||||||
let mut functor_writer = Heap::functor_writer(functor);
|
let mut functor_writer = Heap::functor_writer(functor);
|
||||||
functor_writer(&mut heap).unwrap();
|
functor_writer(&mut heap).unwrap();
|
||||||
|
|
||||||
assert_eq!(heap.cell_len(), 7);
|
assert_eq!(heap.cell_len(), 8);
|
||||||
|
|
||||||
assert_eq!(heap[0], atom_as_cell!(atom!("second"), 1));
|
assert_eq!(heap[0], atom_as_cell!(atom!("second"), 1));
|
||||||
assert_eq!(heap[1], pstr_loc_as_cell!(heap_index!(2)));
|
assert_eq!(heap[1], pstr_loc_as_cell!(heap_index!(2)));
|
||||||
assert_eq!(heap.slice_to_str(heap_index!(2), "a stuttered".len()), "a stuttered");
|
assert_eq!(
|
||||||
|
heap.slice_to_str(heap_index!(2), "a stuttered".len()),
|
||||||
|
"a stuttered"
|
||||||
|
);
|
||||||
assert_eq!(heap[4], pstr_loc_as_cell!(heap_index!(5)));
|
assert_eq!(heap[4], pstr_loc_as_cell!(heap_index!(5)));
|
||||||
assert_eq!(heap.slice_to_str(heap_index!(5), " string".len()), " string");
|
assert_eq!(
|
||||||
assert_eq!(heap[6], empty_list_as_cell!());
|
heap.slice_to_str(heap_index!(5), " string".len()),
|
||||||
|
" string"
|
||||||
|
);
|
||||||
|
assert_eq!(heap[7], empty_list_as_cell!());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn functors_with_lists_in_heap() {
|
fn functors_with_lists_in_heap() {
|
||||||
let functor = functor!(
|
let functor = functor!(
|
||||||
atom!("first"),
|
atom!("first"),
|
||||||
[list([fixnum(1),
|
[list([fixnum(1), atom_as_cell((atom!("a"))), fixnum(2)])]
|
||||||
atom_as_cell((atom!("a"))),
|
|
||||||
fixnum(2)])]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(functor.len(), 3);
|
assert_eq!(functor.len(), 3);
|
||||||
@@ -462,8 +549,10 @@ mod tests {
|
|||||||
let code_ptr = IndexingCodePtr::Internal(0);
|
let code_ptr = IndexingCodePtr::Internal(0);
|
||||||
let functor = functor!(
|
let functor = functor!(
|
||||||
atom!("first"),
|
atom!("first"),
|
||||||
[string((String::from("a string"))),
|
[
|
||||||
indexing_code_ptr(code_ptr)]
|
string((String::from("a string"))),
|
||||||
|
indexing_code_ptr(code_ptr)
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut heap = Heap::new();
|
let mut heap = Heap::new();
|
||||||
@@ -476,18 +565,30 @@ mod tests {
|
|||||||
assert_eq!(heap[0], atom_as_cell!(atom!("first"), 2));
|
assert_eq!(heap[0], atom_as_cell!(atom!("first"), 2));
|
||||||
assert_eq!(heap[1], pstr_loc_as_cell!(heap_index!(3)));
|
assert_eq!(heap[1], pstr_loc_as_cell!(heap_index!(3)));
|
||||||
assert_eq!(heap[2], str_loc_as_cell!(6));
|
assert_eq!(heap[2], str_loc_as_cell!(6));
|
||||||
assert_eq!(heap.slice_to_str(heap_index!(3), "a string".len()), "a string");
|
assert_eq!(
|
||||||
|
heap.slice_to_str(heap_index!(3), "a string".len()),
|
||||||
|
"a string"
|
||||||
|
);
|
||||||
assert_eq!(heap[5], empty_list_as_cell!());
|
assert_eq!(heap[5], empty_list_as_cell!());
|
||||||
assert_eq!(heap[6], atom_as_cell!(atom!("internal"), 1));
|
assert_eq!(heap[6], atom_as_cell!(atom!("internal"), 1));
|
||||||
assert_eq!(heap[7], fixnum_as_cell!(Fixnum::build_with(0)));
|
assert_eq!(heap[7], fixnum_as_cell!(Fixnum::build_with(0)));
|
||||||
|
|
||||||
heap.truncate(0);
|
heap.truncate(0);
|
||||||
|
|
||||||
let functor = functor!(atom!("second"),
|
let functor = functor!(
|
||||||
[string((String::from("a string"))),
|
atom!("second"),
|
||||||
functor((atom!("third")), [atom_as_cell((atom!("a"))),
|
[
|
||||||
string((String::from("another string"))),
|
string((String::from("a string"))),
|
||||||
indexing_code_ptr(code_ptr)])]);
|
functor(
|
||||||
|
(atom!("third")),
|
||||||
|
[
|
||||||
|
atom_as_cell((atom!("a"))),
|
||||||
|
string((String::from("another string"))),
|
||||||
|
indexing_code_ptr(code_ptr)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
let mut functor_writer = Heap::functor_writer(functor);
|
let mut functor_writer = Heap::functor_writer(functor);
|
||||||
functor_writer(&mut heap).unwrap();
|
functor_writer(&mut heap).unwrap();
|
||||||
@@ -497,24 +598,43 @@ mod tests {
|
|||||||
assert_eq!(heap[0], atom_as_cell!(atom!("second"), 2));
|
assert_eq!(heap[0], atom_as_cell!(atom!("second"), 2));
|
||||||
assert_eq!(heap[1], pstr_loc_as_cell!(heap_index!(3)));
|
assert_eq!(heap[1], pstr_loc_as_cell!(heap_index!(3)));
|
||||||
assert_eq!(heap[2], str_loc_as_cell!(6));
|
assert_eq!(heap[2], str_loc_as_cell!(6));
|
||||||
assert_eq!(heap.slice_to_str(heap_index!(3), "a string".len()), "a string");
|
assert_eq!(
|
||||||
|
heap.slice_to_str(heap_index!(3), "a string".len()),
|
||||||
|
"a string"
|
||||||
|
);
|
||||||
assert_eq!(heap[5], empty_list_as_cell!());
|
assert_eq!(heap[5], empty_list_as_cell!());
|
||||||
assert_eq!(heap[6], atom_as_cell!(atom!("third"), 3));
|
assert_eq!(heap[6], atom_as_cell!(atom!("third"), 3));
|
||||||
assert_eq!(heap[7], atom_as_cell!(atom!("a")));
|
assert_eq!(heap[7], atom_as_cell!(atom!("a")));
|
||||||
assert_eq!(heap[8], pstr_loc_as_cell!(heap_index!(10)));
|
assert_eq!(heap[8], pstr_loc_as_cell!(heap_index!(10)));
|
||||||
assert_eq!(heap[9], str_loc_as_cell!(13));
|
assert_eq!(heap[9], str_loc_as_cell!(13));
|
||||||
assert_eq!(heap.slice_to_str(heap_index!(10), "another string".len()), "another string");
|
assert_eq!(
|
||||||
|
heap.slice_to_str(heap_index!(10), "another string".len()),
|
||||||
|
"another string"
|
||||||
|
);
|
||||||
assert_eq!(heap[12], empty_list_as_cell!());
|
assert_eq!(heap[12], empty_list_as_cell!());
|
||||||
assert_eq!(heap[13], atom_as_cell!(atom!("internal"), 1));
|
assert_eq!(heap[13], atom_as_cell!(atom!("internal"), 1));
|
||||||
assert_eq!(heap[14], fixnum_as_cell!(Fixnum::build_with(0)));
|
assert_eq!(heap[14], fixnum_as_cell!(Fixnum::build_with(0)));
|
||||||
|
|
||||||
let functor = functor!(atom!("fourth"),
|
let functor = functor!(
|
||||||
[string((String::from("a string"))),
|
atom!("fourth"),
|
||||||
functor((atom!("a")),
|
[
|
||||||
[functor((atom!("fifth")), [fixnum(5),
|
string((String::from("a string"))),
|
||||||
string((String::from("another string"))),
|
functor(
|
||||||
indexing_code_ptr(code_ptr)]),
|
(atom!("a")),
|
||||||
string((String::from("and another")))])]);
|
[
|
||||||
|
functor(
|
||||||
|
(atom!("fifth")),
|
||||||
|
[
|
||||||
|
fixnum(5),
|
||||||
|
string((String::from("another string"))),
|
||||||
|
indexing_code_ptr(code_ptr)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
string((String::from("and another")))
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
heap.truncate(0);
|
heap.truncate(0);
|
||||||
|
|
||||||
@@ -526,7 +646,10 @@ mod tests {
|
|||||||
assert_eq!(heap[0], atom_as_cell!(atom!("fourth"), 2));
|
assert_eq!(heap[0], atom_as_cell!(atom!("fourth"), 2));
|
||||||
assert_eq!(heap[1], pstr_loc_as_cell!(heap_index!(3)));
|
assert_eq!(heap[1], pstr_loc_as_cell!(heap_index!(3)));
|
||||||
assert_eq!(heap[2], str_loc_as_cell!(6));
|
assert_eq!(heap[2], str_loc_as_cell!(6));
|
||||||
assert_eq!(heap.slice_to_str(heap_index!(3), "a string".len()), "a string");
|
assert_eq!(
|
||||||
|
heap.slice_to_str(heap_index!(3), "a string".len()),
|
||||||
|
"a string"
|
||||||
|
);
|
||||||
assert_eq!(heap[5], empty_list_as_cell!());
|
assert_eq!(heap[5], empty_list_as_cell!());
|
||||||
assert_eq!(heap[6], atom_as_cell!(atom!("a"), 2));
|
assert_eq!(heap[6], atom_as_cell!(atom!("a"), 2));
|
||||||
assert_eq!(heap[7], str_loc_as_cell!(9));
|
assert_eq!(heap[7], str_loc_as_cell!(9));
|
||||||
@@ -535,11 +658,17 @@ mod tests {
|
|||||||
assert_eq!(heap[10], fixnum_as_cell!(Fixnum::build_with(5)));
|
assert_eq!(heap[10], fixnum_as_cell!(Fixnum::build_with(5)));
|
||||||
assert_eq!(heap[11], pstr_loc_as_cell!(heap_index!(13)));
|
assert_eq!(heap[11], pstr_loc_as_cell!(heap_index!(13)));
|
||||||
assert_eq!(heap[12], str_loc_as_cell!(16));
|
assert_eq!(heap[12], str_loc_as_cell!(16));
|
||||||
assert_eq!(heap.slice_to_str(heap_index!(13), "another string".len()), "another string");
|
assert_eq!(
|
||||||
|
heap.slice_to_str(heap_index!(13), "another string".len()),
|
||||||
|
"another string"
|
||||||
|
);
|
||||||
assert_eq!(heap[15], empty_list_as_cell!());
|
assert_eq!(heap[15], empty_list_as_cell!());
|
||||||
assert_eq!(heap[16], atom_as_cell!(atom!("internal"), 1));
|
assert_eq!(heap[16], atom_as_cell!(atom!("internal"), 1));
|
||||||
assert_eq!(heap[17], fixnum_as_cell!(Fixnum::build_with(0)));
|
assert_eq!(heap[17], fixnum_as_cell!(Fixnum::build_with(0)));
|
||||||
assert_eq!(heap.slice_to_str(heap_index!(18), "and another".len()), "and another");
|
assert_eq!(
|
||||||
|
heap.slice_to_str(heap_index!(18), "and another".len()),
|
||||||
|
"and another"
|
||||||
|
);
|
||||||
assert_eq!(heap[20], empty_list_as_cell!());
|
assert_eq!(heap[20], empty_list_as_cell!());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,17 +679,16 @@ mod tests {
|
|||||||
|
|
||||||
let stub = functor!(
|
let stub = functor!(
|
||||||
atom!("existence_error"),
|
atom!("existence_error"),
|
||||||
[atom_as_cell((atom!("procedure"))), functor((culprit.clone()))]
|
[
|
||||||
|
atom_as_cell((atom!("procedure"))),
|
||||||
|
functor((culprit.clone()))
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
println!("{:?}", stub);
|
println!("{:?}", stub);
|
||||||
|
|
||||||
// now the error form
|
// now the error form
|
||||||
let lineless_error_form = functor!(
|
let lineless_error_form = functor!(atom!("error"), [functor(stub), functor(culprit)]);
|
||||||
atom!("error"),
|
|
||||||
[functor(stub),
|
|
||||||
functor(culprit)]
|
|
||||||
);
|
|
||||||
|
|
||||||
println!("{:?}", lineless_error_form);
|
println!("{:?}", lineless_error_form);
|
||||||
|
|
||||||
|
|||||||
159
src/heap_iter.rs
159
src/heap_iter.rs
@@ -116,10 +116,10 @@ impl<'a> EagerStackfulPreOrderHeapIter<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::PStrLoc, h) => {
|
(HeapCellValueTag::PStrLoc, h) => {
|
||||||
let (_, tail_loc) = self.heap.scan_slice_to_str(h);
|
let tail_idx = self.heap.scan_slice_to_str(h).tail_idx;
|
||||||
|
|
||||||
self.heap[tail_loc].set_mark_bit(self.mark_phase);
|
self.heap[tail_idx].set_mark_bit(self.mark_phase);
|
||||||
self.iter_stack.push(self.heap[tail_loc]);
|
self.iter_stack.push(self.heap[tail_idx]);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
}
|
}
|
||||||
@@ -452,12 +452,12 @@ impl<'a, ElideLists: ListElisionPolicy> StackfulPreOrderHeapIter<'a, ElideLists>
|
|||||||
}
|
}
|
||||||
(HeapCellValueTag::PStrLoc, vh) => {
|
(HeapCellValueTag::PStrLoc, vh) => {
|
||||||
let cell = *cell;
|
let cell = *cell;
|
||||||
let (_, tail_loc) = self.heap.scan_slice_to_str(vh);
|
let tail_idx = self.heap.scan_slice_to_str(vh).tail_idx;
|
||||||
|
|
||||||
// forward the current PStrLoc cell if the zero
|
// forward the current PStrLoc cell if the zero
|
||||||
// byte at the end of the string buffer
|
// byte at the end of the string buffer
|
||||||
// is marked
|
// is marked
|
||||||
let buf_bytes = self.heap[tail_loc - 1].into_bytes();
|
let buf_bytes = self.heap[tail_idx - 1].into_bytes();
|
||||||
|
|
||||||
if buf_bytes[7] != 0u8 {
|
if buf_bytes[7] != 0u8 {
|
||||||
let cell = self.read_cell_mut(h);
|
let cell = self.read_cell_mut(h);
|
||||||
@@ -469,9 +469,9 @@ impl<'a, ElideLists: ListElisionPolicy> StackfulPreOrderHeapIter<'a, ElideLists>
|
|||||||
// is never inspected, which it isn't.
|
// is never inspected, which it isn't.
|
||||||
|
|
||||||
self.push_if_unmarked(
|
self.push_if_unmarked(
|
||||||
IterStackLoc::iterable_loc(tail_loc - 1, HeapOrStackTag::Heap),
|
IterStackLoc::iterable_loc(tail_idx - 1, HeapOrStackTag::Heap),
|
||||||
);
|
);
|
||||||
self.stack.push(IterStackLoc::mark_loc(tail_loc, HeapOrStackTag::Heap));
|
self.stack.push(IterStackLoc::mark_loc(tail_idx, HeapOrStackTag::Heap));
|
||||||
|
|
||||||
return Some(cell);
|
return Some(cell);
|
||||||
}
|
}
|
||||||
@@ -502,7 +502,6 @@ impl<'a, ElideLists: ListElisionPolicy> StackfulPreOrderHeapIter<'a, ElideLists>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'a, ElideLists: ListElisionPolicy> Iterator for StackfulPreOrderHeapIter<'a, ElideLists> {
|
impl<'a, ElideLists: ListElisionPolicy> Iterator for StackfulPreOrderHeapIter<'a, ElideLists> {
|
||||||
type Item = HeapCellValue;
|
type Item = HeapCellValue;
|
||||||
|
|
||||||
@@ -707,9 +706,8 @@ mod tests {
|
|||||||
|
|
||||||
let mut functor_writer = Heap::functor_writer(functor!(
|
let mut functor_writer = Heap::functor_writer(functor!(
|
||||||
f_atom,
|
f_atom,
|
||||||
[atom_as_cell(a_atom),
|
[atom_as_cell(a_atom), atom_as_cell(b_atom)]
|
||||||
atom_as_cell(b_atom)]),
|
));
|
||||||
);
|
|
||||||
|
|
||||||
let cell = functor_writer(&mut wam.machine_st.heap).unwrap();
|
let cell = functor_writer(&mut wam.machine_st.heap).unwrap();
|
||||||
wam.machine_st.heap.push_cell(cell).unwrap();
|
wam.machine_st.heap.push_cell(cell).unwrap();
|
||||||
@@ -733,7 +731,7 @@ mod tests {
|
|||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
@@ -758,10 +756,7 @@ mod tests {
|
|||||||
unmark_cell_bits!(iter.next().unwrap()),
|
unmark_cell_bits!(iter.next().unwrap()),
|
||||||
atom_as_cell!(f_atom, 4)
|
atom_as_cell!(f_atom, 4)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), str_loc_as_cell!(0));
|
||||||
unmark_cell_bits!(iter.next().unwrap()),
|
|
||||||
str_loc_as_cell!(0)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unmark_cell_bits!(iter.next().unwrap()),
|
unmark_cell_bits!(iter.next().unwrap()),
|
||||||
atom_as_cell!(a_atom)
|
atom_as_cell!(a_atom)
|
||||||
@@ -778,7 +773,7 @@ mod tests {
|
|||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
@@ -794,7 +789,7 @@ mod tests {
|
|||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
@@ -837,7 +832,7 @@ mod tests {
|
|||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
// now make the list cyclic.
|
// now make the list cyclic.
|
||||||
wam.machine_st.heap[4] = heap_loc_as_cell!(0);
|
wam.machine_st.heap[4] = heap_loc_as_cell!(0);
|
||||||
@@ -939,8 +934,6 @@ mod tests {
|
|||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
|
||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
let mut writer = wam.machine_st.heap.reserve(96).unwrap();
|
let mut writer = wam.machine_st.heap.reserve(96).unwrap();
|
||||||
@@ -955,9 +948,11 @@ mod tests {
|
|||||||
|
|
||||||
let mut functor_writer = Heap::functor_writer(functor!(
|
let mut functor_writer = Heap::functor_writer(functor!(
|
||||||
f_atom,
|
f_atom,
|
||||||
[atom_as_cell(a_atom),
|
[
|
||||||
atom_as_cell(b_atom),
|
atom_as_cell(a_atom),
|
||||||
atom_as_cell(b_atom)]
|
atom_as_cell(b_atom),
|
||||||
|
atom_as_cell(b_atom)
|
||||||
|
]
|
||||||
));
|
));
|
||||||
|
|
||||||
functor_writer(&mut wam.machine_st.heap).unwrap();
|
functor_writer(&mut wam.machine_st.heap).unwrap();
|
||||||
@@ -1003,7 +998,7 @@ mod tests {
|
|||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, 0);
|
let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, 0);
|
||||||
@@ -1044,7 +1039,7 @@ mod tests {
|
|||||||
// instance.
|
// instance.
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.heap[0], list_loc_as_cell!(1));
|
assert_eq!(wam.machine_st.heap[0], list_loc_as_cell!(1));
|
||||||
assert_eq!(wam.machine_st.heap[1], str_loc_as_cell!(5));
|
assert_eq!(wam.machine_st.heap[1], str_loc_as_cell!(5));
|
||||||
@@ -1074,7 +1069,7 @@ mod tests {
|
|||||||
// instance.
|
// instance.
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.heap[0], list_loc_as_cell!(1));
|
assert_eq!(wam.machine_st.heap[0], list_loc_as_cell!(1));
|
||||||
assert_eq!(wam.machine_st.heap[1], str_loc_as_cell!(5));
|
assert_eq!(wam.machine_st.heap[1], str_loc_as_cell!(5));
|
||||||
@@ -1126,7 +1121,7 @@ mod tests {
|
|||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
@@ -1147,7 +1142,7 @@ mod tests {
|
|||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unmark_cell_bits!(wam.machine_st.heap[0]),
|
unmark_cell_bits!(wam.machine_st.heap[0]),
|
||||||
@@ -1193,7 +1188,7 @@ mod tests {
|
|||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unmark_cell_bits!(wam.machine_st.heap[0]),
|
unmark_cell_bits!(wam.machine_st.heap[0]),
|
||||||
@@ -1427,7 +1422,10 @@ mod tests {
|
|||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
{
|
{
|
||||||
wam.machine_st.heap.push_cell(fixnum_as_cell!(Fixnum::build_with(0))).unwrap();
|
wam.machine_st
|
||||||
|
.heap
|
||||||
|
.push_cell(fixnum_as_cell!(Fixnum::build_with(0)))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, 0);
|
let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, 0);
|
||||||
|
|
||||||
@@ -1439,7 +1437,7 @@ mod tests {
|
|||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
@@ -1473,7 +1471,7 @@ mod tests {
|
|||||||
assert!(iter.next().is_none());
|
assert!(iter.next().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
@@ -1504,7 +1502,7 @@ mod tests {
|
|||||||
assert!(iter.next().is_none());
|
assert!(iter.next().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
@@ -1564,7 +1562,7 @@ mod tests {
|
|||||||
assert!(iter.next().is_none());
|
assert!(iter.next().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.heap[0], str_loc_as_cell!(1));
|
assert_eq!(wam.machine_st.heap[0], str_loc_as_cell!(1));
|
||||||
assert_eq!(wam.machine_st.heap[1], atom_as_cell!(atom!("g"), 2));
|
assert_eq!(wam.machine_st.heap[1], atom_as_cell!(atom!("g"), 2));
|
||||||
@@ -1634,13 +1632,6 @@ mod tests {
|
|||||||
{
|
{
|
||||||
let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, 9);
|
let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, 9);
|
||||||
|
|
||||||
/*
|
|
||||||
while let Some(_) = iter.next() {
|
|
||||||
print_heap_terms(iter.heap.iter(), 0);
|
|
||||||
println!("");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unmark_cell_bits!(iter.next().unwrap()),
|
unmark_cell_bits!(iter.next().unwrap()),
|
||||||
list_loc_as_cell!(7)
|
list_loc_as_cell!(7)
|
||||||
@@ -1693,9 +1684,8 @@ mod tests {
|
|||||||
|
|
||||||
let mut functor_writer = Heap::functor_writer(functor!(
|
let mut functor_writer = Heap::functor_writer(functor!(
|
||||||
f_atom,
|
f_atom,
|
||||||
[atom_as_cell(a_atom),
|
[atom_as_cell(a_atom), atom_as_cell(b_atom)]
|
||||||
atom_as_cell(b_atom)]),
|
));
|
||||||
);
|
|
||||||
|
|
||||||
let cell = functor_writer(&mut wam.machine_st.heap).unwrap();
|
let cell = functor_writer(&mut wam.machine_st.heap).unwrap();
|
||||||
let h = wam.machine_st.heap.cell_len();
|
let h = wam.machine_st.heap.cell_len();
|
||||||
@@ -1924,7 +1914,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.heap[0], list_loc_as_cell!(1));
|
assert_eq!(wam.machine_st.heap[0], list_loc_as_cell!(1));
|
||||||
assert_eq!(wam.machine_st.heap[1], atom_as_cell!(a_atom));
|
assert_eq!(wam.machine_st.heap[1], atom_as_cell!(a_atom));
|
||||||
@@ -2021,7 +2011,11 @@ mod tests {
|
|||||||
|
|
||||||
let functor = functor!(
|
let functor = functor!(
|
||||||
f_atom,
|
f_atom,
|
||||||
[atom_as_cell(a_atom), atom_as_cell(b_atom), atom_as_cell(b_atom)]
|
[
|
||||||
|
atom_as_cell(a_atom),
|
||||||
|
atom_as_cell(b_atom),
|
||||||
|
atom_as_cell(b_atom)
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut writer = wam.machine_st.heap.reserve(96).unwrap();
|
let mut writer = wam.machine_st.heap.reserve(96).unwrap();
|
||||||
@@ -2098,7 +2092,7 @@ mod tests {
|
|||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap[4] = list_loc_as_cell!(1);
|
wam.machine_st.heap[4] = list_loc_as_cell!(1);
|
||||||
|
|
||||||
@@ -2163,7 +2157,7 @@ mod tests {
|
|||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
@@ -2202,7 +2196,7 @@ mod tests {
|
|||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
@@ -2221,18 +2215,18 @@ mod tests {
|
|||||||
2,
|
2,
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(iter.heap.slice_to_str(0, "a string".len()), "a string");
|
||||||
iter.heap.slice_to_str(0, "a string".len()),
|
assert_eq!(iter.next().unwrap(), empty_list_as_cell!());
|
||||||
"a string"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
iter.next().unwrap(),
|
|
||||||
empty_list_as_cell!()
|
|
||||||
);
|
|
||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
assert_eq!(wam.machine_st.heap.slice_to_str(0, "a string".len()), "a string");
|
||||||
|
assert_eq!(wam.machine_st.heap[1], HeapCellValue::build_with(HeapCellValueTag::Cons, 0));
|
||||||
|
|
||||||
|
for idx in 2 ..= 3 {
|
||||||
|
assert!(!wam.machine_st.heap[idx].get_mark_bit());
|
||||||
|
assert!(!wam.machine_st.heap[idx].get_forwarding_bit());
|
||||||
|
}
|
||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
@@ -2291,9 +2285,8 @@ mod tests {
|
|||||||
|
|
||||||
let mut functor_writer = Heap::functor_writer(functor!(
|
let mut functor_writer = Heap::functor_writer(functor!(
|
||||||
f_atom,
|
f_atom,
|
||||||
[atom_as_cell(a_atom),
|
[atom_as_cell(a_atom), atom_as_cell(b_atom)]
|
||||||
atom_as_cell(b_atom)]),
|
));
|
||||||
);
|
|
||||||
|
|
||||||
let cell = functor_writer(&mut wam.machine_st.heap).unwrap();
|
let cell = functor_writer(&mut wam.machine_st.heap).unwrap();
|
||||||
let h = wam.machine_st.heap.cell_len();
|
let h = wam.machine_st.heap.cell_len();
|
||||||
@@ -2325,7 +2318,6 @@ mod tests {
|
|||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
|
|
||||||
let mut functor_writer = Heap::functor_writer(functor!(
|
let mut functor_writer = Heap::functor_writer(functor!(
|
||||||
f_atom,
|
f_atom,
|
||||||
[
|
[
|
||||||
@@ -2361,10 +2353,7 @@ mod tests {
|
|||||||
unmark_cell_bits!(iter.next().unwrap()),
|
unmark_cell_bits!(iter.next().unwrap()),
|
||||||
atom_as_cell!(a_atom)
|
atom_as_cell!(a_atom)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), str_loc_as_cell!(0));
|
||||||
unmark_cell_bits!(iter.next().unwrap()),
|
|
||||||
str_loc_as_cell!(0)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unmark_cell_bits!(iter.next().unwrap()),
|
unmark_cell_bits!(iter.next().unwrap()),
|
||||||
atom_as_cell!(f_atom, 4)
|
atom_as_cell!(f_atom, 4)
|
||||||
@@ -2519,7 +2508,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.heap[0], list_loc_as_cell!(1));
|
assert_eq!(wam.machine_st.heap[0], list_loc_as_cell!(1));
|
||||||
assert_eq!(wam.machine_st.heap[1], atom_as_cell!(a_atom));
|
assert_eq!(wam.machine_st.heap[1], atom_as_cell!(a_atom));
|
||||||
@@ -2616,7 +2605,11 @@ mod tests {
|
|||||||
|
|
||||||
let functor = functor!(
|
let functor = functor!(
|
||||||
f_atom,
|
f_atom,
|
||||||
[atom_as_cell(a_atom), atom_as_cell(b_atom), atom_as_cell(b_atom)]
|
[
|
||||||
|
atom_as_cell(a_atom),
|
||||||
|
atom_as_cell(b_atom),
|
||||||
|
atom_as_cell(b_atom)
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut writer = wam.machine_st.heap.reserve(96).unwrap();
|
let mut writer = wam.machine_st.heap.reserve(96).unwrap();
|
||||||
@@ -2694,7 +2687,7 @@ mod tests {
|
|||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap[4] = list_loc_as_cell!(1);
|
wam.machine_st.heap[4] = list_loc_as_cell!(1);
|
||||||
|
|
||||||
@@ -2761,7 +2754,7 @@ mod tests {
|
|||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2778,9 +2771,8 @@ mod tests {
|
|||||||
|
|
||||||
let mut functor_writer = Heap::functor_writer(functor!(
|
let mut functor_writer = Heap::functor_writer(functor!(
|
||||||
f_atom,
|
f_atom,
|
||||||
[atom_as_cell(a_atom),
|
[atom_as_cell(a_atom), atom_as_cell(b_atom)]
|
||||||
atom_as_cell(b_atom)]),
|
));
|
||||||
);
|
|
||||||
|
|
||||||
let cell = functor_writer(&mut wam.machine_st.heap).unwrap();
|
let cell = functor_writer(&mut wam.machine_st.heap).unwrap();
|
||||||
wam.machine_st.heap.push_cell(cell).unwrap();
|
wam.machine_st.heap.push_cell(cell).unwrap();
|
||||||
@@ -2969,7 +2961,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.heap[0], list_loc_as_cell!(1));
|
assert_eq!(wam.machine_st.heap[0], list_loc_as_cell!(1));
|
||||||
assert_eq!(wam.machine_st.heap[1], atom_as_cell!(a_atom));
|
assert_eq!(wam.machine_st.heap[1], atom_as_cell!(a_atom));
|
||||||
@@ -3039,7 +3031,7 @@ mod tests {
|
|||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap[4] = pstr_loc_as_cell!(heap_index!(3) + 2);
|
wam.machine_st.heap[4] = pstr_loc_as_cell!(heap_index!(3) + 2);
|
||||||
|
|
||||||
@@ -3053,11 +3045,18 @@ mod tests {
|
|||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
let functor = functor!(f_atom, [atom_as_cell(a_atom), atom_as_cell(b_atom), atom_as_cell(b_atom)]);
|
let functor = functor!(
|
||||||
|
f_atom,
|
||||||
|
[
|
||||||
|
atom_as_cell(a_atom),
|
||||||
|
atom_as_cell(b_atom),
|
||||||
|
atom_as_cell(b_atom)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
let mut writer = wam.machine_st.heap.reserve(96).unwrap();
|
let mut writer = wam.machine_st.heap.reserve(96).unwrap();
|
||||||
|
|
||||||
@@ -3116,7 +3115,7 @@ mod tests {
|
|||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap[4] = list_loc_as_cell!(1);
|
wam.machine_st.heap[4] = list_loc_as_cell!(1);
|
||||||
|
|
||||||
@@ -3164,6 +3163,6 @@ mod tests {
|
|||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -486,7 +486,12 @@ pub struct HCPrinter<'a, Outputter> {
|
|||||||
pub double_quotes: bool,
|
pub double_quotes: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ambiguity_check(outputter: &impl HCValueOutputter, quoted: bool, last_item_idx: usize, atom: &str) -> bool {
|
fn ambiguity_check(
|
||||||
|
outputter: &impl HCValueOutputter,
|
||||||
|
quoted: bool,
|
||||||
|
last_item_idx: usize,
|
||||||
|
atom: &str,
|
||||||
|
) -> bool {
|
||||||
let tail = &outputter.as_str()[last_item_idx..];
|
let tail = &outputter.as_str()[last_item_idx..];
|
||||||
|
|
||||||
if atom == "," || !quoted || non_quoted_token(atom.chars()) {
|
if atom == "," || !quoted || non_quoted_token(atom.chars()) {
|
||||||
@@ -1132,7 +1137,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! emit_char {
|
macro_rules! emit_char {
|
||||||
($c:expr) => ({
|
($c:expr) => {{
|
||||||
append_str!(self, "'.'");
|
append_str!(self, "'.'");
|
||||||
push_char!(self, '(');
|
push_char!(self, '(');
|
||||||
|
|
||||||
@@ -1141,14 +1146,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Close);
|
self.state_stack.push(TokenOrRedirect::Close);
|
||||||
char_count += 1;
|
char_count += 1;
|
||||||
});
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
match iteratee {
|
match iteratee {
|
||||||
PStrIteratee::Char { value, .. } => {
|
PStrIteratee::Char { value, .. } => {
|
||||||
emit_char!(value);
|
emit_char!(value);
|
||||||
}
|
}
|
||||||
PStrIteratee::PStrSlice { slice_loc, slice_len } => {
|
PStrIteratee::PStrSlice {
|
||||||
|
slice_loc,
|
||||||
|
slice_len,
|
||||||
|
} => {
|
||||||
let s = iter.heap.slice_to_str(slice_loc, slice_len);
|
let s = iter.heap.slice_to_str(slice_loc, slice_len);
|
||||||
|
|
||||||
for c in s.chars() {
|
for c in s.chars() {
|
||||||
@@ -1181,10 +1189,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
if max_depth == 0 {
|
if max_depth == 0 {
|
||||||
while let Some(iteratee) = iter.next() {
|
while let Some(iteratee) = iter.next() {
|
||||||
let iter: Box<dyn Iterator<Item = char>> = match iteratee {
|
let iter: Box<dyn Iterator<Item = char>> = match iteratee {
|
||||||
PStrIteratee::Char { value: c, .. } => {
|
PStrIteratee::Char { value: c, .. } => Box::new(std::iter::once(c)),
|
||||||
Box::new(std::iter::once(c))
|
PStrIteratee::PStrSlice {
|
||||||
}
|
slice_loc,
|
||||||
PStrIteratee::PStrSlice { slice_loc, slice_len } => {
|
slice_len,
|
||||||
|
} => {
|
||||||
let s = iter.heap.slice_to_str(slice_loc, slice_len);
|
let s = iter.heap.slice_to_str(slice_loc, slice_len);
|
||||||
Box::new(s.chars())
|
Box::new(s.chars())
|
||||||
}
|
}
|
||||||
@@ -1201,10 +1210,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
while let Some(iteratee) = iter.next() {
|
while let Some(iteratee) = iter.next() {
|
||||||
let iter: Box<dyn Iterator<Item = char>> = match iteratee {
|
let iter: Box<dyn Iterator<Item = char>> = match iteratee {
|
||||||
PStrIteratee::Char { value: c, .. } => {
|
PStrIteratee::Char { value: c, .. } => Box::new(std::iter::once(c)),
|
||||||
Box::new(std::iter::once(c))
|
PStrIteratee::PStrSlice {
|
||||||
}
|
slice_loc,
|
||||||
PStrIteratee::PStrSlice { slice_loc, slice_len } => {
|
slice_len,
|
||||||
|
} => {
|
||||||
let s = iter.heap.slice_to_str(slice_loc, slice_len);
|
let s = iter.heap.slice_to_str(slice_loc, slice_len);
|
||||||
Box::new(s.chars())
|
Box::new(s.chars())
|
||||||
}
|
}
|
||||||
@@ -1583,22 +1593,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
|
self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
|
||||||
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
|
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
|
||||||
} else {
|
} else {
|
||||||
/*
|
self.state_stack
|
||||||
let end_cell_h = Heap::neighboring_cell_offset(pstr_loc);
|
.push(TokenOrRedirect::FunctorRedirect(max_depth + 1));
|
||||||
let end_cell = self.iter.heap[end_cell_h];
|
|
||||||
let end_cell = heap_bound_store(
|
|
||||||
self.iter.heap,
|
|
||||||
heap_bound_deref(self.iter.heap, end_cell),
|
|
||||||
);
|
|
||||||
|
|
||||||
if end_cell != empty_list_as_cell!() {
|
|
||||||
self.iter.push_stack(
|
|
||||||
IterStackLoc::iterable_loc(end_cell_h, HeapOrStackTag::Heap),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth + 1));
|
|
||||||
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
|
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1872,9 +1868,8 @@ mod tests {
|
|||||||
|
|
||||||
let mut functor_writer = Heap::functor_writer(functor!(
|
let mut functor_writer = Heap::functor_writer(functor!(
|
||||||
f_atom,
|
f_atom,
|
||||||
[atom_as_cell(a_atom),
|
[atom_as_cell(a_atom), atom_as_cell(b_atom)]
|
||||||
atom_as_cell(b_atom)]),
|
));
|
||||||
);
|
|
||||||
|
|
||||||
let cell = functor_writer(&mut wam.machine_st.heap).unwrap();
|
let cell = functor_writer(&mut wam.machine_st.heap).unwrap();
|
||||||
wam.machine_st.heap.push_cell(cell).unwrap();
|
wam.machine_st.heap.push_cell(cell).unwrap();
|
||||||
@@ -1893,7 +1888,7 @@ mod tests {
|
|||||||
assert_eq!(output.result(), "f(a,b)");
|
assert_eq!(output.result(), "f(a,b)");
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
@@ -1925,7 +1920,7 @@ mod tests {
|
|||||||
assert_eq!(output.result(), "f(a,b,a,...)");
|
assert_eq!(output.result(), "f(a,b,a,...)");
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
@@ -1968,7 +1963,7 @@ mod tests {
|
|||||||
assert_eq!(output.result(), "[L|L]");
|
assert_eq!(output.result(), "[L|L]");
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
@@ -1984,9 +1979,11 @@ mod tests {
|
|||||||
|
|
||||||
let mut functor_writer = Heap::functor_writer(functor!(
|
let mut functor_writer = Heap::functor_writer(functor!(
|
||||||
f_atom,
|
f_atom,
|
||||||
[atom_as_cell(a_atom),
|
[
|
||||||
atom_as_cell(b_atom),
|
atom_as_cell(a_atom),
|
||||||
atom_as_cell(b_atom)]
|
atom_as_cell(b_atom),
|
||||||
|
atom_as_cell(b_atom)
|
||||||
|
]
|
||||||
));
|
));
|
||||||
|
|
||||||
functor_writer(&mut wam.machine_st.heap).unwrap();
|
functor_writer(&mut wam.machine_st.heap).unwrap();
|
||||||
@@ -2005,7 +2002,7 @@ mod tests {
|
|||||||
assert_eq!(output.result(), "[f(a,b,b),f(a,b,b)]");
|
assert_eq!(output.result(), "[f(a,b,b),f(a,b,b)]");
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap[4] = list_loc_as_cell!(1);
|
wam.machine_st.heap[4] = list_loc_as_cell!(1);
|
||||||
|
|
||||||
@@ -2023,7 +2020,7 @@ mod tests {
|
|||||||
assert_eq!(output.result(), "[f(a,b,b),f(a,b,b)|...]");
|
assert_eq!(output.result(), "[f(a,b,b),f(a,b,b)|...]");
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut printer = HCPrinter::new(
|
let mut printer = HCPrinter::new(
|
||||||
@@ -2043,7 +2040,7 @@ mod tests {
|
|||||||
assert_eq!(output.result(), "[f(a,b,b),f(a,b,b)|L]");
|
assert_eq!(output.result(), "[f(a,b,b),f(a,b,b)|L]");
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
// issue #382
|
// issue #382
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
@@ -2077,7 +2074,7 @@ mod tests {
|
|||||||
assert_eq!(output.result(), "[_1,_3,_5,_7,_9|...]");
|
assert_eq!(output.result(), "[_1,_3,_5,_7,_9|...]");
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
@@ -2100,7 +2097,7 @@ mod tests {
|
|||||||
assert_eq!(output.result(), "[a,b,c|_1]");
|
assert_eq!(output.result(), "[a,b,c|_1]");
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
let mut writer = wam.machine_st.heap.reserve(96).unwrap();
|
let mut writer = wam.machine_st.heap.reserve(96).unwrap();
|
||||||
|
|
||||||
@@ -2131,7 +2128,7 @@ mod tests {
|
|||||||
assert_eq!(output.result(), "\"abcabc\"");
|
assert_eq!(output.result(), "\"abcabc\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
@@ -2140,14 +2137,14 @@ mod tests {
|
|||||||
"=(X,[a,b,c|X])"
|
"=(X,[a,b,c|X])"
|
||||||
);
|
);
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&wam.parse_and_print_term("[a,b,\"a\",[a,b,c]].").unwrap(),
|
&wam.parse_and_print_term("[a,b,\"a\",[a,b,c]].").unwrap(),
|
||||||
"[a,b,[a],[a,b,c]]"
|
"[a,b,[a],[a,b,c]]"
|
||||||
);
|
);
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&wam.parse_and_print_term("[\"abc\",e,f,[g,e,h,Y,v|[X,Y]]].")
|
&wam.parse_and_print_term("[\"abc\",e,f,[g,e,h,Y,v|[X,Y]]].")
|
||||||
@@ -2155,11 +2152,11 @@ mod tests {
|
|||||||
"[[a,b,c],e,f,[g,e,h,Y,v,X,Y]]"
|
"[[a,b,c],e,f,[g,e,h,Y,v,X,Y]]"
|
||||||
);
|
);
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
assert_eq!(&wam.parse_and_print_term("f((a,b)).").unwrap(), "f((a,b))");
|
assert_eq!(&wam.parse_and_print_term("f((a,b)).").unwrap(), "f((a,b))");
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.op_dir
|
wam.op_dir
|
||||||
.insert((atom!("+"), Fixity::In), OpDesc::build_with(500, YFX));
|
.insert((atom!("+"), Fixity::In), OpDesc::build_with(500, YFX));
|
||||||
@@ -2171,14 +2168,14 @@ mod tests {
|
|||||||
"[a|[]+b]"
|
"[a|[]+b]"
|
||||||
);
|
);
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&wam.parse_and_print_term("[a|[b|c]*d].").unwrap(),
|
&wam.parse_and_print_term("[a|[b|c]*d].").unwrap(),
|
||||||
"[a|[b|c]*d]"
|
"[a|[b|c]*d]"
|
||||||
);
|
);
|
||||||
|
|
||||||
all_cells_unmarked(wam.machine_st.heap.splice(..));
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
wam.op_dir
|
wam.op_dir
|
||||||
.insert((atom!("fy"), Fixity::Pre), OpDesc::build_with(9, FY));
|
.insert((atom!("fy"), Fixity::Pre), OpDesc::build_with(9, FY));
|
||||||
|
|||||||
@@ -1110,12 +1110,11 @@ pub(crate) fn constant_key_alternatives(
|
|||||||
constants.push(
|
constants.push(
|
||||||
Fixnum::build_with_checked(value)
|
Fixnum::build_with_checked(value)
|
||||||
.map(|n| fixnum_as_cell!(n))
|
.map(|n| fixnum_as_cell!(n))
|
||||||
.unwrap()
|
.unwrap(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1465,11 +1464,7 @@ impl<I: Indexer> CodeOffsets<I> {
|
|||||||
self.indices.lists().push_back(index);
|
self.indices.lists().push_back(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn index_constant(
|
fn index_constant(&mut self, constant: HeapCellValue, index: usize) -> Vec<HeapCellValue> {
|
||||||
&mut self,
|
|
||||||
constant: HeapCellValue,
|
|
||||||
index: usize,
|
|
||||||
) -> Vec<HeapCellValue> {
|
|
||||||
let overlapping_constants = constant_key_alternatives(constant);
|
let overlapping_constants = constant_key_alternatives(constant);
|
||||||
let code = self.indices.constants().entry(constant).or_default();
|
let code = self.indices.constants().entry(constant).or_default();
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ use std::iter::*;
|
|||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
|
||||||
pub(crate) trait TermIterator: Deref<Target = Heap> + Iterator<Item = HeapCellValue> {
|
pub(crate) trait TermIterator:
|
||||||
|
Deref<Target = Heap> + Iterator<Item = HeapCellValue>
|
||||||
|
{
|
||||||
fn focus(&self) -> IterStackLoc;
|
fn focus(&self) -> IterStackLoc;
|
||||||
fn level(&mut self) -> Level;
|
fn level(&mut self) -> Level;
|
||||||
}
|
}
|
||||||
@@ -45,9 +47,9 @@ fn record_path(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Lis) => {
|
(HeapCellValueTag::Lis) => {
|
||||||
root_terms.insert(root_loc);
|
root_terms.insert(root_loc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if cell.is_ref() {
|
if cell.is_ref() {
|
||||||
root_terms.insert(cell.get_value() as usize);
|
root_terms.insert(cell.get_value() as usize);
|
||||||
@@ -228,7 +230,10 @@ pub(crate) enum ClauseItem<'a> {
|
|||||||
FirstBranch(usize),
|
FirstBranch(usize),
|
||||||
NextBranch,
|
NextBranch,
|
||||||
BranchEnd(usize),
|
BranchEnd(usize),
|
||||||
Chunk { chunk_num: usize, terms: &'a VecDeque<QueryTerm> },
|
Chunk {
|
||||||
|
chunk_num: usize,
|
||||||
|
terms: &'a VecDeque<QueryTerm>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -271,10 +276,9 @@ impl<'a> ClauseIterator<'a> {
|
|||||||
|
|
||||||
while let Some(state) = self.state_stack.pop() {
|
while let Some(state) = self.state_stack.pop() {
|
||||||
match state {
|
match state {
|
||||||
ClauseIteratorState::RemainingBranches(terms, focus)
|
ClauseIteratorState::RemainingBranches(terms, focus) if terms.len() == focus => {
|
||||||
if terms.len() == focus => {
|
depth += 1;
|
||||||
depth += 1;
|
}
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
self.state_stack.push(state);
|
self.state_stack.push(state);
|
||||||
break;
|
break;
|
||||||
@@ -292,25 +296,27 @@ impl<'a> Iterator for ClauseIterator<'a> {
|
|||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
while let Some(state) = self.state_stack.pop() {
|
while let Some(state) = self.state_stack.pop() {
|
||||||
match state {
|
match state {
|
||||||
ClauseIteratorState::RemainingChunks(chunks, focus)
|
ClauseIteratorState::RemainingChunks(chunks, focus) if focus < chunks.len() => {
|
||||||
if focus < chunks.len() => {
|
if focus + 1 < chunks.len() {
|
||||||
if focus + 1 < chunks.len() {
|
self.state_stack
|
||||||
self.state_stack
|
.push(ClauseIteratorState::RemainingChunks(chunks, focus + 1));
|
||||||
.push(ClauseIteratorState::RemainingChunks(chunks, focus + 1));
|
} else {
|
||||||
} else {
|
self.remaining_chunks_on_stack -= 1;
|
||||||
self.remaining_chunks_on_stack -= 1;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
match &chunks[focus] {
|
match &chunks[focus] {
|
||||||
ChunkedTerms::Branch(branches) => {
|
ChunkedTerms::Branch(branches) => {
|
||||||
self.state_stack
|
self.state_stack
|
||||||
.push(ClauseIteratorState::RemainingBranches(branches, 0));
|
.push(ClauseIteratorState::RemainingBranches(branches, 0));
|
||||||
}
|
}
|
||||||
&ChunkedTerms::Chunk { chunk_num, ref terms } => {
|
&ChunkedTerms::Chunk {
|
||||||
return Some(ClauseItem::Chunk { chunk_num, terms });
|
chunk_num,
|
||||||
}
|
ref terms,
|
||||||
|
} => {
|
||||||
|
return Some(ClauseItem::Chunk { chunk_num, terms });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ClauseIteratorState::RemainingChunks(chunks, focus) => {
|
ClauseIteratorState::RemainingChunks(chunks, focus) => {
|
||||||
debug_assert_eq!(chunks.len(), focus);
|
debug_assert_eq!(chunks.len(), focus);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -568,6 +568,7 @@ parse_options_list(Options, Selector, DefaultPairs, OptionValues, Stub) :-
|
|||||||
% maplist isn't
|
% maplist isn't
|
||||||
% declared as a
|
% declared as a
|
||||||
% meta-predicate yet
|
% meta-predicate yet
|
||||||
|
'$debug_hook',
|
||||||
catch(lists:maplist(Selector, Options, OptionPairs0),
|
catch(lists:maplist(Selector, Options, OptionPairs0),
|
||||||
error(E, _),
|
error(E, _),
|
||||||
builtins:throw(error(E, Stub))) ->
|
builtins:throw(error(E, Stub))) ->
|
||||||
|
|||||||
@@ -1165,9 +1165,8 @@ impl MachineState {
|
|||||||
return Err(self.error_form(type_error, stub_gen()));
|
return Err(self.error_form(type_error, stub_gen()));
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut iter = stackful_post_order_iter::<NonListElider>(
|
let mut iter =
|
||||||
&mut self.heap, &mut self.stack, root_loc,
|
stackful_post_order_iter::<NonListElider>(&mut self.heap, &mut self.stack, root_loc);
|
||||||
);
|
|
||||||
|
|
||||||
while let Some(value) = iter.next() {
|
while let Some(value) = iter.next() {
|
||||||
if value.get_forwarding_bit() {
|
if value.get_forwarding_bit() {
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ verify_attrs([], _, _, []).
|
|||||||
|
|
||||||
|
|
||||||
call_goals([ListOfGoalLists | ListsCubed]) :-
|
call_goals([ListOfGoalLists | ListsCubed]) :-
|
||||||
'$debug_hook',
|
|
||||||
call_goals_0(ListOfGoalLists),
|
call_goals_0(ListOfGoalLists),
|
||||||
call_goals(ListsCubed).
|
call_goals(ListsCubed).
|
||||||
call_goals([]).
|
call_goals([]).
|
||||||
|
|||||||
@@ -145,7 +145,9 @@ impl MachineState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut iter = stackful_preorder_iter::<NonListElider>(
|
let mut iter = stackful_preorder_iter::<NonListElider>(
|
||||||
&mut self.heap, &mut self.stack, root_loc, // cell,
|
&mut self.heap,
|
||||||
|
&mut self.stack,
|
||||||
|
root_loc, // cell,
|
||||||
);
|
);
|
||||||
|
|
||||||
while let Some(value) = iter.next() {
|
while let Some(value) = iter.next() {
|
||||||
|
|||||||
@@ -2102,19 +2102,13 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn compile_and_submit(&mut self) -> Result<(), SessionError> {
|
pub(super) fn compile_and_submit(&mut self) -> Result<(), SessionError> {
|
||||||
let key = match self
|
let key = match self.payload.predicates.first().map(|term| term.focus) {
|
||||||
.payload
|
Some(focus) => clause_predicate_key(self.machine_heap(), focus)
|
||||||
.predicates
|
.ok_or(SessionError::NamelessEntry)?,
|
||||||
.first()
|
None => {
|
||||||
.map(|term| term.focus) {
|
return Err(SessionError::NamelessEntry);
|
||||||
Some(focus) => {
|
}
|
||||||
clause_predicate_key(self.machine_heap(), focus)
|
};
|
||||||
.ok_or(SessionError::NamelessEntry)?
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
return Err(SessionError::NamelessEntry);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let listing_src_file_name = self.listing_src_file_name();
|
let listing_src_file_name = self.listing_src_file_name();
|
||||||
|
|
||||||
@@ -2290,13 +2284,18 @@ impl Machine {
|
|||||||
term_reg: RegType,
|
term_reg: RegType,
|
||||||
vars: Vec<HeapCellValue>,
|
vars: Vec<HeapCellValue>,
|
||||||
) -> Result<(), SessionError> {
|
) -> Result<(), SessionError> {
|
||||||
let body_cell = self.machine_st.store(self.machine_st.deref(self.machine_st[term_reg]));
|
let body_cell = self
|
||||||
|
.machine_st
|
||||||
|
.store(self.machine_st.deref(self.machine_st[term_reg]));
|
||||||
|
|
||||||
let new_header_loc = self.machine_st.heap.cell_len();
|
let new_header_loc = self.machine_st.heap.cell_len();
|
||||||
let arity = vars.len();
|
let arity = vars.len();
|
||||||
let term_loc = self.machine_st.heap.cell_len() + 1 + arity;
|
let term_loc = self.machine_st.heap.cell_len() + 1 + arity;
|
||||||
|
|
||||||
let mut writer = self.machine_st.heap.reserve(4 + arity)
|
let mut writer = self
|
||||||
|
.machine_st
|
||||||
|
.heap
|
||||||
|
.reserve(4 + arity)
|
||||||
.map_err(|_err_loc| ParserError::ResourceError(ParserErrorSrc::default()))?;
|
.map_err(|_err_loc| ParserError::ResourceError(ParserErrorSrc::default()))?;
|
||||||
|
|
||||||
writer.write_with(move |section| {
|
writer.write_with(move |section| {
|
||||||
|
|||||||
@@ -1,13 +1,71 @@
|
|||||||
|
use fxhash::FxBuildHasher;
|
||||||
|
use indexmap::IndexSet;
|
||||||
|
|
||||||
use crate::atom_table::*;
|
use crate::atom_table::*;
|
||||||
use crate::machine::get_structure_index;
|
use crate::machine::get_structure_index;
|
||||||
use crate::machine::heap::*;
|
use crate::machine::heap::*;
|
||||||
use crate::machine::stack::*;
|
use crate::machine::stack::*;
|
||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
|
|
||||||
|
use scryer_modular_bitfield::specifiers::*;
|
||||||
|
use scryer_modular_bitfield::*;
|
||||||
|
|
||||||
|
use std::collections::BTreeMap;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::{IndexMut, Range};
|
use std::ops::{IndexMut, Range};
|
||||||
|
|
||||||
type Trail = Vec<(Ref, HeapCellValue)>;
|
#[derive(BitfieldSpecifier, Copy, Clone, Debug)]
|
||||||
|
#[bits = 6]
|
||||||
|
enum TrailRefTag {
|
||||||
|
HeapCell = 0b001011,
|
||||||
|
StackCell = 0b001101,
|
||||||
|
AttrVar = 0b010001,
|
||||||
|
PStrLoc = 0b001111,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bitfield]
|
||||||
|
#[repr(u64)]
|
||||||
|
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
||||||
|
struct TrailRef {
|
||||||
|
val: B56,
|
||||||
|
#[allow(unused)]
|
||||||
|
m: bool,
|
||||||
|
#[allow(unused)]
|
||||||
|
f: bool,
|
||||||
|
tag: TrailRefTag,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TrailRef {
|
||||||
|
#[inline(always)]
|
||||||
|
fn heap_cell(h: usize) -> Self {
|
||||||
|
TrailRef::new()
|
||||||
|
.with_tag(TrailRefTag::HeapCell)
|
||||||
|
.with_val(h as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn stack_cell(h: usize) -> Self {
|
||||||
|
TrailRef::new()
|
||||||
|
.with_tag(TrailRefTag::StackCell)
|
||||||
|
.with_val(h as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn attr_var(h: usize) -> Self {
|
||||||
|
TrailRef::new()
|
||||||
|
.with_tag(TrailRefTag::AttrVar)
|
||||||
|
.with_val(h as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn pstr_loc(h: usize) -> Self {
|
||||||
|
TrailRef::new()
|
||||||
|
.with_tag(TrailRefTag::PStrLoc)
|
||||||
|
.with_val(h as u64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Trail = Vec<(TrailRef, HeapCellValue)>;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum AttrVarPolicy {
|
pub enum AttrVarPolicy {
|
||||||
@@ -18,15 +76,12 @@ pub enum AttrVarPolicy {
|
|||||||
pub trait CopierTarget: IndexMut<usize, Output = HeapCellValue> {
|
pub trait CopierTarget: IndexMut<usize, Output = HeapCellValue> {
|
||||||
fn store(&self, value: HeapCellValue) -> HeapCellValue;
|
fn store(&self, value: HeapCellValue) -> HeapCellValue;
|
||||||
fn deref(&self, value: HeapCellValue) -> HeapCellValue;
|
fn deref(&self, value: HeapCellValue) -> HeapCellValue;
|
||||||
// fn push_cell(&mut self, value: HeapCellValue) -> Result<(), usize>;
|
|
||||||
fn push_attr_var_queue(&mut self, attr_var_loc: usize);
|
fn push_attr_var_queue(&mut self, attr_var_loc: usize);
|
||||||
fn stack(&mut self) -> &mut Stack;
|
fn stack(&mut self) -> &mut Stack;
|
||||||
fn threshold(&self) -> usize;
|
fn threshold(&self) -> usize;
|
||||||
// returns the tail location of the pstr on success
|
// returns the tail location of the pstr on success
|
||||||
|
fn as_slice_from<'a>(&'a self, from: usize) -> Box<dyn Iterator<Item = u8> + 'a>;
|
||||||
fn copy_pstr_to_threshold(&mut self, pstr_loc: usize) -> Result<usize, usize>;
|
fn copy_pstr_to_threshold(&mut self, pstr_loc: usize) -> Result<usize, usize>;
|
||||||
fn pstr_head_cell_index(&self, pstr_loc: usize) -> usize;
|
|
||||||
fn pstr_at(&self, loc: usize) -> bool;
|
|
||||||
fn next_non_pstr_cell_index(&self, loc: usize) -> usize;
|
|
||||||
fn reserve(&mut self, num_cells: usize) -> Result<HeapWriter, usize>;
|
fn reserve(&mut self, num_cells: usize) -> Result<HeapWriter, usize>;
|
||||||
fn copy_slice_to_end(&mut self, bounds: Range<usize>) -> Result<(), usize>;
|
fn copy_slice_to_end(&mut self, bounds: Range<usize>) -> Result<(), usize>;
|
||||||
}
|
}
|
||||||
@@ -35,14 +90,25 @@ pub(crate) fn copy_term<T: CopierTarget>(
|
|||||||
target: T,
|
target: T,
|
||||||
addr: HeapCellValue,
|
addr: HeapCellValue,
|
||||||
attr_var_policy: AttrVarPolicy,
|
attr_var_policy: AttrVarPolicy,
|
||||||
) -> Result<(), usize> {
|
) -> Result<usize, usize> {
|
||||||
let mut copy_term_state = CopyTermState::new(target, attr_var_policy);
|
let mut copy_term_state = CopyTermState::new(target, attr_var_policy);
|
||||||
|
let old_threshold = copy_term_state.target.threshold();
|
||||||
|
|
||||||
copy_term_state.copy_term_impl(addr)?;
|
copy_term_state.copy_term_impl(addr)?;
|
||||||
copy_term_state.copy_attr_var_lists()?;
|
copy_term_state.copy_attr_var_lists()?;
|
||||||
copy_term_state.unwind_trail();
|
copy_term_state.unwind_trail();
|
||||||
|
|
||||||
Ok(())
|
let new_threshold = copy_term_state.target.threshold();
|
||||||
|
copy_term_state.copy_pstrs()?;
|
||||||
|
|
||||||
|
Ok(new_threshold - old_threshold)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct PStrData {
|
||||||
|
pre_old_h_tail_loc: usize,
|
||||||
|
post_old_h_tail_loc: usize,
|
||||||
|
post_old_h_pstr_loc_locs: IndexSet<usize, FxBuildHasher>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -53,6 +119,9 @@ struct CopyTermState<T: CopierTarget> {
|
|||||||
target: T,
|
target: T,
|
||||||
attr_var_policy: AttrVarPolicy,
|
attr_var_policy: AttrVarPolicy,
|
||||||
attr_var_list_locs: Vec<(usize, HeapCellValue)>,
|
attr_var_list_locs: Vec<(usize, HeapCellValue)>,
|
||||||
|
// keys of pstr_loc_locs are byte indices rounded down to the
|
||||||
|
// nearest cell boundary
|
||||||
|
pstr_loc_locs: BTreeMap<usize, PStrData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: CopierTarget> CopyTermState<T> {
|
impl<T: CopierTarget> CopyTermState<T> {
|
||||||
@@ -64,6 +133,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
target,
|
target,
|
||||||
attr_var_policy,
|
attr_var_policy,
|
||||||
attr_var_list_locs: vec![],
|
attr_var_list_locs: vec![],
|
||||||
|
pstr_loc_locs: BTreeMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +144,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
|
|
||||||
fn trail_list_cell(&mut self, addr: usize, threshold: usize) {
|
fn trail_list_cell(&mut self, addr: usize, threshold: usize) {
|
||||||
let trail_item = mem::replace(&mut self.target[addr], list_loc_as_cell!(threshold));
|
let trail_item = mem::replace(&mut self.target[addr], list_loc_as_cell!(threshold));
|
||||||
self.trail.push((Ref::heap_cell(addr), trail_item));
|
self.trail.push((TrailRef::heap_cell(addr), trail_item));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy_list(&mut self, addr: usize) -> Result<(), usize> {
|
fn copy_list(&mut self, addr: usize) -> Result<(), usize> {
|
||||||
@@ -93,7 +163,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let threshold = self.target.threshold();
|
let threshold = self.target.threshold();
|
||||||
self.target.copy_slice_to_end(addr .. addr + 2)?;
|
self.target.copy_slice_to_end(addr..addr + 2)?;
|
||||||
|
|
||||||
*self.value_at_scan() = list_loc_as_cell!(threshold);
|
*self.value_at_scan() = list_loc_as_cell!(threshold);
|
||||||
|
|
||||||
@@ -122,54 +192,90 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* write a null byte to the first word of a partial string to
|
|
||||||
* flag that it has been copied followed by the copied
|
|
||||||
* string's index in the next 7 bytes. write the bytes in big
|
|
||||||
* endian order so that the null byte is at index 0.
|
|
||||||
*/
|
|
||||||
fn write_pstr_index(&mut self, head_cell_idx: usize, threshold: usize) {
|
|
||||||
let bytes = u64::to_be_bytes(threshold as u64);
|
|
||||||
debug_assert_eq!(bytes[0], 0);
|
|
||||||
self.target[head_cell_idx] = HeapCellValue::from_bytes(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn copy_partial_string(&mut self, pstr_loc: usize) -> Result<(), usize> {
|
fn copy_partial_string(&mut self, pstr_loc: usize) -> Result<(), usize> {
|
||||||
let head_cell_idx = self.target.pstr_head_cell_index(pstr_loc);
|
match self.pstr_loc_locs.range_mut(..=pstr_loc).next_back() {
|
||||||
let head_byte_idx = heap_index!(head_cell_idx);
|
Some((
|
||||||
let pstr_offset = pstr_loc - head_byte_idx;
|
_prev_pstr_loc,
|
||||||
|
&mut PStrData {
|
||||||
// if a partial string has been copied previously, we
|
pre_old_h_tail_loc,
|
||||||
// track it by writing a null byte to its first word, which is trailed,
|
ref mut post_old_h_pstr_loc_locs,
|
||||||
// and then the new pstr_loc in the word's remaining 7 bytes. see write_pstr_index
|
..
|
||||||
// comment.
|
},
|
||||||
|
)) if pre_old_h_tail_loc >= cell_index!(pstr_loc) => {
|
||||||
if self.target[head_cell_idx].into_bytes()[0] == 0u8 {
|
post_old_h_pstr_loc_locs.insert(self.scan);
|
||||||
let head_bytes = self.target[head_cell_idx].into_bytes();
|
self.scan += 1;
|
||||||
let new_pstr_loc = u64::from_be_bytes(head_bytes) as usize;
|
return Ok(());
|
||||||
|
}
|
||||||
*self.value_at_scan() = pstr_loc_as_cell!(heap_index!(new_pstr_loc) + pstr_offset);
|
_ => {}
|
||||||
self.scan += 1;
|
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let threshold = self.target.threshold();
|
let offset = self
|
||||||
let tail_loc = self.target.copy_pstr_to_threshold(head_byte_idx)?;
|
.target
|
||||||
|
.as_slice_from(pstr_loc)
|
||||||
|
.take_while(|b| *b != 0u8)
|
||||||
|
.count();
|
||||||
|
|
||||||
*self.value_at_scan() = pstr_loc_as_cell!(heap_index!(threshold) + pstr_offset);
|
let left_pstr_boundary = cell_index!(pstr_loc + offset);
|
||||||
|
let flag = u64::from_be_bytes(self.target[left_pstr_boundary].into_bytes());
|
||||||
|
let pstr_loc_idx = cell_index!(pstr_loc);
|
||||||
|
|
||||||
self.trail.push((Ref::heap_cell(head_cell_idx), self.target[head_cell_idx]));
|
if flag == 1 {
|
||||||
self.write_pstr_index(head_cell_idx, threshold);
|
if left_pstr_boundary != pstr_loc_idx {
|
||||||
|
let mut pstr_data = self
|
||||||
|
.pstr_loc_locs
|
||||||
|
.remove(&heap_index!(left_pstr_boundary))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let tail_cell = self.target[tail_loc];
|
pstr_data.post_old_h_pstr_loc_locs.insert(self.scan);
|
||||||
let mut writer = self.target.reserve(1)?;
|
self.pstr_loc_locs
|
||||||
|
.insert(heap_index!(cell_index!(pstr_loc)), pstr_data);
|
||||||
|
|
||||||
writer.write_with(|section| {
|
let old_cell = self.target[pstr_loc_idx];
|
||||||
section.push_cell(tail_cell);
|
self.target[pstr_loc_idx] = HeapCellValue::from_bytes(u64::to_be_bytes(1));
|
||||||
});
|
self.trail
|
||||||
|
.push((TrailRef::pstr_loc(pstr_loc_idx), old_cell));
|
||||||
|
} else {
|
||||||
|
let pstr_data = self
|
||||||
|
.pstr_loc_locs
|
||||||
|
.get_mut(&heap_index!(left_pstr_boundary))
|
||||||
|
.unwrap();
|
||||||
|
pstr_data.post_old_h_pstr_loc_locs.insert(self.scan);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let old_cell = self.target[pstr_loc_idx];
|
||||||
|
self.target[pstr_loc_idx] = HeapCellValue::from_bytes(u64::to_be_bytes(1));
|
||||||
|
self.trail
|
||||||
|
.push((TrailRef::pstr_loc(pstr_loc_idx), old_cell));
|
||||||
|
|
||||||
|
let old_tail_idx = if (pstr_loc + offset + 1) % Heap::heap_cell_alignment() == 0 {
|
||||||
|
cell_index!(pstr_loc + offset) + 2
|
||||||
|
} else {
|
||||||
|
cell_index!(pstr_loc + offset) + 1
|
||||||
|
};
|
||||||
|
|
||||||
|
let tail_cell = self.target[old_tail_idx];
|
||||||
|
|
||||||
|
let new_tail_idx = self.target.threshold();
|
||||||
|
let mut writer = self.target.reserve(1)?;
|
||||||
|
|
||||||
|
writer.write_with(|section| {
|
||||||
|
section.push_cell(tail_cell);
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut post_old_h_pstr_loc_locs = IndexSet::with_hasher(FxBuildHasher::default());
|
||||||
|
post_old_h_pstr_loc_locs.insert(self.scan);
|
||||||
|
|
||||||
|
let pstr_data = PStrData {
|
||||||
|
pre_old_h_tail_loc: old_tail_idx,
|
||||||
|
post_old_h_tail_loc: new_tail_idx,
|
||||||
|
post_old_h_pstr_loc_locs,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.pstr_loc_locs
|
||||||
|
.insert(heap_index!(pstr_loc_idx), pstr_data);
|
||||||
|
}
|
||||||
|
|
||||||
self.scan += 1;
|
self.scan += 1;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,6 +316,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
debug_assert_eq!(str_cell.get_tag(), HeapCellValueTag::Str);
|
debug_assert_eq!(str_cell.get_tag(), HeapCellValueTag::Str);
|
||||||
|
|
||||||
self.copy_term_impl(str_cell)?;
|
self.copy_term_impl(str_cell)?;
|
||||||
list_addr = self.target[heap_loc + 1];
|
list_addr = self.target[heap_loc + 1];
|
||||||
|
|
||||||
@@ -227,13 +334,13 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
self.target[frontier] = heap_loc_as_cell!(frontier);
|
self.target[frontier] = heap_loc_as_cell!(frontier);
|
||||||
self.target[h] = heap_loc_as_cell!(frontier);
|
self.target[h] = heap_loc_as_cell!(frontier);
|
||||||
|
|
||||||
self.trail.push((Ref::heap_cell(h), heap_loc_as_cell!(h)));
|
self.trail.push((TrailRef::heap_cell(h), heap_loc_as_cell!(h)));
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::StackVar, s) => {
|
(HeapCellValueTag::StackVar, s) => {
|
||||||
self.target[frontier] = heap_loc_as_cell!(frontier);
|
self.target[frontier] = heap_loc_as_cell!(frontier);
|
||||||
self.target.stack()[s] = heap_loc_as_cell!(frontier);
|
self.target.stack()[s] = heap_loc_as_cell!(frontier);
|
||||||
|
|
||||||
self.trail.push((Ref::stack_cell(s), stack_loc_as_cell!(s)));
|
self.trail.push((TrailRef::stack_cell(s), stack_loc_as_cell!(s)));
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::AttrVar, h) => {
|
(HeapCellValueTag::AttrVar, h) => {
|
||||||
let threshold = if let AttrVarPolicy::DeepCopy = self.attr_var_policy {
|
let threshold = if let AttrVarPolicy::DeepCopy = self.attr_var_policy {
|
||||||
@@ -245,10 +352,10 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
self.target[frontier] = heap_loc_as_cell!(threshold);
|
self.target[frontier] = heap_loc_as_cell!(threshold);
|
||||||
self.target[h] = heap_loc_as_cell!(threshold);
|
self.target[h] = heap_loc_as_cell!(threshold);
|
||||||
|
|
||||||
self.trail.push((Ref::attr_var(h), attr_var_as_cell!(h)));
|
self.trail.push((TrailRef::attr_var(h), attr_var_as_cell!(h)));
|
||||||
|
|
||||||
if let AttrVarPolicy::DeepCopy = self.attr_var_policy {
|
if let AttrVarPolicy::DeepCopy = self.attr_var_policy {
|
||||||
let mut writer = self.target.reserve(2).unwrap();
|
let mut writer = self.target.reserve(2)?;
|
||||||
|
|
||||||
writer.write_with(|section| {
|
writer.write_with(|section| {
|
||||||
section.push_cell(attr_var_as_cell!(threshold));
|
section.push_cell(attr_var_as_cell!(threshold));
|
||||||
@@ -256,7 +363,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let old_list_link = self.target[h + 1];
|
let old_list_link = self.target[h + 1];
|
||||||
self.trail.push((Ref::heap_cell(h + 1), old_list_link));
|
self.trail.push((TrailRef::heap_cell(h + 1), old_list_link));
|
||||||
self.target[h + 1] = heap_loc_as_cell!(threshold + 1);
|
self.target[h + 1] = heap_loc_as_cell!(threshold + 1);
|
||||||
|
|
||||||
if old_list_link.get_tag() == HeapCellValueTag::Lis {
|
if old_list_link.get_tag() == HeapCellValueTag::Lis {
|
||||||
@@ -317,7 +424,21 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
(HeapCellValueTag::Atom, (_name, arity)) => {
|
(HeapCellValueTag::Atom, (_name, arity)) => {
|
||||||
let threshold = self.target.threshold();
|
let threshold = self.target.threshold();
|
||||||
|
|
||||||
*self.value_at_scan() = str_loc_as_cell!(threshold);
|
let index_cell = self.target[addr.saturating_sub(1)];
|
||||||
|
|
||||||
|
*self.value_at_scan() = if get_structure_index(index_cell).is_some() {
|
||||||
|
// copy the index pointer trailing this
|
||||||
|
// inlined or expanded goal.
|
||||||
|
let mut writer = self.target.reserve(1).unwrap();
|
||||||
|
|
||||||
|
writer.write_with(|section| {
|
||||||
|
section.push_cell(index_cell);
|
||||||
|
});
|
||||||
|
|
||||||
|
str_loc_as_cell!(threshold + 1)
|
||||||
|
} else {
|
||||||
|
str_loc_as_cell!(threshold)
|
||||||
|
};
|
||||||
|
|
||||||
self.target.copy_slice_to_end(addr .. addr + 1 + arity)?;
|
self.target.copy_slice_to_end(addr .. addr + 1 + arity)?;
|
||||||
|
|
||||||
@@ -326,28 +447,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
str_loc_as_cell!(threshold),
|
str_loc_as_cell!(threshold),
|
||||||
);
|
);
|
||||||
|
|
||||||
self.trail.push((Ref::heap_cell(addr), trail_item));
|
self.trail.push((TrailRef::heap_cell(addr), trail_item));
|
||||||
/*
|
|
||||||
self.target.push(atom_as_cell!(name, arity));
|
|
||||||
|
|
||||||
for i in 0..arity {
|
|
||||||
let hcv = self.target[addr + 1 + i];
|
|
||||||
self.target.push(hcv);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if !self.target.pstr_at(addr + 1 + arity) {
|
|
||||||
let index_cell = self.target[addr + 1 + arity];
|
|
||||||
|
|
||||||
if get_structure_index(index_cell).is_some() {
|
|
||||||
// copy the index pointer trailing this
|
|
||||||
// inlined or expanded goal.
|
|
||||||
let mut writer = self.target.reserve(1).unwrap();
|
|
||||||
|
|
||||||
writer.write_with(|section| {
|
|
||||||
section.push_cell(index_cell);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Str, h) => {
|
(HeapCellValueTag::Str, h) => {
|
||||||
*self.value_at_scan() = str_loc_as_cell!(h);
|
*self.value_at_scan() = str_loc_as_cell!(h);
|
||||||
@@ -370,11 +470,6 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
while self.scan < self.target.threshold() {
|
while self.scan < self.target.threshold() {
|
||||||
if self.target.pstr_at(self.scan) {
|
|
||||||
self.scan = self.target.next_non_pstr_cell_index(self.scan);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let addr = *self.value_at_scan();
|
let addr = *self.value_at_scan();
|
||||||
|
|
||||||
read_heap_cell!(addr,
|
read_heap_cell!(addr,
|
||||||
@@ -405,17 +500,40 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unwind_trail(mut self) {
|
fn copy_pstrs(&mut self) -> Result<(), usize> {
|
||||||
for (r, value) in self.trail {
|
while let Some((least_pstr_loc, pstr_data)) = self.pstr_loc_locs.pop_first() {
|
||||||
let index = r.get_value() as usize;
|
let threshold = heap_index!(self.target.threshold());
|
||||||
|
|
||||||
match r.get_tag() {
|
for pstr_loc_loc in pstr_data.post_old_h_pstr_loc_locs {
|
||||||
RefTag::AttrVar | RefTag::HeapCell => {
|
let pstr_loc = self.target[pstr_loc_loc].get_value() as usize;
|
||||||
|
self.target[pstr_loc_loc] =
|
||||||
|
pstr_loc_as_cell!(threshold + pstr_loc - least_pstr_loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.target.copy_pstr_to_threshold(least_pstr_loc)?;
|
||||||
|
|
||||||
|
let mut writer = self.target.reserve(1)?;
|
||||||
|
|
||||||
|
writer.write_with(|section| {
|
||||||
|
section.push_cell(heap_loc_as_cell!(pstr_data.post_old_h_tail_loc));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unwind_trail(&mut self) {
|
||||||
|
for (r, value) in self.trail.drain(..) {
|
||||||
|
let index = r.val() as usize;
|
||||||
|
|
||||||
|
match r.tag() {
|
||||||
|
TrailRefTag::AttrVar | TrailRefTag::HeapCell => {
|
||||||
self.target[index] = value;
|
self.target[index] = value;
|
||||||
self.target[index].set_mark_bit(false);
|
self.target[index].set_mark_bit(false);
|
||||||
self.target[index].set_forwarding_bit(false);
|
self.target[index].set_forwarding_bit(false);
|
||||||
}
|
}
|
||||||
RefTag::StackCell => self.target.stack()[index] = value,
|
TrailRefTag::StackCell => self.target.stack()[index] = value,
|
||||||
|
TrailRefTag::PStrLoc => self.target[index] = value,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -438,9 +556,10 @@ mod tests {
|
|||||||
let a_atom = atom!("a");
|
let a_atom = atom!("a");
|
||||||
let b_atom = atom!("b");
|
let b_atom = atom!("b");
|
||||||
|
|
||||||
let mut functor_writer = Heap::functor_writer(
|
let mut functor_writer = Heap::functor_writer(functor!(
|
||||||
functor!(f_atom, [atom_as_cell(a_atom), atom_as_cell(b_atom)]),
|
f_atom,
|
||||||
);
|
[atom_as_cell(a_atom), atom_as_cell(b_atom)]
|
||||||
|
));
|
||||||
|
|
||||||
functor_writer(&mut wam.machine_st.heap).unwrap();
|
functor_writer(&mut wam.machine_st.heap).unwrap();
|
||||||
|
|
||||||
@@ -480,29 +599,233 @@ mod tests {
|
|||||||
copy_term(wam, pstr_loc_as_cell!(0), AttrVarPolicy::DeepCopy).unwrap();
|
copy_term(wam, pstr_loc_as_cell!(0), AttrVarPolicy::DeepCopy).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(wam.machine_st.heap.slice_to_str(0, "abc ".len()), "abc ");
|
||||||
wam.machine_st.heap.slice_to_str(0, "abc ".len()),
|
|
||||||
"abc "
|
|
||||||
);
|
|
||||||
assert_eq!(wam.machine_st.heap[1], pstr_loc_as_cell!(heap_index!(2)));
|
assert_eq!(wam.machine_st.heap[1], pstr_loc_as_cell!(heap_index!(2)));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
wam.machine_st.heap.slice_to_str(heap_index!(2), "def".len()),
|
wam.machine_st
|
||||||
|
.heap
|
||||||
|
.slice_to_str(heap_index!(2), "def".len()),
|
||||||
"def"
|
"def"
|
||||||
);
|
);
|
||||||
assert_eq!(wam.machine_st.heap[3], pstr_loc_as_cell!(0));
|
assert_eq!(wam.machine_st.heap[3], pstr_loc_as_cell!(0));
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.heap[4], pstr_loc_as_cell!(heap_index!(5)));
|
assert_eq!(wam.machine_st.heap[4], pstr_loc_as_cell!(heap_index!(7)));
|
||||||
|
assert_eq!(wam.machine_st.heap[5], pstr_loc_as_cell!(heap_index!(9)));
|
||||||
|
assert_eq!(wam.machine_st.heap[6], pstr_loc_as_cell!(heap_index!(7)));
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
wam.machine_st.heap.slice_to_str(heap_index!(5), "abc ".len()),
|
wam.machine_st
|
||||||
|
.heap
|
||||||
|
.slice_to_str(heap_index!(7), "abc ".len()),
|
||||||
"abc "
|
"abc "
|
||||||
);
|
);
|
||||||
assert_eq!(wam.machine_st.heap[6], pstr_loc_as_cell!(heap_index!(7)));
|
assert_eq!(wam.machine_st.heap[8], heap_loc_as_cell!(5));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
wam.machine_st.heap.slice_to_str(heap_index!(7), "def".len()),
|
wam.machine_st
|
||||||
|
.heap
|
||||||
|
.slice_to_str(heap_index!(9), "def".len()),
|
||||||
"def"
|
"def"
|
||||||
);
|
);
|
||||||
assert_eq!(wam.machine_st.heap[8], pstr_loc_as_cell!(heap_index!(5)));
|
assert_eq!(wam.machine_st.heap[10], heap_loc_as_cell!(6));
|
||||||
|
|
||||||
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
|
let mut writer = wam.machine_st.heap.reserve(4).unwrap();
|
||||||
|
|
||||||
|
writer.write_with(|section| {
|
||||||
|
section.push_pstr("abc ");
|
||||||
|
section.push_cell(pstr_loc_as_cell!(heap_index!(2) + 9));
|
||||||
|
|
||||||
|
section.push_pstr("defdefdefdef");
|
||||||
|
section.push_cell(pstr_loc_as_cell!(0));
|
||||||
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
let wam = TermCopyingMockWAM { wam: &mut wam };
|
||||||
|
copy_term(wam, pstr_loc_as_cell!(0), AttrVarPolicy::DeepCopy).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(wam.machine_st.heap.slice_to_str(0, "abc ".len()), "abc ");
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st.heap[1],
|
||||||
|
pstr_loc_as_cell!(heap_index!(2) + 9)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st
|
||||||
|
.heap
|
||||||
|
.slice_to_str(heap_index!(2), "defdefdefdef".len()),
|
||||||
|
"defdefdefdef"
|
||||||
|
);
|
||||||
|
assert_eq!(wam.machine_st.heap[4], pstr_loc_as_cell!(0));
|
||||||
|
|
||||||
|
assert_eq!(wam.machine_st.heap[5], pstr_loc_as_cell!(heap_index!(8)));
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st.heap[6],
|
||||||
|
pstr_loc_as_cell!(heap_index!(10) + 1)
|
||||||
|
);
|
||||||
|
assert_eq!(wam.machine_st.heap[7], pstr_loc_as_cell!(heap_index!(8)));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st
|
||||||
|
.heap
|
||||||
|
.slice_to_str(heap_index!(8), "abc ".len()),
|
||||||
|
"abc "
|
||||||
|
);
|
||||||
|
assert_eq!(wam.machine_st.heap[9], heap_loc_as_cell!(6));
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st
|
||||||
|
.heap
|
||||||
|
.slice_to_str(heap_index!(10), "fdef".len()),
|
||||||
|
"fdef"
|
||||||
|
);
|
||||||
|
assert_eq!(wam.machine_st.heap[11], heap_loc_as_cell!(7));
|
||||||
|
|
||||||
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
|
let mut writer = wam.machine_st.heap.reserve(4).unwrap();
|
||||||
|
|
||||||
|
writer.write_with(|section| {
|
||||||
|
section.push_pstr("012345678912345");
|
||||||
|
section.push_cell(pstr_loc_as_cell!(heap_index!(0)));
|
||||||
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
let wam = TermCopyingMockWAM { wam: &mut wam };
|
||||||
|
copy_term(wam, pstr_loc_as_cell!(0), AttrVarPolicy::DeepCopy).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st.heap.slice_to_str(0, "012345678912345".len()),
|
||||||
|
"012345678912345"
|
||||||
|
);
|
||||||
|
assert_eq!(wam.machine_st.heap[3], pstr_loc_as_cell!(heap_index!(0)));
|
||||||
|
|
||||||
|
assert_eq!(wam.machine_st.heap[4], pstr_loc_as_cell!(heap_index!(6)));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st
|
||||||
|
.heap
|
||||||
|
.slice_to_str(heap_index!(6), "012345678912345".len()),
|
||||||
|
"012345678912345"
|
||||||
|
);
|
||||||
|
assert_eq!(wam.machine_st.heap[5], pstr_loc_as_cell!(heap_index!(6)));
|
||||||
|
|
||||||
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
|
let mut writer = wam.machine_st.heap.reserve(4).unwrap();
|
||||||
|
|
||||||
|
writer.write_with(|section| {
|
||||||
|
section.push_pstr("012345678912345");
|
||||||
|
section.push_cell(pstr_loc_as_cell!(heap_index!(0) + 9));
|
||||||
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
let wam = TermCopyingMockWAM { wam: &mut wam };
|
||||||
|
copy_term(wam, pstr_loc_as_cell!(0), AttrVarPolicy::DeepCopy).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st.heap.slice_to_str(0, "012345678912345".len()),
|
||||||
|
"012345678912345"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st.heap[3],
|
||||||
|
pstr_loc_as_cell!(heap_index!(0) + 9)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(wam.machine_st.heap[4], pstr_loc_as_cell!(heap_index!(6)));
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st.heap[5],
|
||||||
|
pstr_loc_as_cell!(heap_index!(6) + 9)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st
|
||||||
|
.heap
|
||||||
|
.slice_to_str(heap_index!(6), "012345678912345".len()),
|
||||||
|
"012345678912345"
|
||||||
|
);
|
||||||
|
assert_eq!(wam.machine_st.heap[9], heap_loc_as_cell!(5));
|
||||||
|
|
||||||
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
|
let mut writer = wam.machine_st.heap.reserve(4).unwrap();
|
||||||
|
|
||||||
|
writer.write_with(|section| {
|
||||||
|
section.push_pstr("012345678912345");
|
||||||
|
section.push_cell(pstr_loc_as_cell!(heap_index!(0) + 7));
|
||||||
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
let wam = TermCopyingMockWAM { wam: &mut wam };
|
||||||
|
copy_term(wam, pstr_loc_as_cell!(11), AttrVarPolicy::DeepCopy).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st.heap.slice_to_str(0, "012345678912345".len()),
|
||||||
|
"012345678912345"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st.heap[3],
|
||||||
|
pstr_loc_as_cell!(heap_index!(0) + 7)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st.heap[4],
|
||||||
|
pstr_loc_as_cell!(heap_index!(6) + 11)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st.heap[5],
|
||||||
|
pstr_loc_as_cell!(heap_index!(6) + 7)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st
|
||||||
|
.heap
|
||||||
|
.slice_to_str(heap_index!(6), "012345678912345".len()),
|
||||||
|
"012345678912345"
|
||||||
|
);
|
||||||
|
assert_eq!(wam.machine_st.heap[9], heap_loc_as_cell!(5));
|
||||||
|
|
||||||
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
|
let mut writer = wam.machine_st.heap.reserve(4).unwrap();
|
||||||
|
|
||||||
|
writer.write_with(|section| {
|
||||||
|
section.push_pstr("012345678912345");
|
||||||
|
section.push_cell(pstr_loc_as_cell!(heap_index!(0) + 12));
|
||||||
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
let wam = TermCopyingMockWAM { wam: &mut wam };
|
||||||
|
copy_term(wam, pstr_loc_as_cell!(11), AttrVarPolicy::DeepCopy).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st.heap.slice_to_str(0, "012345678912345".len()),
|
||||||
|
"012345678912345"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st.heap[3],
|
||||||
|
pstr_loc_as_cell!(heap_index!(0) + 12)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st.heap[4],
|
||||||
|
pstr_loc_as_cell!(heap_index!(6) + 3)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st.heap[5],
|
||||||
|
pstr_loc_as_cell!(heap_index!(6) + 4)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
wam.machine_st
|
||||||
|
.heap
|
||||||
|
.slice_to_str(heap_index!(6), "8912345".len()),
|
||||||
|
"8912345"
|
||||||
|
);
|
||||||
|
assert_eq!(wam.machine_st.heap[8], heap_loc_as_cell!(5));
|
||||||
|
|
||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
@@ -528,7 +851,6 @@ mod tests {
|
|||||||
assert_eq!(wam.machine_st.heap[2], atom_as_cell!(b_atom));
|
assert_eq!(wam.machine_st.heap[2], atom_as_cell!(b_atom));
|
||||||
assert_eq!(wam.machine_st.heap[3], atom_as_cell!(a_atom));
|
assert_eq!(wam.machine_st.heap[3], atom_as_cell!(a_atom));
|
||||||
assert_eq!(wam.machine_st.heap[4], str_loc_as_cell!(0));
|
assert_eq!(wam.machine_st.heap[4], str_loc_as_cell!(0));
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.heap[5], str_loc_as_cell!(6));
|
assert_eq!(wam.machine_st.heap[5], str_loc_as_cell!(6));
|
||||||
assert_eq!(wam.machine_st.heap[6], atom_as_cell!(f_atom, 4));
|
assert_eq!(wam.machine_st.heap[6], atom_as_cell!(f_atom, 4));
|
||||||
assert_eq!(wam.machine_st.heap[7], atom_as_cell!(a_atom));
|
assert_eq!(wam.machine_st.heap[7], atom_as_cell!(a_atom));
|
||||||
|
|||||||
@@ -206,9 +206,9 @@ impl<'a, const STOP_AT_CYCLES: bool> CycleDetectingIter<'a, STOP_AT_CYCLES> {
|
|||||||
}
|
}
|
||||||
HeapCellValueTag::PStrLoc => {
|
HeapCellValueTag::PStrLoc => {
|
||||||
let h = self.next as usize;
|
let h = self.next as usize;
|
||||||
let (_, last_cell_loc) = self.heap.scan_slice_to_str(h);
|
let tail_idx = self.heap.scan_slice_to_str(h).tail_idx;
|
||||||
|
|
||||||
if self.heap[last_cell_loc].get_forwarding_bit() {
|
if self.heap[tail_idx].get_forwarding_bit() {
|
||||||
if self.cycle_detection_active() {
|
if self.cycle_detection_active() {
|
||||||
self.cycle_found = true;
|
self.cycle_found = true;
|
||||||
return None;
|
return None;
|
||||||
@@ -219,11 +219,11 @@ impl<'a, const STOP_AT_CYCLES: bool> CycleDetectingIter<'a, STOP_AT_CYCLES> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.heap[last_cell_loc].set_forwarding_bit(true);
|
self.heap[tail_idx].set_forwarding_bit(true);
|
||||||
|
|
||||||
self.next = self.heap[last_cell_loc].get_value();
|
self.next = self.heap[tail_idx].get_value();
|
||||||
self.heap[last_cell_loc].set_value(self.current as u64);
|
self.heap[tail_idx].set_value(self.current as u64);
|
||||||
self.current = last_cell_loc;
|
self.current = tail_idx;
|
||||||
|
|
||||||
return Some(pstr_loc_as_cell!(h));
|
return Some(pstr_loc_as_cell!(h));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ use crate::atom_table::*;
|
|||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
use crate::instructions::*;
|
use crate::instructions::*;
|
||||||
use crate::iterators::fact_iterator;
|
use crate::iterators::fact_iterator;
|
||||||
use crate::machine::Stack;
|
|
||||||
use crate::machine::heap::*;
|
use crate::machine::heap::*;
|
||||||
use crate::machine::loader::*;
|
use crate::machine::loader::*;
|
||||||
use crate::machine::machine_errors::CompilationError;
|
use crate::machine::machine_errors::CompilationError;
|
||||||
use crate::machine::preprocessor::*;
|
use crate::machine::preprocessor::*;
|
||||||
|
use crate::machine::Stack;
|
||||||
use crate::parser::ast::*;
|
use crate::parser::ast::*;
|
||||||
use crate::parser::dashu::Rational;
|
use crate::parser::dashu::Rational;
|
||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
@@ -229,7 +229,8 @@ impl VarLocsToNums {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, idx: VarPtrIndex) -> VarPtr {
|
pub fn get(&self, idx: VarPtrIndex) -> VarPtr {
|
||||||
self.map.get(&idx)
|
self.map
|
||||||
|
.get(&idx)
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(VarPtr::Numbered)
|
.map(VarPtr::Numbered)
|
||||||
.unwrap_or_else(|| VarPtr::Anon)
|
.unwrap_or_else(|| VarPtr::Anon)
|
||||||
@@ -260,8 +261,10 @@ impl VarData {
|
|||||||
|
|
||||||
if let Some(global_cut_var_num) = global_cut_var_num {
|
if let Some(global_cut_var_num) = global_cut_var_num {
|
||||||
let term = QueryTerm::GetLevel(global_cut_var_num);
|
let term = QueryTerm::GetLevel(global_cut_var_num);
|
||||||
self.records[global_cut_var_num].allocation =
|
self.records[global_cut_var_num].allocation = VarAlloc::Perm {
|
||||||
VarAlloc::Perm { reg: 0, allocation: PermVarAllocation::Pending };
|
reg: 0,
|
||||||
|
allocation: PermVarAllocation::Pending,
|
||||||
|
};
|
||||||
|
|
||||||
match build_stack.front_mut() {
|
match build_stack.front_mut() {
|
||||||
Some(ChunkedTerms::Branch(_)) => {
|
Some(ChunkedTerms::Branch(_)) => {
|
||||||
@@ -395,11 +398,7 @@ impl VariableClassifier {
|
|||||||
|
|
||||||
let mut lvl = Level::Shallow;
|
let mut lvl = Level::Shallow;
|
||||||
let mut stack = Stack::uninitialized();
|
let mut stack = Stack::uninitialized();
|
||||||
let mut iter = fact_iterator::<false>(
|
let mut iter = fact_iterator::<false>(term.heap, &mut stack, term.focus);
|
||||||
term.heap,
|
|
||||||
&mut stack,
|
|
||||||
term.focus,
|
|
||||||
);
|
|
||||||
|
|
||||||
// second arg is true to iterate the root, which may be a variable
|
// second arg is true to iterate the root, which may be a variable
|
||||||
while let Some(subterm) = iter.next() {
|
while let Some(subterm) = iter.next() {
|
||||||
@@ -425,8 +424,7 @@ impl VariableClassifier {
|
|||||||
|
|
||||||
fn probe_body_var(&mut self, context: GenContext, var_info: VarInfo) {
|
fn probe_body_var(&mut self, context: GenContext, var_info: VarInfo) {
|
||||||
let chunk_num = context.chunk_num();
|
let chunk_num = context.chunk_num();
|
||||||
let branch_info_v = self.branch_map.entry(var_info.var)
|
let branch_info_v = self.branch_map.entry(var_info.var).or_default();
|
||||||
.or_default();
|
|
||||||
|
|
||||||
let needs_new_branch = if let Some(last_bi) = branch_info_v.last() {
|
let needs_new_branch = if let Some(last_bi) = branch_info_v.last() {
|
||||||
!self.root_set.contains(&last_bi.branch_num)
|
!self.root_set.contains(&last_bi.branch_num)
|
||||||
@@ -489,14 +487,10 @@ impl VariableClassifier {
|
|||||||
|
|
||||||
debug_assert_eq!(value.get_tag(), HeapCellValueTag::Str);
|
debug_assert_eq!(value.get_tag(), HeapCellValueTag::Str);
|
||||||
|
|
||||||
for idx in str_offset + 1 ..= str_offset + arity {
|
for idx in str_offset + 1..=str_offset + arity {
|
||||||
let mut lvl = Level::Shallow;
|
let mut lvl = Level::Shallow;
|
||||||
let mut stack = Stack::uninitialized();
|
let mut stack = Stack::uninitialized();
|
||||||
let mut iter = fact_iterator::<false>(
|
let mut iter = fact_iterator::<false>(heap, &mut stack, idx);
|
||||||
heap,
|
|
||||||
&mut stack,
|
|
||||||
idx,
|
|
||||||
);
|
|
||||||
|
|
||||||
while let Some(subterm) = iter.next() {
|
while let Some(subterm) = iter.next() {
|
||||||
if !subterm.is_var() {
|
if !subterm.is_var() {
|
||||||
@@ -661,13 +655,14 @@ impl VariableClassifier {
|
|||||||
mut term_loc,
|
mut term_loc,
|
||||||
} => {
|
} => {
|
||||||
// return true iff new chunk should be added.
|
// return true iff new chunk should be added.
|
||||||
let update_chunk_data = |build_stack: &mut ChunkedTermVec, key: PredicateKey| {
|
let update_chunk_data =
|
||||||
if ClauseType::is_inlined(key.0, key.1) {
|
|build_stack: &mut ChunkedTermVec, key: PredicateKey| {
|
||||||
build_stack.try_set_chunk_at_inlined_boundary()
|
if ClauseType::is_inlined(key.0, key.1) {
|
||||||
} else {
|
build_stack.try_set_chunk_at_inlined_boundary()
|
||||||
build_stack.try_set_chunk_at_call_boundary()
|
} else {
|
||||||
}
|
build_stack.try_set_chunk_at_call_boundary()
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
macro_rules! add_chunk {
|
macro_rules! add_chunk {
|
||||||
($key:expr, $tag:expr, $term_loc:expr) => {{
|
($key:expr, $tag:expr, $term_loc:expr) => {{
|
||||||
@@ -678,9 +673,10 @@ impl VariableClassifier {
|
|||||||
let context = build_stack.current_gen_context();
|
let context = build_stack.current_gen_context();
|
||||||
|
|
||||||
for (arg_c, term_loc) in
|
for (arg_c, term_loc) in
|
||||||
($term_loc + 1 ..= $term_loc + $key.1).enumerate()
|
($term_loc + 1..=$term_loc + $key.1).enumerate()
|
||||||
{
|
{
|
||||||
let mut term = FocusedHeapRefMut::from(loader.machine_heap(), term_loc);
|
let mut term =
|
||||||
|
FocusedHeapRefMut::from(loader.machine_heap(), term_loc);
|
||||||
|
|
||||||
self.probe_body_term(
|
self.probe_body_term(
|
||||||
arg_c + 1,
|
arg_c + 1,
|
||||||
@@ -710,9 +706,10 @@ impl VariableClassifier {
|
|||||||
let context = build_stack.current_gen_context();
|
let context = build_stack.current_gen_context();
|
||||||
|
|
||||||
for (arg_c, term_loc) in
|
for (arg_c, term_loc) in
|
||||||
($term_loc + 1 ..= $term_loc + $key.1).enumerate()
|
($term_loc + 1..=$term_loc + $key.1).enumerate()
|
||||||
{
|
{
|
||||||
let mut term = FocusedHeapRefMut::from(loader.machine_heap(), term_loc);
|
let mut term =
|
||||||
|
FocusedHeapRefMut::from(loader.machine_heap(), term_loc);
|
||||||
|
|
||||||
self.probe_body_term(
|
self.probe_body_term(
|
||||||
arg_c + 1,
|
arg_c + 1,
|
||||||
@@ -1043,8 +1040,8 @@ impl BranchMap {
|
|||||||
|
|
||||||
for (var, branches) in self.iter_mut() {
|
for (var, branches) in self.iter_mut() {
|
||||||
let (mut var_num, var_num_incr) = match var {
|
let (mut var_num, var_num_incr) = match var {
|
||||||
&ClassifiedVar::InSitu { var_num} => (var_num, false),
|
&ClassifiedVar::InSitu { var_num } => (var_num, false),
|
||||||
_ => (var_data.records.len(), true)
|
_ => (var_data.records.len(), true),
|
||||||
};
|
};
|
||||||
|
|
||||||
for branch in branches.iter_mut() {
|
for branch in branches.iter_mut() {
|
||||||
@@ -1088,7 +1085,10 @@ impl BranchMap {
|
|||||||
let chunk_num = chunk.term_loc.chunk_num();
|
let chunk_num = chunk.term_loc.chunk_num();
|
||||||
|
|
||||||
var_data.var_locs_to_nums.insert(
|
var_data.var_locs_to_nums.insert(
|
||||||
VarPtrIndex { chunk_num, term_loc },
|
VarPtrIndex {
|
||||||
|
chunk_num,
|
||||||
|
term_loc,
|
||||||
|
},
|
||||||
var_num,
|
var_num,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,10 +140,7 @@ impl MachineState {
|
|||||||
let a1 = self.registers[1];
|
let a1 = self.registers[1];
|
||||||
let a2 = self.registers[2];
|
let a2 = self.registers[2];
|
||||||
|
|
||||||
step_or_resource_error!(
|
step_or_resource_error!(self, copy_term(CopyTerm::new(self), a1, attr_var_policy));
|
||||||
self,
|
|
||||||
copy_term(CopyTerm::new(self), a1, attr_var_policy)
|
|
||||||
);
|
|
||||||
|
|
||||||
unify_fn!(*self, heap_loc_as_cell!(old_h), a2);
|
unify_fn!(*self, heap_loc_as_cell!(old_h), a2);
|
||||||
}
|
}
|
||||||
@@ -162,11 +159,7 @@ impl MachineState {
|
|||||||
|
|
||||||
let heap_addr = resource_error_call_result!(
|
let heap_addr = resource_error_call_result!(
|
||||||
self,
|
self,
|
||||||
sized_iter_to_heap_list(
|
sized_iter_to_heap_list(&mut self.heap, list.len(), list.into_iter(),)
|
||||||
&mut self.heap,
|
|
||||||
list.len(),
|
|
||||||
list.into_iter(),
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let target_addr = self.registers[2];
|
let target_addr = self.registers[2];
|
||||||
@@ -5155,9 +5148,8 @@ impl Machine {
|
|||||||
let r = self.machine_st.registers[2];
|
let r = self.machine_st.registers[2];
|
||||||
let r = self.machine_st.store(self.machine_st.deref(r));
|
let r = self.machine_st.store(self.machine_st.deref(r));
|
||||||
|
|
||||||
let mut writer = Heap::functor_writer(
|
let mut writer =
|
||||||
functor!(atom!("-"), [fixnum(n), fixnum(p)]),
|
Heap::functor_writer(functor!(atom!("-"), [fixnum(n), fixnum(p)]));
|
||||||
);
|
|
||||||
|
|
||||||
let str_cell = backtrack_on_resource_error!(
|
let str_cell = backtrack_on_resource_error!(
|
||||||
&mut self.machine_st,
|
&mut self.machine_st,
|
||||||
@@ -5178,9 +5170,8 @@ impl Machine {
|
|||||||
let r = self.machine_st.registers[2];
|
let r = self.machine_st.registers[2];
|
||||||
let r = self.machine_st.store(self.machine_st.deref(r));
|
let r = self.machine_st.store(self.machine_st.deref(r));
|
||||||
|
|
||||||
let mut writer = Heap::functor_writer(
|
let mut writer =
|
||||||
functor!(atom!("-"), [fixnum(n), fixnum(p)]),
|
Heap::functor_writer(functor!(atom!("-"), [fixnum(n), fixnum(p)]));
|
||||||
);
|
|
||||||
|
|
||||||
let str_cell = backtrack_on_resource_error!(
|
let str_cell = backtrack_on_resource_error!(
|
||||||
&mut self.machine_st,
|
&mut self.machine_st,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,22 +5,17 @@ use crate::types::*;
|
|||||||
|
|
||||||
use std::alloc;
|
use std::alloc;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::mem;
|
|
||||||
use std::ops::{Bound, Index, IndexMut, Range, RangeBounds};
|
use std::ops::{Bound, Index, IndexMut, Range, RangeBounds};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
|
|
||||||
use super::MachineState;
|
use super::MachineState;
|
||||||
|
|
||||||
use bitvec::prelude::*;
|
|
||||||
use bitvec::slice::BitSlice;
|
|
||||||
|
|
||||||
const ALIGN: usize = Heap::heap_cell_alignment();
|
const ALIGN: usize = Heap::heap_cell_alignment();
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Heap {
|
pub struct Heap {
|
||||||
inner: InnerHeap,
|
inner: InnerHeap,
|
||||||
pstr_vec: BitVec,
|
|
||||||
resource_err_loc: usize,
|
resource_err_loc: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,40 +85,51 @@ unsafe impl Sync for Heap {}
|
|||||||
|
|
||||||
static RESOURCE_ERROR_OFFSET_INIT: Once = Once::new();
|
static RESOURCE_ERROR_OFFSET_INIT: Once = Once::new();
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct HeapStringScan<'a> {
|
||||||
|
pub string: &'a str,
|
||||||
|
pub tail_idx: usize,
|
||||||
|
}
|
||||||
|
|
||||||
// return the string at ptr and the tail location relative to ptr.
|
// return the string at ptr and the tail location relative to ptr.
|
||||||
// pstr_vec records the location of each string cell starting at index
|
unsafe fn scan_slice_to_str<'a>(heap_slice: &'a [u8]) -> HeapStringScan<'a> {
|
||||||
// 0.
|
let string_len = heap_slice.iter().position(|b| *b == 0u8).unwrap();
|
||||||
fn scan_slice_to_str(orig_ptr: *const u8, pstr_vec: &BitSlice) -> (&str, usize) {
|
let zero_byte_addr = heap_slice.as_ptr().add(string_len);
|
||||||
unsafe {
|
let sentinel_len = pstr_sentinel_length(zero_byte_addr as usize);
|
||||||
debug_assert_eq!(pstr_vec[0], true);
|
let tail_idx = cell_index!(
|
||||||
|
(string_len + sentinel_len).next_multiple_of(ALIGN)
|
||||||
|
+ if sentinel_len <= 1 { heap_index!(1) } else { 0 }
|
||||||
|
);
|
||||||
|
|
||||||
let tail_cell_offset = pstr_vec[0..].first_zero().unwrap();
|
let str_slice = &heap_slice[..string_len];
|
||||||
let offset = (ALIGN - orig_ptr.align_offset(ALIGN)) % 8;
|
|
||||||
let buf_len = heap_index!(tail_cell_offset) - offset;
|
|
||||||
let slice = std::slice::from_raw_parts(orig_ptr, buf_len);
|
|
||||||
|
|
||||||
// skip the final buffer byte which may not be 0 depending on
|
HeapStringScan {
|
||||||
// the context, i.e. marking by an iterator. it is counted by
|
string: std::str::from_utf8_unchecked(str_slice),
|
||||||
// the initial 1 as part of the padding but for this reason
|
tail_idx,
|
||||||
// mustn't be allowed to stop the count.
|
|
||||||
|
|
||||||
let padding_len = 1 + slice.iter()
|
|
||||||
.rev()
|
|
||||||
.skip(1)
|
|
||||||
.position(|b| *b != 0u8)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let s_len = slice.len() - padding_len;
|
|
||||||
(std::str::from_utf8_unchecked(&slice[0 .. s_len]), tail_cell_offset)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub(crate) enum PStrSegmentCmpResult {
|
pub(crate) enum PStrSegmentCmpResult {
|
||||||
Mismatch { c1: char, c2: char },
|
Mismatch {
|
||||||
FirstMatch { pstr_loc1: usize, pstr_loc2: usize, l1_offset: usize },
|
c1: char,
|
||||||
SecondMatch { pstr_loc1: usize, pstr_loc2: usize, l2_offset: usize },
|
c2: char,
|
||||||
BothMatch { pstr_loc1: usize, pstr_loc2: usize, null_offset: usize },
|
},
|
||||||
|
FirstMatch {
|
||||||
|
pstr_loc1: usize,
|
||||||
|
pstr_loc2: usize,
|
||||||
|
l1_offset: usize,
|
||||||
|
},
|
||||||
|
SecondMatch {
|
||||||
|
pstr_loc1: usize,
|
||||||
|
pstr_loc2: usize,
|
||||||
|
l2_offset: usize,
|
||||||
|
},
|
||||||
|
BothMatch {
|
||||||
|
pstr_loc1: usize,
|
||||||
|
pstr_loc2: usize,
|
||||||
|
null_offset: usize,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PStrSegmentCmpResult {
|
impl PStrSegmentCmpResult {
|
||||||
@@ -132,24 +138,36 @@ impl PStrSegmentCmpResult {
|
|||||||
pdl: &mut Vec<HeapCellValue>,
|
pdl: &mut Vec<HeapCellValue>,
|
||||||
) -> Option<std::cmp::Ordering> {
|
) -> Option<std::cmp::Ordering> {
|
||||||
match self {
|
match self {
|
||||||
PStrSegmentCmpResult::FirstMatch { pstr_loc1, pstr_loc2, l1_offset } => {
|
PStrSegmentCmpResult::FirstMatch {
|
||||||
let tail1 = Heap::neighboring_cell_offset(pstr_loc1 + l1_offset);
|
pstr_loc1,
|
||||||
|
pstr_loc2,
|
||||||
|
l1_offset,
|
||||||
|
} => {
|
||||||
|
let tail1 = Heap::pstr_tail_idx(pstr_loc1 + l1_offset);
|
||||||
let rest_of_l2 = pstr_loc_as_cell!(pstr_loc2 + l1_offset);
|
let rest_of_l2 = pstr_loc_as_cell!(pstr_loc2 + l1_offset);
|
||||||
|
|
||||||
pdl.push(heap_loc_as_cell!(tail1));
|
pdl.push(heap_loc_as_cell!(tail1));
|
||||||
pdl.push(rest_of_l2);
|
pdl.push(rest_of_l2);
|
||||||
}
|
}
|
||||||
PStrSegmentCmpResult::SecondMatch { pstr_loc1, pstr_loc2, l2_offset } => {
|
PStrSegmentCmpResult::SecondMatch {
|
||||||
let tail2 = Heap::neighboring_cell_offset(pstr_loc2 + l2_offset);
|
pstr_loc1,
|
||||||
|
pstr_loc2,
|
||||||
|
l2_offset,
|
||||||
|
} => {
|
||||||
|
let tail2 = Heap::pstr_tail_idx(pstr_loc2 + l2_offset);
|
||||||
let rest_of_l1 = pstr_loc_as_cell!(pstr_loc1 + l2_offset);
|
let rest_of_l1 = pstr_loc_as_cell!(pstr_loc1 + l2_offset);
|
||||||
|
|
||||||
pdl.push(rest_of_l1);
|
pdl.push(rest_of_l1);
|
||||||
pdl.push(heap_loc_as_cell!(tail2));
|
pdl.push(heap_loc_as_cell!(tail2));
|
||||||
}
|
}
|
||||||
PStrSegmentCmpResult::BothMatch { pstr_loc1, pstr_loc2, null_offset } => {
|
PStrSegmentCmpResult::BothMatch {
|
||||||
|
pstr_loc1,
|
||||||
|
pstr_loc2,
|
||||||
|
null_offset,
|
||||||
|
} => {
|
||||||
// exhaustive match
|
// exhaustive match
|
||||||
let tail1 = Heap::neighboring_cell_offset(pstr_loc1 + null_offset);
|
let tail1 = Heap::pstr_tail_idx(pstr_loc1 + null_offset);
|
||||||
let tail2 = Heap::neighboring_cell_offset(pstr_loc2 + null_offset);
|
let tail2 = Heap::pstr_tail_idx(pstr_loc2 + null_offset);
|
||||||
|
|
||||||
pdl.push(heap_loc_as_cell!(tail1));
|
pdl.push(heap_loc_as_cell!(tail1));
|
||||||
pdl.push(heap_loc_as_cell!(tail2));
|
pdl.push(heap_loc_as_cell!(tail2));
|
||||||
@@ -163,162 +181,18 @@ impl PStrSegmentCmpResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub(crate) struct HeapView<'a> {
|
|
||||||
slice: *const u8,
|
|
||||||
cell_offset: usize,
|
|
||||||
slice_cell_len: usize,
|
|
||||||
pstr_slice: &'a BitSlice,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> HeapView<'a> {
|
|
||||||
/*
|
|
||||||
pub fn get(&self, idx: usize) -> Option<HeapCellValue> {
|
|
||||||
if idx < self.slice_cell_len {
|
|
||||||
Some(*self.index(idx))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
fn iter_follow(&mut self) -> Option<HeapCellValue> {
|
|
||||||
if self.slice_cell_len == 0 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
let cell;
|
|
||||||
|
|
||||||
if self.pstr_slice[0] {
|
|
||||||
cell = pstr_loc_as_cell!(heap_index!(self.cell_offset));
|
|
||||||
let next_cell_idx = self.pstr_slice[0 ..].first_zero().unwrap();
|
|
||||||
|
|
||||||
unsafe { self.slice = self.slice.add(heap_index!(next_cell_idx)); }
|
|
||||||
self.slice_cell_len -= next_cell_idx;
|
|
||||||
self.cell_offset += next_cell_idx;
|
|
||||||
self.pstr_slice = &self.pstr_slice[next_cell_idx ..];
|
|
||||||
} else {
|
|
||||||
unsafe {
|
|
||||||
cell = ptr::read(self.slice as *mut HeapCellValue);
|
|
||||||
self.slice = self.slice.add(heap_index!(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.cell_offset += 1;
|
|
||||||
self.slice_cell_len -= 1;
|
|
||||||
self.pstr_slice = &self.pstr_slice[1 ..];
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(cell)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Iterator for HeapView<'a> {
|
|
||||||
type Item = HeapCellValue;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
self.iter_follow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Index<usize> for HeapView<'a> {
|
|
||||||
type Output = HeapCellValue;
|
|
||||||
|
|
||||||
fn index(&self, idx: usize) -> &Self::Output {
|
|
||||||
debug_assert!(idx < self.slice_cell_len);
|
|
||||||
unsafe {
|
|
||||||
&*(self.slice.add(heap_index!(idx)) as *const HeapCellValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub(crate) struct HeapViewMut<'a> {
|
|
||||||
slice: *mut u8,
|
|
||||||
cell_offset: usize,
|
|
||||||
slice_cell_len: usize,
|
|
||||||
pstr_slice: &'a BitSlice,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> HeapViewMut<'a> {
|
|
||||||
fn iter_follow(&mut self) -> Option<&'a mut HeapCellValue> {
|
|
||||||
if self.slice_cell_len == 0 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
let cell;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
if self.pstr_slice[0] {
|
|
||||||
let next_cell_idx = self.pstr_slice[0 ..].first_zero().unwrap();
|
|
||||||
|
|
||||||
unsafe { self.slice = self.slice.add(heap_index!(next_cell_idx)); }
|
|
||||||
|
|
||||||
self.slice_cell_len -= next_cell_idx;
|
|
||||||
self.cell_offset += next_cell_idx;
|
|
||||||
self.pstr_slice = &self.pstr_slice[next_cell_idx ..];
|
|
||||||
} else {
|
|
||||||
unsafe {
|
|
||||||
cell = &mut *(self.slice as *mut HeapCellValue);
|
|
||||||
self.slice = self.slice.add(heap_index!(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.cell_offset += 1;
|
|
||||||
self.slice_cell_len -= 1;
|
|
||||||
self.pstr_slice = &self.pstr_slice[1 ..];
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(cell)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
impl<'a> Index<usize> for HeapViewMut<'a> {
|
|
||||||
type Output = HeapCellValue;
|
|
||||||
|
|
||||||
fn index(&self, idx: usize) -> &Self::Output {
|
|
||||||
debug_assert!(idx < self.slice_cell_len);
|
|
||||||
unsafe {
|
|
||||||
&*(self.slice.add(heap_index!(idx)) as *const HeapCellValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> IndexMut<usize> for HeapViewMut<'a> {
|
|
||||||
fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
|
|
||||||
debug_assert!(idx < self.slice_cell_len);
|
|
||||||
unsafe {
|
|
||||||
&mut *(self.slice.add(heap_index!(idx)) as *mut HeapCellValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Iterator for &'a mut HeapViewMut<'a> {
|
|
||||||
type Item = &'a mut HeapCellValue;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
self.iter_follow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PStrWriteInfo {
|
pub struct PStrWriteInfo {
|
||||||
pstr_loc: usize,
|
pstr_loc: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct ReservedHeapSection<'a> {
|
pub(crate) struct ReservedHeapSection {
|
||||||
heap_ptr: *mut u8,
|
heap_ptr: *mut u8,
|
||||||
heap_cell_len: usize,
|
heap_cell_len: usize,
|
||||||
pstr_vec: &'a mut BitVec,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ReservedHeapSection<'a> {
|
impl ReservedHeapSection {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn cell_len(&self) -> usize {
|
pub(crate) fn cell_len(&self) -> usize {
|
||||||
self.heap_cell_len
|
self.heap_cell_len
|
||||||
@@ -326,16 +200,16 @@ impl<'a> ReservedHeapSection<'a> {
|
|||||||
|
|
||||||
pub(crate) fn push_cell(&mut self, cell: HeapCellValue) {
|
pub(crate) fn push_cell(&mut self, cell: HeapCellValue) {
|
||||||
unsafe {
|
unsafe {
|
||||||
ptr::write(self.heap_ptr.add(heap_index!(self.heap_cell_len)) as *mut _, cell);
|
ptr::write(
|
||||||
|
self.heap_ptr.add(heap_index!(self.heap_cell_len)) as *mut _,
|
||||||
|
cell,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
self.pstr_vec.push(false);
|
// self.pstr_vec.push(false);
|
||||||
self.heap_cell_len += 1;
|
self.heap_cell_len += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_pstr_segment(
|
fn push_pstr_segment(&mut self, src: &str) -> usize {
|
||||||
&mut self,
|
|
||||||
src: &str,
|
|
||||||
) -> usize {
|
|
||||||
if src.is_empty() {
|
if src.is_empty() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -354,23 +228,30 @@ impl<'a> ReservedHeapSection<'a> {
|
|||||||
|
|
||||||
let align_offset = pstr_sentinel_length(zero_region_idx);
|
let align_offset = pstr_sentinel_length(zero_region_idx);
|
||||||
|
|
||||||
ptr::write_bytes(
|
ptr::write_bytes(self.heap_ptr.add(zero_region_idx), 0u8, align_offset);
|
||||||
self.heap_ptr.add(zero_region_idx),
|
|
||||||
0u8,
|
cells_written = if align_offset == 1 {
|
||||||
align_offset,
|
ptr::write_bytes(
|
||||||
);
|
self.heap_ptr.add(zero_region_idx + 1),
|
||||||
|
0u8,
|
||||||
|
size_of::<HeapCellValue>(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// ensure there are at least two bytes in the boundary
|
||||||
|
// buffer separating the string data from the tail
|
||||||
|
// cell
|
||||||
|
cell_index!(src.len() + align_offset + size_of::<HeapCellValue>())
|
||||||
|
} else {
|
||||||
|
cell_index!(src.len() + align_offset)
|
||||||
|
};
|
||||||
|
|
||||||
cells_written = cell_index!(src.len() + align_offset);
|
|
||||||
self.heap_cell_len += cells_written;
|
self.heap_cell_len += cells_written;
|
||||||
}
|
}
|
||||||
|
|
||||||
cells_written
|
cells_written
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn push_pstr(
|
pub(crate) fn push_pstr(&mut self, mut src: &str) -> Option<HeapCellValue> {
|
||||||
&mut self,
|
|
||||||
mut src: &str,
|
|
||||||
) -> Option<HeapCellValue> {
|
|
||||||
let orig_h = self.cell_len();
|
let orig_h = self.cell_len();
|
||||||
|
|
||||||
if src.is_empty() {
|
if src.is_empty() {
|
||||||
@@ -386,18 +267,14 @@ impl<'a> ReservedHeapSection<'a> {
|
|||||||
|
|
||||||
loop {
|
loop {
|
||||||
let null_char_idx = src.find('\u{0}').unwrap_or_else(|| src.len());
|
let null_char_idx = src.find('\u{0}').unwrap_or_else(|| src.len());
|
||||||
|
|
||||||
let cell_len = self.cell_len();
|
|
||||||
let cells_written = self.push_pstr_segment(&src[0..null_char_idx]);
|
let cells_written = self.push_pstr_segment(&src[0..null_char_idx]);
|
||||||
let tail_idx = self.cell_len();
|
let tail_idx = self.cell_len();
|
||||||
|
|
||||||
self.pstr_vec.resize(cell_len + cells_written, true);
|
|
||||||
|
|
||||||
if cells_written == 0 {
|
if cells_written == 0 {
|
||||||
return None;
|
return None;
|
||||||
} else if null_char_idx + 1 < src.len() {
|
} else if null_char_idx + 1 < src.len() {
|
||||||
self.push_cell(pstr_loc_as_cell!(heap_index!(tail_idx + 1)));
|
self.push_cell(pstr_loc_as_cell!(heap_index!(tail_idx + 1)));
|
||||||
src = &src[null_char_idx + 1 ..];
|
src = &src[null_char_idx + 1..];
|
||||||
} else {
|
} else {
|
||||||
return Some(pstr_loc_as_cell!(heap_index!(orig_h)));
|
return Some(pstr_loc_as_cell!(heap_index!(orig_h)));
|
||||||
}
|
}
|
||||||
@@ -420,7 +297,12 @@ impl<'a> ReservedHeapSection<'a> {
|
|||||||
cursor: 0,
|
cursor: 0,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
while let Some(FunctorData { functor, cell_offset, mut cursor }) = functor_stack.pop() {
|
while let Some(FunctorData {
|
||||||
|
functor,
|
||||||
|
cell_offset,
|
||||||
|
mut cursor,
|
||||||
|
}) = functor_stack.pop()
|
||||||
|
{
|
||||||
while cursor < functor.len() {
|
while cursor < functor.len() {
|
||||||
match &functor[cursor] {
|
match &functor[cursor] {
|
||||||
&FunctorElement::AbsoluteCell(cell) => {
|
&FunctorElement::AbsoluteCell(cell) => {
|
||||||
@@ -460,15 +342,13 @@ impl<'a> ReservedHeapSection<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Index<usize> for ReservedHeapSection<'a> {
|
impl Index<usize> for ReservedHeapSection {
|
||||||
type Output = HeapCellValue;
|
type Output = HeapCellValue;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index(&self, idx: usize) -> &Self::Output {
|
fn index(&self, idx: usize) -> &Self::Output {
|
||||||
debug_assert!(idx < self.heap_cell_len);
|
debug_assert!(idx < self.heap_cell_len);
|
||||||
unsafe {
|
unsafe { &*(self.heap_ptr as *const HeapCellValue).add(idx) }
|
||||||
&*(self.heap_ptr.add(heap_index!(idx)) as *const HeapCellValue)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,7 +369,7 @@ fn pstr_sentinel_length(chunk_len: usize) -> usize {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct HeapWriter<'a> {
|
pub struct HeapWriter<'a> {
|
||||||
section: ReservedHeapSection<'a>,
|
section: ReservedHeapSection,
|
||||||
heap_byte_len: &'a mut usize,
|
heap_byte_len: &'a mut usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,13 +384,12 @@ impl<'a> HeapWriter<'a> {
|
|||||||
*self.heap_byte_len = heap_index!(self.section.heap_cell_len);
|
*self.heap_byte_len = heap_index!(self.section.heap_cell_len);
|
||||||
|
|
||||||
// return the number of bytes written
|
// return the number of bytes written
|
||||||
Ok(heap_index!(self.section.heap_cell_len - old_section_cell_len))
|
Ok(heap_index!(
|
||||||
|
self.section.heap_cell_len - old_section_cell_len
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn write_with(
|
pub(crate) fn write_with(&mut self, writer: impl FnOnce(&mut ReservedHeapSection)) -> usize {
|
||||||
&mut self,
|
|
||||||
writer: impl FnOnce(&mut ReservedHeapSection),
|
|
||||||
) -> usize {
|
|
||||||
let old_section_cell_len = self.section.heap_cell_len;
|
let old_section_cell_len = self.section.heap_cell_len;
|
||||||
writer(&mut self.section);
|
writer(&mut self.section);
|
||||||
*self.heap_byte_len = heap_index!(self.section.heap_cell_len);
|
*self.heap_byte_len = heap_index!(self.section.heap_cell_len);
|
||||||
@@ -522,7 +401,7 @@ impl<'a> HeapWriter<'a> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn truncate(&mut self, cell_offset: usize) {
|
pub(crate) fn truncate(&mut self, cell_offset: usize) {
|
||||||
self.section.heap_cell_len = cell_offset;
|
self.section.heap_cell_len = cell_offset;
|
||||||
self.section.pstr_vec.truncate(cell_offset);
|
// self.section.pstr_vec.truncate(cell_offset);
|
||||||
*self.heap_byte_len = heap_index!(cell_offset);
|
*self.heap_byte_len = heap_index!(cell_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,9 +422,7 @@ impl<'a> Index<usize> for HeapWriter<'a> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn index(&self, idx: usize) -> &Self::Output {
|
fn index(&self, idx: usize) -> &Self::Output {
|
||||||
debug_assert!(heap_index!(idx) < *self.heap_byte_len);
|
debug_assert!(heap_index!(idx) < *self.heap_byte_len);
|
||||||
unsafe {
|
unsafe { &*(self.section.heap_ptr.add(heap_index!(idx)) as *const HeapCellValue) }
|
||||||
&*(self.section.heap_ptr.add(heap_index!(idx)) as *const HeapCellValue)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -553,9 +430,7 @@ impl<'a> IndexMut<usize> for HeapWriter<'a> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
|
fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
|
||||||
debug_assert!(heap_index!(idx) < *self.heap_byte_len);
|
debug_assert!(heap_index!(idx) < *self.heap_byte_len);
|
||||||
unsafe {
|
unsafe { &mut *(self.section.heap_ptr.add(heap_index!(idx)) as *mut HeapCellValue) }
|
||||||
&mut *(self.section.heap_ptr.add(heap_index!(idx)) as *mut HeapCellValue)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -564,17 +439,29 @@ impl<'a> SizedHeap for HeapWriter<'a> {
|
|||||||
self.section.cell_len()
|
self.section.cell_len()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scan_slice_to_str(&self, slice_loc: usize) -> (&str, usize) {
|
fn scan_slice_to_str(&self, slice_loc: usize) -> HeapStringScan {
|
||||||
let (s, tail_cell_offset) = scan_slice_to_str(
|
let HeapStringScan { string, tail_idx } = unsafe {
|
||||||
unsafe { self.section.heap_ptr.add(slice_loc) },
|
let slice = std::slice::from_raw_parts(
|
||||||
&self.section.pstr_vec.as_bitslice()[cell_index!(slice_loc) ..],
|
self.section.heap_ptr.byte_add(slice_loc),
|
||||||
);
|
heap_index!(self.section.heap_cell_len) - slice_loc,
|
||||||
|
);
|
||||||
|
|
||||||
(s, cell_index!(slice_loc) + tail_cell_offset)
|
scan_slice_to_str(slice)
|
||||||
|
};
|
||||||
|
|
||||||
|
HeapStringScan {
|
||||||
|
string,
|
||||||
|
tail_idx: cell_index!(slice_loc) + tail_idx,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pstr_at(&self, cell_offset: usize) -> bool {
|
fn as_slice(&self) -> &[u8] {
|
||||||
self.section.pstr_vec[cell_offset]
|
unsafe {
|
||||||
|
std::slice::from_raw_parts(
|
||||||
|
self.section.heap_ptr,
|
||||||
|
heap_index!(self.section.heap_cell_len),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -588,20 +475,23 @@ impl Heap {
|
|||||||
byte_len: 0,
|
byte_len: 0,
|
||||||
byte_cap: 0,
|
byte_cap: 0,
|
||||||
},
|
},
|
||||||
pstr_vec: bitvec![],
|
|
||||||
resource_err_loc: 0,
|
resource_err_loc: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// takes a heap index, returns a cell index
|
||||||
|
#[inline]
|
||||||
|
pub const fn pstr_tail_idx(pstr_zero_byte_loc: usize) -> usize {
|
||||||
|
if (pstr_zero_byte_loc + 1) % Heap::heap_cell_alignment() == 0 {
|
||||||
|
cell_index!(pstr_zero_byte_loc) + 2
|
||||||
|
} else {
|
||||||
|
cell_index!(pstr_zero_byte_loc) + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn grow(&mut self) -> bool {
|
unsafe fn grow(&mut self) -> bool {
|
||||||
let result = self.inner.grow();
|
self.inner.grow()
|
||||||
|
|
||||||
if result {
|
|
||||||
self.pstr_vec.reserve(cell_index!(self.inner.byte_cap));
|
|
||||||
}
|
|
||||||
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -624,7 +514,7 @@ impl Heap {
|
|||||||
byte_len: 0,
|
byte_len: 0,
|
||||||
byte_cap: heap_index!(cap),
|
byte_cap: heap_index!(cap),
|
||||||
},
|
},
|
||||||
pstr_vec: bitvec![],
|
// pstr_vec: bitvec![],
|
||||||
resource_err_loc: 0,
|
resource_err_loc: 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -641,7 +531,6 @@ impl Heap {
|
|||||||
section = ReservedHeapSection {
|
section = ReservedHeapSection {
|
||||||
heap_ptr: self.inner.ptr,
|
heap_ptr: self.inner.ptr,
|
||||||
heap_cell_len: self.cell_len(),
|
heap_cell_len: self.cell_len(),
|
||||||
pstr_vec: &mut self.pstr_vec,
|
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
} else if !self.grow() {
|
} else if !self.grow() {
|
||||||
@@ -656,28 +545,42 @@ impl Heap {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn last_cell_mut(&mut self) -> Option<&mut HeapCellValue> {
|
|
||||||
if self.inner.byte_len == 0 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
unsafe {
|
|
||||||
Some(&mut *(self.inner.ptr.add(self.inner.byte_len - heap_index!(1))
|
|
||||||
as *mut HeapCellValue))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn last_cell(&mut self) -> Option<HeapCellValue> {
|
pub(crate) fn last_cell(&mut self) -> Option<HeapCellValue> {
|
||||||
if self.inner.byte_len == 0 {
|
if self.inner.byte_len == 0 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
unsafe {
|
unsafe {
|
||||||
Some(ptr::read(self.inner.ptr.add(self.inner.byte_len - heap_index!(1))
|
Some(ptr::read(
|
||||||
as *const HeapCellValue))
|
self.inner.ptr.add(self.inner.byte_len - heap_index!(1))
|
||||||
|
as *const HeapCellValue,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn append(&mut self, other_heap: &impl SizedHeap) -> Result<(), usize> {
|
||||||
|
let other_len = heap_index!(other_heap.cell_len());
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if self.free_space() >= other_len {
|
||||||
|
let heap_slice = unsafe {
|
||||||
|
std::slice::from_raw_parts_mut(
|
||||||
|
self.inner.ptr.add(self.inner.byte_len),
|
||||||
|
other_len,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
heap_slice.copy_from_slice(other_heap.as_slice());
|
||||||
|
self.inner.byte_len += heap_index!(other_heap.cell_len());
|
||||||
|
break;
|
||||||
|
} else if unsafe { !self.grow() } {
|
||||||
|
return Err(self.resource_error_offset());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn is_empty(&self) -> bool {
|
pub(crate) fn is_empty(&self) -> bool {
|
||||||
self.inner.byte_len == 0
|
self.inner.byte_len == 0
|
||||||
@@ -703,31 +606,31 @@ impl Heap {
|
|||||||
self.inner.byte_len = 0;
|
self.inner.byte_len = 0;
|
||||||
self.inner.byte_cap = 0;
|
self.inner.byte_cap = 0;
|
||||||
|
|
||||||
self.pstr_vec.clear();
|
// self.pstr_vec.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn append(&mut self, heap_slice: HeapView) -> Result<(), usize> {
|
// pub(crate) fn append(&mut self, heap_slice: HeapView) -> Result<(), usize> {
|
||||||
unsafe {
|
// unsafe {
|
||||||
loop {
|
// loop {
|
||||||
if self.free_space() >= heap_index!(heap_slice.slice_cell_len) {
|
// if self.free_space() >= heap_index!(heap_slice.slice_cell_len) {
|
||||||
ptr::copy_nonoverlapping(
|
// ptr::copy_nonoverlapping(
|
||||||
heap_slice.slice,
|
// heap_slice.slice,
|
||||||
self.inner.ptr.add(self.inner.byte_len),
|
// self.inner.ptr.add(self.inner.byte_len),
|
||||||
heap_index!(heap_slice.slice_cell_len),
|
// heap_index!(heap_slice.slice_cell_len),
|
||||||
);
|
// );
|
||||||
|
|
||||||
self.inner.byte_len += heap_index!(heap_slice.slice_cell_len);
|
// self.inner.byte_len += heap_index!(heap_slice.slice_cell_len);
|
||||||
self.pstr_vec.extend(heap_slice.pstr_slice.iter());
|
// // self.pstr_vec.extend(heap_slice.pstr_slice.iter());
|
||||||
|
|
||||||
break;
|
// break;
|
||||||
} else if !self.grow() {
|
// } else if !self.grow() {
|
||||||
return Err(self.resource_error_offset());
|
// return Err(self.resource_error_offset());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
Ok(())
|
// Ok(())
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub(crate) fn store_resource_error(&mut self) {
|
pub(crate) fn store_resource_error(&mut self) {
|
||||||
RESOURCE_ERROR_OFFSET_INIT.call_once(move || {
|
RESOURCE_ERROR_OFFSET_INIT.call_once(move || {
|
||||||
@@ -763,11 +666,23 @@ impl Heap {
|
|||||||
|
|
||||||
for ((idx, c1), c2) in str1.char_indices().zip(str2.chars()) {
|
for ((idx, c1), c2) in str1.char_indices().zip(str2.chars()) {
|
||||||
if c1 == '\u{0}' && c2 == '\u{0}' {
|
if c1 == '\u{0}' && c2 == '\u{0}' {
|
||||||
return PStrSegmentCmpResult::BothMatch { pstr_loc1, pstr_loc2, null_offset: idx };
|
return PStrSegmentCmpResult::BothMatch {
|
||||||
|
pstr_loc1,
|
||||||
|
pstr_loc2,
|
||||||
|
null_offset: idx,
|
||||||
|
};
|
||||||
} else if c1 == '\u{0}' {
|
} else if c1 == '\u{0}' {
|
||||||
return PStrSegmentCmpResult::FirstMatch { pstr_loc1, pstr_loc2, l1_offset: idx };
|
return PStrSegmentCmpResult::FirstMatch {
|
||||||
|
pstr_loc1,
|
||||||
|
pstr_loc2,
|
||||||
|
l1_offset: idx,
|
||||||
|
};
|
||||||
} else if c2 == '\u{0}' {
|
} else if c2 == '\u{0}' {
|
||||||
return PStrSegmentCmpResult::SecondMatch { pstr_loc1, pstr_loc2, l2_offset: idx };
|
return PStrSegmentCmpResult::SecondMatch {
|
||||||
|
pstr_loc1,
|
||||||
|
pstr_loc2,
|
||||||
|
l2_offset: idx,
|
||||||
|
};
|
||||||
} else if c1 != c2 {
|
} else if c1 != c2 {
|
||||||
return PStrSegmentCmpResult::Mismatch { c1, c2 };
|
return PStrSegmentCmpResult::Mismatch { c1, c2 };
|
||||||
}
|
}
|
||||||
@@ -822,7 +737,7 @@ impl Heap {
|
|||||||
// - Invariant: from `InnerHeap`, `self.inner.byte_cap < isize::MAX`.
|
// - Invariant: from `InnerHeap`, `self.inner.byte_cap < isize::MAX`.
|
||||||
let cell_ptr = (self.inner.ptr as *mut HeapCellValue).add(self.cell_len());
|
let cell_ptr = (self.inner.ptr as *mut HeapCellValue).add(self.cell_len());
|
||||||
cell_ptr.write(cell);
|
cell_ptr.write(cell);
|
||||||
self.pstr_vec.push(false);
|
// self.pstr_vec.push(false);
|
||||||
self.inner.byte_len += heap_index!(1);
|
self.inner.byte_len += heap_index!(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -866,6 +781,7 @@ impl Heap {
|
|||||||
Range { start, end }
|
Range { start, end }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
pub(crate) fn splice<R: RangeBounds<usize>>(
|
pub(crate) fn splice<R: RangeBounds<usize>>(
|
||||||
&self,
|
&self,
|
||||||
range: R,
|
range: R,
|
||||||
@@ -876,7 +792,7 @@ impl Heap {
|
|||||||
slice: unsafe { self.inner.ptr.add(heap_index!(range.start)) },
|
slice: unsafe { self.inner.ptr.add(heap_index!(range.start)) },
|
||||||
cell_offset: range.start,
|
cell_offset: range.start,
|
||||||
slice_cell_len: range.end - range.start,
|
slice_cell_len: range.end - range.start,
|
||||||
pstr_slice: &self.pstr_vec.as_bitslice()[range],
|
// pstr_slice: &self.pstr_vec.as_bitslice()[range],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -890,9 +806,10 @@ impl Heap {
|
|||||||
slice: unsafe { self.inner.ptr.add(heap_index!(range.start)) },
|
slice: unsafe { self.inner.ptr.add(heap_index!(range.start)) },
|
||||||
cell_offset: range.start,
|
cell_offset: range.start,
|
||||||
slice_cell_len: range.end - range.start,
|
slice_cell_len: range.end - range.start,
|
||||||
pstr_slice: &self.pstr_vec.as_bitslice()[range],
|
// pstr_slice: &self.pstr_vec.as_bitslice()[range],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
pub fn allocate_pstr(&mut self, src: &str) -> Result<Option<PStrWriteInfo>, usize> {
|
pub fn allocate_pstr(&mut self, src: &str) -> Result<Option<PStrWriteInfo>, usize> {
|
||||||
let size_in_heap = Self::compute_pstr_size(src);
|
let size_in_heap = Self::compute_pstr_size(src);
|
||||||
@@ -911,39 +828,18 @@ impl Heap {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn heap_cell_alignment() -> usize {
|
pub const fn heap_cell_alignment() -> usize {
|
||||||
// yes, size_of, not align_of. the alignment of HeapCellValue
|
// yes, size_of, not align_of. the alignment of HeapCellValue
|
||||||
// is 1 byte. In the heap, though, its alignment must be its
|
// is 1 byte. In the heap, though, its alignment must be its
|
||||||
// size.
|
// size.
|
||||||
mem::size_of::<HeapCellValue>()
|
size_of::<HeapCellValue>()
|
||||||
}
|
|
||||||
|
|
||||||
// takes a byte offset into the Heap ptr.
|
|
||||||
#[inline(always)]
|
|
||||||
pub(crate) const fn neighboring_cell_offset(offset: usize) -> usize {
|
|
||||||
cell_index!((offset & !(ALIGN - 1)) + ALIGN)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub(crate) fn iter(&self) -> HeapView {
|
|
||||||
HeapView {
|
|
||||||
slice: self.inner.ptr,
|
|
||||||
cell_offset: 0,
|
|
||||||
slice_cell_len: cell_index!(self.inner.byte_len),
|
|
||||||
pstr_slice: &self.pstr_vec.as_bitslice(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub(crate) fn pstr_vec(&self) -> &BitSlice<usize> {
|
|
||||||
self.pstr_vec.as_bitslice()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn char_at(&self, byte_idx: usize) -> char {
|
pub(crate) fn char_at(&self, byte_idx: usize) -> char {
|
||||||
let s = unsafe {
|
let s = unsafe {
|
||||||
let char_ptr = self.inner.ptr.add(byte_idx);
|
let char_ptr = self.inner.ptr.add(byte_idx);
|
||||||
let slice = std::slice::from_raw_parts(char_ptr, mem::size_of::<char>());
|
let slice = std::slice::from_raw_parts(char_ptr, size_of::<char>());
|
||||||
std::str::from_utf8_unchecked(&slice)
|
std::str::from_utf8_unchecked(&slice)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -961,7 +857,7 @@ impl Heap {
|
|||||||
let succ_len = loc + c.len_utf8();
|
let succ_len = loc + c.len_utf8();
|
||||||
|
|
||||||
if chars_iter.next() == Some('\u{0}') {
|
if chars_iter.next() == Some('\u{0}') {
|
||||||
(c, heap_loc_as_cell!(Self::neighboring_cell_offset(succ_len)))
|
(c, heap_loc_as_cell!(Self::pstr_tail_idx(succ_len)))
|
||||||
} else {
|
} else {
|
||||||
(c, pstr_loc_as_cell!(succ_len))
|
(c, pstr_loc_as_cell!(succ_len))
|
||||||
}
|
}
|
||||||
@@ -971,8 +867,8 @@ impl Heap {
|
|||||||
// copies only the string, not its tail. returns the cell index of
|
// copies only the string, not its tail. returns the cell index of
|
||||||
// the tail location
|
// the tail location
|
||||||
pub(crate) fn copy_pstr_within(&mut self, pstr_loc: usize) -> Result<usize, usize> {
|
pub(crate) fn copy_pstr_within(&mut self, pstr_loc: usize) -> Result<usize, usize> {
|
||||||
let (s, tail_loc) = self.scan_slice_to_str(pstr_loc);
|
let HeapStringScan { string, tail_idx } = self.scan_slice_to_str(pstr_loc);
|
||||||
let s_len = s.len();
|
let s_len = string.len();
|
||||||
|
|
||||||
let align_offset = pstr_sentinel_length(s_len);
|
let align_offset = pstr_sentinel_length(s_len);
|
||||||
let copy_size = s_len + align_offset;
|
let copy_size = s_len + align_offset;
|
||||||
@@ -980,15 +876,10 @@ impl Heap {
|
|||||||
unsafe {
|
unsafe {
|
||||||
loop {
|
loop {
|
||||||
if self.free_space() >= copy_size {
|
if self.free_space() >= copy_size {
|
||||||
let slice = std::slice::from_raw_parts_mut(
|
let slice =
|
||||||
self.inner.ptr,
|
std::slice::from_raw_parts_mut(self.inner.ptr, self.inner.byte_len + s_len);
|
||||||
self.inner.byte_len + s_len,
|
|
||||||
);
|
|
||||||
|
|
||||||
slice.copy_within(
|
slice.copy_within(pstr_loc..pstr_loc + s_len, self.inner.byte_len);
|
||||||
pstr_loc .. pstr_loc + s_len,
|
|
||||||
self.inner.byte_len,
|
|
||||||
);
|
|
||||||
|
|
||||||
ptr::write_bytes(
|
ptr::write_bytes(
|
||||||
self.inner.ptr.add(self.inner.byte_len + s_len),
|
self.inner.ptr.add(self.inner.byte_len + s_len),
|
||||||
@@ -996,8 +887,17 @@ impl Heap {
|
|||||||
align_offset,
|
align_offset,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.inner.byte_len += copy_size;
|
if align_offset == 1 {
|
||||||
self.pstr_vec.resize(self.cell_len(), true);
|
ptr::write_bytes(
|
||||||
|
self.inner.ptr.add(self.inner.byte_len + copy_size),
|
||||||
|
0u8,
|
||||||
|
size_of::<HeapCellValue>(),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.inner.byte_len += copy_size + heap_index!(1);
|
||||||
|
} else {
|
||||||
|
self.inner.byte_len += copy_size;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} else if !self.grow() {
|
} else if !self.grow() {
|
||||||
@@ -1006,7 +906,7 @@ impl Heap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(tail_loc)
|
Ok(tail_idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// src is a cell-indexed range.
|
// src is a cell-indexed range.
|
||||||
@@ -1023,7 +923,7 @@ impl Heap {
|
|||||||
heap_index!(len),
|
heap_index!(len),
|
||||||
);
|
);
|
||||||
|
|
||||||
self.pstr_vec.resize(self.cell_len() + len, false);
|
// self.pstr_vec.resize(self.cell_len() + len, false);
|
||||||
self.inner.byte_len += heap_index!(len);
|
self.inner.byte_len += heap_index!(len);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -1059,10 +959,14 @@ impl Heap {
|
|||||||
|
|
||||||
byte_size += null_idx + pstr_sentinel_length(null_idx);
|
byte_size += null_idx + pstr_sentinel_length(null_idx);
|
||||||
|
|
||||||
|
// each partial string must be buffered from its tail cell
|
||||||
|
// by at least two null bytes so one of them may be used
|
||||||
|
// to mark partial strings e.g. during iteration
|
||||||
|
|
||||||
if (null_idx + 1) % ALIGN == 0 {
|
if (null_idx + 1) % ALIGN == 0 {
|
||||||
byte_size += 2 * mem::size_of::<HeapCellValue>();
|
byte_size += 2 * size_of::<HeapCellValue>();
|
||||||
} else {
|
} else {
|
||||||
byte_size += mem::size_of::<HeapCellValue>();
|
byte_size += size_of::<HeapCellValue>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if null_idx + 1 >= src.len() {
|
if null_idx + 1 >= src.len() {
|
||||||
@@ -1082,13 +986,13 @@ impl Heap {
|
|||||||
while idx < functor.len() {
|
while idx < functor.len() {
|
||||||
match &functor[idx] {
|
match &functor[idx] {
|
||||||
&FunctorElement::InnerFunctor(inner_cell_size, ref _inner_functor) => {
|
&FunctorElement::InnerFunctor(inner_cell_size, ref _inner_functor) => {
|
||||||
byte_size += inner_cell_size as usize * mem::size_of::<HeapCellValue>();
|
byte_size += inner_cell_size as usize * size_of::<HeapCellValue>();
|
||||||
}
|
}
|
||||||
FunctorElement::AbsoluteCell(_cell) | FunctorElement::Cell(_cell) => {
|
FunctorElement::AbsoluteCell(_cell) | FunctorElement::Cell(_cell) => {
|
||||||
byte_size += mem::size_of::<HeapCellValue>();
|
byte_size += size_of::<HeapCellValue>();
|
||||||
}
|
}
|
||||||
&FunctorElement::String(cell_len, _) => {
|
&FunctorElement::String(cell_len, _) => {
|
||||||
byte_size += cell_len as usize * mem::size_of::<HeapCellValue>();
|
byte_size += cell_len as usize * size_of::<HeapCellValue>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1120,12 +1024,10 @@ impl Heap {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn truncate(&mut self, cell_offset: usize) {
|
pub(crate) fn truncate(&mut self, cell_offset: usize) {
|
||||||
self.inner.byte_len = heap_index!(cell_offset);
|
self.inner.byte_len = heap_index!(cell_offset);
|
||||||
self.pstr_vec.truncate(cell_offset);
|
// self.pstr_vec.truncate(cell_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub(crate) struct PStrSegmentIter<'a> {
|
pub(crate) struct PStrSegmentIter<'a> {
|
||||||
string_buf: &'a str,
|
string_buf: &'a str,
|
||||||
}
|
}
|
||||||
@@ -1153,7 +1055,7 @@ impl<'a> Iterator for PStrSegmentIter<'a> {
|
|||||||
if c == '\u{0}' {
|
if c == '\u{0}' {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
self.string_buf = &self.string_buf[c.len_utf8() ..];
|
self.string_buf = &self.string_buf[c.len_utf8()..];
|
||||||
Some(c)
|
Some(c)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -1187,14 +1089,15 @@ pub trait SizedHeap: Index<usize, Output = HeapCellValue> {
|
|||||||
fn cell_len(&self) -> usize;
|
fn cell_len(&self) -> usize;
|
||||||
|
|
||||||
// return a pointer to the heap string and the cell index of its tail
|
// return a pointer to the heap string and the cell index of its tail
|
||||||
fn scan_slice_to_str(&self, slice_loc: usize) -> (&str, usize);
|
fn scan_slice_to_str<'a>(&'a self, slice_loc: usize) -> HeapStringScan<'a>;
|
||||||
|
|
||||||
|
fn as_slice(&self) -> &[u8];
|
||||||
|
|
||||||
// return true iff a partial string is stored at cell_offset.
|
// return true iff a partial string is stored at cell_offset.
|
||||||
fn pstr_at(&self, cell_offset: usize) -> bool;
|
// fn pstr_at(&self, cell_offset: usize) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SizedHeapMut: IndexMut<usize, Output = HeapCellValue> + SizedHeap {
|
pub trait SizedHeapMut: IndexMut<usize, Output = HeapCellValue> + SizedHeap {}
|
||||||
}
|
|
||||||
|
|
||||||
impl Index<usize> for Heap {
|
impl Index<usize> for Heap {
|
||||||
type Output = HeapCellValue;
|
type Output = HeapCellValue;
|
||||||
@@ -1215,62 +1118,29 @@ impl SizedHeap for Heap {
|
|||||||
self.cell_len()
|
self.cell_len()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scan_slice_to_str(&self, slice_loc: usize) -> (&str, usize) {
|
fn scan_slice_to_str<'a>(&'a self, slice_loc: usize) -> HeapStringScan<'a> {
|
||||||
let (s, tail_cell_offset) = scan_slice_to_str(
|
let HeapStringScan { string, tail_idx } = unsafe {
|
||||||
unsafe { self.inner.ptr.add(slice_loc) },
|
let slice = std::slice::from_raw_parts(
|
||||||
&self.pstr_vec.as_bitslice()[cell_index!(slice_loc) ..],
|
self.inner.ptr.add(slice_loc),
|
||||||
);
|
self.inner.byte_len - slice_loc,
|
||||||
|
);
|
||||||
|
|
||||||
(s, cell_index!(slice_loc) + tail_cell_offset)
|
scan_slice_to_str(slice)
|
||||||
|
};
|
||||||
|
|
||||||
|
HeapStringScan {
|
||||||
|
string,
|
||||||
|
tail_idx: cell_index!(slice_loc) + tail_idx,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pstr_at(&self, cell_offset: usize) -> bool {
|
fn as_slice(&self) -> &[u8] {
|
||||||
self.pstr_vec[cell_offset]
|
unsafe { std::slice::from_raw_parts(self.inner.ptr, self.inner.byte_len) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SizedHeapMut for Heap {}
|
impl SizedHeapMut for Heap {}
|
||||||
|
|
||||||
impl<'a> SizedHeap for HeapView<'a> {
|
|
||||||
fn cell_len(&self) -> usize {
|
|
||||||
self.slice_cell_len
|
|
||||||
}
|
|
||||||
|
|
||||||
fn scan_slice_to_str(&self, slice_loc: usize) -> (&str, usize) {
|
|
||||||
let (s, tail_cell_offset) = scan_slice_to_str(
|
|
||||||
unsafe { self.slice.add(slice_loc) },
|
|
||||||
&self.pstr_slice[cell_index!(slice_loc) ..],
|
|
||||||
);
|
|
||||||
|
|
||||||
(s, cell_index!(slice_loc) + tail_cell_offset)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pstr_at(&self, cell_offset: usize) -> bool {
|
|
||||||
self.pstr_slice[cell_offset]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> SizedHeap for HeapViewMut<'a> {
|
|
||||||
fn cell_len(&self) -> usize {
|
|
||||||
self.slice_cell_len
|
|
||||||
}
|
|
||||||
|
|
||||||
fn scan_slice_to_str(&self, slice_loc: usize) -> (&str, usize) {
|
|
||||||
let (s, tail_cell_offset) = scan_slice_to_str(
|
|
||||||
unsafe { self.slice.add(slice_loc) },
|
|
||||||
&self.pstr_slice[cell_index!(slice_loc) ..],
|
|
||||||
);
|
|
||||||
|
|
||||||
(s, cell_index!(slice_loc) + tail_cell_offset)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pstr_at(&self, cell_offset: usize) -> bool {
|
|
||||||
self.pstr_slice[cell_offset]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> SizedHeapMut for HeapViewMut<'a> {}
|
|
||||||
|
|
||||||
// sometimes we need to dereference variables that are found only in
|
// sometimes we need to dereference variables that are found only in
|
||||||
// the heap without access to the full WAM (e.g., while detecting
|
// the heap without access to the full WAM (e.g., while detecting
|
||||||
// cycles in terms), and which therefore may only point other cells in
|
// cycles in terms), and which therefore may only point other cells in
|
||||||
@@ -1307,9 +1177,10 @@ pub fn heap_bound_store(heap: &impl SizedHeap, value: HeapCellValue) -> HeapCell
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn print_heap_terms<'a, I: Iterator<Item = HeapCellValue>>(heap: I, h: usize) {
|
pub fn print_heap_terms(heap: &Heap, h: usize) {
|
||||||
for (index, term) in heap.enumerate() {
|
for idx in 0..heap.cell_len() {
|
||||||
println!("{} : {:?}", h + index, term);
|
let term = heap[idx];
|
||||||
|
println!("{} : {:?}", h + idx, term);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use std::cmp::Ordering;
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use crate::atom_table;
|
use crate::atom_table;
|
||||||
@@ -442,7 +441,7 @@ impl Iterator for QueryState<'_> {
|
|||||||
if let Err(resource_err_loc) = machine
|
if let Err(resource_err_loc) = machine
|
||||||
.machine_st
|
.machine_st
|
||||||
.heap
|
.heap
|
||||||
.append(machine.machine_st.ball.stub.splice(..))
|
.append(&machine.machine_st.ball.stub)
|
||||||
{
|
{
|
||||||
return Some(Err(Term::from_heapcell(
|
return Some(Err(Term::from_heapcell(
|
||||||
machine,
|
machine,
|
||||||
@@ -530,10 +529,10 @@ impl Machine {
|
|||||||
/// Consults a module into the [`Machine`] from a string.
|
/// Consults a module into the [`Machine`] from a string.
|
||||||
pub fn consult_module_string(&mut self, module_name: &str, program: impl Into<String>) {
|
pub fn consult_module_string(&mut self, module_name: &str, program: impl Into<String>) {
|
||||||
let stream = Stream::from_owned_string(program.into(), &mut self.machine_st.arena);
|
let stream = Stream::from_owned_string(program.into(), &mut self.machine_st.arena);
|
||||||
self.machine_st.registers[1] = stream.into();
|
self.machine_st.registers[1] = stream_as_cell!(stream);
|
||||||
self.machine_st.registers[2] = atom_as_cell!(&atom_table::AtomTable::build_with(
|
self.machine_st.registers[2] = atom_as_cell!(atom_table::AtomTable::build_with(
|
||||||
&self.machine_st.atom_tbl,
|
&self.machine_st.atom_tbl,
|
||||||
module_name
|
module_name,
|
||||||
));
|
));
|
||||||
|
|
||||||
self.run_module_predicate(atom!("loader"), (atom!("consult_stream"), 2));
|
self.run_module_predicate(atom!("loader"), (atom!("consult_stream"), 2));
|
||||||
|
|||||||
@@ -27,15 +27,14 @@ impl TermWriteResult {
|
|||||||
|
|
||||||
heap[0] = value;
|
heap[0] = value;
|
||||||
|
|
||||||
let inverse_var_locs = inverse_var_locs_from_iter(
|
let inverse_var_locs = inverse_var_locs_from_iter(stackful_preorder_iter::<NonListElider>(
|
||||||
stackful_preorder_iter::<NonListElider>(
|
heap, &mut stack, 0,
|
||||||
heap,
|
));
|
||||||
&mut stack,
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(Self { focus, inverse_var_locs })
|
Ok(Self {
|
||||||
|
focus,
|
||||||
|
inverse_var_locs,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -529,9 +528,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
let composite_op_dir = self.wam_prelude.composite_op_dir(compilation_target);
|
let composite_op_dir = self.wam_prelude.composite_op_dir(compilation_target);
|
||||||
|
|
||||||
let mut term = load_state.term_stream.next(&composite_op_dir)?;
|
let mut term = load_state.term_stream.next(&composite_op_dir)?;
|
||||||
let predicate_focus_opt = load_state.predicates.first().map(|term_write_result| {
|
let predicate_focus_opt = load_state
|
||||||
term_write_result.focus
|
.predicates
|
||||||
});
|
.first()
|
||||||
|
.map(|term_write_result| term_write_result.focus);
|
||||||
|
|
||||||
let machine_st = LS::machine_st(&mut self.payload);
|
let machine_st = LS::machine_st(&mut self.payload);
|
||||||
let term_key_opt = clause_predicate_key(&machine_st.heap, term.focus);
|
let term_key_opt = clause_predicate_key(&machine_st.heap, term.focus);
|
||||||
@@ -1072,10 +1072,15 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
let cell = machine_st[r];
|
let cell = machine_st[r];
|
||||||
|
|
||||||
let focus = machine_st.heap.cell_len();
|
let focus = machine_st.heap.cell_len();
|
||||||
machine_st.heap.push_cell(cell)
|
machine_st
|
||||||
|
.heap
|
||||||
|
.push_cell(cell)
|
||||||
.map_err(|_err_loc| ParserError::ResourceError(ParserErrorSrc::default()))?;
|
.map_err(|_err_loc| ParserError::ResourceError(ParserErrorSrc::default()))?;
|
||||||
|
|
||||||
let export_list = FocusedHeapRefMut { heap: &mut machine_st.heap, focus };
|
let export_list = FocusedHeapRefMut {
|
||||||
|
heap: &mut machine_st.heap,
|
||||||
|
focus,
|
||||||
|
};
|
||||||
let export_list = setup_module_export_list(export_list)?;
|
let export_list = setup_module_export_list(export_list)?;
|
||||||
|
|
||||||
Ok(export_list.into_iter().collect())
|
Ok(export_list.into_iter().collect())
|
||||||
@@ -1129,8 +1134,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(TermWriteResult::from(&mut machine_st.heap, heap_loc_as_cell!(focus))
|
Ok(
|
||||||
.map_err(|_err_loc| ParserError::ResourceError(ParserErrorSrc::default()))?)
|
TermWriteResult::from(&mut machine_st.heap, heap_loc_as_cell!(focus))
|
||||||
|
.map_err(|_err_loc| ParserError::ResourceError(ParserErrorSrc::default()))?,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_extensible_predicate_declaration(
|
fn add_extensible_predicate_declaration(
|
||||||
@@ -1628,18 +1635,15 @@ impl Machine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let value = self.machine_st.registers[2];
|
let value = self.machine_st.registers[2];
|
||||||
let term = resource_error_call_result!(
|
let term = resource_error_call_result!(
|
||||||
self.machine_st,
|
self.machine_st,
|
||||||
TermWriteResult::from(&mut self.machine_st.heap, value)
|
TermWriteResult::from(&mut self.machine_st.heap, value)
|
||||||
);
|
);
|
||||||
|
|
||||||
let add_clause = || {
|
let add_clause = || {
|
||||||
let indexing_arg_opt = match term_predicate_key(&self.machine_st.heap, term.focus) {
|
let indexing_arg_opt = match term_predicate_key(&self.machine_st.heap, term.focus) {
|
||||||
Some((atom!(":-"), _)) => {
|
Some((atom!(":-"), _)) => term_nth_arg(&self.machine_st.heap, term.focus, 1)
|
||||||
term_nth_arg(&self.machine_st.heap, term.focus, 1).and_then(|h| {
|
.and_then(|h| term_nth_arg(&self.machine_st.heap, h, 1)),
|
||||||
term_nth_arg(&self.machine_st.heap, h, 1)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Some(_) => term_nth_arg(&self.machine_st.heap, term.focus, 1),
|
Some(_) => term_nth_arg(&self.machine_st.heap, term.focus, 1),
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
@@ -2240,9 +2244,11 @@ impl Machine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut loader = self.loader_from_heap_evacuable(temp_v!(4));
|
let mut loader = self.loader_from_heap_evacuable(temp_v!(4));
|
||||||
let predicate_focus_opt = loader.payload.predicates.first().map(|term_write_result| {
|
let predicate_focus_opt = loader
|
||||||
term_write_result.focus
|
.payload
|
||||||
});
|
.predicates
|
||||||
|
.first()
|
||||||
|
.map(|term_write_result| term_write_result.focus);
|
||||||
|
|
||||||
let is_consistent = if let Some(predicate_focus) = predicate_focus_opt {
|
let is_consistent = if let Some(predicate_focus) = predicate_focus_opt {
|
||||||
let machine_st = LiveLoadAndMachineState::machine_st(&mut loader.payload);
|
let machine_st = LiveLoadAndMachineState::machine_st(&mut loader.payload);
|
||||||
@@ -2253,7 +2259,7 @@ impl Machine {
|
|||||||
|
|
||||||
LiveLoadAndMachineState::machine_st(&mut loader.payload).fail =
|
LiveLoadAndMachineState::machine_st(&mut loader.payload).fail =
|
||||||
(!loader.payload.predicates.is_empty()
|
(!loader.payload.predicates.is_empty()
|
||||||
&& loader.payload.predicates.compilation_target != compilation_target)
|
&& loader.payload.predicates.compilation_target != compilation_target)
|
||||||
|| !is_consistent;
|
|| !is_consistent;
|
||||||
|
|
||||||
let result = LiveLoadAndMachineState::evacuate(loader);
|
let result = LiveLoadAndMachineState::evacuate(loader);
|
||||||
|
|||||||
@@ -187,7 +187,11 @@ impl PermissionError for HeapCellValue {
|
|||||||
|
|
||||||
let stub = functor!(
|
let stub = functor!(
|
||||||
atom!("permission_error"),
|
atom!("permission_error"),
|
||||||
[atom_as_cell((perm.as_atom())), atom_as_cell(index_atom), cell(cell)]
|
[
|
||||||
|
atom_as_cell((perm.as_atom())),
|
||||||
|
atom_as_cell(index_atom),
|
||||||
|
cell(cell)
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
@@ -226,7 +230,10 @@ pub(super) trait DomainError {
|
|||||||
|
|
||||||
impl DomainError for HeapCellValue {
|
impl DomainError for HeapCellValue {
|
||||||
fn domain_error(self, _machine_st: &mut MachineState, error: DomainErrorType) -> MachineError {
|
fn domain_error(self, _machine_st: &mut MachineState, error: DomainErrorType) -> MachineError {
|
||||||
let stub = functor!(atom!("domain_error"), [atom_as_cell((error.as_atom())), cell(self)]);
|
let stub = functor!(
|
||||||
|
atom!("domain_error"),
|
||||||
|
[atom_as_cell((error.as_atom())), cell(self)]
|
||||||
|
);
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -239,7 +246,10 @@ impl DomainError for Number {
|
|||||||
fn domain_error(self, machine_st: &mut MachineState, error: DomainErrorType) -> MachineError {
|
fn domain_error(self, machine_st: &mut MachineState, error: DomainErrorType) -> MachineError {
|
||||||
let stub = functor!(
|
let stub = functor!(
|
||||||
atom!("domain_error"),
|
atom!("domain_error"),
|
||||||
[atom_as_cell((error.as_atom())), number(self, (&mut machine_st.arena))]
|
[
|
||||||
|
atom_as_cell((error.as_atom())),
|
||||||
|
number(self, (&mut machine_st.arena))
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
@@ -280,7 +290,10 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn evaluation_error(&mut self, eval_error: EvalError) -> MachineError {
|
pub(super) fn evaluation_error(&mut self, eval_error: EvalError) -> MachineError {
|
||||||
let stub = functor!(atom!("evaluation_error"), [atom_as_cell((eval_error.as_atom()))]);
|
let stub = functor!(
|
||||||
|
atom!("evaluation_error"),
|
||||||
|
[atom_as_cell((eval_error.as_atom()))]
|
||||||
|
);
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -297,7 +310,10 @@ impl MachineState {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
ResourceError::OutOfFiles => {
|
ResourceError::OutOfFiles => {
|
||||||
functor!(atom!("resource_error"), [atom_as_cell((atom!("file_descriptors")))])
|
functor!(
|
||||||
|
atom!("resource_error"),
|
||||||
|
[atom_as_cell((atom!("file_descriptors")))]
|
||||||
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -480,12 +496,12 @@ impl MachineState {
|
|||||||
SessionError::CannotOverwriteBuiltIn(key) => self.permission_error(
|
SessionError::CannotOverwriteBuiltIn(key) => self.permission_error(
|
||||||
Permission::Modify,
|
Permission::Modify,
|
||||||
atom!("static_procedure"),
|
atom!("static_procedure"),
|
||||||
functor_stub(key.0, key.1)
|
functor_stub(key.0, key.1),
|
||||||
),
|
),
|
||||||
SessionError::CannotOverwriteStaticProcedure(key) => self.permission_error(
|
SessionError::CannotOverwriteStaticProcedure(key) => self.permission_error(
|
||||||
Permission::Modify,
|
Permission::Modify,
|
||||||
atom!("static_procedure"),
|
atom!("static_procedure"),
|
||||||
functor_stub(key.0, key.1)
|
functor_stub(key.0, key.1),
|
||||||
),
|
),
|
||||||
SessionError::CannotOverwriteBuiltInModule(module) => {
|
SessionError::CannotOverwriteBuiltInModule(module) => {
|
||||||
self.permission_error(Permission::Modify, atom!("static_module"), module)
|
self.permission_error(Permission::Modify, atom!("static_module"), module)
|
||||||
@@ -559,14 +575,14 @@ impl MachineState {
|
|||||||
|
|
||||||
let stub = functor!(atom!("syntax_error"), [functor(stub)]);
|
let stub = functor!(atom!("syntax_error"), [functor(stub)]);
|
||||||
|
|
||||||
MachineError {
|
MachineError { stub, location }
|
||||||
stub,
|
|
||||||
location,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn representation_error(&self, flag: RepFlag) -> MachineError {
|
pub(super) fn representation_error(&self, flag: RepFlag) -> MachineError {
|
||||||
let stub = functor!(atom!("representation_error"), [atom_as_cell((flag.as_atom()))]);
|
let stub = functor!(
|
||||||
|
atom!("representation_error"),
|
||||||
|
[atom_as_cell((flag.as_atom()))]
|
||||||
|
);
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -593,13 +609,19 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn error_form(&mut self, err: MachineError, src: MachineStub) -> MachineStub {
|
pub(super) fn error_form(&mut self, err: MachineError, src: MachineStub) -> MachineStub {
|
||||||
if let Some(ParserErrorSrc { line_num, .. }) = err.location {
|
if let Some(ParserErrorSrc { line_num, .. }) = err.location {
|
||||||
functor!(atom!("error"), [functor((err.stub)),
|
functor!(
|
||||||
functor((atom!(":")), [functor(src),
|
atom!("error"),
|
||||||
number(line_num, (&mut self.arena))])])
|
[
|
||||||
|
functor((err.stub)),
|
||||||
|
functor(
|
||||||
|
(atom!(":")),
|
||||||
|
[functor(src), number(line_num, (&mut self.arena))]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
functor!(atom!("error"), [functor((err.stub)),
|
functor!(atom!("error"), [functor((err.stub)), functor(src)])
|
||||||
functor(src)])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -826,13 +848,29 @@ impl EvalError {
|
|||||||
// used by '$skip_max_list'.
|
// used by '$skip_max_list'.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum CycleSearchResult {
|
pub enum CycleSearchResult {
|
||||||
Cyclic { lambda: usize }, // number of steps
|
Cyclic {
|
||||||
|
lambda: usize,
|
||||||
|
}, // number of steps
|
||||||
EmptyList,
|
EmptyList,
|
||||||
NotList { num_steps: usize, heap_loc: HeapCellValue },
|
NotList {
|
||||||
PartialList { num_steps: usize, heap_loc: HeapCellValue },
|
num_steps: usize,
|
||||||
ProperList { num_steps: usize },
|
heap_loc: HeapCellValue,
|
||||||
PStrLocation { num_steps: usize, pstr_loc: HeapCellValue },
|
},
|
||||||
UntouchedList { num_steps: usize, list_loc: usize },
|
PartialList {
|
||||||
|
num_steps: usize,
|
||||||
|
heap_loc: HeapCellValue,
|
||||||
|
},
|
||||||
|
ProperList {
|
||||||
|
num_steps: usize,
|
||||||
|
},
|
||||||
|
PStrLocation {
|
||||||
|
num_steps: usize,
|
||||||
|
pstr_loc: HeapCellValue,
|
||||||
|
},
|
||||||
|
UntouchedList {
|
||||||
|
num_steps: usize,
|
||||||
|
list_loc: usize,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MachineState {
|
impl MachineState {
|
||||||
@@ -856,7 +894,9 @@ impl MachineState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match BrentAlgState::detect_cycles(&self.heap, sorted) {
|
match BrentAlgState::detect_cycles(&self.heap, sorted) {
|
||||||
CycleSearchResult::NotList { .. } | CycleSearchResult::Cyclic { .. } if !sorted.is_var() => {
|
CycleSearchResult::NotList { .. } | CycleSearchResult::Cyclic { .. }
|
||||||
|
if !sorted.is_var() =>
|
||||||
|
{
|
||||||
let err = self.type_error(ValidType::List, sorted);
|
let err = self.type_error(ValidType::List, sorted);
|
||||||
Err(self.error_form(err, stub_gen()))
|
Err(self.error_form(err, stub_gen()))
|
||||||
}
|
}
|
||||||
@@ -868,7 +908,9 @@ impl MachineState {
|
|||||||
let stub_gen = || functor_stub(atom!("keysort"), 2);
|
let stub_gen = || functor_stub(atom!("keysort"), 2);
|
||||||
|
|
||||||
match BrentAlgState::detect_cycles(&self.heap, list) {
|
match BrentAlgState::detect_cycles(&self.heap, list) {
|
||||||
CycleSearchResult::NotList { .. } | CycleSearchResult::Cyclic { .. } if !list.is_var() => {
|
CycleSearchResult::NotList { .. } | CycleSearchResult::Cyclic { .. }
|
||||||
|
if !list.is_var() =>
|
||||||
|
{
|
||||||
let err = self.type_error(ValidType::List, list);
|
let err = self.type_error(ValidType::List, list);
|
||||||
Err(self.error_form(err, stub_gen()))
|
Err(self.error_form(err, stub_gen()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ pub(super) enum MachineMode {
|
|||||||
pub(super) enum HeapPtr {
|
pub(super) enum HeapPtr {
|
||||||
HeapCell(usize),
|
HeapCell(usize),
|
||||||
PStr(usize), // Char(usize),
|
PStr(usize), // Char(usize),
|
||||||
// PStrLocation(usize),
|
// PStrLocation(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for HeapPtr {
|
impl Default for HeapPtr {
|
||||||
@@ -215,7 +215,8 @@ fn push_var_eq_functors(
|
|||||||
let mut writer = heap.reserve(1 + 5 * size)?;
|
let mut writer = heap.reserve(1 + 5 * size)?;
|
||||||
|
|
||||||
writer.write_with(|section| {
|
writer.write_with(|section| {
|
||||||
for (var_loc, var) in iter { // (var, binding) in iter {
|
for (var_loc, var) in iter {
|
||||||
|
// (var, binding) in iter {
|
||||||
let var_atom = AtomTable::build_with(atom_tbl, &var.to_string());
|
let var_atom = AtomTable::build_with(atom_tbl, &var.to_string());
|
||||||
let binding = heap_loc_as_cell!(var_loc);
|
let binding = heap_loc_as_cell!(var_loc);
|
||||||
|
|
||||||
@@ -224,7 +225,7 @@ fn push_var_eq_functors(
|
|||||||
section.push_cell(binding);
|
section.push_cell(binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
for idx in 0 .. size {
|
for idx in 0..size {
|
||||||
section.push_cell(list_loc_as_cell!(section.cell_len() + 1));
|
section.push_cell(list_loc_as_cell!(section.cell_len() + 1));
|
||||||
section.push_cell(str_loc_as_cell!(src_h + 3 * idx));
|
section.push_cell(str_loc_as_cell!(src_h + 3 * idx));
|
||||||
}
|
}
|
||||||
@@ -252,6 +253,7 @@ pub(crate) fn copy_and_align_iter<Iter: Iterator<Item = HeapCellValue>>(
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Ball {
|
pub struct Ball {
|
||||||
pub(super) boundary: usize,
|
pub(super) boundary: usize,
|
||||||
|
pub(super) pstr_boundary: usize,
|
||||||
pub(super) stub: Heap,
|
pub(super) stub: Heap,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,12 +261,14 @@ impl Ball {
|
|||||||
pub(super) fn new() -> Self {
|
pub(super) fn new() -> Self {
|
||||||
Ball {
|
Ball {
|
||||||
boundary: 0,
|
boundary: 0,
|
||||||
|
pstr_boundary: 0,
|
||||||
stub: Heap::new(),
|
stub: Heap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn reset(&mut self) {
|
pub(super) fn reset(&mut self) {
|
||||||
self.boundary = 0;
|
self.boundary = 0;
|
||||||
|
self.pstr_boundary = 0;
|
||||||
self.stub.clear();
|
self.stub.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,10 +276,23 @@ impl Ball {
|
|||||||
let h = dest.cell_len();
|
let h = dest.cell_len();
|
||||||
let diff = self.boundary as i64 - h as i64;
|
let diff = self.boundary as i64 - h as i64;
|
||||||
|
|
||||||
dest.append(self.stub.splice(..))?;
|
let mut dest_writer = dest.reserve(self.stub.cell_len())?;
|
||||||
|
|
||||||
for cell in &mut dest.splice_mut(h ..) {
|
dest_writer.write_with(|section| {
|
||||||
*cell = *cell - diff;
|
for idx in 0..self.pstr_boundary {
|
||||||
|
section.push_cell(self.stub[idx] - diff);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut pstr_threshold = heap_index!(self.pstr_boundary);
|
||||||
|
|
||||||
|
while pstr_threshold < heap_index!(self.stub.cell_len()) {
|
||||||
|
let HeapStringScan { string, tail_idx } = self.stub.scan_slice_to_str(pstr_threshold);
|
||||||
|
|
||||||
|
pstr_threshold += dest_writer.write_with(|section| {
|
||||||
|
section.push_pstr(string).unwrap();
|
||||||
|
section.push_cell(self.stub[tail_idx] - diff);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(h)
|
Ok(h)
|
||||||
@@ -335,32 +352,16 @@ impl<'a> CopierTarget for CopyTerm<'a> {
|
|||||||
self.state.heap.cell_len()
|
self.state.heap.cell_len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn as_slice_from<'b>(&'b self, from: usize) -> Box<dyn Iterator<Item = u8> + 'b> {
|
||||||
|
Box::new(self.state.heap.as_slice()[from..].iter().cloned())
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn copy_pstr_to_threshold(&mut self, pstr_loc: usize) -> Result<usize, usize> {
|
fn copy_pstr_to_threshold(&mut self, pstr_loc: usize) -> Result<usize, usize> {
|
||||||
self.state.heap.copy_pstr_within(pstr_loc)
|
self.state.heap.copy_pstr_within(pstr_loc)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn pstr_head_cell_index(&self, pstr_loc: usize) -> usize {
|
|
||||||
self.state.heap.pstr_vec()[0 .. cell_index!(pstr_loc)]
|
|
||||||
.last_zero()
|
|
||||||
.map(|idx| idx + 1)
|
|
||||||
.unwrap_or(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn pstr_at(&self, loc: usize) -> bool {
|
|
||||||
self.state.heap.pstr_vec()[loc]
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn next_non_pstr_cell_index(&self, loc: usize) -> usize {
|
|
||||||
// unwrap is safe here because a partial string is always
|
|
||||||
// followed by a tail cell, i.e. a non-pstr cell, supposing
|
|
||||||
// self.state.heap[loc] is a pstr cell
|
|
||||||
self.state.heap.pstr_vec()[loc ..].first_zero().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn reserve(&mut self, num_cells: usize) -> Result<HeapWriter, usize> {
|
fn reserve(&mut self, num_cells: usize) -> Result<HeapWriter, usize> {
|
||||||
self.state.heap.reserve(num_cells)
|
self.state.heap.reserve(num_cells)
|
||||||
@@ -469,9 +470,22 @@ impl<'a> CopierTarget for CopyBallTerm<'a> {
|
|||||||
fn copy_pstr_to_threshold(&mut self, pstr_loc: usize) -> Result<usize, usize> {
|
fn copy_pstr_to_threshold(&mut self, pstr_loc: usize) -> Result<usize, usize> {
|
||||||
debug_assert!(pstr_loc < self.heap.byte_len());
|
debug_assert!(pstr_loc < self.heap.byte_len());
|
||||||
|
|
||||||
let (string, tail_loc) = self.heap.scan_slice_to_str(pstr_loc);
|
let HeapStringScan { string, tail_idx } = self.heap.scan_slice_to_str(pstr_loc);
|
||||||
self.stub.allocate_pstr(string)?;
|
self.stub.allocate_pstr(string)?;
|
||||||
Ok(tail_loc)
|
Ok(tail_idx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_slice_from<'b>(&'b self, from: usize) -> Box<dyn Iterator<Item = u8> + 'b> {
|
||||||
|
if from < self.heap.byte_len() {
|
||||||
|
Box::new(
|
||||||
|
self.heap.as_slice()[from..]
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.chain(self.stub.as_slice().iter().cloned()),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Box::new(self.stub.as_slice()[from..].iter().cloned())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -479,41 +493,6 @@ impl<'a> CopierTarget for CopyBallTerm<'a> {
|
|||||||
self.stub.reserve(num_cells)
|
self.stub.reserve(num_cells)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn pstr_head_cell_index(&self, pstr_loc: usize) -> usize {
|
|
||||||
if pstr_loc >= self.heap.byte_len() {
|
|
||||||
self.stub.pstr_vec()[0 .. cell_index!(pstr_loc - self.heap.byte_len())]
|
|
||||||
.last_zero()
|
|
||||||
.map(|idx| idx + 1)
|
|
||||||
.unwrap_or(0)
|
|
||||||
} else {
|
|
||||||
self.heap.pstr_vec()[0 .. cell_index!(pstr_loc)]
|
|
||||||
.last_zero()
|
|
||||||
.map(|idx| idx + 1)
|
|
||||||
.unwrap_or(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn pstr_at(&self, loc: usize) -> bool {
|
|
||||||
if loc >= self.heap.cell_len() {
|
|
||||||
self.stub.pstr_vec()[loc - self.heap.cell_len()]
|
|
||||||
} else {
|
|
||||||
self.heap.pstr_vec()[loc]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next_non_pstr_cell_index(&self, loc: usize) -> usize {
|
|
||||||
let zero_from_loc = if loc >= self.heap.cell_len() {
|
|
||||||
self.stub.pstr_vec()[loc - self.heap.cell_len() ..].first_zero().unwrap()
|
|
||||||
} else {
|
|
||||||
self.heap.pstr_vec()[loc ..].first_zero().unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
zero_from_loc + loc
|
|
||||||
}
|
|
||||||
|
|
||||||
fn copy_slice_to_end(&mut self, bounds: Range<usize>) -> Result<(), usize> {
|
fn copy_slice_to_end(&mut self, bounds: Range<usize>) -> Result<(), usize> {
|
||||||
let len = bounds.end - bounds.start;
|
let len = bounds.end - bounds.start;
|
||||||
let mut stub_writer = self.stub.reserve(len)?;
|
let mut stub_writer = self.stub.reserve(len)?;
|
||||||
@@ -699,9 +678,9 @@ impl MachineState {
|
|||||||
push_var_eq_functors(
|
push_var_eq_functors(
|
||||||
&mut self.heap,
|
&mut self.heap,
|
||||||
var_list.len(),
|
var_list.len(),
|
||||||
var_list.iter().map(|(var_name, var, _)| {
|
var_list
|
||||||
(var.get_value() as usize, var_name.clone())
|
.iter()
|
||||||
}),
|
.map(|(var_name, var, _)| { (var.get_value() as usize, var_name.clone()) }),
|
||||||
&self.atom_tbl,
|
&self.atom_tbl,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -737,7 +716,9 @@ impl MachineState {
|
|||||||
|
|
||||||
let mut singleton_var_set: IndexMap<Ref, bool> = IndexMap::new();
|
let mut singleton_var_set: IndexMap<Ref, bool> = IndexMap::new();
|
||||||
|
|
||||||
for cell in stackful_preorder_iter::<NonListElider>(&mut self.heap, &mut self.stack, term.focus) {
|
for cell in
|
||||||
|
stackful_preorder_iter::<NonListElider>(&mut self.heap, &mut self.stack, term.focus)
|
||||||
|
{
|
||||||
let cell = unmark_cell_bits!(cell);
|
let cell = unmark_cell_bits!(cell);
|
||||||
|
|
||||||
if let Some(var) = cell.as_var() {
|
if let Some(var) = cell.as_var() {
|
||||||
@@ -756,9 +737,10 @@ impl MachineState {
|
|||||||
singleton_var_set
|
singleton_var_set
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(var, is_singleton)| {
|
.filter(|(var, is_singleton)| {
|
||||||
**is_singleton && term.inverse_var_locs.contains_key(
|
**is_singleton
|
||||||
&(var.get_value() as usize)
|
&& term
|
||||||
)
|
.inverse_var_locs
|
||||||
|
.contains_key(&(var.get_value() as usize))
|
||||||
})
|
})
|
||||||
.count(),
|
.count(),
|
||||||
term.inverse_var_locs
|
term.inverse_var_locs
|
||||||
@@ -873,7 +855,8 @@ impl MachineState {
|
|||||||
CompilationError::ParserError(e) if e.is_unexpected_eof() => {
|
CompilationError::ParserError(e) if e.is_unexpected_eof() => {
|
||||||
match eof_handler(self, stream)? {
|
match eof_handler(self, stream)? {
|
||||||
OnEOF::Return => {
|
OnEOF::Return => {
|
||||||
return self.write_read_term_options(vec![], empty_list_as_cell!());
|
return self
|
||||||
|
.write_read_term_options(vec![], empty_list_as_cell!());
|
||||||
}
|
}
|
||||||
OnEOF::Continue => continue,
|
OnEOF::Continue => continue,
|
||||||
}
|
}
|
||||||
@@ -1012,11 +995,9 @@ impl MachineState {
|
|||||||
|
|
||||||
let term_loc = self.heap.cell_len();
|
let term_loc = self.heap.cell_len();
|
||||||
|
|
||||||
step_or_resource_error!(
|
step_or_resource_error!(self, self.heap.push_cell(term_to_be_printed), {
|
||||||
self,
|
return Ok(None);
|
||||||
self.heap.push_cell(term_to_be_printed),
|
});
|
||||||
{ return Ok(None); }
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut printer = HCPrinter::new(
|
let mut printer = HCPrinter::new(
|
||||||
&mut self.heap,
|
&mut self.heap,
|
||||||
|
|||||||
@@ -327,9 +327,9 @@ impl MachineState {
|
|||||||
self.ball.reset();
|
self.ball.reset();
|
||||||
|
|
||||||
let addr = self.registers[1];
|
let addr = self.registers[1];
|
||||||
let ball_boundary = self.heap.cell_len();
|
|
||||||
|
|
||||||
step_or_resource_error!(
|
self.ball.boundary = self.heap.cell_len();
|
||||||
|
self.ball.pstr_boundary = step_or_resource_error!(
|
||||||
self,
|
self,
|
||||||
copy_term(
|
copy_term(
|
||||||
CopyBallTerm::new(
|
CopyBallTerm::new(
|
||||||
@@ -342,8 +342,6 @@ impl MachineState {
|
|||||||
AttrVarPolicy::DeepCopy,
|
AttrVarPolicy::DeepCopy,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
self.ball.boundary = ball_boundary;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -359,14 +357,14 @@ impl MachineState {
|
|||||||
HeapPtr::PStr(h) => {
|
HeapPtr::PStr(h) => {
|
||||||
let mut char_iter = self.heap.char_iter(h);
|
let mut char_iter = self.heap.char_iter(h);
|
||||||
|
|
||||||
if self.s_offset == 0 { // read the car of the list
|
if self.s_offset == 0 {
|
||||||
|
// read the car of the list
|
||||||
let c = char_iter.next().unwrap();
|
let c = char_iter.next().unwrap();
|
||||||
char_as_cell!(c)
|
char_as_cell!(c)
|
||||||
} else { // read the (self.s_offset)^{th} cdr of the list
|
} else {
|
||||||
let byte_offset: usize = char_iter
|
// read the (self.s_offset)^{th} cdr of the list
|
||||||
.take(self.s_offset)
|
let byte_offset: usize =
|
||||||
.map(|c| c.len_utf8())
|
char_iter.take(self.s_offset).map(|c| c.len_utf8()).sum();
|
||||||
.sum();
|
|
||||||
let new_h = h + byte_offset;
|
let new_h = h + byte_offset;
|
||||||
|
|
||||||
self.s_offset = 0;
|
self.s_offset = 0;
|
||||||
@@ -375,7 +373,7 @@ impl MachineState {
|
|||||||
self.s = HeapPtr::PStr(new_h);
|
self.s = HeapPtr::PStr(new_h);
|
||||||
pstr_loc_as_cell!(new_h)
|
pstr_loc_as_cell!(new_h)
|
||||||
} else {
|
} else {
|
||||||
let h = Heap::neighboring_cell_offset(new_h);
|
let h = Heap::pstr_tail_idx(new_h);
|
||||||
self.s = HeapPtr::HeapCell(h);
|
self.s = HeapPtr::HeapCell(h);
|
||||||
self.deref(heap_loc_as_cell!(h))
|
self.deref(heap_loc_as_cell!(h))
|
||||||
}
|
}
|
||||||
@@ -946,7 +944,7 @@ impl MachineState {
|
|||||||
if char_iter.next().is_some() {
|
if char_iter.next().is_some() {
|
||||||
unify_fn!(*self, pstr_loc_as_cell!(pstr_loc + c.len_utf8()), a3);
|
unify_fn!(*self, pstr_loc_as_cell!(pstr_loc + c.len_utf8()), a3);
|
||||||
} else {
|
} else {
|
||||||
let tail_idx = Heap::neighboring_cell_offset(pstr_loc);
|
let tail_idx = Heap::pstr_tail_idx(pstr_loc);
|
||||||
unify_fn!(*self, self.heap[tail_idx]);
|
unify_fn!(*self, self.heap[tail_idx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1044,7 +1042,12 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_functor_fabricate_struct(&mut self, name: Atom, arity: usize, r: Ref) -> Result<(), usize> {
|
fn try_functor_fabricate_struct(
|
||||||
|
&mut self,
|
||||||
|
name: Atom,
|
||||||
|
arity: usize,
|
||||||
|
r: Ref,
|
||||||
|
) -> Result<(), usize> {
|
||||||
let h = self.heap.cell_len();
|
let h = self.heap.cell_len();
|
||||||
let mut writer = self.heap.reserve(arity + 1)?;
|
let mut writer = self.heap.reserve(arity + 1)?;
|
||||||
|
|
||||||
|
|||||||
@@ -51,14 +51,12 @@ impl MockWAM {
|
|||||||
) -> Result<String, CompilationError> {
|
) -> Result<String, CompilationError> {
|
||||||
let term_write_result = self.parse_and_write_parsed_term_to_heap(term_string)?;
|
let term_write_result = self.parse_and_write_parsed_term_to_heap(term_string)?;
|
||||||
|
|
||||||
print_heap_terms(self.machine_st.heap.splice(..), term_write_result.focus);
|
print_heap_terms(&self.machine_st.heap, term_write_result.focus);
|
||||||
|
|
||||||
let var_names = term_write_result
|
let var_names = term_write_result
|
||||||
.inverse_var_locs
|
.inverse_var_locs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(var_loc, var_name)| {
|
.map(|(var_loc, var_name)| (self.machine_st.heap[*var_loc], var_name.clone()))
|
||||||
(self.machine_st.heap[*var_loc], var_name.clone())
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut printer = HCPrinter::new(
|
let mut printer = HCPrinter::new(
|
||||||
@@ -90,6 +88,7 @@ pub struct TermCopyingMockWAM<'a> {
|
|||||||
impl<'a> Index<usize> for TermCopyingMockWAM<'a> {
|
impl<'a> Index<usize> for TermCopyingMockWAM<'a> {
|
||||||
type Output = HeapCellValue;
|
type Output = HeapCellValue;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn index(&self, index: usize) -> &HeapCellValue {
|
fn index(&self, index: usize) -> &HeapCellValue {
|
||||||
&self.wam.machine_st.heap[index]
|
&self.wam.machine_st.heap[index]
|
||||||
}
|
}
|
||||||
@@ -107,6 +106,7 @@ impl<'a> IndexMut<usize> for TermCopyingMockWAM<'a> {
|
|||||||
impl<'a> Deref for TermCopyingMockWAM<'a> {
|
impl<'a> Deref for TermCopyingMockWAM<'a> {
|
||||||
type Target = MockWAM;
|
type Target = MockWAM;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
self.wam
|
self.wam
|
||||||
}
|
}
|
||||||
@@ -114,6 +114,7 @@ impl<'a> Deref for TermCopyingMockWAM<'a> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
impl<'a> DerefMut for TermCopyingMockWAM<'a> {
|
impl<'a> DerefMut for TermCopyingMockWAM<'a> {
|
||||||
|
#[inline]
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
self.wam
|
self.wam
|
||||||
}
|
}
|
||||||
@@ -170,26 +171,8 @@ impl<'a> CopierTarget for TermCopyingMockWAM<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn pstr_head_cell_index(&self, pstr_loc: usize) -> usize {
|
fn as_slice_from<'b>(&'b self, from: usize) -> Box<dyn Iterator<Item = u8> + 'b> {
|
||||||
self.wam.machine_st.heap.pstr_vec()[0 .. cell_index!(pstr_loc)]
|
Box::new(self.wam.machine_st.heap.as_slice()[from..].iter().cloned())
|
||||||
.last_zero()
|
|
||||||
.map(|idx| idx + 1)
|
|
||||||
.unwrap_or(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn pstr_at(&self, loc: usize) -> bool {
|
|
||||||
self.wam.machine_st.heap.pstr_vec()[loc]
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn next_non_pstr_cell_index(&self, loc: usize) -> usize {
|
|
||||||
// unwrap is safe here because a partial string is always
|
|
||||||
// followed by a tail cell, i.e. a non-pstr cell, supposing
|
|
||||||
// self.machine_st.heap[loc] is a pstr cell
|
|
||||||
self.wam.machine_st.heap.pstr_vec()[loc ..].first_zero()
|
|
||||||
.map(|idx| idx + loc)
|
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -204,20 +187,9 @@ impl<'a> CopierTarget for TermCopyingMockWAM<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn all_cells_marked_and_unforwarded(iter: impl SizedHeap) {
|
pub fn all_cells_marked_and_unforwarded(heap: &Heap, offset: usize) {
|
||||||
let mut idx = 0;
|
for curr_idx in offset..heap.cell_len() {
|
||||||
let cell_len = iter.cell_len();
|
let cell = heap[curr_idx];
|
||||||
|
|
||||||
while idx < cell_len {
|
|
||||||
let curr_idx = idx;
|
|
||||||
let cell = if iter.pstr_at(idx) {
|
|
||||||
let (_s, last_cell_loc) = iter.scan_slice_to_str(heap_index!(idx));
|
|
||||||
idx = last_cell_loc;
|
|
||||||
iter[last_cell_loc - 1]
|
|
||||||
} else {
|
|
||||||
idx += 1;
|
|
||||||
iter[curr_idx]
|
|
||||||
};
|
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
cell.get_mark_bit(),
|
cell.get_mark_bit(),
|
||||||
@@ -235,43 +207,21 @@ pub fn all_cells_marked_and_unforwarded(iter: impl SizedHeap) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn unmark_all_cells(mut iter: impl SizedHeapMut) {
|
pub fn unmark_all_cells(heap: &mut Heap, offset: usize) {
|
||||||
let mut idx = 0;
|
for idx in offset..heap.cell_len() {
|
||||||
let cell_len = iter.cell_len();
|
heap[idx].set_mark_bit(false);
|
||||||
|
|
||||||
while idx < cell_len {
|
|
||||||
if iter.pstr_at(idx) {
|
|
||||||
iter[idx].set_mark_bit(false);
|
|
||||||
|
|
||||||
let last_cell_loc = {
|
|
||||||
let (_s, last_cell_loc) = iter.scan_slice_to_str(heap_index!(idx));
|
|
||||||
last_cell_loc
|
|
||||||
};
|
|
||||||
|
|
||||||
iter[last_cell_loc].set_mark_bit(false);
|
|
||||||
idx = last_cell_loc;
|
|
||||||
} else {
|
|
||||||
iter[idx].set_mark_bit(false);
|
|
||||||
idx += 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn all_cells_unmarked(iter: impl SizedHeap) {
|
pub fn all_cells_unmarked(iter: &impl SizedHeap) {
|
||||||
let mut idx = 0;
|
let mut idx = 0;
|
||||||
let cell_len = iter.cell_len();
|
let cell_len = iter.cell_len();
|
||||||
|
|
||||||
while idx < cell_len {
|
while idx < cell_len {
|
||||||
let curr_idx = idx;
|
let curr_idx = idx;
|
||||||
let cell = if iter.pstr_at(idx) {
|
idx += 1;
|
||||||
let (_s, last_cell_loc) = iter.scan_slice_to_str(heap_index!(idx));
|
let cell = iter[curr_idx];
|
||||||
idx = last_cell_loc;
|
|
||||||
iter[last_cell_loc - 1]
|
|
||||||
} else {
|
|
||||||
idx += 1;
|
|
||||||
iter[curr_idx]
|
|
||||||
};
|
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
!cell.get_mark_bit(),
|
!cell.get_mark_bit(),
|
||||||
@@ -354,7 +304,7 @@ mod tests {
|
|||||||
assert!(wam.fail);
|
assert!(wam.fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.heap.splice(..));
|
all_cells_unmarked(&wam.heap);
|
||||||
|
|
||||||
wam.fail = false;
|
wam.fail = false;
|
||||||
wam.heap.clear();
|
wam.heap.clear();
|
||||||
@@ -375,7 +325,7 @@ mod tests {
|
|||||||
assert!(!wam.fail);
|
assert!(!wam.fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.heap.splice(..));
|
all_cells_unmarked(&wam.heap);
|
||||||
|
|
||||||
wam.fail = false;
|
wam.fail = false;
|
||||||
wam.heap.clear();
|
wam.heap.clear();
|
||||||
@@ -396,7 +346,7 @@ mod tests {
|
|||||||
assert!(!wam.fail);
|
assert!(!wam.fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.heap.splice(..));
|
all_cells_unmarked(&wam.heap);
|
||||||
|
|
||||||
wam.fail = false;
|
wam.fail = false;
|
||||||
wam.heap.clear();
|
wam.heap.clear();
|
||||||
@@ -417,7 +367,7 @@ mod tests {
|
|||||||
assert!(!wam.fail);
|
assert!(!wam.fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.heap.splice(..));
|
all_cells_unmarked(&wam.heap);
|
||||||
|
|
||||||
wam.fail = false;
|
wam.fail = false;
|
||||||
wam.heap.clear();
|
wam.heap.clear();
|
||||||
@@ -438,7 +388,7 @@ mod tests {
|
|||||||
assert!(!wam.fail);
|
assert!(!wam.fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.heap.splice(..));
|
all_cells_unmarked(&wam.heap);
|
||||||
|
|
||||||
wam.fail = false;
|
wam.fail = false;
|
||||||
wam.heap.clear();
|
wam.heap.clear();
|
||||||
@@ -450,7 +400,7 @@ mod tests {
|
|||||||
let term_write_result_2 =
|
let term_write_result_2 =
|
||||||
parse_and_write_parsed_term_to_heap(&mut wam, "f(A,f(A)).", &op_dir).unwrap();
|
parse_and_write_parsed_term_to_heap(&mut wam, "f(A,f(A)).", &op_dir).unwrap();
|
||||||
|
|
||||||
all_cells_unmarked(wam.heap.splice(..));
|
all_cells_unmarked(&wam.heap);
|
||||||
|
|
||||||
unify!(
|
unify!(
|
||||||
wam,
|
wam,
|
||||||
@@ -461,7 +411,7 @@ mod tests {
|
|||||||
assert!(!wam.fail);
|
assert!(!wam.fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_cells_unmarked(wam.heap.splice(..));
|
all_cells_unmarked(&wam.heap);
|
||||||
|
|
||||||
wam.heap.clear();
|
wam.heap.clear();
|
||||||
|
|
||||||
@@ -489,9 +439,15 @@ mod tests {
|
|||||||
|
|
||||||
assert!(!wam.fail);
|
assert!(!wam.fail);
|
||||||
|
|
||||||
|
assert_eq!(wam.heap.slice_to_str(heap_index!(0), "this is a string".len()),
|
||||||
|
"this is a string");
|
||||||
assert_eq!(wam.heap[3], pstr_loc_as_cell!(heap_index!(8)));
|
assert_eq!(wam.heap[3], pstr_loc_as_cell!(heap_index!(8)));
|
||||||
|
assert_eq!(wam.heap.slice_to_str(heap_index!(4), "this is a string".len()),
|
||||||
all_cells_unmarked(wam.heap.splice(..));
|
"this is a string");
|
||||||
|
assert_eq!(wam.heap[7], pstr_loc_as_cell!(heap_index!(8)));
|
||||||
|
assert_eq!(wam.heap.slice_to_str(heap_index!(8), "this is a string".len()),
|
||||||
|
"this is a string");
|
||||||
|
assert_eq!(wam.heap[11], pstr_loc_as_cell!(heap_index!(8)));
|
||||||
|
|
||||||
wam.heap.clear();
|
wam.heap.clear();
|
||||||
|
|
||||||
@@ -515,7 +471,7 @@ mod tests {
|
|||||||
|
|
||||||
assert!(!wam.fail);
|
assert!(!wam.fail);
|
||||||
|
|
||||||
all_cells_unmarked(wam.heap.splice(..));
|
all_cells_unmarked(&wam.heap);
|
||||||
|
|
||||||
wam.heap.clear();
|
wam.heap.clear();
|
||||||
|
|
||||||
@@ -540,7 +496,7 @@ mod tests {
|
|||||||
assert!(wam.fail);
|
assert!(wam.fail);
|
||||||
|
|
||||||
wam.fail = false;
|
wam.fail = false;
|
||||||
all_cells_unmarked(wam.heap.splice(..));
|
all_cells_unmarked(&wam.heap);
|
||||||
|
|
||||||
wam.heap.clear();
|
wam.heap.clear();
|
||||||
|
|
||||||
@@ -562,7 +518,7 @@ mod tests {
|
|||||||
|
|
||||||
unify!(wam, heap_loc_as_cell!(0), heap_loc_as_cell!(5));
|
unify!(wam, heap_loc_as_cell!(0), heap_loc_as_cell!(5));
|
||||||
assert!(!wam.fail);
|
assert!(!wam.fail);
|
||||||
all_cells_unmarked(wam.heap.splice(..));
|
all_cells_unmarked(&wam.heap);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -581,7 +537,7 @@ mod tests {
|
|||||||
let term_write_result_2 =
|
let term_write_result_2 =
|
||||||
parse_and_write_parsed_term_to_heap(&mut wam, "f(A,f(A)).", &op_dir).unwrap();
|
parse_and_write_parsed_term_to_heap(&mut wam, "f(A,f(A)).", &op_dir).unwrap();
|
||||||
|
|
||||||
all_cells_unmarked(wam.heap.splice(..));
|
all_cells_unmarked(&wam.heap);
|
||||||
|
|
||||||
unify_with_occurs_check!(
|
unify_with_occurs_check!(
|
||||||
wam,
|
wam,
|
||||||
@@ -632,11 +588,7 @@ mod tests {
|
|||||||
let cstr_cell = wam.allocate_cstr("string").unwrap();
|
let cstr_cell = wam.allocate_cstr("string").unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
compare_term_test!(
|
compare_term_test!(wam, atom_as_cell!(atom!("atom")), cstr_cell),
|
||||||
wam,
|
|
||||||
atom_as_cell!(atom!("atom")),
|
|
||||||
cstr_cell
|
|
||||||
),
|
|
||||||
Some(Ordering::Less)
|
Some(Ordering::Less)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -735,11 +687,7 @@ mod tests {
|
|||||||
let cstr_cell = wam.allocate_cstr("string").unwrap();
|
let cstr_cell = wam.allocate_cstr("string").unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
compare_term_test!(
|
compare_term_test!(wam, empty_list_as_cell!(), cstr_cell),
|
||||||
wam,
|
|
||||||
empty_list_as_cell!(),
|
|
||||||
cstr_cell
|
|
||||||
),
|
|
||||||
Some(Ordering::Less)
|
Some(Ordering::Less)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -782,16 +730,13 @@ mod tests {
|
|||||||
assert!(!wam.is_cyclic_term(1));
|
assert!(!wam.is_cyclic_term(1));
|
||||||
assert!(!wam.is_cyclic_term(2));
|
assert!(!wam.is_cyclic_term(2));
|
||||||
|
|
||||||
all_cells_unmarked(wam.heap.splice(..));
|
all_cells_unmarked(&wam.heap);
|
||||||
wam.heap.clear();
|
wam.heap.clear();
|
||||||
|
|
||||||
let mut functor_writer = Heap::functor_writer(
|
let mut functor_writer = Heap::functor_writer(functor!(
|
||||||
functor!(
|
atom!("f"),
|
||||||
atom!("f"),
|
[atom_as_cell((atom!("a"))), atom_as_cell((atom!("b")))]
|
||||||
[atom_as_cell((atom!("a"))),
|
));
|
||||||
atom_as_cell((atom!("b")))]
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
functor_writer(&mut wam.heap).unwrap();
|
functor_writer(&mut wam.heap).unwrap();
|
||||||
|
|
||||||
@@ -800,30 +745,30 @@ mod tests {
|
|||||||
|
|
||||||
assert!(!wam.is_cyclic_term(h));
|
assert!(!wam.is_cyclic_term(h));
|
||||||
|
|
||||||
all_cells_unmarked(wam.heap.splice(..));
|
all_cells_unmarked(&wam.heap);
|
||||||
|
|
||||||
assert!(!wam.is_cyclic_term(1));
|
assert!(!wam.is_cyclic_term(1));
|
||||||
|
|
||||||
all_cells_unmarked(wam.heap.splice(..));
|
all_cells_unmarked(&wam.heap);
|
||||||
|
|
||||||
assert!(!wam.is_cyclic_term(2));
|
assert!(!wam.is_cyclic_term(2));
|
||||||
|
|
||||||
all_cells_unmarked(wam.heap.splice(..));
|
all_cells_unmarked(&wam.heap);
|
||||||
|
|
||||||
wam.heap[2] = str_loc_as_cell!(0);
|
wam.heap[2] = str_loc_as_cell!(0);
|
||||||
|
|
||||||
print_heap_terms(wam.heap.iter(), 0);
|
print_heap_terms(&wam.heap, 0);
|
||||||
|
|
||||||
assert!(wam.is_cyclic_term(2));
|
assert!(wam.is_cyclic_term(2));
|
||||||
|
|
||||||
all_cells_unmarked(wam.heap.splice(..));
|
all_cells_unmarked(&wam.heap);
|
||||||
|
|
||||||
wam.heap[2] = atom_as_cell!(atom!("b"));
|
wam.heap[2] = atom_as_cell!(atom!("b"));
|
||||||
wam.heap[1] = str_loc_as_cell!(0);
|
wam.heap[1] = str_loc_as_cell!(0);
|
||||||
|
|
||||||
assert!(wam.is_cyclic_term(1));
|
assert!(wam.is_cyclic_term(1));
|
||||||
|
|
||||||
all_cells_unmarked(wam.heap.splice(..));
|
all_cells_unmarked(&wam.heap);
|
||||||
|
|
||||||
wam.heap.clear();
|
wam.heap.clear();
|
||||||
|
|
||||||
|
|||||||
@@ -508,7 +508,8 @@ impl Machine {
|
|||||||
s,
|
s,
|
||||||
)) => {
|
)) => {
|
||||||
cell = self.deref_register(arg);
|
cell = self.deref_register(arg);
|
||||||
self.machine_st.select_switch_on_term_index(cell, v, c, l, s)
|
self.machine_st
|
||||||
|
.select_switch_on_term_index(cell, v, c, l, s)
|
||||||
}
|
}
|
||||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(hm)) => {
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(hm)) => {
|
||||||
// let lit = self.machine_st.constant_to_literal(cell);
|
// let lit = self.machine_st.constant_to_literal(cell);
|
||||||
@@ -1113,6 +1114,7 @@ impl Machine {
|
|||||||
if let Some(idx) = self.indices.code_dir.get(&(name, arity)).cloned() {
|
if let Some(idx) = self.indices.code_dir.get(&(name, arity)).cloned() {
|
||||||
self.try_execute(name, arity, idx.get())
|
self.try_execute(name, arity, idx.get())
|
||||||
} else {
|
} else {
|
||||||
|
println!("aaand undefined!");
|
||||||
self.undefined_procedure(name, arity)
|
self.undefined_procedure(name, arity)
|
||||||
}
|
}
|
||||||
} else if let Some(module) = self.indices.modules.get(&module_name) {
|
} else if let Some(module) = self.indices.modules.get(&module_name) {
|
||||||
|
|||||||
@@ -19,9 +19,17 @@ pub struct HeapPStrIter<'a> {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum PStrCmpResult<'a> {
|
pub enum PStrCmpResult<'a> {
|
||||||
ListMatch { list_loc: usize },
|
ListMatch {
|
||||||
CompletePStrMatch { chars_matched: usize, pstr_loc: usize },
|
list_loc: usize,
|
||||||
PartialPStrMatch { string: &'a str, var_loc: usize },
|
},
|
||||||
|
CompletePStrMatch {
|
||||||
|
chars_matched: usize,
|
||||||
|
pstr_loc: usize,
|
||||||
|
},
|
||||||
|
PartialPStrMatch {
|
||||||
|
string: &'a str,
|
||||||
|
var_loc: usize,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PStrIterStep {
|
struct PStrIterStep {
|
||||||
@@ -81,7 +89,7 @@ impl<'a> HeapPStrIter<'a> {
|
|||||||
if s.is_empty() {
|
if s.is_empty() {
|
||||||
return Some(PStrCmpResult::CompletePStrMatch { chars_matched, pstr_loc: h });
|
return Some(PStrCmpResult::CompletePStrMatch { chars_matched, pstr_loc: h });
|
||||||
} else {
|
} else {
|
||||||
let next_hare = Heap::neighboring_cell_offset(h + bytes_matched);
|
let next_hare = Heap::pstr_tail_idx(h + bytes_matched);
|
||||||
curr_hare = next_hare;
|
curr_hare = next_hare;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,11 +187,11 @@ impl<'a> HeapPStrIter<'a> {
|
|||||||
loop {
|
loop {
|
||||||
read_heap_cell!(self.heap[curr_hare],
|
read_heap_cell!(self.heap[curr_hare],
|
||||||
(HeapCellValueTag::PStrLoc, h) => {
|
(HeapCellValueTag::PStrLoc, h) => {
|
||||||
let (s, tail_loc) = self.heap.scan_slice_to_str(h);
|
let HeapStringScan { string, tail_idx } = self.heap.scan_slice_to_str(h);
|
||||||
|
|
||||||
return Ok(PStrIterStep {
|
return Ok(PStrIterStep {
|
||||||
iteratee: PStrIteratee::PStrSlice { slice_loc: h, slice_len: s.len() },
|
iteratee: PStrIteratee::PStrSlice { slice_loc: h, slice_len: string.len() },
|
||||||
next_hare: tail_loc,
|
next_hare: tail_idx,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Lis, h) => {
|
(HeapCellValueTag::Lis, h) => {
|
||||||
@@ -319,7 +327,10 @@ impl<'a> Iterator for PStrCharsIter<'a> {
|
|||||||
self.item = self.iter.next();
|
self.item = self.iter.next();
|
||||||
return Some(value);
|
return Some(value);
|
||||||
}
|
}
|
||||||
PStrIteratee::PStrSlice { slice_loc, slice_len } => {
|
PStrIteratee::PStrSlice {
|
||||||
|
slice_loc,
|
||||||
|
slice_len,
|
||||||
|
} => {
|
||||||
let s = self.iter.heap.slice_to_str(slice_loc, slice_len);
|
let s = self.iter.heap.slice_to_str(slice_loc, slice_len);
|
||||||
|
|
||||||
match s.chars().next() {
|
match s.chars().next() {
|
||||||
@@ -353,7 +364,10 @@ mod test {
|
|||||||
let mut wam = MockWAM::new();
|
let mut wam = MockWAM::new();
|
||||||
|
|
||||||
let pstr_cell = wam.machine_st.allocate_pstr("abc ").unwrap();
|
let pstr_cell = wam.machine_st.allocate_pstr("abc ").unwrap();
|
||||||
wam.machine_st.heap.push_cell(empty_list_as_cell!()).unwrap();
|
wam.machine_st
|
||||||
|
.heap
|
||||||
|
.push_cell(empty_list_as_cell!())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// not overwriting anything! 0 is an interstitial cell
|
// not overwriting anything! 0 is an interstitial cell
|
||||||
// reserved for use by the runtime
|
// reserved for use by the runtime
|
||||||
@@ -364,7 +378,10 @@ mod test {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
iter.next(),
|
iter.next(),
|
||||||
Some(PStrIteratee::PStrSlice { slice_loc: heap_index!(1), slice_len: "abc ".len() }),
|
Some(PStrIteratee::PStrSlice {
|
||||||
|
slice_loc: heap_index!(1),
|
||||||
|
slice_len: "abc ".len()
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
assert!(!iter.is_cyclic());
|
assert!(!iter.is_cyclic());
|
||||||
@@ -384,7 +401,10 @@ mod test {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
iter.next(),
|
iter.next(),
|
||||||
Some(PStrIteratee::PStrSlice { slice_loc: heap_index!(1), slice_len: "abc ".len() })
|
Some(PStrIteratee::PStrSlice {
|
||||||
|
slice_loc: heap_index!(1),
|
||||||
|
slice_len: "abc ".len()
|
||||||
|
})
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
iter.next(),
|
iter.next(),
|
||||||
@@ -407,7 +427,10 @@ mod test {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
iter.next(),
|
iter.next(),
|
||||||
Some(PStrIteratee::PStrSlice { slice_loc: heap_index!(1), slice_len: "abc ".len() })
|
Some(PStrIteratee::PStrSlice {
|
||||||
|
slice_loc: heap_index!(1),
|
||||||
|
slice_len: "abc ".len()
|
||||||
|
})
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
iter.next(),
|
iter.next(),
|
||||||
@@ -552,7 +575,11 @@ mod test {
|
|||||||
section.push_cell(heap_loc_as_cell!(h));
|
section.push_cell(heap_loc_as_cell!(h));
|
||||||
});
|
});
|
||||||
|
|
||||||
unify!(wam.machine_st, pstr_cell, pstr_loc_as_cell!(heap_index!(start)));
|
unify!(
|
||||||
|
wam.machine_st,
|
||||||
|
pstr_cell,
|
||||||
|
pstr_loc_as_cell!(heap_index!(start))
|
||||||
|
);
|
||||||
|
|
||||||
assert!(!wam.machine_st.fail);
|
assert!(!wam.machine_st.fail);
|
||||||
|
|
||||||
@@ -561,7 +588,9 @@ mod test {
|
|||||||
"abcdef"
|
"abcdef"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
wam.machine_st.heap.slice_to_str(heap_index!(start), "abc".len()),
|
wam.machine_st
|
||||||
|
.heap
|
||||||
|
.slice_to_str(heap_index!(start), "abc".len()),
|
||||||
"abc"
|
"abc"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -587,7 +616,10 @@ mod test {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
iter.next(),
|
iter.next(),
|
||||||
Some(PStrIteratee::PStrSlice { slice_loc: 'a'.len_utf8(), slice_len: "bc".len() })
|
Some(PStrIteratee::PStrSlice {
|
||||||
|
slice_loc: 'a'.len_utf8(),
|
||||||
|
slice_len: "bc".len()
|
||||||
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
for _ in iter {}
|
for _ in iter {}
|
||||||
@@ -609,7 +641,11 @@ mod test {
|
|||||||
section.push_cell(empty_list_as_cell!());
|
section.push_cell(empty_list_as_cell!());
|
||||||
});
|
});
|
||||||
|
|
||||||
unify!(wam.machine_st, list_loc_as_cell!(start), pstr_loc_as_cell!(0));
|
unify!(
|
||||||
|
wam.machine_st,
|
||||||
|
list_loc_as_cell!(start),
|
||||||
|
pstr_loc_as_cell!(0)
|
||||||
|
);
|
||||||
|
|
||||||
assert!(!wam.machine_st.fail);
|
assert!(!wam.machine_st.fail);
|
||||||
|
|
||||||
@@ -629,7 +665,11 @@ mod test {
|
|||||||
section.push_cell(empty_list_as_cell!());
|
section.push_cell(empty_list_as_cell!());
|
||||||
});
|
});
|
||||||
|
|
||||||
unify!(wam.machine_st, list_loc_as_cell!(start), pstr_loc_as_cell!(0));
|
unify!(
|
||||||
|
wam.machine_st,
|
||||||
|
list_loc_as_cell!(start),
|
||||||
|
pstr_loc_as_cell!(0)
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.heap[2 + start], char_as_cell!('a'));
|
assert_eq!(wam.machine_st.heap[2 + start], char_as_cell!('a'));
|
||||||
assert!(!wam.machine_st.fail);
|
assert!(!wam.machine_st.fail);
|
||||||
@@ -652,7 +692,11 @@ mod test {
|
|||||||
section.push_cell(empty_list_as_cell!());
|
section.push_cell(empty_list_as_cell!());
|
||||||
});
|
});
|
||||||
|
|
||||||
unify!(wam.machine_st, list_loc_as_cell!(start), pstr_loc_as_cell!(0));
|
unify!(
|
||||||
|
wam.machine_st,
|
||||||
|
list_loc_as_cell!(start),
|
||||||
|
pstr_loc_as_cell!(0)
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.heap[start], char_as_cell!('a'));
|
assert_eq!(wam.machine_st.heap[start], char_as_cell!('a'));
|
||||||
assert_eq!(wam.machine_st.heap[4 + start], char_as_cell!('b'));
|
assert_eq!(wam.machine_st.heap[4 + start], char_as_cell!('b'));
|
||||||
@@ -676,7 +720,11 @@ mod test {
|
|||||||
section.push_cell(empty_list_as_cell!());
|
section.push_cell(empty_list_as_cell!());
|
||||||
});
|
});
|
||||||
|
|
||||||
unify!(wam.machine_st, list_loc_as_cell!(start), pstr_loc_as_cell!(0));
|
unify!(
|
||||||
|
wam.machine_st,
|
||||||
|
list_loc_as_cell!(start),
|
||||||
|
pstr_loc_as_cell!(0)
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.heap[2 + start], char_as_cell!('a'));
|
assert_eq!(wam.machine_st.heap[2 + start], char_as_cell!('a'));
|
||||||
assert!(!wam.machine_st.fail);
|
assert!(!wam.machine_st.fail);
|
||||||
@@ -699,10 +747,17 @@ mod test {
|
|||||||
section.push_cell(heap_loc_as_cell!(5 + start));
|
section.push_cell(heap_loc_as_cell!(5 + start));
|
||||||
});
|
});
|
||||||
|
|
||||||
unify!(wam.machine_st, list_loc_as_cell!(start), pstr_loc_as_cell!(0));
|
unify!(
|
||||||
|
wam.machine_st,
|
||||||
|
list_loc_as_cell!(start),
|
||||||
|
pstr_loc_as_cell!(0)
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.heap[2 + start], char_as_cell!('a'));
|
assert_eq!(wam.machine_st.heap[2 + start], char_as_cell!('a'));
|
||||||
assert_eq!(wam.machine_st.heap[5 + start], pstr_loc_as_cell!(heap_index!(0) + 3));
|
assert_eq!(
|
||||||
|
wam.machine_st.heap[5 + start],
|
||||||
|
pstr_loc_as_cell!(heap_index!(0) + 3)
|
||||||
|
);
|
||||||
assert!(!wam.machine_st.fail);
|
assert!(!wam.machine_st.fail);
|
||||||
|
|
||||||
// #2293, test6.
|
// #2293, test6.
|
||||||
@@ -723,7 +778,11 @@ mod test {
|
|||||||
section.push_cell(empty_list_as_cell!());
|
section.push_cell(empty_list_as_cell!());
|
||||||
});
|
});
|
||||||
|
|
||||||
unify!(wam.machine_st, list_loc_as_cell!(start), pstr_loc_as_cell!(0));
|
unify!(
|
||||||
|
wam.machine_st,
|
||||||
|
list_loc_as_cell!(start),
|
||||||
|
pstr_loc_as_cell!(0)
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.heap[start], char_as_cell!('a'));
|
assert_eq!(wam.machine_st.heap[start], char_as_cell!('a'));
|
||||||
assert_eq!(wam.machine_st.heap[4 + start], char_as_cell!('c'));
|
assert_eq!(wam.machine_st.heap[4 + start], char_as_cell!('c'));
|
||||||
@@ -750,7 +809,11 @@ mod test {
|
|||||||
section.push_cell(empty_list_as_cell!());
|
section.push_cell(empty_list_as_cell!());
|
||||||
});
|
});
|
||||||
|
|
||||||
unify!(wam.machine_st, list_loc_as_cell!(start), pstr_loc_as_cell!(0));
|
unify!(
|
||||||
|
wam.machine_st,
|
||||||
|
list_loc_as_cell!(start),
|
||||||
|
pstr_loc_as_cell!(0)
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.heap[2 + start], char_as_cell!('b'));
|
assert_eq!(wam.machine_st.heap[2 + start], char_as_cell!('b'));
|
||||||
assert_eq!(wam.machine_st.heap[6 + start], char_as_cell!('d'));
|
assert_eq!(wam.machine_st.heap[6 + start], char_as_cell!('d'));
|
||||||
|
|||||||
@@ -28,26 +28,26 @@ pub(crate) fn to_op_decl_spec(spec: Atom) -> Result<OpDeclSpec, CompilationError
|
|||||||
fn setup_op_decl(term: &FocusedHeapRefMut) -> Result<OpDecl, CompilationError> {
|
fn setup_op_decl(term: &FocusedHeapRefMut) -> Result<OpDecl, CompilationError> {
|
||||||
let (focus, _cell) = subterm_index(term.heap, term.focus);
|
let (focus, _cell) = subterm_index(term.heap, term.focus);
|
||||||
|
|
||||||
let name = match term_predicate_key(term.heap, focus+3) {
|
let name = match term_predicate_key(term.heap, focus + 3) {
|
||||||
Some((name, 0)) => name,
|
Some((name, 0)) => name,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(CompilationError::InvalidDirective(
|
return Err(CompilationError::InvalidDirective(
|
||||||
DirectiveError::InvalidOpDeclNameType(term.heap[focus+3]),
|
DirectiveError::InvalidOpDeclNameType(term.heap[focus + 3]),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let spec = match term_predicate_key(term.heap, focus+2) {
|
let spec = match term_predicate_key(term.heap, focus + 2) {
|
||||||
Some((name, _)) => name,
|
Some((name, _)) => name,
|
||||||
None => {
|
None => {
|
||||||
return Err(CompilationError::InvalidDirective(
|
return Err(CompilationError::InvalidDirective(
|
||||||
DirectiveError::InvalidOpDeclSpecDomain(term.heap[focus+2]),
|
DirectiveError::InvalidOpDeclSpecDomain(term.heap[focus + 2]),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let spec = to_op_decl_spec(spec)?;
|
let spec = to_op_decl_spec(spec)?;
|
||||||
let prec = term.deref_loc(focus+1);
|
let prec = term.deref_loc(focus + 1);
|
||||||
|
|
||||||
let prec = read_heap_cell!(prec,
|
let prec = read_heap_cell!(prec,
|
||||||
(HeapCellValueTag::Fixnum, n) => {
|
(HeapCellValueTag::Fixnum, n) => {
|
||||||
@@ -147,34 +147,34 @@ pub(super) fn setup_module_export_list(
|
|||||||
let mut focus = term.focus;
|
let mut focus = term.focus;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
read_heap_cell!(term.heap[focus],
|
read_heap_cell!(term.heap[focus],
|
||||||
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
|
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
|
||||||
if h == focus {
|
if h == focus {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
focus = h;
|
focus = h;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Lis, l) => {
|
(HeapCellValueTag::Lis, l) => {
|
||||||
let term = FocusedHeapRefMut {
|
let term = FocusedHeapRefMut {
|
||||||
heap: term.heap,
|
heap: term.heap,
|
||||||
focus: l,
|
focus: l,
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.push(setup_module_export(&term)?);
|
exports.push(setup_module_export(&term)?);
|
||||||
focus = l + 1;
|
focus = l + 1;
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Atom, (name, _arity)) => {
|
(HeapCellValueTag::Atom, (name, _arity)) => {
|
||||||
if name == atom!("[]") {
|
if name == atom!("[]") {
|
||||||
return Ok(exports);
|
return Ok(exports);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(CompilationError::InvalidModuleDecl)
|
Err(CompilationError::InvalidModuleDecl)
|
||||||
@@ -281,7 +281,7 @@ fn setup_qualified_import(term: FocusedHeapRefMut) -> Result<UseModuleExport, Co
|
|||||||
* contained in src/lib/ops_and_meta_predicates.pl, which is loaded before
|
* contained in src/lib/ops_and_meta_predicates.pl, which is loaded before
|
||||||
* src/lib/builtins.pl.
|
* src/lib/builtins.pl.
|
||||||
*
|
*
|
||||||
* Meta-specs have three forms:
|
* Meta-specs have four forms:
|
||||||
*
|
*
|
||||||
* (:) (the argument should be expanded with (:)/2 as described above)
|
* (:) (the argument should be expanded with (:)/2 as described above)
|
||||||
* + (mode declarations under the mode syntax, which currently have no effect)
|
* + (mode declarations under the mode syntax, which currently have no effect)
|
||||||
@@ -334,7 +334,7 @@ fn setup_meta_predicate<'a, LS: LoadState<'a>>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let heap = loader.machine_heap();
|
let heap = loader.machine_heap();
|
||||||
let cell = heap_bound_store(heap, heap_bound_deref(heap, heap[term.focus+1]));
|
let cell = heap_bound_store(heap, heap_bound_deref(heap, heap[term.focus + 1]));
|
||||||
|
|
||||||
read_heap_cell!(cell,
|
read_heap_cell!(cell,
|
||||||
(HeapCellValueTag::Str, s) => {
|
(HeapCellValueTag::Str, s) => {
|
||||||
@@ -506,28 +506,27 @@ fn build_meta_predicate_clause<'a, LS: LoadState<'a>>(
|
|||||||
let (subterm_loc, _) = subterm_index(loader.machine_heap(), subterm_loc);
|
let (subterm_loc, _) = subterm_index(loader.machine_heap(), subterm_loc);
|
||||||
let subterm_key_opt = term_predicate_key(loader.machine_heap(), subterm_loc);
|
let subterm_key_opt = term_predicate_key(loader.machine_heap(), subterm_loc);
|
||||||
|
|
||||||
let (module_name, key, term_loc) =
|
let (module_name, key, term_loc) = if subterm_key_opt == Some((atom!(":"), 2)) {
|
||||||
if subterm_key_opt == Some((atom!(":"), 2)) {
|
match get_qualified_name(
|
||||||
match get_qualified_name(loader.machine_heap(), subterm_loc + 1, subterm_loc + 2) {
|
loader.machine_heap(),
|
||||||
Some(QualifiedNameInfo {
|
subterm_loc + 1,
|
||||||
module_name,
|
subterm_loc + 2,
|
||||||
name,
|
) {
|
||||||
arity,
|
Some(QualifiedNameInfo {
|
||||||
qualified_term_loc,
|
module_name,
|
||||||
}) => (
|
name,
|
||||||
module_name,
|
arity,
|
||||||
(name, arity + supp_args),
|
qualified_term_loc,
|
||||||
qualified_term_loc,
|
}) => (module_name, (name, arity + supp_args), qualified_term_loc),
|
||||||
),
|
None => {
|
||||||
None => {
|
continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
(module_name, (name, arity + supp_args), subterm_loc)
|
} else {
|
||||||
};
|
(module_name, (name, arity + supp_args), subterm_loc)
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(index_ptr) = fetch_index_ptr(loader.machine_heap(), key.1, term_loc) {
|
if let Some(index_ptr) = fetch_index_ptr(loader.machine_heap(), term_loc) {
|
||||||
index_ptrs.insert(term_loc, index_ptr);
|
index_ptrs.insert(term_loc, index_ptr);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -642,7 +641,12 @@ impl Preprocessor {
|
|||||||
let classifier = VariableClassifier::new(self.settings.default_call_policy());
|
let classifier = VariableClassifier::new(self.settings.default_call_policy());
|
||||||
let var_data = classifier.classify_fact(loader, &term)?;
|
let var_data = classifier.classify_fact(loader, &term)?;
|
||||||
|
|
||||||
Ok((Fact { term_loc: term.focus }, var_data))
|
Ok((
|
||||||
|
Fact {
|
||||||
|
term_loc: term.focus,
|
||||||
|
},
|
||||||
|
var_data,
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
Err(CompilationError::InadmissibleFact)
|
Err(CompilationError::InadmissibleFact)
|
||||||
}
|
}
|
||||||
@@ -660,7 +664,13 @@ impl Preprocessor {
|
|||||||
let head_loc = term_nth_arg(heap, term.focus, 1).unwrap();
|
let head_loc = term_nth_arg(heap, term.focus, 1).unwrap();
|
||||||
|
|
||||||
if term_predicate_key(heap, head_loc).is_some() {
|
if term_predicate_key(heap, head_loc).is_some() {
|
||||||
Ok((Rule { term_loc: term.focus, clauses }, var_data))
|
Ok((
|
||||||
|
Rule {
|
||||||
|
term_loc: term.focus,
|
||||||
|
clauses,
|
||||||
|
},
|
||||||
|
var_data,
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
Err(CompilationError::InvalidRuleHead)
|
Err(CompilationError::InvalidRuleHead)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,10 +181,7 @@ fn pstr_segment_char_count_and_tail(heap: &Heap, pstr_loc: usize) -> (usize, usi
|
|||||||
byte_offset += c.len_utf8();
|
byte_offset += c.len_utf8();
|
||||||
}
|
}
|
||||||
|
|
||||||
(
|
(char_count, Heap::pstr_tail_idx(pstr_loc + byte_offset))
|
||||||
char_count,
|
|
||||||
Heap::neighboring_cell_offset(pstr_loc + byte_offset),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pstr_segment_char_count_up_to(
|
fn pstr_segment_char_count_up_to(
|
||||||
@@ -217,10 +214,9 @@ fn pstr_segment_char_count_up_to(
|
|||||||
pstr_loc: pstr_loc + byte_offset,
|
pstr_loc: pstr_loc + byte_offset,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let tail_loc = Heap::neighboring_cell_offset(pstr_loc + byte_offset);
|
|
||||||
PStrSegmentCountResult::End {
|
PStrSegmentCountResult::End {
|
||||||
char_count,
|
char_count,
|
||||||
tail_loc,
|
tail_loc: Heap::pstr_tail_idx(pstr_loc + byte_offset),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -567,6 +563,12 @@ struct AttrListMatch {
|
|||||||
prev_tail: Option<usize>,
|
prev_tail: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct FindallCopyInfo {
|
||||||
|
offset: usize,
|
||||||
|
pstr_threshold: usize,
|
||||||
|
}
|
||||||
|
|
||||||
impl MachineState {
|
impl MachineState {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn unattributed_var(&mut self) {
|
pub(crate) fn unattributed_var(&mut self) {
|
||||||
@@ -648,9 +650,8 @@ impl MachineState {
|
|||||||
loop {
|
loop {
|
||||||
read_heap_cell!(value,
|
read_heap_cell!(value,
|
||||||
(HeapCellValueTag::PStrLoc, h) => {
|
(HeapCellValueTag::PStrLoc, h) => {
|
||||||
let (_, tail) = heap.scan_slice_to_str(h);
|
let HeapStringScan { tail_idx, .. } = heap.scan_slice_to_str(h);
|
||||||
// let (h_offset, _) = pstr_loc_and_offset(heap, h);
|
return tail_idx;
|
||||||
return tail;
|
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Lis, h) => {
|
(HeapCellValueTag::Lis, h) => {
|
||||||
return h+1;
|
return h+1;
|
||||||
@@ -855,17 +856,10 @@ impl MachineState {
|
|||||||
&mut self,
|
&mut self,
|
||||||
lh_offset: usize,
|
lh_offset: usize,
|
||||||
copy_target: HeapCellValue,
|
copy_target: HeapCellValue,
|
||||||
) -> Result<usize, usize> {
|
) -> Result<FindallCopyInfo, usize> {
|
||||||
let threshold = self.lifted_heap.cell_len() - lh_offset;
|
let threshold = self.lifted_heap.cell_len() - lh_offset;
|
||||||
|
|
||||||
let mut copy_ball_term = CopyBallTerm::new(
|
let mut writer = self.lifted_heap.reserve(3)?;
|
||||||
&mut self.attr_var_init.attr_var_queue,
|
|
||||||
&mut self.stack,
|
|
||||||
&mut self.heap,
|
|
||||||
&mut self.lifted_heap,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut writer = copy_ball_term.reserve(3)?;
|
|
||||||
|
|
||||||
writer.write_with(|section| {
|
writer.write_with(|section| {
|
||||||
section.push_cell(list_loc_as_cell!(threshold + 1));
|
section.push_cell(list_loc_as_cell!(threshold + 1));
|
||||||
@@ -873,9 +867,21 @@ impl MachineState {
|
|||||||
section.push_cell(heap_loc_as_cell!(threshold + 2));
|
section.push_cell(heap_loc_as_cell!(threshold + 2));
|
||||||
});
|
});
|
||||||
|
|
||||||
copy_term(copy_ball_term, copy_target, AttrVarPolicy::DeepCopy)?;
|
let old_lifted_cell_len = self.lifted_heap.cell_len();
|
||||||
|
|
||||||
Ok(threshold + lh_offset + 2)
|
let copy_ball_term = CopyBallTerm::new(
|
||||||
|
&mut self.attr_var_init.attr_var_queue,
|
||||||
|
&mut self.stack,
|
||||||
|
&mut self.heap,
|
||||||
|
&mut self.lifted_heap,
|
||||||
|
);
|
||||||
|
|
||||||
|
let pstr_boundary = copy_term(copy_ball_term, copy_target, AttrVarPolicy::DeepCopy)?;
|
||||||
|
|
||||||
|
Ok(FindallCopyInfo {
|
||||||
|
offset: threshold + lh_offset + 2,
|
||||||
|
pstr_threshold: pstr_boundary + old_lifted_cell_len,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -1045,18 +1051,6 @@ impl MachineState {
|
|||||||
|
|
||||||
pub fn value_to_str_like(&mut self, value: HeapCellValue) -> Option<AtomOrString> {
|
pub fn value_to_str_like(&mut self, value: HeapCellValue) -> Option<AtomOrString> {
|
||||||
read_heap_cell!(value,
|
read_heap_cell!(value,
|
||||||
/*
|
|
||||||
(HeapCellValueTag::CStr, cstr_atom) => {
|
|
||||||
// avoid allocating a String if possible:
|
|
||||||
// We must be careful to preserve the string "[]" as is,
|
|
||||||
// instead of turning it into the atom [], i.e., "".
|
|
||||||
if cstr_atom == atom!("[]") {
|
|
||||||
Some(AtomOrString::String("[]".to_string()))
|
|
||||||
} else {
|
|
||||||
Some(AtomOrString::Atom(cstr_atom))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
(HeapCellValueTag::Atom, (atom, arity)) => {
|
(HeapCellValueTag::Atom, (atom, arity)) => {
|
||||||
if arity == 0 {
|
if arity == 0 {
|
||||||
// ... likewise.
|
// ... likewise.
|
||||||
@@ -1389,15 +1383,7 @@ impl Machine {
|
|||||||
let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
|
let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
|
||||||
.get_name_and_arity();
|
.get_name_and_arity();
|
||||||
|
|
||||||
(name, arity, if self.machine_st.heap.cell_len() > s + arity + 1 {
|
(name, arity, get_structure_index(self.machine_st.heap[s.saturating_sub(1)]))
|
||||||
if !self.machine_st.heap.pstr_at(s + arity + 1) {
|
|
||||||
get_structure_index(self.machine_st.heap[s + arity + 1])
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Atom, (name, arity)) => {
|
(HeapCellValueTag::Atom, (name, arity)) => {
|
||||||
debug_assert_eq!(arity, 0);
|
debug_assert_eq!(arity, 0);
|
||||||
@@ -1457,7 +1443,6 @@ impl Machine {
|
|||||||
|
|
||||||
if let Some(code_index) = index_cell {
|
if let Some(code_index) = index_cell {
|
||||||
if !code_index.is_undefined() {
|
if !code_index.is_undefined() {
|
||||||
// println!("(fast) calling {}/{}", name.as_str(), arity);
|
|
||||||
load_registers(&mut self.machine_st, goal, goal_arity);
|
load_registers(&mut self.machine_st, goal, goal_arity);
|
||||||
self.machine_st.neck_cut();
|
self.machine_st.neck_cut();
|
||||||
return call_at_index(self, name, arity, code_index.get());
|
return call_at_index(self, name, arity, code_index.get());
|
||||||
@@ -1481,6 +1466,7 @@ impl Machine {
|
|||||||
.variable_set(&mut supp_vars, self.machine_st.registers[2]);
|
.variable_set(&mut supp_vars, self.machine_st.registers[2]);
|
||||||
|
|
||||||
struct GoalAnalysisResult {
|
struct GoalAnalysisResult {
|
||||||
|
index_ptr_loc: usize,
|
||||||
is_simple_goal: bool,
|
is_simple_goal: bool,
|
||||||
goal: HeapCellValue,
|
goal: HeapCellValue,
|
||||||
key: PredicateKey,
|
key: PredicateKey,
|
||||||
@@ -1496,7 +1482,7 @@ impl Machine {
|
|||||||
|
|
||||||
// fill expanded_vars with variables of the partial
|
// fill expanded_vars with variables of the partial
|
||||||
// goal pre-completion by complete_partial_goal.
|
// goal pre-completion by complete_partial_goal.
|
||||||
for idx in s + 1 .. s + arity - supp_vars.len() + 1 {
|
for idx in s + 1 ..= s + arity - supp_vars.len() {
|
||||||
self.machine_st.variable_set(&mut expanded_vars, self.machine_st.heap[idx]);
|
self.machine_st.variable_set(&mut expanded_vars, self.machine_st.heap[idx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1510,7 +1496,8 @@ impl Machine {
|
|||||||
// disjoint from them. if they are not, the
|
// disjoint from them. if they are not, the
|
||||||
// expanded goal is not simple.
|
// expanded goal is not simple.
|
||||||
|
|
||||||
let post_supp_args = self.machine_st.heap.splice(s+arity-supp_vars.len()+1 .. s+arity+1);
|
let post_supp_args = (s+arity-supp_vars.len()+1 ..= s+arity)
|
||||||
|
.map(|idx| self.machine_st.heap[idx]);
|
||||||
|
|
||||||
post_supp_args
|
post_supp_args
|
||||||
.zip(supp_vars.iter())
|
.zip(supp_vars.iter())
|
||||||
@@ -1535,27 +1522,33 @@ impl Machine {
|
|||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
let goal = if is_simple_goal {
|
let (index_ptr_loc, goal) = if is_simple_goal {
|
||||||
let h = self.machine_st.heap.cell_len();
|
let h = self.machine_st.heap.cell_len();
|
||||||
let arity = arity - supp_vars.len();
|
let arity = arity - supp_vars.len();
|
||||||
|
|
||||||
|
resource_error_call_result!(
|
||||||
|
self.machine_st,
|
||||||
|
self.machine_st.heap.push_cell(empty_list_as_cell!())
|
||||||
|
);
|
||||||
|
|
||||||
resource_error_call_result!(
|
resource_error_call_result!(
|
||||||
self.machine_st,
|
self.machine_st,
|
||||||
self.machine_st.heap.copy_slice_to_end(
|
self.machine_st.heap.copy_slice_to_end(
|
||||||
s .. s + arity + 1
|
s ..= s + arity,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
self.machine_st.heap[h] = atom_as_cell!(name, arity);
|
self.machine_st.heap[h+1] = atom_as_cell!(name, arity);
|
||||||
|
|
||||||
// even if arity == 0, goal must be a Str cell,
|
// even if arity == 0, goal must be a Str cell,
|
||||||
// since an index is about to appended to it.
|
// since an index is about to appended to it.
|
||||||
str_loc_as_cell!(h)
|
(h, str_loc_as_cell!(h+1))
|
||||||
} else {
|
} else {
|
||||||
goal
|
(0, goal)
|
||||||
};
|
};
|
||||||
|
|
||||||
GoalAnalysisResult {
|
GoalAnalysisResult {
|
||||||
|
index_ptr_loc,
|
||||||
is_simple_goal,
|
is_simple_goal,
|
||||||
goal,
|
goal,
|
||||||
key: (name, arity),
|
key: (name, arity),
|
||||||
@@ -1566,36 +1559,25 @@ impl Machine {
|
|||||||
debug_assert_eq!(arity, 0);
|
debug_assert_eq!(arity, 0);
|
||||||
|
|
||||||
let h = self.machine_st.heap.cell_len();
|
let h = self.machine_st.heap.cell_len();
|
||||||
resource_error_call_result!(
|
|
||||||
|
let mut writer = resource_error_call_result!(
|
||||||
self.machine_st,
|
self.machine_st,
|
||||||
self.machine_st.heap.push_cell(goal)
|
self.machine_st.heap.reserve(2)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
writer.write_with(|section| {
|
||||||
|
section.push_cell(empty_list_as_cell!());
|
||||||
|
section.push_cell(goal);
|
||||||
|
});
|
||||||
|
|
||||||
GoalAnalysisResult {
|
GoalAnalysisResult {
|
||||||
|
index_ptr_loc: h,
|
||||||
is_simple_goal: true,
|
is_simple_goal: true,
|
||||||
goal: str_loc_as_cell!(h),
|
goal: str_loc_as_cell!(h+1),
|
||||||
key: (name, 0),
|
key: (name, 0),
|
||||||
supp_vars,
|
supp_vars,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
(HeapCellValueTag::Char, c) => {
|
|
||||||
let name = AtomTable::build_with(&self.machine_st.atom_tbl,&c.to_string());
|
|
||||||
let h = self.machine_st.heap.cell_len();
|
|
||||||
|
|
||||||
resource_error_call_result!(
|
|
||||||
self.machine_st,
|
|
||||||
self.machine_st.heap.push_cell(atom_as_cell!(name))
|
|
||||||
);
|
|
||||||
|
|
||||||
GoalAnalysisResult {
|
|
||||||
is_simple_goal: true,
|
|
||||||
goal: str_loc_as_cell!(h),
|
|
||||||
key: (name, 0),
|
|
||||||
supp_vars,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
_ => {
|
_ => {
|
||||||
self.machine_st.fail = true;
|
self.machine_st.fail = true;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@@ -1609,14 +1591,8 @@ impl Machine {
|
|||||||
|
|
||||||
let expanded_term = if result.is_simple_goal {
|
let expanded_term = if result.is_simple_goal {
|
||||||
let idx = self.get_or_insert_qualified_code_index(module_name, result.key);
|
let idx = self.get_or_insert_qualified_code_index(module_name, result.key);
|
||||||
|
self.machine_st.heap[result.index_ptr_loc] =
|
||||||
resource_error_call_result!(
|
untyped_arena_ptr_as_cell!(UntypedArenaPtr::from(idx));
|
||||||
self.machine_st,
|
|
||||||
self.machine_st
|
|
||||||
.heap
|
|
||||||
.push_cell(untyped_arena_ptr_as_cell!(UntypedArenaPtr::from(idx)))
|
|
||||||
);
|
|
||||||
|
|
||||||
result.goal
|
result.goal
|
||||||
} else {
|
} else {
|
||||||
let mut unexpanded_vars = IndexSet::with_hasher(FxBuildHasher::default());
|
let mut unexpanded_vars = IndexSet::with_hasher(FxBuildHasher::default());
|
||||||
@@ -1648,29 +1624,24 @@ impl Machine {
|
|||||||
self.machine_st.heap.reserve(unexpanded_vars.len() + 2)
|
self.machine_st.heap.reserve(unexpanded_vars.len() + 2)
|
||||||
);
|
);
|
||||||
|
|
||||||
writer.write_with(|section| {
|
|
||||||
section.push_cell(atom_as_cell!(atom!("$aux"), 0));
|
|
||||||
|
|
||||||
for value in unexpanded_vars.difference(&result.supp_vars).cloned() {
|
|
||||||
section.push_cell(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
section.push_cell(atom_as_cell!(atom!("[]")));
|
|
||||||
});
|
|
||||||
|
|
||||||
let anon_str_arity = self.machine_st.heap.cell_len() - h - 2;
|
|
||||||
self.machine_st.heap[h] = atom_as_cell!(atom!("$aux"), anon_str_arity);
|
|
||||||
|
|
||||||
let idx = CodeIndex::new(
|
let idx = CodeIndex::new(
|
||||||
IndexPtr::index(helper_clause_loc),
|
IndexPtr::index(helper_clause_loc),
|
||||||
&mut self.machine_st.arena,
|
&mut self.machine_st.arena,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.machine_st.heap.last_cell_mut().map(|cell| {
|
writer.write_with(|section| {
|
||||||
*cell = untyped_arena_ptr_as_cell!(UntypedArenaPtr::from(idx));
|
section.push_cell(untyped_arena_ptr_as_cell!(UntypedArenaPtr::from(idx)));
|
||||||
|
section.push_cell(atom_as_cell!(atom!("$aux"), 0));
|
||||||
|
|
||||||
|
for value in unexpanded_vars.difference(&result.supp_vars).cloned() {
|
||||||
|
section.push_cell(value);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
str_loc_as_cell!(h)
|
let anon_str_arity = self.machine_st.heap.cell_len() - h - 2;
|
||||||
|
self.machine_st.heap[h + 1] = atom_as_cell!(atom!("$aux"), anon_str_arity);
|
||||||
|
|
||||||
|
str_loc_as_cell!(h + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1688,28 +1659,22 @@ impl Machine {
|
|||||||
|
|
||||||
if HeapCellValueTag::Str == qualified_goal.get_tag() {
|
if HeapCellValueTag::Str == qualified_goal.get_tag() {
|
||||||
let s = qualified_goal.get_value() as usize;
|
let s = qualified_goal.get_value() as usize;
|
||||||
let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s]).get_name_and_arity();
|
let name = cell_as_atom_cell!(self.machine_st.heap[s]).get_name();
|
||||||
|
|
||||||
if name == atom!("$call") {
|
if name == atom!("$call") {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.machine_st.heap.cell_len() > s + 1 + arity {
|
let idx_cell = self.machine_st.heap[s.saturating_sub(1)];
|
||||||
if self.machine_st.heap.pstr_at(s + 1 + arity) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let idx_cell = self.machine_st.heap[s + 1 + arity];
|
if HeapCellValueTag::Cons == idx_cell.get_tag() {
|
||||||
|
match_untyped_arena_ptr!(cell_as_untyped_arena_ptr!(idx_cell),
|
||||||
if HeapCellValueTag::Cons == idx_cell.get_tag() {
|
(ArenaHeaderTag::IndexPtr, _ip) => {
|
||||||
match_untyped_arena_ptr!(cell_as_untyped_arena_ptr!(idx_cell),
|
return true;
|
||||||
(ArenaHeaderTag::IndexPtr, _ip) => {
|
}
|
||||||
return true;
|
_ => {
|
||||||
}
|
}
|
||||||
_ => {
|
);
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2312,27 +2277,6 @@ impl Machine {
|
|||||||
let a1 = self.deref_register(1);
|
let a1 = self.deref_register(1);
|
||||||
|
|
||||||
read_heap_cell!(a1,
|
read_heap_cell!(a1,
|
||||||
/*
|
|
||||||
(HeapCellValueTag::Char) => {
|
|
||||||
let h = self.machine_st.heap.cell_len();
|
|
||||||
|
|
||||||
let mut writer = resource_error_call_result!(
|
|
||||||
self.machine_st,
|
|
||||||
self.machine_st.heap.reserve(2)
|
|
||||||
);
|
|
||||||
|
|
||||||
step_or_resource_error!(
|
|
||||||
self.machine_st,
|
|
||||||
writer.write_with(|section| {
|
|
||||||
section.push_cell(a1);
|
|
||||||
section.push_cell(empty_list_as_cell!());
|
|
||||||
Ok::<(), usize>(())
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
unify!(self.machine_st, self.machine_st.registers[2], list_loc_as_cell!(h));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
(HeapCellValueTag::Atom, (name, arity)) => {
|
(HeapCellValueTag::Atom, (name, arity)) => {
|
||||||
debug_assert_eq!(arity, 0);
|
debug_assert_eq!(arity, 0);
|
||||||
|
|
||||||
@@ -2542,7 +2486,7 @@ impl Machine {
|
|||||||
self.machine_st.allocate_pstr(&*atom.as_str())
|
self.machine_st.allocate_pstr(&*atom.as_str())
|
||||||
);
|
);
|
||||||
|
|
||||||
let tail_loc = Heap::neighboring_cell_offset(atom.as_str().len() + heap_index!(pstr_h));
|
let tail_loc = Heap::pstr_tail_idx(atom.as_str().len() + heap_index!(pstr_h));
|
||||||
|
|
||||||
step_or_resource_error!(
|
step_or_resource_error!(
|
||||||
self.machine_st,
|
self.machine_st,
|
||||||
@@ -2585,8 +2529,8 @@ impl Machine {
|
|||||||
|
|
||||||
read_heap_cell!(pstr,
|
read_heap_cell!(pstr,
|
||||||
(HeapCellValueTag::PStrLoc, h) => {
|
(HeapCellValueTag::PStrLoc, h) => {
|
||||||
let (_, tail_loc) = self.machine_st.heap.scan_slice_to_str(h);
|
let HeapStringScan { tail_idx, .. } = self.machine_st.heap.scan_slice_to_str(h);
|
||||||
unify_fn!(self.machine_st, heap_loc_as_cell!(tail_loc), a2);
|
unify_fn!(self.machine_st, heap_loc_as_cell!(tail_idx), a2);
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Lis, h) => {
|
(HeapCellValueTag::Lis, h) => {
|
||||||
unify_fn!(
|
unify_fn!(
|
||||||
@@ -3970,7 +3914,10 @@ impl Machine {
|
|||||||
pub(crate) fn copy_to_lifted_heap(&mut self) {
|
pub(crate) fn copy_to_lifted_heap(&mut self) {
|
||||||
let lh_offset = cell_as_fixnum!(self.deref_register(1)).get_num() as usize;
|
let lh_offset = cell_as_fixnum!(self.deref_register(1)).get_num() as usize;
|
||||||
let copy_target = self.machine_st.registers[2];
|
let copy_target = self.machine_st.registers[2];
|
||||||
let old_threshold = step_or_resource_error!(
|
let FindallCopyInfo {
|
||||||
|
offset: old_threshold,
|
||||||
|
pstr_threshold,
|
||||||
|
} = step_or_resource_error!(
|
||||||
self.machine_st,
|
self.machine_st,
|
||||||
self.machine_st
|
self.machine_st
|
||||||
.copy_findall_solution(lh_offset, copy_target)
|
.copy_findall_solution(lh_offset, copy_target)
|
||||||
@@ -3980,8 +3927,20 @@ impl Machine {
|
|||||||
|
|
||||||
self.machine_st.lifted_heap[old_threshold] = heap_loc_as_cell!(new_threshold);
|
self.machine_st.lifted_heap[old_threshold] = heap_loc_as_cell!(new_threshold);
|
||||||
|
|
||||||
for addr in &mut self.machine_st.lifted_heap.splice_mut(old_threshold + 1..) {
|
for idx in old_threshold + 1..pstr_threshold {
|
||||||
*addr -= self.machine_st.heap.cell_len() + lh_offset;
|
self.machine_st.lifted_heap[idx] -= self.machine_st.heap.cell_len() + lh_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut pstr_threshold = heap_index!(pstr_threshold);
|
||||||
|
|
||||||
|
while pstr_threshold < heap_index!(self.machine_st.lifted_heap.cell_len()) {
|
||||||
|
let HeapStringScan { tail_idx, .. } = self
|
||||||
|
.machine_st
|
||||||
|
.lifted_heap
|
||||||
|
.scan_slice_to_str(pstr_threshold);
|
||||||
|
|
||||||
|
self.machine_st.lifted_heap[tail_idx] -= self.machine_st.heap.cell_len() + lh_offset;
|
||||||
|
pstr_threshold = heap_index!(tail_idx + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5797,17 +5756,18 @@ impl Machine {
|
|||||||
unify_fn!(self.machine_st, solutions, diff);
|
unify_fn!(self.machine_st, solutions, diff);
|
||||||
} else {
|
} else {
|
||||||
let h = self.machine_st.heap.cell_len();
|
let h = self.machine_st.heap.cell_len();
|
||||||
|
let reserve_size = self.machine_st.lifted_heap.cell_len() - lh_offset;
|
||||||
|
|
||||||
step_or_resource_error!(
|
let mut writer = step_or_resource_error!(
|
||||||
self.machine_st,
|
self.machine_st,
|
||||||
self.machine_st
|
self.machine_st.heap.reserve(reserve_size)
|
||||||
.heap
|
|
||||||
.append(self.machine_st.lifted_heap.splice(lh_offset..),)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
for cell in &mut self.machine_st.heap.splice_mut(h..) {
|
writer.write_with(|section| {
|
||||||
*cell = *cell + h;
|
for idx in lh_offset..self.machine_st.lifted_heap.cell_len() {
|
||||||
}
|
section.push_cell(self.machine_st.lifted_heap[idx] + h);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let diff = self.machine_st.registers[3];
|
let diff = self.machine_st.registers[3];
|
||||||
unify_fn!(
|
unify_fn!(
|
||||||
@@ -5834,17 +5794,18 @@ impl Machine {
|
|||||||
unify_fn!(self.machine_st, solutions, empty_list_as_cell!());
|
unify_fn!(self.machine_st, solutions, empty_list_as_cell!());
|
||||||
} else {
|
} else {
|
||||||
let h = self.machine_st.heap.cell_len();
|
let h = self.machine_st.heap.cell_len();
|
||||||
|
let reserve_size = self.machine_st.lifted_heap.cell_len() - lh_offset;
|
||||||
|
|
||||||
step_or_resource_error!(
|
let mut writer = step_or_resource_error!(
|
||||||
self.machine_st,
|
self.machine_st,
|
||||||
self.machine_st
|
self.machine_st.heap.reserve(reserve_size)
|
||||||
.heap
|
|
||||||
.append(self.machine_st.lifted_heap.splice(lh_offset..),)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
for cell in &mut self.machine_st.heap.splice_mut(h..) {
|
writer.write_with(|section| {
|
||||||
*cell = *cell + h;
|
for idx in lh_offset..self.machine_st.lifted_heap.cell_len() {
|
||||||
}
|
section.push_cell(self.machine_st.lifted_heap[idx] + h);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
self.machine_st.lifted_heap.truncate(lh_offset);
|
self.machine_st.lifted_heap.truncate(lh_offset);
|
||||||
|
|
||||||
@@ -7223,8 +7184,7 @@ impl Machine {
|
|||||||
let mut ball = Ball::new();
|
let mut ball = Ball::new();
|
||||||
|
|
||||||
ball.boundary = self.machine_st.heap.cell_len();
|
ball.boundary = self.machine_st.heap.cell_len();
|
||||||
|
ball.pstr_boundary = step_or_resource_error!(
|
||||||
step_or_resource_error!(
|
|
||||||
self.machine_st,
|
self.machine_st,
|
||||||
copy_term(
|
copy_term(
|
||||||
CopyBallTerm::new(
|
CopyBallTerm::new(
|
||||||
|
|||||||
@@ -44,14 +44,19 @@ impl<'a> BootstrappingTermStream<'a> {
|
|||||||
listing_src: ListingSource,
|
listing_src: ListingSource,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let lexer_parser = LexerParser::new(stream, machine_st);
|
let lexer_parser = LexerParser::new(stream, machine_st);
|
||||||
Self { lexer_parser, listing_src }
|
Self {
|
||||||
|
lexer_parser,
|
||||||
|
listing_src,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TermStream for BootstrappingTermStream<'a> {
|
impl<'a> TermStream for BootstrappingTermStream<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self, op_dir: &CompositeOpDir) -> Result<TermWriteResult, CompilationError> {
|
fn next(&mut self, op_dir: &CompositeOpDir) -> Result<TermWriteResult, CompilationError> {
|
||||||
let result = self.lexer_parser.read_term(op_dir, Tokens::Default)
|
let result = self
|
||||||
|
.lexer_parser
|
||||||
|
.read_term(op_dir, Tokens::Default)
|
||||||
.map_err(CompilationError::from);
|
.map_err(CompilationError::from);
|
||||||
|
|
||||||
result
|
result
|
||||||
@@ -125,7 +130,9 @@ pub struct InlineTermStream {}
|
|||||||
|
|
||||||
impl TermStream for InlineTermStream {
|
impl TermStream for InlineTermStream {
|
||||||
fn next(&mut self, _: &CompositeOpDir) -> Result<TermWriteResult, CompilationError> {
|
fn next(&mut self, _: &CompositeOpDir) -> Result<TermWriteResult, CompilationError> {
|
||||||
Err(CompilationError::from(ParserError::unexpected_eof(ParserErrorSrc::default())))
|
Err(CompilationError::from(ParserError::unexpected_eof(
|
||||||
|
ParserErrorSrc::default(),
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eof(&mut self) -> Result<bool, CompilationError> {
|
fn eof(&mut self) -> Result<bool, CompilationError> {
|
||||||
|
|||||||
@@ -507,11 +507,9 @@ fn bind_with_occurs_check<U: Unifier>(unifier: &mut U, r: Ref, value: HeapCellVa
|
|||||||
if value.is_ref() && !value.is_stack_var() {
|
if value.is_ref() && !value.is_stack_var() {
|
||||||
machine_st.heap[0] = value;
|
machine_st.heap[0] = value;
|
||||||
|
|
||||||
for cell in stackful_preorder_iter::<NonListElider>(
|
for cell in
|
||||||
&mut machine_st.heap,
|
stackful_preorder_iter::<NonListElider>(&mut machine_st.heap, &mut machine_st.stack, 0)
|
||||||
&mut machine_st.stack,
|
{
|
||||||
0,
|
|
||||||
) {
|
|
||||||
let cell = unmark_cell_bits!(cell);
|
let cell = unmark_cell_bits!(cell);
|
||||||
|
|
||||||
if let Some(inner_r) = cell.as_var() {
|
if let Some(inner_r) = cell.as_var() {
|
||||||
|
|||||||
@@ -141,7 +141,11 @@ macro_rules! fixnum {
|
|||||||
($n:expr, $arena:expr) => {
|
($n:expr, $arena:expr) => {
|
||||||
Fixnum::build_with_checked($n)
|
Fixnum::build_with_checked($n)
|
||||||
.map(|n| fixnum_as_cell!(n))
|
.map(|n| fixnum_as_cell!(n))
|
||||||
.unwrap_or_else(|_| typed_arena_ptr_as_cell!(arena_alloc!(Integer::from($n), $arena) as TypedArenaPtr<Integer>))
|
.unwrap_or_else(|_| {
|
||||||
|
typed_arena_ptr_as_cell!(
|
||||||
|
arena_alloc!(Integer::from($n), $arena) as TypedArenaPtr<Integer>
|
||||||
|
)
|
||||||
|
})
|
||||||
};
|
};
|
||||||
($wrapper:ty, $n:expr, $arena:expr) => {
|
($wrapper:ty, $n:expr, $arena:expr) => {
|
||||||
Fixnum::build_with_checked($n)
|
Fixnum::build_with_checked($n)
|
||||||
@@ -619,10 +623,7 @@ impl Literal {
|
|||||||
|
|
||||||
pub type Var = Rc<String>;
|
pub type Var = Rc<String>;
|
||||||
|
|
||||||
pub(crate) fn subterm_index(
|
pub(crate) fn subterm_index(heap: &impl SizedHeap, subterm_loc: usize) -> (usize, HeapCellValue) {
|
||||||
heap: &impl SizedHeap,
|
|
||||||
subterm_loc: usize,
|
|
||||||
) -> (usize, HeapCellValue) {
|
|
||||||
let subterm = heap[subterm_loc];
|
let subterm = heap[subterm_loc];
|
||||||
|
|
||||||
if subterm.is_ref() {
|
if subterm.is_ref() {
|
||||||
@@ -715,16 +716,10 @@ pub fn unfold_by_str(mut term: Term, s: Atom) -> Vec<Term> {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pub(crate) fn fetch_index_ptr(
|
pub(crate) fn fetch_index_ptr(heap: &impl SizedHeap, term_loc: usize) -> Option<CodeIndex> {
|
||||||
heap: &impl SizedHeap,
|
let index_cell_loc = term_loc.saturating_sub(1);
|
||||||
arity: usize,
|
|
||||||
term_loc: usize,
|
|
||||||
) -> Option<CodeIndex> {
|
|
||||||
if term_loc + arity + 1 >= heap.cell_len() || heap.pstr_at(term_loc + arity + 1) {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
read_heap_cell!(heap[term_loc + arity + 1],
|
read_heap_cell!(heap[index_cell_loc],
|
||||||
(HeapCellValueTag::Cons, c) => {
|
(HeapCellValueTag::Cons, c) => {
|
||||||
match_untyped_arena_ptr!(c,
|
match_untyped_arena_ptr!(c,
|
||||||
(ArenaHeaderTag::IndexPtr, ptr) => {
|
(ArenaHeaderTag::IndexPtr, ptr) => {
|
||||||
@@ -744,7 +739,7 @@ pub(crate) fn blunt_index_ptr(
|
|||||||
key: PredicateKey,
|
key: PredicateKey,
|
||||||
term_loc: usize,
|
term_loc: usize,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if fetch_index_ptr(heap, key.1, term_loc).is_some() {
|
if fetch_index_ptr(heap, term_loc).is_some() {
|
||||||
heap[term_loc] = atom_as_cell!(key.0, key.1);
|
heap[term_loc] = atom_as_cell!(key.0, key.1);
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
@@ -757,10 +752,7 @@ pub(crate) fn unfold_by_str_once(
|
|||||||
start_term: HeapCellValue,
|
start_term: HeapCellValue,
|
||||||
atom: Atom,
|
atom: Atom,
|
||||||
) -> Option<usize> {
|
) -> Option<usize> {
|
||||||
let start_term = heap_bound_store(
|
let start_term = heap_bound_store(heap, heap_bound_deref(heap, start_term));
|
||||||
heap,
|
|
||||||
heap_bound_deref(heap, start_term),
|
|
||||||
);
|
|
||||||
|
|
||||||
if let HeapCellValueTag::Str = start_term.get_tag() {
|
if let HeapCellValueTag::Str = start_term.get_tag() {
|
||||||
let s = start_term.get_value() as usize;
|
let s = start_term.get_value() as usize;
|
||||||
@@ -769,7 +761,7 @@ pub(crate) fn unfold_by_str_once(
|
|||||||
blunt_index_ptr(heap, (s_atom, s_arity), s);
|
blunt_index_ptr(heap, (s_atom, s_arity), s);
|
||||||
|
|
||||||
if (s_atom, s_arity) == (atom, 2) {
|
if (s_atom, s_arity) == (atom, 2) {
|
||||||
return Some(s+1);
|
return Some(s + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -826,7 +818,7 @@ pub fn unfold_by_str_locs(
|
|||||||
let mut current_term = heap[term_loc];
|
let mut current_term = heap[term_loc];
|
||||||
|
|
||||||
while let Some(fst_loc) = unfold_by_str_once(heap, current_term, atom) {
|
while let Some(fst_loc) = unfold_by_str_once(heap, current_term, atom) {
|
||||||
term_loc = fst_loc+1;
|
term_loc = fst_loc + 1;
|
||||||
current_term = heap[term_loc];
|
current_term = heap[term_loc];
|
||||||
let fst = heap[fst_loc];
|
let fst = heap[fst_loc];
|
||||||
terms.push((fst, fst_loc));
|
terms.push((fst, fst_loc));
|
||||||
@@ -836,10 +828,7 @@ pub fn unfold_by_str_locs(
|
|||||||
terms
|
terms
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn term_predicate_key(
|
pub fn term_predicate_key(heap: &impl SizedHeap, mut term_loc: usize) -> Option<PredicateKey> {
|
||||||
heap: &impl SizedHeap,
|
|
||||||
mut term_loc: usize,
|
|
||||||
) -> Option<PredicateKey> {
|
|
||||||
loop {
|
loop {
|
||||||
read_heap_cell!(heap[term_loc],
|
read_heap_cell!(heap[term_loc],
|
||||||
(HeapCellValueTag::Atom, (name, arity)) => {
|
(HeapCellValueTag::Atom, (name, arity)) => {
|
||||||
@@ -879,10 +868,7 @@ pub fn inverse_var_locs_from_iter<I: Iterator<Item = HeapCellValue>>(iter: I) ->
|
|||||||
let var_loc = var.get_value() as usize;
|
let var_loc = var.get_value() as usize;
|
||||||
|
|
||||||
if count > 1 {
|
if count > 1 {
|
||||||
inverse_var_locs.insert(
|
inverse_var_locs.insert(var_loc, Rc::new(format!("_{}", var_loc)));
|
||||||
var_loc,
|
|
||||||
Rc::new(format!("_{}", var_loc)),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,22 +56,18 @@ impl Token {
|
|||||||
Token::String(string) if flags.double_quotes.is_codes() => {
|
Token::String(string) if flags.double_quotes.is_codes() => {
|
||||||
2 * string.chars().count() + 1
|
2 * string.chars().count() + 1
|
||||||
}
|
}
|
||||||
Token::String(string) => {
|
Token::String(string) => Heap::compute_pstr_size(&string),
|
||||||
Heap::compute_pstr_size(&string)
|
Token::Literal(_)
|
||||||
}
|
| Token::Comma
|
||||||
Token::Literal(_) |
|
| Token::HeadTailSeparator
|
||||||
Token::Comma |
|
| Token::Open
|
||||||
Token::HeadTailSeparator |
|
| Token::OpenCT
|
||||||
Token::Open |
|
| Token::OpenCurly
|
||||||
Token::OpenCT |
|
| Token::OpenList
|
||||||
Token::OpenCurly |
|
| Token::Var(_) => {
|
||||||
Token::OpenList |
|
|
||||||
Token::Var(_) => {
|
|
||||||
heap_index!(1)
|
heap_index!(1)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => 0,
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,10 +458,7 @@ impl<'a, R: CharRead> LexerParser<'a, R> {
|
|||||||
self.skip_char(c);
|
self.skip_char(c);
|
||||||
u32::from_str_radix(&token, radix).map_or_else(
|
u32::from_str_radix(&token, radix).map_or_else(
|
||||||
|_| Err(ParserError::ParseBigInt(self.loc_to_err_src())),
|
|_| Err(ParserError::ParseBigInt(self.loc_to_err_src())),
|
||||||
|n| {
|
|n| char::try_from(n).map_err(|_| ParserError::Utf8Error(self.loc_to_err_src())),
|
||||||
char::try_from(n)
|
|
||||||
.map_err(|_| ParserError::Utf8Error(self.loc_to_err_src()))
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Err(ParserError::IncompleteReduction(self.loc_to_err_src()))
|
Err(ParserError::IncompleteReduction(self.loc_to_err_src()))
|
||||||
@@ -657,7 +650,9 @@ impl<'a, R: CharRead> LexerParser<'a, R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(ParserError::InvalidSingleQuotedCharacter(self.loc_to_err_src()));
|
return Err(ParserError::InvalidSingleQuotedCharacter(
|
||||||
|
self.loc_to_err_src(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match self.get_back_quoted_string() {
|
match self.get_back_quoted_string() {
|
||||||
|
|||||||
@@ -187,7 +187,9 @@ struct Parser<'a> {
|
|||||||
inverse_var_locs: InverseVarLocs,
|
inverse_var_locs: InverseVarLocs,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_tokens<R: CharRead>(lexer: &mut LexerParser<R>) -> Result<(Vec<Token>, usize), ParserError> {
|
pub fn read_tokens<R: CharRead>(
|
||||||
|
lexer: &mut LexerParser<R>,
|
||||||
|
) -> Result<(Vec<Token>, usize), ParserError> {
|
||||||
let mut tokens = vec![];
|
let mut tokens = vec![];
|
||||||
let mut term_size = 0;
|
let mut term_size = 0;
|
||||||
|
|
||||||
@@ -264,9 +266,9 @@ pub(crate) fn as_partial_string(
|
|||||||
tail = heap[l+1];
|
tail = heap[l+1];
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::PStrLoc, l) => {
|
(HeapCellValueTag::PStrLoc, l) => {
|
||||||
let (pstr, tail_loc) = heap.scan_slice_to_str(l);
|
let HeapStringScan { string: pstr, tail_idx } = heap.scan_slice_to_str(l);
|
||||||
string += pstr;
|
string += pstr;
|
||||||
tail = heap[tail_loc];
|
tail = heap[tail_idx];
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
|
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
|
||||||
if heap[h] != tail {
|
if heap[h] != tail {
|
||||||
@@ -306,8 +308,7 @@ impl<'a> Parser<'a> {
|
|||||||
TokenType::Comma => Some(atom!(",")),
|
TokenType::Comma => Some(atom!(",")),
|
||||||
TokenType::Term { heap_loc } => {
|
TokenType::Term { heap_loc } => {
|
||||||
if heap_loc.is_ref() {
|
if heap_loc.is_ref() {
|
||||||
term_predicate_key(&self.terms, heap_loc.get_value() as usize)
|
term_predicate_key(&self.terms, heap_loc.get_value() as usize).map(|key| key.0)
|
||||||
.map(|key| key.0)
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -392,7 +393,8 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
fn promote_atom_op(&mut self, atom: Atom, priority: usize, assoc: u32) {
|
fn promote_atom_op(&mut self, atom: Atom, priority: usize, assoc: u32) {
|
||||||
let h = self.terms.cell_len();
|
let h = self.terms.cell_len();
|
||||||
self.terms.write_with(|section| section.push_cell(atom_as_cell!(atom)));
|
self.terms
|
||||||
|
.write_with(|section| section.push_cell(atom_as_cell!(atom)));
|
||||||
self.stack.push(TokenDesc {
|
self.stack.push(TokenDesc {
|
||||||
tt: TokenType::Term {
|
tt: TokenType::Term {
|
||||||
heap_loc: heap_loc_as_cell!(h),
|
heap_loc: heap_loc_as_cell!(h),
|
||||||
@@ -438,10 +440,12 @@ impl<'a> Parser<'a> {
|
|||||||
section.push_cell(list_loc_as_cell!(h));
|
section.push_cell(list_loc_as_cell!(h));
|
||||||
});
|
});
|
||||||
|
|
||||||
TokenType::Term { heap_loc: heap_loc_as_cell!(h + 2) }
|
TokenType::Term {
|
||||||
|
heap_loc: heap_loc_as_cell!(h + 2),
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.terms.write_with(|section| {
|
self.terms
|
||||||
match section.push_pstr(&s) {
|
.write_with(|section| match section.push_pstr(&s) {
|
||||||
Some(pstr_loc_cell) => {
|
Some(pstr_loc_cell) => {
|
||||||
section.push_cell(empty_list_as_cell!());
|
section.push_cell(empty_list_as_cell!());
|
||||||
let h = section.cell_len();
|
let h = section.cell_len();
|
||||||
@@ -451,10 +455,11 @@ impl<'a> Parser<'a> {
|
|||||||
None => {
|
None => {
|
||||||
section.push_cell(empty_list_as_cell!());
|
section.push_cell(empty_list_as_cell!());
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
TokenType::Term { heap_loc: pstr_cell }
|
TokenType::Term {
|
||||||
|
heap_loc: pstr_cell,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Token::Literal(c) => {
|
Token::Literal(c) => {
|
||||||
@@ -478,13 +483,14 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
if var.trim() != "_" {
|
if var.trim() != "_" {
|
||||||
self.var_locs.insert(var.clone(), heap_loc);
|
self.var_locs.insert(var.clone(), heap_loc);
|
||||||
self.inverse_var_locs.insert(heap_loc.get_value() as usize, var);
|
self.inverse_var_locs
|
||||||
|
.insert(heap_loc.get_value() as usize, var);
|
||||||
}
|
}
|
||||||
|
|
||||||
TokenType::Term { heap_loc }
|
TokenType::Term { heap_loc }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Token::Comma => TokenType::Comma,
|
Token::Comma => TokenType::Comma,
|
||||||
Token::Open => TokenType::Open,
|
Token::Open => TokenType::Open,
|
||||||
Token::Close => TokenType::Close,
|
Token::Close => TokenType::Close,
|
||||||
@@ -619,15 +625,21 @@ impl<'a> Parser<'a> {
|
|||||||
let term_idx = self.terms.cell_len();
|
let term_idx = self.terms.cell_len();
|
||||||
|
|
||||||
let push_structure = |parser: &mut Self, name: Atom| -> TokenType {
|
let push_structure = |parser: &mut Self, name: Atom| -> TokenType {
|
||||||
parser.terms.write_with(|section| section.push_cell(atom_as_cell!(name, arity)));
|
parser
|
||||||
|
.terms
|
||||||
|
.write_with(|section| section.push_cell(atom_as_cell!(name, arity)));
|
||||||
|
|
||||||
for idx in (stack_len + 2..parser.stack.len()).step_by(2) {
|
for idx in (stack_len + 2..parser.stack.len()).step_by(2) {
|
||||||
let subterm = parser.term_from_stack(idx).unwrap();
|
let subterm = parser.term_from_stack(idx).unwrap();
|
||||||
parser.terms.write_with(|section| section.push_cell(subterm));
|
parser
|
||||||
|
.terms
|
||||||
|
.write_with(|section| section.push_cell(subterm));
|
||||||
}
|
}
|
||||||
|
|
||||||
let str_loc_idx = parser.terms.cell_len();
|
let str_loc_idx = parser.terms.cell_len();
|
||||||
parser.terms.write_with(|section| section.push_cell(str_loc_as_cell!(term_idx)));
|
parser
|
||||||
|
.terms
|
||||||
|
.write_with(|section| section.push_cell(str_loc_as_cell!(term_idx)));
|
||||||
|
|
||||||
TokenType::Term {
|
TokenType::Term {
|
||||||
heap_loc: heap_loc_as_cell!(str_loc_idx),
|
heap_loc: heap_loc_as_cell!(str_loc_idx),
|
||||||
@@ -709,23 +721,20 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn loc_to_err_src(&self) -> ParserErrorSrc {
|
fn loc_to_err_src(&self) -> ParserErrorSrc {
|
||||||
ParserErrorSrc { line_num: *self.line_num, col_num: *self.col_num }
|
ParserErrorSrc {
|
||||||
|
line_num: *self.line_num,
|
||||||
|
col_num: *self.col_num,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expand_comma_compacted_terms(&mut self, index: usize) -> usize {
|
fn expand_comma_compacted_terms(&mut self, index: usize) -> usize {
|
||||||
if let Some(term) = self.term_from_stack(index - 1) {
|
if let Some(term) = self.term_from_stack(index - 1) {
|
||||||
let mut op_desc = self.stack[index - 1];
|
let mut op_desc = self.stack[index - 1];
|
||||||
let mut term = heap_bound_store(
|
let mut term = heap_bound_store(&self.terms, heap_bound_deref(&self.terms, term));
|
||||||
&self.terms,
|
|
||||||
heap_bound_deref(
|
|
||||||
&self.terms,
|
|
||||||
term,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
if term.is_ref() &&
|
if term.is_ref()
|
||||||
0 < op_desc.priority &&
|
&& 0 < op_desc.priority
|
||||||
op_desc.priority < self.stack[index].priority
|
&& op_desc.priority < self.stack[index].priority
|
||||||
{
|
{
|
||||||
/* '|' is a head-tail separator here, not
|
/* '|' is a head-tail separator here, not
|
||||||
* an operator, so expand the
|
* an operator, so expand the
|
||||||
@@ -740,11 +749,9 @@ impl<'a> Parser<'a> {
|
|||||||
} else {
|
} else {
|
||||||
let mut terms = vec![];
|
let mut terms = vec![];
|
||||||
|
|
||||||
while let Some(fst_loc) = unfold_by_str_once(
|
while let Some(fst_loc) =
|
||||||
&mut self.terms,
|
unfold_by_str_once(&mut self.terms, term, atom!(","))
|
||||||
term,
|
{
|
||||||
atom!(","),
|
|
||||||
) {
|
|
||||||
let (_, snd) = subterm_index(&self.terms, fst_loc + 1);
|
let (_, snd) = subterm_index(&self.terms, fst_loc + 1);
|
||||||
let (_, fst) = subterm_index(&self.terms, fst_loc);
|
let (_, fst) = subterm_index(&self.terms, fst_loc);
|
||||||
|
|
||||||
@@ -763,14 +770,13 @@ impl<'a> Parser<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let arity = terms.len() - 1;
|
let arity = terms.len() - 1;
|
||||||
self.stack.extend(terms.into_iter().map(|heap_loc| {
|
self.stack
|
||||||
TokenDesc {
|
.extend(terms.into_iter().map(|heap_loc| TokenDesc {
|
||||||
tt: TokenType::Term { heap_loc },
|
tt: TokenType::Term { heap_loc },
|
||||||
priority: 0,
|
priority: 0,
|
||||||
spec: 0,
|
spec: 0,
|
||||||
unfold_bounds: 0,
|
unfold_bounds: 0,
|
||||||
}
|
}));
|
||||||
}));
|
|
||||||
return arity;
|
return arity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -816,7 +822,8 @@ impl<'a> Parser<'a> {
|
|||||||
// parsed an empty list token
|
// parsed an empty list token
|
||||||
if td.tt == TokenType::OpenList {
|
if td.tt == TokenType::OpenList {
|
||||||
let h = self.terms.cell_len();
|
let h = self.terms.cell_len();
|
||||||
self.terms.write_with(|section| section.push_cell(empty_list_as_cell!()));
|
self.terms
|
||||||
|
.write_with(|section| section.push_cell(empty_list_as_cell!()));
|
||||||
|
|
||||||
td.spec = TERM;
|
td.spec = TERM;
|
||||||
td.tt = TokenType::Term {
|
td.tt = TokenType::Term {
|
||||||
@@ -845,9 +852,7 @@ impl<'a> Parser<'a> {
|
|||||||
let tail_term = match self.term_from_stack(idx + 1) {
|
let tail_term = match self.term_from_stack(idx + 1) {
|
||||||
Some(term) => term,
|
Some(term) => term,
|
||||||
None => {
|
None => {
|
||||||
return Err(ParserError::IncompleteReduction(
|
return Err(ParserError::IncompleteReduction(self.loc_to_err_src()));
|
||||||
self.loc_to_err_src(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -863,18 +868,14 @@ impl<'a> Parser<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if arity > self.terms.cell_len() {
|
if arity > self.terms.cell_len() {
|
||||||
return Err(ParserError::IncompleteReduction(
|
return Err(ParserError::IncompleteReduction(self.loc_to_err_src()));
|
||||||
self.loc_to_err_src(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let pre_terms_len = self.terms.cell_len();
|
let pre_terms_len = self.terms.cell_len();
|
||||||
|
|
||||||
while let Some(token_desc) = self.stack.pop() {
|
while let Some(token_desc) = self.stack.pop() {
|
||||||
let subterm = match token_desc.tt {
|
let subterm = match token_desc.tt {
|
||||||
TokenType::Term { heap_loc } => {
|
TokenType::Term { heap_loc } => heap_loc,
|
||||||
heap_loc
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -942,7 +943,8 @@ impl<'a> Parser<'a> {
|
|||||||
if td.tt == TokenType::OpenCurly {
|
if td.tt == TokenType::OpenCurly {
|
||||||
let h = self.terms.cell_len();
|
let h = self.terms.cell_len();
|
||||||
|
|
||||||
self.terms.write_with(|section| section.push_cell(atom_as_cell!(atom!("{}"))));
|
self.terms
|
||||||
|
.write_with(|section| section.push_cell(atom_as_cell!(atom!("{}"))));
|
||||||
|
|
||||||
td.tt = TokenType::Term {
|
td.tt = TokenType::Term {
|
||||||
heap_loc: heap_loc_as_cell!(h),
|
heap_loc: heap_loc_as_cell!(h),
|
||||||
@@ -1160,66 +1162,58 @@ impl<'a> Parser<'a> {
|
|||||||
Token::String(string) => {
|
Token::String(string) => {
|
||||||
self.shift(Token::String(string), 0, TERM);
|
self.shift(Token::String(string), 0, TERM);
|
||||||
}
|
}
|
||||||
Token::Literal(c) => {
|
Token::Literal(c) => match Number::try_from(c) {
|
||||||
match Number::try_from(c) {
|
Ok(Number::Integer(n)) => {
|
||||||
Ok(Number::Integer(n)) => {
|
self.negate_number(n, negate_int_rc, |n, _| typed_arena_ptr_as_cell!(n))
|
||||||
self.negate_number(n, negate_int_rc, |n, _| typed_arena_ptr_as_cell!(n))
|
}
|
||||||
}
|
Ok(Number::Rational(n)) => {
|
||||||
Ok(Number::Rational(n)) => {
|
self.negate_number(n, negate_rat_rc, |r, _| typed_arena_ptr_as_cell!(r))
|
||||||
self.negate_number(n, negate_rat_rc, |r, _| typed_arena_ptr_as_cell!(r))
|
}
|
||||||
}
|
Ok(Number::Float(n)) if n.is_infinite() => {
|
||||||
Ok(Number::Float(n)) if n.is_infinite() => {
|
return Err(ParserError::InfiniteFloat(
|
||||||
return Err(ParserError::InfiniteFloat(
|
self.loc_to_err_src(),
|
||||||
self.lexer.loc_to_err_src(),
|
));
|
||||||
));
|
}
|
||||||
}
|
Ok(Number::Float(n)) => {
|
||||||
Ok(Number::Float(n)) => {
|
use ordered_float::OrderedFloat;
|
||||||
use ordered_float::OrderedFloat;
|
|
||||||
|
|
||||||
self.negate_number(
|
self.negate_number(
|
||||||
n,
|
n,
|
||||||
|n, _| -n,
|
|n, _| -n,
|
||||||
|OrderedFloat(n), arena| HeapCellValue::from(float_alloc!(n, arena)),
|
|OrderedFloat(n), arena| HeapCellValue::from(float_alloc!(n, arena)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Ok(Number::Fixnum(n)) => {
|
Ok(Number::Fixnum(n)) => {
|
||||||
self.negate_number(n, |n, _| -n, |n, _| fixnum_as_cell!(n))
|
self.negate_number(n, |n, _| -n, |n, _| fixnum_as_cell!(n))
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
if let Some(name) = c.to_atom() {
|
if let Some(name) = c.to_atom() {
|
||||||
if !self.shift_op(name, op_dir)? {
|
if !self.shift_op(name, op_dir)? {
|
||||||
self.shift(Token::Literal(c), 0, TERM);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.shift(Token::Literal(c), 0, TERM);
|
self.shift(Token::Literal(c), 0, TERM);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
self.shift(Token::Literal(c), 0, TERM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
Token::Var(v) => self.shift(Token::Var(v), 0, TERM),
|
Token::Var(v) => self.shift(Token::Var(v), 0, TERM),
|
||||||
Token::Open => self.shift(Token::Open, 1300, DELIMITER),
|
Token::Open => self.shift(Token::Open, 1300, DELIMITER),
|
||||||
Token::OpenCT => self.shift(Token::OpenCT, 1300, DELIMITER),
|
Token::OpenCT => self.shift(Token::OpenCT, 1300, DELIMITER),
|
||||||
Token::Close => {
|
Token::Close => {
|
||||||
if !self.reduce_term() && !self.reduce_brackets() {
|
if !self.reduce_term() && !self.reduce_brackets() {
|
||||||
return Err(ParserError::IncompleteReduction(
|
return Err(ParserError::IncompleteReduction(self.loc_to_err_src()));
|
||||||
self.loc_to_err_src(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Token::OpenList => self.shift(Token::OpenList, 1300, DELIMITER),
|
Token::OpenList => self.shift(Token::OpenList, 1300, DELIMITER),
|
||||||
Token::CloseList => {
|
Token::CloseList => {
|
||||||
if !self.reduce_list()? {
|
if !self.reduce_list()? {
|
||||||
return Err(ParserError::IncompleteReduction(
|
return Err(ParserError::IncompleteReduction(self.loc_to_err_src()));
|
||||||
self.loc_to_err_src(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Token::OpenCurly => self.shift(Token::OpenCurly, 1300, DELIMITER),
|
Token::OpenCurly => self.shift(Token::OpenCurly, 1300, DELIMITER),
|
||||||
Token::CloseCurly => {
|
Token::CloseCurly => {
|
||||||
if !self.reduce_curly()? {
|
if !self.reduce_curly()? {
|
||||||
return Err(ParserError::IncompleteReduction(
|
return Err(ParserError::IncompleteReduction(self.loc_to_err_src()));
|
||||||
self.loc_to_err_src(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Token::HeadTailSeparator => {
|
Token::HeadTailSeparator => {
|
||||||
@@ -1253,9 +1247,7 @@ impl<'a> Parser<'a> {
|
|||||||
| Some(TokenType::OpenCurly)
|
| Some(TokenType::OpenCurly)
|
||||||
| Some(TokenType::HeadTailSeparator)
|
| Some(TokenType::HeadTailSeparator)
|
||||||
| Some(TokenType::Comma) => {
|
| Some(TokenType::Comma) => {
|
||||||
return Err(ParserError::IncompleteReduction(
|
return Err(ParserError::IncompleteReduction(self.loc_to_err_src()))
|
||||||
self.loc_to_err_src(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
@@ -1272,7 +1264,10 @@ impl<'a, R: CharRead> LexerParser<'a, R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn loc_to_err_src(&self) -> ParserErrorSrc {
|
pub fn loc_to_err_src(&self) -> ParserErrorSrc {
|
||||||
ParserErrorSrc { line_num: self.line_num, col_num: self.col_num }
|
ParserErrorSrc {
|
||||||
|
line_num: self.line_num,
|
||||||
|
col_num: self.col_num,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// on success, returns the parsed term and the number of lines read.
|
// on success, returns the parsed term and the number of lines read.
|
||||||
@@ -1289,7 +1284,11 @@ impl<'a, R: CharRead> LexerParser<'a, R> {
|
|||||||
// the parser uses conditional indirection in many places so
|
// the parser uses conditional indirection in many places so
|
||||||
// the reserved size should be at least 4 * term_byte_size
|
// the reserved size should be at least 4 * term_byte_size
|
||||||
// so all cells are accounted for.
|
// so all cells are accounted for.
|
||||||
let writer = match self.machine_st.heap.reserve(cell_index!(4 * term_byte_size)) {
|
let writer = match self
|
||||||
|
.machine_st
|
||||||
|
.heap
|
||||||
|
.reserve(cell_index!(4 * term_byte_size))
|
||||||
|
{
|
||||||
Ok(term) => term,
|
Ok(term) => term,
|
||||||
Err(_err_loc) => {
|
Err(_err_loc) => {
|
||||||
return Err(ParserError::ResourceError(self.loc_to_err_src()));
|
return Err(ParserError::ResourceError(self.loc_to_err_src()));
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ impl MachineState {
|
|||||||
let op_dir = CompositeOpDir::new(op_dir, None);
|
let op_dir = CompositeOpDir::new(op_dir, None);
|
||||||
|
|
||||||
let term_result = lexer_parser.read_term(&op_dir, Tokens::Default);
|
let term_result = lexer_parser.read_term(&op_dir, Tokens::Default);
|
||||||
let lines_read = lexer_parser.line_num();
|
let lines_read = lexer_parser.line_num();
|
||||||
|
|
||||||
term_result.map(|term| (term, lines_read))
|
term_result.map(|term| (term, lines_read))
|
||||||
}
|
}
|
||||||
|
|||||||
14
src/types.rs
14
src/types.rs
@@ -369,8 +369,8 @@ impl HeapCellValue {
|
|||||||
name == atom!("[]") && arity == 0
|
name == atom!("[]") && arity == 0
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::PStrLoc, h) => {
|
(HeapCellValueTag::PStrLoc, h) => {
|
||||||
let (_s, tail_loc) = heap.scan_slice_to_str(h);
|
let HeapStringScan { tail_idx, .. } = heap.scan_slice_to_str(h);
|
||||||
self = heap[tail_loc];
|
self = heap[tail_idx];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
|
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
|
||||||
@@ -399,8 +399,7 @@ impl HeapCellValue {
|
|||||||
| HeapCellValueTag::Var
|
| HeapCellValueTag::Var
|
||||||
| HeapCellValueTag::StackVar
|
| HeapCellValueTag::StackVar
|
||||||
| HeapCellValueTag::AttrVar
|
| HeapCellValueTag::AttrVar
|
||||||
| HeapCellValueTag::PStrLoc
|
| HeapCellValueTag::PStrLoc // | HeapCellValueTag::PStrOffset
|
||||||
// | HeapCellValueTag::PStrOffset
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,9 +502,7 @@ impl HeapCellValue {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_atom(self) -> Option<Atom> {
|
pub fn to_atom(self) -> Option<Atom> {
|
||||||
match self.get_tag() {
|
match self.get_tag() {
|
||||||
HeapCellValueTag::Atom => {
|
HeapCellValueTag::Atom => Some(AtomCell::from_bytes(self.into_bytes()).get_name()),
|
||||||
Some(AtomCell::from_bytes(self.into_bytes()).get_name())
|
|
||||||
}
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -775,7 +772,8 @@ impl Sub<i64> for HeapCellValue {
|
|||||||
HeapCellValue::build_with(tag, self.get_value() + rhs.unsigned_abs())
|
HeapCellValue::build_with(tag, self.get_value() + rhs.unsigned_abs())
|
||||||
}
|
}
|
||||||
tag @ HeapCellValueTag::PStrLoc => {
|
tag @ HeapCellValueTag::PStrLoc => {
|
||||||
let value = self.get_value() as usize + heap_index!(rhs.unsigned_abs() as usize);
|
let value =
|
||||||
|
self.get_value() as usize + heap_index!(rhs.unsigned_abs() as usize);
|
||||||
HeapCellValue::build_with(tag, value as u64)
|
HeapCellValue::build_with(tag, value as u64)
|
||||||
}
|
}
|
||||||
_ => self,
|
_ => self,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::parser::ast::*;
|
|
||||||
use crate::forms::GenContext;
|
use crate::forms::GenContext;
|
||||||
|
use crate::parser::ast::*;
|
||||||
|
|
||||||
use bit_set::*;
|
use bit_set::*;
|
||||||
use fxhash::FxBuildHasher;
|
use fxhash::FxBuildHasher;
|
||||||
@@ -88,7 +88,10 @@ pub enum VarAlloc {
|
|||||||
safety: VarSafetyStatus,
|
safety: VarSafetyStatus,
|
||||||
to_perm_var_num: Option<usize>,
|
to_perm_var_num: Option<usize>,
|
||||||
},
|
},
|
||||||
Perm { reg: usize, allocation: PermVarAllocation }, // stack offset, allocation info
|
Perm {
|
||||||
|
reg: usize,
|
||||||
|
allocation: PermVarAllocation,
|
||||||
|
}, // stack offset, allocation info
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VarAlloc {
|
impl VarAlloc {
|
||||||
@@ -152,7 +155,10 @@ pub struct VariableRecord {
|
|||||||
impl Default for VariableRecord {
|
impl Default for VariableRecord {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
VariableRecord {
|
VariableRecord {
|
||||||
allocation: VarAlloc::Perm { reg: 0, allocation: PermVarAllocation::Pending },
|
allocation: VarAlloc::Perm {
|
||||||
|
reg: 0,
|
||||||
|
allocation: PermVarAllocation::Pending,
|
||||||
|
},
|
||||||
num_occurrences: 0,
|
num_occurrences: 0,
|
||||||
running_count: 0,
|
running_count: 0,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user