Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Ast as top level enum #58

Merged
merged 1 commit into from
May 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 33 additions & 9 deletions ast/asdl_rs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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<R>,", depth + 1)

def visitModule(self, mod):
self.emit_attrs(0)
self.emit("""
#[derive(is_macro::Is)]
pub enum Ast<R=TextRange> {
""", 0)
for dfn in mod.dfns:
rust_name = rust_type_name(dfn.name)
generics = "" if self.type_info[dfn.name].is_simple else "<R>"
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<R> Node for Ast<R> {
const NAME: &'static str = "AST";
const FIELD_NAMES: &'static [&'static str] = &[];
}
""", 0)

for dfn in mod.dfns:
self.visit(dfn)

Expand All @@ -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<R>,", depth + 1)

def simple_sum(self, sum, type, depth):
rust_name = rust_type_name(type.name)
self.emit_attrs(depth)
Expand Down
28 changes: 28 additions & 0 deletions ast/src/gen/generic.rs
Original file line number Diff line number Diff line change
@@ -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<R = TextRange> {
#[is(name = "module")]
Mod(Mod<R>),
Stmt(Stmt<R>),
Expr(Expr<R>),
ExprContext(ExprContext),
Boolop(Boolop),
Operator(Operator),
Unaryop(Unaryop),
Cmpop(Cmpop),
Comprehension(Comprehension<R>),
Excepthandler(Excepthandler<R>),
Arguments(Arguments<R>),
Arg(Arg<R>),
Keyword(Keyword<R>),
Alias(Alias<R>),
Withitem(Withitem<R>),
MatchCase(MatchCase<R>),
Pattern(Pattern<R>),
TypeIgnore(TypeIgnore<R>),
}
impl<R> Node for Ast<R> {
const NAME: &'static str = "AST";
const FIELD_NAMES: &'static [&'static str] = &[];
}
Comment on lines +27 to +30
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason that the enums implement the Node trait. They aren't really nodes and have no fields.


#[derive(Clone, Debug, PartialEq)]
pub struct ModModule<R = TextRange> {
pub range: OptionalRange<R>,
Expand Down