forked from AbleOS/ableos_userland
145 lines
4.7 KiB
Rust
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")),
|
|
}
|
|
}
|
|
}
|