1
0
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:
Robert Griesemer 2009-01-30 15:31:04 -08:00
parent 7b6bdfb735
commit 6dd93bbfbc
4 changed files with 56 additions and 40 deletions

View File

@ -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 {

View File

@ -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);

View File

@ -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);

View File

@ -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