1#[macro_use]
2use crate::*;
3
4#[cfg(not(feature = "no-std"))] use core::fmt;
5#[cfg(feature = "no-std")] use alloc::fmt;
6#[cfg(feature = "no-std")] use alloc::string::String;
7#[cfg(feature = "no-std")] use alloc::vec::Vec;
8use nom::{
9 IResult,
10 branch::alt,
11 sequence::tuple as nom_tuple,
12 combinator::{opt, eof},
13 multi::{many1, many_till, many0, separated_list1,separated_list0},
14 Err,
15 Err::Failure
16};
17
18pub fn function_define(input: ParseString) -> ParseResult<FunctionDefine> {
20 let ((input, name)) = identifier(input)?;
21 let ((input, _)) = left_parenthesis(input)?;
22 let ((input, input_args)) = separated_list0(list_separator, function_arg)(input)?;
23 let ((input, _)) = right_parenthesis(input)?;
24 let ((input, _)) = whitespace0(input)?;
25 match function_define_match_arms(input.clone(), name.clone(), input_args.clone()) {
26 Ok((input, fxn_def)) => Ok((input, fxn_def)),
27 Err(_) => function_define_statements(input, name, input_args),
28 }
29}
30
31fn function_define_statements(
32 input: ParseString,
33 name: Identifier,
34 input_args: Vec<FunctionArgument>,
35) -> ParseResult<FunctionDefine> {
36 let ((input, _)) = equal(input)?;
37 let ((input, _)) = whitespace0(input)?;
38 let ((input, output)) = alt((function_out_args,function_out_arg))(input)?;
39 let ((input, _)) = define_operator(input)?;
40 let ((input, statements)) = separated_list1(alt((whitespace1,statement_separator)), statement)(input)?;
41 let ((input, _)) = period(input)?;
42 Ok((input,FunctionDefine{name,input: input_args,output,statements,match_arms: vec![]}))
43}
44
45fn function_define_match_arms(
46 input: ParseString,
47 name: Identifier,
48 input_args: Vec<FunctionArgument>,
49) -> ParseResult<FunctionDefine> {
50 let (input, _) = output_operator(input)?;
51 let (input, _) = whitespace0(input)?;
52 let (input, output_kind) = kind_annotation(input)?;
53 let output_src_range = output_kind
54 .tokens()
55 .first()
56 .map(|token| token.src_range.clone())
57 .unwrap_or_default();
58 let output = vec![FunctionArgument {
59 name: Identifier {
60 name: Token::new(TokenKind::Identifier, output_src_range, vec!['_']),
61 },
62 kind: output_kind,
63 }];
64 let (input, _) = many1(alt((whitespace1, statement_separator)))(input)?;
65 let (input, match_arms) = many1(function_match_arm)(input)?;
66 let (input, _) = opt(period)(input)?;
67 Ok((input, FunctionDefine {
68 name,
69 input: input_args,
70 output,
71 statements: vec![],
72 match_arms,
73 }))
74}
75
76fn function_match_arm(input: ParseString) -> ParseResult<FunctionMatchArm> {
77 let (input, _) = whitespace0(input)?;
78 let (input, _) = alt((box_t_left, box_bl, bar))(input)?;
79 let (input, _) = whitespace0(input)?;
80 if let Ok((input, pattern)) = crate::patterns::pattern(input.clone()) {
81 if let Ok((input, _)) = whitespace0(input) {
82 if let Ok((input, _)) = output_operator(input) {
83 let (input, _) = whitespace0(input)?;
84 let (input, expr) = expression(input)?;
85 let (input, _) = opt(alt((whitespace1, statement_separator)))(input)?;
86 return Ok((input, FunctionMatchArm {
87 pattern,
88 expression: expr,
89 }));
90 }
91 }
92 }
93 let (input, expr) = expression(input)?;
94 let (input, _) = opt(alt((whitespace1, statement_separator)))(input)?;
95 Ok((input, FunctionMatchArm {
96 pattern: Pattern::Wildcard,
97 expression: expr,
98 }))
99}
100
101pub fn function_out_args(input: ParseString) -> ParseResult<Vec<FunctionArgument>> {
103 let ((input, _)) = left_parenthesis(input)?;
104 let ((input, args)) = separated_list1(list_separator,function_arg)(input)?;
105 let ((input, _)) = right_parenthesis(input)?;
106 Ok((input, args))
107}
108
109pub fn function_out_arg(input: ParseString) -> ParseResult<Vec<FunctionArgument>> {
111 let ((input, arg)) = function_arg(input)?;
112 Ok((input, vec![arg]))
113}
114
115pub fn function_arg(input: ParseString) -> ParseResult<FunctionArgument> {
117 let ((input, name)) = identifier(input)?;
118 let ((input, kind)) = kind_annotation(input)?;
119 Ok((input, FunctionArgument{ name, kind }))
120}
121
122pub fn argument_list(input: ParseString) -> ParseResult<ArgumentList> {
124 let (input, _) = left_parenthesis(input)?;
125 let (input, args) = separated_list0(list_separator, alt((call_arg_with_binding,call_arg)))(input)?;
126 let (input, _) = right_parenthesis(input)?;
127 Ok((input, args))
128}
129
130pub fn function_call(input: ParseString) -> ParseResult<FunctionCall> {
132 let (input, name) = identifier(input)?;
133 let (input, args) = argument_list(input)?;
134 Ok((input, FunctionCall{name,args} ))
135}
136
137pub fn call_arg_with_binding(input: ParseString) -> ParseResult<(Option<Identifier>,Expression)> {
139 let (input, arg_name) = identifier(input)?;
140 let (input, _) = whitespace0(input)?;
141 let (input, _) = colon(input)?;
142 let (input, _) = whitespace0(input)?;
143 let (input, expr) = expression(input)?;
144 Ok((input, (Some(arg_name), expr)))
145}
146
147pub fn call_arg(input: ParseString) -> ParseResult<(Option<Identifier>,Expression)> {
149 let (input, expr) = expression(input)?;
150 Ok((input, (None, expr)))
151}