func (n *CommStmt) copy() Node {
c := *n
c.init = c.init.Copy()
- c.List = c.List.Copy()
c.Body = c.Body.Copy()
return &c
}
func (n *CommStmt) doChildren(do func(Node) error) error {
var err error
err = maybeDoList(n.init, err, do)
- err = maybeDoList(n.List, err, do)
err = maybeDo(n.Comm, err, do)
err = maybeDoList(n.Body, err, do)
return err
}
func (n *CommStmt) editChildren(edit func(Node) Node) {
editList(n.init, edit)
- editList(n.List, edit)
n.Comm = maybeEdit(n.Comm, edit)
editList(n.Body, edit)
}
type CommStmt struct {
miniStmt
- List Nodes // list of expressions for switch, early select
- Comm Node // communication case (Exprs[0]) after select is type-checked
+ Comm Node // communication case
Body Nodes
}
-func NewCommStmt(pos src.XPos, list, body []Node) *CommStmt {
- n := &CommStmt{List: list, Body: body}
+func NewCommStmt(pos src.XPos, comm Node, body []Node) *CommStmt {
+ n := &CommStmt{Comm: comm, Body: body}
n.pos = pos
n.op = OCASE
return n
HasBreak bool
}
-func NewForStmt(pos src.XPos, init []Node, cond, post Node, body []Node) *ForStmt {
+func NewForStmt(pos src.XPos, init Node, cond, post Node, body []Node) *ForStmt {
n := &ForStmt{Cond: cond, Post: post}
n.pos = pos
n.op = OFOR
- n.init.Set(init)
+ if init != nil {
+ n.init = []Node{init}
+ }
n.Body.Set(body)
return n
}
func (p *noder) ifStmt(stmt *syntax.IfStmt) ir.Node {
p.openScope(stmt.Pos())
- init := p.simpleStmt(stmt.Init)
+ init := p.stmt(stmt.Init)
n := ir.NewIfStmt(p.pos(stmt), p.expr(stmt.Cond), p.blockStmt(stmt.Then), nil)
- *n.PtrInit() = init
+ if init != nil {
+ *n.PtrInit() = []ir.Node{init}
+ }
if stmt.Else != nil {
e := p.stmt(stmt.Else)
if e.Op() == ir.OBLOCK {
return n
}
- n := ir.NewForStmt(p.pos(stmt), p.simpleStmt(stmt.Init), p.expr(stmt.Cond), p.stmt(stmt.Post), p.blockStmt(stmt.Body))
+ n := ir.NewForStmt(p.pos(stmt), p.stmt(stmt.Init), p.expr(stmt.Cond), p.stmt(stmt.Post), p.blockStmt(stmt.Body))
p.closeAnotherScope()
return n
}
func (p *noder) switchStmt(stmt *syntax.SwitchStmt) ir.Node {
p.openScope(stmt.Pos())
- init := p.simpleStmt(stmt.Init)
+ init := p.stmt(stmt.Init)
n := ir.NewSwitchStmt(p.pos(stmt), p.expr(stmt.Tag), nil)
- *n.PtrInit() = init
+ if init != nil {
+ *n.PtrInit() = []ir.Node{init}
+ }
var tswitch *ir.TypeSwitchGuard
if l := n.Tag; l != nil && l.Op() == ir.OTYPESW {
return ir.NewSelectStmt(p.pos(stmt), p.commClauses(stmt.Body, stmt.Rbrace))
}
-func (p *noder) simpleStmt(stmt syntax.SimpleStmt) []ir.Node {
- if stmt == nil {
- return nil
- }
- return []ir.Node{p.stmt(stmt)}
-}
-
func (p *noder) commClauses(clauses []*syntax.CommClause, rbrace syntax.Pos) []*ir.CommStmt {
nodes := make([]*ir.CommStmt, len(clauses))
for i, clause := range clauses {
}
p.openScope(clause.Pos())
- nodes[i] = ir.NewCommStmt(p.pos(clause), p.simpleStmt(clause.Comm), p.stmts(clause.Body))
+ nodes[i] = ir.NewCommStmt(p.pos(clause), p.stmt(clause.Comm), p.stmts(clause.Body))
}
if len(clauses) > 0 {
p.closeScope(rbrace)
w.uint64(uint64(len(cases)))
for _, cas := range cases {
w.pos(cas.Pos())
- w.stmtList(cas.List)
+ w.node(cas.Comm)
w.stmtList(cas.Body)
}
}
func (r *importReader) commList() []*ir.CommStmt {
cases := make([]*ir.CommStmt, r.uint64())
for i := range cases {
- cases[i] = ir.NewCommStmt(r.pos(), r.stmtList(), r.stmtList())
+ cases[i] = ir.NewCommStmt(r.pos(), r.node(), r.stmtList())
}
return cases
}
case ir.OFOR:
pos, init := r.pos(), r.stmtList()
cond, post := r.exprsOrNil()
- return ir.NewForStmt(pos, init, cond, post, r.stmtList())
+ n := ir.NewForStmt(pos, nil, cond, post, r.stmtList())
+ n.PtrInit().Set(init)
+ return n
case ir.ORANGE:
pos := r.pos()
// select
func tcSelect(sel *ir.SelectStmt) {
- var def ir.Node
+ var def *ir.CommStmt
lno := ir.SetPos(sel)
Stmts(sel.Init())
for _, ncase := range sel.Cases {
- if len(ncase.List) == 0 {
+ if ncase.Comm == nil {
// default
if def != nil {
base.ErrorfAt(ncase.Pos(), "multiple defaults in select (first at %v)", ir.Line(def))
} else {
def = ncase
}
- } else if len(ncase.List) > 1 {
- base.ErrorfAt(ncase.Pos(), "select cases cannot be lists")
} else {
- ncase.List[0] = Stmt(ncase.List[0])
- n := ncase.List[0]
+ n := Stmt(ncase.Comm)
ncase.Comm = n
- ncase.List.Set(nil)
- oselrecv2 := func(dst, recv ir.Node, colas bool) {
- n := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, nil, nil)
- n.Lhs = []ir.Node{dst, ir.BlankNode}
- n.Rhs = []ir.Node{recv}
- n.Def = colas
+ oselrecv2 := func(dst, recv ir.Node, def bool) {
+ n := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, []ir.Node{dst, ir.BlankNode}, []ir.Node{recv})
+ n.Def = def
n.SetTypecheck(1)
ncase.Comm = n
}