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