| 91 | } |
| 92 | |
| 93 | pub fn parse(&mut self) -> Result<Program<'gc>, VmError> { |
| 94 | self.scopes.push(String::from("script")); |
| 95 | let mut program = Program::new(); |
| 96 | self.advance(); |
| 97 | |
| 98 | while !self.is_at_end() { |
| 99 | if let Some(stmt) = self.declaration() { |
| 100 | match &stmt { |
| 101 | Stmt::Class(ClassDecl { name, .. }) | Stmt::Enum(EnumDecl { name, .. }) => { |
| 102 | self.type_resolver |
| 103 | .register_type(name.lexeme, Type::Custom(*name)); |
| 104 | } |
| 105 | _ => {} |
| 106 | } |
| 107 | program.statements.push(stmt); |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | if !self.had_error { |
| 112 | let type_resolver = mem::take(&mut self.type_resolver); |
| 113 | // Validate all type usages |
| 114 | type_resolver.validate_all_types(|token, err| { |
| 115 | self.error_at(token, &err); |
| 116 | }); |
| 117 | } |
| 118 | |
| 119 | if self.had_error { |
| 120 | Err(VmError::CompileError) |
| 121 | } else { |
| 122 | Ok(program) |
| 123 | } |
| 124 | } |
| 125 | |
| 126 | fn parse_type(&mut self) -> Token<'gc> { |
| 127 | if !self.check(TokenType::Identifier) && !self.check(TokenType::Error) { |