Actually just three programming languages in a trenchcoat
at string-repr-callable 55 lines 2.2 kB view raw
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}