rewrite error system and add evaluator architecture

the evaluator architecture is also only a temporary solution and very flawed
but i have no other ideas
This commit is contained in:
Schrottkatze 2023-11-19 16:52:38 +01:00
parent 0ce869e859
commit 17878b3e87
7 changed files with 278 additions and 145 deletions

View file

@ -1,35 +1,56 @@
#[cfg(test)]
mod test;
use crate::syntax::CommandPart;
use crate::{
error::{ErrorKind, Errors, SyntaxErrorKind},
syntax::CommandPart,
};
use super::{error::SyntaxError, CommandPartKind, PipelineElement, PipelineElementKind};
use super::{CommandPartKind, PipelineElement, PipelineElementKind};
pub fn check(syntax: &[PipelineElement]) -> Result<(), Vec<SyntaxError>> {
pub fn check(syntax: &[PipelineElement]) -> Result<(), Vec<Errors>> {
let mut errs = Vec::new();
if let Err(e_span) = check_missing_streamer(syntax) {
errs.push(SyntaxError::MissingStreamer(vec![e_span]));
errs.push(Errors::new_single(
ErrorKind::SyntaxError(SyntaxErrorKind::MissingStreamer),
e_span,
));
}
if let Err(err_locs) = check_missing_filters(syntax) {
errs.push(SyntaxError::MissingFilter(err_locs));
errs.push(Errors::new(
ErrorKind::SyntaxError(SyntaxErrorKind::MissingFilter),
err_locs,
));
}
if let Err(e_span) = check_missing_sink(syntax) {
errs.push(SyntaxError::MissingSink(vec![e_span]));
errs.push(Errors::new_single(
ErrorKind::SyntaxError(SyntaxErrorKind::MissingSink),
e_span,
));
}
if let Err(e_span) = check_literal_as_sink(syntax) {
errs.push(SyntaxError::LiteralAsSink(vec![e_span]));
errs.push(Errors::new_single(
ErrorKind::SyntaxError(SyntaxErrorKind::LiteralAsSink),
e_span,
));
}
if let Err(err_locs) = check_literal_as_filter(syntax) {
errs.push(SyntaxError::LiteralAsFilter(err_locs));
errs.push(Errors::new(
ErrorKind::SyntaxError(SyntaxErrorKind::LiteralAsFilter),
err_locs,
));
}
if let Err(e_span) = check_literal_with_args(syntax) {
errs.push(SyntaxError::LiteralWithArgs(vec![e_span]));
errs.push(Errors::new_single(
ErrorKind::SyntaxError(SyntaxErrorKind::LiteralWithArgs),
e_span,
));
}
if errs.is_empty() {
@ -127,6 +148,8 @@ fn check_literal_as_sink(syntax: &[PipelineElement]) -> Result<(), logos::Span>
fn check_literal_as_filter(syntax: &[PipelineElement]) -> Result<(), Vec<logos::Span>> {
let errs = syntax
.iter()
.take(syntax.len() - 1)
.skip(1)
.filter(|element| {
!matches!(
element,
@ -155,8 +178,6 @@ fn check_literal_as_filter(syntax: &[PipelineElement]) -> Result<(), Vec<logos::
None
}
})
.skip(1)
.take(syntax.len() - 1)
.filter_map(|err| err.map(Clone::clone))
.collect::<Vec<logos::Span>>();

View file

@ -1,79 +0,0 @@
use codespan_reporting::diagnostic::{Diagnostic, Label};
/// The enum representing a syntax error, used for error reporting
#[derive(Debug, Clone)]
pub enum SyntaxError {
/// This variant indicates a token that the Lexer didn't recognize
InvalidToken(Vec<logos::Span>),
/// `MissingStreamer` means, that the pipeline starts with a Pipe (`|`), so it has no streamer as input in front of it.
MissingStreamer(Vec<logos::Span>),
/// `MissingSink` means, that the pipeline ends with a Pipe (`|`), meaning that the output can't go anywhere
MissingSink(Vec<logos::Span>),
/// This indicates a missing filter somewhere in the pipeline, meaning that there's 2 pipes after one another
MissingFilter(Vec<logos::Span>),
/// A literal cannot be a sink, TODO
LiteralAsSink(Vec<logos::Span>),
/// A literal can't be a filter either, TODO
LiteralAsFilter(Vec<logos::Span>),
/// A literal acting as streamer cannot take arguments, TODO
LiteralWithArgs(Vec<logos::Span>),
}
// TODO: much better and more complex errors, with suggestions for fixes
impl SyntaxError {
pub fn to_diagnostic(&self, file_id: usize) -> Diagnostic<usize> {
match self {
Self::InvalidToken(errs) => Diagnostic::error()
.with_message("failed to parse invalid tokens")
.with_labels(
errs.iter()
.map(|span| {
Label::primary(file_id, span.clone()).with_message("invalid token")
})
.collect(),
),
Self::MissingStreamer(locs) => Diagnostic::error()
.with_message("pipelines must always start with a provider")
.with_labels(
locs.iter()
.map(|span| Label::primary(file_id, span.clone()))
.collect(),
),
Self::MissingFilter(locs) => Diagnostic::error()
.with_message("missing filters in pipeline")
.with_labels(
locs.iter()
.map(|span| Label::primary(file_id, span.clone()))
.collect(),
),
Self::MissingSink(locs) => Diagnostic::error()
.with_message("pipelines need to end in a sink")
.with_labels(
locs.iter()
.map(|span| Label::primary(file_id, span.clone()))
.collect(),
),
Self::LiteralAsSink(locs) => Diagnostic::error()
.with_message("literals cannot be sinks")
.with_labels(
locs.iter()
.map(|span| Label::primary(file_id, span.clone()))
.collect(),
),
Self::LiteralAsFilter(locs) => Diagnostic::error()
.with_message("literals cannot be filters")
.with_labels(
locs.iter()
.map(|span| Label::primary(file_id, span.clone()))
.collect(),
),
Self::LiteralWithArgs(locs) => Diagnostic::error()
.with_message("literals cannot take arguments")
.with_labels(
locs.iter()
.map(|span| Label::primary(file_id, span.clone()))
.collect(),
),
}
}
}

View file

@ -6,7 +6,6 @@ use logos::Span;
use crate::lexer::Token;
pub mod check;
pub mod error;
#[derive(Debug, Clone, PartialEq)]
pub struct PipelineElement {