1use crate::{
4 parser::{error::{Error, kind}, fmt::Latex, Parse, Parser},
5 tokenizer::TokenKind,
6};
7use std::{fmt, ops::Range};
8
9#[cfg(feature = "serde")]
10use serde::{Deserialize, Serialize};
11
12#[derive(Debug, Clone, Copy, PartialEq)]
14pub enum Associativity {
15 Left,
21
22 Right,
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq)]
33pub enum Precedence {
34 Any,
36
37 Assign,
40
41 Or,
43
44 And,
46
47 Compare,
49
50 BitOr,
52
53 BitAnd,
55
56 Shift,
58
59 Term,
61
62 Factor,
65
66 Neg,
68
69 Exp,
71
72 Factorial,
74
75 BitNot,
77
78 Not,
80}
81
82impl PartialOrd for Precedence {
83 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
84 Some(self.cmp(other))
85 }
86}
87
88impl Ord for Precedence {
89 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
90 let left = *self as u8;
91 let right = *other as u8;
92 left.cmp(&right)
93 }
94}
95
96#[derive(Debug, Clone, Copy, PartialEq)]
98#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
99pub enum UnaryOpKind {
100 Not,
101 BitNot,
102 Factorial,
103 Neg,
104}
105
106impl UnaryOpKind {
107 pub fn precedence(&self) -> Precedence {
109 match self {
110 Self::Not => Precedence::Not,
111 Self::BitNot => Precedence::BitNot,
112 Self::Factorial => Precedence::Factorial,
113 Self::Neg => Precedence::Neg,
114 }
115 }
116
117 pub fn associativity(&self) -> Associativity {
119 match self {
120 Self::Neg | Self::BitNot | Self::Not => Associativity::Right,
121 Self::Factorial => Associativity::Left,
122 }
123 }
124}
125
126#[derive(Debug, Clone, PartialEq)]
128#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
129pub struct UnaryOp {
130 pub kind: UnaryOpKind,
132
133 pub span: Range<usize>,
135}
136
137impl UnaryOp {
138 pub fn precedence(&self) -> Precedence {
140 self.kind.precedence()
141 }
142
143 pub fn associativity(&self) -> Associativity {
145 self.kind.associativity()
146 }
147}
148
149impl<'source> Parse<'source> for UnaryOp {
150 fn std_parse(
151 input: &mut Parser<'source>,
152 _: &mut Vec<Error>
153 ) -> Result<Self, Vec<Error>> {
154 let token = input.next_token().map_err(|e| vec![e])?;
155 let kind = match token.kind {
156 TokenKind::Not => Ok(UnaryOpKind::Not),
157 TokenKind::BitNot => Ok(UnaryOpKind::BitNot),
158 TokenKind::Factorial => Ok(UnaryOpKind::Factorial),
159 TokenKind::Sub => Ok(UnaryOpKind::Neg),
160 _ => Err(vec![Error::new(
161 vec![token.span.clone()],
162 kind::UnexpectedToken {
163 expected: &[
164 TokenKind::Not,
165 TokenKind::BitNot,
166 TokenKind::Factorial,
167 TokenKind::Sub,
168 ],
169 found: token.kind,
170 },
171 )]),
172 }?;
173
174 Ok(Self {
175 kind,
176 span: token.span,
177 })
178 }
179}
180
181impl std::fmt::Display for UnaryOp {
182 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
183 match self.kind {
184 UnaryOpKind::Not => write!(f, "not"),
185 UnaryOpKind::BitNot => write!(f, "~"),
186 UnaryOpKind::Factorial => write!(f, "!"),
187 UnaryOpKind::Neg => write!(f, "-"),
188 }
189 }
190}
191
192impl Latex for UnaryOp {
193 fn fmt_latex(&self, f: &mut fmt::Formatter) -> fmt::Result {
194 match self.kind {
195 UnaryOpKind::Not => write!(f, "\\neg "),
196 UnaryOpKind::BitNot => write!(f, "\\sim "),
197 UnaryOpKind::Factorial => write!(f, "!"),
198 UnaryOpKind::Neg => write!(f, "-"),
199 }
200 }
201}
202
203#[derive(Debug, Clone, Copy, PartialEq)]
205#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
206pub enum BinOpKind {
207 Exp,
208 Mul,
209 Div,
210 Mod,
211 Add,
212 Sub,
213 BitRight,
214 BitLeft,
215 BitAnd,
216 BitOr,
217 Greater,
218 GreaterEq,
219 Less,
220 LessEq,
221 Eq,
222 NotEq,
223 ApproxEq,
224 ApproxNotEq,
225 And,
226 Or,
227}
228
229impl BinOpKind {
230 pub fn precedence(&self) -> Precedence {
232 match self {
233 Self::Exp => Precedence::Exp,
234 Self::Mul | Self::Div | Self::Mod => Precedence::Factor,
235 Self::Add | Self::Sub => Precedence::Term,
236 Self::BitRight | Self::BitLeft => Precedence::Shift,
237 Self::BitAnd => Precedence::BitAnd,
238 Self::BitOr => Precedence::BitOr,
239 Self::Greater | Self::GreaterEq | Self::Less | Self::LessEq
240 | Self::Eq | Self::NotEq | Self::ApproxEq | Self::ApproxNotEq => Precedence::Compare,
241 Self::And => Precedence::And,
242 Self::Or => Precedence::Or,
243 }
244 }
245
246 pub fn associativity(&self) -> Associativity {
248 match self {
249 Self::Exp => Associativity::Right,
250 Self::Mul | Self::Div | Self::Mod
251 | Self::Add | Self::Sub
252 | Self::BitRight | Self::BitLeft
253 | Self::BitAnd | Self::BitOr
254 | Self::Greater | Self::GreaterEq | Self::Less | Self::LessEq
255 | Self::Eq | Self::NotEq | Self::ApproxEq | Self::ApproxNotEq
256 | Self::And | Self::Or => Associativity::Left,
257 }
258 }
259}
260
261#[derive(Debug, Clone, PartialEq)]
263#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
264pub struct BinOp {
265 pub kind: BinOpKind,
267
268 pub implicit: bool,
270
271 pub span: Range<usize>,
273}
274
275impl BinOp {
276 pub fn precedence(&self) -> Precedence {
278 self.kind.precedence()
279 }
280
281 pub fn associativity(&self) -> Associativity {
283 self.kind.associativity()
284 }
285}
286
287impl<'source> Parse<'source> for BinOp {
288 fn std_parse(
289 input: &mut Parser<'source>,
290 _: &mut Vec<Error>
291 ) -> Result<Self, Vec<Error>> {
292 let token = input.next_token().map_err(|e| vec![e])?;
293 let kind = match token.kind {
294 TokenKind::Exp => Ok(BinOpKind::Exp),
295 TokenKind::Mul => Ok(BinOpKind::Mul),
296 TokenKind::Div => Ok(BinOpKind::Div),
297 TokenKind::Mod => Ok(BinOpKind::Mod),
298 TokenKind::Add => Ok(BinOpKind::Add),
299 TokenKind::Sub => Ok(BinOpKind::Sub),
300 TokenKind::BitRight => Ok(BinOpKind::BitRight),
301 TokenKind::BitLeft => Ok(BinOpKind::BitLeft),
302 TokenKind::BitAnd => Ok(BinOpKind::BitAnd),
303 TokenKind::BitOr => Ok(BinOpKind::BitOr),
304 TokenKind::Greater => Ok(BinOpKind::Greater),
305 TokenKind::GreaterEq => Ok(BinOpKind::GreaterEq),
306 TokenKind::Less => Ok(BinOpKind::Less),
307 TokenKind::LessEq => Ok(BinOpKind::LessEq),
308 TokenKind::Eq => Ok(BinOpKind::Eq),
309 TokenKind::NotEq => Ok(BinOpKind::NotEq),
310 TokenKind::ApproxEq => Ok(BinOpKind::ApproxEq),
311 TokenKind::ApproxNotEq => Ok(BinOpKind::ApproxNotEq),
312 TokenKind::And => Ok(BinOpKind::And),
313 TokenKind::Or => Ok(BinOpKind::Or),
314 _ => Err(vec![Error::new(
315 vec![token.span.clone()],
316 kind::UnexpectedToken {
317 expected: &[
318 TokenKind::Exp,
319 TokenKind::Mul,
320 TokenKind::Div,
321 TokenKind::Add,
322 TokenKind::Sub,
323 ],
324 found: token.kind,
325 },
326 )]),
327 }?;
328
329 Ok(Self {
330 kind,
331 implicit: false,
332 span: token.span,
333 })
334 }
335}
336
337impl std::fmt::Display for BinOp {
338 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
339 if self.implicit {
340 return Ok(());
341 }
342
343 match self.kind {
344 BinOpKind::Exp => write!(f, "^"),
345 BinOpKind::Mul => write!(f, "*"),
346 BinOpKind::Div => write!(f, "/"),
347 BinOpKind::Mod => write!(f, "%"),
348 BinOpKind::Add => write!(f, "+"),
349 BinOpKind::Sub => write!(f, "-"),
350 BinOpKind::BitRight => write!(f, ">>"),
351 BinOpKind::BitLeft => write!(f, "<<"),
352 BinOpKind::BitAnd => write!(f, "&"),
353 BinOpKind::BitOr => write!(f, "|"),
354 BinOpKind::Greater => write!(f, ">"),
355 BinOpKind::GreaterEq => write!(f, ">="),
356 BinOpKind::Less => write!(f, "<"),
357 BinOpKind::LessEq => write!(f, "<="),
358 BinOpKind::Eq => write!(f, "=="),
359 BinOpKind::NotEq => write!(f, "!="),
360 BinOpKind::ApproxEq => write!(f, "~=="),
361 BinOpKind::ApproxNotEq => write!(f, "~!="),
362 BinOpKind::And => write!(f, "&&"),
363 BinOpKind::Or => write!(f, "||"),
364 }
365 }
366}
367
368impl Latex for BinOp {
369 fn fmt_latex(&self, f: &mut fmt::Formatter) -> fmt::Result {
370 if self.implicit {
371 return Ok(());
372 }
373
374 match self.kind {
375 BinOpKind::Exp => write!(f, "^"),
376 BinOpKind::Mul => write!(f, "\\cdot "),
377 BinOpKind::Div => write!(f, "\\div "),
378 BinOpKind::Mod => write!(f, "\\mod "),
379 BinOpKind::Add => write!(f, "+"),
380 BinOpKind::Sub => write!(f, "-"),
381 BinOpKind::BitRight => write!(f, "\\gg "),
382 BinOpKind::BitLeft => write!(f, "\\ll "),
383 BinOpKind::BitAnd => write!(f, "\\&"),
384 BinOpKind::BitOr => write!(f, "\\vert "),
385 BinOpKind::Greater => write!(f, ">"),
386 BinOpKind::GreaterEq => write!(f, "\\geq "),
387 BinOpKind::Less => write!(f, "<"),
388 BinOpKind::LessEq => write!(f, "\\leq "),
389 BinOpKind::Eq => write!(f, "="),
390 BinOpKind::NotEq => write!(f, "\\neq "),
391 BinOpKind::ApproxEq => write!(f, "\\approx "),
392 BinOpKind::ApproxNotEq => write!(f, "\\not\\approx "),
393 BinOpKind::And => write!(f, "\\wedge "),
394 BinOpKind::Or => write!(f, "\\vee "),
395 }
396 }
397}
398
399#[derive(Debug, Clone, Copy, PartialEq)]
401#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
402pub enum AssignOpKind {
403 Assign,
404 Add,
405 Sub,
406 Mul,
407 Div,
408 Mod,
409 Exp,
410 And,
411 Or,
412 BitAnd,
413 BitOr,
414 BitRight,
415 BitLeft,
416}
417
418impl From<AssignOpKind> for BinOpKind {
419 fn from(value: AssignOpKind) -> Self {
420 match value {
421 AssignOpKind::Assign => Self::Eq,
422 AssignOpKind::Add => Self::Add,
423 AssignOpKind::Sub => Self::Sub,
424 AssignOpKind::Mul => Self::Mul,
425 AssignOpKind::Div => Self::Div,
426 AssignOpKind::Mod => Self::Mod,
427 AssignOpKind::Exp => Self::Exp,
428 AssignOpKind::And => Self::And,
429 AssignOpKind::Or => Self::Or,
430 AssignOpKind::BitAnd => Self::BitAnd,
431 AssignOpKind::BitOr => Self::BitOr,
432 AssignOpKind::BitRight => Self::BitRight,
433 AssignOpKind::BitLeft => Self::BitLeft,
434 }
435 }
436}
437
438#[derive(Debug, Clone, PartialEq)]
441#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
442pub struct AssignOp {
443 pub kind: AssignOpKind,
445
446 pub span: Range<usize>,
448}
449
450impl AssignOp {
451 pub fn is_standard(&self) -> bool {
453 matches!(self.kind, AssignOpKind::Assign)
454 }
455
456 pub fn is_compound(&self) -> bool {
458 !self.is_standard()
459 }
460}
461
462impl<'source> Parse<'source> for AssignOp {
463 fn std_parse(
464 input: &mut Parser<'source>,
465 _: &mut Vec<Error>
466 ) -> Result<Self, Vec<Error>> {
467 let token = input.next_token().map_err(|e| vec![e])?;
468 let kind = match token.kind {
469 TokenKind::Assign => Ok(AssignOpKind::Assign),
470 TokenKind::AddAssign => Ok(AssignOpKind::Add),
471 TokenKind::SubAssign => Ok(AssignOpKind::Sub),
472 TokenKind::MulAssign => Ok(AssignOpKind::Mul),
473 TokenKind::DivAssign => Ok(AssignOpKind::Div),
474 TokenKind::ModAssign => Ok(AssignOpKind::Mod),
475 TokenKind::ExpAssign => Ok(AssignOpKind::Exp),
476 TokenKind::AndAssign => Ok(AssignOpKind::And),
477 TokenKind::OrAssign => Ok(AssignOpKind::Or),
478 TokenKind::BitAndAssign => Ok(AssignOpKind::BitAnd),
479 TokenKind::BitOrAssign => Ok(AssignOpKind::BitOr),
480 TokenKind::BitRightAssign => Ok(AssignOpKind::BitRight),
481 TokenKind::BitLeftAssign => Ok(AssignOpKind::BitLeft),
482 _ => Err(vec![Error::new(
483 vec![token.span.clone()],
484 kind::UnexpectedToken {
485 expected: &[
486 TokenKind::Assign,
487 TokenKind::AddAssign,
488 TokenKind::SubAssign,
489 TokenKind::MulAssign,
490 TokenKind::DivAssign,
491 TokenKind::ModAssign,
492 TokenKind::ExpAssign,
493 TokenKind::AndAssign,
494 TokenKind::OrAssign,
495 TokenKind::BitAndAssign,
496 TokenKind::BitOrAssign,
497 TokenKind::BitRightAssign,
498 TokenKind::BitLeftAssign,
499 ],
500 found: token.kind,
501 },
502 )]),
503 }?;
504
505 Ok(Self {
506 kind,
507 span: token.span,
508 })
509 }
510}
511
512impl std::fmt::Display for AssignOp {
513 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
514 match self.kind {
515 AssignOpKind::Assign => write!(f, "="),
516 AssignOpKind::Add => write!(f, "+="),
517 AssignOpKind::Sub => write!(f, "-="),
518 AssignOpKind::Mul => write!(f, "*="),
519 AssignOpKind::Div => write!(f, "/="),
520 AssignOpKind::Mod => write!(f, "%="),
521 AssignOpKind::Exp => write!(f, "^="),
522 AssignOpKind::And => write!(f, "&&="),
523 AssignOpKind::Or => write!(f, "||="),
524 AssignOpKind::BitAnd => write!(f, "&="),
525 AssignOpKind::BitOr => write!(f, "|="),
526 AssignOpKind::BitRight => write!(f, ">>="),
527 AssignOpKind::BitLeft => write!(f, "<<="),
528 }
529 }
530}
531
532impl Latex for AssignOp {
533 fn fmt_latex(&self, f: &mut fmt::Formatter) -> fmt::Result {
534 match self.kind {
535 AssignOpKind::Assign => write!(f, "="),
536 AssignOpKind::Add => write!(f, "+="),
537 AssignOpKind::Sub => write!(f, "-="),
538 AssignOpKind::Mul => write!(f, "*="),
539 AssignOpKind::Div => write!(f, "/="),
540 AssignOpKind::Mod => write!(f, "\\mod="),
541 AssignOpKind::Exp => write!(f, "^="),
542 AssignOpKind::And => write!(f, "\\wedge="),
543 AssignOpKind::Or => write!(f, "\\vee="),
544 AssignOpKind::BitAnd => write!(f, "\\&="),
545 AssignOpKind::BitOr => write!(f, "\\vert="),
546 AssignOpKind::BitRight => write!(f, "\\gg="),
547 AssignOpKind::BitLeft => write!(f, "\\ll="),
548 }
549 }
550}