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

145 lines
4.7 KiB
Rust

use crate::{
ast::{nothing, Function, ItemInterface},
lexer::{Ident, Span, Spanned, Token},
};
use super::{Parser, ParserError};
impl<'a> Parser<'a> {
pub fn ask_interface(&mut self) -> Result<Spanned<ItemInterface>, ParserError> {
// Interface
let Spanned(_, mut span) = self.get_real(
|token| matches!(token, Token::Ident(Ident::Interface)),
"the `Interface` keyword",
)?;
// InterfaceName
let Spanned(name, _) = self.ask_ident()?;
// {
self.get_real(
|token| matches!(token, Token::LeftCurly),
"opening curly brackets",
)?;
let mut functions = vec![];
loop {
match self.tokens.peek()? {
Spanned(Token::RightCurly, end) => {
self.eat();
span += end;
break;
}
Spanned(Token::Ident(Ident::Function), _) => functions.push(self.ask_function()?.0),
_ => return Err(self.expected("A function or closing curly braces")),
}
}
Ok(Spanned(ItemInterface { name, functions }, span))
}
pub fn ask_function(&mut self) -> Result<Spanned<Function>, ParserError> {
let Spanned(_, bsp) = self.get_real(
|token| matches!(token, Token::Ident(Ident::Function)),
"the `Function` keyword",
)?;
let Spanned(name, _) = self.ask_ident()?;
let Spanned(next, esp) = self.tokens.next()?;
match next {
Token::Ident(Ident::Takes) => {
self.get_real(
|token| matches!(token, Token::LeftParen),
"Opening parentheses",
)?;
let mut takes = vec![];
let mut returns = nothing();
loop {
let Spanned(peeked, _) = self.tokens.peek()?;
match peeked {
Token::Ident(_) => {
takes.push(self.ask_type()?.0);
match self.tokens.peek()?.0 {
Token::Comma => {
self.eat();
}
Token::RightParen => {}
_ => return Err(self.expected("a comma or closing parentheses")),
};
}
Token::RightParen => {
self.eat();
break;
}
_ => return Err(self.expected("closing parentheses or a type name")),
}
}
match self.tokens.next()?.0 {
Token::Semicolon => {}
Token::Ident(Ident::Returns) => {
self.get_real(
|token| matches!(token, Token::LeftParen),
"opening parentheses",
)?;
let Spanned(returns_, _) = self.ask_type()?;
returns = returns_;
self.get_real(
|token| matches!(token, Token::RightParen),
"closing parentheses",
)?;
self.semi()?;
}
_ => return Err(self.expected("a semicolon or a Returns clause")),
}
Ok(Spanned(
Function {
name,
takes,
returns,
},
bsp + Span(self.tokens.lexer.span()),
))
}
Token::Ident(Ident::Returns) => {
self.get_real(
|token| matches!(token, Token::LeftParen),
"Opening parentheses",
)?;
let Spanned(returns, _) = self.ask_type()?;
self.get_real(
|token| matches!(token, Token::RightParen),
"Closing parentheses",
)?;
Ok(Spanned(
Function {
name,
takes: Vec::new(),
returns,
},
bsp + self.semi()?,
))
}
Token::Semicolon => Ok(Spanned(
Function {
name,
takes: Vec::new(),
returns: nothing(),
},
bsp + esp,
)),
_ => Err(self.expected("a Takes clause, a Returns clause or a semicolon")),
}
}
}