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#[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 pub code: CompilerErrorCode,
20 pub span: Span,
22 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#[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 Lex(LexerError),
49 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#[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 Preprocess(PreprocessError),
81 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
108pub fn parse_tokens(
114 tokens: Vec<Token>,
115 langspec: Option<&LangSpec>,
116) -> Result<Script, ParserError> {
117 Parser::new(tokens, langspec).parse_script()
118}
119
120pub 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
133pub 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
147pub 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
160pub 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
174pub 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}