Skip to main content

mago_type_syntax/parser/
mod.rs

1use bumpalo::Bump;
2
3use mago_database::file::HasFileId;
4use mago_span::Position;
5
6use crate::ast::Type;
7use crate::error::ParseError;
8use crate::lexer::TypeLexer;
9use crate::parser::internal::stream::TypeTokenStream;
10
11mod internal;
12
13/// Constructs a type AST from a lexer, allocating nodes in the given arena.
14///
15/// # Errors
16///
17/// Returns a [`ParseError`] if the type syntax is invalid.
18pub fn construct<'arena>(arena: &'arena Bump, lexer: TypeLexer<'arena>) -> Result<Type<'arena>, ParseError> {
19    let mut stream = TypeTokenStream::new(arena, lexer);
20
21    let ty = internal::parse_type(&mut stream)?;
22
23    if let Some(next) = stream.lookahead(0)? {
24        return Err(ParseError::UnexpectedToken(vec![], next.kind, next.span_for(stream.file_id())));
25    }
26
27    Ok(ty)
28}
29
30/// Parse the longest type prefix and return the position past the
31/// consumed bytes. Used by embedding callers that tokenise their own
32/// trailing text after the type.
33///
34/// # Errors
35///
36/// Returns a [`ParseError`] if the input does not begin with a valid
37/// type.
38pub fn construct_prefix<'arena>(
39    arena: &'arena Bump,
40    lexer: TypeLexer<'arena>,
41) -> Result<(Type<'arena>, Position), ParseError> {
42    let mut stream = TypeTokenStream::new(arena, lexer);
43    let ty = internal::parse_type(&mut stream)?;
44    Ok((ty, stream.current_position()))
45}