From: Mark Thom Date: Mon, 15 Jan 2018 04:48:10 +0000 (-0700) Subject: mark structures with their fixity X-Git-Tag: v0.8.110~629 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=58ba3682804b8b76d88a35f9592e7db9268d7dcc;p=scryer-prolog.git mark structures with their fixity --- diff --git a/src/prolog/arithmetic.rs b/src/prolog/arithmetic.rs index 4d16c4f7..b6cc97cf 100644 --- a/src/prolog/arithmetic.rs +++ b/src/prolog/arithmetic.rs @@ -19,7 +19,7 @@ impl<'a> ArithExprIterator<'a> { let state = match term { &Term::AnonVar => return Err(ArithmeticError::InvalidTerm), - &Term::Clause(_, _, ref terms) => + &Term::Clause(_, _, ref terms, _) => TermIterState::Clause(0, ClauseType::Root, terms), &Term::Constant(ref cell, ref cons) => TermIterState::Constant(Level::Shallow, cell, cons), @@ -199,7 +199,7 @@ impl<'a> ArithmeticEvaluator<'a> { 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)?)); }, TermRef::Clause(ClauseType::Root, terms) => { diff --git a/src/prolog/ast.rs b/src/prolog/ast.rs index cdb5afd3..61572fd4 100644 --- a/src/prolog/ast.rs +++ b/src/prolog/ast.rs @@ -298,7 +298,7 @@ impl fmt::Display for Constant { pub enum Term { AnonVar, - Clause(Cell, Rc, Vec>), + Clause(Cell, Rc, Vec>, Option), Cons(Cell, Box, Box), Constant(Cell, Constant), Var(Cell, Rc) @@ -369,7 +369,7 @@ pub struct Rule { pub enum ClauseType<'a> { CallN, Catch, - Deep(Level, &'a Cell, &'a Rc), + Deep(Level, &'a Cell, &'a Rc, Option), Is, Root, Throw, @@ -378,7 +378,7 @@ pub enum ClauseType<'a> { impl<'a> ClauseType<'a> { pub fn level_of_subterms(self) -> Level { match self { - ClauseType::Deep(_, _, _) => Level::Deep, + ClauseType::Deep(..) => Level::Deep, _ => Level::Shallow } } @@ -397,10 +397,10 @@ impl<'a> TermRef<'a> { pub fn level(self) -> Level { match self { TermRef::AnonVar(lvl) - | TermRef::Cons(lvl, _, _, _) - | TermRef::Constant(lvl, _, _) - | TermRef::Var(lvl, _, _) => lvl, - TermRef::Clause(ClauseType::Deep(lvl, _, _), _) => lvl, + | TermRef::Cons(lvl, ..) + | TermRef::Constant(lvl, ..) + | TermRef::Var(lvl, ..) => lvl, + TermRef::Clause(ClauseType::Deep(lvl, ..), ..) => lvl, _ => Level::Shallow } } @@ -798,7 +798,7 @@ impl From for Line { pub enum FactInstruction { GetConstant(Level, Constant, RegType), GetList(Level, RegType), - GetStructure(Level, Rc, usize, RegType), + GetStructure(Level, Rc, usize, RegType, Option), GetValue(RegType, usize), GetVariable(RegType, usize), UnifyConstant(Constant), @@ -812,7 +812,7 @@ pub enum QueryInstruction { GetVariable(RegType, usize), PutConstant(Level, Constant, RegType), PutList(Level, RegType), - PutStructure(Level, Rc, usize, RegType), + PutStructure(Level, Rc, usize, RegType, Option), PutUnsafeValue(usize, usize), PutValue(RegType, usize), PutVariable(RegType, usize), @@ -896,14 +896,14 @@ pub enum Ref { #[derive(Clone, PartialEq)] pub enum HeapCellValue { Addr(Addr), - NamedStr(usize, Rc), // arity, name. + NamedStr(usize, Rc, Option), // arity, name. } impl HeapCellValue { pub fn as_addr(&self, focus: usize) -> Addr { match self { &HeapCellValue::Addr(ref a) => a.clone(), - &HeapCellValue::NamedStr(_, _) => Addr::Str(focus) + &HeapCellValue::NamedStr(_, _, _) => Addr::Str(focus) } } } @@ -1010,7 +1010,7 @@ pub type Registers = Vec; impl Term { pub fn first_arg(&self) -> Option<&Term> { match self { - &Term::Clause(_, _, ref terms) => + &Term::Clause(_, _, ref terms, _) => terms.first().map(|bt| bt.as_ref()), _ => None } @@ -1018,7 +1018,7 @@ impl Term { pub fn is_callable(&self) -> bool { match self { - &Term::Clause(_, _, _) | &Term::Constant(_, Constant::Atom(_)) => + &Term::Clause(..) | &Term::Constant(_, Constant::Atom(_)) => true, _ => false } @@ -1027,14 +1027,14 @@ impl Term { pub fn name(&self) -> Option> { match self { &Term::Constant(_, Constant::Atom(ref atom)) - | &Term::Clause(_, ref atom, _) => Some(atom.clone()), + | &Term::Clause(_, ref atom, ..) => Some(atom.clone()), _ => None } } pub fn arity(&self) -> usize { match self { - &Term::Clause(_, _, ref child_terms) => child_terms.len(), + &Term::Clause(_, _, ref child_terms, ..) => child_terms.len(), _ => 0 } } @@ -1054,8 +1054,8 @@ impl<'a> TermIterState<'a> { match term { &Term::AnonVar => TermIterState::AnonVar(lvl), - &Term::Clause(ref cell, ref atom, ref child_terms) => - TermIterState::Clause(0, ClauseType::Deep(lvl, cell, atom), child_terms), + &Term::Clause(ref cell, ref atom, ref child_terms, fixity) => + TermIterState::Clause(0, ClauseType::Deep(lvl, cell, atom, fixity), child_terms), &Term::Cons(ref cell, ref head, ref tail) => TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref()), &Term::Constant(ref cell, ref constant) => diff --git a/src/prolog/builtins.rs b/src/prolog/builtins.rs index 73cac026..d87ac5b2 100644 --- a/src/prolog/builtins.rs +++ b/src/prolog/builtins.rs @@ -115,7 +115,7 @@ fn get_builtins() -> Code { trust!(10), try_me_else!(4), 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!(2))], set_cp!(temp_v!(3)), @@ -132,7 +132,7 @@ fn get_builtins() -> Code { execute_n!(1), retry_me_else!(8), 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!(1)), get_var_in_fact!(perm_v!(3), 3)], @@ -167,12 +167,12 @@ fn get_builtins() -> Code { indexed_try!(3), trust!(5), 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!(2))], goto!(139, 3), 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)], query![put_value!(temp_v!(2), 1)], neck_cut!(), @@ -234,7 +234,8 @@ fn get_builtins() -> Code { put_structure!(Level::Shallow, String::from("type_error"), 1, - temp_v!(1)), + temp_v!(1), + None), set_constant!(Constant::Atom(rc_atom!("integer_expected")))], goto!(59, 1), // goto throw/1. try_me_else!(5), // arg_/3, 173. diff --git a/src/prolog/codegen.rs b/src/prolog/codegen.rs index 075ac3bb..9251622a 100644 --- a/src/prolog/codegen.rs +++ b/src/prolog/codegen.rs @@ -130,7 +130,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> self.marker.mark_anon_var(Level::Deep, target), &Term::AnonVar => 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); 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> { match ct { - ClauseType::Deep(lvl, cell, atom) => { + ClauseType::Deep(lvl, cell, atom, fixity) => { 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 { 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); 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); code.push(Line::Control(call)); }, @@ -317,10 +318,10 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> }, &InlinedQueryTerm::IsAtomic(ref inner_term) => match inner_term[0].as_ref() { - &Term::AnonVar | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => { + &Term::AnonVar | &Term::Clause(..) | &Term::Cons(..) => { code.push(fail!()); }, - &Term::Constant(_, _) => { + &Term::Constant(..) => { code.push(succeed!()); }, &Term::Var(ref vr, ref name) => { @@ -343,7 +344,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> }, &InlinedQueryTerm::IsVar(ref inner_term) => match inner_term[0].as_ref() { - &Term::Constant(_, _) | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => { + &Term::Constant(..) | &Term::Clause(..) | &Term::Cons(..) => { code.push(fail!()); }, &Term::AnonVar => { @@ -482,7 +483,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> self.compile_seq_prelude(&conjunct_info, &mut code); if let &QueryTerm::Term(ref term) = p0 { - if let &Term::Clause(_, _, _) = term { + if let &Term::Clause(..) = term { let iter = FactInstruction::iter(term); 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(); - if let &Term::Clause(_, _, _) = term { + if let &Term::Clause(..) = term { let iter = FactInstruction::iter(term); let mut compiled_fact = self.compile_target(iter, GenContext::Head, false); diff --git a/src/prolog/copier.rs b/src/prolog/copier.rs index cdf7e192..6c598543 100644 --- a/src/prolog/copier.rs +++ b/src/prolog/copier.rs @@ -25,7 +25,7 @@ pub trait CopierTarget while scan < self.threshold() { match self[scan].clone() { - HeapCellValue::NamedStr(_, _) => + HeapCellValue::NamedStr(_, _, _) => scan += 1, HeapCellValue::Addr(a) => match a.clone() { @@ -69,16 +69,16 @@ pub trait CopierTarget }, Addr::Str(s) => { match self[s].clone() { - HeapCellValue::NamedStr(arity, name) => { + HeapCellValue::NamedStr(arity, name, fixity) => { let threshold = self.threshold(); self[scan] = HeapCellValue::Addr(Addr::Str(threshold)); self[s] = HeapCellValue::Addr(Addr::Str(threshold)); 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 { let hcv = self[s + 1 + i].clone(); diff --git a/src/prolog/heap_iter.rs b/src/prolog/heap_iter.rs index ec830e0c..99f0b1cf 100644 --- a/src/prolog/heap_iter.rs +++ b/src/prolog/heap_iter.rs @@ -34,7 +34,7 @@ impl<'a> HeapCellIterator<'a> { fn follow_heap(&mut self, h: usize) -> Addr { match &self.machine_st.heap[h] { - &HeapCellValue::NamedStr(arity, _) => { + &HeapCellValue::NamedStr(arity, _, _) => { for idx in (1 .. arity + 1).rev() { self.state_stack.push(Ref::HeapCell(h + idx)); } diff --git a/src/prolog/heap_print.rs b/src/prolog/heap_print.rs index af9c91ca..67989799 100644 --- a/src/prolog/heap_print.rs +++ b/src/prolog/heap_print.rs @@ -1,5 +1,4 @@ use prolog::ast::*; -use prolog::builtins::*; use prolog::heap_iter::*; 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 // format_struct when convenient. - fn format_clause(&self, arity: usize, name: Rc, state_stack: &mut Vec); + fn format_clause(&self, usize, Rc, Option, &mut Vec); } // the 'classic' display corresponding to the display predicate. pub struct DisplayFormatter {} impl HeapCellValueFormatter for DisplayFormatter { - fn format_clause(&self, arity: usize, name: Rc, state_stack: &mut Vec) + fn format_clause(&self, arity: usize, name: Rc, _: Option, + state_stack: &mut Vec) { self.format_struct(arity, name, state_stack); } } -pub struct TermFormatter<'a> { - op_dir: &'a OpDir -} - -impl<'a> TermFormatter<'a> { - pub fn new(op_dir: &'a OpDir) -> Self { - TermFormatter { op_dir } - } -} +pub struct TermFormatter {} -impl<'a> HeapCellValueFormatter for TermFormatter<'a> { - fn format_clause(&self, arity: usize, name: Rc, state_stack: &mut Vec) { - if arity == 1 { - match self.op_dir.get(&(name.clone(), Fixity::Post)) { - Some(_) => { +impl HeapCellValueFormatter for TermFormatter { + fn format_clause(&self, arity: usize, name: Rc, fixity: Option, + state_stack: &mut Vec) + { + if let Some(fixity) = fixity { + match fixity { + Fixity::Post => { state_stack.push(TokenOrRedirect::Atom(name)); state_stack.push(TokenOrRedirect::Space); state_stack.push(TokenOrRedirect::Redirect); }, - None => match self.op_dir.get(&(name.clone(), Fixity::Pre)) { - Some(_) => { - state_stack.push(TokenOrRedirect::Redirect); - state_stack.push(TokenOrRedirect::Space); - state_stack.push(TokenOrRedirect::Atom(name)); - }, - None => self.format_struct(arity, name, state_stack) - } - } - } else if arity == 2 { - match self.op_dir.get(&(name.clone(), Fixity::In)) { - Some(_) => { + Fixity::Pre => { + state_stack.push(TokenOrRedirect::Redirect); + state_stack.push(TokenOrRedirect::Space); + state_stack.push(TokenOrRedirect::Atom(name)); + }, + Fixity::In => { 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 { 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) { match heap_val { - HeapCellValue::NamedStr(arity, name) => - self.formatter.format_clause(arity, name, &mut self.state_stack), + HeapCellValue::NamedStr(arity, name, fixity) => + self.formatter.format_clause(arity, name, fixity, &mut self.state_stack), HeapCellValue::Addr(Addr::Con(Constant::EmptyList)) => if !Self::at_cdr(result, "") { *result += "[]"; diff --git a/src/prolog/indexing.rs b/src/prolog/indexing.rs index 35b10011..b2b10afc 100644 --- a/src/prolog/indexing.rs +++ b/src/prolog/indexing.rs @@ -45,14 +45,14 @@ impl CodeOffsets { pub fn index_term(&mut self, first_arg: &Term, index: usize) { match first_arg { - &Term::Clause(_, ref name, ref terms) => { + &Term::Clause(_, ref name, ref terms, _) => { let code = self.structures.entry((name.clone(), terms.len())) .or_insert(Vec::new()); let is_initial_index = code.is_empty(); code.push(Self::add_index(is_initial_index, index)); }, - &Term::Cons(_, _, _) => { + &Term::Cons(..) => { let is_initial_index = self.lists.is_empty(); self.lists.push(Self::add_index(is_initial_index, index)); }, diff --git a/src/prolog/io.rs b/src/prolog/io.rs index 2175959f..8cbb748f 100644 --- a/src/prolog/io.rs +++ b/src/prolog/io.rs @@ -21,9 +21,9 @@ impl fmt::Display for FactInstruction { write!(f, "get_list A{}", r.reg_num()), &FactInstruction::GetList(Level::Deep, ref 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), - &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()), &FactInstruction::GetValue(ref x, ref 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()), &QueryInstruction::PutList(Level::Deep, ref 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), - &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()), &QueryInstruction::PutUnsafeValue(y, a) => write!(f, "put_unsafe_value Y{}, A{}", y, a), diff --git a/src/prolog/iterators.rs b/src/prolog/iterators.rs index 26a7c0fa..52293a1b 100644 --- a/src/prolog/iterators.rs +++ b/src/prolog/iterators.rs @@ -17,9 +17,9 @@ impl<'a> QueryIterator<'a> { let state = match term { &Term::AnonVar => return QueryIterator { state_stack: vec![] }, - &Term::Clause(_, _, ref terms) => + &Term::Clause(.., ref terms, _) => TermIterState::Clause(0, ClauseType::Root, terms), - &Term::Cons(_, _, _) => + &Term::Cons(..) => return QueryIterator { state_stack: vec![] }, &Term::Constant(_, _) => return QueryIterator { state_stack: vec![] }, @@ -84,7 +84,7 @@ impl<'a> Iterator for QueryIterator<'a> { match ct { ClauseType::CallN => self.push_subterm(Level::Shallow, child_terms[0].as_ref()), - ClauseType::Deep(_, _, _) => + ClauseType::Deep(..) => return Some(TermRef::Clause(ct, child_terms)), _ => return None @@ -125,7 +125,7 @@ impl<'a> FactIterator<'a> { let states = match term { &Term::AnonVar => vec![TermIterState::AnonVar(Level::Shallow)], - &Term::Clause(_, _, ref terms) => + &Term::Clause(.., ref terms, _) => vec![TermIterState::Clause(0, ClauseType::Root, terms)], &Term::Cons(ref cell, ref head, ref tail) => vec![TermIterState::InitialCons(Level::Shallow, @@ -156,7 +156,7 @@ impl<'a> Iterator for FactIterator<'a> { } match ct { - ClauseType::Deep(_, _, _) => + ClauseType::Deep(..) => return Some(TermRef::Clause(ct, child_terms)), _ => continue diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index fe28879e..36cb2e03 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -290,8 +290,8 @@ impl MachineState { let r1 = &self.heap[a1]; let r2 = &self.heap[a2]; - if let &HeapCellValue::NamedStr(n1, ref f1) = r1 { - if let &HeapCellValue::NamedStr(n2, ref f2) = r2 { + if let &HeapCellValue::NamedStr(n1, ref f1, _) = r1 { + if let &HeapCellValue::NamedStr(n2, ref f2, _) = r2 { if n1 == n2 && *f1 == *f2 { for i in 1 .. n1 + 1 { pdl.push(Addr::HeapCell(a1 + i)); @@ -742,14 +742,14 @@ impl MachineState { _ => self.fail = true }; }, - &FactInstruction::GetStructure(_, ref name, arity, reg) => { + &FactInstruction::GetStructure(_, ref name, arity, reg, fixity) => { let addr = self.deref(self[reg].clone()); match self.store(addr.clone()) { Addr::Str(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 { self.s = a + 1; self.mode = MachineMode::Read; @@ -762,7 +762,7 @@ impl MachineState { let h = self.heap.h; 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)); @@ -911,7 +911,7 @@ impl MachineState { let offset = match addr { 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)) { Some(offset) => *offset, _ => 0 @@ -939,10 +939,10 @@ impl MachineState { self[reg] = Addr::Con(constant.clone()), &QueryInstruction::PutList(_, reg) => 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; - self.heap.push(HeapCellValue::NamedStr(arity, name.clone())); + self.heap.push(HeapCellValue::NamedStr(arity, name.clone(), fixity)); self[reg] = Addr::Str(h); }, &QueryInstruction::PutUnsafeValue(n, arg) => { @@ -1088,7 +1088,7 @@ impl MachineState { Addr::Str(a) => { let result = self.heap[a].clone(); - if let HeapCellValue::NamedStr(narity, name) = result { + if let HeapCellValue::NamedStr(narity, name, _) = result { if narity + arity > 63 { self.throw_exception(functor!("representation_error", 1, @@ -1154,7 +1154,7 @@ impl MachineState { if let Addr::Str(o) = a2 { match self.heap[o].clone() { - HeapCellValue::NamedStr(arity, _) => + HeapCellValue::NamedStr(arity, _, _) => match i.to_usize() { Some(i) if 1 <= i && i <= arity => { let a3 = self[temp_v!(3)].clone(); @@ -1372,7 +1372,7 @@ impl MachineState { match a1.clone() { Addr::Str(o) => match self.heap[o].clone() { - HeapCellValue::NamedStr(arity, name) => { + HeapCellValue::NamedStr(arity, name, _) => { let name = Addr::Con(Constant::Atom(name)); // A2 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 { let h = self.heap.h; diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 367fd859..7fe8d2bd 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -68,7 +68,7 @@ impl Machine { pub fn add_fact<'a>(&mut self, fact: &Term, mut code: Code) -> EvalSession<'a> { 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 arity = fact.arity(); @@ -82,7 +82,7 @@ impl Machine { pub fn add_rule<'a>(&mut self, rule: &Rule, mut code: Code) -> EvalSession<'a> { match &rule.head.0 { - &QueryTerm::Term(Term::Clause(_, ref name, _)) + &QueryTerm::Term(Term::Clause(_, ref name, ..)) | &QueryTerm::Term(Term::Constant(_, Constant::Atom(ref name))) => { let p = self.code.len(); let arity = rule.head.0.arity(); @@ -347,7 +347,7 @@ impl Machine { 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 mut printer = HeapCellPrinter::new(iter, disp); diff --git a/src/prolog/macros.rs b/src/prolog/macros.rs index 91e0bc23..b5b11d18 100644 --- a/src/prolog/macros.rs +++ b/src/prolog/macros.rs @@ -44,7 +44,7 @@ macro_rules! query { macro_rules! functor { ($name:expr, $len:expr, [$($args:expr),*]) => {{ 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 { vec![ atom!($name) ] } @@ -101,8 +101,8 @@ macro_rules! put_var { } macro_rules! put_structure { - ($lvl:expr, $name:expr, $arity:expr, $r:expr) => ( - QueryInstruction::PutStructure($lvl, Rc::new($name), $arity, $r) + ($lvl:expr, $name:expr, $arity:expr, $r:expr, $fix:expr) => ( + QueryInstruction::PutStructure($lvl, Rc::new($name), $arity, $r, $fix) ) } @@ -317,8 +317,8 @@ macro_rules! get_constant { } macro_rules! get_structure { - ($atom:expr, $arity:expr, $r:expr) => ( - FactInstruction::GetStructure(Level::Shallow, Rc::new($atom), $arity, $r) + ($atom:expr, $arity:expr, $r:expr, $fix:expr) => ( + FactInstruction::GetStructure(Level::Shallow, Rc::new($atom), $arity, $r, $fix) ) } @@ -387,3 +387,9 @@ macro_rules! rc_atom { Rc::new(String::from($e)) ) } + +macro_rules! infix { + () => ( + Fixity::In + ) +} diff --git a/src/prolog/parser b/src/prolog/parser index 171e1f6d..159f82cd 160000 --- a/src/prolog/parser +++ b/src/prolog/parser @@ -1 +1 @@ -Subproject commit 171e1f6d6ff8ef5b916cc57062958295a1203895 +Subproject commit 159f82cd836192cc1970187b67b2fb44ef7e6c68 diff --git a/src/prolog/tabled_rc.rs b/src/prolog/tabled_rc.rs index 7e34883c..e16386c7 100644 --- a/src/prolog/tabled_rc.rs +++ b/src/prolog/tabled_rc.rs @@ -1,19 +1,27 @@ use std::cell::RefCell; use std::collections::HashSet; -use std::hash::Hash; -use std::ops::Deref; +use std::fmt; +use std::hash::{Hash, Hasher}; +use std::ops::{Deref, DerefMut}; use std::rc::Rc; pub type TabledData = HashSet>; -#[derive(Clone, PartialEq, Eq, Hash)] +#[derive(Clone, PartialEq, Eq)] pub struct TabledRc { atom: Rc, table: Rc>> } +impl Hash for TabledRc { + fn hash(&self, state: &mut H) + { + self.atom.hash(state) + } +} + impl TabledRc { - pub fn new(atom: T, table: Rc>>) -> Self { + pub fn new(atom: T, table: Rc>>) -> Self { TabledRc { atom: Rc::new(atom), table } } } @@ -21,8 +29,8 @@ impl TabledRc { impl Drop for TabledRc { fn drop(&mut self) { if Rc::strong_count(&self.atom) == 2 { - let table = *self.table.borrow_mut(); - table.remove(&self.atom); + let mut table = self.table.borrow_mut(); + table.deref_mut().remove(&self.atom); } } } @@ -34,3 +42,9 @@ impl Deref for TabledRc { &*self.atom } } + +impl fmt::Display for TabledRc { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", &*self.atom) + } +} diff --git a/src/prolog/targets.rs b/src/prolog/targets.rs index e08d4717..852094c1 100644 --- a/src/prolog/targets.rs +++ b/src/prolog/targets.rs @@ -10,7 +10,7 @@ pub trait CompilationTarget<'a> { fn to_constant(Level, Constant, RegType) -> Self; fn to_list(Level, RegType) -> Self; - fn to_structure(Level, Rc, usize, RegType) -> Self; + fn to_structure(Level, Rc, usize, RegType, Option) -> Self; fn to_void(usize) -> Self; fn is_void_instr(&self) -> bool; @@ -41,8 +41,10 @@ impl<'a> CompilationTarget<'a> for FactInstruction { FactInstruction::GetConstant(lvl, constant, reg) } - fn to_structure(lvl: Level, atom: Rc, arity: usize, reg: RegType) -> Self { - FactInstruction::GetStructure(lvl, atom, arity, reg) + fn to_structure(lvl: Level, atom: Rc, arity: usize, reg: RegType, fixity: Option) + -> Self + { + FactInstruction::GetStructure(lvl, atom, arity, reg, fixity) } fn to_list(lvl: Level, reg: RegType) -> Self { @@ -103,8 +105,10 @@ impl<'a> CompilationTarget<'a> for QueryInstruction { term.post_order_iter() } - fn to_structure(lvl: Level, atom: Rc, arity: usize, reg: RegType) -> Self { - QueryInstruction::PutStructure(lvl, atom, arity, reg) + fn to_structure(lvl: Level, atom: Rc, arity: usize, reg: RegType, fixity: Option) + -> Self + { + QueryInstruction::PutStructure(lvl, atom, arity, reg, fixity) } fn to_constant(lvl: Level, constant: Constant, reg: RegType) -> Self {