diff options
Diffstat (limited to 'xtask/src/codegen/gen_syntax.rs')
-rw-r--r-- | xtask/src/codegen/gen_syntax.rs | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs index ce18f2b8f..fa48853d2 100644 --- a/xtask/src/codegen/gen_syntax.rs +++ b/xtask/src/codegen/gen_syntax.rs | |||
@@ -19,6 +19,10 @@ pub fn generate_syntax(mode: Mode) -> Result<()> { | |||
19 | let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?; | 19 | let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?; |
20 | update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?; | 20 | update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?; |
21 | 21 | ||
22 | let ast_tokens_file = project_root().join(codegen::AST_TOKENS); | ||
23 | let contents = generate_tokens(KINDS_SRC, AST_SRC)?; | ||
24 | update(ast_tokens_file.as_path(), &contents, mode)?; | ||
25 | |||
22 | let ast_nodes_file = project_root().join(codegen::AST_NODES); | 26 | let ast_nodes_file = project_root().join(codegen::AST_NODES); |
23 | let contents = generate_nodes(KINDS_SRC, AST_SRC)?; | 27 | let contents = generate_nodes(KINDS_SRC, AST_SRC)?; |
24 | update(ast_nodes_file.as_path(), &contents, mode)?; | 28 | update(ast_nodes_file.as_path(), &contents, mode)?; |
@@ -33,6 +37,37 @@ struct ElementKinds { | |||
33 | has_tokens: bool, | 37 | has_tokens: bool, |
34 | } | 38 | } |
35 | 39 | ||
40 | fn generate_tokens(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { | ||
41 | let tokens = grammar.tokens.iter().map(|token| { | ||
42 | let name = format_ident!("{}", token); | ||
43 | let kind = format_ident!("{}", to_upper_snake_case(token)); | ||
44 | quote! { | ||
45 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
46 | pub struct #name { | ||
47 | pub(crate) syntax: SyntaxToken, | ||
48 | } | ||
49 | impl std::fmt::Display for #name { | ||
50 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
51 | std::fmt::Display::fmt(&self.syntax, f) | ||
52 | } | ||
53 | } | ||
54 | impl AstToken for #name { | ||
55 | fn can_cast(kind: SyntaxKind) -> bool { kind == #kind } | ||
56 | fn cast(syntax: SyntaxToken) -> Option<Self> { | ||
57 | if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } | ||
58 | } | ||
59 | fn syntax(&self) -> &SyntaxToken { &self.syntax } | ||
60 | } | ||
61 | } | ||
62 | }); | ||
63 | |||
64 | let pretty = crate::reformat(quote! { | ||
65 | use crate::{SyntaxKind::{self, *}, SyntaxToken, ast::AstToken}; | ||
66 | #(#tokens)* | ||
67 | })?; | ||
68 | Ok(pretty) | ||
69 | } | ||
70 | |||
36 | fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { | 71 | fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { |
37 | let nodes = grammar.nodes.iter().map(|node| { | 72 | let nodes = grammar.nodes.iter().map(|node| { |
38 | let name = format_ident!("{}", node.name); | 73 | let name = format_ident!("{}", node.name); |