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}