wagon_parser/parser/
sum.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 wagon_lexer::math::Math;
9
10use super::term::Term;
11use super::helpers::TokenMapper;
12use wagon_macros::TokenMapper;
13use quote::{ToTokens, quote};
14
15use wagon_macros::new_unspanned;
16
17#[derive(PartialEq, Debug, Eq, Hash, Clone)]
18#[new_unspanned]
19pub struct Sum {
26 pub left: SpannableNode<Term>,
28 pub cont: Option<SumP>
30}
31
32#[derive(PartialEq, Debug, Eq, Hash, Clone)]
33#[new_unspanned]
34pub struct SumP {
39 pub op: Op1,
41 pub right: SpannableNode<Term>,
43 pub cont: Option<Box<SumP>>
45}
46
47impl Parse for Sum {
48
49 fn parse(lexer: &mut LexerBridge) -> ParseResult<Self> {
50 Ok(Self {
51 left: SpannableNode::parse(lexer)?,
52 cont: SumP::parse_option(lexer)?
53 })
54 }
55}
56
57impl ParseOption for SumP {
58
59 fn parse_option(lexer: &mut LexerBridge) -> ParseResult<Option<Self>> where Self: Sized {
60 if let Some(op) = Op1::token_to_enum(lexer.peek_result()?) {
61 lexer.next();
62 Ok(Some(Self { op, right: SpannableNode::parse(lexer)?, cont: Self::parse_option(lexer)?.map(Box::new) }))
63 } else {
64 Ok(None)
65 }
66 }
67}
68
69impl GetReqAttributes for Sum {
70 fn get_req_attributes(&self) -> crate::firstpass::ReqAttributes {
71 let mut req = self.left.get_req_attributes();
72 if let Some(cont) = &self.cont {
73 req.extend(cont.get_req_attributes());
74 }
75 req
76 }
77}
78
79impl GetReqAttributes for SumP {
80 fn get_req_attributes(&self) -> crate::firstpass::ReqAttributes {
81 let mut req = self.right.get_req_attributes();
82 if let Some(cont) = &self.cont {
83 req.extend(cont.get_req_attributes());
84 }
85 req
86 }
87}
88
89impl RewriteToSynth for Sum {
90 fn rewrite_to_synth(&mut self) -> crate::firstpass::ReqAttributes {
91 let mut req = self.left.rewrite_to_synth();
92 if let Some(cont) = &mut self.cont {
93 req.extend(cont.rewrite_to_synth());
94 }
95 req
96 }
97}
98
99impl RewriteToSynth for SumP {
100 fn rewrite_to_synth(&mut self) -> crate::firstpass::ReqAttributes {
101 let mut req = self.right.rewrite_to_synth();
102 if let Some(cont) = &mut self.cont {
103 req.extend(cont.rewrite_to_synth());
104 }
105 req
106 }
107}
108
109#[derive(TokenMapper, PartialEq, Debug, Eq, Hash, Clone)]
110pub enum Op1 {
115 Add,
117 Sub
119}
120
121impl Display for Sum {
122 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
123 if let Some(c) = &self.cont {
124 write!(f, "{} {}", self.left, c)
125 } else {
126 write!(f, "{}", self.left)
127 }
128 }
129}
130
131impl Display for SumP {
132 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
133 if let Some(c) = &self.cont {
134 write!(f, "{} {} {}", self.op, self.right, c)
135 } else {
136 write!(f, "{} {}", self.op, self.right)
137 }
138 }
139}
140
141impl Display for Op1 {
142 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
143 match self {
144 Self::Add => write!(f, "+"),
145 Self::Sub => write!(f, "-"),
146 }
147 }
148}
149
150impl ToTokens for Op1 {
151 fn to_tokens(&self, tokens: &mut quote::__private::TokenStream) {
152 match self {
153 Self::Add => tokens.extend(quote!(std::ops::Add::add)),
154 Self::Sub => tokens.extend(quote!(std::ops::Sub::sub)),
155 }
156 }
157}