From 099543a20d1f7cd8b19a3c5f3604cf647eebc02b Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Thu, 18 May 2023 23:03:22 +0900 Subject: [PATCH] Add `Ast` as top level enum --- ast/asdl_rs.py | 42 +++++++++++++++++++++++++++++++++--------- ast/src/gen/generic.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/ast/asdl_rs.py b/ast/asdl_rs.py index f1b2b91f..ab58ba41 100755 --- a/ast/asdl_rs.py +++ b/ast/asdl_rs.py @@ -289,7 +289,40 @@ class StructVisitor(EmitVisitor): def __init__(self, *args, **kw): super().__init__(*args, **kw) + def emit_attrs(self, depth): + self.emit("#[derive(Clone, Debug, PartialEq)]", depth) + + def emit_range(self, has_attributes, depth): + if has_attributes: + self.emit("pub range: R,", depth + 1) + else: + self.emit("pub range: OptionalRange,", depth + 1) + def visitModule(self, mod): + self.emit_attrs(0) + self.emit(""" + #[derive(is_macro::Is)] + pub enum Ast { + """, 0) + for dfn in mod.dfns: + rust_name = rust_type_name(dfn.name) + generics = "" if self.type_info[dfn.name].is_simple else "" + if dfn.name == "mod": + # This is exceptional rule to other enums. + # Unlike other enums, this is justified because `Mod` is only used as + # the top node of parsing result and never a child node of other nodes. + # Because it will be very rarely used in very particular applications, + # "ast_" prefix to everywhere seems less useful. + self.emit('#[is(name = "module")]', 1) + self.emit(f"{rust_name}({rust_name}{generics}),", 1) + self.emit(""" + } + impl Node for Ast { + const NAME: &'static str = "AST"; + const FIELD_NAMES: &'static [&'static str] = &[]; + } + """, 0) + for dfn in mod.dfns: self.visit(dfn) @@ -313,15 +346,6 @@ def visitSum(self, sum, type, depth): depth, ) - def emit_attrs(self, depth): - self.emit("#[derive(Clone, Debug, PartialEq)]", depth) - - def emit_range(self, has_attributes, depth): - if has_attributes: - self.emit("pub range: R,", depth + 1) - else: - self.emit("pub range: OptionalRange,", depth + 1) - def simple_sum(self, sum, type, depth): rust_name = rust_type_name(type.name) self.emit_attrs(depth) diff --git a/ast/src/gen/generic.rs b/ast/src/gen/generic.rs index 39ead973..146191e0 100644 --- a/ast/src/gen/generic.rs +++ b/ast/src/gen/generic.rs @@ -1,6 +1,34 @@ // File automatically generated by ast/asdl_rs.py. use crate::text_size::TextRange; +#[derive(Clone, Debug, PartialEq)] +#[derive(is_macro::Is)] +pub enum Ast { + #[is(name = "module")] + Mod(Mod), + Stmt(Stmt), + Expr(Expr), + ExprContext(ExprContext), + Boolop(Boolop), + Operator(Operator), + Unaryop(Unaryop), + Cmpop(Cmpop), + Comprehension(Comprehension), + Excepthandler(Excepthandler), + Arguments(Arguments), + Arg(Arg), + Keyword(Keyword), + Alias(Alias), + Withitem(Withitem), + MatchCase(MatchCase), + Pattern(Pattern), + TypeIgnore(TypeIgnore), +} +impl Node for Ast { + const NAME: &'static str = "AST"; + const FIELD_NAMES: &'static [&'static str] = &[]; +} + #[derive(Clone, Debug, PartialEq)] pub struct ModModule { pub range: OptionalRange,