trie_get_all_values/2 % +Trie, -Value
]).
+:- use_module(library(format)).
+
:- use_module(library(assoc)).
:- use_module(library(atts)).
:- use_module(library(lists)).
fn copy_partial_string(&mut self, scan_tag: HeapCellValueTag, pstr_loc: usize) {
read_heap_cell!(self.target[pstr_loc],
(HeapCellValueTag::PStrLoc, h) => {
- if h >= self.old_h {
- *self.value_at_scan() = match scan_tag {
- HeapCellValueTag::PStrLoc => {
- pstr_loc_as_cell!(h)
- }
- tag => {
- debug_assert!(tag == HeapCellValueTag::PStrOffset);
- pstr_offset_as_cell!(h)
- }
- };
+ debug_assert!(h >= self.old_h);
- self.scan += 1;
- return;
- }
+ *self.value_at_scan() = match scan_tag {
+ HeapCellValueTag::PStrLoc => {
+ pstr_loc_as_cell!(h)
+ }
+ tag => {
+ debug_assert_eq!(tag, HeapCellValueTag::PStrOffset);
+ pstr_offset_as_cell!(h)
+ }
+ };
+
+ self.scan += 1;
+ return;
+ }
+ (HeapCellValueTag::Var, h) => {
+ debug_assert!(h >= self.old_h);
+ debug_assert_eq!(scan_tag, HeapCellValueTag::PStrOffset);
+
+ *self.value_at_scan() = pstr_offset_as_cell!(h);
+ self.scan += 1;
+
+ return;
}
_ => {}
);
let threshold = self.target.threshold();
- *self.value_at_scan() = pstr_loc_as_cell!(threshold);
- self.scan += 1;
+ let replacement = read_heap_cell!(self.target[pstr_loc],
+ (HeapCellValueTag::CStr) => {
+ debug_assert_eq!(scan_tag, HeapCellValueTag::PStrOffset);
- self.target.push(self.target[pstr_loc]);
+ *self.value_at_scan() = pstr_offset_as_cell!(threshold);
+ self.target.push(self.target[pstr_loc]);
- let replacement = pstr_loc_as_cell!(threshold);
- let trail_item = mem::replace(&mut self.target[pstr_loc], replacement);
+ heap_loc_as_cell!(threshold)
+ }
+ _ => {
+ *self.value_at_scan() = if scan_tag == HeapCellValueTag::PStrLoc {
+ pstr_loc_as_cell!(threshold)
+ } else {
+ debug_assert_eq!(scan_tag, HeapCellValueTag::PStrOffset);
+ pstr_offset_as_cell!(threshold)
+ };
+
+ self.target.push(self.target[pstr_loc]);
+ self.target.push(self.target[pstr_loc + 1]);
+ pstr_loc_as_cell!(threshold)
+ }
+ );
+
+ self.scan += 1;
+
+ let trail_item = mem::replace(&mut self.target[pstr_loc], replacement);
self.trail.push((Ref::heap_cell(pstr_loc), trail_item));
- self.target.push(self.target[pstr_loc + 1]);
}
fn reinstantiate_var(&mut self, addr: HeapCellValue, frontier: usize) {
read_heap_cell!(ra,
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
if h >= self.old_h {
- *self.value_at_scan() = rd;
+ *self.value_at_scan() = ra;
self.scan += 1;
return;
} else {
let offset = (offset + c.len_utf8()) as i64;
let h_len = self.heap.len();
+ let pstr_atom: Atom = pstr.into();
- self.heap.push(pstr_offset_as_cell!(h_len));
- self.heap.push(fixnum_as_cell!(Fixnum::build_with(offset)));
+ if pstr_atom.len() > offset as usize {
+ self.heap.push(pstr_offset_as_cell!(h));
+ self.heap.push(fixnum_as_cell!(Fixnum::build_with(offset)));
- unify_fn!(self, pstr_loc_as_cell!(h_len), a3);
+ unify_fn!(self, pstr_loc_as_cell!(h_len), a3);
+ } else {
+ match self.heap[h].get_tag() {
+ HeapCellValueTag::CStr => {
+ self.unify_atom(atom!("[]"), self.store(self.deref(a3)));
+ }
+ HeapCellValueTag::PStr => {
+ unify_fn!(self, self.heap[h+1], a3);
+ }
+ _ => {
+ unreachable!();
+ }
+ }
+ }
}
} else {
unreachable!()
self.fail = true;
}
}
+ (HeapCellValueTag::CStr, cstr_atom) => {
+ let cstr = PartialString::from(cstr_atom);
+
+ if let Some(c) = cstr.as_str_from(0).chars().next() {
+ if n == 1 {
+ self.unify_char(c, self.store(self.deref(self.registers[3])));
+ } else if n == 2 {
+ let offset = c.len_utf8() as i64;
+ let h_len = self.heap.len();
+
+ if cstr_atom.len() > offset as usize {
+ self.heap.push(atom_as_cstr_cell!(cstr_atom));
+ self.heap.push(pstr_offset_as_cell!(h_len));
+ self.heap.push(fixnum_as_cell!(Fixnum::build_with(offset)));
+
+ unify_fn!(self, pstr_loc_as_cell!(h_len+1), self.registers[3]);
+ } else {
+ self.unify_atom(atom!("[]"), self.store(self.deref(self.registers[3])));
+ }
+ } else {
+ self.fail = true;
+ }
+ } else {
+ unreachable!()
+ }
+ }
_ => {
// 8.5.2.3 d)
let err = self.type_error(ValidType::Compound, term);
let (name, arity) = cell_as_atom_cell!(self.heap[s]).get_name_and_arity();
self.try_functor_compound_case(name, arity);
}
- (HeapCellValueTag::Lis | HeapCellValueTag::PStrOffset) => {
+ (HeapCellValueTag::Lis | HeapCellValueTag::PStrLoc | HeapCellValueTag::CStr) => {
self.try_functor_compound_case(atom!("."), 2);
}
(HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar) => {
tag @ HeapCellValueTag::Str |
tag @ HeapCellValueTag::Lis |
tag @ HeapCellValueTag::PStrOffset |
+ tag @ HeapCellValueTag::PStrLoc |
tag @ HeapCellValueTag::Var |
tag @ HeapCellValueTag::AttrVar => {
HeapCellValue::build_with(tag, (self.get_value() + rhs.abs() as usize) as u64)