1use std::cmp::max;
2
3use crate::{ConsumableToken, Parsable, ParseError, TokenIter};
4
5#[derive(PartialEq, Default, Debug, Clone)]
6pub struct LiteralStringValue {
7 value: String,
8}
9
10impl From<String> for LiteralStringValue {
11 fn from(s: String) -> Self {
12 LiteralStringValue { value: s }
13 }
14}
15
16#[derive(PartialEq, Default, Debug, Clone)]
17pub struct LiteralIntValue {
18 value: String,
19}
20
21impl From<String> for LiteralIntValue {
22 fn from(s: String) -> Self {
23 LiteralIntValue { value: s }
24 }
25}
26
27#[derive(PartialEq, Default, Debug, Clone)]
28pub struct IdentifierValue {
29 value: String,
30}
31
32impl From<String> for IdentifierValue {
33 fn from(s: String) -> Self {
34 IdentifierValue { value: s }
35 }
36}
37
38#[derive(Debug, Clone, PartialEq, Eq)]
39pub enum Token {
40 Assign,
42 Plus,
43 Minus,
44 Mult,
45 Div,
46 KInt,
48 KFloat,
49 KReturn,
50 LiteralString(String),
52 LiteralInt(u32),
53 Identifier(String),
55 RCurly,
57 LCurly,
58 RBracket,
59 LBracket,
60 RParen,
61 LParen,
62 Comma,
63 SemiColon,
65 INVALID,
67 EMPTY,
68}
69
70impl Token {
71 pub fn from_regex_result(&self, input: String) -> (Token, usize) {
72 let token = match *self {
73 Token::LiteralString(_) => Token::LiteralString(input[1..input.len() - 1].to_string()), Token::Identifier(_) => Token::Identifier(input.clone()), Token::LiteralInt(_) => {
76 let s: u32 = input.parse().unwrap();
77 Token::LiteralInt(s)
78 }
79 _ => (*self).clone(),
80 };
81 (token, input.len())
82 }
83}
84
85#[macro_export]
86macro_rules! t {
87 (,) => {
88 Token::Comma
89 };
90 (, def) => {
91 ","
92 };
93 (;) => {
94 Token::SemiColon
95 };
96 (; def) => {
97 ";"
98 };
99 (=) => {
100 Token::Assign
101 };
102 (= def) => {
103 "="
104 };
105 (+) => {
106 Token::Plus
107 };
108 (+ def) => {
109 "+"
110 };
111 (-) => {
112 Token::Minus
113 };
114 (- def) => {
115 "-"
116 };
117 (*) => {
118 Token::Mult
119 };
120 (* def) => {
121 "*"
122 };
123 (/) => {
124 Token::Div
125 };
126 (/ def) => {
127 "/"
128 };
129 (int) => {
130 Token::KInt
131 };
132 (float) => {
133 Token::KFloat
134 };
135 (int def) => {
136 "int"
137 };
138 (return) => {
139 Token::KReturn
140 };
141 (return def) => {
142 "return"
143 };
144
145 (litstr) => {
146 Token::LiteralString("DEFAULT_LITERAL_STRING")
147 };
148 (litint) => {
149 Token::LiteralInt(0)
150 };
151 (ident) => {
152 Token::Identifier("DEFAULT_IDENTIFIER".to_string())
153 };
154
155 (litstr $value:expr) => {
156 Token::LiteralString($value.to_string())
157 };
158 (litint $value:expr) => {
159 Token::LiteralInt($value)
160 };
161 (ident $value:expr) => {
162 Token::Identifier($value.to_string())
163 };
164
165 (r_paren) => {
166 Token::RParen
167 };
168 (r_paren def) => {
169 ")"
170 };
171 (l_paren) => {
172 Token::LParen
173 };
174 (l_paren def) => {
175 "("
176 };
177 (r_curly) => {
178 Token::RCurly
179 };
180 (r_curly def) => {
181 "}"
182 };
183 (l_curly) => {
184 Token::LCurly
185 };
186 (l_curly def) => {
187 "{"
188 };
189 (r_bracket) => {
190 Token::RBracket
191 };
192 (r_bracket def) => {
193 "]"
194 };
195 (l_bracket) => {
196 Token::LBracket
197 };
198 (l_bracket def) => {
199 "["
200 };
201 (empty) => {
202 Token::EMPTY
203 };
204 (invalid) => {
205 Token::INVALID
206 };
207}
208
209impl ConsumableToken for Token {}
210
211impl Parsable<Token> for Token {
212 fn parse(iter: &mut TokenIter<Token>) -> Result<Self, ParseError<Token>>
213 where
214 Self: Sized,
215 {
216 match iter.consume() {
217 Some(token) => Ok(token),
218 None => Err(ParseError::no_more_tokens::<Token>(iter.current)),
219 }
220 }
221
222 fn parse_if_match<F: Fn(&Token) -> bool>(
223 iter: &mut TokenIter<Token>,
224 matches: F,
225 pattern: Option<&'static str>
226 ) -> Result<Self, ParseError<Token>>
227 where
228 Self: Sized,
229 {
230 iter.try_do(|token_iter| match token_iter.consume() {
233 Some(ref found) if matches(found) => Ok(found.clone()),
234 Some(ref found) => Err(ParseError::parsed_but_unmatching::<Token>(
235 if token_iter.current == 0 {
236 token_iter.current
237 } else {
238 token_iter.current - 1
239 },
240 found,
241 pattern
242 )),
243 _ => Err(ParseError::no_more_tokens::<Token>(if token_iter.current == 0 {
244 token_iter.current
245 } else {
246 token_iter.current - 1
247 })),
248 })
249 }
250}