123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- package build
- func Walk(v Expr, f func(x Expr, stk []Expr)) {
- var stack []Expr
- walk1(&v, &stack, func(x Expr, stk []Expr) Expr {
- f(x, stk)
- return nil
- })
- }
- func Edit(v Expr, f func(x Expr, stk []Expr) Expr) Expr {
- var stack []Expr
- return walk1(&v, &stack, f)
- }
- func walk1(v *Expr, stack *[]Expr, f func(x Expr, stk []Expr) Expr) Expr {
- if v == nil {
- return nil
- }
- if res := f(*v, *stack); res != nil {
- *v = res
- }
- *stack = append(*stack, *v)
- switch v := (*v).(type) {
- case *File:
- for _, stmt := range v.Stmt {
- walk1(&stmt, stack, f)
- }
- case *DotExpr:
- walk1(&v.X, stack, f)
- case *IndexExpr:
- walk1(&v.X, stack, f)
- walk1(&v.Y, stack, f)
- case *KeyValueExpr:
- walk1(&v.Key, stack, f)
- walk1(&v.Value, stack, f)
- case *SliceExpr:
- walk1(&v.X, stack, f)
- if v.From != nil {
- walk1(&v.From, stack, f)
- }
- if v.To != nil {
- walk1(&v.To, stack, f)
- }
- if v.Step != nil {
- walk1(&v.Step, stack, f)
- }
- case *ParenExpr:
- walk1(&v.X, stack, f)
- case *UnaryExpr:
- walk1(&v.X, stack, f)
- case *BinaryExpr:
- walk1(&v.X, stack, f)
- walk1(&v.Y, stack, f)
- case *LambdaExpr:
- for i := range v.Var {
- walk1(&v.Var[i], stack, f)
- }
- walk1(&v.Expr, stack, f)
- case *CallExpr:
- walk1(&v.X, stack, f)
- for i := range v.List {
- walk1(&v.List[i], stack, f)
- }
- case *ListExpr:
- for i := range v.List {
- walk1(&v.List[i], stack, f)
- }
- case *SetExpr:
- for i := range v.List {
- walk1(&v.List[i], stack, f)
- }
- case *TupleExpr:
- for i := range v.List {
- walk1(&v.List[i], stack, f)
- }
- case *DictExpr:
- for i := range v.List {
- walk1(&v.List[i], stack, f)
- }
- case *ListForExpr:
- walk1(&v.X, stack, f)
- for _, c := range v.For {
- for j := range c.For.Var {
- walk1(&c.For.Var[j], stack, f)
- }
- walk1(&c.For.Expr, stack, f)
- for _, i := range c.Ifs {
- walk1(&i.Cond, stack, f)
- }
- }
- case *ConditionalExpr:
- walk1(&v.Then, stack, f)
- walk1(&v.Test, stack, f)
- walk1(&v.Else, stack, f)
- }
- *stack = (*stack)[:len(*stack)-1]
- return *v
- }
|