ableos_userland/programs/aidl/src/parser/structure.rs

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"))
}
}