1use crate::{
2 ast::{ExprId, nodes::ExpressionKind},
3 lexer::tokentypes::TokenType,
4 parser::parser_logic::Parser,
5 utils::errors::Error,
6};
7
8impl Parser {
9 pub fn parse_primary(&mut self) -> Result<ExprId, Error> {
36 #[cfg(feature = "debug")]
37 log::debug!("current index: {:?}", self.current);
38 #[cfg(feature = "debug")]
39 log::debug!("current token: {:?}", self.peek());
40
41 let start = self.peek_span();
42
43 if self.match_type(&[TokenType::Identifier(String::new())]) {
45 #[cfg(feature = "debug")]
46 log::debug!("found identifier");
47 let ident_span = self.previous_span();
48
49 if let TokenType::Identifier(first) = self.previous() {
50 let mut path = vec![first];
52 while self.match_type(&[TokenType::ColonColon]) {
53 if !self.match_type(&[TokenType::Identifier(String::new())]) {
54 return Err(self.err("expected identifier after `::`", self.peek_span()));
55 }
56 if let TokenType::Identifier(seg) = self.previous() {
57 path.push(seg);
58 }
59 }
60 let path_span = start.join(self.previous_span());
61
62 if self.match_type(&[TokenType::LeftParen]) {
64 #[cfg(feature = "debug")]
65 log::debug!("found function call");
66 let mut args = Vec::new();
67 while self.match_type(&[TokenType::Newline]) {}
68 if !(std::mem::discriminant(&self.peek())
69 == std::mem::discriminant(&TokenType::RightParen))
70 {
71 loop {
72 args.push(self.parse_expression()?);
73 while self.match_type(&[TokenType::Newline]) {}
74 if !self.match_type(&[TokenType::Comma]) {
75 break;
76 }
77 while self.match_type(&[TokenType::Newline]) {}
78 }
79 }
80 self.match_type(&[TokenType::RightParen]);
81 let span = start.join(self.previous_span());
82 #[cfg(feature = "debug")]
83 log::trace!(
84 "alloc Call expr: path={:?} args={} @ {:?}",
85 path,
86 args.len(),
87 span
88 );
89 let expr = self
90 .ast_arena
91 .alloc_expr(ExpressionKind::Call { path, args }, span);
92
93 return self.parse_postfix(expr, start);
94 }
95
96 if path.len() > 1 {
98 return Err(self.err(
99 format!("module path `{}` used as value", path.join("::")),
100 path_span,
101 ));
102 }
103 let name = path.pop().unwrap();
104
105 if self.record_names.contains(&name) && self.peek() == TokenType::LeftBrace {
107 return self.parse_struct_literal(name, start);
108 }
109
110 if self.tag_names.contains(&name) && self.peek() == TokenType::Dot {
112 self.advance();
113 let variant = match self.peek() {
114 TokenType::Identifier(v) => {
115 self.advance();
116 v
117 }
118 _ => {
119 return Err(
120 self.err("expected variant name after `.`", self.peek_span())
121 );
122 }
123 };
124 let span = start.join(self.previous_span());
125 #[cfg(feature = "debug")]
126 log::trace!(
127 "alloc EnumVariant expr: enum_name={:?} variant={:?} @ {:?}",
128 name,
129 variant,
130 span
131 );
132 let expr = self.ast_arena.alloc_expr(
133 ExpressionKind::EnumVariant {
134 enum_name: name,
135 variant,
136 },
137 span,
138 );
139 return self.parse_postfix(expr, start);
140 }
141
142 if self.match_type(&[TokenType::Assign]) {
144 #[cfg(feature = "debug")]
145 log::debug!("found variable assignment");
146 let value = self.parse_expression()?;
147 let value_id = self.ast_arena.exprs.get(value);
148 let span = start.join(value_id.span);
149 #[cfg(feature = "debug")]
150 log::trace!(
151 "alloc Assign expr: name={} value={:?} @ {:?}",
152 name,
153 value,
154 span
155 );
156 let expr = self
157 .ast_arena
158 .alloc_expr(ExpressionKind::Assign { name, value }, span);
159
160 return self.parse_postfix(expr, start);
161 }
162
163 if self.match_type(&[TokenType::LeftBracket]) {
165 #[cfg(feature = "debug")]
166 log::trace!(
167 "alloc Identifier(index target) expr: name={} @ {:?}",
168 name,
169 ident_span
170 );
171
172 let index = self.parse_expression()?;
173 self.match_type(&[TokenType::RightBracket]);
174 let after_index_span = self.previous_span();
175
176 let target = self
177 .ast_arena
178 .alloc_expr(ExpressionKind::Identifier(name.clone()), ident_span);
179
180 #[cfg(feature = "debug")]
181 log::trace!(
182 "alloc Index expr: target={:?} index={:?} @ {:?}",
183 target,
184 index,
185 self.ast_arena.exprs.get(target).span
186 );
187
188 let mut expr = self.ast_arena.alloc_expr(
189 ExpressionKind::Index { target, index },
190 start.join(after_index_span),
191 );
192
193 while self.peek() == TokenType::LeftBracket {
195 self.advance();
196 let next_index = self.parse_expression()?;
197 self.match_type(&[TokenType::RightBracket]);
198 let span = start.join(self.previous_span());
199
200 #[cfg(feature = "debug")]
201 log::trace!(
202 "alloc Index(chained) expr: target={:?} index={:?} @ {:?}",
203 expr,
204 next_index,
205 span
206 );
207
208 expr = self.ast_arena.alloc_expr(
209 ExpressionKind::Index {
210 target: expr,
211 index: next_index,
212 },
213 span,
214 );
215 }
216
217 if self.match_type(&[TokenType::LeftParen]) {
219 let mut args = Vec::new();
220 while self.match_type(&[TokenType::Newline]) {}
221 if self.peek() != TokenType::RightParen {
222 loop {
223 args.push(self.parse_expression()?);
224 while self.match_type(&[TokenType::Newline]) {}
225 if !self.match_type(&[TokenType::Comma]) {
226 break;
227 }
228 while self.match_type(&[TokenType::Newline]) {}
229 }
230 }
231 while self.match_type(&[TokenType::Newline]) {}
232 self.match_type(&[TokenType::RightParen]);
233 let span = start.join(self.previous_span());
234 #[cfg(feature = "debug")]
235 log::trace!(
236 "alloc CallExpr expr: callee={:?} args={} @ {:?}",
237 expr,
238 args.len(),
239 span
240 );
241
242 let call_expr = self
243 .ast_arena
244 .alloc_expr(ExpressionKind::CallExpr { callee: expr, args }, span);
245
246 return self.parse_postfix(call_expr, start);
247 }
248
249 if self.match_type(&[TokenType::Assign]) {
251 #[cfg(feature = "debug")]
252 log::debug!("found array item assignment");
253 let value = self.parse_expression()?;
254
255 let value_id = self.ast_arena.exprs.get(value);
256 let expr_id = self.ast_arena.exprs.get(expr);
257
258 let span = start.join(value_id.span);
259 if let ExpressionKind::Index { target, index } = expr_id.kind.clone() {
260 let expr = self.ast_arena.alloc_expr(
261 ExpressionKind::IndexAssign {
262 target,
263 index,
264 value,
265 },
266 span,
267 );
268
269 #[cfg(feature = "debug")]
270 log::trace!(
271 "alloc IndexAssign expr: target={:?} index={:?} value={:?} @ {:?}",
272 target,
273 index,
274 value,
275 span
276 );
277 return self.parse_postfix(expr, start);
278 }
279 }
280
281 return self.parse_postfix(expr, start);
282 }
283
284 #[cfg(feature = "debug")]
286 log::trace!("alloc Identifier expr: name={} @ {:?}", name, ident_span);
287
288 let expr = self
289 .ast_arena
290 .alloc_expr(ExpressionKind::Identifier(name), ident_span);
291
292 return self.parse_postfix(expr, start);
293 }
294 }
295 if self.peek() == TokenType::LeftBrace {
299 self.advance();
300 let mut entries = Vec::new();
301 while self.match_type(&[TokenType::Newline]) {}
302 while self.peek() != TokenType::RightBrace {
303 let key = self.parse_expression()?;
304 while self.match_type(&[TokenType::Newline]) {}
305 if !self.match_type(&[TokenType::Colon]) {
306 return Err(self.err("expected `:` after map key", self.peek_span()));
307 }
308 while self.match_type(&[TokenType::Newline]) {}
309 let value = self.parse_expression()?;
310 entries.push((key, value));
311 while self.match_type(&[TokenType::Newline]) {}
312 if self.peek() == TokenType::RightBrace {
313 break;
314 }
315 if !self.match_type(&[TokenType::Comma]) {
316 return Err(self.err("expected `,` between map entries", self.peek_span()));
317 }
318 while self.match_type(&[TokenType::Newline]) {}
319 }
320 self.match_type(&[TokenType::RightBrace]);
321 let span = start.join(self.previous_span());
322
323 #[cfg(feature = "debug")]
324 log::trace!(
325 "alloc MapLiteral expr: entries={} @ {:?}",
326 entries.len(),
327 span
328 );
329
330 let expr = self
331 .ast_arena
332 .alloc_expr(ExpressionKind::MapLiteral(entries), span);
333 return self.parse_postfix(expr, start);
334 }
335
336 if self.match_type(&[TokenType::LeftBrace]) {
338 let mut items = Vec::new();
339 while self.match_type(&[TokenType::Newline]) {}
340 while self.peek() != TokenType::RightBrace {
341 items.push(self.parse_expression()?);
342 while self.match_type(&[TokenType::Newline]) {}
343 if self.peek() == TokenType::RightBrace {
344 break;
345 }
346 if !self.match_type(&[TokenType::Comma]) {
347 return Err(self.err("expected `,` between set items", self.peek_span()));
348 }
349 while self.match_type(&[TokenType::Newline]) {}
350 }
351 self.match_type(&[TokenType::RightBrace]);
352 let span = start.join(self.previous_span());
353
354 #[cfg(feature = "debug")]
355 log::trace!("alloc SetLiteral expr: items={} @ {:?}", items.len(), span);
356
357 let expr = self
358 .ast_arena
359 .alloc_expr(ExpressionKind::SetLiteral(items), span);
360 return self.parse_postfix(expr, start);
361 }
362
363 if self.match_type(&[TokenType::LeftBracket]) {
365 let mut items = Vec::new();
366 while self.match_type(&[TokenType::Newline]) {}
367 while self.peek() != TokenType::RightBracket {
368 items.push(self.parse_expression()?);
369 while self.match_type(&[TokenType::Newline]) {}
370 if self.peek() == TokenType::RightBracket {
371 break;
372 }
373 if !self.match_type(&[TokenType::Comma]) {
374 return Err(self.err("expected `,` between array items", self.peek_span()));
375 }
376 while self.match_type(&[TokenType::Newline]) {}
377 }
378 self.match_type(&[TokenType::RightBracket]);
379 let span = start.join(self.previous_span());
380
381 #[cfg(feature = "debug")]
382 log::trace!(
383 "alloc ArrayLiteral expr: items={} @ {:?}",
384 items.len(),
385 span
386 );
387
388 let expr = self
389 .ast_arena
390 .alloc_expr(ExpressionKind::ArrayLiteral(items), span);
391 return self.parse_postfix(expr, start);
392 }
393
394 if self.match_type(&[TokenType::NumberLiteral(0)]) {
397 #[cfg(feature = "debug")]
398 log::debug!("found number <integer>");
399 let span = self.previous_span();
400 if let TokenType::NumberLiteral(n) = self.previous() {
401 if self.match_type(&[TokenType::As]) {
403 if self.match_type(&[TokenType::Int, TokenType::Byte, TokenType::Float]) {
405 match self.previous() {
406 TokenType::Int => {
407 #[cfg(feature = "debug")]
408 log::trace!(
409 "alloc Integer expr (from number, cast to int): {} @ {:?}",
410 n,
411 span
412 );
413
414 let int_expr =
415 self.ast_arena.alloc_expr(ExpressionKind::Integer(n), span);
416 return self.parse_postfix(int_expr, start);
417 }
418
419 TokenType::Float => {
420 #[cfg(feature = "debug")]
421 log::trace!(
422 "alloc Float expr (from number, cast to float): {} @ {:?}",
423 n as f64,
424 span
425 );
426 let int_expr = self
427 .ast_arena
428 .alloc_expr(ExpressionKind::Float(n as f64), span);
429 return self.parse_postfix(int_expr, start);
430 }
431
432 TokenType::Byte => {
433 #[cfg(feature = "debug")]
434 log::trace!(
435 "alloc Byte expr (from number, cast to byte): {} @ {:?}",
436 n as u8,
437 span
438 );
439 if !(0..=255).contains(&n) {
440 return Err(self
441 .err(format!("value {} is too large for byte", n), span));
442 }
443 let int_expr = self
444 .ast_arena
445 .alloc_expr(ExpressionKind::Byte(n as u8), span);
446 return self.parse_postfix(int_expr, start);
447 }
448
449 other => {
450 return Err(self.err(
451 format!("expected int/byte/float types found {:?}", other),
452 span,
453 ));
454 }
455 }
456 }
457 return Err(self.err("expected type after `as`", self.previous_span()));
458 }
459 #[cfg(feature = "debug")]
463 log::trace!(
464 "alloc Integer expr (plain number literal): {} @ {:?}",
465 n,
466 span
467 );
468 let expr = self.ast_arena.alloc_expr(ExpressionKind::Integer(n), span);
469 return self.parse_postfix(expr, start);
470 }
471 }
472
473 if self.match_type(&[TokenType::FloatLiteral(0.0)]) {
475 #[cfg(feature = "debug")]
476 log::debug!("found number <float>");
477 let span = self.previous_span();
478 if let TokenType::FloatLiteral(f) = self.previous() {
479 if self.match_type(&[TokenType::As]) {
481 if self.match_type(&[TokenType::Int, TokenType::Byte, TokenType::Float]) {
483 match self.previous() {
484 TokenType::Int => {
485 #[cfg(feature = "debug")]
486 log::trace!(
487 "alloc Integer expr (from float, cast to int): {} @ {:?}",
488 f as i64,
489 span
490 );
491 let float_expr = self
492 .ast_arena
493 .alloc_expr(ExpressionKind::Integer(f as i64), span);
494 return self.parse_postfix(float_expr, start);
495 }
496
497 TokenType::Float => {
498 #[cfg(feature = "debug")]
499 log::trace!(
500 "alloc Float expr (from float, cast to float): {} @ {:?}",
501 f,
502 span
503 );
504 let float_expr =
505 self.ast_arena.alloc_expr(ExpressionKind::Float(f), span);
506 return self.parse_postfix(float_expr, start);
507 }
508
509 TokenType::Byte => {
510 #[cfg(feature = "debug")]
511 log::trace!(
512 "alloc Byte expr (from float, cast to byte): {} @ {:?}",
513 f as u8,
514 span
515 );
516 if !(0.0..=255.0).contains(&f) {
517 return Err(self
518 .err(format!("value {} is too large for byte", f), span));
519 }
520 let float_expr = self
521 .ast_arena
522 .alloc_expr(ExpressionKind::Byte(f as u8), span);
523 return self.parse_postfix(float_expr, start);
524 }
525
526 other => {
527 return Err(self.err(
528 format!("expected int/byte/float types found {:?}", other),
529 span,
530 ));
531 }
532 }
533 }
534 return Err(self.err("expected type after `as`", span));
535 }
536 #[cfg(feature = "debug")]
540 log::trace!("alloc Float expr (plain float literal): {} @ {:?}", f, span);
541 let expr = self
542 .ast_arena
543 .alloc_expr(ExpressionKind::Float(f), self.previous_span());
544 return self.parse_postfix(expr, start);
545 }
546 }
547
548 if self.match_type(&[TokenType::ByteLiteral(0)]) {
550 #[cfg(feature = "debug")]
551 log::debug!("found number <byte>");
552 let span = self.previous_span();
553 if let TokenType::ByteLiteral(b) = self.previous() {
554 if self.match_type(&[TokenType::As]) {
556 if self.match_type(&[TokenType::Int, TokenType::Byte, TokenType::Float]) {
558 match self.previous() {
559 TokenType::Int => {
560 #[cfg(feature = "debug")]
561 log::trace!(
562 "alloc Integer expr (from byte, cast to int): {} @ {:?}",
563 b as i64,
564 span
565 );
566 let byte_expr = self
567 .ast_arena
568 .alloc_expr(ExpressionKind::Integer(b as i64), span);
569 return self.parse_postfix(byte_expr, start);
570 }
571
572 TokenType::Float => {
573 #[cfg(feature = "debug")]
574 log::trace!(
575 "alloc Float expr (from byte, cast to float): {} @ {:?}",
576 b as f64,
577 span
578 );
579 let byte_expr = self
580 .ast_arena
581 .alloc_expr(ExpressionKind::Float(b as f64), span);
582 return self.parse_postfix(byte_expr, start);
583 }
584
585 TokenType::Byte => {
586 #[cfg(feature = "debug")]
589 log::trace!(
590 "alloc Byte expr (from byte, cast to byte): {} @ {:?}",
591 b,
592 span
593 );
594 if !(0..=255).contains(&b) {
595 return Err(self
596 .err(format!("value {} is too large for byte", b), span));
597 }
598 let byte_expr =
599 self.ast_arena.alloc_expr(ExpressionKind::Byte(b), span);
600 return self.parse_postfix(byte_expr, start);
601 }
602
603 other => {
604 return Err(self.err(
605 format!("expected int/byte/float types found {:?}", other),
606 span,
607 ));
608 }
609 }
610 }
611 return Err(self.err("expected type after `as`", self.previous_span()));
612 }
613 #[cfg(feature = "debug")]
617 log::trace!("alloc Byte expr (plain byte literal): {} @ {:?}", b, span);
618 let expr = self.ast_arena.alloc_expr(ExpressionKind::Byte(b), span);
619 return self.parse_postfix(expr, start);
620 }
621 }
622 if self.match_type(&[TokenType::StringLiteral(String::new())]) {
626 #[cfg(feature = "debug")]
627 log::debug!("found string");
628 let span = self.previous_span();
629 if let TokenType::StringLiteral(s) = self.previous() {
630 #[cfg(feature = "debug")]
631 log::trace!("alloc String expr: {:?} @ {:?}", s, span);
632 let expr = self.ast_arena.alloc_expr(ExpressionKind::String(s), span);
633 return self.parse_postfix(expr, start);
634 }
635 }
636
637 if matches!(
639 self.tokens[self.current].token,
640 TokenType::CharacterLiteral(_)
641 ) {
642 self.advance();
643 #[cfg(feature = "debug")]
644 log::debug!("found character");
645 let span = self.previous_span();
646 if let TokenType::CharacterLiteral(c) = self.previous() {
647 #[cfg(feature = "debug")]
648 log::trace!("alloc Character expr: {:?} @ {:?}", c, span);
649 let expr = self
650 .ast_arena
651 .alloc_expr(ExpressionKind::Character(c), span);
652 return self.parse_postfix(expr, start);
653 }
654 }
655
656 if self.match_type(&[TokenType::BoolLiteral(false)]) {
658 let span = self.previous_span();
659 if let TokenType::BoolLiteral(b) = self.previous() {
660 let expr = self.ast_arena.alloc_expr(ExpressionKind::Bool(b), span);
661 #[cfg(feature = "debug")]
662 log::trace!("alloc Bool expr: {} @ {:?}", b, span);
663 return self.parse_postfix(expr, start);
664 }
665 }
666
667 if self.match_type(&[TokenType::Error]) {
669 let error_start = self.previous_span();
670 while self.match_type(&[TokenType::Newline]) {}
671 if !self.match_type(&[TokenType::LeftParen]) {
672 return Err(self.err("expected `(` after `error`", self.peek_span()));
673 }
674 while self.match_type(&[TokenType::Newline]) {}
675 let inner = self.parse_expression()?;
676 while self.match_type(&[TokenType::Newline]) {}
677 if !self.match_type(&[TokenType::RightParen]) {
678 return Err(self.err("expected `)` after error value", self.peek_span()));
679 }
680 let span = error_start.join(self.previous_span());
681 let expr = self
682 .ast_arena
683 .alloc_expr(ExpressionKind::ErrorLiteral(inner), span);
684 #[cfg(feature = "debug")]
685 log::trace!("alloc ErrorLiteral expr: inner={:?} @ {:?}", inner, span);
686 return self.parse_postfix(expr, start);
687 }
688
689 if self.match_type(&[TokenType::Ok]) {
692 let kw_span = self.previous_span();
693 while self.match_type(&[TokenType::Newline]) {}
694 if !self.match_type(&[TokenType::LeftParen]) {
695 return Err(self.err("expected `(` after `ok`", self.peek_span()));
696 }
697 while self.match_type(&[TokenType::Newline]) {}
698 let inner = self.parse_expression()?;
699 while self.match_type(&[TokenType::Newline]) {}
700 if !self.match_type(&[TokenType::RightParen]) {
701 return Err(self.err("expected `)` after ok value", self.peek_span()));
702 }
703 let span = kw_span.join(self.previous_span());
704 #[cfg(feature = "debug")]
705 log::trace!("alloc OkLiteral expr: inner={:?} @ {:?}", inner, span);
706 let ok_expr = self
707 .ast_arena
708 .alloc_expr(ExpressionKind::OkLiteral(inner), span);
709 return self.parse_postfix(ok_expr, start);
710 }
711
712 if self.match_type(&[TokenType::Err]) {
714 let kw_span = self.previous_span();
715 while self.match_type(&[TokenType::Newline]) {}
716 if !self.match_type(&[TokenType::LeftParen]) {
717 return Err(self.err("expected `(` after `err`", self.peek_span()));
718 }
719 while self.match_type(&[TokenType::Newline]) {}
720 let inner = self.parse_expression()?;
721 while self.match_type(&[TokenType::Newline]) {}
722 if !self.match_type(&[TokenType::RightParen]) {
723 return Err(self.err("expected `)` after err value", self.peek_span()));
724 }
725 let span = kw_span.join(self.previous_span());
726 #[cfg(feature = "debug")]
727 log::trace!("alloc ErrLiteral expr: inner={:?} @ {:?}", inner, span);
728 let err_expr = self
729 .ast_arena
730 .alloc_expr(ExpressionKind::ErrLiteral(inner), span);
731 return self.parse_postfix(err_expr, start);
732 }
733 if self.match_type(&[TokenType::Null]) {
737 let span = self.previous_span();
738 let expr = self.ast_arena.alloc_expr(ExpressionKind::Null, span);
739 #[cfg(feature = "debug")]
740 log::trace!("alloc Null expr @ {:?}", span);
741 return self.parse_postfix(expr, start);
742 }
743
744 if self.match_type(&[TokenType::LeftParen]) {
746 #[cfg(feature = "debug")]
747 log::debug!("found group start");
748 while self.match_type(&[TokenType::Newline]) {}
749 let first = self.parse_expression()?;
750
751 if self.match_type(&[TokenType::Comma]) {
752 let mut items = vec![first];
754 while self.peek() != TokenType::RightParen && self.peek() != TokenType::Eof {
755 while self.match_type(&[TokenType::Newline]) {}
756 items.push(self.parse_expression()?);
757 while self.match_type(&[TokenType::Newline]) {}
758 if self.peek() == TokenType::RightParen {
759 break;
760 }
761 if !self.match_type(&[TokenType::Comma]) {
762 return Err(self.err("expected , between tuple elements", self.peek_span()));
763 }
764 }
765 while self.match_type(&[TokenType::Newline]) {}
766 if !self.match_type(&[TokenType::RightParen]) {
767 return Err(self.err("expected ) after tuple elements", self.peek_span()));
768 }
769 let span = start.join(self.previous_span());
770 #[cfg(feature = "debug")]
771 log::trace!(
772 "alloc TupleLiteral expr: items={} @ {:?}",
773 items.len(),
774 span
775 );
776
777 let expr = self
778 .ast_arena
779 .alloc_expr(ExpressionKind::TupleLiteral(items), span);
780 return self.parse_postfix(expr, start);
781 }
782
783 while self.match_type(&[TokenType::Newline]) {}
785 self.match_type(&[TokenType::RightParen]);
786
787 let span = start.join(self.previous_span());
788 let expr = self
789 .ast_arena
790 .alloc_expr(ExpressionKind::Grouping(first), span);
791 #[cfg(feature = "debug")]
792 log::trace!("alloc Grouping expr: inner={:?} @ {:?}", first, span);
793 return self.parse_postfix(expr, start);
794 }
795
796 if self.match_type(&[TokenType::Fn]) {
798 let lambda_start = self.previous_span();
799 while self.match_type(&[TokenType::Newline]) {}
800 self.match_type(&[TokenType::LeftParen]);
801
802 let mut params: Vec<crate::ast::statements::Param> = Vec::new();
803 while self.match_type(&[TokenType::Newline]) {}
804 while !self.match_type(&[TokenType::RightParen]) {
805 let param_type = self.parse_param_type()?;
806 while self.match_type(&[TokenType::Newline]) {}
807 let param_name = match self.peek() {
808 TokenType::Identifier(n) => {
809 self.advance();
810 n
811 }
812 _ => return Err(self.err("expected parameter name", self.peek_span())),
813 };
814 params.push(crate::ast::statements::Param {
815 param_name,
816 param_type,
817 });
818 while self.match_type(&[TokenType::Newline]) {}
819 if !self.match_type(&[TokenType::Comma]) {
820 break;
821 }
822 }
823 while self.match_type(&[TokenType::Newline]) {}
824 self.match_type(&[TokenType::RightParen]);
825
826 while self.match_type(&[TokenType::Newline]) {}
827 let return_type = if self.match_type(&[TokenType::Arrow]) {
828 while self.match_type(&[TokenType::Newline]) {}
829 Some(self.parse_param_type()?)
830 } else {
831 None
832 };
833
834 while self.match_type(&[TokenType::Newline]) {}
835 let body = self.parse_block()?;
836 let span = lambda_start.join(self.previous_span());
837 #[cfg(feature = "debug")]
838 log::trace!(
839 "alloc Lambda expr: params={} return_type={:?} body_stmts={} @ {:?}",
840 params.len(),
841 return_type,
842 body.len(),
843 span
844 );
845 let expr = self.ast_arena.alloc_expr(
846 ExpressionKind::Lambda {
847 params,
848 return_type,
849 body,
850 },
851 span,
852 );
853 return self.parse_postfix(expr, start);
854 }
855
856 Err(self.err("expected expression", self.peek_span()))
858 }
859}