Commit b761b07b authored by Matthew Dempsky's avatar Matthew Dempsky

cmd/compile: simplify noding const declarations

By grouping all the logic into constDecl, we're able to get rid of the
lastconst and lasttype globals, and simplify the logic slightly. Still
clunky, but much easier to reason about.

Change-Id: I446696c31084b3bfc1fd5d3651655a81ddd159ab
Reviewed-on: https://go-review.googlesource.com/36023
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: 's avatarJosh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 1cbc5aa5
......@@ -286,47 +286,6 @@ func variter(vl []*Node, t *Node, el []*Node) []*Node {
return init
}
// declare constants from grammar
// new_name_list [[type] = expr_list]
func constiter(vl []*Node, t *Node, cl []*Node, iotaVal int64) []*Node {
var lno src.XPos // default is to leave line number alone in listtreecopy
if len(cl) == 0 {
if t != nil {
yyerror("const declaration cannot have type without expression")
}
cl = lastconst
t = lasttype
lno = vl[0].Pos
} else {
lastconst = cl
lasttype = t
}
var vv []*Node
for i, v := range vl {
if i >= len(cl) {
yyerror("missing value in const declaration")
break
}
c := treecopy(cl[i], lno)
v.Op = OLITERAL
declare(v, dclcontext)
v.Name.Param.Ntype = t
v.Name.Defn = c
v.SetIota(iotaVal)
vv = append(vv, nod(ODCLCONST, v, nil))
}
if len(cl) > len(vl) {
yyerror("extra expression in const declaration")
}
return vv
}
// newname returns a new ONAME Node associated with symbol s.
func newname(s *Sym) *Node {
if s == nil {
......
......@@ -223,10 +223,6 @@ var dclcontext Class // PEXTERN/PAUTO
var statuniqgen int // name generator for static temps
var lastconst []*Node
var lasttype *Node
var Maxarg int64
var Stksize int64 // stack size for current frame
......
......@@ -117,9 +117,7 @@ func (p *noder) node() {
}
func (p *noder) decls(decls []syntax.Decl) (l []*Node) {
var lastConstGroup *syntax.Group
var lastConstRHS []*Node
var iotaVal int64
var cs constState
for _, decl := range decls {
p.lineno(decl)
......@@ -131,23 +129,7 @@ func (p *noder) decls(decls []syntax.Decl) (l []*Node) {
l = append(l, p.varDecl(decl)...)
case *syntax.ConstDecl:
// Tricky to handle golang.org/issue/15550 correctly.
if decl.Group == nil || decl.Group != lastConstGroup {
iotaVal = 0
lastConstRHS = nil
}
lastconst = lastConstRHS
l = append(l, p.constDecl(decl, iotaVal)...)
lastConstRHS = lastconst
lastconst = nil
iotaVal++
lastConstGroup = decl.Group
l = append(l, p.constDecl(decl, &cs)...)
case *syntax.TypeDecl:
l = append(l, p.typeDecl(decl))
......@@ -222,16 +204,62 @@ func (p *noder) varDecl(decl *syntax.VarDecl) []*Node {
return variter(names, typ, exprs)
}
func (p *noder) constDecl(decl *syntax.ConstDecl, iotaVal int64) []*Node {
type constState struct {
group *syntax.Group
typ *Node
values []*Node
iota int64
}
func (p *noder) constDecl(decl *syntax.ConstDecl, cs *constState) []*Node {
if decl.Group == nil || decl.Group != cs.group {
*cs = constState{
group: decl.Group,
}
}
names := p.declNames(decl.NameList)
typ := p.typeExprOrNil(decl.Type)
var exprs []*Node
var values []*Node
if decl.Values != nil {
exprs = p.exprList(decl.Values)
values = p.exprList(decl.Values)
cs.typ, cs.values = typ, values
} else {
if typ != nil {
yyerror("const declaration cannot have type without expression")
}
typ, values = cs.typ, cs.values
}
return constiter(names, typ, exprs, iotaVal)
var nn []*Node
for i, n := range names {
if i >= len(values) {
yyerror("missing value in const declaration")
break
}
v := values[i]
if decl.Values == nil {
v = treecopy(v, n.Pos)
}
n.Op = OLITERAL
declare(n, dclcontext)
n.Name.Param.Ntype = typ
n.Name.Defn = v
n.SetIota(cs.iota)
nn = append(nn, p.nod(decl, ODCLCONST, n, nil))
}
if len(values) > len(names) {
yyerror("extra expression in const declaration")
}
cs.iota++
return nn
}
func (p *noder) typeDecl(decl *syntax.TypeDecl) *Node {
......
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