forked from AbleOS/ableos_userland
46 lines
1.3 KiB
Rust
46 lines
1.3 KiB
Rust
use crate::{
|
|
ast::{Type, TypeArguments, INFER_TYPE},
|
|
lexer::{Spanned, Token},
|
|
};
|
|
|
|
use super::{Parser, ParserError};
|
|
|
|
impl<'a> Parser<'a> {
|
|
pub fn ask_type(&mut self) -> Result<Spanned<Type>, ParserError> {
|
|
let Spanned(name, span) = self.ask_ident()?;
|
|
|
|
if name == INFER_TYPE {
|
|
return Ok(Spanned(Type::infer(), span));
|
|
}
|
|
|
|
let mut arguments = TypeArguments::None;
|
|
|
|
if let Spanned(crate::lexer::Token::LeftArrow, _) = self.tokens.peek()? {
|
|
self.eat(); // eat `<`
|
|
|
|
let mut args = vec![];
|
|
|
|
args.push(Box::new(self.ask_type()?.0));
|
|
|
|
if let Spanned(Token::Comma, _) = self.tokens.peek()? {
|
|
self.eat(); // skip comma, allow trailing comma
|
|
};
|
|
|
|
loop {
|
|
match self.tokens.peek()? {
|
|
Spanned(Token::Ident(_), _) => args.push(Box::new(self.ask_type()?.0)),
|
|
Spanned(Token::RightArrow, _) => {
|
|
self.eat();
|
|
break;
|
|
}
|
|
_ => return Err(self.expected("closing angle brackets or a type name")),
|
|
}
|
|
}
|
|
|
|
arguments = TypeArguments::AngleBracketed(args);
|
|
};
|
|
|
|
Ok(Spanned(Type { name, arguments }, span + self.tokens.span()))
|
|
}
|
|
}
|