1use crate::{
2 common::Pos,
3 error::{OperatorKind, ParseError},
4 tokenizer::{Keyword, Operator, Token, TokenKind},
5};
6
7#[derive(Debug, Clone)]
8pub enum Ast {
9 Lines(Vec<Ast>),
10 Null,
11 NumberLiteral(f64),
12 BooleanLiteral(bool),
13 StringLiteral(String),
14 ListLiteral(Vec<Ast>),
15 ObjectLiteral(Vec<(String, Ast)>),
16 Variable(String),
17 Add(Box<Ast>, Box<Ast>),
18 Subtract(Box<Ast>, Box<Ast>),
19 Multiply(Box<Ast>, Box<Ast>),
20 Divide(Box<Ast>, Box<Ast>),
21 Modulo(Box<Ast>, Box<Ast>),
22 Power(Box<Ast>, Box<Ast>),
23 UnaryMinus(Box<Ast>),
24 BooleanNegate(Box<Ast>),
25 Equality(Box<Ast>, Box<Ast>),
26 Inequality(Box<Ast>, Box<Ast>),
27 LessThan(Box<Ast>, Box<Ast>),
28 GreaterThan(Box<Ast>, Box<Ast>),
29 LessThanOrEqual(Box<Ast>, Box<Ast>),
30 GreaterThanOrEqual(Box<Ast>, Box<Ast>),
31 And(Box<Ast>, Box<Ast>),
32 Or(Box<Ast>, Box<Ast>),
33 Brackets(Box<Ast>),
34 Assign(String, Box<Ast>),
35 IndexingAssign {
36 value: Box<Ast>,
37 index: Box<Ast>,
38 rhs: Box<Ast>,
39 },
40 MemberAssign {
41 value: Box<Ast>,
42 member: String,
43 rhs: Box<Ast>,
44 },
45 FunctionCall {
46 value: Box<Ast>,
47 args: Vec<Ast>,
48 },
49 FunctionDefinition {
50 name: String,
51 arg_names: Vec<String>,
52 body: Box<Ast>,
53 },
54 UnnamedFunction {
55 arg_names: Vec<String>,
56 body: Box<Ast>,
57 },
58 MemberAccess {
59 value: Box<Ast>,
60 member: String,
61 },
62 Indexing {
63 value: Box<Ast>,
64 index: Box<Ast>,
65 },
66 IfStatement {
67 condition: Box<Ast>,
68 if_body: Box<Ast>,
69 else_body: Option<Box<Ast>>,
70 },
71 WhileLoop {
72 condition: Box<Ast>,
73 body: Box<Ast>,
74 },
75 ForLoop {
76 variable: String,
77 iterable: Box<Ast>,
78 body: Box<Ast>,
79 },
80 Continue,
81 Break,
82 Return(Option<Box<Ast>>),
83}
84
85fn op_precedence(op: Operator, is_binary: bool, op_pos: Pos) -> Result<u8, ParseError> {
92 let precedence = match (op, is_binary) {
93 (Operator::Or, true) => 1,
94 (Operator::And, true) => 2,
95 (
96 Operator::Equal
97 | Operator::Unequal
98 | Operator::LessThan
99 | Operator::GreaterThan
100 | Operator::LessThanOrEqual
101 | Operator::GreaterThanOrEqual,
102 true,
103 ) => 3,
104 (Operator::Plus | Operator::Minus, true) => 4,
105 (Operator::Star | Operator::Slash | Operator::Percent, true) => 5,
106 (Operator::Caret, true) => 6,
107 (Operator::Minus | Operator::Exclamation, false) => 7,
108 _ => {
109 let kind = if is_binary {
110 OperatorKind::Binary
111 } else {
112 OperatorKind::Unary
113 };
114 return Err(ParseError::InvalidOperator {
115 op,
116 kind,
117 pos: op_pos,
118 });
119 }
120 };
121
122 Ok(precedence)
123}
124
125fn combine_lhs_rhs(op: Operator, lhs: Ast, rhs: Ast) -> Result<Ast, ParseError> {
126 let combined = match op {
127 Operator::Plus => Ast::Add(Box::new(lhs), Box::new(rhs)),
128 Operator::Minus => Ast::Subtract(Box::new(lhs), Box::new(rhs)),
129 Operator::Star => Ast::Multiply(Box::new(lhs), Box::new(rhs)),
130 Operator::Slash => Ast::Divide(Box::new(lhs), Box::new(rhs)),
131 Operator::Percent => Ast::Modulo(Box::new(lhs), Box::new(rhs)),
132 Operator::Caret => Ast::Power(Box::new(lhs), Box::new(rhs)),
133 Operator::Equal => Ast::Equality(Box::new(lhs), Box::new(rhs)),
134 Operator::Unequal => Ast::Inequality(Box::new(lhs), Box::new(rhs)),
135 Operator::LessThan => Ast::LessThan(Box::new(lhs), Box::new(rhs)),
136 Operator::GreaterThan => Ast::GreaterThan(Box::new(lhs), Box::new(rhs)),
137 Operator::LessThanOrEqual => Ast::LessThanOrEqual(Box::new(lhs), Box::new(rhs)),
138 Operator::GreaterThanOrEqual => Ast::GreaterThanOrEqual(Box::new(lhs), Box::new(rhs)),
139 Operator::And => Ast::And(Box::new(lhs), Box::new(rhs)),
140 Operator::Or => Ast::Or(Box::new(lhs), Box::new(rhs)),
141 Operator::Exclamation => unreachable!(),
142 };
143 Ok(combined)
144}
145
146pub fn parse(tokens: &[Token]) -> Result<Ast, ParseError> {
147 Parser::new(tokens).parse()
148}
149
150struct Parser<'a> {
151 tokens: &'a [Token],
152 idx: usize,
153}
154
155impl<'a> Parser<'a> {
156 fn new(tokens: &'a [Token]) -> Self {
157 Parser { tokens, idx: 0 }
158 }
159
160 fn parse(&mut self) -> Result<Ast, ParseError> {
162 let ast = self.parse_block()?;
163 if self.idx < self.tokens.len() {
169 return Err(ParseError::UnexpectedToken {
170 token: self.tokens[self.idx].clone(),
171 expected: None,
172 });
173 }
174 Ok(ast)
175 }
176
177 fn parse_block(&mut self) -> Result<Ast, ParseError> {
178 let mut lines = Vec::new();
179 let mut want_newline_this_iteration = false;
180 while let Some(token) = self.peek() {
181 let (line, want_newline_next_iteration) = match &token.kind {
182 TokenKind::Eof | TokenKind::Newline => {
183 self.next();
184 (None, false)
185 }
186 TokenKind::RBrace => break,
187 _ if want_newline_this_iteration => {
189 return Err(ParseError::UnexpectedToken {
190 token: token.clone(),
191 expected: Some(TokenKind::Newline),
192 });
193 }
194 TokenKind::Keyword(Keyword::Fn)
195 if matches!(
196 self.peek_next_non_newline_from_offset(2),
197 Some(Token {
198 kind: TokenKind::Identifier(_),
199 ..
200 })
201 ) =>
202 {
203 (Some(self.parse_function_definition(true)?), true)
204 }
205 TokenKind::Keyword(Keyword::If) => (Some(self.parse_if_statement()?), true),
206 TokenKind::Keyword(Keyword::While) => (Some(self.parse_while_loop()?), true),
207 TokenKind::Keyword(Keyword::For) => (Some(self.parse_for_loop()?), true),
208 TokenKind::Keyword(Keyword::Continue) => {
209 self.next();
210 (Some(Ast::Continue), true)
211 }
212 TokenKind::Keyword(Keyword::Break) => {
213 self.next();
214 (Some(Ast::Break), true)
215 }
216 TokenKind::Keyword(Keyword::Return) => (Some(self.parse_return()?), true),
217 _ => (Some(self.parse_expression_or_assignment()?), true),
218 };
219
220 if let Some(token) = line {
221 lines.push(token);
222 }
223
224 want_newline_this_iteration = want_newline_next_iteration;
225 }
226 Ok(Ast::Lines(lines))
227 }
228
229 fn parse_expression_or_assignment(&mut self) -> Result<Ast, ParseError> {
230 let is_potential_assignment = matches!(self.peek_kind(), Some(TokenKind::Identifier(_)));
231 let lhs = self.parse_expression()?;
232 if is_potential_assignment && self.peek_next_non_newline_kind() == Some(&TokenKind::Equal) {
233 match lhs {
234 Ast::Variable(var) => {
235 self.skip_newlines();
236 self.next();
237 self.skip_newlines();
238 let rhs = self.parse_expression()?;
239 return Ok(Ast::Assign(var, Box::new(rhs)));
240 }
241 Ast::Indexing { value, index } => {
242 self.skip_newlines();
243 self.next();
244 self.skip_newlines();
245 let rhs = self.parse_expression()?;
246 return Ok(Ast::IndexingAssign {
247 value,
248 index,
249 rhs: Box::new(rhs),
250 });
251 }
252 Ast::MemberAccess { value, member } => {
253 self.skip_newlines();
254 self.next();
255 self.skip_newlines();
256 let rhs = self.parse_expression()?;
257 return Ok(Ast::MemberAssign {
258 value,
259 member,
260 rhs: Box::new(rhs),
261 });
262 }
263 _ => {}
264 }
265 }
266
267 Ok(lhs)
268 }
269
270 fn parse_expression(&mut self) -> Result<Ast, ParseError> {
277 let mut lhs = self.parse_expression_with_min_precedence(0)?;
278 while let Some(Token {
279 kind: TokenKind::Operator(op),
280 pos,
281 }) = self.peek_next_non_newline()
282 {
283 let op = *op;
284 let pos = *pos;
285 self.skip_newlines();
286 self.next();
287 self.skip_newlines();
288 let precedence = op_precedence(op, true, pos)?;
289 let rhs = self.parse_expression_with_min_precedence(precedence + 1)?;
290 lhs = combine_lhs_rhs(op, lhs, rhs)?;
291 }
292 Ok(lhs)
293 }
294
295 fn parse_expression_with_min_precedence(
322 &mut self,
323 min_precedence: u8,
324 ) -> Result<Ast, ParseError> {
325 match self.peek() {
326 Some(token) => {
327 match token.kind {
328 TokenKind::Operator(Operator::Minus) => {
329 let pos = token.pos;
330 self.next();
331 self.skip_newlines();
332 let unary_minus_precedence = op_precedence(Operator::Minus, false, pos)?;
333 let rhs =
336 self.parse_expression_with_min_precedence(unary_minus_precedence)?;
337 Ok(Ast::UnaryMinus(Box::new(rhs)))
338 }
339 TokenKind::Operator(Operator::Exclamation) => {
340 let pos = token.pos;
341 self.next();
342 self.skip_newlines();
343 let boolean_negate_precedence =
344 op_precedence(Operator::Exclamation, false, pos)?;
345 let rhs =
348 self.parse_expression_with_min_precedence(boolean_negate_precedence)?;
349 Ok(Ast::BooleanNegate(Box::new(rhs)))
350 }
351 TokenKind::LParen
352 | TokenKind::LBrace
353 | TokenKind::LBracket
354 | TokenKind::Identifier(_)
355 | TokenKind::Number(_)
356 | TokenKind::String(_)
357 | TokenKind::Keyword(Keyword::True | Keyword::False)
358 | TokenKind::Keyword(Keyword::Null)
359 | TokenKind::Keyword(Keyword::Fn) => {
360 let mut lhs = self.parse_identifier_or_value()?;
361 while let Some(Token {
362 kind: TokenKind::Operator(op),
363 pos,
364 }) = self.peek_next_non_newline()
365 {
366 let op = *op;
367 let precedence = op_precedence(op, true, *pos)?;
368 if precedence >= min_precedence {
369 self.skip_newlines();
370 self.next();
371 self.skip_newlines();
372 let rhs =
373 self.parse_expression_with_min_precedence(precedence + 1)?;
374 lhs = combine_lhs_rhs(op, lhs, rhs)?;
375 } else {
376 break;
377 }
378 }
379 Ok(lhs)
380 }
381 _ => Err(ParseError::UnexpectedToken {
382 token: token.clone(),
383 expected: None,
384 }),
385 }
386 }
387 None => Err(ParseError::NoTokensLeft),
388 }
389 }
390
391 fn parse_identifier_or_value(&mut self) -> Result<Ast, ParseError> {
392 let mut ast = match self.next() {
393 Some(token) => match &token.kind {
394 TokenKind::LParen => {
395 self.skip_newlines();
396 let inner = self.parse_expression()?;
397 self.skip_newlines();
398 self.expect(TokenKind::RParen)?;
399 Ast::Brackets(Box::new(inner))
400 }
401 TokenKind::LBrace => {
402 self.idx -= 1;
404 self.parse_object_literal()?
405 }
406 TokenKind::LBracket => {
407 self.idx -= 1;
409 self.parse_list_literal()?
410 }
411 TokenKind::Identifier(name) => Ast::Variable(name.clone()),
412 TokenKind::Number(num) => Ast::NumberLiteral(*num),
413 TokenKind::String(str) => Ast::StringLiteral(str.clone()),
414 TokenKind::Keyword(Keyword::True) => Ast::BooleanLiteral(true),
415 TokenKind::Keyword(Keyword::False) => Ast::BooleanLiteral(false),
416 TokenKind::Keyword(Keyword::Null) => Ast::Null,
417 TokenKind::Keyword(Keyword::Fn) => {
418 self.idx -= 1;
420 self.parse_function_definition(false)?
421 }
422 _ => {
423 return Err(ParseError::UnexpectedToken {
424 token: token.clone(),
425 expected: None,
426 })
427 }
428 },
429 None => return Err(ParseError::NoTokensLeft),
430 };
431 loop {
432 match self.peek_kind() {
435 Some(TokenKind::LParen) => {
436 ast = self.parse_function_call(ast)?;
437 }
438 Some(TokenKind::LBracket) => {
439 ast = self.parse_indexing(ast)?;
440 }
441 _ if self.peek_next_non_newline_kind() == Some(&TokenKind::Dot) => {
442 self.skip_newlines();
443 self.next();
444 self.skip_newlines();
445 let member = self.expect_identifier()?;
446 ast = Ast::MemberAccess {
447 value: Box::new(ast),
448 member: member.to_string(),
449 };
450 }
451 _ => break,
452 }
453 }
454 Ok(ast)
455 }
456
457 fn parse_function_call(&mut self, called_value: Ast) -> Result<Ast, ParseError> {
458 self.expect(TokenKind::LParen)?;
460 self.skip_newlines();
461 let mut args = Vec::new();
462 while self.peek_kind() != Some(&TokenKind::RParen) {
463 let arg = self.parse_expression()?;
464 args.push(arg);
465 self.skip_newlines();
466
467 if self.peek_kind() != Some(&TokenKind::Comma) {
468 break;
469 }
470
471 self.next();
472 self.skip_newlines();
473 }
474 self.expect(TokenKind::RParen)?;
475 Ok(Ast::FunctionCall {
476 value: Box::new(called_value),
477 args,
478 })
479 }
480
481 fn parse_indexing(&mut self, value: Ast) -> Result<Ast, ParseError> {
482 self.expect(TokenKind::LBracket)?;
484 self.skip_newlines();
485 let index = self.parse_expression()?;
486 self.skip_newlines();
487 self.expect(TokenKind::RBracket)?;
488 Ok(Ast::Indexing {
489 value: Box::new(value),
490 index: Box::new(index),
491 })
492 }
493
494 fn parse_object_literal(&mut self) -> Result<Ast, ParseError> {
495 self.expect(TokenKind::LBrace)?;
497 let mut key_value_pairs = Vec::new();
498 while self.peek_kind() != Some(&TokenKind::RBrace) {
499 self.skip_newlines();
500 let key = self.expect_identifier()?.to_string();
501 self.skip_newlines();
502 let value = match self.peek() {
503 Some(Token {
504 kind: TokenKind::Colon,
505 ..
506 }) => {
507 self.next();
508 self.skip_newlines();
509 self.parse_expression()?
510 }
511 Some(Token {
512 kind: TokenKind::LParen,
513 ..
514 }) => self.parse_function_definition_without_fn(false)?,
515 Some(Token {
516 kind: TokenKind::Comma | TokenKind::RBrace,
517 ..
518 }) => Ast::Variable(key.clone()),
519 Some(t) => {
520 return Err(ParseError::UnexpectedToken {
521 token: t.clone(),
522 expected: Some(TokenKind::Colon),
523 })
524 }
525 None => return Err(ParseError::NoTokensLeft),
526 };
527 key_value_pairs.push((key, value));
528
529 self.skip_newlines();
530 if self.peek_kind() != Some(&TokenKind::Comma) {
531 break;
532 }
533
534 self.next();
535 self.skip_newlines();
536 }
537 self.expect(TokenKind::RBrace)?;
538 Ok(Ast::ObjectLiteral(key_value_pairs))
539 }
540
541 fn parse_list_literal(&mut self) -> Result<Ast, ParseError> {
542 self.expect(TokenKind::LBracket)?;
544 self.skip_newlines();
545 let mut values = Vec::new();
546 while self.peek_kind() != Some(&TokenKind::RBracket) {
547 let value = self.parse_expression()?;
548 values.push(value);
549 self.skip_newlines();
550
551 if self.peek_kind() != Some(&TokenKind::Comma) {
552 break;
553 }
554
555 self.next();
556 self.skip_newlines();
557 }
558 self.expect(TokenKind::RBracket)?;
559 Ok(Ast::ListLiteral(values))
560 }
561
562 fn parse_function_definition(&mut self, named: bool) -> Result<Ast, ParseError> {
563 self.expect(TokenKind::Keyword(Keyword::Fn))?;
565 self.skip_newlines();
566 self.parse_function_definition_without_fn(named)
567 }
568
569 fn parse_function_definition_without_fn(&mut self, named: bool) -> Result<Ast, ParseError> {
570 let fn_name = if named {
572 let ident = self.expect_identifier()?.to_string();
573 self.skip_newlines();
574 Some(ident)
575 } else {
576 None
577 };
578 self.expect(TokenKind::LParen)?;
579 self.skip_newlines();
580
581 let mut arg_names = Vec::new();
582 while let Some(TokenKind::Identifier(arg_name)) = self.peek_kind() {
583 arg_names.push(arg_name.to_string());
584 self.next();
585 self.skip_newlines();
586
587 if self.peek_kind() != Some(&TokenKind::Comma) {
588 break;
589 }
590
591 self.next();
592 self.skip_newlines();
593 }
594
595 self.expect(TokenKind::RParen)?;
596 self.skip_newlines();
597 self.expect(TokenKind::LBrace)?;
598 let body = self.parse_block()?;
599 self.expect(TokenKind::RBrace)?;
600
601 if let Some(name) = fn_name {
602 Ok(Ast::FunctionDefinition {
603 name,
604 arg_names,
605 body: Box::new(body),
606 })
607 } else {
608 Ok(Ast::UnnamedFunction {
609 arg_names,
610 body: Box::new(body),
611 })
612 }
613 }
614
615 fn parse_if_statement(&mut self) -> Result<Ast, ParseError> {
616 self.expect(TokenKind::Keyword(Keyword::If))?;
618 self.skip_newlines();
619 self.expect(TokenKind::LParen)?;
620 self.skip_newlines();
621 let condition = self.parse_expression()?;
622 self.skip_newlines();
623 self.expect(TokenKind::RParen)?;
624 self.skip_newlines();
625 self.expect(TokenKind::LBrace)?;
626 let if_body = self.parse_block()?;
627 self.skip_newlines();
628 self.expect(TokenKind::RBrace)?;
629
630 let else_body = if self.peek_next_non_newline().map(|t| &t.kind)
631 == Some(&TokenKind::Keyword(Keyword::Else))
632 {
633 self.skip_newlines();
634 self.next();
635 if self.peek_kind() == Some(&TokenKind::Keyword(Keyword::If)) {
636 let else_if_statement = self.parse_if_statement()?;
637 Some(Box::new(else_if_statement))
638 } else {
639 self.skip_newlines();
640 self.expect(TokenKind::LBrace)?;
641 let else_body = self.parse_block()?;
642 self.skip_newlines();
643 self.expect(TokenKind::RBrace)?;
644 Some(Box::new(else_body))
645 }
646 } else {
647 None
648 };
649
650 Ok(Ast::IfStatement {
651 condition: Box::new(condition),
652 if_body: Box::new(if_body),
653 else_body,
654 })
655 }
656
657 fn parse_while_loop(&mut self) -> Result<Ast, ParseError> {
658 self.expect(TokenKind::Keyword(Keyword::While))?;
660 self.skip_newlines();
661 self.expect(TokenKind::LParen)?;
662 self.skip_newlines();
663 let condition = self.parse_expression()?;
664 self.skip_newlines();
665 self.expect(TokenKind::RParen)?;
666 self.skip_newlines();
667
668 self.expect(TokenKind::LBrace)?;
669 let body = self.parse_block()?;
670 self.expect(TokenKind::RBrace)?;
671
672 Ok(Ast::WhileLoop {
673 condition: Box::new(condition),
674 body: Box::new(body),
675 })
676 }
677
678 fn parse_for_loop(&mut self) -> Result<Ast, ParseError> {
679 self.expect(TokenKind::Keyword(Keyword::For))?;
681 self.skip_newlines();
682 self.expect(TokenKind::LParen)?;
683 self.skip_newlines();
684 let variable = self.expect_identifier()?.to_string();
685 self.skip_newlines();
686 self.expect(TokenKind::Keyword(Keyword::In))?;
687 self.skip_newlines();
688 let iterable = self.parse_expression()?;
689 self.skip_newlines();
690 self.expect(TokenKind::RParen)?;
691 self.skip_newlines();
692
693 self.expect(TokenKind::LBrace)?;
694 let body = self.parse_block()?;
695 self.expect(TokenKind::RBrace)?;
696
697 Ok(Ast::ForLoop {
698 variable,
699 iterable: Box::new(iterable),
700 body: Box::new(body),
701 })
702 }
703
704 fn parse_return(&mut self) -> Result<Ast, ParseError> {
705 self.expect(TokenKind::Keyword(Keyword::Return))?;
707 let expr = match self.peek_kind() {
708 Some(&TokenKind::Newline | &TokenKind::RBrace) => None,
709 _ => Some(Box::new(self.parse_expression()?)),
710 };
711 Ok(Ast::Return(expr))
712 }
713
714 fn next(&mut self) -> Option<&Token> {
716 let token = self.tokens.get(self.idx);
717 self.idx += 1;
718 token
719 }
720
721 fn peek_nth(&self, n: usize) -> Option<&Token> {
725 self.tokens.get(self.idx + n - 1)
726 }
727
728 fn peek(&self) -> Option<&Token> {
730 self.peek_nth(1)
731 }
732
733 fn peek_nth_kind(&self, n: usize) -> Option<&TokenKind> {
735 self.peek_nth(n).map(|t| &t.kind)
736 }
737
738 fn peek_kind(&self) -> Option<&TokenKind> {
740 self.peek_nth_kind(1)
741 }
742
743 fn peek_next_non_newline(&self) -> Option<&Token> {
748 self.peek_next_non_newline_from_offset(1)
749 }
750
751 fn peek_next_non_newline_kind(&self) -> Option<&TokenKind> {
755 self.peek_next_non_newline_from_offset(1).map(|t| &t.kind)
756 }
757
758 fn peek_next_non_newline_from_offset(&self, offset: usize) -> Option<&Token> {
762 let mut peek_idx = offset.max(1);
763 while let Some(TokenKind::Newline) = self.peek_nth_kind(peek_idx) {
764 peek_idx += 1;
765 }
766
767 self.peek_nth(peek_idx)
768 }
769
770 fn expect(&mut self, expected: TokenKind) -> Result<(), ParseError> {
772 match self.next() {
773 Some(actual) => {
774 if actual.kind != expected {
775 Err(ParseError::UnexpectedToken {
776 token: actual.clone(),
777 expected: Some(expected),
778 })
779 } else {
780 Ok(())
781 }
782 }
783 None => Err(ParseError::NoTokensLeft),
784 }
785 }
786
787 fn expect_identifier(&mut self) -> Result<&str, ParseError> {
790 match self.next() {
791 Some(Token {
792 kind: TokenKind::Identifier(ref name),
793 ..
794 }) => Ok(name),
795 Some(Token { pos, .. }) => Err(ParseError::ExpectedIdentifier { pos: *pos }),
796 None => Err(ParseError::NoTokensLeft),
797 }
798 }
799
800 fn skip_newlines(&mut self) {
802 while self.peek_kind() == Some(&TokenKind::Newline) {
803 self.next();
804 }
805 }
806}