]> Cypherpunks repositories - gostls13.git/commitdiff
- allow ()'s and {}'s for now when parsing calls/composite literals
authorRobert Griesemer <gri@golang.org>
Wed, 4 Mar 2009 00:00:06 +0000 (16:00 -0800)
committerRobert Griesemer <gri@golang.org>
Wed, 4 Mar 2009 00:00:06 +0000 (16:00 -0800)
- require ()'s around composite literals at the if/for/switch control clause level
- fixed a nasty bug: passing a value instead of a pointer to a value to an interface
  variable - and not noticing that the value is copied

R=r
OCL=25649
CL=25649

usr/gri/pretty/ast.go
usr/gri/pretty/compilation.go
usr/gri/pretty/parser.go
usr/gri/pretty/platform.go
usr/gri/pretty/printer.go
usr/gri/pretty/scanner.go

index 0bad5bb82df54fbe10f9bfa7a8c2871678abc13c..d618a1bf41a72edab0baacb4a6949d967e1e1798 100644 (file)
@@ -112,7 +112,8 @@ type (
        };
        
        Call struct {
-               Pos_ int;  // position of "("
+               Pos_ int;  // position of "(" or "{"
+               Tok int;
                F, Args Expr
        };
 
index 75f62f2fa640e725dd431428e352e395cc70dc1b..74b589e40dc6c800b17fd4842e93d1b0a8a6b189 100644 (file)
@@ -90,8 +90,7 @@ func (h *errorHandler) ErrorMsg(pos int, msg string) {
        h.errpos = pos;
 
        if h.nerrors >= 10 {
-               // TODO enable when done with name convention
-               //sys.Exit(1);
+               sys.Exit(1);
        }
 }
 
@@ -111,11 +110,6 @@ func (h *errorHandler) Error(pos int, msg string) {
 }
 
 
