From: Mark Thom Date: Tue, 19 May 2020 05:45:21 +0000 (-0600) Subject: accomodate \0\ in partial strings, print null as \0\ (#267, #526), update prolog... X-Git-Tag: v0.8.123~15 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=e0e3b180e783f6e1e81d6867b59852216a0d3e51;p=scryer-prolog.git accomodate \0\ in partial strings, print null as \0\ (#267, #526), update prolog parser, version bump --- diff --git a/Cargo.lock b/Cargo.lock index be47e095..5af43295 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -606,9 +606,9 @@ dependencies = [ [[package]] name = "prolog_parser" -version = "0.8.58" +version = "0.8.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e90d34a4268bf5256d4e55f8ec920220aa96dc7ee779441b32f97635cba72aa9" +checksum = "029a4682cf40923b8eb05c4b943d1d6be73775e7bf80bcb0866b5ef29abb0802" dependencies = [ "lexical", "num-rug-adapter", @@ -740,7 +740,7 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "scryer-prolog" -version = "0.8.122" +version = "0.8.123" dependencies = [ "cpu-time", "crossterm", diff --git a/Cargo.toml b/Cargo.toml index e8f52cd7..3f48283c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "scryer-prolog" -version = "0.8.122" +version = "0.8.123" authors = ["Mark Thom "] build = "build.rs" repository = "https://github.com/mthom/scryer-prolog" @@ -29,7 +29,7 @@ libc = "0.2.62" nix = "0.15.0" num-rug-adapter = { optional = true, version = "0.1.3" } ordered-float = "0.5.0" -prolog_parser = { version = "0.8.58", default-features = false } +prolog_parser = { version = "0.8.59", default-features = false } ref_thread_local = "0.0.0" rug = { version = "1.4.0", optional = true } rustyline = "6.0.0" diff --git a/src/prolog/heap_print.rs b/src/prolog/heap_print.rs index ca462e02..ee92ff0c 100644 --- a/src/prolog/heap_print.rs +++ b/src/prolog/heap_print.rs @@ -160,7 +160,7 @@ fn char_to_string(is_quoted: bool, c: char) -> String { '\u{d8}' ..= '\u{f6}' => c.to_string(), '\u{f8}' ..= '\u{74f}' => c.to_string(), '\x20' ..= '\x7e' => c.to_string(), - _ => format!("\\x{:x}\\", c as u32), + _ => format!("\\{:x}\\", c as u32), } } diff --git a/src/prolog/machine/heap.rs b/src/prolog/machine/heap.rs index 68d4a2f9..91639423 100644 --- a/src/prolog/machine/heap.rs +++ b/src/prolog/machine/heap.rs @@ -189,6 +189,10 @@ impl HeapTemplate { #[inline] pub(crate) fn put_complete_string(&mut self, s: &str) -> Addr { + if s.is_empty() { + return Addr::EmptyList; + } + let addr = self.allocate_pstr(s); self.pop(); @@ -316,20 +320,7 @@ impl HeapTemplate { pub(crate) fn allocate_pstr(&mut self, src: &str) -> Addr { self.write_pstr(src) - .unwrap_or_else(|| { - let h = self.h(); - - self.push(HeapCellValue::PartialString( - PartialString::empty(), - true, - )); - - self.push(HeapCellValue::Addr( - Addr::HeapCell(h + 1) - )); - - Addr::PStrLocation(h, 0) - }) + .unwrap_or_else(|| Addr::EmptyList) } #[inline] diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index ec06f9fc..a26c4cde 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -1492,9 +1492,13 @@ impl MachineState { &QueryInstruction::PutPartialString(_, ref string, reg, has_tail) => { let pstr_addr = if has_tail { - let pstr_addr = self.heap.allocate_pstr(&string); - self.heap.pop(); // the tail will be added by the next instruction. - pstr_addr + if !string.is_empty() { + let pstr_addr = self.heap.allocate_pstr(&string); + self.heap.pop(); // the tail will be added by the next instruction. + pstr_addr + } else { + Addr::EmptyList + } } else { self.heap.put_complete_string(&string) }; diff --git a/src/prolog/machine/partial_string.rs b/src/prolog/machine/partial_string.rs index 2d821ac4..1413b37c 100644 --- a/src/prolog/machine/partial_string.rs +++ b/src/prolog/machine/partial_string.rs @@ -37,8 +37,8 @@ fn scan_for_terminator>(iter: Iter) -> usize { let mut terminator_idx = 0; for c in iter { - if c == '\u{0}' { - break; + if c == '\u{0}' && terminator_idx != 0 { + return terminator_idx; } terminator_idx += c.len_utf8(); @@ -98,37 +98,9 @@ impl PartialString { } } - #[inline] - pub(super) - fn empty() -> Self { - let mut pstr = PartialString { - buf: ptr::null(), - len: 0, - _marker: PhantomData, - }; - - unsafe { - let layout = alloc::Layout::from_size_align_unchecked( - '\u{0}'.len_utf8(), - mem::align_of::(), - ); - - pstr.buf = alloc::alloc(layout) as *const _; - pstr.len = '\u{0}'.len_utf8(); - - pstr.write_terminator_at(0); - } - - pstr - } - unsafe fn append_chars(mut self, src: &str) -> Option<(Self, &str)> { let terminator_idx = scan_for_terminator(src.chars()); - if terminator_idx == 0 { - return None; - } - let layout = alloc::Layout::from_size_align_unchecked( terminator_idx + '\u{0}'.len_utf8(), mem::align_of::(), @@ -145,8 +117,8 @@ impl PartialString { self.write_terminator_at(terminator_idx); - Some(if terminator_idx != src.len() { - (self, &src[terminator_idx + '\u{0}'.len_utf8() ..]) + Some(if terminator_idx != src.as_bytes().len() { + (self, &src[terminator_idx ..]) } else { (self, "") }) @@ -211,9 +183,7 @@ impl PartialString { #[inline] pub fn at_end(&self, end_n: usize) -> bool { - unsafe { - ptr::read((self.buf as usize + end_n) as *const u8) == 0u8 - } + end_n + 1 == self.len } #[inline] diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index 47b36012..6160e7dd 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -1110,6 +1110,11 @@ impl MachineState { let h = self.heap.h(); + if atom.as_str().is_empty() { + self.fail = true; + return Ok(()); + } + let pstr = self.heap.allocate_pstr(atom.as_str()); let pstr_tail = self.heap[h + 1].as_addr(h + 1);