syn_solidity/yul/expr/
mod.rs

1use crate::{Lit, Spanned, YulPath};
2use proc_macro2::Span;
3use std::fmt;
4use syn::{
5    parse::{discouraged::Speculative, Parse, ParseStream, Result},
6    token::Paren,
7};
8
9mod fn_call;
10pub use fn_call::{YulFnCall, YulFnType};
11
12/// A Yul expression.
13///
14/// Solidity Reference:
15/// <https://docs.soliditylang.org/en/latest/grammar.html#a4.SolidityParser.yulExpression>
16#[derive(Clone)]
17pub enum YulExpr {
18    Path(YulPath),
19    Call(YulFnCall),
20    Literal(Lit),
21}
22
23impl Parse for YulExpr {
24    fn parse(input: ParseStream<'_>) -> Result<Self> {
25        if input.peek2(Paren) {
26            return input.parse().map(Self::Call);
27        }
28
29        let speculative_parse = input.fork();
30
31        if let Ok(lit) = speculative_parse.parse::<Lit>() {
32            input.advance_to(&speculative_parse);
33            return Ok(Self::Literal(lit));
34        }
35
36        input.parse().map(Self::Path)
37    }
38}
39
40impl Spanned for YulExpr {
41    fn span(&self) -> Span {
42        match self {
43            Self::Path(path) => path.span(),
44            Self::Call(call) => call.span(),
45            Self::Literal(lit) => lit.span(),
46        }
47    }
48
49    fn set_span(&mut self, span: Span) {
50        match self {
51            Self::Path(path) => path.set_span(span),
52            Self::Call(call) => call.set_span(span),
53            Self::Literal(lit) => lit.set_span(span),
54        }
55    }
56}
57
58impl fmt::Debug for YulExpr {
59    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60        f.write_str("YulExpr::")?;
61        match self {
62            Self::Path(path) => path.fmt(f),
63            Self::Call(call) => call.fmt(f),
64            Self::Literal(lit) => lit.fmt(f),
65        }
66    }
67}