introduce bespoke Heap type for in-heap partial strings
This commit is contained in:
@@ -5,6 +5,7 @@ use crate::parser::ast::*;
|
||||
#[cfg(feature = "ffi")]
|
||||
use crate::ffi::FFIError;
|
||||
use crate::forms::*;
|
||||
use crate::functor_macro::*;
|
||||
use crate::machine::heap::*;
|
||||
use crate::machine::loader::CompilationTarget;
|
||||
use crate::machine::machine_state::*;
|
||||
@@ -12,20 +13,13 @@ use crate::machine::streams::*;
|
||||
use crate::machine::system_calls::BrentAlgState;
|
||||
use crate::types::*;
|
||||
|
||||
pub type MachineStub = Vec<HeapCellValue>;
|
||||
pub type MachineStub = Vec<FunctorElement>;
|
||||
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<ParserErrorSrc>,
|
||||
from: ErrorProvenance,
|
||||
}
|
||||
|
||||
// from 7.12.2 b) of 13211-1:1995
|
||||
@@ -91,45 +85,26 @@ 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)]
|
||||
[atom_as_cell((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 {
|
||||
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]
|
||||
[atom_as_cell((valid_type.as_atom())), functor(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,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,15 +114,14 @@ impl TypeError for Number {
|
||||
let stub = functor!(
|
||||
atom!("type_error"),
|
||||
[
|
||||
atom(valid_type.as_atom()),
|
||||
number(&mut machine_st.arena, self)
|
||||
atom_as_cell((valid_type.as_atom())),
|
||||
number(self, (&mut machine_st.arena))
|
||||
]
|
||||
);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -171,16 +145,15 @@ impl PermissionError for Atom {
|
||||
let stub = functor!(
|
||||
atom!("permission_error"),
|
||||
[
|
||||
atom(perm.as_atom()),
|
||||
atom(index_atom),
|
||||
cell(atom_as_cell!(self))
|
||||
atom_as_cell((perm.as_atom())),
|
||||
atom_as_cell(index_atom),
|
||||
atom_as_cell(self)
|
||||
]
|
||||
);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -214,13 +187,12 @@ impl PermissionError for HeapCellValue {
|
||||
|
||||
let stub = functor!(
|
||||
atom!("permission_error"),
|
||||
[atom(perm.as_atom()), atom(index_atom), cell(cell)]
|
||||
[atom_as_cell((perm.as_atom())), atom_as_cell(index_atom), cell(cell)]
|
||||
);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -228,24 +200,22 @@ impl PermissionError for HeapCellValue {
|
||||
impl PermissionError for MachineStub {
|
||||
fn permission_error(
|
||||
self,
|
||||
machine_st: &mut MachineState,
|
||||
_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]
|
||||
atom_as_cell((perm.as_atom())),
|
||||
atom_as_cell(index_atom),
|
||||
functor(self)
|
||||
]
|
||||
);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Constructed,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -256,32 +226,11 @@ pub(super) trait DomainError {
|
||||
|
||||
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)]);
|
||||
let stub = functor!(atom!("domain_error"), [atom_as_cell((error.as_atom())), cell(self)]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DomainError for FunctorStub {
|
||||
fn domain_error(
|
||||
self,
|
||||
machine_st: &mut MachineState,
|
||||
valid_type: DomainErrorType,
|
||||
) -> MachineError {
|
||||
let stub = functor!(
|
||||
atom!("domain_error"),
|
||||
[atom(valid_type.as_atom()), str(machine_st.heap.len(), 0)],
|
||||
[self]
|
||||
);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Constructed,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -290,26 +239,33 @@ 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)]
|
||||
[atom_as_cell((error.as_atom())), number(self, (&mut machine_st.arena))]
|
||||
);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) type FunctorStub = [HeapCellValue; 3];
|
||||
impl DomainError for MachineStub {
|
||||
fn domain_error(self, _machine_st: &mut MachineState, error: DomainErrorType) -> MachineError {
|
||||
let stub = functor!(
|
||||
atom!("domain_error"),
|
||||
[atom_as_cell((error.as_atom())), functor(self)]
|
||||
);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[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)),
|
||||
]
|
||||
pub(super) fn functor_stub(name: Atom, arity: usize) -> MachineStub {
|
||||
functor!(atom!("/"), [atom_as_cell(name), fixnum(arity)])
|
||||
}
|
||||
|
||||
impl MachineState {
|
||||
@@ -320,17 +276,15 @@ impl MachineState {
|
||||
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())]);
|
||||
let stub = functor!(atom!("evaluation_error"), [atom_as_cell((eval_error.as_atom()))]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,18 +293,17 @@ impl MachineState {
|
||||
ResourceError::FiniteMemory(size_requested) => {
|
||||
functor!(
|
||||
atom!("resource_error"),
|
||||
[atom(atom!("finite_memory")), cell(size_requested)]
|
||||
[atom_as_cell((atom!("finite_memory"))), cell(size_requested)]
|
||||
)
|
||||
}
|
||||
ResourceError::OutOfFiles => {
|
||||
functor!(atom!("resource_error"), [atom(atom!("file_descriptors"))])
|
||||
functor!(atom!("resource_error"), [atom_as_cell((atom!("file_descriptors")))])
|
||||
}
|
||||
};
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,13 +320,12 @@ impl MachineState {
|
||||
ExistenceError::Module(name) => {
|
||||
let stub = functor!(
|
||||
atom!("existence_error"),
|
||||
[atom(atom!("source_sink")), atom(name)]
|
||||
[atom_as_cell((atom!("source_sink"))), atom_as_cell(name)]
|
||||
);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
ExistenceError::QualifiedProcedure {
|
||||
@@ -381,36 +333,30 @@ impl MachineState {
|
||||
name,
|
||||
arity,
|
||||
} => {
|
||||
let h = self.heap.len();
|
||||
|
||||
let ind_stub = functor!(atom!("/"), [atom(name), fixnum(arity)]);
|
||||
let res_stub = functor!(atom!(":"), [atom(module_name), str(h + 3, 0)], [ind_stub]);
|
||||
let ind_stub = functor!(atom!("/"), [atom_as_cell(name), fixnum(arity)]);
|
||||
let res_stub = functor!(atom!(":"), [atom_as_cell(module_name), functor(ind_stub)]);
|
||||
|
||||
let stub = functor!(
|
||||
atom!("existence_error"),
|
||||
[atom(atom!("procedure")), str(h, 0)],
|
||||
[res_stub]
|
||||
[atom_as_cell((atom!("procedure"))), functor(res_stub)]
|
||||
);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Constructed,
|
||||
}
|
||||
}
|
||||
ExistenceError::Procedure(name, arity) => {
|
||||
let culprit = functor!(atom!("/"), [atom(name), fixnum(arity)]);
|
||||
let culprit = functor!(atom!("/"), [atom_as_cell(name), fixnum(arity)]);
|
||||
|
||||
let stub = functor!(
|
||||
atom!("existence_error"),
|
||||
[atom(atom!("procedure")), str(self.heap.len(), 0)],
|
||||
[culprit]
|
||||
[atom_as_cell((atom!("procedure"))), functor(culprit)]
|
||||
);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Constructed,
|
||||
}
|
||||
}
|
||||
ExistenceError::ModuleSource(source) => {
|
||||
@@ -418,43 +364,75 @@ impl MachineState {
|
||||
|
||||
let stub = functor!(
|
||||
atom!("existence_error"),
|
||||
[atom(atom!("source_sink")), str(self.heap.len(), 0)],
|
||||
[source_stub]
|
||||
[atom_as_cell((atom!("source_sink"))), functor(source_stub)]
|
||||
);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Constructed,
|
||||
}
|
||||
}
|
||||
ExistenceError::SourceSink(culprit) => {
|
||||
let stub = functor!(
|
||||
atom!("existence_error"),
|
||||
[atom(atom!("source_sink")), cell(culprit)]
|
||||
[atom_as_cell((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)]
|
||||
[atom_as_cell((atom!("stream"))), cell(culprit)]
|
||||
);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn directive_error(&mut self, err: DirectiveError) -> MachineError {
|
||||
match err {
|
||||
DirectiveError::ExpectedDirective(_term) => self.domain_error(
|
||||
DomainErrorType::Directive,
|
||||
atom_as_cell!(atom!("todo_insert_invalid_term_here")),
|
||||
),
|
||||
DirectiveError::InvalidDirective(name, arity) => {
|
||||
self.domain_error(DomainErrorType::Directive, functor_stub(name, arity))
|
||||
}
|
||||
DirectiveError::InvalidOpDeclNameType(_term) => self.type_error(
|
||||
ValidType::List,
|
||||
atom_as_cell!(atom!("todo_insert_invalid_term_here")),
|
||||
),
|
||||
DirectiveError::InvalidOpDeclSpecDomain(_term) => self.domain_error(
|
||||
DomainErrorType::OperatorSpecifier,
|
||||
atom_as_cell!(atom!("todo_insert_invalid_term_here")),
|
||||
),
|
||||
DirectiveError::InvalidOpDeclSpecValue(atom) => {
|
||||
self.domain_error(DomainErrorType::OperatorSpecifier, atom_as_cell!(atom))
|
||||
}
|
||||
DirectiveError::InvalidOpDeclPrecType(_term) => self.type_error(
|
||||
ValidType::Integer,
|
||||
atom_as_cell!(atom!("todo_insert_invalid_term_here")),
|
||||
),
|
||||
DirectiveError::InvalidOpDeclPrecDomain(num) => {
|
||||
self.domain_error(DomainErrorType::OperatorPriority, fixnum_as_cell!(num))
|
||||
}
|
||||
DirectiveError::ShallNotCreate(atom) => {
|
||||
self.permission_error(Permission::Create, atom!("operator"), atom)
|
||||
}
|
||||
DirectiveError::ShallNotModify(atom) => {
|
||||
self.permission_error(Permission::Modify, atom!("operator"), atom)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn permission_error<T: PermissionError>(
|
||||
&mut self,
|
||||
err: Permission,
|
||||
@@ -471,7 +449,6 @@ impl MachineState {
|
||||
|
||||
fn arithmetic_error(&mut self, err: ArithmeticError) -> MachineError {
|
||||
match err {
|
||||
ArithmeticError::UninstantiatedVar => self.instantiation_error(),
|
||||
ArithmeticError::NonEvaluableFunctor(cell, arity) => {
|
||||
let culprit = functor!(atom!("/"), [cell(cell), fixnum(arity)]);
|
||||
|
||||
@@ -495,7 +472,6 @@ impl MachineState {
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,15 +481,11 @@ impl MachineState {
|
||||
Permission::Modify,
|
||||
atom!("static_procedure"),
|
||||
functor_stub(key.0, key.1)
|
||||
.into_iter()
|
||||
.collect::<MachineStub>(),
|
||||
),
|
||||
SessionError::CannotOverwriteStaticProcedure(key) => self.permission_error(
|
||||
Permission::Modify,
|
||||
atom!("static_procedure"),
|
||||
functor_stub(key.0, key.1)
|
||||
.into_iter()
|
||||
.collect::<MachineStub>(),
|
||||
),
|
||||
SessionError::CannotOverwriteBuiltInModule(module) => {
|
||||
self.permission_error(Permission::Modify, atom!("static_module"), module)
|
||||
@@ -524,8 +496,7 @@ impl MachineState {
|
||||
|
||||
let stub = functor!(
|
||||
atom!("module_does_not_contain_claimed_export"),
|
||||
[atom(module_name), str(self.heap.len() + 4, 0)],
|
||||
[functor_stub]
|
||||
[atom_as_cell(module_name), functor(functor_stub)]
|
||||
);
|
||||
|
||||
self.permission_error(Permission::Access, atom!("private_procedure"), stub)
|
||||
@@ -536,7 +507,7 @@ impl MachineState {
|
||||
self.permission_error(
|
||||
Permission::Modify,
|
||||
atom!("module"),
|
||||
functor!(error_atom, [atom(module_name)]),
|
||||
functor!(error_atom, [atom_as_cell(module_name)]),
|
||||
)
|
||||
}
|
||||
SessionError::NamelessEntry => {
|
||||
@@ -555,15 +526,12 @@ impl MachineState {
|
||||
}
|
||||
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]
|
||||
atom_as_cell((compilation_target.module_name())),
|
||||
functor((key.0), [fixnum((key.1))])
|
||||
]
|
||||
);
|
||||
|
||||
self.permission_error(
|
||||
@@ -587,30 +555,27 @@ impl MachineState {
|
||||
}
|
||||
|
||||
let location = err.line_and_col_num();
|
||||
let len = self.heap.len();
|
||||
let stub = err.as_functor();
|
||||
|
||||
let stub = functor!(atom!("syntax_error"), [str(len, 0)], [stub]);
|
||||
let stub = functor!(atom!("syntax_error"), [functor(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())]);
|
||||
pub(super) fn representation_error(&self, flag: RepFlag) -> MachineError {
|
||||
let stub = functor!(atom!("representation_error"), [atom_as_cell((flag.as_atom()))]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ffi")]
|
||||
pub(super) fn ffi_error(&mut self, err: FFIError) -> MachineError {
|
||||
pub(super) fn ffi_error(&self, err: FFIError) -> MachineError {
|
||||
let error_atom = match err {
|
||||
FFIError::ValueCast => atom!("value_cast"),
|
||||
FFIError::ValueDontFit => atom!("value_dont_fit"),
|
||||
@@ -619,62 +584,44 @@ impl MachineState {
|
||||
FFIError::FunctionNotFound => atom!("function_not_found"),
|
||||
FFIError::StructNotFound => atom!("struct_not_found"),
|
||||
};
|
||||
let stub = functor!(atom!("ffi_error"), [atom(error_atom)]);
|
||||
let stub = functor!(atom!("ffi_error"), [atom_as_cell(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].
|
||||
pub(super) fn error_form(&mut self, err: MachineError, src: MachineStub) -> MachineStub {
|
||||
if let Some(ParserErrorSrc { line_num, .. }) = err.location {
|
||||
functor!(atom!("error"), [functor((err.stub)),
|
||||
functor((atom!(":")), [functor(src),
|
||||
number(line_num, (&mut self.arena))])])
|
||||
} 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];
|
||||
functor!(atom!("error"), [functor((err.stub)),
|
||||
functor(src)])
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ParserErrorSrc { 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
|
||||
// throw an error pre-allocated in the heap
|
||||
pub(super) fn throw_resource_error(&mut self, err_loc: usize) {
|
||||
self.registers[1] = str_loc_as_cell!(err_loc);
|
||||
self.set_ball();
|
||||
self.unwind_stack();
|
||||
}
|
||||
|
||||
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);
|
||||
let mut writer = Heap::functor_writer(err);
|
||||
|
||||
self.registers[1] = if err_len == 1 {
|
||||
heap_loc_as_cell!(h)
|
||||
} else {
|
||||
str_loc_as_cell!(h)
|
||||
self.registers[1] = match writer(&mut self.heap) {
|
||||
Ok(loc) => loc,
|
||||
Err(resource_err_loc) => {
|
||||
self.throw_resource_error(resource_err_loc);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
self.set_ball();
|
||||
@@ -682,21 +629,6 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
|
||||
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),
|
||||
@@ -715,12 +647,12 @@ pub enum CompilationError {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DirectiveError {
|
||||
ExpectedDirective(Term),
|
||||
ExpectedDirective(HeapCellValue),
|
||||
InvalidDirective(Atom, usize /* arity */),
|
||||
InvalidOpDeclNameType(Term),
|
||||
InvalidOpDeclSpecDomain(Term),
|
||||
InvalidOpDeclNameType(HeapCellValue),
|
||||
InvalidOpDeclSpecDomain(HeapCellValue),
|
||||
InvalidOpDeclSpecValue(Atom),
|
||||
InvalidOpDeclPrecType(Term),
|
||||
InvalidOpDeclPrecType(HeapCellValue),
|
||||
InvalidOpDeclPrecDomain(Fixnum),
|
||||
ShallNotCreate(Atom),
|
||||
ShallNotModify(Atom),
|
||||
@@ -757,11 +689,9 @@ impl CompilationError {
|
||||
functor!(atom!("exceeded_max_arity"))
|
||||
}
|
||||
CompilationError::InadmissibleFact => {
|
||||
// TODO: type_error(callable, _).
|
||||
functor!(atom!("inadmissible_fact"))
|
||||
}
|
||||
CompilationError::InadmissibleQueryTerm => {
|
||||
// TODO: type_error(callable, _).
|
||||
functor!(atom!("inadmissible_query_term"))
|
||||
}
|
||||
CompilationError::InvalidDirective(_) => {
|
||||
@@ -776,8 +706,8 @@ impl CompilationError {
|
||||
CompilationError::InvalidModuleExport => {
|
||||
functor!(atom!("invalid_module_export"))
|
||||
}
|
||||
CompilationError::InvalidModuleResolution(ref module_name) => {
|
||||
functor!(atom!("no_such_module"), [atom(module_name)])
|
||||
&CompilationError::InvalidModuleResolution(module_name) => {
|
||||
functor!(atom!("no_such_module"), [atom_as_cell(module_name)])
|
||||
}
|
||||
CompilationError::InvalidRuleHead => {
|
||||
functor!(atom!("invalid_head_of_rule")) // TODO: type_error(callable, _).
|
||||
@@ -896,14 +826,13 @@ impl EvalError {
|
||||
// used by '$skip_max_list'.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum CycleSearchResult {
|
||||
Cyclic(usize),
|
||||
Cyclic { lambda: usize }, // number of steps
|
||||
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),
|
||||
NotList { num_steps: usize, heap_loc: HeapCellValue },
|
||||
PartialList { num_steps: usize, heap_loc: HeapCellValue },
|
||||
ProperList { num_steps: usize },
|
||||
PStrLocation { num_steps: usize, pstr_loc: HeapCellValue },
|
||||
UntouchedList { num_steps: usize, list_loc: usize },
|
||||
}
|
||||
|
||||
impl MachineState {
|
||||
@@ -915,11 +844,11 @@ impl MachineState {
|
||||
let sorted = self.store(self.deref(self.registers[2]));
|
||||
|
||||
match BrentAlgState::detect_cycles(&self.heap, list) {
|
||||
CycleSearchResult::PartialList(..) => {
|
||||
CycleSearchResult::PartialList { .. } => {
|
||||
let err = self.instantiation_error();
|
||||
return Err(self.error_form(err, stub_gen()));
|
||||
}
|
||||
CycleSearchResult::NotList(..) | CycleSearchResult::Cyclic(_) => {
|
||||
CycleSearchResult::NotList { .. } | CycleSearchResult::Cyclic { .. } => {
|
||||
let err = self.type_error(ValidType::List, list);
|
||||
return Err(self.error_form(err, stub_gen()));
|
||||
}
|
||||
@@ -927,7 +856,7 @@ impl MachineState {
|
||||
};
|
||||
|
||||
match BrentAlgState::detect_cycles(&self.heap, sorted) {
|
||||
CycleSearchResult::NotList(..) | CycleSearchResult::Cyclic(_) if !sorted.is_var() => {
|
||||
CycleSearchResult::NotList { .. } | CycleSearchResult::Cyclic { .. } if !sorted.is_var() => {
|
||||
let err = self.type_error(ValidType::List, sorted);
|
||||
Err(self.error_form(err, stub_gen()))
|
||||
}
|
||||
@@ -939,7 +868,7 @@ impl MachineState {
|
||||
let stub_gen = || functor_stub(atom!("keysort"), 2);
|
||||
|
||||
match BrentAlgState::detect_cycles(&self.heap, list) {
|
||||
CycleSearchResult::NotList(..) | CycleSearchResult::Cyclic(_) if !list.is_var() => {
|
||||
CycleSearchResult::NotList { .. } | CycleSearchResult::Cyclic { .. } if !list.is_var() => {
|
||||
let err = self.type_error(ValidType::List, list);
|
||||
Err(self.error_form(err, stub_gen()))
|
||||
}
|
||||
@@ -1001,11 +930,11 @@ impl MachineState {
|
||||
let sorted = self.store(self.deref(self[temp_v!(2)]));
|
||||
|
||||
match BrentAlgState::detect_cycles(&self.heap, pairs) {
|
||||
CycleSearchResult::PartialList(..) => {
|
||||
CycleSearchResult::PartialList { .. } => {
|
||||
let err = self.instantiation_error();
|
||||
Err(self.error_form(err, stub_gen()))
|
||||
}
|
||||
CycleSearchResult::NotList(..) | CycleSearchResult::Cyclic(_) => {
|
||||
CycleSearchResult::NotList { .. } | CycleSearchResult::Cyclic { .. } => {
|
||||
let err = self.type_error(ValidType::List, pairs);
|
||||
Err(self.error_form(err, stub_gen()))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user