shape_ast/parser/expressions/
functions.rs1use super::super::pair_span;
12use crate::ast::{Expr, FunctionParameter, Span, Statement, TypeAnnotation};
13use crate::error::Result;
14use crate::parser::Rule;
15use pest::iterators::Pair;
16
17pub fn parse_function_expr(pair: Pair<Rule>) -> Result<Expr> {
19 match pair.as_rule() {
20 Rule::function_expr => {
21 let inner_pairs: Vec<_> = pair.clone().into_inner().collect();
23 if !inner_pairs.is_empty() && inner_pairs[0].as_rule() == Rule::pipe_lambda {
24 parse_pipe_lambda(inner_pairs.into_iter().next().unwrap())
25 } else {
26 parse_regular_function_expr(pair)
28 }
29 }
30 Rule::pipe_lambda => parse_pipe_lambda(pair),
31 _ => parse_regular_function_expr(pair),
32 }
33}
34
35pub fn parse_pipe_lambda(pair: Pair<Rule>) -> Result<Expr> {
38 let span = pair_span(&pair);
39 let inner = pair.into_inner();
40 let mut params = vec![];
41 let mut body_expr = None;
42 let mut body_stmts = vec![];
43
44 for part in inner {
45 match part.as_rule() {
46 Rule::function_params => {
47 for param_pair in part.into_inner() {
48 if param_pair.as_rule() == Rule::function_param {
49 params.push(crate::parser::functions::parse_function_param(param_pair)?);
50 }
51 }
52 }
53 Rule::expression => {
54 body_expr = Some(super::parse_expression(part)?);
55 }
56 Rule::function_body => {
57 body_stmts = crate::parser::statements::parse_statements(part.into_inner())?;
58 }
59 _ => {}
60 }
61 }
62
63 let body = if let Some(expr) = body_expr {
64 vec![Statement::Return(Some(expr), Span::DUMMY)]
65 } else {
66 body_stmts
67 };
68
69 Ok(Expr::FunctionExpr {
70 params,
71 return_type: None,
72 body,
73 span,
74 })
75}
76
77pub fn parse_arrow_function(pair: Pair<Rule>) -> Result<Expr> {
79 let span = pair_span(&pair);
80 let inner = pair.into_inner();
81 let mut params = vec![];
82 let mut return_type: Option<TypeAnnotation> = None;
83 let mut body_expr = None;
84 let mut body_stmts = vec![];
85
86 for part in inner {
87 match part.as_rule() {
88 Rule::ident => {
89 let pattern = crate::ast::DestructurePattern::Identifier(
91 part.as_str().to_string(),
92 pair_span(&part),
93 );
94 params.push(FunctionParameter {
95 pattern,
96 is_const: false,
97 is_reference: false,
98 is_mut_reference: false,
99 is_out: false,
100 type_annotation: None,
101 default_value: None,
102 });
103 }
104 Rule::function_params => {
105 for param_pair in part.into_inner() {
107 if param_pair.as_rule() == Rule::function_param {
108 params.push(crate::parser::functions::parse_function_param(param_pair)?);
109 }
110 }
111 }
112 Rule::function_param => {
113 params.push(crate::parser::functions::parse_function_param(part)?);
115 }
116 Rule::return_type => {
117 return_type = Some(crate::parser::parse_type_annotation(
118 part.into_inner().next().unwrap(),
119 )?);
120 }
121 Rule::expression => {
122 body_expr = Some(super::parse_expression(part)?);
124 }
125 Rule::function_body => {
126 body_stmts = crate::parser::statements::parse_statements(part.into_inner())?;
128 }
129 _ => {}
130 }
131 }
132
133 let body = if let Some(expr) = body_expr {
135 vec![Statement::Return(Some(expr), Span::DUMMY)]
136 } else {
137 body_stmts
138 };
139
140 Ok(Expr::FunctionExpr {
141 params,
142 return_type,
143 body,
144 span,
145 })
146}
147
148pub fn parse_regular_function_expr(pair: Pair<Rule>) -> Result<Expr> {
150 let span = pair_span(&pair);
151 let inner_pairs: Vec<_> = if pair.as_rule() == Rule::function_expr {
152 pair.into_inner().collect()
153 } else {
154 vec![pair]
155 };
156 let mut params = vec![];
157 let mut return_type: Option<TypeAnnotation> = None;
158 let mut body = vec![];
159
160 for part in inner_pairs {
164 match part.as_rule() {
165 Rule::function_params => {
166 for param_pair in part.into_inner() {
168 if param_pair.as_rule() == Rule::function_param {
169 params.push(crate::parser::functions::parse_function_param(param_pair)?);
170 }
171 }
172 }
173 Rule::return_type => {
174 return_type = Some(crate::parser::parse_type_annotation(
175 part.into_inner().next().unwrap(),
176 )?);
177 }
178 Rule::function_body => {
179 for stmt_pair in part.into_inner() {
181 if stmt_pair.as_rule() == Rule::statement {
182 body.push(crate::parser::statements::parse_statement(stmt_pair)?);
183 }
184 }
185 }
186 _ => {}
187 }
188 }
189
190 Ok(Expr::FunctionExpr {
191 params,
192 return_type,
193 body,
194 span,
195 })
196}
197
198pub fn parse_arg_list(pair: Pair<Rule>) -> Result<(Vec<Expr>, Vec<(String, Expr)>)> {
201 let mut positional_args = Vec::new();
202 let mut named_args = Vec::new();
203
204 if let Some(arg_list) = pair.into_inner().next() {
205 for argument in arg_list.into_inner() {
206 match argument.as_rule() {
207 Rule::argument => {
208 let inner = argument.into_inner().next().unwrap();
210 match inner.as_rule() {
211 Rule::named_arg => {
212 let mut parts = inner.into_inner();
213 let name = parts.next().unwrap().as_str().to_string();
214 let value = super::parse_expression(parts.next().unwrap())?;
215 named_args.push((name, value));
216 }
217 _ => {
218 positional_args.push(super::parse_expression(inner)?);
220 }
221 }
222 }
223 Rule::named_arg => {
224 let mut parts = argument.into_inner();
225 let name = parts.next().unwrap().as_str().to_string();
226 let value = super::parse_expression(parts.next().unwrap())?;
227 named_args.push((name, value));
228 }
229 _ => {
230 positional_args.push(super::parse_expression(argument)?);
232 }
233 }
234 }
235 }
236
237 Ok((positional_args, named_args))
238}