ntypeType := lookup("Ntype")
nodesType := lookup("Nodes")
slicePtrCaseStmtType := types.NewSlice(types.NewPointer(lookup("CaseStmt")))
+ slicePtrCommStmtType := types.NewSlice(types.NewPointer(lookup("CommStmt")))
ptrFieldType := types.NewPointer(lookup("Field"))
slicePtrFieldType := types.NewSlice(ptrFieldType)
ptrIdentType := types.NewPointer(lookup("Ident"))
fmt.Fprintf(&buf, "c.%s = c.%s.Copy()\n", name, name)
case is(slicePtrCaseStmtType):
fmt.Fprintf(&buf, "c.%s = copyCases(c.%s)\n", name, name)
+ case is(slicePtrCommStmtType):
+ fmt.Fprintf(&buf, "c.%s = copyComms(c.%s)\n", name, name)
case is(ptrFieldType):
fmt.Fprintf(&buf, "if c.%s != nil { c.%s = c.%s.copy() }\n", name, name, name)
case is(slicePtrFieldType):
fmt.Fprintf(&buf, "err = maybeDoList(n.%s, err, do)\n", name)
case is(slicePtrCaseStmtType):
fmt.Fprintf(&buf, "err = maybeDoCases(n.%s, err, do)\n", name)
+ case is(slicePtrCommStmtType):
+ fmt.Fprintf(&buf, "err = maybeDoComms(n.%s, err, do)\n", name)
case is(ptrFieldType):
fmt.Fprintf(&buf, "err = maybeDoField(n.%s, err, do)\n", name)
case is(slicePtrFieldType):
fmt.Fprintf(&buf, "editList(n.%s, edit)\n", name)
case is(slicePtrCaseStmtType):
fmt.Fprintf(&buf, "editCases(n.%s, edit)\n", name)
+ case is(slicePtrCommStmtType):
+ fmt.Fprintf(&buf, "editComms(n.%s, edit)\n", name)
case is(ptrFieldType):
fmt.Fprintf(&buf, "editField(n.%s, edit)\n", name)
case is(slicePtrFieldType):
err = maybeDoList(n.init, err, do)
err = maybeDo(n.Var, err, do)
err = maybeDoList(n.List, err, do)
- err = maybeDo(n.Comm, err, do)
err = maybeDoList(n.Body, err, do)
return err
}
editList(n.init, edit)
n.Var = maybeEdit(n.Var, edit)
editList(n.List, edit)
- n.Comm = maybeEdit(n.Comm, edit)
editList(n.Body, edit)
}
editList(n.init, edit)
}
+func (n *CommStmt) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+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)
+}
+
func (n *CompLitExpr) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
func (n *CompLitExpr) copy() Node {
c := *n
func (n *SelectStmt) copy() Node {
c := *n
c.init = c.init.Copy()
- c.Cases = copyCases(c.Cases)
+ c.Cases = copyComms(c.Cases)
c.Compiled = c.Compiled.Copy()
return &c
}
func (n *SelectStmt) doChildren(do func(Node) error) error {
var err error
err = maybeDoList(n.init, err, do)
- err = maybeDoCases(n.Cases, err, do)
+ err = maybeDoComms(n.Cases, err, do)
err = maybeDoList(n.Compiled, err, do)
return err
}
func (n *SelectStmt) editChildren(edit func(Node) Node) {
editList(n.init, edit)
- editCases(n.Cases, edit)
+ editComms(n.Cases, edit)
editList(n.Compiled, edit)
}
miniStmt
Var Node // declared variable for this case in type switch
List Nodes // list of expressions for switch, early select
- Comm Node // communication case (Exprs[0]) after select is type-checked
Body Nodes
}
func NewCaseStmt(pos src.XPos, list, body []Node) *CaseStmt {
- n := &CaseStmt{}
+ n := &CaseStmt{List: list, Body: body}
n.pos = pos
n.op = OCASE
- n.List.Set(list)
- n.Body.Set(body)
return n
}
+// TODO(mdempsky): Generate these with mknode.go.
func copyCases(list []*CaseStmt) []*CaseStmt {
if list == nil {
return nil
copy(c, list)
return c
}
-
func maybeDoCases(list []*CaseStmt, err error, do func(Node) error) error {
if err != nil {
return err
}
return nil
}
-
func editCases(list []*CaseStmt, edit func(Node) Node) {
for i, x := range list {
if x != nil {
}
}
+type CommStmt struct {
+ miniStmt
+ List Nodes // list of expressions for switch, early select
+ Comm Node // communication case (Exprs[0]) after select is type-checked
+ Body Nodes
+}
+
+func NewCommStmt(pos src.XPos, list, body []Node) *CommStmt {
+ n := &CommStmt{List: list, Body: body}
+ n.pos = pos
+ n.op = OCASE
+ return n
+}
+
+// TODO(mdempsky): Generate these with mknode.go.
+func copyComms(list []*CommStmt) []*CommStmt {
+ if list == nil {
+ return nil
+ }
+ c := make([]*CommStmt, len(list))
+ copy(c, list)
+ return c
+}
+func maybeDoComms(list []*CommStmt, err error, do func(Node) error) error {
+ if err != nil {
+ return err
+ }
+ for _, x := range list {
+ if x != nil {
+ if err := do(x); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+func editComms(list []*CommStmt, edit func(Node) Node) {
+ for i, x := range list {
+ if x != nil {
+ list[i] = edit(x).(*CommStmt)
+ }
+ }
+}
+
// A ForStmt is a non-range for loop: for Init; Cond; Post { Body }
// Op can be OFOR or OFORUNTIL (!Cond).
type ForStmt struct {
type SelectStmt struct {
miniStmt
Label *types.Sym
- Cases []*CaseStmt
+ Cases []*CommStmt
HasBreak bool
// TODO(rsc): Instead of recording here, replace with a block?
Compiled Nodes // compiled form, after walkswitch
}
-func NewSelectStmt(pos src.XPos, cases []*CaseStmt) *SelectStmt {
- n := &SelectStmt{}
+func NewSelectStmt(pos src.XPos, cases []*CommStmt) *SelectStmt {
+ n := &SelectStmt{Cases: cases}
n.pos = pos
n.op = OSELECT
- n.Cases = cases
return n
}
}
func NewSwitchStmt(pos src.XPos, tag Node, cases []*CaseStmt) *SwitchStmt {
- n := &SwitchStmt{Tag: tag}
+ n := &SwitchStmt{Tag: tag, Cases: cases}
n.pos = pos
n.op = OSWITCH
- n.Cases = cases
return n
}
return []ir.Node{p.stmt(stmt)}
}
-func (p *noder) commClauses(clauses []*syntax.CommClause, rbrace syntax.Pos) []*ir.CaseStmt {
- nodes := make([]*ir.CaseStmt, len(clauses))
+func (p *noder) commClauses(clauses []*syntax.CommClause, rbrace syntax.Pos) []*ir.CommStmt {
+ nodes := make([]*ir.CommStmt, len(clauses))
for i, clause := range clauses {
p.setlineno(clause)
if i > 0 {
}
p.openScope(clause.Pos())
- nodes[i] = ir.NewCaseStmt(p.pos(clause), p.simpleStmt(clause.Comm), p.stmts(clause.Body))
+ nodes[i] = ir.NewCommStmt(p.pos(clause), p.simpleStmt(clause.Comm), p.stmts(clause.Body))
}
if len(clauses) > 0 {
p.closeScope(rbrace)
w.op(n.Op())
w.pos(n.Pos())
w.stmtList(n.Init())
- w.caseList(n.Cases, false)
+ w.commList(n.Cases)
case ir.OSWITCH:
n := n.(*ir.SwitchStmt)
}
}
+func (w *exportWriter) commList(cases []*ir.CommStmt) {
+ w.uint64(uint64(len(cases)))
+ for _, cas := range cases {
+ w.pos(cas.Pos())
+ w.stmtList(cas.List)
+ w.stmtList(cas.Body)
+ }
+}
+
func (w *exportWriter) exprList(list ir.Nodes) {
for _, n := range list {
w.expr(n)
return cases
}
+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())
+ }
+ return cases
+}
+
func (r *importReader) exprList() []ir.Node {
var list []ir.Node
for {
case ir.OSELECT:
pos := r.pos()
init := r.stmtList()
- n := ir.NewSelectStmt(pos, r.caseList(nil))
+ n := ir.NewSelectStmt(pos, r.commList())
n.PtrInit().Set(init)
return n
base.Pos = lno
}
-func walkSelectCases(cases []*ir.CaseStmt) []ir.Node {
+func walkSelectCases(cases []*ir.CommStmt) []ir.Node {
ncas := len(cases)
sellineno := base.Pos
// convert case value arguments to addresses.
// this rewrite is used by both the general code and the next optimization.
- var dflt *ir.CaseStmt
+ var dflt *ir.CommStmt
for _, cas := range cases {
ir.SetPos(cas)
n := cas.Comm
if dflt != nil {
ncas--
}
- casorder := make([]*ir.CaseStmt, ncas)
+ casorder := make([]*ir.CommStmt, ncas)
nsends, nrecvs := 0, 0
var init []ir.Node
}
// dispatch cases
- dispatch := func(cond ir.Node, cas *ir.CaseStmt) {
+ dispatch := func(cond ir.Node, cas *ir.CommStmt) {
cond = typecheck.Expr(cond)
cond = typecheck.DefaultLit(cond, nil)