clean up arithmetic.rs

This commit is contained in:
Mark Thom
2018-01-18 19:54:15 -07:00
parent 8f012ecfd3
commit 1b402b2673
3 changed files with 69 additions and 57 deletions

View File

@@ -1,6 +1,5 @@
use prolog::ast::*; use prolog::ast::*;
use prolog::fixtures::*; use prolog::fixtures::*;
use prolog::tabled_rc::*;
use std::cell::Cell; use std::cell::Cell;
use std::cmp::{min, max}; use std::cmp::{min, max};
@@ -21,8 +20,8 @@ impl<'a> ArithInstructionIterator<'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 name, ref terms, _) =>
TermIterState::Clause(0, ClauseType::Root, terms), TermIterState::Clause(0, ClauseType::Root(name), 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),
&Term::Cons(_, _, _) => &Term::Cons(_, _, _) =>
@@ -37,7 +36,7 @@ impl<'a> ArithInstructionIterator<'a> {
pub enum ArithTermRef<'a> { pub enum ArithTermRef<'a> {
Constant(&'a Constant), Constant(&'a Constant),
Op(ClauseType<'a>, &'a Vec<Box<Term>>), Op(&'a str, usize), // name, arity.
Var(&'a Cell<VarReg>, &'a Var) Var(&'a Cell<VarReg>, &'a Var)
} }
@@ -50,8 +49,10 @@ impl<'a> Iterator for ArithInstructionIterator<'a> {
TermIterState::AnonVar(_) => TermIterState::AnonVar(_) =>
return Some(Err(ArithmeticError::UninstantiatedVar)), return Some(Err(ArithmeticError::UninstantiatedVar)),
TermIterState::Clause(child_num, ct, child_terms) => { TermIterState::Clause(child_num, ct, child_terms) => {
if child_num == child_terms.len() { let arity = child_terms.len();
return Some(Ok(ArithTermRef::Op(ct, child_terms)));
if child_num == arity {
return Some(Ok(ArithTermRef::Op(ct.name(), arity)));
} else { } else {
self.state_stack.push(TermIterState::Clause(child_num + 1, ct, child_terms)); self.state_stack.push(TermIterState::Clause(child_num + 1, ct, child_terms));
self.push_subterm(ct.level_of_subterms(), child_terms[child_num].as_ref()); self.push_subterm(ct.level_of_subterms(), child_terms[child_num].as_ref());
@@ -80,7 +81,6 @@ pub trait ArithmeticTermIter<'a> {
type Iter : Iterator<Item=Result<ArithTermRef<'a>, ArithmeticError>>; type Iter : Iterator<Item=Result<ArithTermRef<'a>, ArithmeticError>>;
fn iter(&self) -> Result<Self::Iter, ArithmeticError>; fn iter(&self) -> Result<Self::Iter, ArithmeticError>;
fn root_name(&self) -> Result<TabledRc<Atom>, ArithmeticError>;
} }
impl<'a> ArithmeticTermIter<'a> for &'a Term { impl<'a> ArithmeticTermIter<'a> for &'a Term {
@@ -89,13 +89,6 @@ impl<'a> ArithmeticTermIter<'a> for &'a Term {
fn iter(&self) -> Result<Self::Iter, ArithmeticError> { fn iter(&self) -> Result<Self::Iter, ArithmeticError> {
ArithInstructionIterator::new(self) ArithInstructionIterator::new(self)
} }
fn root_name(&self) -> Result<TabledRc<Atom>, ArithmeticError> {
match self {
&&Term::Clause(_, ref name, _, _) => Ok(name.clone()),
_ => Err(ArithmeticError::InvalidTerm)
}
}
} }
impl<'a> ArithmeticEvaluator<'a> impl<'a> ArithmeticEvaluator<'a>
@@ -104,19 +97,19 @@ impl<'a> ArithmeticEvaluator<'a>
ArithmeticEvaluator { bindings, interm: Vec::new(), interm_c: target_int } ArithmeticEvaluator { bindings, interm: Vec::new(), interm_c: target_int }
} }
fn get_unary_instr(name: &Atom, a1: ArithmeticTerm, t: usize) fn get_unary_instr(name: &str, a1: ArithmeticTerm, t: usize)
-> Result<ArithmeticInstruction, ArithmeticError> -> Result<ArithmeticInstruction, ArithmeticError>
{ {
match name.as_str() { match name {
"-" => Ok(ArithmeticInstruction::Neg(a1, t)), "-" => Ok(ArithmeticInstruction::Neg(a1, t)),
_ => Err(ArithmeticError::InvalidOp) _ => Err(ArithmeticError::InvalidOp)
} }
} }
fn get_binary_instr(name: &Atom, a1: ArithmeticTerm, a2: ArithmeticTerm, t: usize) fn get_binary_instr(name: &str, a1: ArithmeticTerm, a2: ArithmeticTerm, t: usize)
-> Result<ArithmeticInstruction, ArithmeticError> -> Result<ArithmeticInstruction, ArithmeticError>
{ {
match name.as_str() { match name {
"+" => Ok(ArithmeticInstruction::Add(a1, a2, t)), "+" => Ok(ArithmeticInstruction::Add(a1, a2, t)),
"-" => Ok(ArithmeticInstruction::Sub(a1, a2, t)), "-" => Ok(ArithmeticInstruction::Sub(a1, a2, t)),
"/" => Ok(ArithmeticInstruction::Div(a1, a2, t)), "/" => Ok(ArithmeticInstruction::Div(a1, a2, t)),
@@ -144,10 +137,10 @@ impl<'a> ArithmeticEvaluator<'a>
temp temp
} }
fn instr_from_clause(&mut self, name: &Atom, terms: &Vec<Box<Term>>) fn instr_from_clause(&mut self, name: &str, arity: usize)
-> Result<ArithmeticInstruction, ArithmeticError> -> Result<ArithmeticInstruction, ArithmeticError>
{ {
match terms.len() { match arity {
1 => { 1 => {
let a1 = self.interm.pop().unwrap(); let a1 = self.interm.pop().unwrap();
@@ -221,15 +214,9 @@ impl<'a> ArithmeticEvaluator<'a>
self.interm.push(ArithmeticTerm::Reg(r)); self.interm.push(ArithmeticTerm::Reg(r));
}, },
ArithTermRef::Op(ClauseType::Deep(_, _, name, _), terms) => { ArithTermRef::Op(name, arity) => {
code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?)); code.push(Line::Arithmetic(self.instr_from_clause(&*name, arity)?));
}, }
ArithTermRef::Op(ClauseType::Root, terms) => {
let name = src.root_name()?;
code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?));
},
_ =>
return Err(ArithmeticError::InvalidTerm)
} }
} }

