Testing stuff for an upcoming project
1use std::iter::Peekable;
2
3use ecow::EcoString;
4
5use crate::{
6 lexer::{self, Span, Token, TokenKind},
7 parser::ast::{
8 Annotation, Argument, BinaryOperator, Constant, Definition, Expression, Function, Module,
9 Mutability, Parameter, Publicity, Statement, StructDefinition, StructField, UnaryOperator,
10 UntypedConstant, UntypedDefinition, UntypedExpression, UntypedFunction, UntypedModule,
11 UntypedParameter, UntypedStatement,
12 },
13};
14
15mod ast;
16#[cfg(test)]
17mod tests;
18
19#[derive(Debug)]
20pub enum Error {
21 LexError(Vec<lexer::Error>),
22 UnexpectedEndOfFile {
23 expected: Vec<&'static str>,
24 },
25 UnexpectedToken {
26 token: Token,
27 expected: Vec<&'static str>,
28 },
29 InvalidEscapeSequence {
30 location: Span,
31 },
32}
33
34pub fn parse(src: &str) -> Result<UntypedModule, Error> {
35 let lexer = lexer::new(src);
36 let mut parser = Parser::new(lexer.peekable());
37 let result = parser.parse();
38 if !parser.lexer_errors.is_empty() {
39 Err(Error::LexError(parser.lexer_errors))
40 } else {
41 result
42 }
43}
44
45#[cfg(test)]
46pub fn parse_statement(src: &str) -> Result<UntypedStatement, Error> {
47 let lexer = lexer::new(src);
48 let mut parser = Parser::new(lexer.peekable());
49 let result = parser.parse_statement();
50 if !parser.lexer_errors.is_empty() {
51 Err(Error::LexError(parser.lexer_errors))
52 } else {
53 result
54 }
55}
56
57struct Parser<Tokens: Iterator> {
58 tokens: Peekable<Tokens>,
59 lexer_errors: Vec<lexer::Error>,
60 no_braces: Vec<bool>,
61}
62
63impl<Tokens> Parser<Tokens>
64where
65 Tokens: Iterator<Item = Result<Token, lexer::Error>>,
66{
67 fn new(tokens: Peekable<Tokens>) -> Self {
68 Self {
69 tokens,
70 lexer_errors: Vec::new(),
71 no_braces: vec![false],
72 }
73 }
74
75 fn nest(&mut self) {
76 self.no_braces.push(false);
77 }
78
79 fn denest(&mut self) {
80 self.no_braces.pop();
81 }
82
83 fn peek(&mut self) -> Option<Token> {
84 match self.tokens.peek() {
85 Some(Err(error)) => {
86 self.lexer_errors.push(*error);
87 self.tokens.next();
88 self.peek()
89 }
90 Some(Ok(token)) => Some(token.clone()),
91 None => None,
92 }
93 }
94
95 fn expect_peek(&mut self, one_of: &[&'static str]) -> Result<Token, Error> {
96 match self.peek() {
97 Some(token) => Ok(token),
98 None => Err(Error::UnexpectedEndOfFile {
99 expected: one_of.into(),
100 }),
101 }
102 }
103
104 fn next(&mut self) -> Option<Token> {
105 match self.tokens.next() {
106 Some(Err(error)) => {
107 self.lexer_errors.push(error);
108 self.next()
109 }
110 Some(Ok(token)) => Some(token),
111 None => None,
112 }
113 }
114
115 fn expect_token(&mut self, one_of: &[&'static str]) -> Result<Token, Error> {
116 if let Some(token) = self.next() {
117 Ok(token)
118 } else {
119 Err(Error::UnexpectedEndOfFile {
120 expected: one_of.into(),
121 })
122 }
123 }
124
125 fn expect_identifier(&mut self) -> Result<(EcoString, Span), Error> {
126 match self.next() {
127 Some(Token {
128 kind: TokenKind::Identifier(name),
129 location,
130 }) => Ok((name, location)),
131 Some(token) => Err(Error::UnexpectedToken {
132 token,
133 expected: vec!["an identifier"],
134 }),
135 None => Err(Error::UnexpectedEndOfFile {
136 expected: vec!["an identifier"],
137 }),
138 }
139 }
140
141 fn expect(&mut self, kind: TokenKind, one_of: &[&'static str]) -> Result<Token, Error> {
142 match self.next() {
143 Some(token) if token.kind == kind => Ok(token),
144 Some(token) => Err(Error::UnexpectedToken {
145 token,
146 expected: one_of.into(),
147 }),
148 _ => Err(Error::UnexpectedEndOfFile {
149 expected: one_of.into(),
150 }),
151 }
152 }
153
154 fn maybe_consume(&mut self, kind: &TokenKind) -> Option<Token> {
155 match self.peek() {
156 Some(token) if token.kind == *kind => self.next(),
157 _ => None,
158 }
159 }
160
161 fn parse(&mut self) -> Result<UntypedModule, Error> {
162 let mut definitions = Vec::new();
163
164 while self.peek().is_some() {
165 definitions.push(self.parse_definition()?);
166 }
167
168 Ok(Module { ast: definitions })
169 }
170
171 fn parse_definition(&mut self) -> Result<UntypedDefinition, Error> {
172 let mut start = None;
173
174 let publicity = if let Some(token) = self.maybe_consume(&TokenKind::Pub) {
175 start = Some(token.location.start);
176 Publicity::Public
177 } else {
178 Publicity::Private
179 };
180
181 let next = self.expect_token(&["a function"])?;
182 match next.kind {
183 TokenKind::Fn => self
184 .parse_function(publicity, start.unwrap_or(next.location.start))
185 .map(Definition::Function),
186 TokenKind::Const => self
187 .parse_constant(publicity, start.unwrap_or(next.location.start))
188 .map(Definition::Constant),
189 TokenKind::Struct => self
190 .parse_struct_definition(publicity, start.unwrap_or(next.location.start))
191 .map(Definition::Struct),
192 _ => Err(Error::UnexpectedToken {
193 token: next,
194 expected: vec!["a function", "a constant"],
195 }),
196 }
197 }
198
199 fn parse_struct_definition(
200 &mut self,
201 publicity: Publicity,
202 start: usize,
203 ) -> Result<StructDefinition, Error> {
204 let (name, _) = self.expect_identifier()?;
205
206 let parameters = if self.maybe_consume(&TokenKind::Less).is_some() {
207 let (parameters, _) = self.sequence(
208 |this| {
209 let (name, _) = this.expect_identifier()?;
210 Ok(name)
211 },
212 Some(TokenKind::Comma),
213 TokenKind::Greater,
214 )?;
215
216 parameters
217 } else {
218 Vec::new()
219 };
220
221 self.expect(TokenKind::LeftBrace, &["a struct body"])?;
222
223 let (fields, end) = self.sequence(
224 Self::parse_struct_field,
225 Some(TokenKind::Comma),
226 TokenKind::RightBrace,
227 )?;
228
229 Ok(StructDefinition {
230 publicity,
231 name,
232 parameters,
233 fields,
234 location: Span { start, end },
235 })
236 }
237
238 fn parse_struct_field(&mut self) -> Result<StructField, Error> {
239 let publicity = if self.maybe_consume(&TokenKind::Pub).is_some() {
240 Publicity::Public
241 } else {
242 Publicity::Private
243 };
244
245 let (name, _) = self.expect_identifier()?;
246
247 self.expect(TokenKind::Colon, &["a type annotation"])?;
248 let annotation = self.parse_annotation()?;
249
250 Ok(StructField {
251 publicity,
252 name,
253 annotation,
254 })
255 }
256
257 fn parse_constant(
258 &mut self,
259 publicity: Publicity,
260 start: usize,
261 ) -> Result<UntypedConstant, Error> {
262 let (name, _) = self.expect_identifier()?;
263
264 let annotation = self.maybe_annotation(TokenKind::Colon)?;
265
266 self.expect(TokenKind::Equals, &["a constant value"])?;
267
268 let value = self.parse_expression()?;
269 let end = value.location().end;
270
271 Ok(Constant {
272 publicity,
273 name,
274 annotation,
275 value,
276 location: Span { start, end },
277 })
278 }
279
280 fn parse_function(
281 &mut self,
282 publicity: Publicity,
283 start: usize,
284 ) -> Result<UntypedFunction, Error> {
285 let (name, _) = self.expect_identifier()?;
286 self.expect(TokenKind::LeftParen, &["an argument list"])?;
287 let (parameters, _) = self.sequence(
288 Self::parse_parameter,
289 Some(TokenKind::Comma),
290 TokenKind::RightParen,
291 )?;
292
293 let return_annotation = self.maybe_annotation(TokenKind::Arrow)?;
294
295 self.expect(TokenKind::LeftBrace, &["a function body"])?;
296
297 let (body, end) = self.sequence(Self::parse_statement, None, TokenKind::RightBrace)?;
298
299 Ok(Function {
300 publicity,
301 name,
302 parameters,
303 return_type: (),
304 return_annotation,
305 body,
306 location: Span { start, end },
307 })
308 }
309
310 fn parse_parameter(&mut self) -> Result<UntypedParameter, Error> {
311 let (label_or_name, _) = self.expect_identifier()?;
312 let (label, name) = match self.peek().map(|token| token.kind) {
313 Some(TokenKind::Identifier(name)) => {
314 self.next();
315 (Some(label_or_name), name)
316 }
317 _ => (None, label_or_name),
318 };
319
320 let annotation = self.maybe_annotation(TokenKind::Colon)?;
321
322 Ok(Parameter {
323 label,
324 name,
325 annotation,
326 type_: (),
327 })
328 }
329
330 fn maybe_annotation(&mut self, start: TokenKind) -> Result<Option<Annotation>, Error> {
331 if self.maybe_consume(&start).is_none() {
332 Ok(None)
333 } else {
334 self.parse_annotation().map(Some)
335 }
336 }
337
338 fn parse_annotation(&mut self) -> Result<Annotation, Error> {
339 let next = self.expect_token(&["a type annotation"])?;
340 let start = next.location.start;
341 match next.kind {
342 TokenKind::Identifier(name) => {
343 let (generics, end) = if self.maybe_consume(&TokenKind::Less).is_some() {
344 self.sequence(
345 Self::parse_annotation,
346 Some(TokenKind::Comma),
347 TokenKind::Greater,
348 )?
349 } else {
350 (Vec::new(), next.location.end)
351 };
352
353 Ok(Annotation::Name {
354 location: Span { start, end },
355 name,
356 generics,
357 })
358 }
359 TokenKind::LeftParen => {
360 let (elements, end) = self.sequence(
361 Self::parse_annotation,
362 Some(TokenKind::Comma),
363 TokenKind::RightParen,
364 )?;
365 Ok(Annotation::Tuple {
366 location: Span { start, end },
367 elements,
368 })
369 }
370 TokenKind::Star => {
371 let mutability = if self.maybe_consume(&TokenKind::Mut).is_some() {
372 Mutability::Mutable
373 } else {
374 Mutability::Immutable
375 };
376 let underlying = self.parse_annotation()?;
377 Ok(Annotation::Pointer {
378 location: Span {
379 start,
380 end: underlying.location().end,
381 },
382 mutability,
383 underlying: Box::new(underlying),
384 })
385 }
386 TokenKind::LeftSquare => {
387 let token = self.expect_token(&["an array length", "a closing bracket"])?;
388 match token.kind {
389 TokenKind::RightSquare => {
390 let element = self.parse_annotation()?;
391 Ok(Annotation::List {
392 location: Span {
393 start,
394 end: element.location().end,
395 },
396 element: Box::new(element),
397 })
398 }
399 TokenKind::Identifier(name) if name == "_" => {
400 self.expect(TokenKind::RightSquare, &["a closing bracket"])?;
401 let element = self.parse_annotation()?;
402 Ok(Annotation::Array {
403 location: Span {
404 start,
405 end: element.location().end,
406 },
407 length: None,
408 element: Box::new(element),
409 })
410 }
411 TokenKind::Int(length) => {
412 self.expect(TokenKind::RightSquare, &["a closing bracket"])?;
413 let element = self.parse_annotation()?;
414 let length = length.parse().expect("Lexed integers must be valid");
415 Ok(Annotation::Array {
416 location: Span {
417 start,
418 end: element.location().end,
419 },
420 length: Some(length),
421 element: Box::new(element),
422 })
423 }
424 _ => Err(Error::UnexpectedToken {
425 token,
426 expected: vec!["an array length", "a closing bracket"],
427 }),
428 }
429 }
430 TokenKind::LeftBrace => {
431 let key = self.parse_annotation()?;
432 self.expect(TokenKind::Colon, &["a colon"])?;
433 let value = self.parse_annotation()?;
434 let end = self
435 .expect(TokenKind::RightBrace, &["a closing brace"])?
436 .location
437 .end;
438 Ok(Annotation::Map {
439 location: Span { start, end },
440 key: Box::new(key),
441 value: Box::new(value),
442 })
443 }
444 _ => Err(Error::UnexpectedToken {
445 token: next,
446 expected: vec!["a type annotation"],
447 }),
448 }
449 }
450
451 fn parse_statement(&mut self) -> Result<UntypedStatement, Error> {
452 match self.expect_peek(&["a statement"])?.kind {
453 _ => self.parse_expression().map(Statement::Expression),
454 }
455 }
456
457 fn parse_expression(&mut self) -> Result<UntypedExpression, Error> {
458 self.nest();
459 let result = self.do_parse_expression(Precedence::None);
460 self.denest();
461 result
462 }
463
464 fn do_parse_expression(
465 &mut self,
466 target_precedence: Precedence,
467 ) -> Result<UntypedExpression, Error> {
468 use Precedence::*;
469 let mut left = self.parse_expression_unit()?;
470
471 loop {
472 let Some(token) = self.peek() else {
473 return Ok(left);
474 };
475 left = match token.kind {
476 TokenKind::Equals if target_precedence <= Assignment => {
477 self.parse_binary_operation(left, BinaryOperator::Assign, Assignment)
478 }
479 TokenKind::PlusEquals if target_precedence <= Assignment => {
480 self.parse_binary_operation(left, BinaryOperator::AddAssign, Assignment)
481 }
482 TokenKind::MinusEquals if target_precedence <= Assignment => {
483 self.parse_binary_operation(left, BinaryOperator::SubAssign, Assignment)
484 }
485 TokenKind::StarEquals if target_precedence <= Assignment => {
486 self.parse_binary_operation(left, BinaryOperator::MulAssign, Assignment)
487 }
488 TokenKind::SlashEquals if target_precedence <= Assignment => {
489 self.parse_binary_operation(left, BinaryOperator::DivAssign, Assignment)
490 }
491 TokenKind::PercentEquals if target_precedence <= Assignment => {
492 self.parse_binary_operation(left, BinaryOperator::ModAssign, Assignment)
493 }
494 TokenKind::DoubleAmpersand if target_precedence < Logical => {
495 self.parse_binary_operation(left, BinaryOperator::LogicalAnd, Logical)
496 }
497 TokenKind::DoublePipe if target_precedence < Logical => {
498 self.parse_binary_operation(left, BinaryOperator::LogicalOr, Logical)
499 }
500 TokenKind::Less if target_precedence < Comparison => {
501 self.parse_binary_operation(left, BinaryOperator::Less, Comparison)
502 }
503 TokenKind::LessEquals if target_precedence < Comparison => {
504 self.parse_binary_operation(left, BinaryOperator::LessEquals, Comparison)
505 }
506 TokenKind::Greater if target_precedence < Comparison => {
507 self.parse_binary_operation(left, BinaryOperator::Greater, Comparison)
508 }
509 TokenKind::GreaterEquals if target_precedence < Comparison => {
510 self.parse_binary_operation(left, BinaryOperator::GreaterEquals, Comparison)
511 }
512 TokenKind::DoubleEquals if target_precedence < Comparison => {
513 self.parse_binary_operation(left, BinaryOperator::Equal, Comparison)
514 }
515 TokenKind::BangEquals if target_precedence < Comparison => {
516 self.parse_binary_operation(left, BinaryOperator::NotEqual, Comparison)
517 }
518 TokenKind::DoubleLess if target_precedence < Bitwise => {
519 self.parse_binary_operation(left, BinaryOperator::LeftShift, Bitwise)
520 }
521 TokenKind::DoubleGreater if target_precedence < Bitwise => {
522 self.parse_binary_operation(left, BinaryOperator::RightShift, Bitwise)
523 }
524 TokenKind::TripleGreater if target_precedence < Bitwise => {
525 self.parse_binary_operation(left, BinaryOperator::ArithmeticRightShift, Bitwise)
526 }
527 TokenKind::Ampersand if target_precedence < Bitwise => {
528 self.parse_binary_operation(left, BinaryOperator::BitwiseAnd, Bitwise)
529 }
530 TokenKind::Pipe if target_precedence < Bitwise => {
531 self.parse_binary_operation(left, BinaryOperator::BitwiseOr, Bitwise)
532 }
533 TokenKind::Caret if target_precedence < Bitwise => {
534 self.parse_binary_operation(left, BinaryOperator::BitwiseXor, Bitwise)
535 }
536 TokenKind::Plus if target_precedence < Add => {
537 self.parse_binary_operation(left, BinaryOperator::Add, Add)
538 }
539 TokenKind::Minus if target_precedence < Add => {
540 self.parse_binary_operation(left, BinaryOperator::Subtract, Add)
541 }
542 TokenKind::Star if target_precedence < Multiply => {
543 self.parse_binary_operation(left, BinaryOperator::Multiply, Multiply)
544 }
545 TokenKind::Slash if target_precedence < Multiply => {
546 self.parse_binary_operation(left, BinaryOperator::Divide, Multiply)
547 }
548 TokenKind::Percent if target_precedence < Multiply => {
549 self.parse_binary_operation(left, BinaryOperator::Remainder, Multiply)
550 }
551 TokenKind::DoubleStar if target_precedence <= Power => {
552 self.parse_binary_operation(left, BinaryOperator::Power, Power)
553 }
554 TokenKind::DoublePlus if target_precedence < Postfix => {
555 self.next();
556 Ok(Expression::UnaryOperator {
557 location: Span::new(left.location().start, token.location.end),
558 value: Box::new(left),
559 operator: UnaryOperator::Increment,
560 type_: (),
561 })
562 }
563 TokenKind::DoubleMinus if target_precedence < Postfix => {
564 self.next();
565 Ok(Expression::UnaryOperator {
566 location: Span::new(left.location().start, token.location.end),
567 value: Box::new(left),
568 operator: UnaryOperator::Decrement,
569 type_: (),
570 })
571 }
572 TokenKind::Question if target_precedence < Postfix => {
573 self.next();
574 Ok(Expression::UnaryOperator {
575 location: Span::new(left.location().start, token.location.end),
576 value: Box::new(left),
577 operator: UnaryOperator::ErrorPropagation,
578 type_: (),
579 })
580 }
581 TokenKind::LeftBrace
582 if !self.no_braces.last().unwrap_or(&false) && target_precedence < Postfix =>
583 {
584 self.parse_struct(left)
585 }
586 TokenKind::LeftParen if target_precedence < Postfix => self.parse_call(left),
587 TokenKind::Dot if target_precedence < Postfix => self.parse_field_access(left),
588 TokenKind::LeftSquare if target_precedence < Postfix => self.parse_index(left),
589 _ => return Ok(left),
590 }?;
591 }
592 }
593
594 fn parse_struct(&mut self, left: UntypedExpression) -> Result<UntypedExpression, Error> {
595 self.next();
596 let (fields, end) = self.sequence(
597 Self::parse_argument,
598 Some(TokenKind::Comma),
599 TokenKind::RightBrace,
600 )?;
601
602 let location = Span::new(left.location().start, end);
603
604 Ok(Expression::Struct {
605 location,
606 struct_: Box::new(left),
607 fields,
608 type_: (),
609 })
610 }
611
612 fn parse_call(&mut self, left: UntypedExpression) -> Result<UntypedExpression, Error> {
613 self.next();
614 let (arguments, end) = self.sequence(
615 Self::parse_argument,
616 Some(TokenKind::Comma),
617 TokenKind::RightParen,
618 )?;
619
620 let location = Span::new(left.location().start, end);
621
622 Ok(Expression::Call {
623 location,
624 function: Box::new(left),
625 arguments,
626 type_: (),
627 })
628 }
629
630 fn parse_argument(&mut self) -> Result<Argument<UntypedExpression>, Error> {
631 let expression_or_label = self.parse_expression()?;
632 let (label, value) = match expression_or_label {
633 Expression::Variable { name, .. }
634 if self.maybe_consume(&TokenKind::Colon).is_some() =>
635 {
636 let value = self.parse_expression()?;
637 (Some(name), value)
638 }
639 _ => (None, expression_or_label),
640 };
641
642 Ok(Argument { label, value })
643 }
644
645 fn parse_field_access(&mut self, left: UntypedExpression) -> Result<UntypedExpression, Error> {
646 self.next();
647 let (field, field_location) = self.expect_identifier()?;
648 let location = Span::new(left.location().start, field_location.end);
649 Ok(Expression::FieldAccess {
650 location,
651 left: Box::new(left),
652 field,
653 type_: (),
654 })
655 }
656
657 fn parse_index(&mut self, left: UntypedExpression) -> Result<UntypedExpression, Error> {
658 self.next();
659 let index = self.parse_expression()?;
660 let closing_token = self.expect(TokenKind::RightSquare, &["A closing bracket"])?;
661 let location = Span::new(left.location().start, closing_token.location.end);
662 Ok(Expression::Index {
663 location,
664 left: Box::new(left),
665 index: Box::new(index),
666 type_: (),
667 })
668 }
669
670 fn parse_binary_operation(
671 &mut self,
672 left: UntypedExpression,
673 operator: BinaryOperator,
674 precedence: Precedence,
675 ) -> Result<UntypedExpression, Error> {
676 self.next();
677 let right = self.do_parse_expression(precedence)?;
678 Ok(Expression::BinaryOperator {
679 location: Span::new(left.location().start, right.location().end),
680 left: Box::new(left),
681 operator,
682 right: Box::new(right),
683 type_: (),
684 })
685 }
686
687 fn parse_expression_unit(&mut self) -> Result<UntypedExpression, Error> {
688 let next = self.expect_token(&["an expression"])?;
689 match next.kind {
690 TokenKind::Int(value) => {
691 let value = value.parse().expect("Lexed integers must be valid");
692 Ok(Expression::Int {
693 location: next.location,
694 value,
695 })
696 }
697 TokenKind::True => Ok(Expression::Bool {
698 location: next.location,
699 value: true,
700 }),
701 TokenKind::False => Ok(Expression::Bool {
702 location: next.location,
703 value: false,
704 }),
705 TokenKind::Float(value) => {
706 let value = value.parse().expect("Lexed floats must be valid");
707 Ok(Expression::Float {
708 location: next.location,
709 value,
710 })
711 }
712 TokenKind::String(value) => {
713 let value = self.escape_string_value(value, next.location.start)?;
714 Ok(Expression::String {
715 location: next.location,
716 value,
717 })
718 }
719 TokenKind::LeftParen => {
720 let (elements, end) = self.sequence(
721 Self::parse_expression,
722 Some(TokenKind::Comma),
723 TokenKind::RightParen,
724 )?;
725
726 if elements.len() == 1 {
727 let first = elements
728 .into_iter()
729 .next()
730 .expect("Elements has one element");
731 return Ok(Expression::Group {
732 location: Span::new(next.location.start, end),
733 inner: Box::new(first),
734 });
735 }
736
737 Ok(Expression::Tuple {
738 location: Span::new(next.location.start, end),
739 elements,
740 type_: (),
741 })
742 }
743 TokenKind::LeftSquare => {
744 let (elements, end) = self.sequence(
745 Self::parse_expression,
746 Some(TokenKind::Comma),
747 TokenKind::RightSquare,
748 )?;
749 Ok(Expression::Array {
750 location: Span::new(next.location.start, end),
751 elements,
752 type_: (),
753 })
754 }
755 TokenKind::LeftBrace => self.parse_map_or_block(next.location.start),
756 TokenKind::Identifier(name) => Ok(Expression::Variable {
757 location: next.location,
758 name,
759 type_: (),
760 }),
761 TokenKind::Fn => {
762 self.expect(TokenKind::LeftParen, &["an argument list"])?;
763 let (parameters, _) = self.sequence(
764 Self::parse_parameter,
765 Some(TokenKind::Comma),
766 TokenKind::RightParen,
767 )?;
768
769 let return_annotation = self.maybe_annotation(TokenKind::Arrow)?;
770
771 self.expect(TokenKind::LeftBrace, &["a function body"])?;
772
773 let (body, end) =
774 self.sequence(Self::parse_statement, None, TokenKind::RightBrace)?;
775
776 Ok(Expression::Function {
777 location: Span::new(next.location.start, end),
778 parameters,
779 return_annotation,
780 body,
781 type_: (),
782 })
783 }
784 TokenKind::If => self.parse_if(next.location.start),
785 TokenKind::Match => {
786 todo!()
787 }
788 TokenKind::Plus => {
789 let value = self.do_parse_expression(Precedence::Prefix)?;
790 Ok(Expression::UnaryOperator {
791 location: Span::new(next.location.start, value.location().end),
792 value: Box::new(value),
793 operator: UnaryOperator::Plus,
794 type_: (),
795 })
796 }
797 TokenKind::Minus => {
798 let value = self.do_parse_expression(Precedence::Prefix)?;
799 Ok(Expression::UnaryOperator {
800 location: Span::new(next.location.start, value.location().end),
801 value: Box::new(value),
802 operator: UnaryOperator::Minus,
803 type_: (),
804 })
805 }
806 TokenKind::Bang => {
807 let value = self.do_parse_expression(Precedence::Prefix)?;
808 Ok(Expression::UnaryOperator {
809 location: Span::new(next.location.start, value.location().end),
810 value: Box::new(value),
811 operator: UnaryOperator::LogicalNot,
812 type_: (),
813 })
814 }
815 TokenKind::Star => {
816 let value = self.do_parse_expression(Precedence::Prefix)?;
817 Ok(Expression::UnaryOperator {
818 location: Span::new(next.location.start, value.location().end),
819 value: Box::new(value),
820 operator: UnaryOperator::Dereference,
821 type_: (),
822 })
823 }
824 TokenKind::Ampersand => {
825 let operator = if self.maybe_consume(&TokenKind::Mut).is_some() {
826 UnaryOperator::MutableReference
827 } else {
828 UnaryOperator::Reference
829 };
830
831 let value = self.do_parse_expression(Precedence::Prefix)?;
832 Ok(Expression::UnaryOperator {
833 location: Span::new(next.location.start, value.location().end),
834 value: Box::new(value),
835 operator,
836 type_: (),
837 })
838 }
839 TokenKind::Tilde => {
840 let value = self.do_parse_expression(Precedence::Prefix)?;
841 Ok(Expression::UnaryOperator {
842 location: Span::new(next.location.start, value.location().end),
843 value: Box::new(value),
844 operator: UnaryOperator::BitwiseNot,
845 type_: (),
846 })
847 }
848 // Block
849 _ => Err(Error::UnexpectedToken {
850 token: next,
851 expected: vec!["an expression"],
852 }),
853 }
854 }
855
856 fn parse_if(&mut self, start: usize) -> Result<UntypedExpression, Error> {
857 self.no_braces.push(true);
858 let condition = self.do_parse_expression(Precedence::None)?;
859 self.no_braces.pop();
860
861 self.expect(TokenKind::LeftBrace, &["a block"])?;
862 let (body, mut end) = self.sequence(Self::parse_statement, None, TokenKind::RightBrace)?;
863
864 let mut else_branch = None;
865
866 if self.maybe_consume(&TokenKind::Else).is_some() {
867 let next = self.expect_token(&["an if statement", "a block"])?;
868 let else_ = match next.kind {
869 TokenKind::If => self.parse_if(next.location.start)?,
870 TokenKind::LeftBrace => {
871 let (statements, end) =
872 self.sequence(Self::parse_statement, None, TokenKind::RightBrace)?;
873 Expression::Block {
874 location: Span::new(next.location.start, end),
875 statements,
876 }
877 }
878 _ => {
879 return Err(Error::UnexpectedToken {
880 token: next,
881 expected: vec!["an if statement", "a block"],
882 });
883 }
884 };
885
886 end = else_.location().end;
887 else_branch = Some(Box::new(else_));
888 }
889
890 Ok(Expression::If {
891 location: Span { start, end },
892 condition: Box::new(condition),
893 body,
894 else_branch,
895 })
896 }
897
898 fn parse_map_or_block(&mut self, start: usize) -> Result<UntypedExpression, Error> {
899 if let Some(token) = self.maybe_consume(&TokenKind::RightBrace) {
900 return Ok(Expression::Map {
901 location: Span::new(start, token.location.end),
902 elements: Vec::new(),
903 type_: (),
904 });
905 }
906
907 let first = self.parse_statement()?;
908
909 match first {
910 Statement::Expression(key) if self.maybe_consume(&TokenKind::Colon).is_some() => {
911 let value = self.parse_expression()?;
912
913 let (elements, end) = self.sequence_with_start(
914 (key, value),
915 |this| {
916 let key = this.parse_expression()?;
917 this.expect(TokenKind::Colon, &["a colon"])?;
918 let value = this.parse_expression()?;
919 Ok((key, value))
920 },
921 Some(TokenKind::Comma),
922 TokenKind::RightBrace,
923 )?;
924
925 Ok(Expression::Map {
926 location: Span { start, end },
927 elements,
928 type_: (),
929 })
930 }
931 _ => {
932 let (statements, end) = self.sequence_with_start(
933 first,
934 Self::parse_statement,
935 None,
936 TokenKind::RightBrace,
937 )?;
938
939 Ok(Expression::Block {
940 location: Span { start, end },
941 statements,
942 })
943 }
944 }
945 }
946
947 fn escape_string_value(&self, value: EcoString, start: usize) -> Result<EcoString, Error> {
948 let mut out = EcoString::new();
949 let mut chars = value.char_indices();
950 chars.next();
951 while let Some((i, char)) = chars.next() {
952 if char == '"' {
953 break;
954 } else if char == '\\' {
955 let (escape_index, char) = chars
956 .next()
957 .expect("Valid strings do not end in backslashes");
958 match char {
959 '\\' => out.push('\\'),
960 '"' => out.push('"'),
961 'n' => out.push('\n'),
962 't' => out.push('\t'),
963 '\n' => {}
964 _ => {
965 return Err(Error::InvalidEscapeSequence {
966 location: Span::new(start + i, start + escape_index + char.len_utf8()),
967 });
968 }
969 }
970 } else {
971 out.push(char);
972 }
973 }
974 Ok(out)
975 }
976
977 fn sequence<A>(
978 &mut self,
979 parse: impl FnMut(&mut Self) -> Result<A, Error>,
980 delimiter: Option<TokenKind>,
981 end: TokenKind,
982 ) -> Result<(Vec<A>, usize), Error> {
983 self.do_sequence(parse, delimiter, end, Vec::new())
984 }
985
986 fn sequence_with_start<A>(
987 &mut self,
988 start: A,
989 parse: impl FnMut(&mut Self) -> Result<A, Error>,
990 delimiter: Option<TokenKind>,
991 end: TokenKind,
992 ) -> Result<(Vec<A>, usize), Error> {
993 if let Some(delimiter) = &delimiter {
994 if self.maybe_consume(delimiter).is_none() {
995 let end = self.expect(end, &["the end of the list"])?.location.end;
996 return Ok((vec![start], end));
997 }
998 }
999
1000 self.do_sequence(parse, delimiter, end, vec![start])
1001 }
1002
1003 fn do_sequence<A>(
1004 &mut self,
1005 mut parse: impl FnMut(&mut Self) -> Result<A, Error>,
1006 delimiter: Option<TokenKind>,
1007 end: TokenKind,
1008 mut results: Vec<A>,
1009 ) -> Result<(Vec<A>, usize), Error> {
1010 loop {
1011 if self.peek().is_none_or(|token| token.kind == end) {
1012 break;
1013 }
1014 results.push(parse(self)?);
1015 if let Some(delimiter) = &delimiter {
1016 if self.maybe_consume(delimiter).is_none() {
1017 break;
1018 }
1019 }
1020 }
1021
1022 let end = self.expect(end, &["the end of the list"])?.location.end;
1023
1024 Ok((results, end))
1025 }
1026}
1027
1028#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
1029enum Precedence {
1030 None,
1031 Assignment,
1032 Logical,
1033 Comparison,
1034 Bitwise,
1035 Add,
1036 Multiply,
1037 Power,
1038 Prefix,
1039 Postfix,
1040}