2022-06-18 21:56:31 -07:00
|
|
|
use super::*;
|
2017-11-16 23:30:08 -08:00
|
|
|
|
2020-02-14 04:49:25 -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).
|
2019-11-07 10:55:15 -08:00
|
|
|
///
|
|
|
|
/// The parser parses both values and expressions into `Expression`s.
|
2021-06-08 01:01:27 -07:00
|
|
|
#[derive(PartialEq, Debug, Clone)]
|
2019-11-07 10:55:15 -08:00
|
|
|
pub(crate) enum Expression<'src> {
|
|
|
|
/// `contents`
|
2018-12-08 14:29:41 -08:00
|
|
|
Backtick {
|
2021-04-05 21:28:37 -07:00
|
|
|
contents: String,
|
2021-09-16 06:44:40 -07:00
|
|
|
token: Token<'src>,
|
2018-12-08 14:29:41 -08:00
|
|
|
},
|
2019-11-07 10:55:15 -08:00
|
|
|
/// `name(arguments)`
|
2019-11-21 10:14:10 -08:00
|
|
|
Call { thunk: Thunk<'src> },
|
2019-11-07 10:55:15 -08:00
|
|
|
/// `lhs + rhs`
|
2022-05-28 19:07:53 -07:00
|
|
|
Concatenation {
|
2019-11-07 10:55:15 -08:00
|
|
|
lhs: Box<Expression<'src>>,
|
|
|
|
rhs: Box<Expression<'src>>,
|
2018-12-08 14:29:41 -08:00
|
|
|
},
|
2020-10-26 18:16:42 -07:00
|
|
|
/// `if lhs == rhs { then } else { otherwise }`
|
|
|
|
Conditional {
|
2021-09-16 06:44:40 -07:00
|
|
|
lhs: Box<Expression<'src>>,
|
|
|
|
rhs: Box<Expression<'src>>,
|
|
|
|
then: Box<Expression<'src>>,
|
2020-10-26 18:16:42 -07:00
|
|
|
otherwise: Box<Expression<'src>>,
|
2021-09-16 16:45:56 -07:00
|
|
|
operator: ConditionalOperator,
|
2020-10-26 18:16:42 -07:00
|
|
|
},
|
2019-11-07 10:55:15 -08:00
|
|
|
/// `(contents)`
|
|
|
|
Group { contents: Box<Expression<'src>> },
|
2022-06-25 02:39:06 -07:00
|
|
|
/// `lhs / rhs`
|
|
|
|
Join {
|
2022-09-11 00:48:02 -07:00
|
|
|
lhs: Option<Box<Expression<'src>>>,
|
2022-06-25 02:39:06 -07:00
|
|
|
rhs: Box<Expression<'src>>,
|
|
|
|
},
|
2019-11-07 10:55:15 -08:00
|
|
|
/// `"string_literal"` or `'string_literal'`
|
2019-11-21 06:23:32 -08:00
|
|
|
StringLiteral { string_literal: StringLiteral<'src> },
|
2019-11-07 10:55:15 -08:00
|
|
|
/// `variable`
|
|
|
|
Variable { name: Name<'src> },
|
2017-11-16 23:30:08 -08:00
|
|
|
}
|
|
|
|
|
2019-11-07 10:55:15 -08:00
|
|
|
impl<'src> Expression<'src> {
|
|
|
|
pub(crate) fn variables<'expression>(&'expression self) -> Variables<'expression, 'src> {
|
2019-04-15 22:40:02 -07:00
|
|
|
Variables::new(self)
|
2017-11-16 23:30:08 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-07 10:55:15 -08:00
|
|
|
impl<'src> Display for Expression<'src> {
|
2019-04-11 15:23:14 -07:00
|
|
|
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
2019-11-07 10:55:15 -08:00
|
|
|
match self {
|
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}"),
|
2022-09-11 00:48:02 -07:00
|
|
|
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}"),
|
2020-10-26 18:16:42 -07:00
|
|
|
Expression::Conditional {
|
|
|
|
lhs,
|
|
|
|
rhs,
|
|
|
|
then,
|
|
|
|
otherwise,
|
2021-09-16 16:45:56 -07:00
|
|
|
operator,
|
2020-10-26 18:16:42 -07:00
|
|
|
} => write!(
|
|
|
|
f,
|
2023-01-26 18:49:03 -08:00
|
|
|
"if {lhs} {operator} {rhs} {{ {then} }} else {{ {otherwise} }}"
|
2020-10-26 18:16:42 -07:00
|
|
|
),
|
2022-12-15 16:53:21 -08:00
|
|
|
Expression::StringLiteral { string_literal } => write!(f, "{string_literal}"),
|
2019-11-21 10:14:10 -08:00
|
|
|
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 {
|
|
|
|
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 {
|
|
|
|
lhs,
|
|
|
|
rhs,
|
|
|
|
then,
|
|
|
|
otherwise,
|
|
|
|
operator,
|
|
|
|
} => {
|
|
|
|
let mut seq = serializer.serialize_seq(None)?;
|
|
|
|
seq.serialize_element("if")?;
|
|
|
|
seq.serialize_element(&operator.to_string())?;
|
|
|
|
seq.serialize_element(lhs)?;
|
|
|
|
seq.serialize_element(rhs)?;
|
|
|
|
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()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|