forked from AbleOS/ableos_userland
67 lines
2.1 KiB
Rust
67 lines
2.1 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> {
|
|
if let Spanned(Token::NumberLiteral(_), _) = self.tokens.peek()? {
|
|
let Spanned(number, span) = self._ask_number_literal()?;
|
|
return Ok(Spanned(
|
|
Type {
|
|
name: number.to_string(),
|
|
arguments: TypeArguments::None,
|
|
},
|
|
span,
|
|
));
|
|
};
|
|
|
|
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));
|
|
|
|
match self.tokens.peek()?.0 {
|
|
Token::Comma => self.eat(),
|
|
Token::RightArrow => {}
|
|
_ => return Err(self.expected("a comma or closing angle brackets")),
|
|
};
|
|
|
|
loop {
|
|
match self.tokens.peek()? {
|
|
Spanned(Token::Ident(_) | Token::NumberLiteral(_), _) => {
|
|
args.push(Box::new(self.ask_type()?.0));
|
|
|
|
match self.tokens.peek()?.0 {
|
|
Token::Comma => self.eat(),
|
|
Token::RightArrow => {}
|
|
_ => return Err(self.expected("a comma or closing angle brackets")),
|
|
}
|
|
}
|
|
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()))
|
|
}
|
|
}
|