ArithmeticEvaluator { bindings, interm: Vec::new(), interm_c: 1 }
}
- fn get_un_instr(name: &Atom, a1: ArithmeticTerm, t: usize)
- -> Result<ArithmeticInstruction, ArithmeticError>
+ fn get_unary_instr(name: &Atom, a1: ArithmeticTerm, t: usize)
+ -> Result<ArithmeticInstruction, ArithmeticError>
{
match name.as_str() {
"-" => Ok(ArithmeticInstruction::Neg(a1, t)),
}
}
- fn gen_bin_instr(name: &Atom, a1: ArithmeticTerm, a2: ArithmeticTerm, t: usize)
- -> Result<ArithmeticInstruction, ArithmeticError>
+ fn gen_binary_instr(name: &Atom, a1: ArithmeticTerm, a2: ArithmeticTerm, t: usize)
+ -> Result<ArithmeticInstruction, ArithmeticError>
{
match name.as_str() {
"+" => Ok(ArithmeticInstruction::Add(a1, a2, t)),
a1.interm_or(0)
};
- Self::get_un_instr(name, a1, ninterm)
+ Self::get_unary_instr(name, a1, ninterm)
},
2 => {
let a2 = self.interm.pop().unwrap();
min_interm
};
- Self::gen_bin_instr(name, a1, a2, ninterm)
+ Self::gen_binary_instr(name, a1, a2, ninterm)
},
_ => Err(ArithmeticError::InvalidOp)
}
_ => {}
};
}
-
+
Ok(code)
}
}
use prolog::iterators::*;
use prolog::targets::*;
+use std::cell::Cell;
use std::collections::HashMap;
use std::mem::swap;
use std::vec::Vec;
*self.var_count.get(var).unwrap()
}
+ fn mark_non_callable(&mut self,
+ name: &'a Atom,
+ arity: usize,
+ term_loc: GenContext,
+ vr: &'a Cell<VarReg>,
+ code: &mut Code)
+ -> RegType
+ {
+ match self.marker.bindings().get(name) {
+ Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t),
+ Some(&VarData::Perm(p)) if p != 0 => RegType::Perm(p),
+ _ => {
+ let mut target = Vec::new();
+
+ self.marker.reset_arg(arity);
+ self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target);
+
+ code.push(Line::Query(target));
+ vr.get().norm()
+ }
+ }
+ }
+
fn add_or_increment_void_instr<Target>(target: &mut Vec<Target>)
where Target: CompilationTarget<'a>
{
code.append(&mut arith_code);
match terms[0].as_ref() {
- &Term::Var(ref vr, ref name) =>
- match self.marker.bindings().get(name) {
- Some(&VarData::Temp(_, t, _)) if t != 0 =>
- code.push(is_call!(temp_v!(t))),
- Some(&VarData::Perm(p)) if p != 0 =>
- code.push(is_call!(perm_v!(p))),
- _ => {
- let mut target = Vec::new();
-
- // reset self.marker.arg_c to 1.
- self.marker.advance(term_loc, term.arity());
- self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target);
-
- code.push(Line::Query(target));
- code.push(is_call!(vr.get().norm()));
- }
- },
+ &Term::Var(ref vr, ref name) => {
+ let r = self.mark_non_callable(name,
+ term.arity(),
+ term_loc,
+ vr,
+ code);
+
+ code.push(is_call!(r));
+ },
&Term::Constant(_, Constant::Float(fl)) => {
code.push(query![put_constant!(Level::Shallow,
Constant::Float(fl),
&Term::Constant(_, _) => {
code.push(succeed!());
},
- &Term::Var(ref vr, ref name) =>
- match self.marker.bindings().get(name) {
- Some(&VarData::Temp(_, t, _)) if t != 0 =>
- code.push(is_atomic!(RegType::Temp(t))),
- Some(&VarData::Perm(p)) if p != 0 =>
- code.push(is_atomic!(RegType::Perm(p))),
- _ => {
- let mut target = Vec::new();
-
- // reset self.marker.arg_c to 1.
- self.marker.advance(term_loc, term.arity());
- self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target);
-
- code.push(Line::Query(target));
- code.push(is_atomic!(vr.get().norm()));
- }
- },
+ &Term::Var(ref vr, ref name) => {
+ let r = self.mark_non_callable(name,
+ term.arity(),
+ term_loc,
+ vr,
+ code);
+
+ code.push(is_atomic!(r));
+ }
},
&QueryTerm::IsVar(ref inner_term) =>
match inner_term[0].as_ref() {
&Term::AnonVar => {
code.push(succeed!());
},
- &Term::Var(ref vr, ref name) =>
- match self.marker.bindings().get(name) {
- Some(&VarData::Temp(_, t, _)) if t != 0 =>
- code.push(is_var!(RegType::Temp(t))),
- Some(&VarData::Perm(p)) if p != 0 =>
- code.push(is_var!(RegType::Perm(p))),
- _ => {
- let mut target = Vec::new();
-
- // reset self.marker.arg_c to 1.
- self.marker.advance(term_loc, term.arity());
- self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target);
-
- code.push(Line::Query(target));
- code.push(is_var!(vr.get().norm()));
- }
- }
+ &Term::Var(ref vr, ref name) => {
+ let r = self.mark_non_callable(name,
+ term.arity(),
+ term_loc,
+ vr,
+ code);
+
+ code.push(is_var!(r));
+ }
},
_ if chunk_num == 0 => {
- self.marker.advance(GenContext::Head, term.arity());
+ self.marker.reset_arg(term.arity());
let iter = term.post_order_iter();
code.push(Line::Query(self.compile_target(iter, term_loc, is_exposed)));
let &Rule { head: (ref p0, ref p1), ref clauses } = rule;
let mut code = Vec::new();
- self.marker.advance(GenContext::Head, p0.arity());
+ self.marker.reset_arg(p0.arity());
self.compile_seq_prelude(&conjunct_info, &mut code);
if let &QueryTerm::Term(ref term) = p0 {
vs.populate_restricting_sets();
self.marker.drain_var_data(vs);
- self.marker.advance(GenContext::Head, term.arity());
+ self.marker.reset_arg(term.arity());
let mut code = Vec::new();
index: usize,
is_exposed: bool)
{
- self.marker.advance(term_loc, term.arity());
+ self.marker.reset_arg(term.arity());
let iter = term.post_order_iter();
let compiled_query = Line::Query(self.compile_target(iter, term_loc, is_exposed));
+++ /dev/null
-use prolog::allocator::*;
-use prolog::ast::*;
-use prolog::fixtures::*;
-use prolog::targets::*;
-
-use std::cell::Cell;
-use std::cmp::max;
-use std::collections::HashMap;
-
-pub struct NaiveAllocator<'a> {
- bindings: AllocVarDict<'a>,
- arg_c: usize,
- temp_c: usize,
-}
-
-impl<'a> Allocator<'a> for NaiveAllocator<'a>
-{
- fn new() -> Self {
- NaiveAllocator {
- arg_c: 1,
- temp_c: 1,
- bindings: HashMap::new(),
- }
- }
-
- fn mark_anon_var<Target>(&mut self, lvl: Level, target: &mut Vec<Target>)
- where Target: CompilationTarget<'a>
- {
- let r = {
- let temp = self.temp_c;
- self.temp_c += 1;
- RegType::Temp(temp)
- };
-
- match lvl {
- Level::Deep => target.push(Target::subterm_to_variable(r)),
- Level::Shallow => {
- let k = self.arg_c;
- self.arg_c += 1;
-
- target.push(Target::argument_to_variable(r, k));
- }
- }
- }
-
- fn mark_non_var<Target>(&mut self,
- lvl: Level,
- _: GenContext,
- cell: &Cell<RegType>,
- _: &mut Vec<Target>)
- where Target: CompilationTarget<'a>
- {
- let r = cell.get();
-
- if r.reg_num() == 0 {
- let r = match lvl {
- Level::Shallow => {
- let k = self.arg_c;
- self.arg_c += 1;
-
- RegType::Temp(k)
- },
- _ => {
- let temp = self.temp_c;
- self.temp_c += 1;
-
- RegType::Temp(temp)
- }
- };
-
- cell.set(r);
- }
- }
-
- fn mark_var<Target>(&mut self,
- var: &'a Var,
- lvl: Level,
- cell: &'a Cell<VarReg>,
- _: GenContext,
- target: &mut Vec<Target>)
- where Target: CompilationTarget<'a>
- {
- let (r, is_new_var) = match self.get(var) {
- RegType::Temp(0) => {
- let o = self.temp_c;
- self.temp_c += 1;
-
- (RegType::Temp(o), true)
- },
- RegType::Perm(0) => {
- let pr = cell.get().norm();
- self.record_register(var, pr);
-
- (pr, true)
- },
- r => (r, false)
- };
-
- match lvl {
- Level::Shallow => {
- let k = self.arg_c;
- self.arg_c += 1;
-
- cell.set(VarReg::ArgAndNorm(r, k));
-
- if is_new_var {
- target.push(Target::argument_to_variable(r, k));
- } else {
- target.push(Target::argument_to_value(r, k));
- }
- },
- Level::Deep => {
- cell.set(VarReg::Norm(r));
-
- if is_new_var {
- target.push(Target::subterm_to_variable(r));
- } else {
- target.push(Target::subterm_to_value(r));
- }
- }
- };
-
- if !r.is_perm() {
- self.record_register(var, r);
- }
- }
-
- fn reset(&mut self) {
- self.bindings.clear();
- }
-
- fn advance(&mut self, term_loc: GenContext, arity: usize) {
- if let GenContext::Head = term_loc {
- self.arg_c = 1;
- self.temp_c = max(arity + 1, self.temp_c);
- } else {
- self.arg_c = 1;
- self.temp_c = arity + 1;
- }
- }
-
- fn advance_arg(&mut self) {
- self.arg_c += 1;
- }
-
- fn bindings(&self) -> &AllocVarDict<'a> {
- &self.bindings
- }
-
- fn bindings_mut(&mut self) -> &mut AllocVarDict<'a> {
- &mut self.bindings
- }
-
- fn take_bindings(self) -> AllocVarDict<'a> {
- self.bindings
- }
-}