}
if !self.import_decl(name, arity, submodule) {
- return EvalSession::from(EvalError::ModuleDoesNotContainExport);
+ return EvalSession::from(SessionError::ModuleDoesNotContainExport);
}
}
fn use_module(&mut self, submodule: &Module) -> EvalSession {
for (name, arity) in submodule.module_decl.exports.iter().cloned() {
if !self.import_decl(name, arity, submodule) {
- return EvalSession::from(EvalError::ModuleDoesNotContainExport);
+ return EvalSession::from(SessionError::ModuleDoesNotContainExport);
}
}
pub type HeapVarDict = HashMap<Rc<Var>, Addr>;
pub type AllocVarDict = HashMap<Rc<Var>, VarData>;
-pub enum EvalError {
+pub enum SessionError {
ImpermissibleEntry(String),
ModuleDoesNotContainExport,
ModuleNotFound,
pub enum EvalSession {
EntrySuccess,
- Error(EvalError),
+ Error(SessionError),
InitialQuerySuccess(AllocVarDict, HeapVarDict),
SubsequentQuerySuccess,
}
-impl From<EvalError> for EvalSession {
- fn from(err: EvalError) -> Self {
+impl From<SessionError> for EvalSession {
+ fn from(err: SessionError) -> Self {
EvalSession::Error(err)
}
}
-impl From<ParserError> for EvalError {
+impl From<ParserError> for SessionError {
fn from(err: ParserError) -> Self {
- EvalError::ParserError(err)
+ SessionError::ParserError(err)
}
}
impl From<ParserError> for EvalSession {
fn from(err: ParserError) -> Self {
- EvalSession::from(EvalError::ParserError(err))
+ EvalSession::from(SessionError::ParserError(err))
}
}
pub struct OpDecl(pub usize, pub Specifier, pub ClauseName);
impl OpDecl {
- pub fn submit(&self, module: ClauseName, op_dir: &mut OpDir) -> Result<(), EvalError>
+ pub fn submit(&self, module: ClauseName, op_dir: &mut OpDir) -> Result<(), SessionError>
{
let (prec, spec, name) = (self.0, self.1, self.2.clone());
if is_infix!(spec) {
match op_dir.get(&(name.clone(), Fixity::Post)) {
- Some(_) => return Err(EvalError::OpIsInfixAndPostFix),
+ Some(_) => return Err(SessionError::OpIsInfixAndPostFix),
_ => {}
};
}
if is_postfix!(spec) {
match op_dir.get(&(name.clone(), Fixity::In)) {
- Some(_) => return Err(EvalError::OpIsInfixAndPostFix),
+ Some(_) => return Err(SessionError::OpIsInfixAndPostFix),
_ => {}
};
}
use std::collections::HashMap;
use std::rc::Rc;
+// 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,
+ 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::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.
is_atomic!(temp_v!(1)), // atomic/1, 1.
goto_execute!(165, 3), // goto get_arg/3, 185.
trust_me!(),
query![get_var_in_query!(temp_v!(4), 1),
- put_structure!("type_error", 1, temp_v!(1), None),
- set_constant!(atom!("integer_expected"))],
+ put_structure!("type_error", 2, temp_v!(2), None),
+ set_constant!(atom!(ValidType::Integer.as_str())),
+ set_value!(temp_v!(4)),
+ put_structure!("error", 2, temp_v!(1), None),
+ set_value!(temp_v!(2)),
+ set_void!(1)],
goto_execute!(59, 1), // goto throw/1.
try_me_else!(5), // arg_/5, 189.
fact![get_value!(temp_v!(1), 2),
}
}
-impl fmt::Display for EvalError {
+impl fmt::Display for SessionError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- &EvalError::ModuleNotFound => write!(f, "module not found."),
- &EvalError::ModuleDoesNotContainExport => write!(f, "module does not contain claimed export."),
- &EvalError::QueryFailure => write!(f, "false."),
- &EvalError::QueryFailureWithException(ref e) => write!(f, "{}", error_string(e)),
- &EvalError::ImpermissibleEntry(ref msg) => write!(f, "cannot overwrite {}.", msg),
- &EvalError::OpIsInfixAndPostFix =>
+ &SessionError::ModuleNotFound => write!(f, "module not found."),
+ &SessionError::ModuleDoesNotContainExport => write!(f, "module does not contain claimed export."),
+ &SessionError::QueryFailure => write!(f, "false."),
+ &SessionError::QueryFailureWithException(ref e) => write!(f, "{}", error_string(e)),
+ &SessionError::ImpermissibleEntry(ref msg) => write!(f, "cannot overwrite {}.", msg),
+ &SessionError::OpIsInfixAndPostFix =>
write!(f, "cannot define an op to be both postfix and infix."),
- &EvalError::NamelessEntry => write!(f, "the predicate head is not an atom or clause."),
- &EvalError::ParserError(ref e) => write!(f, "{:?}", e)
+ &SessionError::NamelessEntry => write!(f, "the predicate head is not an atom or clause."),
+ &SessionError::ParserError(ref e) => write!(f, "{:?}", e)
}
}
}
let name = try_eval_session!(if let Some(name) = tl.name() {
Ok(name)
} else {
- Err(EvalError::NamelessEntry)
+ Err(SessionError::NamelessEntry)
});
let mut code = try_eval_session!(compile_relation(&tl));
if !code.is_empty() {
wam.add_user_code(name, tl.arity(), code, tl.as_predicate().ok().unwrap())
} else {
- EvalSession::from(EvalError::ImpermissibleEntry(String::from("no code generated.")))
+ EvalSession::from(SessionError::ImpermissibleEntry(String::from("no code generated.")))
}
}
}
continue;
}
} else {
- return EvalSession::from(EvalError::ModuleNotFound);
+ return EvalSession::from(SessionError::ModuleNotFound);
}
wam.use_module_in_toplevel(name);
continue;
}
} else {
- return EvalSession::from(EvalError::ModuleNotFound);
+ return EvalSession::from(SessionError::ModuleNotFound);
}
wam.use_qualified_module_in_toplevel(name, exports);
let name = try_eval_session!(if let Some(name) = decl.name() {
Ok(name)
} else {
- Err(EvalError::NamelessEntry)
+ Err(SessionError::NamelessEntry)
});
let module_name = get_module_name(&module);
}
loop {
- let mut result = EvalSession::from(EvalError::QueryFailure);
+ let mut result = EvalSession::from(SessionError::QueryFailure);
let mut output = PrinterOutputter::new();
let bindings = wam.heap_view(&heap_locs, output).result();
}
}
- if let &EvalSession::Error(EvalError::QueryFailure) = &result
+ if let &EvalSession::Error(SessionError::QueryFailure) = &result
{
write!(stdout, "false.\n\r").unwrap();
stdout.flush().unwrap();
return;
}
- if let &EvalSession::Error(EvalError::QueryFailureWithException(ref e)) = &result
+ if let &EvalSession::Error(SessionError::QueryFailureWithException(ref e)) = &result
{
write!(stdout, "{}\n\r", error_string(e)).unwrap();
stdout.flush().unwrap();
--- /dev/null
+use prolog::ast::*;
+use prolog::builtins::*;
+use prolog::machine::machine_state::*;
+use prolog::num::bigint::BigInt;
+
+use std::rc::Rc;
+
+pub(super) type MachineError = Vec<HeapCellValue>;
+
+impl MachineState {
+ pub(super) fn evaluation_error(&self, eval_error: EvalError) -> MachineError {
+ functor!("evaluation_error", 1, [heap_atom!(eval_error.as_str())])
+ }
+
+ pub(super) fn type_error(&self, valid_type: ValidType, culprit: Addr) -> MachineError {
+ functor!("type_error", 2, [heap_atom!(valid_type.as_str()), HeapCellValue::Addr(culprit)])
+ }
+
+ pub(super) fn existence_error(&self, name: ClauseName, arity: usize) -> MachineError {
+ let name = HeapCellValue::Addr(Addr::Con(Constant::Atom(name)));
+ let h = self.heap.h;
+
+ let mut error = functor!("existence_error", 2, [heap_atom!("procedure"), heap_str!(3 + h)]);
+ error.append(&mut functor!("/", 2, [name, heap_integer!(arity)], Fixity::In));
+
+ error
+ }
+
+ pub(super) fn instantiation_error(&self) -> MachineError {
+ functor!("instantiation_error")
+ }
+
+ pub(super) fn representation_error(&self, flag: RepFlag) -> MachineError {
+ functor!("representation_error", 1, [heap_atom!(flag.as_str())])
+ }
+
+ pub(super) fn error_form(&self, mut err: MachineError) -> MachineError {
+ let h = self.heap.h;
+ let mut error_form = functor!("error", 2,
+ [HeapCellValue::Addr(Addr::HeapCell(h + 3)),
+ HeapCellValue::Addr(Addr::HeapCell(h + 2))]);
+
+ error_form.append(&mut err);
+ error_form
+ }
+
+ pub(super) fn throw_exception(&mut self, err: MachineError) {
+ let h = self.heap.h;
+
+ self.ball.0 = 0;
+ self.ball.1.truncate(0);
+
+ self.heap.append(err);
+
+ self.registers[1] = Addr::HeapCell(h);
+ self.goto_throw();
+ }
+}
use prolog::and_stack::*;
use prolog::ast::*;
+use prolog::builtins::*;
use prolog::copier::*;
use prolog::heap_iter::*;
use prolog::heap_print::*;
+use prolog::machine::machine_errors::*;
use prolog::machine::machine_state::*;
use prolog::num::{Integer, Signed, ToPrimitive, Zero};
use prolog::num::bigint::{BigInt, BigUint};
// used by '$skip_max_list'.
enum CycleSearchResult {
EmptyList,
- NotList,
+ NotList,
PartialList(usize, usize), // the list length (up to max), and an offset into the heap.
ProperList(usize), // the list length.
UntouchedList(usize) // the address of an uniterated Addr::Lis(address).
};
}
- fn get_number(&self, at: &ArithmeticTerm) -> Result<Number, Vec<HeapCellValue>> {
+ fn get_number(&self, at: &ArithmeticTerm) -> Result<Number, MachineError> {
match at {
&ArithmeticTerm::Reg(r) => self.arith_eval_by_metacall(r),
&ArithmeticTerm::Interm(i) => Ok(self.interms[i-1].clone()),
}
}
- fn get_rational(&self, at: &ArithmeticTerm) -> Result<Rc<Ratio<BigInt>>, Vec<HeapCellValue>> {
+ fn get_rational(&self, at: &ArithmeticTerm) -> Result<Rc<Ratio<BigInt>>, MachineError> {
let n = self.get_number(at)?;
match n {
if let Some(r) = Ratio::from_float(fl.into_inner()) {
Ok(Rc::new(r))
} else {
- Err(functor!("instantiation_error", 1, [heap_atom!("(is)/2")]))
+ Err(self.error_form(self.instantiation_error()))
},
Number::Integer(bi) =>
Ok(Rc::new(Ratio::from_integer((*bi).clone())))
Rc::new(BigInt::from_signed_bytes_le(&f(&u_n1, &u_n2).to_bytes_le()))
}
- pub(super) fn arith_eval_by_metacall(&self, r: RegType) -> Result<Number, Vec<HeapCellValue>>
+ pub(super) fn arith_eval_by_metacall(&self, r: RegType) -> Result<Number, MachineError>
{
- let instantiation_err = functor!("instantiation_error", 1, [heap_atom!("(is)/2")]);
let a = self[r].clone();
let mut interms: Vec<Number> = Vec::with_capacity(64);
"xor" => interms.push(Number::Integer(self.xor(a1, a2)?)),
"mod" => interms.push(Number::Integer(self.modulus(a1, a2)?)),
"rem" => interms.push(Number::Integer(self.remainder(a1, a2)?)),
- _ => return Err(instantiation_err)
+ _ => return Err(self.error_form(self.instantiation_error()))
}
},
HeapCellValue::NamedStr(1, name, Some(Fixity::Pre)) => {
match name.as_str() {
"-" => interms.push(- a1),
- _ => return Err(instantiation_err)
+ _ => return Err(self.error_form(self.instantiation_error()))
}
},
HeapCellValue::Addr(Addr::Con(Constant::Number(n))) =>
interms.push(n),
_ =>
- return Err(instantiation_err)
+ return Err(self.error_form(self.instantiation_error()))
}
};
}
fn rdiv(&self, r1: Rc<Ratio<BigInt>>, r2: Rc<Ratio<BigInt>>)
- -> Result<Rc<Ratio<BigInt>>, Vec<HeapCellValue>>
+ -> Result<Rc<Ratio<BigInt>>, MachineError>
{
if *r2 == Ratio::zero() {
- Err(functor!("evaluation_error", 1, [heap_atom!("zero_divisor")]))
+ Err(self.error_form(self.evaluation_error(EvalError::ZeroDivisor)))
} else {
Ok(Rc::new(&*r1 / &*r2))
}
}
- fn fidiv(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, Vec<HeapCellValue>>
+ fn fidiv(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, MachineError>
{
match (n1, n2) {
(Number::Integer(n1), Number::Integer(n2)) =>
if *n2 == BigInt::zero() {
- Err(functor!("evaluation_error", 1, [heap_atom!("zero_divisor")]))
+ Err(self.error_form(self.evaluation_error(EvalError::ZeroDivisor)))
} else {
Ok(Rc::new(n1.div_floor(&n2)))
},
- _ => Err(functor!("evaluation_error", 1, [heap_atom!("expected_integer_args")]))
+ (Number::Integer(_), n2) =>
+ Err(self.error_form(self.type_error(ValidType::Integer,
+ Addr::Con(Constant::Number(n2))))),
+ (n1, _) =>
+ Err(self.error_form(self.type_error(ValidType::Integer,
+ Addr::Con(Constant::Number(n1)))))
}
}
- fn idiv(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, Vec<HeapCellValue>>
+ fn idiv(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, MachineError>
{
match (n1, n2) {
(Number::Integer(n1), Number::Integer(n2)) =>
if *n2 == BigInt::zero() {
- Err(functor!("evaluation_error", 1, [heap_atom!("zero_divisor")]))
+ Err(self.error_form(self.evaluation_error(EvalError::ZeroDivisor)))
} else {
Ok(Rc::new(&*n1 / &*n2))
},
- _ =>
- Err(functor!("evaluation_error", 1, [heap_atom!("expected_integer_args")]))
+ (Number::Integer(_), n2) =>
+ Err(self.error_form(self.type_error(ValidType::Integer,
+ Addr::Con(Constant::Number(n2))))),
+ (n1, _) =>
+ Err(self.error_form(self.type_error(ValidType::Integer,
+ Addr::Con(Constant::Number(n1)))))
}
}
- fn div(&self, n1: Number, n2: Number) -> Result<Number, Vec<HeapCellValue>>
+ fn div(&self, n1: Number, n2: Number) -> Result<Number, MachineError>
{
if n2.is_zero() {
- Err(functor!("evaluation_error", 1, [heap_atom!("zero_divisor")]))
+ Err(self.error_form(self.evaluation_error(EvalError::ZeroDivisor)))
} else {
Ok(n1 / n2)
}
}
- fn shr(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, Vec<HeapCellValue>>
+ fn shr(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, MachineError>
{
match (n1, n2) {
(Number::Integer(n1), Number::Integer(n2)) =>
Some(n2) => Ok(Rc::new(&*n1 >> n2)),
_ => Ok(Rc::new(&*n1 >> usize::max_value()))
},
- _ =>
- Err(functor!("evaluation_error", 1, [heap_atom!("expected_integer_args")]))
+ (Number::Integer(_), n2) =>
+ Err(self.error_form(self.type_error(ValidType::Integer,
+ Addr::Con(Constant::Number(n2))))),
+ (n1, _) =>
+ Err(self.error_form(self.type_error(ValidType::Integer,
+ Addr::Con(Constant::Number(n1)))))
}
}
- fn shl(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, Vec<HeapCellValue>>
+ fn shl(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, MachineError>
{
match (n1, n2) {
(Number::Integer(n1), Number::Integer(n2)) =>
Some(n2) => Ok(Rc::new(&*n1 << n2)),
_ => Ok(Rc::new(&*n1 << usize::max_value()))
},
- _ =>
- Err(functor!("evaluation_error", 1, [heap_atom!("expected_integer_args")]))
+ (Number::Integer(_), n2) =>
+ Err(self.error_form(self.type_error(ValidType::Integer,
+ Addr::Con(Constant::Number(n2))))),
+ (n1, _) =>
+ Err(self.error_form(self.type_error(ValidType::Integer,
+ Addr::Con(Constant::Number(n1)))))
}
}
- fn xor(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, Vec<HeapCellValue>>
+ fn xor(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, MachineError>
{
match (n1, n2) {
(Number::Integer(n1), Number::Integer(n2)) =>
Ok(self.signed_bitwise_op(&*n1, &*n2, |u_n1, u_n2| u_n1 ^ u_n2)),
- _ =>
- Err(functor!("evaluation_error", 1, [heap_atom!("expected_integer_args")]))
+ (Number::Integer(_), n2) =>
+ Err(self.error_form(self.type_error(ValidType::Integer,
+ Addr::Con(Constant::Number(n2))))),
+ (n1, _) =>
+ Err(self.error_form(self.type_error(ValidType::Integer,
+ Addr::Con(Constant::Number(n1)))))
}
}
- fn and(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, Vec<HeapCellValue>>
+ fn and(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, MachineError>
{
match (n1, n2) {
(Number::Integer(n1), Number::Integer(n2)) =>
- Ok(self.signed_bitwise_op(&*n1, &*n2, |u_n1, u_n2| u_n1 & u_n2)),
- _ =>
- Err(functor!("evaluation_error", 1, [heap_atom!("expected_integer_args")]))
+ Ok(self.signed_bitwise_op(&*n1, &*n2, |u_n1, u_n2| u_n1 & u_n2)),
+ (Number::Integer(_), n2) =>
+ Err(self.error_form(self.type_error(ValidType::Integer,
+ Addr::Con(Constant::Number(n2))))),
+ (n1, _) =>
+ Err(self.error_form(self.type_error(ValidType::Integer,
+ Addr::Con(Constant::Number(n1)))))
}
}
- fn modulus(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, Vec<HeapCellValue>>
+ fn modulus(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, MachineError>
{
match (n1, n2) {
(Number::Integer(n1), Number::Integer(n2)) =>
if *n2 == BigInt::zero() {
- Err(functor!("evaluation_error", 1, [heap_atom!("zero_divisor")]))
+ Err(self.error_form(self.evaluation_error(EvalError::ZeroDivisor)))
} else {
Ok(Rc::new(n1.mod_floor(&n2)))
},
- _ =>
- Err(functor!("evaluation_error", 1, [heap_atom!("expected_integer_args")]))
+ (Number::Integer(_), n2) =>
+ Err(self.error_form(self.type_error(ValidType::Integer,
+ Addr::Con(Constant::Number(n2))))),
+ (n1, _) =>
+ Err(self.error_form(self.type_error(ValidType::Integer,
+ Addr::Con(Constant::Number(n1)))))
}
}
- fn remainder(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, Vec<HeapCellValue>>
+ fn remainder(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, MachineError>
{
match (n1, n2) {
(Number::Integer(n1), Number::Integer(n2)) =>
if *n2 == BigInt::zero() {
- Err(functor!("evaluation_error", 1, [heap_atom!("zero_divisor")]))
+ Err(self.error_form(self.evaluation_error(EvalError::ZeroDivisor)))
} else {
Ok(Rc::new(&*n1 % &*n2))
},
- _ =>
- Err(functor!("evaluation_error", 1, [heap_atom!("expected_integer_args")]))
+ (Number::Integer(_), n2) =>
+ Err(self.error_form(self.type_error(ValidType::Integer,
+ Addr::Con(Constant::Number(n2))))),
+ (n1, _) =>
+ Err(self.error_form(self.type_error(ValidType::Integer,
+ Addr::Con(Constant::Number(n1)))))
}
}
- fn or(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, Vec<HeapCellValue>>
+ fn or(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, MachineError>
{
match (n1, n2) {
(Number::Integer(n1), Number::Integer(n2)) =>
- Ok(self.signed_bitwise_op(&*n1, &*n2, |u_n1, u_n2| u_n1 & u_n2)),
- _ =>
- Err(functor!("evaluation_error", 1, [heap_atom!("expected_integer_args")]))
+ Ok(self.signed_bitwise_op(&*n1, &*n2, |u_n1, u_n2| u_n1 & u_n2)),
+ (Number::Integer(_), n2) =>
+ Err(self.error_form(self.type_error(ValidType::Integer,
+ Addr::Con(Constant::Number(n2))))),
+ (n1, _) =>
+ Err(self.error_form(self.type_error(ValidType::Integer,
+ Addr::Con(Constant::Number(n1)))))
}
}
self.fail = true;
}
- fn throw_exception(&mut self, hcv: Vec<HeapCellValue>) {
- let h = self.heap.h;
-
- self.ball.0 = 0;
- self.ball.1.truncate(0);
-
- self.registers[1] = Addr::HeapCell(h);
-
- self.heap.append(hcv);
- self.goto_throw();
- }
-
- pub(super) fn existence_error(&self, name: ClauseName, arity: usize) -> Vec<HeapCellValue> {
- let name = HeapCellValue::Addr(Addr::Con(Constant::Atom(name)));
- let h = self.heap.h;
-
- let mut error = functor!("existence_error", 2, [heap_atom!("procedure"), heap_str!(3 + h)]);
- error.append(&mut functor!("/", 2, [name, heap_integer!(arity)], Fixity::In));
-
- error
- }
-
pub(super) fn setup_call_n(&mut self, arity: usize) -> Option<PredicateKey>
{
let addr = self.store(self.deref(self.registers[arity].clone()));
if let HeapCellValue::NamedStr(narity, name, _) = result {
if narity + arity > 63 {
- self.throw_exception(functor!("representation_error", 1,
- [heap_atom!("exceeds_max_arity")]));
+ let representation_error =
+ self.error_form(self.representation_error(RepFlag::MaxArity));
+
+ self.throw_exception(representation_error);
+
return None;
}
},
Addr::Con(Constant::Atom(name)) => (name, 0),
Addr::HeapCell(_) | Addr::StackCell(_, _) => {
- self.throw_exception(functor!("instantiation_error"));
+ let instantiation_error = self.error_form(self.instantiation_error());
+ self.throw_exception(instantiation_error);
+
return None;
},
_ => {
- self.throw_exception(functor!("type_error", 2,
- [heap_atom!("callable"),
- HeapCellValue::Addr(addr)]));
+ let type_error = self.error_form(self.type_error(ValidType::Callable, addr));
+ self.throw_exception(type_error);
+
return None;
}
};
fail
}
- fn try_get_arg(&mut self) -> Result<(), Vec<HeapCellValue>>
+ fn try_get_arg(&mut self) -> Result<(), MachineError>
{
let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
_ => self.fail = true
};
} else {
- return Err(functor!("type_error", 1, [heap_atom!("compound_expected")]))
+ return Err(self.error_form(self.type_error(ValidType::Compound, a2)));
}
}
self.p += 1;
- match (a1, a2) {
+ match (a1, a2.clone()) {
(Addr::Con(Constant::Usize(bp)),
Addr::Con(Constant::Number(Number::Integer(n)))) =>
match call_policy.downcast_mut::<CallWithInferenceLimitCallPolicy>().ok() {
None => panic!("install_inference_counter: should have installed \\
CallWithInferenceLimitCallPolicy.")
},
- _ => self.throw_exception(functor!("type_error", 1, [heap_atom!("integer_expected")]))
+ _ => {
+ let type_error = self.error_form(self.type_error(ValidType::Integer, a2));
+ self.throw_exception(type_error)
+ }
};
},
&BuiltInInstruction::RemoveCallPolicyCheck => {
};
}
- pub(super) fn try_functor(&mut self) -> Result<(), Vec<HeapCellValue>> {
+ pub(super) fn try_functor(&mut self) -> Result<(), MachineError> {
let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
match a1.clone() {
self.unify(a1, f_a);
} else {
- return Err(functor!("instantiation_error"));
+ return Err(self.error_form(self.instantiation_error()));
}
} else {
- return Err(functor!("instantiation_error"));
+ return Err(self.error_form(self.instantiation_error()));
}
},
_ => {
head_addr
}
- pub(super) fn try_from_list(&self, r: RegType) -> Result<Vec<Addr>, Vec<HeapCellValue>>
+ pub(super) fn try_from_list(&self, r: RegType) -> Result<Vec<Addr>, MachineError>
{
let a1 = self.store(self.deref(self[r].clone()));
HeapCellValue::Addr(Addr::Con(Constant::EmptyList)) =>
break,
hcv =>
- return Err(functor!("type_error", 2, [heap_atom!("list"), hcv]))
+ return Err(self.type_error(ValidType::List, hcv.as_addr(l)))
};
}
Ok(result)
},
Addr::HeapCell(_) | Addr::StackCell(..) =>
- Err(functor!("instantiation_error")),
+ Err(self.error_form(self.instantiation_error())),
addr =>
- Err(functor!("type_error", 2, [heap_atom!("list"), HeapCellValue::Addr(addr)]))
+ Err(self.error_form(self.type_error(ValidType::List, addr)))
}
}
- pub(super) fn project_onto_key(&self, a: Addr) -> Result<Addr, Vec<HeapCellValue>> {
+ pub(super) fn project_onto_key(&self, a: Addr) -> Result<Addr, MachineError> {
match self.store(self.deref(a)) {
Addr::Str(s) =>
match self.heap[s].clone() {
_ =>
panic!("Addr::Str doesn't point to NamedStr.")
},
- a => Err(functor!("type_error", 2, [heap_atom!("callable"), HeapCellValue::Addr(a)]))
+ a => Err(self.error_form(self.type_error(ValidType::Callable, a)))
}
}
self.unify(addr, xs);
}
}
-
+
pub(super) fn skip_max_list(&mut self) {
let max = self.store(self.deref(self[temp_v!(2)].clone()));
use prolog::heap_print::*;
use prolog::tabled_rc::*;
+mod machine_errors;
pub(crate) mod machine_state;
#[macro_use]
mod machine_state_impl;
indices.use_qualified_module(module, &exports)
},
- None => EvalSession::from(EvalError::ModuleNotFound)
+ None => EvalSession::from(SessionError::ModuleNotFound)
}
}
indices.use_module(module)
},
- None => EvalSession::from(EvalError::ModuleNotFound)
+ None => EvalSession::from(SessionError::ModuleNotFound)
}
}
{
match self.code_dir.get(&(name.clone(), arity)) {
Some(&CodeIndex (ref idx)) if idx.borrow().1 != clause_name!("user") =>
- return EvalSession::from(EvalError::ImpermissibleEntry(format!("{}/{}",
+ return EvalSession::from(SessionError::ImpermissibleEntry(format!("{}/{}",
name,
arity))),
_ => {}
PrinterOutputter::new())
.result();
- EvalSession::from(EvalError::QueryFailureWithException(msg))
+ EvalSession::from(SessionError::QueryFailureWithException(msg))
} else {
- EvalSession::from(EvalError::QueryFailure)
+ EvalSession::from(SessionError::QueryFailure)
}
}
self.ms.p = self.ms.or_stack[b].bp.clone();
if let CodePtr::TopLevel(_, 0) = self.ms.p {
- return EvalSession::from(EvalError::QueryFailure);
+ return EvalSession::from(SessionError::QueryFailure);
}
self.run_query(alloc_l, heap_l);
EvalSession::SubsequentQuerySuccess
}
} else {
- EvalSession::from(EvalError::QueryFailure)
+ EvalSession::from(SessionError::QueryFailure)
}
}
)
}
+macro_rules! set_void {
+ ($n:expr) => (
+ QueryInstruction::SetVoid($n)
+ )
+}
+
macro_rules! set_value {
($r:expr) => (
QueryInstruction::SetValue($r)
TopLevelWorker { parser: Parser::new(inner, atom_tbl) }
}
- pub fn parse_batch(&mut self, op_dir: &mut OpDir) -> Result<Vec<TopLevelPacket>, EvalError>
+ pub fn parse_batch(&mut self, op_dir: &mut OpDir) -> Result<Vec<TopLevelPacket>, SessionError>
{
let mut preds = vec![];
let mut mod_name = clause_name!("user");
submit(&mut wam, "f(X) :- X is 5 // 0.");
- assert_prolog_success!(&mut wam, "?- catch(f(X), evaluation_error(E), true), E = zero_divisor.",
+ assert_prolog_success!(&mut wam, "?- catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
[["E = zero_divisor", "X = _1"]]);
submit(&mut wam, "f(X) :- X is (5 rdiv 1) / 0.");
- assert_prolog_success!(&mut wam, "?- catch(f(X), evaluation_error(E), true), E = zero_divisor.",
+ assert_prolog_success!(&mut wam, "?- catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
[["E = zero_divisor", "X = _1"]]);
submit(&mut wam, "f(X) :- X is 5.0 / 0.");
- assert_prolog_success!(&mut wam, "?- catch(f(X), evaluation_error(E), true), E = zero_divisor.",
+ assert_prolog_success!(&mut wam, "?- catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
[["E = zero_divisor", "X = _1"]]);
assert_prolog_success!(&mut wam, "?- X is ((3 + 4) // 2) + 2 - 1 // 1, Y is 2+2, Z is X+Y.",
assert_prolog_success!(&mut wam, "?- X is 3 + 3, call(<, 3, X).", [["X = 6"]]);
assert_prolog_success!(&mut wam, "?- X is 3 + 3, X =:= 3 + 3.", [["X = 6"]]);
- assert_prolog_success!(&mut wam, "?- catch(call(is, X, 3 // 0), E, true).",
+ assert_prolog_success!(&mut wam, "?- catch(call(is, X, 3 // 0), error(E, _), true).",
[["X = _5", "E = evaluation_error(zero_divisor)"]]);
assert_prolog_success!(&mut wam, "?- catch(call(is, X, 3 // 3), _, true).", [["X = 1"]]);
; A = \"not 2 or 3\"
).");
- assert_prolog_success!(&mut wam, "?- catch(test(A), instantiation_error(_), true).");
+ assert_prolog_success!(&mut wam, "?- catch(test(A), error(instantiation_error, _), true).");
assert_prolog_success!(&mut wam, "?- A = 2, test(A).", [["A = 2"]]);
assert_prolog_success!(&mut wam, "?- A = 3, test(A), B = 3, test(B).", [["A = 3", "B = 3"]]);
assert_prolog_success!(&mut wam, "?- arg(3, f(a,b,c,d), Arg).", [["Arg = c"]]);
assert_prolog_success!(&mut wam, "?- arg(4, f(a,b,c,d), Arg).", [["Arg = d"]]);
- assert_prolog_success!(&mut wam, "?- catch(arg(N, f, Arg), type_error(E), true).",
- [["E = compound_expected", "Arg = _3", "N = _1"]]);
- assert_prolog_success!(&mut wam, "?- catch(arg(N, _, Arg), E, true).",
+ assert_prolog_success!(&mut wam, "?- catch(arg(N, f, Arg), error(type_error(E, _), _), true).",
+ [["E = compound", "Arg = _3", "N = _1"]]);
+
+ assert_prolog_success!(&mut wam, "?- catch(arg(N, _, Arg), error(E, _), true).",
[["E = instantiation_error", "Arg = _3", "N = _1"]]);
assert_prolog_success!(&mut wam, "?- arg(N, f(X, Y, Z), arg_val).",
assert_prolog_success!(&mut wam, "?- functor(Func, f, 3).", [["Func = f(_2, _3, _4)"]]);
assert_prolog_success!(&mut wam, "?- functor(Func, f, 4).", [["Func = f(_2, _3, _4, _5)"]]);
- assert_prolog_success!(&mut wam, "?- catch(functor(F, \"sdf\", 3), E, true).",
+ assert_prolog_success!(&mut wam, "?- catch(functor(F, \"sdf\", 3), error(E, _), true).",
[["E = instantiation_error", "F = _1"]]);
- assert_prolog_success!(&mut wam, "?- catch(functor(Func, F, 3), E, true).",
+ assert_prolog_success!(&mut wam, "?- catch(functor(Func, F, 3), error(E, _), true).",
[["E = instantiation_error", "Func = _1", "F = _2"]]);
- assert_prolog_success!(&mut wam, "?- catch(functor(Func, f, N), E, true).",
+ assert_prolog_success!(&mut wam, "?- catch(functor(Func, f, N), error(E, _), true).",
[["E = instantiation_error", "Func = _1", "N = _3"]]);
- assert_prolog_failure!(&mut wam, "?- catch(functor(Func, f, N), E, false).");
+ assert_prolog_failure!(&mut wam, "?- catch(functor(Func, f, N), error(E, _), false).");
assert_prolog_success!(&mut wam, "?- X is 3, call(integer, X).");
assert_prolog_failure!(&mut wam, "?- X is 3 + 3.5, call(integer, X).");
assert_prolog_success!(&mut wam, "?- Func =.. [atom].", [["Func = atom"]]);
assert_prolog_success!(&mut wam, "?- Func =.. [\"sdf\"].", [["Func = \"sdf\""]]);
assert_prolog_success!(&mut wam, "?- Func =.. [1].", [["Func = 1"]]);
- assert_prolog_success!(&mut wam, "?- catch(Func =.. [1,2], instantiation_error, true).");
+ assert_prolog_success!(&mut wam, "?- catch(Func =.. [1,2], error(instantiation_error, _), true).");
assert_prolog_success!(&mut wam, "?- f(1,2,3) =.. List.", [["List = [f, 1, 2, 3]"]]);
assert_prolog_success!(&mut wam, "?- f(1,2,3) =.. [f,1,2,3].");
assert_prolog_failure!(&mut wam, "?- f(1,2,3) =.. [f,1].");