]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: add nodeSeqIterator interface
authorIan Lance Taylor <iant@golang.org>
Thu, 3 Mar 2016 19:30:17 +0000 (11:30 -0800)
committerIan Lance Taylor <iant@golang.org>
Thu, 3 Mar 2016 20:14:06 +0000 (20:14 +0000)
I tried to write a program to convert *NodeList to Node, but ran into
too many problem cases.  I'm backing off and trying a more iterative
approach using interfaces.

This CL adds an interface for iteration over either a *NodeList or a
Nodes.  I changed typechecklist to use it, to show how it works.  After
NodeList is eliminated, we can change the typechecklist parameter type
to Nodes.

Passes toolstash -cmp.

Change-Id: I5c7593714b020d20868b99151b1e7cadbbdbc397
Reviewed-on: https://go-review.googlesource.com/20190
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/compile/internal/gc/alg.go
src/cmd/compile/internal/gc/closure.go
src/cmd/compile/internal/gc/inl.go
src/cmd/compile/internal/gc/lex.go
src/cmd/compile/internal/gc/range.go
src/cmd/compile/internal/gc/select.go
src/cmd/compile/internal/gc/subr.go
src/cmd/compile/internal/gc/swt.go
src/cmd/compile/internal/gc/syntax.go
src/cmd/compile/internal/gc/typecheck.go
src/cmd/compile/internal/gc/walk.go

index 36cd1198a037de497f509a0c6b00797671d944b3..6f11b968f92d3e9e0419eb90e662b5ee3e11b775 100644 (file)
@@ -303,7 +303,7 @@ func genhash(sym *Sym, t *Type) {
        Curfn = fn
        fn.Func.Dupok = true
        typecheck(&fn, Etop)
-       typecheckslice(fn.Nbody.Slice(), Etop)
+       typechecklist(fn.Nbody, Etop)
        Curfn = nil
 
        // Disable safemode while compiling this code: the code we
@@ -511,7 +511,7 @@ func geneq(sym *Sym, t *Type) {
        Curfn = fn
        fn.Func.Dupok = true
        typecheck(&fn, Etop)
-       typecheckslice(fn.Nbody.Slice(), Etop)
+       typechecklist(fn.Nbody, Etop)
        Curfn = nil
 
        // Disable safemode while compiling this code: the code we
index 40829d0e31ac36d105c02ed3742c7ae31a2ff3df..e284604db08c3c2b10b4a87241d621054f566d27 100644 (file)
@@ -111,7 +111,7 @@ func typecheckclosure(func_ *Node, top int) {
                Curfn = func_
                olddd := decldepth
                decldepth = 1
-               typecheckslice(func_.Nbody.Slice(), Etop)
+               typechecklist(func_.Nbody, Etop)
                decldepth = olddd
                Curfn = oldfn
        }
index 7b8020d2ca660537b09cf56ee866efe91447ff1b..347296ba6b26c4b3feabbf1a18e603b19ef4373b 100644 (file)
@@ -87,7 +87,7 @@ func typecheckinl(fn *Node) {
 
        savefn := Curfn
        Curfn = fn
-       typecheckslice(fn.Func.Inl.Slice(), Etop)
+       typechecklist(fn.Func.Inl, Etop)
        Curfn = savefn
 
        safemode = save_safemode
index 153928ec06af6020b2d796e56bf0e3eb78c23c30..6509e83c92e18fe5e24f8585a4c991dcc4b7e0e4 100644 (file)
@@ -406,7 +406,7 @@ func Main() {
                        Curfn = l.N
                        decldepth = 1
                        saveerrors()
-                       typecheckslice(l.N.Nbody.Slice(), Etop)
+                       typechecklist(l.N.Nbody, Etop)
                        checkreturn(l.N)
                        if nerrors != 0 {
                                l.N.Nbody.Set(nil) // type errors; do not compile
index b6fd388b0a77a9b7b6a5303f8c18bd3c137e20e9..beacec7128c73e035515a578fb06e4089d696c9d 100644 (file)
@@ -128,7 +128,7 @@ out:
        }
 
        decldepth++
-       typecheckslice(n.Nbody.Slice(), Etop)
+       typechecklist(n.Nbody, Etop)
        decldepth--
 }
 
@@ -400,7 +400,7 @@ func memclrrange(n, v1, v2, a *Node) bool {
        n.Nbody.Append(v1)
 
        typecheck(&n.Left, Erv)
-       typecheckslice(n.Nbody.Slice(), Etop)
+       typechecklist(n.Nbody, Etop)
        walkstmt(&n)
        return true
 }
index 5c3eea8efb5efa1099c26dfaf1166c3cf3b43451..64c35d25332036b9e8287b8e2165bb94d1a1abc6 100644 (file)
@@ -79,7 +79,7 @@ func typecheckselect(sel *Node) {
                        }
                }
 
-               typecheckslice(ncase.Nbody.Slice(), Etop)
+               typechecklist(ncase.Nbody, Etop)
        }
 
        sel.Xoffset = int64(count)
index b8bd66c7b199632851c58a341da7fdbbfdc59875..6997659b576c974ab0db026d475de9316e3eeff0 100644 (file)
@@ -2215,7 +2215,7 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) {
                fn.Func.Dupok = true
        }
        typecheck(&fn, Etop)
