go__parsing_demo/03-tree_walk_with_packages/stmt.go
Frédéric G. MARAND 3d784fdb6f
WIP
2023-04-04 11:06:18 +02:00

100 lines
1.9 KiB
Go

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,
*ast.BranchStmt: // break, continue, fallthrough, goto,
// fmt.Printf("%s/(%T)\n", loc, s)
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 {
// fmt.Printf("%s/(nil case)\n", loc)
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"
// fmt.Println(loc)
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 {
// fmt.Printf("%s/(nil else)\n", loc)
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"
// fmt.Println(loc)
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)"
// fmt.Println(loc)
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 {
// fmt.Printf("%s/empty clause\n", loc)
continue
}
for _, rs := range body {
parseStmt(loc, rs)
}
}
}