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, PrettyPrintSExpr)]
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 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 _ (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 _ (Expression::Unary _)))");
47 test_parse!(application_keyword: "hello if x then 3 else 4" => Expression::parse => "(Expression::Application (Application _ (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 => "
50 (Expression::Binary
51 (BinaryOperation
52 (Expression::Application (Application _ _))
53 _
54 _))");
55}