wagon_parser/parser/
comp.rs1use std::fmt::Display;
2use std::write;
3
4use crate::firstpass::{GetReqAttributes, RewriteToSynth};
5
6use super::{Parse, LexerBridge, ParseResult, ParseOption, Tokens, SpannableNode, ResultPeek};
7
8use super::helpers::TokenMapper;
9
10use wagon_lexer::math::Math;
11
12use super::sum::Sum;
13use wagon_macros::TokenMapper;
14
15use quote::{ToTokens, quote};
16
17use wagon_macros::new_unspanned;
18
19#[derive(PartialEq, Debug, Eq, Hash, Clone)]
20#[new_unspanned]
21pub struct Comparison {
28 pub sum: SpannableNode<Sum>,
30 pub comp: Option<Comp>
32}
33
34#[derive(PartialEq, Debug, Eq, Hash, Clone)]
35#[cfg_attr(test, new_unspanned)]
36pub struct Comp {
38 pub op: CompOp,
40 pub right: SpannableNode<Sum>
42}
43
44#[derive(TokenMapper, PartialEq, Debug, Eq, Hash, Clone)]
45pub enum CompOp {
50 Eq,
52 Neq,
54 Lte,
56 Lt,
58 Gte,
60 Gt,
62 In
64}
65
66impl Parse for Comparison {
67
68 fn parse(lexer: &mut LexerBridge) -> ParseResult<Self> where Self: Sized {
69 Ok(Self { sum: SpannableNode::parse(lexer)?, comp: Comp::parse_option(lexer)? })
70 }
71
72}
73
74impl ParseOption for Comp {
75
76 fn parse_option(lexer: &mut LexerBridge) -> ParseResult<Option<Self>> where Self: Sized {
77 if let Some(op) = CompOp::token_to_enum(lexer.peek_result()?) {
78 lexer.next();
79 Ok(Some(Self { op, right: SpannableNode::parse(lexer)?}))
80 } else {
81 Ok(None)
82 }
83 }
84}
85
86impl GetReqAttributes for Comparison {
87 fn get_req_attributes(&self) -> crate::firstpass::ReqAttributes {
88 let mut req = self.sum.get_req_attributes();
89 if let Some(cont) = &self.comp {
90 req.extend(cont.right.get_req_attributes());
91 }
92 req
93 }
94}
95
96impl RewriteToSynth for Comparison {
97 fn rewrite_to_synth(&mut self) -> crate::firstpass::ReqAttributes {
98 let mut req = self.sum.rewrite_to_synth();
99 if let Some(cont) = &mut self.comp {
100 req.extend(cont.right.rewrite_to_synth());
101 }
102 req
103 }
104}
105
106impl Display for Comparison {
107 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
108 if let Some(c) = &self.comp {
109 write!(f, "{} {} {}", self.sum, c.op, c.right)
110 } else {
111 write!(f, "{}", self.sum)
112 }
113 }
114}
115
116impl Display for CompOp {
117 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118 match self {
119 Self::Eq => write!(f, "=="),
120 Self::Neq => write!(f, "!="),
121 Self::Lte => write!(f, "<="),
122 Self::Lt => write!(f, "<"),
123 Self::Gte => write!(f, ">="),
124 Self::Gt => write!(f, ">"),
125 Self::In => write!(f, "in"),
126 }
127 }
128}
129
130impl ToTokens for CompOp {
131 fn to_tokens(&self, tokens: &mut quote::__private::TokenStream) {
132 match self {
133 Self::Eq => tokens.extend(quote!(==)),
134 Self::Neq => tokens.extend(quote!(!=)),
135 Self::Lte => tokens.extend(quote!(<=)),
136 Self::Lt => tokens.extend(quote!(<)),
137 Self::Gte => tokens.extend(quote!(>=)),
138 Self::Gt => tokens.extend(quote!(>)),
139 Self::In => unimplemented!("Should be a special case!"),
140 };
141 }
142}