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