initial commit for merge

This commit is contained in:
Mark Thom
2020-03-26 22:01:23 -06:00
parent 121c8d8a48
commit 194e5dc94e
25 changed files with 5077 additions and 3280 deletions

View File

@@ -1,26 +1,11 @@
use crate::prolog::machine::raw_block::*;
use std::alloc;
use std::mem;
use std::ptr;
use std::slice;
use std::ops::{Range, RangeFrom};
use std::str;
pub(crate) struct PartialStringTraits {}
impl RawBlockTraits for PartialStringTraits {
#[inline]
fn init_size() -> usize {
0
}
#[inline]
fn align() -> usize {
mem::align_of::<char>()
}
}
pub struct PartialString {
pub(super) buf: RawBlock<PartialStringTraits>,
buf: *const u8,
}
impl Clone for PartialString {
@@ -30,17 +15,10 @@ impl Clone for PartialString {
}
}
impl PartialEq for PartialString {
#[inline]
fn eq(&self, other: &Self) -> bool {
self as *const _ == other as *const _
}
}
fn scan_for_terminator(src: &str) -> usize {
fn scan_for_terminator<Iter: Iterator<Item = char>>(iter: Iter) -> usize {
let mut terminator_idx = 0;
for c in src.chars() {
for c in iter {
if c == '\u{0}' {
break;
}
@@ -51,11 +29,82 @@ fn scan_for_terminator(src: &str) -> usize {
terminator_idx
}
pub struct PStrIter {
buf: *const u8,
}
impl PStrIter {
#[inline]
fn from(buf: *const u8, idx: usize) -> Self {
PStrIter {
buf: (buf as usize + idx) as *const _
}
}
}
impl Iterator for PStrIter {
type Item = char;
fn next(&mut self) -> Option<Self::Item> {
unsafe {
let b = ptr::read(self.buf);
if b == 0u8 {
return None;
}
let c = ptr::read(self.buf as *const char);
self.buf = self.buf.offset(c.len_utf8() as isize);
Some(c)
}
}
}
pub struct PStrIterBounded {
buf: *const u8,
end: *const u8,
}
impl PStrIterBounded {
#[inline]
fn from(buf: *const u8, start: usize, end: usize) -> Self {
PStrIterBounded {
buf: (buf as usize + start) as *const _,
end: (buf as usize + end) as *const _,
}
}
}
impl Iterator for PStrIterBounded {
type Item = char;
fn next(&mut self) -> Option<Self::Item> {
unsafe {
if self.buf >= self.end {
return None;
}
let b = ptr::read(self.buf);
if b == 0u8 {
return None;
}
let c = ptr::read(self.buf as *const char);
self.buf = self.buf.offset(c.len_utf8() as isize);
Some(c)
}
}
}
impl PartialString {
#[inline]
pub(super)
fn new(src: &str) -> Option<(Self, &str)> {
let pstr = PartialString {
buf: RawBlock::with_capacity(src.len() + '\u{0}'.len_utf8()),
buf: ptr::null_mut(),
};
unsafe {
@@ -63,22 +112,34 @@ impl PartialString {
}
}
#[inline]
pub(super)
fn empty() -> Self {
PartialString {
buf: "\u{0}".as_bytes()[0] as *const _,
}
}
unsafe fn append_chars(mut self, src: &str) -> Option<(Self, &str)> {
let terminator_idx = scan_for_terminator(src);
let terminator_idx = scan_for_terminator(src.chars());
if terminator_idx == 0 {
return None;
}
let new_top = self.buf.new_block(terminator_idx + '\u{0}'.len_utf8());
let layout = alloc::Layout::from_size_align_unchecked(
src.len() + '\u{0}'.len_utf8(),
mem::align_of::<u8>(),
);
self.buf = alloc::alloc(layout) as *const _;
ptr::copy(
src.as_ptr(),
self.buf.top as *mut _,
self.buf as *mut _,
terminator_idx,
);
self.buf.top = (new_top as usize - '\u{0}'.len_utf8()) as *const _;
self.write_terminator_at(terminator_idx);
Some(if terminator_idx != src.len() {
@@ -88,26 +149,40 @@ impl PartialString {
})
}
#[inline]
pub(crate)
fn iter(&self) -> PStrIter {
PStrIter {
buf: self.buf,
}
}
pub(super)
fn clone_from_offset(&self, n: usize) -> Self {
let mut pstr = PartialString {
buf: RawBlock::with_capacity(self.len() + '\u{0}'.len_utf8()),
buf: ptr::null_mut(),
};
unsafe {
let len = if self.len() > n { self.len() - n } else { 0 };
let new_top = pstr.buf.new_block(len + '\u{0}'.len_utf8());
let len = scan_for_terminator(self.range_from(0 ..));
let len = if len > n { len - n } else { 0 };
let layout = alloc::Layout::from_size_align_unchecked(
len + '\u{0}'.len_utf8(),
mem::align_of::<u8>(),
);
pstr.buf = alloc::alloc(layout);
if len > 0 {
ptr::copy(
(self.buf.base as usize + n) as *mut u8,
pstr.buf.base as *mut _,
(self.buf as usize + n) as *const u8,
pstr.buf as *mut _,
len,
);
}
pstr.write_terminator_at(len);
pstr.buf.top = (new_top as usize - '\u{0}'.len_utf8()) as *const _;
}
pstr
@@ -118,23 +193,26 @@ impl PartialString {
fn write_terminator_at(&mut self, index: usize) {
unsafe {
ptr::write(
(self.buf.base as usize + index) as *mut u8,
(self.buf as usize + index) as *mut u8,
0u8,
);
}
}
#[inline]
pub(crate)
fn block_as_str(&self) -> &str {
unsafe {
let slice = slice::from_raw_parts(self.buf.base, self.len());
str::from_utf8(slice).unwrap()
}
pub fn range(&self, index: Range<usize>) -> PStrIterBounded {
PStrIterBounded::from(self.buf, index.start, index.end)
}
#[inline]
pub fn len(&self) -> usize {
self.buf.top as usize - self.buf.base as usize
pub fn range_from(&self, index: RangeFrom<usize>) -> PStrIter {
PStrIter::from(self.buf, index.start)
}
#[inline]
pub fn at_end(&self, end_n: usize) -> bool {
unsafe {
ptr::read((self.buf as usize + end_n) as *const u8) == 0u8
}
}
}