and_stack: AndStack::new(),
or_stack: OrStack::new(),
registers: vec![Addr::HeapCell(0); MAX_ARITY + 1], // self.registers[0] is never used.
- trail: Vec::new(),
+ trail: vec![],
+ partial_string_trail: vec![],
tr: 0,
hb: 0,
block: 0,
let mut output = printer.print(addr);
let bad_ending = format!("= {}", &var);
-
+
if output.ends_with(&bad_ending) {
output.truncate(orig_len);
}
self.fail = true;
},
(Addr::Lis(a1), Addr::Con(Constant::String(ref mut s)))
- | (Addr::Con(Constant::String(ref mut s)), Addr::Lis(a1))
+ | (Addr::Con(Constant::String(ref mut s)), Addr::Lis(a1))
if self.flags.double_quotes.is_chars() => {
if let Some(c) = s.head() {
pdl.push(Addr::Con(Constant::String(s.tail())));
self.fail = true;
},
(Addr::Con(Constant::EmptyList), Addr::Con(Constant::String(ref s)))
- | (Addr::Con(Constant::String(ref s)), Addr::Con(Constant::EmptyList))
+ | (Addr::Con(Constant::String(ref s)), Addr::Con(Constant::EmptyList))
if self.flags.double_quotes.is_chars() => {
if s.is_expandable() && s.is_empty() {
s.set_non_expandable();
pdl.push(Addr::HeapCell(a1 + 1));
pdl.push(Addr::HeapCell(a2 + 1));
},
- (Addr::Con(Constant::String(ref mut s1)), Addr::Con(Constant::String(ref mut s2))) => {
+ (Addr::Con(Constant::String(ref mut s1)),
+ Addr::Con(Constant::String(ref mut s2))) => {
let mut stepper = |s1: &mut StringList, s2: &mut StringList| -> bool {
if let Some(c1) = s1.head() {
if let Some(c2) = s2.head() {
}
}
}
-
+
fn trail(&mut self, r: Ref) {
match r {
Ref::HeapCell(hc) =>
match tr_i {
Ref::HeapCell(tr_i) =>
- if tr_i < hb { //|| ((h < tr_i) && tr_i < b) {
+ if tr_i < hb {
i += 1;
} else {
let tr = self.tr;
}
}
+ #[inline]
+ fn write_char_to_string(&mut self, s: &mut StringList, c: char) -> bool {
+ let new_s = s.push_char(c);
+ self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::String(new_s))));
+ false
+ }
+
pub(super) fn write_constant_to_var(&mut self, addr: Addr, c: Constant) {
match self.store(self.deref(addr)) {
Addr::HeapCell(hc) => {
false
},
Constant::String(s2) => *s != s2,
+ Constant::Atom(ref a, _) if s.is_empty() && s.is_expandable() =>
+ if let Some(c) = a.as_str().chars().next() {
+ if c.len_utf8() == a.as_str().len() {
+ self.write_char_to_string(s, c)
+ } else {
+ true
+ }
+ } else {
+ true
+ },
+ Constant::Char(ref c) if s.is_empty() && s.is_expandable() =>
+ self.write_char_to_string(s, *c),
_ => true
},
- Addr::Con(c1) => {
+ Addr::Con(c1) =>
if c1 != c {
self.fail = true;
- }
- },
+ },
_ => self.fail = true
};
}
return Ordering::Greater,
(HeapCellValue::Addr(Addr::Con(Constant::String(_))),
HeapCellValue::Addr(Addr::Con(Constant::Number(_)))) =>
- return Ordering::Greater,
+ return Ordering::Greater,
(HeapCellValue::Addr(Addr::Con(Constant::String(s1))),
HeapCellValue::Addr(Addr::Con(Constant::String(s2)))) =>
return if s1.is_expandable() {
self.p += 1;
}
-
+
fn handle_call_clause<'a>(&mut self, indices: MachineCodeIndices<'a>,
call_policy: &mut Box<CallPolicy>,
cut_policy: &mut Box<CutPolicy>,
&ControlInstruction::Allocate(num_cells) =>
self.allocate(num_cells),
&ControlInstruction::CallClause(ref ct, arity, _, lco, use_default_cp) =>
- self.handle_call_clause(indices, call_policy, cut_policy,
+ self.handle_call_clause(indices, call_policy, cut_policy,
ct, arity, lco, use_default_cp),
&ControlInstruction::Deallocate => self.deallocate(),
&ControlInstruction::JmpBy(arity, offset, _, lco) => {
self.p += 1;
},
&CutInstruction::GetLevelAndUnify(r) => {
- // let b0 = Addr::Con(Constant::Usize(self.b0));
let b0 = self[perm_v!(1)].clone();
let a = self[r].clone();
self.fail = false;
self.trail.clear();
+ self.partial_string_trail.clear();
self.heap.clear();
self.mode = MachineMode::Write;
self.and_stack.clear();
assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), X @> \"abc\".");
assert_prolog_failure!(&mut wam, "?- partial_string(\"abc\", X), X \\=@= \"abc\".");
assert_prolog_failure!(&mut wam, "?- partial_string(\"abc\", X), X @< \"abc\".");
+
+ assert_prolog_success!(&mut wam, "?- partial_string(\"ab\", X), matcher(X, Y), Y = [a,b|V],
+ matcher(Y, Z), is_partial_string(Y).",
+ [["V = [c | _]", "X = [a, b, c, a, b, c | _]", "Y = [a, b, c | _]", "Z = _"]]);
+ assert_prolog_success!(&mut wam, "?- partial_string(\"a\", X), matcher(X, Y).",
+ [["X = [a, b, c | _]", "Y = _"]]);
+ assert_prolog_success!(&mut wam, "?- partial_string(\"a\", X), matcher(X, Y), is_partial_string(Y).",
+ [["X = [a, b, c | _]", "Y = _"]]);
+ assert_prolog_success!(&mut wam, "?- partial_string(\"a\", X), matcher(X, Y), Y = \"def\".",
+ [["X = [a, b, c, d, e, f]", "Y = [d, e, f]"]]);
}