pub_just/
expression.rs

1use super::*;
2
3/// An expression. Note that the Just language grammar has both an `expression`
4/// production of additions (`a + b`) and values, and a `value` production of
5/// all other value types (for example strings, function calls, and
6/// parenthetical groups).
7///
8/// The parser parses both values and expressions into `Expression`s.
9#[derive(PartialEq, Debug, Clone)]
10pub enum Expression<'src> {
11  /// `lhs && rhs`
12  And {
13    lhs: Box<Expression<'src>>,
14    rhs: Box<Expression<'src>>,
15  },
16  /// `assert(condition, error)`
17  Assert {
18    condition: Condition<'src>,
19    error: Box<Expression<'src>>,
20  },
21  /// `contents`
22  Backtick {
23    contents: String,
24    token: Token<'src>,
25  },
26  /// `name(arguments)`
27  Call { thunk: Thunk<'src> },
28  /// `lhs + rhs`
29  Concatenation {
30    lhs: Box<Expression<'src>>,
31    rhs: Box<Expression<'src>>,
32  },
33  /// `if condition { then } else { otherwise }`
34  Conditional {
35    condition: Condition<'src>,
36    then: Box<Expression<'src>>,
37    otherwise: Box<Expression<'src>>,
38  },
39  /// `(contents)`
40  Group { contents: Box<Expression<'src>> },
41  /// `lhs / rhs`
42  Join {
43    lhs: Option<Box<Expression<'src>>>,
44    rhs: Box<Expression<'src>>,
45  },
46  /// `lhs || rhs`
47  Or {
48    lhs: Box<Expression<'src>>,
49    rhs: Box<Expression<'src>>,
50  },
51  /// `"string_literal"` or `'string_literal'`
52  StringLiteral { string_literal: StringLiteral<'src> },
53  /// `variable`
54  Variable { name: Name<'src> },
55}
56
57impl<'src> Expression<'src> {
58  pub fn variables<'expression>(&'expression self) -> Variables<'expression, 'src> {
59    Variables::new(self)
60  }
61}
62
63impl<'src> Display for Expression<'src> {
64  fn fmt(&self, f: &mut Formatter) -> fmt::Result {
65    match self {
66      Self::And { lhs, rhs } => write!(f, "{lhs} && {rhs}"),
67      Self::Assert { condition, error } => write!(f, "assert({condition}, {error})"),
68      Self::Backtick { token, .. } => write!(f, "{}", token.lexeme()),
69      Self::Call { thunk } => write!(f, "{thunk}"),
70      Self::Concatenation { lhs, rhs } => write!(f, "{lhs} + {rhs}"),
71      Self::Conditional {
72        condition,
73        then,
74        otherwise,
75      } => write!(f, "if {condition} {{ {then} }} else {{ {otherwise} }}"),
76      Self::Group { contents } => write!(f, "({contents})"),
77      Self::Join { lhs: None, rhs } => write!(f, "/ {rhs}"),
78      Self::Join {
79        lhs: Some(lhs),
80        rhs,
81      } => write!(f, "{lhs} / {rhs}"),
82      Self::Or { lhs, rhs } => write!(f, "{lhs} || {rhs}"),
83      Self::StringLiteral { string_literal } => write!(f, "{string_literal}"),
84      Self::Variable { name } => write!(f, "{}", name.lexeme()),
85    }
86  }
87}
88
89impl<'src> Serialize for Expression<'src> {
90  fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
91  where
92    S: Serializer,
93  {
94    match self {
95      Self::And { lhs, rhs } => {
96        let mut seq = serializer.serialize_seq(None)?;
97        seq.serialize_element("and")?;
98        seq.serialize_element(lhs)?;
99        seq.serialize_element(rhs)?;
100        seq.end()
101      }
102      Self::Assert { condition, error } => {
103        let mut seq: <S as Serializer>::SerializeSeq = serializer.serialize_seq(None)?;
104        seq.serialize_element("assert")?;
105        seq.serialize_element(condition)?;
106        seq.serialize_element(error)?;
107        seq.end()
108      }
109      Self::Backtick { contents, .. } => {
110        let mut seq = serializer.serialize_seq(None)?;
111        seq.serialize_element("evaluate")?;
112        seq.serialize_element(contents)?;
113        seq.end()
114      }
115      Self::Call { thunk } => thunk.serialize(serializer),
116      Self::Concatenation { lhs, rhs } => {
117        let mut seq = serializer.serialize_seq(None)?;
118        seq.serialize_element("concatenate")?;
119        seq.serialize_element(lhs)?;
120        seq.serialize_element(rhs)?;
121        seq.end()
122      }
123      Self::Conditional {
124        condition,
125        then,
126        otherwise,
127      } => {
128        let mut seq = serializer.serialize_seq(None)?;
129        seq.serialize_element("if")?;
130        seq.serialize_element(condition)?;
131        seq.serialize_element(then)?;
132        seq.serialize_element(otherwise)?;
133        seq.end()
134      }
135      Self::Group { contents } => contents.serialize(serializer),
136      Self::Join { lhs, rhs } => {
137        let mut seq = serializer.serialize_seq(None)?;
138        seq.serialize_element("join")?;
139        seq.serialize_element(lhs)?;
140        seq.serialize_element(rhs)?;
141        seq.end()
142      }
143      Self::Or { lhs, rhs } => {
144        let mut seq = serializer.serialize_seq(None)?;
145        seq.serialize_element("or")?;
146        seq.serialize_element(lhs)?;
147        seq.serialize_element(rhs)?;
148        seq.end()
149      }
150      Self::StringLiteral { string_literal } => string_literal.serialize(serializer),
151      Self::Variable { name } => {
152        let mut seq = serializer.serialize_seq(None)?;
153        seq.serialize_element("variable")?;
154        seq.serialize_element(name)?;
155        seq.end()
156      }
157    }
158  }
159}