mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: cleanup in parser.go (2)
Inlined fntype, othertype, recvchantype, ptrtype into ntype and simplified callers. Minor cleanups elsewhere (better names). Change-Id: I54924969996641a802de00c078b4cd0eabfda8c1 Reviewed-on: https://go-review.googlesource.com/16894 Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Chris Manghane <cmang@golang.org>
This commit is contained in:
parent
18160e0740
commit
8d733ecafb
1 changed files with 113 additions and 163 deletions
|
|
@ -1231,9 +1231,7 @@ var prectab = map[int32]struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) bexpr(prec int) *Node {
|
func (p *parser) bexpr(prec int) *Node {
|
||||||
if trace && Debug['x'] != 0 {
|
// don't trace bexpr - only leads to overly nested trace output
|
||||||
defer p.trace("expr")()
|
|
||||||
}
|
|
||||||
|
|
||||||
x := p.uexpr()
|
x := p.uexpr()
|
||||||
t := prectab[p.tok]
|
t := prectab[p.tok]
|
||||||
|
|
@ -1251,6 +1249,10 @@ func (p *parser) bexpr(prec int) *Node {
|
||||||
|
|
||||||
// go.y:expr
|
// go.y:expr
|
||||||
func (p *parser) expr() *Node {
|
func (p *parser) expr() *Node {
|
||||||
|
if trace && Debug['x'] != 0 {
|
||||||
|
defer p.trace("expr")()
|
||||||
|
}
|
||||||
|
|
||||||
return p.bexpr(1)
|
return p.bexpr(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1373,7 +1375,7 @@ func (p *parser) operand(keep_parens bool) *Node {
|
||||||
return x
|
return x
|
||||||
|
|
||||||
case LFUNC:
|
case LFUNC:
|
||||||
t := p.fntype()
|
t := p.ntype() // fntype
|
||||||
if p.tok == '{' {
|
if p.tok == '{' {
|
||||||
// fnlitdcl
|
// fnlitdcl
|
||||||
closurehdr(t)
|
closurehdr(t)
|
||||||
|
|
@ -1388,7 +1390,7 @@ func (p *parser) operand(keep_parens bool) *Node {
|
||||||
return t
|
return t
|
||||||
|
|
||||||
case '[', LCHAN, LMAP, LSTRUCT, LINTERFACE:
|
case '[', LCHAN, LMAP, LSTRUCT, LINTERFACE:
|
||||||
return p.othertype()
|
return p.ntype() // othertype
|
||||||
|
|
||||||
case '{':
|
case '{':
|
||||||
// common case: p.header is missing simple_stmt before { in if, for, switch
|
// common case: p.header is missing simple_stmt before { in if, for, switch
|
||||||
|
|
@ -1420,7 +1422,6 @@ loop:
|
||||||
case LNAME, '@', '?':
|
case LNAME, '@', '?':
|
||||||
// pexpr '.' sym
|
// pexpr '.' sym
|
||||||
sel := p.sym()
|
sel := p.sym()
|
||||||
|
|
||||||
if x.Op == OPACK {
|
if x.Op == OPACK {
|
||||||
s := restrictlookup(sel.Name, x.Name.Pkg)
|
s := restrictlookup(sel.Name, x.Name.Pkg)
|
||||||
x.Used = true
|
x.Used = true
|
||||||
|
|
@ -1706,117 +1707,24 @@ func (p *parser) ntype() *Node {
|
||||||
|
|
||||||
switch p.tok {
|
switch p.tok {
|
||||||
case LCOMM:
|
case LCOMM:
|
||||||
return p.recvchantype()
|
// recvchantype
|
||||||
|
|
||||||
case LFUNC:
|
|
||||||
return p.fntype()
|
|
||||||
|
|
||||||
case '[', LCHAN, LMAP, LSTRUCT, LINTERFACE:
|
|
||||||
return p.othertype()
|
|
||||||
|
|
||||||
case '*':
|
|
||||||
return p.ptrtype()
|
|
||||||
|
|
||||||
case LNAME, '@', '?':
|
|
||||||
return p.dotname()
|
|
||||||
|
|
||||||
case '(':
|
|
||||||
p.next()
|
p.next()
|
||||||
t := p.ntype()
|
p.want(LCHAN)
|
||||||
p.want(')')
|
t := Nod(OTCHAN, p.chan_elem(), nil)
|
||||||
|
t.Etype = Crecv
|
||||||
return t
|
return t
|
||||||
|
|
||||||
case LDDD:
|
|
||||||
// permit ...T but complain
|
|
||||||
// TODO(gri) introduced for test/fixedbugs/bug228.go - maybe adjust bug or find better solution
|
|
||||||
p.syntax_error("")
|
|
||||||
p.advance()
|
|
||||||
return p.ntype()
|
|
||||||
|
|
||||||
default:
|
|
||||||
p.syntax_error("")
|
|
||||||
p.advance()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *parser) chan_elem() *Node {
|
|
||||||
if trace && Debug['x'] != 0 {
|
|
||||||
defer p.trace("chan_elem")()
|
|
||||||
}
|
|
||||||
|
|
||||||
switch p.tok {
|
|
||||||
case LCOMM, LFUNC,
|
|
||||||
'[', LCHAN, LMAP, LSTRUCT, LINTERFACE,
|
|
||||||
'*',
|
|
||||||
LNAME, '@', '?',
|
|
||||||
'(',
|
|
||||||
LDDD:
|
|
||||||
return p.ntype()
|
|
||||||
default:
|
|
||||||
p.syntax_error("missing channel element type")
|
|
||||||
// assume element type is simply absent - don't advance
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// go.y:fnret_type
|
|
||||||
func (p *parser) fnret_type() *Node {
|
|
||||||
if trace && Debug['x'] != 0 {
|
|
||||||
defer p.trace("fnret_type")()
|
|
||||||
}
|
|
||||||
|
|
||||||
switch p.tok {
|
|
||||||
case LCOMM:
|
|
||||||
return p.recvchantype()
|
|
||||||
|
|
||||||
case LFUNC:
|
case LFUNC:
|
||||||
return p.fntype()
|
// fntype
|
||||||
|
|
||||||
case '[', LCHAN, LMAP, LSTRUCT, LINTERFACE:
|
|
||||||
return p.othertype()
|
|
||||||
|
|
||||||
case '*':
|
|
||||||
return p.ptrtype()
|
|
||||||
|
|
||||||
default:
|
|
||||||
return p.dotname()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// go.y:dotname
|
|
||||||
func (p *parser) dotname() *Node {
|
|
||||||
if trace && Debug['x'] != 0 {
|
|
||||||
defer p.trace("dotname")()
|
|
||||||
}
|
|
||||||
|
|
||||||
s1 := p.name()
|
|
||||||
|
|
||||||
switch p.tok {
|
|
||||||
default:
|
|
||||||
return s1
|
|
||||||
|
|
||||||
case '.':
|
|
||||||
p.next()
|
p.next()
|
||||||
s3 := p.sym()
|
params := p.param_list()
|
||||||
|
result := p.fnres()
|
||||||
|
params = checkarglist(params, 1)
|
||||||
|
t := Nod(OTFUNC, nil, nil)
|
||||||
|
t.List = params
|
||||||
|
t.Rlist = result
|
||||||
|
return t
|
||||||
|
|
||||||
if s1.Op == OPACK {
|
|
||||||
var s *Sym
|
|
||||||
s = restrictlookup(s3.Name, s1.Name.Pkg)
|
|
||||||
s1.Used = true
|
|
||||||
return oldname(s)
|
|
||||||
}
|
|
||||||
return Nod(OXDOT, s1, newname(s3))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// go.y:othertype
|
|
||||||
func (p *parser) othertype() *Node {
|
|
||||||
if trace && Debug['x'] != 0 {
|
|
||||||
defer p.trace("othertype")()
|
|
||||||
}
|
|
||||||
|
|
||||||
switch p.tok {
|
|
||||||
case '[':
|
case '[':
|
||||||
// '[' oexpr ']' ntype
|
// '[' oexpr ']' ntype
|
||||||
// '[' LDDD ']' ntype
|
// '[' LDDD ']' ntype
|
||||||
|
|
@ -1856,39 +1764,101 @@ func (p *parser) othertype() *Node {
|
||||||
return Nod(OTMAP, key, val)
|
return Nod(OTMAP, key, val)
|
||||||
|
|
||||||
case LSTRUCT:
|
case LSTRUCT:
|
||||||
// structtype
|
|
||||||
return p.structtype()
|
return p.structtype()
|
||||||
|
|
||||||
case LINTERFACE:
|
case LINTERFACE:
|
||||||
// interfacetype
|
|
||||||
return p.interfacetype()
|
return p.interfacetype()
|
||||||
|
|
||||||
default:
|
case '*':
|
||||||
panic("unreachable")
|
// ptrtype
|
||||||
}
|
p.next()
|
||||||
}
|
|
||||||
|
|
||||||
// go.y:ptrtype
|
|
||||||
func (p *parser) ptrtype() *Node {
|
|
||||||
if trace && Debug['x'] != 0 {
|
|
||||||
defer p.trace("ptrtype")()
|
|
||||||
}
|
|
||||||
|
|
||||||
p.want('*')
|
|
||||||
return Nod(OIND, p.ntype(), nil)
|
return Nod(OIND, p.ntype(), nil)
|
||||||
|
|
||||||
|
case LNAME, '@', '?':
|
||||||
|
return p.dotname()
|
||||||
|
|
||||||
|
case '(':
|
||||||
|
p.next()
|
||||||
|
t := p.ntype()
|
||||||
|
p.want(')')
|
||||||
|
return t
|
||||||
|
|
||||||
|
case LDDD:
|
||||||
|
// permit ...T but complain
|
||||||
|
// TODO(gri) introduced for test/fixedbugs/bug228.go - maybe adjust bug or find better solution
|
||||||
|
p.syntax_error("")
|
||||||
|
p.advance()
|
||||||
|
return p.ntype()
|
||||||
|
|
||||||
|
default:
|
||||||
|
p.syntax_error("")
|
||||||
|
p.advance()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// go.y:recvchantype
|
func (p *parser) chan_elem() *Node {
|
||||||
func (p *parser) recvchantype() *Node {
|
|
||||||
if trace && Debug['x'] != 0 {
|
if trace && Debug['x'] != 0 {
|
||||||
defer p.trace("recvchantype")()
|
defer p.trace("chan_elem")()
|
||||||
}
|
}
|
||||||
|
|
||||||
p.want(LCOMM)
|
switch p.tok {
|
||||||
p.want(LCHAN)
|
case LCOMM, LFUNC,
|
||||||
t := Nod(OTCHAN, p.chan_elem(), nil)
|
'[', LCHAN, LMAP, LSTRUCT, LINTERFACE,
|
||||||
t.Etype = Crecv
|
'*',
|
||||||
return t
|
LNAME, '@', '?',
|
||||||
|
'(',
|
||||||
|
LDDD:
|
||||||
|
return p.ntype()
|
||||||
|
|
||||||
|
default:
|
||||||
|
p.syntax_error("missing channel element type")
|
||||||
|
// assume element type is simply absent - don't advance
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// go.y:fnret_type
|
||||||
|
// TODO(gri) only called from fnres - inline and remove this one
|
||||||
|
func (p *parser) fnret_type() *Node {
|
||||||
|
if trace && Debug['x'] != 0 {
|
||||||
|
defer p.trace("fnret_type")()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch p.tok {
|
||||||
|
case LFUNC, // fntype
|
||||||
|
LCOMM, // recvchantype
|
||||||
|
'[', LCHAN, LMAP, LSTRUCT, LINTERFACE, // othertype
|
||||||
|
'*': // ptrtype
|
||||||
|
return p.ntype()
|
||||||
|
|
||||||
|
default:
|
||||||
|
return p.dotname()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// go.y:dotname
|
||||||
|
func (p *parser) dotname() *Node {
|
||||||
|
if trace && Debug['x'] != 0 {
|
||||||
|
defer p.trace("dotname")()
|
||||||
|
}
|
||||||
|
|
||||||
|
name := p.name()
|
||||||
|
|
||||||
|
switch p.tok {
|
||||||
|
default:
|
||||||
|
return name
|
||||||
|
|
||||||
|
case '.':
|
||||||
|
p.next()
|
||||||
|
sel := p.sym()
|
||||||
|
if name.Op == OPACK {
|
||||||
|
s := restrictlookup(sel.Name, name.Name.Pkg)
|
||||||
|
name.Used = true
|
||||||
|
return oldname(s)
|
||||||
|
}
|
||||||
|
return Nod(OXDOT, name, newname(sel))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// go.y:structtype
|
// go.y:structtype
|
||||||
|
|
@ -2116,24 +2086,6 @@ func (p *parser) hidden_fndcl() *Node {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// go.y:fntype
|
|
||||||
func (p *parser) fntype() *Node {
|
|
||||||
if trace && Debug['x'] != 0 {
|
|
||||||
defer p.trace("fntype")()
|
|
||||||
}
|
|
||||||
|
|
||||||
p.want(LFUNC)
|
|
||||||
params := p.param_list()
|
|
||||||
result := p.fnres()
|
|
||||||
|
|
||||||
params = checkarglist(params, 1)
|
|
||||||
t := Nod(OTFUNC, nil, nil)
|
|
||||||
t.List = params
|
|
||||||
t.Rlist = result
|
|
||||||
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
// go.y:fnbody
|
// go.y:fnbody
|
||||||
func (p *parser) fnbody() *NodeList {
|
func (p *parser) fnbody() *NodeList {
|
||||||
if trace && Debug['x'] != 0 {
|
if trace && Debug['x'] != 0 {
|
||||||
|
|
@ -2470,38 +2422,36 @@ func (p *parser) arg_type() *Node {
|
||||||
|
|
||||||
switch p.tok {
|
switch p.tok {
|
||||||
case LNAME, '@', '?':
|
case LNAME, '@', '?':
|
||||||
s1 := p.sym()
|
name := p.sym()
|
||||||
switch p.tok {
|
switch p.tok {
|
||||||
case LCOMM, LFUNC, '[', LCHAN, LMAP, LSTRUCT, LINTERFACE, '*', LNAME, '@', '?', '(':
|
case LCOMM, LFUNC, '[', LCHAN, LMAP, LSTRUCT, LINTERFACE, '*', LNAME, '@', '?', '(':
|
||||||
// sym name_or_type
|
// sym name_or_type
|
||||||
s2 := p.ntype()
|
typ := p.ntype()
|
||||||
ss := Nod(ONONAME, nil, nil)
|
nn := Nod(ONONAME, nil, nil)
|
||||||
ss.Sym = s1
|
nn.Sym = name
|
||||||
return Nod(OKEY, ss, s2)
|
return Nod(OKEY, nn, typ)
|
||||||
|
|
||||||
case LDDD:
|
case LDDD:
|
||||||
// sym dotdotdot
|
// sym dotdotdot
|
||||||
s2 := p.dotdotdot()
|
typ := p.dotdotdot()
|
||||||
ss := Nod(ONONAME, nil, nil)
|
nn := Nod(ONONAME, nil, nil)
|
||||||
ss.Sym = s1
|
nn.Sym = name
|
||||||
return Nod(OKEY, ss, s2)
|
return Nod(OKEY, nn, typ)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// name_or_type
|
// name_or_type
|
||||||
s1 := mkname(s1)
|
name := mkname(name)
|
||||||
// from dotname
|
// from dotname
|
||||||
if p.got('.') {
|
if p.got('.') {
|
||||||
s3 := p.sym()
|
sel := p.sym()
|
||||||
|
if name.Op == OPACK {
|
||||||
if s1.Op == OPACK {
|
s := restrictlookup(sel.Name, name.Name.Pkg)
|
||||||
var s *Sym
|
name.Used = true
|
||||||
s = restrictlookup(s3.Name, s1.Name.Pkg)
|
|
||||||
s1.Used = true
|
|
||||||
return oldname(s)
|
return oldname(s)
|
||||||
}
|
}
|
||||||
return Nod(OXDOT, s1, newname(s3))
|
return Nod(OXDOT, name, newname(sel))
|
||||||
}
|
}
|
||||||
return s1
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
case LDDD:
|
case LDDD:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue