Skip to content

Commit

Permalink
Merge pull request #2463 from Skgland/split-up-inconsitent-entry-error
Browse files Browse the repository at this point in the history
Split up inconsistent entry error
  • Loading branch information
mthom authored Aug 5, 2024
2 parents 2814d79 + 058b9c5 commit 7cfe8ee
Show file tree
Hide file tree
Showing 30 changed files with 475 additions and 160 deletions.
12 changes: 12 additions & 0 deletions src/atom_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@ impl indexmap::Equivalent<Atom> for str {
}
}

impl PartialEq<str> 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;

Expand Down
18 changes: 3 additions & 15 deletions src/forms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.

/*
Expand Down Expand Up @@ -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 {
Expand All @@ -429,7 +417,7 @@ impl OpDecl {
}

pub(crate) fn insert_into_op_dir(&self, op_dir: &mut OpDir) -> Option<OpDesc> {
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();
Expand All @@ -447,15 +435,15 @@ 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));
}
}
}

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));
Expand Down
40 changes: 20 additions & 20 deletions src/heap_print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -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()
}
}
}
Expand All @@ -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()
}
}
}
Expand All @@ -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 {
Expand All @@ -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);
Expand All @@ -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 {
Expand Down Expand Up @@ -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!("...")));
Expand All @@ -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!("...")));
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -1328,7 +1328,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {

fn close_list(&mut self, switch: Rc<Cell<(bool, usize)>>) -> Option<Rc<Cell<(bool, usize)>>> {
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;
}
Expand Down Expand Up @@ -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)));
}
}
Expand Down Expand Up @@ -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(),
Expand All @@ -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(),
Expand Down
10 changes: 5 additions & 5 deletions src/machine/arithmetic_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
6 changes: 2 additions & 4 deletions src/machine/load_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
52 changes: 48 additions & 4 deletions src/machine/machine_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,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!(
Expand Down Expand Up @@ -571,10 +591,15 @@ impl MachineState {
return self.arithmetic_error(err);
}

if let CompilationError::InvalidDirective(err) = err {
return self.directive_error(err);
}

let location = err.line_and_col_num();
let len = self.heap.len();
let stub = err.as_functor();

let stub = functor!(atom!("syntax_error"), [str(self.heap.len(), 0)], [stub]);
let stub = functor!(atom!("syntax_error"), [str(len, 0)], [stub]);

MachineError {
stub,
Expand Down Expand Up @@ -690,7 +715,7 @@ pub enum CompilationError {
ExpectedRel,
InadmissibleFact,
InadmissibleQueryTerm,
InconsistentEntry,
InvalidDirective(DirectiveError),
InvalidMetaPredicateDecl,
InvalidModuleDecl,
InvalidModuleExport,
Expand All @@ -700,6 +725,19 @@ pub enum CompilationError {
UnreadableTerm,
}

#[derive(Debug)]
pub enum DirectiveError {
ExpectedDirective(Term),
InvalidDirective(Atom, usize /* arity */),
InvalidOpDeclNameType(Term),
InvalidOpDeclSpecDomain(Term),
InvalidOpDeclSpecValue(Atom),
InvalidOpDeclPrecType(Term),
InvalidOpDeclPrecDomain(Fixnum),
ShallNotCreate(Atom),
ShallNotModify(Atom),
}

impl From<ArithmeticError> for CompilationError {
#[inline]
fn from(err: ArithmeticError) -> CompilationError {
Expand Down Expand Up @@ -744,8 +782,8 @@ impl CompilationError {
// TODO: type_error(callable, _).
functor!(atom!("inadmissible_query_term"))
}
CompilationError::InconsistentEntry => {
functor!(atom!("inconsistent_entry"))
CompilationError::InvalidDirective(_) => {
functor!(atom!("directive_error"))
}
CompilationError::InvalidMetaPredicateDecl => {
functor!(atom!("invalid_meta_predicate_decl"))
Expand Down Expand Up @@ -809,6 +847,9 @@ pub(crate) enum DomainErrorType {
SourceSink,
Stream,
StreamOrAlias,
OperatorSpecifier,
OperatorPriority,
Directive,
}

impl DomainErrorType {
Expand All @@ -820,6 +861,9 @@ 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"),
DomainErrorType::Directive => atom!("directive"),
}
}
}
Expand Down
Loading

0 comments on commit 7cfe8ee

Please sign in to comment.