Add type arguments to function calls

This commit is contained in:
Jeff 2024-03-24 10:58:09 -04:00
parent 2b797c19f7
commit a0a9bc2fdf
3 changed files with 55 additions and 13 deletions

View File

@ -9,16 +9,19 @@ use super::{AbstractNode, Action, Expression, Type, WithPosition};
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord)]
pub struct FunctionCall { pub struct FunctionCall {
function: Box<WithPosition<Expression>>, function: Box<WithPosition<Expression>>,
type_arguments: Vec<WithPosition<Type>>,
arguments: Vec<WithPosition<Expression>>, arguments: Vec<WithPosition<Expression>>,
} }
impl FunctionCall { impl FunctionCall {
pub fn new( pub fn new(
function: WithPosition<Expression>, function: WithPosition<Expression>,
type_arguments: Vec<WithPosition<Type>>,
arguments: Vec<WithPosition<Expression>>, arguments: Vec<WithPosition<Expression>>,
) -> Self { ) -> Self {
FunctionCall { FunctionCall {
function: Box::new(function), function: Box::new(function),
type_arguments,
arguments, arguments,
} }
} }

View File

@ -291,6 +291,20 @@ pub fn parser<'src>() -> impl Parser<
.with_position(state.span()) .with_position(state.span())
}); });
let turbofish = r#type
.clone()
.separated_by(just(Token::Control(Control::Comma)))
.at_least(1)
.collect()
.delimited_by(
just(Token::Control(Control::ParenOpen)),
just(Token::Control(Control::ParenClose)),
)
.delimited_by(
just(Token::Control(Control::DoubleColon)),
just(Token::Control(Control::DoubleColon)),
);
let atom = choice(( let atom = choice((
range.clone(), range.clone(),
structure_instance.clone(), structure_instance.clone(),
@ -323,6 +337,7 @@ pub fn parser<'src>() -> impl Parser<
), ),
postfix( postfix(
3, 3,
turbofish.clone().or_not().then(
positioned_expression positioned_expression
.clone() .clone()
.separated_by(just(Token::Control(Control::Comma))) .separated_by(just(Token::Control(Control::Comma)))
@ -331,8 +346,18 @@ pub fn parser<'src>() -> impl Parser<
just(Token::Control(Control::ParenOpen)), just(Token::Control(Control::ParenOpen)),
just(Token::Control(Control::ParenClose)), just(Token::Control(Control::ParenClose)),
), ),
|function_expression, arguments, span| { ),
Expression::FunctionCall(FunctionCall::new(function_expression, arguments)) |function_expression,
(type_arguments, arguments): (
Option<Vec<WithPosition<Type>>>,
Vec<WithPosition<Expression>>,
),
span| {
Expression::FunctionCall(FunctionCall::new(
function_expression,
type_arguments.unwrap_or_else(|| Vec::with_capacity(0)),
arguments,
))
.with_position(span) .with_position(span)
}, },
), ),
@ -690,6 +715,7 @@ mod tests {
vec![ vec![
Statement::Expression(Expression::FunctionCall(FunctionCall::new( Statement::Expression(Expression::FunctionCall(FunctionCall::new(
Expression::Identifier(Identifier::new("output")).with_position((13, 19)), Expression::Identifier(Identifier::new("output")).with_position((13, 19)),
Vec::with_capacity(0),
vec![Expression::Value(ValueNode::String("hi".to_string())) vec![Expression::Value(ValueNode::String("hi".to_string()))
.with_position((20, 24))] .with_position((20, 24))]
))) )))
@ -793,6 +819,19 @@ mod tests {
))) )))
.with_position((0, 13)), .with_position((0, 13)),
Vec::with_capacity(0), Vec::with_capacity(0),
Vec::with_capacity(0),
)))
)
}
#[test]
fn function_call_with_type_arguments() {
assert_eq!(
parse(&lex("foobar::(str)::('hi')").unwrap()).unwrap()[0].node,
Statement::Expression(Expression::FunctionCall(FunctionCall::new(
Expression::Identifier(Identifier::new("foobar")).with_position((0, 6)),
vec![Type::String.with_position((9, 12))],
vec![Expression::Value(ValueNode::String("hi".to_string())).with_position((16, 20))],
))) )))
) )
} }

View File

@ -51,8 +51,8 @@ impl Value {
Value(Arc::new(ValueInner::Range(range))) Value(Arc::new(ValueInner::Range(range)))
} }
pub fn string(string: String) -> Self { pub fn string<T: ToString>(to_string: T) -> Self {
Value(Arc::new(ValueInner::String(string))) Value(Arc::new(ValueInner::String(to_string.to_string())))
} }
pub fn function( pub fn function(