1use std::{
55 fmt::{Debug, Display},
56 num::{ParseFloatError, ParseIntError},
57 ops::ControlFlow,
58};
59
60use crate::{
61 ast::{
62 Body, Break, Continue, Else, EmptyReturn, Expression, ExternalFunction, For, Function,
63 FunctionArgument, GlobalVariable, If, Item, LeftHandExpression, Literal, LiteralValue,
64 Loop, Program, ReturnDecl, ReturnWithValue, RightHandExpression, Statement, TypeHint,
65 VariableDefinition,
66 },
67 lexer::{Token, TokenKind, Tokenizer},
68 parser::private::Sealed,
69 Error, Location,
70};
71
72mod private {
73 pub trait Sealed {}
74
75 impl Sealed for u32 {}
76 impl Sealed for u64 {}
77 impl Sealed for u128 {}
78 impl Sealed for f32 {}
79 impl Sealed for f64 {}
80}
81
82pub trait IntParser: Sized + Sealed {
84 fn parse(str: &str, radix: u32) -> Result<Self, ParseIntError>;
85}
86
87impl IntParser for u32 {
88 fn parse(str: &str, radix: u32) -> Result<Self, ParseIntError> {
89 u32::from_str_radix(str, radix)
90 }
91}
92impl IntParser for u64 {
93 fn parse(str: &str, radix: u32) -> Result<Self, ParseIntError> {
94 u64::from_str_radix(str, radix)
95 }
96}
97impl IntParser for u128 {
98 fn parse(str: &str, radix: u32) -> Result<Self, ParseIntError> {
99 u128::from_str_radix(str, radix)
100 }
101}
102
103pub trait FloatParser: Sized + Sealed {
105 fn parse(str: &str) -> Result<Self, ParseFloatError>;
106}
107
108impl FloatParser for f32 {
109 fn parse(str: &str) -> Result<Self, ParseFloatError> {
110 str.parse::<f32>()
111 }
112}
113impl FloatParser for f64 {
114 fn parse(str: &str) -> Result<Self, ParseFloatError> {
115 str.parse::<f64>()
116 }
117}
118
119pub trait TypeSet: Debug + Default {
121 type Integer: IntParser + Clone + Copy + PartialEq + Debug;
122 type Float: FloatParser + Clone + Copy + PartialEq + Debug;
123}
124
125#[derive(Debug, Default)]
127pub struct DefaultTypeSet;
128impl Sealed for DefaultTypeSet {}
129
130impl TypeSet for DefaultTypeSet {
131 type Integer = u64;
132 type Float = f64;
133}
134
135#[derive(Debug, Default)]
137pub struct TypeSet32;
138impl Sealed for TypeSet32 {}
139impl TypeSet for TypeSet32 {
140 type Integer = u32;
141 type Float = f32;
142}
143
144#[derive(Debug, Default)]
146pub struct TypeSet128;
147impl Sealed for TypeSet128 {}
148impl TypeSet for TypeSet128 {
149 type Integer = u128;
150 type Float = f64;
151}
152
153impl<T> Program<T>
154where
155 T: TypeSet,
156{
157 fn parse(stream: &mut TokenStream<'_, impl Tokenizer>) -> Result<Self, Error> {
158 let mut items = Vec::new();
159
160 while !stream.end()? {
161 items.push(Item::parse(stream)?);
162 }
163
164 Ok(Program { items })
165 }
166}
167
168impl<T> Item<T>
169where
170 T: TypeSet,
171{
172 fn parse(stream: &mut TokenStream<'_, impl Tokenizer>) -> Result<Self, Error> {
173 if let Some(global_var) = GlobalVariable::try_parse(stream)? {
174 return Ok(Item::GlobalVariable(global_var));
175 }
176 if let Some(function) = ExternalFunction::try_parse(stream)? {
177 return Ok(Item::ExternFunction(function));
178 }
179 if let Some(function) = Function::try_parse(stream)? {
180 return Ok(Item::Function(function));
181 }
182
183 Err(stream.error("Expected global variable or function definition"))
184 }
185}
186
187impl<T> GlobalVariable<T>
188where
189 T: TypeSet,
190{
191 fn try_parse(stream: &mut TokenStream<'_, impl Tokenizer>) -> Result<Option<Self>, Error> {
192 let Some(decl_token) = stream.take_match(TokenKind::Identifier, &["var"])? else {
193 return Ok(None);
194 };
195
196 let identifier = stream.expect_match(TokenKind::Identifier, &[])?;
197 let colon = stream.expect_match(TokenKind::Symbol, &[":"])?;
198 let type_token = TypeHint::parse(stream)?;
199 let equals_token = stream.expect_match(TokenKind::Symbol, &["="])?;
200 let initializer = Expression::Expression {
201 expression: RightHandExpression::parse(stream)?,
202 };
203 let semicolon = stream.expect_match(TokenKind::Symbol, &[";"])?;
204
205 Ok(Some(GlobalVariable {
206 decl_token,
207 identifier,
208 colon,
209 type_token,
210 equals_token,
211 initializer,
212 semicolon,
213 }))
214 }
215}
216
217impl ExternalFunction {
218 fn try_parse(stream: &mut TokenStream<'_, impl Tokenizer>) -> Result<Option<Self>, Error> {
219 let Some(extern_fn_token) = stream.take_match(TokenKind::Identifier, &["extern"])? else {
220 return Ok(None);
221 };
222 let Some(fn_token) = stream.take_match(TokenKind::Identifier, &["fn"])? else {
223 return Ok(None);
224 };
225
226 let name = stream.expect_match(TokenKind::Identifier, &[])?;
227 let opening_paren = stream.expect_match(TokenKind::Symbol, &["("])?;
228
229 let mut arguments = Vec::new();
230 while let Some(arg_name) = stream.take_match(TokenKind::Identifier, &[])? {
231 let colon = stream.expect_match(TokenKind::Symbol, &[":"])?;
232 let reference_token = stream.take_match(TokenKind::Symbol, &["&"])?;
233 let type_token = TypeHint::parse(stream)?;
234
235 arguments.push(FunctionArgument {
236 name: arg_name,
237 colon,
238 reference_token,
239 arg_type: type_token,
240 });
241
242 if stream.take_match(TokenKind::Symbol, &[","])?.is_none() {
243 break;
244 }
245 }
246
247 let closing_paren = stream.expect_match(TokenKind::Symbol, &[")"])?;
248
249 let return_decl =
250 if let Some(return_token) = stream.take_match(TokenKind::Symbol, &["->"])? {
251 Some(ReturnDecl {
252 return_token,
253 return_type: TypeHint::parse(stream)?,
254 })
255 } else {
256 None
257 };
258
259 let semicolon = stream.expect_match(TokenKind::Symbol, &[";"])?;
260
261 Ok(Some(ExternalFunction {
262 extern_fn_token,
263 fn_token,
264 name,
265 opening_paren,
266 arguments,
267 closing_paren,
268 return_decl,
269 semicolon,
270 }))
271 }
272}
273
274impl<T> Function<T>
275where
276 T: TypeSet,
277{
278 fn try_parse(stream: &mut TokenStream<'_, impl Tokenizer>) -> Result<Option<Self>, Error> {
279 let Some(fn_token) = stream.take_match(TokenKind::Identifier, &["fn"])? else {
280 return Ok(None);
281 };
282
283 let name = stream.expect_match(TokenKind::Identifier, &[])?;
284 let opening_paren = stream.expect_match(TokenKind::Symbol, &["("])?;
285
286 let mut arguments = Vec::new();
287 while let Some(arg_name) = stream.take_match(TokenKind::Identifier, &[])? {
288 let colon = stream.expect_match(TokenKind::Symbol, &[":"])?;
289 let reference_token = stream.take_match(TokenKind::Symbol, &["&"])?;
290 let type_token = TypeHint::parse(stream)?;
291
292 arguments.push(FunctionArgument {
293 name: arg_name,
294 colon,
295 reference_token,
296 arg_type: type_token,
297 });
298
299 if stream.take_match(TokenKind::Symbol, &[","])?.is_none() {
300 break;
301 }
302 }
303
304 let closing_paren = stream.expect_match(TokenKind::Symbol, &[")"])?;
305
306 let return_decl =
307 if let Some(return_token) = stream.take_match(TokenKind::Symbol, &["->"])? {
308 Some(ReturnDecl {
309 return_token,
310 return_type: TypeHint::parse(stream)?,
311 })
312 } else {
313 None
314 };
315
316 let body = Body::parse(stream)?;
317
318 Ok(Some(Function {
319 fn_token,
320 name,
321 opening_paren,
322 arguments,
323 closing_paren,
324 return_decl,
325 body,
326 }))
327 }
328}
329
330impl<T> Body<T>
331where
332 T: TypeSet,
333{
334 fn parse(stream: &mut TokenStream<'_, impl Tokenizer>) -> Result<Self, Error> {
335 let opening_brace = stream.expect_match(TokenKind::Symbol, &["{"])?;
336
337 let mut body = Vec::new();
338 while Statement::<T>::matches(stream)? {
339 let (statement, stop) = match Statement::parse(stream)? {
340 ControlFlow::Continue(statement) => (statement, false),
341 ControlFlow::Break(statement) => (statement, true),
342 };
343 body.push(statement);
344 if stop {
345 break;
346 }
347 }
348
349 let closing_brace = stream.expect_match(TokenKind::Symbol, &["}"])?;
350
351 Ok(Body {
352 opening_brace,
353 statements: body,
354 closing_brace,
355 })
356 }
357}
358
359impl TypeHint {
360 fn parse(stream: &mut TokenStream<'_, impl Tokenizer>) -> Result<Self, Error> {
361 let type_name = stream.expect_match(TokenKind::Identifier, &[])?;
362
363 Ok(TypeHint { type_name })
364 }
365}
366
367impl<T> Statement<T>
368where
369 T: TypeSet,
370{
371 fn matches(stream: &mut TokenStream<'_, impl Tokenizer>) -> Result<bool, Error> {
372 stream
373 .peek_match(TokenKind::Symbol, &["}"])
374 .map(|t| t.is_none())
375 }
376
377 fn parse(
378 stream: &mut TokenStream<'_, impl Tokenizer>,
379 ) -> Result<ControlFlow<Self, Self>, Error> {
380 if let Some(return_token) = stream.take_match(TokenKind::Identifier, &["return"])? {
381 let return_kind =
382 if let Some(semicolon) = stream.take_match(TokenKind::Symbol, &[";"])? {
383 Statement::EmptyReturn(EmptyReturn {
385 return_token,
386 semicolon,
387 })
388 } else {
389 let expr = RightHandExpression::parse(stream)?;
390 let semicolon = stream.expect_match(TokenKind::Symbol, &[";"])?;
391 Statement::Return(ReturnWithValue {
392 return_token,
393 expression: expr,
394 semicolon,
395 })
396 };
397
398 return Ok(ControlFlow::Continue(return_kind));
400 }
401
402 if let Some(decl_token) = stream.take_match(TokenKind::Identifier, &["var"])? {
403 let identifier = stream.expect_match(TokenKind::Identifier, &[])?;
404
405 let type_token = if stream.take_match(TokenKind::Symbol, &[":"])?.is_some() {
406 Some(TypeHint::parse(stream)?)
407 } else {
408 None
409 };
410
411 let equals_token = stream.expect_match(TokenKind::Symbol, &["="])?;
412 let expression = RightHandExpression::parse(stream)?;
413 let semicolon = stream.expect_match(TokenKind::Symbol, &[";"])?;
414
415 return Ok(ControlFlow::Continue(Statement::VariableDefinition(
416 VariableDefinition {
417 decl_token,
418 identifier,
419 type_token,
420 equals_token,
421 initializer: expression,
422 semicolon,
423 },
424 )));
425 }
426
427 if let Some(if_token) = stream.take_match(TokenKind::Identifier, &["if"])? {
428 let condition = RightHandExpression::parse(stream)?;
429 let body = Body::parse(stream)?;
430
431 let else_branch =
432 if let Some(else_token) = stream.take_match(TokenKind::Identifier, &["else"])? {
433 let else_body = Body::parse(stream)?;
434
435 Some(Else {
436 else_token,
437 else_body,
438 })
439 } else {
440 None
441 };
442
443 return Ok(ControlFlow::Continue(Statement::If(If {
444 if_token,
445 condition,
446 body,
447 else_branch,
448 })));
449 }
450
451 if let Some(loop_token) = stream.take_match(TokenKind::Identifier, &["loop"])? {
452 let body = Body::parse(stream)?;
453 return Ok(ControlFlow::Continue(Statement::Loop(Loop {
454 loop_token,
455 body,
456 })));
457 }
458
459 if let Some(while_token) = stream.take_match(TokenKind::Identifier, &["while"])? {
460 let condition = RightHandExpression::parse(stream)?;
462 let body = Body::parse(stream)?;
463 return Ok(ControlFlow::Continue(Statement::Loop(Loop {
464 loop_token: while_token,
465 body: Body {
466 opening_brace: body.opening_brace,
467 closing_brace: body.closing_brace,
468 statements: vec![Statement::If(If {
469 if_token: while_token,
470 condition: condition.clone(),
471 body: body.clone(),
472 else_branch: Some(Else {
473 else_token: while_token,
474 else_body: Body {
475 opening_brace: body.opening_brace,
476 closing_brace: body.closing_brace,
477 statements: vec![Statement::Break(Break {
478 break_token: while_token,
479 semicolon: while_token,
480 })],
481 },
482 }),
483 })],
484 },
485 })));
486 }
487
488 if let Some(for_token) = stream.take_match(TokenKind::Identifier, &["for"])? {
489 let variable = stream.expect_match(TokenKind::Identifier, &[])?;
490 let var_type = match stream.take_match(TokenKind::Symbol, &[":"])? {
493 Some(_) => Some(TypeHint::parse(stream)?),
494 None => None,
495 };
496 let in_token = stream.expect_match(TokenKind::Identifier, &["in"])?;
497 let iterable = RightHandExpression::parse(stream)?;
498 let body = Body::parse(stream)?;
499
500 return Ok(ControlFlow::Continue(Statement::For(For {
501 for_token,
502 variable,
503 var_type,
504 in_token,
505 iterable,
506 body,
507 })));
508 }
509
510 if let Some(break_token) = stream.take_match(TokenKind::Identifier, &["break"])? {
511 let semicolon = stream.expect_match(TokenKind::Symbol, &[";"])?;
512 return Ok(ControlFlow::Continue(Statement::Break(Break {
514 break_token,
515 semicolon,
516 })));
517 }
518 if let Some(continue_token) = stream.take_match(TokenKind::Identifier, &["continue"])? {
519 let semicolon = stream.expect_match(TokenKind::Symbol, &[";"])?;
520 return Ok(ControlFlow::Continue(Statement::Continue(Continue {
522 continue_token,
523 semicolon,
524 })));
525 }
526
527 if let Ok(Some(_)) = stream.peek_match(TokenKind::Symbol, &["{"]) {
528 return Ok(ControlFlow::Continue(Statement::Scope(Body::parse(
529 stream,
530 )?)));
531 }
532
533 let save = stream.clone();
534 let expression = Expression::parse(stream)?;
535 match stream.take_match(TokenKind::Symbol, &[";"])? {
536 Some(semicolon) => Ok(ControlFlow::Continue(Statement::Expression {
537 expression,
538 semicolon,
539 })),
540 None => {
541 *stream = save;
543 let expression = RightHandExpression::parse(stream)?;
544
545 Ok(ControlFlow::Break(Statement::ImplicitReturn(expression)))
546 }
547 }
548 }
549}
550
551impl<T> Literal<T>
552where
553 T: TypeSet,
554{
555 fn parse(stream: &mut TokenStream<'_, impl Tokenizer>) -> Result<Self, Error> {
556 let token = stream.peek_expect()?;
557
558 let token_source = stream.source(token.location);
559 let location = token.location;
560
561 let literal_value = match token.kind {
562 TokenKind::BinaryInteger => {
563 let token_source = token_source.replace("_", "");
564 Self::parse_integer_literal(&token_source[2..], 2)
565 .map_err(|_| stream.error("Invalid binary integer literal"))?
566 }
567 TokenKind::DecimalInteger => {
568 let token_source = token_source.replace("_", "");
569 Self::parse_integer_literal(&token_source, 10)
570 .map_err(|_| stream.error("Invalid integer literal"))?
571 }
572 TokenKind::HexInteger => {
573 let token_source = token_source.replace("_", "");
574 Self::parse_integer_literal(&token_source[2..], 16)
575 .map_err(|_| stream.error("Invalid hexadecimal integer literal"))?
576 }
577 TokenKind::Float => {
578 let token_source = token_source.replace("_", "");
579 <T::Float as FloatParser>::parse(&token_source)
580 .map(LiteralValue::Float)
581 .map_err(|_| stream.error("Invalid float literal"))?
582 }
583 TokenKind::String => match unescape(&token_source[1..token_source.len() - 1]) {
584 Ok(string) => LiteralValue::String(string),
585 Err(offset) => {
586 return Err(Error {
587 error: String::from("Invalid escape sequence in string literal")
588 .into_boxed_str(),
589 location: Location {
590 start: token.location.start + offset,
591 end: token.location.start + offset + 1,
592 },
593 });
594 }
595 },
596 TokenKind::Identifier if token_source == "true" => LiteralValue::Boolean(true),
597 TokenKind::Identifier if token_source == "false" => LiteralValue::Boolean(false),
598 _ => return Err(stream.error("Expected literal (number, string, or boolean)")),
599 };
600
601 stream.expect_match(token.kind, &[])?;
602 Ok(Self {
603 value: literal_value,
604 location,
605 })
606 }
607
608 fn parse_integer_literal(
609 token_source: &str,
610 radix: u32,
611 ) -> Result<LiteralValue<T>, ParseIntError> {
612 <T::Integer as IntParser>::parse(token_source, radix).map(LiteralValue::Integer)
613 }
614}
615
616fn unescape(s: &str) -> Result<String, usize> {
617 let mut result = String::new();
618 let mut escaped = false;
619 for (i, c) in s.char_indices().peekable() {
620 if escaped {
621 match c {
622 'n' => result.push('\n'),
623 't' => result.push('\t'),
624 '\\' => result.push('\\'),
625 '"' => result.push('"'),
626 '\'' => result.push('\''),
627 _ => return Err(i), }
629 escaped = false;
630 } else if c == '\\' {
631 escaped = true;
632 } else {
633 result.push(c);
634 }
635 }
636
637 Ok(result)
638}
639
640impl LeftHandExpression {
641 fn parse<T: TypeSet>(stream: &mut TokenStream<'_, impl Tokenizer>) -> Result<Self, Error> {
642 const UNARY_OPERATORS: &[&str] = &["*"];
643 let expr = if let Some(operator) = stream.take_match(TokenKind::Symbol, UNARY_OPERATORS)? {
644 Self::Deref {
645 operator,
646 name: Self::parse_name::<T>(stream)?,
647 }
648 } else {
649 Self::Name {
650 variable: Self::parse_name::<T>(stream)?,
651 }
652 };
653
654 Ok(expr)
655 }
656
657 fn parse_name<T: TypeSet>(
658 stream: &mut TokenStream<'_, impl Tokenizer>,
659 ) -> Result<Token, Error> {
660 let token = stream.peek_expect()?;
661 match token.kind {
662 TokenKind::Identifier => {
663 match Literal::<T>::parse(stream) {
665 Ok(_) => Err(Error {
666 error: "Parse error: Literals are not valid on the left-hand side"
667 .to_string()
668 .into_boxed_str(),
669 location: token.location,
670 }),
671 _ => stream
672 .take_match(TokenKind::Identifier, &[])
673 .map(|v| v.unwrap()),
674 }
675 }
676 _ => Err(stream.error("Expected variable name or deref operator")),
677 }
678 }
679}
680
681impl<T> Expression<T>
682where
683 T: TypeSet,
684{
685 fn parse(stream: &mut TokenStream<'_, impl Tokenizer>) -> Result<Self, Error> {
686 let save = stream.clone();
687
688 let expression = RightHandExpression::<T>::parse(stream)?;
689
690 if let Ok(Some(operator)) = stream.take_match(TokenKind::Symbol, &["="]) {
691 *stream = save;
693 let left_expr = LeftHandExpression::parse::<T>(stream)?;
694 stream.expect_match(TokenKind::Symbol, &["="])?;
695 let right_expr = RightHandExpression::parse(stream)?;
696
697 Ok(Self::Assignment {
698 left_expr,
699 operator,
700 right_expr,
701 })
702 } else {
703 Ok(Self::Expression { expression })
704 }
705 }
706}
707
708impl<T> RightHandExpression<T>
709where
710 T: TypeSet,
711{
712 fn parse(stream: &mut TokenStream<'_, impl Tokenizer>) -> Result<Self, Error> {
713 let operators: &[&[&str]] = &[
717 &["||"],
718 &["&&"],
719 &["<", "<=", ">", ">=", "==", "!="],
720 &["|"],
721 &["^"],
722 &["&"],
723 &["<<", ">>"],
724 &["+", "-"],
725 &["*", "/", "%"],
726 ];
727
728 Self::parse_binary(stream, operators)
729 }
730
731 fn parse_binary(
732 stream: &mut TokenStream<'_, impl Tokenizer>,
733 binary_operators: &[&[&str]],
734 ) -> Result<Self, Error> {
735 let Some((current, higher)) = binary_operators.split_first() else {
736 unreachable!("At least one operator set is expected");
737 };
738
739 let mut expr = if higher.is_empty() {
740 Self::parse_unary(stream)?
741 } else {
742 Self::parse_binary(stream, higher)?
743 };
744
745 while let Some(operator) = stream.take_match(TokenKind::Symbol, current)? {
746 let rhs = if higher.is_empty() {
747 Self::parse_unary(stream)?
748 } else {
749 Self::parse_binary(stream, higher)?
750 };
751
752 expr = Self::BinaryOperator {
753 name: operator,
754 operands: Box::new([expr, rhs]),
755 };
756 }
757
758 Ok(expr)
759 }
760
761 fn parse_unary(stream: &mut TokenStream<'_, impl Tokenizer>) -> Result<Self, Error> {
762 const UNARY_OPERATORS: &[&str] = &["!", "-", "&", "*"];
763 if let Some(operator) = stream.take_match(TokenKind::Symbol, UNARY_OPERATORS)? {
764 let operand = Self::parse_unary(stream)?;
765 Ok(Self::UnaryOperator {
766 name: operator,
767 operand: Box::new(operand),
768 })
769 } else {
770 Self::parse_primary(stream)
771 }
772 }
773
774 fn parse_primary(stream: &mut TokenStream<'_, impl Tokenizer>) -> Result<Self, Error> {
775 let token = stream.peek_expect()?;
776
777 match token.kind {
778 TokenKind::Identifier => {
779 if let Ok(literal) = Literal::<T>::parse(stream) {
781 return Ok(Self::Literal { value: literal });
782 }
783
784 Self::parse_call(stream)
785 }
786 TokenKind::Symbol if stream.source(token.location) == "(" => {
787 stream.take_match(token.kind, &[])?;
788 let expr = Self::parse(stream)?;
789 stream.expect_match(TokenKind::Symbol, &[")"])?;
790 Ok(expr)
791 }
792 TokenKind::HexInteger
793 | TokenKind::DecimalInteger
794 | TokenKind::BinaryInteger
795 | TokenKind::Float
796 | TokenKind::String => Literal::<T>::parse(stream).map(|value| Self::Literal { value }),
797 _ => Err(stream.error("Expected variable, literal, or '('")),
798 }
799 }
800
801 fn parse_call(stream: &mut TokenStream<'_, impl Tokenizer>) -> Result<Self, Error> {
802 let token = stream.expect_match(TokenKind::Identifier, &[])?;
803
804 if stream.take_match(TokenKind::Symbol, &["("])?.is_none() {
805 return Ok(Self::Variable { variable: token });
806 };
807
808 let mut arguments = Vec::new();
809 while stream.peek_match(TokenKind::Symbol, &[")"])?.is_none() {
810 let arg = Self::parse(stream)?;
811 arguments.push(arg);
812
813 if stream.take_match(TokenKind::Symbol, &[","])?.is_none() {
814 break;
815 }
816 }
817 stream.expect_match(TokenKind::Symbol, &[")"])?;
818
819 Ok(Self::FunctionCall {
820 name: token,
821 arguments: arguments.into_boxed_slice(),
822 })
823 }
824}
825
826#[derive(Clone)]
827struct TokenStream<'s, I>
828where
829 I: Tokenizer,
830{
831 source: &'s str,
832 tokens: I,
833}
834
835impl<'s, I> TokenStream<'s, I>
836where
837 I: Tokenizer,
838{
839 fn new(source: &'s str, tokens: I) -> Self {
840 TokenStream { source, tokens }
841 }
842
843 fn skip_comments(&mut self) -> Result<(), Error> {
845 let mut peekable = self.tokens.clone();
846 while let Some(token) = peekable.next() {
847 if token?.kind == TokenKind::Comment {
848 self.tokens = peekable.clone();
849 } else {
850 break;
851 }
852 }
853
854 Ok(())
855 }
856
857 fn end(&mut self) -> Result<bool, Error> {
858 self.skip_comments()?;
859
860 Ok(self.tokens.clone().next().is_none())
861 }
862
863 fn peek(&mut self) -> Result<Option<Token>, Error> {
864 self.skip_comments()?;
865
866 match self.tokens.clone().next() {
867 Some(Ok(token)) => Ok(Some(token)),
868 Some(Err(error)) => Err(error),
869 None => Ok(None),
870 }
871 }
872
873 fn peek_expect(&mut self) -> Result<Token, Error> {
874 self.peek()?.ok_or_else(|| Error {
875 location: Location {
876 start: self.source.len(),
877 end: self.source.len(),
878 },
879 error: String::from("Unexpected end of input").into_boxed_str(),
880 })
881 }
882
883 fn peek_match(
884 &mut self,
885 token_kind: TokenKind,
886 source: &[&str],
887 ) -> Result<Option<Token>, Error> {
888 let Some(token) = self.peek()? else {
889 return Ok(None);
890 };
891
892 let peeked = if token.kind == token_kind
893 && (source.is_empty() || source.contains(&self.source(token.location)))
894 {
895 Some(token)
896 } else {
897 None
898 };
899
900 Ok(peeked)
901 }
902
903 fn take_match(
904 &mut self,
905 token_kind: TokenKind,
906 source: &[&str],
907 ) -> Result<Option<Token>, Error> {
908 self.peek_match(token_kind, source).map(|token| {
909 if let Some(token) = token {
910 self.tokens.next();
911 Some(token)
912 } else {
913 None
914 }
915 })
916 }
917
918 fn expect_match(&mut self, token_kind: TokenKind, source: &[&str]) -> Result<Token, Error> {
924 if let Some(token) = self.take_match(token_kind, source)? {
925 Ok(token)
926 } else {
927 let token = self.peek()?;
928 let found = if let Some(token) = token {
929 if token.kind == token_kind {
930 format!("found '{}'", self.source(token.location))
931 } else {
932 format!("found {:?}", token.kind)
933 }
934 } else {
935 "reached end of input".to_string()
936 };
937 match source {
938 [] => Err(self.error(format_args!("Expected {token_kind:?}, {found}"))),
939 [s] => Err(self.error(format_args!("Expected '{s}', {found}"))),
940 _ => Err(self.error(format_args!("Expected one of {source:?}, {found}"))),
941 }
942 }
943 }
944
945 fn error(&self, message: impl Display) -> Error {
946 Error {
947 error: format!("Parse error: {message}").into_boxed_str(),
948 location: if let Some(Ok(token)) = self.tokens.clone().next() {
949 token.location
950 } else {
951 Location {
952 start: self.source.len(),
953 end: self.source.len(),
954 }
955 },
956 }
957 }
958
959 fn source(&self, location: Location) -> &'s str {
960 location.extract(self.source)
961 }
962}
963
964pub fn parse<T>(source: &str) -> Result<Program<T>, Error>
965where
966 T: TypeSet,
967{
968 let tokens = crate::lexer::tokenize(source);
969 let mut stream = TokenStream::new(source, tokens);
970
971 Program::<T>::parse(&mut stream)
972}
973
974pub fn parse_expression<T>(source: &str) -> Result<Expression<T>, Error>
975where
976 T: TypeSet,
977{
978 let tokens = crate::lexer::tokenize(source);
979 let mut stream = TokenStream::new(source, tokens);
980
981 Expression::<T>::parse(&mut stream)
982}
983
984#[cfg(test)]
985mod tests {
986 use super::*;
987
988 #[test]
989 fn test_unescape() {
990 assert_eq!(unescape(r#"Hello\nWorld\t!"#).unwrap(), "Hello\nWorld\t!");
991 assert_eq!(unescape(r#"Hello\\World"#).unwrap(), "Hello\\World");
992 assert_eq!(unescape(r#"Hello\zWorld"#), Err(6)); }
994
995 #[test]
996 fn test_out_of_range_literal() {
997 let source = "0x100000000";
998
999 let result = parse_expression::<TypeSet32>(source).expect_err("Parsing should fail");
1000 assert_eq!(
1001 "Parse error: Invalid hexadecimal integer literal",
1002 result.error.as_ref()
1003 );
1004 }
1005
1006 #[test]
1007 fn test_grouped_numeric_literal() {
1008 let source = "1_000_000";
1009
1010 let result = parse_expression::<TypeSet32>(source).unwrap();
1011
1012 assert_eq!(source, result.location().extract(source));
1013 }
1014
1015 #[test]
1016 fn test_parse_strings() {
1017 type LitVal = LiteralValue<TypeSet32>;
1018
1019 let test_data = [
1020 (r#""hel_lo""#, Ok(LitVal::String(r#"hel_lo"#.to_string()))),
1021 ("1_000", Ok(LitVal::Integer(1000))),
1022 ("true", Ok(LitVal::Boolean(true))),
1023 ("false", Ok(LitVal::Boolean(false))),
1024 (
1025 "fal_se",
1026 Err("Parse error: Expected literal (number, string, or boolean)"),
1027 ),
1028 ];
1029
1030 for (source, expected) in test_data {
1031 let tokens = crate::lexer::tokenize(source);
1032 let mut stream = TokenStream::new(source, tokens);
1033
1034 let lit = match Literal::<TypeSet32>::parse(&mut stream) {
1035 Ok(lit) => lit,
1036 Err(err) => {
1037 let Err(expected_err) = expected else {
1038 panic!(
1039 "Expected parsing to succeed, but it failed with error: {}",
1040 err
1041 );
1042 };
1043 assert_eq!(expected_err, err.to_string());
1044 continue;
1045 }
1046 };
1047
1048 let Ok(expected) = expected else {
1049 panic!("Expected error, but `{source}` was parsed successfully");
1050 };
1051
1052 match (lit.value, expected) {
1053 (LitVal::Integer(a), LitVal::Integer(b)) => assert_eq!(a, b),
1054 (LitVal::Float(a), LitVal::Float(b)) => assert_eq!(a, b),
1055 (LitVal::String(a), LitVal::String(b)) => assert_eq!(a, b),
1056 (LitVal::Boolean(a), LitVal::Boolean(b)) => assert_eq!(a, b),
1057 _ => panic!("Unexpected literal type"),
1058 }
1059 }
1060 }
1061}