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:
parent
1cbc5aa529
commit
b761b07bf9
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user