1use super::position::{Located, Position};
2use crate::lang::{ast::*, tokens::Token};
3use std::{error::Error, fmt::Display, iter::Peekable, vec::IntoIter};
4
5pub type Parser = Peekable<IntoIter<Located<Token>>>;
6pub trait Parsable
7where
8 Self: Sized,
9{
10 fn parse(parser: &mut Parser) -> Result<Located<Self>, Located<ParseError>>;
11}
12#[derive(Debug, Clone, PartialEq)]
13pub enum ParseError {
14 UnexpectedEOF,
15 UnexpectedToken(Token),
16 ExpectedToken { expected: Token, got: Token },
17 ExpectedIdentNotPath,
18 MultipleParams,
19 NoExprs,
20 MultipleExprs,
21}
22impl Display for ParseError {
23 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24 match self {
25 ParseError::UnexpectedEOF => write!(f, "unexpected end of file"),
26 ParseError::UnexpectedToken(token) => write!(f, "unexpected {}", token.name()),
27 ParseError::ExpectedToken { expected, got } => {
28 write!(f, "expected {}, got {}", expected.name(), got.name())
29 }
30 ParseError::ExpectedIdentNotPath => write!(
31 f,
32 "expected {} not a path",
33 Token::Ident(Default::default()).name()
34 ),
35 ParseError::MultipleParams => write!(f, "multiple parameters not allowed for let-else"),
36 ParseError::NoExprs => write!(f, "expected one expression for let-else"),
37 ParseError::MultipleExprs => write!(f, "multiple expressions not allowed for let-else"),
38 }
39 }
40}
41impl Error for ParseError {}
42
43macro_rules! expect {
44 ($parser:ident) => {{
45 let Some(loc_token) = $parser.next() else {
46 return Err(Located::new(ParseError::UnexpectedEOF, Position::default()));
47 };
48 loc_token
49 }};
50}
51macro_rules! expect_token {
52 ($parser:ident : $expect:ident) => {{
53 let Located {
54 value: token,
55 pos: token_pos,
56 } = expect!($parser);
57 if token != Token::$expect {
58 return Err(Located::new(
59 ParseError::ExpectedToken {
60 expected: Token::$expect,
61 got: token,
62 },
63 token_pos,
64 ));
65 }
66 token_pos
67 }};
68}
69macro_rules! if_token {
70 ($parser:ident : $token:ident : _ => $body:block $(else $else:block)?) => {{
71 if matches!(
72 $parser.peek(),
73 Some(Located {
74 value: Token::$token(_),
75 pos: _
76 })
77 ) {
78 $parser.next();
79 $body
80 } $(else $else)?
81 }};
82 ($parser:ident : $token:ident : $ident:ident $pos:ident => $body:block $(else $else:block)?) => {{
83 if matches!(
84 $parser.peek(),
85 Some(Located {
86 value: Token::$token(_),
87 pos: _
88 })
89 ) {
90 let Located {
91 value: Token::$token($ident),
92 pos: $pos,
93 } = $parser.next().unwrap() else {
94 panic!();
95 };
96 $body
97 } $(else $else)?
98 }};
99 ($parser:ident : $token:ident $pos:pat => $body:block $(else $else:block)?) => {{
100 if matches!(
101 $parser.peek(),
102 Some(Located {
103 value: Token::$token,
104 pos: $pos
105 })
106 ) $body $(else $else)?
107 }};
108 ($parser:ident : $token:ident => $body:block $(else $else:block)?) => {{
109 if matches!(
110 $parser.peek(),
111 Some(Located {
112 value: Token::$token,
113 pos: _
114 })
115 ) {
116 $parser.next();
117 $body
118 } $(else $else)?
119 }};
120}
121macro_rules! skip_token {
122 ($parser:ident : $token:ident) => {{
123 if matches!(
124 $parser.peek(),
125 Some(Located {
126 value: Token::$token,
127 pos: _
128 })
129 ) {
130 $parser.next();
131 }
132 }};
133}
134macro_rules! while_match {
135 ($parser:ident : $token:ident $pos:pat => $body:block) => {{
136 while matches!(
137 $parser.peek(),
138 Some(Located {
139 value: Token::$token,
140 pos: $pos
141 })
142 ) $body
143 }};
144 ($parser:ident : $token:ident $body:block) => {{
145 while matches!(
146 $parser.peek(),
147 Some(Located {
148 value: Token::$token,
149 pos: _
150 })
151 ) {
152 $parser.next();
153 $body
154 }
155 }};
156}
157macro_rules! until_match {
158 ($parser:ident : $token:ident $body:block) => {{
159 while let Some(Located {
160 value: token,
161 pos: _,
162 }) = $parser.peek()
163 {
164 if token == &Token::$token {
165 break;
166 }
167 $body
168 }
169 expect_token!($parser: $token)
170 }};
171}
172
173impl Parsable for Chunk {
174 fn parse(parser: &mut Parser) -> Result<Located<Self>, Located<ParseError>> {
175 let mut stats = vec![];
176 let mut pos = Position::default();
177 while parser.peek().is_some() {
178 let stat = Statement::parse(parser)?;
179 pos.extend(&stat.pos);
180 stats.push(stat);
181 }
182 Ok(Located::new(Self(stats), pos))
183 }
184}
185impl Parsable for Block {
186 fn parse(parser: &mut Parser) -> Result<Located<Self>, Located<ParseError>> {
187 let mut pos = expect_token!(parser: BraceLeft);
188 let mut stats = vec![];
189 let end_pos = until_match!(parser: BraceRight {
190 let stat = Statement::parse(parser)?;
191 pos.extend(&stat.pos);
192 stats.push(stat);
193 });
194 pos.extend(&end_pos);
195 Ok(Located::new(Self(stats), pos))
196 }
197}
198impl Statement {
199 pub fn parse_let(parser: &mut Parser) -> Result<Located<Self>, Located<ParseError>> {
200 let Located { value: _, mut pos } = parser.next().unwrap();
201 if_token!(parser: Fn _ => {
202 return Self::parse_fn(parser, true);
203 });
204 let mut params = vec![];
205 let mut exprs = vec![];
206 let ident = Parameter::parse(parser)?;
207 pos.extend(&ident.pos);
208 params.push(ident);
209 while_match!(parser: Comma {
210 let ident = Path::ident(parser)?;
211 pos.extend(&ident.pos);
212 params.push(Parameter::parse(parser)?);
213 });
214 if_token!(parser: Equal => {
215 let expr = Expression::parse(parser)?;
216 pos.extend(&expr.pos);
217 exprs.push(expr);
218 while_match!(parser: Comma {
219 let expr = Expression::parse(parser)?;
220 pos.extend(&expr.pos);
221 exprs.push(expr);
222 });
223 });
224 if_token!(parser: Else => {
225 if params.len() > 1 {
226 return Err(Located::new(ParseError::MultipleParams, pos))
227 }
228 if exprs.is_empty() {
229 return Err(Located::new(ParseError::NoExprs, pos))
230 }
231 if exprs.len() > 1 {
232 return Err(Located::new(ParseError::MultipleExprs, pos))
233 }
234 let else_case = Block::parse(parser)?;
235 pos.extend(&else_case.pos);
236 Ok(Located::new(Self::LetElse { param: params.remove(0), expr: exprs.remove(0), else_case }, pos))
237 } else {
238 Ok(Located::new(Self::LetBinding { params, exprs }, pos))
239 })
240 }
241 pub fn parse_fn(
242 parser: &mut Parser,
243 local: bool,
244 ) -> Result<Located<Self>, Located<ParseError>> {
245 let Located { value: _, mut pos } = parser.next().unwrap();
246 let path = Path::parse(parser)?;
247 let mut params = vec![];
248 let var_args = None;
249 expect_token!(parser: ParanLeft);
250 until_match!(parser: ParanRight {
251 params.push(Parameter::parse(parser)?);
252 skip_token!(parser: Comma);
253 });
254 let body = Block::parse(parser)?;
255 pos.extend(&body.pos);
256 if local {
257 let Located {
258 value: path,
259 pos: path_pos,
260 } = path;
261 if let Path::Ident(ident) = path {
262 Ok(Located::new(
263 Self::LetFn {
264 ident: Located::new(ident, path_pos),
265 params,
266 var_args,
267 body,
268 },
269 pos,
270 ))
271 } else {
272 Err(Located::new(ParseError::ExpectedIdentNotPath, path_pos))
273 }
274 } else {
275 Ok(Located::new(
276 Self::Fn {
277 path,
278 params,
279 var_args,
280 body,
281 },
282 pos,
283 ))
284 }
285 }
286 pub fn parse_if(parser: &mut Parser) -> Result<Located<Self>, Located<ParseError>> {
287 let Located { value: _, mut pos } = parser.next().unwrap();
288 if_token!(parser: Let => {
289 let param = Parameter::parse(parser)?;
290 expect_token!(parser: Equal);
291 let expr = Expression::parse(parser)?;
292 let case = Block::parse(parser)?;
293 pos.extend(&case.pos);
294 let mut else_case = None;
295 if_token!(parser: Else => {
296 else_case = Some(
297 if let Some(Located {
298 value: Token::If,
299 pos: _,
300 }) = parser.peek()
301 {
302 let stat = Self::parse_if(parser)?;
303 pos.extend(&stat.pos);
304 let pos = stat.pos.clone();
305 Located::new(Block(vec![stat]), pos)
306 } else {
307 let block = Block::parse(parser)?;
308 pos.extend(&block.pos);
309 block
310 },
311 );
312 });
313 Ok(Located::new(
314 Self::IfLet {
315 param,
316 expr,
317 case,
318 else_case,
319 },
320 pos,
321 ))
322 } else {
323 let cond = Expression::parse(parser)?;
324 let case = Block::parse(parser)?;
325 pos.extend(&case.pos);
326 let mut else_case = None;
327 if_token!(parser: Else => {
328 else_case = Some(
329 if let Some(Located {
330 value: Token::If,
331 pos: _,
332 }) = parser.peek()
333 {
334 let stat = Self::parse_if(parser)?;
335 pos.extend(&stat.pos);
336 let pos = stat.pos.clone();
337 Located::new(Block(vec![stat]), pos)
338 } else {
339 let block = Block::parse(parser)?;
340 pos.extend(&block.pos);
341 block
342 },
343 );
344 });
345 Ok(Located::new(
346 Self::If {
347 cond,
348 case,
349 else_case,
350 },
351 pos,
352 ))
353 })
354 }
355 pub fn parse_match(parser: &mut Parser) -> Result<Located<Self>, Located<ParseError>> {
356 let Located { value: _, mut pos } = parser.next().unwrap();
357 let expr = Expression::parse(parser)?;
358 let mut cases = vec![];
359 expect_token!(parser: BraceLeft);
360 let end_pos = until_match!(parser: BraceRight {
361 let pattern = Pattern::parse(parser)?;
362 expect_token!(parser: EqualArrow);
363 let body = Block::parse(parser)?;
364 skip_token!(parser: Comma);
365 cases.push((pattern, body));
366 });
367 pos.extend(&end_pos);
368 Ok(Located::new(Self::Match { expr, cases }, pos))
369 }
370 pub fn parse_while(parser: &mut Parser) -> Result<Located<Self>, Located<ParseError>> {
371 let Located { value: _, mut pos } = parser.next().unwrap();
372 if_token!(parser: Let => {
373 let param = Parameter::parse(parser)?;
374 expect_token!(parser: Equal);
375 let expr = Expression::parse(parser)?;
376 let body = Block::parse(parser)?;
377 pos.extend(&body.pos);
378 Ok(Located::new(Self::WhileLet { param, expr, body }, pos))
379 } else {
380 let cond = Expression::parse(parser)?;
381 let body = Block::parse(parser)?;
382 pos.extend(&body.pos);
383 Ok(Located::new(Self::While { cond, body }, pos))
384 })
385 }
386 pub fn parse_for(parser: &mut Parser) -> Result<Located<Self>, Located<ParseError>> {
387 let Located { value: _, mut pos } = parser.next().unwrap();
388 let ident = Path::ident(parser)?;
389 expect_token!(parser: In);
390 let iter = Expression::parse(parser)?;
391 let body = Block::parse(parser)?;
392 pos.extend(&body.pos);
393 Ok(Located::new(Self::For { ident, iter, body }, pos))
394 }
395}
396impl Parsable for Statement {
397 fn parse(parser: &mut Parser) -> Result<Located<Self>, Located<ParseError>> {
398 let Some(Located { value: token, pos }) = parser.peek() else {
399 return Err(Located::new(ParseError::UnexpectedEOF, Position::default()));
400 };
401 match token {
402 Token::BraceLeft => Ok(Block::parse(parser)?.map(Self::Block)),
403 Token::Let => Self::parse_let(parser),
404 Token::Fn => Self::parse_fn(parser, false),
405 Token::If => Self::parse_if(parser),
406 Token::Match => Self::parse_match(parser),
407 Token::While => Self::parse_while(parser),
408 Token::For => Self::parse_for(parser),
409 Token::Break => {
410 let Located { value: _, pos } = parser.next().unwrap();
411 Ok(Located::new(Self::Break, pos))
412 }
413 Token::Continue => {
414 let Located { value: _, pos } = parser.next().unwrap();
415 Ok(Located::new(Self::Continue, pos))
416 }
417 Token::Ident(_) => {
418 let path = Path::parse(parser)?;
419 let mut pos = path.pos.clone();
420 let Located {
421 value: token,
422 pos: token_pos,
423 } = expect!(parser);
424 match token {
425 Token::Comma => {
426 let mut paths = vec![path];
427 let path = Path::parse(parser)?;
428 paths.push(path);
429 while_match!(parser: Comma {
430 paths.push(Path::parse(parser)?);
431 });
432 expect_token!(parser: Equal);
433 let mut exprs = vec![];
434 let expr = Expression::parse(parser)?;
435 exprs.push(expr);
436 while_match!(parser: Comma {
437 let expr = Expression::parse(parser)?;
438 pos.extend(&expr.pos);
439 exprs.push(expr);
440 });
441 Ok(Located::new(Self::Assign { paths, exprs }, pos))
442 }
443 Token::Equal => {
444 let mut exprs = vec![];
445 let expr = Expression::parse(parser)?;
446 exprs.push(expr);
447 while_match!(parser: Comma {
448 exprs.push(Expression::parse(parser)?);
449 });
450 Ok(Located::new(
451 Self::Assign {
452 paths: vec![path],
453 exprs,
454 },
455 pos,
456 ))
457 }
458 token
459 if matches!(
460 &token,
461 Token::PlusEqual
462 | Token::MinusEqual
463 | Token::StarEqual
464 | Token::SlashEqual
465 | Token::PercentEqual
466 | Token::ExponentEqual
467 ) =>
468 {
469 let op = AssignOperator::try_from(&token).expect("should transform");
470 let expr = Expression::parse(parser)?;
471 Ok(Located::new(Self::AssignOperation { op, path, expr }, pos))
472 }
473 Token::ParanLeft => {
474 let mut args = vec![];
475 let end_pos = until_match!(parser: ParanRight {
476 args.push(Expression::parse(parser)?);
477 skip_token!(parser: Comma);
478 });
479 pos.extend(&end_pos);
480 Ok(Located::new(Self::Call { path, args }, pos))
481 }
482 Token::String(string) => {
483 pos.extend(&token_pos);
484 Ok(Located::new(
485 Self::Call {
486 path,
487 args: vec![Located::new(
488 Expression::Atom(Atom::String(string)),
489 token_pos,
490 )],
491 },
492 pos,
493 ))
494 }
495 Token::Colon => {
496 let field = Path::ident(parser)?;
497 expect_token!(parser: ParanLeft);
498 let mut args = vec![];
499 let end_pos = until_match!(parser: ParanRight {
500 args.push(Expression::parse(parser)?);
501 skip_token!(parser: Comma);
502 });
503 pos.extend(&end_pos);
504 Ok(Located::new(
505 Self::SelfCall {
506 head: path,
507 field,
508 args,
509 },
510 pos,
511 ))
512 }
513 token => Err(Located::new(ParseError::UnexpectedToken(token), pos)),
514 }
515 }
516 Token::Return => {
517 let Located { value: _, mut pos } = parser.next().unwrap();
518 let expr = Expression::parse(parser)?;
519 pos.extend(&expr.pos);
520 Ok(Located::new(Self::Return(Some(expr)), pos))
521 }
522 _ => Err(Located::new(
523 ParseError::UnexpectedToken(token.clone()),
524 pos.clone(),
525 )),
526 }
527 }
528}
529impl Parsable for Pattern {
530 fn parse(parser: &mut Parser) -> Result<Located<Self>, Located<ParseError>> {
531 let pattern = if_token!(parser: Ident: ident pos => {
532 Located::new(Self::Ident(ident), pos)
533 } else {
534 Atom::parse(parser)?.map(Self::Atom)
535 });
536 if_token!(parser: If => {
537 let cond = Expression::parse(parser)?;
538 let mut pos = pattern.pos.clone();
539 pos.extend(&cond.pos);
540 Ok(Located::new(Self::Guard { pattern: Box::new(pattern), cond }, pos))
541 } else {
542 Ok(pattern)
543 })
544 }
545}
546impl Parsable for Expression {
547 fn parse(parser: &mut Parser) -> Result<Located<Self>, Located<ParseError>> {
548 Self::binary(parser, 0)
549 }
550}
551impl Expression {
552 pub fn binary(parser: &mut Parser, layer: usize) -> Result<Located<Self>, Located<ParseError>> {
553 let Some(ops) = BinaryOperator::layer(layer) else {
554 return Self::unary(parser, 0);
555 };
556 let mut left = Self::binary(parser, layer + 1)?;
557 while let Some(Located {
558 value: token,
559 pos: _,
560 }) = parser.peek()
561 {
562 let Ok(op) = BinaryOperator::try_from(token) else {
563 break;
564 };
565 if !ops.contains(&op) {
566 break;
567 }
568 parser.next();
569 let right = Self::binary(parser, layer + 1)?;
570 let mut pos = left.pos.clone();
571 pos.extend(&right.pos);
572 left = Located::new(
573 Self::Binary {
574 op,
575 left: Box::new(left),
576 right: Box::new(right),
577 },
578 pos,
579 );
580 }
581 Ok(left)
582 }
583 pub fn unary(parser: &mut Parser, layer: usize) -> Result<Located<Self>, Located<ParseError>> {
584 let Some(ops) = UnaryOperator::layer(layer) else {
585 return Self::call(parser);
586 };
587 if let Some(Located {
588 value: token,
589 pos: _,
590 }) = parser.peek()
591 {
592 if let Ok(op) = UnaryOperator::try_from(token) {
593 if ops.contains(&op) {
594 let Located { value: _, mut pos } = parser.next().unwrap();
595 let right = Self::unary(parser, layer)?;
596 pos.extend(&right.pos);
597 return Ok(Located::new(
598 Self::Unary {
599 op,
600 right: Box::new(right),
601 },
602 pos,
603 ));
604 }
605 }
606 }
607 Self::unary(parser, layer + 1)
608 }
609 pub fn call(parser: &mut Parser) -> Result<Located<Self>, Located<ParseError>> {
610 let mut head = Atom::parse(parser)?.map(Self::Atom);
611 while let Some(Located {
612 value: token,
613 pos: token_pos,
614 }) = parser.peek()
615 {
616 match token {
617 Token::ParanLeft => {
618 parser.next();
619 let mut pos = head.pos.clone();
620 let mut args = vec![];
621 let end_pos = until_match!(parser: ParanRight {
622 args.push(Expression::parse(parser)?);
623 skip_token!(parser: Comma);
624 });
625 pos.extend(&end_pos);
626 head = Located::new(
627 Self::Call {
628 head: Box::new(head),
629 args,
630 },
631 pos,
632 );
633 }
634 Token::String(string) => {
635 let mut pos = head.pos.clone();
636 pos.extend(token_pos);
637 let token_pos = token_pos.clone();
638 let string = string.clone();
639 parser.next();
640 return Ok(Located::new(
641 Self::Call {
642 head: Box::new(head),
643 args: vec![Located::new(
644 Expression::Atom(Atom::String(string)),
645 token_pos,
646 )],
647 },
648 pos,
649 ));
650 }
651 Token::Colon => {
652 parser.next().unwrap();
653 let mut pos = head.pos.clone();
654 let field = Path::ident(parser)?;
655 expect_token!(parser: ParanLeft);
656 let mut args = vec![];
657 let end_pos = until_match!(parser: ParanRight {
658 args.push(Expression::parse(parser)?);
659 skip_token!(parser: Comma)
660 });
661 pos.extend(&end_pos);
662 head = Located::new(
663 Self::SelfCall {
664 head: Box::new(head),
665 field,
666 args,
667 },
668 pos,
669 );
670 }
671 Token::Dot => {
672 parser.next().unwrap();
673 let mut pos = head.pos.clone();
674 let field = Path::ident(parser)?;
675 pos.extend(&field.pos);
676 head = Located::new(
677 Self::Field {
678 head: Box::new(head),
679 field,
680 },
681 pos,
682 );
683 }
684 Token::BracketLeft => {
685 parser.next();
686 let index = Expression::parse(parser)?;
687 let end_pos = expect_token!(parser: BracketRight);
688 let mut pos = head.pos.clone();
689 pos.extend(&end_pos);
690 head = Located::new(
691 Self::Index {
692 head: Box::new(head),
693 index: Box::new(index),
694 },
695 pos,
696 )
697 }
698 _ => break,
699 }
700 }
701 Ok(head)
702 }
703 pub fn atom(parser: &mut Parser) -> Result<Located<Self>, Located<ParseError>> {
704 Ok(Atom::parse(parser)?.map(Self::Atom))
705 }
706}
707impl Parsable for Path {
708 fn parse(parser: &mut Parser) -> Result<Located<Self>, Located<ParseError>> {
709 let mut head = Self::ident(parser)?.map(Self::Ident);
710 while let Some(Located {
711 value: token,
712 pos: _,
713 }) = parser.peek()
714 {
715 match token {
716 Token::Dot => {
717 parser.next();
718 let field = Self::ident(parser)?;
719 let mut pos = head.pos.clone();
720 pos.extend(&field.pos);
721 head = Located::new(
722 Self::Field {
723 head: Box::new(head),
724 field,
725 },
726 pos,
727 )
728 }
729 Token::BracketLeft => {
730 parser.next();
731 let index = Expression::parse(parser)?;
732 let end_pos = expect_token!(parser: BracketRight);
733 let mut pos = head.pos.clone();
734 pos.extend(&end_pos);
735 head = Located::new(
736 Self::Index {
737 head: Box::new(head),
738 index: Box::new(index),
739 },
740 pos,
741 )
742 }
743 _ => break,
744 }
745 }
746 Ok(head)
747 }
748}
749impl Path {
750 pub fn ident(parser: &mut Parser) -> Result<Located<String>, Located<ParseError>> {
751 let Located { value: token, pos } = expect!(parser);
752 if let Token::Ident(ident) = token {
753 Ok(Located::new(ident, pos))
754 } else {
755 Err(Located::new(
756 ParseError::ExpectedToken {
757 expected: Token::Ident(Default::default()),
758 got: token,
759 },
760 pos,
761 ))
762 }
763 }
764}
765impl Parsable for Atom {
766 fn parse(parser: &mut Parser) -> Result<Located<Self>, Located<ParseError>> {
767 if let Some(Located {
768 value: Token::Ident(_),
769 pos: _,
770 }) = parser.peek()
771 {
772 return Ok(Path::parse(parser)?.map(Self::Path));
773 }
774 let Located {
775 value: token,
776 mut pos,
777 } = expect!(parser);
778 match token {
779 Token::Null => Ok(Located::new(Self::Null, pos)),
780 Token::Int(v) => Ok(Located::new(Self::Int(v), pos)),
781 Token::Float(v) => Ok(Located::new(Self::Float(v), pos)),
782 Token::Bool(v) => Ok(Located::new(Self::Bool(v), pos)),
783 Token::Char(v) => Ok(Located::new(Self::Char(v), pos)),
784 Token::String(v) => Ok(Located::new(Self::String(v), pos)),
785 Token::ParanLeft => {
786 let expr = Expression::parse(parser)?;
787 let end_pos = expect_token!(parser: ParanRight);
788 pos.extend(&end_pos);
789 Ok(Located::new(Self::Expression(Box::new(expr)), pos))
790 }
791 Token::BracketLeft => {
792 let mut exprs = vec![];
793 let end_pos = until_match!(parser: BracketRight {
794 exprs.push(Expression::parse(parser)?);
795 skip_token!(parser: Comma)
796 });
797 pos.extend(&end_pos);
798 Ok(Located::new(Self::Vector(exprs), pos))
799 }
800 Token::BraceLeft => {
801 let mut pairs = vec![];
802 let end_pos = until_match!(parser: BraceRight {
803 let key = Path::ident(parser)?;
804 expect_token!(parser: Equal);
805 let expr = Expression::parse(parser)?;
806 pairs.push((key, expr));
807 skip_token!(parser: Comma);
808 });
809 pos.extend(&end_pos);
810 Ok(Located::new(Self::Object(pairs), pos))
811 }
812 Token::If => {
813 let cond = Expression::parse(parser)?;
814 let case = Expression::parse(parser)?;
815 expect_token!(parser: Else);
816 let else_case = Expression::parse(parser)?;
817 pos.extend(&else_case.pos);
818 Ok(Located::new(
819 Self::If {
820 cond: Box::new(cond),
821 case: Box::new(case),
822 else_case: Box::new(else_case),
823 },
824 pos,
825 ))
826 }
827 Token::Fn => {
828 let mut params = vec![];
829 let var_args = None;
830 expect_token!(parser: ParanLeft);
831 until_match!(parser: ParanRight {
832 params.push(Parameter::parse(parser)?);
833 skip_token!(parser: Comma);
834 });
835 let body = Block::parse(parser)?;
836 pos.extend(&body.pos);
837 Ok(Located::new(
838 Self::Fn {
839 params,
840 var_args,
841 body,
842 },
843 pos,
844 ))
845 }
846 token => Err(Located::new(ParseError::UnexpectedToken(token), pos)),
847 }
848 }
849}
850impl Parsable for Parameter {
851 fn parse(parser: &mut Parser) -> Result<Located<Self>, Located<ParseError>> {
852 if let Some(Located {
853 value: Token::Ident(_),
854 pos: _,
855 }) = parser.peek()
856 {
857 return Ok(Path::ident(parser)?.map(Self::Ident));
858 }
859 let Located {
860 value: token,
861 mut pos,
862 } = expect!(parser);
863 match token {
864 Token::BraceLeft => {
865 let mut fields = vec![];
866 let end_pos = until_match!(parser: BraceRight {
867 let field = Path::ident(parser)?;
868 fields.push(field);
869 skip_token!(parser: Comma);
870 });
871 pos.extend(&end_pos);
872 Ok(Located::new(Self::Object(fields), pos))
873 }
874 Token::BracketLeft => {
875 let mut fields = vec![];
876 let end_pos = until_match!(parser: BracketRight {
877 let field = Path::ident(parser)?;
878 fields.push(field);
879 skip_token!(parser: Comma);
880 });
881 pos.extend(&end_pos);
882 Ok(Located::new(Self::Vector(fields), pos))
883 }
884 token => Err(Located::new(ParseError::UnexpectedToken(token), pos)),
885 }
886 }
887}