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

@@ -31,8 +31,8 @@ fn prolog_repl() {
load_init_str_and_include(&mut wam, BUILTINS, "builtins"); load_init_str_and_include(&mut wam, BUILTINS, "builtins");
// load_init_str(&mut wam, LISTS); // load_init_str(&mut wam, LISTS);
// load_init_str(&mut wam, CONTROL); // load_init_str(&mut wam, CONTROL);
// load_init_str(&mut wam, QUEUES); // load_init_str(&mut wam, QUEUES);
loop { loop {
print!("prolog> "); print!("prolog> ");

View File

@@ -1,3 +1,4 @@
use prolog::builtins::*;
use prolog::num::bigint::BigInt; use prolog::num::bigint::BigInt;
use prolog::num::{Float, ToPrimitive, Zero}; use prolog::num::{Float, ToPrimitive, Zero};
use prolog::num::rational::Ratio; use prolog::num::rational::Ratio;
@@ -162,7 +163,7 @@ impl Module {
pub fn new(module_decl: ModuleDecl) -> Self { pub fn new(module_decl: ModuleDecl) -> Self {
Module { module_decl, Module { module_decl,
code_dir: ModuleCodeDir::new(), code_dir: ModuleCodeDir::new(),
op_dir: OpDir::new() } op_dir: default_op_dir() }
} }
} }
@@ -1367,8 +1368,9 @@ pub enum ArithmeticInstruction {
Neg(ArithmeticTerm, usize) Neg(ArithmeticTerm, usize)
} }
// call and cut policy exempt instructions.
#[derive(Clone)] #[derive(Clone)]
pub enum BuiltInInstruction { pub enum PEInstruction {
InstallCleaner, InstallCleaner,
InstallInferenceCounter(RegType, RegType, RegType), InstallInferenceCounter(RegType, RegType, RegType),
RemoveCallPolicyCheck, RemoveCallPolicyCheck,
@@ -1451,7 +1453,7 @@ pub type CompiledQuery = Vec<QueryInstruction>;
#[derive(Clone)] #[derive(Clone)]
pub enum Line { pub enum Line {
Arithmetic(ArithmeticInstruction), Arithmetic(ArithmeticInstruction),
BuiltIn(BuiltInInstruction), PolicyExempt(PEInstruction),
Choice(ChoiceInstruction), Choice(ChoiceInstruction),
Control(ControlInstruction), Control(ControlInstruction),
Cut(CutInstruction), Cut(CutInstruction),

View File

@@ -2,94 +2,6 @@ use prolog::ast::*;
use std::collections::HashMap; use std::collections::HashMap;
// 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"
}
}
}
/* /*
fn get_builtins() -> Code { fn get_builtins() -> Code {
vec![internal_call_n!(), // callN/N, 0. vec![internal_call_n!(), // callN/N, 0.

View File

@@ -166,20 +166,20 @@ impl fmt::Display for IndexedChoiceInstruction {
} }
} }
impl fmt::Display for BuiltInInstruction { impl fmt::Display for PEInstruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
&BuiltInInstruction::InstallInferenceCounter(r1, r2, r3) => &PEInstruction::InstallInferenceCounter(r1, r2, r3) =>
write!(f, "install_inference_counter {}, {}, {}", r1, r2, r3), write!(f, "install_inference_counter {}, {}, {}", r1, r2, r3),
&BuiltInInstruction::InstallCleaner => &PEInstruction::InstallCleaner =>
write!(f, "install_cleaner"), write!(f, "install_cleaner"),
&BuiltInInstruction::RemoveCallPolicyCheck => &PEInstruction::RemoveCallPolicyCheck =>
write!(f, "remove_call_policy_check"), write!(f, "remove_call_policy_check"),
&BuiltInInstruction::RemoveInferenceCounter(r1, r2) => &PEInstruction::RemoveInferenceCounter(r1, r2) =>
write!(f, "remove_inference_counter {}, {}", r1, r2), write!(f, "remove_inference_counter {}, {}", r1, r2),
&BuiltInInstruction::RestoreCutPolicy => &PEInstruction::RestoreCutPolicy =>
write!(f, "restore_cut_point"), write!(f, "restore_cut_point"),
&BuiltInInstruction::SetCutPoint(r) => &PEInstruction::SetCutPoint(r) =>
write!(f, "set_cp {}", r), write!(f, "set_cp {}", r),
} }
} }
@@ -328,7 +328,7 @@ pub fn print_code(code: &Code) {
for fact_instr in fact { for fact_instr in fact {
println!("{}", fact_instr); println!("{}", fact_instr);
}, },
&Line::BuiltIn(ref instr) => &Line::PolicyExempt(ref instr) =>
println!("{}", instr), println!("{}", instr),
&Line::Cut(ref cut) => &Line::Cut(ref cut) =>
println!("{}", cut), println!("{}", cut),

View File

@@ -1,5 +1,4 @@
use prolog::ast::*; use prolog::ast::*;
use prolog::builtins::*;
use prolog::machine::machine_state::*; use prolog::machine::machine_state::*;
use prolog::num::bigint::BigInt; use prolog::num::bigint::BigInt;
@@ -8,6 +7,94 @@ use std::rc::Rc;
pub(super) type MachineError = Vec<HeapCellValue>; pub(super) type MachineError = Vec<HeapCellValue>;
pub(super) type MachineStub = 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'. // used by '$skip_max_list'.
pub(super) enum CycleSearchResult { pub(super) enum CycleSearchResult {
EmptyList, EmptyList,
@@ -125,7 +212,7 @@ impl MachineState {
let mut error_form = vec![HeapCellValue::NamedStr(2, clause_name!("error"), None), let mut error_form = vec![HeapCellValue::NamedStr(2, clause_name!("error"), None),
HeapCellValue::Addr(Addr::HeapCell(h + 3)), HeapCellValue::Addr(Addr::HeapCell(h + 3)),
HeapCellValue::Addr(Addr::HeapCell(h + 3 + err.len()))]; HeapCellValue::Addr(Addr::HeapCell(h + 3 + err.len()))];
error_form.extend(err.into_iter()); error_form.extend(err.into_iter());
error_form.extend(src.into_iter()); error_form.extend(src.into_iter());
@@ -143,6 +230,6 @@ impl MachineState {
self.registers[1] = Addr::HeapCell(h); self.registers[1] = Addr::HeapCell(h);
self.set_ball(); self.set_ball();
self.unwind_stack(); self.unwind_stack();
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

@@ -152,7 +152,7 @@ macro_rules! is_call {
macro_rules! set_cp { macro_rules! set_cp {
($r:expr) => ( ($r:expr) => (
Line::BuiltIn(BuiltInInstruction::SetCutPoint($r)) Line::PolicyExempt(PEInstruction::SetCutPoint($r))
) )
} }