/* Copyright (c) 2017-2026 Li Jin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #pragma once #include "yuescript/ast.hpp" namespace parserlib { template std::string_view ast_name() { return {}; } #define AST_LEAF(type) \ COUNTER_INC; \ namespace yue { \ class type##_t : public ast_node { \ public: \ virtual int get_id() const override { return COUNTER_READ; } \ virtual std::string to_string(void*) const override; \ virtual const std::string_view get_name() const override { return #type ""sv; } #define AST_NODE(type) \ COUNTER_INC; \ namespace yue { \ class type##_t : public ast_container { \ public: \ virtual int get_id() const override { return COUNTER_READ; } \ virtual std::string to_string(void*) const override; \ virtual const std::string_view get_name() const override { return #type ""sv; } #define AST_MEMBER(type, ...) \ type##_t() { \ add_members({__VA_ARGS__}); \ } #define AST_END(type) \ } \ ; \ } \ template <> \ constexpr int id() { return COUNTER_READ; } \ template <> \ constexpr std::string_view ast_name() { return #type ""sv; } // clang-format off namespace yue { class ExpList_t; class TableBlock_t; class SimpleTable_t; class TableLit_t; class Assign_t; class Exp_t; class VariablePair_t; class NormalPair_t; class MetaVariablePair_t; class MetaNormalPair_t; class FnArgsDef_t; class ChainValue_t; class ExistentialOp_t; class Block_t; class Statement_t; class Body_t; class AssignableNameList_t; class StarExp_t; class CompFor_t; class AssignableChain_t; class UnaryExp_t; class Parens_t; class MacroName_t; class String_t; class ConstValue_t; class ClassDecl_t; class UnaryValue_t; class FunLit_t; class DefaultValue_t; class InvokeArgs_t; class TableBlockIndent_t; class Macro_t; class In_t; class NormalDef_t; class SpreadListExp_t; class Comprehension_t; class Value_t; class YueComment_t; class EmptyLine_t; } // namespace yue AST_LEAF(Num) AST_END(Num) AST_LEAF(Name) AST_END(Name) AST_LEAF(UnicodeName) AST_END(UnicodeName) AST_NODE(Variable) ast_sel name; AST_MEMBER(Variable, &name) AST_END(Variable) AST_NODE(LuaKeyword) ast_ptr name; AST_MEMBER(LuaKeyword, &name) AST_END(LuaKeyword) AST_LEAF(Self) AST_END(Self) AST_NODE(SelfName) ast_sel name; AST_MEMBER(SelfName, &name) AST_END(SelfName) AST_LEAF(SelfClass) AST_END(SelfClass) AST_NODE(SelfClassName) ast_sel name; AST_MEMBER(SelfClassName, &name) AST_END(SelfClassName) AST_NODE(SelfItem) ast_sel name; AST_MEMBER(SelfItem, &name) AST_END(SelfItem) AST_NODE(KeyName) ast_sel name; AST_MEMBER(KeyName, &name) AST_END(KeyName) AST_NODE(VarArgDef) ast_ptr name; AST_MEMBER(VarArgDef, &name) AST_END(VarArgDef) AST_LEAF(VarArg) AST_END(VarArg) AST_LEAF(LocalFlag) AST_END(LocalFlag) AST_LEAF(Seperator) AST_END(Seperator) AST_NODE(NameList) ast_ptr sep; ast_list names; AST_MEMBER(NameList, &sep, &names) AST_END(NameList) AST_NODE(LocalValues) ast_ptr nameList; ast_sel valueList; AST_MEMBER(LocalValues, &nameList, &valueList) AST_END(LocalValues) AST_NODE(Local) ast_sel item; std::list forceDecls; std::list decls; bool collected = false; bool defined = false; AST_MEMBER(Local, &item) AST_END(Local) AST_LEAF(ConstAttrib) AST_END(ConstAttrib) AST_LEAF(CloseAttrib) AST_END(CloseAttrib) AST_NODE(LocalAttrib) ast_sel attrib; ast_ptr sep; ast_sel_list leftList; ast_ptr assign; bool forceLocal = true; AST_MEMBER(LocalAttrib, &attrib, &sep, &leftList, &assign) AST_END(LocalAttrib) AST_NODE(ColonImportName) ast_ptr name; AST_MEMBER(ColonImportName, &name) AST_END(ColonImportName) AST_LEAF(ImportLiteralInner) AST_END(ImportLiteralInner) AST_NODE(ImportLiteral) ast_ptr sep; ast_sel_list inners; AST_MEMBER(ImportLiteral, &sep, &inners) AST_END(ImportLiteral) AST_NODE(ImportFrom) ast_ptr sep; ast_sel_list names; ast_sel item; AST_MEMBER(ImportFrom, &sep, &names, &item) AST_END(ImportFrom) AST_NODE(FromImport) ast_sel item; ast_ptr sep; ast_sel_list names; AST_MEMBER(FromImport, &item, &sep, &names) AST_END(FromImport) AST_NODE(MacroNamePair) ast_ptr key; ast_ptr value; AST_MEMBER(MacroNamePair, &key, &value) AST_END(MacroNamePair) AST_LEAF(ImportAllMacro) AST_END(ImportAllMacro) AST_NODE(ImportTabLit) ast_ptr sep; ast_sel_list items; AST_MEMBER(ImportTabLit, &sep, &items) AST_END(ImportTabLit) AST_NODE(ImportAs) ast_ptr literal; ast_sel target; AST_MEMBER(ImportAs, &literal, &target) AST_END(ImportAs) AST_LEAF(ImportAllGlobal) AST_END(ImportAllGlobal) AST_NODE(ImportGlobal) ast_ptr sep; ast_list segs; ast_ptr target; AST_MEMBER(ImportGlobal, &sep, &segs, &target) AST_END(ImportGlobal) AST_NODE(Import) ast_sel content; AST_MEMBER(Import, &content) AST_END(Import) AST_NODE(Label) ast_ptr label; AST_MEMBER(Label, &label) AST_END(Label) AST_NODE(Goto) ast_ptr label; AST_MEMBER(Goto, &label) AST_END(Goto) AST_NODE(ShortTabAppending) ast_ptr assign; AST_MEMBER(ShortTabAppending, &assign) AST_END(ShortTabAppending) AST_LEAF(FnArrowBack) AST_END(FnArrowBack) AST_NODE(Backcall) ast_ptr argsDef; ast_ptr arrow; ast_ptr value; AST_MEMBER(Backcall, &argsDef, &arrow, &value) AST_END(Backcall) AST_NODE(ExpList) ast_ptr sep; ast_list exprs; AST_MEMBER(ExpList, &sep, &exprs) bool followStmtProcessed = false; Statement_t* followStmt = nullptr; AST_END(ExpList) AST_NODE(Return) bool allowBlockMacroReturn = false; bool explicitReturn = true; ast_sel valueList; AST_MEMBER(Return, &valueList) AST_END(Return) AST_NODE(With) ast_ptr eop; ast_ptr valueList; ast_ptr assign; ast_sel body; AST_MEMBER(With, &eop, &valueList, &assign, &body) AST_END(With) AST_NODE(SwitchList) ast_ptr sep; ast_list exprs; AST_MEMBER(SwitchList, &sep, &exprs) AST_END(SwitchList) AST_NODE(SwitchCase) ast_ptr condition; ast_sel body; AST_MEMBER(SwitchCase, &condition, &body) AST_END(SwitchCase) AST_NODE(Assignment) ast_ptr expList; ast_ptr assign; AST_MEMBER(Assignment, &expList, &assign) AST_END(Assignment) AST_NODE(Switch) ast_ptr target; ast_ptr assignment; ast_ptr sep; ast_list branches; ast_sel lastBranch; AST_MEMBER(Switch, &target, &assignment, &sep, &branches, &lastBranch) AST_END(Switch) AST_NODE(IfCond) ast_ptr condition; ast_ptr assignment; AST_MEMBER(IfCond, &condition, &assignment) AST_END(IfCond) AST_LEAF(IfType) AST_END(IfType) AST_NODE(If) ast_ptr type; ast_sel_list nodes; AST_MEMBER(If, &type, &nodes) AST_END(If) AST_LEAF(WhileType) AST_END(WhileType) AST_NODE(While) ast_ptr type; ast_ptr condition; ast_ptr assignment; ast_sel body; AST_MEMBER(While, &type, &condition, &assignment, &body) AST_END(While) AST_NODE(Repeat) ast_sel body; ast_ptr condition; AST_MEMBER(Repeat, &body, &condition) AST_END(Repeat) AST_NODE(ForStepValue) ast_ptr value; AST_MEMBER(ForStepValue, &value) AST_END(ForStepValue) AST_NODE(ForNum) ast_ptr varName; ast_ptr startValue; ast_ptr stopValue; ast_ptr stepValue; ast_sel body; AST_MEMBER(ForNum, &varName, &startValue, &stopValue, &stepValue, &body) AST_END(ForNum) AST_NODE(ForEach) ast_ptr nameList; ast_sel loopValue; ast_sel body; AST_MEMBER(ForEach, &nameList, &loopValue, &body) AST_END(ForEach) AST_NODE(For) ast_sel forLoop; AST_MEMBER(For, &forLoop) AST_END(For) AST_NODE(Do) ast_ptr body; AST_MEMBER(Do, &body) AST_END(Do) AST_NODE(CatchBlock) ast_ptr err; ast_ptr block; AST_MEMBER(CatchBlock, &err, &block) AST_END(CatchBlock) AST_NODE(Try) ast_ptr eop; ast_sel func; ast_ptr catchBlock; AST_MEMBER(Try, &eop, &func, &catchBlock) AST_END(Try) AST_NODE(Comprehension) ast_ptr sep; ast_sel_list items; AST_MEMBER(Comprehension, &sep, &items) AST_END(Comprehension) AST_NODE(CompValue) ast_ptr value; AST_MEMBER(CompValue, &value) AST_END(CompValue) AST_NODE(TblComprehension) ast_ptr key; ast_ptr value; ast_ptr forLoop; AST_MEMBER(TblComprehension, &key, &value, &forLoop) AST_END(TblComprehension) AST_NODE(StarExp) ast_ptr value; AST_MEMBER(StarExp, &value) AST_END(StarExp) AST_NODE(CompForEach) ast_ptr nameList; ast_sel loopValue; AST_MEMBER(CompForEach, &nameList, &loopValue) AST_END(CompForEach) AST_NODE(CompForNum) ast_ptr varName; ast_ptr startValue; ast_ptr stopValue; ast_ptr stepValue; AST_MEMBER(CompForNum, &varName, &startValue, &stopValue, &stepValue) AST_END(CompForNum) AST_NODE(CompFor) ast_ptr sep; ast_sel_list items; AST_MEMBER(CompFor, &sep, &items) AST_END(CompFor) AST_NODE(Assign) ast_ptr sep; ast_sel_list values; AST_MEMBER(Assign, &sep, &values) AST_END(Assign) AST_LEAF(UpdateOp) AST_END(UpdateOp) AST_NODE(Update) ast_ptr op; ast_ptr value; AST_MEMBER(Update, &op, &value) AST_END(Update) AST_LEAF(BinaryOperator) AST_END(BinaryOperator) AST_LEAF(UnaryOperator) AST_END(UnaryOperator) AST_LEAF(NotIn) AST_END(NotIn) AST_NODE(In) ast_ptr not_; ast_ptr value; AST_MEMBER(In, ¬_, &value) AST_END(In) AST_NODE(Assignable) ast_sel item; AST_MEMBER(Assignable, &item) AST_END(Assignable) AST_NODE(ExpOpValue) ast_ptr op; ast_list pipeExprs; AST_MEMBER(ExpOpValue, &op, &pipeExprs) AST_END(ExpOpValue) AST_NODE(Exp) ast_ptr sep; ast_list pipeExprs; ast_list opValues; ast_ptr nilCoalesed; AST_MEMBER(Exp, &sep, &pipeExprs, &opValues, &nilCoalesed) AST_END(Exp) AST_NODE(Callable) ast_sel item; AST_MEMBER(Callable, &item) AST_END(Callable) AST_NODE(VariablePair) ast_ptr name; AST_MEMBER(VariablePair, &name) AST_END(VariablePair) AST_NODE(VariablePairDef) ast_ptr pair; ast_ptr defVal; AST_MEMBER(VariablePairDef, &pair, &defVal) AST_END(VariablePairDef) AST_NODE(NormalPair) ast_sel key; ast_sel value; AST_MEMBER(NormalPair, &key, &value) AST_END(NormalPair) AST_NODE(NormalPairDef) ast_ptr pair; ast_ptr defVal; AST_MEMBER(NormalPairDef, &pair, &defVal) AST_END(NormalPairDef) AST_NODE(NormalDef) ast_ptr item; ast_ptr sep; ast_ptr defVal; AST_MEMBER(NormalDef, &item, &sep, &defVal) AST_END(NormalDef) AST_NODE(MetaVariablePair) ast_ptr name; AST_MEMBER(MetaVariablePair, &name) AST_END(MetaVariablePair) AST_NODE(MetaVariablePairDef) ast_ptr pair; ast_ptr defVal; AST_MEMBER(MetaVariablePairDef, &pair, &defVal) AST_END(MetaVariablePairDef) AST_NODE(MetaNormalPair) ast_sel key; ast_sel value; AST_MEMBER(MetaNormalPair, &key, &value) AST_END(MetaNormalPair) AST_NODE(MetaNormalPairDef) ast_ptr pair; ast_ptr defVal; AST_MEMBER(MetaNormalPairDef, &pair, &defVal) AST_END(MetaNormalPairDef) AST_NODE(SimpleTable) ast_ptr sep; ast_sel_list pairs; AST_MEMBER(SimpleTable, &sep, &pairs) AST_END(SimpleTable) AST_NODE(SimpleValue) ast_sel value; AST_MEMBER(SimpleValue, &value) AST_END(SimpleValue) AST_LEAF(LuaStringOpen) AST_END(LuaStringOpen) AST_LEAF(LuaStringContent) AST_END(LuaStringContent) AST_LEAF(LuaStringClose) AST_END(LuaStringClose) AST_NODE(LuaString) ast_ptr open; ast_ptr content; ast_ptr close; AST_MEMBER(LuaString, &open, &content, &close) AST_END(LuaString) AST_LEAF(SingleString) AST_END(SingleString) AST_LEAF(DoubleStringInner) AST_END(DoubleStringInner) AST_NODE(DoubleStringContent) ast_sel content; AST_MEMBER(DoubleStringContent, &content) AST_END(DoubleStringContent) AST_NODE(DoubleString) ast_ptr sep; ast_list segments; AST_MEMBER(DoubleString, &sep, &segments) AST_END(DoubleString) AST_LEAF(YAMLIndent) AST_END(YAMLIndent) AST_LEAF(YAMLLineInner) AST_END(YAMLLineInner) AST_NODE(YAMLLineContent) ast_sel content; AST_MEMBER(YAMLLineContent, &content) AST_END(YAMLLineContent) AST_NODE(YAMLLine) ast_ptr indent; ast_list segments; AST_MEMBER(YAMLLine, &indent, &segments) AST_END(YAMLLine) AST_NODE(YAMLMultiline) ast_ptr sep; ast_list lines; AST_MEMBER(YAMLMultiline, &sep, &lines) AST_END(YAMLMultiline) AST_NODE(String) ast_sel str; AST_MEMBER(String, &str) AST_END(String) AST_LEAF(Metatable) AST_END(Metatable) AST_NODE(Metamethod) ast_sel item; AST_MEMBER(Metamethod, &item) AST_END(Metamethod) AST_NODE(DotChainItem) ast_sel name; AST_MEMBER(DotChainItem, &name) AST_END(DotChainItem) AST_NODE(ColonChainItem) ast_sel name; bool switchToDot = false; AST_MEMBER(ColonChainItem, &name) AST_END(ColonChainItem) AST_NODE(Slice) ast_sel startValue; ast_sel stopValue; ast_sel stepValue; AST_MEMBER(Slice, &startValue, &stopValue, &stepValue) AST_END(Slice) AST_NODE(Parens) ast_ptr expr; bool extra = false; AST_MEMBER(Parens, &expr) AST_END(Parens) AST_NODE(Invoke) ast_ptr sep; ast_sel_list args; AST_MEMBER(Invoke, &sep, &args) AST_END(Invoke) AST_LEAF(ExistentialOp) AST_END(ExistentialOp) AST_LEAF(TableAppendingOp) AST_END(TableAppendingOp) AST_LEAF(PlainItem) AST_END(PlainItem) AST_NODE(ReversedIndex) ast_ptr modifier; AST_MEMBER(ReversedIndex, &modifier) AST_END(ReversedIndex) AST_NODE(ChainValue) ast_ptr sep; ast_sel_list items; AST_MEMBER(ChainValue, &sep, &items) AST_END(ChainValue) AST_NODE(AssignableChain) ast_ptr sep; ast_sel_list items; AST_MEMBER(AssignableChain, &sep, &items) AST_END(AssignableChain) AST_NODE(Value) ast_sel item; AST_MEMBER(Value, &item) AST_END(Value) AST_LEAF(DefaultValue) AST_END(DefaultValue) AST_NODE(SpreadExp) ast_ptr exp; AST_MEMBER(SpreadExp, &exp) AST_END(SpreadExp) AST_NODE(SpreadListExp) ast_ptr exp; AST_MEMBER(SpreadListExp, &exp) AST_END(SpreadListExp) AST_NODE(TableLit) ast_ptr sep; ast_sel_list values; AST_MEMBER(TableLit, &sep, &values) AST_END(TableLit) AST_NODE(TableBlockIndent) ast_ptr sep; ast_sel_list values; AST_MEMBER(TableBlockIndent, &sep, &values) AST_END(TableBlockIndent) AST_NODE(TableBlock) ast_ptr sep; ast_sel_list values; AST_MEMBER(TableBlock, &sep, &values) AST_END(TableBlock) AST_NODE(ClassMemberList) ast_ptr sep; ast_sel_list values; AST_MEMBER(ClassMemberList, &sep, &values) AST_END(ClassMemberList) AST_NODE(ClassBlock) ast_ptr sep; ast_sel_list contents; AST_MEMBER(ClassBlock, &sep, &contents) AST_END(ClassBlock) AST_NODE(ClassDecl) ast_ptr name; ast_ptr extend; ast_ptr mixes; ast_ptr body; AST_MEMBER(ClassDecl, &name, &extend, &mixes, &body) AST_END(ClassDecl) AST_NODE(GlobalValues) ast_ptr nameList; ast_sel valueList; AST_MEMBER(GlobalValues, &nameList, &valueList) AST_END(GlobalValues) AST_LEAF(GlobalOp) AST_END(GlobalOp) AST_NODE(Global) ast_ptr constAttrib; ast_sel item; AST_MEMBER(Global, &constAttrib, &item) AST_END(Global) AST_LEAF(ExportDefault) AST_END(ExportDefault) AST_NODE(Export) ast_ptr def; ast_sel target; ast_ptr assign; AST_MEMBER(Export, &def, &target, &assign) AST_END(Export) AST_NODE(FnArgDef) ast_sel name; ast_ptr op; ast_ptr label; ast_ptr defaultValue; AST_MEMBER(FnArgDef, &name, &op, &label, &defaultValue) AST_END(FnArgDef) AST_NODE(FnArgDefList) ast_ptr sep; ast_list definitions; ast_ptr varArg; ast_ptr label; AST_MEMBER(FnArgDefList, &sep, &definitions, &varArg, &label) AST_END(FnArgDefList) AST_NODE(OuterVarShadow) ast_ptr varList; AST_MEMBER(OuterVarShadow, &varList) AST_END(OuterVarShadow) AST_NODE(FnArgsDef) ast_ptr defList; ast_ptr shadowOption; AST_MEMBER(FnArgsDef, &defList, &shadowOption) AST_END(FnArgsDef) AST_LEAF(FnArrow) AST_END(FnArrow) AST_NODE(FunLit) ast_ptr argsDef; ast_sel defaultReturn; ast_ptr arrow; ast_ptr body; bool noRecursion = false; bool isAnon = false; AST_MEMBER(FunLit, &argsDef, &defaultReturn, &arrow, &body) AST_END(FunLit) AST_NODE(MacroName) ast_ptr name; AST_MEMBER(MacroName, &name) AST_END(MacroName) AST_NODE(MacroLit) ast_ptr argsDef; ast_ptr body; AST_MEMBER(MacroLit, &argsDef, &body) AST_END(MacroLit) AST_NODE(MacroFunc) ast_ptr name; ast_sel invoke; AST_MEMBER(MacroFunc, &name, &invoke) AST_END(MacroFunc) AST_NODE(MacroInPlace) ast_ptr body; AST_MEMBER(MacroInPlace, &body) AST_END(MacroInPlace) AST_NODE(Macro) ast_ptr name; ast_sel decl; AST_MEMBER(Macro, &name, &decl) AST_END(Macro) AST_NODE(Annotation) ast_ptr name; ast_sel invoke; AST_MEMBER(Annotation, &name, &invoke) AST_END(Annotation) AST_NODE(NameOrDestructure) ast_sel item; AST_MEMBER(NameOrDestructure, &item) AST_END(NameOrDestructure) AST_NODE(AssignableNameList) ast_ptr sep; ast_list items; AST_MEMBER(AssignableNameList, &sep, &items) AST_END(AssignableNameList) AST_NODE(InvokeArgs) ast_ptr sep; ast_sel_list args; AST_MEMBER(InvokeArgs, &sep, &args) AST_END(InvokeArgs) AST_LEAF(ConstValue) AST_END(ConstValue) AST_NODE(UnaryValue) ast_list ops; ast_ptr value; AST_MEMBER(UnaryValue, &ops, &value) AST_END(UnaryValue) AST_NODE(UnaryExp) ast_list ops; ast_list expos; ast_ptr inExp; AST_MEMBER(UnaryExp, &ops, &expos, &inExp) AST_END(UnaryExp) AST_NODE(SubBackcall) ast_ptr arrow; ast_ptr value; AST_MEMBER(SubBackcall, &arrow, &value) AST_END(SubBackcall) AST_NODE(ExpListAssign) ast_ptr expList; ast_sel action; AST_MEMBER(ExpListAssign, &expList, &action) AST_END(ExpListAssign) AST_NODE(IfLine) ast_ptr type; ast_ptr condition; AST_MEMBER(IfLine, &type, &condition) AST_END(IfLine) AST_NODE(WhileLine) ast_ptr type; ast_ptr condition; AST_MEMBER(WhileLine, &type, &condition) AST_END(WhileLine) AST_LEAF(Break) AST_END(Break) AST_LEAF(Continue) AST_END(Continue) AST_NODE(BreakLoop) ast_sel type; ast_ptr valueList; AST_MEMBER(BreakLoop, &type, &valueList) std::deque vars; AST_END(BreakLoop) AST_NODE(PipeBody) ast_ptr sep; ast_list values; AST_MEMBER(PipeBody, &sep, &values) AST_END(PipeBody) AST_NODE(StatementAppendix) ast_sel item; AST_MEMBER(StatementAppendix, &item) AST_END(StatementAppendix) AST_LEAF(StatementSep) AST_END(StatementSep) AST_LEAF(YueLineComment) AST_END(YueLineComment) AST_LEAF(YueMultilineComment) AST_END(YueMultilineComment) AST_NODE(YueComment) ast_sel_list comments; AST_MEMBER(YueComment, &comments) AST_END(YueComment) AST_LEAF(EmptyLine) AST_END(EmptyLine) AST_NODE(ChainAssign) ast_ptr sep; ast_list exprs; ast_ptr assign; AST_MEMBER(ChainAssign, &sep, &exprs, &assign) AST_END(ChainAssign) AST_NODE(Statement) ast_sel content; ast_ptr appendix; AST_MEMBER(Statement, &content, &appendix) AST_END(Statement) AST_NODE(Body) ast_sel content; AST_MEMBER(Body, &content) AST_END(Body) AST_NODE(Block) ast_ptr sep; ast_sel_list statementOrComments; AST_MEMBER(Block, &sep, &statementOrComments) AST_END(Block) AST_NODE(BlockEnd) ast_ptr block; AST_MEMBER(BlockEnd, &block) AST_END(BlockEnd) AST_NODE(File) ast_ptr block; AST_MEMBER(File, &block) AST_END(File) // clang-format on struct YueFormat { int indent = 0; bool spaceOverTab = false; int tabSpaces = 4; bool reserveComment = true; std::string toString(ast_node* node); void pushScope(); void popScope(); std::string convert(const ast_node* node); std::string ind() const; }; } // namespace parserlib