1use std::fmt::Display;
19
20use crate::{
21 common::TextLocation,
22 mel::{compiler::error::CompilerLocatableError, types::Type},
23};
24
25#[derive(Debug, Clone)]
26pub enum AnalysisAssertions {
27 ContextMissing,
28 ContextMissingExpr(String),
29 ContextWrongExprType(String, String, String),
30 ContextMissingParams,
31 InvalidOperator(String, String),
32}
33
34impl Display for AnalysisAssertions {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 match self {
37 AnalysisAssertions::ContextMissing => write!(f, "Missing analysis context"),
38 AnalysisAssertions::ContextWrongExprType(expected, actual, whre) => write!(
39 f,
40 "Wrong expression type in analysis context; expected {} but found {} in {}",
41 expected, actual, whre
42 ),
43 AnalysisAssertions::ContextMissingParams => {
44 write!(f, "Missing parameters in analysis context")
45 }
46 AnalysisAssertions::ContextMissingExpr(s) => {
47 write!(f, "Missing expression in {}", s)
48 }
49 AnalysisAssertions::InvalidOperator(o, l) => {
50 write!(f, "Invalid operator {o} in {l}")
51 }
52 }
53 }
54}
55
56#[derive(Debug, Clone)]
57pub enum AnalysisPreconditions {
58 ContextMissingExpr(String),
59}
60
61impl Display for AnalysisPreconditions {
62 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63 match self {
64 AnalysisPreconditions::ContextMissingExpr(s) => {
65 write!(f, "Missing expression in {}", s)
66 }
67 }
68 }
69}
70
71#[derive(Debug, Clone)]
72pub enum AnalysisError {
73 CompilerError(CompilerLocatableError),
74 Mismatch(Type, Type),
75 RegexSame,
76 InvalidType(Vec<Type>, Type),
77 Miscount(usize, usize),
78 InvalidRegex(String),
79 UnknownField(String, String),
80 UnknownIdentifier(String),
81 AssertionFailure(AnalysisAssertions),
82 PreconditionFailure(AnalysisPreconditions),
83 OptimizationNotSupported(String),
84 Incalculable,
85}
86
87impl Display for AnalysisError {
88 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89 match self {
90 Self::CompilerError(e) => write!(f, "Compiler error: {:?}", e),
91 Self::Mismatch(expected, found) => {
92 write!(f, "Expected {:?}, found {:?}", expected, found)
93 }
94 Self::Miscount(expected, found) => {
95 write!(f, "Expected {expected} arguments, found {found}")
96 }
97 Self::UnknownIdentifier(i) => write!(f, "Unknown identifier {:?}", i),
98 Self::AssertionFailure(c) => write!(f, "Missing compiler context: {:?}", c),
99 Self::PreconditionFailure(c) => {
100 write!(f, "Precondition not satisfied during analysis: {:?}", c)
101 }
102 Self::UnknownField(strct, member) => write!(f, "No field named {member} in {strct}"),
103 Self::Incalculable => write!(f, "Incalculable expression analysis"),
104 Self::OptimizationNotSupported(o) => write!(f, "Optimization not supported: {o}"),
105 Self::InvalidRegex(i) => write!(f, "Regular expression literal not valid: {i}"),
106 Self::RegexSame => write!(
107 f,
108 "The operands to the regular expression match operator must be a string and a regular expression"
109 ),
110 Self::InvalidType(valids, actual) => write!(
111 f,
112 "{actual} is not one of the expected types ({})",
113 valids
114 .iter()
115 .map(|v| v.to_string())
116 .collect::<Vec<_>>()
117 .join(",")
118 ),
119 }
120 }
121}
122
123#[derive(Debug, Clone)]
124pub struct AnalysisLocatableError {
125 pub error: Box<AnalysisError>,
126 pub location: TextLocation,
127}
128
129impl Display for AnalysisLocatableError {
130 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
131 write!(f, "{} ({})", self.error, self.location)
132 }
133}