mirror of
https://github.com/powdr-labs/powdr.git
synced 2026-05-13 03:00:26 -04:00
Refactor error to use SourceRef (#1398)
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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::{
|
||||
|
||||
@@ -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};
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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>(
|
||||
|
||||
@@ -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};
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user