1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use crate::ast::{NodeId, Syntax};
use crate::error::SyntaxResult;
use crate::parse::expr::parse_expr_until_either;
use crate::parse::parser::Parser;
use crate::parse::pattern::parse_pattern;
use crate::symbol::ScopeId;
use crate::token::TokenType;
use super::pattern::{ParsePatternAction, ParsePatternSyntax};
pub fn parse_signature_function(
scope: ScopeId,
parser: &mut Parser,
syntax: &ParsePatternSyntax,
) -> SyntaxResult<NodeId> {
let start_pos = parser.checkpoint();
let mut parameters = Vec::new();
parser.require(TokenType::ParenthesisOpen)?;
loop {
if parser.consume_if(TokenType::ParenthesisClose)?.is_match() {
break;
};
let rest = parser.consume_if(TokenType::DotDotDot)?.is_match();
let pattern = parse_pattern(scope, parser, ParsePatternAction::AddToClosureScope, syntax)?;
let default_value = parser.consume_if(TokenType::Equals)?.and_then(|| {
parse_expr_until_either(
scope,
parser,
TokenType::Comma,
TokenType::ParenthesisClose,
syntax,
)
})?;
parameters.push(parser.create_node(
scope,
parser[pattern].loc().clone(),
Syntax::ParamDecl {
rest,
pattern,
default_value,
},
));
if !parser.consume_if(TokenType::Comma)?.is_match() {
parser.require(TokenType::ParenthesisClose)?;
break;
};
}
Ok(parser.create_node(
scope,
parser.since_checkpoint(start_pos),
Syntax::FunctionSignature { parameters },
))
}