introduce bespoke Heap type for in-heap partial strings
This commit is contained in:
@@ -3,10 +3,8 @@
|
||||
use crate::arena::*;
|
||||
use crate::atom_table::*;
|
||||
use crate::forms::PredicateKey;
|
||||
use crate::machine::copier::*;
|
||||
use crate::machine::heap::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::machine_state::*;
|
||||
use crate::types::*;
|
||||
|
||||
use std::fmt;
|
||||
@@ -14,11 +12,8 @@ use std::hash::Hash;
|
||||
use std::io::{Error as IOError, ErrorKind};
|
||||
use std::ops::Neg;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use std::vec::Vec;
|
||||
|
||||
use crate::parser::dashu::{Integer, Rational};
|
||||
|
||||
use fxhash::FxBuildHasher;
|
||||
use indexmap::IndexMap;
|
||||
use scryer_modular_bitfield::error::OutOfBounds;
|
||||
@@ -26,7 +21,7 @@ use scryer_modular_bitfield::prelude::*;
|
||||
|
||||
pub type Specifier = u32;
|
||||
|
||||
pub const MAX_ARITY: usize = 1023;
|
||||
pub const MAX_ARITY: usize = 255;
|
||||
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
@@ -143,7 +138,12 @@ pub const BTERM: u32 = 0x11000;
|
||||
pub const NEGATIVE_SIGN: u32 = 0x0200;
|
||||
|
||||
macro_rules! fixnum {
|
||||
($wrapper:tt, $n:expr, $arena:expr) => {
|
||||
($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>))
|
||||
};
|
||||
($wrapper:ty, $n:expr, $arena:expr) => {
|
||||
Fixnum::build_with_checked($n)
|
||||
.map(<$wrapper>::Fixnum)
|
||||
.unwrap_or_else(|_| <$wrapper>::Integer(arena_alloc!(Integer::from($n), $arena)))
|
||||
@@ -272,50 +272,12 @@ impl fmt::Display for RegType {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub enum VarReg {
|
||||
ArgAndNorm(RegType, usize),
|
||||
Norm(RegType),
|
||||
}
|
||||
|
||||
impl VarReg {
|
||||
pub fn norm(self) -> RegType {
|
||||
match self {
|
||||
VarReg::ArgAndNorm(reg, _) | VarReg::Norm(reg) => reg,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for VarReg {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
VarReg::Norm(RegType::Perm(reg)) => write!(f, "Y{}", reg),
|
||||
VarReg::Norm(RegType::Temp(reg)) => write!(f, "X{}", reg),
|
||||
VarReg::ArgAndNorm(RegType::Perm(reg), arg) => write!(f, "Y{} A{}", reg, arg),
|
||||
VarReg::ArgAndNorm(RegType::Temp(reg), arg) => write!(f, "X{} A{}", reg, arg),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for VarReg {
|
||||
fn default() -> Self {
|
||||
VarReg::Norm(RegType::default())
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! temp_v {
|
||||
($x:expr) => {
|
||||
$crate::parser::ast::RegType::Temp($x)
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! perm_v {
|
||||
($x:expr) => {
|
||||
$crate::parser::ast::RegType::Perm($x)
|
||||
};
|
||||
}
|
||||
|
||||
#[bitfield]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
|
||||
pub struct OpDesc {
|
||||
@@ -410,7 +372,6 @@ pub fn default_op_dir() -> OpDir {
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ArithmeticError {
|
||||
NonEvaluableFunctor(HeapCellValue, usize),
|
||||
UninstantiatedVar,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Default)]
|
||||
@@ -430,6 +391,7 @@ pub enum ParserError {
|
||||
MissingQuote(ParserErrorSrc),
|
||||
NonPrologChar(ParserErrorSrc),
|
||||
ParseBigInt(ParserErrorSrc),
|
||||
ResourceError(ParserErrorSrc),
|
||||
UnexpectedChar(char, ParserErrorSrc),
|
||||
// UnexpectedEOF,
|
||||
Utf8Error(ParserErrorSrc),
|
||||
@@ -447,6 +409,7 @@ impl ParserError {
|
||||
| &ParserError::MissingQuote(err_src)
|
||||
| &ParserError::NonPrologChar(err_src)
|
||||
| &ParserError::ParseBigInt(err_src)
|
||||
| &ParserError::ResourceError(err_src)
|
||||
| &ParserError::UnexpectedChar(_, err_src)
|
||||
| &ParserError::Utf8Error(err_src) => err_src,
|
||||
}
|
||||
@@ -475,6 +438,7 @@ impl ParserError {
|
||||
ParserError::ParseBigInt(..) => atom!("cannot_parse_big_int"),
|
||||
ParserError::UnexpectedChar(..) => atom!("unexpected_char"),
|
||||
ParserError::Utf8Error(..) => atom!("utf8_conversion_error"),
|
||||
ParserError::ResourceError(..) => atom!("resource_error"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -492,29 +456,13 @@ impl ParserError {
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
impl From<lexical::Error> for ParserError {
|
||||
fn from((e, err_src): (lexical::Error, ParserErrorSrc)) -> ParserError {
|
||||
ParserError::LexicalError(e, err_src)
|
||||
|
||||
impl From<ParserErrorSrc> for ParserError {
|
||||
fn from(err_src: ParserErrorSrc) -> ParserError {
|
||||
ParserError::LexicalError(err_src)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<IOError> for ParserError {
|
||||
fn from(e: IOError) -> ParserError {
|
||||
ParserError::IO(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&IOError> for ParserError {
|
||||
fn from(error: &IOError) -> ParserError {
|
||||
if error.get_ref().filter(|e| e.is::<BadUtf8Error>()).is_some() {
|
||||
ParserError::Utf8Error(0, 0)
|
||||
} else {
|
||||
ParserError::IO(error.kind().into())
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct CompositeOpDir<'a, 'b> {
|
||||
pub primary_op_dir: Option<&'b OpDir>,
|
||||
@@ -623,16 +571,16 @@ impl Neg for Fixnum {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
/*
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Literal {
|
||||
Atom(Atom),
|
||||
Char(char),
|
||||
CodeIndex(CodeIndex),
|
||||
Fixnum(Fixnum),
|
||||
Integer(TypedArenaPtr<Integer>),
|
||||
Rational(TypedArenaPtr<Rational>),
|
||||
Float(F64Offset),
|
||||
String(Atom),
|
||||
String(Rc<String>),
|
||||
}
|
||||
|
||||
impl From<F64Ptr> for Literal {
|
||||
@@ -648,7 +596,7 @@ impl fmt::Display for Literal {
|
||||
Literal::Atom(ref atom) => {
|
||||
write!(f, "{}", atom.flat_index())
|
||||
}
|
||||
Literal::Char(c) => write!(f, "'{}'", *c as u32),
|
||||
// Literal::Char(c) => write!(f, "'{}'", *c as u32),
|
||||
Literal::CodeIndex(i) => write!(f, "{:x}", i.as_ptr() as u64),
|
||||
Literal::Fixnum(n) => write!(f, "{}", n.get_num()),
|
||||
Literal::Integer(ref n) => write!(f, "{}", n),
|
||||
@@ -667,10 +615,14 @@ impl Literal {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
pub type Var = Rc<String>;
|
||||
|
||||
pub(crate) fn subterm_index(heap: &[HeapCellValue], 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() {
|
||||
@@ -696,11 +648,12 @@ pub enum Term {
|
||||
AnonVar,
|
||||
Clause(Cell<RegType>, Atom, Vec<Term>),
|
||||
Cons(Cell<RegType>, Box<Term>, Box<Term>),
|
||||
Literal(Cell<RegType>, Literal),
|
||||
Literal(Cell<RegType>, HeapCellValue),
|
||||
// Literal(Cell<RegType>, Literal),
|
||||
// PartialString wraps a String in anticipation of it absorbing
|
||||
// other PartialString variants in as_partial_string.
|
||||
PartialString(Cell<RegType>, String, Box<Term>),
|
||||
CompleteString(Cell<RegType>, Atom),
|
||||
PartialString(Cell<RegType>, Rc<String>, Box<Term>),
|
||||
CompleteString(Cell<RegType>, Rc<String>),
|
||||
Var(Cell<VarReg>, VarPtr),
|
||||
}
|
||||
|
||||
@@ -714,8 +667,11 @@ impl Term {
|
||||
|
||||
pub fn name(&self) -> Option<Atom> {
|
||||
match self {
|
||||
&Term::Literal(_, Literal::Atom(ref atom)) | &Term::Clause(_, ref atom, ..) => {
|
||||
Some(*atom)
|
||||
Term::Literal(_, cell) => {
|
||||
cell.to_atom()
|
||||
}
|
||||
&Term::Clause(_, atom, ..) => {
|
||||
Some(atom)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
@@ -760,11 +716,11 @@ pub fn unfold_by_str(mut term: Term, s: Atom) -> Vec<Term> {
|
||||
*/
|
||||
|
||||
pub(crate) fn fetch_index_ptr(
|
||||
heap: &[HeapCellValue],
|
||||
heap: &impl SizedHeap,
|
||||
arity: usize,
|
||||
term_loc: usize,
|
||||
) -> Option<CodeIndex> {
|
||||
if term_loc + arity + 1 >= heap.len() {
|
||||
if term_loc + arity + 1 >= heap.cell_len() || heap.pstr_at(term_loc + arity + 1) {
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -784,7 +740,7 @@ pub(crate) fn fetch_index_ptr(
|
||||
}
|
||||
|
||||
pub(crate) fn blunt_index_ptr(
|
||||
heap: &mut [HeapCellValue],
|
||||
heap: &mut impl SizedHeapMut,
|
||||
key: PredicateKey,
|
||||
term_loc: usize,
|
||||
) -> bool {
|
||||
@@ -797,7 +753,7 @@ pub(crate) fn blunt_index_ptr(
|
||||
}
|
||||
|
||||
pub(crate) fn unfold_by_str_once(
|
||||
heap: &mut [HeapCellValue],
|
||||
heap: &mut impl SizedHeapMut,
|
||||
start_term: HeapCellValue,
|
||||
atom: Atom,
|
||||
) -> Option<usize> {
|
||||
@@ -821,7 +777,7 @@ pub(crate) fn unfold_by_str_once(
|
||||
}
|
||||
|
||||
pub fn unfold_by_str(
|
||||
heap: &mut [HeapCellValue],
|
||||
heap: &mut impl SizedHeapMut,
|
||||
mut start_term: HeapCellValue,
|
||||
atom: Atom,
|
||||
) -> Vec<HeapCellValue> {
|
||||
@@ -862,7 +818,7 @@ pub fn unfold_by_str_locs(
|
||||
*/
|
||||
|
||||
pub fn unfold_by_str_locs(
|
||||
heap: &mut [HeapCellValue],
|
||||
heap: &mut impl SizedHeapMut,
|
||||
mut term_loc: usize,
|
||||
atom: Atom,
|
||||
) -> Vec<(HeapCellValue, usize)> {
|
||||
@@ -880,11 +836,14 @@ pub fn unfold_by_str_locs(
|
||||
terms
|
||||
}
|
||||
|
||||
pub fn term_name(heap: &[HeapCellValue], mut term_loc: usize) -> Option<Atom> {
|
||||
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)) => {
|
||||
return Some(name);
|
||||
(HeapCellValueTag::Atom, (name, arity)) => {
|
||||
return Some((name, arity));
|
||||
}
|
||||
(HeapCellValueTag::Str, s) => {
|
||||
term_loc = s;
|
||||
@@ -903,32 +862,6 @@ pub fn term_name(heap: &[HeapCellValue], mut term_loc: usize) -> Option<Atom> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn term_arity(heap: &[HeapCellValue], mut term_loc: usize) -> usize {
|
||||
loop {
|
||||
read_heap_cell!(heap[term_loc],
|
||||
(HeapCellValueTag::Atom, (_name, arity)) => {
|
||||
return arity;
|
||||
}
|
||||
(HeapCellValueTag::Str, s) => {
|
||||
term_loc = s;
|
||||
}
|
||||
(HeapCellValueTag::Lis) => {
|
||||
return 2;
|
||||
}
|
||||
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
|
||||
if h != term_loc {
|
||||
term_loc = h;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return 0;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inverse_var_locs_from_iter<I: Iterator<Item = HeapCellValue>>(iter: I) -> InverseVarLocs {
|
||||
let mut occurrence_set: IndexMap<HeapCellValue, usize, FxBuildHasher> =
|
||||
IndexMap::with_hasher(FxBuildHasher::default());
|
||||
@@ -975,7 +908,7 @@ pub fn term_deref(heap: &[HeapCellValue], mut term_loc: usize) -> HeapCellValue
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn term_nth_arg(heap: &[HeapCellValue], mut term_loc: usize, n: usize) -> Option<usize> {
|
||||
pub fn term_nth_arg(heap: &impl SizedHeap, mut term_loc: usize, n: usize) -> Option<usize> {
|
||||
loop {
|
||||
read_heap_cell!(heap[term_loc],
|
||||
(HeapCellValueTag::Str, s) => {
|
||||
@@ -1015,108 +948,55 @@ pub fn term_nth_arg(heap: &[HeapCellValue], mut term_loc: usize, n: usize) -> Op
|
||||
}
|
||||
}
|
||||
|
||||
pub type VarLocs = IndexMap<Var, HeapCellValue, FxBuildHasher>;
|
||||
pub type InverseVarLocs = IndexMap<usize, Var, FxBuildHasher>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FocusedHeap {
|
||||
pub heap: Vec<HeapCellValue>,
|
||||
pub struct TermWriteResult {
|
||||
pub focus: usize,
|
||||
pub inverse_var_locs: InverseVarLocs,
|
||||
}
|
||||
|
||||
impl FocusedHeap {
|
||||
pub fn empty() -> Self {
|
||||
Self {
|
||||
heap: vec![],
|
||||
focus: 0,
|
||||
inverse_var_locs: InverseVarLocs::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn copy_term_from_machine_heap(
|
||||
&mut self,
|
||||
machine_st: &mut MachineState,
|
||||
cell: HeapCellValue,
|
||||
) {
|
||||
let hb = machine_st.heap.len();
|
||||
|
||||
copy_term(
|
||||
CopyBallTerm::new(
|
||||
&mut machine_st.attr_var_init.attr_var_queue,
|
||||
&mut machine_st.stack,
|
||||
&mut machine_st.heap,
|
||||
&mut self.heap,
|
||||
),
|
||||
cell,
|
||||
AttrVarPolicy::DeepCopy,
|
||||
);
|
||||
|
||||
for cell in self.heap.iter_mut() {
|
||||
*cell = *cell - hb;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_ref_mut(&mut self, focus: usize) -> FocusedHeapRefMut {
|
||||
FocusedHeapRefMut {
|
||||
heap: &mut self.heap,
|
||||
focus,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deref_loc(&self, term_loc: usize) -> HeapCellValue {
|
||||
use crate::machine::heap::*;
|
||||
|
||||
let cell = self.heap[term_loc];
|
||||
heap_bound_store(&self.heap, heap_bound_deref(&self.heap, cell))
|
||||
}
|
||||
|
||||
pub fn name(&self, term_loc: usize) -> Option<Atom> {
|
||||
term_name(&self.heap, term_loc)
|
||||
}
|
||||
|
||||
pub fn arity(&self, term_loc: usize) -> usize {
|
||||
term_arity(&self.heap, term_loc)
|
||||
}
|
||||
|
||||
pub fn nth_arg(&self, term_loc: usize, n: usize) -> Option<usize> {
|
||||
term_nth_arg(&self.heap, term_loc, n)
|
||||
}
|
||||
}
|
||||
pub type VarLocs = IndexMap<Var, HeapCellValue, FxBuildHasher>;
|
||||
pub type InverseVarLocs = IndexMap<usize, Var, FxBuildHasher>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FocusedHeapRefMut<'a> {
|
||||
pub heap: &'a mut Vec<HeapCellValue>,
|
||||
pub heap: &'a mut Heap,
|
||||
pub focus: usize,
|
||||
}
|
||||
|
||||
impl<'a> FocusedHeapRefMut<'a> {
|
||||
pub fn name(&self, term_loc: usize) -> Option<Atom> {
|
||||
term_name(&self.heap, term_loc)
|
||||
#[inline]
|
||||
pub fn from(heap: &'a mut Heap, focus: usize) -> Self {
|
||||
Self { heap, focus }
|
||||
}
|
||||
|
||||
pub fn predicate_key(&self, term_loc: usize) -> Option<PredicateKey> {
|
||||
term_predicate_key(self.heap, term_loc)
|
||||
}
|
||||
|
||||
pub fn arity(&self, term_loc: usize) -> usize {
|
||||
term_arity(&self.heap, term_loc)
|
||||
self.predicate_key(term_loc)
|
||||
.map(|(_, arity)| arity)
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn deref_loc(&self, term_loc: usize) -> HeapCellValue {
|
||||
use crate::machine::heap::*;
|
||||
|
||||
let cell = self.heap[term_loc];
|
||||
heap_bound_store(&self.heap, heap_bound_deref(&self.heap, cell))
|
||||
heap_bound_store(self.heap, heap_bound_deref(self.heap, cell))
|
||||
}
|
||||
|
||||
pub fn nth_arg(&self, term_loc: usize, n: usize) -> Option<usize> {
|
||||
term_nth_arg(self.heap, term_loc, n)
|
||||
}
|
||||
|
||||
pub fn from_cell(heap: &'a mut Vec<HeapCellValue>, cell: HeapCellValue) -> Self {
|
||||
/*
|
||||
pub fn from_cell(heap: &'a mut Heap, cell: HeapCellValue) -> Self {
|
||||
let focus = read_heap_cell!(cell,
|
||||
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
|
||||
h
|
||||
}
|
||||
_ => {
|
||||
let h = heap.len();
|
||||
heap.push(cell);
|
||||
heap.push_cell(cell).unwrap();
|
||||
|
||||
h
|
||||
}
|
||||
@@ -1124,4 +1004,5 @@ impl<'a> FocusedHeapRefMut<'a> {
|
||||
|
||||
Self { heap, focus }
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user