summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2009-03-03 16:00:06 -0800
committerRobert Griesemer <gri@golang.org>2009-03-03 16:00:06 -0800
commit79ae0065d879dc065a29670c078026a9339f0542 (patch)
treeb3e0f33c6a5ebeb47d96527acc21839212ce9a4f
parent88f30e6c1447305754a0847891c84090d046b7e2 (diff)
downloadgolang-79ae0065d879dc065a29670c078026a9339f0542.tar.gz
- allow ()'s and {}'s for now when parsing calls/composite literals
- 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
-rw-r--r--usr/gri/pretty/ast.go3
-rw-r--r--usr/gri/pretty/compilation.go10
-rw-r--r--usr/gri/pretty/parser.go41
-rw-r--r--usr/gri/pretty/platform.go4
-rw-r--r--usr/gri/pretty/printer.go9
-rw-r--r--usr/gri/pretty/scanner.go2
6 files changed, 42 insertions, 27 deletions
diff --git a/usr/gri/pretty/ast.go b/usr/gri/pretty/ast.go
index 0bad5bb82..d618a1bf4 100644
--- a/usr/gri/pretty/ast.go
+++ b/usr/gri/pretty/ast.go
@@ -112,7 +112,8 @@ type (
};
Call struct {
- Pos_ int; // position of "("
+ Pos_ int; // position of "(" or "{"
+ Tok int;
F, Args Expr
};
diff --git a/usr/gri/pretty/compilation.go b/usr/gri/pretty/compilation.go
index 75f62f2fa..74b589e40 100644
--- a/usr/gri/pretty/compilation.go
+++ b/usr/gri/pretty/compilation.go
@@ -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();
diff --git a/usr/gri/pretty/parser.go b/usr/gri/pretty/parser.go
index 27bf4b3cb..ad72d47dd 100644
--- a/usr/gri/pretty/parser.go
+++ b/usr/gri/pretty/parser.go
@@ -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;
diff --git a/usr/gri/pretty/platform.go b/usr/gri/pretty/platform.go
index 3037ac300..8aced7b9f 100644
--- a/usr/gri/pretty/platform.go
+++ b/usr/gri/pretty/platform.go
@@ -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;
}
diff --git a/usr/gri/pretty/printer.go b/usr/gri/pretty/printer.go
index f08e70ccd..0a7741500 100644
--- a/usr/gri/pretty/printer.go
+++ b/usr/gri/pretty/printer.go
@@ -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>");
}
diff --git a/usr/gri/pretty/scanner.go b/usr/gri/pretty/scanner.go
index c9aee58f7..1c3094597 100644
--- a/usr/gri/pretty/scanner.go
+++ b/usr/gri/pretty/scanner.go
@@ -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();