Callable,
Character,
Compound,
+ Declaration,
Evaluable,
Float,
InByte,
// ValidType::PredicateIndicator => atom!("predicate_indicator"),
// ValidType::Variable => atom!("variable")
ValidType::TcpListener => atom!("tcp_listener"),
+ ValidType::Declaration => atom!("declaration"),
}
}
}
from: ErrorProvenance::Constructed,
}
}
+ ExistenceError::Declaration(name, arity) => {
+ let culprit = functor!(atom!("/"), [atom(name), fixnum(arity)]);
+
+ let stub = functor!(
+ atom!("existence_error"),
+ [atom(atom!("declaration")), str(self.heap.len(), 0)],
+ [culprit]
+ );
+
+ MachineError {
+ stub,
+ location: None,
+ from: ErrorProvenance::Constructed,
+ }
+ }
ExistenceError::ModuleSource(source) => {
let source_stub = source.as_functor_stub();
return self.arithmetic_error(err);
}
+ if let CompilationError::InvalidDecl(err) = err {
+ return self.declaration_error(err);
+ }
+
let location = err.line_and_col_num();
let len = self.heap.len();
- let stub = err.as_functor(&mut self.heap);
+ let stub = err.as_functor();
let stub = functor!(atom!("syntax_error"), [str(len, 0)], [stub]);
ExpectedRel,
InadmissibleFact,
InadmissibleQueryTerm,
- ExpectedDecl(Term),
- InvalidDecl(Atom, usize /* arity */),
- InvalidOpDeclName(Term),
- InvalidOpDeclSpecTerm(Term),
- InvalidOpDeclSpecValue(Atom),
- InvalidOpDeclPrec(Term),
+ InvalidDecl(DeclarationError),
InvalidMetaPredicateDecl,
InvalidModuleDecl,
InvalidModuleExport,
UnreadableTerm,
}
+#[derive(Debug)]
+pub enum DeclarationError {
+ ExpectedDecl(Term),
+ InvalidDecl(Atom, usize /* arity */),
+ InvalidOpDeclNameType(Term),
+ InvalidOpDeclSpecDomain(Term),
+ InvalidOpDeclSpecValue(Atom),
+ InvalidOpDeclPrecType(Term),
+ InvalidOpDeclPrecDomain(Fixnum),
+}
+
impl From<ArithmeticError> for CompilationError {
#[inline]
fn from(err: ArithmeticError) -> CompilationError {
}
}
- pub(crate) fn as_functor(&self, heap: &mut Heap) -> MachineStub {
+ pub(crate) fn as_functor(&self) -> MachineStub {
match self {
CompilationError::Arithmetic(..) => {
functor!(atom!("arithmetic_error"))
// TODO: type_error(callable, _).
functor!(atom!("inadmissible_query_term"))
}
- CompilationError::ExpectedDecl(_term) => {
- functor!(atom!("not_a_declaration"))
- }
- CompilationError::InvalidDecl(name, arity) => {
- let culprit = functor_stub(*name, *arity);
- functor!(
- atom!("existence_error"),
- [atom(atom!("declaration")), str(heap.len() + 2, 0)],
- [culprit]
- )
- }
- CompilationError::InvalidOpDeclName(_term) => {
- functor!(
- atom!("invalid_op_decl"),
- [atom(atom!("name")), atom(atom!("expected_string_or_atom"))]
- )
- }
- CompilationError::InvalidOpDeclSpecTerm(_term) => {
- functor!(
- atom!("invalid_op_decl"),
- [
- atom(atom!("specification")),
- atom(atom!("expected_string_or_atom"))
- ]
- )
- }
- CompilationError::InvalidOpDeclSpecValue(spec) => {
- let functor = functor!(atom!("invalid_value"), [atom(spec)]);
- functor!(
- atom!("invalid_op_decl"),
- [atom(atom!("specification")), str(heap.len() + 2, 0)],
- [functor]
- )
- }
- CompilationError::InvalidOpDeclPrec(_term) => {
- functor!(
- atom!("invalid_op_decl"),
- [
- atom(atom!("precedence")),
- atom(atom!("expected_integer_in_range_0_to_1200"))
- ]
- )
+ CompilationError::InvalidDecl(_) => {
+ functor!(atom!("declaration_error"))
}
CompilationError::InvalidMetaPredicateDecl => {
functor!(atom!("invalid_meta_predicate_decl"))
SourceSink,
Stream,
StreamOrAlias,
+ OperatorSpecifier,
+ OperatorPriority,
}
impl DomainErrorType {
DomainErrorType::SourceSink => atom!("source_sink"),
DomainErrorType::Stream => atom!("stream"),
DomainErrorType::StreamOrAlias => atom!("stream_or_alias"),
+ DomainErrorType::OperatorSpecifier => atom!("operator_specifier"),
+ DomainErrorType::OperatorPriority => atom!("operator_priority"),
}
}
}
Module(Atom),
ModuleSource(ModuleSource),
Procedure(Atom, usize),
+ Declaration(Atom, usize),
QualifiedProcedure {
module_name: Atom,
name: Atom,
}
);
}
+
+ pub(crate) fn declaration_error(&mut self, err: DeclarationError) -> MachineError {
+ match err {
+ DeclarationError::ExpectedDecl(_term) => self.type_error(
+ ValidType::Declaration,
+ atom_as_cell!(atom!("todo_insert_invalid_term_here")),
+ ),
+ DeclarationError::InvalidDecl(name, arity) => {
+ self.existence_error(ExistenceError::Declaration(name, arity))
+ }
+ DeclarationError::InvalidOpDeclNameType(_term) => self.type_error(
+ ValidType::List,
+ atom_as_cell!(atom!("todo_insert_invalid_term_here")),
+ ),
+ DeclarationError::InvalidOpDeclSpecDomain(_term) => self.domain_error(
+ DomainErrorType::OperatorSpecifier,
+ atom_as_cell!(atom!("todo_insert_invalid_term_here")),
+ ),
+ DeclarationError::InvalidOpDeclSpecValue(atom) => {
+ self.domain_error(DomainErrorType::OperatorSpecifier, atom_as_cell!(atom))
+ }
+ DeclarationError::InvalidOpDeclPrecType(_term) => self.type_error(
+ ValidType::Integer,
+ atom_as_cell!(atom!("todo_insert_invalid_term_here")),
+ ),
+ DeclarationError::InvalidOpDeclPrecDomain(num) => {
+ self.domain_error(DomainErrorType::OperatorPriority, fixnum_as_cell!(num))
+ }
+ }
+ }
}
#[allow(clippy::upper_case_acronyms)]
}
pub(crate) fn to_op_decl_spec(spec: Atom) -> Result<OpDeclSpec, CompilationError> {
- OpDeclSpec::try_from(spec).map_err(|_err| CompilationError::InvalidOpDeclSpecValue(spec))
+ OpDeclSpec::try_from(spec).map_err(|_err| {
+ CompilationError::InvalidDecl(DeclarationError::InvalidOpDeclSpecValue(spec))
+ })
}
fn setup_op_decl(mut terms: Vec<Term>, atom_tbl: &AtomTable) -> Result<OpDecl, CompilationError> {
+ // should allow non-partial lists?
let name = match terms.pop().unwrap() {
Term::Literal(_, Literal::Atom(name)) => name,
Term::Literal(_, Literal::Char(c)) => AtomTable::build_with(atom_tbl, &c.to_string()),
other => {
- return Err(CompilationError::InvalidOpDeclName(other));
+ return Err(CompilationError::InvalidDecl(
+ DeclarationError::InvalidOpDeclNameType(other),
+ ));
}
};
let spec = match terms.pop().unwrap() {
Term::Literal(_, Literal::Atom(name)) => name,
other => {
- return Err(CompilationError::InvalidOpDeclSpecTerm(other));
+ return Err(CompilationError::InvalidDecl(
+ DeclarationError::InvalidOpDeclSpecDomain(other),
+ ))
}
};
let spec = to_op_decl_spec(spec)?;
let prec = match terms.pop().unwrap() {
- // once msrv is >= 1.78 we can remove the ref and the clone of term below
- ref term @ Term::Literal(_, Literal::Fixnum(bi)) => match u16::try_from(bi.get_num()) {
+ Term::Literal(_, Literal::Fixnum(bi)) => match u16::try_from(bi.get_num()) {
Ok(n) if n <= 1200 => n,
_ => {
- return Err(CompilationError::InvalidOpDeclPrec(term.clone()));
+ return Err(CompilationError::InvalidDecl(
+ DeclarationError::InvalidOpDeclPrecDomain(bi),
+ ));
}
},
other => {
- return Err(CompilationError::InvalidOpDeclPrec(other));
+ return Err(CompilationError::InvalidDecl(
+ DeclarationError::InvalidOpDeclPrecType(other),
+ ));
}
};
let (module_name, name, meta_specs) = setup_meta_predicate(terms, loader)?;
Ok(Declaration::MetaPredicate(module_name, name, meta_specs))
}
- _ => Err(CompilationError::InvalidDecl(name, terms.len())),
+ _ => Err(CompilationError::InvalidDecl(
+ DeclarationError::InvalidDecl(name, terms.len()),
+ )),
},
- other => Err(CompilationError::ExpectedDecl(other)),
+ other => Err(CompilationError::InvalidDecl(
+ DeclarationError::ExpectedDecl(other),
+ )),
}
}
--- /dev/null
+:- op(10, xf, [example, test]).
\ No newline at end of file
--- /dev/null
+:- op(10, xf, [example, Var]).
\ No newline at end of file
--- /dev/null
+:- op(10, Var, example).
\ No newline at end of file
--- /dev/null
+:- op(Var, xf, example).
\ No newline at end of file
```trycmd
$ scryer-prolog -f --no-add-history tests-pl/invalid_decl1.pl -g halt
- error(syntax_error(invalid_op_decl(specification,invalid_value(moin))),load/1).
+ error(domain_error(operator_specifier,moin),load/1).
```
```trycmd
$ scryer-prolog -f --no-add-history tests-pl/invalid_decl2.pl -g halt
- error(syntax_error(invalid_op_decl(precedence,expected_integer_in_range_0_to_1200)),load/1).
+ error(domain_error(operator_priority,4000),load/1).
```
```trycmd
$ scryer-prolog -f --no-add-history tests-pl/invalid_decl3.pl -g halt
- error(syntax_error(invalid_op_decl(name,expected_string_or_atom)),load/1).
+ error(type_error(list,todo_insert_invalid_term_here),load/1).
```
```trycmd
$ scryer-prolog -f --no-add-history tests-pl/invalid_decl4.pl -g halt
- error(syntax_error(existence_error(declaration,op/4)),load/1).
+ error(existence_error(declaration,op/4),load/1).
```
```trycmd
$ scryer-prolog -f --no-add-history tests-pl/invalid_decl5.pl -g halt
- error(syntax_error(existence_error(declaration,(;)/2)),load/1).
+ error(existence_error(declaration,(;)/2),load/1).
```
```trycmd
$ scryer-prolog -f --no-add-history tests-pl/invalid_decl6.pl -g halt
- error(syntax_error(not_a_declaration),load/1).
+ error(type_error(declaration,todo_insert_invalid_term_here),load/1).
-```
\ No newline at end of file
+```
+
+```trycmd
+$ scryer-prolog -f --no-add-history tests-pl/invalid_decl7.pl -g halt
+ error(domain_error(operator_specifier,todo_insert_invalid_term_here),load/1).
+
+```
+
+```trycmd
+$ scryer-prolog -f --no-add-history tests-pl/invalid_decl8.pl -g halt
+% Warning: singleton variables Var at line 0 of invalid_decl8.pl
+ error(domain_error(operator_specifier,todo_insert_invalid_term_here),load/1).
+
+```
+
+```trycmd
+$ scryer-prolog -f --no-add-history tests-pl/invalid_decl9.pl -g halt
+% Warning: singleton variables Var at line 0 of invalid_decl9.pl
+ error(type_error(integer,todo_insert_invalid_term_here),load/1).
+
+```
+
+```trycmd
+$ scryer-prolog -f --no-add-history tests-pl/invalid_decl10.pl -g halt
+
+```
+
+The following test doesn't appear to terminate so its moved to a block quote for now
+
+> ```trycmd
+> $ scryer-prolog -f --no-add-history tests-pl/invalid_decl11.pl -g halt
+> % Warning: singleton variables Var at line 0 of invalid_decl11.pl
+> error(instantiation_error,load/1).
+> ```