From 409f56ea37174da9e699b3f2adc1ea0db9d0fdb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bennet=20Ble=C3=9Fmann?= Date: Wed, 31 Jul 2024 23:48:27 +0200 Subject: [PATCH 01/11] use an enum for OpDesc spec --- src/forms.rs | 18 +--- src/heap_print.rs | 40 ++++---- src/machine/arithmetic_ops.rs | 10 +- src/machine/load_state.rs | 6 +- src/machine/mock_wam.rs | 18 ++-- src/machine/preprocessor.rs | 20 ++-- src/machine/system_calls.rs | 40 +++----- src/parser/ast.rs | 188 +++++++++++++++++++++++++--------- src/parser/parser.rs | 24 +++-- 9 files changed, 216 insertions(+), 148 deletions(-) diff --git a/src/forms.rs b/src/forms.rs index d18d41f15..2425b0626 100644 --- a/src/forms.rs +++ b/src/forms.rs @@ -24,8 +24,6 @@ use std::fmt; use std::ops::{AddAssign, Deref, DerefMut}; use std::path::PathBuf; -use crate::{is_infix, is_postfix}; - pub type PredicateKey = (Atom, usize); // name, arity. /* @@ -403,16 +401,6 @@ pub struct OpDecl { pub(crate) name: Atom, } -#[inline(always)] -pub(crate) fn fixity(spec: u32) -> Fixity { - match spec { - XFY | XFX | YFX => Fixity::In, - XF | YF => Fixity::Post, - FX | FY => Fixity::Pre, - _ => unreachable!(), - } -} - impl OpDecl { #[inline] pub(crate) fn new(op_desc: OpDesc, name: Atom) -> Self { @@ -429,7 +417,7 @@ impl OpDecl { } pub(crate) fn insert_into_op_dir(&self, op_dir: &mut OpDir) -> Option { - let key = (self.name, fixity(self.op_desc.get_spec() as u32)); + let key = (self.name, self.op_desc.get_spec().fixity()); if let Some(cell) = op_dir.get_mut(&key) { let (old_prec, old_spec) = cell.get(); @@ -447,7 +435,7 @@ impl OpDecl { ) -> Result<(), SessionError> { let (spec, name) = (self.op_desc.get_spec(), self.name); - if is_infix!(spec as u32) { + if spec.is_infix() { if let Some(desc) = existing_desc { if desc.post > 0 { return Err(SessionError::OpIsInfixAndPostFix(name)); @@ -455,7 +443,7 @@ impl OpDecl { } } - if is_postfix!(spec as u32) { + if spec.is_postfix() { if let Some(desc) = existing_desc { if desc.inf > 0 { return Err(SessionError::OpIsInfixAndPostFix(name)); diff --git a/src/heap_print.rs b/src/heap_print.rs index 4982b2dea..a25406172 100644 --- a/src/heap_print.rs +++ b/src/heap_print.rs @@ -6,8 +6,8 @@ use crate::parser::dashu::integer::Sign; use crate::parser::dashu::{ibig, Integer, Rational}; use crate::{ alpha_numeric_char, capital_letter_char, cut_char, decimal_digit_char, graphic_token_char, - is_fx, is_infix, is_postfix, is_prefix, is_xf, is_xfx, is_xfy, is_yfx, semicolon_char, - sign_char, single_quote_char, small_letter_char, solo_char, variable_indicator_char, + semicolon_char, sign_char, single_quote_char, small_letter_char, solo_char, + variable_indicator_char, }; use crate::forms::*; @@ -51,7 +51,7 @@ impl DirectedOp { fn is_prefix(&self) -> bool { match self { &DirectedOp::Left(_name, cell) | &DirectedOp::Right(_name, cell) => { - is_prefix!(cell.get_spec() as u32) + cell.get_spec().is_prefix() } } } @@ -60,7 +60,7 @@ impl DirectedOp { fn is_negative_sign(&self) -> bool { match self { &DirectedOp::Left(name, cell) | &DirectedOp::Right(name, cell) => { - name == atom!("-") && is_prefix!(cell.get_spec() as u32) + name == atom!("-") && cell.get_spec().is_prefix() } } } @@ -78,24 +78,24 @@ fn needs_bracketing(child_desc: OpDesc, op: &DirectedOp) -> bool { if &*name.as_str() == "-" { let child_assoc = child_desc.get_spec(); - if is_prefix!(spec) && (is_postfix!(child_assoc) || is_infix!(child_assoc)) { + if spec.is_prefix() && (child_assoc.is_postfix() || child_assoc.is_infix()) { return true; } } - let is_strict_right = is_yfx!(spec) || is_xfx!(spec) || is_fx!(spec); + let is_strict_right = spec.is_strict_right(); child_desc.get_prec() > priority || (child_desc.get_prec() == priority && is_strict_right) } DirectedOp::Right(_, cell) => { let (priority, spec) = cell.get(); - let is_strict_left = is_xfx!(spec) || is_xfy!(spec) || is_xf!(spec); + let is_strict_left = spec.is_strict_left(); if child_desc.get_prec() > priority || (child_desc.get_prec() == priority && is_strict_left) { true - } else if (is_postfix!(spec) || is_infix!(spec)) && !is_postfix!(child_desc.get_spec()) + } else if (spec.is_postfix() || spec.is_infix()) && !child_desc.get_spec().is_postfix() { *cell != child_desc && child_desc.get_prec() == priority } else { @@ -121,7 +121,7 @@ impl<'a, ElideLists> StackfulPreOrderHeapIter<'a, ElideLists> { None => return false, }; - let mut parent_spec = DirectedOp::Left(atom!("-"), OpDesc::build_with(200, FY as u8)); + let mut parent_spec = DirectedOp::Left(atom!("-"), OpDesc::build_with(200, FY)); loop { let cell = self.read_cell(h); @@ -131,7 +131,7 @@ impl<'a, ElideLists> StackfulPreOrderHeapIter<'a, ElideLists> { read_heap_cell!(self.heap[s], (HeapCellValueTag::Atom, (name, _arity)) => { if let Some(spec) = fetch_atom_op_spec(name, None, op_dir) { - if is_postfix!(spec.get_spec() as u32) || is_infix!(spec.get_spec() as u32) { + if spec.get_spec().is_postfix() || spec.get_spec().is_infix() { if needs_bracketing(spec, &parent_spec) { return false; } else { @@ -592,7 +592,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { } fn enqueue_op(&mut self, mut max_depth: usize, name: Atom, spec: OpDesc) { - if is_postfix!(spec.get_spec()) { + if spec.get_spec().is_postfix() { if self.max_depth_exhausted(max_depth) { self.iter.pop_stack(); self.state_stack.push(TokenOrRedirect::Atom(atom!("..."))); @@ -610,7 +610,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { right_directed_op, )); } - } else if is_prefix!(spec.get_spec()) { + } else if spec.get_spec().is_prefix() { if self.max_depth_exhausted(max_depth) { self.iter.pop_stack(); self.state_stack.push(TokenOrRedirect::Atom(atom!("..."))); @@ -639,7 +639,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { self.state_stack.push(TokenOrRedirect::Atom(atom!("..."))); } else if self.check_max_depth(&mut max_depth) { - if is_xfy!(spec.get_spec()) { + if matches!(spec.get_spec(), XFY) { let left_directed_op = DirectedOp::Left(name, spec); self.state_stack @@ -791,7 +791,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { let dot_atom = atom!("."); if let Some(spec) = op_desc { - if dot_atom == name && is_infix!(spec.get_spec()) && !self.ignore_ops { + if dot_atom == name && spec.get_spec().is_infix() && !self.ignore_ops { self.push_list(max_depth); return true; } @@ -1328,7 +1328,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { fn close_list(&mut self, switch: Rc>) -> Option>> { if let Some(TokenOrRedirect::Op(_, op_desc)) = self.state_stack.last() { - if is_postfix!(op_desc.get_spec()) || is_infix!(op_desc.get_spec()) { + if op_desc.get_spec().is_postfix() || op_desc.get_spec().is_infix() { self.state_stack.push(TokenOrRedirect::ChildCloseList); return None; } @@ -1775,7 +1775,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { TokenOrRedirect::Op(atom, op) => { self.print_op(&atom.as_str()); - if is_prefix!(op.get_spec()) { + if op.get_spec().is_prefix() { self.set_parent_of_first_op(Some(DirectedOp::Left(atom, op))); } } @@ -2120,9 +2120,9 @@ mod tests { all_cells_unmarked(&wam.machine_st.heap); wam.op_dir - .insert((atom!("+"), Fixity::In), OpDesc::build_with(500, YFX as u8)); + .insert((atom!("+"), Fixity::In), OpDesc::build_with(500, YFX)); wam.op_dir - .insert((atom!("*"), Fixity::In), OpDesc::build_with(400, YFX as u8)); + .insert((atom!("*"), Fixity::In), OpDesc::build_with(400, YFX)); assert_eq!( &wam.parse_and_print_term("[a|[] + b].").unwrap(), @@ -2139,10 +2139,10 @@ mod tests { all_cells_unmarked(&wam.machine_st.heap); wam.op_dir - .insert((atom!("fy"), Fixity::Pre), OpDesc::build_with(9, FY as u8)); + .insert((atom!("fy"), Fixity::Pre), OpDesc::build_with(9, FY)); wam.op_dir - .insert((atom!("yf"), Fixity::Post), OpDesc::build_with(9, YF as u8)); + .insert((atom!("yf"), Fixity::Post), OpDesc::build_with(9, YF)); assert_eq!( &wam.parse_and_print_term("(fy (fy 1)yf)yf.").unwrap(), diff --git a/src/machine/arithmetic_ops.rs b/src/machine/arithmetic_ops.rs index 2616e447a..a1e715e31 100644 --- a/src/machine/arithmetic_ops.rs +++ b/src/machine/arithmetic_ops.rs @@ -1419,11 +1419,11 @@ mod tests { let mut wam = MachineState::new(); let mut op_dir = default_op_dir(); - op_dir.insert((atom!("+"), Fixity::In), OpDesc::build_with(500, YFX as u8)); - op_dir.insert((atom!("-"), Fixity::In), OpDesc::build_with(500, YFX as u8)); - op_dir.insert((atom!("-"), Fixity::Pre), OpDesc::build_with(200, FY as u8)); - op_dir.insert((atom!("*"), Fixity::In), OpDesc::build_with(400, YFX as u8)); - op_dir.insert((atom!("/"), Fixity::In), OpDesc::build_with(400, YFX as u8)); + op_dir.insert((atom!("+"), Fixity::In), OpDesc::build_with(500, YFX)); + op_dir.insert((atom!("-"), Fixity::In), OpDesc::build_with(500, YFX)); + op_dir.insert((atom!("-"), Fixity::Pre), OpDesc::build_with(200, FY)); + op_dir.insert((atom!("*"), Fixity::In), OpDesc::build_with(400, YFX)); + op_dir.insert((atom!("/"), Fixity::In), OpDesc::build_with(400, YFX)); let term_write_result = parse_and_write_parsed_term_to_heap(&mut wam, "3 + 4 - 1 + 2.", &op_dir).unwrap(); diff --git a/src/machine/load_state.rs b/src/machine/load_state.rs index 89b82f1cf..86c1b6812 100644 --- a/src/machine/load_state.rs +++ b/src/machine/load_state.rs @@ -555,10 +555,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { } } ModuleExport::OpDecl(op_decl) => { - let op_dir_value_opt = op_dir.swap_remove(&( - op_decl.name, - fixity(op_decl.op_desc.get_spec() as u32), - )); + let op_dir_value_opt = op_dir + .swap_remove(&(op_decl.name, op_decl.op_desc.get_spec().fixity())); if let Some(op_desc) = op_dir_value_opt { retraction_info.push_record(op_retractor(*op_decl, op_desc)); diff --git a/src/machine/mock_wam.rs b/src/machine/mock_wam.rs index 0da42e08d..0a6f77239 100644 --- a/src/machine/mock_wam.rs +++ b/src/machine/mock_wam.rs @@ -264,11 +264,11 @@ mod tests { let mut wam = MachineState::new(); let mut op_dir = default_op_dir(); - op_dir.insert((atom!("+"), Fixity::In), OpDesc::build_with(500, YFX as u8)); - op_dir.insert((atom!("-"), Fixity::In), OpDesc::build_with(500, YFX as u8)); - op_dir.insert((atom!("*"), Fixity::In), OpDesc::build_with(500, YFX as u8)); - op_dir.insert((atom!("/"), Fixity::In), OpDesc::build_with(400, YFX as u8)); - op_dir.insert((atom!("="), Fixity::In), OpDesc::build_with(700, XFX as u8)); + op_dir.insert((atom!("+"), Fixity::In), OpDesc::build_with(500, YFX)); + op_dir.insert((atom!("-"), Fixity::In), OpDesc::build_with(500, YFX)); + op_dir.insert((atom!("*"), Fixity::In), OpDesc::build_with(500, YFX)); + op_dir.insert((atom!("/"), Fixity::In), OpDesc::build_with(400, YFX)); + op_dir.insert((atom!("="), Fixity::In), OpDesc::build_with(700, XFX)); { parse_and_write_parsed_term_to_heap(&mut wam, "f(X,X).", &op_dir).unwrap(); @@ -485,10 +485,10 @@ mod tests { let mut wam = MachineState::new(); let mut op_dir = default_op_dir(); - op_dir.insert((atom!("+"), Fixity::In), OpDesc::build_with(500, YFX as u8)); - op_dir.insert((atom!("-"), Fixity::In), OpDesc::build_with(500, YFX as u8)); - op_dir.insert((atom!("*"), Fixity::In), OpDesc::build_with(400, YFX as u8)); - op_dir.insert((atom!("/"), Fixity::In), OpDesc::build_with(400, YFX as u8)); + op_dir.insert((atom!("+"), Fixity::In), OpDesc::build_with(500, YFX)); + op_dir.insert((atom!("-"), Fixity::In), OpDesc::build_with(500, YFX)); + op_dir.insert((atom!("*"), Fixity::In), OpDesc::build_with(400, YFX)); + op_dir.insert((atom!("/"), Fixity::In), OpDesc::build_with(400, YFX)); { parse_and_write_parsed_term_to_heap(&mut wam, "f(X,X).", &op_dir).unwrap(); diff --git a/src/machine/preprocessor.rs b/src/machine/preprocessor.rs index b6e82ab70..ded794dd6 100644 --- a/src/machine/preprocessor.rs +++ b/src/machine/preprocessor.rs @@ -11,18 +11,12 @@ use indexmap::IndexSet; use std::cell::Cell; use std::convert::TryFrom; +pub(crate) fn to_op_decl(prec: u16, spec: OpDeclSpec, name: Atom) -> OpDecl { + OpDecl::new(OpDesc::build_with(prec, spec), name) +} -pub(crate) fn to_op_decl(prec: u16, spec: Atom, name: Atom) -> Result { - match spec { - atom!("xfx") => Ok(OpDecl::new(OpDesc::build_with(prec, XFX as u8), name)), - atom!("xfy") => Ok(OpDecl::new(OpDesc::build_with(prec, XFY as u8), name)), - atom!("yfx") => Ok(OpDecl::new(OpDesc::build_with(prec, YFX as u8), name)), - atom!("fx") => Ok(OpDecl::new(OpDesc::build_with(prec, FX as u8), name)), - atom!("fy") => Ok(OpDecl::new(OpDesc::build_with(prec, FY as u8), name)), - atom!("xf") => Ok(OpDecl::new(OpDesc::build_with(prec, XF as u8), name)), - atom!("yf") => Ok(OpDecl::new(OpDesc::build_with(prec, YF as u8), name)), - _ => Err(CompilationError::InconsistentEntry), - } +pub(crate) fn to_op_decl_spec(spec: Atom) -> Result { + OpDeclSpec::try_from(spec).map_err(|_err| CompilationError::InconsistentEntry) } fn setup_op_decl(mut terms: Vec, atom_tbl: &AtomTable) -> Result { @@ -38,6 +32,8 @@ fn setup_op_decl(mut terms: Vec, atom_tbl: &AtomTable) -> Result return Err(CompilationError::InconsistentEntry), }; + let spec = to_op_decl_spec(spec)?; + let prec = match terms.pop().unwrap() { Term::Literal(_, Literal::Fixnum(bi)) => match u16::try_from(bi.get_num()) { Ok(n) if n <= 1200 => n, @@ -46,7 +42,7 @@ fn setup_op_decl(mut terms: Vec, atom_tbl: &AtomTable) -> Result return Err(CompilationError::InconsistentEntry), }; - to_op_decl(prec, spec, name) + Ok(to_op_decl(prec, spec, name)) } fn setup_predicate_indicator(term: &mut Term) -> Result { diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 9cbdca3f1..ce5803756 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -24,7 +24,6 @@ use crate::machine::machine_errors::*; use crate::machine::machine_indices::*; use crate::machine::machine_state::*; use crate::machine::partial_string::*; -use crate::machine::preprocessor::to_op_decl; use crate::machine::stack::*; use crate::machine::streams::*; use crate::machine::{get_structure_index, Machine, VERIFY_ATTR_INTERRUPT_LOC}; @@ -102,6 +101,8 @@ use warp::hyper::{HeaderMap, Method}; use warp::{Buf, Filter}; use super::libraries; +use super::preprocessor::to_op_decl; +use super::preprocessor::to_op_decl_spec; #[cfg(feature = "repl")] pub(crate) fn get_key() -> KeyEvent { @@ -3987,19 +3988,6 @@ impl Machine { pub(crate) fn get_next_op_db_ref(&mut self) { let prec = self.deref_register(1); - fn get_spec(op_spec: u8) -> Atom { - match op_spec as u32 { - XFX => atom!("xfx"), - XFY => atom!("xfy"), - YFX => atom!("yfx"), - FX => atom!("fx"), - FY => atom!("fy"), - XF => atom!("xf"), - YF => atom!("yf"), - _ => unreachable!(), - } - } - let h = self.machine_st.heap.len(); fn write_op_functors_to_heap( @@ -4016,7 +4004,7 @@ impl Machine { continue; } - let spec_atom = get_spec(op_desc.get_spec()); + let spec_atom = op_desc.get_spec().get_spec(); heap.extend(functor!( atom!("op"), @@ -4038,17 +4026,14 @@ impl Machine { let orig_op = self.deref_register(3); let spec_num = if spec.get_tag() == HeapCellValueTag::Atom { - (match cell_as_atom!(spec) { - atom!("xfx") => XFX, - atom!("xfy") => XFY, - atom!("yfx") => YFX, - atom!("fx") => FX, - atom!("fy") => FY, - atom!("xf") => XF, - _ => unreachable!(), - }) as u8 + Some( + OpDeclSpec::try_from(cell_as_atom!(spec)) + .ok() + .filter(|spec| matches!(spec, XFX | XFY | YFX | FX | FY | XF)) + .expect("we should only get valid values != YF here"), + ) } else { - 0 + None }; let num_functors = if !orig_op.is_var() { @@ -4111,7 +4096,7 @@ impl Machine { } if (!orig_op.is_var() && atom_as_cell!(name) != orig_op) - || (!spec.is_var() && other_spec != spec_num) + || (!spec.is_var() && Some(other_spec) != spec_num) { return None; } @@ -5051,8 +5036,9 @@ impl Machine { } ); - let result = to_op_decl(priority, specifier, op) + let result = to_op_decl_spec(specifier) .map_err(SessionError::from) + .map(|specifier| to_op_decl(priority, specifier, op)) .and_then(|mut op_decl| { if op_decl.op_desc.get_prec() == 0 { op_decl.remove(&mut self.indices.op_dir); diff --git a/src/parser/ast.rs b/src/parser/ast.rs index 0e98aca84..ec699c211 100644 --- a/src/parser/ast.rs +++ b/src/parser/ast.rs @@ -26,13 +26,112 @@ pub type Specifier = u32; pub const MAX_ARITY: usize = 1023; -pub const XFX: u32 = 0x0001; -pub const XFY: u32 = 0x0002; -pub const YFX: u32 = 0x0004; -pub const XF: u32 = 0x0010; -pub const YF: u32 = 0x0020; -pub const FX: u32 = 0x0040; -pub const FY: u32 = 0x0080; +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub enum OpDeclSpec { + XFX = 0x0001, + XFY = 0x0002, + YFX = 0x0004, + XF = 0x0010, + YF = 0x0020, + FX = 0x0040, + FY = 0x0080, +} + +pub use OpDeclSpec::*; + +impl OpDeclSpec { + pub const fn value(self) -> u32 { + self as u32 + } + + pub fn get_spec(self) -> Atom { + match self { + XFX => atom!("xfx"), + XFY => atom!("xfy"), + YFX => atom!("yfx"), + FX => atom!("fx"), + FY => atom!("fy"), + XF => atom!("xf"), + YF => atom!("yf"), + } + } + + pub const fn is_prefix(self) -> bool { + matches!(self, Self::FX | Self::FY) + } + + pub const fn is_postfix(self) -> bool { + matches!(self, Self::XF | Self::YF) + } + + pub const fn is_infix(self) -> bool { + matches!(self, Self::XFX | Self::XFY | Self::YFX) + } + + pub const fn is_strict_left(self) -> bool { + matches!(self, Self::XFX | Self::XFY | Self::XF) + } + + pub const fn is_strict_right(self) -> bool { + matches!(self, Self::XFX | Self::YFX | Self::FX) + } + + #[inline(always)] + pub(crate) fn fixity(self) -> Fixity { + match self { + XFY | XFX | YFX => Fixity::In, + XF | YF => Fixity::Post, + FX | FY => Fixity::Pre, + } + } +} + +impl From for u8 { + fn from(value: OpDeclSpec) -> Self { + value as u8 + } +} + +impl From for u32 { + fn from(value: OpDeclSpec) -> Self { + value as u32 + } +} + +impl TryFrom for OpDeclSpec { + type Error = (); + + fn try_from(value: u8) -> Result { + Ok(match value { + 0x0001 => XFX, + 0x0002 => XFY, + 0x0004 => YFX, + 0x0010 => XF, + 0x0020 => YF, + 0x0040 => FX, + 0x0080 => FY, + _ => return Err(()), + }) + } +} + +impl TryFrom for OpDeclSpec { + type Error = (); + + fn try_from(value: Atom) -> Result { + Ok(match value { + atom!("xfx") => Self::XFX, + atom!("xfy") => Self::XFY, + atom!("yfx") => Self::YFX, + atom!("fx") => Self::FX, + atom!("fy") => Self::FY, + atom!("xf") => Self::XF, + atom!("yf") => Self::YF, + _ => return Err(()), + }) + } +} + pub const DELIMITER: u32 = 0x0100; pub const TERM: u32 = 0x1000; pub const LTERM: u32 = 0x3000; @@ -64,13 +163,13 @@ macro_rules! is_lterm { macro_rules! is_op { ($x:expr) => { $x as u32 - & ($crate::parser::ast::XF - | $crate::parser::ast::YF - | $crate::parser::ast::FX - | $crate::parser::ast::FY - | $crate::parser::ast::XFX - | $crate::parser::ast::XFY - | $crate::parser::ast::YFX) + & ($crate::parser::ast::XF as u32 + | $crate::parser::ast::YF as u32 + | $crate::parser::ast::FX as u32 + | $crate::parser::ast::FY as u32 + | $crate::parser::ast::XFX as u32 + | $crate::parser::ast::XFY as u32 + | $crate::parser::ast::YFX as u32) != 0 }; } @@ -84,14 +183,14 @@ macro_rules! is_negate { #[macro_export] macro_rules! is_prefix { ($x:expr) => { - $x as u32 & ($crate::parser::ast::FX | $crate::parser::ast::FY) != 0 + $x as u32 & ($crate::parser::ast::FX as u32 | $crate::parser::ast::FY as u32) != 0 }; } #[macro_export] macro_rules! is_postfix { ($x:expr) => { - $x as u32 & ($crate::parser::ast::XF | $crate::parser::ast::YF) != 0 + $x as u32 & ($crate::parser::ast::XF as u32 | $crate::parser::ast::YF as u32) != 0 }; } @@ -99,7 +198,9 @@ macro_rules! is_postfix { macro_rules! is_infix { ($x:expr) => { ($x as u32 - & ($crate::parser::ast::XFX | $crate::parser::ast::XFY | $crate::parser::ast::YFX)) + & ($crate::parser::ast::XFX as u32 + | $crate::parser::ast::XFY as u32 + | $crate::parser::ast::YFX as u32)) != 0 }; } @@ -107,49 +208,48 @@ macro_rules! is_infix { #[macro_export] macro_rules! is_xfx { ($x:expr) => { - ($x as u32 & $crate::parser::ast::XFX) != 0 + ($x as u32 & $crate::parser::ast::XFX as u32) != 0 }; } #[macro_export] macro_rules! is_xfy { ($x:expr) => { - ($x as u32 & $crate::parser::ast::XFY) != 0 + ($x as u32 & $crate::parser::ast::XFY as u32) != 0 }; } #[macro_export] macro_rules! is_yfx { ($x:expr) => { - ($x as u32 & $crate::parser::ast::YFX) != 0 + ($x as u32 & $crate::parser::ast::YFX as u32) != 0 }; } - #[macro_export] macro_rules! is_yf { ($x:expr) => { - ($x as u32 & $crate::parser::ast::YF) != 0 + ($x as u32 & $crate::parser::ast::YF as u32) != 0 }; } #[macro_export] macro_rules! is_xf { ($x:expr) => { - ($x as u32 & $crate::parser::ast::XF) != 0 + ($x as u32 & $crate::parser::ast::XF as u32) != 0 }; } #[macro_export] macro_rules! is_fx { ($x:expr) => { - ($x as u32 & $crate::parser::ast::FX) != 0 + ($x as u32 & $crate::parser::ast::FX as u32) != 0 }; } #[macro_export] macro_rules! is_fy { ($x:expr) => { - ($x as u32 & $crate::parser::ast::FY) != 0 + ($x as u32 & $crate::parser::ast::FY as u32) != 0 }; } @@ -264,18 +364,18 @@ pub struct OpDesc { impl OpDesc { #[inline] - pub fn build_with(prec: u16, spec: u8) -> Self { - OpDesc::new().with_spec(spec).with_prec(prec) + pub fn build_with(prec: u16, spec: OpDeclSpec) -> Self { + OpDesc::new().with_spec(spec as u8).with_prec(prec) } #[inline] - pub fn get(self) -> (u16, u8) { - (self.prec(), self.spec()) + pub fn get(self) -> (u16, OpDeclSpec) { + (self.prec(), self.get_spec()) } - pub fn set(&mut self, prec: u16, spec: u8) { + pub fn set(&mut self, prec: u16, spec: OpDeclSpec) { self.set_prec(prec); - self.set_spec(spec); + self.set_spec(spec as u8); } #[inline] @@ -284,13 +384,13 @@ impl OpDesc { } #[inline] - pub fn get_spec(self) -> u8 { - self.spec() + pub fn get_spec(self) -> OpDeclSpec { + OpDeclSpec::try_from(self.spec()).expect("OpDecl always contains a valud OpDeclSpec") } #[inline] pub fn arity(self) -> usize { - if self.spec() as u32 & (XFX | XFY | YFX) == 0 { + if !self.get_spec().is_infix() { 1 } else { 2 @@ -354,22 +454,10 @@ impl Unknown { pub fn default_op_dir() -> OpDir { let mut op_dir = OpDir::with_hasher(FxBuildHasher::default()); - op_dir.insert( - (atom!(":-"), Fixity::In), - OpDesc::build_with(1200, XFX as u8), - ); - op_dir.insert( - (atom!(":-"), Fixity::Pre), - OpDesc::build_with(1200, FX as u8), - ); - op_dir.insert( - (atom!("?-"), Fixity::Pre), - OpDesc::build_with(1200, FX as u8), - ); - op_dir.insert( - (atom!(","), Fixity::In), - OpDesc::build_with(1000, XFY as u8), - ); + op_dir.insert((atom!(":-"), Fixity::In), OpDesc::build_with(1200, XFX)); + op_dir.insert((atom!(":-"), Fixity::Pre), OpDesc::build_with(1200, FX)); + op_dir.insert((atom!("?-"), Fixity::Pre), OpDesc::build_with(1200, FX)); + op_dir.insert((atom!(","), Fixity::In), OpDesc::build_with(1000, XFY)); op_dir } diff --git a/src/parser/parser.rs b/src/parser/parser.rs index c4d509b4e..e89ac5a1a 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -385,10 +385,10 @@ impl<'a, R: CharRead> Parser<'a, R> { } } - fn push_unary_op(&mut self, td: TokenDesc, spec: Specifier, assoc: u32) { + fn push_unary_op(&mut self, td: TokenDesc, spec: Specifier, assoc: OpDeclSpec) { if let Some(mut arg1) = self.terms.pop() { if let Some(mut name) = self.terms.pop() { - if is_postfix!(assoc) { + if assoc.is_postfix() { mem::swap(&mut arg1, &mut name); } @@ -912,7 +912,11 @@ impl<'a, R: CharRead> Parser<'a, R> { // can't be prefix, so either inf == 0 // or post == 0. self.reduce_op(inf + post); - self.promote_atom_op(name, inf + post, spec & (XFX | XFY | YFX | YF | XF)); + self.promote_atom_op( + name, + inf + post, + spec & (XFX as u32 | XFY as u32 | YFX as u32 | YF as u32 | XF as u32), + ); } _ => { self.reduce_op(inf + post); @@ -923,14 +927,22 @@ impl<'a, R: CharRead> Parser<'a, R> { self.promote_atom_op( name, inf + post, - spec & (XFX | XFY | YFX | XF | YF), + spec & (XFX as u32 + | XFY as u32 + | YFX as u32 + | XF as u32 + | YF as u32), ); return Ok(true); } } - self.promote_atom_op(name, pre, spec & (FX | FY | NEGATIVE_SIGN)); + self.promote_atom_op( + name, + pre, + spec & (FX as u32 | FY as u32 | NEGATIVE_SIGN), + ); } } } else { @@ -1066,7 +1078,7 @@ impl<'a, R: CharRead> Parser<'a, R> { } Token::Comma => { self.reduce_op(1000); - self.shift(Token::Comma, 1000, XFY); + self.shift(Token::Comma, 1000, XFY as u32); } Token::End => match self.stack.last().map(|t| t.tt) { Some(TokenType::Open) From add03cb4ee62cce3422c2b0ba149a6b06db8113f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bennet=20Ble=C3=9Fmann?= Date: Sat, 3 Aug 2024 18:34:34 +0200 Subject: [PATCH 02/11] add test for declaration errors --- tests-pl/invalid_decl1.pl | 1 + tests-pl/invalid_decl2.pl | 1 + tests-pl/invalid_decl3.pl | 1 + tests-pl/invalid_decl4.pl | 1 + tests-pl/invalid_decl5.pl | 1 + tests-pl/invalid_decl6.pl | 1 + tests-pl/invalid_decl7.pl | 1 + .../cli/src_tests/declaration_errors.md | 35 +++++++++++++++++++ tests/scryer/main.rs | 3 +- 9 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 tests-pl/invalid_decl1.pl create mode 100644 tests-pl/invalid_decl2.pl create mode 100644 tests-pl/invalid_decl3.pl create mode 100644 tests-pl/invalid_decl4.pl create mode 100644 tests-pl/invalid_decl5.pl create mode 100644 tests-pl/invalid_decl6.pl create mode 100644 tests-pl/invalid_decl7.pl create mode 100644 tests/scryer/cli/src_tests/declaration_errors.md diff --git a/tests-pl/invalid_decl1.pl b/tests-pl/invalid_decl1.pl new file mode 100644 index 000000000..ac7a49205 --- /dev/null +++ b/tests-pl/invalid_decl1.pl @@ -0,0 +1 @@ +:- op(10, moin, example). \ No newline at end of file diff --git a/tests-pl/invalid_decl2.pl b/tests-pl/invalid_decl2.pl new file mode 100644 index 000000000..cf3c263c8 --- /dev/null +++ b/tests-pl/invalid_decl2.pl @@ -0,0 +1 @@ +:- op(4000, xfx, example). \ No newline at end of file diff --git a/tests-pl/invalid_decl3.pl b/tests-pl/invalid_decl3.pl new file mode 100644 index 000000000..42112dbbd --- /dev/null +++ b/tests-pl/invalid_decl3.pl @@ -0,0 +1 @@ +:- op(5, xfx, example(a,b)). \ No newline at end of file diff --git a/tests-pl/invalid_decl4.pl b/tests-pl/invalid_decl4.pl new file mode 100644 index 000000000..d1c9764db --- /dev/null +++ b/tests-pl/invalid_decl4.pl @@ -0,0 +1 @@ +:- op(5, xfx, example, too_many_arguments). \ No newline at end of file diff --git a/tests-pl/invalid_decl5.pl b/tests-pl/invalid_decl5.pl new file mode 100644 index 000000000..96646f81c --- /dev/null +++ b/tests-pl/invalid_decl5.pl @@ -0,0 +1 @@ +:- (test -> set_prolog_flag(double_quotes, codes); true). \ No newline at end of file diff --git a/tests-pl/invalid_decl6.pl b/tests-pl/invalid_decl6.pl new file mode 100644 index 000000000..b2935078b --- /dev/null +++ b/tests-pl/invalid_decl6.pl @@ -0,0 +1 @@ +:- 9001. \ No newline at end of file diff --git a/tests-pl/invalid_decl7.pl b/tests-pl/invalid_decl7.pl new file mode 100644 index 000000000..fcee15f31 --- /dev/null +++ b/tests-pl/invalid_decl7.pl @@ -0,0 +1 @@ +:- op(10, 42, example). \ No newline at end of file diff --git a/tests/scryer/cli/src_tests/declaration_errors.md b/tests/scryer/cli/src_tests/declaration_errors.md new file mode 100644 index 000000000..e2b711230 --- /dev/null +++ b/tests/scryer/cli/src_tests/declaration_errors.md @@ -0,0 +1,35 @@ +```trycmd +$ scryer-prolog -f --no-add-history tests-pl/invalid_decl1.pl -g halt + error(syntax_error(inconsistent_entry),load/1). + +``` + +```trycmd +$ scryer-prolog -f --no-add-history tests-pl/invalid_decl2.pl -g halt + error(syntax_error(inconsistent_entry),load/1). + +``` + +```trycmd +$ scryer-prolog -f --no-add-history tests-pl/invalid_decl3.pl -g halt + error(syntax_error(inconsistent_entry),load/1). + +``` + +```trycmd +$ scryer-prolog -f --no-add-history tests-pl/invalid_decl4.pl -g halt + error(syntax_error(inconsistent_entry),load/1). + +``` + +```trycmd +$ scryer-prolog -f --no-add-history tests-pl/invalid_decl5.pl -g halt + error(syntax_error(inconsistent_entry),load/1). + +``` + +```trycmd +$ scryer-prolog -f --no-add-history tests-pl/invalid_decl6.pl -g halt + error(syntax_error(inconsistent_entry),load/1). + +``` \ No newline at end of file diff --git a/tests/scryer/main.rs b/tests/scryer/main.rs index 85f7df98f..bb77f334b 100644 --- a/tests/scryer/main.rs +++ b/tests/scryer/main.rs @@ -23,5 +23,6 @@ fn cli_tests() { .default_bin_name("scryer-prolog") .case("tests/scryer/cli/issues/*.toml") .skip("tests/scryer/cli/issues/singleton_warning.toml") // wrong line number - .case("tests/scryer/cli/src_tests/*.toml"); + .case("tests/scryer/cli/src_tests/*.toml") + .case("tests/scryer/cli/src_tests/*.md"); } From 59af900aaf478f8397a36a025da74c0cb2a8d0f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bennet=20Ble=C3=9Fmann?= Date: Wed, 31 Jul 2024 23:49:42 +0200 Subject: [PATCH 03/11] split up CompilationError::InconsistentEntry --- src/machine/machine_errors.rs | 58 +++++++++++++++++-- src/machine/preprocessor.rs | 25 +++++--- .../cli/src_tests/declaration_errors.md | 12 ++-- 3 files changed, 74 insertions(+), 21 deletions(-) diff --git a/src/machine/machine_errors.rs b/src/machine/machine_errors.rs index 5860fb5d7..bc88e017c 100644 --- a/src/machine/machine_errors.rs +++ b/src/machine/machine_errors.rs @@ -572,9 +572,10 @@ impl MachineState { } let location = err.line_and_col_num(); - let stub = err.as_functor(); + let len = self.heap.len(); + let stub = err.as_functor(&mut self.heap); - let stub = functor!(atom!("syntax_error"), [str(self.heap.len(), 0)], [stub]); + let stub = functor!(atom!("syntax_error"), [str(len, 0)], [stub]); MachineError { stub, @@ -690,7 +691,12 @@ pub enum CompilationError { ExpectedRel, InadmissibleFact, InadmissibleQueryTerm, - InconsistentEntry, + ExpectedDecl(Term), + InvalidDecl(Atom, usize /* arity */), + InvalidOpDeclName(Term), + InvalidOpDeclSpecTerm(Term), + InvalidOpDeclSpecValue(Atom), + InvalidOpDeclPrec(Term), InvalidMetaPredicateDecl, InvalidModuleDecl, InvalidModuleExport, @@ -722,7 +728,7 @@ impl CompilationError { } } - pub(crate) fn as_functor(&self) -> MachineStub { + pub(crate) fn as_functor(&self, heap: &mut Heap) -> MachineStub { match self { CompilationError::Arithmetic(..) => { functor!(atom!("arithmetic_error")) @@ -744,8 +750,48 @@ impl CompilationError { // TODO: type_error(callable, _). functor!(atom!("inadmissible_query_term")) } - CompilationError::InconsistentEntry => { - functor!(atom!("inconsistent_entry")) + 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::InvalidMetaPredicateDecl => { functor!(atom!("invalid_meta_predicate_decl")) diff --git a/src/machine/preprocessor.rs b/src/machine/preprocessor.rs index ded794dd6..b4effba33 100644 --- a/src/machine/preprocessor.rs +++ b/src/machine/preprocessor.rs @@ -16,30 +16,37 @@ pub(crate) fn to_op_decl(prec: u16, spec: OpDeclSpec, name: Atom) -> OpDecl { } pub(crate) fn to_op_decl_spec(spec: Atom) -> Result { - OpDeclSpec::try_from(spec).map_err(|_err| CompilationError::InconsistentEntry) + OpDeclSpec::try_from(spec).map_err(|_err| CompilationError::InvalidOpDeclSpecValue(spec)) } fn setup_op_decl(mut terms: Vec, atom_tbl: &AtomTable) -> Result { 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()), - _ => return Err(CompilationError::InconsistentEntry), + other => { + return Err(CompilationError::InvalidOpDeclName(other)); + } }; let spec = match terms.pop().unwrap() { Term::Literal(_, Literal::Atom(name)) => name, - Term::Literal(_, Literal::Char(c)) => AtomTable::build_with(atom_tbl, &c.to_string()), - _ => return Err(CompilationError::InconsistentEntry), + other => { + return Err(CompilationError::InvalidOpDeclSpecTerm(other)); + } }; let spec = to_op_decl_spec(spec)?; let prec = match terms.pop().unwrap() { - Term::Literal(_, Literal::Fixnum(bi)) => match u16::try_from(bi.get_num()) { + term @ Term::Literal(_, Literal::Fixnum(bi)) => match u16::try_from(bi.get_num()) { Ok(n) if n <= 1200 => n, - _ => return Err(CompilationError::InconsistentEntry), + _ => { + return Err(CompilationError::InvalidOpDeclPrec(term)); + } }, - _ => return Err(CompilationError::InconsistentEntry), + other => { + return Err(CompilationError::InvalidOpDeclPrec(other)); + } }; Ok(to_op_decl(prec, spec, name)) @@ -327,9 +334,9 @@ pub(super) fn setup_declaration<'a, LS: LoadState<'a>>( let (module_name, name, meta_specs) = setup_meta_predicate(terms, loader)?; Ok(Declaration::MetaPredicate(module_name, name, meta_specs)) } - _ => Err(CompilationError::InconsistentEntry), + _ => Err(CompilationError::InvalidDecl(name, terms.len())), }, - _ => Err(CompilationError::InconsistentEntry), + other => Err(CompilationError::ExpectedDecl(other)), } } diff --git a/tests/scryer/cli/src_tests/declaration_errors.md b/tests/scryer/cli/src_tests/declaration_errors.md index e2b711230..684824270 100644 --- a/tests/scryer/cli/src_tests/declaration_errors.md +++ b/tests/scryer/cli/src_tests/declaration_errors.md @@ -1,35 +1,35 @@ ```trycmd $ scryer-prolog -f --no-add-history tests-pl/invalid_decl1.pl -g halt - error(syntax_error(inconsistent_entry),load/1). + error(syntax_error(invalid_op_decl(specification,invalid_value(moin))),load/1). ``` ```trycmd $ scryer-prolog -f --no-add-history tests-pl/invalid_decl2.pl -g halt - error(syntax_error(inconsistent_entry),load/1). + error(syntax_error(invalid_op_decl(precedence,expected_integer_in_range_0_to_1200)),load/1). ``` ```trycmd $ scryer-prolog -f --no-add-history tests-pl/invalid_decl3.pl -g halt - error(syntax_error(inconsistent_entry),load/1). + error(syntax_error(invalid_op_decl(name,expected_string_or_atom)),load/1). ``` ```trycmd $ scryer-prolog -f --no-add-history tests-pl/invalid_decl4.pl -g halt - error(syntax_error(inconsistent_entry),load/1). + error(syntax_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(inconsistent_entry),load/1). + error(syntax_error(existence_error(declaration,(;)/2)),load/1). ``` ```trycmd $ scryer-prolog -f --no-add-history tests-pl/invalid_decl6.pl -g halt - error(syntax_error(inconsistent_entry),load/1). + error(syntax_error(not_a_declaration),load/1). ``` \ No newline at end of file From c16d2d41477f8804addcb92475e469c2b850f186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bennet=20Ble=C3=9Fmann?= Date: Sat, 3 Aug 2024 20:04:16 +0200 Subject: [PATCH 04/11] fix compilation for 1.77 --- src/machine/preprocessor.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/machine/preprocessor.rs b/src/machine/preprocessor.rs index b4effba33..4c9c412e6 100644 --- a/src/machine/preprocessor.rs +++ b/src/machine/preprocessor.rs @@ -38,10 +38,11 @@ fn setup_op_decl(mut terms: Vec, atom_tbl: &AtomTable) -> Result match u16::try_from(bi.get_num()) { + // 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()) { Ok(n) if n <= 1200 => n, _ => { - return Err(CompilationError::InvalidOpDeclPrec(term)); + return Err(CompilationError::InvalidOpDeclPrec(term.clone())); } }, other => { From 880e22d1646c32499f798dbb114eecc4bbdf87a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bennet=20Ble=C3=9Fmann?= Date: Sat, 3 Aug 2024 22:07:48 +0200 Subject: [PATCH 05/11] adjust errors to be more standard compliant --- src/machine/machine_errors.rs | 92 +++++++++---------- src/machine/machine_state.rs | 30 ++++++ src/machine/preprocessor.rs | 32 +++++-- tests-pl/invalid_decl10.pl | 1 + tests-pl/invalid_decl11.pl | 1 + tests-pl/invalid_decl8.pl | 1 + tests-pl/invalid_decl9.pl | 1 + .../cli/src_tests/declaration_errors.md | 47 ++++++++-- 8 files changed, 139 insertions(+), 66 deletions(-) create mode 100644 tests-pl/invalid_decl10.pl create mode 100644 tests-pl/invalid_decl11.pl create mode 100644 tests-pl/invalid_decl8.pl create mode 100644 tests-pl/invalid_decl9.pl diff --git a/src/machine/machine_errors.rs b/src/machine/machine_errors.rs index bc88e017c..899424b41 100644 --- a/src/machine/machine_errors.rs +++ b/src/machine/machine_errors.rs @@ -38,6 +38,7 @@ pub(crate) enum ValidType { Callable, Character, Compound, + Declaration, Evaluable, Float, InByte, @@ -73,6 +74,7 @@ impl ValidType { // ValidType::PredicateIndicator => atom!("predicate_indicator"), // ValidType::Variable => atom!("variable") ValidType::TcpListener => atom!("tcp_listener"), + ValidType::Declaration => atom!("declaration"), } } } @@ -393,6 +395,21 @@ impl MachineState { 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(); @@ -571,9 +588,13 @@ impl MachineState { 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]); @@ -691,12 +712,7 @@ pub enum CompilationError { ExpectedRel, InadmissibleFact, InadmissibleQueryTerm, - ExpectedDecl(Term), - InvalidDecl(Atom, usize /* arity */), - InvalidOpDeclName(Term), - InvalidOpDeclSpecTerm(Term), - InvalidOpDeclSpecValue(Atom), - InvalidOpDeclPrec(Term), + InvalidDecl(DeclarationError), InvalidMetaPredicateDecl, InvalidModuleDecl, InvalidModuleExport, @@ -706,6 +722,17 @@ pub enum CompilationError { UnreadableTerm, } +#[derive(Debug)] +pub enum DeclarationError { + ExpectedDecl(Term), + InvalidDecl(Atom, usize /* arity */), + InvalidOpDeclNameType(Term), + InvalidOpDeclSpecDomain(Term), + InvalidOpDeclSpecValue(Atom), + InvalidOpDeclPrecType(Term), + InvalidOpDeclPrecDomain(Fixnum), +} + impl From for CompilationError { #[inline] fn from(err: ArithmeticError) -> CompilationError { @@ -728,7 +755,7 @@ impl 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")) @@ -750,48 +777,8 @@ impl CompilationError { // 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")) @@ -855,6 +842,8 @@ pub(crate) enum DomainErrorType { SourceSink, Stream, StreamOrAlias, + OperatorSpecifier, + OperatorPriority, } impl DomainErrorType { @@ -866,6 +855,8 @@ 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"), } } } @@ -1044,6 +1035,7 @@ pub enum ExistenceError { Module(Atom), ModuleSource(ModuleSource), Procedure(Atom, usize), + Declaration(Atom, usize), QualifiedProcedure { module_name: Atom, name: Atom, diff --git a/src/machine/machine_state.rs b/src/machine/machine_state.rs index e90b86440..4f03c8e03 100644 --- a/src/machine/machine_state.rs +++ b/src/machine/machine_state.rs @@ -978,6 +978,36 @@ impl MachineState { } ); } + + 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)] diff --git a/src/machine/preprocessor.rs b/src/machine/preprocessor.rs index 4c9c412e6..4fcdf9b71 100644 --- a/src/machine/preprocessor.rs +++ b/src/machine/preprocessor.rs @@ -16,37 +16,47 @@ pub(crate) fn to_op_decl(prec: u16, spec: OpDeclSpec, name: Atom) -> OpDecl { } pub(crate) fn to_op_decl_spec(spec: Atom) -> Result { - 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, atom_tbl: &AtomTable) -> Result { + // 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), + )); } }; @@ -335,9 +345,13 @@ pub(super) fn setup_declaration<'a, LS: LoadState<'a>>( 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), + )), } } diff --git a/tests-pl/invalid_decl10.pl b/tests-pl/invalid_decl10.pl new file mode 100644 index 000000000..82838ee62 --- /dev/null +++ b/tests-pl/invalid_decl10.pl @@ -0,0 +1 @@ +:- op(10, xf, [example, test]). \ No newline at end of file diff --git a/tests-pl/invalid_decl11.pl b/tests-pl/invalid_decl11.pl new file mode 100644 index 000000000..9d4c61930 --- /dev/null +++ b/tests-pl/invalid_decl11.pl @@ -0,0 +1 @@ +:- op(10, xf, [example, Var]). \ No newline at end of file diff --git a/tests-pl/invalid_decl8.pl b/tests-pl/invalid_decl8.pl new file mode 100644 index 000000000..67432dbbf --- /dev/null +++ b/tests-pl/invalid_decl8.pl @@ -0,0 +1 @@ +:- op(10, Var, example). \ No newline at end of file diff --git a/tests-pl/invalid_decl9.pl b/tests-pl/invalid_decl9.pl new file mode 100644 index 000000000..0721f18ba --- /dev/null +++ b/tests-pl/invalid_decl9.pl @@ -0,0 +1 @@ +:- op(Var, xf, example). \ No newline at end of file diff --git a/tests/scryer/cli/src_tests/declaration_errors.md b/tests/scryer/cli/src_tests/declaration_errors.md index 684824270..caa304122 100644 --- a/tests/scryer/cli/src_tests/declaration_errors.md +++ b/tests/scryer/cli/src_tests/declaration_errors.md @@ -1,35 +1,68 @@ ```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). +> ``` From 17a816eff424d96b9c3b14b3e34ed8fae9a793d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bennet=20Ble=C3=9Fmann?= Date: Sat, 3 Aug 2024 22:41:02 +0200 Subject: [PATCH 06/11] impl PartialEq and PartialEq<&str> for Atom --- src/atom_table.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/atom_table.rs b/src/atom_table.rs index 4a426cd0c..ea3a3a782 100644 --- a/src/atom_table.rs +++ b/src/atom_table.rs @@ -56,6 +56,18 @@ impl indexmap::Equivalent for str { } } +impl PartialEq for Atom { + fn eq(&self, other: &str) -> bool { + self.as_str().deref() == other + } +} + +impl PartialEq<&str> for Atom { + fn eq(&self, &other: &&str) -> bool { + self.as_str().deref() == other + } +} + const ATOM_TABLE_INIT_SIZE: usize = 1 << 16; const ATOM_TABLE_ALIGN: usize = 8; From df33da111e04577fad169e552846c8d48e77e5ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bennet=20Ble=C3=9Fmann?= Date: Sat, 3 Aug 2024 22:59:29 +0200 Subject: [PATCH 07/11] ajust/add devlaration errors to be more standard compliant --- src/machine/machine_errors.rs | 24 +++++++++++++ src/machine/machine_state.rs | 8 ++++- src/machine/preprocessor.rs | 18 ++++++++++ tests-pl/invalid_decl12.pl | 1 + tests-pl/invalid_decl13.pl | 1 + tests-pl/invalid_decl14.pl | 1 + tests-pl/invalid_decl15.pl | 1 + tests-pl/invalid_decl16.pl | 1 + .../cli/src_tests/declaration_errors.md | 34 +++++++++++++++++-- 9 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 tests-pl/invalid_decl12.pl create mode 100644 tests-pl/invalid_decl13.pl create mode 100644 tests-pl/invalid_decl14.pl create mode 100644 tests-pl/invalid_decl15.pl create mode 100644 tests-pl/invalid_decl16.pl diff --git a/src/machine/machine_errors.rs b/src/machine/machine_errors.rs index 899424b41..87c4adf39 100644 --- a/src/machine/machine_errors.rs +++ b/src/machine/machine_errors.rs @@ -268,6 +268,26 @@ impl DomainError for HeapCellValue { } } +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, + } + } +} + impl DomainError for Number { fn domain_error(self, machine_st: &mut MachineState, error: DomainErrorType) -> MachineError { let stub = functor!( @@ -731,6 +751,8 @@ pub enum DeclarationError { InvalidOpDeclSpecValue(Atom), InvalidOpDeclPrecType(Term), InvalidOpDeclPrecDomain(Fixnum), + ShallNotCreate(Atom), + ShallNotModify(Atom), } impl From for CompilationError { @@ -844,6 +866,7 @@ pub(crate) enum DomainErrorType { StreamOrAlias, OperatorSpecifier, OperatorPriority, + Declaration, } impl DomainErrorType { @@ -857,6 +880,7 @@ impl DomainErrorType { DomainErrorType::StreamOrAlias => atom!("stream_or_alias"), DomainErrorType::OperatorSpecifier => atom!("operator_specifier"), DomainErrorType::OperatorPriority => atom!("operator_priority"), + DomainErrorType::Declaration => atom!("declaration"), } } } diff --git a/src/machine/machine_state.rs b/src/machine/machine_state.rs index 4f03c8e03..919017acf 100644 --- a/src/machine/machine_state.rs +++ b/src/machine/machine_state.rs @@ -986,7 +986,7 @@ impl MachineState { atom_as_cell!(atom!("todo_insert_invalid_term_here")), ), DeclarationError::InvalidDecl(name, arity) => { - self.existence_error(ExistenceError::Declaration(name, arity)) + self.domain_error(DomainErrorType::Declaration, functor_stub(name, arity)) } DeclarationError::InvalidOpDeclNameType(_term) => self.type_error( ValidType::List, @@ -1006,6 +1006,12 @@ impl MachineState { DeclarationError::InvalidOpDeclPrecDomain(num) => { self.domain_error(DomainErrorType::OperatorPriority, fixnum_as_cell!(num)) } + DeclarationError::ShallNotCreate(atom) => { + self.permission_error(Permission::Create, atom!("operator"), atom) + } + DeclarationError::ShallNotModify(atom) => { + self.permission_error(Permission::Modify, atom!("operator"), atom) + } } } } diff --git a/src/machine/preprocessor.rs b/src/machine/preprocessor.rs index 4fcdf9b71..66d6e48e2 100644 --- a/src/machine/preprocessor.rs +++ b/src/machine/preprocessor.rs @@ -60,6 +60,24 @@ fn setup_op_decl(mut terms: Vec, atom_tbl: &AtomTable) -> Result % Warning: singleton variables Var at line 0 of invalid_decl11.pl > error(instantiation_error,load/1). > ``` + +```trycmd +$ scryer-prolog -f --no-add-history tests-pl/invalid_decl12.pl -g halt + error(permission_error(create,operator,{}),load/1). + +``` + +```trycmd +$ scryer-prolog -f --no-add-history tests-pl/invalid_decl13.pl -g halt + error(permission_error(create,operator,{}),load/1). + +``` + +```trycmd +$ scryer-prolog -f --no-add-history tests-pl/invalid_decl14.pl -g halt + error(permission_error(create,operator,'|'),load/1). + +``` + +```trycmd +$ scryer-prolog -f --no-add-history tests-pl/invalid_decl15.pl -g halt + error(permission_error(create,operator,'|'),load/1). + +``` + +```trycmd +$ scryer-prolog -f --no-add-history tests-pl/invalid_decl16.pl -g halt + error(permission_error(modify,operator,','),load/1). + +``` From 5a0abd713edac0c217d0fa1f9fc8058013813f0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bennet=20Ble=C3=9Fmann?= Date: Sun, 4 Aug 2024 12:10:15 +0200 Subject: [PATCH 08/11] change declaration to directive --- src/machine/machine_errors.rs | 22 +++++------ src/machine/machine_state.rs | 24 ++++++------ src/machine/preprocessor.rs | 38 +++++++++---------- ...laration_errors.md => directive_errors.md} | 6 +-- 4 files changed, 45 insertions(+), 45 deletions(-) rename tests/scryer/cli/src_tests/{declaration_errors.md => directive_errors.md} (93%) diff --git a/src/machine/machine_errors.rs b/src/machine/machine_errors.rs index 87c4adf39..df38d5c53 100644 --- a/src/machine/machine_errors.rs +++ b/src/machine/machine_errors.rs @@ -38,7 +38,7 @@ pub(crate) enum ValidType { Callable, Character, Compound, - Declaration, + Directive, Evaluable, Float, InByte, @@ -74,7 +74,7 @@ impl ValidType { // ValidType::PredicateIndicator => atom!("predicate_indicator"), // ValidType::Variable => atom!("variable") ValidType::TcpListener => atom!("tcp_listener"), - ValidType::Declaration => atom!("declaration"), + ValidType::Directive => atom!("directive"), } } } @@ -608,8 +608,8 @@ impl MachineState { return self.arithmetic_error(err); } - if let CompilationError::InvalidDecl(err) = err { - return self.declaration_error(err); + if let CompilationError::InvalidDirective(err) = err { + return self.directive_error(err); } let location = err.line_and_col_num(); @@ -732,7 +732,7 @@ pub enum CompilationError { ExpectedRel, InadmissibleFact, InadmissibleQueryTerm, - InvalidDecl(DeclarationError), + InvalidDirective(DirectiveError), InvalidMetaPredicateDecl, InvalidModuleDecl, InvalidModuleExport, @@ -743,9 +743,9 @@ pub enum CompilationError { } #[derive(Debug)] -pub enum DeclarationError { - ExpectedDecl(Term), - InvalidDecl(Atom, usize /* arity */), +pub enum DirectiveError { + ExpectedDirective(Term), + InvalidDirective(Atom, usize /* arity */), InvalidOpDeclNameType(Term), InvalidOpDeclSpecDomain(Term), InvalidOpDeclSpecValue(Atom), @@ -799,7 +799,7 @@ impl CompilationError { // TODO: type_error(callable, _). functor!(atom!("inadmissible_query_term")) } - CompilationError::InvalidDecl(_) => { + CompilationError::InvalidDirective(_) => { functor!(atom!("declaration_error")) } CompilationError::InvalidMetaPredicateDecl => { @@ -866,7 +866,7 @@ pub(crate) enum DomainErrorType { StreamOrAlias, OperatorSpecifier, OperatorPriority, - Declaration, + Directive, } impl DomainErrorType { @@ -880,7 +880,7 @@ impl DomainErrorType { DomainErrorType::StreamOrAlias => atom!("stream_or_alias"), DomainErrorType::OperatorSpecifier => atom!("operator_specifier"), DomainErrorType::OperatorPriority => atom!("operator_priority"), - DomainErrorType::Declaration => atom!("declaration"), + DomainErrorType::Directive => atom!("directive"), } } } diff --git a/src/machine/machine_state.rs b/src/machine/machine_state.rs index 919017acf..eecac17fb 100644 --- a/src/machine/machine_state.rs +++ b/src/machine/machine_state.rs @@ -979,37 +979,37 @@ impl MachineState { ); } - pub(crate) fn declaration_error(&mut self, err: DeclarationError) -> MachineError { + pub(crate) fn directive_error(&mut self, err: DirectiveError) -> MachineError { match err { - DeclarationError::ExpectedDecl(_term) => self.type_error( - ValidType::Declaration, + DirectiveError::ExpectedDirective(_term) => self.type_error( + ValidType::Directive, atom_as_cell!(atom!("todo_insert_invalid_term_here")), ), - DeclarationError::InvalidDecl(name, arity) => { - self.domain_error(DomainErrorType::Declaration, functor_stub(name, arity)) + DirectiveError::InvalidDirective(name, arity) => { + self.domain_error(DomainErrorType::Directive, functor_stub(name, arity)) } - DeclarationError::InvalidOpDeclNameType(_term) => self.type_error( + DirectiveError::InvalidOpDeclNameType(_term) => self.type_error( ValidType::List, atom_as_cell!(atom!("todo_insert_invalid_term_here")), ), - DeclarationError::InvalidOpDeclSpecDomain(_term) => self.domain_error( + DirectiveError::InvalidOpDeclSpecDomain(_term) => self.domain_error( DomainErrorType::OperatorSpecifier, atom_as_cell!(atom!("todo_insert_invalid_term_here")), ), - DeclarationError::InvalidOpDeclSpecValue(atom) => { + DirectiveError::InvalidOpDeclSpecValue(atom) => { self.domain_error(DomainErrorType::OperatorSpecifier, atom_as_cell!(atom)) } - DeclarationError::InvalidOpDeclPrecType(_term) => self.type_error( + DirectiveError::InvalidOpDeclPrecType(_term) => self.type_error( ValidType::Integer, atom_as_cell!(atom!("todo_insert_invalid_term_here")), ), - DeclarationError::InvalidOpDeclPrecDomain(num) => { + DirectiveError::InvalidOpDeclPrecDomain(num) => { self.domain_error(DomainErrorType::OperatorPriority, fixnum_as_cell!(num)) } - DeclarationError::ShallNotCreate(atom) => { + DirectiveError::ShallNotCreate(atom) => { self.permission_error(Permission::Create, atom!("operator"), atom) } - DeclarationError::ShallNotModify(atom) => { + DirectiveError::ShallNotModify(atom) => { self.permission_error(Permission::Modify, atom!("operator"), atom) } } diff --git a/src/machine/preprocessor.rs b/src/machine/preprocessor.rs index 66d6e48e2..9fcd1825f 100644 --- a/src/machine/preprocessor.rs +++ b/src/machine/preprocessor.rs @@ -17,7 +17,7 @@ pub(crate) fn to_op_decl(prec: u16, spec: OpDeclSpec, name: Atom) -> OpDecl { pub(crate) fn to_op_decl_spec(spec: Atom) -> Result { OpDeclSpec::try_from(spec).map_err(|_err| { - CompilationError::InvalidDecl(DeclarationError::InvalidOpDeclSpecValue(spec)) + CompilationError::InvalidDirective(DirectiveError::InvalidOpDeclSpecValue(spec)) }) } @@ -27,8 +27,8 @@ fn setup_op_decl(mut terms: Vec, atom_tbl: &AtomTable) -> Result name, Term::Literal(_, Literal::Char(c)) => AtomTable::build_with(atom_tbl, &c.to_string()), other => { - return Err(CompilationError::InvalidDecl( - DeclarationError::InvalidOpDeclNameType(other), + return Err(CompilationError::InvalidDirective( + DirectiveError::InvalidOpDeclNameType(other), )); } }; @@ -36,8 +36,8 @@ fn setup_op_decl(mut terms: Vec, atom_tbl: &AtomTable) -> Result name, other => { - return Err(CompilationError::InvalidDecl( - DeclarationError::InvalidOpDeclSpecDomain(other), + return Err(CompilationError::InvalidDirective( + DirectiveError::InvalidOpDeclSpecDomain(other), )) } }; @@ -48,33 +48,33 @@ fn setup_op_decl(mut terms: Vec, atom_tbl: &AtomTable) -> Result match u16::try_from(bi.get_num()) { Ok(n) if n <= 1200 => n, _ => { - return Err(CompilationError::InvalidDecl( - DeclarationError::InvalidOpDeclPrecDomain(bi), + return Err(CompilationError::InvalidDirective( + DirectiveError::InvalidOpDeclPrecDomain(bi), )); } }, other => { - return Err(CompilationError::InvalidDecl( - DeclarationError::InvalidOpDeclPrecType(other), + return Err(CompilationError::InvalidDirective( + DirectiveError::InvalidOpDeclPrecType(other), )); } }; if name == "[]" || name == "{}" { - return Err(CompilationError::InvalidDecl( - DeclarationError::ShallNotCreate(name), + return Err(CompilationError::InvalidDirective( + DirectiveError::ShallNotCreate(name), )); } if name == "," { - return Err(CompilationError::InvalidDecl( - DeclarationError::ShallNotModify(name), + return Err(CompilationError::InvalidDirective( + DirectiveError::ShallNotModify(name), )); } if name == "|" && (prec < 1001 || !spec.is_infix()) { - return Err(CompilationError::InvalidDecl( - DeclarationError::ShallNotCreate(name), + return Err(CompilationError::InvalidDirective( + DirectiveError::ShallNotCreate(name), )); } @@ -363,12 +363,12 @@ pub(super) fn setup_declaration<'a, LS: LoadState<'a>>( let (module_name, name, meta_specs) = setup_meta_predicate(terms, loader)?; Ok(Declaration::MetaPredicate(module_name, name, meta_specs)) } - _ => Err(CompilationError::InvalidDecl( - DeclarationError::InvalidDecl(name, terms.len()), + _ => Err(CompilationError::InvalidDirective( + DirectiveError::InvalidDirective(name, terms.len()), )), }, - other => Err(CompilationError::InvalidDecl( - DeclarationError::ExpectedDecl(other), + other => Err(CompilationError::InvalidDirective( + DirectiveError::ExpectedDirective(other), )), } } diff --git a/tests/scryer/cli/src_tests/declaration_errors.md b/tests/scryer/cli/src_tests/directive_errors.md similarity index 93% rename from tests/scryer/cli/src_tests/declaration_errors.md rename to tests/scryer/cli/src_tests/directive_errors.md index db942c83d..95ed55a41 100644 --- a/tests/scryer/cli/src_tests/declaration_errors.md +++ b/tests/scryer/cli/src_tests/directive_errors.md @@ -18,19 +18,19 @@ $ scryer-prolog -f --no-add-history tests-pl/invalid_decl3.pl -g halt ```trycmd $ scryer-prolog -f --no-add-history tests-pl/invalid_decl4.pl -g halt - error(domain_error(declaration,op/4),load/1). + error(domain_error(directive,op/4),load/1). ``` ```trycmd $ scryer-prolog -f --no-add-history tests-pl/invalid_decl5.pl -g halt - error(domain_error(declaration,(;)/2),load/1). + error(domain_error(directive,(;)/2),load/1). ``` ```trycmd $ scryer-prolog -f --no-add-history tests-pl/invalid_decl6.pl -g halt - error(type_error(declaration,todo_insert_invalid_term_here),load/1). + error(type_error(directive,todo_insert_invalid_term_here),load/1). ``` From 2d04c0dcf875aee47d9fbd0bd6ad7d208df89155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bennet=20Ble=C3=9Fmann?= Date: Sun, 4 Aug 2024 12:23:31 +0200 Subject: [PATCH 09/11] remove obsolete ExistenceError::Declaration --- src/machine/machine_errors.rs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/machine/machine_errors.rs b/src/machine/machine_errors.rs index df38d5c53..16ab4b60d 100644 --- a/src/machine/machine_errors.rs +++ b/src/machine/machine_errors.rs @@ -415,21 +415,6 @@ impl MachineState { 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(); @@ -1059,7 +1044,6 @@ pub enum ExistenceError { Module(Atom), ModuleSource(ModuleSource), Procedure(Atom, usize), - Declaration(Atom, usize), QualifiedProcedure { module_name: Atom, name: Atom, From deed6fb984cbb823f03f5826f48d0b52a25da811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bennet=20Ble=C3=9Fmann?= Date: Sun, 4 Aug 2024 12:24:44 +0200 Subject: [PATCH 10/11] fix remaining use of declaration instead of directive --- src/machine/machine_errors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_errors.rs b/src/machine/machine_errors.rs index 16ab4b60d..cb4edba8b 100644 --- a/src/machine/machine_errors.rs +++ b/src/machine/machine_errors.rs @@ -785,7 +785,7 @@ impl CompilationError { functor!(atom!("inadmissible_query_term")) } CompilationError::InvalidDirective(_) => { - functor!(atom!("declaration_error")) + functor!(atom!("directive_error")) } CompilationError::InvalidMetaPredicateDecl => { functor!(atom!("invalid_meta_predicate_decl")) From 058b9c5e512f80fd68f93713547961009be5a44a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bennet=20Ble=C3=9Fmann?= Date: Sun, 4 Aug 2024 15:16:37 +0200 Subject: [PATCH 11/11] switch invalid term from type to domain error --- src/machine/machine_errors.rs | 2 -- src/machine/machine_state.rs | 4 ++-- tests/scryer/cli/src_tests/directive_errors.md | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/machine/machine_errors.rs b/src/machine/machine_errors.rs index cb4edba8b..9f22d0e3b 100644 --- a/src/machine/machine_errors.rs +++ b/src/machine/machine_errors.rs @@ -38,7 +38,6 @@ pub(crate) enum ValidType { Callable, Character, Compound, - Directive, Evaluable, Float, InByte, @@ -74,7 +73,6 @@ impl ValidType { // ValidType::PredicateIndicator => atom!("predicate_indicator"), // ValidType::Variable => atom!("variable") ValidType::TcpListener => atom!("tcp_listener"), - ValidType::Directive => atom!("directive"), } } } diff --git a/src/machine/machine_state.rs b/src/machine/machine_state.rs index eecac17fb..5376042ce 100644 --- a/src/machine/machine_state.rs +++ b/src/machine/machine_state.rs @@ -981,8 +981,8 @@ impl MachineState { pub(crate) fn directive_error(&mut self, err: DirectiveError) -> MachineError { match err { - DirectiveError::ExpectedDirective(_term) => self.type_error( - ValidType::Directive, + DirectiveError::ExpectedDirective(_term) => self.domain_error( + DomainErrorType::Directive, atom_as_cell!(atom!("todo_insert_invalid_term_here")), ), DirectiveError::InvalidDirective(name, arity) => { diff --git a/tests/scryer/cli/src_tests/directive_errors.md b/tests/scryer/cli/src_tests/directive_errors.md index 95ed55a41..48b25fe05 100644 --- a/tests/scryer/cli/src_tests/directive_errors.md +++ b/tests/scryer/cli/src_tests/directive_errors.md @@ -30,7 +30,7 @@ $ scryer-prolog -f --no-add-history tests-pl/invalid_decl5.pl -g halt ```trycmd $ scryer-prolog -f --no-add-history tests-pl/invalid_decl6.pl -g halt - error(type_error(directive,todo_insert_invalid_term_here),load/1). + error(domain_error(directive,todo_insert_invalid_term_here),load/1). ```