microcad_lang/parse/
parse_error.rs

1// Copyright © 2024-2025 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4//! Parser errors
5
6use crate::{parse::*, ty::*};
7use thiserror::Error;
8
9/// Parsing errors
10#[derive(Debug, Error)]
11pub enum ParseError {
12    /// Error parsing floating point literal
13    #[error("Error parsing floating point literal: {0}")]
14    ParseFloatError(Refer<std::num::ParseFloatError>),
15
16    /// Error parsing integer literal
17    #[error("Error parsing integer literal: {0}")]
18    ParseIntError(Refer<std::num::ParseIntError>),
19
20    /// Parser rule not found error
21    #[error("Rule not found: {0:?}")]
22    RuleNotFoundError(Box<crate::parser::Rule>),
23
24    /// IO Error
25    #[error("IO Error: {0}")]
26    IoError(Refer<std::io::Error>),
27
28    /// Error in pest parser
29    #[error("Parser error: {0}")]
30    Parser(Box<pest::error::Error<crate::parser::Rule>>),
31
32    /// Error parsing color literal
33    #[error("Error parsing color: {0}")]
34    ParseColorError(Refer<microcad_core::ParseColorError>),
35
36    /// Unknown color name
37    #[error("Unknown color: {0}")]
38    UnknownColorName(Refer<String>),
39
40    /// Unknown unit
41    #[error("Unknown unit: {0}")]
42    UnknownUnit(Refer<String>),
43
44    /// Unexpected token
45    #[error("Unexpected token")]
46    UnexpectedToken(SrcRef),
47
48    /// Tuple expression contains both named and positional arguments
49    #[error("Tuple expression contains both named and positional arguments")]
50    MixedTupleArguments(SrcRef),
51
52    /// Duplicate named argument
53    #[error("Duplicate named argument: {0}")]
54    DuplicateNamedArgument(Identifier),
55
56    /// Positional argument after named argument
57    #[error("Positional argument after named argument")]
58    PositionalArgumentAfterNamed(SrcRef),
59
60    /// Empty tuple expression
61    #[error("Empty tuple expression")]
62    EmptyTupleExpression(SrcRef),
63
64    /// Missing type or value for definition parameter
65    #[error("Missing type or value for definition parameter: {0}")]
66    ParameterMissingTypeOrValue(Identifier),
67
68    /// Duplicate parameter
69    #[error("Duplicate parameter: {0}")]
70    DuplicateParameter(Identifier),
71
72    /// Duplicate argument
73    #[error("Duplicate argument: {0}")]
74    DuplicateArgument(Identifier),
75
76    /// Duplicated type name in map
77    #[error("Duplicated type name in map: {0}")]
78    DuplicatedMapType(Identifier),
79
80    /// Duplicate id
81    #[error("Duplicate id: {0}")]
82    DuplicateIdentifier(Identifier),
83
84    /// Duplicate id in tuple
85    #[error("Duplicate id in tuple: {0}")]
86    DuplicateTupleIdentifier(Identifier),
87
88    /// Duplicate unnamed type in tuple
89    #[error("Duplicate unnamed type in tuple: {0}")]
90    DuplicateTupleType(Refer<Type>),
91
92    /// Missing format expression
93    #[error("Missing format expression")]
94    MissingFormatExpression(SrcRef),
95
96    /// Statement between two init statements
97    #[error("Statement between two init statements")]
98    StatementBetweenInit(SrcRef),
99
100    /// Loading of a source file failed
101    #[error("Loading of source file {0:?} failed")]
102    LoadSource(Refer<std::path::PathBuf>),
103
104    /// Grammar rule error
105    #[error("Grammar rule error {0}")]
106    GrammarRuleError(Refer<String>),
107
108    /// Grammar rule error
109    #[error("Invalid qualified name '{0}'")]
110    InvalidQualifiedName(Refer<String>),
111
112    /// Grammar rule error
113    #[error("Invalid id '{0}'")]
114    InvalidIdentifier(Refer<String>),
115
116    /// Qualified name cannot be converted into an Id
117    #[error("Qualified name {0} cannot be converted into an Id")]
118    QualifiedNameIsNoId(QualifiedName),
119
120    /// Element is not available
121    #[error("Element is not available")]
122    NotAvailable(SrcRef),
123
124    /// Unknown type
125    #[error("Unknown type: {0}")]
126    UnknownType(Refer<String>),
127}
128
129/// Result with parse error
130pub type ParseResult<T> = Result<T, ParseError>;
131
132impl SrcReferrer for ParseError {
133    fn src_ref(&self) -> SrcRef {
134        match self {
135            ParseError::Parser(error) => SrcRef::new(
136                match error.location {
137                    pest::error::InputLocation::Pos(pos) => std::ops::Range {
138                        start: pos,
139                        end: pos,
140                    },
141                    pest::error::InputLocation::Span((start, end)) => {
142                        std::ops::Range { start, end }
143                    }
144                },
145                match error.line_col {
146                    pest::error::LineColLocation::Pos(pos) => pos.0,
147                    pest::error::LineColLocation::Span(start, _) => start.0,
148                },
149                match error.line_col {
150                    pest::error::LineColLocation::Pos(pos) => pos.1,
151                    pest::error::LineColLocation::Span(start, _) => start.1,
152                },
153                0,
154            ),
155            ParseError::DuplicateNamedArgument(id)
156            | ParseError::ParameterMissingTypeOrValue(id)
157            | ParseError::DuplicateParameter(id)
158            | ParseError::DuplicateArgument(id)
159            | ParseError::DuplicatedMapType(id)
160            | ParseError::DuplicateIdentifier(id)
161            | ParseError::DuplicateTupleIdentifier(id) => id.src_ref(),
162            ParseError::QualifiedNameIsNoId(name) => name.src_ref(),
163            ParseError::UnexpectedToken(src_ref)
164            | ParseError::MixedTupleArguments(src_ref)
165            | ParseError::PositionalArgumentAfterNamed(src_ref)
166            | ParseError::EmptyTupleExpression(src_ref)
167            | ParseError::MissingFormatExpression(src_ref)
168            | ParseError::StatementBetweenInit(src_ref)
169            | ParseError::NotAvailable(src_ref) => src_ref.clone(),
170            ParseError::ParseFloatError(parse_float_error) => parse_float_error.src_ref(),
171            ParseError::ParseIntError(parse_int_error) => parse_int_error.src_ref(),
172            ParseError::RuleNotFoundError(_) => SrcRef(None),
173            ParseError::IoError(error) => error.src_ref(),
174            ParseError::ParseColorError(parse_color_error) => parse_color_error.src_ref(),
175            ParseError::UnknownColorName(name) => name.src_ref(),
176            ParseError::UnknownUnit(unit) => unit.src_ref(),
177            ParseError::DuplicateTupleType(ty) => ty.src_ref(),
178            ParseError::LoadSource(path) => path.src_ref(),
179            ParseError::GrammarRuleError(rule) => rule.src_ref(),
180            ParseError::InvalidQualifiedName(name) => name.src_ref(),
181            ParseError::InvalidIdentifier(id) => id.src_ref(),
182            ParseError::UnknownType(ty) => ty.src_ref(),
183        }
184    }
185}