use super::*;
use leo_errors::{ParserError, Result};
pub(super) const TYPE_TOKENS: &[Token] = &[
Token::Address,
Token::Bool,
Token::Field,
Token::Group,
Token::Scalar,
Token::String,
Token::I8,
Token::I16,
Token::I32,
Token::I64,
Token::I128,
Token::U8,
Token::U16,
Token::U32,
Token::U64,
Token::U128,
];
impl ParserContext<'_> {
pub(super) fn token_to_int_type(token: &Token) -> Option<IntegerType> {
Some(match token {
Token::I8 => IntegerType::I8,
Token::I16 => IntegerType::I16,
Token::I32 => IntegerType::I32,
Token::I64 => IntegerType::I64,
Token::I128 => IntegerType::I128,
Token::U8 => IntegerType::U8,
Token::U16 => IntegerType::U16,
Token::U32 => IntegerType::U32,
Token::U64 => IntegerType::U64,
Token::U128 => IntegerType::U128,
_ => return None,
})
}
pub fn parse_primitive_type(&mut self) -> Result<(Type, Span)> {
let span = self.expect_any(TYPE_TOKENS)?;
Ok((
match &self.prev_token.token {
Token::Address => Type::Address,
Token::Bool => Type::Boolean,
Token::Field => Type::Field,
Token::Group => Type::Group,
Token::Scalar => Type::Scalar,
Token::String => Type::String,
x => Type::Integer(Self::token_to_int_type(x).expect("invalid int type")),
},
span,
))
}
pub fn parse_type(&mut self) -> Result<(Type, Span)> {
if let Some(ident) = self.eat_identifier() {
Ok((Type::Identifier(ident), ident.span))
} else if self.token.token == Token::LeftParen {
let (types, _, span) = self.parse_paren_comma_list(|p| p.parse_type().map(Some))?;
match types.len() {
0 => Ok((Type::Unit, span)),
1 => Err(ParserError::tuple_must_have_at_least_two_elements("type", span).into()),
_ => Ok((Type::Tuple(Tuple(types.into_iter().map(|t| t.0).collect())), span)),
}
} else {
self.parse_primitive_type()
}
}
}