[[package]]
name = "prolog_parser"
-version = "0.7.13"
+version = "0.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"downcast 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "prolog_parser 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "prolog_parser 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
"checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
"checksum ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f"
-"checksum prolog_parser 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e6180d11b22e5ad469413211521123d4e83597ee8af0d047c31b5fdc59226e56"
+"checksum prolog_parser 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "5a7a659f57a1c0e9c375a82cc224462dc1b7c259e645fcc283928ef38947b584"
"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
downcast = "0.9.1"
num = "0.2"
ordered-float = "0.5.0"
-prolog_parser = "0.7.13"
+prolog_parser = "0.7.14"
[dependencies.termion]
version = "1.4.0"
\ No newline at end of file
&InlinedClauseType::IsAtom(..) =>
match terms[0].as_ref() {
&Term::Constant(_, Constant::Char(_))
- | &Term::Constant(_, Constant::Atom(_)) => {
+ | &Term::Constant(_, Constant::Atom(..)) => {
code.push(succeed!());
},
&Term::Var(ref vr, ref name) => {
pub enum TokenOrRedirect {
Atom(ClauseName),
Op(ClauseName),
- NumberedVar(String),
+ NumberedVar(String),
+ CompositeRedirect,
Redirect,
Open,
Close,
fn push_char(&mut self, c: char) {
self.contents.push(c);
}
-
+
fn begin_new_var(&mut self) {
if self.contents.len() != 0 {
self.contents += ", ";
match fixity {
Fixity::Post => {
state_stack.push(TokenOrRedirect::Op(ct.name()));
- state_stack.push(TokenOrRedirect::Redirect);
+ state_stack.push(TokenOrRedirect::CompositeRedirect);
},
Fixity::Pre => {
- state_stack.push(TokenOrRedirect::Redirect);
+ state_stack.push(TokenOrRedirect::CompositeRedirect);
state_stack.push(TokenOrRedirect::Op(ct.name()));
},
Fixity::In => {
- state_stack.push(TokenOrRedirect::Redirect);
+ state_stack.push(TokenOrRedirect::CompositeRedirect);
state_stack.push(TokenOrRedirect::Op(ct.name()));
- state_stack.push(TokenOrRedirect::Redirect);
+ state_stack.push(TokenOrRedirect::CompositeRedirect);
}
- }
+ }
}
impl HCValueFormatter for WriteqFormatter {
match iter.machine_st.store(iter.machine_st.deref(addr)) {
Addr::Con(Constant::Number(Number::Integer(ref n))) if !n.is_negative() => {
iter.stack().pop();
-
+
let i = n.mod_floor(&BigInt::from(26)).to_usize().unwrap();
let j = n.div_floor(&BigInt::from(26));
} else {
format!("{}{}", CHAR_CODES[i], j)
};
-
+
state_stack.push(TokenOrRedirect::NumberedVar(result));
-
+
return;
}
_ => {}
- };
+ };
}
-
- self.format_struct(arity, ct.name(), state_stack);
+
+ self.format_struct(arity, ct.name(), state_stack);
}
}
}
} else {
iter.all(|c| graphic_token_char!(c))
- }
+ }
}
fn non_quoted_token<Iter: Iterator<Item=char>>(mut iter: Iter) -> bool {
} else if cut_char!(c) {
iter.next().is_none()
} else if solo_char!(c) {
- !iter.next().is_none()
+ !iter.next().is_none()
} else if c == '[' {
(iter.next() == Some(']') && iter.next().is_none())
} else if c == '{' {
}
})
}
-
+
fn print_atom(&mut self, atom: &ClauseName, is_op: bool) {
match atom.as_str() {
"" => self.outputter.append("''"),
for c in atom.as_str().chars() {
self.print_char(c);
}
-
+
self.outputter.push_char('\'');
}
}
_ => self.outputter.push_char(c)
};
}
-
- fn print_constant(&mut self, c: Constant) {
- match c {
- Constant::Atom(ref atom) =>
+
+ fn print_constant(&mut self, c: Constant, composite_brackets: bool) {
+ match c {
+ Constant::Atom(ref atom, Some(_)) => {
+ if composite_brackets {
+ self.outputter.push_char('(');
+ }
+
+ self.print_atom(atom, true);
+
+ if composite_brackets {
+ self.outputter.push_char(')');
+ }
+ },
+ Constant::Atom(ref atom, _) =>
self.print_atom(atom, false),
Constant::Char(c) if non_quoted_token(once(c)) =>
self.print_char(c),
}
} else { // for now, == DoubleQuotes::Atom
let borrowed_str = s.borrow();
-
+
self.outputter.append("\"");
self.outputter.append(&borrowed_str[s.cursor() ..]);
self.outputter.append("\"");
- },
+ },
Constant::Usize(i) =>
self.outputter.append(&format!("u{}", i))
}
self.state_stack.push(TokenOrRedirect::HeadTailSeparator); // bar
self.state_stack.push(TokenOrRedirect::Redirect);
- self.state_stack.push(TokenOrRedirect::OpenList(cell));
+ self.state_stack.push(TokenOrRedirect::OpenList(cell));
}
-
- fn handle_heap_term(&mut self, iter: &mut HCPreOrderIterator)
+
+ fn handle_heap_term(&mut self, iter: &mut HCPreOrderIterator, composite_brackets: bool)
{
let heap_val = match self.check_for_seen(iter) {
Some(heap_val) => heap_val,
};
match heap_val {
+ HeapCellValue::NamedStr(arity, name, Some(fixity)) => {
+ if composite_brackets {
+ self.state_stack.push(TokenOrRedirect::Close);
+ }
+
+ let ct = ClauseType::from(name, arity, Some(fixity));
+ self.formatter.format_clause(iter, arity, ct, &mut self.state_stack);
+
+ if composite_brackets {
+ self.state_stack.push(TokenOrRedirect::Open);
+ }
+ },
HeapCellValue::NamedStr(arity, name, fixity) => {
let ct = ClauseType::from(name, arity, fixity);
self.formatter.format_clause(iter, arity, ct, &mut self.state_stack)
self.outputter.append("[]");
},
HeapCellValue::Addr(Addr::Con(c)) =>
- self.print_constant(c),
+ self.print_constant(c, composite_brackets),
HeapCellValue::Addr(Addr::Lis(_)) =>
self.push_list(),
HeapCellValue::Addr(addr) => self.print_offset(addr)
self.print_atom(&atom, true),
TokenOrRedirect::NumberedVar(num_var) =>
self.outputter.append(num_var.as_str()),
+ TokenOrRedirect::CompositeRedirect =>
+ self.handle_heap_term(&mut iter, true),
TokenOrRedirect::Redirect =>
- self.handle_heap_term(&mut iter),
+ self.handle_heap_term(&mut iter, false),
TokenOrRedirect::Close =>
self.outputter.append(")"),
TokenOrRedirect::Open =>
self.outputter.append(", ")
}
} else if !iter.stack().is_empty() {
- self.handle_heap_term(&mut iter);
+ self.handle_heap_term(&mut iter, false);
} else {
break;
}
--- /dev/null
+:- module(numbervars, [numbervars/2, numbervars/3]).
+
+numbervars(Term, NewTerm) :- duplicate_term(Term, NewTerm), numbervars(Term, NewTerm, 0, _).
+
+numbervars(Term, NewTerm, N) :-
+ ( integer(N), N >= 0 -> duplicate_term(Term, NewTerm), numbervars(Term, NewTerm, N, _)
+ ; integer(N) -> throw(error(domain_error(not_less_than_zero, N), numbervars/3))
+ ; throw(error(type_error(integer, N), numbervars/3))
+ ).
+
+numbervars(Term, NewTerm, N1, N2) :-
+ var(Term), !, NewTerm = '$VAR'(N1), N2 is N1 + 1.
+numbervars([Arg | Args], NewTerms, N1, N2) :- !,
+ fold_numbervars([Arg | Args], NewTerms, N1, N2).
+numbervars(Term, NewTerm, N1, N2) :- compound(Term), !,
+ Term =.. [Name | Args],
+ NewTerm =.. [Name | NewArgs],
+ fold_numbervars(Args, NewArgs, N1, N2).
+numbervars(_, _, _, _).
+
+marked_already(Term, NewTerm) :-
+ var(Term), nonvar(NewTerm), NewTerm = '$VAR'(_).
+marked_already(Term, NewTerm) :-
+ atomic(Term).
+
+fold_numbervars([HeadTerm | Terms], [NewHeadTerm | NewTerms], N1, Nn) :-
+ ( marked_already(HeadTerm, NewHeadTerm) -> N1 = N2
+ ; numbervars(HeadTerm, NewHeadTerm, N1, N2),
+ ( var(N2) -> N1 = N2
+ ; true )
+ ),
+ fold_numbervars(Terms, NewTerms, N2, Nn).
+fold_numbervars([], [], _, _).
impl MachineError {
pub(super) fn functor_stub(name: ClauseName, arity: usize) -> MachineStub {
- let name = HeapCellValue::Addr(Addr::Con(Constant::Atom(name)));
+ let name = HeapCellValue::Addr(Addr::Con(Constant::Atom(name, None)));
functor!("/", 2, [name, heap_integer!(arity)], Fixity::In)
}
pub(super)
fn module_resolution_error(h: usize, mod_name: ClauseName, name: ClauseName, arity: usize) -> Self
{
- let mod_name = HeapCellValue::Addr(Addr::Con(Constant::Atom(mod_name)));
- let name = HeapCellValue::Addr(Addr::Con(Constant::Atom(name)));
+ let mod_name = HeapCellValue::Addr(Addr::Con(Constant::Atom(mod_name, None)));
+ let name = HeapCellValue::Addr(Addr::Con(Constant::Atom(name, None)));
let mut stub = functor!("evaluation_error", 1, [HeapCellValue::Addr(Addr::HeapCell(h + 2))]);
stub));
},
ClauseType::System(_) => {
- let name = Addr::Con(Constant::Atom(name));
+ let name = Addr::Con(Constant::Atom(name, None));
let stub = MachineError::functor_stub(clause_name!("call"), arity + 1);
return Err(machine_st.error_form(MachineError::type_error(ValidType::Callable,
stepper(c);
continue;
},
- HeapCellValue::Addr(Addr::Con(Constant::Atom(ref a))) =>
+ HeapCellValue::Addr(Addr::Con(Constant::Atom(ref a, _))) =>
if let Some(c) = a.as_str().chars().next() {
if c.len_utf8() == a.as_str().len() {
stepper(c);
return None;
}
},
- Addr::Con(Constant::Atom(name)) => (name, 0),
+ Addr::Con(Constant::Atom(name, _)) => (name, 0),
Addr::HeapCell(_) | Addr::StackCell(_, _) => {
let instantiation_error = self.error_form(MachineError::instantiation_error(), stub);
self.throw_exception(instantiation_error);
} else {
return Ordering::Greater;
},
- (HeapCellValue::Addr(Addr::Con(Constant::Atom(atom))),
+ (HeapCellValue::Addr(Addr::Con(Constant::Atom(atom, _))),
HeapCellValue::Addr(Addr::Con(Constant::Char(c)))) =>
return if atom.as_str().chars().count() == 1 {
atom.as_str().chars().next().cmp(&Some(c))
Ordering::Greater
},
(HeapCellValue::Addr(Addr::Con(Constant::Char(c))),
- HeapCellValue::Addr(Addr::Con(Constant::Atom(atom)))) =>
+ HeapCellValue::Addr(Addr::Con(Constant::Atom(atom, _)))) =>
return if atom.as_str().chars().count() == 1 {
Some(c).cmp(&atom.as_str().chars().next())
} else {
(HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
HeapCellValue::Addr(Addr::StackCell(..))) =>
return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::Atom(_))),
+ (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
HeapCellValue::Addr(Addr::Con(Constant::Number(_)))) =>
return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::Atom(_))),
+ (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
HeapCellValue::Addr(Addr::Con(Constant::String(_)))) =>
return Ordering::Greater,
- (HeapCellValue::Addr(Addr::Con(Constant::Atom(s1))),
- HeapCellValue::Addr(Addr::Con(Constant::Atom(s2)))) =>
+ (HeapCellValue::Addr(Addr::Con(Constant::Atom(s1, _))),
+ HeapCellValue::Addr(Addr::Con(Constant::Atom(s2, _)))) =>
if s1 != s2 {
return s1.cmp(&s2);
},
- (HeapCellValue::Addr(Addr::Con(Constant::Atom(_))), _) =>
+ (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))), _) =>
return Ordering::Less,
(HeapCellValue::NamedStr(ar1, n1, _), HeapCellValue::NamedStr(ar2, n2, _)) =>
if ar1 < ar2 {
let d = self.store(self.deref(self[r1].clone()));
match d {
- Addr::Con(Constant::Atom(_)) | Addr::Con(Constant::Char(_)) => self.p += 1,
+ Addr::Con(Constant::Atom(..)) | Addr::Con(Constant::Char(_)) => self.p += 1,
_ => self.fail = true
};
},
}
fn try_functor_compound_case(&mut self, name: ClauseName, arity: usize) {
- let name = Addr::Con(Constant::Atom(name));
+ let name = Addr::Con(Constant::Atom(name, None));
let arity = Addr::Con(integer!(arity));
self.try_functor_unify_components(name, arity);
match name {
Addr::Con(_) if arity == 0 =>
self.unify(a1, name),
- Addr::Con(Constant::Atom(name)) => {
+ Addr::Con(Constant::Atom(name, _)) => {
let f_a = if name.as_str() == "." && arity == 2 {
Addr::Lis(self.heap.h)
} else {
deref_cut(self, r),
&SystemClauseType::SetDoubleQuotes =>
match self[temp_v!(1)].clone() {
- Addr::Con(Constant::Atom(ref atom)) if atom.as_str() == "chars" =>
+ Addr::Con(Constant::Atom(ref atom, _)) if atom.as_str() == "chars" =>
self.flags.double_quotes = DoubleQuotes::Chars,
- Addr::Con(Constant::Atom(ref atom)) if atom.as_str() == "atom" =>
+ Addr::Con(Constant::Atom(ref atom, _)) if atom.as_str() == "atom" =>
self.flags.double_quotes = DoubleQuotes::Atom,
_ => self.fail = true
},
fn setup_fact(term: Term) -> Result<Term, ParserError>
{
match term {
- Term::Clause(..) | Term::Constant(_, Constant::Atom(_)) =>
+ Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) =>
Ok(term),
_ =>
Err(ParserError::InadmissibleFact)
fn setup_op_decl(mut terms: Vec<Box<Term>>) -> Result<OpDecl, ParserError>
{
let name = match *terms.pop().unwrap() {
- Term::Constant(_, Constant::Atom(name)) => name,
+ Term::Constant(_, Constant::Atom(name, _)) => name,
_ => return Err(ParserError::InconsistentEntry)
};
let spec = match *terms.pop().unwrap() {
- Term::Constant(_, Constant::Atom(name)) => name,
+ Term::Constant(_, Constant::Atom(name, _)) => name,
_ => return Err(ParserError::InconsistentEntry)
};
fn mark_cut_variables_as(terms: &mut Vec<Term>, name: ClauseName) {
for term in terms.iter_mut() {
match term {
- &mut Term::Constant(_, Constant::Atom(ref mut var)) if var.as_str() == "!" =>
+ &mut Term::Constant(_, Constant::Atom(ref mut var, _)) if var.as_str() == "!" =>
*var = name.clone(),
_ => {}
}
fn mark_cut_variable(term: &mut Term) -> bool {
let cut_var_found = match term {
- &mut Term::Constant(_, Constant::Atom(ref var)) if var.as_str() == "!" => true,
+ &mut Term::Constant(_, Constant::Atom(ref var, _)) if var.as_str() == "!" => true,
_ => false
};
}
fn module_resolution_call(mod_name: Term, body: Term) -> Result<QueryTerm, ParserError> {
- if let Term::Constant(_, Constant::Atom(mod_name)) = mod_name {
+ if let Term::Constant(_, Constant::Atom(mod_name, _)) = mod_name {
if let Term::Clause(_, name, terms, _) = body {
let idx = CodeIndex(Rc::new(RefCell::new((IndexPtr::Module, mod_name))));
return Ok(QueryTerm::Clause(Cell::default(), ClauseType::Named(name, idx), terms,
fn to_query_term(&mut self, indices: &mut CompositeIndices, term: Term) -> Result<QueryTerm, ParserError>
{
match term {
- Term::Constant(r, Constant::Atom(name)) =>
+ Term::Constant(r, Constant::Atom(name, fixity)) =>
if name.as_str() == "!" || name.as_str() == "blocked_!" {
Ok(QueryTerm::BlockedCut)
} else {
- let ct = indices.get_clause_type(name, 0, None);
+ let ct = indices.get_clause_type(name, 0, fixity);
Ok(QueryTerm::Clause(r, ct, vec![], false))
},
Term::Var(_, ref v) if v.as_str() == "!" =>
match *terms.pop().unwrap() {
Term::Clause(_, name, terms, _) =>
Ok(Rule { head: (name, terms, qt), clauses }),
- Term::Constant(_, Constant::Atom(name)) =>
+ Term::Constant(_, Constant::Atom(name, _)) =>
Ok(Rule { head: (name, vec![], qt), clauses }),
_ => Err(ParserError::InvalidRuleHead)
}
[["X = '\\f'"]]);
assert_prolog_success!(&mut wam, "?- X = '\\b\\r\\f\\t\\n'.",
[["X = '\\b\\r\\f\\t\\n'"]]);
+
+ assert_prolog_success!(&mut wam, "?- X = ((*)=(*)).",
+ [["X = (*)=(*)"]]);
+ assert_prolog_success!(&mut wam, "?- X = [.,.(.,.,.)].",
+ [["X = ['.', '.'('.', '.', '.')]"]]);
+ assert_prolog_success!(&mut wam, "?- X = a+(b*c).",
+ [["X = a+(b*c)"]]);
+ assert_prolog_success!(&mut wam, "?- X = [:-,-].",
+ [["X = [:-, -]"]]);
+ assert_prolog_success!(&mut wam, "?- X = a*(b+c).",
+ [["X = a*(b+c)"]]);
+ assert_prolog_success!(&mut wam, "?- X = (-)-(-).",
+ [["X = (-)-(-)"]]);
+ assert_prolog_success!(&mut wam, "?- X = ((:-):-(:-)).",
+ [["X = (:-):-(:-)"]]);
}
#[test]