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

59 lines
1.9 KiB
Rust
Raw Normal View History

2023-05-05 11:21:24 +00:00
use std::collections::HashMap;
2023-05-05 14:15:38 +00:00
use crate::{
ast::{ItemStructure, Type},
lexer::{Ident, Spanned, Token},
};
2023-05-05 11:21:24 +00:00
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",
)?;
2023-05-05 14:15:38 +00:00
let Spanned(Type { name, arguments }, _) = self.ask_type()?;
2023-05-05 11:21:24 +00:00
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);
2023-05-06 15:57:45 +00:00
match self.tokens.peek()?.0 {
Token::Comma => {
self.eat();
}
Token::RightCurly => {}
_ => return Err(self.expected("a comma or closing curly braces")),
2023-05-05 11:21:24 +00:00
};
}
Token::RightCurly => break,
_ => return Err(self.expected("an identifier or a closing curly brace (`}`)")),
}
}
if let Spanned(Token::RightCurly, end) = self.tokens.next()? {
2023-05-05 14:15:38 +00:00
return Ok(Spanned(
ItemStructure {
name,
fields,
arguments,
},
span + end,
));
2023-05-05 11:21:24 +00:00
};
Err(self.expected("closing curly braces"))
}
}