Skip to main content

mist_parser/
lib.rs

1use pest::Parser;
2use pest_derive::Parser;
3
4pub mod ast;
5pub mod error;
6pub mod parser;
7
8use ast::*;
9
10use crate::error::{IntoErr, ParseError};
11
12#[derive(Parser)]
13#[grammar = "./src/grammar.pest"]
14pub struct MistParser;
15
16pub fn parse<'a>(source: &'a str) -> Result<Vec<TopLevel>, ParseError<'a, Vec<TopLevel>>> {
17    let mut pairs = MistParser::parse(Rule::program, source)?;
18
19    let mut statements = vec![];
20
21    let mut analyzer = error::AstErrorAnalyzer(None);
22
23    for pair in pairs.next().unwrap().into_inner() {
24        if pair.as_rule() != Rule::EOI {
25            statements.push(analyzer.get(TopLevel::try_from(pair)).get()?);
26        }
27    }
28
29    match analyzer.build(statements) {
30        Ok(v) => Ok(v),
31        Err(e) => Err(ParseError::Ast(e)),
32    }
33}
34
35#[macro_export]
36macro_rules! ast_ensure {
37    ($pair:expr, $rule:expr => $body:block) => {
38        if $pair.as_rule() == $rule
39            $body
40        else {
41            Err(AstError {
42                span: $pair.as_span(),
43                error_code: crate::error::ErrorCode::AstGenBug,
44                error_message: format!("Possible bug: expected {:?}, got {}", $rule, $pair),
45                recovered: None,
46            })
47        }
48    };
49}
50
51#[macro_export]
52macro_rules! ast_expr {
53    ($($item:ident)::+ { $($k:ident: $v:expr),* $(,)? }) => {{
54        let mut analyzer = $crate::error::AstErrorAnalyzer(None);
55
56        let v = $($item)::+ { $($k: analyzer.get($v).get()?),* };
57
58        analyzer.build(v)
59    }};
60
61    ($($item:ident)::+ ( $($v:expr),* $(,)? )) => {{
62        let mut analyzer = $crate::error::AstErrorAnalyzer(None);
63
64        let v = $($item)::+ ( $(analyzer.get($v).get()?),* );
65
66        analyzer.build(v)
67    }};
68
69    ($($item:ident)::+) => {
70        $($item)::+
71    };
72}