1use crate::{
2 parser::{
3 ast::{
4 assign::Assign,
5 binary::Binary,
6 block::Block,
7 call::Call,
8 if_expr::If,
9 literal::Literal,
10 loop_expr::{Break, Continue, Loop},
11 paren::Paren,
12 unary::Unary,
13 while_expr::While,
14 },
15 error::{kind, Error},
16 fmt::Latex,
17 iter::ExprIter,
18 token::{op::Precedence, CloseParen},
19 Parse,
20 Parser,
21 },
22 return_if_ok,
23};
24use std::{fmt, ops::Range};
25
26#[cfg(feature = "serde")]
27use serde::{Deserialize, Serialize};
28
29#[derive(Debug, Clone, PartialEq)]
34#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
35pub enum Expr {
36 Literal(Literal),
38
39 Paren(Paren),
41
42 Block(Block),
44
45 If(If),
47
48 Loop(Loop),
50
51 While(While),
53
54 Break(Break),
56
57 Continue(Continue),
59
60 Call(Call),
62
63 Unary(Unary),
65
66 Binary(Binary),
68
69 Assign(Assign),
71}
72
73impl Expr {
74 pub fn span(&self) -> Range<usize> {
76 match self {
77 Expr::Literal(literal) => literal.span(),
78 Expr::Paren(paren) => paren.span(),
79 Expr::Block(block) => block.span(),
80 Expr::If(if_expr) => if_expr.span(),
81 Expr::Loop(loop_expr) => loop_expr.span(),
82 Expr::While(while_expr) => while_expr.span(),
83 Expr::Break(break_expr) => break_expr.span(),
84 Expr::Continue(continue_expr) => continue_expr.span(),
85 Expr::Call(call) => call.span(),
86 Expr::Unary(unary) => unary.span(),
87 Expr::Binary(binary) => binary.span(),
88 Expr::Assign(assign) => assign.span(),
89 }
90 }
91
92 pub fn post_order_iter(&self) -> ExprIter {
95 ExprIter::new(self)
96 }
97
98 pub fn innermost(&self) -> &Expr {
101 let mut inner = self;
102 while let Expr::Paren(paren) = inner {
103 inner = &paren.expr;
104 }
105 inner
106 }
107}
108
109impl<'source> Parse<'source> for Expr {
110 fn std_parse(
111 input: &mut Parser<'source>,
112 recoverable_errors: &mut Vec<Error>
113 ) -> Result<Self, Vec<Error>> {
114 if input.clone().try_parse::<CloseParen>().is_ok() {
115 return Err(vec![input.error(kind::UnclosedParenthesis { opening: false })]);
116 }
117
118 let _ = return_if_ok!(input.try_parse().map(Self::Assign).forward_errors(recoverable_errors));
119 let lhs = Unary::parse_or_lower(input, recoverable_errors)?;
120 Ok(Binary::parse_expr(input, recoverable_errors, lhs, Precedence::Any)?.0)
121 }
122}
123
124impl std::fmt::Display for Expr {
125 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126 match self {
127 Expr::Literal(literal) => literal.fmt(f),
128 Expr::Paren(paren) => paren.fmt(f),
129 Expr::Block(block) => block.fmt(f),
130 Expr::If(if_expr) => if_expr.fmt(f),
131 Expr::Loop(loop_expr) => loop_expr.fmt(f),
132 Expr::While(while_expr) => while_expr.fmt(f),
133 Expr::Break(break_expr) => break_expr.fmt(f),
134 Expr::Continue(continue_expr) => continue_expr.fmt(f),
135 Expr::Call(call) => call.fmt(f),
136 Expr::Unary(unary) => unary.fmt(f),
137 Expr::Binary(binary) => binary.fmt(f),
138 Expr::Assign(assign) => assign.fmt(f),
139 }
140 }
141}
142
143impl Latex for Expr {
144 fn fmt_latex(&self, f: &mut fmt::Formatter) -> fmt::Result {
145 match self {
146 Expr::Literal(literal) => literal.fmt_latex(f),
147 Expr::Paren(paren) => paren.fmt_latex(f),
148 Expr::Block(block) => block.fmt_latex(f),
149 Expr::If(if_expr) => if_expr.fmt_latex(f),
150 Expr::Loop(loop_expr) => loop_expr.fmt_latex(f),
151 Expr::While(while_expr) => while_expr.fmt_latex(f),
152 Expr::Break(break_expr) => break_expr.fmt_latex(f),
153 Expr::Continue(continue_expr) => continue_expr.fmt_latex(f),
154 Expr::Call(call) => call.fmt_latex(f),
155 Expr::Unary(unary) => unary.fmt_latex(f),
156 Expr::Binary(binary) => binary.fmt_latex(f),
157 Expr::Assign(assign) => assign.fmt_latex(f),
158 }
159 }
160}
161
162#[derive(Debug, Clone, PartialEq)]
169pub enum Primary {
170 Literal(Literal),
172
173 Paren(Paren),
175
176 Block(Block),
178
179 If(If),
181
182 Loop(Loop),
184
185 While(While),
187
188 Break(Break),
190
191 Continue(Continue),
193
194 Call(Call),
196}
197
198impl Primary {
199 pub fn span(&self) -> Range<usize> {
201 match self {
202 Primary::Literal(literal) => literal.span(),
203 Primary::Paren(paren) => paren.span(),
204 Primary::Block(block) => block.span(),
205 Primary::If(if_expr) => if_expr.span(),
206 Primary::Loop(loop_expr) => loop_expr.span(),
207 Primary::While(while_expr) => while_expr.span(),
208 Primary::Break(break_expr) => break_expr.span(),
209 Primary::Continue(continue_expr) => continue_expr.span(),
210 Primary::Call(call) => call.span(),
211 }
212 }
213}
214
215impl<'source> Parse<'source> for Primary {
216 fn std_parse(
217 input: &mut Parser<'source>,
218 recoverable_errors: &mut Vec<Error>
219 ) -> Result<Self, Vec<Error>> {
220 let _ = return_if_ok!(input.try_parse().map(Self::If).forward_errors(recoverable_errors));
221 let _ = return_if_ok!(input.try_parse().map(Self::Loop).forward_errors(recoverable_errors));
222 let _ = return_if_ok!(input.try_parse().map(Self::While).forward_errors(recoverable_errors));
223 let _ = return_if_ok!(input.try_parse().map(Self::Break).forward_errors(recoverable_errors));
224 let _ = return_if_ok!(input.try_parse().map(Self::Continue).forward_errors(recoverable_errors));
225 let _ = return_if_ok!(input.try_parse().map(Self::Call).forward_errors(recoverable_errors));
228 let _ = return_if_ok!(input.try_parse().map(Self::Literal).forward_errors(recoverable_errors));
229 let _ = return_if_ok!(input.try_parse().map(Self::Paren).forward_errors(recoverable_errors));
230 input.try_parse().map(Self::Block).forward_errors(recoverable_errors)
231 }
232}
233
234impl From<Primary> for Expr {
235 fn from(primary: Primary) -> Self {
236 match primary {
237 Primary::Literal(literal) => Self::Literal(literal),
238 Primary::Paren(paren) => Self::Paren(paren),
239 Primary::Block(block) => Self::Block(block),
240 Primary::If(if_expr) => Self::If(if_expr),
241 Primary::Loop(loop_expr) => Self::Loop(loop_expr),
242 Primary::While(while_expr) => Self::While(while_expr),
243 Primary::Break(break_expr) => Self::Break(break_expr),
244 Primary::Continue(continue_expr) => Self::Continue(continue_expr),
245 Primary::Call(call) => Self::Call(call),
246 }
247 }
248}