Skip to content

Commit

Permalink
pkg/ast: refactor Walk
Browse files Browse the repository at this point in the history
Refactor Walk so that it's possible to abort or wrap walk of child nodes.
Will be needed for future changes.
  • Loading branch information
dvyukov committed Jan 11, 2018
1 parent 7a4d53c commit 9dc808a
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 80 deletions.
3 changes: 3 additions & 0 deletions pkg/ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ type Node interface {
// If newPos is not zero, sets Pos of all nodes to newPos.
// If newPos is zero, Pos of nodes is left intact.
Clone(newPos Pos) Node
// Walk calls callback cb for all child nodes of this node.
// Note: it's not recursive. Use Recursive helper for recursive walk.
Walk(cb func(Node))
}

// Top-level AST nodes:
Expand Down
2 changes: 1 addition & 1 deletion pkg/ast/clone.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

package ast

func Clone(desc *Description) *Description {
func (desc *Description) Clone() *Description {
desc1 := &Description{}
for _, n := range desc.Nodes {
desc1.Nodes = append(desc1.Nodes, n.Clone(Pos{}))
Expand Down
2 changes: 1 addition & 1 deletion pkg/ast/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func TestParseAll(t *testing.T) {
t.Fatalf("formatting changed code:\n%#v\nvs:\n%#v", n1, n2)
}
}
data3 := Format(Clone(desc))
data3 := Format(desc.Clone())
if !bytes.Equal(data, data3) {
t.Fatalf("Clone lost data")
}
Expand Down
165 changes: 93 additions & 72 deletions pkg/ast/walk.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,81 +3,102 @@

package ast

import (
"fmt"
)

// Walk calls callback cb for every node in AST.
func Walk(desc *Description, cb func(n Node)) {
// Walk calls callback cb for every top-level node in description.
// Note: it's not recursive. Use Recursive helper for recursive walk.
func (desc *Description) Walk(cb func(Node)) {
for _, n := range desc.Nodes {
WalkNode(n, cb)
cb(n)
}
}

func Recursive(cb func(Node)) func(Node) {
var rec func(Node)
rec = func(n Node) {
cb(n)
n.Walk(rec)
}
return rec
}

func (n *NewLine) Walk(cb func(Node)) {}
func (n *Comment) Walk(cb func(Node)) {}
func (n *Ident) Walk(cb func(Node)) {}
func (n *String) Walk(cb func(Node)) {}
func (n *Int) Walk(cb func(Node)) {}

func (n *Include) Walk(cb func(Node)) {
cb(n.File)
}

func (n *Incdir) Walk(cb func(Node)) {
cb(n.Dir)
}

func (n *Define) Walk(cb func(Node)) {
cb(n.Name)
cb(n.Value)
}

func (n *Resource) Walk(cb func(Node)) {
cb(n.Name)
cb(n.Base)
for _, v := range n.Values {
cb(v)
}
}

func (n *TypeDef) Walk(cb func(Node)) {
cb(n.Name)
cb(n.Type)
}

func (n *Call) Walk(cb func(Node)) {
cb(n.Name)
for _, f := range n.Args {
cb(f)
}
if n.Ret != nil {
cb(n.Ret)
}
}

func (n *Struct) Walk(cb func(Node)) {
cb(n.Name)
for _, f := range n.Fields {
cb(f)
}
for _, a := range n.Attrs {
cb(a)
}
for _, c := range n.Comments {
cb(c)
}
}

func (n *IntFlags) Walk(cb func(Node)) {
cb(n.Name)
for _, v := range n.Values {
cb(v)
}
}

func (n *StrFlags) Walk(cb func(Node)) {
cb(n.Name)
for _, v := range n.Values {
cb(v)
}
}

func (n *Type) Walk(cb func(Node)) {
for _, t := range n.Args {
cb(t)
}
}

func WalkNode(n0 Node, cb func(n Node)) {
cb(n0)
switch n := n0.(type) {
case *NewLine:
case *Comment:
case *Include:
WalkNode(n.File, cb)
case *Incdir:
WalkNode(n.Dir, cb)
case *Define:
WalkNode(n.Name, cb)
WalkNode(n.Value, cb)
case *Resource:
WalkNode(n.Name, cb)
WalkNode(n.Base, cb)
for _, v := range n.Values {
WalkNode(v, cb)
}
case *TypeDef:
WalkNode(n.Name, cb)
WalkNode(n.Type, cb)
case *Call:
WalkNode(n.Name, cb)
for _, f := range n.Args {
WalkNode(f, cb)
}
if n.Ret != nil {
WalkNode(n.Ret, cb)
}
case *Struct:
WalkNode(n.Name, cb)
for _, f := range n.Fields {
WalkNode(f, cb)
}
for _, a := range n.Attrs {
WalkNode(a, cb)
}
for _, c := range n.Comments {
WalkNode(c, cb)
}
case *IntFlags:
WalkNode(n.Name, cb)
for _, v := range n.Values {
WalkNode(v, cb)
}
case *StrFlags:
WalkNode(n.Name, cb)
for _, v := range n.Values {
WalkNode(v, cb)
}
case *Ident:
case *String:
case *Int:
case *Type:
for _, t := range n.Args {
WalkNode(t, cb)
}
case *Field:
WalkNode(n.Name, cb)
WalkNode(n.Type, cb)
for _, c := range n.Comments {
WalkNode(c, cb)
}
default:
panic(fmt.Sprintf("unknown AST node: %#v", n))
func (n *Field) Walk(cb func(Node)) {
cb(n.Name)
cb(n.Type)
for _, c := range n.Comments {
cb(c)
}
}
2 changes: 1 addition & 1 deletion pkg/compiler/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func Compile(desc *ast.Description, consts map[string]uint64, target *targets.Ta
eh = ast.LoggingHandler
}
comp := &compiler{
desc: ast.Clone(desc),
desc: desc.Clone(),
target: target,
eh: eh,
ptrSize: target.PtrSize,
Expand Down
10 changes: 5 additions & 5 deletions pkg/compiler/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ func ExtractConsts(desc *ast.Description, target *targets.Target, eh0 ast.ErrorH
incdirMap := make(map[string]bool)
constMap := make(map[string]bool)

ast.Walk(desc, func(n1 ast.Node) {
switch n := n1.(type) {
desc.Walk(ast.Recursive(func(n0 ast.Node) {
switch n := n0.(type) {
case *ast.Include:
file := n.File.Value
if includeMap[file] {
Expand Down Expand Up @@ -85,7 +85,7 @@ func ExtractConsts(desc *ast.Description, target *targets.Target, eh0 ast.ErrorH
case *ast.Int:
constMap[n.Ident] = true
}
})
}))

if errors != 0 {
return nil
Expand Down Expand Up @@ -179,7 +179,7 @@ func (comp *compiler) patchConsts(consts map[string]uint64) {
case *ast.Resource, *ast.Struct, *ast.Call, *ast.TypeDef:
// Walk whole tree and replace consts in Int's and Type's.
missing := ""
ast.WalkNode(decl, func(n0 ast.Node) {
decl.Walk(ast.Recursive(func(n0 ast.Node) {
switch n := n0.(type) {
case *ast.Int:
comp.patchIntConst(n.Pos, &n.Value, &n.Ident, consts, &missing)
Expand All @@ -193,7 +193,7 @@ func (comp *compiler) patchConsts(consts map[string]uint64) {
}
}
}
})
}))
if missing == "" {
top = append(top, decl)
continue
Expand Down

0 comments on commit 9dc808a

Please sign in to comment.