kodept-parse 0.3.0

Simple compiler with dependent types support in mind
Documentation
use nom::multi::{many0, many1};
use nom::Parser;
use nom::sequence::tuple;
use nom_supreme::ParserExt;

use kodept_core::structure::rlt;

use crate::{
    lexer::{Identifier::*, Keyword::*, Operator::*, Symbol::*, Token},
    token_stream::TokenStream,
};
use crate::nom::parser::{ParseResult, top_level};
use crate::nom::parser::macros::{function, match_any_token, match_token};
use crate::nom::parser::utils::{match_token, newline_separated};

fn module_statement(input: TokenStream) -> ParseResult<rlt::Module> {
    tuple((
        match_token(Module),
        match_token!(Token::Identifier(Type(_))),
        match_token(LBrace),
        newline_separated(top_level::grammar),
        match_token(RBrace).cut(),
    ))
    .context(function!())
    .map(|it| rlt::Module::Ordinary {
        keyword: it.0.span.into(),
        id: it.1.span.into(),
        lbrace: it.2.span.into(),
        rest: it.3.into_boxed_slice(),
        rbrace: it.4.span.into(),
    })
    .parse(input)
}

fn global_module_statement(input: TokenStream) -> ParseResult<rlt::Module> {
    tuple((
        match_token(Module),
        match_token!(Token::Identifier(Type(_))),
        match_token(Flow),
        many0(top_level::grammar).cut(),
    ))
    .context(function!())
    .map(|it| rlt::Module::Global {
        keyword: it.0.span.into(),
        id: it.1.span.into(),
        flow: it.2.span.into(),
        rest: it.3.into_boxed_slice(),
    })
    .parse(input)
}

pub fn grammar(input: TokenStream) -> ParseResult<rlt::File> {
    many1(module_statement)
        .map(|m| rlt::File::new(m.into_boxed_slice()))
        .or(global_module_statement.map(|m| rlt::File::new(Box::new([m]))))
        .terminated(match_any_token!(Token::Ignore(_)).opt())
        .context(function!())
        .parse(input)
}