Commit 63b332ed authored by Robert Griesemer's avatar Robert Griesemer

- 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
parent 7a5e97ba
......@@ -112,7 +112,8 @@ type (
};
Call struct {
Pos_ int; // position of "("
Pos_ int; // position of "(" or "{"
Tok int;
F, Args Expr
};
......
......@@ -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();
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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>");
}
......
......@@ -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();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment