forked from AbleOS/ableos_userland
59 lines
1.9 KiB
Rust
59 lines
1.9 KiB
Rust
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<Spanned<ItemStructure>, 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::<String, Type>::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"))
|
|
}
|
|
}
|