aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2016-06-09 14:55:56 -0700
committerMatthew Dempsky <mdempsky@google.com>2016-08-16 14:32:08 -0700
commit0d8ac5ecf1c6be4d81214b11579a7fd1cf7a4514 (patch)
tree2ab4b968dd48de85f342bdd7355e920c651c4f4e
parent573afbcdb6bf11e1fc7ed176b07a04719c1e9a26 (diff)
downloadgo-0d8ac5ecf1c6be4d81214b11579a7fd1cf7a4514.tar.gz
go-0d8ac5ecf1c6be4d81214b11579a7fd1cf7a4514.zip
cmd/compile/internal/syntax: cleanup TypeSwitchGuard handling
Fixes typeswitch3.go and at least recognizes the error in typesw.go (albeit wrong line number and non-pretty-printed syntax.Expr output). Change-Id: I38b8e923265b0e7b3c301aea2f4a901bbabc24b5
-rw-r--r--src/cmd/compile/internal/syntax/nodes.go2
-rw-r--r--src/cmd/compile/internal/syntax/parser.go59
2 files changed, 23 insertions, 38 deletions
diff --git a/src/cmd/compile/internal/syntax/nodes.go b/src/cmd/compile/internal/syntax/nodes.go
index de677a847a..087d7acafe 100644
--- a/src/cmd/compile/internal/syntax/nodes.go
+++ b/src/cmd/compile/internal/syntax/nodes.go
@@ -171,7 +171,7 @@ type (
AssertExpr struct {
X Expr
// TODO(gri) consider using Name{"..."} instead of nil (permits attaching of comments)
- Type Expr // nil means x.(type) (for use in type switch)
+ Type Expr
expr
}
diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go
index 903a89c2ff..39e7347849 100644
--- a/src/cmd/compile/internal/syntax/parser.go
+++ b/src/cmd/compile/internal/syntax/parser.go
@@ -689,14 +689,19 @@ loop:
case _Lparen:
p.next()
- t := new(AssertExpr)
- t.init(p)
- t.X = x
- if !p.got(_Type) {
+ if p.got(_Type) {
+ t := new(TypeSwitchGuard)
+ t.init(p)
+ t.X = x
+ x = t
+ } else {
+ t := new(AssertExpr)
+ t.init(p)
+ t.X = x
t.Type = p.expr()
+ x = t
}
p.want(_Rparen)
- x = t
default:
p.syntax_error("expecting name or (")
@@ -1446,16 +1451,17 @@ func (p *parser) simpleStmt(lhs Expr, rangeOk bool) SimpleStmt {
// expr_list ':=' expr_list
rhs := p.exprList()
- if x, ok := rhs.(*AssertExpr); ok && x.Type == nil {
- // x.(type)
- // if len(rhs) > 1 {
- // p.error("expr.(type) must be alone on ths")
- // }
- // if len(lhs) > 1 {
- // p.error("argument count mismatch: %d = %d", len(lhs), 1)
- // } else if x, ok := lhs[0].(*Name); !ok {
- // p.error("invalid variable name %s in type switch", x)
- // }
+ if x, ok := rhs.(*TypeSwitchGuard); ok {
+ switch lhs := lhs.(type) {
+ case *Name:
+ x.Lhs = lhs
+ case *ListExpr:
+ p.error(fmt.Sprintf("argument count mismatch: %d = %d", len(lhs.ElemList), 1))
+ default:
+ // TODO(mdempsky): Have Expr types implement Stringer?
+ p.error(fmt.Sprintf("invalid variable name %s in type switch", lhs))
+ }
+ return &ExprStmt{X: x}
}
return p.newAssignStmt(Def, lhs, rhs)
@@ -1598,12 +1604,7 @@ func (p *parser) header(forStmt bool) (init SimpleStmt, cond Expr, post SimpleSt
case nil:
// nothing to do
case *ExprStmt:
- cond = p.unpackCond(nil, s.X)
- case *AssignStmt:
- // TODO(gri) allow := and =
- if name, ok := s.Lhs.(*Name); ok && s.Op == Def {
- cond = p.unpackCond(name, s.Rhs)
- }
+ cond = s.X
default:
p.error("invalid condition, tag, or type switch guard")
}
@@ -1612,22 +1613,6 @@ func (p *parser) header(forStmt bool) (init SimpleStmt, cond Expr, post SimpleSt
return
}
-func (p *parser) unpackCond(lhs *Name, x Expr) Expr {
- if x, ok := x.(*AssertExpr); ok && x.Type == nil {
- g := new(TypeSwitchGuard)
- g.init(p) // TODO(gri) use correct position info
- g.Lhs = lhs
- g.X = x.X
- return g
- }
-
- if lhs != nil {
- p.error("invalid type switch guard")
- }
-
- return x
-}
-
func (p *parser) ifStmt() *IfStmt {
if trace {
defer p.trace("ifStmt")()