lwb_parser/language/
mod.rs

1use crate::parser::syntax_file::ParseError;
2use crate::sources::source_file::SourceFile;
3
4pub trait Language {
5    type Ast;
6
7    /// parses a source file into an AST. Panics (and nicely displays an error)
8    /// when the parse failed.
9    fn parse(source: &SourceFile) -> Self::Ast {
10        match Self::try_parse(source) {
11            Ok(i) => i,
12            Err(e) => {
13                panic!("failed to parse: {e}");
14            }
15        }
16    }
17
18    /// Tries to parse a source file. Returns an error if parsing failed.
19    fn try_parse(source: &SourceFile) -> Result<Self::Ast, ParseError>;
20}
21
22#[macro_export]
23macro_rules! language {
24    ($vis: vis $name: ident at mod $path: path) => {
25        $vis struct $name;
26
27        use $path as AST;
28
29        impl $crate::language::Language for $name {
30            type Ast = AST::AST_ROOT<$crate::parser::ast::generate_ast::BasicAstInfo>;
31
32            fn try_parse(
33                source: &$crate::sources::source_file::SourceFile,
34            ) -> Result<Self::Ast, $crate::parser::syntax_file::ParseError> {
35                $crate::parser::syntax_file::parse_language(source, AST::PARSER)
36            }
37        }
38    };
39
40    ($name: ident at mod $path: path) => {
41        language!(pub(self) $name at mod $path);
42    };
43    ($vis: vis $name: ident at path $path: literal) => {
44        paste! {
45            #[path = $path]
46            mod [<$name _MODULE>];
47
48            language!($vis $name at mod [<$name _MODULE>]);
49        }
50    };
51    ($name: ident at path $path: literal) => {
52        language!(pub(self) $name at path $path);
53    };
54}