throw exception when call-ing a system instruction.
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user