)),
}?,
Term::Literal(cell, cons) => TermIterState::Literal(Level::Shallow, cell, cons),
- Term::Cons(..) | Term::PartialString(..) => {
+ Term::Cons(..) | Term::PartialString(..) | Term::CompleteString(..) => {
return Err(ArithmeticError::NonEvaluableFunctor(
Literal::Atom(atom!(".")),
2,
}
&Term::Cons(ref cell, ..) |
&Term::Clause(ref cell, ..) |
- Term::PartialString(ref cell, ..) => {
+ Term::PartialString(ref cell, ..) |
+ Term::CompleteString(ref cell, ..) => {
self.marker.mark_non_var::<Target>(Level::Deep, term_loc, cell, target);
target.push(Target::clause_arg_to_instr(cell.get()));
}
}
TermRef::PartialString(lvl, cell, string, tail) => {
self.marker.mark_non_var::<Target>(lvl, term_loc, cell, &mut target);
+ let atom = self.atom_tbl.build_with(&string);
- if let Some(tail) = tail {
- target.push(Target::to_pstr(lvl, string, cell.get(), true));
- self.subterm_to_instr::<Target>(tail, term_loc, is_exposed, &mut target);
- } else {
- target.push(Target::to_pstr(lvl, string, cell.get(), false));
- }
+ target.push(Target::to_pstr(lvl, atom, cell.get(), true));
+ self.subterm_to_instr::<Target>(tail, term_loc, is_exposed, &mut target);
+ }
+ TermRef::CompleteString(lvl, cell, atom) => {
+ self.marker.mark_non_var::<Target>(lvl, term_loc, cell, &mut target);
+ target.push(Target::to_pstr(lvl, atom, cell.get(), false));
}
TermRef::Var(lvl @ Level::Shallow, cell, ref var) if var.as_str() == "!" => {
if self.marker.is_unbound(var.clone()) {
&Term::AnonVar |
&Term::Clause(..) |
&Term::Cons(..) |
- &Term::PartialString(..) => {
+ &Term::PartialString(..) |
+ &Term::CompleteString(..) => {
code.push(instr!("$fail", 0));
}
&Term::Literal(_, Literal::String(_)) => {
&Term::Clause(..) |
&Term::Cons(..) |
&Term::PartialString(..) |
+ &Term::CompleteString(..) |
&Term::Literal(_, Literal::String(..)) => {
code.push(instr!("$succeed", 0));
}
&Term::Literal(..) |
&Term::Clause(..) |
&Term::Cons(..) |
- &Term::PartialString(..) => {
+ &Term::PartialString(..) |
+ &Term::CompleteString(..) => {
code.push(instr!("$fail", 0));
}
&Term::AnonVar => {
Cons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
Literal(Level, &'a Cell<RegType>, &'a Literal),
Clause(Level, &'a Cell<RegType>, ClauseType, &'a Vec<Term>),
- PartialString(Level, &'a Cell<RegType>, Atom, &'a Option<Box<Term>>),
+ PartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>),
+ CompleteString(Level, &'a Cell<RegType>, Atom),
Var(Level, &'a Cell<VarReg>, Rc<String>),
}
| TermRef::Cons(lvl, ..)
| TermRef::Literal(lvl, ..)
| TermRef::Var(lvl, ..)
- | TermRef::Clause(lvl, ..) => lvl,
- TermRef::PartialString(lvl, ..) => lvl,
+ | TermRef::Clause(lvl, ..)
+ | TermRef::CompleteString(lvl, ..)
+ | TermRef::PartialString(lvl, ..) => lvl,
}
}
}
Clause(Level, usize, &'a Cell<RegType>, ClauseType, &'a Vec<Term>),
InitialCons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
FinalCons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
- InitialPartialString(Level, &'a Cell<RegType>, Atom, &'a Option<Box<Term>>),
- FinalPartialString(Level, &'a Cell<RegType>, Atom, &'a Option<Box<Term>>),
+ InitialPartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>),
+ FinalPartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>),
+ CompleteString(Level, &'a Cell<RegType>, Atom),
Var(Level, &'a Cell<VarReg>, Rc<String>),
}
}
Term::Literal(cell, constant) => TermIterState::Literal(lvl, cell, constant),
Term::PartialString(cell, string_buf, tail) => {
- TermIterState::InitialPartialString(lvl, cell, *string_buf, tail)
+ TermIterState::InitialPartialString(lvl, cell, string_buf, tail)
+ }
+ Term::CompleteString(cell, atom) => {
+ TermIterState::CompleteString(lvl, cell, *atom)
}
Term::Var(cell, var) => TermIterState::Var(lvl, cell, var.clone()),
}
fn from_term(term: &'a Term) -> Self {
let state = match term {
- Term::AnonVar | Term::Cons(..) | Term::Literal(..) | Term::PartialString(..) => {
+ Term::AnonVar | Term::Cons(..) | Term::Literal(..) |
+ Term::PartialString(..) | Term::CompleteString(..) => {
return QueryIterator {
state_stack: vec![],
}
}
TermIterState::InitialPartialString(lvl, cell, string, tail) => {
self.state_stack.push(TermIterState::FinalPartialString(lvl, cell, string, tail));
-
- if let Some(tail) = tail {
- self.push_subterm(lvl.child_level(), tail);
- }
+ self.push_subterm(lvl.child_level(), tail);
}
- TermIterState::FinalPartialString(lvl, cell, string, tail) => {
- return Some(TermRef::PartialString(lvl, cell, string, tail));
+ TermIterState::FinalPartialString(lvl, cell, atom, tail) => {
+ return Some(TermRef::PartialString(lvl, cell, atom, tail));
+ }
+ TermIterState::CompleteString(lvl, cell, atom) => {
+ return Some(TermRef::CompleteString(lvl, cell, atom));
}
TermIterState::FinalCons(lvl, cell, head, tail) => {
return Some(TermRef::Cons(lvl, cell, head, tail));
head.as_ref(),
tail.as_ref(),
)],
- Term::PartialString(cell, string_buf, tail_opt) => {
+ Term::PartialString(cell, string_buf, tail) => {
vec![TermIterState::InitialPartialString(
Level::Root,
cell,
- *string_buf,
- tail_opt,
+ string_buf,
+ tail,
+ )]
+ }
+ Term::CompleteString(cell, atom) => {
+ vec![TermIterState::CompleteString(
+ Level::Root,
+ cell,
+ *atom,
)]
}
Term::Literal(cell, constant) => {
return Some(TermRef::Cons(lvl, cell, head, tail));
}
- TermIterState::InitialPartialString(lvl, cell, string_buf, tail_opt) => {
- if let Some(tail) = tail_opt {
- self.push_subterm(Level::Deep, tail);
- }
-
- return Some(TermRef::PartialString(lvl, cell, string_buf, tail_opt));
+ TermIterState::InitialPartialString(lvl, cell, string_buf, tail) => {
+ self.push_subterm(Level::Deep, tail);
+ return Some(TermRef::PartialString(lvl, cell, string_buf, tail));
+ }
+ TermIterState::CompleteString(lvl, cell, atom) => {
+ return Some(TermRef::CompleteString(lvl, cell, atom));
}
TermIterState::Literal(lvl, cell, constant) => {
return Some(TermRef::Literal(lvl, cell, constant))
]).
:- use_module(library(error)).
+:- use_module(library(iso_ext)).
:- use_module(library(lists), [append/3, member/2]).
:- use_module(library(loader), [strip_module/3]).
read_heap_cell!(addr,
(HeapCellValueTag::Lis) => {
+ use crate::parser::parser::as_partial_string;
+
let tail = term_stack.pop().unwrap();
let head = term_stack.pop().unwrap();
- term_stack.push(Term::Cons(Cell::default(), Box::new(head), Box::new(tail)));
+ match as_partial_string(head, tail) {
+ Ok((string, Some(tail))) => {
+ term_stack.push(Term::PartialString(Cell::default(), string, tail));
+ }
+ Ok((string, None)) => {
+ let atom = machine_st.atom_tbl.build_with(&string);
+ term_stack.push(Term::CompleteString(Cell::default(), atom));
+ }
+ Err(cons_term) => term_stack.push(cons_term),
+ }
}
(HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar, h) => {
let offset_string = format!("_{}", h);
term_stack.push(Term::Clause(Cell::default(), name, subterms));
}
}
- (HeapCellValueTag::PStr, string) => {
+ (HeapCellValueTag::PStr, atom) => {
let tail = term_stack.pop().unwrap();
if let Term::Literal(_, Literal::Atom(atom!("[]"))) = &tail {
- term_stack.push(Term::PartialString(
- Cell::default(),
- string,
- None,
- ));
+ term_stack.push(Term::CompleteString(Cell::default(), atom));
} else {
term_stack.push(Term::PartialString(
Cell::default(),
- string,
- Some(Box::new(tail)),
+ atom.as_str().to_owned(),
+ Box::new(tail),
));
}
}
(HeapCellValueTag::PStrLoc, h) => {
- let string = cell_as_atom_cell!(iter.heap[h]).get_name();
+ let atom = cell_as_atom_cell!(iter.heap[h]).get_name();
let tail = term_stack.pop().unwrap();
term_stack.push(Term::PartialString(
Cell::default(),
- string,
- Some(Box::new(tail)),
+ atom.as_str().to_owned(),
+ Box::new(tail),
));
}
_ => {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Literal::Atom(ref atom) => {
- // if atom.as_str().chars().any(|c| "`.$'\" ".contains(c)) {
- // write!(f, "'{}'", atom)
- // } else {
write!(f, "{}", atom.flat_index())
- // }
}
Literal::Char(c) => write!(f, "'{}'", *c as u32),
Literal::Fixnum(n) => write!(f, "{}", n.get_num()),
Literal::Rational(ref n) => write!(f, "{}", n),
Literal::Float(ref n) => write!(f, "{}", *n),
Literal::String(ref s) => write!(f, "\"{}\"", s.as_str()),
- // Literal::Usize(integer) => write!(f, "u{}", integer),
}
}
}
Clause(Cell<RegType>, Atom, Vec<Term>),
Cons(Cell<RegType>, Box<Term>, Box<Term>),
Literal(Cell<RegType>, Literal),
- PartialString(Cell<RegType>, Atom, Option<Box<Term>>),
+ // PartialString wraps a String in anticipation of it absorbing
+ // other PartialString variants in as_partial_string.
+ PartialString(Cell<RegType>, String, Box<Term>),
+ CompleteString(Cell<RegType>, Atom),
Var(Cell<VarReg>, Rc<String>),
}
spec: u32,
}
-fn is_partial_string(
+pub(crate) fn as_partial_string(
head: Term,
mut tail: Term,
- atom_tbl: &mut AtomTable,
-) -> Result<(Atom, Option<Box<Term>>), Term> {
+) -> Result<(String, Option<Box<Term>>), Term> {
let mut string = match &head {
Term::Literal(_, Literal::Atom(atom)) => {
if let Some(c) = atom.as_char() {
tail_ref = succ;
}
+ Term::PartialString(_, pstr, tail) => {
+ string += &pstr;
+ tail_ref = tail;
+ }
+ Term::CompleteString(_, cstr) => {
+ string += cstr.as_str();
+ tail = Term::Literal(Cell::default(), Literal::Atom(atom!("[]")));
+ break;
+ }
tail_ref => {
tail = mem::replace(tail_ref, Term::AnonVar);
break;
match &tail {
Term::AnonVar | Term::Var(..) => {
- let pstr_atom = atom_tbl.build_with(&string);
- Ok((pstr_atom, Some(Box::new(tail))))
+ Ok((string, Some(Box::new(tail))))
}
Term::Literal(_, Literal::Atom(atom!("[]"))) => {
- let pstr_atom = atom_tbl.build_with(&string);
- Ok((pstr_atom, None))
+ Ok((string, None))
}
Term::Literal(_, Literal::String(tail)) => {
string += tail.as_str();
- let pstr_atom = atom_tbl.build_with(&string);
- Ok((pstr_atom, None))
+ Ok((string, None))
}
_ => {
- let pstr_atom = atom_tbl.build_with(&string);
- Ok((pstr_atom, Some(Box::new(tail))))
+ Ok((string, Some(Box::new(tail))))
}
}
}
TokenType::Term
}
Token::Literal(Literal::String(s)) if self.lexer.machine_st.flags.double_quotes.is_chars() => {
- self.terms.push(Term::PartialString(Cell::default(), s, None));
+ self.terms.push(Term::CompleteString(Cell::default(), s));
TokenType::Term
}
Token::Literal(c) => {
let head = subterms.pop().unwrap();
self.terms.push(
- match is_partial_string(head, tail, &mut self.lexer.machine_st.atom_tbl) {
- Ok((string_buf, tail_opt)) => {
- Term::PartialString(Cell::default(), string_buf, tail_opt)
+ match as_partial_string(head, tail) {
+ Ok((string_buf, Some(tail))) => {
+ Term::PartialString(Cell::default(), string_buf, tail)
+ }
+ Ok((string_buf, None)) => {
+ let atom = self.lexer.machine_st.atom_tbl.build_with(&string_buf);
+ Term::CompleteString(Cell::default(), atom)
}
Err(term) => term,
},
);
-
- /*
- self.terms.push(Term::Cons(
- Cell::default(),
- Box::new(head),
- Box::new(tail),
- ));
- */
} else {
- self.terms
- .push(Term::Clause(Cell::default(), name, subterms));
+ self.terms.push(Term::Clause(Cell::default(), name, subterms));
}
if let Some(&mut TokenDesc {
self.terms.push(match list {
Term::Cons(_, head, tail) => {
- match is_partial_string(*head, *tail, &mut self.lexer.machine_st.atom_tbl) {
- Ok((string_buf, tail_opt)) => {
- Term::PartialString(Cell::default(), string_buf, tail_opt)
+ match as_partial_string(*head, *tail) {
+ Ok((string_buf, Some(tail))) => {
+ Term::PartialString(Cell::default(), string_buf, tail)
+ }
+ Ok((string_buf, None)) => {
+ let atom = self.lexer.machine_st.atom_tbl.build_with(&string_buf);
+ Term::CompleteString(Cell::default(), atom)
}
Err(term) => term,
}
match term {
&TermRef::Cons(..) => list_loc_as_cell!(h),
&TermRef::AnonVar(_) | &TermRef::Var(..) => heap_loc_as_cell!(h),
- &TermRef::PartialString(_, _, ref src, None) =>
+ &TermRef::CompleteString(_, _, ref src) =>
if src.as_str().is_empty() {
empty_list_as_cell!()
} else if self.heap[h].get_tag() == HeapCellValueTag::CStr {
continue;
}
- &TermRef::PartialString(lvl, _, ref src, tail) => {
- if tail.is_some() {
- allocate_pstr(self.heap, src.as_str(), self.atom_tbl);
- } else {
- put_complete_string(self.heap, src.as_str(), self.atom_tbl);
- }
+ &TermRef::CompleteString(_, _, ref src) => {
+ put_complete_string(self.heap, src.as_str(), self.atom_tbl);
+ }
+ &TermRef::PartialString(lvl, _, ref src, _) => {
+ allocate_pstr(self.heap, src.as_str(), self.atom_tbl);
- if tail.is_some() {
- let h = self.heap.len();
- self.queue.push_back((1, h - 1));
+ let h = self.heap.len();
+ self.queue.push_back((1, h - 1));
- if let Level::Root = lvl {
- continue;
- }
+ if let Level::Root = lvl {
+ continue;
}
}
&TermRef::Var(_, _, ref var) => {