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