Files
scryer-prolog/src/machine/machine_errors.rs

978 lines
30 KiB
Rust

use crate::atom_table::*;
use crate::parser::ast::*;
use crate::ffi::FFIError;
use crate::forms::*;
use crate::machine::heap::*;
use crate::machine::loader::CompilationTarget;
use crate::machine::machine_state::*;
use crate::machine::system_calls::BrentAlgState;
use crate::types::*;
pub type MachineStub = Vec<HeapCellValue>;
pub type MachineStubGen = Box<dyn Fn(&mut MachineState) -> MachineStub>;
#[derive(Debug, Clone, Copy)]
enum ErrorProvenance {
Constructed, // if constructed, offset the addresses.
Received, // otherwise, preserve the addresses.
}
#[derive(Debug)]
pub(crate) struct MachineError {
stub: MachineStub,
location: Option<(usize, usize)>, // line_num, col_num
from: ErrorProvenance,
}
// from 7.12.2 b) of 13211-1:1995
#[derive(Debug, Clone, Copy)]
pub(crate) enum ValidType {
Atom,
Atomic,
// Boolean,
Byte,
Callable,
Character,
Compound,
Evaluable,
Float,
InByte,
InCharacter,
Integer,
List,
#[allow(unused)] Number,
Pair,
// PredicateIndicator,
// Variable
TcpListener,
}
impl ValidType {
pub(crate) fn as_atom(self) -> Atom {
match self {
ValidType::Atom => atom!("atom"),
ValidType::Atomic => atom!("atomic"),
// ValidType::Boolean => atom!("boolean"),
ValidType::Byte => atom!("byte"),
ValidType::Callable => atom!("callable"),
ValidType::Character => atom!("character"),
ValidType::Compound => atom!("compound"),
ValidType::Evaluable => atom!("evaluable"),
ValidType::Float => atom!("float"),
ValidType::InByte => atom!("in_byte"),
ValidType::InCharacter => atom!("in_character"),
ValidType::Integer => atom!("integer"),
ValidType::List => atom!("list"),
ValidType::Number => atom!("number"),
ValidType::Pair => atom!("pair"),
// ValidType::PredicateIndicator => atom!("predicate_indicator"),
// ValidType::Variable => atom!("variable")
ValidType::TcpListener => atom!("tcp_listener"),
}
}
}
pub(crate) trait TypeError {
fn type_error(self, machine_st: &mut MachineState, valid_type: ValidType) -> MachineError;
}
impl TypeError for HeapCellValue {
fn type_error(self, _machine_st: &mut MachineState, valid_type: ValidType) -> MachineError {
let stub = functor!(
atom!("type_error"),
[atom(valid_type.as_atom()), cell(self)]
);
MachineError {
stub,
location: None,
from: ErrorProvenance::Received,
}
}
}
impl TypeError for MachineStub {
fn type_error(self, machine_st: &mut MachineState, valid_type: ValidType) -> MachineError {
let stub = functor!(
atom!("type_error"),
[atom(valid_type.as_atom()), str(machine_st.heap.len(), 0)],
[self]
);
MachineError {
stub,
location: None,
from: ErrorProvenance::Constructed,
}
}
}
impl TypeError for FunctorStub {
fn type_error(self, machine_st: &mut MachineState, valid_type: ValidType) -> MachineError {
let stub = functor!(
atom!("type_error"),
[atom(valid_type.as_atom()), str(machine_st.heap.len(), 0)],
[self]
);
MachineError {
stub,
location: None,
from: ErrorProvenance::Constructed,
}
}
}
impl TypeError for Number {
fn type_error(self, machine_st: &mut MachineState, valid_type: ValidType) -> MachineError {
let stub = functor!(
atom!("type_error"),
[
atom(valid_type.as_atom()),
number(&mut machine_st.arena, self)
]
);
MachineError {
stub,
location: None,
from: ErrorProvenance::Received,
}
}
}
pub(crate) trait PermissionError {
fn permission_error(
self,
machine_st: &mut MachineState,
index_atom: Atom,
perm: Permission,
) -> MachineError;
}
impl PermissionError for HeapCellValue {
fn permission_error(
self,
_machine_st: &mut MachineState,
index_atom: Atom,
perm: Permission,
) -> MachineError {
let stub = functor!(
atom!("permission_error"),
[atom(perm.as_atom()), atom(index_atom), cell(self)]
);
MachineError {
stub,
location: None,
from: ErrorProvenance::Received,
}
}
}
impl PermissionError for MachineStub {
fn permission_error(
self,
machine_st: &mut MachineState,
index_atom: Atom,
perm: Permission,
) -> MachineError {
let stub = functor!(
atom!("permission_error"),
[
atom(perm.as_atom()),
atom(index_atom),
str(machine_st.heap.len(), 0)
],
[self]
);
MachineError {
stub,
location: None,
from: ErrorProvenance::Constructed,
}
}
}
pub(super) trait DomainError {
fn domain_error(self, machine_st: &mut MachineState, error: DomainErrorType) -> MachineError;
}
impl DomainError for HeapCellValue {
fn domain_error(self, _machine_st: &mut MachineState, error: DomainErrorType) -> MachineError {
let stub = functor!(atom!("domain_error"), [atom(error.as_atom()), cell(self)]);
MachineError {
stub,
location: None,
from: ErrorProvenance::Received,
}
}
}
impl DomainError for Number {
fn domain_error(self, machine_st: &mut MachineState, error: DomainErrorType) -> MachineError {
let stub = functor!(
atom!("domain_error"),
[atom(error.as_atom()), number(&mut machine_st.arena, self)]
);
MachineError {
stub,
location: None,
from: ErrorProvenance::Received,
}
}
}
pub(super) type FunctorStub = [HeapCellValue; 3];
#[inline(always)]
pub(super) fn functor_stub(name: Atom, arity: usize) -> FunctorStub {
[atom_as_cell!(atom!("/"), 2),
atom_as_cell!(name),
fixnum_as_cell!(Fixnum::build_with(arity as i64))]
}
impl MachineState {
#[inline]
pub(super) fn interrupt_error(&mut self) -> MachineError {
let stub = functor!(atom!("$interrupt_thrown"));
MachineError {
stub,
location: None,
from: ErrorProvenance::Received,
}
}
pub(super) fn evaluation_error(&mut self, eval_error: EvalError) -> MachineError {
let stub = functor!(atom!("evaluation_error"), [atom(eval_error.as_atom())]);
MachineError {
stub,
location: None,
from: ErrorProvenance::Received,
}
}
pub(super) fn resource_error(&mut self, value: HeapCellValue) -> MachineError {
let stub = functor!(
atom!("resource_error"),
[atom(atom!("finite_memory")), cell(value)]
);
MachineError {
stub,
location: None,
from: ErrorProvenance::Received,
}
}
pub(super) fn type_error<T: TypeError>(
&mut self,
valid_type: ValidType,
culprit: T,
) -> MachineError {
culprit.type_error(self, valid_type)
}
pub(super) fn module_resolution_error(
&mut self,
mod_name: Atom,
name: Atom,
arity: usize,
) -> MachineError {
let h = self.heap.len();
let res_stub = functor!(atom!(":"), [atom(mod_name), atom(name)]);
let ind_stub = functor!(atom!("/"), [str(h + 2, 0), fixnum(arity)], [res_stub]);
let stub = functor!(atom!("evaluation_error"), [str(h, 0)], [ind_stub]);
MachineError {
stub,
location: None,
from: ErrorProvenance::Constructed,
}
}
pub(super) fn existence_error(&mut self, err: ExistenceError) -> MachineError {
match err {
ExistenceError::Module(name) => {
let stub = functor!(
atom!("existence_error"),
[atom(atom!("source_sink")), atom(name)]
);
MachineError {
stub,
location: None,
from: ErrorProvenance::Received,
}
}
ExistenceError::Procedure(name, arity) => {
let culprit = functor!(atom!("/"), [atom(name), fixnum(arity)]);
let stub = functor!(
atom!("existence_error"),
[atom(atom!("procedure")), str(self.heap.len(), 0)],
[culprit]
);
MachineError {
stub,
location: None,
from: ErrorProvenance::Constructed,
}
}
ExistenceError::ModuleSource(source) => {
let source_stub = source.as_functor_stub();
let stub = functor!(
atom!("existence_error"),
[atom(atom!("source_sink")), str(self.heap.len(), 0)],
[source_stub]
);
MachineError {
stub,
location: None,
from: ErrorProvenance::Constructed,
}
}
ExistenceError::SourceSink(culprit) => {
let stub = functor!(
atom!("existence_error"),
[atom(atom!("source_sink")), cell(culprit)]
);
MachineError {
stub,
location: None,
from: ErrorProvenance::Received,
}
}
ExistenceError::Stream(culprit) => {
let stub = functor!(
atom!("existence_error"),
[atom(atom!("stream")), cell(culprit)]
);
MachineError {
stub,
location: None,
from: ErrorProvenance::Received,
}
}
}
}
pub(super) fn permission_error<T: PermissionError>(
&mut self,
err: Permission,
index_atom: Atom,
culprit: T,
) -> MachineError {
culprit.permission_error(self, index_atom, err)
}
pub(super) fn evaluable_error(&mut self, name: Atom, arity: usize) -> MachineError {
let evaluable_stub = functor_stub(name, arity);
evaluable_stub.type_error(self, ValidType::Evaluable)
}
fn arithmetic_error(&mut self, err: ArithmeticError) -> MachineError {
match err {
ArithmeticError::UninstantiatedVar => self.instantiation_error(),
ArithmeticError::NonEvaluableFunctor(literal, arity) => {
let culprit = functor!(atom!("/"), [literal(literal), fixnum(arity)]);
self.type_error(ValidType::Evaluable, culprit)
}
}
}
#[inline]
pub(super) fn domain_error<T: DomainError>(
&mut self,
error: DomainErrorType,
culprit: T,
) -> MachineError {
culprit.domain_error(self, error)
}
pub(super) fn instantiation_error(&mut self) -> MachineError {
let stub = functor!(atom!("instantiation_error"));
MachineError {
stub,
location: None,
from: ErrorProvenance::Received,
}
}
pub(super) fn session_error(&mut self, err: SessionError) -> MachineError {
match err {
SessionError::CannotOverwriteBuiltIn(key) => {
// SessionError::CannotOverwriteImport(pred_atom) => {
self.permission_error(
Permission::Modify,
atom!("private_procedure"),
functor_stub(key.0, key.1).into_iter().collect::<MachineStub>(),
)
}
SessionError::ExistenceError(err) => self.existence_error(err),
// SessionError::InvalidFileName(filename) => {
// Self::existence_error(h, ExistenceError::Module(filename))
// }
SessionError::ModuleDoesNotContainExport(..) => {
let error_atom = atom!("module_does_not_contain_claimed_export");
self.permission_error(
Permission::Access,
atom!("private_procedure"),
functor!(error_atom),
)
}
SessionError::ModuleCannotImportSelf(module_name) => {
let error_atom = atom!("module_cannot_import_self");
self.permission_error(
Permission::Modify,
atom!("module"),
functor!(error_atom, [atom(module_name)]),
)
}
SessionError::NamelessEntry => {
let error_atom = atom!("nameless_procedure");
self.permission_error(Permission::Create, atom!("static_procedure"), functor!(error_atom))
}
SessionError::OpIsInfixAndPostFix(op) => {
self.permission_error(Permission::Create, atom!("operator"), functor!(op))
}
SessionError::CompilationError(CompilationError::ExceededMaxArity) => {
self.representation_error(RepFlag::MaxArity)
}
SessionError::CompilationError(err) => self.syntax_error(err),
SessionError::PredicateNotMultifileOrDiscontiguous(compilation_target, key) => {
let functor_stub = functor_stub(key.0, key.1);
let stub = functor!(
atom!(":"),
[
atom(compilation_target.module_name()),
str(self.heap.len() + 4, 0)
],
[functor_stub]
);
self.permission_error(
Permission::Modify,
atom!("not_declared_multifile_or_discontiguous"),
stub,
)
}
SessionError::QueryCannotBeDefinedAsFact => {
let error_atom = atom!("query_cannot_be_defined_as_fact");
self.permission_error(
Permission::Create,
atom!("static_procedure"),
functor!(error_atom),
)
}
}
}
pub(super) fn syntax_error<E: Into<CompilationError>>(&mut self, err: E) -> MachineError {
let err = err.into();
if let CompilationError::Arithmetic(err) = err {
return self.arithmetic_error(err);
}
let location = err.line_and_col_num();
let stub = err.as_functor();
let stub = functor!(atom!("syntax_error"), [str(self.heap.len(), 0)], [stub]);
MachineError {
stub,
location,
from: ErrorProvenance::Constructed,
}
}
pub(super) fn representation_error(&mut self, flag: RepFlag) -> MachineError {
let stub = functor!(atom!("representation_error"), [atom(flag.as_atom())]);
MachineError {
stub,
location: None,
from: ErrorProvenance::Received,
}
}
pub(super) fn ffi_error(&mut self, err: FFIError) -> MachineError {
let error_atom = match err {
FFIError::ValueCast => atom!("value_cast"),
FFIError::ValueDontFit => atom!("value_dont_fit"),
FFIError::InvalidFFIType => atom!("invalid_ffi_type"),
FFIError::InvalidStructName => atom!("invalid_struct_name"),
FFIError::FunctionNotFound => atom!("function_not_found"),
FFIError::StructNotFound => atom!("struct_not_found"),
};
let stub = functor!(atom!("ffi_error"),[atom(error_atom)]);
MachineError {
stub,
location: None,
from: ErrorProvenance::Constructed,
}
}
pub(super) fn error_form(&mut self, err: MachineError, src: FunctorStub) -> MachineStub {
let h = self.heap.len();
let location = err.location;
let stub_addition_len = if err.len() == 1 {
0 // if err contains 1 cell, it can be inlined at stub[1].
} else {
err.len()
};
let mut stub = vec![
atom_as_cell!(atom!("error"), 2),
str_loc_as_cell!(h + 3),
str_loc_as_cell!(h + 3 + stub_addition_len),
];
if stub_addition_len > 0 {
stub.extend(err.into_iter(3));
} else {
stub[1] = err.stub[0];
}
if let Some((line_num, _)) = location {
stub.push(atom_as_cell!(atom!(":"), 2));
stub.push(str_loc_as_cell!(h + 6 + stub_addition_len));
stub.push(integer_as_cell!(Number::arena_from(
line_num,
&mut self.arena
)));
}
stub.extend(src.iter());
stub
}
pub(super) fn throw_exception(&mut self, err: MachineStub) {
let h = self.heap.len();
let err_len = err.len();
self.ball.boundary = 0;
self.ball.stub.truncate(0);
self.heap.extend(err.into_iter());
self.registers[1] = if err_len == 1 {
heap_loc_as_cell!(h)
} else {
str_loc_as_cell!(h)
};
self.set_ball();
self.unwind_stack();
}
}
impl MachineError {
fn into_iter(self, offset: usize) -> Box<dyn Iterator<Item = HeapCellValue>> {
match self.from {
ErrorProvenance::Constructed => {
Box::new(self.stub.into_iter().map(move |hcv| hcv + offset))
}
ErrorProvenance::Received => Box::new(self.stub.into_iter()),
}
}
fn len(&self) -> usize {
self.stub.len()
}
}
#[derive(Debug)]
pub enum CompilationError {
Arithmetic(ArithmeticError),
ParserError(ParserError),
CannotParseCyclicTerm,
ExceededMaxArity,
ExpectedRel,
InadmissibleFact,
InadmissibleQueryTerm,
InconsistentEntry,
InvalidMetaPredicateDecl,
InvalidModuleDecl,
InvalidModuleExport,
InvalidRuleHead,
InvalidUseModuleDecl,
InvalidModuleResolution(Atom),
UnreadableTerm,
}
impl From<ArithmeticError> for CompilationError {
#[inline]
fn from(err: ArithmeticError) -> CompilationError {
CompilationError::Arithmetic(err)
}
}
impl From<ParserError> for CompilationError {
#[inline]
fn from(err: ParserError) -> CompilationError {
CompilationError::ParserError(err)
}
}
impl CompilationError {
pub(crate) fn line_and_col_num(&self) -> Option<(usize, usize)> {
match self {
&CompilationError::ParserError(ref err) => err.line_and_col_num(),
_ => None,
}
}
pub(crate) fn as_functor(&self) -> MachineStub {
match self {
&CompilationError::Arithmetic(..) => {
functor!(atom!("arithmetic_error"))
}
&CompilationError::CannotParseCyclicTerm => {
functor!(atom!("cannot_parse_cyclic_term"))
}
&CompilationError::ExceededMaxArity => {
functor!(atom!("exceeded_max_arity"))
}
&CompilationError::ExpectedRel => {
functor!(atom!("expected_relation"))
}
&CompilationError::InadmissibleFact => { // TODO: type_error(callable, _).
functor!(atom!("inadmissible_fact"))
}
&CompilationError::InadmissibleQueryTerm => { // TODO: type_error(callable, _).
functor!(atom!("inadmissible_query_term"))
}
&CompilationError::InconsistentEntry => {
functor!(atom!("inconsistent_entry"))
}
&CompilationError::InvalidMetaPredicateDecl => {
functor!(atom!("invalid_meta_predicate_decl"))
}
&CompilationError::InvalidModuleDecl => {
functor!(atom!("invalid_module_declaration"))
}
&CompilationError::InvalidModuleExport => {
functor!(atom!("invalid_module_export"))
}
&CompilationError::InvalidModuleResolution(ref module_name) => {
functor!(atom!("no_such_module"), [atom(module_name)])
}
&CompilationError::InvalidRuleHead => {
functor!(atom!("invalid_head_of_rule")) // TODO: type_error(callable, _).
}
&CompilationError::InvalidUseModuleDecl => {
functor!(atom!("invalid_use_module_declaration"))
}
&CompilationError::ParserError(ref err) => {
functor!(err.as_atom())
}
&CompilationError::UnreadableTerm => {
functor!(atom!("unreadable_term"))
}
}
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) enum Permission {
Access,
Create,
InputStream,
Modify,
Open,
OutputStream,
Reposition,
}
impl Permission {
#[inline]
pub(crate) fn as_atom(self) -> Atom {
match self {
Permission::Access => atom!("access"),
Permission::Create => atom!("create"),
Permission::InputStream => atom!("input"),
Permission::Modify => atom!("modify"),
Permission::Open => atom!("open"),
Permission::OutputStream => atom!("output"),
Permission::Reposition => atom!("reposition"),
}
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) enum DomainErrorType {
IOMode,
NotLessThanZero,
Order,
SourceSink,
Stream,
StreamOrAlias,
}
impl DomainErrorType {
pub(crate) fn as_atom(self) -> Atom {
match self {
DomainErrorType::IOMode => atom!("io_mode"),
DomainErrorType::NotLessThanZero => atom!("not_less_than_zero"),
DomainErrorType::Order => atom!("order"),
DomainErrorType::SourceSink => atom!("source_sink"),
DomainErrorType::Stream => atom!("stream"),
DomainErrorType::StreamOrAlias => atom!("stream_or_alias"),
}
}
}
// from 7.12.2 f) of 13211-1:1995
#[derive(Debug, Clone, Copy)]
pub(crate) enum RepFlag {
Character,
CharacterCode,
InCharacterCode,
MaxArity,
// MaxInteger,
// MinInteger,
Term,
}
impl RepFlag {
pub(crate) fn as_atom(self) -> Atom {
match self {
RepFlag::Character => atom!("character"),
RepFlag::CharacterCode => atom!("character_code"),
RepFlag::InCharacterCode => atom!("in_character_code"),
RepFlag::MaxArity => atom!("max_arity"),
RepFlag::Term => atom!("term"),
// RepFlag::MaxInteger => atom!("max_integer"),
// RepFlag::MinInteger => atom!("min_integer")
}
}
}
// from 7.12.2 g) of 13211-1:1995
#[derive(Debug, Clone, Copy)]
pub enum EvalError {
FloatOverflow,
Undefined,
// Underflow,
ZeroDivisor,
}
impl EvalError {
pub(crate) fn as_atom(self) -> Atom {
match self {
EvalError::FloatOverflow => atom!("float_overflow"),
EvalError::Undefined => atom!("undefined"),
// EvalError::FloatUnderflow => atom!("underflow"),
EvalError::ZeroDivisor => atom!("zero_divisor"),
}
}
}
// used by '$skip_max_list'.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CycleSearchResult {
Cyclic(usize),
EmptyList,
NotList(usize, HeapCellValue), // the list length until the second argument in the heap
PartialList(usize, Ref), // the list length (up to max), and an offset into the heap.
ProperList(usize), // the list length.
PStrLocation(usize, usize, usize), // list length (up to max), the heap address of the PStr, the offset
UntouchedList(usize, usize), // list length (up to max), the address of an uniterated Addr::Lis(address).
UntouchedCStr(Atom, usize),
}
impl MachineState {
// see 8.4.3 of Draft Technical Corrigendum 2.
pub(super) fn check_sort_errors(&mut self) -> CallResult {
let stub_gen = || functor_stub(atom!("sort"), 2);
let list = self.store(self.deref(self.registers[1]));
let sorted = self.store(self.deref(self.registers[2]));
match BrentAlgState::detect_cycles(&self.heap, list) {
CycleSearchResult::PartialList(..) => {
let err = self.instantiation_error();
return Err(self.error_form(err, stub_gen()))
}
CycleSearchResult::NotList(..) | CycleSearchResult::Cyclic(_) => {
let err = self.type_error(ValidType::List, list);
return Err(self.error_form(err, stub_gen()));
}
_ => {}
};
match BrentAlgState::detect_cycles(&self.heap, sorted) {
CycleSearchResult::NotList(..) | CycleSearchResult::Cyclic(_) if !sorted.is_var() => {
let err = self.type_error(ValidType::List, sorted);
Err(self.error_form(err, stub_gen()))
}
_ => Ok(()),
}
}
fn check_for_list_pairs(&mut self, mut list: HeapCellValue) -> CallResult {
let stub_gen = || functor_stub(atom!("keysort"), 2);
match BrentAlgState::detect_cycles(&self.heap, list) {
CycleSearchResult::NotList(..) | CycleSearchResult::Cyclic(_) if !list.is_var() => {
let err = self.type_error(ValidType::List, list);
Err(self.error_form(err, stub_gen()))
}
_ => {
loop {
read_heap_cell!(self.store(self.deref(list)),
(HeapCellValueTag::Lis, l) => {
let mut new_l = l;
loop {
read_heap_cell!(self.heap[new_l],
(HeapCellValueTag::Str, s) => {
new_l = s;
}
(HeapCellValueTag::Atom, (name, arity)) => {
if name == atom!("-") && arity == 2 {
break;
} else {
let err = self.type_error(
ValidType::Pair,
list_loc_as_cell!(l),
);
return Err(self.error_form(err, stub_gen()));
}
}
(HeapCellValueTag::Var | HeapCellValueTag::AttrVar) => {
break;
}
_ => {
let err = self.type_error(
ValidType::Pair,
list_loc_as_cell!(l),
);
return Err(self.error_form(err, stub_gen()));
}
);
}
list = heap_loc_as_cell!(l+1);
}
_ => {
break;
}
);
}
Ok(())
}
}
}
// see 8.4.4 of Draft Technical Corrigendum 2.
pub(super) fn check_keysort_errors(&mut self) -> CallResult {
let stub_gen = || functor_stub(atom!("keysort"), 2);
let pairs = self.store(self.deref(self[temp_v!(1)]));
let sorted = self.store(self.deref(self[temp_v!(2)]));
match BrentAlgState::detect_cycles(&self.heap, pairs) {
CycleSearchResult::PartialList(..) => {
let err = self.instantiation_error();
Err(self.error_form(err, stub_gen()))
}
CycleSearchResult::NotList(..) | CycleSearchResult::Cyclic(_) => {
let err = self.type_error(ValidType::List, pairs);
Err(self.error_form(err, stub_gen()))
}
_ => Ok(()),
}?;
self.check_for_list_pairs(sorted)
}
}
#[derive(Debug)]
pub enum ExistenceError {
Module(Atom),
ModuleSource(ModuleSource),
Procedure(Atom, usize),
SourceSink(HeapCellValue),
Stream(HeapCellValue),
}
#[derive(Debug)]
pub enum SessionError {
CompilationError(CompilationError),
CannotOverwriteBuiltIn(PredicateKey),
ExistenceError(ExistenceError),
ModuleDoesNotContainExport(Atom, PredicateKey),
ModuleCannotImportSelf(Atom),
NamelessEntry,
OpIsInfixAndPostFix(Atom),
PredicateNotMultifileOrDiscontiguous(CompilationTarget, PredicateKey),
QueryCannotBeDefinedAsFact,
}
#[derive(Debug)]
pub(crate) enum EvalSession {
// EntrySuccess,
Error(SessionError),
}
impl From<SessionError> for EvalSession {
#[inline]
fn from(err: SessionError) -> Self {
EvalSession::Error(err)
}
}
impl From<std::io::Error> for SessionError {
#[inline]
fn from(err: std::io::Error) -> SessionError {
SessionError::from(ParserError::from(err))
}
}
impl From<ParserError> for SessionError {
#[inline]
fn from(err: ParserError) -> Self {
SessionError::CompilationError(CompilationError::from(err))
}
}
impl From<CompilationError> for SessionError {
#[inline]
fn from(err: CompilationError) -> Self {
SessionError::CompilationError(err)
}
}
impl From<ParserError> for EvalSession {
#[inline]
fn from(err: ParserError) -> Self {
EvalSession::from(SessionError::from(err))
}
}