]> Cypherpunks repositories - gostls13.git/commitdiff
- accept new composite literal syntax
authorRobert Griesemer <gri@golang.org>
Sat, 14 Feb 2009 00:27:53 +0000 (16:27 -0800)
committerRobert Griesemer <gri@golang.org>
Sat, 14 Feb 2009 00:27:53 +0000 (16:27 -0800)
- remove all parsing heuristics
- as a result, accept a wider syntax, but parser is simpler

R=r
OCL=25029
CL=25029

usr/gri/pretty/ast.go
usr/gri/pretty/parser.go
usr/gri/pretty/printer.go

index 05bbafdbf5772c63781a0302a9f491a9b12bcf20..b82e1f1c5b034e9c0fba8ae41f80d3c4c9189248 100644 (file)
@@ -167,12 +167,6 @@ type (
                Body *Block;
        };
        
-       CompositeLit struct {
-               Pos_ int;  // position of "{"
-               Typ *Type;
-               Elts Expr;
-       };
-
        TypeLit struct {
                Typ *Type;
        };
@@ -208,7 +202,6 @@ type ExprVisitor interface {
        DoUnaryExpr(x *UnaryExpr);
        DoBasicLit(x *BasicLit);
        DoFunctionLit(x *FunctionLit);
-       DoCompositeLit(x *CompositeLit);
        DoTypeLit(x *TypeLit);
        DoSelector(x *Selector);
        DoTypeGuard(x *TypeGuard);
@@ -223,7 +216,6 @@ func (x *BinaryExpr) Pos() int { return x.Pos_; }
 func (x *UnaryExpr) Pos() int { return x.Pos_; }
 func (x *BasicLit) Pos() int { return x.Pos_; }
 func (x *FunctionLit) Pos() int { return x.Pos_; }
-func (x *CompositeLit) Pos() int { return x.Pos_; }
 func (x *TypeLit) Pos() int { return x.Typ.Pos; }
 func (x *Selector) Pos() int { return x.Pos_; }
 func (x *TypeGuard) Pos() int { return x.Pos_; }
@@ -237,7 +229,6 @@ func (x *BinaryExpr) Visit(v ExprVisitor) { v.DoBinaryExpr(x); }
 func (x *UnaryExpr) Visit(v ExprVisitor) { v.DoUnaryExpr(x); }
 func (x *BasicLit) Visit(v ExprVisitor) { v.DoBasicLit(x); }
 func (x *FunctionLit) Visit(v ExprVisitor) { v.DoFunctionLit(x); }
-func (x *CompositeLit) Visit(v ExprVisitor) { v.DoCompositeLit(x); }
 func (x *TypeLit) Visit(v ExprVisitor) { v.DoTypeLit(x); }
 func (x *Selector) Visit(v ExprVisitor) { v.DoSelector(x); }
 func (x *TypeGuard) Visit(v ExprVisitor) { v.DoTypeGuard(x); }
index 53e409e2794bae52c24c3d25cfa36c680fd2b324..991286733669cf9fb4bfdd3df6b75012257a59a0 100644 (file)
@@ -32,7 +32,6 @@ type Parser struct {
        opt_semi bool;  // true if semicolon is optional
 
        // Nesting levels
-       expr_lev int;  // 0 = control clause level, 1 = expr inside ()'s
        scope_lev int;  // 0 = global scope, 1 = function scope of global functions, etc.
 
        // Scopes
@@ -129,7 +128,6 @@ func (P *Parser) Open(trace, sixg, deps bool, scanner *Scanner.Scanner) {
        P.comments = vector.New(0);
 
        P.next();
-       P.expr_lev = 0;
        P.scope_lev = 0;
 }
 
@@ -211,43 +209,6 @@ func (P *Parser) declare(x AST.Expr, kind int, typ *AST.Type) {
 }
 
 
-// ----------------------------------------------------------------------------
-// AST support
-
-func exprType(x AST.Expr) *AST.Type {
-       var typ *AST.Type;
-       if t, is_type := x.(*AST.TypeLit); is_type {
-               typ = t.Typ
-       } else if t, is_ident := x.(*AST.Ident); is_ident {
-               // assume a type name
-               typ = AST.NewType(t.Pos(), AST.TYPENAME);
-               typ.Expr = x;
-       } else if t, is_selector := x.(*AST.Selector); is_selector && exprType(t.Sel) != nil {
-               // possibly a qualified (type) identifier
-               typ = AST.NewType(t.Pos(), AST.TYPENAME);
-               typ.Expr = x;
-       }
-       return typ;
-}
-
-
-func (P *Parser) noType(x AST.Expr) AST.Expr {
-       if x != nil {
-               lit, ok := x.(*AST.TypeLit);
-               if ok {
-                       P.error(lit.Typ.Pos, "expected expression, found type");
-                       x = &AST.BasicLit(lit.Typ.Pos, Scanner.STRING, "");
-               }
-       }
-       return x;
-}
-
-
-func (P *Parser) newBinaryExpr(pos, tok int, x, y AST.Expr) *AST.BinaryExpr {
-       return &AST.BinaryExpr(pos, tok, P.noType(x), P.noType(y));
-}
-
-
 // ----------------------------------------------------------------------------
 // Common productions
 
@@ -295,10 +256,10 @@ func (P *Parser) parseIdentList() AST.Expr {
                P.next();
                y := P.parseIdent(nil);
                if last == nil {
-                       last = P.newBinaryExpr(pos, Scanner.COMMA, x, y);
+                       last = &AST.BinaryExpr(pos, Scanner.COMMA, x, y);
                        x = last;
                } else {
-                       last.Y = P.newBinaryExpr(pos, Scanner.COMMA, last.Y, y);
+                       last.Y = &AST.BinaryExpr(pos, Scanner.COMMA, last.Y, y);
                        last = last.Y.(*AST.BinaryExpr);
                }
        }
@@ -371,7 +332,7 @@ func (P *Parser) parseArrayType() *AST.Type {
        t := AST.NewType(P.pos, AST.ARRAY);
        P.expect(Scanner.LBRACK);
        if P.tok == Scanner.ELLIPSIS {
-               t.Expr = P.newBinaryExpr(P.pos, Scanner.ELLIPSIS, nil, nil);
+               t.Expr = &AST.BinaryExpr(P.pos, Scanner.ELLIPSIS, nil, nil);
                P.next();
        } else if P.tok != Scanner.RBRACK {
                t.Expr = P.parseExpression(1);
@@ -708,19 +669,19 @@ func (P *Parser) tryType() *AST.Type {
                defer un(trace(P, "Type (try)"));
        }
 
-       t := AST.BadType;
        switch P.tok {
-       case Scanner.IDENT: t = P.parseTypeName();
-       case Scanner.LBRACK: t = P.parseArrayType();
-       case Scanner.CHAN, Scanner.ARROW: t = P.parseChannelType();
-       case Scanner.INTERFACE: t = P.parseInterfaceType();
-       case Scanner.FUNC: t = P.parseFunctionType();
-       case Scanner.MAP: t = P.parseMapType();
-       case Scanner.STRUCT: t = P.parseStructType();
-       case Scanner.MUL: t = P.parsePointerType();
-       default: t = nil;  // no type found
-       }
-       return t;
+       case Scanner.IDENT: return P.parseTypeName();
+       case Scanner.LBRACK: return P.parseArrayType();
+       case Scanner.CHAN, Scanner.ARROW: return P.parseChannelType();
+       case Scanner.INTERFACE: return P.parseInterfaceType();
+       case Scanner.FUNC: return P.parseFunctionType();
+       case Scanner.MAP: return P.parseMapType();
+       case Scanner.STRUCT: return P.parseStructType();
+       case Scanner.MUL: return P.parsePointerType();
+       }
+       
+       // no type found
+       return nil;
 }
 
 
@@ -801,10 +762,10 @@ func (P *Parser) parseExpressionList() AST.Expr {
                P.next();
                y := P.parseExpression(1);
                if first {
-                       x = P.newBinaryExpr(pos, Scanner.COMMA, x, y);
+                       x = &AST.BinaryExpr(pos, Scanner.COMMA, x, y);
                        first = false;
                } else {
-                       x.(*AST.BinaryExpr).Y = P.newBinaryExpr(pos, Scanner.COMMA, x.(*AST.BinaryExpr).Y, y);
+                       x.(*AST.BinaryExpr).Y = &AST.BinaryExpr(pos, Scanner.COMMA, x.(*AST.BinaryExpr).Y, y);
                }
        }
 
@@ -820,11 +781,9 @@ func (P *Parser) parseFunctionLit() AST.Expr {
        pos := P.pos;
        P.expect(Scanner.FUNC);
        typ := P.parseSignature();
-       P.expr_lev++;
        P.scope_lev++;
        body := P.parseBlock(typ, Scanner.LBRACE);
        P.scope_lev--;
-       P.expr_lev--;
 
        return &AST.FunctionLit(pos, typ, body);
 }
@@ -841,9 +800,7 @@ func (P *Parser) parseOperand() AST.Expr {
 
        case Scanner.LPAREN:
                P.next();
-               P.expr_lev++;
                x := P.parseExpression(1);
-               P.expr_lev--;
                P.expect(Scanner.RPAREN);
                return x;
 
@@ -904,9 +861,7 @@ func (P *Parser) parseIndex(x AST.Expr) AST.Expr {
 
        pos := P.pos;
        P.expect(Scanner.LBRACK);
-       P.expr_lev++;
        i := P.parseExpression(0);
-       P.expr_lev--;
        P.expect(Scanner.RBRACK);
 
        return &AST.Index(pos, x, i);
@@ -915,43 +870,6 @@ func (P *Parser) parseIndex(x AST.Expr) AST.Expr {
 
 func (P *Parser) parseBinaryExpr(prec1 int) AST.Expr
 
-func (P *Parser) parseCall(f AST.Expr) AST.Expr {
-       if P.trace {
-               defer un(trace(P, "Call"));
-       }
-
-       call := &AST.Call(P.pos, f, nil);
-       P.expect(Scanner.LPAREN);
-       if P.tok != Scanner.RPAREN {
-               P.expr_lev++;
-               var t *AST.Type;
-               if x0, ok := f.(*AST.Ident); ok && (x0.Obj.Ident == "new" || x0.Obj.Ident == "make") {
-                       // heuristic: assume it's a new(T) or make(T, ...) call, try to parse a type
-                       t = P.tryType();
-               }
-               if t != nil {
-                       // we found a type
-                       args := &AST.TypeLit(t);
-                       if P.tok == Scanner.COMMA {
-                               pos := P.pos;
-                               P.next();
-                               y := P.parseExpressionList();
-                               // create list manually because NewExpr checks for type expressions
-                               args := &AST.BinaryExpr(pos, Scanner.COMMA, args, y);
-                       }
-                       call.Args = args;
-               } else {
-                       // normal argument list
-                       call.Args = P.parseExpressionList();
-               }
-               P.expr_lev--;
-       }
-       P.expect(Scanner.RPAREN);
-
-       return call;
-}
-
-
 func (P *Parser) parseCompositeElements() AST.Expr {
        x := P.parseExpression(0);
        if P.tok == Scanner.COMMA {
@@ -965,7 +883,7 @@ func (P *Parser) parseCompositeElements() AST.Expr {
                }
 
                var last *AST.BinaryExpr;
-               for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
+               for P.tok != Scanner.RPAREN && P.tok != Scanner.EOF {
                        y := P.parseExpression(0);
 
                        if singles {
@@ -979,10 +897,10 @@ func (P *Parser) parseCompositeElements() AST.Expr {
                        }
 
                        if last == nil {
-                               last = P.newBinaryExpr(pos, Scanner.COMMA, x, y);
+                               last = &AST.BinaryExpr(pos, Scanner.COMMA, x, y);
                                x = last;
                        } else {
-                               last.Y = P.newBinaryExpr(pos, Scanner.COMMA, last.Y, y);
+                               last.Y = &AST.BinaryExpr(pos, Scanner.COMMA, last.Y, y);
                                last = last.Y.(*AST.BinaryExpr);
                        }
 
@@ -999,20 +917,20 @@ func (P *Parser) parseCompositeElements() AST.Expr {
 }
 
 
-func (P *Parser) parseCompositeLit(t *AST.Type) AST.Expr {
+func (P *Parser) parseCallOrCompositeLit(f AST.Expr) AST.Expr {
        if P.trace {
-               defer un(trace(P, "CompositeLit"));
+               defer un(trace(P, "CallOrCompositeLit"));
        }
 
        pos := P.pos;
-       P.expect(Scanner.LBRACE);
-       var elts AST.Expr;
-       if P.tok != Scanner.RBRACE {
-               elts = P.parseCompositeElements();
+       P.expect(Scanner.LPAREN);
+       var args AST.Expr;
+       if P.tok != Scanner.RPAREN {
+               args = P.parseCompositeElements();
        }
-       P.expect(Scanner.RBRACE);
+       P.expect(Scanner.RPAREN);
 
-       return &AST.CompositeLit(pos, t, elts);
+       return &AST.Call(pos, f, args);
 }
 
 
@@ -1026,20 +944,7 @@ func (P *Parser) parsePrimaryExpr() AST.Expr {
                switch P.tok {
                case Scanner.PERIOD: x = P.parseSelectorOrTypeGuard(x);
                case Scanner.LBRACK: x = P.parseIndex(x);
-               case Scanner.LPAREN: x = P.parseCall(x);
-               case Scanner.LBRACE:
-                       // assume a composite literal only if x could be a type
-                       // and if we are not inside a control clause (expr_lev >= 0)
-                       // (composites inside control clauses must be parenthesized)
-                       var t *AST.Type;
-                       if P.expr_lev >= 0 {
-                               t = exprType(x);
-                       }
-                       if t != nil {
-                               x = P.parseCompositeLit(t);
-                       } else {
-                               return x;
-                       }
+               case Scanner.LPAREN: x = P.parseCallOrCompositeLit(x);
                default:
                        return x;
                }
@@ -1085,7 +990,7 @@ func (P *Parser) parseBinaryExpr(prec1 int) AST.Expr {
                        pos, tok := P.pos, P.tok;
                        P.next();
                        y := P.parseBinaryExpr(prec + 1);
-                       x = P.newBinaryExpr(pos, tok, x, y);
+                       x = &AST.BinaryExpr(pos, tok, x, y);
                }
        }
 
@@ -1102,7 +1007,7 @@ func (P *Parser) parseExpression(prec int) AST.Expr {
                panic("precedence must be >= 0");
        }
 
-       return P.noType(P.parseBinaryExpr(prec));
+       return P.parseBinaryExpr(prec);
 }
 
 
@@ -1153,7 +1058,7 @@ func (P *Parser) parseSimpleStat(range_ok bool) AST.Stat {
                        }
                }
                // TODO changed ILLEGAL -> NONE
-               return &AST.ExpressionStat(x.Pos(), Scanner.ILLEGAL, P.newBinaryExpr(pos, tok, x, y));
+               return &AST.ExpressionStat(x.Pos(), Scanner.ILLEGAL, &AST.BinaryExpr(pos, tok, x, y));
 
        default:
                if AST.ExprLen(x) != 1 {
@@ -1223,8 +1128,6 @@ func (P *Parser) parseControlClause(isForStat bool) (init AST.Stat, expr AST.Exp
        }
 
        if P.tok != Scanner.LBRACE {
-               prev_lev := P.expr_lev;
-               P.expr_lev = -1;
                if P.tok != Scanner.SEMICOLON {
                        init = P.parseSimpleStat(isForStat);
                        // TODO check for range clause and exit if found
@@ -1249,7 +1152,6 @@ func (P *Parser) parseControlClause(isForStat bool) (init AST.Stat, expr AST.Exp
                                }
                        }
                }
-               P.expr_lev = prev_lev;
        }
 
        return init, expr, post;
@@ -1361,7 +1263,7 @@ func (P *Parser) parseCommClause() *AST.CaseClause {
                        P.next();
                        if P.tok == Scanner.ARROW {
                                y := P.parseExpression(1);
-                               x = P.newBinaryExpr(pos, tok, x, y);
+                               x = &AST.BinaryExpr(pos, tok, x, y);
                        } else {
                                P.expect(Scanner.ARROW);  // use expect() error handling
                        }
index 67a9615809faa63a64aff9757f97c3d82b690dee..64ce715a1db54e091e0861e63ca6bb0502fd795f 100644 (file)
@@ -680,14 +680,6 @@ func (P *Printer) DoFunctionLit(x *AST.FunctionLit) {
 }
 
 
-func (P *Printer) DoCompositeLit(x *AST.CompositeLit) {
-       P.Type(x.Typ);
-       P.String(x.Pos(), "{");
-       P.Expr(x.Elts);
-       P.String(0, "}");
-}
-
-
 func (P *Printer) DoSelector(x *AST.Selector) {
        P.Expr1(x.X, Scanner.HighestPrec);
        P.String(x.Pos(), ".");