1use std::num::ParseIntError;
2
3use derive_more::derive::{Display, From};
4
5use crate::{Loc, LocInfo, PQLType, pql_parser, range_parser};
6
7mod parse_error;
8
9pub use parse_error::ParseError;
10
11type SelectorName = String;
12type OpSymbol = String;
13
14type NumGiven = usize;
15type NumExpected = NumGiven;
16
17type GotType = PQLType;
18type ExpectedType = GotType;
19
20#[derive(Debug, Clone, PartialEq, Eq, From, Display)]
21pub enum PQLError {
22 TooManyVariables,
23 #[display("UnknownIdent")]
24 UnknownIdent(LocInfo),
25 #[display("UnrecognizedGame")]
26 UnrecognizedGame(LocInfo),
27 #[display("UnrecognizedFunction")]
28 UnrecognizedFunction(LocInfo),
29 #[display("WrongNumberOfArguments. expected {_2} got {_1}")]
30 WrongNumberOfArguments(LocInfo, NumGiven, NumExpected),
31 #[display("ParseIntError {_1}")]
32 ParseIntError(LocInfo, ParseIntError),
33 #[from]
34 #[display("TypeError {_1}")]
35 TypeError(LocInfo, TypeError),
36 #[from]
37 #[display("RuntimeError {_0}")]
38 RuntimeError(RuntimeError),
39 #[from]
40 #[display("InvalidPQL {_0:?}")]
41 InvalidPQL(pql_parser::Error),
42 #[from]
43 #[display("InvalidRange")]
44 InvalidRange(Loc, range_parser::Error),
45 #[from]
46 Internal(InternalError),
47}
48
49#[derive(Debug, Clone, PartialEq, Eq, Display)]
53pub enum RuntimeError {
54 ToRankParseFailed(String),
55 ToCardParseFailed(String),
56 RateHiHandExpectedFiveCards(String),
57 RateHiHandParseFailed(String),
58 AddFailed,
59 CmpFailed,
60 MinMaxNotDefined,
61 DefaultNotDefined,
62}
63
64#[derive(Debug, Clone, PartialEq, Eq, Display)]
66pub enum TypeError {
67 #[display("BinOpError {_1} {_0} {_2}")]
68 BinOpError(OpSymbol, PQLType, PQLType),
69 #[display("InvalidIdent")]
70 InvalidIdent(PQLType),
71 #[display("SelectorDoesNotSupport {_0} {_1}")]
72 SelectorDoesNotSupport(SelectorName, GotType),
73 #[display("expected {_0}")]
74 TypeMismatch(ExpectedType),
75}
76
77#[derive(Debug, Clone, PartialEq, Eq, Display)]
79pub enum InternalError {
80 BrokenStack,
81 CannotAddValue,
82 ThreadJoinFailed,
83 InvalidVmValue,
84}
85
86impl From<&PQLError> for Option<LocInfo> {
87 fn from(e: &PQLError) -> Self {
88 match e {
89 PQLError::Internal(_)
90 | PQLError::TooManyVariables
91 | PQLError::RuntimeError(_) => None,
92
93 PQLError::UnknownIdent(loc)
94 | PQLError::ParseIntError(loc, _)
95 | PQLError::UnrecognizedGame(loc)
96 | PQLError::WrongNumberOfArguments(loc, _, _)
97 | PQLError::UnrecognizedFunction(loc)
98 | PQLError::TypeError(loc, _) => Some(*loc),
99
100 PQLError::InvalidPQL(e) => Some(e.into()),
101
102 PQLError::InvalidRange(offset, e) => {
103 let (a, b): LocInfo = e.into();
104
105 Some((a + offset + 1, b + offset + 1))
106 }
107 }
108 }
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114
115 #[test]
116 fn test_loc() {
117 let opt: Option<LocInfo> =
118 (&PQLError::Internal(InternalError::BrokenStack)).into();
119 assert!(opt.is_none());
120
121 let opt: Option<LocInfo> = (&PQLError::TooManyVariables).into();
122 assert!(opt.is_none());
123 }
124}