mon_core/
parser.rs

1//! # MON Parser
2//!
3//! This module provides the `Parser` for the MON language. Its primary responsibility
4//! is to transform a linear sequence of tokens from the [`lexer`](crate::lexer) into a
5//! hierarchical Abstract Syntax Tree (AST), as defined in the [`ast`](crate::ast) module.
6//!
7//! ## Architectural Overview
8//!
9//! The `Parser` is a recursive descent parser. This parsing strategy uses a set of mutually
10//! recursive functions to process the token stream, with each function typically corresponding
11//! to a non-terminal symbol in the MON grammar. For example, `parse_object()`, `parse_array()`,
12//! and `parse_member()` each handle a specific part of the language syntax.
13//!
14//! The parser's entry point is [`Parser::parse_document`], which orchestrates the parsing of
15//! the entire document, including any top-level import statements and the root object.
16//!
17//! The parser does **not** perform semantic validation. It only checks for syntactic
18//! correctness. For example, it will successfully parse `value: *non_existent_anchor`, but the
19//! [`resolver`](crate::resolver) will later flag an error because the anchor does not exist.
20//!
21//! ## Use Cases
22//!
23//! Direct interaction with the parser is less common than using the top-level [`analyze`](crate::api::analyze)
24//! function. However, it can be useful for:
25//!
26//! - **Syntax Tree Inspection:** Building tools that need to analyze the raw structure of a MON
27//!   file without performing full semantic analysis.
28//! - **Custom Analysis Pipelines:** Creating a custom analysis process where the AST needs to be
29//!   inspected or transformed before being passed to the resolver.
30//!
31//! ## Example: Direct Parser Usage
32//!
33//! ```rust
34//! use mon_core::parser::Parser;
35//! use mon_core::error::MonError;
36//!
37//! # fn main() -> Result<(), MonError> {
38//! let source = r#"
39//! {
40//!     // This is a syntactically correct MON file.
41//!     key: "value",
42//!     nested: { flag: on }
43//! }
44//! "#;
45//!
46//! // 1. Create a new parser for the source code.
47//! let mut parser = Parser::new_with_name(source, "my_file.mon".to_string())?;
48//!
49//! // 2. Parse the source into a document (AST).
50//! let document = parser.parse_document()?;
51//!
52//! // The `document` can now be inspected.
53//! assert!(document.imports.is_empty());
54//! // Further processing would be needed to make sense of the values.
55//!
56//! # Ok(())
57//! # }
58//! ```
59use crate::ast::{
60    EnumDef, FieldDef, ImportSpec, ImportSpecifier, ImportStatement, Member, MonDocument, MonValue,
61    MonValueKind, Pair, StructDef, TypeDef, TypeDefinition, TypeSpec,
62};
63use crate::error::{MonError, ParserError};
64use crate::lexer::{Lexer, Token, TokenType};
65use miette::{GraphicalReportHandler, NamedSource, Report};
66use std::panic::Location;
67use std::sync::Arc;
68
69/// A recursive descent parser for the MON language.
70///
71/// The `Parser` takes a stream of tokens from a [`Lexer`] and produces an
72/// Abstract Syntax Tree (AST), represented by a [`MonDocument`]. It is responsible
73/// for enforcing the grammatical structure of the MON language but does not perform
74/// semantic analysis like validation or alias resolution (see [`crate::resolver::Resolver`]).
75///
76/// The main entry point is [`Parser::parse_document`], which parses the entire source.
77///
78/// # Example: How to use the Parser
79///
80/// You can use the `Parser` directly to get the raw AST of a MON file.
81///
82/// ```rust
83/// use mon_core::parser::Parser;
84/// use mon_core::error::MonError;
85///
86/// # fn main() -> Result<(), MonError> {
87/// let source = r#"
88/// import { MyType } from "./types.mon"
89///
90/// {
91///     &my_anchor: { a: 1 },
92///     value :: MyType = *my_anchor
93/// }
94/// "#;
95///
96/// // 1. Create a new parser for the source code.
97/// let mut parser = Parser::new_with_name(source, "my_file.mon".to_string())?;
98///
99/// // 2. Parse the source into a document.
100/// let document = parser.parse_document()?;
101///
102/// // The `document` now contains the raw AST, including imports and the unresolved root object.
103/// assert_eq!(document.imports.len(), 1);
104/// // Further processing would be needed by the resolver to handle the alias and validation.
105///
106/// # Ok(())
107/// # }
108/// ```
109#[derive(Debug)]
110pub struct Parser<'a> {
111    source: Arc<NamedSource<String>>,
112    tokens: Vec<Token>,
113    position: usize,
114    source_text: &'a str,
115}
116
117impl<'a> Parser<'a> {
118    /// Creates a new `Parser` instance with a default file name "source.mon".
119    ///
120    /// This is a convenience method that calls [`Parser::new_with_name`].
121    ///
122    /// # Arguments
123    ///
124    /// * `source_text` - The MON source code as a string.
125    ///
126    /// # Errors
127    ///
128    /// Returns a [`MonError`] if lexing the source text fails.
129    pub fn new(source_text: &'a str) -> Result<Self, MonError> {
130        Self::new_with_name(source_text, "source.mon".to_string())
131    }
132
133    /// Creates a new `Parser` instance with a specified file name.
134    ///
135    /// The parser initializes a [`Lexer`] and filters out whitespace and comments.
136    ///
137    /// # Arguments
138    ///
139    /// * `source_text` - The MON source code as a string.
140    /// * `name` - The name of the file being parsed, used for error reporting.
141    ///
142    /// # Errors
143    ///
144    /// Returns a [`MonError`] if lexing the source text fails.
145    pub fn new_with_name(source_text: &'a str, name: String) -> Result<Self, MonError> {
146        let source = Arc::new(NamedSource::new(name, source_text.to_string()));
147        let mut lexer = Lexer::new(source_text);
148        let tokens: Vec<Token> = lexer
149            .lex()
150            .into_iter()
151            .filter(|t| !matches!(t.ttype, TokenType::Whitespace | TokenType::Comment(_)))
152            .collect();
153
154        Ok(Self {
155            source,
156            tokens,
157            position: 0,
158            source_text,
159        })
160    }
161
162    // === Main Parsing Methods ===
163
164    /// Parses the entire MON source into a [`MonDocument`].
165    ///
166    /// This method parses import statements first, followed by the root object,
167    /// and ensures no unexpected tokens are left at the end of the file.
168    ///
169    /// # Errors
170    ///
171    /// Returns a [`MonError`] if parsing fails at any point.
172    pub fn parse_document(&mut self) -> Result<MonDocument, MonError> {
173        let mut imports: Vec<ImportStatement> = Vec::new();
174
175        // consume zero-or-more import statements
176        while self.check(&TokenType::Import) {
177            let imp = self.parse_import_statement()?;
178            imports.push(imp);
179        }
180
181        // After imports, we expect the root object.
182        let root = self.parse_object()?;
183
184        // After the root object, we expect the end of the file.
185        self.expect(&TokenType::Eof)?;
186        Ok(MonDocument { root, imports })
187    }
188
189    /// Object ::= "{" [ `MemberList` ] "}"
190    /// `MemberList` ::= `Member { , Member } [ , ]`
191    fn parse_object(&mut self) -> Result<MonValue, MonError> {
192        let start_token = self.current_token()?.clone();
193        self.expect(&TokenType::LBrace)?;
194        let mut members = Vec::new();
195        if !self.check(&TokenType::RBrace) {
196            // Parse the first member
197            members.push(self.parse_member()?);
198            // Keep parsing members as long as they are preceded by a comma
199            while self.match_token(&TokenType::Comma) {
200                // If we match a comma but the next token is a brace, it's a trailing comma
201                if self.check(&TokenType::RBrace) {
202                    break;
203                }
204                members.push(self.parse_member()?);
205            }
206        }
207        let end_token = self.current_token()?.clone();
208        self.expect(&TokenType::RBrace)?;
209        Ok(MonValue {
210            kind: MonValueKind::Object(members),
211            anchor: None, // Anchors are attached to values, not objects themselves
212            pos_start: start_token.pos_start,
213            pos_end: end_token.pos_end,
214        })
215    }
216
217    /// Array ::= "[" [ `ValueList` ] "]"
218    /// `ValueList` ::= `Value { , Value } [ , ]`
219    fn parse_array(&mut self) -> Result<MonValue, MonError> {
220        let start_token = self.current_token()?.clone();
221        self.expect(&TokenType::LBracket)?;
222        let mut values = Vec::new();
223        if !self.check(&TokenType::RBracket) {
224            loop {
225                if self.check(&TokenType::Spread) {
226                    let spread_start_token = self.current_token()?.clone();
227                    let spread_name = self.parse_spread()?;
228                    let spread_end_token = self.current_token_before_advance()?.clone(); // Get token before advance
229                    values.push(MonValue {
230                        kind: MonValueKind::ArraySpread(spread_name),
231                        anchor: None,
232                        pos_start: spread_start_token.pos_start,
233                        pos_end: spread_end_token.pos_end,
234                    });
235                } else {
236                    values.push(self.parse_value()?);
237                }
238
239                if !self.match_token(&TokenType::Comma) {
240                    break;
241                }
242                if self.check(&TokenType::RBracket) {
243                    break; // Allow trailing comma
244                }
245            }
246        }
247        let end_token = self.current_token()?.clone();
248        self.expect(&TokenType::RBracket)?;
249        Ok(MonValue {
250            kind: MonValueKind::Array(values),
251            anchor: None,
252            pos_start: start_token.pos_start,
253            pos_end: end_token.pos_end,
254        })
255    }
256
257    /// Value ::= Object | Array | Alias | `EnumValue` | Literal
258    /// Attaches an anchor if one is present.
259    fn parse_value(&mut self) -> Result<MonValue, MonError> {
260        let anchor = self.parse_optional_anchor()?;
261
262        let start_token = self.current_token()?.clone(); // Capture start token for pos_start
263
264        let mut value = match &start_token.ttype.clone() {
265            // Use start_token here
266            TokenType::LBrace => self.parse_object(),
267            TokenType::LBracket => self.parse_array(),
268            TokenType::String(s) => {
269                self.advance();
270                Ok(MonValue {
271                    kind: MonValueKind::String(s.clone()),
272                    anchor: None,
273                    pos_start: start_token.pos_start,
274                    pos_end: start_token.pos_end,
275                })
276            }
277            TokenType::Number(n) => {
278                self.advance();
279                Ok(MonValue {
280                    kind: MonValueKind::Number(*n),
281                    anchor: None,
282                    pos_start: start_token.pos_start,
283                    pos_end: start_token.pos_end,
284                })
285            }
286            TokenType::True => {
287                self.advance();
288                Ok(MonValue {
289                    kind: MonValueKind::Boolean(true),
290                    anchor: None,
291                    pos_start: start_token.pos_start,
292                    pos_end: start_token.pos_end,
293                })
294            }
295            TokenType::False => {
296                self.advance();
297                Ok(MonValue {
298                    kind: MonValueKind::Boolean(false),
299                    anchor: None,
300                    pos_start: start_token.pos_start,
301                    pos_end: start_token.pos_end,
302                })
303            }
304            TokenType::Null => {
305                self.advance();
306                Ok(MonValue {
307                    kind: MonValueKind::Null,
308                    anchor: None,
309                    pos_start: start_token.pos_start,
310                    pos_end: start_token.pos_end,
311                })
312            }
313            TokenType::Asterisk => self.parse_alias(),
314            TokenType::Dollar => self.parse_enum_value(),
315            _ => self.err_unexpected("a value"),
316        }?;
317
318        value.anchor = anchor;
319        Ok(value)
320    }
321
322    /// Member ::= Pair | `TypeDefinition` | Spread
323    fn parse_member(&mut self) -> Result<Member, MonError> {
324        match self.current_token()?.ttype {
325            TokenType::Spread => self.parse_spread().map(Member::Spread),
326            // A TypeDefinition starts with an Identifier followed by a Colon and a Hash
327            TokenType::Identifier(_)
328                if self.peek_is(&TokenType::Colon) && self.peek_next_is(&TokenType::Hash) =>
329            {
330                self.parse_type_definition().map(Member::TypeDefinition)
331            }
332            // Otherwise, it's a regular pair
333            _ => self.parse_pair().map(Member::Pair),
334        }
335    }
336
337    /// Pair ::= `KeyPart` [ Validation ] ( ":" | "=" ) Value
338    /// `KeyPart` ::= [ Anchor ] Key
339    /// Key ::= Identifier | String
340    fn parse_pair(&mut self) -> Result<Pair, MonError> {
341        let mut anchor_from_key: Option<String> = None;
342
343        // Handle the case where the key itself is an anchor, e.g., `&my_anchor: value`
344        let key = if self.match_token(&TokenType::Ampersand) {
345            let key_name = self.parse_key()?;
346            anchor_from_key = Some(key_name.clone());
347            key_name
348        } else {
349            self.parse_key()?
350        };
351
352        let validation = self.parse_optional_validation()?;
353
354        if !self.match_token(&TokenType::Colon) && !self.match_token(&TokenType::Equals) {
355            return self.err_unexpected("':' or '=' after key");
356        }
357
358        let mut value = self.parse_value()?;
359
360        // If the key was an anchor, attach the anchor to the value.
361        // This handles `&anchor: value`.
362        // The `parse_value` function handles the `key: &anchor value` case on its own.
363        if let Some(anchor_name) = anchor_from_key {
364            value.anchor = Some(anchor_name);
365        }
366
367        Ok(Pair {
368            key,
369            value,
370            validation,
371        })
372    }
373
374    // === EBNF Sub-Rules ===
375
376    /// Key ::= Identifier | String
377    fn parse_key(&mut self) -> Result<String, MonError> {
378        let token = self.current_token()?;
379        let mut key_parts = Vec::new();
380
381        match &token.ttype {
382            TokenType::Identifier(s) | TokenType::String(s) => {
383                key_parts.push(s.clone());
384                self.advance();
385            }
386            _ => return self.err_unexpected("an identifier or string for a key"),
387        }
388
389        // Handle dotted keys like `schemas.User`
390        while self.match_token(&TokenType::Dot) {
391            let token = self.current_token()?;
392            if let TokenType::Identifier(s) = &token.ttype {
393                key_parts.push(s.clone());
394                self.advance();
395            } else {
396                return self.err_unexpected("an identifier after a dot in a key");
397            }
398        }
399
400        Ok(key_parts.join("."))
401    }
402
403    /// Anchor ::= "&" Identifier
404    fn parse_optional_anchor(&mut self) -> Result<Option<String>, MonError> {
405        if self.match_token(&TokenType::Ampersand) {
406            let token = self.current_token()?;
407            if let TokenType::Identifier(name) = &token.ttype {
408                let name = name.clone();
409                self.advance();
410                Ok(Some(name))
411            } else {
412                self.err_unexpected("an identifier for the anchor name")
413            }
414        } else {
415            Ok(None)
416        }
417    }
418
419    /// Alias ::= "*" Identifier { "." Identifier }
420    fn parse_alias(&mut self) -> Result<MonValue, MonError> {
421        let start_token = self.current_token()?.clone();
422        self.expect(&TokenType::Asterisk)?;
423        let mut name = self.parse_key()?;
424        let mut end_pos = self.current_token_before_advance()?.pos_end; // End of the first key part
425
426        while self.match_token(&TokenType::Dot) {
427            name.push('.');
428            let key_part = self.parse_key()?;
429            end_pos = self.current_token_before_advance()?.pos_end; // Update end_pos
430            name.push_str(&key_part);
431        }
432        Ok(MonValue {
433            kind: MonValueKind::Alias(name),
434            anchor: None,
435            pos_start: start_token.pos_start,
436            pos_end: end_pos,
437        })
438    }
439
440    /// Spread ::= "..." Alias
441    fn parse_spread(&mut self) -> Result<String, MonError> {
442        self.expect(&TokenType::Spread)?;
443        let alias = self.parse_alias()?;
444        if let MonValueKind::Alias(name) = alias.kind {
445            Ok(name)
446        } else {
447            // This should be unreachable if parse_alias is correct
448            self.err_unexpected("an alias after '...' ")
449        }
450    }
451
452    /// `ImportStatement` ::= "import" ( `NamespaceImport` | `NamedImport` ) "from" String
453    fn parse_import_statement(&mut self) -> Result<ImportStatement, MonError> {
454        let start_token = self.current_token()?.clone(); // Capture start token for pos_start
455        self.expect(&TokenType::Import)?;
456
457        let spec = if self.match_token(&TokenType::Asterisk) {
458            // NamespaceImport ::= "*" "as" Identifier
459            self.expect(&TokenType::As)?;
460            let name = self.parse_key()?;
461            ImportSpec::Namespace(name)
462        } else {
463            // NamedImport ::= "{" [ ImportSpecifier { "," ImportSpecifier } [ "," ] ] "}"
464            self.expect(&TokenType::LBrace)?;
465            let mut specifiers = Vec::new();
466            if !self.check(&TokenType::RBrace) {
467                loop {
468                    // ImportSpecifier ::= [ "&" ] Identifier
469                    let is_anchor = self.match_token(&TokenType::Ampersand);
470                    let name = self.parse_key()?;
471                    specifiers.push(ImportSpecifier { name, is_anchor });
472                    if !self.match_token(&TokenType::Comma) {
473                        break;
474                    }
475                    if self.check(&TokenType::RBrace) {
476                        break;
477                    }
478                }
479            }
480            self.expect(&TokenType::RBrace)?;
481            ImportSpec::Named(specifiers)
482        };
483
484        self.expect(&TokenType::From)?;
485        let path_token = self.current_token()?.clone(); // Capture path token for pos_end
486        let path = self.parse_key()?;
487
488        Ok(ImportStatement {
489            path,
490            spec,
491            pos_start: start_token.pos_start,
492            pos_end: path_token.pos_end,
493        })
494    }
495
496    /// `TypeDefinition` ::= Identifier ":" ( `StructDefinition` | `EnumDefinition` )
497    fn parse_type_definition(&mut self) -> Result<TypeDefinition, MonError> {
498        let name_token = self.current_token()?.clone();
499        let name = self.parse_key()?;
500        self.expect(&TokenType::Colon)?;
501        let hash_token = self.current_token()?.clone();
502        self.expect(&TokenType::Hash)?;
503
504        let token = self.current_token()?;
505        let (def_type, end_pos) = match &token.ttype {
506            TokenType::Identifier(s) if s == "struct" => {
507                self.advance();
508                let mut struct_def = self.parse_struct_definition()?;
509                let end_pos = struct_def.pos_end;
510                struct_def.pos_start = hash_token.pos_start;
511                Ok((TypeDef::Struct(struct_def), end_pos))
512            }
513            TokenType::Identifier(s) if s == "enum" => {
514                self.advance();
515                let mut enum_def = self.parse_enum_definition()?;
516                let end_pos = enum_def.pos_end;
517                enum_def.pos_start = hash_token.pos_start;
518                Ok((TypeDef::Enum(enum_def), end_pos))
519            }
520            _ => self.err_unexpected("'struct' or 'enum' keyword"),
521        }?;
522
523        Ok(TypeDefinition {
524            name,
525            name_span: (
526                name_token.pos_start,
527                name_token.pos_end - name_token.pos_start,
528            )
529                .into(),
530            def_type,
531            pos_start: name_token.pos_start,
532            pos_end: end_pos,
533        })
534    }
535
536    /// `StructDefinition` ::= "{" [ `FieldList` ] "}"
537    fn parse_struct_definition(&mut self) -> Result<StructDef, MonError> {
538        let start_token = self.current_token()?.clone();
539        self.expect(&TokenType::LBrace)?;
540        let mut fields = Vec::new();
541        if !self.check(&TokenType::RBrace) {
542            loop {
543                fields.push(self.parse_field_definition()?);
544                if !self.match_token(&TokenType::Comma) {
545                    break;
546                }
547                if self.check(&TokenType::RBrace) {
548                    break;
549                }
550            }
551        }
552        let end_token = self.current_token()?.clone();
553        self.expect(&TokenType::RBrace)?;
554        Ok(StructDef {
555            fields,
556            pos_start: start_token.pos_start,
557            pos_end: end_token.pos_end,
558        })
559    }
560
561    /// `FieldDefinition` ::= Identifier "(" Type ")" [ "=" Value ]
562    fn parse_field_definition(&mut self) -> Result<FieldDef, MonError> {
563        let name = self.parse_key()?;
564        self.expect(&TokenType::LParen)?;
565        let type_spec = self.parse_type_spec()?;
566        self.expect(&TokenType::RParen)?;
567
568        let default_value = if self.match_token(&TokenType::Equals) {
569            Some(self.parse_value()?)
570        } else {
571            None
572        };
573
574        Ok(FieldDef {
575            name,
576            type_spec,
577            default_value,
578        })
579    }
580
581    /// `EnumDefinition` ::= `{ [ Identifier { , Identifier } [ , ] ] }`
582    fn parse_enum_definition(&mut self) -> Result<EnumDef, MonError> {
583        let start_token = self.current_token()?.clone();
584        self.expect(&TokenType::LBrace)?;
585        let mut variants = Vec::new();
586        if !self.check(&TokenType::RBrace) {
587            loop {
588                variants.push(self.parse_key()?);
589                if !self.match_token(&TokenType::Comma) {
590                    break;
591                }
592                if self.check(&TokenType::RBrace) {
593                    break;
594                }
595            }
596        }
597        let end_token = self.current_token()?.clone();
598        self.expect(&TokenType::RBrace)?;
599        Ok(EnumDef {
600            variants,
601            pos_start: start_token.pos_start,
602            pos_end: end_token.pos_end,
603        })
604    }
605
606    /// Validation ::= "::" Type
607    fn parse_optional_validation(&mut self) -> Result<Option<TypeSpec>, MonError> {
608        if self.match_token(&TokenType::DoubleColon) {
609            self.parse_type_spec().map(Some)
610        } else {
611            Ok(None)
612        }
613    }
614
615    /// Type ::= `CollectionType` | Identifier | "String" | ...
616    fn parse_type_spec(&mut self) -> Result<TypeSpec, MonError> {
617        let start_token = self.current_token()?.clone();
618        if self.check(&TokenType::LBracket) {
619            // CollectionType ::= "[" Type [ "..." ] { "," Type [ "..." ] } "]"
620            self.expect(&TokenType::LBracket)?;
621            let mut types = Vec::new();
622            if !self.check(&TokenType::RBracket) {
623                loop {
624                    let mut type_spec = self.parse_type_spec()?;
625                    if self.match_token(&TokenType::Spread) {
626                        let end_token = self.current_token_before_advance()?.clone();
627                        let span = (
628                            type_spec.get_span().offset(),
629                            end_token.pos_end - type_spec.get_span().offset(),
630                        )
631                            .into();
632                        type_spec = TypeSpec::Spread(Box::new(type_spec), span);
633                    }
634                    types.push(type_spec);
635
636                    if !self.match_token(&TokenType::Comma) {
637                        break;
638                    }
639                    if self.check(&TokenType::RBracket) {
640                        break;
641                    }
642                }
643            }
644            let end_token = self.current_token()?.clone();
645            self.expect(&TokenType::RBracket)?;
646            let span = (
647                start_token.pos_start,
648                end_token.pos_end - start_token.pos_start,
649            )
650                .into();
651            Ok(TypeSpec::Collection(types, span))
652        } else {
653            // Simple Type
654            let name = self.parse_key()?;
655            let end_token = self.current_token_before_advance()?.clone();
656            let span = (
657                start_token.pos_start,
658                end_token.pos_end - start_token.pos_start,
659            )
660                .into();
661            Ok(TypeSpec::Simple(name, span))
662        }
663    }
664
665    /// `EnumValue` ::= "$" Identifier "." Identifier
666    fn parse_enum_value(&mut self) -> Result<MonValue, MonError> {
667        let start_token = self.current_token()?.clone();
668        self.expect(&TokenType::Dollar)?;
669
670        // parse enum name as a single Identifier
671        let enum_token = self.current_token()?.clone();
672        let enum_name = if let TokenType::Identifier(s) = &enum_token.ttype {
673            let s = s.clone();
674            self.advance();
675            s
676        } else {
677            return self.err_unexpected("an identifier for enum name");
678        };
679
680        self.expect(&TokenType::Dot)?;
681
682        // parse variant name as a single Identifier
683        let variant_token = self.current_token()?.clone();
684        let variant_name = if let TokenType::Identifier(s) = &variant_token.ttype {
685            let s = s.clone();
686            self.advance();
687            s
688        } else {
689            return self.err_unexpected("an identifier for enum variant");
690        };
691
692        Ok(MonValue {
693            kind: MonValueKind::EnumValue {
694                enum_name,
695                variant_name,
696            },
697            anchor: None,
698            pos_start: start_token.pos_start,
699            pos_end: variant_token.pos_end,
700        })
701    }
702
703    // === Tokenizer Helper Methods ===
704
705    fn current_token(&self) -> Result<&Token, MonError> {
706        self.tokens.get(self.position).ok_or_else(|| {
707            let pos = self.source_text.len().saturating_sub(1);
708            ParserError::UnexpectedEof {
709                src: (*self.source).clone().into(), // ineficiency is my passion
710                span: (pos, 0).into(),
711            }
712            .into()
713        })
714    }
715
716    fn current_token_before_advance(&self) -> Result<&Token, MonError> {
717        self.tokens
718            .get(self.position.saturating_sub(1))
719            .ok_or_else(|| {
720                let pos = self.source_text.len().saturating_sub(1);
721                ParserError::UnexpectedEof {
722                    src: (*self.source).clone().into(),
723                    span: (pos, 0).into(),
724                }
725                .into()
726            })
727    }
728
729    fn advance(&mut self) {
730        if self.position < self.tokens.len() {
731            self.position += 1;
732        }
733    }
734
735    #[track_caller]
736    fn expect(&mut self, expected: &TokenType) -> Result<(), MonError> {
737        let token = self.current_token()?.clone();
738        if std::mem::discriminant(&token.ttype) == std::mem::discriminant(expected) {
739            self.advance();
740            Ok(())
741        } else {
742            self.err_unexpected(&format!("{expected:?}"))
743        }
744    }
745
746    fn match_token(&mut self, ttype: &TokenType) -> bool {
747        if self.check(ttype) {
748            self.advance();
749            true
750        } else {
751            false
752        }
753    }
754
755    fn check(&self, ttype: &TokenType) -> bool {
756        if let Ok(token) = self.current_token() {
757            std::mem::discriminant(&token.ttype) == std::mem::discriminant(ttype)
758        } else {
759            false
760        }
761    }
762
763    fn peek_is(&self, ttype: &TokenType) -> bool {
764        if let Some(token) = self.tokens.get(self.position + 1) {
765            std::mem::discriminant(&token.ttype) == std::mem::discriminant(ttype)
766        } else {
767            false
768        }
769    }
770
771    fn peek_next_is(&self, ttype: &TokenType) -> bool {
772        if let Some(token) = self.tokens.get(self.position + 2) {
773            std::mem::discriminant(&token.ttype) == std::mem::discriminant(ttype)
774        } else {
775            false
776        }
777    }
778
779    #[track_caller]
780    fn err_unexpected<T>(&self, expected: &str) -> Result<T, MonError> {
781        let token = self.current_token()?;
782        print!("caller: {}", Location::caller());
783        Err(ParserError::UnexpectedToken {
784            src: (*self.source).clone().into(),
785            span: (token.pos_start, token.pos_end - token.pos_start).into(),
786            expected: expected.to_string(),
787        }
788        .into())
789    }
790}
791
792// internal debug function. I really can't stand bad strings
793#[allow(dead_code)]
794fn pretty_result(out: Result<MonDocument, MonError>) -> String {
795    match out {
796        Ok(doc) => format!("{doc:#?}"), // debug format for success
797        Err(err) => {
798            let report: Report = Report::new(err);
799            let handler = GraphicalReportHandler::new(); // pretty ANSI colors
800            let mut buffer = String::new();
801            handler.render_report(&mut buffer, &*report).unwrap();
802            buffer
803        }
804    }
805}
806
807#[cfg(test)]
808#[allow(clippy::match_wildcard_for_single_variants)]
809mod tests {
810    use super::*;
811    use miette::Report;
812
813    impl Member {
814        fn unwrap_pair(self) -> Pair {
815            match self {
816                Member::Pair(p) => p,
817                _ => panic!("Expected Pair, got {self:?}"),
818            }
819        }
820        fn unwrap_type_definition(self) -> TypeDefinition {
821            match self {
822                Member::TypeDefinition(td) => td,
823                _ => panic!("Expected TypeDefinition, got {self:?}"),
824            }
825        }
826    }
827
828    impl MonValueKind {
829        fn unwrap_object(self) -> Vec<Member> {
830            match self {
831                MonValueKind::Object(m) => m,
832                _ => panic!("Expected Object, got {self:?}"),
833            }
834        }
835        #[allow(dead_code)]
836        fn unwrap_array(self) -> Vec<MonValue> {
837            match self {
838                MonValueKind::Array(v) => v,
839                _ => panic!("Expected Array, got {self:?}"),
840            }
841        }
842    }
843
844    fn parse_ok(source: &str) -> MonDocument {
845        let mut parser = Parser::new_with_name(source, "test.mon".to_string()).unwrap();
846        match parser.parse_document() {
847            Ok(doc) => doc,
848            Err(err) => {
849                let report = Report::from(err);
850                panic!("Parsing failed when it should have succeeded:\n{report:?}");
851            }
852        }
853    }
854
855    #[test]
856    fn test_empty_object() {
857        let doc = parse_ok("{}");
858        assert_eq!(doc.root.kind, MonValueKind::Object(vec![]));
859    }
860
861    #[test]
862    fn test_simple_pair() {
863        let doc = parse_ok(r#"{ key: "value" }"#);
864        let members = match doc.root.kind {
865            MonValueKind::Object(m) => m,
866            _ => panic!(),
867        };
868        assert_eq!(members.len(), 1);
869        match &members[0] {
870            Member::Pair(p) => {
871                assert_eq!(p.key, "key");
872                assert!(matches!(p.value.kind, MonValueKind::String(_)));
873            }
874            _ => panic!(),
875        }
876    }
877
878    #[test]
879    fn test_anchor_and_alias() {
880        let doc = parse_ok(r#"{ &anchor1 : 123, key2: *anchor1 }"#);
881        let members = match doc.root.kind {
882            MonValueKind::Object(m) => m,
883            _ => panic!(),
884        };
885        assert_eq!(members.len(), 2);
886        match &members[0] {
887            Member::Pair(p) => {
888                assert_eq!(p.key, "anchor1");
889                assert_eq!(p.value.anchor, Some("anchor1".to_string()));
890            }
891            _ => panic!(),
892        }
893        match &members[1] {
894            Member::Pair(p) => {
895                assert_eq!(p.key, "key2");
896                assert!(matches!(p.value.kind, MonValueKind::Alias(_)));
897            }
898            _ => panic!(),
899        }
900    }
901
902    #[test]
903    fn test_spread() {
904        let doc = parse_ok(r#"{ ...*my_anchor }"#);
905        let members = match doc.root.kind {
906            MonValueKind::Object(m) => m,
907            _ => panic!(),
908        };
909        assert_eq!(members.len(), 1);
910        match &members[0] {
911            Member::Spread(name) => assert_eq!(name, "my_anchor"),
912            _ => panic!(),
913        }
914    }
915
916    #[test]
917    fn test_namespace_import() {
918        let doc = parse_ok(
919            r###"import * as schemas from "./schemas.mon"
920{
921    a: 1
922}"###,
923        );
924        assert!(!doc.imports.is_empty());
925        match &doc.imports[0].spec {
926            ImportSpec::Namespace(name) => assert_eq!(name, "schemas"),
927            _ => panic!("Expected namespace import"),
928        }
929    }
930
931    #[test]
932    fn test_trailing_comma_in_object() {
933        let doc = parse_ok("{ a: 1, b: 2, }");
934        let members = match doc.root.kind {
935            MonValueKind::Object(m) => m,
936            _ => panic!(),
937        };
938        assert_eq!(members.len(), 2);
939    }
940
941    #[test]
942    fn test_trailing_comma_in_array() {
943        let doc = parse_ok("{arr: [ 1, 2, ]}");
944        let members = doc.root.kind.unwrap_object();
945        let pair = members[0].clone().unwrap_pair();
946        let values = match pair.value.kind {
947            MonValueKind::Array(v) => v,
948            _ => panic!("Expected Array"),
949        };
950        assert_eq!(values.len(), 2);
951    }
952
953    #[test]
954    fn test_array_with_spread() {
955        let doc = parse_ok("{arr: [ 1, ...*other, 3 ]}");
956        let members = doc.root.kind.unwrap_object();
957        let pair = members[0].clone().unwrap_pair();
958        let values = match pair.value.kind {
959            MonValueKind::Array(v) => v,
960            _ => panic!("Expected Array"),
961        };
962        assert_eq!(values.len(), 3);
963        assert!(matches!(values[0].kind, MonValueKind::Number(_)));
964        assert!(matches!(values[1].kind, MonValueKind::ArraySpread(_)));
965        assert!(matches!(values[2].kind, MonValueKind::Number(_)));
966    }
967
968    #[test]
969    fn test_all_value_types() {
970        let doc = parse_ok(
971            r#"{ 
972            s: "string",
973            n: 123.45,
974            b1: true,
975            b2: false,
976            nu: null,
977            obj: {},
978            arr: [],
979            alias: *somewhere,
980            enum_val: $MyEnum.Variant
981        }"#,
982        );
983        let members = match doc.root.kind {
984            MonValueKind::Object(m) => m,
985            _ => panic!(),
986        };
987        assert_eq!(members.len(), 9);
988        assert!(matches!(
989            members[0].clone().unwrap_pair().value.kind,
990            MonValueKind::String(_)
991        ));
992        assert!(matches!(
993            members[1].clone().unwrap_pair().value.kind,
994            MonValueKind::Number(_)
995        ));
996        assert!(matches!(
997            members[2].clone().unwrap_pair().value.kind,
998            MonValueKind::Boolean(true)
999        ));
1000        assert!(matches!(
1001            members[3].clone().unwrap_pair().value.kind,
1002            MonValueKind::Boolean(false)
1003        ));
1004        assert!(matches!(
1005            members[4].clone().unwrap_pair().value.kind,
1006            MonValueKind::Null
1007        ));
1008        assert!(matches!(
1009            members[5].clone().unwrap_pair().value.kind,
1010            MonValueKind::Object(_)
1011        ));
1012        assert!(matches!(
1013            members[6].clone().unwrap_pair().value.kind,
1014            MonValueKind::Array(_)
1015        ));
1016        assert!(matches!(
1017            members[7].clone().unwrap_pair().value.kind,
1018            MonValueKind::Alias(_)
1019        ));
1020        assert!(matches!(
1021            members[8].clone().unwrap_pair().value.kind,
1022            MonValueKind::EnumValue { .. }
1023        ));
1024    }
1025
1026    #[test]
1027    fn test_dotted_key() {
1028        let doc = parse_ok(r#"{ a.b.c: 1 }"#);
1029        let pair = doc.root.kind.unwrap_object().remove(0).unwrap_pair();
1030        assert_eq!(pair.key, "a.b.c");
1031    }
1032
1033    #[test]
1034    fn test_string_key() {
1035        let doc = parse_ok(r#"{ "a-b-c": 1 }"#);
1036        let pair = doc.root.kind.unwrap_object().remove(0).unwrap_pair();
1037        assert_eq!(pair.key, "a-b-c");
1038    }
1039
1040    #[test]
1041    fn test_pair_with_equals() {
1042        let doc = parse_ok(r#"{ key = 1 }"#);
1043        let pair = doc.root.kind.unwrap_object().remove(0).unwrap_pair();
1044        assert_eq!(pair.key, "key");
1045        assert!(matches!(pair.value.kind, MonValueKind::Number(_)));
1046    }
1047
1048    #[test]
1049    fn test_named_imports() {
1050        let doc = parse_ok(
1051            r#"import { A, &B, C } from "./types.mon"
1052{
1053    x: 1
1054}"#,
1055        );
1056        assert!(!doc.imports.is_empty());
1057        match &doc.imports[0].spec {
1058            ImportSpec::Named(specifiers) => {
1059                assert_eq!(specifiers.len(), 3);
1060                assert_eq!(specifiers[0].name, "A");
1061                assert!(!specifiers[0].is_anchor);
1062                assert_eq!(specifiers[1].name, "B");
1063                assert!(specifiers[1].is_anchor);
1064                assert_eq!(specifiers[2].name, "C");
1065                assert!(!specifiers[2].is_anchor);
1066            }
1067            _ => panic!("Expected named import"),
1068        }
1069    }
1070
1071    #[test]
1072    fn test_struct_type_definition() {
1073        let doc = parse_ok(
1074            r#"{
1075User: #struct {
1076    name(String),
1077    age(Number) = 30,
1078}
1079}"#,
1080        );
1081        let members = doc.root.kind.unwrap_object();
1082        let td = members[0].clone().unwrap_type_definition();
1083        match td.def_type {
1084            TypeDef::Struct(s) => {
1085                assert_eq!(s.fields.len(), 2);
1086                assert_eq!(s.fields[0].name, "name");
1087                assert!(s.fields[0].default_value.is_none());
1088                assert_eq!(s.fields[1].name, "age");
1089                assert!(s.fields[1].default_value.is_some());
1090            }
1091            _ => panic!("Expected struct definition"),
1092        }
1093    }
1094
1095    #[test]
1096    fn test_enum_type_definition() {
1097        let doc = parse_ok(
1098            r#"{
1099Status: #enum { Active, Inactive, Pending }
1100}"#,
1101        );
1102        let members = doc.root.kind.unwrap_object();
1103        let td = members[0].clone().unwrap_type_definition();
1104        match td.def_type {
1105            TypeDef::Enum(e) => {
1106                assert_eq!(e.variants, vec!["Active", "Inactive", "Pending"]);
1107            }
1108            _ => panic!("Expected enum definition"),
1109        }
1110    }
1111
1112    #[test]
1113    fn test_validation_on_pair() {
1114        let doc = parse_ok(r#"{ key :: Number = 42 }"#);
1115        let pair = doc.root.kind.unwrap_object().remove(0).unwrap_pair();
1116
1117        //                                                              should have been 69
1118        assert_eq!(
1119            pair.validation.unwrap(),
1120            TypeSpec::Simple("Number".into(), (9, 6).into())
1121        )
1122    }
1123
1124    #[test]
1125    fn test_nested_objects_and_arrays() {
1126        let doc = parse_ok(r#"{ obj: { a: 1, b: 2 }, arr: [1, 2, 3] }"#);
1127        let members = doc.root.kind.unwrap_object();
1128        let obj_val = members[0].clone().unwrap_pair().value;
1129        assert!(matches!(obj_val.kind, MonValueKind::Object(_)));
1130        let arr_val = members[1].clone().unwrap_pair().value;
1131        assert!(matches!(arr_val.kind, MonValueKind::Array(_)));
1132    }
1133
1134    #[test]
1135    fn test_enum_value_in_object() {
1136        let doc = parse_ok(r#"{ status: $Status.Active }"#);
1137        let pair = doc.root.kind.unwrap_object().remove(0).unwrap_pair();
1138        match pair.value.kind {
1139            MonValueKind::EnumValue {
1140                enum_name,
1141                variant_name,
1142            } => {
1143                assert_eq!(enum_name, "Status");
1144                assert_eq!(variant_name, "Active");
1145            }
1146            _ => panic!("Expected enum value"),
1147        }
1148    }
1149
1150    #[test]
1151    fn test_complex_document() {
1152        let doc = parse_ok(
1153            r#"
1154import { &A, B } from "./types.mon"
1155
1156{
1157    &anchor1: { x: 1 },
1158    key2: *anchor1,
1159    list: [1, 2, 3, ...*B],
1160    status: $Status.Active
1161}"#,
1162        );
1163        assert_eq!(doc.imports.len(), 1);
1164        let members = doc.root.kind.unwrap_object();
1165        assert_eq!(members.len(), 4);
1166    }
1167}