Commit 6bd63ca3 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/compile: hide NodeList details in evconst

The new code is a bit less efficient,
but it does not involve altering the structure
of any linked lists.
This will make it easier to replace NodeLists
with Node slices.
We can return to a more efficient algorithm
when NodeLists have been replaced.

Passes toolstash -cmp.

Change-Id: I0bb5ee75e7c0646e6d37fe558c8f0548729d8aa1
Reviewed-on: https://go-review.googlesource.com/20277
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 1d40e2b1
...@@ -543,33 +543,34 @@ func evconst(n *Node) { ...@@ -543,33 +543,34 @@ func evconst(n *Node) {
// merge adjacent constants in the argument list. // merge adjacent constants in the argument list.
case OADDSTR: case OADDSTR:
var nr *Node // TODO: We make a copy of n.List in order to abstract
var nl *Node // away the details of deleting elements.
var l2 *NodeList // Once n.List is some kind of Node slice,
for l1 := n.List; l1 != nil; l1 = l1.Next { // re-implement using deletion.
if Isconst(l1.N, CTSTR) && l1.Next != nil && Isconst(l1.Next.N, CTSTR) { var l *NodeList // replacement list
// merge from l1 up to but not including l2 for l1 := n.List; l1 != nil; {
if !Isconst(l1.N, CTSTR) || l1.Next == nil || !Isconst(l1.Next.N, CTSTR) {
// non-constant string or solitary constant string
l = list(l, l1.N)
l1 = l1.Next
continue
}
first := l1.N
// merge run of constants
var strs []string var strs []string
l2 = l1 for ; l1 != nil && Isconst(l1.N, CTSTR); l1 = l1.Next {
for l2 != nil && Isconst(l2.N, CTSTR) { strs = append(strs, l1.N.Val().U.(string))
nr = l2.N
strs = append(strs, nr.Val().U.(string))
l2 = l2.Next
} }
nl = Nod(OXXX, nil, nil) nl := Nod(OXXX, nil, nil)
*nl = *l1.N *nl = *first
nl.Orig = nl nl.Orig = nl
nl.SetVal(Val{strings.Join(strs, "")}) nl.SetVal(Val{strings.Join(strs, "")})
l1.N = nl l = list(l, nl)
l1.Next = l2
}
}
// fix list end pointer.
for l2 := n.List; l2 != nil; l2 = l2.Next {
n.List.End = l2
} }
n.List = l
// collapse single-constant list to single constant. // collapse single-constant list to single constant.
if count(n.List) == 1 && Isconst(n.List.N, CTSTR) { if count(n.List) == 1 && Isconst(n.List.N, CTSTR) {
......
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