throw exception when call-ing a system instruction.

This commit is contained in:
Mark Thom
2018-05-10 23:08:56 -06:00
parent 910bafef61
commit ba7e7ac895
10 changed files with 122 additions and 122 deletions

View File

@@ -1,5 +1,4 @@
use prolog::ast::*;
use prolog::builtins::*;
use prolog::machine::machine_state::*;
use prolog::num::bigint::BigInt;
@@ -8,6 +7,94 @@ use std::rc::Rc;
pub(super) type MachineError = Vec<HeapCellValue>;
pub(super) type MachineStub = Vec<HeapCellValue>;
// from 7.12.2 b) of 13211-1:1995
#[derive(Clone, Copy)]
pub enum ValidType {
Atom,
Atomic,
Byte,
Callable,
Character,
Compound,
Evaluable,
InByte,
InCharacter,
Integer,
List,
Number,
Pair,
PredicateIndicator,
Variable
}
impl ValidType {
pub fn as_str(self) -> &'static str {
match self {
ValidType::Atom => "atom",
ValidType::Atomic => "atomic",
ValidType::Byte => "byte",
ValidType::Callable => "callable",
ValidType::Character => "character",
ValidType::Compound => "compound",
ValidType::Evaluable => "evaluable",
ValidType::InByte => "in_byte",
ValidType::InCharacter => "in_character",
ValidType::Integer => "integer",
ValidType::List => "list",
ValidType::Number => "number",
ValidType::Pair => "pair",
ValidType::PredicateIndicator => "predicate_indicator",
ValidType::Variable => "variable"
}
}
}
// from 7.12.2 f) of 13211-1:1995
#[derive(Clone, Copy)]
pub enum RepFlag {
Character,
CharacterCode,
InCharacterCode,
MaxArity,
MaxInteger,
MinInteger
}
impl RepFlag {
pub fn as_str(self) -> &'static str {
match self {
RepFlag::Character => "character",
RepFlag::CharacterCode => "character_code",
RepFlag::InCharacterCode => "in_character_code",
RepFlag::MaxArity => "max_arity",
RepFlag::MaxInteger => "max_integer",
RepFlag::MinInteger => "min_integer"
}
}
}
// from 7.12.2 g) of 13211-1:1995
#[derive(Clone, Copy)]
pub enum EvalError {
FloatOverflow,
IntOverflow,
Undefined,
Underflow,
ZeroDivisor
}
impl EvalError {
pub fn as_str(self) -> &'static str {
match self {
EvalError::FloatOverflow => "float_overflow",
EvalError::IntOverflow => "int_overflow",
EvalError::Undefined => "undefined",
EvalError::Underflow => "underflow",
EvalError::ZeroDivisor => "zero_divisor"
}
}
}
// used by '$skip_max_list'.
pub(super) enum CycleSearchResult {
EmptyList,
@@ -125,7 +212,7 @@ impl MachineState {
let mut error_form = vec![HeapCellValue::NamedStr(2, clause_name!("error"), None),
HeapCellValue::Addr(Addr::HeapCell(h + 3)),
HeapCellValue::Addr(Addr::HeapCell(h + 3 + err.len()))];
error_form.extend(err.into_iter());
error_form.extend(src.into_iter());
@@ -143,6 +230,6 @@ impl MachineState {
self.registers[1] = Addr::HeapCell(h);
self.set_ball();
self.unwind_stack();
self.unwind_stack();
}
}

View File

@@ -2,7 +2,7 @@ use prolog::and_stack::*;
use prolog::ast::*;
use prolog::copier::*;
use prolog::heap_print::*;
use prolog::machine::machine_errors::MachineStub;
use prolog::machine::machine_errors::*;
use prolog::num::{BigInt, BigUint, Zero, One};
use prolog::or_stack::*;
use prolog::tabled_rc::*;
@@ -546,7 +546,8 @@ pub(crate) trait CallPolicy: Any {
return Err(machine_st.existence_error(name, inner_arity));
},
ClauseType::System(ct) =>
return machine_st.system_call(&ct)
return Err(machine_st.type_error(ValidType::Callable,
Addr::Con(Constant::Atom(name))))
};
break;