-func (h *errorHandler) Warning(pos int, msg string) {
-       panic("UNIMPLEMENTED");
-}
-
-
 func Compile(src_file string, flags *Flags) (*AST.Program, int) {
        src, ok := Platform.ReadSourceFile(src_file);
        if !ok {
@@ -130,7 +124,7 @@ func Compile(src_file string, flags *Flags) (*AST.Program, int) {
        scanner.Init(src, &err, true);
 
        var parser Parser.Parser;
-       parser.Open(&scanner, err, flags.Verbose, flags.Sixg, flags.Deps);
+       parser.Open(&scanner, &err, flags.Verbose, flags.Sixg, flags.Deps);
 
        prog := parser.ParseProgram();
 
index 27bf4b3cb68c6aa0fd3c2a474a705c7eb1da3c6b..ad72d47dd661f181a12e4ade42b0e80ccfe8f59e 100644 (file)
@@ -16,7 +16,6 @@ import (
 
 type ErrorHandler interface {
        Error(pos int, msg string);
-       Warning(pos int, msg string);
 }
 
 
@@ -39,7 +38,8 @@ type Parser struct {
        opt_semi bool;  // true if semicolon separator is optional in statement list
 
        // Nesting levels
-       scope_lev int;  // 0 = global scope, 1 = function scope of global functions, etc.
+       expr_lev int;  // < 0: in control clause, >= 0: in expression
+       scope_lev int;  // 0: global scope, 1: function scope of global functions, etc.
 
        // Scopes
        top_scope *SymbolTable.Scope;
@@ -141,6 +141,7 @@ func (P *Parser) Open(scanner *Scanner.Scanner, err ErrorHandler, trace, sixg, d
 
        P.next();
        P.scope_lev = 0;
+       P.expr_lev = 0;
 }
 
 
@@ -774,7 +775,7 @@ func (P *Parser) tryType() AST.Expr {
                P.expect(Scanner.RPAREN);
                return &AST.Group{pos, t};
        }
-       
+
        // no type found
        return nil;
 }
@@ -881,9 +882,11 @@ 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(Scanner.LBRACE);
        P.scope_lev--;
+       P.expr_lev--;
 
        return &AST.FunctionLit{pos, typ, body};
 }
@@ -901,7 +904,9 @@ func (P *Parser) parseOperand() AST.Expr {
        case Scanner.LPAREN:
                pos := P.pos;
                P.next();
+               P.expr_lev++;
                x := P.parseExpression(1);
+               P.expr_lev--;
                P.expect(Scanner.RPAREN);
                return &AST.Group{pos, x};
 
@@ -962,7 +967,9 @@ 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};
@@ -971,7 +978,7 @@ func (P *Parser) parseIndex(x AST.Expr) AST.Expr {
 
 func (P *Parser) parseBinaryExpr(prec1 int) AST.Expr
 
-func (P *Parser) parseCompositeElements() AST.Expr {
+func (P *Parser) parseCompositeElements(close int) AST.Expr {
        x := P.parseExpression(0);
        if P.tok == Scanner.COMMA {
                pos := P.pos;
@@ -984,7 +991,7 @@ func (P *Parser) parseCompositeElements() AST.Expr {
                }
 
                var last *AST.BinaryExpr;
-               for P.tok != Scanner.RPAREN && P.tok != Scanner.EOF {
+               for P.tok != close && P.tok != Scanner.EOF {
                        y := P.parseExpression(0);
 
                        if singles {
@@ -1018,20 +1025,20 @@ func (P *Parser) parseCompositeElements() AST.Expr {
 }
 
 
-func (P *Parser) parseCallOrCompositeLit(f AST.Expr) AST.Expr {
+func (P *Parser) parseCallOrCompositeLit(f AST.Expr, open, close int) AST.Expr {
        if P.trace {
                defer un(trace(P, "CallOrCompositeLit"));
        }
 
        pos := P.pos;
-       P.expect(Scanner.LPAREN);
+       P.expect(open);
        var args AST.Expr;
-       if P.tok != Scanner.RPAREN {
-               args = P.parseCompositeElements();
+       if P.tok != close {
+               args = P.parseCompositeElements(close);
        }
-       P.expect(Scanner.RPAREN);
+       P.expect(close);
 
-       return &AST.Call{pos, f, args};
+       return &AST.Call{pos, open, f, args};
 }
 
 
@@ -1045,7 +1052,14 @@ 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.parseCallOrCompositeLit(x);
+               // TODO fix once we have decided on literal/conversion syntax
+               case Scanner.LPAREN: x = P.parseCallOrCompositeLit(x, Scanner.LPAREN, Scanner.RPAREN);
+               case Scanner.LBRACE:
+                       if P.expr_lev >= 0 {
+                               x = P.parseCallOrCompositeLit(x, Scanner.LBRACE, Scanner.RBRACE);
+                       } else {
+                               return x;
+                       }
                default:
                        return x;
                }
@@ -1232,6 +1246,8 @@ 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
@@ -1256,6 +1272,7 @@ func (P *Parser) parseControlClause(isForStat bool) (init AST.Stat, expr AST.Exp
                                }
                        }
                }
+               P.expr_lev = prev_lev;
        }
 
        return init, expr, post;
index 3037ac300159ac2fddd7b432b717601a4e22e0f4..8aced7b9fc3797e56aa235279bcca07dddafc44b 100644 (file)
@@ -40,7 +40,7 @@ const (
 func readfile(filename string) ([]byte, *OS.Error) {
        fd, err := OS.Open(filename, OS.O_RDONLY, 0);
        if err != nil {
-               return []byte(), err;
+               return []byte{}, err;
        }
        var buf [1<<20]byte;
        n, err1 := IO.Readn(fd, buf);
@@ -67,7 +67,7 @@ func ReadObjectFile(filename string) ([]byte, bool) {
        if err == nil && len(data) >= len(magic) && string(data[0 : len(magic)]) == magic {
                return data, true;
        }
-       return []byte(), false;
+       return []byte{}, false;
 }
 
 
index f08e70ccdb771925796674689f4d78274974b724..0a7741500a03708428598854fcb4ed8f23ec9750 100644 (file)
@@ -649,9 +649,12 @@ func (P *Printer) DoIndex(x *AST.Index) {
 
 func (P *Printer) DoCall(x *AST.Call) {
        P.Expr1(x.F, Scanner.HighestPrec);
-       P.Token(x.Pos_, Scanner.LPAREN);
+       P.Token(x.Pos_, x.Tok);
        P.Expr(x.Args);
-       P.Token(0, Scanner.RPAREN);
+       switch x.Tok {
+       case Scanner.LPAREN: P.Token(0, Scanner.RPAREN);
+       case Scanner.LBRACE: P.Token(0, Scanner.RBRACE);
+       }
 }
 
 
@@ -946,7 +949,7 @@ func (P *Printer) DoEmptyStat(s *AST.EmptyStat) {
 // Declarations
 
 func (P *Printer) DoBadDecl(d *AST.BadDecl) {
-       unimplemented();
+       P.String(d.Pos, "<BAD DECL>");
 }
 
 
index c9aee58f74bd0e393f33a64df210d469968f0cb4..1c3094597a4588486ee2e30147238dc2fb952aa7 100644 (file)
@@ -620,7 +620,7 @@ loop:
                S.next();  // always make progress
                switch ch {
                case -1: tok = EOF;
-               case '\n': tok, val = COMMENT, []byte('\n');
+               case '\n': tok, val = COMMENT, []byte{'\n'};
                case '"': tok, val = STRING, S.scanString();
                case '\'': tok, val = INT, S.scanChar();
                case '`': tok, val = STRING, S.scanRawString();