1
0
mirror of https://github.com/golang/go synced 2024-11-11 22:20:22 -07:00

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: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Matthew Dempsky 2017-01-31 16:31:11 -08:00
parent 1cbc5aa529
commit b761b07bf9
3 changed files with 52 additions and 69 deletions

View File

@ -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 {

View File

@ -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

View File

@ -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 {