add redone partial strings (#24, #95)

This commit is contained in:
Mark Thom
2020-02-19 21:34:09 -07:00
parent 617f803355
commit 0457b38e41
16 changed files with 1422 additions and 290 deletions

View File

@@ -3,6 +3,7 @@ use core::marker::PhantomData;
use crate::prolog_parser::ast::*;
use crate::prolog::machine::machine_indices::*;
use crate::prolog::machine::partial_string::*;
use crate::prolog::machine::raw_block::*;
use std::mem;
@@ -149,12 +150,93 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
#[inline]
pub(crate)
fn take<U: RawBlockTraits>(&mut self) -> HeapTemplate<U> {
unsafe {
HeapTemplate {
buf: mem::transmute::<RawBlock<T>, RawBlock<U>>(self.buf.take()),
_marker: PhantomData,
fn allocate_pstr(&mut self, mut src: &str) -> Option<Addr> {
let orig_h = self.h();
loop {
if src == "" {
return if orig_h == self.h() {
None
} else {
let prev_h = self.h() - 1;
match &mut self[prev_h] {
HeapCellValue::PartialString(ref mut pstr) => {
let s = pstr.block_as_str();
pstr.tail = Addr::PStrTail(prev_h, s.len());
}
_ => {
unreachable!()
}
}
Some(Addr::PStrLocation(orig_h, 0))
};
}
let h = self.h();
let (mut pstr, rest_src) =
match PartialString::new(src, h) {
Some(tuple) => {
tuple
}
None => {
if src.len() > '\u{0}'.len_utf8() {
src = &src['\u{0}'.len_utf8() ..];
continue;
} else if orig_h == h {
return None;
} else {
let prev_h = h - 1;
match &mut self[prev_h] {
HeapCellValue::PartialString(ref mut pstr) => {
let s = pstr.block_as_str();
pstr.tail = Addr::PStrTail(prev_h, s.len());
}
_ => {
unreachable!()
}
}
return Some(Addr::PStrLocation(orig_h, 0));
}
}
};
let new_top = unsafe {
self.buf.new_block(mem::size_of::<HeapCellValue>())
};
if rest_src != "" {
pstr.tail = Addr::PStrLocation(h+1, 0);
src = rest_src;
} else {
pstr.tail = Addr::PStrTail(h, src.len());
}
unsafe{
ptr::write(
self.buf.top as *mut _,
HeapCellValue::PartialString(pstr),
);
}
self.buf.top = new_top;
if rest_src == "" {
return Some(Addr::PStrLocation(orig_h, 0));
}
}
}
#[inline]
pub(crate)
fn take(&mut self) -> Self {
HeapTemplate {
buf: self.buf.take(),
_marker: PhantomData,
}
}