Actually just three programming languages in a trenchcoat
1use source_span::Span;
2
3use super::{expression::Precedence, *};
4use crate::{Parser, Spanned};
5
6/// A function application expression.
7///
8/// ```trilogy
9/// f x
10/// ```
11#[derive(Clone, Debug)]
12pub struct Application {
13 /// An expression that evaluates to the function being applied.
14 pub function: Expression,
15 /// An expression that evalutes to the argument to the function.
16 pub argument: Expression,
17 pub span: Span,
18}
19
20impl Spanned for Application {
21 fn span(&self) -> Span {
22 self.span
23 }
24}
25
26impl Application {
27 pub(crate) fn parse(parser: &mut Parser, function: Expression) -> SyntaxResult<Self> {
28 let argument = Expression::parse_precedence(parser, Precedence::Application)?;
29 Ok(Self {
30 span: function.span().union(argument.span()),
31 function,
32 argument,
33 })
34 }
35}
36
37#[cfg(test)]
38mod test {
39 use super::*;
40
41 test_parse!(application_simple: "hello world" => Expression::parse => Expression::Application(Application { .. }));
42 test_parse!(application_path: "a::hello (b::world)" => Expression::parse => Expression::Application (Application { .. }));
43 test_parse!(application_parenthesized: "hello (a + world)" => Expression::parse => Expression::Application (Application { .. }));
44 test_parse!(application_unary_not: "hello !b" => Expression::parse => Expression::Application(Application { argument: Expression::Unary(..), .. }));
45 test_parse!(not_application_unary_minus: "hello - b" => Expression::parse => Expression::Binary(..));
46 test_parse!(application_unary_negate: "hello ~b" => Expression::parse => Expression::Application(Application { argument: Expression::Unary(..), .. }));
47 test_parse!(application_keyword: "hello if x then 3 else 4" => Expression::parse => Expression::Application(Application { argument: Expression::IfElse(..), .. }));
48 test_parse!(application_of_number: "3 4 5" => Expression::parse => Expression::Application(Application { .. }));
49 test_parse!(application_binop: "hello a + world" => Expression::parse => Expression::Binary(BinaryOperation { lhs: Expression::Application(Application { .. }), .. }));
50}