mark structures with their fixity

This commit is contained in:
Mark Thom
2018-01-14 21:48:10 -07:00
parent b2b4ce6877
commit 58ba368280
16 changed files with 131 additions and 118 deletions

View File

@@ -19,7 +19,7 @@ impl<'a> ArithExprIterator<'a> {
let state = match term { let state = match term {
&Term::AnonVar => &Term::AnonVar =>
return Err(ArithmeticError::InvalidTerm), return Err(ArithmeticError::InvalidTerm),
&Term::Clause(_, _, ref terms) => &Term::Clause(_, _, ref terms, _) =>
TermIterState::Clause(0, ClauseType::Root, terms), TermIterState::Clause(0, ClauseType::Root, terms),
&Term::Constant(ref cell, ref cons) => &Term::Constant(ref cell, ref cons) =>
TermIterState::Constant(Level::Shallow, cell, cons), TermIterState::Constant(Level::Shallow, cell, cons),
@@ -199,7 +199,7 @@ impl<'a> ArithmeticEvaluator<'a> {
self.interm.push(ArithmeticTerm::Reg(r)); self.interm.push(ArithmeticTerm::Reg(r));
}, },
TermRef::Clause(ClauseType::Deep(_, _, name), terms) => { TermRef::Clause(ClauseType::Deep(_, _, name, _), terms) => {
code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?)); code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?));
}, },
TermRef::Clause(ClauseType::Root, terms) => { TermRef::Clause(ClauseType::Root, terms) => {

View File

@@ -298,7 +298,7 @@ impl fmt::Display for Constant {
pub enum Term { pub enum Term {
AnonVar, AnonVar,
Clause(Cell<RegType>, Rc<Atom>, Vec<Box<Term>>), Clause(Cell<RegType>, Rc<Atom>, Vec<Box<Term>>, Option<Fixity>),
Cons(Cell<RegType>, Box<Term>, Box<Term>), Cons(Cell<RegType>, Box<Term>, Box<Term>),
Constant(Cell<RegType>, Constant), Constant(Cell<RegType>, Constant),
Var(Cell<VarReg>, Rc<Var>) Var(Cell<VarReg>, Rc<Var>)
@@ -369,7 +369,7 @@ pub struct Rule {
pub enum ClauseType<'a> { pub enum ClauseType<'a> {
CallN, CallN,
Catch, Catch,
Deep(Level, &'a Cell<RegType>, &'a Rc<Atom>), Deep(Level, &'a Cell<RegType>, &'a Rc<Atom>, Option<Fixity>),
Is, Is,
Root, Root,
Throw, Throw,
@@ -378,7 +378,7 @@ pub enum ClauseType<'a> {
impl<'a> ClauseType<'a> { impl<'a> ClauseType<'a> {
pub fn level_of_subterms(self) -> Level { pub fn level_of_subterms(self) -> Level {
match self { match self {
ClauseType::Deep(_, _, _) => Level::Deep, ClauseType::Deep(..) => Level::Deep,
_ => Level::Shallow _ => Level::Shallow
} }
} }
@@ -397,10 +397,10 @@ impl<'a> TermRef<'a> {
pub fn level(self) -> Level { pub fn level(self) -> Level {
match self { match self {
TermRef::AnonVar(lvl) TermRef::AnonVar(lvl)
| TermRef::Cons(lvl, _, _, _) | TermRef::Cons(lvl, ..)
| TermRef::Constant(lvl, _, _) | TermRef::Constant(lvl, ..)
| TermRef::Var(lvl, _, _) => lvl, | TermRef::Var(lvl, ..) => lvl,
TermRef::Clause(ClauseType::Deep(lvl, _, _), _) => lvl, TermRef::Clause(ClauseType::Deep(lvl, ..), ..) => lvl,
_ => Level::Shallow _ => Level::Shallow
} }
} }
@@ -798,7 +798,7 @@ impl From<IndexingInstruction> for Line {
pub enum FactInstruction { pub enum FactInstruction {
GetConstant(Level, Constant, RegType), GetConstant(Level, Constant, RegType),
GetList(Level, RegType), GetList(Level, RegType),
GetStructure(Level, Rc<Atom>, usize, RegType), GetStructure(Level, Rc<Atom>, usize, RegType, Option<Fixity>),
GetValue(RegType, usize), GetValue(RegType, usize),
GetVariable(RegType, usize), GetVariable(RegType, usize),
UnifyConstant(Constant), UnifyConstant(Constant),
@@ -812,7 +812,7 @@ pub enum QueryInstruction {
GetVariable(RegType, usize), GetVariable(RegType, usize),
PutConstant(Level, Constant, RegType), PutConstant(Level, Constant, RegType),
PutList(Level, RegType), PutList(Level, RegType),
PutStructure(Level, Rc<Atom>, usize, RegType), PutStructure(Level, Rc<Atom>, usize, RegType, Option<Fixity>),
PutUnsafeValue(usize, usize), PutUnsafeValue(usize, usize),
PutValue(RegType, usize), PutValue(RegType, usize),
PutVariable(RegType, usize), PutVariable(RegType, usize),
@@ -896,14 +896,14 @@ pub enum Ref {
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq)]
pub enum HeapCellValue { pub enum HeapCellValue {
Addr(Addr), Addr(Addr),
NamedStr(usize, Rc<Atom>), // arity, name. NamedStr(usize, Rc<Atom>, Option<Fixity>), // arity, name.
} }
impl HeapCellValue { impl HeapCellValue {
pub fn as_addr(&self, focus: usize) -> Addr { pub fn as_addr(&self, focus: usize) -> Addr {
match self { match self {
&HeapCellValue::Addr(ref a) => a.clone(), &HeapCellValue::Addr(ref a) => a.clone(),
&HeapCellValue::NamedStr(_, _) => Addr::Str(focus) &HeapCellValue::NamedStr(_, _, _) => Addr::Str(focus)
} }
} }
} }
@@ -1010,7 +1010,7 @@ pub type Registers = Vec<Addr>;
impl Term { impl Term {
pub fn first_arg(&self) -> Option<&Term> { pub fn first_arg(&self) -> Option<&Term> {
match self { match self {
&Term::Clause(_, _, ref terms) => &Term::Clause(_, _, ref terms, _) =>
terms.first().map(|bt| bt.as_ref()), terms.first().map(|bt| bt.as_ref()),
_ => None _ => None
} }
@@ -1018,7 +1018,7 @@ impl Term {
pub fn is_callable(&self) -> bool { pub fn is_callable(&self) -> bool {
match self { match self {
&Term::Clause(_, _, _) | &Term::Constant(_, Constant::Atom(_)) => &Term::Clause(..) | &Term::Constant(_, Constant::Atom(_)) =>
true, true,
_ => false _ => false
} }
@@ -1027,14 +1027,14 @@ impl Term {
pub fn name(&self) -> Option<Rc<Atom>> { pub fn name(&self) -> Option<Rc<Atom>> {
match self { match self {
&Term::Constant(_, Constant::Atom(ref atom)) &Term::Constant(_, Constant::Atom(ref atom))
| &Term::Clause(_, ref atom, _) => Some(atom.clone()), | &Term::Clause(_, ref atom, ..) => Some(atom.clone()),
_ => None _ => None
} }
} }
pub fn arity(&self) -> usize { pub fn arity(&self) -> usize {
match self { match self {
&Term::Clause(_, _, ref child_terms) => child_terms.len(), &Term::Clause(_, _, ref child_terms, ..) => child_terms.len(),
_ => 0 _ => 0
} }
} }
@@ -1054,8 +1054,8 @@ impl<'a> TermIterState<'a> {
match term { match term {
&Term::AnonVar => &Term::AnonVar =>
TermIterState::AnonVar(lvl), TermIterState::AnonVar(lvl),
&Term::Clause(ref cell, ref atom, ref child_terms) => &Term::Clause(ref cell, ref atom, ref child_terms, fixity) =>
TermIterState::Clause(0, ClauseType::Deep(lvl, cell, atom), child_terms), TermIterState::Clause(0, ClauseType::Deep(lvl, cell, atom, fixity), child_terms),
&Term::Cons(ref cell, ref head, ref tail) => &Term::Cons(ref cell, ref head, ref tail) =>
TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref()), TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref()),
&Term::Constant(ref cell, ref constant) => &Term::Constant(ref cell, ref constant) =>

View File

@@ -115,7 +115,7 @@ fn get_builtins() -> Code {
trust!(10), trust!(10),
try_me_else!(4), try_me_else!(4),
fact![get_constant!(Constant::from("!"), temp_v!(1)), fact![get_constant!(Constant::from("!"), temp_v!(1)),
get_structure!(String::from(","), 2, temp_v!(2)), get_structure!(String::from(","), 2, temp_v!(2), Some(infix!())),
unify_variable!(temp_v!(1)), unify_variable!(temp_v!(1)),
unify_variable!(temp_v!(2))], unify_variable!(temp_v!(2))],
set_cp!(temp_v!(3)), set_cp!(temp_v!(3)),
@@ -132,7 +132,7 @@ fn get_builtins() -> Code {
execute_n!(1), execute_n!(1),
retry_me_else!(8), retry_me_else!(8),
allocate!(3), allocate!(3),
fact![get_structure!(String::from(","), 2, temp_v!(2)), fact![get_structure!(String::from(","), 2, temp_v!(2), Some(infix!())),
unify_variable!(perm_v!(2)), unify_variable!(perm_v!(2)),
unify_variable!(perm_v!(1)), unify_variable!(perm_v!(1)),
get_var_in_fact!(perm_v!(3), 3)], get_var_in_fact!(perm_v!(3), 3)],
@@ -167,12 +167,12 @@ fn get_builtins() -> Code {
indexed_try!(3), indexed_try!(3),
trust!(5), trust!(5),
try_me_else!(3), try_me_else!(3),
fact![get_structure!(String::from("->"), 2, temp_v!(1)), fact![get_structure!(String::from("->"), 2, temp_v!(1), Some(infix!())),
unify_variable!(temp_v!(1)), unify_variable!(temp_v!(1)),
unify_variable!(temp_v!(2))], unify_variable!(temp_v!(2))],
goto!(139, 3), goto!(139, 3),
trust_me!(), trust_me!(),
fact![get_structure!(String::from("->"), 2, temp_v!(1)), fact![get_structure!(String::from("->"), 2, temp_v!(1), Some(infix!())),
unify_void!(2)], unify_void!(2)],
query![put_value!(temp_v!(2), 1)], query![put_value!(temp_v!(2), 1)],
neck_cut!(), neck_cut!(),
@@ -234,7 +234,8 @@ fn get_builtins() -> Code {
put_structure!(Level::Shallow, put_structure!(Level::Shallow,
String::from("type_error"), String::from("type_error"),
1, 1,
temp_v!(1)), temp_v!(1),
None),
set_constant!(Constant::Atom(rc_atom!("integer_expected")))], set_constant!(Constant::Atom(rc_atom!("integer_expected")))],
goto!(59, 1), // goto throw/1. goto!(59, 1), // goto throw/1.
try_me_else!(5), // arg_/3, 173. try_me_else!(5), // arg_/3, 173.

View File

@@ -130,7 +130,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
self.marker.mark_anon_var(Level::Deep, target), self.marker.mark_anon_var(Level::Deep, target),
&Term::AnonVar => &Term::AnonVar =>
Self::add_or_increment_void_instr(target), Self::add_or_increment_void_instr(target),
&Term::Cons(ref cell, _, _) | &Term::Clause(ref cell, _, _) => { &Term::Cons(ref cell, _, _) | &Term::Clause(ref cell, _, _, _) => {
self.marker.mark_non_var(Level::Deep, term_loc, cell, target); self.marker.mark_non_var(Level::Deep, term_loc, cell, target);
target.push(Target::clause_arg_to_instr(cell.get())); target.push(Target::clause_arg_to_instr(cell.get()));
}, },
@@ -154,9 +154,10 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
where Target: CompilationTarget<'a> where Target: CompilationTarget<'a>
{ {
match ct { match ct {
ClauseType::Deep(lvl, cell, atom) => { ClauseType::Deep(lvl, cell, atom, fixity) => {
self.marker.mark_non_var(lvl, term_loc, cell, target); self.marker.mark_non_var(lvl, term_loc, cell, target);
target.push(Target::to_structure(lvl, atom.clone(), terms.len(), cell.get())); target.push(Target::to_structure(lvl, atom.clone(), terms.len(),
cell.get(), fixity));
for subterm in terms { for subterm in terms {
self.subterm_to_instr(subterm.as_ref(), term_loc, is_exposed, target); self.subterm_to_instr(subterm.as_ref(), term_loc, is_exposed, target);
@@ -254,7 +255,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
let call = ControlInstruction::Call(atom.clone(), 0, pvs); let call = ControlInstruction::Call(atom.clone(), 0, pvs);
code.push(Line::Control(call)); code.push(Line::Control(call));
}, },
&QueryTerm::Term(Term::Clause(_, ref atom, ref terms)) => { &QueryTerm::Term(Term::Clause(_, ref atom, ref terms, _)) => {
let call = ControlInstruction::Call(atom.clone(), terms.len(), pvs); let call = ControlInstruction::Call(atom.clone(), terms.len(), pvs);
code.push(Line::Control(call)); code.push(Line::Control(call));
}, },
@@ -317,10 +318,10 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
}, },
&InlinedQueryTerm::IsAtomic(ref inner_term) => &InlinedQueryTerm::IsAtomic(ref inner_term) =>
match inner_term[0].as_ref() { match inner_term[0].as_ref() {
&Term::AnonVar | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => { &Term::AnonVar | &Term::Clause(..) | &Term::Cons(..) => {
code.push(fail!()); code.push(fail!());
}, },
&Term::Constant(_, _) => { &Term::Constant(..) => {
code.push(succeed!()); code.push(succeed!());
}, },
&Term::Var(ref vr, ref name) => { &Term::Var(ref vr, ref name) => {
@@ -343,7 +344,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
}, },
&InlinedQueryTerm::IsVar(ref inner_term) => &InlinedQueryTerm::IsVar(ref inner_term) =>
match inner_term[0].as_ref() { match inner_term[0].as_ref() {
&Term::Constant(_, _) | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => { &Term::Constant(..) | &Term::Clause(..) | &Term::Cons(..) => {
code.push(fail!()); code.push(fail!());
}, },
&Term::AnonVar => { &Term::AnonVar => {
@@ -482,7 +483,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
self.compile_seq_prelude(&conjunct_info, &mut code); self.compile_seq_prelude(&conjunct_info, &mut code);
if let &QueryTerm::Term(ref term) = p0 { if let &QueryTerm::Term(ref term) = p0 {
if let &Term::Clause(_, _, _) = term { if let &Term::Clause(..) = term {
let iter = FactInstruction::iter(term); let iter = FactInstruction::iter(term);
let fact = self.compile_target(iter, GenContext::Head, false); let fact = self.compile_target(iter, GenContext::Head, false);
@@ -554,7 +555,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
let mut code = Vec::new(); let mut code = Vec::new();
if let &Term::Clause(_, _, _) = term { if let &Term::Clause(..) = term {
let iter = FactInstruction::iter(term); let iter = FactInstruction::iter(term);
let mut compiled_fact = self.compile_target(iter, GenContext::Head, false); let mut compiled_fact = self.compile_target(iter, GenContext::Head, false);

View File

@@ -25,7 +25,7 @@ pub trait CopierTarget
while scan < self.threshold() { while scan < self.threshold() {
match self[scan].clone() { match self[scan].clone() {
HeapCellValue::NamedStr(_, _) => HeapCellValue::NamedStr(_, _, _) =>
scan += 1, scan += 1,
HeapCellValue::Addr(a) => HeapCellValue::Addr(a) =>
match a.clone() { match a.clone() {
@@ -69,16 +69,16 @@ pub trait CopierTarget
}, },
Addr::Str(s) => { Addr::Str(s) => {
match self[s].clone() { match self[s].clone() {
HeapCellValue::NamedStr(arity, name) => { HeapCellValue::NamedStr(arity, name, fixity) => {
let threshold = self.threshold(); let threshold = self.threshold();
self[scan] = HeapCellValue::Addr(Addr::Str(threshold)); self[scan] = HeapCellValue::Addr(Addr::Str(threshold));
self[s] = HeapCellValue::Addr(Addr::Str(threshold)); self[s] = HeapCellValue::Addr(Addr::Str(threshold));
trail.push((Ref::HeapCell(s), trail.push((Ref::HeapCell(s),
HeapCellValue::NamedStr(arity, name.clone()))); HeapCellValue::NamedStr(arity, name.clone(), fixity)));
self.push(HeapCellValue::NamedStr(arity, name)); self.push(HeapCellValue::NamedStr(arity, name, fixity));
for i in 0 .. arity { for i in 0 .. arity {
let hcv = self[s + 1 + i].clone(); let hcv = self[s + 1 + i].clone();

View File

@@ -34,7 +34,7 @@ impl<'a> HeapCellIterator<'a> {
fn follow_heap(&mut self, h: usize) -> Addr fn follow_heap(&mut self, h: usize) -> Addr
{ {
match &self.machine_st.heap[h] { match &self.machine_st.heap[h] {
&HeapCellValue::NamedStr(arity, _) => { &HeapCellValue::NamedStr(arity, _, _) => {
for idx in (1 .. arity + 1).rev() { for idx in (1 .. arity + 1).rev() {
self.state_stack.push(Ref::HeapCell(h + idx)); self.state_stack.push(Ref::HeapCell(h + idx));
} }

View File

@@ -1,5 +1,4 @@
use prolog::ast::*; use prolog::ast::*;
use prolog::builtins::*;
use prolog::heap_iter::*; use prolog::heap_iter::*;
use std::cell::Cell; use std::cell::Cell;
@@ -38,58 +37,46 @@ pub trait HeapCellValueFormatter {
// this can be overloaded to handle special cases, falling back on the default of // this can be overloaded to handle special cases, falling back on the default of
// format_struct when convenient. // format_struct when convenient.
fn format_clause(&self, arity: usize, name: Rc<Atom>, state_stack: &mut Vec<TokenOrRedirect>); fn format_clause(&self, usize, Rc<Atom>, Option<Fixity>, &mut Vec<TokenOrRedirect>);
} }
// the 'classic' display corresponding to the display predicate. // the 'classic' display corresponding to the display predicate.
pub struct DisplayFormatter {} pub struct DisplayFormatter {}
impl HeapCellValueFormatter for DisplayFormatter { impl HeapCellValueFormatter for DisplayFormatter {
fn format_clause(&self, arity: usize, name: Rc<Atom>, state_stack: &mut Vec<TokenOrRedirect>) fn format_clause(&self, arity: usize, name: Rc<Atom>, _: Option<Fixity>,
state_stack: &mut Vec<TokenOrRedirect>)
{ {
self.format_struct(arity, name, state_stack); self.format_struct(arity, name, state_stack);
} }
} }
pub struct TermFormatter<'a> { pub struct TermFormatter {}
op_dir: &'a OpDir
}
impl<'a> TermFormatter<'a> { impl HeapCellValueFormatter for TermFormatter {
pub fn new(op_dir: &'a OpDir) -> Self { fn format_clause(&self, arity: usize, name: Rc<Atom>, fixity: Option<Fixity>,
TermFormatter { op_dir } state_stack: &mut Vec<TokenOrRedirect>)
} {
} if let Some(fixity) = fixity {
match fixity {
impl<'a> HeapCellValueFormatter for TermFormatter<'a> { Fixity::Post => {
fn format_clause(&self, arity: usize, name: Rc<Atom>, state_stack: &mut Vec<TokenOrRedirect>) {
if arity == 1 {
match self.op_dir.get(&(name.clone(), Fixity::Post)) {
Some(_) => {
state_stack.push(TokenOrRedirect::Atom(name)); state_stack.push(TokenOrRedirect::Atom(name));
state_stack.push(TokenOrRedirect::Space); state_stack.push(TokenOrRedirect::Space);
state_stack.push(TokenOrRedirect::Redirect); state_stack.push(TokenOrRedirect::Redirect);
}, },
None => match self.op_dir.get(&(name.clone(), Fixity::Pre)) { Fixity::Pre => {
Some(_) => { state_stack.push(TokenOrRedirect::Redirect);
state_stack.push(TokenOrRedirect::Redirect); state_stack.push(TokenOrRedirect::Space);
state_stack.push(TokenOrRedirect::Space); state_stack.push(TokenOrRedirect::Atom(name));
state_stack.push(TokenOrRedirect::Atom(name)); },
}, Fixity::In => {
None => self.format_struct(arity, name, state_stack) state_stack.push(TokenOrRedirect::Redirect);
state_stack.push(TokenOrRedirect::Space);
state_stack.push(TokenOrRedirect::Atom(name));
state_stack.push(TokenOrRedirect::Space);
state_stack.push(TokenOrRedirect::Redirect);
} }
} }
} else if arity == 2 {
match self.op_dir.get(&(name.clone(), Fixity::In)) {
Some(_) => {
state_stack.push(TokenOrRedirect::Redirect);
state_stack.push(TokenOrRedirect::Space);
state_stack.push(TokenOrRedirect::Atom(name));
state_stack.push(TokenOrRedirect::Space);
state_stack.push(TokenOrRedirect::Redirect);
},
None => self.format_struct(arity, name, state_stack)
};
} else { } else {
self.format_struct(arity, name, state_stack); self.format_struct(arity, name, state_stack);
} }
@@ -110,8 +97,8 @@ impl<'a, Formatter: HeapCellValueFormatter> HeapCellPrinter<'a, Formatter>
fn handle_heap_term(&mut self, heap_val: HeapCellValue, result: &mut String) { fn handle_heap_term(&mut self, heap_val: HeapCellValue, result: &mut String) {
match heap_val { match heap_val {
HeapCellValue::NamedStr(arity, name) => HeapCellValue::NamedStr(arity, name, fixity) =>
self.formatter.format_clause(arity, name, &mut self.state_stack), self.formatter.format_clause(arity, name, fixity, &mut self.state_stack),
HeapCellValue::Addr(Addr::Con(Constant::EmptyList)) => HeapCellValue::Addr(Addr::Con(Constant::EmptyList)) =>
if !Self::at_cdr(result, "") { if !Self::at_cdr(result, "") {
*result += "[]"; *result += "[]";

View File

@@ -45,14 +45,14 @@ impl CodeOffsets {
pub fn index_term(&mut self, first_arg: &Term, index: usize) pub fn index_term(&mut self, first_arg: &Term, index: usize)
{ {
match first_arg { match first_arg {
&Term::Clause(_, ref name, ref terms) => { &Term::Clause(_, ref name, ref terms, _) => {
let code = self.structures.entry((name.clone(), terms.len())) let code = self.structures.entry((name.clone(), terms.len()))
.or_insert(Vec::new()); .or_insert(Vec::new());
let is_initial_index = code.is_empty(); let is_initial_index = code.is_empty();
code.push(Self::add_index(is_initial_index, index)); code.push(Self::add_index(is_initial_index, index));
}, },
&Term::Cons(_, _, _) => { &Term::Cons(..) => {
let is_initial_index = self.lists.is_empty(); let is_initial_index = self.lists.is_empty();
self.lists.push(Self::add_index(is_initial_index, index)); self.lists.push(Self::add_index(is_initial_index, index));
}, },

View File

@@ -21,9 +21,9 @@ impl fmt::Display for FactInstruction {
write!(f, "get_list A{}", r.reg_num()), write!(f, "get_list A{}", r.reg_num()),
&FactInstruction::GetList(Level::Deep, ref r) => &FactInstruction::GetList(Level::Deep, ref r) =>
write!(f, "get_list {}", r), write!(f, "get_list {}", r),
&FactInstruction::GetStructure(Level::Deep, ref name, ref arity, ref r) => &FactInstruction::GetStructure(Level::Deep, ref name, ref arity, ref r, _) =>
write!(f, "get_structure {}/{}, {}", name, arity, r), write!(f, "get_structure {}/{}, {}", name, arity, r),
&FactInstruction::GetStructure(Level::Shallow, ref name, ref arity, ref r) => &FactInstruction::GetStructure(Level::Shallow, ref name, ref arity, ref r, _) =>
write!(f, "get_structure {}/{}, A{}", name, arity, r.reg_num()), write!(f, "get_structure {}/{}, A{}", name, arity, r.reg_num()),
&FactInstruction::GetValue(ref x, ref a) => &FactInstruction::GetValue(ref x, ref a) =>
write!(f, "get_value {}, A{}", x, a), write!(f, "get_value {}, A{}", x, a),
@@ -56,9 +56,9 @@ impl fmt::Display for QueryInstruction {
write!(f, "put_list A{}", r.reg_num()), write!(f, "put_list A{}", r.reg_num()),
&QueryInstruction::PutList(Level::Deep, ref r) => &QueryInstruction::PutList(Level::Deep, ref r) =>
write!(f, "put_list {}", r), write!(f, "put_list {}", r),
&QueryInstruction::PutStructure(Level::Deep, ref name, ref arity, ref r) => &QueryInstruction::PutStructure(Level::Deep, ref name, ref arity, ref r, _) =>
write!(f, "put_structure {}/{}, {}", name, arity, r), write!(f, "put_structure {}/{}, {}", name, arity, r),
&QueryInstruction::PutStructure(Level::Shallow, ref name, ref arity, ref r) => &QueryInstruction::PutStructure(Level::Shallow, ref name, ref arity, ref r, _) =>
write!(f, "put_structure {}/{}, A{}", name, arity, r.reg_num()), write!(f, "put_structure {}/{}, A{}", name, arity, r.reg_num()),
&QueryInstruction::PutUnsafeValue(y, a) => &QueryInstruction::PutUnsafeValue(y, a) =>
write!(f, "put_unsafe_value Y{}, A{}", y, a), write!(f, "put_unsafe_value Y{}, A{}", y, a),

View File

@@ -17,9 +17,9 @@ impl<'a> QueryIterator<'a> {
let state = match term { let state = match term {
&Term::AnonVar => &Term::AnonVar =>
return QueryIterator { state_stack: vec![] }, return QueryIterator { state_stack: vec![] },
&Term::Clause(_, _, ref terms) => &Term::Clause(.., ref terms, _) =>
TermIterState::Clause(0, ClauseType::Root, terms), TermIterState::Clause(0, ClauseType::Root, terms),
&Term::Cons(_, _, _) => &Term::Cons(..) =>
return QueryIterator { state_stack: vec![] }, return QueryIterator { state_stack: vec![] },
&Term::Constant(_, _) => &Term::Constant(_, _) =>
return QueryIterator { state_stack: vec![] }, return QueryIterator { state_stack: vec![] },
@@ -84,7 +84,7 @@ impl<'a> Iterator for QueryIterator<'a> {
match ct { match ct {
ClauseType::CallN => ClauseType::CallN =>
self.push_subterm(Level::Shallow, child_terms[0].as_ref()), self.push_subterm(Level::Shallow, child_terms[0].as_ref()),
ClauseType::Deep(_, _, _) => ClauseType::Deep(..) =>
return Some(TermRef::Clause(ct, child_terms)), return Some(TermRef::Clause(ct, child_terms)),
_ => _ =>
return None return None
@@ -125,7 +125,7 @@ impl<'a> FactIterator<'a> {
let states = match term { let states = match term {
&Term::AnonVar => &Term::AnonVar =>
vec![TermIterState::AnonVar(Level::Shallow)], vec![TermIterState::AnonVar(Level::Shallow)],
&Term::Clause(_, _, ref terms) => &Term::Clause(.., ref terms, _) =>
vec![TermIterState::Clause(0, ClauseType::Root, terms)], vec![TermIterState::Clause(0, ClauseType::Root, terms)],
&Term::Cons(ref cell, ref head, ref tail) => &Term::Cons(ref cell, ref head, ref tail) =>
vec![TermIterState::InitialCons(Level::Shallow, vec![TermIterState::InitialCons(Level::Shallow,
@@ -156,7 +156,7 @@ impl<'a> Iterator for FactIterator<'a> {
} }
match ct { match ct {
ClauseType::Deep(_, _, _) => ClauseType::Deep(..) =>
return Some(TermRef::Clause(ct, child_terms)), return Some(TermRef::Clause(ct, child_terms)),
_ => _ =>
continue continue

View File

@@ -290,8 +290,8 @@ impl MachineState {
let r1 = &self.heap[a1]; let r1 = &self.heap[a1];
let r2 = &self.heap[a2]; let r2 = &self.heap[a2];
if let &HeapCellValue::NamedStr(n1, ref f1) = r1 { if let &HeapCellValue::NamedStr(n1, ref f1, _) = r1 {
if let &HeapCellValue::NamedStr(n2, ref f2) = r2 { if let &HeapCellValue::NamedStr(n2, ref f2, _) = r2 {
if n1 == n2 && *f1 == *f2 { if n1 == n2 && *f1 == *f2 {
for i in 1 .. n1 + 1 { for i in 1 .. n1 + 1 {
pdl.push(Addr::HeapCell(a1 + i)); pdl.push(Addr::HeapCell(a1 + i));
@@ -742,14 +742,14 @@ impl MachineState {
_ => self.fail = true _ => self.fail = true
}; };
}, },
&FactInstruction::GetStructure(_, ref name, arity, reg) => { &FactInstruction::GetStructure(_, ref name, arity, reg, fixity) => {
let addr = self.deref(self[reg].clone()); let addr = self.deref(self[reg].clone());
match self.store(addr.clone()) { match self.store(addr.clone()) {
Addr::Str(a) => { Addr::Str(a) => {
let result = &self.heap[a]; let result = &self.heap[a];
if let &HeapCellValue::NamedStr(narity, ref str) = result { if let &HeapCellValue::NamedStr(narity, ref str, _) = result {
if narity == arity && *name == *str { if narity == arity && *name == *str {
self.s = a + 1; self.s = a + 1;
self.mode = MachineMode::Read; self.mode = MachineMode::Read;
@@ -762,7 +762,7 @@ impl MachineState {
let h = self.heap.h; let h = self.heap.h;
self.heap.push(HeapCellValue::Addr(Addr::Str(h + 1))); self.heap.push(HeapCellValue::Addr(Addr::Str(h + 1)));
self.heap.push(HeapCellValue::NamedStr(arity, name.clone())); self.heap.push(HeapCellValue::NamedStr(arity, name.clone(), fixity));
self.bind(addr.as_var().unwrap(), Addr::HeapCell(h)); self.bind(addr.as_var().unwrap(), Addr::HeapCell(h));
@@ -911,7 +911,7 @@ impl MachineState {
let offset = match addr { let offset = match addr {
Addr::Str(s) => { Addr::Str(s) => {
if let &HeapCellValue::NamedStr(arity, ref name) = &self.heap[s] { if let &HeapCellValue::NamedStr(arity, ref name, _) = &self.heap[s] {
match hm.get(&(name.clone(), arity)) { match hm.get(&(name.clone(), arity)) {
Some(offset) => *offset, Some(offset) => *offset,
_ => 0 _ => 0
@@ -939,10 +939,10 @@ impl MachineState {
self[reg] = Addr::Con(constant.clone()), self[reg] = Addr::Con(constant.clone()),
&QueryInstruction::PutList(_, reg) => &QueryInstruction::PutList(_, reg) =>
self[reg] = Addr::Lis(self.heap.h), self[reg] = Addr::Lis(self.heap.h),
&QueryInstruction::PutStructure(_, ref name, arity, reg) => { &QueryInstruction::PutStructure(_, ref name, arity, reg, fixity) => {
let h = self.heap.h; let h = self.heap.h;
self.heap.push(HeapCellValue::NamedStr(arity, name.clone())); self.heap.push(HeapCellValue::NamedStr(arity, name.clone(), fixity));
self[reg] = Addr::Str(h); self[reg] = Addr::Str(h);
}, },
&QueryInstruction::PutUnsafeValue(n, arg) => { &QueryInstruction::PutUnsafeValue(n, arg) => {
@@ -1088,7 +1088,7 @@ impl MachineState {
Addr::Str(a) => { Addr::Str(a) => {
let result = self.heap[a].clone(); let result = self.heap[a].clone();
if let HeapCellValue::NamedStr(narity, name) = result { if let HeapCellValue::NamedStr(narity, name, _) = result {
if narity + arity > 63 { if narity + arity > 63 {
self.throw_exception(functor!("representation_error", self.throw_exception(functor!("representation_error",
1, 1,
@@ -1154,7 +1154,7 @@ impl MachineState {
if let Addr::Str(o) = a2 { if let Addr::Str(o) = a2 {
match self.heap[o].clone() { match self.heap[o].clone() {
HeapCellValue::NamedStr(arity, _) => HeapCellValue::NamedStr(arity, _, _) =>
match i.to_usize() { match i.to_usize() {
Some(i) if 1 <= i && i <= arity => { Some(i) if 1 <= i && i <= arity => {
let a3 = self[temp_v!(3)].clone(); let a3 = self[temp_v!(3)].clone();
@@ -1372,7 +1372,7 @@ impl MachineState {
match a1.clone() { match a1.clone() {
Addr::Str(o) => Addr::Str(o) =>
match self.heap[o].clone() { match self.heap[o].clone() {
HeapCellValue::NamedStr(arity, name) => { HeapCellValue::NamedStr(arity, name, _) => {
let name = Addr::Con(Constant::Atom(name)); // A2 let name = Addr::Con(Constant::Atom(name)); // A2
let arity = Addr::Con(Constant::Number(rc_integer!(arity))); let arity = Addr::Con(Constant::Number(rc_integer!(arity)));
@@ -1401,7 +1401,7 @@ impl MachineState {
} }
}; };
self.heap.push(HeapCellValue::NamedStr(arity, name)); self.heap.push(HeapCellValue::NamedStr(arity, name, None));
for _ in 0 .. arity { for _ in 0 .. arity {
let h = self.heap.h; let h = self.heap.h;

View File

@@ -68,7 +68,7 @@ impl Machine {
pub fn add_fact<'a>(&mut self, fact: &Term, mut code: Code) -> EvalSession<'a> pub fn add_fact<'a>(&mut self, fact: &Term, mut code: Code) -> EvalSession<'a>
{ {
match fact { match fact {
&Term::Clause(_, ref name, _) | &Term::Constant(_, Constant::Atom(ref name)) => { &Term::Clause(_, ref name, ..) | &Term::Constant(_, Constant::Atom(ref name)) => {
let p = self.code.len(); let p = self.code.len();
let arity = fact.arity(); let arity = fact.arity();
@@ -82,7 +82,7 @@ impl Machine {
pub fn add_rule<'a>(&mut self, rule: &Rule, mut code: Code) -> EvalSession<'a> pub fn add_rule<'a>(&mut self, rule: &Rule, mut code: Code) -> EvalSession<'a>
{ {
match &rule.head.0 { match &rule.head.0 {
&QueryTerm::Term(Term::Clause(_, ref name, _)) &QueryTerm::Term(Term::Clause(_, ref name, ..))
| &QueryTerm::Term(Term::Constant(_, Constant::Atom(ref name))) => { | &QueryTerm::Term(Term::Constant(_, Constant::Atom(ref name))) => {
let p = self.code.len(); let p = self.code.len();
let arity = rule.head.0.arity(); let arity = rule.head.0.arity();
@@ -347,7 +347,7 @@ impl Machine {
fn print_var(&self, r: Ref) -> String fn print_var(&self, r: Ref) -> String
{ {
let disp = TermFormatter::new(&self.op_dir); let disp = TermFormatter {};
let iter = HeapCellIterator::new(&self.ms, r); let iter = HeapCellIterator::new(&self.ms, r);
let mut printer = HeapCellPrinter::new(iter, disp); let mut printer = HeapCellPrinter::new(iter, disp);

View File

@@ -44,7 +44,7 @@ macro_rules! query {
macro_rules! functor { macro_rules! functor {
($name:expr, $len:expr, [$($args:expr),*]) => {{ ($name:expr, $len:expr, [$($args:expr),*]) => {{
if $len > 0 { if $len > 0 {
vec![ HeapCellValue::NamedStr($len, Rc::new(String::from($name))), $($args),* ] vec![ HeapCellValue::NamedStr($len, Rc::new(String::from($name)), None), $($args),* ]
} else { } else {
vec![ atom!($name) ] vec![ atom!($name) ]
} }
@@ -101,8 +101,8 @@ macro_rules! put_var {
} }
macro_rules! put_structure { macro_rules! put_structure {
($lvl:expr, $name:expr, $arity:expr, $r:expr) => ( ($lvl:expr, $name:expr, $arity:expr, $r:expr, $fix:expr) => (
QueryInstruction::PutStructure($lvl, Rc::new($name), $arity, $r) QueryInstruction::PutStructure($lvl, Rc::new($name), $arity, $r, $fix)
) )
} }
@@ -317,8 +317,8 @@ macro_rules! get_constant {
} }
macro_rules! get_structure { macro_rules! get_structure {
($atom:expr, $arity:expr, $r:expr) => ( ($atom:expr, $arity:expr, $r:expr, $fix:expr) => (
FactInstruction::GetStructure(Level::Shallow, Rc::new($atom), $arity, $r) FactInstruction::GetStructure(Level::Shallow, Rc::new($atom), $arity, $r, $fix)
) )
} }
@@ -387,3 +387,9 @@ macro_rules! rc_atom {
Rc::new(String::from($e)) Rc::new(String::from($e))
) )
} }
macro_rules! infix {
() => (
Fixity::In
)
}

View File

@@ -1,19 +1,27 @@
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashSet; use std::collections::HashSet;
use std::hash::Hash; use std::fmt;
use std::ops::Deref; use std::hash::{Hash, Hasher};
use std::ops::{Deref, DerefMut};
use std::rc::Rc; use std::rc::Rc;
pub type TabledData<T> = HashSet<Rc<T>>; pub type TabledData<T> = HashSet<Rc<T>>;
#[derive(Clone, PartialEq, Eq, Hash)] #[derive(Clone, PartialEq, Eq)]
pub struct TabledRc<T: Hash + Eq> { pub struct TabledRc<T: Hash + Eq> {
atom: Rc<T>, atom: Rc<T>,
table: Rc<RefCell<TabledData<T>>> table: Rc<RefCell<TabledData<T>>>
} }
impl<T: Hash + Eq> Hash for TabledRc<T> {
fn hash<H: Hasher>(&self, state: &mut H)
{
self.atom.hash(state)
}
}
impl<T: Hash + Eq> TabledRc<T> { impl<T: Hash + Eq> TabledRc<T> {
pub fn new(atom: T, table: Rc<RefCell<TabledData<T>>>) -> Self { pub fn new(atom: T, table: Rc<RefCell<TabledData<T>>>) -> Self {
TabledRc { atom: Rc::new(atom), table } TabledRc { atom: Rc::new(atom), table }
} }
} }
@@ -21,8 +29,8 @@ impl<T: Hash + Eq> TabledRc<T> {
impl<T: Hash + Eq> Drop for TabledRc<T> { impl<T: Hash + Eq> Drop for TabledRc<T> {
fn drop(&mut self) { fn drop(&mut self) {
if Rc::strong_count(&self.atom) == 2 { if Rc::strong_count(&self.atom) == 2 {
let table = *self.table.borrow_mut(); let mut table = self.table.borrow_mut();
table.remove(&self.atom); table.deref_mut().remove(&self.atom);
} }
} }
} }
@@ -34,3 +42,9 @@ impl<T: Hash + Eq> Deref for TabledRc<T> {
&*self.atom &*self.atom
} }
} }
impl<T: Hash + Eq + fmt::Display> fmt::Display for TabledRc<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", &*self.atom)
}
}

View File

@@ -10,7 +10,7 @@ pub trait CompilationTarget<'a> {
fn to_constant(Level, Constant, RegType) -> Self; fn to_constant(Level, Constant, RegType) -> Self;
fn to_list(Level, RegType) -> Self; fn to_list(Level, RegType) -> Self;
fn to_structure(Level, Rc<Atom>, usize, RegType) -> Self; fn to_structure(Level, Rc<Atom>, usize, RegType, Option<Fixity>) -> Self;
fn to_void(usize) -> Self; fn to_void(usize) -> Self;
fn is_void_instr(&self) -> bool; fn is_void_instr(&self) -> bool;
@@ -41,8 +41,10 @@ impl<'a> CompilationTarget<'a> for FactInstruction {
FactInstruction::GetConstant(lvl, constant, reg) FactInstruction::GetConstant(lvl, constant, reg)
} }
fn to_structure(lvl: Level, atom: Rc<Atom>, arity: usize, reg: RegType) -> Self { fn to_structure(lvl: Level, atom: Rc<Atom>, arity: usize, reg: RegType, fixity: Option<Fixity>)
FactInstruction::GetStructure(lvl, atom, arity, reg) -> Self
{
FactInstruction::GetStructure(lvl, atom, arity, reg, fixity)
} }
fn to_list(lvl: Level, reg: RegType) -> Self { fn to_list(lvl: Level, reg: RegType) -> Self {
@@ -103,8 +105,10 @@ impl<'a> CompilationTarget<'a> for QueryInstruction {
term.post_order_iter() term.post_order_iter()
} }
fn to_structure(lvl: Level, atom: Rc<Atom>, arity: usize, reg: RegType) -> Self { fn to_structure(lvl: Level, atom: Rc<Atom>, arity: usize, reg: RegType, fixity: Option<Fixity>)
QueryInstruction::PutStructure(lvl, atom, arity, reg) -> Self
{
QueryInstruction::PutStructure(lvl, atom, arity, reg, fixity)
} }
fn to_constant(lvl: Level, constant: Constant, reg: RegType) -> Self { fn to_constant(lvl: Level, constant: Constant, reg: RegType) -> Self {