m.Orig = m
m.Left = treecopy(n.Left, lineno)
m.Right = treecopy(n.Right, lineno)
- m.List = listtreecopy(n.List, lineno)
+ setNodeSeq(&m.List, listtreecopy(n.List, lineno))
if lineno != 0 {
m.Lineno = lineno
}
var ul int
var ur int
- if n.Ninit != nil {
+ if nodeSeqLen(n.Ninit) != 0 {
ul = UINF
goto out
}
}
// Given funarg struct list, return list of ODCLFIELD Node fn args.
-func structargs(tl **Type, mustname int) *NodeList {
+func structargs(tl **Type, mustname int) []*Node {
var savet Iter
var a *Node
var n *Node
var buf string
- var args *NodeList
+ var args []*Node
gen := 0
for t := Structfirst(&savet, tl); t != nil; t = structnext(&savet) {
n = nil
if n != nil {
n.Isddd = t.Isddd
}
- args = list(args, a)
+ args = append(args, a)
}
return args
out := structargs(Getoutarg(method.Type), 0)
t := Nod(OTFUNC, nil, nil)
- l := list1(this)
+ l := []*Node{this}
if iface != 0 && rcvr.Width < Types[Tptr].Width {
// Building method for interface table and receiver
// is smaller than the single pointer-sized word
tpad.Type = Types[TUINT8]
tpad.Bound = Types[Tptr].Width - rcvr.Width
pad := Nod(ODCLFIELD, newname(Lookup(".pad")), typenod(tpad))
- l = list(l, pad)
+ l = append(l, pad)
}
- t.List = concat(l, in)
- t.Rlist = out
+ setNodeSeq(&t.List, append(l, in...))
+ setNodeSeq(&t.Rlist, out)
fn := Nod(ODCLFUNC, nil, nil)
fn.Func.Nname = newname(newnam)
funchdr(fn)
// arg list
- var args *NodeList
+ var args []*Node
isddd := false
- for l := in; l != nil; l = l.Next {
- args = list(args, l.N.Left)
- isddd = l.N.Left.Isddd
+ for _, n := range in {
+ args = append(args, n.Left)
+ isddd = n.Left.Isddd
}
methodrcvr := getthisx(method.Type).Type.Type
// these strings are already in the reflect tables,
// so no space cost to use them here.
- var l *NodeList
+ var l []*Node
var v Val
v.U = rcvr.Type.Sym.Pkg.Name // package name
- l = list(l, nodlit(v))
+ l = append(l, nodlit(v))
v.U = rcvr.Type.Sym.Name // type name
- l = list(l, nodlit(v))
+ l = append(l, nodlit(v))
v.U = method.Sym.Name
- l = list(l, nodlit(v)) // method name
+ l = append(l, nodlit(v)) // method name
call := Nod(OCALL, syslook("panicwrap"), nil)
- call.List = l
+ setNodeSeq(&call.List, l)
n.Nbody.Set([]*Node{call})
fn.Nbody.Append(n)
}
} else {
fn.Func.Wrapper = true // ignore frame for panic+recover matching
call := Nod(OCALL, dot, nil)
- call.List = args
+ setNodeSeq(&call.List, args)
call.Isddd = isddd
if method.Type.Outtuple > 0 {
n := Nod(ORETURN, nil, nil)
- n.List = list1(call)
+ setNodeSeq(&n.List, []*Node{call})
call = n
}
n := newname(sym)
n.Class = PFUNC
tfn := Nod(OTFUNC, nil, nil)
- tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Ptrto(t))))
- tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
- tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
- tfn.Rlist = list(tfn.Rlist, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
+ appendNodeSeqNode(&tfn.List, Nod(ODCLFIELD, nil, typenod(Ptrto(t))))
+ appendNodeSeqNode(&tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
+ appendNodeSeqNode(&tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
+ appendNodeSeqNode(&tfn.Rlist, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
typecheck(&tfn, Etype)
n.Type = tfn.Type
return n
return et
}
-func listtreecopy(l *NodeList, lineno int32) *NodeList {
- var out *NodeList
- for ; l != nil; l = l.Next {
- out = list(out, treecopy(l.N, lineno))
+func listtreecopy(l nodesOrNodeList, lineno int32) []*Node {
+ var out []*Node
+ for it := nodeSeqIterate(l); !it.Done(); it.Next() {
+ out = append(out, treecopy(it.N(), lineno))
}
return out
}
n.Type = t
var def *Node
- var ll *NodeList
- for l := n.List; l != nil; l = l.Next {
- ncase := l.N
+ for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
+ ncase := it.N()
setlineno(n)
- if ncase.List == nil {
+ if nodeSeqLen(ncase.List) == 0 {
// default
if def != nil {
Yyerror("multiple defaults in switch (first at %v)", def.Line())
def = ncase
}
} else {
- for ll = ncase.List; ll != nil; ll = ll.Next {
- setlineno(ll.N)
- typecheck(&ll.N, Erv|Etype)
- if ll.N.Type == nil || t == nil {
+ for it2 := nodeSeqIterate(ncase.List); !it2.Done(); it2.Next() {
+ setlineno(it2.N())
+ typecheck(it2.P(), Erv|Etype)
+ if it2.N().Type == nil || t == nil {
continue
}
setlineno(ncase)
switch top {
// expression switch
case Erv:
- defaultlit(&ll.N, t)
+ defaultlit(it2.P(), t)
switch {
- case ll.N.Op == OTYPE:
- Yyerror("type %v is not an expression", ll.N.Type)
- case ll.N.Type != nil && assignop(ll.N.Type, t, nil) == 0 && assignop(t, ll.N.Type, nil) == 0:
+ case it2.N().Op == OTYPE:
+ Yyerror("type %v is not an expression", it2.N().Type)
+ case it2.N().Type != nil && assignop(it2.N().Type, t, nil) == 0 && assignop(t, it2.N().Type, nil) == 0:
if n.Left != nil {
- Yyerror("invalid case %v in switch on %v (mismatched types %v and %v)", ll.N, n.Left, ll.N.Type, t)
+ Yyerror("invalid case %v in switch on %v (mismatched types %v and %v)", it2.N(), n.Left, it2.N().Type, t)
} else {
- Yyerror("invalid case %v in switch (mismatched types %v and bool)", ll.N, ll.N.Type)
+ Yyerror("invalid case %v in switch (mismatched types %v and bool)", it2.N(), it2.N().Type)
}
- case nilonly != "" && !isnil(ll.N):
- Yyerror("invalid case %v in switch (can only compare %s %v to nil)", ll.N, nilonly, n.Left)
- case Isinter(t) && !Isinter(ll.N.Type) && algtype1(ll.N.Type, nil) == ANOEQ:
- Yyerror("invalid case %v in switch (incomparable type)", Nconv(ll.N, obj.FmtLong))
+ case nilonly != "" && !isnil(it2.N()):
+ Yyerror("invalid case %v in switch (can only compare %s %v to nil)", it2.N(), nilonly, n.Left)
+ case Isinter(t) && !Isinter(it2.N().Type) && algtype1(it2.N().Type, nil) == ANOEQ:
+ Yyerror("invalid case %v in switch (incomparable type)", Nconv(it2.N(), obj.FmtLong))
}
// type switch
var missing, have *Type
var ptr int
switch {
- case ll.N.Op == OLITERAL && Istype(ll.N.Type, TNIL):
- case ll.N.Op != OTYPE && ll.N.Type != nil: // should this be ||?
- Yyerror("%v is not a type", Nconv(ll.N, obj.FmtLong))
+ case it2.N().Op == OLITERAL && Istype(it2.N().Type, TNIL):
+ case it2.N().Op != OTYPE && it2.N().Type != nil: // should this be ||?
+ Yyerror("%v is not a type", Nconv(it2.N(), obj.FmtLong))
// reset to original type
- ll.N = n.Left.Right
- case ll.N.Type.Etype != TINTER && t.Etype == TINTER && !implements(ll.N.Type, t, &missing, &have, &ptr):
+ *it2.P() = n.Left.Right
+ case it2.N().Type.Etype != TINTER && t.Etype == TINTER && !implements(it2.N().Type, t, &missing, &have, &ptr):
if have != nil && !missing.Broke && !have.Broke {
- Yyerror("impossible type switch case: %v cannot have dynamic type %v"+" (wrong type for %v method)\n\thave %v%v\n\twant %v%v", Nconv(n.Left.Right, obj.FmtLong), ll.N.Type, missing.Sym, have.Sym, Tconv(have.Type, obj.FmtShort), missing.Sym, Tconv(missing.Type, obj.FmtShort))
+ Yyerror("impossible type switch case: %v cannot have dynamic type %v"+" (wrong type for %v method)\n\thave %v%v\n\twant %v%v", Nconv(n.Left.Right, obj.FmtLong), it2.N().Type, missing.Sym, have.Sym, Tconv(have.Type, obj.FmtShort), missing.Sym, Tconv(missing.Type, obj.FmtShort))
} else if !missing.Broke {
- Yyerror("impossible type switch case: %v cannot have dynamic type %v"+" (missing %v method)", Nconv(n.Left.Right, obj.FmtLong), ll.N.Type, missing.Sym)
+ Yyerror("impossible type switch case: %v cannot have dynamic type %v"+" (missing %v method)", Nconv(n.Left.Right, obj.FmtLong), it2.N().Type, missing.Sym)
}
}
}
}
if top == Etype && n.Type != nil {
- ll = ncase.List
- if ncase.Rlist != nil {
- nvar := ncase.Rlist.N
- if ll != nil && ll.Next == nil && ll.N.Type != nil && !Istype(ll.N.Type, TNIL) {
+ ll := ncase.List
+ if nodeSeqLen(ncase.Rlist) != 0 {
+ nvar := nodeSeqFirst(ncase.Rlist)
+ if nodeSeqLen(ll) == 1 && nodeSeqFirst(ll).Type != nil && !Istype(nodeSeqFirst(ll).Type, TNIL) {
// single entry type switch
- nvar.Name.Param.Ntype = typenod(ll.N.Type)
+ nvar.Name.Param.Ntype = typenod(nodeSeqFirst(ll).Type)
} else {
// multiple entry type switch or default
nvar.Name.Param.Ntype = typenod(n.Type)
}
typecheck(&nvar, Erv|Easgn)
- ncase.Rlist.N = nvar
+ rit := nodeSeqIterate(ncase.Rlist)
+ *rit.P() = nvar
}
}
// enumerate the cases, and lop off the default case
cc := caseClauses(sw, s.kind)
- sw.List = nil
+ setNodeSeq(&sw.List, nil)
var def *Node
if len(cc) > 0 && cc[0].typ == caseKindDefault {
def = cc[0].node.Right
}
typecheck(&a.Left, Erv)
a.Nbody.Set([]*Node{s.walkCases(cc[:half])})
- a.Rlist = list1(s.walkCases(cc[half:]))
+ setNodeSeq(&a.Rlist, []*Node{s.walkCases(cc[half:])})
return a
}
// It makes labels between cases and statements
// and deals with fallthrough, break, and unreachable statements.
func casebody(sw *Node, typeswvar *Node) {
- if sw.List == nil {
+ if nodeSeqLen(sw.List) == 0 {
return
}
lno := setlineno(sw)
- var cas *NodeList // cases
- var stat []*Node // statements
- var def *Node // defaults
+ var cas []*Node // cases
+ var stat []*Node // statements
+ var def *Node // defaults
br := Nod(OBREAK, nil, nil)
- for l := sw.List; l != nil; l = l.Next {
- n := l.N
+ for it := nodeSeqIterate(sw.List); !it.Done(); it.Next() {
+ n := it.N()
setlineno(n)
if n.Op != OXCASE {
Fatalf("casebody %v", Oconv(int(n.Op), 0))
}
n.Op = OCASE
- needvar := count(n.List) != 1 || n.List.N.Op == OLITERAL
+ needvar := nodeSeqLen(n.List) != 1 || nodeSeqFirst(n.List).Op == OLITERAL
jmp := Nod(OGOTO, newCaseLabel(), nil)
- if n.List == nil {
+ if nodeSeqLen(n.List) == 0 {
if def != nil {
Yyerror("more than one default case")
}
def = n
}
- if n.List != nil && n.List.Next == nil {
+ if nodeSeqLen(n.List) == 1 {
// one case -- reuse OCASE node
- n.Left = n.List.N
+ n.Left = nodeSeqFirst(n.List)
n.Right = jmp
- n.List = nil
- cas = list(cas, n)
+ setNodeSeq(&n.List, nil)
+ cas = append(cas, n)
} else {
// expand multi-valued cases
- for lc := n.List; lc != nil; lc = lc.Next {
- cas = list(cas, Nod(OCASE, lc.N, jmp))
+ for lcit := nodeSeqIterate(n.List); !lcit.Done(); lcit.Next() {
+ cas = append(cas, Nod(OCASE, lcit.N(), jmp))
}
}
stat = append(stat, Nod(OLABEL, jmp.Left, nil))
- if typeswvar != nil && needvar && n.Rlist != nil {
+ if typeswvar != nil && needvar && nodeSeqLen(n.Rlist) != 0 {
l := []*Node{
- Nod(ODCL, n.Rlist.N, nil),
- Nod(OAS, n.Rlist.N, typeswvar),
+ Nod(ODCL, nodeSeqFirst(n.Rlist), nil),
+ Nod(OAS, nodeSeqFirst(n.Rlist), typeswvar),
}
typecheckslice(l, Etop)
stat = append(stat, l...)
Yyerror("cannot fallthrough in type switch")
}
- if l.Next == nil {
+ if it.Len() <= 1 {
setlineno(last)
Yyerror("cannot fallthrough final case in switch")
}
stat = append(stat, br)
if def != nil {
- cas = list(cas, def)
+ cas = append(cas, def)
}
- sw.List = cas
+ setNodeSeq(&sw.List, cas)
sw.Nbody.Set(stat)
lineno = lno
}
// Kind is the kind of switch statement.
func caseClauses(sw *Node, kind int) []*caseClause {
var cc []*caseClause
- for l := sw.List; l != nil; l = l.Next {
- n := l.N
+ for it := nodeSeqIterate(sw.List); !it.Done(); it.Next() {
+ n := it.N()
c := new(caseClause)
cc = append(cc, c)
c.ordinal = len(cc)
sw.Left = nil
if cond == nil {
- sw.List = nil
+ setNodeSeq(&sw.List, nil)
return
}
if cond.Right == nil {
casebody(sw, s.facename)
cc := caseClauses(sw, switchKindType)
- sw.List = nil
+ setNodeSeq(&sw.List, nil)
var def *Node
if len(cc) > 0 && cc[0].typ == caseKindDefault {
def = cc[0].node.Right
i.Nbody.Set([]*Node{Nod(OGOTO, lbl, nil)})
// Wrap default case with label.
blk := Nod(OBLOCK, nil, nil)
- blk.List = list(list1(Nod(OLABEL, lbl, nil)), def)
+ setNodeSeq(&blk.List, []*Node{Nod(OLABEL, lbl, nil), def})
def = blk
}
typecheck(&i.Left, Erv)
if nerrors == 0 {
cas = append(cas, def)
sw.Nbody.Set(append(cas, sw.Nbody.Slice()...))
- sw.List = nil
+ setNodeSeq(&sw.List, nil)
walkstmtlist(sw.Nbody)
}
}
func (s *typeSwitch) typeone(t *Node) *Node {
var name *Node
var init *NodeList
- if t.Rlist == nil {
+ if nodeSeqLen(t.Rlist) == 0 {
name = nblank
typecheck(&nblank, Erv|Easgn)
} else {
- name = t.Rlist.N
+ name = nodeSeqFirst(t.Rlist)
init = list1(Nod(ODCL, name, nil))
a := Nod(OAS, name, nil)
typecheck(&a, Etop)
}
a := Nod(OAS2, nil, nil)
- a.List = list(list1(name), s.okname) // name, ok =
+ setNodeSeq(&a.List, []*Node{name, s.okname}) // name, ok =
b := Nod(ODOTTYPE, s.facename, nil)
b.Type = t.Left.Type // interface.(type)
- a.Rlist = list1(b)
+ setNodeSeq(&a.Rlist, []*Node{b})
typecheck(&a, Etop)
init = list(init, a)
a.Left = Nod(OLE, s.hashname, Nodintconst(int64(cc[half-1].hash)))
typecheck(&a.Left, Erv)
a.Nbody.Set([]*Node{s.walkCases(cc[:half])})
- a.Rlist = list1(s.walkCases(cc[half:]))
+ setNodeSeq(&a.Rlist, []*Node{s.walkCases(cc[half:])})
return a
}
return true
}
- return callrecv(n.Left) || callrecv(n.Right) || callrecvlist(n.Ninit) || callrecvslice(n.Nbody.Slice()) || callrecvlist(n.List) || callrecvlist(n.Rlist)
+ return callrecv(n.Left) || callrecv(n.Right) || callrecvlist(n.Ninit) || callrecvlist(n.Nbody) || callrecvlist(n.List) || callrecvlist(n.Rlist)
}
-func callrecvlist(l *NodeList) bool {
- for ; l != nil; l = l.Next {
- if callrecv(l.N) {
- return true
- }
- }
- return false
-}
-
-func callrecvslice(l []*Node) bool {
- for _, n := range l {
- if callrecv(n) {
+func callrecvlist(l nodesOrNodeList) bool {
+ for it := nodeSeqIterate(l); !it.Done(); it.Next() {
+ if callrecv(it.N()) {
return true
}
}
n.Type = nil
return
}
- n.List = nil
+ setNodeSeq(&n.List, nil)
case OTINTER:
ok |= Etype
n.Op = OADDSTR
if l.Op == OADDSTR {
- n.List = l.List
+ setNodeSeq(&n.List, l.List)
} else {
- n.List = list1(l)
+ setNodeSeq(&n.List, []*Node{l})
}
if r.Op == OADDSTR {
- n.List = concat(n.List, r.List)
+ appendNodeSeq(&n.List, r.List)
} else {
- n.List = list(n.List, r)
+ appendNodeSeqNode(&n.List, r)
}
n.Left = nil
n.Right = nil
return
}
- if count(n.List) == 1 && !n.Isddd {
- typecheck(&n.List.N, Erv|Efnstruct)
+ if nodeSeqLen(n.List) == 1 && !n.Isddd {
+ it := nodeSeqIterate(n.List)
+ typecheck(it.P(), Erv|Efnstruct)
} else {
typechecklist(n.List, Erv)
}
ok |= Erv
var r *Node
var l *Node
- if count(n.List) == 1 {
+ if nodeSeqLen(n.List) == 1 {
typechecklist(n.List, Efnstruct)
- if n.List.N.Op != OCALLFUNC && n.List.N.Op != OCALLMETH {
+ if nodeSeqFirst(n.List).Op != OCALLFUNC && nodeSeqFirst(n.List).Op != OCALLMETH {
Yyerror("invalid operation: complex expects two arguments")
n.Type = nil
return
}
- t := n.List.N.Left.Type
+ t := nodeSeqFirst(n.List).Left.Type
if t.Outtuple != 2 {
- Yyerror("invalid operation: complex expects two arguments, %v returns %d results", n.List.N, t.Outtuple)
+ Yyerror("invalid operation: complex expects two arguments, %v returns %d results", nodeSeqFirst(n.List), t.Outtuple)
n.Type = nil
return
}
- t = n.List.N.Type.Type
+ t = nodeSeqFirst(n.List).Type.Type
l = t.Nname
r = t.Down.Nname
} else {
case ODELETE:
args := n.List
- if args == nil {
+ if nodeSeqLen(args) == 0 {
Yyerror("missing arguments to delete")
n.Type = nil
return
}
- if args.Next == nil {
+ if nodeSeqLen(args) == 1 {
Yyerror("missing second (key) argument to delete")
n.Type = nil
return
}
- if args.Next.Next != nil {
+ if nodeSeqLen(args) != 2 {
Yyerror("too many arguments to delete")
n.Type = nil
return
ok |= Etop
typechecklist(args, Erv)
- l := args.N
- r := args.Next.N
+ l := nodeSeqFirst(args)
+ r := nodeSeqSecond(args)
if l.Type != nil && l.Type.Etype != TMAP {
Yyerror("first argument to delete must be map; have %v", Tconv(l.Type, obj.FmtLong))
n.Type = nil
return
}
- args.Next.N = assignconv(r, l.Type.Down, "delete")
+ it := nodeSeqIterate(args)
+ it.Next()
+ *it.P() = assignconv(r, l.Type.Down, "delete")
break OpSwitch
case OAPPEND:
ok |= Erv
args := n.List
- if args == nil {
+ if nodeSeqLen(args) == 0 {
Yyerror("missing arguments to append")
n.Type = nil
return
}
- if count(args) == 1 && !n.Isddd {
- typecheck(&args.N, Erv|Efnstruct)
+ if nodeSeqLen(args) == 1 && !n.Isddd {
+ it := nodeSeqIterate(args)
+ typecheck(it.P(), Erv|Efnstruct)
} else {
typechecklist(args, Erv)
}
- t := args.N.Type
+ t := nodeSeqFirst(args).Type
if t == nil {
n.Type = nil
return
n.Type = t
if !Isslice(t) {
- if Isconst(args.N, CTNIL) {
+ if Isconst(nodeSeqFirst(args), CTNIL) {
Yyerror("first argument to append must be typed slice; have untyped nil")
n.Type = nil
return
}
if n.Isddd {
- if args.Next == nil {
+ if nodeSeqLen(args) == 1 {
Yyerror("cannot use ... on first argument to append")
n.Type = nil
return
}
- if args.Next.Next != nil {
+ if nodeSeqLen(args) != 2 {
Yyerror("too many arguments to append")
n.Type = nil
return
}
- if Istype(t.Type, TUINT8) && Istype(args.Next.N.Type, TSTRING) {
- defaultlit(&args.Next.N, Types[TSTRING])
+ if Istype(t.Type, TUINT8) && Istype(nodeSeqSecond(args).Type, TSTRING) {
+ it := nodeSeqIterate(args)
+ it.Next()
+ defaultlit(it.P(), Types[TSTRING])
break OpSwitch
}
- args.Next.N = assignconv(args.Next.N, t.Orig, "append")
+ it := nodeSeqIterate(args)
+ it.Next()
+ *it.P() = assignconv(nodeSeqSecond(args), t.Orig, "append")
break OpSwitch
}
}
}
} else {
- for args = args.Next; args != nil; args = args.Next {
- if args.N.Type == nil {
+ it := nodeSeqIterate(args)
+ it.Next()
+ for ; !it.Done(); it.Next() {
+ if it.N().Type == nil {
continue
}
- args.N = assignconv(args.N, t.Type, "append")
+ *it.P() = assignconv(it.N(), t.Type, "append")
}
}
case OCOPY:
ok |= Etop | Erv
args := n.List
- if args == nil || args.Next == nil {
+ if nodeSeqLen(args) == 0 || args.Next == nil {
Yyerror("missing arguments to copy")
n.Type = nil
return
}
- if args.Next.Next != nil {
+ if nodeSeqLen(args) > 2 {
Yyerror("too many arguments to copy")
n.Type = nil
return
}
- n.Left = args.N
- n.Right = args.Next.N
- n.List = nil
+ n.Left = nodeSeqFirst(args)
+ n.Right = nodeSeqSecond(args)
+ setNodeSeq(&n.List, nil)
n.Type = Types[TINT]
typecheck(&n.Left, Erv)
typecheck(&n.Right, Erv)
case OMAKE:
ok |= Erv
- args := n.List
- if args == nil {
+ args := nodeSeqIterate(n.List)
+ if args.Len() == 0 {
Yyerror("missing argument to make")
n.Type = nil
return
}
- n.List = nil
- l := args.N
- args = args.Next
+ setNodeSeq(&n.List, nil)
+ l := args.N()
+ args.Next()
typecheck(&l, Etype)
t := l.Type
if t == nil {
return
}
- if args == nil {
+ if args.Done() {
Yyerror("missing len argument to make(%v)", t)
n.Type = nil
return
}
- l = args.N
- args = args.Next
+ l = args.N()
+ args.Next()
typecheck(&l, Erv)
var r *Node
- if args != nil {
- r = args.N
- args = args.Next
+ if !args.Done() {
+ r = args.N()
+ args.Next()
typecheck(&r, Erv)
}
n.Op = OMAKESLICE
case TMAP:
- if args != nil {
- l = args.N
- args = args.Next
+ if !args.Done() {
+ l = args.N()
+ args.Next()
typecheck(&l, Erv)
defaultlit(&l, Types[TINT])
if l.Type == nil {
case TCHAN:
l = nil
- if args != nil {
- l = args.N
- args = args.Next
+ if !args.Done() {
+ l = args.N()
+ args.Next()
typecheck(&l, Erv)
defaultlit(&l, Types[TINT])
if l.Type == nil {
n.Op = OMAKECHAN
}
- if args != nil {
+ if !args.Done() {
Yyerror("too many arguments to make(%v)", t)
n.Op = OMAKE
n.Type = nil
case ONEW:
ok |= Erv
args := n.List
- if args == nil {
+ if nodeSeqLen(args) == 0 {
Yyerror("missing argument to new")
n.Type = nil
return
}
- l := args.N
+ l := nodeSeqFirst(args)
typecheck(&l, Etype)
t := l.Type
if t == nil {
n.Type = nil
return
}
- if args.Next != nil {
+ if nodeSeqLen(args) > 1 {
Yyerror("too many arguments to new(%v)", t)
n.Type = nil
return
case OPRINT, OPRINTN:
ok |= Etop
typechecklist(n.List, Erv|Eindir) // Eindir: address does not escape
- for args := n.List; args != nil; args = args.Next {
+ for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
// Special case for print: int constant is int64, not int.
- if Isconst(args.N, CTINT) {
- defaultlit(&args.N, Types[TINT64])
+ if Isconst(it.N(), CTINT) {
+ defaultlit(it.P(), Types[TINT64])
} else {
- defaultlit(&args.N, nil)
+ defaultlit(it.P(), nil)
}
}
case ORECOVER:
ok |= Erv | Etop
- if n.List != nil {
+ if nodeSeqLen(n.List) != 0 {
Yyerror("too many arguments to recover")
n.Type = nil
return
case ORETURN:
ok |= Etop
- if count(n.List) == 1 {
+ if nodeSeqLen(n.List) == 1 {
typechecklist(n.List, Erv|Efnstruct)
} else {
typechecklist(n.List, Erv)
return
}
- if Curfn.Type.Outnamed && n.List == nil {
+ if Curfn.Type.Outnamed && nodeSeqLen(n.List) == 0 {
break OpSwitch
}
typecheckaste(ORETURN, nil, false, getoutargx(Curfn.Type), n.List, func() string { return "return argument" })
if n.Left != nil {
return true
}
- if n.List == nil {
+ if nodeSeqLen(n.List) == 0 {
p := fmt.Sprintf(f, args...)
Yyerror("missing argument to %s: %v", p, n)
return false
}
- if n.List.Next != nil {
+ if nodeSeqLen(n.List) > 1 {
p := fmt.Sprintf(f, args...)
Yyerror("too many arguments to %s: %v", p, n)
- n.Left = n.List.N
- n.List = nil
+ n.Left = nodeSeqFirst(n.List)
+ setNodeSeq(&n.List, nil)
return false
}
- n.Left = n.List.N
- n.List = nil
+ n.Left = nodeSeqFirst(n.List)
+ setNodeSeq(&n.List, nil)
return true
}
if n.Left != nil {
return true
}
- if n.List == nil {
+ if nodeSeqLen(n.List) == 0 {
Yyerror("missing argument to %v - %v", Oconv(int(n.Op), 0), n)
return false
}
- n.Left = n.List.N
- if n.List.Next == nil {
+ n.Left = nodeSeqFirst(n.List)
+ if nodeSeqLen(n.List) == 1 {
Yyerror("missing argument to %v - %v", Oconv(int(n.Op), 0), n)
- n.List = nil
+ setNodeSeq(&n.List, nil)
return false
}
- if n.List.Next.Next != nil {
+ if nodeSeqLen(n.List) > 2 {
Yyerror("too many arguments to %v - %v", Oconv(int(n.Op), 0), n)
- n.List = nil
+ setNodeSeq(&n.List, nil)
return false
}
- n.Right = n.List.Next.N
- n.List = nil
+ n.Right = nodeSeqSecond(n.List)
+ setNodeSeq(&n.List, nil)
return true
}
}()
if n.Right == nil {
- if n.List != nil {
- setlineno(n.List.N)
+ if nodeSeqLen(n.List) != 0 {
+ setlineno(nodeSeqFirst(n.List))
}
Yyerror("missing type in composite literal")
n.Type = nil
case TARRAY:
// Only allocate hash if there are some key/value pairs.
var hash map[int64]*Node
- for ll := n.List; ll != nil; ll = ll.Next {
- if ll.N.Op == OKEY {
+ for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
+ if it.N().Op == OKEY {
hash = make(map[int64]*Node)
break
}
}
length := int64(0)
i := 0
- for ll := n.List; ll != nil; ll = ll.Next {
- l := ll.N
+ for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
+ l := it.N()
setlineno(l)
if l.Op != OKEY {
l = Nod(OKEY, Nodintconst(int64(i)), l)
l.Left.Type = Types[TINT]
l.Left.Typecheck = 1
- ll.N = l
+ *it.P() = l
}
typecheck(&l.Left, Erv)
case TMAP:
hash := make(map[uint32][]*Node)
var l *Node
- for ll := n.List; ll != nil; ll = ll.Next {
- l = ll.N
+ for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
+ l = it.N()
setlineno(l)
if l.Op != OKEY {
- typecheck(&ll.N, Erv)
+ typecheck(it.P(), Erv)
Yyerror("missing key in map literal")
continue
}
case TSTRUCT:
bad := 0
- if n.List != nil && nokeys(n.List) {
+ if nodeSeqLen(n.List) != 0 && nokeys(n.List) {
// simple list of variables
f := t.Type
var s *Sym
- for ll := n.List; ll != nil; ll = ll.Next {
- setlineno(ll.N)
- typecheck(&ll.N, Erv)
+ for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
+ setlineno(it.N())
+ typecheck(it.P(), Erv)
if f == nil {
if bad == 0 {
Yyerror("too many values in struct initializer")
}
// No pushtype allowed here. Must name fields for that.
- ll.N = assignconv(ll.N, f.Type, "field value")
+ *it.P() = assignconv(it.N(), f.Type, "field value")
- ll.N = Nod(OKEY, newname(f.Sym), ll.N)
- ll.N.Left.Type = f
- ll.N.Left.Typecheck = 1
+ *it.P() = Nod(OKEY, newname(f.Sym), it.N())
+ it.N().Left.Type = f
+ it.N().Left.Typecheck = 1
f = f.Down
}
var f *Type
var l *Node
var s1 *Sym
- for ll := n.List; ll != nil; ll = ll.Next {
- l = ll.N
+ for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
+ l = it.N()
setlineno(l)
if l.Op != OKEY {
if bad == 0 {
Yyerror("mixture of field:value and value initializers")
}
bad++
- typecheck(&ll.N, Erv)
+ typecheck(it.P(), Erv)
continue
}
}
func typecheckas2(n *Node) {
- for ll := n.List; ll != nil; ll = ll.Next {
+ for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
// delicate little dance.
- ll.N = resolve(ll.N)
+ *it.P() = resolve(it.N())
- if ll.N.Name == nil || ll.N.Name.Defn != n || ll.N.Name.Param.Ntype != nil {
- typecheck(&ll.N, Erv|Easgn)
+ if it.N().Name == nil || it.N().Name.Defn != n || it.N().Name.Param.Ntype != nil {
+ typecheck(it.P(), Erv|Easgn)
}
}
- cl := count(n.List)
- cr := count(n.Rlist)
+ cl := nodeSeqLen(n.List)
+ cr := nodeSeqLen(n.Rlist)
if cl > 1 && cr == 1 {
- typecheck(&n.Rlist.N, Erv|Efnstruct)
+ it := nodeSeqIterate(n.Rlist)
+ typecheck(it.P(), Erv|Efnstruct)
} else {
typechecklist(n.Rlist, Erv)
}
var r *Node
if cl == cr {
// easy
- ll := n.List
- lr := n.Rlist
- for ; ll != nil; ll, lr = ll.Next, lr.Next {
- if ll.N.Type != nil && lr.N.Type != nil {
- lr.N = assignconv(lr.N, ll.N.Type, "assignment")
+ llit := nodeSeqIterate(n.List)
+ lrit := nodeSeqIterate(n.Rlist)
+ for llit = nodeSeqIterate(n.List); !llit.Done(); llit.Next() {
+ if llit.N().Type != nil && lrit.N().Type != nil {
+ *lrit.P() = assignconv(lrit.N(), llit.N().Type, "assignment")
}
- if ll.N.Name != nil && ll.N.Name.Defn == n && ll.N.Name.Param.Ntype == nil {
- defaultlit(&lr.N, nil)
- ll.N.Type = lr.N.Type
+ if llit.N().Name != nil && llit.N().Name.Defn == n && llit.N().Name.Param.Ntype == nil {
+ defaultlit(lrit.P(), nil)
+ llit.N().Type = lrit.N().Type
}
+ lrit.Next()
}
goto out
}
- l = n.List.N
- r = n.Rlist.N
+ l = nodeSeqFirst(n.List)
+ r = nodeSeqFirst(n.Rlist)
// x,y,z = f()
if cr == 1 {
n.Op = OAS2FUNC
var s Iter
t := Structfirst(&s, &r.Type)
- for ll := n.List; ll != nil; ll = ll.Next {
- if t.Type != nil && ll.N.Type != nil {
- checkassignto(t.Type, ll.N)
+ for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
+ if t.Type != nil && it.N().Type != nil {
+ checkassignto(t.Type, it.N())
}
- if ll.N.Name != nil && ll.N.Name.Defn == n && ll.N.Name.Param.Ntype == nil {
- ll.N.Type = t.Type
+ if it.N().Name != nil && it.N().Name.Defn == n && it.N().Name.Param.Ntype == nil {
+ it.N().Type = t.Type
}
t = structnext(&s)
}
if l.Name != nil && l.Name.Defn == n {
l.Type = r.Type
}
- l := n.List.Next.N
+ l := nodeSeqSecond(n.List)
if l.Type != nil && l.Type.Etype != TBOOL {
checkassignto(Types[TBOOL], l)
}
out:
n.Typecheck = 1
- for ll := n.List; ll != nil; ll = ll.Next {
- if ll.N.Typecheck == 0 {
- typecheck(&ll.N, Erv|Easgn)
+ for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
+ if it.N().Typecheck == 0 {
+ typecheck(it.P(), Erv|Easgn)
}
}
}
}
s := n.Left.Val().U.(string)
- var l *NodeList
+ var l []*Node
if n.Type.Type.Etype == TUINT8 {
// []byte
for i := 0; i < len(s); i++ {
- l = list(l, Nod(OKEY, Nodintconst(int64(i)), Nodintconst(int64(s[0]))))
+ l = append(l, Nod(OKEY, Nodintconst(int64(i)), Nodintconst(int64(s[0]))))
}
} else {
// []rune
i := 0
for _, r := range s {
- l = list(l, Nod(OKEY, Nodintconst(int64(i)), Nodintconst(int64(r))))
+ l = append(l, Nod(OKEY, Nodintconst(int64(i)), Nodintconst(int64(r))))
i++
}
}
nn := Nod(OCOMPLIT, nil, typenod(n.Type))
- nn.List = l
+ setNodeSeq(&nn.List, l)
typecheck(&nn, Erv)
*np = nn
}
markbreak(n.Right, implicit)
markbreaklist(n.Ninit, implicit)
- markbreakslice(n.Nbody.Slice(), implicit)
+ markbreaklist(n.Nbody, implicit)
markbreaklist(n.List, implicit)
markbreaklist(n.Rlist, implicit)
}
}
-func markbreaklist(l *NodeList, implicit *Node) {
- var n *Node
- var lab *Label
-
- for ; l != nil; l = l.Next {
- n = l.N
- if n.Op == OLABEL && l.Next != nil && n.Name.Defn == l.Next.N {
- switch n.Name.Defn.Op {
- case OFOR,
- OSWITCH,
- OTYPESW,
- OSELECT,
- ORANGE:
- lab = new(Label)
- lab.Def = n.Name.Defn
- n.Left.Sym.Label = lab
- markbreak(n.Name.Defn, n.Name.Defn)
- n.Left.Sym.Label = nil
- l = l.Next
- continue
- }
- }
-
- markbreak(n, implicit)
- }
-}
-
-func markbreakslice(l []*Node, implicit *Node) {
- for i := 0; i < len(l); i++ {
- n := l[i]
- if n.Op == OLABEL && i+1 < len(l) && n.Name.Defn == l[i+1] {
+func markbreaklist(l nodesOrNodeList, implicit *Node) {
+ for it := nodeSeqIterate(l); !it.Done(); it.Next() {
+ n := it.N()
+ if n.Op == OLABEL && it.Len() > 1 && n.Name.Defn == nodeSeqSlice(it.Seq())[1] {
switch n.Name.Defn.Op {
case OFOR, OSWITCH, OTYPESW, OSELECT, ORANGE:
lab := new(Label)
n.Left.Sym.Label = lab
markbreak(n.Name.Defn, n.Name.Defn)
n.Left.Sym.Label = nil
- i++
+ it.Next()
continue
}
}
return false
}
def := 0
- for l := n.List; l != nil; l = l.Next {
- if !l.N.Nbody.isterminating() {
+ for it := nodeSeqIterate(n.List); !it.Done(); it.Next() {
+ if !it.N().Nbody.isterminating() {
return false
}
- if l.N.List == nil { // default
+ if nodeSeqLen(it.N().List) == 0 { // default
def = 1
}
}
func checkreturn(fn *Node) {
if fn.Type.Outtuple != 0 && len(fn.Nbody.Slice()) != 0 {
- markbreakslice(fn.Nbody.Slice(), nil)
+ markbreaklist(fn.Nbody, nil)
if !fn.Nbody.isterminating() {
yyerrorl(fn.Func.Endlineno, "missing return at end of function")
}