Converted Interner to work with Rc-s

- Interner no longer contains unsafe code
- Tokens now hold a reference to the value they represent directly

This will enable many future improvements
This commit is contained in:
2023-08-19 14:03:05 +01:00
parent ab0b57b1b8
commit 0b887ced70
62 changed files with 592 additions and 762 deletions

View File

@@ -1,16 +1,16 @@
use std::fmt;
use std::fmt::{self, Display};
use std::rc::Rc;
use hashbrown::HashSet;
use crate::ast::{self, search_all_slcs, PHClass, Placeholder, Rule};
use crate::error::{ErrorPosition, ProjectError};
use crate::interner::{InternedDisplay, Interner, Tok};
use crate::interner::Tok;
use crate::utils::BoxedIter;
use crate::{Location, Sym};
/// Various reasons why a substitution rule may be invalid
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum RuleError {
/// A key is present in the template but not the pattern
Missing(Tok<String>),
@@ -33,25 +33,17 @@ impl RuleError {
}
}
impl InternedDisplay for RuleError {
fn fmt_i(&self, f: &mut fmt::Formatter<'_>, i: &Interner) -> fmt::Result {
match *self {
Self::Missing(key) => {
write!(f, "Key {:?} not in match pattern", i.r(key))
},
Self::ArityMismatch(key) => write!(
f,
"Key {:?} used inconsistently with and without ellipsis",
i.r(key)
),
Self::Multiple(key) => {
write!(f, "Key {:?} appears multiple times in match pattern", i.r(key))
},
impl Display for RuleError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Missing(key) => write!(f, "Key {key} not in match pattern"),
Self::ArityMismatch(key) =>
write!(f, "Key {key} used inconsistently with and without ellipsis"),
Self::Multiple(key) =>
write!(f, "Key {key} appears multiple times in match pattern"),
Self::VecNeighbors(left, right) => write!(
f,
"Keys {:?} and {:?} are two vectorials right next to each other",
i.r(left),
i.r(right)
"Keys {left} and {right} are two vectorials right next to each other"
),
}
}
@@ -83,13 +75,13 @@ impl ProjectError for Missing {
fn description(&self) -> &str {
"A key appears in the template but not the pattern of a rule"
}
fn message(&self, i: &Interner) -> String {
fn message(&self) -> String {
format!(
"The key {} appears in the template but not the pattern of this rule",
i.r(self.name)
self.name
)
}
fn positions(&self, _i: &Interner) -> BoxedIter<ErrorPosition> {
fn positions(&self) -> BoxedIter<ErrorPosition> {
Box::new(
(self.locations.iter())
.cloned()
@@ -124,10 +116,10 @@ impl ProjectError for Multiple {
fn description(&self) -> &str {
"A key appears multiple times in the pattern of a rule"
}
fn message(&self, i: &Interner) -> String {
format!("The key {} appears multiple times in this pattern", i.r(self.name))
fn message(&self) -> String {
format!("The key {} appears multiple times in this pattern", self.name)
}
fn positions(&self, _i: &Interner) -> BoxedIter<ErrorPosition> {
fn positions(&self) -> BoxedIter<ErrorPosition> {
Box::new(
(self.locations.iter())
.cloned()
@@ -162,13 +154,13 @@ impl ProjectError for ArityMismatch {
fn description(&self) -> &str {
"A key appears with different arities in a rule"
}
fn message(&self, i: &Interner) -> String {
fn message(&self) -> String {
format!(
"The key {} appears multiple times with different arities in this rule",
i.r(self.name)
self.name
)
}
fn positions(&self, _i: &Interner) -> BoxedIter<ErrorPosition> {
fn positions(&self) -> BoxedIter<ErrorPosition> {
Box::new((self.locations.iter()).cloned().map(|(location, class)| {
ErrorPosition {
location,
@@ -199,12 +191,12 @@ impl VecNeighbors {
search_all_slcs(&rule.template[..], &mut |ev| {
for pair in ev.windows(2) {
let (a, b) = (&pair[0], &pair[1]);
let a_vec = matches!(a.value, ast::Clause::Placeh(
let a_vec = matches!(&a.value, ast::Clause::Placeh(
Placeholder{ class: PHClass::Vec { .. }, name }
) if name == n1);
let b_vec = matches!(b.value, ast::Clause::Placeh(
) if name == &n1);
let b_vec = matches!(&b.value, ast::Clause::Placeh(
Placeholder{ class: PHClass::Vec { .. }, name }
) if name == n2);
) if name == &n2);
if a_vec && b_vec {
locations.insert(a.location.clone());
locations.insert(b.location.clone());
@@ -219,14 +211,13 @@ impl ProjectError for VecNeighbors {
fn description(&self) -> &str {
"Two vectorial placeholders appear next to each other"
}
fn message(&self, i: &Interner) -> String {
fn message(&self) -> String {
format!(
"The keys {} and {} appear next to each other with a vectorial arity",
i.r(self.n1),
i.r(self.n2)
self.n1, self.n2
)
}
fn positions(&self, _i: &Interner) -> BoxedIter<ErrorPosition> {
fn positions(&self) -> BoxedIter<ErrorPosition> {
Box::new(
(self.locations.iter())
.cloned()