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

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()))
}
}