Commit 6dd93bbf authored by Robert Griesemer's avatar Robert Griesemer

- changed pretty parser to parse and print new function type syntax

- added more test cases
- fixed a bug in test script which prevented errors to show up...

R=r
OCL=23832
CL=23974
parent 7b6bdfb7
......@@ -526,7 +526,7 @@ func (P *Parser) ParseResult(ftyp *AST.Type) *AST.Type {
var t *AST.Type;
if P.tok == Scanner.LPAREN {
t = P.ParseParameters(false);
} else {
} else if P.tok != Scanner.FUNC {
typ := P.TryType();
if typ != nil {
t = AST.NewType(P.pos, AST.STRUCT);
......@@ -547,8 +547,8 @@ func (P *Parser) ParseResult(ftyp *AST.Type) *AST.Type {
// (params) type
// (params) (results)
func (P *Parser) ParseFunctionType() *AST.Type {
P.Trace("FunctionType");
func (P *Parser) ParseSignature() *AST.Type {
P.Trace("Signature");
P.OpenScope();
P.scope_lev++;
......@@ -567,16 +567,22 @@ func (P *Parser) ParseFunctionType() *AST.Type {
}
func (P *Parser) ParseFunctionType() *AST.Type {
P.Trace("FunctionType");
P.Expect(Scanner.FUNC);
t := P.ParseSignature();
P.Ecart();
return t;
}
func (P *Parser) ParseMethodSpec(list *array.Array) {
P.Trace("MethodDecl");
list.Push(P.ParseIdentList());
t := AST.BadType;
if P.sixg {
t = P.ParseType();
} else {
t = P.ParseFunctionType();
}
t := P.ParseSignature();
list.Push(AST.NewTypeExpr(t));
P.Ecart();
......@@ -691,7 +697,7 @@ func (P *Parser) TryType() *AST.Type {
case Scanner.LBRACK: t = P.ParseArrayType();
case Scanner.CHAN, Scanner.ARROW: t = P.ParseChannelType();
case Scanner.INTERFACE: t = P.ParseInterfaceType();
case Scanner.LPAREN: t = P.ParseFunctionType();
case Scanner.FUNC: t = P.ParseFunctionType();
case Scanner.MAP: t = P.ParseMapType();
case Scanner.STRUCT: t = P.ParseStructType();
case Scanner.MUL: t = P.ParsePointerType();
......@@ -798,7 +804,7 @@ func (P *Parser) ParseFunctionLit() *AST.Expr {
f := AST.NewObject(P.pos, AST.FUNC, "");
P.Expect(Scanner.FUNC);
f.Typ = P.ParseFunctionType();
f.Typ = P.ParseSignature();
P.expr_lev++;
P.scope_lev++;
f.Body = P.ParseBlock(f.Typ, Scanner.LBRACE);
......@@ -1630,7 +1636,7 @@ func (P *Parser) ParseFunctionDecl() *AST.Decl {
}
d.Ident = P.ParseIdent(nil);
d.Typ = P.ParseFunctionType();
d.Typ = P.ParseSignature();
d.Typ.Key = recv;
if P.tok == Scanner.LBRACE {
......
......@@ -52,7 +52,10 @@ func main() {
} else {
prog, nerrors := Compilation.Compile(src_file, &flags);
if nerrors > 0 {
return;
if flags.Testmode {
return; // TODO we shouldn't need this
}
sys.Exit(1);
}
if !*silent && !flags.Testmode {
Printer.Print(prog);
......
......@@ -408,8 +408,9 @@ func (P *Printer) HtmlIdentifier(x *AST.Expr) {
// ----------------------------------------------------------------------------
// Types
func (P *Printer) Type(t *AST.Type) int
func (P *Printer) Type(t *AST.Type, full_function_type bool) int
func (P *Printer) Expr(x *AST.Expr)
func (P *Printer) Expr1(x *AST.Expr, prec1 int, full_function_type bool)
func (P *Printer) Parameters(pos int, list *array.Array) {
P.String(pos, "(");
......@@ -432,7 +433,7 @@ func (P *Printer) Parameters(pos int, list *array.Array) {
}
func (P *Printer) Fields(list *array.Array, end int) {
func (P *Printer) Fields(list *array.Array, end int, full_function_type bool) {
P.state = opening_scope;
P.String(0, "{");
......@@ -451,7 +452,7 @@ func (P *Printer) Fields(list *array.Array, end int) {
P.separator = tab;
}
}
P.Expr(x);
P.Expr1(x, Scanner.LowestPrec, full_function_type);
prev = x.Tok;
}
P.newlines = 1;
......@@ -464,7 +465,7 @@ func (P *Printer) Fields(list *array.Array, end int) {
// Returns the separator (semicolon or none) required if
// the type is terminating a declaration or statement.
func (P *Printer) Type(t *AST.Type) int {
func (P *Printer) Type(t *AST.Type, full_function_type bool) int {
separator := semicolon;
switch t.Form {
......@@ -477,7 +478,7 @@ func (P *Printer) Type(t *AST.Type) int {
P.Expr(t.Expr);
}
P.String(0, "]");
separator = P.Type(t.Elt);
separator = P.Type(t.Elt, true);
case AST.STRUCT, AST.INTERFACE:
switch t.Form {
......@@ -486,15 +487,15 @@ func (P *Printer) Type(t *AST.Type) int {
}
if t.List != nil {
P.separator = blank;
P.Fields(t.List, t.End);
P.Fields(t.List, t.End, t.Form == AST.STRUCT);
}
separator = none;
case AST.MAP:
P.String(t.Pos, "map [");
P.Type(t.Key);
P.Type(t.Key, true);
P.String(0, "]");
separator = P.Type(t.Elt);
separator = P.Type(t.Elt, true);
case AST.CHANNEL:
var m string;
......@@ -504,18 +505,23 @@ func (P *Printer) Type(t *AST.Type) int {
case AST.SEND: m = "chan <- ";
}
P.String(t.Pos, m);
separator = P.Type(t.Elt);
separator = P.Type(t.Elt, true);
case AST.POINTER:
P.String(t.Pos, "*");
separator = P.Type(t.Elt);
separator = P.Type(t.Elt, true);
case AST.FUNCTION:
if full_function_type {
P.Token(0, Scanner.FUNC);
}
P.Parameters(t.Pos, t.List);
if t.Elt != nil {
P.separator = blank;
list := t.Elt.List;
if list.Len() > 1 {
if list.Len() > 1 || list.At(0).(*AST.Expr).Typ.Form == AST.FUNCTION {
// single, anonymous result types which are functions must
// be parenthesized as well
P.Parameters(0, list);
} else {
// single, anonymous result type
......@@ -539,7 +545,7 @@ func (P *Printer) Type(t *AST.Type) int {
func (P *Printer) Block(b *AST.Block, indent bool);
func (P *Printer) Expr1(x *AST.Expr, prec1 int) {
func (P *Printer) Expr1(x *AST.Expr, prec1 int, full_function_type bool) {
if x == nil {
return; // empty expression list
}
......@@ -547,7 +553,7 @@ func (P *Printer) Expr1(x *AST.Expr, prec1 int) {
switch x.Tok {
case Scanner.TYPE:
// type expr
P.Type(x.Typ);
P.Type(x.Typ, full_function_type);
case Scanner.IDENT:
P.HtmlIdentifier(x);
......@@ -559,7 +565,7 @@ func (P *Printer) Expr1(x *AST.Expr, prec1 int) {
case Scanner.FUNC:
// function literal
P.String(x.Pos, "func");
P.Type(x.Obj.Typ);
P.Type(x.Obj.Typ, false);
P.Block(x.Obj.Body, true);
P.newlines = 0;
......@@ -574,33 +580,33 @@ func (P *Printer) Expr1(x *AST.Expr, prec1 int) {
case Scanner.PERIOD:
// selector or type guard
P.Expr1(x.X, Scanner.HighestPrec);
P.Expr1(x.X, Scanner.HighestPrec, true);
P.String(x.Pos, ".");
if x.Y.Tok == Scanner.TYPE {
P.String(0, "(");
P.Expr(x.Y);
P.String(0, ")");
} else {
P.Expr1(x.Y, Scanner.HighestPrec);
P.Expr1(x.Y, Scanner.HighestPrec, true);
}
case Scanner.LBRACK:
// index
P.Expr1(x.X, Scanner.HighestPrec);
P.Expr1(x.X, Scanner.HighestPrec, true);
P.String(x.Pos, "[");
P.Expr1(x.Y, 0);
P.Expr1(x.Y, 0, true);
P.String(0, "]");
case Scanner.LPAREN:
// call
P.Expr1(x.X, Scanner.HighestPrec);
P.Expr1(x.X, Scanner.HighestPrec, true);
P.String(x.Pos, "(");
P.Expr(x.Y);
P.String(0, ")");
case Scanner.LBRACE:
// composite literal
P.Type(x.Obj.Typ);
P.Type(x.Obj.Typ, true);
P.String(x.Pos, "{");
P.Expr(x.Y);
P.String(0, "}");
......@@ -622,12 +628,12 @@ func (P *Printer) Expr1(x *AST.Expr, prec1 int) {
}
} else {
// binary expression
P.Expr1(x.X, prec);
P.Expr1(x.X, prec, true);
P.separator = blank;
P.Token(x.Pos, x.Tok);
P.separator = blank;
}
P.Expr1(x.Y, prec);
P.Expr1(x.Y, prec, true);
if prec < prec1 {
P.String(0, ")");
}
......@@ -636,7 +642,7 @@ func (P *Printer) Expr1(x *AST.Expr, prec1 int) {
func (P *Printer) Expr(x *AST.Expr) {
P.Expr1(x, Scanner.LowestPrec);
P.Expr1(x, Scanner.LowestPrec, true);
}
......@@ -832,13 +838,13 @@ func (P *Printer) Declaration(d *AST.Decl, parenthesized bool) {
case Scanner.TYPE:
P.Expr(d.Ident);
P.separator = blank; // TODO switch to tab? (but indentation problem with structs)
P.separator = P.Type(d.Typ);
P.separator = P.Type(d.Typ, true);
case Scanner.CONST, Scanner.VAR:
P.Expr(d.Ident);
if d.Typ != nil {
P.separator = blank; // TODO switch to tab? (indentation problem with structs)
P.separator = P.Type(d.Typ);
P.separator = P.Type(d.Typ, true);
}
if d.Val != nil {
P.separator = tab;
......@@ -855,7 +861,7 @@ func (P *Printer) Declaration(d *AST.Decl, parenthesized bool) {
P.separator = blank;
}
P.Expr(d.Ident);
P.separator = P.Type(d.Typ);
P.separator = P.Type(d.Typ, false);
if d.Val != nil {
P.separator = blank;
P.Block(d.Val.Obj.Body, true);
......
......@@ -27,7 +27,7 @@ apply1() {
# the following have semantic errors: bug039.go | bug040.go
method1.go | selftest1.go | func3.go | \
bug014.go | bug025.go | bug029.go | bug032.go | bug039.go | bug040.go | bug050.go | bug068.go | \
bug088.go | bug083.go | bug106.go | bug125.go | bug126.go | bug132.go | bug133.go ) ;;
bug088.go | bug083.go | bug106.go | bug121.go | bug125.go | bug126.go | bug132.go | bug133.go | bug134.go ) ;;
* ) $1 $2; count $F;;
esac
}
......@@ -49,6 +49,7 @@ apply() {
$GOROOT/test/*.go \
$GOROOT/test/bugs/*.go \
$GOROOT/test/fixedbugs/*.go \
$GOROOT/doc/progs/*.go \
$GOROOT/src/lib/*.go \
$GOROOT/src/lib/*/*.go \
$GOROOT/usr/r/*/*.go
......
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