Skip to main content

mago_type_syntax/parser/
mod.rs

1use mago_allocator::Arena;
2
3use mago_database::file::HasFileId;
4use mago_span::Position;
5
6use crate::cst::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, A>(arena: &'arena A, lexer: TypeLexer<'arena>) -> Result<Type<'arena>, ParseError>
19where
20    A: Arena,
21{
22    let mut stream = TypeTokenStream::new(arena, lexer);
23
24    let ty = internal::parse_type(&mut stream)?;
25
26    if let Some(next) = stream.lookahead(0)? {
27        return Err(ParseError::UnexpectedToken(vec![], next.kind, next.span_for(stream.file_id())));
28    }
29
30    Ok(ty)
31}
32
33/// Parse the longest type prefix and return the position past the
34/// consumed bytes. Used by embedding callers that tokenise their own
35/// trailing text after the type.
36///
37/// # Errors
38///
39/// Returns a [`ParseError`] if the input does not begin with a valid
40/// type.
41pub fn construct_prefix<'arena, A>(
42    arena: &'arena A,
43    lexer: TypeLexer<'arena>,
44) -> Result<(Type<'arena>, Position), ParseError>
45where
46    A: Arena,
47{
48    let mut stream = TypeTokenStream::new(arena, lexer);
49    let ty = internal::parse_type(&mut stream)?;
50    Ok((ty, stream.current_position()))
51}