I propose to take some in inspiration from this config. There are two things that are different from whitequark/parser and right now I think it was my mistake to introduce them: IfMod and IfTernary should go away, If node is enough to cover all cases.
Apart from this it makes a lot of sense to me. Thoughts on current config:
Assignment - in static analysis from my experience people never look for "an abstract assignment", there's always a need to find a certain type of assignment, like lvar assignment (to track local variables) or ivar assignment. I think it makes sense to introduce separate nodes for all types of assignment like it's done in whitequark/parser, ruby_parser and all parsers derived from them.
Binary - I think it's too generic and complex at the same time. 2 + 2 is a Binary, right? I think it should have the same type as foo.bar, because it is a method call. On the other side all types of "real" binary operators need their own node types because they have special behaviour.
CharacterLiteral - it should be just a String, there's no different between them.
FloatLiteral - let's keep it.
Identifier - this node has no value on its own and it always requires tracking current context to understand the meaning.
IfModifier - like I described above a single If node is enough. If there's a need to track a modifier version source maps can be used, but there's no different in how "normal if" works vs "if modifier". AST should represent meaning, not layout.
ImaginaryLiteral - let's keep it
IntegerLiteral - keep
OperatorAssignment - keep, there's an equivalent in whitequark/parser
Program - ehh, we can keep it, both whitequark/parser, ruby_parser (and IIRC all parsers except parser.y/Ripper) use begin node for it, because there's difference in how top-level block of code is treated comparing to let's say block body or begin..end.
RationalLiteral - keep
Range - I think it makes sense to split it to .. and ... ranges
Redo / Retry - keep
Statements - should be just begin I guess
Ternary - redundant, can be replaced with If
UnlessModifier - redundant, can be if with "inverted" branches
UntilModifier - redundant, there can be a single Until node
VariableReference - sounds a bit verbose, lvar or localvariable should be enough
WhileModifier - redundant, there can be a single While node
@kddnewton PTAL at the document that I linked above and let me know what you think
I propose to take some in inspiration from this config. There are two things that are different from whitequark/parser and right now I think it was my mistake to introduce them:
IfModandIfTernaryshould go away,Ifnode is enough to cover all cases.Apart from this it makes a lot of sense to me. Thoughts on current config:
Assignment- in static analysis from my experience people never look for "an abstract assignment", there's always a need to find a certain type of assignment, like lvar assignment (to track local variables) or ivar assignment. I think it makes sense to introduce separate nodes for all types of assignment like it's done in whitequark/parser, ruby_parser and all parsers derived from them.Binary- I think it's too generic and complex at the same time.2 + 2is aBinary, right? I think it should have the same type asfoo.bar, because it is a method call. On the other side all types of "real" binary operators need their own node types because they have special behaviour.CharacterLiteral- it should be just aString, there's no different between them.FloatLiteral- let's keep it.Identifier- this node has no value on its own and it always requires tracking current context to understand the meaning.IfModifier- like I described above a singleIfnode is enough. If there's a need to track a modifier version source maps can be used, but there's no different in how "normal if" works vs "if modifier". AST should represent meaning, not layout.ImaginaryLiteral- let's keep itIntegerLiteral- keepOperatorAssignment- keep, there's an equivalent in whitequark/parserProgram- ehh, we can keep it, both whitequark/parser, ruby_parser (and IIRC all parsers except parser.y/Ripper) usebeginnode for it, because there's difference in how top-level block of code is treated comparing to let's say block body orbegin..end.RationalLiteral- keepRange- I think it makes sense to split it to..and...rangesRedo/Retry- keepStatements- should be justbeginI guessTernary- redundant, can be replaced withIfUnlessModifier- redundant, can beifwith "inverted" branchesUntilModifier- redundant, there can be a singleUntilnodeVariableReference- sounds a bit verbose,lvarorlocalvariableshould be enoughWhileModifier- redundant, there can be a singleWhilenode@kddnewton PTAL at the document that I linked above and let me know what you think