fn static_string_index(string: &str, index: usize) -> u64 {
if 0 < string.len() && string.len() <= INLINED_ATOM_MAX_LEN {
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
} else {
(index << 1) as u64
let mut static_strs = vec![];
let mut static_str_indices = vec![];
- let indices: Vec<u64> = visitor.static_strs.iter().map(|string| {
- let index = static_string_index(string, static_strs.len());
+ let indices: Vec<u64> = visitor
+ .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 {
- index
- } else {
- static_str_indices.push(index);
- static_strs.push(string);
- index
- }
- }).collect();
+ if index & 1 == 1 {
+ index
+ } else {
+ static_str_indices.push(index);
+ static_strs.push(string);
+ index
+ }
+ })
+ .collect();
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! {
static STRINGS: [&str; #static_strs_len] = [
}
}
-
impl PartialEq for Number {
fn eq(&self, rhs: &Self) -> bool {
match (self, rhs) {
}
}
-
impl Ord for Number {
fn cmp(&self, rhs: &Number) -> Ordering {
match (self, rhs) {
debug_assert!(string.len() <= INLINED_ATOM_MAX_LEN);
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);
AtomCell::new()
#[inline]
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);
let encoding = u64::from_le_bytes(char_buf);
#[inline]
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]
pub enum AtomString<'a> {
Static(&'a str),
- Inlined([u8;8]),
+ Inlined([u8; 8]),
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
let slice_len = if bytes[0] == 0 {
1
} 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 {
- str::from_utf8_unchecked(&bytes[..slice_len])
- }
+ unsafe { str::from_utf8_unchecked(&bytes[..slice_len]) }
}
impl std::fmt::Debug for AtomString<'_> {
self.mark_var::<QueryInstruction>(var_num, Level::Shallow, context, code);
temp_v!(arg)
} else {
- if let VarAlloc::Perm { allocation: PermVarAllocation::Pending, .. } =
- &self.var_data.records[var_num].allocation
+ if let VarAlloc::Perm {
+ allocation: PermVarAllocation::Pending,
+ ..
+ } = &self.var_data.records[var_num].allocation
{
self.mark_var::<QueryInstruction>(var_num, Level::Shallow, context, code);
} else {
fn add_index_ptr<'a, Target: crate::targets::CompilationTarget<'a>>(
index_ptrs: &IndexMap<usize, CodeIndex, FxBuildHasher>,
heap: &Heap,
- arity: usize,
heap_loc: usize,
) -> Option<Instruction> {
- match fetch_index_ptr(heap, arity, heap_loc) {
- Some(index_ptr) => {
+ if let Some(index_ptr) = index_ptrs.get(&heap_loc) {
+ 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);
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
let (heap_loc, _) = subterm_index(iter.deref(), heap_loc);
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);
- target.push_back(Target::to_structure(lvl, name, 0, r));
target.push_back(instr);
+ target.push_back(Target::to_structure(lvl, name, 0, r));
} else if lvl == Level::Shallow {
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));
}
} else {
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(
self,
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)
.map(|subterm_loc| {
let (subterm_loc, subterm) = subterm_index(iter.deref(), subterm_loc);
})
.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 {
if let Some(r) = r_opt {
<CodeGenerator as AddToFreeList<'a, Target>>::add_subterm_to_free_list(
let heap_loc = iter.focus().value() as usize;
let (heap_loc, _) = subterm_index(iter.deref(), heap_loc);
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>(
tail, tail_loc, context, index_ptrs, &mut target,
);
&InlinedClauseType::CompareNumber(mut cmp) => {
self.marker.reset_arg(2);
- let (mut lcode, at_1) =
- if let Some(r) = variable_marker(&mut self.marker) {
- (CodeDeque::default(), Some(ArithmeticTerm::Reg(r)))
- } else {
- self.compile_arith_expr(terms, first_arg_loc, 1, context, 1)?
- };
+ let (mut lcode, at_1) = if let Some(r) = variable_marker(&mut self.marker) {
+ (CodeDeque::default(), Some(ArithmeticTerm::Reg(r)))
+ } else {
+ self.compile_arith_expr(terms, first_arg_loc, 1, context, 1)?
+ };
let (mut rcode, at_2) =
self.compile_arith_expr(terms, first_arg_loc + 1, 2, context, 2)?;
if let Some(r) = variable_marker(&mut self.marker) {
instr!("atomic", r)
} else {
- read_heap_cell!(first_arg,
- (HeapCellValueTag::Fixnum |
- HeapCellValueTag::F64) => {
- instr!("$succeed")
- }
- (HeapCellValueTag::Cons, cons_ptr) => {
- match cons_ptr.get_tag() {
- ArenaHeaderTag::Integer | ArenaHeaderTag::Rational => {
- instr!("$succeed")
- }
- _ => {
- instr!("$fail")
- }
- }
- }
- (HeapCellValueTag::Atom, (_name, arity)) => {
- if arity == 0 {
- instr!("$succeed")
- } else {
- instr!("$fail")
- }
- }
- (HeapCellValueTag::Lis
- | HeapCellValueTag::Str
- | HeapCellValueTag::PStrLoc) => {
- instr!("$fail")
- }
- _ => {
- if first_arg.is_constant() {
- instr!("$succeed")
- } else {
- instr!("$fail")
- }
- }
- )
+ read_heap_cell!(first_arg,
+ (HeapCellValueTag::Fixnum |
+ HeapCellValueTag::F64) => {
+ instr!("$succeed")
+ }
+ (HeapCellValueTag::Cons, cons_ptr) => {
+ match cons_ptr.get_tag() {
+ ArenaHeaderTag::Integer | ArenaHeaderTag::Rational => {
+ instr!("$succeed")
+ }
+ _ => {
+ instr!("$fail")
+ }
+ }
+ }
+ (HeapCellValueTag::Atom, (_name, arity)) => {
+ if arity == 0 {
+ instr!("$succeed")
+ } else {
+ instr!("$fail")
+ }
+ }
+ (HeapCellValueTag::Lis
+ | HeapCellValueTag::Str
+ | HeapCellValueTag::PStrLoc) => {
+ instr!("$fail")
+ }
+ _ => {
+ if first_arg.is_constant() {
+ instr!("$succeed")
+ } else {
+ instr!("$fail")
+ }
+ }
+ )
}
}
InlinedClauseType::IsCompound(..) => {
}
}
}
- },
+ }
InlinedClauseType::IsVar(..) => {
self.marker.reset_arg(1);
} else {
instr!("$fail")
}
- },
+ }
};
// inlined predicates are never counted, so this overrides nothing.
) -> Result<(), CompilationError> {
macro_rules! compile_expr {
($self:expr, $terms:expr, $context:expr, $code:expr) => {{
- let (acode, at) =
- $self.compile_arith_expr($terms, term_loc + 2, 1, $context, 2)?;
+ let (acode, at) = $self.compile_arith_expr($terms, term_loc + 2, 1, $context, 2)?;
$code.extend(acode.into_iter());
at
}};
code.push_back(instr!("deallocate"));
}
- code.push_back(
- if self.marker.in_tail_position {
- instr!("$succeed").into_execute()
- } else {
- instr!("$succeed")
- },
- );
+ code.push_back(if self.marker.in_tail_position {
+ instr!("$succeed").into_execute()
+ } else {
+ instr!("$succeed")
+ });
}
QueryTerm::Clause(clause) => {
self.compile_query_line(
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 head_loc = term.nth_arg(term.focus, 1).unwrap();
let mut stack = Stack::uninitialized();
let iter = query_iterator::<true>(&mut term.heap, &mut stack, clause.term_loc());
- let query = self.compile_target::<QueryInstruction, _>(
- iter,
- &clause.code_indices,
- context,
- );
+ let query = self.compile_target::<QueryInstruction, _>(iter, &clause.code_indices, context);
code.extend(query);
self.add_call(code, clause.ct.to_instr(), clause.call_policy);
skip_stub_try_me_else = !self.settings.is_dynamic();
}
- let arg = clause.args(heap)
- .map(|r| heap[r.start() + optimal_index]);
+ let arg = clause.args(heap).map(|r| heap[r.start() + optimal_index]);
if let Some(arg) = arg {
let index = code.len();
if clauses_len > 1 || self.settings.is_extensible {
let arg = heap_bound_store(heap, heap_bound_deref(heap, arg));
- code_offsets.index_term(
- heap,
- arg,
- index,
- &mut clause_index_info,
- );
+ code_offsets.index_term(heap, arg, index, &mut clause_index_info);
}
}
for var_num in subsumed_hits {
match &mut self.var_data.records[var_num].allocation {
- VarAlloc::Perm { ref mut allocation, .. } => {
+ VarAlloc::Perm {
+ ref mut allocation, ..
+ } => {
if let PermVarAllocation::Done {
shallow_safety,
deep_safety,
let num_occurrences = self.var_data.records[var_num].num_occurrences;
match &mut self.var_data.records[var_num].allocation {
- VarAlloc::Perm { allocation, ..} => {
+ VarAlloc::Perm { allocation, .. } => {
let shallow_safety = VarSafetyStatus::needed_if(
shallow_safety.contains(var_num),
branch_designator,
self.perm_free_list.pop_front();
match &mut self.var_data.records[var_num].allocation {
- VarAlloc::Perm { reg: p, allocation: PermVarAllocation::Pending }
- if *p > 0 => {
- return Some(std::mem::replace(p, 0));
- }
+ VarAlloc::Perm {
+ reg: p,
+ allocation: PermVarAllocation::Pending,
+ } if *p > 0 => {
+ return Some(std::mem::replace(p, 0));
+ }
_ => {}
}
} else {
match &mut self.var_data.records[var_num].allocation {
VarAlloc::Perm {
- allocation: PermVarAllocation::Done {
- deep_safety,
- shallow_safety,
- ..
- },
+ allocation:
+ PermVarAllocation::Done {
+ deep_safety,
+ shallow_safety,
+ ..
+ },
..
} => {
*deep_safety = VarSafetyStatus::unneeded(branch_designator);
match &mut self.var_data.records[var_num].allocation {
VarAlloc::Perm {
- allocation: PermVarAllocation::Done {
- deep_safety,
- shallow_safety,
- ..
- },
+ allocation:
+ PermVarAllocation::Done {
+ deep_safety,
+ shallow_safety,
+ ..
+ },
..
} => {
// GetVariable in head chunk is considered safe.
match &mut self.var_data.records[var_num].allocation {
VarAlloc::Perm {
- allocation: PermVarAllocation::Done {
- ref mut shallow_safety,
- ..
- },
+ allocation:
+ PermVarAllocation::Done {
+ ref mut shallow_safety,
+ ..
+ },
..
} => {
if !self.in_tail_position
match &mut self.var_data.records[var_num].allocation {
VarAlloc::Perm {
- allocation: PermVarAllocation::Done {
- ref mut deep_safety,
- ..
- },
+ allocation:
+ PermVarAllocation::Done {
+ ref mut deep_safety,
+ ..
+ },
..
} => {
if self
}
fn reset_at_head(&mut self, heap: &mut Heap, head_loc: usize) {
- let head_cell = heap_bound_store(
- heap,
- heap_bound_deref(heap, heap_loc_as_cell!(head_loc)),
- );
+ let head_cell = heap_bound_store(heap, heap_bound_deref(heap, heap_loc_as_cell!(head_loc)));
read_heap_cell!(head_cell,
(HeapCellValueTag::Str, s) => {
self.reset_arg(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() {
let var = heap_bound_store(
heap,
let r = self.get_var_binding(var_num);
if !r.is_perm() && r.reg_num() == 0 {
- self.in_use.insert(idx + 1);
- self.shallow_temp_mappings.insert(idx + 1, var_num);
+ self.in_use.insert(c_idx + 1);
+ self.shallow_temp_mappings.insert(c_idx + 1, var_num);
self.var_data.records[var_num]
.allocation
- .set_register(idx + 1);
+ .set_register(c_idx + 1);
}
}
VarPtr::Anon => {}
use crate::arena::*;
use crate::atom_table::*;
-use crate::instructions::*;
use crate::functor_macro::*;
+use crate::instructions::*;
use crate::machine::disjuncts::VarData;
use crate::machine::heap::*;
// use crate::machine::loader::PredicateQueue;
#[inline]
pub fn chunk_type(&self) -> ChunkType {
match self {
- GenContext::Head => ChunkType::Head,
- GenContext::Mid(_) => ChunkType::Mid,
+ GenContext::Head => ChunkType::Head,
+ GenContext::Mid(_) => ChunkType::Mid,
GenContext::Last(_) => ChunkType::Last,
}
}
#[derive(Debug)]
pub enum ChunkedTerms {
Branch(Vec<VecDeque<ChunkedTerms>>),
- Chunk { chunk_num: usize, terms: VecDeque<QueryTerm> },
+ Chunk {
+ chunk_num: usize,
+ terms: VecDeque<QueryTerm>,
+ },
}
#[derive(Debug)]
}
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) {
let key_opt = term_predicate_key(heap, term_loc);
if Some((atom!(":-"), 2)) == key_opt {
- term_nth_arg(heap, term_loc, 1).and_then(|arg_loc| {
- term_predicate_key(heap, arg_loc)
- })
+ term_nth_arg(heap, term_loc, 1).and_then(|arg_loc| term_predicate_key(heap, arg_loc))
} else {
key_opt
}
+//! A macro to construct functor terms ready to be written to the WAM
+//! heap.
+
use crate::atom_table::*;
use crate::instructions::IndexingCodePtr;
use crate::machine::heap::Heap;
use crate::types::*;
#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum FunctorElement {
+pub(crate) enum FunctorElement {
AbsoluteCell(HeapCellValue),
Cell(HeapCellValue),
InnerFunctor(u64, Vec<FunctorElement>),
let num_items = key_value_pairs.len();
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.pop();
arg_vec.push(FunctorElement::Cell(empty_list_as_cell!()));
- arg_vec.extend(key_value_pairs
- .into_iter()
- .map(|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.extend(key_value_pairs.into_iter().map(|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
}
#[allow(unused_parens)]
mod tests {
use super::*;
- use FunctorElement::*;
use std::string::String;
+ use FunctorElement::*;
#[test]
fn basic_terms() {
- let functor = functor!(atom!("first"), [atom_as_cell((atom!("a"))),
- char_as_cell('c')]);
+ let functor = functor!(
+ atom!("first"),
+ [atom_as_cell((atom!("a"))), char_as_cell('c')]
+ );
assert_eq!(functor.len(), 3);
assert_eq!(functor[1], Cell(atom_as_cell!(atom!("a"))));
assert_eq!(functor[2], Cell(char_as_cell!('c')));
- let functor = functor!(atom!("second"), [atom_as_cell((atom!("a"))),
- functor((atom!("b")), [fixnum(1),
- fixnum(2)]),
- char_as_cell('c')]);
+ let functor = functor!(
+ atom!("second"),
+ [
+ atom_as_cell((atom!("a"))),
+ functor((atom!("b")), [fixnum(1), fixnum(2)]),
+ char_as_cell('c')
+ ]
+ );
assert_eq!(functor.len(), 5);
assert_eq!(functor[1], Cell(atom_as_cell!(atom!("a"))));
assert_eq!(functor[2], Cell(str_loc_as_cell!(4)));
assert_eq!(functor[3], Cell(char_as_cell!('c')));
- assert_eq!(functor[4], InnerFunctor(3, functor!(atom!("b"), [fixnum(1),
- fixnum(2)])));
+ assert_eq!(
+ functor[4],
+ InnerFunctor(3, functor!(atom!("b"), [fixnum(1), fixnum(2)]))
+ );
- let functor = functor!(atom!("third"), [atom_as_cell((atom!("a"))),
- functor((atom!("b")), [fixnum(1), fixnum(2)]),
- functor((atom!("c")), [fixnum(1), fixnum(2)]),
- char_as_cell('c')]);
+ let functor = functor!(
+ atom!("third"),
+ [
+ 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[2], Cell(str_loc_as_cell!(5)));
assert_eq!(functor[3], Cell(str_loc_as_cell!(8)));
assert_eq!(functor[4], Cell(char_as_cell!('c')));
- assert_eq!(functor[5], InnerFunctor(3, functor!(atom!("b"), [fixnum(1), fixnum(2)])));
- assert_eq!(functor[6], InnerFunctor(3, functor!(atom!("c"), [fixnum(1), fixnum(2)])));
+ assert_eq!(
+ 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"))),
- functor((atom!("b")), [fixnum(1), fixnum(2)]),
- functor((atom!("c")), [fixnum(1)]),
- functor((atom!("d")), [fixnum(453), fixnum(2)]),
- char_as_cell('c')]);
+ let functor = functor!(
+ atom!("fourth"),
+ [
+ atom_as_cell((atom!("a"))),
+ 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[3], Cell(str_loc_as_cell!(9)));
assert_eq!(functor[4], Cell(str_loc_as_cell!(11)));
assert_eq!(functor[5], Cell(char_as_cell!('c')));
- assert_eq!(functor[6], 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)])));
+ assert_eq!(
+ functor[6],
+ 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]
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);
heap.truncate(2);
- let functor = functor!(atom!("second"), [atom_as_cell((atom!("a"))),
- functor((atom!("b")), [fixnum(1), fixnum(2)]),
- functor((atom!("c")), [fixnum(1), fixnum(2)]),
- char_as_cell('b')]);
+ let functor = functor!(
+ atom!("second"),
+ [
+ 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);
#[test]
fn nested_functors() {
- let functor = functor!(atom!("first"), [atom_as_cell((atom!("a"))),
- functor((atom!("d")), [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')]);
+ let functor = functor!(
+ atom!("first"),
+ [
+ atom_as_cell((atom!("a"))),
+ functor(
+ (atom!("d")),
+ [
+ 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[2], Cell(str_loc_as_cell!(5)));
assert_eq!(functor[3], Cell(str_loc_as_cell!(11)));
assert_eq!(functor[4], Cell(char_as_cell!('b')));
- assert_eq!(functor[5], InnerFunctor(6, vec![Cell(atom_as_cell!(atom!("d"), 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)])));
+ assert_eq!(
+ functor[5],
+ InnerFunctor(
+ 6,
+ vec![
+ Cell(atom_as_cell!(atom!("d"), 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]
fn nested_functors_in_heap() {
- let functor = functor!(atom!("first"), [atom_as_cell((atom!("a"))),
- functor((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 functor = functor!(
+ atom!("first"),
+ [
+ atom_as_cell((atom!("a"))),
+ functor(
+ (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 functor_writer = Heap::functor_writer(functor);
assert_eq!(heap[0], atom_as_cell!(atom!("first"), 1));
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!());
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);
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[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.slice_to_str(heap_index!(5), " string".len()), " string");
- assert_eq!(heap[6], empty_list_as_cell!());
+ assert_eq!(
+ heap.slice_to_str(heap_index!(5), " string".len()),
+ " string"
+ );
+ assert_eq!(heap[7], empty_list_as_cell!());
}
#[test]
fn functors_with_lists_in_heap() {
let functor = functor!(
atom!("first"),
- [list([fixnum(1),
- atom_as_cell((atom!("a"))),
- fixnum(2)])]
+ [list([fixnum(1), atom_as_cell((atom!("a"))), fixnum(2)])]
);
assert_eq!(functor.len(), 3);
let code_ptr = IndexingCodePtr::Internal(0);
let functor = functor!(
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();
assert_eq!(heap[0], atom_as_cell!(atom!("first"), 2));
assert_eq!(heap[1], pstr_loc_as_cell!(heap_index!(3)));
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[6], atom_as_cell!(atom!("internal"), 1));
assert_eq!(heap[7], fixnum_as_cell!(Fixnum::build_with(0)));
heap.truncate(0);
- let functor = functor!(atom!("second"),
- [string((String::from("a string"))),
- functor((atom!("third")), [atom_as_cell((atom!("a"))),
- string((String::from("another string"))),
- indexing_code_ptr(code_ptr)])]);
+ let functor = functor!(
+ atom!("second"),
+ [
+ string((String::from("a string"))),
+ 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);
functor_writer(&mut heap).unwrap();
assert_eq!(heap[0], atom_as_cell!(atom!("second"), 2));
assert_eq!(heap[1], pstr_loc_as_cell!(heap_index!(3)));
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[6], atom_as_cell!(atom!("third"), 3));
assert_eq!(heap[7], atom_as_cell!(atom!("a")));
assert_eq!(heap[8], pstr_loc_as_cell!(heap_index!(10)));
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[13], atom_as_cell!(atom!("internal"), 1));
assert_eq!(heap[14], fixnum_as_cell!(Fixnum::build_with(0)));
- let functor = functor!(atom!("fourth"),
- [string((String::from("a string"))),
- functor((atom!("a")),
- [functor((atom!("fifth")), [fixnum(5),
- string((String::from("another string"))),
- indexing_code_ptr(code_ptr)]),
- string((String::from("and another")))])]);
+ let functor = functor!(
+ atom!("fourth"),
+ [
+ string((String::from("a string"))),
+ functor(
+ (atom!("a")),
+ [
+ functor(
+ (atom!("fifth")),
+ [
+ fixnum(5),
+ string((String::from("another string"))),
+ indexing_code_ptr(code_ptr)
+ ]
+ ),
+ string((String::from("and another")))
+ ]
+ )
+ ]
+ );
heap.truncate(0);
assert_eq!(heap[0], atom_as_cell!(atom!("fourth"), 2));
assert_eq!(heap[1], pstr_loc_as_cell!(heap_index!(3)));
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[6], atom_as_cell!(atom!("a"), 2));
assert_eq!(heap[7], str_loc_as_cell!(9));
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[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[16], atom_as_cell!(atom!("internal"), 1));
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!());
}
let stub = functor!(
atom!("existence_error"),
- [atom_as_cell((atom!("procedure"))), functor((culprit.clone()))]
+ [
+ atom_as_cell((atom!("procedure"))),
+ functor((culprit.clone()))
+ ]
);
println!("{:?}", stub);
// now the error form
- let lineless_error_form = functor!(
- atom!("error"),
- [functor(stub),
- functor(culprit)]
- );
+ let lineless_error_form = functor!(atom!("error"), [functor(stub), functor(culprit)]);
println!("{:?}", lineless_error_form);
}
}
(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.iter_stack.push(self.heap[tail_loc]);
+ self.heap[tail_idx].set_mark_bit(self.mark_phase);
+ self.iter_stack.push(self.heap[tail_idx]);
}
_ => {
}
}
(HeapCellValueTag::PStrLoc, vh) => {
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
// byte at the end of the string buffer
// 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 {
let cell = self.read_cell_mut(h);
// is never inspected, which it isn't.
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);
}
}
}
-
impl<'a, ElideLists: ListElisionPolicy> Iterator for StackfulPreOrderHeapIter<'a, ElideLists> {
type Item = HeapCellValue;
let mut functor_writer = Heap::functor_writer(functor!(
f_atom,
- [atom_as_cell(a_atom),
- atom_as_cell(b_atom)]),
- );
+ [atom_as_cell(a_atom), atom_as_cell(b_atom)]
+ ));
let cell = functor_writer(&mut wam.machine_st.heap).unwrap();
wam.machine_st.heap.push_cell(cell).unwrap();
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();
unmark_cell_bits!(iter.next().unwrap()),
atom_as_cell!(f_atom, 4)
);
- assert_eq!(
- unmark_cell_bits!(iter.next().unwrap()),
- str_loc_as_cell!(0)
- );
+ assert_eq!(unmark_cell_bits!(iter.next().unwrap()), str_loc_as_cell!(0));
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
atom_as_cell!(a_atom)
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();
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();
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.
wam.machine_st.heap[4] = heap_loc_as_cell!(0);
assert_eq!(iter.next(), None);
}
- all_cells_unmarked(wam.machine_st.heap.splice(..));
-
wam.machine_st.heap.clear();
let mut writer = wam.machine_st.heap.reserve(96).unwrap();
let mut functor_writer = Heap::functor_writer(functor!(
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)
+ ]
));
functor_writer(&mut wam.machine_st.heap).unwrap();
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);
// 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[1], str_loc_as_cell!(5));
// 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[1], str_loc_as_cell!(5));
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();
assert_eq!(iter.next(), None);
}
- all_cells_unmarked(wam.machine_st.heap.splice(..));
+ all_cells_unmarked(&wam.machine_st.heap);
assert_eq!(
unmark_cell_bits!(wam.machine_st.heap[0]),
assert_eq!(iter.next(), None);
}
- all_cells_unmarked(wam.machine_st.heap.splice(..));
+ all_cells_unmarked(&wam.machine_st.heap);
assert_eq!(
unmark_cell_bits!(wam.machine_st.heap[0]),
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);
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();
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();
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();
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[1], atom_as_cell!(atom!("g"), 2));
{
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!(
unmark_cell_bits!(iter.next().unwrap()),
list_loc_as_cell!(7)
let mut functor_writer = Heap::functor_writer(functor!(
f_atom,
- [atom_as_cell(a_atom),
- atom_as_cell(b_atom)]),
- );
+ [atom_as_cell(a_atom), atom_as_cell(b_atom)]
+ ));
let cell = functor_writer(&mut wam.machine_st.heap).unwrap();
let h = wam.machine_st.heap.cell_len();
);
}
- 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[1], atom_as_cell!(a_atom));
let functor = functor!(
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();
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);
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();
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();
2,
);
- assert_eq!(
- iter.heap.slice_to_str(0, "a string".len()),
- "a string"
- );
- assert_eq!(
- iter.next().unwrap(),
- empty_list_as_cell!()
- );
+ assert_eq!(iter.heap.slice_to_str(0, "a string".len()), "a string");
+ assert_eq!(iter.next().unwrap(), empty_list_as_cell!());
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();
let mut functor_writer = Heap::functor_writer(functor!(
f_atom,
- [atom_as_cell(a_atom),
- atom_as_cell(b_atom)]),
- );
+ [atom_as_cell(a_atom), atom_as_cell(b_atom)]
+ ));
let cell = functor_writer(&mut wam.machine_st.heap).unwrap();
let h = wam.machine_st.heap.cell_len();
wam.machine_st.heap.clear();
-
let mut functor_writer = Heap::functor_writer(functor!(
f_atom,
[
unmark_cell_bits!(iter.next().unwrap()),
atom_as_cell!(a_atom)
);
- assert_eq!(
- unmark_cell_bits!(iter.next().unwrap()),
- str_loc_as_cell!(0)
- );
+ assert_eq!(unmark_cell_bits!(iter.next().unwrap()), str_loc_as_cell!(0));
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
atom_as_cell!(f_atom, 4)
);
}
- 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[1], atom_as_cell!(a_atom));
let functor = functor!(
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();
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);
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();
}
let mut functor_writer = Heap::functor_writer(functor!(
f_atom,
- [atom_as_cell(a_atom),
- atom_as_cell(b_atom)]),
- );
+ [atom_as_cell(a_atom), atom_as_cell(b_atom)]
+ ));
let cell = functor_writer(&mut wam.machine_st.heap).unwrap();
wam.machine_st.heap.push_cell(cell).unwrap();
);
}
- 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[1], atom_as_cell!(a_atom));
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);
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();
- 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();
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);
assert_eq!(iter.next(), None);
}
- all_cells_unmarked(wam.machine_st.heap.splice(..));
+ all_cells_unmarked(&wam.machine_st.heap);
}
}
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..];
if atom == "," || !quoted || non_quoted_token(atom.chars()) {
}
macro_rules! emit_char {
- ($c:expr) => ({
+ ($c:expr) => {{
append_str!(self, "'.'");
push_char!(self, '(');
self.state_stack.push(TokenOrRedirect::Close);
char_count += 1;
- });
+ }};
}
match iteratee {
PStrIteratee::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);
for c in s.chars() {
if max_depth == 0 {
while let Some(iteratee) = iter.next() {
let iter: Box<dyn Iterator<Item = char>> = match iteratee {
- PStrIteratee::Char { value: c, .. } => {
- Box::new(std::iter::once(c))
- }
- PStrIteratee::PStrSlice { slice_loc, slice_len } => {
+ PStrIteratee::Char { value: c, .. } => Box::new(std::iter::once(c)),
+ PStrIteratee::PStrSlice {
+ slice_loc,
+ slice_len,
+ } => {
let s = iter.heap.slice_to_str(slice_loc, slice_len);
Box::new(s.chars())
}
while let Some(iteratee) = iter.next() {
let iter: Box<dyn Iterator<Item = char>> = match iteratee {
- PStrIteratee::Char { value: c, .. } => {
- Box::new(std::iter::once(c))
- }
- PStrIteratee::PStrSlice { slice_loc, slice_len } => {
+ PStrIteratee::Char { value: c, .. } => Box::new(std::iter::once(c)),
+ PStrIteratee::PStrSlice {
+ slice_loc,
+ slice_len,
+ } => {
let s = iter.heap.slice_to_str(slice_loc, slice_len);
Box::new(s.chars())
}
self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
} else {
- /*
- let end_cell_h = Heap::neighboring_cell_offset(pstr_loc);
- 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::FunctorRedirect(max_depth + 1));
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
}
}
let mut functor_writer = Heap::functor_writer(functor!(
f_atom,
- [atom_as_cell(a_atom),
- atom_as_cell(b_atom)]),
- );
+ [atom_as_cell(a_atom), atom_as_cell(b_atom)]
+ ));
let cell = functor_writer(&mut wam.machine_st.heap).unwrap();
wam.machine_st.heap.push_cell(cell).unwrap();
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();
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();
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();
let mut functor_writer = Heap::functor_writer(functor!(
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)
+ ]
));
functor_writer(&mut wam.machine_st.heap).unwrap();
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);
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(
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
wam.machine_st.heap.clear();
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();
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();
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();
"=(X,[a,b,c|X])"
);
- all_cells_unmarked(wam.machine_st.heap.splice(..));
+ all_cells_unmarked(&wam.machine_st.heap);
assert_eq!(
&wam.parse_and_print_term("[a,b,\"a\",[a,b,c]].").unwrap(),
"[a,b,[a],[a,b,c]]"
);
- all_cells_unmarked(wam.machine_st.heap.splice(..));
+ all_cells_unmarked(&wam.machine_st.heap);
assert_eq!(
&wam.parse_and_print_term("[\"abc\",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))");
- all_cells_unmarked(wam.machine_st.heap.splice(..));
+ all_cells_unmarked(&wam.machine_st.heap);
wam.op_dir
.insert((atom!("+"), Fixity::In), OpDesc::build_with(500, YFX));
"[a|[]+b]"
);
- all_cells_unmarked(wam.machine_st.heap.splice(..));
+ all_cells_unmarked(&wam.machine_st.heap);
assert_eq!(
&wam.parse_and_print_term("[a|[b|c]*d].").unwrap(),
"[a|[b|c]*d]"
);
- all_cells_unmarked(wam.machine_st.heap.splice(..));
+ all_cells_unmarked(&wam.machine_st.heap);
wam.op_dir
.insert((atom!("fy"), Fixity::Pre), OpDesc::build_with(9, FY));
constants.push(
Fixnum::build_with_checked(value)
.map(|n| fixnum_as_cell!(n))
- .unwrap()
+ .unwrap(),
);
}
}
- _ => {
- }
+ _ => {}
}
/*
self.indices.lists().push_back(index);
}
- fn index_constant(
- &mut self,
- constant: HeapCellValue,
- index: usize,
- ) -> Vec<HeapCellValue> {
+ fn index_constant(&mut self, constant: HeapCellValue, index: usize) -> Vec<HeapCellValue> {
let overlapping_constants = constant_key_alternatives(constant);
let code = self.indices.constants().entry(constant).or_default();
use std::ops::Deref;
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 level(&mut self) -> Level;
}
}
}
(HeapCellValueTag::Lis) => {
- root_terms.insert(root_loc);
- break;
- }
+ root_terms.insert(root_loc);
+ break;
+ }
_ => {
if cell.is_ref() {
root_terms.insert(cell.get_value() as usize);
FirstBranch(usize),
NextBranch,
BranchEnd(usize),
- Chunk { chunk_num: usize, terms: &'a VecDeque<QueryTerm> },
+ Chunk {
+ chunk_num: usize,
+ terms: &'a VecDeque<QueryTerm>,
+ },
}
#[derive(Debug)]
while let Some(state) = self.state_stack.pop() {
match state {
- ClauseIteratorState::RemainingBranches(terms, focus)
- if terms.len() == focus => {
- depth += 1;
- }
+ ClauseIteratorState::RemainingBranches(terms, focus) if terms.len() == focus => {
+ depth += 1;
+ }
_ => {
self.state_stack.push(state);
break;
fn next(&mut self) -> Option<Self::Item> {
while let Some(state) = self.state_stack.pop() {
match state {
- ClauseIteratorState::RemainingChunks(chunks, focus)
- if focus < chunks.len() => {
- if focus + 1 < chunks.len() {
+ ClauseIteratorState::RemainingChunks(chunks, focus) if focus < chunks.len() => {
+ if focus + 1 < chunks.len() {
+ self.state_stack
+ .push(ClauseIteratorState::RemainingChunks(chunks, focus + 1));
+ } else {
+ self.remaining_chunks_on_stack -= 1;
+ }
+
+ match &chunks[focus] {
+ ChunkedTerms::Branch(branches) => {
self.state_stack
- .push(ClauseIteratorState::RemainingChunks(chunks, focus + 1));
- } else {
- self.remaining_chunks_on_stack -= 1;
+ .push(ClauseIteratorState::RemainingBranches(branches, 0));
}
-
- match &chunks[focus] {
- ChunkedTerms::Branch(branches) => {
- self.state_stack
- .push(ClauseIteratorState::RemainingBranches(branches, 0));
- }
- &ChunkedTerms::Chunk { chunk_num, ref terms } => {
- return Some(ClauseItem::Chunk { chunk_num, terms });
- }
+ &ChunkedTerms::Chunk {
+ chunk_num,
+ ref terms,
+ } => {
+ return Some(ClauseItem::Chunk { chunk_num, terms });
}
}
+ }
ClauseIteratorState::RemainingChunks(chunks, focus) => {
debug_assert_eq!(chunks.len(), focus);
}
% maplist isn't
% declared as a
% meta-predicate yet
+ '$debug_hook',
catch(lists:maplist(Selector, Options, OptionPairs0),
error(E, _),
builtins:throw(error(E, Stub))) ->
return Err(self.error_form(type_error, stub_gen()));
};
- let mut iter = stackful_post_order_iter::<NonListElider>(
- &mut self.heap, &mut self.stack, root_loc,
- );
+ let mut iter =
+ stackful_post_order_iter::<NonListElider>(&mut self.heap, &mut self.stack, root_loc);
while let Some(value) = iter.next() {
if value.get_forwarding_bit() {
call_goals([ListOfGoalLists | ListsCubed]) :-
- '$debug_hook',
call_goals_0(ListOfGoalLists),
call_goals(ListsCubed).
call_goals([]).
};
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() {
}
pub(super) fn compile_and_submit(&mut self) -> Result<(), SessionError> {
- let key = match self
- .payload
- .predicates
- .first()
- .map(|term| term.focus) {
- Some(focus) => {
- clause_predicate_key(self.machine_heap(), focus)
- .ok_or(SessionError::NamelessEntry)?
- }
- None => {
- return Err(SessionError::NamelessEntry);
- }
- };
+ let key = match self.payload.predicates.first().map(|term| term.focus) {
+ 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();
term_reg: RegType,
vars: Vec<HeapCellValue>,
) -> 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 arity = vars.len();
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()))?;
writer.write_with(move |section| {
+use fxhash::FxBuildHasher;
+use indexmap::IndexSet;
+
use crate::atom_table::*;
use crate::machine::get_structure_index;
use crate::machine::heap::*;
use crate::machine::stack::*;
use crate::types::*;
+use scryer_modular_bitfield::specifiers::*;
+use scryer_modular_bitfield::*;
+
+use std::collections::BTreeMap;
use std::mem;
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)]
pub enum AttrVarPolicy {
pub trait CopierTarget: IndexMut<usize, Output = HeapCellValue> {
fn store(&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 stack(&mut self) -> &mut Stack;
fn threshold(&self) -> usize;
// 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 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 copy_slice_to_end(&mut self, bounds: Range<usize>) -> Result<(), usize>;
}
target: T,
addr: HeapCellValue,
attr_var_policy: AttrVarPolicy,
-) -> Result<(), usize> {
+) -> Result<usize, usize> {
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_attr_var_lists()?;
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)]
target: T,
attr_var_policy: AttrVarPolicy,
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> {
target,
attr_var_policy,
attr_var_list_locs: vec![],
+ pstr_loc_locs: BTreeMap::new(),
}
}
fn trail_list_cell(&mut self, addr: usize, threshold: usize) {
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> {
}
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);
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> {
- let head_cell_idx = self.target.pstr_head_cell_index(pstr_loc);
- let head_byte_idx = heap_index!(head_cell_idx);
- let pstr_offset = pstr_loc - head_byte_idx;
+ match self.pstr_loc_locs.range_mut(..=pstr_loc).next_back() {
+ Some((
+ _prev_pstr_loc,
+ &mut PStrData {
+ pre_old_h_tail_loc,
+ ref mut post_old_h_pstr_loc_locs,
+ ..
+ },
+ )) if pre_old_h_tail_loc >= cell_index!(pstr_loc) => {
+ post_old_h_pstr_loc_locs.insert(self.scan);
+ self.scan += 1;
+ return Ok(());
+ }
+ _ => {}
+ }
- // if a partial string has been copied previously, we
- // track it by writing a null byte to its first word, which is trailed,
- // and then the new pstr_loc in the word's remaining 7 bytes. see write_pstr_index
- // comment.
+ let offset = self
+ .target
+ .as_slice_from(pstr_loc)
+ .take_while(|b| *b != 0u8)
+ .count();
+
+ 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);
+
+ if flag == 1 {
+ if left_pstr_boundary != pstr_loc_idx {
+ let mut pstr_data = self
+ .pstr_loc_locs
+ .remove(&heap_index!(left_pstr_boundary))
+ .unwrap();
+
+ pstr_data.post_old_h_pstr_loc_locs.insert(self.scan);
+ self.pstr_loc_locs
+ .insert(heap_index!(cell_index!(pstr_loc)), pstr_data);
+
+ 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));
+ } 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));
- if self.target[head_cell_idx].into_bytes()[0] == 0u8 {
- let head_bytes = self.target[head_cell_idx].into_bytes();
- let new_pstr_loc = u64::from_be_bytes(head_bytes) as usize;
+ 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
+ };
- *self.value_at_scan() = pstr_loc_as_cell!(heap_index!(new_pstr_loc) + pstr_offset);
- self.scan += 1;
- return Ok(());
- }
+ let tail_cell = self.target[old_tail_idx];
- let threshold = self.target.threshold();
- let tail_loc = self.target.copy_pstr_to_threshold(head_byte_idx)?;
+ let new_tail_idx = self.target.threshold();
+ let mut writer = self.target.reserve(1)?;
- *self.value_at_scan() = pstr_loc_as_cell!(heap_index!(threshold) + pstr_offset);
+ writer.write_with(|section| {
+ section.push_cell(tail_cell);
+ });
- self.trail.push((Ref::heap_cell(head_cell_idx), self.target[head_cell_idx]));
- self.write_pstr_index(head_cell_idx, threshold);
+ let mut post_old_h_pstr_loc_locs = IndexSet::with_hasher(FxBuildHasher::default());
+ post_old_h_pstr_loc_locs.insert(self.scan);
- let tail_cell = self.target[tail_loc];
- let mut writer = self.target.reserve(1)?;
+ 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,
+ };
- writer.write_with(|section| {
- section.push_cell(tail_cell);
- });
+ self.pstr_loc_locs
+ .insert(heap_index!(pstr_loc_idx), pstr_data);
+ }
self.scan += 1;
-
Ok(())
}
});
debug_assert_eq!(str_cell.get_tag(), HeapCellValueTag::Str);
+
self.copy_term_impl(str_cell)?;
list_addr = self.target[heap_loc + 1];
self.target[frontier] = 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) => {
self.target[frontier] = 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) => {
let threshold = if let AttrVarPolicy::DeepCopy = self.attr_var_policy {
self.target[frontier] = 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 {
- let mut writer = self.target.reserve(2).unwrap();
+ let mut writer = self.target.reserve(2)?;
writer.write_with(|section| {
section.push_cell(attr_var_as_cell!(threshold));
});
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);
if old_list_link.get_tag() == HeapCellValueTag::Lis {
(HeapCellValueTag::Atom, (_name, arity)) => {
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)?;
str_loc_as_cell!(threshold),
);
- self.trail.push((Ref::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);
- });
- }
- }
+ self.trail.push((TrailRef::heap_cell(addr), trail_item));
}
(HeapCellValueTag::Str, h) => {
*self.value_at_scan() = str_loc_as_cell!(h);
});
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();
read_heap_cell!(addr,
Ok(())
}
- fn unwind_trail(mut self) {
- for (r, value) in self.trail {
- let index = r.get_value() as usize;
+ fn copy_pstrs(&mut self) -> Result<(), usize> {
+ while let Some((least_pstr_loc, pstr_data)) = self.pstr_loc_locs.pop_first() {
+ let threshold = heap_index!(self.target.threshold());
+
+ for pstr_loc_loc in pstr_data.post_old_h_pstr_loc_locs {
+ 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.get_tag() {
- RefTag::AttrVar | RefTag::HeapCell => {
+ match r.tag() {
+ TrailRefTag::AttrVar | TrailRefTag::HeapCell => {
self.target[index] = value;
self.target[index].set_mark_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,
}
}
}
let a_atom = atom!("a");
let b_atom = atom!("b");
- let mut functor_writer = Heap::functor_writer(
- functor!(f_atom, [atom_as_cell(a_atom), atom_as_cell(b_atom)]),
- );
+ let mut functor_writer = Heap::functor_writer(functor!(
+ f_atom,
+ [atom_as_cell(a_atom), atom_as_cell(b_atom)]
+ ));
functor_writer(&mut wam.machine_st.heap).unwrap();
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.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.slice_to_str(heap_index!(2), "def".len()),
+ wam.machine_st
+ .heap
+ .slice_to_str(heap_index!(2), "def".len()),
"def"
);
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!(
- 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 "
);
- 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!(
- 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"
);
- 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();
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[4], str_loc_as_cell!(0));
-
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[7], atom_as_cell!(a_atom));
}
HeapCellValueTag::PStrLoc => {
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() {
self.cycle_found = true;
return None;
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.heap[last_cell_loc].set_value(self.current as u64);
- self.current = last_cell_loc;
+ self.next = self.heap[tail_idx].get_value();
+ self.heap[tail_idx].set_value(self.current as u64);
+ self.current = tail_idx;
return Some(pstr_loc_as_cell!(h));
}
use crate::forms::*;
use crate::instructions::*;
use crate::iterators::fact_iterator;
-use crate::machine::Stack;
use crate::machine::heap::*;
use crate::machine::loader::*;
use crate::machine::machine_errors::CompilationError;
use crate::machine::preprocessor::*;
+use crate::machine::Stack;
use crate::parser::ast::*;
use crate::parser::dashu::Rational;
use crate::types::*;
}
pub fn get(&self, idx: VarPtrIndex) -> VarPtr {
- self.map.get(&idx)
+ self.map
+ .get(&idx)
.cloned()
.map(VarPtr::Numbered)
.unwrap_or_else(|| VarPtr::Anon)
if let Some(global_cut_var_num) = global_cut_var_num {
let term = QueryTerm::GetLevel(global_cut_var_num);
- self.records[global_cut_var_num].allocation =
- VarAlloc::Perm { reg: 0, allocation: PermVarAllocation::Pending };
+ self.records[global_cut_var_num].allocation = VarAlloc::Perm {
+ reg: 0,
+ allocation: PermVarAllocation::Pending,
+ };
match build_stack.front_mut() {
Some(ChunkedTerms::Branch(_)) => {
let mut lvl = Level::Shallow;
let mut stack = Stack::uninitialized();
- let mut iter = fact_iterator::<false>(
- term.heap,
- &mut stack,
- term.focus,
- );
+ let mut iter = fact_iterator::<false>(term.heap, &mut stack, term.focus);
// second arg is true to iterate the root, which may be a variable
while let Some(subterm) = iter.next() {
fn probe_body_var(&mut self, context: GenContext, var_info: VarInfo) {
let chunk_num = context.chunk_num();
- let branch_info_v = self.branch_map.entry(var_info.var)
- .or_default();
+ let branch_info_v = self.branch_map.entry(var_info.var).or_default();
let needs_new_branch = if let Some(last_bi) = branch_info_v.last() {
!self.root_set.contains(&last_bi.branch_num)
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 stack = Stack::uninitialized();
- let mut iter = fact_iterator::<false>(
- heap,
- &mut stack,
- idx,
- );
+ let mut iter = fact_iterator::<false>(heap, &mut stack, idx);
while let Some(subterm) = iter.next() {
if !subterm.is_var() {
mut term_loc,
} => {
// return true iff new chunk should be added.
- let update_chunk_data = |build_stack: &mut ChunkedTermVec, key: PredicateKey| {
- if ClauseType::is_inlined(key.0, key.1) {
- build_stack.try_set_chunk_at_inlined_boundary()
- } else {
- build_stack.try_set_chunk_at_call_boundary()
- }
- };
+ let update_chunk_data =
+ |build_stack: &mut ChunkedTermVec, key: PredicateKey| {
+ if ClauseType::is_inlined(key.0, key.1) {
+ build_stack.try_set_chunk_at_inlined_boundary()
+ } else {
+ build_stack.try_set_chunk_at_call_boundary()
+ }
+ };
macro_rules! add_chunk {
($key:expr, $tag:expr, $term_loc:expr) => {{
let context = build_stack.current_gen_context();
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(
arg_c + 1,
let context = build_stack.current_gen_context();
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(
arg_c + 1,
for (var, branches) in self.iter_mut() {
let (mut var_num, var_num_incr) = match var {
- &ClassifiedVar::InSitu { var_num} => (var_num, false),
- _ => (var_data.records.len(), true)
+ &ClassifiedVar::InSitu { var_num } => (var_num, false),
+ _ => (var_data.records.len(), true),
};
for branch in branches.iter_mut() {
let chunk_num = chunk.term_loc.chunk_num();
var_data.var_locs_to_nums.insert(
- VarPtrIndex { chunk_num, term_loc },
+ VarPtrIndex {
+ chunk_num,
+ term_loc,
+ },
var_num,
);
}
let a1 = self.registers[1];
let a2 = self.registers[2];
- step_or_resource_error!(
- self,
- copy_term(CopyTerm::new(self), a1, attr_var_policy)
- );
+ step_or_resource_error!(self, copy_term(CopyTerm::new(self), a1, attr_var_policy));
unify_fn!(*self, heap_loc_as_cell!(old_h), a2);
}
let heap_addr = resource_error_call_result!(
self,
- sized_iter_to_heap_list(
- &mut self.heap,
- list.len(),
- list.into_iter(),
- )
+ sized_iter_to_heap_list(&mut self.heap, list.len(), list.into_iter(),)
);
let target_addr = self.registers[2];
let r = self.machine_st.registers[2];
let r = self.machine_st.store(self.machine_st.deref(r));
- let mut writer = Heap::functor_writer(
- functor!(atom!("-"), [fixnum(n), fixnum(p)]),
- );
+ let mut writer =
+ Heap::functor_writer(functor!(atom!("-"), [fixnum(n), fixnum(p)]));
let str_cell = backtrack_on_resource_error!(
&mut self.machine_st,
let r = self.machine_st.registers[2];
let r = self.machine_st.store(self.machine_st.deref(r));
- let mut writer = Heap::functor_writer(
- functor!(atom!("-"), [fixnum(n), fixnum(p)]),
- );
+ let mut writer =
+ Heap::functor_writer(functor!(atom!("-"), [fixnum(n), fixnum(p)]));
let str_cell = backtrack_on_resource_error!(
&mut self.machine_st,
use crate::types::*;
#[cfg(test)]
-use fxhash::FxBuildHasher;
+use crate::heap_iter::{FocusedHeapIter, HeapOrStackTag, IterStackLoc};
+
#[cfg(test)]
-use indexmap::IndexMap;
+use std::collections::BTreeMap;
+#[cfg(test)]
+use std::ops::Deref;
#[cfg(test)]
-use crate::heap_iter::{FocusedHeapIter, HeapOrStackTag, IterStackLoc};
+use fxhash::FxBuildHasher;
#[cfg(test)]
-use std::ops::Deref;
+use indexmap::IndexMap;
#[cfg(test)]
pub(crate) trait UnmarkPolicy {
fn record_focus(_iter: &mut StacklessPreOrderHeapIter<Self>)
where
Self: Sized,
- {}
+ {
+ }
}
#[cfg(test)]
}
#[cfg(test)]
-type PStrLocValuesMap = IndexMap<usize, usize, FxBuildHasher>;
+#[derive(Debug)]
+struct PStrLocValuesMap {
+ hit_set: BTreeMap<usize, usize>,
+ pstr_loc_locs: IndexMap<usize, usize, FxBuildHasher>,
+}
+
+#[cfg(test)]
+impl PStrLocValuesMap {
+ #[inline]
+ fn new() -> Self {
+ Self {
+ hit_set: BTreeMap::default(),
+ pstr_loc_locs: IndexMap::with_hasher(FxBuildHasher::default()),
+ }
+ }
+
+ fn progress_pstr_marking(&mut self, heap_slice: &[u8], pstr_loc: usize) -> usize {
+ match self.hit_set.range(..= pstr_loc).next_back() {
+ Some((_prev_pstr_loc, &tail_idx)) if pstr_loc < heap_index!(tail_idx) => {
+ return tail_idx;
+ }
+ _ => {}
+ }
+
+ let delimiter = match self.hit_set.range(pstr_loc + 1..).next() {
+ Some((&prev_pstr_loc, _)) => prev_pstr_loc,
+ None => heap_slice.len(),
+ };
+
+ match heap_slice[pstr_loc..delimiter].iter().position(|b| *b == 0u8) {
+ Some(zero_byte_offset) => {
+ let tail_idx = if (zero_byte_offset + 1) % Heap::heap_cell_alignment() == 0 {
+ cell_index!(pstr_loc + zero_byte_offset) + 2
+ } else {
+ cell_index!(pstr_loc + zero_byte_offset) + 1
+ };
+ self.hit_set.insert(pstr_loc, tail_idx);
+ tail_idx
+ }
+ None => {
+ let tail_idx = self.hit_set.remove(&delimiter).unwrap();
+ self.hit_set.insert(pstr_loc, tail_idx);
+ tail_idx //None
+ }
+ }
+ }
+
+ #[inline]
+ fn pstr_loc_loc_value(&self, pstr_loc_loc: usize) -> Option<usize> {
+ self.pstr_loc_locs.get(&pstr_loc_loc).cloned()
+ }
+
+ #[inline]
+ fn insert_pstr_loc_value(&mut self, pstr_loc_loc: usize, pstr_loc: usize) {
+ self.pstr_loc_locs.insert(pstr_loc_loc, pstr_loc);
+ }
+}
#[cfg(test)]
#[derive(Debug)]
current: start,
next,
iter_state: MarkerUMP {},
- pstr_loc_values: PStrLocValuesMap::with_hasher(FxBuildHasher::default()),
+ pstr_loc_values: PStrLocValuesMap::new(),
}
}
}
current: start,
next,
iter_state: IteratorUMP { mark_phase: true },
- pstr_loc_values: PStrLocValuesMap::with_hasher(FxBuildHasher::default()),
+ pstr_loc_values: PStrLocValuesMap::new(),
}
}
}
let arity = cell_as_atom_cell!(self.heap[h]).get_arity();
- for cell in &mut self.heap.splice_mut(h + 1..h + arity + 1) {
- cell.set_forwarding_bit(true);
+ for idx in h + 1..=h + arity {
+ self.heap[idx].set_forwarding_bit(true);
}
let last_cell_loc = h + arity;
return Some(list_loc_as_cell!(last_cell_loc - 1));
}
HeapCellValueTag::PStrLoc => {
- let h = self.next as usize;
- let (_, last_cell_loc) = self.heap.scan_slice_to_str(h);
+ let pstr_loc = self.next as usize;
- self.pstr_loc_values.insert(self.current, h);
+ let tail_idx = self
+ .pstr_loc_values
+ .progress_pstr_marking(self.heap.as_slice(), pstr_loc);
- if self.heap[last_cell_loc].get_forwarding_bit() {
+ self.pstr_loc_values.insert_pstr_loc_value(self.current, pstr_loc);
+
+ if self.heap[tail_idx].get_forwarding_bit() {
return Some(self.backward_and_return());
}
- self.next = self.heap[last_cell_loc].get_value();
- self.heap[last_cell_loc].set_value(self.current as u64);
- self.current = last_cell_loc;
+ self.next = self.heap[tail_idx].get_value();
+ self.heap[tail_idx].set_value(self.current as u64);
+ self.current = tail_idx;
- self.heap[last_cell_loc].set_forwarding_bit(true);
+ self.heap[tail_idx].set_forwarding_bit(true);
- return Some(pstr_loc_as_cell!(h));
+ return Some(pstr_loc_as_cell!(pstr_loc));
}
tag @ HeapCellValueTag::Atom => {
let cell = HeapCellValue::build_with(tag, self.next);
return None;
}
}
- HeapCellValueTag::Cons if self.heap.pstr_at(self.current) => {
- let pstr_loc_loc = self.heap[self.current].get_value() as usize;
- let pstr_loc_val = self.pstr_loc_values.get(&pstr_loc_loc).unwrap();
-
- self.heap[self.current].set_value(self.next);
-
- self.next = *pstr_loc_val as u64;
- self.current = pstr_loc_loc;
-
- if self.backward() {
- return None;
+ HeapCellValueTag::Cons => {
+ match self.pstr_loc_values.hit_set.range(.. heap_index!(self.current + 1)).next_back() {
+ Some((_prev_pstr_loc, &tail_idx)) if self.current + 1 == tail_idx => {
+ let pstr_loc_loc = self.heap[self.current].get_value() as usize;
+ let pstr_loc_val = self.pstr_loc_values.pstr_loc_loc_value(pstr_loc_loc).unwrap();
+
+ self.heap[self.current].set_value(self.next);
+
+ self.next = pstr_loc_val as u64;
+ self.current = pstr_loc_loc;
+
+ if self.backward() {
+ return None;
+ }
+ }
+ _ => {
+ return Some(self.backward_and_return());
+ }
}
}
_ => {
let a_atom = atom!("a");
let b_atom = atom!("b");
- let mut functor_writer = Heap::functor_writer(
- functor!(f_atom, [atom_as_cell(a_atom), atom_as_cell(b_atom)]),
- );
+ let mut functor_writer = Heap::functor_writer(functor!(
+ f_atom,
+ [atom_as_cell(a_atom), atom_as_cell(b_atom)]
+ ));
let cell = functor_writer(&mut wam.machine_st.heap).unwrap();
let h = wam.machine_st.heap.cell_len();
mark_cells(&mut wam.machine_st.heap, h);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
assert_eq!(
unmark_cell_bits!(wam.machine_st.heap[3]),
wam.machine_st.heap.clear();
- let mut functor_writer = Heap::functor_writer(
- functor!(
- f_atom,
- [
- atom_as_cell(a_atom),
- atom_as_cell(b_atom),
- atom_as_cell(a_atom),
- str_loc_as_cell(1)
- ]
- ),
- );
+ let mut functor_writer = Heap::functor_writer(functor!(
+ f_atom,
+ [
+ atom_as_cell(a_atom),
+ atom_as_cell(b_atom),
+ atom_as_cell(a_atom),
+ str_loc_as_cell(1)
+ ]
+ ));
let cell = functor_writer(&mut wam.machine_st.heap).unwrap();
let h = wam.machine_st.heap.cell_len();
wam.machine_st.heap.push_cell(cell).unwrap();
mark_cells(&mut wam.machine_st.heap, h);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
assert_eq!(
unmark_cell_bits!(wam.machine_st.heap[5]),
atom_as_cell!(a_atom)
);
- unmark_all_cells(wam.machine_st.heap.splice_mut(..));
+ unmark_all_cells(&mut wam.machine_st.heap, 0);
// make the structure doubly cyclic.
wam.machine_st.heap[1] = str_loc_as_cell!(0);
mark_cells(&mut wam.machine_st.heap, h);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
wam.machine_st.heap.clear();
- let mut functor_writer = Heap::functor_writer(
- functor!(
- f_atom,
- [
- atom_as_cell(a_atom),
- atom_as_cell(b_atom),
- atom_as_cell(a_atom),
- str_loc_as_cell(0)
- ]
- ),
- );
+ let mut functor_writer = Heap::functor_writer(functor!(
+ f_atom,
+ [
+ atom_as_cell(a_atom),
+ atom_as_cell(b_atom),
+ atom_as_cell(a_atom),
+ str_loc_as_cell(0)
+ ]
+ ));
let cell = functor_writer(&mut wam.machine_st.heap).unwrap();
let h = wam.machine_st.heap.cell_len();
mark_cells(&mut wam.machine_st.heap, h);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
assert_eq!(
unmark_cell_bits!(wam.machine_st.heap[5]),
mark_cells(&mut wam.machine_st.heap, 0);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
assert_eq!(
unmark_cell_bits!(wam.machine_st.heap[0]),
mark_cells(&mut wam.machine_st.heap, 0);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
assert_eq!(
unmark_cell_bits!(wam.machine_st.heap[0]),
empty_list_as_cell!()
);
- unmark_all_cells(wam.machine_st.heap.splice_mut(..));
+ unmark_all_cells(&mut wam.machine_st.heap, 0);
// now make the list cyclic.
wam.machine_st.heap[4] = heap_loc_as_cell!(0);
mark_cells(&mut wam.machine_st.heap, 0);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
assert_eq!(
unmark_cell_bits!(wam.machine_st.heap[0]),
heap_loc_as_cell!(0)
);
- for cell in &mut wam.machine_st.heap.splice_mut(..) {
- cell.set_mark_bit(false);
- }
+ unmark_all_cells(&mut wam.machine_st.heap, 0);
// make the list doubly cyclic.
wam.machine_st.heap[3] = heap_loc_as_cell!(0);
mark_cells(&mut wam.machine_st.heap, 0);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
wam.machine_st.heap.clear();
// term is: [a, <stream ptr>]
let stream = Stream::from_static_string("test", &mut wam.machine_st.arena);
- let stream_cell = HeapCellValue::from(
- ConsPtr::build_with(stream.as_ptr(), ConsPtrMaskTag::Cons),
- );
+ let stream_cell =
+ HeapCellValue::from(ConsPtr::build_with(stream.as_ptr(), ConsPtrMaskTag::Cons));
let mut writer = wam.machine_st.heap.reserve(16).unwrap();
mark_cells(&mut wam.machine_st.heap, 0);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
assert_eq!(
unmark_cell_bits!(wam.machine_st.heap[0]),
mark_cells(&mut wam.machine_st.heap, 0);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
assert_eq!(
unmark_cell_bits!(wam.machine_st.heap[0]),
let pstr_cell_loc = wam.machine_st.heap.cell_len();
- wam.machine_st.heap.push_cell(pstr_loc_as_cell!(heap_index!(0))).unwrap();
+ wam.machine_st
+ .heap
+ .push_cell(pstr_loc_as_cell!(heap_index!(0)))
+ .unwrap();
mark_cells(&mut wam.machine_st.heap, pstr_cell_loc);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 1);
- unmark_all_cells(wam.machine_st.heap.splice_mut(..));
+ unmark_all_cells(&mut wam.machine_st.heap, 1);
assert_eq!(
- wam.machine_st.heap.slice_to_str(heap_index!(0), "abc ".len()),
+ wam.machine_st
+ .heap
+ .slice_to_str(heap_index!(0), "abc ".len()),
"abc "
);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[pstr_cell_loc]), pstr_cell);
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[pstr_cell_loc]),
+ pstr_cell
+ );
assert_eq!(
unmark_cell_bits!(wam.machine_st.heap[1]),
heap_loc_as_cell!(1)
wam.machine_st.heap[1] = pstr_loc_as_cell!(heap_index!(3));
- wam.machine_st.allocate_pstr("abc ").unwrap();
- wam.machine_st.heap.push_cell(heap_loc_as_cell!(4)).unwrap();
+ wam.machine_st.allocate_pstr("abcdef ").unwrap();
+ wam.machine_st.heap.push_cell(heap_loc_as_cell!(5)).unwrap();
mark_cells(&mut wam.machine_st.heap, 2);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ assert!(wam.machine_st.heap[0].get_mark_bit());
+ assert!(!wam.machine_st.heap[0].get_forwarding_bit());
+ assert!(wam.machine_st.heap[1].get_mark_bit());
+ assert!(!wam.machine_st.heap[1].get_forwarding_bit());
+ assert!(wam.machine_st.heap[2].get_mark_bit());
+ assert!(!wam.machine_st.heap[2].get_forwarding_bit());
- unmark_all_cells(wam.machine_st.heap.splice_mut(..));
+ assert!(wam.machine_st.heap[4].get_mark_bit());
+ assert!(!wam.machine_st.heap[4].get_forwarding_bit());
+ assert!(wam.machine_st.heap[5].get_mark_bit());
+ assert!(!wam.machine_st.heap[5].get_forwarding_bit());
+
+ unmark_all_cells(&mut wam.machine_st.heap, 0);
assert_eq!(
- wam.machine_st.heap.slice_to_str(heap_index!(0), "abc ".len()),
- "abc "
- );
- assert_eq!(
- wam.machine_st.heap[1],
- pstr_loc_as_cell!(heap_index!(3))
- );
- assert_eq!(
- wam.machine_st.heap[2],
- pstr_loc_as_cell!(heap_index!(0))
- );
- assert_eq!(
- wam.machine_st.heap.slice_to_str(heap_index!(3), "abc ".len()),
+ wam.machine_st
+ .heap
+ .slice_to_str(heap_index!(0), "abc ".len()),
"abc "
);
+ assert_eq!(wam.machine_st.heap[1], pstr_loc_as_cell!(heap_index!(3)));
+ assert_eq!(wam.machine_st.heap[2], pstr_loc_as_cell!(heap_index!(0)));
assert_eq!(
- wam.machine_st.heap[4],
- heap_loc_as_cell!(4)
+ wam.machine_st
+ .heap
+ .slice_to_str(heap_index!(3), "abcdef ".len()),
+ "abcdef "
);
+ assert_eq!(wam.machine_st.heap[5], heap_loc_as_cell!(5));
// create a cycle offset two characters into the partial string at 0
- wam.machine_st.heap[4] = pstr_loc_as_cell!(heap_index!(0) + 2);
+ wam.machine_st.heap[5] = pstr_loc_as_cell!(heap_index!(0) + 2);
mark_cells(&mut wam.machine_st.heap, 2);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ assert!(wam.machine_st.heap[0].get_mark_bit());
+ assert!(!wam.machine_st.heap[0].get_forwarding_bit());
+ assert!(wam.machine_st.heap[1].get_mark_bit());
+ assert!(!wam.machine_st.heap[1].get_forwarding_bit());
+ assert!(wam.machine_st.heap[2].get_mark_bit());
+ assert!(!wam.machine_st.heap[2].get_forwarding_bit());
- unmark_all_cells(wam.machine_st.heap.splice_mut(..));
+ assert!(wam.machine_st.heap[4].get_mark_bit());
+ assert!(!wam.machine_st.heap[4].get_forwarding_bit());
+ assert!(wam.machine_st.heap[5].get_mark_bit());
+ assert!(!wam.machine_st.heap[5].get_forwarding_bit());
+ wam.machine_st.heap[0].set_mark_bit(false);
+ wam.machine_st.heap[1].set_mark_bit(false);
+ wam.machine_st.heap[2].set_mark_bit(false);
+ wam.machine_st.heap[4].set_mark_bit(false);
+ wam.machine_st.heap[5].set_mark_bit(false);
+
+ 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!(3)));
+ assert_eq!(wam.machine_st.heap[2], pstr_loc_as_cell!(heap_index!(0)));
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!(3))
- );
- assert_eq!(
- wam.machine_st.heap[2],
- pstr_loc_as_cell!(heap_index!(0))
+ wam.machine_st
+ .heap
+ .slice_to_str(heap_index!(3), "abcdef ".len()),
+ "abcdef "
);
assert_eq!(
- wam.machine_st.heap.slice_to_str(heap_index!(3), "abc ".len()),
- "abc "
- );
- assert_eq!(
- wam.machine_st.heap[4],
+ wam.machine_st.heap[5],
pstr_loc_as_cell!(heap_index!(0) + 2)
);
- wam.machine_st.heap[4] = heap_loc_as_cell!(2);
-
+ wam.machine_st.heap[5] = heap_loc_as_cell!(2);
wam.machine_st.heap.push_cell(heap_loc_as_cell!(2)).unwrap();
- mark_cells(&mut wam.machine_st.heap, 5);
+ mark_cells(&mut wam.machine_st.heap, 6);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ assert!(wam.machine_st.heap[0].get_mark_bit());
+ assert!(!wam.machine_st.heap[0].get_forwarding_bit());
+ assert!(wam.machine_st.heap[1].get_mark_bit());
+ assert!(!wam.machine_st.heap[1].get_forwarding_bit());
+ assert!(wam.machine_st.heap[2].get_mark_bit());
+ assert!(!wam.machine_st.heap[2].get_forwarding_bit());
- unmark_all_cells(wam.machine_st.heap.splice_mut(..));
+ assert!(wam.machine_st.heap[4].get_mark_bit());
+ assert!(!wam.machine_st.heap[4].get_forwarding_bit());
+ assert!(wam.machine_st.heap[5].get_mark_bit());
+ assert!(!wam.machine_st.heap[5].get_forwarding_bit());
+ assert!(wam.machine_st.heap[6].get_mark_bit());
+ assert!(!wam.machine_st.heap[6].get_forwarding_bit());
+ wam.machine_st.heap[0].set_mark_bit(false);
+ wam.machine_st.heap[1].set_mark_bit(false);
+ wam.machine_st.heap[2].set_mark_bit(false);
+ wam.machine_st.heap[4].set_mark_bit(false);
+ wam.machine_st.heap[5].set_mark_bit(false);
+ wam.machine_st.heap[6].set_mark_bit(false);
+
+ 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!(3)));
+ assert_eq!(wam.machine_st.heap[2], pstr_loc_as_cell!(heap_index!(0)));
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!(3))
- );
- assert_eq!(
- wam.machine_st.heap[2],
- pstr_loc_as_cell!(heap_index!(0))
- );
- assert_eq!(
- wam.machine_st.heap.slice_to_str(heap_index!(3), "abc ".len()),
- "abc "
- );
- assert_eq!(
- wam.machine_st.heap[4],
- heap_loc_as_cell!(2)
- );
- assert_eq!(
- wam.machine_st.heap[5],
- heap_loc_as_cell!(2)
+ wam.machine_st
+ .heap
+ .slice_to_str(heap_index!(3), "abcdef ".len()),
+ "abcdef "
);
+ assert_eq!(wam.machine_st.heap[5], heap_loc_as_cell!(2));
+ assert_eq!(wam.machine_st.heap[6], heap_loc_as_cell!(2));
- wam.machine_st.heap[4] = pstr_loc_as_cell!(0);
+ wam.machine_st.heap[5] = pstr_loc_as_cell!(0);
mark_cells(&mut wam.machine_st.heap, 2);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(.. 5));
+ assert!(wam.machine_st.heap[0].get_mark_bit());
+ assert!(wam.machine_st.heap[1].get_mark_bit());
+ assert!(wam.machine_st.heap[2].get_mark_bit());
+ assert!(!wam.machine_st.heap[3].get_mark_bit());
+ assert!(wam.machine_st.heap[4].get_mark_bit());
+ assert!(wam.machine_st.heap[5].get_mark_bit());
+ assert!(!wam.machine_st.heap[6].get_mark_bit());
- unmark_all_cells(wam.machine_st.heap.splice_mut(.. 5));
+ assert!(!wam.machine_st.heap[0].get_forwarding_bit());
+ assert!(!wam.machine_st.heap[1].get_forwarding_bit());
+ assert!(!wam.machine_st.heap[2].get_forwarding_bit());
+ assert!(!wam.machine_st.heap[3].get_forwarding_bit());
+ assert!(!wam.machine_st.heap[4].get_forwarding_bit());
+ assert!(!wam.machine_st.heap[5].get_forwarding_bit());
+ assert!(!wam.machine_st.heap[6].get_forwarding_bit());
+ wam.machine_st.heap[0].set_mark_bit(false);
+ wam.machine_st.heap[1].set_mark_bit(false);
+ wam.machine_st.heap[2].set_mark_bit(false);
+ wam.machine_st.heap[4].set_mark_bit(false);
+ wam.machine_st.heap[5].set_mark_bit(false);
+
+ 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!(3)));
+ assert_eq!(wam.machine_st.heap[2], pstr_loc_as_cell!(heap_index!(0)));
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!(3))
- );
- assert_eq!(
- wam.machine_st.heap[2],
- pstr_loc_as_cell!(heap_index!(0))
- );
- assert_eq!(
- wam.machine_st.heap.slice_to_str(heap_index!(3), "abc ".len()),
- "abc "
- );
- assert_eq!(
- wam.machine_st.heap[4],
- pstr_loc_as_cell!(heap_index!(0))
- );
- assert_eq!(
- wam.machine_st.heap[5],
- heap_loc_as_cell!(2)
+ wam.machine_st
+ .heap
+ .slice_to_str(heap_index!(3), "abcdef ".len()),
+ "abcdef "
);
+ assert_eq!(wam.machine_st.heap[5], pstr_loc_as_cell!(heap_index!(0)));
+ assert_eq!(wam.machine_st.heap[6], heap_loc_as_cell!(2));
- wam.machine_st.heap.truncate(4);
+ wam.machine_st.heap.truncate(5);
let mut writer = wam.machine_st.heap.reserve(2).unwrap();
section.push_cell(pstr_loc_as_cell!(heap_index!(0) + 2)); // offset two chars into pstr at 0
});
- wam.machine_st.heap.push_cell(heap_loc_as_cell!(5)).unwrap();
+ wam.machine_st.heap.push_cell(heap_loc_as_cell!(6)).unwrap();
- mark_cells(&mut wam.machine_st.heap, 6);
+ mark_cells(&mut wam.machine_st.heap, 7);
- // indices 0 and 3 are the beginning of one-cell partial
- // strings, and they should be marked! despite the HeapCellValue casts
- // otherwise not being sensible.
+ // indices 0 and 3 - 4 are the beginning of one-cell partial
+ // strings, and they should be marked! despite the
+ // HeapCellValue casts otherwise not being sensible.
assert!(wam.machine_st.heap[0].get_mark_bit());
assert!(wam.machine_st.heap[1].get_mark_bit());
assert!(!wam.machine_st.heap[2].get_mark_bit());
- assert!(wam.machine_st.heap[3].get_mark_bit());
+ assert!(!wam.machine_st.heap[3].get_mark_bit());
assert!(wam.machine_st.heap[4].get_mark_bit());
assert!(wam.machine_st.heap[5].get_mark_bit());
assert!(wam.machine_st.heap[6].get_mark_bit());
+ assert!(wam.machine_st.heap[7].get_mark_bit());
- unmark_all_cells(wam.machine_st.heap.splice_mut(..));
+ unmark_all_cells(&mut wam.machine_st.heap, 0);
+ 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!(3)));
+ assert_eq!(wam.machine_st.heap[2], pstr_loc_as_cell!(heap_index!(0)));
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!(3))
- );
- assert_eq!(
- wam.machine_st.heap[2],
- pstr_loc_as_cell!(heap_index!(0))
- );
- assert_eq!(
- wam.machine_st.heap.slice_to_str(heap_index!(3), "abc ".len()),
- "abc "
- );
- assert_eq!(
- wam.machine_st.heap[4],
- atom_as_cell!(atom!("irrelevant stuff"))
+ wam.machine_st
+ .heap
+ .slice_to_str(heap_index!(3), "abcdef ".len()),
+ "abcdef "
);
assert_eq!(
wam.machine_st.heap[5],
- pstr_loc_as_cell!(heap_index!(0) + 2)
+ atom_as_cell!(atom!("irrelevant stuff"))
);
assert_eq!(
wam.machine_st.heap[6],
- heap_loc_as_cell!(5)
+ pstr_loc_as_cell!(heap_index!(0) + 2)
);
+ assert_eq!(wam.machine_st.heap[7], heap_loc_as_cell!(6));
wam.machine_st.heap.clear();
assert!(!wam.machine_st.heap[5].get_forwarding_bit());
assert!(!wam.machine_st.heap[6].get_forwarding_bit());
- unmark_all_cells(wam.machine_st.heap.splice_mut(..));
+ unmark_all_cells(&mut wam.machine_st.heap, 0);
assert_eq!(
wam.machine_st.heap[0],
atom_as_cell!(atom!("irrelevant stuff"))
);
assert_eq!(
- wam.machine_st.heap.slice_to_str(heap_index!(1), "abc ".len()),
+ wam.machine_st
+ .heap
+ .slice_to_str(heap_index!(1), "abc ".len()),
"abc "
);
- assert_eq!(
- wam.machine_st.heap[2],
- pstr_loc_as_cell!(heap_index!(4))
- );
+ assert_eq!(wam.machine_st.heap[2], pstr_loc_as_cell!(heap_index!(4)));
assert_eq!(
wam.machine_st.heap[3],
atom_as_cell!(atom!("irrelevant stuff"))
);
assert_eq!(
- wam.machine_st.heap.slice_to_str(heap_index!(4), "def".len()),
+ wam.machine_st
+ .heap
+ .slice_to_str(heap_index!(4), "def".len()),
"def"
);
assert_eq!(
assert!(!wam.machine_st.heap[6].get_mark_bit());
assert!(wam.machine_st.heap[7].get_mark_bit());
- unmark_all_cells(wam.machine_st.heap.splice_mut(..));
+ unmark_all_cells(&mut wam.machine_st.heap, 0);
- assert!(!wam.machine_st.heap[0].get_forwarding_bit());
- assert!(!wam.machine_st.heap[1].get_forwarding_bit());
- assert!(!wam.machine_st.heap[2].get_forwarding_bit());
- assert!(!wam.machine_st.heap[3].get_forwarding_bit());
- assert!(!wam.machine_st.heap[4].get_forwarding_bit());
- assert!(!wam.machine_st.heap[5].get_forwarding_bit());
- assert!(!wam.machine_st.heap[6].get_forwarding_bit());
+ for idx in 0..=6 {
+ assert!(!wam.machine_st.heap[idx].get_forwarding_bit());
+ }
assert_eq!(
wam.machine_st.heap[0],
atom_as_cell!(atom!("irrelevant stuff"))
);
assert_eq!(
- wam.machine_st.heap.slice_to_str(heap_index!(1), "abc ".len()),
+ wam.machine_st
+ .heap
+ .slice_to_str(heap_index!(1), "abc ".len()),
"abc "
);
- assert_eq!(
- wam.machine_st.heap[2],
- pstr_loc_as_cell!(heap_index!(4))
- );
+ assert_eq!(wam.machine_st.heap[2], pstr_loc_as_cell!(heap_index!(4)));
assert_eq!(
wam.machine_st.heap[3],
atom_as_cell!(atom!("irrelevant stuff"))
);
assert_eq!(
- wam.machine_st.heap.slice_to_str(heap_index!(4), "def".len()),
+ wam.machine_st
+ .heap
+ .slice_to_str(heap_index!(4), "def".len()),
"def"
);
assert_eq!(
assert!(!wam.machine_st.heap[6].get_mark_bit());
assert!(wam.machine_st.heap[7].get_mark_bit());
- unmark_all_cells(wam.machine_st.heap.splice_mut(..));
+ unmark_all_cells(&mut wam.machine_st.heap, 0);
- assert!(!wam.machine_st.heap[0].get_forwarding_bit());
- assert!(!wam.machine_st.heap[1].get_forwarding_bit());
- assert!(!wam.machine_st.heap[2].get_forwarding_bit());
- assert!(!wam.machine_st.heap[3].get_forwarding_bit());
- assert!(!wam.machine_st.heap[4].get_forwarding_bit());
- assert!(!wam.machine_st.heap[5].get_forwarding_bit());
- assert!(!wam.machine_st.heap[6].get_forwarding_bit());
+ for idx in 0..=6 {
+ assert!(!wam.machine_st.heap[idx].get_forwarding_bit());
+ }
assert_eq!(
wam.machine_st.heap[0],
atom_as_cell!(atom!("irrelevant stuff"))
);
assert_eq!(
- wam.machine_st.heap.slice_to_str(heap_index!(1), "abc ".len()),
+ wam.machine_st
+ .heap
+ .slice_to_str(heap_index!(1), "abc ".len()),
"abc "
);
- assert_eq!(
- wam.machine_st.heap[2],
- pstr_loc_as_cell!(heap_index!(4))
- );
+ assert_eq!(wam.machine_st.heap[2], pstr_loc_as_cell!(heap_index!(4)));
assert_eq!(
wam.machine_st.heap[3],
atom_as_cell!(atom!("irrelevant stuff"))
);
assert_eq!(
- wam.machine_st.heap.slice_to_str(heap_index!(4), "def".len()),
+ wam.machine_st
+ .heap
+ .slice_to_str(heap_index!(4), "def".len()),
"def"
);
assert_eq!(
mark_cells(&mut wam.machine_st.heap, 5);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
- unmark_all_cells(wam.machine_st.heap.splice_mut(..));
+ unmark_all_cells(&mut wam.machine_st.heap, 0);
assert_eq!(
- wam.machine_st.heap.slice_to_str(heap_index!(0), "abc ".len()),
+ wam.machine_st
+ .heap
+ .slice_to_str(heap_index!(0), "abc ".len()),
"abc "
);
assert_eq!(
wam.machine_st.heap[1],
pstr_loc_as_cell!(heap_index!(0) + 3)
);
- assert_eq!(
- wam.machine_st.heap[2],
- list_loc_as_cell!(3)
- );
- assert_eq!(
- wam.machine_st.heap[3],
- pstr_loc_as_cell!(0)
- );
- assert_eq!(
- wam.machine_st.heap[4],
- empty_list_as_cell!()
- );
- assert_eq!(
- wam.machine_st.heap[5],
- heap_loc_as_cell!(2)
- );
+ assert_eq!(wam.machine_st.heap[2], list_loc_as_cell!(3));
+ assert_eq!(wam.machine_st.heap[3], pstr_loc_as_cell!(0));
+ assert_eq!(wam.machine_st.heap[4], empty_list_as_cell!());
+ assert_eq!(wam.machine_st.heap[5], heap_loc_as_cell!(2));
wam.machine_st.heap.clear();
mark_cells(&mut wam.machine_st.heap, 0);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
- unmark_all_cells(wam.machine_st.heap.splice_mut(..));
+ unmark_all_cells(&mut wam.machine_st.heap, 0);
- assert_eq!(
- wam.machine_st.heap[0],
- heap_loc_as_cell!(1)
- );
- assert_eq!(
- wam.machine_st.heap[1],
- heap_loc_as_cell!(2)
- );
- assert_eq!(
- wam.machine_st.heap[2],
- heap_loc_as_cell!(3)
- );
- assert_eq!(
- wam.machine_st.heap[3],
- heap_loc_as_cell!(3)
- );
+ assert_eq!(wam.machine_st.heap[0], heap_loc_as_cell!(1));
+ assert_eq!(wam.machine_st.heap[1], heap_loc_as_cell!(2));
+ assert_eq!(wam.machine_st.heap[2], heap_loc_as_cell!(3));
+ assert_eq!(wam.machine_st.heap[3], heap_loc_as_cell!(3));
wam.machine_st.heap.clear();
mark_cells(&mut wam.machine_st.heap, 0);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
assert_eq!(
unmark_cell_bits!(wam.machine_st.heap[0]),
mark_cells(&mut wam.machine_st.heap, 0);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
assert_eq!(
unmark_cell_bits!(wam.machine_st.heap[0]),
let clpz_atom = atom!("clpz");
let p_atom = atom!("p");
- for cell in &mut wam.machine_st.heap.splice_mut(..) {
+ for idx in 0..wam.machine_st.heap.cell_len() {
+ let cell = &mut wam.machine_st.heap[idx];
cell.set_mark_bit(false);
cell.set_forwarding_bit(false);
}
mark_cells(&mut wam.machine_st.heap, 0);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
assert_eq!(
unmark_cell_bits!(wam.machine_st.heap[0]),
heap_loc_as_cell!(23)
);
- for cell in &mut wam.machine_st.heap.splice_mut(..) {
+ for idx in 0..wam.machine_st.heap.cell_len() {
+ let cell = &mut wam.machine_st.heap[idx];
+
cell.set_mark_bit(false);
cell.set_forwarding_bit(false);
}
mark_cells(&mut wam.machine_st.heap, 0);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(0..24));
+ for idx in 0..24 {
+ assert!(wam.machine_st.heap[idx].get_mark_bit());
+ assert!(!wam.machine_st.heap[idx].get_forwarding_bit());
+ }
- for cell in wam.machine_st.heap.splice(24..) {
- assert!(!cell.get_mark_bit());
+ for idx in 24..wam.machine_st.heap.cell_len() {
+ assert!(!wam.machine_st.heap[idx].get_mark_bit());
}
assert_eq!(
assert_eq!(wam.machine_st.heap.cell_len(), 1);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
wam.machine_st.heap.clear();
assert_eq!(wam.machine_st.heap.cell_len(), 10);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
assert_eq!(
unmark_cell_bits!(wam.machine_st.heap[0]),
mark_cells(&mut wam.machine_st.heap, 3);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
assert_eq!(
unmark_cell_bits!(wam.machine_st.heap[0]),
mark_cells(&mut wam.machine_st.heap, 7);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
assert_eq!(
unmark_cell_bits!(wam.machine_st.heap[0]),
assert!(wam.machine_st.heap[0].get_mark_bit());
assert!(!wam.machine_st.heap[1].get_mark_bit());
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(2..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 2);
assert_eq!(
unmark_cell_bits!(wam.machine_st.heap[0]),
mark_cells(&mut wam.machine_st.heap, 0);
- all_cells_marked_and_unforwarded(wam.machine_st.heap.splice(..));
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap, 0);
assert_eq!(
unmark_cell_bits!(wam.machine_st.heap[0]),
use std::alloc;
use std::convert::TryFrom;
-use std::mem;
use std::ops::{Bound, Index, IndexMut, Range, RangeBounds};
use std::ptr;
use std::sync::Once;
use super::MachineState;
-use bitvec::prelude::*;
-use bitvec::slice::BitSlice;
-
const ALIGN: usize = Heap::heap_cell_alignment();
#[derive(Debug)]
pub struct Heap {
inner: InnerHeap,
- pstr_vec: BitVec,
resource_err_loc: usize,
}
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.
-// pstr_vec records the location of each string cell starting at index
-// 0.
-fn scan_slice_to_str(orig_ptr: *const u8, pstr_vec: &BitSlice) -> (&str, usize) {
- unsafe {
- debug_assert_eq!(pstr_vec[0], true);
-
- let tail_cell_offset = pstr_vec[0..].first_zero().unwrap();
- 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
- // the context, i.e. marking by an iterator. it is counted by
- // the initial 1 as part of the padding but for this reason
- // 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)
+unsafe fn scan_slice_to_str<'a>(heap_slice: &'a [u8]) -> HeapStringScan<'a> {
+ let string_len = heap_slice.iter().position(|b| *b == 0u8).unwrap();
+ let zero_byte_addr = heap_slice.as_ptr().add(string_len);
+ let sentinel_len = pstr_sentinel_length(zero_byte_addr as usize);
+ let tail_idx = cell_index!(
+ (string_len + sentinel_len).next_multiple_of(ALIGN)
+ + if sentinel_len <= 1 { heap_index!(1) } else { 0 }
+ );
+
+ let str_slice = &heap_slice[..string_len];
+
+ HeapStringScan {
+ string: std::str::from_utf8_unchecked(str_slice),
+ tail_idx,
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) enum PStrSegmentCmpResult {
- Mismatch { c1: char, c2: char },
- 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 },
+ Mismatch {
+ c1: char,
+ c2: char,
+ },
+ 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 {
pdl: &mut Vec<HeapCellValue>,
) -> Option<std::cmp::Ordering> {
match self {
- PStrSegmentCmpResult::FirstMatch { pstr_loc1, pstr_loc2, l1_offset } => {
- let tail1 = Heap::neighboring_cell_offset(pstr_loc1 + l1_offset);
+ PStrSegmentCmpResult::FirstMatch {
+ 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);
pdl.push(heap_loc_as_cell!(tail1));
pdl.push(rest_of_l2);
}
- PStrSegmentCmpResult::SecondMatch { pstr_loc1, pstr_loc2, l2_offset } => {
- let tail2 = Heap::neighboring_cell_offset(pstr_loc2 + l2_offset);
+ PStrSegmentCmpResult::SecondMatch {
+ 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);
pdl.push(rest_of_l1);
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
- let tail1 = Heap::neighboring_cell_offset(pstr_loc1 + null_offset);
- let tail2 = Heap::neighboring_cell_offset(pstr_loc2 + null_offset);
+ let tail1 = Heap::pstr_tail_idx(pstr_loc1 + 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!(tail2));
}
}
-#[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)]
pub struct PStrWriteInfo {
pstr_loc: usize,
}
#[derive(Debug)]
-pub(crate) struct ReservedHeapSection<'a> {
+pub(crate) struct ReservedHeapSection {
heap_ptr: *mut u8,
heap_cell_len: usize,
- pstr_vec: &'a mut BitVec,
}
-impl<'a> ReservedHeapSection<'a> {
+impl ReservedHeapSection {
#[inline]
pub(crate) fn cell_len(&self) -> usize {
self.heap_cell_len
pub(crate) fn push_cell(&mut self, cell: HeapCellValue) {
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;
}
- fn push_pstr_segment(
- &mut self,
- src: &str,
- ) -> usize {
+ fn push_pstr_segment(&mut self, src: &str) -> usize {
if src.is_empty() {
return 0;
}
let align_offset = pstr_sentinel_length(zero_region_idx);
- ptr::write_bytes(
- self.heap_ptr.add(zero_region_idx),
- 0u8,
- align_offset,
- );
+ ptr::write_bytes(self.heap_ptr.add(zero_region_idx), 0u8, align_offset);
+
+ cells_written = if align_offset == 1 {
+ 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;
}
cells_written
}
- pub(crate) fn push_pstr(
- &mut self,
- mut src: &str,
- ) -> Option<HeapCellValue> {
+ pub(crate) fn push_pstr(&mut self, mut src: &str) -> Option<HeapCellValue> {
let orig_h = self.cell_len();
if src.is_empty() {
loop {
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 tail_idx = self.cell_len();
- self.pstr_vec.resize(cell_len + cells_written, true);
-
if cells_written == 0 {
return None;
} else if null_char_idx + 1 < src.len() {
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 {
return Some(pstr_loc_as_cell!(heap_index!(orig_h)));
}
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() {
match &functor[cursor] {
&FunctorElement::AbsoluteCell(cell) => {
}
}
-impl<'a> Index<usize> for ReservedHeapSection<'a> {
+impl Index<usize> for ReservedHeapSection {
type Output = HeapCellValue;
#[inline]
fn index(&self, idx: usize) -> &Self::Output {
debug_assert!(idx < self.heap_cell_len);
- unsafe {
- &*(self.heap_ptr.add(heap_index!(idx)) as *const HeapCellValue)
- }
+ unsafe { &*(self.heap_ptr as *const HeapCellValue).add(idx) }
}
}
#[must_use]
#[derive(Debug)]
pub struct HeapWriter<'a> {
- section: ReservedHeapSection<'a>,
+ section: ReservedHeapSection,
heap_byte_len: &'a mut usize,
}
*self.heap_byte_len = heap_index!(self.section.heap_cell_len);
// 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(
- &mut self,
- writer: impl FnOnce(&mut ReservedHeapSection),
- ) -> usize {
+ pub(crate) fn write_with(&mut self, writer: impl FnOnce(&mut ReservedHeapSection)) -> usize {
let old_section_cell_len = self.section.heap_cell_len;
writer(&mut self.section);
*self.heap_byte_len = heap_index!(self.section.heap_cell_len);
#[inline]
pub(crate) fn truncate(&mut self, cell_offset: usize) {
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);
}
#[inline]
fn index(&self, idx: usize) -> &Self::Output {
debug_assert!(heap_index!(idx) < *self.heap_byte_len);
- unsafe {
- &*(self.section.heap_ptr.add(heap_index!(idx)) as *const HeapCellValue)
- }
+ unsafe { &*(self.section.heap_ptr.add(heap_index!(idx)) as *const HeapCellValue) }
}
}
#[inline]
fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
debug_assert!(heap_index!(idx) < *self.heap_byte_len);
- unsafe {
- &mut *(self.section.heap_ptr.add(heap_index!(idx)) as *mut HeapCellValue)
- }
+ unsafe { &mut *(self.section.heap_ptr.add(heap_index!(idx)) as *mut HeapCellValue) }
}
}
self.section.cell_len()
}
- fn scan_slice_to_str(&self, slice_loc: usize) -> (&str, usize) {
- let (s, tail_cell_offset) = scan_slice_to_str(
- unsafe { self.section.heap_ptr.add(slice_loc) },
- &self.section.pstr_vec.as_bitslice()[cell_index!(slice_loc) ..],
- );
+ fn scan_slice_to_str(&self, slice_loc: usize) -> HeapStringScan {
+ let HeapStringScan { string, tail_idx } = unsafe {
+ let slice = std::slice::from_raw_parts(
+ self.section.heap_ptr.byte_add(slice_loc),
+ heap_index!(self.section.heap_cell_len) - slice_loc,
+ );
+
+ scan_slice_to_str(slice)
+ };
- (s, cell_index!(slice_loc) + tail_cell_offset)
+ HeapStringScan {
+ string,
+ tail_idx: cell_index!(slice_loc) + tail_idx,
+ }
}
- fn pstr_at(&self, cell_offset: usize) -> bool {
- self.section.pstr_vec[cell_offset]
+ fn as_slice(&self) -> &[u8] {
+ unsafe {
+ std::slice::from_raw_parts(
+ self.section.heap_ptr,
+ heap_index!(self.section.heap_cell_len),
+ )
+ }
}
}
byte_len: 0,
byte_cap: 0,
},
- pstr_vec: bitvec![],
resource_err_loc: 0,
}
}
- #[inline(always)]
- unsafe fn grow(&mut self) -> bool {
- let result = self.inner.grow();
-
- if result {
- self.pstr_vec.reserve(cell_index!(self.inner.byte_cap));
+ // 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
}
+ }
- result
+ #[inline(always)]
+ unsafe fn grow(&mut self) -> bool {
+ self.inner.grow()
}
#[inline]
byte_len: 0,
byte_cap: heap_index!(cap),
},
- pstr_vec: bitvec![],
+ // pstr_vec: bitvec![],
resource_err_loc: 0,
})
}
section = ReservedHeapSection {
heap_ptr: self.inner.ptr,
heap_cell_len: self.cell_len(),
- pstr_vec: &mut self.pstr_vec,
};
break;
} else if !self.grow() {
})
}
- pub(crate) fn last_cell_mut(&mut self) -> Option<&mut HeapCellValue> {
+ pub(crate) fn last_cell(&mut self) -> Option<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))
+ Some(ptr::read(
+ self.inner.ptr.add(self.inner.byte_len - heap_index!(1))
+ as *const HeapCellValue,
+ ))
}
}
}
- pub(crate) fn last_cell(&mut self) -> Option<HeapCellValue> {
- if self.inner.byte_len == 0 {
- None
- } else {
- unsafe {
- Some(ptr::read(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]
self.inner.byte_len = 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> {
- unsafe {
- loop {
- if self.free_space() >= heap_index!(heap_slice.slice_cell_len) {
- ptr::copy_nonoverlapping(
- heap_slice.slice,
- self.inner.ptr.add(self.inner.byte_len),
- heap_index!(heap_slice.slice_cell_len),
- );
+ // pub(crate) fn append(&mut self, heap_slice: HeapView) -> Result<(), usize> {
+ // unsafe {
+ // loop {
+ // if self.free_space() >= heap_index!(heap_slice.slice_cell_len) {
+ // ptr::copy_nonoverlapping(
+ // heap_slice.slice,
+ // self.inner.ptr.add(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.inner.byte_len += heap_index!(heap_slice.slice_cell_len);
+ // // self.pstr_vec.extend(heap_slice.pstr_slice.iter());
- break;
- } else if !self.grow() {
- return Err(self.resource_error_offset());
- }
- }
- }
+ // break;
+ // } else if !self.grow() {
+ // return Err(self.resource_error_offset());
+ // }
+ // }
+ // }
- Ok(())
- }
+ // Ok(())
+ // }
pub(crate) fn store_resource_error(&mut self) {
RESOURCE_ERROR_OFFSET_INIT.call_once(move || {
for ((idx, c1), c2) in str1.char_indices().zip(str2.chars()) {
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}' {
- 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}' {
- return PStrSegmentCmpResult::SecondMatch { pstr_loc1, pstr_loc2, l2_offset: idx };
+ return PStrSegmentCmpResult::SecondMatch {
+ pstr_loc1,
+ pstr_loc2,
+ l2_offset: idx,
+ };
} else if c1 != c2 {
return PStrSegmentCmpResult::Mismatch { c1, c2 };
}
// - Invariant: from `InnerHeap`, `self.inner.byte_cap < isize::MAX`.
let cell_ptr = (self.inner.ptr as *mut HeapCellValue).add(self.cell_len());
cell_ptr.write(cell);
- self.pstr_vec.push(false);
+ // self.pstr_vec.push(false);
self.inner.byte_len += heap_index!(1);
}
Range { start, end }
}
+ /*
pub(crate) fn splice<R: RangeBounds<usize>>(
&self,
range: R,
slice: unsafe { self.inner.ptr.add(heap_index!(range.start)) },
cell_offset: 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],
}
}
slice: unsafe { self.inner.ptr.add(heap_index!(range.start)) },
cell_offset: 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> {
let size_in_heap = Self::compute_pstr_size(src);
})
}
- const fn heap_cell_alignment() -> usize {
+ pub const fn heap_cell_alignment() -> usize {
// yes, size_of, not align_of. the alignment of HeapCellValue
// is 1 byte. In the heap, though, its alignment must be its
// size.
- mem::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()
+ size_of::<HeapCellValue>()
}
#[inline]
pub(crate) fn char_at(&self, byte_idx: usize) -> char {
let s = unsafe {
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)
};
let succ_len = loc + c.len_utf8();
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 {
(c, pstr_loc_as_cell!(succ_len))
}
// copies only the string, not its tail. returns the cell index of
// the tail location
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 s_len = s.len();
+ let HeapStringScan { string, tail_idx } = self.scan_slice_to_str(pstr_loc);
+ let s_len = string.len();
let align_offset = pstr_sentinel_length(s_len);
let copy_size = s_len + align_offset;
unsafe {
loop {
if self.free_space() >= copy_size {
- let slice = std::slice::from_raw_parts_mut(
- self.inner.ptr,
- self.inner.byte_len + s_len,
- );
+ let slice =
+ std::slice::from_raw_parts_mut(self.inner.ptr, self.inner.byte_len + s_len);
- slice.copy_within(
- pstr_loc .. pstr_loc + s_len,
- self.inner.byte_len,
- );
+ slice.copy_within(pstr_loc..pstr_loc + s_len, self.inner.byte_len);
ptr::write_bytes(
self.inner.ptr.add(self.inner.byte_len + s_len),
align_offset,
);
- self.inner.byte_len += copy_size;
- self.pstr_vec.resize(self.cell_len(), true);
+ if align_offset == 1 {
+ 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;
} else if !self.grow() {
}
}
- Ok(tail_loc)
+ Ok(tail_idx)
}
// src is a cell-indexed range.
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);
break;
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 {
- byte_size += 2 * mem::size_of::<HeapCellValue>();
+ byte_size += 2 * size_of::<HeapCellValue>();
} else {
- byte_size += mem::size_of::<HeapCellValue>();
+ byte_size += size_of::<HeapCellValue>();
}
if null_idx + 1 >= src.len() {
while idx < functor.len() {
match &functor[idx] {
&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) => {
- byte_size += mem::size_of::<HeapCellValue>();
+ byte_size += size_of::<HeapCellValue>();
}
&FunctorElement::String(cell_len, _) => {
- byte_size += cell_len as usize * mem::size_of::<HeapCellValue>();
+ byte_size += cell_len as usize * size_of::<HeapCellValue>();
}
}
#[inline]
pub(crate) fn truncate(&mut self, cell_offset: usize) {
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> {
string_buf: &'a str,
}
if c == '\u{0}' {
None
} else {
- self.string_buf = &self.string_buf[c.len_utf8() ..];
+ self.string_buf = &self.string_buf[c.len_utf8()..];
Some(c)
}
})
fn cell_len(&self) -> usize;
// 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.
- 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 {
type Output = HeapCellValue;
self.cell_len()
}
- fn scan_slice_to_str(&self, slice_loc: usize) -> (&str, usize) {
- let (s, tail_cell_offset) = scan_slice_to_str(
- unsafe { self.inner.ptr.add(slice_loc) },
- &self.pstr_vec.as_bitslice()[cell_index!(slice_loc) ..],
- );
-
- (s, cell_index!(slice_loc) + tail_cell_offset)
- }
-
- fn pstr_at(&self, cell_offset: usize) -> bool {
- self.pstr_vec[cell_offset]
- }
-}
-
-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<'a>(&'a self, slice_loc: usize) -> HeapStringScan<'a> {
+ let HeapStringScan { string, tail_idx } = unsafe {
+ let slice = std::slice::from_raw_parts(
+ self.inner.ptr.add(slice_loc),
+ self.inner.byte_len - slice_loc,
+ );
- 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) ..],
- );
+ scan_slice_to_str(slice)
+ };
- (s, cell_index!(slice_loc) + tail_cell_offset)
+ HeapStringScan {
+ string,
+ tail_idx: cell_index!(slice_loc) + tail_idx,
+ }
}
- fn pstr_at(&self, cell_offset: usize) -> bool {
- self.pstr_slice[cell_offset]
+ fn as_slice(&self) -> &[u8] {
+ unsafe { std::slice::from_raw_parts(self.inner.ptr, self.inner.byte_len) }
}
}
-impl<'a> SizedHeapMut for HeapViewMut<'a> {}
+impl SizedHeapMut for Heap {}
// sometimes we need to dereference variables that are found only in
// the heap without access to the full WAM (e.g., while detecting
}
#[allow(dead_code)]
-pub fn print_heap_terms<'a, I: Iterator<Item = HeapCellValue>>(heap: I, h: usize) {
- for (index, term) in heap.enumerate() {
- println!("{} : {:?}", h + index, term);
+pub fn print_heap_terms(heap: &Heap, h: usize) {
+ for idx in 0..heap.cell_len() {
+ let term = heap[idx];
+ println!("{} : {:?}", h + idx, term);
}
}
-use std::cmp::Ordering;
use std::collections::BTreeMap;
use crate::atom_table;
if let Err(resource_err_loc) = machine
.machine_st
.heap
- .append(machine.machine_st.ball.stub.splice(..))
+ .append(&machine.machine_st.ball.stub)
{
return Some(Err(Term::from_heapcell(
machine,
/// Consults a module into the [`Machine`] from a 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);
- self.machine_st.registers[1] = stream.into();
- self.machine_st.registers[2] = atom_as_cell!(&atom_table::AtomTable::build_with(
+ 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.atom_tbl,
- module_name
+ module_name,
));
self.run_module_predicate(atom!("loader"), (atom!("consult_stream"), 2));
heap[0] = value;
- let inverse_var_locs = inverse_var_locs_from_iter(
- stackful_preorder_iter::<NonListElider>(
- heap,
- &mut stack,
- 0,
- ),
- );
+ let inverse_var_locs = inverse_var_locs_from_iter(stackful_preorder_iter::<NonListElider>(
+ heap, &mut stack, 0,
+ ));
- Ok(Self { focus, inverse_var_locs })
+ Ok(Self {
+ focus,
+ inverse_var_locs,
+ })
}
}
let composite_op_dir = self.wam_prelude.composite_op_dir(compilation_target);
let mut term = load_state.term_stream.next(&composite_op_dir)?;
- let predicate_focus_opt = load_state.predicates.first().map(|term_write_result| {
- term_write_result.focus
- });
+ let predicate_focus_opt = load_state
+ .predicates
+ .first()
+ .map(|term_write_result| term_write_result.focus);
let machine_st = LS::machine_st(&mut self.payload);
let term_key_opt = clause_predicate_key(&machine_st.heap, term.focus);
let cell = machine_st[r];
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()))?;
- 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)?;
Ok(export_list.into_iter().collect())
}
);
- Ok(TermWriteResult::from(&mut machine_st.heap, heap_loc_as_cell!(focus))
- .map_err(|_err_loc| ParserError::ResourceError(ParserErrorSrc::default()))?)
+ Ok(
+ TermWriteResult::from(&mut machine_st.heap, heap_loc_as_cell!(focus))
+ .map_err(|_err_loc| ParserError::ResourceError(ParserErrorSrc::default()))?,
+ )
}
fn add_extensible_predicate_declaration(
};
let value = self.machine_st.registers[2];
- let term = resource_error_call_result!(
+ let term = resource_error_call_result!(
self.machine_st,
TermWriteResult::from(&mut self.machine_st.heap, value)
);
let add_clause = || {
let indexing_arg_opt = match term_predicate_key(&self.machine_st.heap, term.focus) {
- Some((atom!(":-"), _)) => {
- term_nth_arg(&self.machine_st.heap, term.focus, 1).and_then(|h| {
- term_nth_arg(&self.machine_st.heap, h, 1)
- })
- }
+ Some((atom!(":-"), _)) => term_nth_arg(&self.machine_st.heap, term.focus, 1)
+ .and_then(|h| term_nth_arg(&self.machine_st.heap, h, 1)),
Some(_) => term_nth_arg(&self.machine_st.heap, term.focus, 1),
None => None,
};
};
let mut loader = self.loader_from_heap_evacuable(temp_v!(4));
- let predicate_focus_opt = loader.payload.predicates.first().map(|term_write_result| {
- term_write_result.focus
- });
+ let predicate_focus_opt = loader
+ .payload
+ .predicates
+ .first()
+ .map(|term_write_result| term_write_result.focus);
let is_consistent = if let Some(predicate_focus) = predicate_focus_opt {
let machine_st = LiveLoadAndMachineState::machine_st(&mut loader.payload);
LiveLoadAndMachineState::machine_st(&mut loader.payload).fail =
(!loader.payload.predicates.is_empty()
- && loader.payload.predicates.compilation_target != compilation_target)
+ && loader.payload.predicates.compilation_target != compilation_target)
|| !is_consistent;
let result = LiveLoadAndMachineState::evacuate(loader);
let stub = functor!(
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 {
impl DomainError for HeapCellValue {
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 {
stub,
fn domain_error(self, machine_st: &mut MachineState, error: DomainErrorType) -> MachineError {
let stub = functor!(
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 {
}
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 {
stub,
)
}
ResourceError::OutOfFiles => {
- functor!(atom!("resource_error"), [atom_as_cell((atom!("file_descriptors")))])
+ functor!(
+ atom!("resource_error"),
+ [atom_as_cell((atom!("file_descriptors")))]
+ )
}
};
SessionError::CannotOverwriteBuiltIn(key) => self.permission_error(
Permission::Modify,
atom!("static_procedure"),
- functor_stub(key.0, key.1)
+ functor_stub(key.0, key.1),
),
SessionError::CannotOverwriteStaticProcedure(key) => self.permission_error(
Permission::Modify,
atom!("static_procedure"),
- functor_stub(key.0, key.1)
+ functor_stub(key.0, key.1),
),
SessionError::CannotOverwriteBuiltInModule(module) => {
self.permission_error(Permission::Modify, atom!("static_module"), module)
let stub = functor!(atom!("syntax_error"), [functor(stub)]);
- MachineError {
- stub,
- location,
- }
+ MachineError { stub, location }
}
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 {
stub,
}
pub(super) fn error_form(&mut self, err: MachineError, src: MachineStub) -> MachineStub {
- if let Some(ParserErrorSrc { line_num, .. }) = err.location {
- functor!(atom!("error"), [functor((err.stub)),
- functor((atom!(":")), [functor(src),
- number(line_num, (&mut self.arena))])])
+ if let Some(ParserErrorSrc { line_num, .. }) = err.location {
+ functor!(
+ atom!("error"),
+ [
+ functor((err.stub)),
+ functor(
+ (atom!(":")),
+ [functor(src), number(line_num, (&mut self.arena))]
+ )
+ ]
+ )
} else {
- functor!(atom!("error"), [functor((err.stub)),
- functor(src)])
+ functor!(atom!("error"), [functor((err.stub)), functor(src)])
}
}
// used by '$skip_max_list'.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CycleSearchResult {
- Cyclic { lambda: usize }, // number of steps
+ Cyclic {
+ lambda: usize,
+ }, // number of steps
EmptyList,
- NotList { num_steps: usize, heap_loc: HeapCellValue },
- 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 },
+ NotList {
+ num_steps: usize,
+ heap_loc: HeapCellValue,
+ },
+ 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 {
};
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);
Err(self.error_form(err, stub_gen()))
}
let stub_gen = || functor_stub(atom!("keysort"), 2);
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);
Err(self.error_form(err, stub_gen()))
}
pub(super) enum HeapPtr {
HeapCell(usize),
PStr(usize), // Char(usize),
- // PStrLocation(usize),
+ // PStrLocation(usize),
}
impl Default for HeapPtr {
let mut writer = heap.reserve(1 + 5 * size)?;
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 binding = heap_loc_as_cell!(var_loc);
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(str_loc_as_cell!(src_h + 3 * idx));
}
#[derive(Debug)]
pub struct Ball {
pub(super) boundary: usize,
+ pub(super) pstr_boundary: usize,
pub(super) stub: Heap,
}
pub(super) fn new() -> Self {
Ball {
boundary: 0,
+ pstr_boundary: 0,
stub: Heap::new(),
}
}
pub(super) fn reset(&mut self) {
self.boundary = 0;
+ self.pstr_boundary = 0;
self.stub.clear();
}
let h = dest.cell_len();
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 ..) {
- *cell = *cell - diff;
+ dest_writer.write_with(|section| {
+ 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)
}
#[inline(always)]
- fn copy_pstr_to_threshold(&mut self, pstr_loc: usize) -> Result<usize, usize> {
- 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)
+ 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)]
- 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()
+ fn copy_pstr_to_threshold(&mut self, pstr_loc: usize) -> Result<usize, usize> {
+ self.state.heap.copy_pstr_within(pstr_loc)
}
#[inline(always)]
fn copy_pstr_to_threshold(&mut self, pstr_loc: usize) -> Result<usize, usize> {
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)?;
- Ok(tail_loc)
+ Ok(tail_idx)
}
- #[inline]
- fn reserve(&mut self, num_cells: usize) -> Result<HeapWriter, usize> {
- 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()]
+ 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 {
- self.heap.pstr_vec()[loc]
+ Box::new(self.stub.as_slice()[from..].iter().cloned())
}
}
#[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 reserve(&mut self, num_cells: usize) -> Result<HeapWriter, usize> {
+ self.stub.reserve(num_cells)
}
fn copy_slice_to_end(&mut self, bounds: Range<usize>) -> Result<(), usize> {
push_var_eq_functors(
&mut self.heap,
var_list.len(),
- var_list.iter().map(|(var_name, var, _)| {
- (var.get_value() as usize, var_name.clone())
- }),
+ var_list
+ .iter()
+ .map(|(var_name, var, _)| { (var.get_value() as usize, var_name.clone()) }),
&self.atom_tbl,
)
);
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);
if let Some(var) = cell.as_var() {
singleton_var_set
.iter()
.filter(|(var, is_singleton)| {
- **is_singleton && term.inverse_var_locs.contains_key(
- &(var.get_value() as usize)
- )
+ **is_singleton
+ && term
+ .inverse_var_locs
+ .contains_key(&(var.get_value() as usize))
})
.count(),
term.inverse_var_locs
CompilationError::ParserError(e) if e.is_unexpected_eof() => {
match eof_handler(self, stream)? {
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,
}
let term_loc = self.heap.cell_len();
- step_or_resource_error!(
- self,
- self.heap.push_cell(term_to_be_printed),
- { return Ok(None); }
- );
+ step_or_resource_error!(self, self.heap.push_cell(term_to_be_printed), {
+ return Ok(None);
+ });
let mut printer = HCPrinter::new(
&mut self.heap,
self.ball.reset();
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,
copy_term(
CopyBallTerm::new(
AttrVarPolicy::DeepCopy,
)
);
-
- self.ball.boundary = ball_boundary;
}
#[inline(always)]
HeapPtr::PStr(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();
char_as_cell!(c)
- } else { // read the (self.s_offset)^{th} cdr of the list
- let byte_offset: usize = char_iter
- .take(self.s_offset)
- .map(|c| c.len_utf8())
- .sum();
+ } else {
+ // read the (self.s_offset)^{th} cdr of the list
+ let byte_offset: usize =
+ char_iter.take(self.s_offset).map(|c| c.len_utf8()).sum();
let new_h = h + byte_offset;
self.s_offset = 0;
self.s = HeapPtr::PStr(new_h);
pstr_loc_as_cell!(new_h)
} else {
- let h = Heap::neighboring_cell_offset(new_h);
+ let h = Heap::pstr_tail_idx(new_h);
self.s = HeapPtr::HeapCell(h);
self.deref(heap_loc_as_cell!(h))
}
if char_iter.next().is_some() {
unify_fn!(*self, pstr_loc_as_cell!(pstr_loc + c.len_utf8()), a3);
} 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]);
}
}
}
- 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 mut writer = self.heap.reserve(arity + 1)?;
};
read_heap_cell!(store_name,
- (HeapCellValueTag::Cons | HeapCellValueTag::Fixnum | // HeapCellValueTag::Char |
+ (HeapCellValueTag::Cons | HeapCellValueTag::Fixnum | // HeapCellValueTag::Char |
HeapCellValueTag::F64) if arity == 0 => {
self.bind(a1.as_var().unwrap(), deref_name);
}
) -> Result<String, CompilationError> {
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
.inverse_var_locs
.iter()
- .map(|(var_loc, var_name)| {
- (self.machine_st.heap[*var_loc], var_name.clone())
- })
+ .map(|(var_loc, var_name)| (self.machine_st.heap[*var_loc], var_name.clone()))
.collect();
let mut printer = HCPrinter::new(
impl<'a> Index<usize> for TermCopyingMockWAM<'a> {
type Output = HeapCellValue;
+ #[inline]
fn index(&self, index: usize) -> &HeapCellValue {
&self.wam.machine_st.heap[index]
}
impl<'a> Deref for TermCopyingMockWAM<'a> {
type Target = MockWAM;
+ #[inline]
fn deref(&self) -> &Self::Target {
self.wam
}
#[cfg(test)]
impl<'a> DerefMut for TermCopyingMockWAM<'a> {
+ #[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
self.wam
}
}
#[inline(always)]
- fn pstr_head_cell_index(&self, pstr_loc: usize) -> usize {
- self.wam.machine_st.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.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()
+ fn as_slice_from<'b>(&'b self, from: usize) -> Box<dyn Iterator<Item = u8> + 'b> {
+ Box::new(self.wam.machine_st.heap.as_slice()[from..].iter().cloned())
}
#[inline(always)]
}
#[cfg(test)]
-pub fn all_cells_marked_and_unforwarded(iter: impl SizedHeap) {
- let mut idx = 0;
- let cell_len = iter.cell_len();
-
- 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]
- };
+pub fn all_cells_marked_and_unforwarded(heap: &Heap, offset: usize) {
+ for curr_idx in offset..heap.cell_len() {
+ let cell = heap[curr_idx];
assert!(
cell.get_mark_bit(),
}
#[cfg(test)]
-pub fn unmark_all_cells(mut iter: impl SizedHeapMut) {
- let mut idx = 0;
- let cell_len = iter.cell_len();
-
- 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;
- }
+pub fn unmark_all_cells(heap: &mut Heap, offset: usize) {
+ for idx in offset..heap.cell_len() {
+ heap[idx].set_mark_bit(false);
}
}
#[cfg(test)]
-pub fn all_cells_unmarked(iter: impl SizedHeap) {
+pub fn all_cells_unmarked(iter: &impl SizedHeap) {
let mut idx = 0;
let cell_len = iter.cell_len();
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]
- };
+ idx += 1;
+ let cell = iter[curr_idx];
assert!(
!cell.get_mark_bit(),
assert!(wam.fail);
}
- all_cells_unmarked(wam.heap.splice(..));
+ all_cells_unmarked(&wam.heap);
wam.fail = false;
wam.heap.clear();
assert!(!wam.fail);
}
- all_cells_unmarked(wam.heap.splice(..));
+ all_cells_unmarked(&wam.heap);
wam.fail = false;
wam.heap.clear();
assert!(!wam.fail);
}
- all_cells_unmarked(wam.heap.splice(..));
+ all_cells_unmarked(&wam.heap);
wam.fail = false;
wam.heap.clear();
assert!(!wam.fail);
}
- all_cells_unmarked(wam.heap.splice(..));
+ all_cells_unmarked(&wam.heap);
wam.fail = false;
wam.heap.clear();
assert!(!wam.fail);
}
- all_cells_unmarked(wam.heap.splice(..));
+ all_cells_unmarked(&wam.heap);
wam.fail = false;
wam.heap.clear();
let term_write_result_2 =
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!(
wam,
assert!(!wam.fail);
}
- all_cells_unmarked(wam.heap.splice(..));
+ all_cells_unmarked(&wam.heap);
wam.heap.clear();
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)));
-
- all_cells_unmarked(wam.heap.splice(..));
+ assert_eq!(wam.heap.slice_to_str(heap_index!(4), "this is a string".len()),
+ "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();
assert!(!wam.fail);
- all_cells_unmarked(wam.heap.splice(..));
+ all_cells_unmarked(&wam.heap);
wam.heap.clear();
assert!(wam.fail);
wam.fail = false;
- all_cells_unmarked(wam.heap.splice(..));
+ all_cells_unmarked(&wam.heap);
wam.heap.clear();
unify!(wam, heap_loc_as_cell!(0), heap_loc_as_cell!(5));
assert!(!wam.fail);
- all_cells_unmarked(wam.heap.splice(..));
+ all_cells_unmarked(&wam.heap);
}
#[test]
let term_write_result_2 =
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!(
wam,
let cstr_cell = wam.allocate_cstr("string").unwrap();
assert_eq!(
- compare_term_test!(
- wam,
- atom_as_cell!(atom!("atom")),
- cstr_cell
- ),
+ compare_term_test!(wam, atom_as_cell!(atom!("atom")), cstr_cell),
Some(Ordering::Less)
);
let cstr_cell = wam.allocate_cstr("string").unwrap();
assert_eq!(
- compare_term_test!(
- wam,
- empty_list_as_cell!(),
- cstr_cell
- ),
+ compare_term_test!(wam, empty_list_as_cell!(), cstr_cell),
Some(Ordering::Less)
);
assert!(!wam.is_cyclic_term(1));
assert!(!wam.is_cyclic_term(2));
- all_cells_unmarked(wam.heap.splice(..));
+ all_cells_unmarked(&wam.heap);
wam.heap.clear();
- let mut functor_writer = Heap::functor_writer(
- functor!(
- atom!("f"),
- [atom_as_cell((atom!("a"))),
- atom_as_cell((atom!("b")))]
- ),
- );
+ let mut functor_writer = Heap::functor_writer(functor!(
+ atom!("f"),
+ [atom_as_cell((atom!("a"))), atom_as_cell((atom!("b")))]
+ ));
functor_writer(&mut wam.heap).unwrap();
assert!(!wam.is_cyclic_term(h));
- all_cells_unmarked(wam.heap.splice(..));
+ all_cells_unmarked(&wam.heap);
assert!(!wam.is_cyclic_term(1));
- all_cells_unmarked(wam.heap.splice(..));
+ all_cells_unmarked(&wam.heap);
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);
- print_heap_terms(wam.heap.iter(), 0);
+ print_heap_terms(&wam.heap, 0);
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[1] = str_loc_as_cell!(0);
assert!(wam.is_cyclic_term(1));
- all_cells_unmarked(wam.heap.splice(..));
+ all_cells_unmarked(&wam.heap);
wam.heap.clear();
s,
)) => {
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)) => {
// let lit = self.machine_st.constant_to_literal(cell);
if let Some(idx) = self.indices.code_dir.get(&(name, arity)).cloned() {
self.try_execute(name, arity, idx.get())
} else {
+ println!("aaand undefined!");
self.undefined_procedure(name, arity)
}
} else if let Some(module) = self.indices.modules.get(&module_name) {
#[derive(Debug, Clone, Copy)]
pub enum PStrCmpResult<'a> {
- ListMatch { list_loc: usize },
- CompletePStrMatch { chars_matched: usize, pstr_loc: usize },
- PartialPStrMatch { string: &'a str, var_loc: usize },
+ ListMatch {
+ list_loc: usize,
+ },
+ CompletePStrMatch {
+ chars_matched: usize,
+ pstr_loc: usize,
+ },
+ PartialPStrMatch {
+ string: &'a str,
+ var_loc: usize,
+ },
}
struct PStrIterStep {
if s.is_empty() {
return Some(PStrCmpResult::CompletePStrMatch { chars_matched, pstr_loc: h });
} 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;
}
}
loop {
read_heap_cell!(self.heap[curr_hare],
(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 {
- iteratee: PStrIteratee::PStrSlice { slice_loc: h, slice_len: s.len() },
- next_hare: tail_loc,
+ iteratee: PStrIteratee::PStrSlice { slice_loc: h, slice_len: string.len() },
+ next_hare: tail_idx,
});
}
(HeapCellValueTag::Lis, h) => {
self.item = self.iter.next();
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);
match s.chars().next() {
let mut wam = MockWAM::new();
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
// reserved for use by the runtime
assert_eq!(
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!(!iter.is_cyclic());
assert_eq!(
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(),
assert_eq!(
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(),
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);
"abcdef"
);
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"
);
assert_eq!(
assert_eq!(
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 {}
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);
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!(!wam.machine_st.fail);
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[4 + start], char_as_cell!('b'));
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!(!wam.machine_st.fail);
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[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);
// #2293, test6.
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[4 + start], char_as_cell!('c'));
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[6 + start], char_as_cell!('d'));
fn setup_op_decl(term: &FocusedHeapRefMut) -> Result<OpDecl, CompilationError> {
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,
_ => {
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,
None => {
return Err(CompilationError::InvalidDirective(
- DirectiveError::InvalidOpDeclSpecDomain(term.heap[focus+2]),
+ DirectiveError::InvalidOpDeclSpecDomain(term.heap[focus + 2]),
));
}
};
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,
(HeapCellValueTag::Fixnum, n) => {
let mut focus = term.focus;
loop {
- read_heap_cell!(term.heap[focus],
- (HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
- if h == focus {
- break;
- } else {
- focus = h;
- }
- }
- (HeapCellValueTag::Lis, l) => {
- let term = FocusedHeapRefMut {
- heap: term.heap,
- focus: l,
- };
-
- exports.push(setup_module_export(&term)?);
- focus = l + 1;
- }
- (HeapCellValueTag::Atom, (name, _arity)) => {
- if name == atom!("[]") {
- return Ok(exports);
- } else {
- break;
- }
- }
- _ => {
- break;
- }
- );
+ read_heap_cell!(term.heap[focus],
+ (HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
+ if h == focus {
+ break;
+ } else {
+ focus = h;
+ }
+ }
+ (HeapCellValueTag::Lis, l) => {
+ let term = FocusedHeapRefMut {
+ heap: term.heap,
+ focus: l,
+ };
+
+ exports.push(setup_module_export(&term)?);
+ focus = l + 1;
+ }
+ (HeapCellValueTag::Atom, (name, _arity)) => {
+ if name == atom!("[]") {
+ return Ok(exports);
+ } else {
+ break;
+ }
+ }
+ _ => {
+ break;
+ }
+ );
}
Err(CompilationError::InvalidModuleDecl)
* contained in src/lib/ops_and_meta_predicates.pl, which is loaded before
* src/lib/builtins.pl.
*
- * Meta-specs have three forms:
+ * Meta-specs have four forms:
*
* (:) (the argument should be expanded with (:)/2 as described above)
* + (mode declarations under the mode syntax, which currently have no effect)
}
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,
(HeapCellValueTag::Str, s) => {
let (subterm_loc, _) = subterm_index(loader.machine_heap(), subterm_loc);
let subterm_key_opt = term_predicate_key(loader.machine_heap(), subterm_loc);
- let (module_name, key, term_loc) =
- if subterm_key_opt == Some((atom!(":"), 2)) {
- match get_qualified_name(loader.machine_heap(), subterm_loc + 1, subterm_loc + 2) {
- Some(QualifiedNameInfo {
- module_name,
- name,
- arity,
- qualified_term_loc,
- }) => (
- module_name,
- (name, arity + supp_args),
- qualified_term_loc,
- ),
- None => {
- continue;
- }
+ let (module_name, key, term_loc) = if subterm_key_opt == Some((atom!(":"), 2)) {
+ match get_qualified_name(
+ loader.machine_heap(),
+ subterm_loc + 1,
+ subterm_loc + 2,
+ ) {
+ Some(QualifiedNameInfo {
+ module_name,
+ name,
+ arity,
+ qualified_term_loc,
+ }) => (module_name, (name, arity + supp_args), qualified_term_loc),
+ None => {
+ 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);
continue;
}
let classifier = VariableClassifier::new(self.settings.default_call_policy());
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 {
Err(CompilationError::InadmissibleFact)
}
let head_loc = term_nth_arg(heap, term.focus, 1).unwrap();
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 {
Err(CompilationError::InvalidRuleHead)
}
byte_offset += c.len_utf8();
}
- (
- char_count,
- Heap::neighboring_cell_offset(pstr_loc + byte_offset),
- )
+ (char_count, Heap::pstr_tail_idx(pstr_loc + byte_offset))
}
fn pstr_segment_char_count_up_to(
pstr_loc: pstr_loc + byte_offset,
}
} else {
- let tail_loc = Heap::neighboring_cell_offset(pstr_loc + byte_offset);
PStrSegmentCountResult::End {
char_count,
- tail_loc,
+ tail_loc: Heap::pstr_tail_idx(pstr_loc + byte_offset),
}
}
}
prev_tail: Option<usize>,
}
+#[derive(Debug)]
+pub(crate) struct FindallCopyInfo {
+ offset: usize,
+ pstr_threshold: usize,
+}
+
impl MachineState {
#[inline(always)]
pub(crate) fn unattributed_var(&mut self) {
loop {
read_heap_cell!(value,
(HeapCellValueTag::PStrLoc, h) => {
- let (_, tail) = heap.scan_slice_to_str(h);
- // let (h_offset, _) = pstr_loc_and_offset(heap, h);
- return tail;
+ let HeapStringScan { tail_idx, .. } = heap.scan_slice_to_str(h);
+ return tail_idx;
}
(HeapCellValueTag::Lis, h) => {
return h+1;
&mut self,
lh_offset: usize,
copy_target: HeapCellValue,
- ) -> Result<usize, usize> {
+ ) -> Result<FindallCopyInfo, usize> {
let threshold = self.lifted_heap.cell_len() - lh_offset;
- let mut copy_ball_term = CopyBallTerm::new(
- &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)?;
+ let mut writer = self.lifted_heap.reserve(3)?;
writer.write_with(|section| {
section.push_cell(list_loc_as_cell!(threshold + 1));
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();
+
+ let copy_ball_term = CopyBallTerm::new(
+ &mut self.attr_var_init.attr_var_queue,
+ &mut self.stack,
+ &mut self.heap,
+ &mut self.lifted_heap,
+ );
- Ok(threshold + lh_offset + 2)
+ 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)]
pub fn value_to_str_like(&mut self, value: HeapCellValue) -> Option<AtomOrString> {
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)) => {
if arity == 0 {
// ... likewise.
let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
.get_name_and_arity();
- (name, arity, if self.machine_st.heap.cell_len() > s + arity + 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
- })
+ (name, arity, get_structure_index(self.machine_st.heap[s.saturating_sub(1)]))
}
(HeapCellValueTag::Atom, (name, arity)) => {
debug_assert_eq!(arity, 0);
if let Some(code_index) = index_cell {
if !code_index.is_undefined() {
- // println!("(fast) calling {}/{}", name.as_str(), arity);
load_registers(&mut self.machine_st, goal, goal_arity);
self.machine_st.neck_cut();
return call_at_index(self, name, arity, code_index.get());
.variable_set(&mut supp_vars, self.machine_st.registers[2]);
struct GoalAnalysisResult {
+ index_ptr_loc: usize,
is_simple_goal: bool,
goal: HeapCellValue,
key: PredicateKey,
// fill expanded_vars with variables of the partial
// 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]);
}
// disjoint from them. if they are not, the
// 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
.zip(supp_vars.iter())
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 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!(
self.machine_st,
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,
// since an index is about to appended to it.
- str_loc_as_cell!(h)
+ (h, str_loc_as_cell!(h+1))
} else {
- goal
+ (0, goal)
};
GoalAnalysisResult {
+ index_ptr_loc,
is_simple_goal,
goal,
key: (name, arity),
(HeapCellValueTag::Atom, (name, arity)) => {
debug_assert_eq!(arity, 0);
- let h = self.machine_st.heap.cell_len();
- resource_error_call_result!(
- self.machine_st,
- self.machine_st.heap.push_cell(goal)
- );
-
- GoalAnalysisResult {
- is_simple_goal: true,
- goal: str_loc_as_cell!(h),
- key: (name, 0),
- 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!(
+ let mut writer = resource_error_call_result!(
self.machine_st,
- self.machine_st.heap.push_cell(atom_as_cell!(name))
+ self.machine_st.heap.reserve(2)
);
+ writer.write_with(|section| {
+ section.push_cell(empty_list_as_cell!());
+ section.push_cell(goal);
+ });
+
GoalAnalysisResult {
+ index_ptr_loc: h,
is_simple_goal: true,
- goal: str_loc_as_cell!(h),
+ goal: str_loc_as_cell!(h+1),
key: (name, 0),
supp_vars,
}
}
- */
_ => {
self.machine_st.fail = true;
return Ok(());
let expanded_term = if result.is_simple_goal {
let idx = self.get_or_insert_qualified_code_index(module_name, result.key);
-
- resource_error_call_result!(
- self.machine_st,
- self.machine_st
- .heap
- .push_cell(untyped_arena_ptr_as_cell!(UntypedArenaPtr::from(idx)))
- );
-
+ self.machine_st.heap[result.index_ptr_loc] =
+ untyped_arena_ptr_as_cell!(UntypedArenaPtr::from(idx));
result.goal
} else {
let mut unexpanded_vars = IndexSet::with_hasher(FxBuildHasher::default());
self.machine_st.heap.reserve(unexpanded_vars.len() + 2)
);
+ let idx = CodeIndex::new(
+ IndexPtr::index(helper_clause_loc),
+ &mut self.machine_st.arena,
+ );
+
writer.write_with(|section| {
+ 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);
}
-
- 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(
- IndexPtr::index(helper_clause_loc),
- &mut self.machine_st.arena,
- );
+ self.machine_st.heap[h + 1] = atom_as_cell!(atom!("$aux"), anon_str_arity);
- self.machine_st.heap.last_cell_mut().map(|cell| {
- *cell = untyped_arena_ptr_as_cell!(UntypedArenaPtr::from(idx));
- });
-
- str_loc_as_cell!(h)
+ str_loc_as_cell!(h + 1)
}
}
};
if HeapCellValueTag::Str == qualified_goal.get_tag() {
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") {
return false;
}
- if self.machine_st.heap.cell_len() > s + 1 + arity {
- if self.machine_st.heap.pstr_at(s + 1 + arity) {
- return false;
- }
+ let idx_cell = self.machine_st.heap[s.saturating_sub(1)];
- 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),
- (ArenaHeaderTag::IndexPtr, _ip) => {
- return true;
- }
- _ => {
- }
- );
- }
+ if HeapCellValueTag::Cons == idx_cell.get_tag() {
+ match_untyped_arena_ptr!(cell_as_untyped_arena_ptr!(idx_cell),
+ (ArenaHeaderTag::IndexPtr, _ip) => {
+ return true;
+ }
+ _ => {
+ }
+ );
}
}
let a1 = self.deref_register(1);
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)) => {
debug_assert_eq!(arity, 0);
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!(
self.machine_st,
read_heap_cell!(pstr,
(HeapCellValueTag::PStrLoc, h) => {
- let (_, tail_loc) = self.machine_st.heap.scan_slice_to_str(h);
- unify_fn!(self.machine_st, heap_loc_as_cell!(tail_loc), a2);
+ let HeapStringScan { tail_idx, .. } = self.machine_st.heap.scan_slice_to_str(h);
+ unify_fn!(self.machine_st, heap_loc_as_cell!(tail_idx), a2);
}
(HeapCellValueTag::Lis, h) => {
unify_fn!(
pub(crate) fn copy_to_lifted_heap(&mut self) {
let lh_offset = cell_as_fixnum!(self.deref_register(1)).get_num() as usize;
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
.copy_findall_solution(lh_offset, copy_target)
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..) {
- *addr -= self.machine_st.heap.cell_len() + lh_offset;
+ for idx in old_threshold + 1..pstr_threshold {
+ 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);
}
}
unify_fn!(self.machine_st, solutions, diff);
} else {
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
- .heap
- .append(self.machine_st.lifted_heap.splice(lh_offset..),)
+ self.machine_st.heap.reserve(reserve_size)
);
- for cell in &mut self.machine_st.heap.splice_mut(h..) {
- *cell = *cell + h;
- }
+ writer.write_with(|section| {
+ 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];
unify_fn!(
unify_fn!(self.machine_st, solutions, empty_list_as_cell!());
} else {
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
- .heap
- .append(self.machine_st.lifted_heap.splice(lh_offset..),)
+ self.machine_st.heap.reserve(reserve_size)
);
- for cell in &mut self.machine_st.heap.splice_mut(h..) {
- *cell = *cell + h;
- }
+ writer.write_with(|section| {
+ 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);
let mut ball = Ball::new();
ball.boundary = self.machine_st.heap.cell_len();
-
- step_or_resource_error!(
+ ball.pstr_boundary = step_or_resource_error!(
self.machine_st,
copy_term(
CopyBallTerm::new(
listing_src: ListingSource,
) -> Self {
let lexer_parser = LexerParser::new(stream, machine_st);
- Self { lexer_parser, listing_src }
+ Self {
+ lexer_parser,
+ listing_src,
+ }
}
}
impl<'a> TermStream for BootstrappingTermStream<'a> {
#[inline]
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);
result
impl TermStream for InlineTermStream {
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> {
if value.is_ref() && !value.is_stack_var() {
machine_st.heap[0] = value;
- for cell in stackful_preorder_iter::<NonListElider>(
- &mut machine_st.heap,
- &mut machine_st.stack,
- 0,
- ) {
+ for cell in
+ stackful_preorder_iter::<NonListElider>(&mut machine_st.heap, &mut machine_st.stack, 0)
+ {
let cell = unmark_cell_bits!(cell);
if let Some(inner_r) = cell.as_var() {
($n:expr, $arena:expr) => {
Fixnum::build_with_checked($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) => {
Fixnum::build_with_checked($n)
pub type Var = Rc<String>;
-pub(crate) fn subterm_index(
- heap: &impl SizedHeap,
- subterm_loc: usize,
-) -> (usize, HeapCellValue) {
+pub(crate) fn subterm_index(heap: &impl SizedHeap, subterm_loc: usize) -> (usize, HeapCellValue) {
let subterm = heap[subterm_loc];
if subterm.is_ref() {
}
*/
-pub(crate) fn fetch_index_ptr(
- heap: &impl SizedHeap,
- arity: usize,
- term_loc: usize,
-) -> Option<CodeIndex> {
- if term_loc + arity + 1 >= heap.cell_len() || heap.pstr_at(term_loc + arity + 1) {
- return None;
- }
+pub(crate) fn fetch_index_ptr(heap: &impl SizedHeap, term_loc: usize) -> Option<CodeIndex> {
+ let index_cell_loc = term_loc.saturating_sub(1);
- read_heap_cell!(heap[term_loc + arity + 1],
+ read_heap_cell!(heap[index_cell_loc],
(HeapCellValueTag::Cons, c) => {
match_untyped_arena_ptr!(c,
(ArenaHeaderTag::IndexPtr, ptr) => {
key: PredicateKey,
term_loc: usize,
) -> 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);
true
} else {
start_term: HeapCellValue,
atom: Atom,
) -> Option<usize> {
- let start_term = heap_bound_store(
- heap,
- heap_bound_deref(heap, start_term),
- );
+ let start_term = heap_bound_store(heap, heap_bound_deref(heap, start_term));
if let HeapCellValueTag::Str = start_term.get_tag() {
let s = start_term.get_value() as usize;
blunt_index_ptr(heap, (s_atom, s_arity), s);
if (s_atom, s_arity) == (atom, 2) {
- return Some(s+1);
+ return Some(s + 1);
}
}
let mut current_term = heap[term_loc];
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];
let fst = heap[fst_loc];
terms.push((fst, fst_loc));
terms
}
-pub fn term_predicate_key(
- heap: &impl SizedHeap,
- mut term_loc: usize,
-) -> Option<PredicateKey> {
+pub fn term_predicate_key(heap: &impl SizedHeap, mut term_loc: usize) -> Option<PredicateKey> {
loop {
read_heap_cell!(heap[term_loc],
(HeapCellValueTag::Atom, (name, arity)) => {
let var_loc = var.get_value() as usize;
if count > 1 {
- inverse_var_locs.insert(
- var_loc,
- Rc::new(format!("_{}", var_loc)),
- );
+ inverse_var_locs.insert(var_loc, Rc::new(format!("_{}", var_loc)));
}
}
Token::String(string) if flags.double_quotes.is_codes() => {
2 * string.chars().count() + 1
}
- Token::String(string) => {
- Heap::compute_pstr_size(&string)
- }
- Token::Literal(_) |
- Token::Comma |
- Token::HeadTailSeparator |
- Token::Open |
- Token::OpenCT |
- Token::OpenCurly |
- Token::OpenList |
- Token::Var(_) => {
+ Token::String(string) => Heap::compute_pstr_size(&string),
+ Token::Literal(_)
+ | Token::Comma
+ | Token::HeadTailSeparator
+ | Token::Open
+ | Token::OpenCT
+ | Token::OpenCurly
+ | Token::OpenList
+ | Token::Var(_) => {
heap_index!(1)
}
- _ => {
- 0
- }
+ _ => 0,
}
}
self.skip_char(c);
u32::from_str_radix(&token, radix).map_or_else(
|_| Err(ParserError::ParseBigInt(self.loc_to_err_src())),
- |n| {
- char::try_from(n)
- .map_err(|_| ParserError::Utf8Error(self.loc_to_err_src()))
- },
+ |n| char::try_from(n).map_err(|_| ParserError::Utf8Error(self.loc_to_err_src())),
)
} else {
Err(ParserError::IncompleteReduction(self.loc_to_err_src()))
}
}
} else {
- return Err(ParserError::InvalidSingleQuotedCharacter(self.loc_to_err_src()));
+ return Err(ParserError::InvalidSingleQuotedCharacter(
+ self.loc_to_err_src(),
+ ));
}
} else {
match self.get_back_quoted_string() {
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 term_size = 0;
tail = heap[l+1];
}
(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;
- tail = heap[tail_loc];
+ tail = heap[tail_idx];
}
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
if heap[h] != tail {
TokenType::Comma => Some(atom!(",")),
TokenType::Term { heap_loc } => {
if heap_loc.is_ref() {
- term_predicate_key(&self.terms, heap_loc.get_value() as usize)
- .map(|key| key.0)
+ term_predicate_key(&self.terms, heap_loc.get_value() as usize).map(|key| key.0)
} else {
None
}
fn promote_atom_op(&mut self, atom: Atom, priority: usize, assoc: u32) {
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 {
tt: TokenType::Term {
heap_loc: heap_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 {
- self.terms.write_with(|section| {
- match section.push_pstr(&s) {
+ self.terms
+ .write_with(|section| match section.push_pstr(&s) {
Some(pstr_loc_cell) => {
section.push_cell(empty_list_as_cell!());
let h = section.cell_len();
None => {
section.push_cell(empty_list_as_cell!());
}
- }
- });
+ });
- TokenType::Term { heap_loc: pstr_cell }
+ TokenType::Term {
+ heap_loc: pstr_cell,
+ }
}
}
Token::Literal(c) => {
if var.trim() != "_" {
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 }
}
}
- },
+ }
Token::Comma => TokenType::Comma,
Token::Open => TokenType::Open,
Token::Close => TokenType::Close,
let term_idx = self.terms.cell_len();
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) {
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();
- 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 {
heap_loc: heap_loc_as_cell!(str_loc_idx),
}
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 {
if let Some(term) = self.term_from_stack(index - 1) {
let mut op_desc = self.stack[index - 1];
- let mut term = heap_bound_store(
- &self.terms,
- heap_bound_deref(
- &self.terms,
- term,
- ),
- );
-
- if term.is_ref() &&
- 0 < op_desc.priority &&
- op_desc.priority < self.stack[index].priority
+ let mut term = heap_bound_store(&self.terms, heap_bound_deref(&self.terms, term));
+
+ if term.is_ref()
+ && 0 < op_desc.priority
+ && op_desc.priority < self.stack[index].priority
{
/* '|' is a head-tail separator here, not
* an operator, so expand the
} else {
let mut terms = vec![];
- while let Some(fst_loc) = unfold_by_str_once(
- &mut self.terms,
- term,
- atom!(","),
- ) {
+ while let Some(fst_loc) =
+ unfold_by_str_once(&mut self.terms, term, atom!(","))
+ {
let (_, snd) = subterm_index(&self.terms, fst_loc + 1);
let (_, fst) = subterm_index(&self.terms, fst_loc);
};
let arity = terms.len() - 1;
- self.stack.extend(terms.into_iter().map(|heap_loc| {
- TokenDesc {
+ self.stack
+ .extend(terms.into_iter().map(|heap_loc| TokenDesc {
tt: TokenType::Term { heap_loc },
priority: 0,
spec: 0,
unfold_bounds: 0,
- }
- }));
+ }));
return arity;
}
}
// parsed an empty list token
if td.tt == TokenType::OpenList {
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.tt = TokenType::Term {
let tail_term = match self.term_from_stack(idx + 1) {
Some(term) => term,
None => {
- return Err(ParserError::IncompleteReduction(
- self.loc_to_err_src(),
- ));
+ return Err(ParserError::IncompleteReduction(self.loc_to_err_src()));
}
};
};
if arity > self.terms.cell_len() {
- return Err(ParserError::IncompleteReduction(
- self.loc_to_err_src(),
- ));
+ return Err(ParserError::IncompleteReduction(self.loc_to_err_src()));
}
let pre_terms_len = self.terms.cell_len();
while let Some(token_desc) = self.stack.pop() {
let subterm = match token_desc.tt {
- TokenType::Term { heap_loc } => {
- heap_loc
- }
+ TokenType::Term { heap_loc } => heap_loc,
_ => {
continue;
}
if td.tt == TokenType::OpenCurly {
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 {
heap_loc: heap_loc_as_cell!(h),
Token::String(string) => {
self.shift(Token::String(string), 0, TERM);
}
- Token::Literal(c) => {
- match Number::try_from(c) {
- Ok(Number::Integer(n)) => {
- self.negate_number(n, negate_int_rc, |n, _| typed_arena_ptr_as_cell!(n))
- }
- Ok(Number::Rational(n)) => {
- self.negate_number(n, negate_rat_rc, |r, _| typed_arena_ptr_as_cell!(r))
- }
- Ok(Number::Float(n)) if n.is_infinite() => {
- return Err(ParserError::InfiniteFloat(
- self.lexer.loc_to_err_src(),
- ));
- }
- Ok(Number::Float(n)) => {
- use ordered_float::OrderedFloat;
-
- self.negate_number(
- n,
- |n, _| -n,
- |OrderedFloat(n), arena| HeapCellValue::from(float_alloc!(n, arena)),
- )
- }
- Ok(Number::Fixnum(n)) => {
- self.negate_number(n, |n, _| -n, |n, _| fixnum_as_cell!(n))
- }
- Err(_) => {
- if let Some(name) = c.to_atom() {
- if !self.shift_op(name, op_dir)? {
- self.shift(Token::Literal(c), 0, TERM);
- }
- } else {
+ Token::Literal(c) => match Number::try_from(c) {
+ Ok(Number::Integer(n)) => {
+ self.negate_number(n, negate_int_rc, |n, _| typed_arena_ptr_as_cell!(n))
+ }
+ Ok(Number::Rational(n)) => {
+ self.negate_number(n, negate_rat_rc, |r, _| typed_arena_ptr_as_cell!(r))
+ }
+ Ok(Number::Float(n)) if n.is_infinite() => {
+ return Err(ParserError::InfiniteFloat(
+ self.loc_to_err_src(),
+ ));
+ }
+ Ok(Number::Float(n)) => {
+ use ordered_float::OrderedFloat;
+
+ self.negate_number(
+ n,
+ |n, _| -n,
+ |OrderedFloat(n), arena| HeapCellValue::from(float_alloc!(n, arena)),
+ )
+ }
+ Ok(Number::Fixnum(n)) => {
+ self.negate_number(n, |n, _| -n, |n, _| fixnum_as_cell!(n))
+ }
+ Err(_) => {
+ if let Some(name) = c.to_atom() {
+ if !self.shift_op(name, op_dir)? {
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::Open => self.shift(Token::Open, 1300, DELIMITER),
Token::OpenCT => self.shift(Token::OpenCT, 1300, DELIMITER),
Token::Close => {
if !self.reduce_term() && !self.reduce_brackets() {
- return Err(ParserError::IncompleteReduction(
- self.loc_to_err_src(),
- ));
+ return Err(ParserError::IncompleteReduction(self.loc_to_err_src()));
}
}
Token::OpenList => self.shift(Token::OpenList, 1300, DELIMITER),
Token::CloseList => {
if !self.reduce_list()? {
- return Err(ParserError::IncompleteReduction(
- self.loc_to_err_src(),
- ));
+ return Err(ParserError::IncompleteReduction(self.loc_to_err_src()));
}
}
Token::OpenCurly => self.shift(Token::OpenCurly, 1300, DELIMITER),
Token::CloseCurly => {
if !self.reduce_curly()? {
- return Err(ParserError::IncompleteReduction(
- self.loc_to_err_src(),
- ));
+ return Err(ParserError::IncompleteReduction(self.loc_to_err_src()));
}
}
Token::HeadTailSeparator => {
| Some(TokenType::OpenCurly)
| Some(TokenType::HeadTailSeparator)
| Some(TokenType::Comma) => {
- return Err(ParserError::IncompleteReduction(
- self.loc_to_err_src(),
- ))
+ return Err(ParserError::IncompleteReduction(self.loc_to_err_src()))
}
_ => {}
},
}
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.
// the parser uses conditional indirection in many places so
// the reserved size should be at least 4 * term_byte_size
// 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,
Err(_err_loc) => {
return Err(ParserError::ResourceError(self.loc_to_err_src()));
let op_dir = CompositeOpDir::new(op_dir, None);
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))
}
name == atom!("[]") && arity == 0
}
(HeapCellValueTag::PStrLoc, h) => {
- let (_s, tail_loc) = heap.scan_slice_to_str(h);
- self = heap[tail_loc];
+ let HeapStringScan { tail_idx, .. } = heap.scan_slice_to_str(h);
+ self = heap[tail_idx];
continue;
}
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
| HeapCellValueTag::Var
| HeapCellValueTag::StackVar
| HeapCellValueTag::AttrVar
- | HeapCellValueTag::PStrLoc
- // | HeapCellValueTag::PStrOffset
+ | HeapCellValueTag::PStrLoc // | HeapCellValueTag::PStrOffset
)
}
#[inline]
pub fn to_atom(self) -> Option<Atom> {
match self.get_tag() {
- HeapCellValueTag::Atom => {
- Some(AtomCell::from_bytes(self.into_bytes()).get_name())
- }
+ HeapCellValueTag::Atom => Some(AtomCell::from_bytes(self.into_bytes()).get_name()),
_ => None,
}
}
HeapCellValue::build_with(tag, self.get_value() + rhs.unsigned_abs())
}
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)
}
_ => self,
-use crate::parser::ast::*;
use crate::forms::GenContext;
+use crate::parser::ast::*;
use bit_set::*;
use fxhash::FxBuildHasher;
safety: VarSafetyStatus,
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 Default for VariableRecord {
fn default() -> Self {
VariableRecord {
- allocation: VarAlloc::Perm { reg: 0, allocation: PermVarAllocation::Pending },
+ allocation: VarAlloc::Perm {
+ reg: 0,
+ allocation: PermVarAllocation::Pending,
+ },
num_occurrences: 0,
running_count: 0,
}