Commit 466c948b authored by Ian Lance Taylor's avatar Ian Lance Taylor

cmd/compile: add nodeSeqIterator interface

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: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 0c84c4f1
...@@ -303,7 +303,7 @@ func genhash(sym *Sym, t *Type) { ...@@ -303,7 +303,7 @@ func genhash(sym *Sym, t *Type) {
Curfn = fn Curfn = fn
fn.Func.Dupok = true fn.Func.Dupok = true
typecheck(&fn, Etop) typecheck(&fn, Etop)
typecheckslice(fn.Nbody.Slice(), Etop) typechecklist(fn.Nbody, Etop)
Curfn = nil Curfn = nil
// Disable safemode while compiling this code: the code we // Disable safemode while compiling this code: the code we
...@@ -511,7 +511,7 @@ func geneq(sym *Sym, t *Type) { ...@@ -511,7 +511,7 @@ func geneq(sym *Sym, t *Type) {
Curfn = fn Curfn = fn
fn.Func.Dupok = true fn.Func.Dupok = true
typecheck(&fn, Etop) typecheck(&fn, Etop)
typecheckslice(fn.Nbody.Slice(), Etop) typechecklist(fn.Nbody, Etop)
Curfn = nil Curfn = nil
// Disable safemode while compiling this code: the code we // Disable safemode while compiling this code: the code we
......
...@@ -111,7 +111,7 @@ func typecheckclosure(func_ *Node, top int) { ...@@ -111,7 +111,7 @@ func typecheckclosure(func_ *Node, top int) {
Curfn = func_ Curfn = func_
olddd := decldepth olddd := decldepth
decldepth = 1 decldepth = 1
typecheckslice(func_.Nbody.Slice(), Etop) typechecklist(func_.Nbody, Etop)
decldepth = olddd decldepth = olddd
Curfn = oldfn Curfn = oldfn
} }
......
...@@ -87,7 +87,7 @@ func typecheckinl(fn *Node) { ...@@ -87,7 +87,7 @@ func typecheckinl(fn *Node) {
savefn := Curfn savefn := Curfn
Curfn = fn Curfn = fn
typecheckslice(fn.Func.Inl.Slice(), Etop) typechecklist(fn.Func.Inl, Etop)
Curfn = savefn Curfn = savefn
safemode = save_safemode safemode = save_safemode
......
...@@ -406,7 +406,7 @@ func Main() { ...@@ -406,7 +406,7 @@ func Main() {
Curfn = l.N Curfn = l.N
decldepth = 1 decldepth = 1
saveerrors() saveerrors()
typecheckslice(l.N.Nbody.Slice(), Etop) typechecklist(l.N.Nbody, Etop)
checkreturn(l.N) checkreturn(l.N)
if nerrors != 0 { if nerrors != 0 {
l.N.Nbody.Set(nil) // type errors; do not compile l.N.Nbody.Set(nil) // type errors; do not compile
......
...@@ -128,7 +128,7 @@ out: ...@@ -128,7 +128,7 @@ out:
} }
decldepth++ decldepth++
typecheckslice(n.Nbody.Slice(), Etop) typechecklist(n.Nbody, Etop)
decldepth-- decldepth--
} }
...@@ -400,7 +400,7 @@ func memclrrange(n, v1, v2, a *Node) bool { ...@@ -400,7 +400,7 @@ func memclrrange(n, v1, v2, a *Node) bool {
n.Nbody.Append(v1) n.Nbody.Append(v1)
typecheck(&n.Left, Erv) typecheck(&n.Left, Erv)
typecheckslice(n.Nbody.Slice(), Etop) typechecklist(n.Nbody, Etop)
walkstmt(&n) walkstmt(&n)
return true return true
} }
...@@ -79,7 +79,7 @@ func typecheckselect(sel *Node) { ...@@ -79,7 +79,7 @@ func typecheckselect(sel *Node) {
} }
} }
typecheckslice(ncase.Nbody.Slice(), Etop) typechecklist(ncase.Nbody, Etop)
} }
sel.Xoffset = int64(count) sel.Xoffset = int64(count)
......
...@@ -2215,7 +2215,7 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) { ...@@ -2215,7 +2215,7 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) {
fn.Func.Dupok = true fn.Func.Dupok = true
} }
typecheck(&fn, Etop) typecheck(&fn, Etop)
typecheckslice(fn.Nbody.Slice(), Etop) typechecklist(fn.Nbody, Etop)
inlcalls(fn) inlcalls(fn)
escAnalyze([]*Node{fn}, false) escAnalyze([]*Node{fn}, false)
......
...@@ -181,7 +181,7 @@ func typecheckswitch(n *Node) { ...@@ -181,7 +181,7 @@ func typecheckswitch(n *Node) {
} }
} }
typecheckslice(ncase.Nbody.Slice(), Etop) typechecklist(ncase.Nbody, Etop)
} }
lineno = lno lineno = lno
......
...@@ -494,3 +494,72 @@ func (n *Nodes) AppendNodeList(l *NodeList) { ...@@ -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")
}
}
...@@ -34,9 +34,9 @@ func resolve(n *Node) *Node { ...@@ -34,9 +34,9 @@ func resolve(n *Node) *Node {
return n return n
} }
func typechecklist(l *NodeList, top int) { func typechecklist(l interface{}, top int) {
for ; l != nil; l = l.Next { for it := nodeSeqIterate(l); !it.Done(); it.Next() {
typecheck(&l.N, top) typecheck(it.P(), top)
} }
} }
...@@ -2073,7 +2073,7 @@ OpSwitch: ...@@ -2073,7 +2073,7 @@ OpSwitch:
} }
} }
typecheck(&n.Right, Etop) typecheck(&n.Right, Etop)
typecheckslice(n.Nbody.Slice(), Etop) typechecklist(n.Nbody, Etop)
decldepth-- decldepth--
break OpSwitch break OpSwitch
...@@ -2087,7 +2087,7 @@ OpSwitch: ...@@ -2087,7 +2087,7 @@ OpSwitch:
Yyerror("non-bool %v used as if condition", Nconv(n.Left, obj.FmtLong)) 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) typechecklist(n.Rlist, Etop)
break OpSwitch break OpSwitch
...@@ -2137,7 +2137,7 @@ OpSwitch: ...@@ -2137,7 +2137,7 @@ OpSwitch:
case OXCASE: case OXCASE:
ok |= Etop ok |= Etop
typechecklist(n.List, Erv) typechecklist(n.List, Erv)
typecheckslice(n.Nbody.Slice(), Etop) typechecklist(n.Nbody, Etop)
break OpSwitch break OpSwitch
case ODCLFUNC: case ODCLFUNC:
......
...@@ -3965,7 +3965,7 @@ func walkprintfunc(np **Node, init **NodeList) { ...@@ -3965,7 +3965,7 @@ func walkprintfunc(np **Node, init **NodeList) {
funcbody(fn) funcbody(fn)
typecheck(&fn, Etop) typecheck(&fn, Etop)
typecheckslice(fn.Nbody.Slice(), Etop) typechecklist(fn.Nbody, Etop)
xtop = list(xtop, fn) xtop = list(xtop, fn)
Curfn = oldfn Curfn = oldfn
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment