| 215 | if self.peek_n(2) == Some(&Token::Import) { |
| 216 | let alias = self.expect_ident()?; |
| 217 | self.expect_colon_equal()?; |
| 218 | let path = self.parse_import_call()?; |
| 219 | DeclNode::ModuleImport { alias, path } |
| 220 | } else { |
| 221 | self.parse_inferred_variable_decl()? |
| 222 | } |
| 223 | } else if self.peek_n(1) == Some(&Token::Colon) |
| 224 | && (self.peek_n(2) == Some(&Token::LParen) |
| 225 | || self.peek_n(2) == Some(&Token::Lt)) |
| 226 | { |
| 227 | self.parse_function_decl(false, false)? |
| 228 | } else { |
| 229 | self.parse_variable_decl()? |
| 230 | } |
| 231 | } |
| 232 | Some(tok) => { |
| 233 | return Err(self.error_with_token("unexpected token at declaration start", tok)); |
| 234 | } |
| 235 | None => return Err(self.error("unexpected end of input")), |
| 236 | }; |
| 237 | |
| 238 | if let DeclNode::Type { name, .. } |
| 239 | | DeclNode::Struct { name, .. } |
| 240 | | DeclNode::Enum { name, .. } = &decl |
| 241 | { |
| 242 | self.type_names.insert(name.clone()); |
| 243 | } |
| 244 | if let DeclNode::Enum { name, .. } = &decl { |
| 245 | self.enum_names.insert(name.clone()); |
| 246 | } |
| 247 | Ok(Declaration { decl, exported }) |
| 248 | } |
| 249 | |
| 250 | fn parse_block(&mut self) -> Result<Block, ParserError> { |
| 251 | self.expect_lbrace()?; |
| 252 | let mut statements = Vec::new(); |
| 253 | let mut stmt_lines = Vec::new(); |
| 254 | |
| 255 | self.consume_terminators(); |
| 256 | while !self.check_rbrace() { |
| 257 | let line = self.current_line(); |
| 258 | statements.push(self.parse_statement()?); |
| 259 | stmt_lines.push(line); |
| 260 | self.consume_terminators(); |
| 261 | } |
| 262 | |
| 263 | self.expect_rbrace()?; |
| 264 | Ok(Block { |
| 265 | statements, |
| 266 | stmt_lines, |
| 267 | }) |
| 268 | } |
| 269 | |
| 270 | // 1-based source line of the current token (0 if unavailable, e.g. tests). |
| 271 | fn current_line(&self) -> u32 { |
| 272 | self.spans.get(self.pos).map(|s| s.line).unwrap_or(0) |
| 273 | } |
| 274 | |