Skip to main content

nwnrs_nwscript/
parser.rs

1use std::{collections::HashSet, error::Error, fmt};
2
3use crate::{
4    AssignmentOp, BinaryOp, BlockStmt, CaseStmt, CompilerErrorCode, Declaration, DefaultStmt,
5    DoWhileStmt, Expr, ExprKind, ExpressionStmt, ForStmt, FunctionDecl, IfStmt, IncludeDirective,
6    Keyword, LangSpec, Literal, MagicLiteral, NamedItem, Parameter, ReturnStmt, Script, SimpleStmt,
7    Span, Stmt, StructDecl, StructFieldDecl, SwitchStmt, Token, TokenKind, TopLevelItem, TypeKind,
8    TypeSpec, UnaryOp, VarDeclarator, WhileStmt,
9    int_literal::{parse_wrapping_decimal_i32, parse_wrapping_prefixed_i32},
10    lexer::{LexerError, lex_source},
11    preprocess::{PreprocessError, preprocess_source_bundle},
12    source::{SourceFile, SourceId},
13};
14
15/// One parser error aligned to the upstream compiler's diagnostic space.
16#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ParserError {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "ParserError",
            "code", &self.code, "span", &self.span, "message", &&self.message)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for ParserError {
    #[inline]
    fn clone(&self) -> ParserError {
        ParserError {
            code: ::core::clone::Clone::clone(&self.code),
            span: ::core::clone::Clone::clone(&self.span),
            message: ::core::clone::Clone::clone(&self.message),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for ParserError {
    #[inline]
    fn eq(&self, other: &ParserError) -> bool {
        self.code == other.code && self.span == other.span &&
            self.message == other.message
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for ParserError {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<CompilerErrorCode>;
        let _: ::core::cmp::AssertParamIsEq<Span>;
        let _: ::core::cmp::AssertParamIsEq<String>;
    }
}Eq)]
17pub struct ParserError {
18    /// Stable upstream-aligned compiler error code.
19    pub code:    CompilerErrorCode,
20    /// Source span where parsing failed.
21    pub span:    Span,
22    /// Human-readable error message.
23    pub message: String,
24}
25
26impl ParserError {
27    fn new(code: CompilerErrorCode, span: Span, message: impl Into<String>) -> Self {
28        Self {
29            code,
30            span,
31            message: message.into(),
32        }
33    }
34}
35
36impl fmt::Display for ParserError {
37    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38        f.write_fmt(format_args!("{0} ({1})", self.message, self.code.code()))write!(f, "{} ({})", self.message, self.code.code())
39    }
40}
41
42impl Error for ParserError {}
43
44/// One parser failure.
45#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ParseError {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            ParseError::Lex(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Lex",
                    &__self_0),
            ParseError::Parse(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Parse",
                    &__self_0),
        }
    }
}Debug)]
46pub enum ParseError {
47    /// Lexing failed before parsing could begin.
48    Lex(LexerError),
49    /// Syntactic parsing failed.
50    Parse(ParserError),
51}
52
53impl fmt::Display for ParseError {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        match self {
56            Self::Lex(error) => error.fmt(f),
57            Self::Parse(error) => error.fmt(f),
58        }
59    }
60}
61
62impl Error for ParseError {}
63
64impl From<LexerError> for ParseError {
65    fn from(value: LexerError) -> Self {
66        Self::Lex(value)
67    }
68}
69
70impl From<ParserError> for ParseError {
71    fn from(value: ParserError) -> Self {
72        Self::Parse(value)
73    }
74}
75
76/// One parser failure after source resolution and preprocessing.
77#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ResolvedParseError {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            ResolvedParseError::Preprocess(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Preprocess", &__self_0),
            ResolvedParseError::Parse(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Parse",
                    &__self_0),
        }
    }
}Debug)]
78pub enum ResolvedParseError {
79    /// Source loading or preprocessing failed.
80    Preprocess(PreprocessError),
81    /// Parsing failed after preprocessing.
82    Parse(ParserError),
83}
84
85impl fmt::Display for ResolvedParseError {
86    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87        match self {
88            Self::Preprocess(error) => error.fmt(f),
89            Self::Parse(error) => error.fmt(f),
90        }
91    }
92}
93
94impl Error for ResolvedParseError {}
95
96impl From<PreprocessError> for ResolvedParseError {
97    fn from(value: PreprocessError) -> Self {
98        Self::Preprocess(value)
99    }
100}
101
102impl From<ParserError> for ResolvedParseError {
103    fn from(value: ParserError) -> Self {
104        Self::Parse(value)
105    }
106}
107
108/// Parses one already-tokenized `NWScript` translation unit.
109///
110/// # Errors
111///
112/// Returns [`ParserError`] if the token stream is syntactically invalid.
113pub fn parse_tokens(
114    tokens: Vec<Token>,
115    langspec: Option<&LangSpec>,
116) -> Result<Script, ParserError> {
117    Parser::new(tokens, langspec).parse_script()
118}
119
120/// Lexes and parses one source file.
121///
122/// # Errors
123///
124/// Returns [`ParseError`] if lexing or parsing fails.
125pub fn parse_source(
126    source: &SourceFile,
127    langspec: Option<&LangSpec>,
128) -> Result<Script, ParseError> {
129    let tokens = lex_source(source)?;
130    parse_tokens(tokens, langspec).map_err(ParseError::from)
131}
132
133/// Lexes and parses a byte buffer associated with `source_id`.
134///
135/// # Errors
136///
137/// Returns [`ParseError`] if lexing or parsing fails.
138pub fn parse_bytes(
139    source_id: SourceId,
140    input: &[u8],
141    langspec: Option<&LangSpec>,
142) -> Result<Script, ParseError> {
143    let tokens = crate::lex_bytes(source_id, input)?;
144    parse_tokens(tokens, langspec).map_err(ParseError::from)
145}
146
147/// Lexes and parses a text buffer associated with `source_id`.
148///
149/// # Errors
150///
151/// Returns [`ParseError`] if lexing or parsing fails.
152pub fn parse_text(
153    source_id: SourceId,
154    input: &str,
155    langspec: Option<&LangSpec>,
156) -> Result<Script, ParseError> {
157    parse_bytes(source_id, input.as_bytes(), langspec)
158}
159
160/// Parses one already-loaded source bundle after include traversal and macro
161/// expansion.
162///
163/// # Errors
164///
165/// Returns [`ResolvedParseError`] if preprocessing or parsing fails.
166pub fn parse_source_bundle(
167    bundle: &crate::SourceBundle,
168    langspec: Option<&LangSpec>,
169) -> Result<Script, ResolvedParseError> {
170    let preprocessed = preprocess_source_bundle(bundle)?;
171    parse_tokens(preprocessed.tokens, langspec).map_err(ResolvedParseError::from)
172}
173
174/// Resolves, preprocesses, and parses one named root script.
175///
176/// # Errors
177///
178/// Returns [`ResolvedParseError`] if resolution, preprocessing, or parsing
179/// fails.
180pub fn parse_resolved_script<R: crate::ScriptResolver + ?Sized>(
181    resolver: &R,
182    root_name: &str,
183    options: crate::SourceLoadOptions,
184    langspec: Option<&LangSpec>,
185) -> Result<Script, ResolvedParseError> {
186    let bundle = crate::load_source_bundle(resolver, root_name, options)?;
187    parse_source_bundle(&bundle, langspec)
188}
189
190struct Parser<'a> {
191    tokens:            Vec<Token>,
192    position:          usize,
193    engine_structures: HashSet<&'a str>,
194}
195
196impl<'a> Parser<'a> {
197    fn new(tokens: Vec<Token>, langspec: Option<&'a LangSpec>) -> Self {
198        let engine_structures = langspec
199            .map(|spec| {
200                spec.engine_structures
201                    .iter()
202                    .map(String::as_str)
203                    .collect::<HashSet<_>>()
204            })
205            .unwrap_or_default();
206        Self {
207            tokens,
208            position: 0,
209            engine_structures,
210        }
211    }
212
213    fn parse_script(mut self) -> Result<Script, ParserError> {
214        let mut items = Vec::new();
215        while !self.at_eof() {
216            if self.matches_keyword(Keyword::Include) {
217                items.push(TopLevelItem::Include(self.parse_include_directive()?));
218                continue;
219            }
220            items.push(self.parse_top_level_item()?);
221        }
222        Ok(Script {
223            items,
224        })
225    }
226
227    fn parse_include_directive(&mut self) -> Result<IncludeDirective, ParserError> {
228        let include = self.consume_keyword(
229            Keyword::Include,
230            CompilerErrorCode::UnknownStateInCompiler,
231            "expected #include",
232        )?;
233        let path = self.consume_string(
234            CompilerErrorCode::UnknownStateInCompiler,
235            "expected string literal after #include",
236        )?;
237        Ok(IncludeDirective {
238            span: join_spans(include.span, path.span),
239            path: path.text,
240        })
241    }
242
243    fn parse_top_level_item(&mut self) -> Result<TopLevelItem, ParserError> {
244        let ty = self.parse_any_type_specifier()?;
245
246        if #[allow(non_exhaustive_omitted_patterns)] match ty.kind {
    TypeKind::Struct(_) => true,
    _ => false,
}matches!(ty.kind, TypeKind::Struct(_)) && self.matches_kind(&TokenKind::LeftBrace) {
247            return self.parse_struct_definition(&ty).map(TopLevelItem::Struct);
248        }
249
250        let name = self.consume_identifier(
251            CompilerErrorCode::FunctionDefinitionMissingName,
252            "expected identifier after type specifier",
253        )?;
254
255        if self.matches_kind(&TokenKind::LeftParen) {
256            return self
257                .parse_function_declaration_or_definition(ty, name)
258                .map(TopLevelItem::Function);
259        }
260
261        let declaration = self.parse_declaration_after_name(ty, name)?;
262        Ok(TopLevelItem::Global(declaration))
263    }
264
265    fn parse_struct_definition(&mut self, ty: &TypeSpec) -> Result<StructDecl, ParserError> {
266        let name = match &ty.kind {
267            TypeKind::Struct(name) => name.clone(),
268            _ => {
269                return Err(ParserError::new(
270                    CompilerErrorCode::BadTypeSpecifier,
271                    ty.span,
272                    "struct definition requires a named struct type specifier",
273                ));
274            }
275        };
276
277        self.consume_kind(
278            TokenKind::LeftBrace,
279            CompilerErrorCode::BadTypeSpecifier,
280            "expected { after struct name",
281        )?;
282
283        let mut fields = Vec::new();
284        while !self.matches_kind(&TokenKind::RightBrace) && !self.at_eof() {
285            let field_type = self.parse_non_void_type_specifier()?;
286            let names = self.parse_struct_field_names()?;
287            let semicolon = self.consume_kind(
288                TokenKind::Semicolon,
289                CompilerErrorCode::NoSemicolonAfterExpression,
290                "expected ; after struct field declaration",
291            )?;
292            fields.push(StructFieldDecl {
293                span: join_spans(field_type.span, semicolon.span),
294                ty: field_type,
295                names,
296            });
297        }
298
299        self.consume_kind(
300            TokenKind::RightBrace,
301            CompilerErrorCode::BadTypeSpecifier,
302            "expected } after struct body",
303        )?;
304        let semicolon = self.consume_kind(
305            TokenKind::Semicolon,
306            CompilerErrorCode::NoSemicolonAfterStructure,
307            "expected ; after struct declaration",
308        )?;
309
310        Ok(StructDecl {
311            span: join_spans(ty.span, semicolon.span),
312            name,
313            fields,
314        })
315    }
316
317    fn parse_struct_field_names(&mut self) -> Result<Vec<NamedItem>, ParserError> {
318        let mut names = Vec::new();
319        loop {
320            let name = self.consume_identifier(
321                CompilerErrorCode::ParsingVariableList,
322                "expected field name",
323            )?;
324            names.push(NamedItem {
325                span: name.span,
326                name: name.text,
327            });
328            if !self.matches_kind(&TokenKind::Comma) {
329                break;
330            }
331            self.advance();
332        }
333        Ok(names)
334    }
335
336    fn parse_function_declaration_or_definition(
337        &mut self,
338        return_type: TypeSpec,
339        name: Token,
340    ) -> Result<FunctionDecl, ParserError> {
341        self.consume_kind(
342            TokenKind::LeftParen,
343            CompilerErrorCode::FunctionDefinitionMissingParameterList,
344            "expected ( after function name",
345        )?;
346        let parameters = self.parse_parameter_list()?;
347        self.consume_kind(
348            TokenKind::RightParen,
349            CompilerErrorCode::MalformedParameterList,
350            "expected ) after parameter list",
351        )?;
352
353        if self.matches_kind(&TokenKind::Semicolon) {
354            let semicolon = self.advance_required(
355                CompilerErrorCode::NoSemicolonAfterExpression,
356                "expected ; after parameter list",
357            )?;
358            return Ok(FunctionDecl {
359                span: join_spans(return_type.span, semicolon.span),
360                return_type,
361                name: name.text,
362                parameters,
363                body: None,
364            });
365        }
366
367        if !self.matches_kind(&TokenKind::LeftBrace) {
368            return Err(self.error_here(
369                CompilerErrorCode::UnknownStateInCompiler,
370                "expected ; or function body after parameter list",
371            ));
372        }
373
374        let body = self.parse_block_statement()?;
375        Ok(FunctionDecl {
376            span: join_spans(return_type.span, body.span),
377            return_type,
378            name: name.text,
379            parameters,
380            body: Some(body),
381        })
382    }
383
384    fn parse_parameter_list(&mut self) -> Result<Vec<Parameter>, ParserError> {
385        let mut parameters = Vec::new();
386        if self.matches_kind(&TokenKind::RightParen) {
387            return Ok(parameters);
388        }
389
390        loop {
391            let ty = self.parse_non_void_type_specifier()?;
392            let name = self.consume_identifier(
393                CompilerErrorCode::BadVariableName,
394                "expected parameter name",
395            )?;
396            let default = if self.matches_kind(&TokenKind::Assign) {
397                self.advance();
398                Some(self.parse_parameter_default_value()?)
399            } else {
400                None
401            };
402            let end_span = default.as_ref().map_or(name.span, |expr| expr.span);
403            parameters.push(Parameter {
404                span: join_spans(ty.span, end_span),
405                ty,
406                name: name.text,
407                default,
408            });
409
410            if !self.matches_kind(&TokenKind::Comma) {
411                break;
412            }
413            self.advance();
414        }
415
416        Ok(parameters)
417    }
418
419    fn parse_parameter_default_value(&mut self) -> Result<Expr, ParserError> {
420        self.parse_expression()
421    }
422
423    fn parse_any_type_specifier(&mut self) -> Result<TypeSpec, ParserError> {
424        if self.matches_keyword(Keyword::Void) {
425            let token = self.advance_required(
426                CompilerErrorCode::InvalidDeclarationType,
427                "expected void token",
428            )?;
429            return Ok(TypeSpec {
430                span:     token.span,
431                is_const: false,
432                kind:     TypeKind::Void,
433            });
434        }
435        self.parse_non_void_type_specifier()
436    }
437
438    fn parse_non_void_type_specifier(&mut self) -> Result<TypeSpec, ParserError> {
439        let const_token = if self.matches_keyword(Keyword::Const) {
440            self.advance()
441        } else {
442            None
443        };
444        let is_const = const_token.is_some();
445
446        let token = self.peek().cloned().ok_or_else(|| {
447            self.error_here(
448                CompilerErrorCode::InvalidDeclarationType,
449                "unexpected EOF in type specifier",
450            )
451        })?;
452
453        let kind = match token.kind {
454            TokenKind::Keyword(Keyword::Int) => {
455                self.advance();
456                TypeKind::Int
457            }
458            TokenKind::Keyword(Keyword::Float) => {
459                self.advance();
460                TypeKind::Float
461            }
462            TokenKind::Keyword(Keyword::String) => {
463                self.advance();
464                TypeKind::String
465            }
466            TokenKind::Keyword(Keyword::Object) => {
467                if is_const {
468                    return Err(ParserError::new(
469                        CompilerErrorCode::InvalidTypeForConstKeyword,
470                        token.span,
471                        "const is only valid for int, float, and string declarations",
472                    ));
473                }
474                self.advance();
475                TypeKind::Object
476            }
477            TokenKind::Keyword(Keyword::Vector) => {
478                if is_const {
479                    return Err(ParserError::new(
480                        CompilerErrorCode::InvalidTypeForConstKeyword,
481                        token.span,
482                        "const is only valid for int, float, and string declarations",
483                    ));
484                }
485                self.advance();
486                TypeKind::Vector
487            }
488            TokenKind::Keyword(Keyword::Struct) => {
489                if is_const {
490                    return Err(ParserError::new(
491                        CompilerErrorCode::InvalidTypeForConstKeyword,
492                        token.span,
493                        "const is not valid on struct declarations",
494                    ));
495                }
496                self.advance();
497                let name = self.consume_identifier(
498                    CompilerErrorCode::InvalidDeclarationType,
499                    "expected struct name after struct",
500                )?;
501                return Ok(TypeSpec {
502                    span: join_spans(
503                        const_token.map_or(token.span, |token| token.span),
504                        name.span,
505                    ),
506                    is_const,
507                    kind: TypeKind::Struct(name.text),
508                });
509            }
510            TokenKind::Identifier if self.is_engine_structure_name(&token) => {
511                if is_const {
512                    return Err(ParserError::new(
513                        CompilerErrorCode::InvalidTypeForConstKeyword,
514                        token.span,
515                        "const is not valid on engine structure declarations",
516                    ));
517                }
518                self.advance();
519                TypeKind::EngineStructure(token.text)
520            }
521            _ => {
522                return Err(ParserError::new(
523                    if is_const {
524                        CompilerErrorCode::InvalidTypeForConstKeyword
525                    } else {
526                        CompilerErrorCode::InvalidDeclarationType
527                    },
528                    token.span,
529                    "expected a non-void type specifier",
530                ));
531            }
532        };
533
534        let start_span = const_token.map_or(token.span, |token| token.span);
535        Ok(TypeSpec {
536            span: join_spans(start_span, token.span),
537            is_const,
538            kind,
539        })
540    }
541
542    fn parse_declaration_after_name(
543        &mut self,
544        ty: TypeSpec,
545        first_name: Token,
546    ) -> Result<Declaration, ParserError> {
547        let mut declarators = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [self.parse_declarator_after_name(first_name)?]))vec![self.parse_declarator_after_name(first_name)?];
548        while self.matches_kind(&TokenKind::Comma) {
549            self.advance();
550            let name = self.consume_identifier(
551                CompilerErrorCode::ParsingVariableList,
552                "expected variable name after comma",
553            )?;
554            declarators.push(self.parse_declarator_after_name(name)?);
555        }
556        let semicolon = self.consume_kind(
557            TokenKind::Semicolon,
558            CompilerErrorCode::NoSemicolonAfterExpression,
559            "expected ; after declaration",
560        )?;
561        Ok(Declaration {
562            span: join_spans(ty.span, semicolon.span),
563            ty,
564            declarators,
565        })
566    }
567
568    fn parse_declarator_after_name(&mut self, name: Token) -> Result<VarDeclarator, ParserError> {
569        let initializer = if self.matches_kind(&TokenKind::Assign) {
570            self.advance();
571            Some(self.parse_expression()?)
572        } else {
573            None
574        };
575        let end_span = initializer.as_ref().map_or(name.span, |expr| expr.span);
576        Ok(VarDeclarator {
577            span: join_spans(name.span, end_span),
578            name: name.text,
579            initializer,
580        })
581    }
582
583    fn parse_block_statement(&mut self) -> Result<BlockStmt, ParserError> {
584        let left_brace = self.consume_kind(
585            TokenKind::LeftBrace,
586            CompilerErrorCode::ProgramCompoundStatementAtStart,
587            "expected {",
588        )?;
589        let mut statements = Vec::new();
590        while !self.matches_kind(&TokenKind::RightBrace) && !self.at_eof() {
591            statements.push(self.parse_statement()?);
592        }
593        let right_brace = self.consume_kind(
594            TokenKind::RightBrace,
595            CompilerErrorCode::UnexpectedEndCompoundStatement,
596            "expected } at end of compound statement",
597        )?;
598        Ok(BlockStmt {
599            span: join_spans(left_brace.span, right_brace.span),
600            statements,
601        })
602    }
603
604    fn parse_statement(&mut self) -> Result<Stmt, ParserError> {
605        if self.matches_kind(&TokenKind::LeftBrace) {
606            return self.parse_block_statement().map(Stmt::Block);
607        }
608        if self.matches_keyword(Keyword::If) {
609            return self.parse_if_statement().map(Stmt::If);
610        }
611        if self.matches_keyword(Keyword::Else) {
612            return Err(self.error_here(
613                CompilerErrorCode::ElseWithoutCorrespondingIf,
614                "else without corresponding if",
615            ));
616        }
617        if self.matches_keyword(Keyword::Switch) {
618            return self.parse_switch_statement().map(Stmt::Switch);
619        }
620        if self.matches_keyword(Keyword::Return) {
621            return self.parse_return_statement().map(Stmt::Return);
622        }
623        if self.matches_keyword(Keyword::While) {
624            return self.parse_while_statement().map(Stmt::While);
625        }
626        if self.matches_keyword(Keyword::Do) {
627            return self.parse_do_while_statement().map(Stmt::DoWhile);
628        }
629        if self.matches_keyword(Keyword::For) {
630            return self.parse_for_statement().map(Stmt::For);
631        }
632        if self.matches_keyword(Keyword::Case) {
633            return self.parse_case_statement().map(Stmt::Case);
634        }
635        if self.matches_keyword(Keyword::Default) {
636            return self.parse_default_statement().map(Stmt::Default);
637        }
638        if self.matches_keyword(Keyword::Break) {
639            let keyword = self.advance_required(
640                CompilerErrorCode::NoSemicolonAfterStatement,
641                "expected break token",
642            )?;
643            let semicolon = self.consume_kind(
644                TokenKind::Semicolon,
645                CompilerErrorCode::NoSemicolonAfterStatement,
646                "expected ; after break",
647            )?;
648            return Ok(Stmt::Break(SimpleStmt {
649                span: join_spans(keyword.span, semicolon.span),
650            }));
651        }
652        if self.matches_keyword(Keyword::Continue) {
653            let keyword = self.advance_required(
654                CompilerErrorCode::NoSemicolonAfterStatement,
655                "expected continue token",
656            )?;
657            let semicolon = self.consume_kind(
658                TokenKind::Semicolon,
659                CompilerErrorCode::NoSemicolonAfterStatement,
660                "expected ; after continue",
661            )?;
662            return Ok(Stmt::Continue(SimpleStmt {
663                span: join_spans(keyword.span, semicolon.span),
664            }));
665        }
666        if self.matches_kind(&TokenKind::Semicolon) {
667            let semicolon =
668                self.advance_required(CompilerErrorCode::NoSemicolonAfterStatement, "expected ;")?;
669            return Ok(Stmt::Empty(SimpleStmt {
670                span: semicolon.span,
671            }));
672        }
673        if self.starts_non_void_type_specifier() {
674            return self.parse_statement_declaration().map(Stmt::Declaration);
675        }
676
677        let expr = self.parse_expression()?;
678        let semicolon = self.consume_kind(
679            TokenKind::Semicolon,
680            CompilerErrorCode::NoSemicolonAfterExpression,
681            "expected ; after expression",
682        )?;
683        Ok(Stmt::Expression(ExpressionStmt {
684            span: join_spans(expr.span, semicolon.span),
685            expr,
686        }))
687    }
688
689    fn parse_statement_declaration(&mut self) -> Result<Declaration, ParserError> {
690        let ty = self.parse_non_void_type_specifier()?;
691        let name = self.consume_identifier(
692            CompilerErrorCode::ParsingVariableList,
693            "expected variable name in declaration",
694        )?;
695        self.parse_declaration_after_name(ty, name)
696    }
697
698    fn parse_if_statement(&mut self) -> Result<IfStmt, ParserError> {
699        let if_token = self.consume_keyword(
700            Keyword::If,
701            CompilerErrorCode::UnknownStateInCompiler,
702            "expected if",
703        )?;
704        self.consume_kind(
705            TokenKind::LeftParen,
706            CompilerErrorCode::NoLeftBracketOnExpression,
707            "expected ( after if",
708        )?;
709        let condition = self.parse_expression()?;
710        self.consume_kind(
711            TokenKind::RightParen,
712            CompilerErrorCode::NoRightBracketOnExpression,
713            "expected ) after if condition",
714        )?;
715        let then_branch = self.parse_statement()?;
716        if #[allow(non_exhaustive_omitted_patterns)] match then_branch {
    Stmt::Empty(_) => true,
    _ => false,
}matches!(then_branch, Stmt::Empty(_)) {
717            return Err(ParserError::new(
718                CompilerErrorCode::IfConditionCannotBeFollowedByANullStatement,
719                if_token.span,
720                "if condition cannot be followed by an empty statement",
721            ));
722        }
723        let else_branch = if self.matches_keyword(Keyword::Else) {
724            self.advance();
725            let branch = self.parse_statement()?;
726            if #[allow(non_exhaustive_omitted_patterns)] match branch {
    Stmt::Empty(_) => true,
    _ => false,
}matches!(branch, Stmt::Empty(_)) {
727                return Err(ParserError::new(
728                    CompilerErrorCode::ElseCannotBeFollowedByANullStatement,
729                    if_token.span,
730                    "else cannot be followed by an empty statement",
731                ));
732            }
733            Some(Box::new(branch))
734        } else {
735            None
736        };
737        let end_span = else_branch
738            .as_ref()
739            .map_or_else(|| then_branch.span(), |stmt| stmt.span());
740        Ok(IfStmt {
741            span: join_spans(if_token.span, end_span),
742            condition,
743            then_branch: Box::new(then_branch),
744            else_branch,
745        })
746    }
747
748    fn parse_switch_statement(&mut self) -> Result<SwitchStmt, ParserError> {
749        let switch_token = self.consume_keyword(
750            Keyword::Switch,
751            CompilerErrorCode::UnknownStateInCompiler,
752            "expected switch",
753        )?;
754        self.consume_kind(
755            TokenKind::LeftParen,
756            CompilerErrorCode::NoLeftBracketOnExpression,
757            "expected ( after switch",
758        )?;
759        let condition = self.parse_expression()?;
760        self.consume_kind(
761            TokenKind::RightParen,
762            CompilerErrorCode::NoRightBracketOnExpression,
763            "expected ) after switch condition",
764        )?;
765        let body = self.parse_statement()?;
766        if #[allow(non_exhaustive_omitted_patterns)] match body {
    Stmt::Empty(_) => true,
    _ => false,
}matches!(body, Stmt::Empty(_)) {
767            return Err(ParserError::new(
768                CompilerErrorCode::SwitchConditionCannotBeFollowedByANullStatement,
769                switch_token.span,
770                "switch condition cannot be followed by an empty statement",
771            ));
772        }
773        Ok(SwitchStmt {
774            span: join_spans(switch_token.span, body.span()),
775            condition,
776            body: Box::new(body),
777        })
778    }
779
780    fn parse_return_statement(&mut self) -> Result<ReturnStmt, ParserError> {
781        let return_token = self.consume_keyword(
782            Keyword::Return,
783            CompilerErrorCode::UnknownStateInCompiler,
784            "expected return",
785        )?;
786        if self.matches_kind(&TokenKind::Semicolon) {
787            let semicolon = self.advance_required(
788                CompilerErrorCode::ParsingReturnStatement,
789                "expected ; after return",
790            )?;
791            return Ok(ReturnStmt {
792                span:  join_spans(return_token.span, semicolon.span),
793                value: None,
794            });
795        }
796        let value = self.parse_expression()?;
797        let semicolon = self.consume_kind(
798            TokenKind::Semicolon,
799            CompilerErrorCode::ParsingReturnStatement,
800            "expected ; after return value",
801        )?;
802        Ok(ReturnStmt {
803            span:  join_spans(return_token.span, semicolon.span),
804            value: Some(value),
805        })
806    }
807
808    fn parse_while_statement(&mut self) -> Result<WhileStmt, ParserError> {
809        let while_token = self.consume_keyword(
810            Keyword::While,
811            CompilerErrorCode::UnknownStateInCompiler,
812            "expected while",
813        )?;
814        self.consume_kind(
815            TokenKind::LeftParen,
816            CompilerErrorCode::NoLeftBracketOnExpression,
817            "expected ( after while",
818        )?;
819        let condition = self.parse_expression()?;
820        self.consume_kind(
821            TokenKind::RightParen,
822            CompilerErrorCode::NoRightBracketOnExpression,
823            "expected ) after while condition",
824        )?;
825        let body = self.parse_statement()?;
826        if #[allow(non_exhaustive_omitted_patterns)] match body {
    Stmt::Empty(_) => true,
    _ => false,
}matches!(body, Stmt::Empty(_)) {
827            return Err(ParserError::new(
828                CompilerErrorCode::WhileConditionCannotBeFollowedByANullStatement,
829                while_token.span,
830                "while condition cannot be followed by an empty statement",
831            ));
832        }
833        Ok(WhileStmt {
834            span: join_spans(while_token.span, body.span()),
835            condition,
836            body: Box::new(body),
837        })
838    }
839
840    fn parse_do_while_statement(&mut self) -> Result<DoWhileStmt, ParserError> {
841        let do_token = self.consume_keyword(
842            Keyword::Do,
843            CompilerErrorCode::UnknownStateInCompiler,
844            "expected do",
845        )?;
846        let body = self.parse_statement()?;
847        self.consume_keyword(
848            Keyword::While,
849            CompilerErrorCode::NoWhileAfterDoKeyword,
850            "expected while after do body",
851        )?;
852        self.consume_kind(
853            TokenKind::LeftParen,
854            CompilerErrorCode::NoLeftBracketOnExpression,
855            "expected ( after while in do-while statement",
856        )?;
857        let condition = self.parse_expression()?;
858        self.consume_kind(
859            TokenKind::RightParen,
860            CompilerErrorCode::NoRightBracketOnExpression,
861            "expected ) after do-while condition",
862        )?;
863        let semicolon = self.consume_kind(
864            TokenKind::Semicolon,
865            CompilerErrorCode::NoSemicolonAfterExpression,
866            "expected ; after do-while statement",
867        )?;
868        Ok(DoWhileStmt {
869            span: join_spans(do_token.span, semicolon.span),
870            body: Box::new(body),
871            condition,
872        })
873    }
874
875    fn parse_for_statement(&mut self) -> Result<ForStmt, ParserError> {
876        let for_token = self.consume_keyword(
877            Keyword::For,
878            CompilerErrorCode::UnknownStateInCompiler,
879            "expected for",
880        )?;
881        self.consume_kind(
882            TokenKind::LeftParen,
883            CompilerErrorCode::NoLeftBracketOnExpression,
884            "expected ( after for",
885        )?;
886        let initializer = if self.matches_kind(&TokenKind::Semicolon) {
887            None
888        } else {
889            Some(self.parse_expression()?)
890        };
891        self.consume_kind(
892            TokenKind::Semicolon,
893            CompilerErrorCode::NoSemicolonAfterExpression,
894            "expected ; after for initializer",
895        )?;
896        let condition = if self.matches_kind(&TokenKind::Semicolon) {
897            None
898        } else {
899            Some(self.parse_expression()?)
900        };
901        self.consume_kind(
902            TokenKind::Semicolon,
903            CompilerErrorCode::NoSemicolonAfterExpression,
904            "expected ; after for condition",
905        )?;
906        let update = if self.matches_kind(&TokenKind::RightParen) {
907            None
908        } else {
909            Some(self.parse_expression()?)
910        };
911        self.consume_kind(
912            TokenKind::RightParen,
913            CompilerErrorCode::NoRightBracketOnExpression,
914            "expected ) after for update expression",
915        )?;
916        let body = self.parse_statement()?;
917        if #[allow(non_exhaustive_omitted_patterns)] match body {
    Stmt::Empty(_) => true,
    _ => false,
}matches!(body, Stmt::Empty(_)) {
918            return Err(ParserError::new(
919                CompilerErrorCode::ForStatementCannotBeFollowedByANullStatement,
920                for_token.span,
921                "for statement cannot be followed by an empty statement",
922            ));
923        }
924        Ok(ForStmt {
925            span: join_spans(for_token.span, body.span()),
926            initializer,
927            condition,
928            update,
929            body: Box::new(body),
930        })
931    }
932
933    fn parse_case_statement(&mut self) -> Result<CaseStmt, ParserError> {
934        let case_token = self.consume_keyword(
935            Keyword::Case,
936            CompilerErrorCode::UnknownStateInCompiler,
937            "expected case",
938        )?;
939        let value = self.parse_conditional_expression()?;
940        let colon = self.consume_kind(
941            TokenKind::Colon,
942            CompilerErrorCode::NoColonAfterCaseLabel,
943            "expected : after case expression",
944        )?;
945        Ok(CaseStmt {
946            span: join_spans(case_token.span, colon.span),
947            value,
948        })
949    }
950
951    fn parse_default_statement(&mut self) -> Result<DefaultStmt, ParserError> {
952        let token = self.consume_keyword(
953            Keyword::Default,
954            CompilerErrorCode::UnknownStateInCompiler,
955            "expected default",
956        )?;
957        let colon = self.consume_kind(
958            TokenKind::Colon,
959            CompilerErrorCode::NoColonAfterDefaultLabel,
960            "expected : after default",
961        )?;
962        Ok(DefaultStmt {
963            span: join_spans(token.span, colon.span),
964        })
965    }
966
967    fn parse_expression(&mut self) -> Result<Expr, ParserError> {
968        self.parse_assignment_expression()
969    }
970
971    fn parse_assignment_expression(&mut self) -> Result<Expr, ParserError> {
972        let left = self.parse_conditional_expression()?;
973        let Some(op) = self.current_assignment_op() else {
974            return Ok(left);
975        };
976        self.advance();
977        let right = self.parse_conditional_expression()?;
978        Ok(Expr {
979            span: join_spans(left.span, right.span),
980            kind: ExprKind::Assignment {
981                op,
982                left: Box::new(left),
983                right: Box::new(right),
984            },
985        })
986    }
987
988    fn parse_conditional_expression(&mut self) -> Result<Expr, ParserError> {
989        let condition = self.parse_logical_or_expression()?;
990        if !self.matches_kind(&TokenKind::QuestionMark) {
991            return Ok(condition);
992        }
993        self.advance();
994        let when_true = self.parse_conditional_expression()?;
995        self.consume_kind(
996            TokenKind::Colon,
997            CompilerErrorCode::ConditionalRequiresSecondExpression,
998            "expected : in conditional expression",
999        )?;
1000        let when_false = self.parse_conditional_expression()?;
1001        Ok(Expr {
1002            span: join_spans(condition.span, when_false.span),
1003            kind: ExprKind::Conditional {
1004                condition:  Box::new(condition),
1005                when_true:  Box::new(when_true),
1006                when_false: Box::new(when_false),
1007            },
1008        })
1009    }
1010
1011    fn parse_logical_or_expression(&mut self) -> Result<Expr, ParserError> {
1012        self.parse_left_associative_binary(
1013            Self::parse_logical_and_expression,
1014            &[(TokenKind::LogicalOr, BinaryOp::LogicalOr)],
1015        )
1016    }
1017
1018    fn parse_logical_and_expression(&mut self) -> Result<Expr, ParserError> {
1019        self.parse_left_associative_binary(
1020            Self::parse_inclusive_or_expression,
1021            &[(TokenKind::LogicalAnd, BinaryOp::LogicalAnd)],
1022        )
1023    }
1024
1025    fn parse_inclusive_or_expression(&mut self) -> Result<Expr, ParserError> {
1026        self.parse_left_associative_binary(
1027            Self::parse_exclusive_or_expression,
1028            &[(TokenKind::InclusiveOr, BinaryOp::InclusiveOr)],
1029        )
1030    }
1031
1032    fn parse_exclusive_or_expression(&mut self) -> Result<Expr, ParserError> {
1033        self.parse_left_associative_binary(
1034            Self::parse_boolean_and_expression,
1035            &[(TokenKind::ExclusiveOr, BinaryOp::ExclusiveOr)],
1036        )
1037    }
1038
1039    fn parse_boolean_and_expression(&mut self) -> Result<Expr, ParserError> {
1040        self.parse_left_associative_binary(
1041            Self::parse_equality_expression,
1042            &[(TokenKind::BooleanAnd, BinaryOp::BooleanAnd)],
1043        )
1044    }
1045
1046    fn parse_equality_expression(&mut self) -> Result<Expr, ParserError> {
1047        self.parse_left_associative_binary(
1048            Self::parse_relational_expression,
1049            &[
1050                (TokenKind::NotEqual, BinaryOp::NotEqual),
1051                (TokenKind::EqualEqual, BinaryOp::EqualEqual),
1052            ],
1053        )
1054    }
1055
1056    fn parse_relational_expression(&mut self) -> Result<Expr, ParserError> {
1057        self.parse_left_associative_binary(
1058            Self::parse_shift_expression,
1059            &[
1060                (TokenKind::GreaterEqual, BinaryOp::GreaterEqual),
1061                (TokenKind::LessEqual, BinaryOp::LessEqual),
1062                (TokenKind::LessThan, BinaryOp::LessThan),
1063                (TokenKind::GreaterThan, BinaryOp::GreaterThan),
1064            ],
1065        )
1066    }
1067
1068    fn parse_shift_expression(&mut self) -> Result<Expr, ParserError> {
1069        self.parse_left_associative_binary(
1070            Self::parse_additive_expression,
1071            &[
1072                (TokenKind::ShiftLeft, BinaryOp::ShiftLeft),
1073                (TokenKind::ShiftRight, BinaryOp::ShiftRight),
1074                (TokenKind::UnsignedShiftRight, BinaryOp::UnsignedShiftRight),
1075            ],
1076        )
1077    }
1078
1079    fn parse_additive_expression(&mut self) -> Result<Expr, ParserError> {
1080        self.parse_left_associative_binary(
1081            Self::parse_multiplicative_expression,
1082            &[
1083                (TokenKind::Plus, BinaryOp::Add),
1084                (TokenKind::Minus, BinaryOp::Subtract),
1085            ],
1086        )
1087    }
1088
1089    fn parse_multiplicative_expression(&mut self) -> Result<Expr, ParserError> {
1090        self.parse_left_associative_binary(
1091            Self::parse_unary_expression,
1092            &[
1093                (TokenKind::Multiply, BinaryOp::Multiply),
1094                (TokenKind::Divide, BinaryOp::Divide),
1095                (TokenKind::Modulus, BinaryOp::Modulus),
1096            ],
1097        )
1098    }
1099
1100    fn parse_unary_expression(&mut self) -> Result<Expr, ParserError> {
1101        let Some(token) = self.peek().cloned() else {
1102            return Err(self.error_here(
1103                CompilerErrorCode::UnknownStateInCompiler,
1104                "unexpected EOF in expression",
1105            ));
1106        };
1107
1108        let op = match token.kind {
1109            TokenKind::Minus => Some(UnaryOp::Negate),
1110            TokenKind::Tilde => Some(UnaryOp::OnesComplement),
1111            TokenKind::BooleanNot => Some(UnaryOp::BooleanNot),
1112            TokenKind::Increment => Some(UnaryOp::PreIncrement),
1113            TokenKind::Decrement => Some(UnaryOp::PreDecrement),
1114            TokenKind::Plus => None,
1115            _ => return self.parse_postfix_expression(),
1116        };
1117
1118        self.advance();
1119        let expr = self.parse_postfix_expression()?;
1120        if #[allow(non_exhaustive_omitted_patterns)] match token.kind {
    TokenKind::Plus => true,
    _ => false,
}matches!(token.kind, TokenKind::Plus) {
1121            return Ok(expr);
1122        }
1123        Ok(Expr {
1124            span: join_spans(token.span, expr.span),
1125            kind: ExprKind::Unary {
1126                op:   op.ok_or_else(|| {
1127                    self.error_here(
1128                        CompilerErrorCode::UnknownStateInCompiler,
1129                        "missing unary operator",
1130                    )
1131                })?,
1132                expr: Box::new(expr),
1133            },
1134        })
1135    }
1136
1137    fn parse_postfix_expression(&mut self) -> Result<Expr, ParserError> {
1138        let mut expr = self.parse_primary_expression()?;
1139        loop {
1140            if self.matches_kind(&TokenKind::StructurePartSpecify) {
1141                self.advance();
1142                let field = self.consume_identifier(
1143                    CompilerErrorCode::UndefinedFieldInStructure,
1144                    "expected field name after .",
1145                )?;
1146                expr = Expr {
1147                    span: join_spans(expr.span, field.span),
1148                    kind: ExprKind::FieldAccess {
1149                        base:  Box::new(expr),
1150                        field: field.text,
1151                    },
1152                };
1153                continue;
1154            }
1155            if self.matches_kind(&TokenKind::Increment) {
1156                let token = self.advance_required(
1157                    CompilerErrorCode::UnknownStateInCompiler,
1158                    "expected increment token",
1159                )?;
1160                expr = Expr {
1161                    span: join_spans(expr.span, token.span),
1162                    kind: ExprKind::Unary {
1163                        op:   UnaryOp::PostIncrement,
1164                        expr: Box::new(expr),
1165                    },
1166                };
1167                continue;
1168            }
1169            if self.matches_kind(&TokenKind::Decrement) {
1170                let token = self.advance_required(
1171                    CompilerErrorCode::UnknownStateInCompiler,
1172                    "expected decrement token",
1173                )?;
1174                expr = Expr {
1175                    span: join_spans(expr.span, token.span),
1176                    kind: ExprKind::Unary {
1177                        op:   UnaryOp::PostDecrement,
1178                        expr: Box::new(expr),
1179                    },
1180                };
1181                continue;
1182            }
1183            break;
1184        }
1185        Ok(expr)
1186    }
1187
1188    fn parse_primary_expression(&mut self) -> Result<Expr, ParserError> {
1189        let token = self.peek().cloned().ok_or_else(|| {
1190            self.error_here(
1191                CompilerErrorCode::UnknownStateInCompiler,
1192                "unexpected EOF in expression",
1193            )
1194        })?;
1195
1196        match token.kind {
1197            TokenKind::Integer
1198            | TokenKind::HexInteger
1199            | TokenKind::BinaryInteger
1200            | TokenKind::OctalInteger
1201            | TokenKind::Float
1202            | TokenKind::String
1203            | TokenKind::LeftSquareBracket
1204            | TokenKind::Keyword(
1205                Keyword::ObjectSelf
1206                | Keyword::ObjectInvalid
1207                | Keyword::LocationInvalid
1208                | Keyword::JsonNull
1209                | Keyword::JsonFalse
1210                | Keyword::JsonTrue
1211                | Keyword::JsonObject
1212                | Keyword::JsonArray
1213                | Keyword::JsonString
1214                | Keyword::FunctionMacro
1215                | Keyword::FileMacro
1216                | Keyword::LineMacro
1217                | Keyword::DateMacro
1218                | Keyword::TimeMacro,
1219            ) => self.parse_literal_expression(),
1220            TokenKind::LeftParen => {
1221                let left = self
1222                    .advance_required(CompilerErrorCode::NoLeftBracketOnExpression, "expected (")?;
1223                let expr = self.parse_expression()?;
1224                let right = self.consume_kind(
1225                    TokenKind::RightParen,
1226                    CompilerErrorCode::NoRightBracketOnExpression,
1227                    "expected ) after parenthesized expression",
1228                )?;
1229                Ok(Expr {
1230                    span: join_spans(left.span, right.span),
1231                    kind: expr.kind,
1232                })
1233            }
1234            TokenKind::Identifier => {
1235                let identifier = self
1236                    .advance_required(CompilerErrorCode::BadVariableName, "expected identifier")?;
1237                let mut expr = Expr {
1238                    span: identifier.span,
1239                    kind: ExprKind::Identifier(identifier.text),
1240                };
1241                if self.matches_kind(&TokenKind::LeftParen) {
1242                    let (arguments, end_span) = self.parse_argument_list()?;
1243                    expr = Expr {
1244                        span: join_spans(expr.span, end_span),
1245                        kind: ExprKind::Call {
1246                            callee: Box::new(expr),
1247                            arguments,
1248                        },
1249                    };
1250                }
1251                Ok(expr)
1252            }
1253            _ => Err(ParserError::new(
1254                CompilerErrorCode::UnknownStateInCompiler,
1255                token.span,
1256                "unexpected token in expression",
1257            )),
1258        }
1259    }
1260
1261    fn parse_argument_list(&mut self) -> Result<(Vec<Expr>, Span), ParserError> {
1262        let left_paren = self.consume_kind(
1263            TokenKind::LeftParen,
1264            CompilerErrorCode::NoLeftBracketOnArgList,
1265            "expected ( before argument list",
1266        )?;
1267        let mut arguments = Vec::new();
1268        if self.matches_kind(&TokenKind::RightParen) {
1269            let right =
1270                self.advance_required(CompilerErrorCode::MalformedParameterList, "expected )")?;
1271            return Ok((arguments, join_spans(left_paren.span, right.span)));
1272        }
1273
1274        loop {
1275            arguments.push(self.parse_expression()?);
1276            if self.matches_kind(&TokenKind::RightParen) {
1277                let right =
1278                    self.advance_required(CompilerErrorCode::MalformedParameterList, "expected )")?;
1279                return Ok((arguments, join_spans(left_paren.span, right.span)));
1280            }
1281            self.consume_kind(
1282                TokenKind::Comma,
1283                CompilerErrorCode::UnknownStateInCompiler,
1284                "expected , or ) in argument list",
1285            )?;
1286        }
1287    }
1288
1289    fn parse_literal_expression(&mut self) -> Result<Expr, ParserError> {
1290        let token = self.peek().cloned().ok_or_else(|| {
1291            self.error_here(
1292                CompilerErrorCode::BadConstantType,
1293                "unexpected EOF in literal",
1294            )
1295        })?;
1296
1297        let (span, literal) = match token.kind {
1298            TokenKind::Integer => {
1299                self.advance();
1300                (token.span, Literal::Integer(parse_decimal_integer(&token)?))
1301            }
1302            TokenKind::HexInteger => {
1303                self.advance();
1304                (
1305                    token.span,
1306                    Literal::Integer(parse_prefixed_integer(&token, 16)?),
1307                )
1308            }
1309            TokenKind::BinaryInteger => {
1310                self.advance();
1311                (
1312                    token.span,
1313                    Literal::Integer(parse_prefixed_integer(&token, 2)?),
1314                )
1315            }
1316            TokenKind::OctalInteger => {
1317                self.advance();
1318                (
1319                    token.span,
1320                    Literal::Integer(parse_prefixed_integer(&token, 8)?),
1321                )
1322            }
1323            TokenKind::Float => {
1324                self.advance();
1325                let value = token.text.parse::<f32>().map_err(|_error| {
1326                    ParserError::new(
1327                        CompilerErrorCode::BadConstantType,
1328                        token.span,
1329                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("invalid floating-point literal {0:?}",
                token.text))
    })format!("invalid floating-point literal {:?}", token.text),
1330                    )
1331                })?;
1332                (token.span, Literal::Float(value))
1333            }
1334            TokenKind::String => {
1335                self.advance();
1336                (token.span, Literal::String(token.text))
1337            }
1338            TokenKind::LeftSquareBracket => self.parse_vector_literal()?,
1339            TokenKind::Keyword(Keyword::ObjectSelf) => {
1340                self.advance();
1341                (token.span, Literal::ObjectSelf)
1342            }
1343            TokenKind::Keyword(Keyword::ObjectInvalid) => {
1344                self.advance();
1345                (token.span, Literal::ObjectInvalid)
1346            }
1347            TokenKind::Keyword(Keyword::LocationInvalid) => {
1348                self.advance();
1349                (token.span, Literal::LocationInvalid)
1350            }
1351            TokenKind::Keyword(Keyword::JsonNull) => {
1352                self.advance();
1353                (token.span, Literal::Json("null".to_string()))
1354            }
1355            TokenKind::Keyword(Keyword::JsonFalse) => {
1356                self.advance();
1357                (token.span, Literal::Json("false".to_string()))
1358            }
1359            TokenKind::Keyword(Keyword::JsonTrue) => {
1360                self.advance();
1361                (token.span, Literal::Json("true".to_string()))
1362            }
1363            TokenKind::Keyword(Keyword::JsonObject) => {
1364                self.advance();
1365                (token.span, Literal::Json("{}".to_string()))
1366            }
1367            TokenKind::Keyword(Keyword::JsonArray) => {
1368                self.advance();
1369                (token.span, Literal::Json("[]".to_string()))
1370            }
1371            TokenKind::Keyword(Keyword::JsonString) => {
1372                self.advance();
1373                (token.span, Literal::Json("\"\"".to_string()))
1374            }
1375            TokenKind::Keyword(Keyword::FunctionMacro) => {
1376                self.advance();
1377                (token.span, Literal::Magic(MagicLiteral::Function))
1378            }
1379            TokenKind::Keyword(Keyword::FileMacro) => {
1380                self.advance();
1381                (token.span, Literal::Magic(MagicLiteral::File))
1382            }
1383            TokenKind::Keyword(Keyword::LineMacro) => {
1384                self.advance();
1385                (token.span, Literal::Magic(MagicLiteral::Line))
1386            }
1387            TokenKind::Keyword(Keyword::DateMacro) => {
1388                self.advance();
1389                (token.span, Literal::Magic(MagicLiteral::Date))
1390            }
1391            TokenKind::Keyword(Keyword::TimeMacro) => {
1392                self.advance();
1393                (token.span, Literal::Magic(MagicLiteral::Time))
1394            }
1395            _ => {
1396                return Err(ParserError::new(
1397                    CompilerErrorCode::BadConstantType,
1398                    token.span,
1399                    "unexpected token in literal expression",
1400                ));
1401            }
1402        };
1403        Ok(Expr {
1404            span,
1405            kind: ExprKind::Literal(literal),
1406        })
1407    }
1408
1409    fn parse_vector_literal(&mut self) -> Result<(Span, Literal), ParserError> {
1410        let left = self.consume_kind(
1411            TokenKind::LeftSquareBracket,
1412            CompilerErrorCode::ParsingConstantVector,
1413            "expected [ to start vector literal",
1414        )?;
1415        let mut values = [0.0_f32; 3];
1416        let mut count = 0;
1417
1418        if self.matches_kind(&TokenKind::RightSquareBracket) {
1419            let right =
1420                self.advance_required(CompilerErrorCode::ParsingConstantVector, "expected ]")?;
1421            return Ok((join_spans(left.span, right.span), Literal::Vector(values)));
1422        }
1423
1424        loop {
1425            let token = self.consume_kind(
1426                TokenKind::Float,
1427                CompilerErrorCode::ParsingConstantVector,
1428                "expected float literal in vector constant",
1429            )?;
1430            if count >= 3 {
1431                return Err(ParserError::new(
1432                    CompilerErrorCode::ParsingConstantVector,
1433                    token.span,
1434                    "vector literal cannot contain more than three elements",
1435                ));
1436            }
1437            let value = token.text.parse::<f32>().map_err(|_error| {
1438                ParserError::new(
1439                    CompilerErrorCode::ParsingConstantVector,
1440                    token.span,
1441                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("invalid vector component {0:?}",
                token.text))
    })format!("invalid vector component {:?}", token.text),
1442                )
1443            })?;
1444            let Some(slot) = values.get_mut(count) else {
1445                return Err(ParserError::new(
1446                    CompilerErrorCode::ParsingConstantVector,
1447                    token.span,
1448                    "vector literal cannot contain more than three elements",
1449                ));
1450            };
1451            *slot = value;
1452            count += 1;
1453            if self.matches_kind(&TokenKind::RightSquareBracket) {
1454                let right =
1455                    self.advance_required(CompilerErrorCode::ParsingConstantVector, "expected ]")?;
1456                return Ok((join_spans(left.span, right.span), Literal::Vector(values)));
1457            }
1458            self.consume_kind(
1459                TokenKind::Comma,
1460                CompilerErrorCode::ParsingConstantVector,
1461                "expected , or ] in vector constant",
1462            )?;
1463        }
1464    }
1465
1466    fn parse_left_associative_binary(
1467        &mut self,
1468        subparser: fn(&mut Self) -> Result<Expr, ParserError>,
1469        operators: &[(TokenKind, BinaryOp)],
1470    ) -> Result<Expr, ParserError> {
1471        let mut expr = subparser(self)?;
1472        while let Some(op) = self.current_binary_op(operators) {
1473            self.advance();
1474            let right = subparser(self)?;
1475            expr = Expr {
1476                span: join_spans(expr.span, right.span),
1477                kind: ExprKind::Binary {
1478                    op,
1479                    left: Box::new(expr),
1480                    right: Box::new(right),
1481                },
1482            };
1483        }
1484        Ok(expr)
1485    }
1486
1487    fn current_binary_op(&self, operators: &[(TokenKind, BinaryOp)]) -> Option<BinaryOp> {
1488        let token = self.peek()?;
1489        operators
1490            .iter()
1491            .find_map(|(kind, op)| (token.kind == *kind).then_some(*op))
1492    }
1493
1494    fn current_assignment_op(&self) -> Option<AssignmentOp> {
1495        let token = self.peek()?;
1496        match token.kind {
1497            TokenKind::Assign => Some(AssignmentOp::Assign),
1498            TokenKind::AssignMinus => Some(AssignmentOp::AssignMinus),
1499            TokenKind::AssignPlus => Some(AssignmentOp::AssignPlus),
1500            TokenKind::AssignMultiply => Some(AssignmentOp::AssignMultiply),
1501            TokenKind::AssignDivide => Some(AssignmentOp::AssignDivide),
1502            TokenKind::AssignModulus => Some(AssignmentOp::AssignModulus),
1503            TokenKind::AssignAnd => Some(AssignmentOp::AssignAnd),
1504            TokenKind::AssignXor => Some(AssignmentOp::AssignXor),
1505            TokenKind::AssignOr => Some(AssignmentOp::AssignOr),
1506            TokenKind::AssignShiftLeft => Some(AssignmentOp::AssignShiftLeft),
1507            TokenKind::AssignShiftRight => Some(AssignmentOp::AssignShiftRight),
1508            TokenKind::AssignUnsignedShiftRight => Some(AssignmentOp::AssignUnsignedShiftRight),
1509            _ => None,
1510        }
1511    }
1512
1513    fn starts_non_void_type_specifier(&self) -> bool {
1514        let Some(token) = self.peek() else {
1515            return false;
1516        };
1517        match token.kind {
1518            TokenKind::Keyword(
1519                Keyword::Const
1520                | Keyword::Int
1521                | Keyword::Float
1522                | Keyword::String
1523                | Keyword::Object
1524                | Keyword::Struct
1525                | Keyword::Vector,
1526            ) => true,
1527            TokenKind::Identifier => self.is_engine_structure_name(token),
1528            _ => false,
1529        }
1530    }
1531
1532    fn is_engine_structure_name(&self, token: &Token) -> bool {
1533        #[allow(non_exhaustive_omitted_patterns)] match token.kind {
    TokenKind::Identifier => true,
    _ => false,
}matches!(token.kind, TokenKind::Identifier)
1534            && self.engine_structures.contains(token.text.as_str())
1535    }
1536
1537    fn matches_keyword(&self, keyword: Keyword) -> bool {
1538        #[allow(non_exhaustive_omitted_patterns)] match self.peek() {
    Some(Token { kind: TokenKind::Keyword(found), .. }) if *found == keyword
        => true,
    _ => false,
}matches!(
1539            self.peek(),
1540            Some(Token {
1541                kind: TokenKind::Keyword(found),
1542                ..
1543            }) if *found == keyword
1544        )
1545    }
1546
1547    fn matches_kind(&self, kind: &TokenKind) -> bool {
1548        self.peek().is_some_and(|token| token.kind == *kind)
1549    }
1550
1551    fn consume_keyword(
1552        &mut self,
1553        keyword: Keyword,
1554        code: CompilerErrorCode,
1555        message: &str,
1556    ) -> Result<Token, ParserError> {
1557        if self.matches_keyword(keyword) {
1558            self.advance_required(code, message)
1559        } else {
1560            Err(self.error_here(code, message))
1561        }
1562    }
1563
1564    #[allow(clippy::needless_pass_by_value)]
1565    fn consume_kind(
1566        &mut self,
1567        kind: TokenKind,
1568        code: CompilerErrorCode,
1569        message: &str,
1570    ) -> Result<Token, ParserError> {
1571        if self.matches_kind(&kind) {
1572            self.advance_required(code, message)
1573        } else {
1574            Err(self.error_here(code, message))
1575        }
1576    }
1577
1578    fn consume_identifier(
1579        &mut self,
1580        code: CompilerErrorCode,
1581        message: &str,
1582    ) -> Result<Token, ParserError> {
1583        match self.peek() {
1584            Some(Token {
1585                kind: TokenKind::Identifier,
1586                ..
1587            }) => self.advance_required(code, message),
1588            _ => Err(self.error_here(code, message)),
1589        }
1590    }
1591
1592    fn consume_string(
1593        &mut self,
1594        code: CompilerErrorCode,
1595        message: &str,
1596    ) -> Result<Token, ParserError> {
1597        match self.peek() {
1598            Some(Token {
1599                kind: TokenKind::String,
1600                ..
1601            }) => self.advance_required(code, message),
1602            _ => Err(self.error_here(code, message)),
1603        }
1604    }
1605
1606    fn error_here(&self, code: CompilerErrorCode, message: impl Into<String>) -> ParserError {
1607        let span = self
1608            .peek()
1609            .map_or_else(|| self.eof_span(), |token| token.span);
1610        ParserError::new(code, span, message)
1611    }
1612
1613    fn eof_span(&self) -> Span {
1614        self.tokens
1615            .last()
1616            .map_or_else(|| Span::new(SourceId::new(0), 0, 0), |token| token.span)
1617    }
1618
1619    fn at_eof(&self) -> bool {
1620        #[allow(non_exhaustive_omitted_patterns)] match self.peek() {
    Some(Token { kind: TokenKind::Eof, .. }) | None => true,
    _ => false,
}matches!(
1621            self.peek(),
1622            Some(Token {
1623                kind: TokenKind::Eof,
1624                ..
1625            }) | None
1626        )
1627    }
1628
1629    fn peek(&self) -> Option<&Token> {
1630        self.tokens.get(self.position)
1631    }
1632
1633    fn advance(&mut self) -> Option<Token> {
1634        let token = self.tokens.get(self.position)?.clone();
1635        self.position += 1;
1636        Some(token)
1637    }
1638
1639    fn advance_required(
1640        &mut self,
1641        code: CompilerErrorCode,
1642        message: &str,
1643    ) -> Result<Token, ParserError> {
1644        self.advance().ok_or_else(|| self.error_here(code, message))
1645    }
1646}
1647
1648impl Stmt {
1649    #[allow(clippy::match_same_arms)]
1650    fn span(&self) -> Span {
1651        match self {
1652            Self::Block(stmt) => stmt.span,
1653            Self::Declaration(stmt) => stmt.span,
1654            Self::Expression(stmt) => stmt.span,
1655            Self::If(stmt) => stmt.span,
1656            Self::Switch(stmt) => stmt.span,
1657            Self::Return(stmt) => stmt.span,
1658            Self::While(stmt) => stmt.span,
1659            Self::DoWhile(stmt) => stmt.span,
1660            Self::For(stmt) => stmt.span,
1661            Self::Case(stmt) => stmt.span,
1662            Self::Default(stmt) => stmt.span,
1663            Self::Break(stmt) => stmt.span,
1664            Self::Continue(stmt) => stmt.span,
1665            Self::Empty(stmt) => stmt.span,
1666        }
1667    }
1668}
1669
1670fn join_spans(start: Span, end: Span) -> Span {
1671    if true {
    match (&start.source_id, &end.source_id) {
        (left_val, right_val) => {
            if !(*left_val == *right_val) {
                let kind = ::core::panicking::AssertKind::Eq;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val, ::core::option::Option::None);
            }
        }
    };
};debug_assert_eq!(start.source_id, end.source_id);
1672    Span::new(
1673        start.source_id,
1674        start.start.min(end.start),
1675        start.end.max(end.end),
1676    )
1677}
1678
1679fn parse_decimal_integer(token: &Token) -> Result<i32, ParserError> {
1680    parse_wrapping_decimal_i32(&token.text).map_err(|_error| {
1681        ParserError::new(
1682            CompilerErrorCode::BadConstantType,
1683            token.span,
1684            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("invalid integer literal {0:?}",
                token.text))
    })format!("invalid integer literal {:?}", token.text),
1685        )
1686    })
1687}
1688
1689fn parse_prefixed_integer(token: &Token, radix: u32) -> Result<i32, ParserError> {
1690    let value = parse_wrapping_prefixed_i32(&token.text, radix).map_err(|_error| {
1691        ParserError::new(
1692            CompilerErrorCode::BadConstantType,
1693            token.span,
1694            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("invalid integer literal {0:?}",
                token.text))
    })format!("invalid integer literal {:?}", token.text),
1695        )
1696    })?;
1697    Ok(value)
1698}
1699
1700#[cfg(test)]
1701mod tests {
1702    use super::{
1703        ExprKind, Literal, ParseError, Stmt, TopLevelItem, parse_resolved_script, parse_text,
1704    };
1705    use crate::{InMemoryScriptResolver, LangSpec, SourceId, SourceLoadOptions, TypeKind};
1706
1707    fn test_langspec() -> LangSpec {
1708        LangSpec {
1709            engine_num_structures: 3,
1710            engine_structures:     vec![
1711                "effect".to_string(),
1712                "location".to_string(),
1713                "json".to_string(),
1714            ],
1715            constants:             Vec::new(),
1716            functions:             Vec::new(),
1717        }
1718    }
1719
1720    #[test]
1721    fn parses_top_level_items_using_upstream_shapes() -> Result<(), Box<dyn std::error::Error>> {
1722        let script = parse_text(
1723            SourceId::new(1),
1724            "#include \"x\"\nint VALUE = 1;\nvoid main(int n = -1) { return; }\neffect fx;",
1725            Some(&test_langspec()),
1726        )?;
1727
1728        assert_eq!(script.items.len(), 4);
1729        assert!(matches!(
1730            script.items.first(),
1731            Some(TopLevelItem::Include(_))
1732        ));
1733        assert!(matches!(script.items.get(1), Some(TopLevelItem::Global(_))));
1734        assert!(matches!(
1735            script.items.get(2),
1736            Some(TopLevelItem::Function(_))
1737        ));
1738        match script.items.get(3) {
1739            Some(TopLevelItem::Global(decl)) => {
1740                assert_eq!(
1741                    decl.ty.kind,
1742                    TypeKind::EngineStructure("effect".to_string())
1743                );
1744                assert_eq!(
1745                    decl.declarators
1746                        .first()
1747                        .map(|declarator| declarator.name.as_str()),
1748                    Some("fx")
1749                );
1750            }
1751            other => {
1752                return Err(std::io::Error::other(format!(
1753                    "expected global declaration, got {other:?}"
1754                ))
1755                .into());
1756            }
1757        }
1758        Ok(())
1759    }
1760
1761    #[test]
1762    fn parses_struct_definitions_and_fields() -> Result<(), Box<dyn std::error::Error>> {
1763        let script = parse_text(
1764            SourceId::new(2),
1765            "struct Foo { int a, b; vector dir; struct Bar child; };",
1766            Some(&test_langspec()),
1767        )?;
1768
1769        match script.items.first() {
1770            Some(TopLevelItem::Global(decl)) => {
1771                return Err(std::io::Error::other(format!(
1772                    "expected struct declaration, got global {decl:?}"
1773                ))
1774                .into());
1775            }
1776            Some(TopLevelItem::Struct(def)) => {
1777                assert_eq!(def.name, "Foo");
1778                assert_eq!(def.fields.len(), 3);
1779                assert_eq!(def.fields.first().map(|field| field.names.len()), Some(2));
1780                assert_eq!(
1781                    def.fields.get(1).map(|field| field.ty.kind.clone()),
1782                    Some(TypeKind::Vector)
1783                );
1784                assert_eq!(
1785                    def.fields.get(2).map(|field| field.ty.kind.clone()),
1786                    Some(TypeKind::Struct("Bar".to_string()))
1787                );
1788            }
1789            other => {
1790                return Err(std::io::Error::other(format!(
1791                    "expected struct declaration, got {other:?}"
1792                ))
1793                .into());
1794            }
1795        }
1796        Ok(())
1797    }
1798
1799    #[test]
1800    fn parses_expression_precedence_and_postfix_forms() -> Result<(), Box<dyn std::error::Error>> {
1801        let script = parse_text(
1802            SourceId::new(3),
1803            "void main() { a >>= b + c * d.e++ ? f : g; }",
1804            Some(&test_langspec()),
1805        )?;
1806
1807        let function = match script.items.first() {
1808            Some(TopLevelItem::Function(function)) => function,
1809            other => {
1810                return Err(
1811                    std::io::Error::other(format!("expected function, got {other:?}")).into(),
1812                );
1813            }
1814        };
1815        let body = function
1816            .body
1817            .as_ref()
1818            .ok_or_else(|| std::io::Error::other("function body must exist"))?;
1819        let stmt = match body.statements.first() {
1820            Some(Stmt::Expression(stmt)) => stmt,
1821            other => {
1822                return Err(std::io::Error::other(format!(
1823                    "expected expression statement, got {other:?}"
1824                ))
1825                .into());
1826            }
1827        };
1828
1829        match &stmt.expr.kind {
1830            ExprKind::Assignment {
1831                ..
1832            } => {}
1833            other => {
1834                return Err(std::io::Error::other(format!(
1835                    "expected assignment expression, got {other:?}"
1836                ))
1837                .into());
1838            }
1839        }
1840        Ok(())
1841    }
1842
1843    #[test]
1844    fn parses_control_flow_statements() -> Result<(), Box<dyn std::error::Error>> {
1845        let script = parse_text(
1846            SourceId::new(4),
1847            "void main() { if (a) { return; } else { while (b) { continue; } } for (i = 0; i < 3; \
1848             i += 1) { break; } switch (n) { case 1: break; default: return; } do { n -= 1; } \
1849             while (n); }",
1850            Some(&test_langspec()),
1851        )?;
1852
1853        let function = match script.items.first() {
1854            Some(TopLevelItem::Function(function)) => function,
1855            other => {
1856                return Err(
1857                    std::io::Error::other(format!("expected function, got {other:?}")).into(),
1858                );
1859            }
1860        };
1861        let body = function
1862            .body
1863            .as_ref()
1864            .ok_or_else(|| std::io::Error::other("function body must exist"))?;
1865        assert!(matches!(body.statements.first(), Some(Stmt::If(_))));
1866        assert!(matches!(body.statements.get(1), Some(Stmt::For(_))));
1867        assert!(matches!(body.statements.get(2), Some(Stmt::Switch(_))));
1868        assert!(matches!(body.statements.get(3), Some(Stmt::DoWhile(_))));
1869        Ok(())
1870    }
1871
1872    #[test]
1873    fn preserves_magic_and_vector_literals() -> Result<(), Box<dyn std::error::Error>> {
1874        let script = parse_text(
1875            SourceId::new(5),
1876            "void main() { string a = __FILE__; vector v = [1.0, 2.0]; json j = JSON_OBJECT; }",
1877            Some(&test_langspec()),
1878        )?;
1879
1880        let function = match script.items.first() {
1881            Some(TopLevelItem::Function(function)) => function,
1882            other => {
1883                return Err(
1884                    std::io::Error::other(format!("expected function, got {other:?}")).into(),
1885                );
1886            }
1887        };
1888        let body = function
1889            .body
1890            .as_ref()
1891            .ok_or_else(|| std::io::Error::other("function body must exist"))?;
1892        match body.statements.first() {
1893            Some(Stmt::Declaration(decl)) => match decl
1894                .declarators
1895                .first()
1896                .and_then(|declarator| declarator.initializer.as_ref())
1897            {
1898                Some(expr) => assert!(matches!(expr.kind, ExprKind::Literal(Literal::Magic(_)))),
1899                None => return Err(std::io::Error::other("expected initializer").into()),
1900            },
1901            other => {
1902                return Err(
1903                    std::io::Error::other(format!("expected declaration, got {other:?}")).into(),
1904                );
1905            }
1906        }
1907        Ok(())
1908    }
1909
1910    #[test]
1911    fn rejects_null_statement_after_if_like_upstream() -> Result<(), Box<dyn std::error::Error>> {
1912        let error = parse_text(
1913            SourceId::new(6),
1914            "void main() { if (TRUE) ; }",
1915            Some(&test_langspec()),
1916        )
1917        .expect_err("parser should reject null if body");
1918
1919        match error {
1920            ParseError::Parse(error) => {
1921                assert_eq!(
1922                    error.code,
1923                    crate::CompilerErrorCode::IfConditionCannotBeFollowedByANullStatement
1924                );
1925            }
1926            other => {
1927                return Err(
1928                    std::io::Error::other(format!("expected parse error, got {other:?}")).into(),
1929                );
1930            }
1931        }
1932        Ok(())
1933    }
1934
1935    #[test]
1936    fn parses_resolved_script_through_includes_and_object_like_defines()
1937    -> Result<(), Box<dyn std::error::Error>> {
1938        let mut resolver = InMemoryScriptResolver::new();
1939        resolver.insert_source(
1940            "root",
1941            br#"#define BASE 2
1942#include "util"
1943int main_value = UTIL_PLUS;
1944"#,
1945        );
1946        resolver.insert_source(
1947            "util",
1948            br#"#define UTIL_PLUS BASE + 3
1949int helper = UTIL_PLUS;
1950"#,
1951        );
1952
1953        let script = parse_resolved_script(
1954            &resolver,
1955            "root",
1956            SourceLoadOptions::default(),
1957            Some(&test_langspec()),
1958        )?;
1959
1960        assert_eq!(script.items.len(), 2);
1961        assert!(matches!(
1962            script.items.first(),
1963            Some(TopLevelItem::Global(_))
1964        ));
1965        assert!(matches!(script.items.get(1), Some(TopLevelItem::Global(_))));
1966        Ok(())
1967    }
1968
1969    #[test]
1970    fn parses_full_constant_expressions_in_parameter_defaults()
1971    -> Result<(), Box<dyn std::error::Error>> {
1972        let script = parse_text(
1973            SourceId::new(7),
1974            "const int BASE = 1; void main(int nValue = BASE + 2 * 3) { return; }",
1975            Some(&test_langspec()),
1976        )?;
1977
1978        let function = match script.items.get(1) {
1979            Some(TopLevelItem::Function(function)) => function,
1980            other => {
1981                return Err(
1982                    std::io::Error::other(format!("expected function, got {other:?}")).into(),
1983                );
1984            }
1985        };
1986        let default = function
1987            .parameters
1988            .first()
1989            .and_then(|parameter| parameter.default.as_ref())
1990            .ok_or_else(|| std::io::Error::other("expected parameter default"))?;
1991        assert!(matches!(default.kind, ExprKind::Binary { .. }));
1992        Ok(())
1993    }
1994}