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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use ::parser::*;
named!(pub parse_function<NomSpan, AstItem>,
do_parse!(
// zero or more whitespaces, including line endings and tabs
ws0 >>
// parse the `fn` keyword
from: tag!("fn") >>
// after the function keyword, return an error if parsing fails
data: return_error!(do_parse!(
// parse one or more whitespaces, including line endings and tabs
ws1 >>
// parse the function name, return an InvalidFunctionName error if it failed
function_name: add_return_error!(ErrorKind::Custom(ParseErrorKind::InvalidFunctionName as u32), parse_identifier) >>
// zero or more whitespaces, including line endings and tabs
ws0 >>
// parse function type arguments
type_arguments: opt!(do_parse!(
tag!("<") >>
type_arguments: separated_list!(tag!(","), parse_identifier) >>
tag!(">") >>
(type_arguments)
)) >>
// zero or more whitespaces, including line endings and tabs
ws0 >>
// parse the beginning of the argument list
add_return_error!(ErrorKind::Custom(ParseErrorKind::MissingArgumentList as u32), tag!("(")) >>
// parse the argument list
arguments: separated_list!(tag!(","), parse_function_argument) >>
// zero or more whitespaces, including line endings and tabs
ws0 >>
// parse the end of the argument list
void: tag!(")") >>
// zero or more whitespaces, including line endings and tabs
ws0 >>
return_type_name: opt!(do_parse!(
// parse the arrow indicating a following return type
tag!("->") >>
// zero or more whitespaces, including line endings and tabs
ws0 >>
// parse return type
return_type_name: parse_type_identifier >>
// zero or more whitespaces, including line endings and tabs
ws0 >>
(return_type_name)
)) >>
// parse the function body as a block
block: parse_block_declaration >>
((function_name, type_arguments, arguments, return_type_name, block, void))
)) >>
(AstItem::Function(FunctionDeclaration{
span: Span::from_to(Span::from_nom_span(&from), data.4.span),
function_name: data.0,
type_arguments: data.1.unwrap_or(vec![]),
arguments: data.2,
return_type_name: data.3.unwrap_or(TypeIdentifier::void(Span::from_nom_span(&data.5))),
block: data.4,
}))
)
);
named!(parse_function_argument<NomSpan, FunctionArgumentDeclaration>,
do_parse!(
// zero or more whitespaces, including line endings and tabs
ws0 >>
// parse the argument identifier
argument_name: parse_identifier >>
// zero or more whitespaces, including line endings and tabs
ws0 >>
// parse the `:` denoting a following type information
tag!(":") >>
// zero or more whitespaces, including line endings and tabs
ws0 >>
// parse the argument's type identifier
argument_type_name: parse_type_identifier >>
// zero or more whitespaces, including line endings and tabs
ws0 >>
(FunctionArgumentDeclaration{
span: Span::from_to(argument_name.get_span(), argument_type_name.get_span()),
argument_name: argument_name,
argument_type_name: argument_type_name,
})
)
);