// merge adjacent constants in the argument list.
case OADDSTR:
- var nr *Node
- var nl *Node
- var l2 *NodeList
- for l1 := n.List; l1 != nil; l1 = l1.Next {
- if Isconst(l1.N, CTSTR) && l1.Next != nil && Isconst(l1.Next.N, CTSTR) {
- // merge from l1 up to but not including l2
- var strs []string
- l2 = l1
- for l2 != nil && Isconst(l2.N, CTSTR) {
- nr = l2.N
- strs = append(strs, nr.Val().U.(string))
- l2 = l2.Next
- }
-
- nl = Nod(OXXX, nil, nil)
- *nl = *l1.N
- nl.Orig = nl
- nl.SetVal(Val{strings.Join(strs, "")})
- l1.N = nl
- l1.Next = l2
+ // TODO: We make a copy of n.List in order to abstract
+ // away the details of deleting elements.
+ // Once n.List is some kind of Node slice,
+ // re-implement using deletion.
+ var l *NodeList // replacement list
+ 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
+ for ; l1 != nil && Isconst(l1.N, CTSTR); l1 = l1.Next {
+ strs = append(strs, l1.N.Val().U.(string))
}
- }
- // fix list end pointer.
- for l2 := n.List; l2 != nil; l2 = l2.Next {
- n.List.End = l2
+ nl := Nod(OXXX, nil, nil)
+ *nl = *first
+ nl.Orig = nl
+ nl.SetVal(Val{strings.Join(strs, "")})
+ l = list(l, nl)
}
+ n.List = l
// collapse single-constant list to single constant.
if count(n.List) == 1 && Isconst(n.List.N, CTSTR) {