github.com/hirochachacha/plua@v0.0.0-20170217012138-c82f520cc725/compiler/ast/printer/tree_printer.go (about) 1 package printer 2 3 import ( 4 "fmt" 5 "io" 6 "reflect" 7 "strings" 8 9 "github.com/hirochachacha/plua/compiler/ast" 10 "github.com/hirochachacha/plua/internal/strconv" 11 ) 12 13 const treeIndent = " " 14 15 type treeprinter struct { 16 w io.Writer 17 err error 18 } 19 20 func (p treeprinter) printf(s string, args ...interface{}) { 21 if p.err != nil { 22 return 23 } 24 _, p.err = fmt.Fprintf(p.w, s, args...) 25 } 26 27 func (p treeprinter) printNode(node ast.Node, prefix string, depth int) { 28 if p.err != nil { 29 return 30 } 31 32 ind := strings.Repeat(treeIndent, depth) 33 nind := ind + treeIndent 34 35 if reflect.ValueOf(node).IsNil() { 36 p.printf("%snil\n", prefix) 37 38 return 39 } 40 41 switch node := node.(type) { 42 case *ast.Comment: 43 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 44 p.printf("%sHyphen: %s\n", nind, node.Hyphen) 45 p.printf("%sText: %s\n", nind, strconv.Quote(node.Text)) 46 p.printf("%s}\n", ind) 47 case *ast.CommentGroup: 48 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 49 p.printf("%sList: {\n", nind) 50 for _, e := range node.List { 51 p.printNode(e, nind+treeIndent, depth+2) 52 } 53 p.printf("%s}\n", nind) 54 p.printf("%s}\n", ind) 55 case *ast.ParamList: 56 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 57 p.printf("%sLparen: %s\n", nind, node.Lparen) 58 p.printf("%sList: {\n", nind) 59 for _, e := range node.List { 60 p.printNode(e, nind+treeIndent, depth+2) 61 } 62 p.printf("%s}\n", nind) 63 p.printf("%sEllipsis: %s\n", nind, node.Ellipsis) 64 p.printf("%sRparen: %s\n", nind, node.Rparen) 65 p.printf("%s}\n", ind) 66 67 case *ast.BadExpr: 68 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 69 p.printf("%sFrom: %s\n", nind, node.From) 70 p.printf("%sTo: %s\n", nind, node.To) 71 p.printf("%s}\n", ind) 72 case *ast.Name: 73 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 74 p.printf("%sNamePos: %s\n", nind, node.NamePos) 75 p.printf("%sName: %s\n", nind, node.Name) 76 // p.printf("%sIsLHS: %t\n", nind, node.IsLHS) 77 p.printf("%s}\n", ind) 78 case *ast.Vararg: 79 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 80 p.printf("%sEllipsis: %s\n", nind, node.Ellipsis) 81 p.printf("%s}\n", ind) 82 case *ast.BasicLit: 83 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 84 p.printf("%sToken.Type: %s\n", nind, node.Token.Type) 85 p.printf("%sToken.Pos: %s\n", nind, node.Token.Pos) 86 p.printf("%sToken.Lit: %s\n", nind, node.Token.Lit) 87 p.printf("%s}\n", ind) 88 case *ast.FuncLit: 89 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 90 p.printf("%sFunc: %s\n", nind, node.Func) 91 p.printNode(node.Body, fmt.Sprintf("%sBody: ", nind), depth+1) 92 p.printf("%sEndPos: %s\n", nind, node.EndPos) 93 p.printf("%s}\n", ind) 94 case *ast.TableLit: 95 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 96 p.printf("%sLbrace: %s\n", nind, node.Lbrace) 97 p.printf("%sFields: {\n", nind) 98 for _, e := range node.Fields { 99 p.printNode(e, nind+treeIndent, depth+2) 100 } 101 p.printf("%s}\n", nind) 102 p.printf("%sRbrace: %s\n", nind, node.Rbrace) 103 p.printf("%s}\n", ind) 104 case *ast.ParenExpr: 105 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 106 p.printf("%sLparen: %s\n", nind, node.Lparen) 107 p.printNode(node.X, fmt.Sprintf("%sX: ", nind), depth+1) 108 p.printf("%sRparen: %s\n", nind, node.Rparen) 109 p.printf("%s}\n", ind) 110 case *ast.SelectorExpr: 111 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 112 p.printNode(node.X, fmt.Sprintf("%sX: ", nind), depth+1) 113 p.printNode(node.Sel, fmt.Sprintf("%sSel: ", nind), depth+1) 114 // p.printf("%sIsLHS: %t\n", nind, node.IsLHS) 115 p.printf("%s}\n", ind) 116 case *ast.IndexExpr: 117 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 118 p.printNode(node.X, fmt.Sprintf("%sX: ", nind), depth+1) 119 p.printf("%sLbrack: %s\n", nind, node.Lbrack) 120 p.printNode(node.Index, fmt.Sprintf("%sIndex: ", nind), depth+1) 121 p.printf("%sRbrack: %s\n", nind, node.Rbrack) 122 // p.printf("%sIsLHS: %t\n", nind, node.IsLHS) 123 p.printf("%s}\n", ind) 124 case *ast.CallExpr: 125 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 126 p.printNode(node.X, fmt.Sprintf("%sX: ", nind), depth+1) 127 p.printf("%sColon: %s\n", nind, node.Colon) 128 p.printNode(node.Name, fmt.Sprintf("%sName: ", nind), depth+1) 129 p.printf("%sLparen: %s\n", nind, node.Lparen) 130 p.printf("%sArgs: {\n", nind) 131 for _, e := range node.Args { 132 p.printNode(e, nind+treeIndent, depth+2) 133 } 134 p.printf("%s}\n", nind) 135 p.printf("%sRparen: %s\n", nind, node.Rparen) 136 p.printf("%s}\n", ind) 137 case *ast.UnaryExpr: 138 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 139 p.printf("%sOpPos: %s\n", nind, node.OpPos) 140 p.printf("%sOp: %s\n", nind, node.Op) 141 p.printNode(node.X, fmt.Sprintf("%sX: ", nind), depth+1) 142 p.printf("%s}\n", ind) 143 case *ast.BinaryExpr: 144 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 145 p.printNode(node.X, fmt.Sprintf("%sX: ", nind), depth+1) 146 p.printf("%sOpPos: %s\n", nind, node.OpPos) 147 p.printf("%sOp: %s\n", nind, node.Op) 148 p.printNode(node.Y, fmt.Sprintf("%sY: ", nind), depth+1) 149 p.printf("%s}\n", ind) 150 case *ast.KeyValueExpr: 151 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 152 p.printf("%sLbrack: %s\n", nind, node.Lbrack) 153 p.printNode(node.Key, fmt.Sprintf("%sKey: ", nind), depth+1) 154 p.printf("%sRbrack: %s\n", nind, node.Rbrack) 155 p.printf("%sEqual: %s\n", nind, node.Equal) 156 p.printNode(node.Value, fmt.Sprintf("%sValue: ", nind), depth+1) 157 p.printf("%s}\n", ind) 158 159 case *ast.BadStmt: 160 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 161 p.printf("%sFrom: %s\n", nind, node.From) 162 p.printf("%sTo: %s\n", nind, node.To) 163 p.printf("%s}\n", ind) 164 case *ast.EmptyStmt: 165 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 166 p.printf("%sSemicolon: %s\n", nind, node.Semicolon) 167 p.printf("%s}\n", ind) 168 case *ast.LocalAssignStmt: 169 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 170 p.printf("%sLHS: {\n", nind) 171 for _, e := range node.LHS { 172 p.printNode(e, nind+treeIndent, depth+2) 173 } 174 p.printf("%s}\n", nind) 175 p.printf("%sEqual: %s\n", nind, node.Equal) 176 p.printf("%sRHS: {\n", nind) 177 for _, e := range node.RHS { 178 p.printNode(e, nind+treeIndent, depth+2) 179 } 180 p.printf("%s}\n", nind) 181 p.printf("%s}\n", ind) 182 case *ast.LocalFuncStmt: 183 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 184 p.printf("%sLocal: %s\n", nind, node.Local) 185 p.printf("%sFunc: %s\n", nind, node.Func) 186 p.printNode(node.Name, fmt.Sprintf("%sName: ", nind), depth+1) 187 p.printNode(node.Body, fmt.Sprintf("%sBody: ", nind), depth+1) 188 p.printf("%sEndPos: %s\n", nind, node.EndPos) 189 p.printf("%s}\n", ind) 190 case *ast.FuncStmt: 191 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 192 p.printf("%sFunc: %s\n", nind, node.Func) 193 p.printf("%sPathList: {\n", nind) 194 for _, e := range node.PathList { 195 p.printNode(e, nind+treeIndent, depth+2) 196 } 197 p.printf("%s}\n", nind) 198 p.printNode(node.Name, fmt.Sprintf("%sName: ", nind), depth+1) 199 p.printf("%sAccessTok: '%s'\n", nind, node.AccessTok) 200 p.printf("%sAccessPos: %s\n", nind, node.AccessPos) 201 p.printNode(node.Body, fmt.Sprintf("%sBody: ", nind), depth+1) 202 p.printf("%sEndPos: %s\n", nind, node.EndPos) 203 p.printf("%s}\n", ind) 204 case *ast.LabelStmt: 205 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 206 p.printf("%sLabel: %s\n", nind, node.Label) 207 p.printNode(node.Name, fmt.Sprintf("%sName: ", nind), depth+1) 208 p.printf("%sEndLabel: %s\n", nind, node.EndLabel) 209 p.printf("%s}\n", ind) 210 case *ast.ExprStmt: 211 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 212 p.printNode(node.X, fmt.Sprintf("%sX: ", nind), depth+1) 213 p.printf("%s}\n", ind) 214 case *ast.AssignStmt: 215 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 216 p.printf("%sLHS: {\n", nind) 217 for _, e := range node.LHS { 218 p.printNode(e, nind+treeIndent, depth+2) 219 } 220 p.printf("%s}\n", nind) 221 p.printf("%sEqual: %s\n", nind, node.Equal) 222 p.printf("%sRHS: {\n", nind) 223 for _, e := range node.RHS { 224 p.printNode(e, nind+treeIndent, depth+2) 225 } 226 p.printf("%s}\n", nind) 227 p.printf("%s}\n", ind) 228 case *ast.GotoStmt: 229 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 230 p.printf("%sGoto: %s\n", nind, node.Goto) 231 p.printNode(node.Label, fmt.Sprintf("%sLabel: ", nind), depth+1) 232 p.printf("%s}\n", ind) 233 case *ast.BreakStmt: 234 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 235 p.printf("%sBreak: %s\n", nind, node.Break) 236 p.printf("%s}\n", ind) 237 case *ast.IfStmt: 238 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 239 p.printf("%sIf: %s\n", nind, node.If) 240 p.printNode(node.Cond, fmt.Sprintf("%sCond: ", nind), depth+1) 241 p.printf("%sThen: %s\n", nind, node.Then) 242 p.printNode(node.Body, fmt.Sprintf("%sBody: ", nind), depth+1) 243 p.printf("%sElseIfList: {\n", nind) 244 for _, e := range node.ElseIfList { 245 p.printf("%sElseIf: %s\n", nind+treeIndent, e.If) 246 p.printNode(e.Cond, fmt.Sprintf("%sCond: ", nind+treeIndent), depth+2) 247 p.printf("%sThen: %s\n", nind+treeIndent, e.Then) 248 p.printNode(e.Body, fmt.Sprintf("%sBody: ", nind+treeIndent), depth+2) 249 } 250 p.printf("%s}\n", nind) 251 p.printf("%sElse: %s\n", nind, node.Else) 252 p.printNode(node.ElseBody, fmt.Sprintf("%sElseBody: ", nind), depth+1) 253 p.printf("%sEndPos: %s\n", nind, node.EndPos) 254 p.printf("%s}\n", ind) 255 case *ast.DoStmt: 256 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 257 p.printf("%sDo: %s\n", nind, node.Do) 258 p.printNode(node.Body, fmt.Sprintf("%sBody: ", nind), depth+1) 259 p.printf("%sEndPos: %s\n", nind, node.EndPos) 260 p.printf("%s}\n", ind) 261 case *ast.WhileStmt: 262 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 263 p.printf("%sWhile: %s\n", nind, node.While) 264 p.printNode(node.Cond, fmt.Sprintf("%sCond: ", nind), depth+1) 265 p.printf("%sDo: %s\n", nind, node.Do) 266 p.printNode(node.Body, fmt.Sprintf("%sBody: ", nind), depth+1) 267 p.printf("%sEndPos: %s\n", nind, node.EndPos) 268 p.printf("%s}\n", ind) 269 case *ast.RepeatStmt: 270 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 271 p.printf("%sRepeat: %s\n", nind, node.Repeat) 272 p.printNode(node.Body, fmt.Sprintf("%sBody: ", nind), depth+1) 273 p.printf("%sUntil: %s\n", nind, node.Until) 274 p.printNode(node.Cond, fmt.Sprintf("%sCond: ", nind), depth+1) 275 p.printf("%s}\n", ind) 276 case *ast.ReturnStmt: 277 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 278 p.printf("%sReturn: %s\n", nind, node.Return) 279 p.printf("%sResults: {\n", nind) 280 for _, e := range node.Results { 281 p.printNode(e, nind+treeIndent, depth+2) 282 } 283 p.printf("%s}\n", nind) 284 p.printf("%s}\n", ind) 285 case *ast.ForStmt: 286 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 287 p.printf("%sFor: %s\n", nind, node.For) 288 p.printNode(node.Name, fmt.Sprintf("%sName: ", nind), depth+1) 289 p.printf("%sEqual: %s\n", nind, node.Equal) 290 p.printNode(node.Start, fmt.Sprintf("%sStart: ", nind), depth+1) 291 p.printNode(node.Finish, fmt.Sprintf("%sFinish: ", nind), depth+1) 292 p.printNode(node.Step, fmt.Sprintf("%sStep: ", nind), depth+1) 293 p.printf("%sDo: %s\n", nind, node.Do) 294 p.printNode(node.Body, fmt.Sprintf("%sBody: ", nind), depth+1) 295 p.printf("%sEndPos: %s\n", nind, node.EndPos) 296 p.printf("%s}\n", ind) 297 case *ast.ForEachStmt: 298 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 299 p.printf("%sFor: %s\n", nind, node.For) 300 p.printf("%sNames: {\n", nind) 301 for _, e := range node.Names { 302 p.printNode(e, nind+treeIndent, depth+2) 303 } 304 p.printf("%s}\n", nind) 305 p.printf("%sIn: %s\n", nind, node.In) 306 p.printf("%sExprs: {\n", nind) 307 for _, e := range node.Exprs { 308 p.printNode(e, nind+treeIndent, depth+2) 309 } 310 p.printf("%s}\n", nind) 311 p.printf("%sDo: %s\n", nind, node.Do) 312 p.printNode(node.Body, fmt.Sprintf("%sBody: ", nind), depth+1) 313 p.printf("%sEndPos: %s\n", nind, node.EndPos) 314 p.printf("%s}\n", ind) 315 case *ast.File: 316 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 317 p.printf("%sShebang: %s\n", nind, strconv.Quote(node.Shebang)) 318 p.printf("%sChunk: {\n", nind) 319 for _, e := range node.Chunk { 320 p.printNode(e, nind+treeIndent, depth+2) 321 } 322 p.printf("%s}\n", nind) 323 p.printf("%sComments: {\n", nind) 324 for _, e := range node.Comments { 325 p.printNode(e, nind+treeIndent, depth+2) 326 } 327 p.printf("%s}\n", nind) 328 p.printf("%s}\n", ind) 329 case *ast.Block: 330 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 331 p.printf("%sOpening: %s\n", nind, node.Opening) 332 p.printf("%sList: {\n", nind) 333 for _, e := range node.List { 334 p.printNode(e, nind+treeIndent, depth+2) 335 } 336 p.printf("%s}\n", nind) 337 p.printf("%sClosing: %s\n", nind, node.Closing) 338 p.printf("%s}\n", ind) 339 case *ast.FuncBody: 340 p.printf("%s%s { %s-%s\n", prefix, node.Type(), node.Pos(), node.End()) 341 p.printNode(node.Params, fmt.Sprintf("%sParams: ", nind), depth+1) 342 p.printNode(node.Body, fmt.Sprintf("%sBody: ", nind), depth+1) 343 p.printf("%s}\n", ind) 344 default: 345 panic("unreachable") 346 } 347 }