View File

@@ -366,15 +366,34 @@ pub struct Rule {
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum ClauseType<'a> { pub enum ClauseType<'a> {
Arg,
CallN, CallN,
Catch, Catch,
Deep(Level, &'a Cell<RegType>, &'a TabledRc<Atom>, Option<Fixity>), Deep(Level, &'a Cell<RegType>, &'a TabledRc<Atom>, Option<Fixity>),
Display,
DuplicateTerm,
Functor,
Is, Is,
Root, Root(&'a TabledRc<Atom>),
Throw, Throw,
} }
impl<'a> ClauseType<'a> { impl<'a> ClauseType<'a> {
pub fn name(&self) -> &'a str {
match self {
&ClauseType::Arg => "arg",
&ClauseType::CallN => "call",
&ClauseType::Catch => "catch",
&ClauseType::Deep(_, _, name, _) => name.as_str(),
&ClauseType::Display => "display",
&ClauseType::DuplicateTerm => "duplicate_term",
&ClauseType::Functor => "functor",
&ClauseType::Is => "is",
&ClauseType::Root(name) => name.as_str(),
&ClauseType::Throw => "throw"
}
}
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,

View File

@@ -17,8 +17,8 @@ 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 name, ref terms, _) =>
TermIterState::Clause(0, ClauseType::Root, terms), TermIterState::Clause(0, ClauseType::Root(name), terms),
&Term::Cons(..) => &Term::Cons(..) =>
return QueryIterator { state_stack: vec![] }, return QueryIterator { state_stack: vec![] },
&Term::Constant(_, _) => &Term::Constant(_, _) =>
@@ -40,14 +40,20 @@ impl<'a> QueryIterator<'a> {
let state = TermIterState::Clause(0, ClauseType::Catch, terms); let state = TermIterState::Clause(0, ClauseType::Catch, terms);
QueryIterator { state_stack: vec![state] } QueryIterator { state_stack: vec![state] }
}, },
&QueryTerm::Display(ref terms) &QueryTerm::Display(ref terms) => {
| &QueryTerm::DuplicateTerm(ref terms) => { let state = TermIterState::Clause(0, ClauseType::Display, terms);
let state = TermIterState::Clause(0, ClauseType::Root, terms);
QueryIterator { state_stack: vec![state] } QueryIterator { state_stack: vec![state] }
}, },
&QueryTerm::Arg(ref terms) &QueryTerm::DuplicateTerm(ref terms) => {
| &QueryTerm::Functor(ref terms) => { let state = TermIterState::Clause(0, ClauseType::DuplicateTerm, terms);
let state = TermIterState::Clause(0, ClauseType::Root, terms); QueryIterator { state_stack: vec![state] }
},
&QueryTerm::Arg(ref terms) => {
let state = TermIterState::Clause(0, ClauseType::Arg, terms);
QueryIterator { state_stack: vec![state] }
},
&QueryTerm::Functor(ref terms) => {
let state = TermIterState::Clause(0, ClauseType::Functor, terms);
QueryIterator { state_stack: vec![state] } QueryIterator { state_stack: vec![state] }
}, },
&QueryTerm::Inlined(InlinedQueryTerm::CompareNumber(_, ref terms)) &QueryTerm::Inlined(InlinedQueryTerm::CompareNumber(_, ref terms))
@@ -130,8 +136,8 @@ 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 name, ref terms, _) =>
vec![TermIterState::Clause(0, ClauseType::Root, terms)], vec![TermIterState::Clause(0, ClauseType::Root(name), 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,
cell, cell,