View File

@@ -1401,13 +1401,11 @@ impl MachineState {
}
pub(super)
fn execute_built_in_instr<'a>(&mut self, code_dirs: CodeDirs<'a>,
call_policy: &mut Box<CallPolicy>,
cut_policy: &mut Box<CutPolicy>,
instr: &BuiltInInstruction)
fn execute_pe_instr<'a>(&mut self, code_dirs: CodeDirs<'a>, call_policy: &mut Box<CallPolicy>,
cut_policy: &mut Box<CutPolicy>, instr: &PEInstruction)
{
match instr {
&BuiltInInstruction::InstallCleaner => {
&PEInstruction::InstallCleaner => {
let addr = self[temp_v!(1)].clone();
let b = self.b;
let block = self.block;
@@ -1425,7 +1423,7 @@ impl MachineState {
self.p += 1;
},
&BuiltInInstruction::InstallInferenceCounter(r1, r2, r3) => { // A1 = B, A2 = L
&PEInstruction::InstallInferenceCounter(r1, r2, r3) => { // A1 = B, A2 = L
let a1 = self.store(self.deref(self[r1].clone()));
let a2 = self.store(self.deref(self[r2].clone()));
@@ -1454,7 +1452,7 @@ impl MachineState {
}
};
},
&BuiltInInstruction::RemoveCallPolicyCheck => {
&PEInstruction::RemoveCallPolicyCheck => {
let restore_default =
match call_policy.downcast_mut::<CallWithInferenceLimitCallPolicy>().ok() {
Some(call_policy) => {
@@ -1480,7 +1478,7 @@ impl MachineState {
self.p += 1;
},
&BuiltInInstruction::RemoveInferenceCounter(r1, r2) => { // A1 = B
&PEInstruction::RemoveInferenceCounter(r1, r2) => { // A1 = B
match call_policy.downcast_mut::<CallWithInferenceLimitCallPolicy>().ok() {
Some(call_policy) => {
let a1 = self.store(self.deref(self[r1].clone()));
@@ -1498,7 +1496,7 @@ impl MachineState {
self.p += 1;
},
&BuiltInInstruction::RestoreCutPolicy => {
&PEInstruction::RestoreCutPolicy => {
let restore_default =
if let Ok(cut_policy) = cut_policy.downcast_ref::<SetupCallCleanupCutPolicy>() {
cut_policy.out_of_cont_pts()
@@ -1512,7 +1510,7 @@ impl MachineState {
self.p += 1;
},
&BuiltInInstruction::SetCutPoint(r) =>
&PEInstruction::SetCutPoint(r) =>
cut_policy.cut(self, r),
};
}

View File

@@ -247,10 +247,10 @@ impl Machine {
match instr {
Line::Arithmetic(ref arith_instr) =>
self.ms.execute_arith_instr(arith_instr),
Line::BuiltIn(ref built_in_instr) => {
Line::PolicyExempt(ref built_in_instr) => {
let code_dirs = CodeDirs::new(&self.code_dir, &self.modules);
self.ms.execute_built_in_instr(code_dirs, &mut self.call_policy,
&mut self.cut_policy, built_in_instr);
self.ms.execute_pe_instr(code_dirs, &mut self.call_policy,
&mut self.cut_policy, built_in_instr);
},
Line::Choice(ref choice_instr) =>
self.ms.execute_choice_instr(choice_instr, &mut self.call_policy),

View File

@@ -165,10 +165,10 @@ impl MachineState {
match a2 {
Addr::Con(Constant::Usize(bp)) =>
if self.b <= bp + 1 {
let a2 = Addr::Con(atom!("!", self.atom_tbl));
let a2 = Addr::Con(atom!("!"));
self.unify(a1, a2);
} else {
let a2 = Addr::Con(atom!("true", self.atom_tbl));
let a2 = Addr::Con(atom!("true"));
self.unify(a1, a2);
},
_ => self.fail = true