ast.go (2567B)
1 package ini 2 3 // ASTKind represents different states in the parse table 4 // and the type of AST that is being constructed 5 type ASTKind int 6 7 // ASTKind* is used in the parse table to transition between 8 // the different states 9 const ( 10 ASTKindNone = ASTKind(iota) 11 ASTKindStart 12 ASTKindExpr 13 ASTKindEqualExpr 14 ASTKindStatement 15 ASTKindSkipStatement 16 ASTKindExprStatement 17 ASTKindSectionStatement 18 ASTKindNestedSectionStatement 19 ASTKindCompletedNestedSectionStatement 20 ASTKindCommentStatement 21 ASTKindCompletedSectionStatement 22 ) 23 24 func (k ASTKind) String() string { 25 switch k { 26 case ASTKindNone: 27 return "none" 28 case ASTKindStart: 29 return "start" 30 case ASTKindExpr: 31 return "expr" 32 case ASTKindStatement: 33 return "stmt" 34 case ASTKindSectionStatement: 35 return "section_stmt" 36 case ASTKindExprStatement: 37 return "expr_stmt" 38 case ASTKindCommentStatement: 39 return "comment" 40 case ASTKindNestedSectionStatement: 41 return "nested_section_stmt" 42 case ASTKindCompletedSectionStatement: 43 return "completed_stmt" 44 case ASTKindSkipStatement: 45 return "skip" 46 default: 47 return "" 48 } 49 } 50 51 // AST interface allows us to determine what kind of node we 52 // are on and casting may not need to be necessary. 53 // 54 // The root is always the first node in Children 55 type AST struct { 56 Kind ASTKind 57 Root Token 58 RootToken bool 59 Children []AST 60 } 61 62 func newAST(kind ASTKind, root AST, children ...AST) AST { 63 return AST{ 64 Kind: kind, 65 Children: append([]AST{root}, children...), 66 } 67 } 68 69 func newASTWithRootToken(kind ASTKind, root Token, children ...AST) AST { 70 return AST{ 71 Kind: kind, 72 Root: root, 73 RootToken: true, 74 Children: children, 75 } 76 } 77 78 // AppendChild will append to the list of children an AST has. 79 func (a *AST) AppendChild(child AST) { 80 a.Children = append(a.Children, child) 81 } 82 83 // GetRoot will return the root AST which can be the first entry 84 // in the children list or a token. 85 func (a *AST) GetRoot() AST { 86 if a.RootToken { 87 return *a 88 } 89 90 if len(a.Children) == 0 { 91 return AST{} 92 } 93 94 return a.Children[0] 95 } 96 97 // GetChildren will return the current AST's list of children 98 func (a *AST) GetChildren() []AST { 99 if len(a.Children) == 0 { 100 return []AST{} 101 } 102 103 if a.RootToken { 104 return a.Children 105 } 106 107 return a.Children[1:] 108 } 109 110 // SetChildren will set and override all children of the AST. 111 func (a *AST) SetChildren(children []AST) { 112 if a.RootToken { 113 a.Children = children 114 } else { 115 a.Children = append(a.Children[:1], children...) 116 } 117 } 118 119 // Start is used to indicate the starting state of the parse table. 120 var Start = newAST(ASTKindStart, AST{})