Reduce ambiguity for function parsing

This commit is contained in:
Jeff 2024-06-18 21:44:22 -04:00
parent 7c809fa764
commit 799467b25b
3 changed files with 28 additions and 20 deletions

View File

@ -84,9 +84,13 @@ pub fn parser<'src>(
.clone() .clone()
.separated_by(just(Token::Control(Control::Comma))) .separated_by(just(Token::Control(Control::Comma)))
.at_least(1) .at_least(1)
.collect(), .collect()
.delimited_by(
just(Token::Control(Control::Pipe)),
just(Token::Control(Control::Pipe)),
)
.or_not(),
) )
.or_not()
.then( .then(
type_constructor type_constructor
.clone() .clone()
@ -226,9 +230,13 @@ pub fn parser<'src>(
.separated_by(just(Token::Control(Control::Comma))) .separated_by(just(Token::Control(Control::Comma)))
.at_least(1) .at_least(1)
.allow_trailing() .allow_trailing()
.collect(), .collect()
.delimited_by(
just(Token::Control(Control::Pipe)),
just(Token::Control(Control::Pipe)),
)
.or_not(),
) )
.or_not()
.then( .then(
identifier identifier
.clone() .clone()
@ -939,26 +947,26 @@ mod tests {
#[test] #[test]
fn function_type() { fn function_type() {
assert_eq!( 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( Statement::TypeAssignment(
TypeAssignment::new( TypeAssignment::new(
Identifier::new("Foo").with_position((5, 8)), Identifier::new("Foo").with_position((5, 8)),
TypeConstructor::Function( TypeConstructor::Function(
FunctionTypeConstructor { FunctionTypeConstructor {
type_parameters: Some(vec![ type_parameters: Some(vec![
Identifier::new("T").with_position((14, 15)) Identifier::new("T").with_position((15, 16))
]), ]),
value_parameters: vec![TypeConstructor::Type( value_parameters: vec![TypeConstructor::Type(
Type::Integer.with_position((17, 20)) Type::Integer.with_position((19, 22))
)], )],
return_type: Box::new(TypeConstructor::Identifier( 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] #[test]
fn function_with_type_arguments() { fn function_with_type_arguments() {
assert_eq!( 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( Statement::Expression(Expression::Value(
ValueNode::Function { ValueNode::Function {
type_parameters: Some(vec![Identifier::new("T"), Identifier::new("U"),]), type_parameters: Some(vec![Identifier::new("T"), Identifier::new("U"),]),
@ -1056,25 +1064,25 @@ mod tests {
( (
Identifier::new("x"), Identifier::new("x"),
TypeConstructor::Identifier( TypeConstructor::Identifier(
Identifier::new("T").with_position((12, 13)) Identifier::new("T").with_position((14, 15))
) )
), ),
( (
Identifier::new("y"), Identifier::new("y"),
TypeConstructor::Identifier( TypeConstructor::Identifier(
Identifier::new("U").with_position((18, 19)) Identifier::new("U").with_position((20, 21))
) )
) )
], ],
return_type: TypeConstructor::Identifier( 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( 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))
)) ))
) )
} }

View File

@ -6,7 +6,7 @@ fn function_call_with_type_argument() {
interpret( interpret(
"test", "test",
" "
foobar = fn T (x: T) -> T { x } foobar = fn |T| (x: T) -> T { x }
foobar::(int)::(42) foobar::(int)::(42)
", ",
), ),
@ -20,7 +20,7 @@ fn function_call() {
interpret( interpret(
"test", "test",
" "
foobar = fn (message: str) -> str { message } foobar = fn (message: str) -> str { message }
foobar('Hiya') foobar('Hiya')
", ",
), ),

View File

@ -1,5 +1,5 @@
json = { json = {
parse = fn T (input: str) -> T { parse = fn |T| (input: str) -> T {
JSON_PARSE T input JSON_PARSE T input
} }
} }