From ba7e7ac895206a60bb30f80a960a46a3a0b7086b Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Thu, 10 May 2018 23:08:56 -0600 Subject: [PATCH] throw exception when call-ing a system instruction. --- src/main.rs | 4 +- src/prolog/ast.rs | 8 +- src/prolog/builtins.rs | 88 ---------------------- src/prolog/io.rs | 16 ++-- src/prolog/machine/machine_errors.rs | 93 +++++++++++++++++++++++- src/prolog/machine/machine_state.rs | 5 +- src/prolog/machine/machine_state_impl.rs | 18 ++--- src/prolog/machine/mod.rs | 6 +- src/prolog/machine/system_calls.rs | 4 +- src/prolog/macros.rs | 2 +- 10 files changed, 122 insertions(+), 122 deletions(-) diff --git a/src/main.rs b/src/main.rs index a220f41a..46aa4add 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,8 +31,8 @@ fn prolog_repl() { load_init_str_and_include(&mut wam, BUILTINS, "builtins"); // load_init_str(&mut wam, LISTS); -// load_init_str(&mut wam, CONTROL); -// load_init_str(&mut wam, QUEUES); + // load_init_str(&mut wam, CONTROL); + // load_init_str(&mut wam, QUEUES); loop { print!("prolog> "); diff --git a/src/prolog/ast.rs b/src/prolog/ast.rs index ac62082a..8137dfe8 100644 --- a/src/prolog/ast.rs +++ b/src/prolog/ast.rs @@ -1,3 +1,4 @@ +use prolog::builtins::*; use prolog::num::bigint::BigInt; use prolog::num::{Float, ToPrimitive, Zero}; use prolog::num::rational::Ratio; @@ -162,7 +163,7 @@ impl Module { pub fn new(module_decl: ModuleDecl) -> Self { Module { module_decl, code_dir: ModuleCodeDir::new(), - op_dir: OpDir::new() } + op_dir: default_op_dir() } } } @@ -1367,8 +1368,9 @@ pub enum ArithmeticInstruction { Neg(ArithmeticTerm, usize) } +// call and cut policy exempt instructions. #[derive(Clone)] -pub enum BuiltInInstruction { +pub enum PEInstruction { InstallCleaner, InstallInferenceCounter(RegType, RegType, RegType), RemoveCallPolicyCheck, @@ -1451,7 +1453,7 @@ pub type CompiledQuery = Vec; #[derive(Clone)] pub enum Line { Arithmetic(ArithmeticInstruction), - BuiltIn(BuiltInInstruction), + PolicyExempt(PEInstruction), Choice(ChoiceInstruction), Control(ControlInstruction), Cut(CutInstruction), diff --git a/src/prolog/builtins.rs b/src/prolog/builtins.rs index ab9d4903..6996b6ea 100644 --- a/src/prolog/builtins.rs +++ b/src/prolog/builtins.rs @@ -2,94 +2,6 @@ use prolog::ast::*; 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 { vec![internal_call_n!(), // callN/N, 0. diff --git a/src/prolog/io.rs b/src/prolog/io.rs index 68659c79..bab5f0e4 100644 --- a/src/prolog/io.rs +++ b/src/prolog/io.rs @@ -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 { match self { - &BuiltInInstruction::InstallInferenceCounter(r1, r2, r3) => + &PEInstruction::InstallInferenceCounter(r1, r2, r3) => write!(f, "install_inference_counter {}, {}, {}", r1, r2, r3), - &BuiltInInstruction::InstallCleaner => + &PEInstruction::InstallCleaner => write!(f, "install_cleaner"), - &BuiltInInstruction::RemoveCallPolicyCheck => + &PEInstruction::RemoveCallPolicyCheck => write!(f, "remove_call_policy_check"), - &BuiltInInstruction::RemoveInferenceCounter(r1, r2) => + &PEInstruction::RemoveInferenceCounter(r1, r2) => write!(f, "remove_inference_counter {}, {}", r1, r2), - &BuiltInInstruction::RestoreCutPolicy => + &PEInstruction::RestoreCutPolicy => write!(f, "restore_cut_point"), - &BuiltInInstruction::SetCutPoint(r) => + &PEInstruction::SetCutPoint(r) => write!(f, "set_cp {}", r), } } @@ -328,7 +328,7 @@ pub fn print_code(code: &Code) { for fact_instr in fact { println!("{}", fact_instr); }, - &Line::BuiltIn(ref instr) => + &Line::PolicyExempt(ref instr) => println!("{}", instr), &Line::Cut(ref cut) => println!("{}", cut), diff --git a/src/prolog/machine/machine_errors.rs b/src/prolog/machine/machine_errors.rs index 984cf4d2..df7d3e3f 100644 --- a/src/prolog/machine/machine_errors.rs +++ b/src/prolog/machine/machine_errors.rs @@ -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; pub(super) type MachineStub = Vec; +// 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(); } } diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index 74ac779a..be859058 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -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; diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index 9abe45be..7958abf2 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -1401,13 +1401,11 @@ impl MachineState { } pub(super) - fn execute_built_in_instr<'a>(&mut self, code_dirs: CodeDirs<'a>, - call_policy: &mut Box, - cut_policy: &mut Box, - instr: &BuiltInInstruction) + fn execute_pe_instr<'a>(&mut self, code_dirs: CodeDirs<'a>, call_policy: &mut Box, + cut_policy: &mut Box, 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::().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::().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::() { 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), }; } diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 425ee1e4..5ef8748a 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -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), diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index d9500de0..0662876b 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -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 diff --git a/src/prolog/macros.rs b/src/prolog/macros.rs index 723b02c7..7881509c 100644 --- a/src/prolog/macros.rs +++ b/src/prolog/macros.rs @@ -152,7 +152,7 @@ macro_rules! is_call { macro_rules! set_cp { ($r:expr) => ( - Line::BuiltIn(BuiltInInstruction::SetCutPoint($r)) + Line::PolicyExempt(PEInstruction::SetCutPoint($r)) ) } -- 2.54.0