|
@@ -0,0 +1,99 @@
|
|
|
+package main
|
|
|
+
|
|
|
+import (
|
|
|
+ "fmt"
|
|
|
+ "go/ast"
|
|
|
+)
|
|
|
+
|
|
|
+func parseStmt(loc string, s ast.Stmt) {
|
|
|
+ switch s := s.(type) {
|
|
|
+ case *ast.CaseClause:
|
|
|
+ parseCaseClause(loc, s)
|
|
|
+ case *ast.DeclStmt:
|
|
|
+ parseDeclStmt(loc, s)
|
|
|
+ case *ast.ExprStmt, *ast.AssignStmt, *ast.ReturnStmt:
|
|
|
+
|
|
|
+ case *ast.IfStmt:
|
|
|
+ parseIfStmt(loc, s)
|
|
|
+ case *ast.RangeStmt:
|
|
|
+ parseRangeStmt(loc, s)
|
|
|
+ case *ast.TypeSwitchStmt:
|
|
|
+ parseTypeSwitchStmt(loc, s)
|
|
|
+ default:
|
|
|
+ fmt.Printf("Unhandled type %T\n", s)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func parseCaseClause(loc string, s *ast.CaseClause) {
|
|
|
+ loc += "/case"
|
|
|
+ if s.Body == nil {
|
|
|
+
|
|
|
+ return
|
|
|
+ }
|
|
|
+ for _, rs := range s.Body {
|
|
|
+ parseStmt(loc, rs)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func parseDeclStmt(loc string, s *ast.DeclStmt) {
|
|
|
+ loc += "/decl"
|
|
|
+ switch d := s.Decl.(type) {
|
|
|
+ case *ast.GenDecl:
|
|
|
+ parseGenDecl(loc, d)
|
|
|
+ default:
|
|
|
+ fmt.Printf("DeclStmt: %T\n", d)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func parseIfStmt(loc string, s *ast.IfStmt) {
|
|
|
+ loc += "/if"
|
|
|
+
|
|
|
+ if s.Body == nil {
|
|
|
+ fmt.Printf("%s/(nil if)\n", loc)
|
|
|
+ } else {
|
|
|
+ thenLoc := loc + "/then"
|
|
|
+ for _, rs := range s.Body.List {
|
|
|
+ parseStmt(thenLoc, rs)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if s.Else == nil {
|
|
|
+
|
|
|
+ return
|
|
|
+ } else {
|
|
|
+ elseLoc := loc + "/else"
|
|
|
+ for _, rs := range s.Else.(*ast.BlockStmt).List {
|
|
|
+ parseStmt(elseLoc, rs)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func parseRangeStmt(loc string, s *ast.RangeStmt) {
|
|
|
+ loc += "/range"
|
|
|
+
|
|
|
+ if s.Body == nil {
|
|
|
+ fmt.Printf("%s/(nil range)\n", loc)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ for _, rs := range s.Body.List {
|
|
|
+ parseStmt(loc, rs)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func parseTypeSwitchStmt(loc string, s *ast.TypeSwitchStmt) {
|
|
|
+ loc += "/(type)"
|
|
|
+
|
|
|
+ if s.Body == nil {
|
|
|
+ fmt.Printf("%s/(nil body)\n", loc)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ for _, clause := range s.Body.List {
|
|
|
+ body := clause.(*ast.CaseClause).Body
|
|
|
+ if body == nil {
|
|
|
+
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ for _, rs := range body {
|
|
|
+ parseStmt(loc, rs)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|