1use std::mem;
2
3use either::Either;
4
5use crate::{ast::*, Error, Lex, Location, Result, Span, Token, TokenKind};
6
7pub struct Parser<'src, Lexer: Lex<'src>> {
8 lexer: Lexer,
9 prev_tok: Token<'src>,
10 curr_tok: Token<'src>,
11 errors: Vec<Error<'src>>,
12}
13
14impl<'src, Lexer: Lex<'src>> Parser<'src, Lexer> {
15 pub fn new(lexer: Lexer) -> Self {
17 Self {
18 lexer,
19 prev_tok: Token::dummy(),
21 curr_tok: Token::dummy(),
22 errors: vec![],
23 }
24 }
25
26 pub fn parse(mut self) -> (Result<'src, Program<'src>>, Vec<Error<'src>>) {
35 if let Err(err) = self.next() {
36 return (Err(err), self.errors);
37 }
38
39 let program = match self.program() {
40 Ok(program) => program,
41 Err(err) => return (Err(err), self.errors),
42 };
43
44 if self.curr_tok.kind != TokenKind::Eof {
45 self.errors.push(Error::new(
46 format!("expected EOF, found `{}`", self.curr_tok.kind),
47 self.curr_tok.span,
48 self.lexer.source(),
49 ))
50 }
51
52 (Ok(program), self.errors)
53 }
54
55 fn next(&mut self) -> Result<'src, ()> {
57 mem::swap(&mut self.prev_tok, &mut self.curr_tok);
59 self.curr_tok = self.lexer.next_token()?;
61
62 Ok(())
63 }
64
65 fn expect(&mut self, kind: TokenKind) -> Result<'src, ()> {
67 if self.curr_tok.kind != kind {
68 return Err(Error::new_boxed(
69 format!("expected `{kind}`, found `{}`", self.curr_tok.kind),
70 self.curr_tok.span,
71 self.lexer.source(),
72 ));
73 }
74 self.next()?;
75 Ok(())
76 }
77
78 fn expect_ident(&mut self) -> Result<'src, Spanned<'src, &'src str>> {
80 match self.curr_tok.kind {
81 TokenKind::Ident(ident) => {
82 let ident = Spanned {
83 span: self.curr_tok.span,
84 inner: ident,
85 };
86 self.next()?;
87 Ok(ident)
88 }
89 _ => Err(Error::new_boxed(
90 format!("expected identifier, found `{}`", self.curr_tok.kind),
91 self.curr_tok.span,
92 self.lexer.source(),
93 )),
94 }
95 }
96
97 fn expect_recoverable(
99 &mut self,
100 kind: TokenKind,
101 message: impl Into<String>,
102 span: Span<'src>,
103 ) -> Result<'src, Span<'src>> {
104 let start_loc = self.curr_tok.span.start;
105 let end_loc = if self.curr_tok.kind != kind {
106 self.errors
107 .push(Error::new(message.into(), span, self.lexer.source()));
108 self.curr_tok.span.start
109 } else {
110 self.next()?;
111 self.prev_tok.span.end
112 };
113 Ok(start_loc.until(end_loc))
114 }
115
116 fn program(&mut self) -> Result<'src, Program<'src>> {
119 let start_loc = self.curr_tok.span.start;
120 let mut functions = vec![];
121 let mut globals = vec![];
122
123 while self.curr_tok.kind != TokenKind::Eof {
124 match self.curr_tok.kind {
125 TokenKind::Fn => functions.push(self.function_definition()?),
126 TokenKind::Let => globals.push(self.let_stmt()?),
127 _ => {
128 return Err(Error::new_boxed(
129 format!(
130 "expected either `fn` or `let`, found `{}`",
131 self.curr_tok.kind
132 ),
133 self.curr_tok.span,
134 self.lexer.source(),
135 ))
136 }
137 }
138 }
139
140 Ok(Program {
141 span: start_loc.until(self.prev_tok.span.end),
142 functions,
143 globals,
144 })
145 }
146
147 fn type_(&mut self) -> Result<'src, Spanned<'src, Type>> {
148 let start_loc = self.curr_tok.span.start;
149
150 let mut ptr_count = 0;
151 while matches!(self.curr_tok.kind, TokenKind::Star | TokenKind::Pow) {
152 ptr_count += match self.curr_tok.kind == TokenKind::Star {
153 true => 1,
154 false => 2,
155 };
156 self.next()?;
157 }
158
159 let type_ = match self.curr_tok.kind {
160 TokenKind::Ident("int") => Type::Int(ptr_count),
161 TokenKind::Ident("float") => Type::Float(ptr_count),
162 TokenKind::Ident("bool") => Type::Bool(ptr_count),
163 TokenKind::Ident("char") => Type::Char(ptr_count),
164 TokenKind::Ident(ident) => {
165 self.errors.push(Error::new(
166 format!("unknown type `{ident}`"),
167 self.curr_tok.span,
168 self.lexer.source(),
169 ));
170 Type::Unknown
171 }
172 TokenKind::LParen => {
173 self.next()?;
174 self.expect_recoverable(
175 TokenKind::RParen,
176 "missing closing parenthesis",
177 self.curr_tok.span,
178 )?;
179
180 if ptr_count > 0 {
181 self.errors.push(Error::new(
182 format!("illegal type `{}()`", "*".repeat(ptr_count)),
183 start_loc.until(self.prev_tok.span.end),
184 self.lexer.source(),
185 ))
186 }
187
188 return Ok(Spanned {
189 span: start_loc.until(self.prev_tok.span.end),
190 inner: Type::Unit,
191 });
192 }
193 invalid => {
194 return Err(Error::new_boxed(
195 format!("expected a type, found `{invalid}`"),
196 self.curr_tok.span,
197 self.lexer.source(),
198 ));
199 }
200 };
201 self.next()?;
202 Ok(Spanned {
203 span: start_loc.until(self.prev_tok.span.end),
204 inner: type_,
205 })
206 }
207
208 fn function_definition(&mut self) -> Result<'src, FunctionDefinition<'src>> {
209 let start_loc = self.curr_tok.span.start;
210
211 self.expect(TokenKind::Fn)?;
212 let name = self.expect_ident()?;
213 let l_paren = self.curr_tok.span;
214 self.expect(TokenKind::LParen)?;
215
216 let mut params = vec![];
217 if !matches!(self.curr_tok.kind, TokenKind::RParen | TokenKind::Eof) {
218 params.push(self.parameter()?);
219 while self.curr_tok.kind == TokenKind::Comma {
220 self.next()?;
221 if matches!(self.curr_tok.kind, TokenKind::RParen | TokenKind::Eof) {
222 break;
223 }
224 params.push(self.parameter()?);
225 }
226 }
227
228 let r_paren = self.expect_recoverable(
229 TokenKind::RParen,
230 "missing closing parenthesis",
231 self.curr_tok.span,
232 )?;
233
234 let params = Spanned {
235 span: l_paren.start.until(r_paren.end),
236 inner: params,
237 };
238
239 let return_type = match self.curr_tok.kind {
240 TokenKind::Arrow => {
241 self.next()?;
242 let type_ = self.type_()?;
243 Spanned {
244 span: type_.span,
245 inner: Some(type_.inner),
246 }
247 }
248 _ => Spanned {
249 span: r_paren.start.until(self.curr_tok.span.end),
250 inner: None,
251 },
252 };
253
254 let block = self.block()?;
255
256 Ok(FunctionDefinition {
257 span: start_loc.until(self.prev_tok.span.end),
258 name,
259 params,
260 return_type,
261 block,
262 })
263 }
264
265 fn parameter(&mut self) -> Result<'src, Parameter<'src>> {
266 let mutable = self.curr_tok.kind == TokenKind::Mut;
267 if mutable {
268 self.next()?;
269 }
270
271 let name = self.expect_ident()?;
272 let type_ = match self.curr_tok.kind {
273 TokenKind::Comma | TokenKind::RParen => {
274 self.errors.push(Error::new(
275 format!("missing type for parameter `{}`", name.inner),
276 name.span,
277 self.lexer.source(),
278 ));
279 Spanned {
280 span: Span::dummy(),
281 inner: Type::Unknown,
282 }
283 }
284 _ => {
285 self.expect(TokenKind::Colon)?;
286 self.type_()?
287 }
288 };
289 Ok(Parameter {
290 mutable,
291 name,
292 type_,
293 })
294 }
295
296 fn block(&mut self) -> Result<'src, Block<'src>> {
297 let start_loc = self.curr_tok.span.start;
298
299 self.expect(TokenKind::LBrace)?;
300
301 let mut stmts = vec![];
302 let mut expr = None;
303 while !matches!(self.curr_tok.kind, TokenKind::RBrace | TokenKind::Eof) {
304 match self.statement()? {
305 Either::Left(stmt) => stmts.push(stmt),
306 Either::Right(expression) => {
307 expr = Some(expression);
308 break;
309 }
310 }
311 }
312
313 self.expect_recoverable(
314 TokenKind::RBrace,
315 "missing closing brace",
316 self.curr_tok.span,
317 )?;
318
319 Ok(Block {
320 span: start_loc.until(self.prev_tok.span.end),
321 stmts,
322 expr,
323 })
324 }
325
326 fn statement(&mut self) -> Result<'src, Either<Statement<'src>, Expression<'src>>> {
327 Ok(match self.curr_tok.kind {
328 TokenKind::Let => Either::Left(Statement::Let(self.let_stmt()?)),
329 TokenKind::Return => Either::Left(self.return_stmt()?),
330 TokenKind::Loop => Either::Left(self.loop_stmt()?),
331 TokenKind::While => Either::Left(self.while_stmt()?),
332 TokenKind::For => Either::Left(self.for_stmt()?),
333 TokenKind::Break => Either::Left(self.break_stmt()?),
334 TokenKind::Continue => Either::Left(self.continue_stmt()?),
335 _ => self.expr_stmt()?,
336 })
337 }
338
339 fn let_stmt(&mut self) -> Result<'src, LetStmt<'src>> {
340 let start_loc = self.curr_tok.span.start;
341
342 self.next()?;
344
345 let mutable = self.curr_tok.kind == TokenKind::Mut;
346 if mutable {
347 self.next()?;
348 }
349
350 let name = self.expect_ident()?;
351
352 let type_ = match self.curr_tok.kind {
353 TokenKind::Colon => {
354 self.next()?;
355 Some(self.type_()?)
356 }
357 _ => None,
358 };
359
360 self.expect(TokenKind::Assign)?;
361 let expr = self.expression(0)?;
362 self.expect_recoverable(
363 TokenKind::Semicolon,
364 "missing semicolon after statement",
365 start_loc.until(self.prev_tok.span.end),
366 )?;
367
368 Ok(LetStmt {
369 span: start_loc.until(self.prev_tok.span.end),
370 mutable,
371 type_,
372 name,
373 expr,
374 })
375 }
376
377 fn return_stmt(&mut self) -> Result<'src, Statement<'src>> {
378 let start_loc = self.curr_tok.span.start;
379
380 self.next()?;
382
383 let expr = match self.curr_tok.kind {
384 TokenKind::Semicolon | TokenKind::RBrace | TokenKind::Eof => None,
385 _ => Some(self.expression(0)?),
386 };
387
388 self.expect_recoverable(
389 TokenKind::Semicolon,
390 "missing semicolon after statement",
391 start_loc.until(self.prev_tok.span.end),
392 )?;
393
394 Ok(Statement::Return(ReturnStmt {
395 span: start_loc.until(self.prev_tok.span.end),
396 expr,
397 }))
398 }
399
400 fn loop_stmt(&mut self) -> Result<'src, Statement<'src>> {
401 let start_loc = self.curr_tok.span.start;
402
403 self.next()?;
405
406 let block = self.block()?;
407
408 if self.curr_tok.kind == TokenKind::Semicolon {
410 self.next()?;
411 }
412
413 Ok(Statement::Loop(LoopStmt {
414 span: start_loc.until(self.prev_tok.span.end),
415 block,
416 }))
417 }
418
419 fn while_stmt(&mut self) -> Result<'src, Statement<'src>> {
420 let start_loc = self.curr_tok.span.start;
421
422 self.next()?;
424
425 let cond = self.expression(0)?;
426
427 let block = self.block()?;
428
429 if self.curr_tok.kind == TokenKind::Semicolon {
431 self.next()?;
432 }
433
434 Ok(Statement::While(WhileStmt {
435 span: start_loc.until(self.prev_tok.span.end),
436 cond,
437 block,
438 }))
439 }
440
441 fn for_stmt(&mut self) -> Result<'src, Statement<'src>> {
442 let start_loc = self.curr_tok.span.start;
443
444 self.next()?;
446
447 let ident = self.expect_ident()?;
449 self.expect_recoverable(
450 TokenKind::Assign,
451 format!("expected `=`, found `{}`", self.curr_tok.kind),
452 self.curr_tok.span,
453 )?;
454 let initializer = self.expression(0)?;
455
456 self.expect_recoverable(
458 TokenKind::Semicolon,
459 format!("expected semicolon, found `{}`", self.curr_tok.kind),
460 self.curr_tok.span,
461 )?;
462 let cond = self.expression(0)?;
463
464 self.expect_recoverable(
466 TokenKind::Semicolon,
467 format!("expected semicolon, found `{}`", self.curr_tok.kind),
468 self.curr_tok.span,
469 )?;
470 let update = self.expression(0)?;
471
472 let block = self.block()?;
474
475 if self.curr_tok.kind == TokenKind::Semicolon {
477 self.next()?;
478 }
479
480 Ok(Statement::For(ForStmt {
481 span: start_loc.until(self.prev_tok.span.end),
482 ident,
483 initializer,
484 cond,
485 update,
486 block,
487 }))
488 }
489
490 fn break_stmt(&mut self) -> Result<'src, Statement<'src>> {
491 let start_loc = self.curr_tok.span.start;
492
493 self.next()?;
495
496 self.expect_recoverable(
497 TokenKind::Semicolon,
498 "missing semicolon after statement",
499 self.prev_tok.span,
500 )?;
501
502 Ok(Statement::Break(BreakStmt {
503 span: start_loc.until(self.prev_tok.span.end),
504 }))
505 }
506
507 fn continue_stmt(&mut self) -> Result<'src, Statement<'src>> {
508 let start_loc = self.curr_tok.span.start;
509
510 self.next()?;
512
513 self.expect_recoverable(
514 TokenKind::Semicolon,
515 "missing semicolon after statement",
516 self.prev_tok.span,
517 )?;
518
519 Ok(Statement::Continue(ContinueStmt {
520 span: start_loc.until(self.prev_tok.span.end),
521 }))
522 }
523
524 fn expr_stmt(&mut self) -> Result<'src, Either<Statement<'src>, Expression<'src>>> {
525 let start_loc = self.curr_tok.span.start;
526
527 let (expr, with_block) = match self.curr_tok.kind {
528 TokenKind::If => (Expression::If(self.if_expr()?.into()), true),
529 TokenKind::LBrace => (Expression::Block(self.block()?.into()), true),
530 _ => (self.expression(0)?, false),
531 };
532
533 match (self.curr_tok.kind, with_block) {
534 (TokenKind::Semicolon, true) => self.next()?,
535 (TokenKind::Semicolon, false) => self.next()?,
536 (TokenKind::RBrace, _) => return Ok(Either::Right(expr)),
537 (_, true) => {}
538 (_, false) => self.errors.push(Error::new(
539 "missing semicolon after statement".to_string(),
540 expr.span(),
541 self.lexer.source(),
542 )),
543 }
544
545 Ok(Either::Left(Statement::Expr(ExprStmt {
546 span: start_loc.until(self.prev_tok.span.end),
547 expr,
548 })))
549 }
550
551 fn expression(&mut self, prec: u8) -> Result<'src, Expression<'src>> {
552 let start_loc = self.curr_tok.span.start;
553
554 let mut lhs = match self.curr_tok.kind {
555 TokenKind::LBrace => Expression::Block(self.block()?.into()),
556 TokenKind::If => Expression::If(self.if_expr()?.into()),
557 TokenKind::Int(num) => Expression::Int(self.atom(num)?),
558 TokenKind::Float(num) => Expression::Float(self.atom(num)?),
559 TokenKind::True => Expression::Bool(self.atom(true)?),
560 TokenKind::False => Expression::Bool(self.atom(false)?),
561 TokenKind::Char(char) => Expression::Char(self.atom(char)?),
562 TokenKind::Ident(ident) => Expression::Ident(self.atom(ident)?),
563 TokenKind::Not => Expression::Prefix(self.prefix_expr(PrefixOp::Not, false)?.into()),
564 TokenKind::Minus => Expression::Prefix(self.prefix_expr(PrefixOp::Neg, false)?.into()),
565 TokenKind::Star => Expression::Prefix(self.prefix_expr(PrefixOp::Deref, false)?.into()),
566 TokenKind::Pow => Expression::Prefix(self.prefix_expr(PrefixOp::Deref, true)?.into()),
567 TokenKind::BitAnd => Expression::Prefix(self.prefix_expr(PrefixOp::Ref, false)?.into()),
568 TokenKind::LParen => Expression::Grouped(self.grouped_expr()?),
569 invalid => {
570 return Err(Error::new_boxed(
571 format!("expected an expression, found `{invalid}`"),
572 self.curr_tok.span,
573 self.lexer.source(),
574 ));
575 }
576 };
577
578 while self.curr_tok.kind.prec().0 > prec {
579 lhs = match self.curr_tok.kind {
580 TokenKind::Plus => self.infix_expr(start_loc, lhs, InfixOp::Plus)?,
581 TokenKind::Minus => self.infix_expr(start_loc, lhs, InfixOp::Minus)?,
582 TokenKind::Star => self.infix_expr(start_loc, lhs, InfixOp::Mul)?,
583 TokenKind::Slash => self.infix_expr(start_loc, lhs, InfixOp::Div)?,
584 TokenKind::Percent => self.infix_expr(start_loc, lhs, InfixOp::Rem)?,
585 TokenKind::Pow => self.infix_expr(start_loc, lhs, InfixOp::Pow)?,
586 TokenKind::Eq => self.infix_expr(start_loc, lhs, InfixOp::Eq)?,
587 TokenKind::Neq => self.infix_expr(start_loc, lhs, InfixOp::Neq)?,
588 TokenKind::Lt => self.infix_expr(start_loc, lhs, InfixOp::Lt)?,
589 TokenKind::Gt => self.infix_expr(start_loc, lhs, InfixOp::Gt)?,
590 TokenKind::Lte => self.infix_expr(start_loc, lhs, InfixOp::Lte)?,
591 TokenKind::Gte => self.infix_expr(start_loc, lhs, InfixOp::Gte)?,
592 TokenKind::Shl => self.infix_expr(start_loc, lhs, InfixOp::Shl)?,
593 TokenKind::Shr => self.infix_expr(start_loc, lhs, InfixOp::Shr)?,
594 TokenKind::BitOr => self.infix_expr(start_loc, lhs, InfixOp::BitOr)?,
595 TokenKind::BitAnd => self.infix_expr(start_loc, lhs, InfixOp::BitAnd)?,
596 TokenKind::BitXor => self.infix_expr(start_loc, lhs, InfixOp::BitXor)?,
597 TokenKind::And => self.infix_expr(start_loc, lhs, InfixOp::And)?,
598 TokenKind::Or => self.infix_expr(start_loc, lhs, InfixOp::Or)?,
599 TokenKind::Assign => self.assign_expr(start_loc, lhs, AssignOp::Basic)?,
600 TokenKind::PlusAssign => self.assign_expr(start_loc, lhs, AssignOp::Plus)?,
601 TokenKind::MinusAssign => self.assign_expr(start_loc, lhs, AssignOp::Minus)?,
602 TokenKind::MulAssign => self.assign_expr(start_loc, lhs, AssignOp::Mul)?,
603 TokenKind::DivAssign => self.assign_expr(start_loc, lhs, AssignOp::Div)?,
604 TokenKind::RemAssign => self.assign_expr(start_loc, lhs, AssignOp::Rem)?,
605 TokenKind::PowAssign => self.assign_expr(start_loc, lhs, AssignOp::Pow)?,
606 TokenKind::ShlAssign => self.assign_expr(start_loc, lhs, AssignOp::Shl)?,
607 TokenKind::ShrAssign => self.assign_expr(start_loc, lhs, AssignOp::Shr)?,
608 TokenKind::BitOrAssign => self.assign_expr(start_loc, lhs, AssignOp::BitOr)?,
609 TokenKind::BitAndAssign => self.assign_expr(start_loc, lhs, AssignOp::BitAnd)?,
610 TokenKind::BitXorAssign => self.assign_expr(start_loc, lhs, AssignOp::BitXor)?,
611 TokenKind::LParen => self.call_expr(start_loc, lhs)?,
612 TokenKind::As => self.cast_expr(start_loc, lhs)?,
613 _ => return Ok(lhs),
614 };
615 }
616
617 Ok(lhs)
618 }
619
620 fn if_expr(&mut self) -> Result<'src, IfExpr<'src>> {
621 let start_loc = self.curr_tok.span.start;
622
623 self.next()?;
625
626 let cond = self.expression(0)?;
627 let then_block = self.block()?;
628 let else_block = match self.curr_tok.kind {
629 TokenKind::Else => {
630 self.next()?;
631 Some(match self.curr_tok.kind {
632 TokenKind::If => {
633 let if_expr = self.if_expr()?;
634 Block {
635 span: if_expr.span,
636 stmts: vec![],
637 expr: Some(Expression::If(if_expr.into())),
638 }
639 }
640 TokenKind::LBrace => self.block()?,
641 invalid => {
642 return Err(Error::new_boxed(
643 format!(
644 "expected either `if` or block after `else`, found `{invalid}`"
645 ),
646 self.curr_tok.span,
647 self.lexer.source(),
648 ));
649 }
650 })
651 }
652 _ => None,
653 };
654
655 Ok(IfExpr {
656 span: start_loc.until(self.prev_tok.span.end),
657 cond,
658 then_block,
659 else_block,
660 })
661 }
662
663 fn atom<T>(&mut self, inner: T) -> Result<'src, Spanned<'src, T>> {
664 let start_loc = self.curr_tok.span.start;
665 self.next()?;
666 Ok(Spanned {
667 span: start_loc.until(self.prev_tok.span.end),
668 inner,
669 })
670 }
671
672 fn prefix_expr(
673 &mut self,
674 op: PrefixOp,
675 deref_counts_double: bool,
676 ) -> Result<'src, PrefixExpr<'src>> {
677 let start_loc = self.curr_tok.span.start;
678
679 self.next()?;
681
682 let expr = self.expression(27)?;
684
685 match (op, &expr) {
686 (PrefixOp::Ref | PrefixOp::Deref, Expression::Ident(_)) => Ok(PrefixExpr {
687 span: start_loc.until(self.prev_tok.span.end),
688 op,
689 expr: match deref_counts_double {
690 true => Expression::Prefix(Box::new(PrefixExpr {
691 span: start_loc.until(self.prev_tok.span.end),
692 op,
693 expr,
694 })),
695 false => expr,
696 },
697 }),
698 (PrefixOp::Deref, Expression::Prefix(_)) => Ok(PrefixExpr {
699 span: start_loc.until(self.prev_tok.span.end),
700 op,
701 expr: match deref_counts_double {
702 true => Expression::Prefix(Box::new(PrefixExpr {
703 span: start_loc.until(self.prev_tok.span.end),
704 op,
705 expr,
706 })),
707 false => expr,
708 },
709 }),
710 (PrefixOp::Ref | PrefixOp::Deref, _) => {
711 self.errors.push(Error::new(
712 format!("prefix operator `{op}` requires an identifier on its right hand side"),
713 expr.span(),
714 self.lexer.source(),
715 ));
716 Ok(PrefixExpr {
717 span: start_loc.until(self.prev_tok.span.end),
718 op,
719 expr: Expression::Ident(Spanned {
720 span: Span::dummy(),
721 inner: "",
722 }),
723 })
724 }
725 _ => Ok(PrefixExpr {
726 span: start_loc.until(self.prev_tok.span.end),
727 op,
728 expr,
729 }),
730 }
731 }
732
733 fn grouped_expr(&mut self) -> Result<'src, Spanned<'src, Box<Expression<'src>>>> {
734 let start_loc = self.curr_tok.span.start;
735 self.next()?;
737
738 let expr = self.expression(0)?;
739 self.expect_recoverable(
740 TokenKind::RParen,
741 "missing closing parenthesis",
742 self.curr_tok.span,
743 )?;
744
745 Ok(Spanned {
746 span: start_loc.until(self.prev_tok.span.end),
747 inner: expr.into(),
748 })
749 }
750
751 fn infix_expr(
752 &mut self,
753 start_loc: Location<'src>,
754 lhs: Expression<'src>,
755 op: InfixOp,
756 ) -> Result<'src, Expression<'src>> {
757 let right_prec = self.curr_tok.kind.prec().1;
758 self.next()?;
759 let rhs = self.expression(right_prec)?;
760
761 Ok(Expression::Infix(
762 InfixExpr {
763 span: start_loc.until(self.prev_tok.span.end),
764 lhs,
765 op,
766 rhs,
767 }
768 .into(),
769 ))
770 }
771
772 fn assign_expr(
773 &mut self,
774 start_loc: Location<'src>,
775 lhs: Expression<'src>,
776 op: AssignOp,
777 ) -> Result<'src, Expression<'src>> {
778 let lhs_start_loc = lhs.span().start;
779 let (assignee, assignee_ptr_count) =
780 match self.reduce_prefix_expr_to_ident(lhs, lhs_start_loc, 0) {
781 Ok(res) => res,
782 Err(err) => {
783 self.errors.push(*err);
784 (
785 Spanned {
786 span: Span::dummy(),
787 inner: "",
788 },
789 0,
790 )
791 }
792 };
793
794 let right_prec = self.curr_tok.kind.prec().1;
795 self.next()?;
796 let expr = self.expression(right_prec)?;
797
798 Ok(Expression::Assign(
799 AssignExpr {
800 span: start_loc.until(self.prev_tok.span.end),
801 assignee,
802 assignee_ptr_count,
803 op,
804 expr,
805 }
806 .into(),
807 ))
808 }
809
810 fn reduce_prefix_expr_to_ident(
813 &self,
814 expr: Expression<'src>,
815 start_loc: Location<'src>,
816 count: usize,
817 ) -> Result<'src, (Spanned<'src, &'src str>, usize)> {
818 match expr {
819 Expression::Ident(ident) => {
820 let mut ident = ident;
821 ident.span = start_loc.until(ident.span.end);
822 Ok((ident, count))
823 }
824 Expression::Prefix(prefix) => {
825 self.reduce_prefix_expr_to_ident(prefix.expr, start_loc, count + 1)
826 }
827 _ => Err(Error::new_boxed(
828 "left hand side of assignment must be an identifier".to_string(),
829 expr.span(),
830 self.lexer.source(),
831 )),
832 }
833 }
834
835 fn call_expr(
836 &mut self,
837 start_loc: Location<'src>,
838 expr: Expression<'src>,
839 ) -> Result<'src, Expression<'src>> {
840 let func = match expr {
841 Expression::Ident(func) => func,
842 _ => {
843 self.errors.push(Error::new(
844 "only identifiers can be called".to_string(),
845 self.curr_tok.span,
846 self.lexer.source(),
847 ));
848 Spanned {
849 span: Span::dummy(),
850 inner: "",
851 }
852 }
853 };
854
855 self.next()?;
857
858 let mut args = vec![];
859 if !matches!(self.curr_tok.kind, TokenKind::RParen | TokenKind::Eof) {
860 args.push(self.expression(0)?);
861
862 while self.curr_tok.kind == TokenKind::Comma {
863 self.next()?;
864 if let TokenKind::RParen | TokenKind::Eof = self.curr_tok.kind {
865 break;
866 }
867 args.push(self.expression(0)?);
868 }
869 }
870
871 self.expect_recoverable(
872 TokenKind::RParen,
873 "missing closing parenthesis",
874 self.curr_tok.span,
875 )?;
876
877 Ok(Expression::Call(
878 CallExpr {
879 span: start_loc.until(self.prev_tok.span.end),
880 func,
881 args,
882 }
883 .into(),
884 ))
885 }
886
887 fn cast_expr(
888 &mut self,
889 start_loc: Location<'src>,
890 expr: Expression<'src>,
891 ) -> Result<'src, Expression<'src>> {
892 self.next()?;
894
895 let type_ = self.type_()?;
896
897 Ok(Expression::Cast(
898 CastExpr {
899 span: start_loc.until(self.prev_tok.span.end),
900 expr,
901 type_,
902 }
903 .into(),
904 ))
905 }
906}
907
908#[cfg(test)]
909mod tests {
910 use super::*;
911
912 impl<'src, T> Lex<'src> for T
914 where
915 T: Iterator<Item = Token<'src>>,
916 {
917 fn next_token(&mut self) -> Result<'src, Token<'src>> {
918 Ok(self.next().unwrap_or_else(Token::dummy))
919 }
920
921 fn source(&self) -> &'src str {
922 ""
923 }
924 }
925
926 fn expr_test(
929 tokens: impl IntoIterator<Item = Token<'static>>,
930 tree: Expression<'static>,
931 ) -> Result<'static, ()> {
932 let mut parser = Parser::new(tokens.into_iter());
933 parser.next()?;
934 let expr = parser.expression(0)?;
935 assert!(dbg!(parser.errors).is_empty());
936 assert_eq!(dbg!(expr), dbg!(tree));
937 Ok(())
938 }
939
940 fn stmt_test(
943 tokens: impl IntoIterator<Item = Token<'static>>,
944 tree: Statement<'static>,
945 ) -> Result<'static, ()> {
946 let mut parser = Parser::new(tokens.into_iter());
947 parser.next()?;
948 let stmt = parser.statement()?;
949 assert!(dbg!(parser.errors).is_empty());
950 assert_eq!(dbg!(stmt), Either::Left(dbg!(tree)));
951 Ok(())
952 }
953
954 fn program_test(
957 tokens: impl IntoIterator<Item = Token<'static>>,
958 tree: Program<'static>,
959 ) -> Result<'static, ()> {
960 let parser = Parser::new(tokens.into_iter());
961 let (res, errors) = parser.parse();
962 assert!(dbg!(errors).is_empty());
963 assert_eq!(dbg!(res?), dbg!(tree));
964 Ok(())
965 }
966
967 #[test]
968 fn arithmetic_expressions() -> Result<'static, ()> {
969 expr_test(
971 tokens![
972 Int(3) @ 0..1,
973 Minus @ 1..2,
974 Int(2) @ 2..3,
975 Minus @ 3..4,
976 Int(1) @ 4..5,
977 ],
978 tree! {
979 (InfixExpr @ 0..5,
980 lhs: (InfixExpr @ 0..3,
981 lhs: (Int 3, @ 0..1),
982 op: InfixOp::Minus,
983 rhs: (Int 2, @ 2..3)),
984 op: InfixOp::Minus,
985 rhs: (Int 1, @ 4..5))
986 },
987 )?;
988
989 expr_test(
991 tokens![
992 Int(1) @ 0..1,
993 Plus @ 1..2,
994 Int(2) @ 2..3,
995 Star @ 3..4,
996 Int(3) @ 4..5,
997 ],
998 tree! {
999 (InfixExpr @ 0..5,
1000 lhs: (Int 1, @ 0..1),
1001 op: InfixOp::Plus,
1002 rhs: (InfixExpr @ 2..5,
1003 lhs: (Int 2, @ 2..3),
1004 op: InfixOp::Mul,
1005 rhs: (Int 3, @ 4..5)))
1006 },
1007 )?;
1008
1009 expr_test(
1011 tokens![
1012 Int(2) @ 0..1,
1013 Pow @ 1..3,
1014 Int(3) @ 3..4,
1015 Pow @ 4..6,
1016 Int(4) @ 6..7,
1017 ],
1018 tree! {
1019 (InfixExpr @ 0..7,
1020 lhs: (Int 2, @ 0..1),
1021 op: InfixOp::Pow,
1022 rhs: (InfixExpr @ 3..7,
1023 lhs: (Int 3, @ 3..4),
1024 op: InfixOp::Pow,
1025 rhs: (Int 4, @ 6..7)))
1026 },
1027 )?;
1028
1029 Ok(())
1030 }
1031
1032 #[test]
1033 fn assignment_expressions() -> Result<'static, ()> {
1034 expr_test(
1036 tokens![
1037 Ident("a") @ 0..1,
1038 Assign @ 1..2,
1039 Int(1) @ 2..3,
1040 ],
1041 tree! {
1042 (AssignExpr @ 0..3,
1043 assignee: ("a", @ 0..1),
1044 assignee_ptr_count: 0,
1045 op: AssignOp::Basic,
1046 expr: (Int 1, @ 2..3))
1047 },
1048 )?;
1049
1050 expr_test(
1052 tokens![
1053 Ident("answer") @ 0..6,
1054 PlusAssign @ 7..9,
1055 Float(42.0) @ 10..14,
1056 Minus @ 15..16,
1057 Float(0.0) @ 17..19,
1058 ],
1059 tree! {
1060 (AssignExpr @ 0..19,
1061 assignee: ("answer", @ 0..6),
1062 assignee_ptr_count: 0,
1063 op: AssignOp::Plus,
1064 expr: (InfixExpr @ 10..19,
1065 lhs: (Float 42.0, @ 10..14),
1066 op: InfixOp::Minus,
1067 rhs: (Float 0.0, @ 17..19)))
1068 },
1069 )?;
1070
1071 Ok(())
1072 }
1073
1074 #[test]
1075 fn if_expr() -> Result<'static, ()> {
1076 expr_test(
1078 tokens![
1079 If @ 0..2,
1080 True @ 3..7,
1081 LBrace @ 7..8,
1082 RBrace @ 8..9,
1083 ],
1084 tree! {
1085 (IfExpr @ 0..9,
1086 cond: (Bool true, @ 3..7),
1087 then_block: (Block @ 7..9,
1088 stmts: [],
1089 expr: (None)),
1090 else_block: (None))
1091 },
1092 )?;
1093
1094 expr_test(
1096 tokens![
1097 If @ 0..2,
1098 Int(2) @ 3..4,
1099 Gt @ 5..6,
1100 Int(1) @ 7..8,
1101 LBrace @ 9..10,
1102 Int(1) @ 11..12,
1103 RBrace @ 13..14,
1104 Else @ 15..19,
1105 LBrace @ 20..21,
1106 LBrace @ 22..23,
1107 Int(2) @ 24..25,
1108 RBrace @ 26..27,
1109 RBrace @ 28..29,
1110 ],
1111 tree! {
1112 (IfExpr @ 0..29,
1113 cond: (InfixExpr @ 3..8,
1114 lhs: (Int 2, @ 3..4),
1115 op: InfixOp::Gt,
1116 rhs: (Int 1, @ 7..8)),
1117 then_block: (Block @ 9..14,
1118 stmts: [],
1119 expr: (Some(Int 1, @ 11..12))),
1120 else_block: (Some(Block @ 20..29,
1121 stmts: [],
1122 expr: (Some(BlockExpr @ 22..27,
1123 stmts: [],
1124 expr: (Some(Int 2, @ 24..25)))))))
1125 },
1126 )?;
1127
1128 expr_test(
1130 tokens![
1131 If @ 0..2,
1132 False @ 3..8,
1133 LBrace @ 9..10,
1134 RBrace @ 10..11,
1135 Else @ 12..16,
1136 If @ 17..19,
1137 Ident("cond") @ 20..24,
1138 LBrace @ 25..26,
1139 Int(1) @ 26..27,
1140 Semicolon @ 27..28,
1141 RBrace @ 28..29,
1142 ],
1143 tree! {
1144 (IfExpr @ 0..29,
1145 cond: (Bool false, @ 3..8),
1146 then_block: (Block @ 9..11,
1147 stmts: [],
1148 expr: (None)),
1149 else_block: (Some(Block @ 17..29,
1150 stmts: [],
1151 expr: (Some(IfExpr @ 17..29,
1152 cond: (Ident "cond", @ 20..24),
1153 then_block: (Block @ 25..29,
1154 stmts: [
1155 (ExprStmt @ 26..28, (Int 1, @ 26..27))],
1156 expr: (None)),
1157 else_block: (None))))))
1158 },
1159 )?;
1160
1161 Ok(())
1162 }
1163
1164 #[test]
1165 fn prefix_expressions() -> Result<'static, ()> {
1166 expr_test(
1168 tokens![
1169 Not @ 0..1,
1170 Ident("func") @ 1..5,
1171 LParen @ 5..6,
1172 RParen @ 6..7,
1173 ],
1174 tree! {
1175 (PrefixExpr @ 0..7,
1176 op: PrefixOp::Not,
1177 expr: (CallExpr @ 1..7,
1178 func: ("func", @ 1..5),
1179 args: []))
1180 },
1181 )?;
1182
1183 Ok(())
1184 }
1185
1186 fn infix_expr_test(token: TokenKind<'static>, op: InfixOp) -> Result<()> {
1187 expr_test(
1188 [
1189 TokenKind::Int(1).spanned(span!(0..1)),
1190 token.spanned(span!(1..2)),
1191 TokenKind::Int(2).spanned(span!(2..3)),
1192 ],
1193 tree! {
1194 (InfixExpr @ 0..3,
1195 lhs: (Int 1, @ 0..1),
1196 op: op,
1197 rhs: (Int 2, @ 2..3))
1198 },
1199 )
1200 }
1201
1202 #[test]
1203 fn infix_expr() -> Result<'static, ()> {
1204 infix_expr_test(TokenKind::Plus, InfixOp::Plus)?;
1205 infix_expr_test(TokenKind::Minus, InfixOp::Minus)?;
1206 infix_expr_test(TokenKind::Star, InfixOp::Mul)?;
1207 infix_expr_test(TokenKind::Slash, InfixOp::Div)?;
1208 infix_expr_test(TokenKind::Percent, InfixOp::Rem)?;
1209 infix_expr_test(TokenKind::Pow, InfixOp::Pow)?;
1210 infix_expr_test(TokenKind::Eq, InfixOp::Eq)?;
1211 infix_expr_test(TokenKind::Neq, InfixOp::Neq)?;
1212 infix_expr_test(TokenKind::Lt, InfixOp::Lt)?;
1213 infix_expr_test(TokenKind::Gt, InfixOp::Gt)?;
1214 infix_expr_test(TokenKind::Lte, InfixOp::Lte)?;
1215 infix_expr_test(TokenKind::Gte, InfixOp::Gte)?;
1216 infix_expr_test(TokenKind::Shl, InfixOp::Shl)?;
1217 infix_expr_test(TokenKind::Shr, InfixOp::Shr)?;
1218 infix_expr_test(TokenKind::BitOr, InfixOp::BitOr)?;
1219 infix_expr_test(TokenKind::BitAnd, InfixOp::BitAnd)?;
1220 infix_expr_test(TokenKind::BitXor, InfixOp::BitXor)?;
1221 infix_expr_test(TokenKind::And, InfixOp::And)?;
1222 infix_expr_test(TokenKind::Or, InfixOp::Or)?;
1223
1224 Ok(())
1225 }
1226
1227 fn assign_expr_test(token: TokenKind<'static>, op: AssignOp) -> Result<()> {
1228 expr_test(
1229 [
1230 TokenKind::Ident("a").spanned(span!(0..1)),
1231 token.spanned(span!(1..2)),
1232 TokenKind::Int(2).spanned(span!(2..3)),
1233 ],
1234 tree! {
1235 (AssignExpr @ 0..3,
1236 assignee: ("a", @ 0..1),
1237 assignee_ptr_count: 0,
1238 op: op,
1239 expr: (Int 2, @ 2..3))
1240 },
1241 )
1242 }
1243
1244 #[test]
1245 fn assign_expr() -> Result<'static, ()> {
1246 assign_expr_test(TokenKind::Assign, AssignOp::Basic)?;
1247 assign_expr_test(TokenKind::PlusAssign, AssignOp::Plus)?;
1248 assign_expr_test(TokenKind::MinusAssign, AssignOp::Minus)?;
1249 assign_expr_test(TokenKind::MulAssign, AssignOp::Mul)?;
1250 assign_expr_test(TokenKind::DivAssign, AssignOp::Div)?;
1251 assign_expr_test(TokenKind::RemAssign, AssignOp::Rem)?;
1252 assign_expr_test(TokenKind::PowAssign, AssignOp::Pow)?;
1253 assign_expr_test(TokenKind::ShlAssign, AssignOp::Shl)?;
1254 assign_expr_test(TokenKind::ShrAssign, AssignOp::Shr)?;
1255 assign_expr_test(TokenKind::BitOrAssign, AssignOp::BitOr)?;
1256 assign_expr_test(TokenKind::BitAndAssign, AssignOp::BitAnd)?;
1257 assign_expr_test(TokenKind::BitXorAssign, AssignOp::BitXor)?;
1258
1259 Ok(())
1260 }
1261
1262 #[test]
1263 fn let_stmt() -> Result<'static, ()> {
1264 stmt_test(
1266 tokens![
1267 Let @ 0..3,
1268 Ident("a") @ 4..5,
1269 Assign @ 5..6,
1270 Int(1) @ 6..7,
1271 Semicolon @ 7..8,
1272 ],
1273 tree! {
1274 (LetStmt @ 0..8,
1275 mutable: false,
1276 name: ("a", @ 4..5),
1277 type: (None),
1278 expr: (Int 1, @ 6..7))
1279 },
1280 )?;
1281
1282 stmt_test(
1284 tokens![
1285 Let @ 0..3,
1286 Mut @ 4..7,
1287 Ident("b") @ 8..9,
1288 Assign @ 10..11,
1289 Int(2) @ 12..13,
1290 Semicolon @ 13..14,
1291 ],
1292 tree! {
1293 (LetStmt @ 0..14,
1294 mutable: true,
1295 name: ("b", @ 8..9),
1296 type: (None),
1297 expr: (Int 2, @ 12..13))
1298 },
1299 )?;
1300
1301 stmt_test(
1303 tokens![
1304 Let @ 0..3,
1305 Ident("c") @ 4..5,
1306 Colon @ 5..6,
1307 Ident("float") @ 7..12,
1308 Assign @ 13..14,
1309 Float(3.0) @ 15..17,
1310 Semicolon @ 17..18,
1311 ],
1312 tree! {
1313 (LetStmt @ 0..18,
1314 mutable: false,
1315 name: ("c", @ 4..5),
1316 type: (Some(Type::Float(0), @ 7..12)),
1317 expr: (Float 3.0, @ 15..17))
1318 },
1319 )?;
1320
1321 Ok(())
1322 }
1323
1324 #[test]
1325 fn return_stmt() -> Result<'static, ()> {
1326 stmt_test(
1328 tokens![
1329 Return @ 0..6,
1330 Semicolon @ 6..7,
1331 ],
1332 tree! { (ReturnStmt @ 0..7, (None)) },
1333 )?;
1334
1335 stmt_test(
1337 tokens![
1338 Return @ 0..6,
1339 Int(1) @ 6..7,
1340 Semicolon @ 7..8,
1341 ],
1342 tree! { (ReturnStmt @ 0..8, (Some(Int 1, @ 6..7))) },
1343 )?;
1344
1345 Ok(())
1346 }
1347
1348 #[test]
1349 fn expr_stmt() -> Result<'static, ()> {
1350 stmt_test(
1352 tokens![
1353 Int(1) @ 0..1,
1354 Semicolon @ 1..2,
1355 ],
1356 tree! { (ExprStmt @ 0..2, (Int 1, @ 0..1)) },
1357 )?;
1358
1359 stmt_test(
1361 tokens![
1362 LBrace @ 0..1,
1363 RBrace @ 1..2,
1364 ],
1365 tree! {
1366 (ExprStmt @ 0..2, (BlockExpr @ 0..2,
1367 stmts: [],
1368 expr: (None)))
1369 },
1370 )?;
1371
1372 Ok(())
1373 }
1374
1375 #[test]
1376 fn programs() -> Result<'static, ()> {
1377 program_test(
1379 tokens![
1380 Fn @ 0..2,
1381 Ident("main") @ 3..7,
1382 LParen @ 7..8,
1383 RParen @ 8..9,
1384 LBrace @ 10..11,
1385 Let @ 12..15,
1386 Ident("a") @ 16..17,
1387 Assign @ 18..19,
1388 True @ 20..24,
1389 Semicolon @ 24..25,
1390 Ident("a") @ 26..27,
1391 Semicolon @ 27..28,
1392 RBrace @ 29..30,
1393 ],
1394 tree! {
1395 (Program @ 0..30,
1396 functions: [
1397 (FunctionDefinition @ 0..30,
1398 name: ("main", @ 3..7),
1399 params @ 7..9: [],
1400 return_type: (None, @ 8..11),
1401 block: (Block @ 10..30,
1402 stmts: [
1403 (LetStmt @ 12..25,
1404 mutable: false,
1405 name: ("a", @ 16..17),
1406 type: (None),
1407 expr: (Bool true, @ 20..24)),
1408 (ExprStmt @ 26..28, (Ident "a", @ 26..27))],
1409 expr: (None)))],
1410 globals: [])
1411 },
1412 )?;
1413
1414 program_test(
1416 tokens![
1417 Fn @ 0..2,
1418 Ident("add") @ 3..6,
1419 LParen @ 6..7,
1420 Ident("left") @ 7..11,
1421 Colon @ 11..12,
1422 Ident("int") @ 13..16,
1423 Comma @ 16..17,
1424 Ident("right") @ 18..23,
1425 Colon @ 23..24,
1426 Ident("int") @ 25..28,
1427 RParen @ 28..29,
1428 Arrow @ 30..32,
1429 Ident("int") @ 33..36,
1430 LBrace @ 37..38,
1431 Return @ 39..45,
1432 Ident("left") @ 46..50,
1433 Plus @ 51..52,
1434 Ident("right") @ 53..58,
1435 Semicolon @ 58..59,
1436 RBrace @ 60..61,
1437 ],
1438 tree! {
1439 (Program @ 0..61,
1440 functions: [
1441 (FunctionDefinition @ 0..61,
1442 name: ("add", @ 3..6),
1443 params @ 6..29: [
1444 (Parameter,
1445 mutable: false,
1446 name: ("left", @ 7..11),
1447 type: (Type::Int(0), @ 13..16)),
1448 (Parameter,
1449 mutable: false,
1450 name: ("right", @ 18..23),
1451 type: (Type::Int(0), @ 25..28))],
1452 return_type: (Some(Type::Int(0)), @ 33..36),
1453 block: (Block @ 37..61,
1454 stmts: [
1455 (ReturnStmt @ 39..59, (Some(InfixExpr @ 46..58,
1456 lhs: (Ident "left", @ 46..50),
1457 op: InfixOp::Plus,
1458 rhs: (Ident "right", @ 53..58))))],
1459 expr: (None)))],
1460 globals: [])
1461 },
1462 )?;
1463
1464 program_test(
1466 tokens![
1467 Fn @ 0..2,
1468 Ident("a") @ 3..4,
1469 LParen @ 4..5,
1470 RParen @ 5..6,
1471 LBrace @ 7..8,
1472 RBrace @ 8..9,
1473 Fn @ 10..12,
1474 Ident("b") @ 13..14,
1475 LParen @ 14..15,
1476 RParen @ 15..16,
1477 LBrace @ 17..18,
1478 RBrace @ 18..19,
1479 Let @ 20..23,
1480 Ident("a") @ 24..25,
1481 Assign @ 26..27,
1482 Int(1) @ 28..29,
1483 Semicolon @ 29..30,
1484 ],
1485 tree! {
1486 (Program @ 0..30,
1487 functions: [
1488 (FunctionDefinition @ 0..9,
1489 name: ("a", @ 3..4),
1490 params @ 4..6: [],
1491 return_type: (None, @ 5..8),
1492 block: (Block @ 7..9,
1493 stmts: [],
1494 expr: (None))),
1495 (FunctionDefinition @ 10..19,
1496 name: ("b", @ 13..14),
1497 params @ 14..16: [],
1498 return_type: (None, @ 15..18),
1499 block: (Block @ 17..19,
1500 stmts: [],
1501 expr: (None)))],
1502 globals: [
1503 (Let @ 20..30,
1504 mutable: false,
1505 name: ("a", @ 24..25),
1506 type: (None),
1507 expr: (Int 1, @ 28..29))])
1508 },
1509 )?;
1510
1511 Ok(())
1512 }
1513}