-       typecheckslice(fn.Nbody.Slice(), Etop)
+       typechecklist(fn.Nbody, Etop)
 
        inlcalls(fn)
        escAnalyze([]*Node{fn}, false)
index 1835642b9555061a9841596fefa86694342ce84f..d29377b8aefb8071e871ac83f2684f2682a963fd 100644 (file)
@@ -181,7 +181,7 @@ func typecheckswitch(n *Node) {
                        }
                }
 
-               typecheckslice(ncase.Nbody.Slice(), Etop)
+               typechecklist(ncase.Nbody, Etop)
        }
 
        lineno = lno
index f18733104f0da29c51f6b4912e73aaa9502f9d7f..70d79d87130551718392f174feaa1c66869237cb 100644 (file)
@@ -494,3 +494,72 @@ func (n *Nodes) AppendNodeList(l *NodeList) {
                }
        }
 }
+
+// nodeSeqIterator is an interface used to iterate over a sequence of nodes.
+// TODO(iant): Remove after conversion from NodeList to Nodes is complete.
+type nodeSeqIterator interface {
+       // Return whether iteration is complete.
+       Done() bool
+       // Advance to the next node.
+       Next()
+       // Return the current node.
+       N() *Node
+       // Return the address of the current node.
+       P() **Node
+}
+
+// nodeListIterator is a type that implements nodeSeqIterator using a
+// *NodeList.
+type nodeListIterator struct {
+       l *NodeList
+}
+
+func (nli *nodeListIterator) Done() bool {
+       return nli.l == nil
+}
+
+func (nli *nodeListIterator) Next() {
+       nli.l = nli.l.Next
+}
+
+func (nli *nodeListIterator) N() *Node {
+       return nli.l.N
+}
+
+func (nli *nodeListIterator) P() **Node {
+       return &nli.l.N
+}
+
+// nodesIterator implements nodeSeqIterator using a Nodes.
+type nodesIterator struct {
+       n Nodes
+       i int
+}
+
+func (ni *nodesIterator) Done() bool {
+       return ni.i >= len(ni.n.Slice())
+}
+
+func (ni *nodesIterator) Next() {
+       ni.i++
+}
+
+func (ni *nodesIterator) N() *Node {
+       return ni.n.Slice()[ni.i]
+}
+
+func (ni *nodesIterator) P() **Node {
+       return &ni.n.Slice()[ni.i]
+}
+
+// nodeSeqIterate returns an iterator over either a *Nodelist or a *Nodes.
+func nodeSeqIterate(ns interface{}) nodeSeqIterator {
+       switch ns := ns.(type) {
+       case *NodeList:
+               return &nodeListIterator{ns}
+       case Nodes:
+               return &nodesIterator{ns, 0}
+       default:
+               panic("can't happen")
+       }
+}
index 17ea693d3174648ed3edd93a4c10acef09565cc1..760ee8fc1780cea9b51c336ad5c75194881c346d 100644 (file)
@@ -34,9 +34,9 @@ func resolve(n *Node) *Node {
        return n
 }
 
-func typechecklist(l *NodeList, top int) {
-       for ; l != nil; l = l.Next {
-               typecheck(&l.N, top)
+func typechecklist(l interface{}, top int) {
+       for it := nodeSeqIterate(l); !it.Done(); it.Next() {
+               typecheck(it.P(), top)
        }
 }
 
@@ -2073,7 +2073,7 @@ OpSwitch:
                        }
                }
                typecheck(&n.Right, Etop)
-               typecheckslice(n.Nbody.Slice(), Etop)
+               typechecklist(n.Nbody, Etop)
                decldepth--
                break OpSwitch
 
@@ -2087,7 +2087,7 @@ OpSwitch:
                                Yyerror("non-bool %v used as if condition", Nconv(n.Left, obj.FmtLong))
                        }
                }
-               typecheckslice(n.Nbody.Slice(), Etop)
+               typechecklist(n.Nbody, Etop)
                typechecklist(n.Rlist, Etop)
                break OpSwitch
 
@@ -2137,7 +2137,7 @@ OpSwitch:
        case OXCASE:
                ok |= Etop
                typechecklist(n.List, Erv)
-               typecheckslice(n.Nbody.Slice(), Etop)
+               typechecklist(n.Nbody, Etop)
                break OpSwitch
 
        case ODCLFUNC:
index dba8ad3fde8a762a8947feea8c267f94c1f0d2af..c85bfd7b0f2224c60750bab2cd1f90cf076f407d 100644 (file)
@@ -3965,7 +3965,7 @@ func walkprintfunc(np **Node, init **NodeList) {
        funcbody(fn)
 
        typecheck(&fn, Etop)
-       typecheckslice(fn.Nbody.Slice(), Etop)
+       typechecklist(fn.Nbody, Etop)
        xtop = list(xtop, fn)
        Curfn = oldfn