throw a representation error if max arity is exceeded (#1483)
This commit is contained in:
@@ -867,7 +867,7 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
self.compile_query_line(term, term_loc, code, num_perm_vars, is_exposed);
|
self.compile_query_line(term, term_loc, code, num_perm_vars, is_exposed);
|
||||||
|
|
||||||
if self.marker.max_reg_allocated() > MAX_ARITY {
|
if self.marker.max_reg_allocated() > MAX_ARITY {
|
||||||
return Err(CompilationError::from(ParserError::ExceededMaxArity));
|
return Err(CompilationError::ExceededMaxArity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -939,7 +939,7 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
let mut fact = self.compile_target::<FactInstruction, _>(iter, GenContext::Head, false);
|
let mut fact = self.compile_target::<FactInstruction, _>(iter, GenContext::Head, false);
|
||||||
|
|
||||||
if self.marker.max_reg_allocated() > MAX_ARITY {
|
if self.marker.max_reg_allocated() > MAX_ARITY {
|
||||||
return Err(CompilationError::from(ParserError::ExceededMaxArity));
|
return Err(CompilationError::ExceededMaxArity);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut unsafe_var_marker = UnsafeVarMarker::new();
|
let mut unsafe_var_marker = UnsafeVarMarker::new();
|
||||||
@@ -1002,7 +1002,7 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if self.marker.max_reg_allocated() > MAX_ARITY {
|
if self.marker.max_reg_allocated() > MAX_ARITY {
|
||||||
return Err(CompilationError::from(ParserError::ExceededMaxArity));
|
return Err(CompilationError::ExceededMaxArity);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.mark_unsafe_fact_vars(&mut compiled_fact);
|
self.mark_unsafe_fact_vars(&mut compiled_fact);
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ impl Machine {
|
|||||||
let value = self.machine_st.registers[2];
|
let value = self.machine_st.registers[2];
|
||||||
unify_fn!(&mut self.machine_st, value, heap_loc_as_cell!(offset.heap_loc));
|
unify_fn!(&mut self.machine_st, value, heap_loc_as_cell!(offset.heap_loc));
|
||||||
}
|
}
|
||||||
Err(ParserError::UnexpectedEOF) => {
|
Err(CompilationError::ParserError(ParserError::UnexpectedEOF)) => {
|
||||||
let value = self.machine_st.registers[2];
|
let value = self.machine_st.registers[2];
|
||||||
self.machine_st.unify_atom(atom!("end_of_file"), value);
|
self.machine_st.unify_atom(atom!("end_of_file"), value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -452,6 +452,9 @@ impl MachineState {
|
|||||||
SessionError::OpIsInfixAndPostFix(op) => {
|
SessionError::OpIsInfixAndPostFix(op) => {
|
||||||
self.permission_error(Permission::Create, atom!("operator"), functor!(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::CompilationError(err) => self.syntax_error(err),
|
||||||
SessionError::PredicateNotMultifileOrDiscontiguous(compilation_target, key) => {
|
SessionError::PredicateNotMultifileOrDiscontiguous(compilation_target, key) => {
|
||||||
let functor_stub = functor_stub(key.0, key.1);
|
let functor_stub = functor_stub(key.0, key.1);
|
||||||
@@ -586,6 +589,7 @@ pub enum CompilationError {
|
|||||||
Arithmetic(ArithmeticError),
|
Arithmetic(ArithmeticError),
|
||||||
ParserError(ParserError),
|
ParserError(ParserError),
|
||||||
CannotParseCyclicTerm,
|
CannotParseCyclicTerm,
|
||||||
|
ExceededMaxArity,
|
||||||
ExpectedRel,
|
ExpectedRel,
|
||||||
InadmissibleFact,
|
InadmissibleFact,
|
||||||
InadmissibleQueryTerm,
|
InadmissibleQueryTerm,
|
||||||
@@ -629,6 +633,9 @@ impl CompilationError {
|
|||||||
&CompilationError::CannotParseCyclicTerm => {
|
&CompilationError::CannotParseCyclicTerm => {
|
||||||
functor!(atom!("cannot_parse_cyclic_term"))
|
functor!(atom!("cannot_parse_cyclic_term"))
|
||||||
}
|
}
|
||||||
|
&CompilationError::ExceededMaxArity => {
|
||||||
|
functor!(atom!("exceeded_max_arity"))
|
||||||
|
}
|
||||||
&CompilationError::ExpectedRel => {
|
&CompilationError::ExpectedRel => {
|
||||||
functor!(atom!("expected_relation"))
|
functor!(atom!("expected_relation"))
|
||||||
}
|
}
|
||||||
@@ -900,9 +907,7 @@ pub enum ExistenceError {
|
|||||||
pub enum SessionError {
|
pub enum SessionError {
|
||||||
CompilationError(CompilationError),
|
CompilationError(CompilationError),
|
||||||
CannotOverwriteBuiltIn(PredicateKey),
|
CannotOverwriteBuiltIn(PredicateKey),
|
||||||
// CannotOverwriteImport(Atom),
|
|
||||||
ExistenceError(ExistenceError),
|
ExistenceError(ExistenceError),
|
||||||
// InvalidFileName(Atom),
|
|
||||||
ModuleDoesNotContainExport(Atom, PredicateKey),
|
ModuleDoesNotContainExport(Atom, PredicateKey),
|
||||||
ModuleCannotImportSelf(Atom),
|
ModuleCannotImportSelf(Atom),
|
||||||
NamelessEntry,
|
NamelessEntry,
|
||||||
|
|||||||
@@ -602,7 +602,7 @@ impl MachineState {
|
|||||||
return Ok(unify_fn!(*self, var_names_offset, var_names_addr));
|
return Ok(unify_fn!(*self, var_names_offset, var_names_addr));
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if let ParserError::UnexpectedEOF = err {
|
if let CompilationError::ParserError(ParserError::UnexpectedEOF) = err {
|
||||||
self.eof_action(
|
self.eof_action(
|
||||||
self.registers[2],
|
self.registers[2],
|
||||||
stream,
|
stream,
|
||||||
|
|||||||
@@ -39,14 +39,14 @@ impl MockWAM {
|
|||||||
pub fn write_parsed_term_to_heap(
|
pub fn write_parsed_term_to_heap(
|
||||||
&mut self,
|
&mut self,
|
||||||
input_stream: Stream,
|
input_stream: Stream,
|
||||||
) -> Result<TermWriteResult, ParserError> {
|
) -> Result<TermWriteResult, CompilationError> {
|
||||||
self.machine_st.read(input_stream, &self.op_dir)
|
self.machine_st.read(input_stream, &self.op_dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_and_write_parsed_term_to_heap(
|
pub fn parse_and_write_parsed_term_to_heap(
|
||||||
&mut self,
|
&mut self,
|
||||||
term_string: &'static str,
|
term_string: &'static str,
|
||||||
) -> Result<TermWriteResult, ParserError> {
|
) -> Result<TermWriteResult, CompilationError> {
|
||||||
let stream = Stream::from_static_string(term_string, &mut self.machine_st.arena);
|
let stream = Stream::from_static_string(term_string, &mut self.machine_st.arena);
|
||||||
self.write_parsed_term_to_heap(stream)
|
self.write_parsed_term_to_heap(stream)
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,7 @@ impl MockWAM {
|
|||||||
pub fn parse_and_print_term(
|
pub fn parse_and_print_term(
|
||||||
&mut self,
|
&mut self,
|
||||||
term_string: &'static str,
|
term_string: &'static str,
|
||||||
) -> Result<String, ParserError> {
|
) -> Result<String, CompilationError> {
|
||||||
let term_write_result = self.parse_and_write_parsed_term_to_heap(term_string)?;
|
let term_write_result = self.parse_and_write_parsed_term_to_heap(term_string)?;
|
||||||
|
|
||||||
print_heap_terms(self.machine_st.heap.iter(), term_write_result.heap_loc);
|
print_heap_terms(self.machine_st.heap.iter(), term_write_result.heap_loc);
|
||||||
@@ -200,7 +200,7 @@ pub(crate) fn write_parsed_term_to_heap(
|
|||||||
machine_st: &mut MachineState,
|
machine_st: &mut MachineState,
|
||||||
input_stream: Stream,
|
input_stream: Stream,
|
||||||
op_dir: &OpDir,
|
op_dir: &OpDir,
|
||||||
) -> Result<TermWriteResult, ParserError> {
|
) -> Result<TermWriteResult, CompilationError> {
|
||||||
machine_st.read(input_stream, op_dir)
|
machine_st.read(input_stream, op_dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +209,7 @@ pub(crate) fn parse_and_write_parsed_term_to_heap(
|
|||||||
machine_st: &mut MachineState,
|
machine_st: &mut MachineState,
|
||||||
term_string: &'static str,
|
term_string: &'static str,
|
||||||
op_dir: &OpDir,
|
op_dir: &OpDir,
|
||||||
) -> Result<TermWriteResult, ParserError> {
|
) -> Result<TermWriteResult, CompilationError> {
|
||||||
let stream = Stream::from_static_string(term_string, &mut machine_st.arena);
|
let stream = Stream::from_static_string(term_string, &mut machine_st.arena);
|
||||||
write_parsed_term_to_heap(machine_st, stream, op_dir)
|
write_parsed_term_to_heap(machine_st, stream, op_dir)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -371,7 +371,6 @@ pub enum ArithmeticError {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ParserError {
|
pub enum ParserError {
|
||||||
BackQuotedString(usize, usize),
|
BackQuotedString(usize, usize),
|
||||||
ExceededMaxArity,
|
|
||||||
IO(IOError),
|
IO(IOError),
|
||||||
IncompleteReduction(usize, usize),
|
IncompleteReduction(usize, usize),
|
||||||
InvalidSingleQuotedCharacter(char),
|
InvalidSingleQuotedCharacter(char),
|
||||||
@@ -401,7 +400,6 @@ impl ParserError {
|
|||||||
pub fn as_atom(&self) -> Atom {
|
pub fn as_atom(&self) -> Atom {
|
||||||
match self {
|
match self {
|
||||||
ParserError::BackQuotedString(..) => atom!("back_quoted_string"),
|
ParserError::BackQuotedString(..) => atom!("back_quoted_string"),
|
||||||
ParserError::ExceededMaxArity => atom!("exceeded_max_arity"),
|
|
||||||
ParserError::IncompleteReduction(..) => atom!("incomplete_reduction"),
|
ParserError::IncompleteReduction(..) => atom!("incomplete_reduction"),
|
||||||
ParserError::InvalidSingleQuotedCharacter(..) => atom!("invalid_single_quoted_character"),
|
ParserError::InvalidSingleQuotedCharacter(..) => atom!("invalid_single_quoted_character"),
|
||||||
ParserError::IO(_) => atom!("input_output_error"),
|
ParserError::IO(_) => atom!("input_output_error"),
|
||||||
|
|||||||
13
src/read.rs
13
src/read.rs
@@ -5,6 +5,7 @@ use crate::atom_table::*;
|
|||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
use crate::iterators::*;
|
use crate::iterators::*;
|
||||||
use crate::machine::heap::*;
|
use crate::machine::heap::*;
|
||||||
|
use crate::machine::machine_errors::*;
|
||||||
use crate::machine::machine_indices::*;
|
use crate::machine::machine_indices::*;
|
||||||
use crate::machine::machine_state::MachineState;
|
use crate::machine::machine_state::MachineState;
|
||||||
use crate::machine::streams::*;
|
use crate::machine::streams::*;
|
||||||
@@ -40,14 +41,16 @@ impl MachineState {
|
|||||||
&mut self,
|
&mut self,
|
||||||
mut inner: Stream,
|
mut inner: Stream,
|
||||||
op_dir: &OpDir,
|
op_dir: &OpDir,
|
||||||
) -> Result<TermWriteResult, ParserError> {
|
) -> Result<TermWriteResult, CompilationError> {
|
||||||
let (term, num_lines_read) = {
|
let (term, num_lines_read) = {
|
||||||
let prior_num_lines_read = inner.lines_read();
|
let prior_num_lines_read = inner.lines_read();
|
||||||
let mut parser = Parser::new(inner, self);
|
let mut parser = Parser::new(inner, self);
|
||||||
|
|
||||||
parser.add_lines_read(prior_num_lines_read);
|
parser.add_lines_read(prior_num_lines_read);
|
||||||
|
|
||||||
let term = parser.read_term(&CompositeOpDir::new(op_dir, None))?;
|
let term = parser.read_term(&CompositeOpDir::new(op_dir, None))
|
||||||
|
.map_err(CompilationError::from)?;
|
||||||
|
|
||||||
(term, parser.lines_read() - prior_num_lines_read)
|
(term, parser.lines_read() - prior_num_lines_read)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -245,7 +248,7 @@ pub(crate) fn write_term_to_heap(
|
|||||||
term: &Term,
|
term: &Term,
|
||||||
heap: &mut Heap,
|
heap: &mut Heap,
|
||||||
atom_tbl: &mut AtomTable,
|
atom_tbl: &mut AtomTable,
|
||||||
) -> Result<TermWriteResult, ParserError> {
|
) -> Result<TermWriteResult, CompilationError> {
|
||||||
let term_writer = TermWriter::new(heap, atom_tbl);
|
let term_writer = TermWriter::new(heap, atom_tbl);
|
||||||
term_writer.write_term_to_heap(term)
|
term_writer.write_term_to_heap(term)
|
||||||
}
|
}
|
||||||
@@ -311,7 +314,7 @@ impl<'a, 'b> TermWriter<'a, 'b> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_term_to_heap(mut self, term: &'a Term) -> Result<TermWriteResult, ParserError> {
|
fn write_term_to_heap(mut self, term: &'a Term) -> Result<TermWriteResult, CompilationError> {
|
||||||
let heap_loc = self.heap.len();
|
let heap_loc = self.heap.len();
|
||||||
|
|
||||||
for term in breadth_first_iter(term, true) {
|
for term in breadth_first_iter(term, true) {
|
||||||
@@ -335,7 +338,7 @@ impl<'a, 'b> TermWriter<'a, 'b> {
|
|||||||
}
|
}
|
||||||
&TermRef::Clause(Level::Root, _, ref ct, subterms) => {
|
&TermRef::Clause(Level::Root, _, ref ct, subterms) => {
|
||||||
if subterms.len() > MAX_ARITY {
|
if subterms.len() > MAX_ARITY {
|
||||||
return Err(ParserError::ExceededMaxArity);
|
return Err(CompilationError::ExceededMaxArity);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.heap.push(if subterms.len() == 0 {
|
self.heap.push(if subterms.len() == 0 {
|
||||||
|
|||||||
Reference in New Issue
Block a user