use std::collections::HashMap; use crate::{ ast::{ItemStructure, Type}, lexer::{Ident, Spanned, Token}, }; use super::{Parser, ParserError}; impl<'a> Parser<'a> { pub fn ask_structure(&mut self) -> Result, ParserError> { let Spanned(_, span) = self.get_real( |token| matches!(token, Token::Ident(Ident::Structure)), "the `Structure` keyword", )?; let Spanned(Type { name, arguments }, _) = self.ask_type()?; let Spanned(_, _) = self.get_real( |token| matches!(token, Token::LeftCurly), "an opening curly brace (`{`)", )?; let mut fields = HashMap::::new(); loop { match self.tokens.peek()?.0 { Token::Ident(_) => { let Spanned(ident, _) = self.ask_ident().unwrap(); self.get_real(|token| matches!(token, Token::Colon), "a colon")?; let Spanned(value, _) = self.ask_type()?; fields.insert(ident, value); match self.tokens.peek()?.0 { Token::Comma => { self.eat(); } Token::RightCurly => {} _ => return Err(self.expected("a comma or closing curly braces")), }; } Token::RightCurly => break, _ => return Err(self.expected("an identifier or a closing curly brace (`}`)")), } } if let Spanned(Token::RightCurly, end) = self.tokens.next()? { return Ok(Spanned( ItemStructure { name, fields, arguments, }, span + end, )); }; Err(self.expected("closing curly braces")) } }