use binary_pow for (^)/2

This commit is contained in:
Mark Thom
2019-04-22 19:48:09 -06:00
parent 59c21dbc3b
commit f9448e894e
4 changed files with 20 additions and 6 deletions

View File

@@ -14,7 +14,7 @@ cfg-if = "0.1.7"
downcast = "0.10.0" downcast = "0.10.0"
num = "0.2" num = "0.2"
ordered-float = "0.5.0" ordered-float = "0.5.0"
prolog_parser = "0.8.20" prolog_parser = "0.8.21"
readline_rs_compat = { version = "0.1.9", optional = true } readline_rs_compat = { version = "0.1.9", optional = true }
ref_thread_local = "0.0.0" ref_thread_local = "0.0.0"

View File

@@ -123,6 +123,8 @@ fn compile_query(terms: Vec<QueryTerm>, queue: VecDeque<TopLevel>, flags: Machin
let mut code = try!(cg.compile_query(&terms)); let mut code = try!(cg.compile_query(&terms));
compile_appendix(&mut code, &queue, false, flags)?; compile_appendix(&mut code, &queue, false, flags)?;
print_code(&code);
Ok((code, cg.take_vars())) Ok((code, cg.take_vars()))
} }

View File

@@ -249,7 +249,6 @@ impl RepFlag {
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum EvalError { pub enum EvalError {
// FloatOverflow, // FloatOverflow,
// IntOverflow,
// Undefined, // Undefined,
// FloatUnderflow, // FloatUnderflow,
ZeroDivisor, ZeroDivisor,
@@ -260,7 +259,6 @@ impl EvalError {
pub fn as_str(self) -> &'static str { pub fn as_str(self) -> &'static str {
match self { match self {
// EvalError::FloatOverflow => "float_overflow", // EvalError::FloatOverflow => "float_overflow",
// EvalError::IntOverflow => "int_overflow",
// EvalError::Undefined => "undefined", // EvalError::Undefined => "undefined",
// EvalError::FloatUnderflow => "underflow", // EvalError::FloatUnderflow => "underflow",
EvalError::ZeroDivisor => "zero_divisor", EvalError::ZeroDivisor => "zero_divisor",

View File

@@ -721,7 +721,7 @@ impl MachineState {
let caller = MachineError::functor_stub(clause_name!("(is)"), 2); let caller = MachineError::functor_stub(clause_name!("(is)"), 2);
let mut interms: Vec<Number> = Vec::with_capacity(64); let mut interms: Vec<Number> = Vec::with_capacity(64);
for heap_val in self.post_order_iter(a) { for heap_val in self.heap.post_order_iter(a) {
match heap_val { match heap_val {
HeapCellValue::NamedStr(2, name, _) => { HeapCellValue::NamedStr(2, name, _) => {
let a2 = interms.pop().unwrap(); let a2 = interms.pop().unwrap();
@@ -733,7 +733,7 @@ impl MachineState {
"*" => interms.push(a1 * a2), "*" => interms.push(a1 * a2),
"/" => interms.push(self.div(a1, a2)?), "/" => interms.push(self.div(a1, a2)?),
"**" => interms.push(self.pow(a1, a2)?), "**" => interms.push(self.pow(a1, a2)?),
"^" => interms.push(self.pow(a1, a2)?), "^" => interms.push(self.binary_pow(a1, a2)?),
"max" => interms.push(self.max(a1, a2)?), "max" => interms.push(self.max(a1, a2)?),
"rdiv" => { "rdiv" => {
let r1 = self.get_rational(&ArithmeticTerm::Number(a1), &caller)?; let r1 = self.get_rational(&ArithmeticTerm::Number(a1), &caller)?;
@@ -841,6 +841,20 @@ impl MachineState {
} }
} }
fn binary_pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub>
{
match (n1, n2) {
(Number::Integer(n1), Number::Integer(n2)) =>
self.pow(Number::Integer(n1), Number::Integer(n2)),
(Number::Integer(_), n) | (n, _) => {
let n = Addr::Con(Constant::Number(n));
let stub = MachineError::functor_stub(clause_name!("^"), 2);
Err(self.error_form(MachineError::type_error(ValidType::Integer, n), stub))
}
}
}
fn pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub> fn pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub>
{ {
match n1.pow(n2) { match n1.pow(n2) {
@@ -1033,7 +1047,7 @@ impl MachineState {
let n1 = try_or_fail!(self, self.get_number(a1)); let n1 = try_or_fail!(self, self.get_number(a1));
let n2 = try_or_fail!(self, self.get_number(a2)); let n2 = try_or_fail!(self, self.get_number(a2));
self.interms[t - 1] = try_or_fail!(self, self.pow(n1, n2)); self.interms[t - 1] = try_or_fail!(self, self.binary_pow(n1, n2));
self.p += 1; self.p += 1;
}, },
&ArithmeticInstruction::Pow(ref a1, ref a2, t) => { &ArithmeticInstruction::Pow(ref a1, ref a2, t) => {