erl_parse/cst/exprs/
mod.rs

1use erl_tokenize::tokens::{KeywordToken, SymbolToken};
2use erl_tokenize::values::{Keyword, Symbol};
3use erl_tokenize::{Position, PositionRange};
4
5use self::parts::{Body, Qualifier, Timeout, TryAfter, TryCatch, TryOf};
6use crate::cst::clauses::{CaseClause, FunClause, IfClause, NamedFunClause};
7use crate::cst::commons::parts::{Clauses, ModulePrefix, NameAndArity, Sequence};
8use crate::cst::commons::{self, AtomOrVariable, IntegerOrVariable};
9use crate::cst::Expr;
10use crate::traits::{Parse, ParseTail, TokenRead};
11use crate::{Parser, Result};
12
13pub mod parts;
14
15pub type Tuple = commons::Tuple<Expr>;
16pub type Map = commons::Map<Expr>;
17pub type Record = commons::Record<Expr>;
18pub type RecordFieldIndex = commons::RecordFieldIndex;
19pub type List = commons::List<Expr>;
20pub type Bits = commons::Bits<Expr>;
21pub type Parenthesized = commons::Parenthesized<Expr>;
22pub type FunCall = commons::Call<Expr>;
23pub type UnaryOpCall = commons::UnaryOpCall<Expr>;
24pub type BinaryOpCall = commons::BinaryOpCall<Expr>;
25pub type Match = commons::Match<Expr>;
26
27/// `Expr` `Map`
28#[derive(Debug, Clone)]
29pub struct MapUpdate {
30    pub map: Expr,
31    pub update: Map,
32}
33impl ParseTail for MapUpdate {
34    type Head = Expr;
35    fn parse_tail<T: TokenRead>(parser: &mut Parser<T>, head: Self::Head) -> Result<Self> {
36        Ok(MapUpdate {
37            map: head,
38            update: track!(parser.parse())?,
39        })
40    }
41}
42impl PositionRange for MapUpdate {
43    fn start_position(&self) -> Position {
44        self.map.start_position()
45    }
46    fn end_position(&self) -> Position {
47        self.update.end_position()
48    }
49}
50
51/// `Expr` `Record`
52#[derive(Debug, Clone)]
53pub struct RecordUpdate {
54    pub record: Expr,
55    pub update: Record,
56}
57impl ParseTail for RecordUpdate {
58    type Head = Expr;
59    fn parse_tail<T: TokenRead>(parser: &mut Parser<T>, head: Self::Head) -> Result<Self> {
60        Ok(RecordUpdate {
61            record: head,
62            update: track!(parser.parse())?,
63        })
64    }
65}
66impl PositionRange for RecordUpdate {
67    fn start_position(&self) -> Position {
68        self.record.start_position()
69    }
70    fn end_position(&self) -> Position {
71        self.update.end_position()
72    }
73}
74
75/// `try` `Body` `Option<TryOf>` `Option<TryCatch>` `Option<TryAfter>` `end`
76#[derive(Debug, Clone)]
77pub struct Try {
78    pub _try: KeywordToken,
79    pub body: Body,
80    pub branch: Option<TryOf>,
81    pub catch: Option<TryCatch>,
82    pub after: Option<TryAfter>,
83    pub _end: KeywordToken,
84}
85impl Parse for Try {
86    fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
87        Ok(Try {
88            _try: track!(parser.expect(&Keyword::Try))?,
89            body: track!(parser.parse())?,
90            branch: track!(parser.parse())?,
91            catch: track!(parser.parse())?,
92            after: track!(parser.parse())?,
93            _end: track!(parser.expect(&Keyword::End))?,
94        })
95    }
96}
97impl PositionRange for Try {
98    fn start_position(&self) -> Position {
99        self._try.start_position()
100    }
101    fn end_position(&self) -> Position {
102        self._end.end_position()
103    }
104}
105
106/// `receive` `Clauses<CaseClause>` `Option<Timeout>` `end`
107#[derive(Debug, Clone)]
108pub struct Receive {
109    pub _receive: KeywordToken,
110    pub clauses: Clauses<CaseClause>,
111    pub timeout: Option<Timeout>,
112    pub _end: KeywordToken,
113}
114impl Parse for Receive {
115    fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
116        Ok(Receive {
117            _receive: track!(parser.expect(&Keyword::Receive))?,
118            clauses: track!(parser.parse())?,
119            timeout: track!(parser.parse())?,
120            _end: track!(parser.expect(&Keyword::End))?,
121        })
122    }
123}
124impl PositionRange for Receive {
125    fn start_position(&self) -> Position {
126        self._receive.start_position()
127    }
128    fn end_position(&self) -> Position {
129        self._end.end_position()
130    }
131}
132
133/// `if` `Clauses<IfClause>` `end`
134#[derive(Debug, Clone)]
135pub struct If {
136    pub _if: KeywordToken,
137    pub clauses: Clauses<IfClause>,
138    pub _end: KeywordToken,
139}
140impl Parse for If {
141    fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
142        Ok(If {
143            _if: track!(parser.expect(&Keyword::If))?,
144            clauses: track!(parser.parse())?,
145            _end: track!(parser.expect(&Keyword::End))?,
146        })
147    }
148}
149impl PositionRange for If {
150    fn start_position(&self) -> Position {
151        self._if.start_position()
152    }
153    fn end_position(&self) -> Position {
154        self._end.end_position()
155    }
156}
157
158/// `case` `Expr` `of` `Clauses<CaseClause>` `end`
159#[derive(Debug, Clone)]
160pub struct Case {
161    pub _case: KeywordToken,
162    pub expr: Expr,
163    pub _of: KeywordToken,
164    pub clauses: Clauses<CaseClause>,
165    pub _end: KeywordToken,
166}
167impl Parse for Case {
168    fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
169        Ok(Case {
170            _case: track!(parser.expect(&Keyword::Case))?,
171            expr: track!(parser.parse())?,
172            _of: track!(parser.expect(&Keyword::Of))?,
173            clauses: track!(parser.parse())?,
174            _end: track!(parser.expect(&Keyword::End))?,
175        })
176    }
177}
178impl PositionRange for Case {
179    fn start_position(&self) -> Position {
180        self._case.start_position()
181    }
182    fn end_position(&self) -> Position {
183        self._end.end_position()
184    }
185}
186
187/// `DefinedFun | AnonymousFun | NamedFun`
188#[derive(Debug, Clone)]
189#[allow(clippy::large_enum_variant)]
190pub enum Fun {
191    Defined(DefinedFun),
192    Anonymous(AnonymousFun),
193    Named(NamedFun),
194}
195impl Parse for Fun {
196    fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
197        // TODO: look ahead
198        if let Ok(x) = parser.transaction(Parser::parse) {
199            Ok(Fun::Defined(x))
200        } else if let Ok(x) = parser.transaction(Parser::parse) {
201            Ok(Fun::Anonymous(x))
202        } else {
203            Ok(Fun::Named(track!(parser.parse())?))
204        }
205    }
206}
207impl PositionRange for Fun {
208    fn start_position(&self) -> Position {
209        match *self {
210            Fun::Defined(ref x) => x.start_position(),
211            Fun::Anonymous(ref x) => x.start_position(),
212            Fun::Named(ref x) => x.start_position(),
213        }
214    }
215    fn end_position(&self) -> Position {
216        match *self {
217            Fun::Defined(ref x) => x.end_position(),
218            Fun::Anonymous(ref x) => x.end_position(),
219            Fun::Named(ref x) => x.end_position(),
220        }
221    }
222}
223
224/// `fun` `Option<ModulePrefix>` `NameAndArity`
225#[derive(Debug, Clone)]
226pub struct DefinedFun {
227    pub _fun: KeywordToken,
228    pub module: Option<ModulePrefix<AtomOrVariable>>,
229    pub fun: NameAndArity<AtomOrVariable, IntegerOrVariable>,
230}
231impl Parse for DefinedFun {
232    fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
233        Ok(DefinedFun {
234            _fun: track!(parser.expect(&Keyword::Fun))?,
235            module: track!(parser.parse())?,
236            fun: track!(parser.parse())?,
237        })
238    }
239}
240impl PositionRange for DefinedFun {
241    fn start_position(&self) -> Position {
242        self._fun.start_position()
243    }
244    fn end_position(&self) -> Position {
245        self.fun.end_position()
246    }
247}
248
249/// `fun` `Clauses<FunClause>` `end`
250#[derive(Debug, Clone)]
251pub struct AnonymousFun {
252    pub _fun: KeywordToken,
253    pub clauses: Clauses<FunClause>,
254    pub _end: KeywordToken,
255}
256impl Parse for AnonymousFun {
257    fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
258        Ok(AnonymousFun {
259            _fun: track!(parser.expect(&Keyword::Fun))?,
260            clauses: track!(parser.parse())?,
261            _end: track!(parser.expect(&Keyword::End))?,
262        })
263    }
264}
265impl PositionRange for AnonymousFun {
266    fn start_position(&self) -> Position {
267        self._fun.start_position()
268    }
269    fn end_position(&self) -> Position {
270        self._end.end_position()
271    }
272}
273
274/// `fun` `Clauses<NamedFunClause>` `end`
275#[derive(Debug, Clone)]
276pub struct NamedFun {
277    pub _fun: KeywordToken,
278    pub clauses: Clauses<NamedFunClause>,
279    pub _end: KeywordToken,
280}
281impl Parse for NamedFun {
282    fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
283        Ok(NamedFun {
284            _fun: track!(parser.expect(&Keyword::Fun))?,
285            clauses: track!(parser.parse())?,
286            _end: track!(parser.expect(&Keyword::End))?,
287        })
288    }
289}
290impl PositionRange for NamedFun {
291    fn start_position(&self) -> Position {
292        self._fun.start_position()
293    }
294    fn end_position(&self) -> Position {
295        self._end.end_position()
296    }
297}
298
299/// `[` `Expr` `||` `Sequence<Qualifier>` `]`
300#[derive(Debug, Clone)]
301pub struct ListComprehension {
302    pub _open: SymbolToken,
303    pub element: Expr,
304    pub _bar: SymbolToken,
305    pub qualifiers: Sequence<Qualifier>,
306    pub _close: SymbolToken,
307}
308impl Parse for ListComprehension {
309    fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
310        Ok(ListComprehension {
311            _open: track!(parser.expect(&Symbol::OpenSquare))?,
312            element: track!(parser.parse())?,
313            _bar: track!(parser.expect(&Symbol::DoubleVerticalBar))?,
314            qualifiers: track!(parser.parse())?,
315            _close: track!(parser.expect(&Symbol::CloseSquare))?,
316        })
317    }
318}
319impl PositionRange for ListComprehension {
320    fn start_position(&self) -> Position {
321        self._open.start_position()
322    }
323    fn end_position(&self) -> Position {
324        self._close.end_position()
325    }
326}
327
328/// `<<` `Expr` `||` `Sequence<Qualifiers>` `>>`
329#[derive(Debug, Clone)]
330pub struct BitsComprehension {
331    pub _open: SymbolToken,
332    pub element: Expr,
333    pub _bar: SymbolToken,
334    pub qualifiers: Sequence<Qualifier>,
335    pub _close: SymbolToken,
336}
337impl Parse for BitsComprehension {
338    fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
339        Ok(BitsComprehension {
340            _open: track!(parser.expect(&Symbol::DoubleLeftAngle))?,
341            element: track!(parser.parse())?,
342            _bar: track!(parser.expect(&Symbol::DoubleVerticalBar))?,
343            qualifiers: track!(parser.parse())?,
344            _close: track!(parser.expect(&Symbol::DoubleRightAngle))?,
345        })
346    }
347}
348impl PositionRange for BitsComprehension {
349    fn start_position(&self) -> Position {
350        self._open.start_position()
351    }
352    fn end_position(&self) -> Position {
353        self._close.end_position()
354    }
355}
356
357/// `catch` `Body`
358#[derive(Debug, Clone)]
359pub struct Catch {
360    pub _catch: KeywordToken,
361    pub expr: Body,
362}
363impl Parse for Catch {
364    fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
365        Ok(Catch {
366            _catch: track!(parser.expect(&Keyword::Catch))?,
367            expr: track!(parser.parse())?,
368        })
369    }
370}
371impl PositionRange for Catch {
372    fn start_position(&self) -> Position {
373        self._catch.start_position()
374    }
375    fn end_position(&self) -> Position {
376        self.expr.end_position()
377    }
378}
379
380/// `begin` `Body` `end`
381#[derive(Debug, Clone)]
382pub struct Block {
383    pub _begin: KeywordToken,
384    pub body: Body,
385    pub _end: KeywordToken,
386}
387impl Parse for Block {
388    fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
389        Ok(Block {
390            _begin: track!(parser.expect(&Keyword::Begin))?,
391            body: track!(parser.parse())?,
392            _end: track!(parser.expect(&Keyword::End))?,
393        })
394    }
395}
396impl PositionRange for Block {
397    fn start_position(&self) -> Position {
398        self._begin.start_position()
399    }
400    fn end_position(&self) -> Position {
401        self._end.end_position()
402    }
403}
404
405/// `Expr` `RecordFieldIndex`
406#[derive(Debug, Clone)]
407pub struct RecordFieldAccess<T = Expr> {
408    pub record: T,
409    pub index: RecordFieldIndex,
410}
411impl<T> ParseTail for RecordFieldAccess<T> {
412    type Head = T;
413    fn parse_tail<U: TokenRead>(parser: &mut Parser<U>, head: Self::Head) -> Result<Self> {
414        Ok(RecordFieldAccess {
415            record: head,
416            index: track!(parser.parse())?,
417        })
418    }
419}
420impl<T: PositionRange> PositionRange for RecordFieldAccess<T> {
421    fn start_position(&self) -> Position {
422        self.record.start_position()
423    }
424    fn end_position(&self) -> Position {
425        self.index.end_position()
426    }
427}