Refactor error to use SourceRef (#1398)

This commit is contained in:
chriseth
2024-05-31 16:47:05 +02:00
committed by GitHub
parent fba0ba8d08
commit adee683796
21 changed files with 76 additions and 70 deletions

View File

@@ -11,6 +11,7 @@ repository = { workspace = true }
powdr-ast.workspace = true
powdr-number.workspace = true
powdr-parser.workspace = true
powdr-parser-util.workspace = true
lazy_static = "1.4.0"
log = "0.4.17"

View File

@@ -12,8 +12,8 @@ use powdr_ast::parsed::{
asm::{OperationId, Param, Params},
Expression,
};
use powdr_ast::SourceRef;
use powdr_number::{BigUint, FieldElement};
use powdr_parser_util::SourceRef;
use crate::common::{instruction_flag, RETURN_NAME};
use crate::{

View File

@@ -16,9 +16,9 @@ use powdr_ast::{
FunctionDefinition, FunctionKind, LambdaExpression, MatchArm, MatchExpression, Number,
Pattern, PilStatement, PolynomialName, SelectedExpressions, UnaryOperation, UnaryOperator,
},
SourceRef,
};
use powdr_number::{BigUint, FieldElement, LargeInt};
use powdr_parser_util::SourceRef;
use crate::common::{instruction_flag, return_instruction, RETURN_NAME};

View File

@@ -9,6 +9,7 @@ repository = { workspace = true }
[dependencies]
powdr-number.workspace = true
powdr-parser-util.workspace = true
itertools = "0.11.0"
num-traits = "0.2.15"

View File

@@ -10,6 +10,7 @@ use std::ops::{self, ControlFlow};
use std::sync::Arc;
use powdr_number::{DegreeType, FieldElement};
use powdr_parser_util::SourceRef;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
@@ -18,7 +19,6 @@ use crate::parsed::visitor::{Children, ExpressionVisitable};
pub use crate::parsed::BinaryOperator;
pub use crate::parsed::UnaryOperator;
use crate::parsed::{self, EnumDeclaration, EnumVariant, SelectedExpressions};
use crate::SourceRef;
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
pub enum StatementIdentifier {
@@ -1045,7 +1045,7 @@ impl Display for PolynomialType {
#[cfg(test)]
mod tests {
use crate::SourceRef;
use powdr_parser_util::SourceRef;
use super::{AlgebraicExpression, Analyzed};

View File

@@ -10,6 +10,7 @@ use std::{
};
use itertools::Either;
use powdr_parser_util::SourceRef;
use crate::parsed::{
asm::{
@@ -19,7 +20,6 @@ use crate::parsed::{
visitor::{ExpressionVisitable, VisitOrder},
EnumDeclaration, NamespacedPolynomialReference, PilStatement, TypedExpression,
};
use crate::SourceRef;
pub use crate::parsed::Expression;

View File

@@ -1,10 +1,7 @@
#![deny(clippy::print_stdout)]
use itertools::Itertools;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::fmt::{Display, Result, Write};
use std::sync::Arc;
/// Analyzed PIL
pub mod analyzed;
@@ -15,22 +12,6 @@ pub mod object;
/// A parsed ASM + PIL AST
pub mod parsed;
#[derive(
Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, JsonSchema,
)]
pub struct SourceRef {
pub file_name: Option<Arc<str>>,
pub file_contents: Option<Arc<str>>,
pub start: usize,
pub end: usize,
}
impl SourceRef {
pub fn unknown() -> Self {
Default::default()
}
}
/// quick and dirty String to String indentation
pub fn indent<S: ToString>(s: S, indentation: usize) -> String {
s.to_string()

View File

@@ -8,11 +8,10 @@ use itertools::Itertools;
use powdr_number::BigUint;
use derive_more::From;
use powdr_parser_util::SourceRef;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::SourceRef;
use super::{
visitor::Children, EnumDeclaration, EnumVariant, Expression, PilStatement, TypedExpression,
};

View File

@@ -18,12 +18,13 @@ use powdr_number::{BigInt, BigUint, DegreeType};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use powdr_parser_util::SourceRef;
use self::{
asm::{Part, SymbolPath},
types::{FunctionType, Type, TypeBounds, TypeScheme},
visitor::Children,
};
use crate::SourceRef;
#[derive(Display, Clone, Copy, PartialEq, Eq)]
pub enum SymbolCategory {

View File

@@ -17,6 +17,7 @@ powdr-ast.workspace = true
powdr-number.workspace = true
powdr-pil-analyzer.workspace = true
powdr-executor.workspace = true
powdr-parser-util.workspace = true
starky = { git = "https://github.com/0xEigenLabs/eigen-zkvm.git", rev = "cf405b2e2cecb8567cfd083a55936b71722276d5" }
pil-stark-prover = { git = "https://github.com/powdr-labs/pil-stark-prover.git", rev = "769b1153f3ae2d7cbab4c8acf33865ed13f8a823", optional = true }

View File

@@ -6,6 +6,7 @@ use powdr_ast::analyzed::{
AlgebraicBinaryOperator, AlgebraicExpression as Expression, AlgebraicUnaryOperator, Analyzed,
IdentityKind, PolyID, PolynomialType, StatementIdentifier, SymbolKind,
};
use powdr_parser_util::SourceRef;
use starky::types::{
ConnectionIdentity, Expression as StarkyExpr, PermutationIdentity, PlookupIdentity,
PolIdentity, Reference, PIL,
@@ -385,7 +386,7 @@ impl<'a, T: FieldElement> Exporter<'a, T> {
(1, poly)
}
fn line_of_source_ref(&mut self, source: &powdr_ast::SourceRef) -> usize {
fn line_of_source_ref(&mut self, source: &SourceRef) -> usize {
let Some(file_contents) = source.file_contents.as_ref() else {
return 0;
};

View File

@@ -11,6 +11,7 @@ repository = { workspace = true }
powdr-analysis.workspace = true
powdr-ast.workspace = true
powdr-number.workspace = true
powdr-parser-util.workspace = true
pretty_assertions = "1.4.0"
itertools = "^0.10"

View File

@@ -10,8 +10,8 @@ use powdr_ast::{
build::{index_access, namespaced_reference},
PILFile, PilStatement, SelectedExpressions, TypedExpression,
},
SourceRef,
};
use powdr_parser_util::SourceRef;
use itertools::Itertools;

View File

@@ -10,6 +10,8 @@ repository = { workspace = true }
[dependencies]
lalrpop-util = {version = "^0.19", features = ["lexer"]}
codespan-reporting = "^0.11"
serde = { version = "1.0", default-features = false, features = ["alloc", "derive", "rc"] }
schemars = { version = "0.8.16", features = ["preserve_order"]}
[dev-dependencies]
test-log = "0.2.12"

View File

@@ -2,16 +2,34 @@
#![deny(clippy::print_stdout)]
use std::sync::Arc;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(
Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, JsonSchema,
)]
pub struct SourceRef {
pub file_name: Option<Arc<str>>,
pub file_contents: Option<Arc<str>>,
pub start: usize,
pub end: usize,
}
impl SourceRef {
pub fn unknown() -> Self {
Default::default()
}
}
#[derive(Debug)]
pub struct ParseError<'a> {
start: usize,
end: usize,
file_name: String,
contents: &'a str,
pub struct Error {
source_ref: SourceRef,
message: String,
}
impl<'a> ParseError<'a> {
impl Error {
pub fn output_to_stderr(&self) {
use codespan_reporting::diagnostic::{Diagnostic, Label};
use codespan_reporting::files::SimpleFiles;
@@ -20,20 +38,25 @@ impl<'a> ParseError<'a> {
let config = term::Config::default();
let mut files = SimpleFiles::new();
let file_id = files.add(&self.file_name, self.contents);
let file_name = self.source_ref.file_name.as_deref().unwrap_or("input");
let contents = self.source_ref.file_contents.as_deref().unwrap_or_default();
let file_id = files.add(file_name, contents);
let diagnostic = Diagnostic::error()
.with_message(&self.message)
.with_labels(vec![Label::primary(file_id, self.start..self.end)]);
.with_labels(vec![Label::primary(
file_id,
self.source_ref.start..self.source_ref.end,
)]);
let mut writer = StandardStream::stderr(ColorChoice::Always);
term::emit(&mut writer, &config, &files, &diagnostic).unwrap()
}
}
pub fn handle_parse_error<'a>(
pub fn handle_parse_error(
err: lalrpop_util::ParseError<usize, lalrpop_util::lexer::Token, String>,
file_name: Option<&str>,
input: &'a str,
) -> ParseError<'a> {
input: &str,
) -> Error {
let (&start, &end) = match &err {
lalrpop_util::ParseError::InvalidToken { location } => (location, location),
lalrpop_util::ParseError::UnrecognizedEOF {
@@ -49,12 +72,14 @@ pub fn handle_parse_error<'a>(
} => (start, end),
lalrpop_util::ParseError::User { error: _ } => (&0, &0),
};
ParseError {
start,
end,
file_name: file_name.unwrap_or("input").to_string(),
contents: input,
message: format!("{err}"),
Error {
source_ref: SourceRef {
start,
end,
file_name: file_name.map(Into::into),
file_contents: Some(input.into()),
},
message: err.to_string(),
}
}
@@ -65,7 +90,7 @@ pub trait UnwrapErrToStderr {
fn unwrap_err_to_stderr(self) -> Self::Inner;
}
impl<'a, T> UnwrapErrToStderr for Result<T, ParseError<'a>> {
impl<T> UnwrapErrToStderr for Result<T, Error> {
type Inner = T;
fn unwrap_err_to_stderr(self) -> Self::Inner {

View File

@@ -8,9 +8,7 @@ use powdr_ast::parsed::{
types::{Type, TypeBounds, TypeScheme},
Expression, SourceReference,
};
use powdr_ast::SourceRef;
use powdr_parser_util::{handle_parse_error, ParseError};
use powdr_parser_util::{handle_parse_error, Error, SourceRef};
use std::sync::Arc;
@@ -63,41 +61,38 @@ lazy_static::lazy_static! {
static ref TYPE_VAR_BOUNDS_PARSER: powdr::TypeVarBoundsParser = powdr::TypeVarBoundsParser::new();
}
pub fn parse<'a>(
file_name: Option<&str>,
input: &'a str,
) -> Result<powdr_ast::parsed::PILFile, ParseError<'a>> {
pub fn parse(file_name: Option<&str>, input: &str) -> Result<powdr_ast::parsed::PILFile, Error> {
let ctx = ParserContext::new(file_name, input);
PIL_FILE_PARSER
.parse(&ctx, input)
.map_err(|err| handle_parse_error(err, file_name, input))
}
pub fn parse_asm<'a>(
pub fn parse_asm(
file_name: Option<&str>,
input: &'a str,
) -> Result<powdr_ast::parsed::asm::ASMProgram, ParseError<'a>> {
input: &str,
) -> Result<powdr_ast::parsed::asm::ASMProgram, Error> {
parse_module(file_name, input).map(|main| ASMProgram { main })
}
pub fn parse_module<'a>(
pub fn parse_module(
file_name: Option<&str>,
input: &'a str,
) -> Result<powdr_ast::parsed::asm::ASMModule, ParseError<'a>> {
input: &str,
) -> Result<powdr_ast::parsed::asm::ASMModule, Error> {
let ctx = ParserContext::new(file_name, input);
ASM_MODULE_PARSER
.parse(&ctx, input)
.map_err(|err| handle_parse_error(err, file_name, input))
}
pub fn parse_type(input: &str) -> Result<Type<powdr_ast::parsed::Expression>, ParseError<'_>> {
pub fn parse_type(input: &str) -> Result<Type<powdr_ast::parsed::Expression>, Error> {
let ctx = ParserContext::new(None, input);
TYPE_PARSER
.parse(&ctx, input)
.map_err(|err| handle_parse_error(err, None, input))
}
pub fn parse_type_var_bounds(input: &str) -> Result<TypeBounds, ParseError<'_>> {
pub fn parse_type_var_bounds(input: &str) -> Result<TypeBounds, Error> {
let ctx = ParserContext::new(None, input);
// We use GoldilocksField here, because we need to specify a concrete type,
// even though the grammar for TypeBounds does not depend on the field.

View File

@@ -1,9 +1,7 @@
use powdr_ast::parsed::visitor::Children;
use powdr_ast::parsed::SourceReference;
use powdr_ast::{
parsed::{PILFile, PilStatement},
SourceRef,
};
use powdr_ast::parsed::{PILFile, PilStatement};
use powdr_parser_util::SourceRef;
// helper function to clear SourceRef's inside the AST so we can compare for equality
pub fn pil_clear_source_refs(ast: &mut PILFile) {

View File

@@ -20,9 +20,9 @@ use powdr_ast::{
types::{ArrayType, Type},
SelectedExpressions,
},
SourceRef,
};
use powdr_number::{DegreeType, FieldElement};
use powdr_parser_util::SourceRef;
use crate::{
evaluator::{self, Definitions, EvalError, SymbolLookup, Value},

View File

@@ -20,9 +20,9 @@ use powdr_ast::{
IndexAccess, LambdaExpression, LetStatementInsideBlock, MatchArm, MatchExpression, Number,
Pattern, StatementInsideBlock, UnaryOperation, UnaryOperator,
},
SourceRef,
};
use powdr_number::{BigInt, BigUint, FieldElement, LargeInt};
use powdr_parser_util::SourceRef;
/// Evaluates an expression given a hash map of definitions.
pub fn evaluate_expression<'a, T: FieldElement>(

View File

@@ -12,9 +12,9 @@ use powdr_ast::{
NamespacedPolynomialReference, Number, Pattern, SelectedExpressions, StatementInsideBlock,
SymbolCategory, UnaryOperation,
},
SourceRef,
};
use powdr_number::DegreeType;
use powdr_parser_util::SourceRef;
use crate::{type_processor::TypeProcessor, AnalysisDriver};

View File

@@ -12,8 +12,8 @@ use powdr_ast::parsed::{
SelectedExpressions,
};
use powdr_ast::parsed::{FunctionKind, LambdaExpression};
use powdr_ast::SourceRef;
use powdr_number::DegreeType;
use powdr_parser_util::SourceRef;
use powdr_ast::analyzed::{
Expression, FunctionValueDefinition, Identity, IdentityKind, PolynomialType, PublicDeclaration,