From 799467b25b66c9236a8a29fb774075d96e9a6e16 Mon Sep 17 00:00:00 2001 From: Jeff Date: Tue, 18 Jun 2024 21:44:22 -0400 Subject: [PATCH] Reduce ambiguity for function parsing --- dust-lang/src/parser.rs | 42 +++++++++++++++++++++--------------- dust-lang/tests/functions.rs | 4 ++-- std/json.ds | 2 +- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/dust-lang/src/parser.rs b/dust-lang/src/parser.rs index a007a0e..e91f8ad 100644 --- a/dust-lang/src/parser.rs +++ b/dust-lang/src/parser.rs @@ -84,9 +84,13 @@ pub fn parser<'src>( .clone() .separated_by(just(Token::Control(Control::Comma))) .at_least(1) - .collect(), + .collect() + .delimited_by( + just(Token::Control(Control::Pipe)), + just(Token::Control(Control::Pipe)), + ) + .or_not(), ) - .or_not() .then( type_constructor .clone() @@ -226,9 +230,13 @@ pub fn parser<'src>( .separated_by(just(Token::Control(Control::Comma))) .at_least(1) .allow_trailing() - .collect(), + .collect() + .delimited_by( + just(Token::Control(Control::Pipe)), + just(Token::Control(Control::Pipe)), + ) + .or_not(), ) - .or_not() .then( identifier .clone() @@ -939,26 +947,26 @@ mod tests { #[test] fn function_type() { assert_eq!( - parse(&lex("type Foo = fn T (int) -> T").unwrap()).unwrap()[0], + parse(&lex("type Foo = fn |T| (int) -> T").unwrap()).unwrap()[0], Statement::TypeAssignment( TypeAssignment::new( Identifier::new("Foo").with_position((5, 8)), TypeConstructor::Function( FunctionTypeConstructor { type_parameters: Some(vec![ - Identifier::new("T").with_position((14, 15)) + Identifier::new("T").with_position((15, 16)) ]), value_parameters: vec![TypeConstructor::Type( - Type::Integer.with_position((17, 20)) + Type::Integer.with_position((19, 22)) )], return_type: Box::new(TypeConstructor::Identifier( - Identifier::new("T").with_position((25, 26)) + Identifier::new("T").with_position((27, 28)) )), } - .with_position((11, 26)) + .with_position((11, 28)) ) ) - .with_position((0, 26)) + .with_position((0, 28)) ) ); } @@ -1048,7 +1056,7 @@ mod tests { #[test] fn function_with_type_arguments() { assert_eq!( - parse(&lex("fn T, U (x: T, y: U) -> T { x }").unwrap()).unwrap()[0], + parse(&lex("fn |T, U| (x: T, y: U) -> T { x }").unwrap()).unwrap()[0], Statement::Expression(Expression::Value( ValueNode::Function { type_parameters: Some(vec![Identifier::new("T"), Identifier::new("U"),]), @@ -1056,25 +1064,25 @@ mod tests { ( Identifier::new("x"), TypeConstructor::Identifier( - Identifier::new("T").with_position((12, 13)) + Identifier::new("T").with_position((14, 15)) ) ), ( Identifier::new("y"), TypeConstructor::Identifier( - Identifier::new("U").with_position((18, 19)) + Identifier::new("U").with_position((20, 21)) ) ) ], return_type: TypeConstructor::Identifier( - Identifier::new("T").with_position((24, 25)) + Identifier::new("T").with_position((26, 27)) ), body: Block::new(vec![Statement::Expression(Expression::Identifier( - Identifier::new("x").with_position((28, 29)) + Identifier::new("x").with_position((30, 31)) ))]) - .with_position((26, 31)), + .with_position((28, 33)), } - .with_position((0, 31)) + .with_position((0, 33)) )) ) } diff --git a/dust-lang/tests/functions.rs b/dust-lang/tests/functions.rs index 47aef58..957fbed 100644 --- a/dust-lang/tests/functions.rs +++ b/dust-lang/tests/functions.rs @@ -6,7 +6,7 @@ fn function_call_with_type_argument() { interpret( "test", " - foobar = fn T (x: T) -> T { x } + foobar = fn |T| (x: T) -> T { x } foobar::(int)::(42) ", ), @@ -20,7 +20,7 @@ fn function_call() { interpret( "test", " - foobar = fn (message: str) -> str { message } + foobar = fn (message: str) -> str { message } foobar('Hiya') ", ), diff --git a/std/json.ds b/std/json.ds index 0557c7d..6f90528 100644 --- a/std/json.ds +++ b/std/json.ds @@ -1,5 +1,5 @@ json = { - parse = fn T (input: str) -> T { + parse = fn |T| (input: str) -> T { JSON_PARSE T input } }