just/src/expression.rs

134 lines
4.2 KiB
Rust
Raw Normal View History

use super::*;
2017-11-16 23:30:08 -08:00
/// An expression. Note that the Just language grammar has both an `expression`
/// production of additions (`a + b`) and values, and a `value` production of
/// all other value types (for example strings, function calls, and
/// parenthetical groups).
///
/// The parser parses both values and expressions into `Expression`s.
2021-06-08 01:01:27 -07:00
#[derive(PartialEq, Debug, Clone)]
pub(crate) enum Expression<'src> {
2024-05-14 18:55:32 -07:00
/// `assert(condition, error)`
Assert {
condition: Condition<'src>,
error: Box<Expression<'src>>,
},
/// `contents`
Backtick {
contents: String,
token: Token<'src>,
},
/// `name(arguments)`
Call { thunk: Thunk<'src> },
/// `lhs + rhs`
2022-05-28 19:07:53 -07:00
Concatenation {
lhs: Box<Expression<'src>>,
rhs: Box<Expression<'src>>,
},
2024-05-14 18:55:32 -07:00
/// `if condition { then } else { otherwise }`
Conditional {
2024-05-14 18:55:32 -07:00
condition: Condition<'src>,
then: Box<Expression<'src>>,
otherwise: Box<Expression<'src>>,
},
/// `(contents)`
Group { contents: Box<Expression<'src>> },
2022-06-25 02:39:06 -07:00
/// `lhs / rhs`
Join {
lhs: Option<Box<Expression<'src>>>,
2022-06-25 02:39:06 -07:00
rhs: Box<Expression<'src>>,
},
/// `"string_literal"` or `'string_literal'`
StringLiteral { string_literal: StringLiteral<'src> },
/// `variable`
Variable { name: Name<'src> },
2017-11-16 23:30:08 -08:00
}
impl<'src> Expression<'src> {
pub(crate) fn variables<'expression>(&'expression self) -> Variables<'expression, 'src> {
Variables::new(self)
2017-11-16 23:30:08 -08:00
}
}
impl<'src> Display for Expression<'src> {
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
match self {
2024-05-14 18:55:32 -07:00
Expression::Assert { condition, error } => write!(f, "assert({condition}, {error})"),
2021-06-08 01:01:27 -07:00
Expression::Backtick { token, .. } => write!(f, "{}", token.lexeme()),
2022-12-15 16:53:21 -08:00
Expression::Join { lhs: None, rhs } => write!(f, "/ {rhs}"),
Expression::Join {
lhs: Some(lhs),
rhs,
2022-12-15 16:53:21 -08:00
} => write!(f, "{lhs} / {rhs}"),
Expression::Concatenation { lhs, rhs } => write!(f, "{lhs} + {rhs}"),
Expression::Conditional {
2024-05-14 18:55:32 -07:00
condition,
then,
otherwise,
2024-05-14 18:55:32 -07:00
} => write!(f, "if {condition} {{ {then} }} else {{ {otherwise} }}"),
2022-12-15 16:53:21 -08:00
Expression::StringLiteral { string_literal } => write!(f, "{string_literal}"),
Expression::Variable { name } => write!(f, "{}", name.lexeme()),
2022-12-15 16:53:21 -08:00
Expression::Call { thunk } => write!(f, "{thunk}"),
Expression::Group { contents } => write!(f, "({contents})"),
2017-11-16 23:30:08 -08:00
}
}
}
2021-11-17 00:07:48 -08:00
impl<'src> Serialize for Expression<'src> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
2024-05-14 18:55:32 -07:00
Self::Assert { condition, error } => {
let mut seq: <S as Serializer>::SerializeSeq = serializer.serialize_seq(None)?;
seq.serialize_element("assert")?;
seq.serialize_element(condition)?;
seq.serialize_element(error)?;
seq.end()
}
2021-11-17 00:07:48 -08:00
Self::Backtick { contents, .. } => {
let mut seq = serializer.serialize_seq(None)?;
seq.serialize_element("evaluate")?;
seq.serialize_element(contents)?;
seq.end()
}
Self::Call { thunk } => thunk.serialize(serializer),
2022-05-28 19:07:53 -07:00
Self::Concatenation { lhs, rhs } => {
2021-11-17 00:07:48 -08:00
let mut seq = serializer.serialize_seq(None)?;
2022-12-30 12:36:08 -08:00
seq.serialize_element("concatenate")?;
2021-11-17 00:07:48 -08:00
seq.serialize_element(lhs)?;
seq.serialize_element(rhs)?;
seq.end()
}
2022-06-25 02:39:06 -07:00
Self::Join { lhs, rhs } => {
let mut seq = serializer.serialize_seq(None)?;
seq.serialize_element("join")?;
seq.serialize_element(lhs)?;
seq.serialize_element(rhs)?;
seq.end()
}
2021-11-17 00:07:48 -08:00
Self::Conditional {
2024-05-14 18:55:32 -07:00
condition,
2021-11-17 00:07:48 -08:00
then,
otherwise,
} => {
let mut seq = serializer.serialize_seq(None)?;
seq.serialize_element("if")?;
2024-05-14 18:55:32 -07:00
seq.serialize_element(condition)?;
2021-11-17 00:07:48 -08:00
seq.serialize_element(then)?;
seq.serialize_element(otherwise)?;
seq.end()
}
Self::Group { contents } => contents.serialize(serializer),
Self::StringLiteral { string_literal } => string_literal.serialize(serializer),
Self::Variable { name } => {
let mut seq = serializer.serialize_seq(None)?;
seq.serialize_element("variable")?;
seq.serialize_element(name)?;
seq.end()
}
}
}
}