summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/gri/pretty/ast.go309
-rw-r--r--usr/gri/pretty/compilation.go11
-rw-r--r--usr/gri/pretty/parser.go575
-rw-r--r--usr/gri/pretty/printer.go553
-rw-r--r--usr/gri/pretty/selftest1.go2
-rwxr-xr-xusr/gri/pretty/test.sh15
-rw-r--r--usr/gri/pretty/typechecker.go6
7 files changed, 847 insertions, 624 deletions
diff --git a/usr/gri/pretty/ast.go b/usr/gri/pretty/ast.go
index b82e1f1c5..0bad5bb82 100644
--- a/usr/gri/pretty/ast.go
+++ b/usr/gri/pretty/ast.go
@@ -14,7 +14,7 @@ import (
type (
Block struct;
Expr interface;
- Decl struct;
+ Decl interface;
)
@@ -38,41 +38,7 @@ type Node struct {
// ----------------------------------------------------------------------------
-// Types
-
-const /* form */ (
- // BADTYPE types are compatible with any type and don't cause further errors.
- // They are introduced only as a result of an error in the source code. A
- // correct program cannot have BAD types.
- BADTYPE = iota;
-
- // A type name
- TYPENAME;
-
- // composite types
- ARRAY; STRUCT; INTERFACE; MAP; CHANNEL; FUNCTION; POINTER;
-
- // open-ended parameter type
- ELLIPSIS
-)
-
-
-func FormStr(form int) string {
- switch form {
- case BADTYPE: return "BADTYPE";
- case TYPENAME: return "TYPENAME";
- case ARRAY: return "ARRAY";
- case STRUCT: return "STRUCT";
- case INTERFACE: return "INTERFACE";
- case MAP: return "MAP";
- case CHANNEL: return "CHANNEL";
- case FUNCTION: return "FUNCTION";
- case POINTER: return "POINTER";
- case ELLIPSIS: return "ELLIPSIS";
- }
- return "<unknown Type form>";
-}
-
+// Expressions
const /* channel mode */ (
FULL = iota;
@@ -81,62 +47,15 @@ const /* channel mode */ (
)
-type Type struct {
- Id int; // unique id
-
- Form int; // type form
- Size int; // size in bytes
- Scope *SymbolTable.Scope; // locals, fields & methods
-
- // syntactic components
- Pos int; // source position (< 0 if unknown position)
- Expr Expr; // type name, vector length
- Mode int; // channel mode
- Key *Type; // receiver type or map key
- Elt *Type; // type name type, vector, map, channel or pointer element type, function result type
- List *vector.Vector; End int; // struct fields, interface methods, function parameters
-}
-
-
-var typeId int;
-
-func NewType(pos, form int) *Type {
- typ := new(Type);
- typ.Id = typeId;
- typeId++;
-
- typ.Pos = pos;
- typ.Form = form;
-
- return typ;
-}
-
-
-func (typ* Type) String() string {
- if typ != nil {
- return
- "Type(" +
- FormStr(typ.Form) +
- ")";
- }
- return "nil";
-}
-
-
-var BadType = NewType(0, Scanner.ILLEGAL);
-
-
-// ----------------------------------------------------------------------------
-// Expressions
-
type (
ExprVisitor interface;
+ Signature struct;
Expr interface {
Pos() int;
Visit(v ExprVisitor);
};
-
+
BadExpr struct {
Pos_ int;
};
@@ -147,28 +66,32 @@ type (
};
BinaryExpr struct {
- Pos_, Tok int;
+ Pos_ int;
+ Tok int;
X, Y Expr;
};
UnaryExpr struct {
- Pos_, Tok int;
+ Pos_ int;
+ Tok int;
X Expr;
};
BasicLit struct {
- Pos_, Tok int;
+ Pos_ int;
+ Tok int;
Val string
};
FunctionLit struct {
Pos_ int; // position of "func"
- Typ *Type;
+ Typ *Signature;
Body *Block;
};
- TypeLit struct {
- Typ *Type;
+ Group struct {
+ Pos_ int; // position of "("
+ X Expr;
};
Selector struct {
@@ -180,7 +103,7 @@ type (
TypeGuard struct {
Pos_ int; // position of "."
X Expr;
- Typ *Type;
+ Typ Expr;
};
Index struct {
@@ -192,6 +115,66 @@ type (
Pos_ int; // position of "("
F, Args Expr
};
+
+ // Type literals are treated like expressions.
+ Ellipsis struct { // neither a type nor an expression
+ Pos_ int;
+ };
+
+ ArrayType struct {
+ Pos_ int; // position of "["
+ Len Expr;
+ Elt Expr;
+ };
+
+ Field struct {
+ Idents []*Ident;
+ Typ Expr;
+ Tag Expr; // nil = no tag
+ };
+
+ StructType struct {
+ Pos_ int; // position of "struct"
+ Fields []*Field;
+ End int; // position of "}", End == 0 if forward declaration
+ };
+
+ PointerType struct {
+ Pos_ int; // position of "*"
+ Base Expr;
+ };
+
+ Signature struct {
+ Params []*Field;
+ Result []*Field;
+ };
+
+ FunctionType struct {
+ Pos_ int; // position of "func"
+ Sig *Signature;
+ };
+
+ InterfaceType struct {
+ Pos_ int; // position of "interface"
+ Methods []*Field;
+ End int; // position of "}", End == 0 if forward declaration
+ };
+
+ SliceType struct {
+ Pos_ int; // position of "["
+ };
+
+ MapType struct {
+ Pos_ int; // position of "map"
+ Key Expr;
+ Val Expr;
+ };
+
+ ChannelType struct {
+ Pos_ int; // position of "chan" or "<-"
+ Mode int;
+ Val Expr;
+ };
)
@@ -202,26 +185,47 @@ type ExprVisitor interface {
DoUnaryExpr(x *UnaryExpr);
DoBasicLit(x *BasicLit);
DoFunctionLit(x *FunctionLit);
- DoTypeLit(x *TypeLit);
+ DoGroup(x *Group);
DoSelector(x *Selector);
DoTypeGuard(x *TypeGuard);
DoIndex(x *Index);
DoCall(x *Call);
+
+ DoEllipsis(x *Ellipsis);
+ DoArrayType(x *ArrayType);
+ DoStructType(x *StructType);
+ DoPointerType(x *PointerType);
+ DoFunctionType(x *FunctionType);
+ DoInterfaceType(x *InterfaceType);
+ DoSliceType(x *SliceType);
+ DoMapType(x *MapType);
+ DoChannelType(x *ChannelType);
}
+// TODO replace these with an embedded field
func (x *BadExpr) Pos() int { return x.Pos_; }
func (x *Ident) Pos() int { return x.Pos_; }
func (x *BinaryExpr) Pos() int { return x.Pos_; }
func (x *UnaryExpr) Pos() int { return x.Pos_; }
func (x *BasicLit) Pos() int { return x.Pos_; }
func (x *FunctionLit) Pos() int { return x.Pos_; }
-func (x *TypeLit) Pos() int { return x.Typ.Pos; }
+func (x *Group) Pos() int { return x.Pos_; }
func (x *Selector) Pos() int { return x.Pos_; }
func (x *TypeGuard) Pos() int { return x.Pos_; }
func (x *Index) Pos() int { return x.Pos_; }
func (x *Call) Pos() int { return x.Pos_; }
+func (x *Ellipsis) Pos() int { return x.Pos_; }
+func (x *ArrayType) Pos() int { return x.Pos_; }
+func (x *StructType) Pos() int { return x.Pos_; }
+func (x *PointerType) Pos() int { return x.Pos_; }
+func (x *FunctionType) Pos() int { return x.Pos_; }
+func (x *InterfaceType) Pos() int { return x.Pos_; }
+func (x *SliceType) Pos() int { return x.Pos_; }
+func (x *MapType) Pos() int { return x.Pos_; }
+func (x *ChannelType) Pos() int { return x.Pos_; }
+
func (x *BadExpr) Visit(v ExprVisitor) { v.DoBadExpr(x); }
func (x *Ident) Visit(v ExprVisitor) { v.DoIdent(x); }
@@ -229,12 +233,22 @@ func (x *BinaryExpr) Visit(v ExprVisitor) { v.DoBinaryExpr(x); }
func (x *UnaryExpr) Visit(v ExprVisitor) { v.DoUnaryExpr(x); }
func (x *BasicLit) Visit(v ExprVisitor) { v.DoBasicLit(x); }
func (x *FunctionLit) Visit(v ExprVisitor) { v.DoFunctionLit(x); }
-func (x *TypeLit) Visit(v ExprVisitor) { v.DoTypeLit(x); }
+func (x *Group) Visit(v ExprVisitor) { v.DoGroup(x); }
func (x *Selector) Visit(v ExprVisitor) { v.DoSelector(x); }
func (x *TypeGuard) Visit(v ExprVisitor) { v.DoTypeGuard(x); }
func (x *Index) Visit(v ExprVisitor) { v.DoIndex(x); }
func (x *Call) Visit(v ExprVisitor) { v.DoCall(x); }
+func (x *Ellipsis) Visit(v ExprVisitor) { v.DoEllipsis(x); }
+func (x *ArrayType) Visit(v ExprVisitor) { v.DoArrayType(x); }
+func (x *StructType) Visit(v ExprVisitor) { v.DoStructType(x); }
+func (x *PointerType) Visit(v ExprVisitor) { v.DoPointerType(x); }
+func (x *FunctionType) Visit(v ExprVisitor) { v.DoFunctionType(x); }
+func (x *InterfaceType) Visit(v ExprVisitor) { v.DoInterfaceType(x); }
+func (x *SliceType) Visit(v ExprVisitor) { v.DoSliceType(x); }
+func (x *MapType) Visit(v ExprVisitor) { v.DoMapType(x); }
+func (x *ChannelType) Visit(v ExprVisitor) { v.DoChannelType(x); }
+
// Length of a comma-separated expression list.
@@ -267,25 +281,6 @@ func ExprAt(x Expr, i int) Expr {
}
-func (t *Type) Nfields() int {
- if t.List == nil {
- return 0;
- }
- nx, nt := 0, 0;
- for i, n := 0, t.List.Len(); i < n; i++ {
- if dummy, ok := t.List.At(i).(*TypeLit); ok {
- nt++;
- } else {
- nx++;
- }
- }
- if nx == 0 {
- return nt;
- }
- return nx;
-}
-
-
// ----------------------------------------------------------------------------
// Blocks
//
@@ -329,7 +324,7 @@ type (
};
DeclarationStat struct {
- Decl *Decl;
+ Decl Decl;
};
ExpressionStat struct {
@@ -421,25 +416,79 @@ func (s *EmptyStat) Visit(v StatVisitor) { v.DoEmptyStat(s); }
// ----------------------------------------------------------------------------
// Declarations
-type Decl struct {
- Node;
- Ident Expr; // nil for ()-style declarations
- Typ *Type;
- Val Expr;
- Body *Block;
- // list of *Decl for ()-style declarations
- List *vector.Vector; End int;
-}
+type (
+ DeclVisitor interface;
+
+ Decl interface {
+ Visit(v DeclVisitor);
+ };
+
+ BadDecl struct {
+ Pos int;
+ };
+
+ ImportDecl struct {
+ Pos int; // if > 0: position of "import"
+ Ident *Ident;
+ Path Expr;
+ };
+
+ ConstDecl struct {
+ Pos int; // if > 0: position of "const"
+ Idents []*Ident;
+ Typ Expr;
+ Vals Expr;
+ };
+
+ TypeDecl struct {
+ Pos int; // if > 0: position of "type"
+ Ident *Ident;
+ Typ Expr;
+ };
+
+ VarDecl struct {
+ Pos int; // if > 0: position of "var"
+ Idents []*Ident;
+ Typ Expr;
+ Vals Expr;
+ };
+
+ FuncDecl struct {
+ Pos_ int; // position of "func"
+ Recv *Field;
+ Ident *Ident;
+ Sig *Signature;
+ Body *Block;
+ };
+
+ DeclList struct {
+ Pos int; // position of Tok
+ Tok int;
+ List []Decl;
+ End int;
+ };
+)
-func NewDecl(pos, tok int) *Decl {
- d := new(Decl);
- d.Pos, d.Tok = pos, tok;
- return d;
+type DeclVisitor interface {
+ DoBadDecl(d *BadDecl);
+ DoImportDecl(d *ImportDecl);
+ DoConstDecl(d *ConstDecl);
+ DoTypeDecl(d *TypeDecl);
+ DoVarDecl(d *VarDecl);
+ DoFuncDecl(d *FuncDecl);
+ DoDeclList(d *DeclList);
}
-var BadDecl = NewDecl(0, Scanner.ILLEGAL);
+//func (d *Decl) Visit(v DeclVisitor) { v.DoDecl(d); }
+func (d *BadDecl) Visit(v DeclVisitor) { v.DoBadDecl(d); }
+func (d *ImportDecl) Visit(v DeclVisitor) { v.DoImportDecl(d); }
+func (d *ConstDecl) Visit(v DeclVisitor) { v.DoConstDecl(d); }
+func (d *TypeDecl) Visit(v DeclVisitor) { v.DoTypeDecl(d); }
+func (d *VarDecl) Visit(v DeclVisitor) { v.DoVarDecl(d); }
+func (d *FuncDecl) Visit(v DeclVisitor) { v.DoFuncDecl(d); }
+func (d *DeclList) Visit(v DeclVisitor) { v.DoDeclList(d); }
// ----------------------------------------------------------------------------
@@ -461,7 +510,7 @@ func NewComment(pos int, text string) *Comment {
type Program struct {
Pos int; // tok is Scanner.PACKAGE
Ident Expr;
- Decls *vector.Vector;
+ Decls []Decl;
Comments *vector.Vector;
}
diff --git a/usr/gri/pretty/compilation.go b/usr/gri/pretty/compilation.go
index 460bedac5..44bcb8315 100644
--- a/usr/gri/pretty/compilation.go
+++ b/usr/gri/pretty/compilation.go
@@ -150,7 +150,8 @@ func fileExists(name string) bool {
}
-func printDep(localset map [string] bool, wset *vector.Vector, decl *AST.Decl) {
+/*
+func printDep(localset map [string] bool, wset *vector.Vector, decl AST.Decl2) {
src := decl.Val.(*AST.BasicLit).Val;
src = src[1 : len(src) - 1]; // strip "'s
@@ -171,6 +172,7 @@ func printDep(localset map [string] bool, wset *vector.Vector, decl *AST.Decl) {
}
}
}
+*/
func addDeps(globalset map [string] bool, wset *vector.Vector, src_file string, flags *Flags) {
@@ -183,13 +185,15 @@ func addDeps(globalset map [string] bool, wset *vector.Vector, src_file string,
return;
}
- nimports := prog.Decls.Len();
+ nimports := len(prog.Decls);
if nimports > 0 {
fmt.Printf("%s.6:\t", src_file);
localset := make(map [string] bool);
for i := 0; i < nimports; i++ {
- decl := prog.Decls.At(i).(*AST.Decl);
+ decl := prog.Decls[i];
+ panic();
+ /*
assert(decl.Tok == Scanner.IMPORT);
if decl.List == nil {
printDep(localset, wset, decl);
@@ -198,6 +202,7 @@ func addDeps(globalset map [string] bool, wset *vector.Vector, src_file string,
printDep(localset, wset, decl.List.At(j).(*AST.Decl));
}
}
+ */
}
print("\n\n");
}
diff --git a/usr/gri/pretty/parser.go b/usr/gri/pretty/parser.go
index c2af6ce20..0eced7fdb 100644
--- a/usr/gri/pretty/parser.go
+++ b/usr/gri/pretty/parser.go
@@ -29,7 +29,7 @@ type Parser struct {
val string; // token value (for IDENT, NUMBER, STRING only)
// Non-syntactic parser control
- opt_semi bool; // true if semicolon is optional
+ 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.
@@ -170,6 +170,7 @@ func (P *Parser) closeScope() {
}
+/*
func (P *Parser) declareInScope(scope *SymbolTable.Scope, x AST.Expr, kind int, typ *AST.Type) {
if P.scope_lev < 0 {
panic("cannot declare objects in other packages");
@@ -207,15 +208,16 @@ func (P *Parser) declare(x AST.Expr, kind int, typ *AST.Type) {
}
P.declareInScope(P.top_scope, x, kind, typ);
}
+*/
// ----------------------------------------------------------------------------
// Common productions
-func (P *Parser) tryType() *AST.Type;
+func (P *Parser) tryType() AST.Expr;
func (P *Parser) parseExpression(prec int) AST.Expr;
func (P *Parser) parseStatement() AST.Stat;
-func (P *Parser) parseDeclaration() *AST.Decl;
+func (P *Parser) parseDeclaration() AST.Decl;
// If scope != nil, lookup identifier in scope. Otherwise create one.
@@ -270,10 +272,34 @@ func (P *Parser) parseIdentList(x AST.Expr) AST.Expr {
}
+func (P *Parser) parseIdentList2(x AST.Expr) []*AST.Ident {
+ if P.trace {
+ defer un(trace(P, "IdentList"));
+ }
+
+ list := vector.New(0);
+ if x == nil {
+ x = P.parseIdent(nil);
+ }
+ list.Push(x);
+ for P.tok == Scanner.COMMA {
+ P.next();
+ list.Push(P.parseIdent(nil));
+ }
+
+ // convert vector
+ idents := make([]*AST.Ident, list.Len());
+ for i := 0; i < list.Len(); i++ {
+ idents[i] = list.At(i).(*AST.Ident);
+ }
+ return idents;
+}
+
+
// ----------------------------------------------------------------------------
// Types
-func (P *Parser) parseType() *AST.Type {
+func (P *Parser) parseType() AST.Expr {
if P.trace {
defer un(trace(P, "Type"));
}
@@ -281,14 +307,14 @@ func (P *Parser) parseType() *AST.Type {
t := P.tryType();
if t == nil {
P.error(P.pos, "type expected");
- t = AST.BadType;
+ t = &AST.BadExpr(P.pos);
}
return t;
}
-func (P *Parser) parseVarType() *AST.Type {
+func (P *Parser) parseVarType() AST.Expr {
if P.trace {
defer un(trace(P, "VarType"));
}
@@ -314,88 +340,90 @@ func (P *Parser) parseQualifiedIdent() AST.Expr {
}
-func (P *Parser) parseTypeName() *AST.Type {
+func (P *Parser) parseTypeName() AST.Expr {
if P.trace {
defer un(trace(P, "TypeName"));
}
- t := AST.NewType(P.pos, AST.TYPENAME);
- t.Expr = P.parseQualifiedIdent();
-
- return t;
+ return P.parseQualifiedIdent();
}
-func (P *Parser) parseArrayType() *AST.Type {
+func (P *Parser) parseArrayType() *AST.ArrayType {
if P.trace {
defer un(trace(P, "ArrayType"));
}
- t := AST.NewType(P.pos, AST.ARRAY);
+ pos := P.pos;
P.expect(Scanner.LBRACK);
+ var len AST.Expr;
if P.tok == Scanner.ELLIPSIS {
- t.Expr = &AST.BinaryExpr(P.pos, Scanner.ELLIPSIS, nil, nil);
+ len = &AST.Ellipsis(P.pos);
P.next();
} else if P.tok != Scanner.RBRACK {
- t.Expr = P.parseExpression(1);
+ len = P.parseExpression(1);
}
P.expect(Scanner.RBRACK);
- t.Elt = P.parseType();
+ elt := P.parseType();
- return t;
+ return &AST.ArrayType(pos, len, elt);
}
-func (P *Parser) parseChannelType() *AST.Type {
+func (P *Parser) parseChannelType() *AST.ChannelType {
if P.trace {
defer un(trace(P, "ChannelType"));
}
- t := AST.NewType(P.pos, AST.CHANNEL);
- t.Mode = AST.FULL;
+ pos := P.pos;
+ mode := AST.FULL;
if P.tok == Scanner.CHAN {
P.next();
if P.tok == Scanner.ARROW {
P.next();
- t.Mode = AST.SEND;
+ mode = AST.SEND;
}
} else {
P.expect(Scanner.ARROW);
P.expect(Scanner.CHAN);
- t.Mode = AST.RECV;
+ mode = AST.RECV;
}
- t.Elt = P.parseVarType();
+ val := P.parseVarType();
- return t;
+ return &AST.ChannelType(pos, mode, val);
}
-func (P *Parser) parseVar(expect_ident bool) *AST.Type {
- t := AST.BadType;
- if expect_ident {
- x := P.parseIdent(nil);
- t = AST.NewType(x.Pos(), AST.TYPENAME);
- t.Expr = x;
- } else if P.tok == Scanner.ELLIPSIS {
- t = AST.NewType(P.pos, AST.ELLIPSIS);
+func (P *Parser) tryParameterType() AST.Expr {
+ if P.tok == Scanner.ELLIPSIS {
+ pos := P.tok;
P.next();
- } else {
- t = P.parseType();
+ return &AST.Ellipsis(pos);
}
- return t;
+ return P.tryType();
+}
+
+
+func (P *Parser) parseParameterType() AST.Expr {
+ typ := P.tryParameterType();
+ if typ == nil {
+ P.error(P.tok, "type expected");
+ typ = &AST.BadExpr(P.pos);
+ }
+ return typ;
}
-func (P *Parser) parseVarList(list *vector.Vector, ellipsis_ok bool) {
+func (P *Parser) parseParameterDecl(ellipsis_ok bool) (*vector.Vector, AST.Expr) {
if P.trace {
- defer un(trace(P, "VarList"));
+ defer un(trace(P, "ParameterDecl"));
}
- // assume a list of types
- // (a list of identifiers looks like a list of type names)
- i0 := list.Len();
+ // a list of identifiers looks like a list of type names
+ list := vector.New(0);
for {
- list.Push(P.parseVar(ellipsis_ok /* param list */ && i0 > 0));
+ // TODO do not allow ()'s here
+ list.Push(P.parseParameterType());
if P.tok == Scanner.COMMA {
P.next();
} else {
@@ -404,115 +432,87 @@ func (P *Parser) parseVarList(list *vector.Vector, ellipsis_ok bool) {
}
// if we had a list of identifiers, it must be followed by a type
- typ := P.tryType();
- if typ == nil && P.tok == Scanner.ELLIPSIS {
- typ = AST.NewType(P.pos, AST.ELLIPSIS);
- P.next();
- }
+ typ := P.tryParameterType();
+
+ return list, typ;
+}
- if ellipsis_ok /* param list */ && i0 > 0 && typ == nil {
- // not the first parameter section; we must have a type
- P.error(P.pos, "type expected");
- typ = AST.BadType;
+
+func (P *Parser) parseParameterList(ellipsis_ok bool) []*AST.Field {
+ if P.trace {
+ defer un(trace(P, "ParameterList"));
}
- // convert the list into a list of (type) expressions
+ list, typ := P.parseParameterDecl(false);
if typ != nil {
- // all list entries must be identifiers
- // convert the type entries into identifiers
- for i, n := i0, list.Len(); i < n; i++ {
- t := list.At(i).(*AST.Type);
- if t.Form == AST.TYPENAME {
- if ident, ok := t.Expr.(*AST.Ident); ok {
- list.Set(i, ident);
- continue;
- }
- }
- list.Set(i, &AST.BadExpr(0));
- P.error(t.Pos, "identifier expected");
+ // IdentifierList Type
+ // convert list of identifiers into []*Ident
+ idents := make([]*AST.Ident, list.Len());
+ for i := 0; i < list.Len(); i++ {
+ idents[i] = list.At(i).(*AST.Ident);
+ }
+ list.Init(0);
+ list.Push(&AST.Field(idents, typ, nil));
+
+ for P.tok == Scanner.COMMA {
+ P.next();
+ idents := P.parseIdentList2(nil);
+ typ := P.parseParameterType();
+ list.Push(&AST.Field(idents, typ, nil));
}
- // add type
- list.Push(&AST.TypeLit(typ));
} else {
- // all list entries are types
- // convert all type entries into type expressions
- for i, n := i0, list.Len(); i < n; i++ {
- t := list.At(i).(*AST.Type);
- list.Set(i, &AST.TypeLit(t));
+ // Type { "," Type }
+ // convert list of types into list of *Param
+ for i := 0; i < list.Len(); i++ {
+ list.Set(i, &AST.Field(nil, list.At(i).(AST.Expr), nil));
}
}
-}
-
-func (P *Parser) parseParameterList(ellipsis_ok bool) *vector.Vector {
- if P.trace {
- defer un(trace(P, "ParameterList"));
+ // convert list
+ params := make([]*AST.Field, list.Len());
+ for i := 0; i < list.Len(); i++ {
+ params[i] = list.At(i).(*AST.Field);
}
- list := vector.New(0);
- P.parseVarList(list, ellipsis_ok);
- for P.tok == Scanner.COMMA {
- P.next();
- P.parseVarList(list, ellipsis_ok);
- }
-
- return list;
+ return params;
}
-func (P *Parser) parseParameters(ellipsis_ok bool) *AST.Type {
+// TODO make sure Go spec is updated
+func (P *Parser) parseParameters(ellipsis_ok bool) []*AST.Field {
if P.trace {
defer un(trace(P, "Parameters"));
}
- t := AST.NewType(P.pos, AST.STRUCT);
+ var params []*AST.Field;
P.expect(Scanner.LPAREN);
if P.tok != Scanner.RPAREN {
- t.List = P.parseParameterList(ellipsis_ok);
+ params = P.parseParameterList(ellipsis_ok);
}
- t.End = P.pos;
P.expect(Scanner.RPAREN);
- return t;
+ return params;
}
-func (P *Parser) parseResultList() {
- if P.trace {
- defer un(trace(P, "ResultList"));
- }
-
- P.parseType();
- for P.tok == Scanner.COMMA {
- P.next();
- P.parseType();
- }
- if P.tok != Scanner.RPAREN {
- P.parseType();
- }
-}
-
-
-func (P *Parser) parseResult(ftyp *AST.Type) *AST.Type {
+func (P *Parser) parseResult() []*AST.Field {
if P.trace {
defer un(trace(P, "Result"));
}
- var t *AST.Type;
+ var result []*AST.Field;
if P.tok == Scanner.LPAREN {
- t = P.parseParameters(false);
+ result = P.parseParameters(false);
} else if P.tok != Scanner.FUNC {
typ := P.tryType();
if typ != nil {
- t = AST.NewType(P.pos, AST.STRUCT);
- t.List = vector.New(0);
- t.List.Push(&AST.TypeLit(typ));
- t.End = P.pos;
+ result = make([]*AST.Field, 1);
+ result[0] = &AST.Field(nil, typ, nil);
}
}
- return t;
+ return result;
}
@@ -522,120 +522,189 @@ func (P *Parser) parseResult(ftyp *AST.Type) *AST.Type {
// (params) type
// (params) (results)
-func (P *Parser) parseSignature() *AST.Type {
+func (P *Parser) parseSignature() *AST.Signature {
if P.trace {
defer un(trace(P, "Signature"));
}
- P.openScope();
- P.scope_lev++;
+ //P.openScope();
+ //P.scope_lev++;
- t := AST.NewType(P.pos, AST.FUNCTION);
- t.Scope = P.top_scope;
- t.List = P.parseParameters(true).List; // TODO find better solution
- t.End = P.pos;
- t.Elt = P.parseResult(t);
+ //t.Scope = P.top_scope;
+ params := P.parseParameters(true); // TODO find better solution
+ //t.End = P.pos;
+ result := P.parseResult();
- P.scope_lev--;
- P.closeScope();
+ //P.scope_lev--;
+ //P.closeScope();
- return t;
+ return &AST.Signature(params, result);
}
-func (P *Parser) parseFunctionType() *AST.Type {
+func (P *Parser) parseFunctionType() *AST.FunctionType {
if P.trace {
defer un(trace(P, "FunctionType"));
}
+ pos := P.pos;
P.expect(Scanner.FUNC);
- return P.parseSignature();
+ sig := P.parseSignature();
+
+ return &AST.FunctionType(pos, sig);
}
-func (P *Parser) parseMethodOrInterfaceSpec(list *vector.Vector) {
+func (P *Parser) parseMethodSpec() *AST.Field {
if P.trace {
- defer un(trace(P, "MethodOrInterfaceSpec"));
+ defer un(trace(P, "MethodSpec"));
}
+ var idents []*AST.Ident;
+ var typ AST.Expr;
x := P.parseQualifiedIdent();
if tmp, is_ident := x.(*AST.Ident); is_ident && (P.tok == Scanner.COMMA || P.tok == Scanner.LPAREN) {
// method(s)
- list.Push(P.parseIdentList(x));
- list.Push(&AST.TypeLit(P.parseSignature()));
+ idents = P.parseIdentList2(x);
+ typ = &AST.FunctionType(0, P.parseSignature());
} else {
// embedded interface
- list.Push(x);
+ typ = x;
}
+
+ return &AST.Field(idents, typ, nil);
}
-func (P *Parser) parseInterfaceType() *AST.Type {
+func (P *Parser) parseInterfaceType() *AST.InterfaceType {
if P.trace {
defer un(trace(P, "InterfaceType"));
}
- t := AST.NewType(P.pos, AST.INTERFACE);
+ pos := P.pos;
+ end := 0;
+ var methods []*AST.Field;
+
P.expect(Scanner.INTERFACE);
if P.tok == Scanner.LBRACE {
P.next();
- P.openScope();
- P.scope_lev++;
+ //P.openScope();
+ //P.scope_lev++;
- t.List = vector.New(0);
+ list := vector.New(0);
for P.tok == Scanner.IDENT {
- P.parseMethodOrInterfaceSpec(t.List);
+ list.Push(P.parseMethodSpec());
if P.tok != Scanner.RBRACE {
P.expect(Scanner.SEMICOLON);
}
}
- t.End = P.pos;
+ //t.End = P.pos;
- P.scope_lev--;
- P.closeScope();
+ //P.scope_lev--;
+ //P.closeScope();
+ end = P.pos;
P.expect(Scanner.RBRACE);
+ P.opt_semi = true;
+
+ // convert vector
+ methods = make([]*AST.Field, list.Len());
+ for i := list.Len() - 1; i >= 0; i-- {
+ methods[i] = list.At(i).(*AST.Field);
+ }
}
- return t;
+ return &AST.InterfaceType(pos, methods, end);
}
-func (P *Parser) parseMapType() *AST.Type {
+func (P *Parser) parseMapType() *AST.MapType {
if P.trace {
defer un(trace(P, "MapType"));
}
- t := AST.NewType(P.pos, AST.MAP);
+ pos := P.pos;
P.expect(Scanner.MAP);
P.expect(Scanner.LBRACK);
- t.Key = P.parseVarType();
+ key := P.parseVarType();
P.expect(Scanner.RBRACK);
- t.Elt = P.parseVarType();
+ val := P.parseVarType();
- return t;
+ return &AST.MapType(pos, key, val);
}
func (P *Parser) parseOperand() AST.Expr
-func (P *Parser) parseStructType() *AST.Type {
+
+func (P *Parser) parseFieldDecl() *AST.Field {
+ if P.trace {
+ defer un(trace(P, "FieldDecl"));
+ }
+
+ // a list of identifiers looks like a list of type names
+ list := vector.New(0);
+ for {
+ // TODO do not allow ()'s here
+ list.Push(P.parseType());
+ if P.tok == Scanner.COMMA {
+ P.next();
+ } else {
+ break;
+ }
+ }
+
+ // if we had a list of identifiers, it must be followed by a type
+ typ := P.tryType();
+
+ // optional tag
+ var tag AST.Expr;
+ if P.tok == Scanner.STRING {
+ // ParseOperand takes care of string concatenation
+ tag = P.parseOperand();
+ }
+
+ // analyze case
+ var idents []*AST.Ident;
+ if typ != nil {
+ // non-empty identifier list followed by a type
+ idents = make([]*AST.Ident, list.Len());
+ for i := 0; i < list.Len(); i++ {
+ if ident, is_ident := list.At(i).(*AST.Ident); is_ident {
+ idents[i] = ident;
+ } else {
+ P.error(list.At(i).(AST.Expr).Pos(), "identifier expected");
+ }
+ }
+ } else {
+ // anonymous field
+ if list.Len() == 1 {
+ // TODO should do more checks here
+ typ = list.At(0).(AST.Expr);
+ } else {
+ P.error(P.pos, "anonymous field expected");
+ }
+ }
+
+ return &AST.Field(idents, typ, tag);
+}
+
+
+func (P *Parser) parseStructType() AST.Expr {
if P.trace {
defer un(trace(P, "StructType"));
}
- t := AST.NewType(P.pos, AST.STRUCT);
+ pos := P.pos;
+ end := 0;
+ var fields []*AST.Field;
+
P.expect(Scanner.STRUCT);
if P.tok == Scanner.LBRACE {
P.next();
- t.List = vector.New(0);
- t.Scope = SymbolTable.NewScope(nil);
+ list := vector.New(0);
for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
- P.parseVarList(t.List, false);
- if P.tok == Scanner.STRING {
- // ParseOperand takes care of string concatenation
- t.List.Push(P.parseOperand());
- }
+ list.Push(P.parseFieldDecl());
if P.tok == Scanner.SEMICOLON {
P.next();
} else {
@@ -643,36 +712,36 @@ func (P *Parser) parseStructType() *AST.Type {
}
}
P.OptSemicolon();
- t.End = P.pos;
+ end = P.pos;
P.expect(Scanner.RBRACE);
+ P.opt_semi = true;
- // enter fields into struct scope
- for i, n := 0, t.List.Len(); i < n; i++ {
- if x, ok := t.List.At(i).(*AST.Ident); ok {
- P.declareInScope(t.Scope, x, SymbolTable.FIELD, nil);
- }
+ // convert vector
+ fields = make([]*AST.Field, list.Len());
+ for i := list.Len() - 1; i >= 0; i-- {
+ fields[i] = list.At(i).(*AST.Field);
}
}
- return t;
+ return AST.StructType(pos, fields, end);
}
-func (P *Parser) parsePointerType() *AST.Type {
+func (P *Parser) parsePointerType() AST.Expr {
if P.trace {
defer un(trace(P, "PointerType"));
}
- t := AST.NewType(P.pos, AST.POINTER);
+ pos := P.pos;
P.expect(Scanner.MUL);
- t.Elt = P.parseType();
+ base := P.parseType();
- return t;
+ return &AST.PointerType(pos, base);
}
-func (P *Parser) tryType() *AST.Type {
+func (P *Parser) tryType() AST.Expr {
if P.trace {
defer un(trace(P, "Type (try)"));
}
@@ -687,10 +756,11 @@ func (P *Parser) tryType() *AST.Type {
case Scanner.STRUCT: return P.parseStructType();
case Scanner.MUL: return P.parsePointerType();
case Scanner.LPAREN:
+ pos := P.pos;
P.next();
t := P.parseType();
P.expect(Scanner.RPAREN);
- return t;
+ return &AST.Group(pos, t);
}
// no type found
@@ -725,7 +795,7 @@ func (P *Parser) parseStatementList(list *vector.Vector) {
}
-func (P *Parser) parseBlock(ftyp *AST.Type, tok int) *AST.Block {
+func (P *Parser) parseBlock(tok int) *AST.Block {
if P.trace {
defer un(trace(P, "Block"));
}
@@ -733,6 +803,7 @@ func (P *Parser) parseBlock(ftyp *AST.Type, tok int) *AST.Block {
b := AST.NewBlock(P.pos, tok);
P.expect(tok);
+ /*
P.openScope();
// enter recv and parameters into function scope
if ftyp != nil {
@@ -747,9 +818,13 @@ func (P *Parser) parseBlock(ftyp *AST.Type, tok int) *AST.Block {
}
}
}
-
+ */
+
P.parseStatementList(b.List);
+
+ /*
P.closeScope();
+ */
if tok == Scanner.LBRACE {
b.End = P.pos;
@@ -795,7 +870,7 @@ func (P *Parser) parseFunctionLit() AST.Expr {
P.expect(Scanner.FUNC);
typ := P.parseSignature();
P.scope_lev++;
- body := P.parseBlock(typ, Scanner.LBRACE);
+ body := P.parseBlock(Scanner.LBRACE);
P.scope_lev--;
return &AST.FunctionLit(pos, typ, body);
@@ -812,10 +887,11 @@ func (P *Parser) parseOperand() AST.Expr {
return P.parseIdent(P.top_scope);
case Scanner.LPAREN:
+ pos := P.pos;
P.next();
x := P.parseExpression(1);
P.expect(Scanner.RPAREN);
- return x;
+ return &AST.Group(pos, x);
case Scanner.INT, Scanner.FLOAT, Scanner.STRING:
x := &AST.BasicLit(P.pos, P.tok, P.val);
@@ -835,7 +911,7 @@ func (P *Parser) parseOperand() AST.Expr {
default:
t := P.tryType();
if t != nil {
- return &AST.TypeLit(t);
+ return t;
} else {
P.error(P.pos, "operand expected");
P.next(); // make progress
@@ -978,6 +1054,8 @@ func (P *Parser) parseUnaryExpr() AST.Expr {
pos, tok := P.pos, P.tok;
P.next();
y := P.parseUnaryExpr();
+ return &AST.UnaryExpr(pos, tok, y);
+ /*
if lit, ok := y.(*AST.TypeLit); ok && tok == Scanner.MUL {
// pointer type
t := AST.NewType(pos, AST.POINTER);
@@ -986,6 +1064,7 @@ func (P *Parser) parseUnaryExpr() AST.Expr {
} else {
return &AST.UnaryExpr(pos, tok, y);
}
+ */
}
return P.parsePrimaryExpr();
@@ -1180,7 +1259,7 @@ func (P *Parser) parseIfStat() *AST.IfStat {
pos := P.pos;
P.expect(Scanner.IF);
init, cond, dummy := P.parseControlClause(false);
- body := P.parseBlock(nil, Scanner.LBRACE);
+ body := P.parseBlock(Scanner.LBRACE);
var else_ AST.Stat;
if P.tok == Scanner.ELSE {
P.next();
@@ -1211,7 +1290,7 @@ func (P *Parser) parseForStat() *AST.ForStat {
pos := P.pos;
P.expect(Scanner.FOR);
init, cond, post := P.parseControlClause(true);
- body := P.parseBlock(nil, Scanner.LBRACE);
+ body := P.parseBlock(Scanner.LBRACE);
P.closeScope();
return &AST.ForStat(pos, init, cond, post, body);
@@ -1233,7 +1312,7 @@ func (P *Parser) parseCaseClause() *AST.CaseClause {
P.expect(Scanner.DEFAULT);
}
- return &AST.CaseClause(pos, expr, P.parseBlock(nil, Scanner.COLON));
+ return &AST.CaseClause(pos, expr, P.parseBlock(Scanner.COLON));
}
@@ -1286,7 +1365,7 @@ func (P *Parser) parseCommClause() *AST.CaseClause {
P.expect(Scanner.DEFAULT);
}
- return &AST.CaseClause(pos, expr, P.parseBlock(nil, Scanner.COLON));
+ return &AST.CaseClause(pos, expr, P.parseBlock(Scanner.COLON));
}
@@ -1337,7 +1416,7 @@ func (P *Parser) parseStatement() AST.Stat {
case Scanner.BREAK, Scanner.CONTINUE, Scanner.GOTO, Scanner.FALLTHROUGH:
return P.parseControlFlowStat(P.tok);
case Scanner.LBRACE:
- return &AST.CompositeStat(P.parseBlock(nil, Scanner.LBRACE));
+ return &AST.CompositeStat(P.parseBlock(Scanner.LBRACE));
case Scanner.IF:
return P.parseIfStat();
case Scanner.FOR:
@@ -1360,90 +1439,105 @@ func (P *Parser) parseStatement() AST.Stat {
// ----------------------------------------------------------------------------
// Declarations
-func (P *Parser) parseImportSpec(d *AST.Decl) {
+func (P *Parser) parseImportSpec(pos int) *AST.ImportDecl {
if P.trace {
defer un(trace(P, "ImportSpec"));
}
+ var ident *AST.Ident;
if P.tok == Scanner.PERIOD {
P.error(P.pos, `"import ." not yet handled properly`);
P.next();
} else if P.tok == Scanner.IDENT {
- d.Ident = P.parseIdent(nil);
+ ident = P.parseIdent(nil);
}
+ var path AST.Expr;
if P.tok == Scanner.STRING {
// TODO eventually the scanner should strip the quotes
- d.Val = &AST.BasicLit(P.pos, Scanner.STRING, P.val);
+ path = &AST.BasicLit(P.pos, Scanner.STRING, P.val);
P.next();
} else {
P.expect(Scanner.STRING); // use expect() error handling
}
+
+ return &AST.ImportDecl(pos, ident, path);
}
-func (P *Parser) parseConstSpec(d *AST.Decl) {
+func (P *Parser) parseConstSpec(pos int) *AST.ConstDecl {
if P.trace {
defer un(trace(P, "ConstSpec"));
}
- d.Ident = P.parseIdentList(nil);
- d.Typ = P.tryType();
+ idents := P.parseIdentList2(nil);
+ typ := P.tryType();
+ var vals AST.Expr;
if P.tok == Scanner.ASSIGN {
P.next();
- d.Val = P.parseExpressionList();
+ vals = P.parseExpressionList();
}
+
+ return &AST.ConstDecl(pos, idents, typ, vals);
}
-func (P *Parser) parseTypeSpec(d *AST.Decl) {
+func (P *Parser) parseTypeSpec(pos int) *AST.TypeDecl {
if P.trace {
defer un(trace(P, "TypeSpec"));
}
- d.Ident = P.parseIdent(nil);
- d.Typ = P.parseType();
- P.opt_semi = true;
+ ident := P.parseIdent(nil);
+ typ := P.parseType();
+
+ return &AST.TypeDecl(pos, ident, typ);
}
-func (P *Parser) parseVarSpec(d *AST.Decl) {
+func (P *Parser) parseVarSpec(pos int) *AST.VarDecl {
if P.trace {
defer un(trace(P, "VarSpec"));
}
- d.Ident = P.parseIdentList(nil);
+ idents := P.parseIdentList2(nil);
+ var typ AST.Expr;
+ var vals AST.Expr;
if P.tok == Scanner.ASSIGN {
P.next();
- d.Val = P.parseExpressionList();
+ vals = P.parseExpressionList();
} else {
- d.Typ = P.parseVarType();
+ typ = P.parseVarType();
if P.tok == Scanner.ASSIGN {
P.next();
- d.Val = P.parseExpressionList();
+ vals = P.parseExpressionList();
}
}
+
+ return &AST.VarDecl(pos, idents, typ, vals);
}
-func (P *Parser) parseSpec(d *AST.Decl) {
+func (P *Parser) parseSpec(pos, keyword int) AST.Decl {
kind := SymbolTable.NONE;
- switch d.Tok {
- case Scanner.IMPORT: P.parseImportSpec(d); kind = SymbolTable.PACKAGE;
- case Scanner.CONST: P.parseConstSpec(d); kind = SymbolTable.CONST;
- case Scanner.TYPE: P.parseTypeSpec(d); kind = SymbolTable.TYPE;
- case Scanner.VAR: P.parseVarSpec(d); kind = SymbolTable.VAR;
- default: unreachable();
+ switch keyword {
+ case Scanner.IMPORT: return P.parseImportSpec(pos);
+ case Scanner.CONST: return P.parseConstSpec(pos);
+ case Scanner.TYPE: return P.parseTypeSpec(pos);
+ case Scanner.VAR: return P.parseVarSpec(pos);
}
+
+ unreachable();
+ return nil;
+ /*
// semantic checks
if d.Tok == Scanner.IMPORT {
if d.Ident != nil {
- P.declare(d.Ident, kind, nil);
+ //P.declare(d.Ident, kind, nil);
}
} else {
- P.declare(d.Ident, kind, d.Typ);
+ //P.declare(d.Ident, kind, d.Typ);
if d.Val != nil {
// initialization/assignment
llen := AST.ExprLen(d.Ident);
@@ -1463,38 +1557,42 @@ func (P *Parser) parseSpec(d *AST.Decl) {
// TODO
}
}
+ */
}
-func (P *Parser) parseDecl(keyword int) *AST.Decl {
+func (P *Parser) parseDecl(keyword int) AST.Decl {
if P.trace {
defer un(trace(P, "Decl"));
}
- d := AST.NewDecl(P.pos, keyword);
+ pos := P.pos;
P.expect(keyword);
if P.tok == Scanner.LPAREN {
P.next();
- d.List = vector.New(0);
+ list := vector.New(0);
for P.tok != Scanner.RPAREN && P.tok != Scanner.EOF {
- d1 := AST.NewDecl(P.pos, keyword);
- P.parseSpec(d1);
- d.List.Push(d1);
+ list.Push(P.parseSpec(0, keyword));
if P.tok == Scanner.SEMICOLON {
P.next();
} else {
break;
}
}
- d.End = P.pos;
+ end := P.pos;
P.expect(Scanner.RPAREN);
P.opt_semi = true;
-
- } else {
- P.parseSpec(d);
+
+ // convert vector
+ decls := make([]AST.Decl, list.Len());
+ for i := 0; i < list.Len(); i++ {
+ decls[i] = list.At(i).(AST.Decl);
+ }
+
+ return &AST.DeclList(pos, keyword, decls, end);
}
- return d;
+ return P.parseSpec(pos, keyword);
}
@@ -1507,54 +1605,53 @@ func (P *Parser) parseDecl(keyword int) *AST.Decl {
// func (recv) ident (params) type
// func (recv) ident (params) (results)
-func (P *Parser) parseFunctionDecl() *AST.Decl {
+func (P *Parser) parseFunctionDecl() *AST.FuncDecl {
if P.trace {
defer un(trace(P, "FunctionDecl"));
}
- d := AST.NewDecl(P.pos, Scanner.FUNC);
+ pos := P.pos;
P.expect(Scanner.FUNC);
- var recv *AST.Type;
+ var recv *AST.Field;
if P.tok == Scanner.LPAREN {
pos := P.pos;
- recv = P.parseParameters(true);
- if recv.Nfields() != 1 {
+ tmp := P.parseParameters(true);
+ if len(tmp) == 1 {
+ recv = tmp[0];
+ } else {
P.error(pos, "must have exactly one receiver");
}
}
ident := P.parseIdent(nil);
- d.Ident = ident;
- d.Typ = P.parseSignature();
- d.Typ.Key = recv;
+ sig := P.parseSignature();
+ var body *AST.Block;
if P.tok == Scanner.LBRACE {
- d.Body = P.parseBlock(d.Typ, Scanner.LBRACE);
+ body = P.parseBlock(Scanner.LBRACE);
}
- return d;
+ return &AST.FuncDecl(pos, recv, ident, sig, body);
}
-func (P *Parser) parseDeclaration() *AST.Decl {
+func (P *Parser) parseDeclaration() AST.Decl {
if P.trace {
defer un(trace(P, "Declaration"));
}
- d := AST.BadDecl;
-
switch P.tok {
case Scanner.CONST, Scanner.TYPE, Scanner.VAR:
- d = P.parseDecl(P.tok);
+ return P.parseDecl(P.tok);
case Scanner.FUNC:
- d = P.parseFunctionDecl();
- default:
- P.error(P.pos, "declaration expected");
- P.next(); // make progress
+ return P.parseFunctionDecl();
}
-
- return d;
+
+ pos := P.pos;
+ P.error(pos, "declaration expected");
+ P.next(); // make progress
+ return &AST.BadDecl(pos);
}
@@ -1573,18 +1670,24 @@ func (P *Parser) ParseProgram() *AST.Program {
// package body
{ P.openScope();
- p.Decls = vector.New(0);
+ list := vector.New(0);
for P.tok == Scanner.IMPORT {
- p.Decls.Push(P.parseDecl(Scanner.IMPORT));
+ list.Push(P.parseDecl(Scanner.IMPORT));
P.OptSemicolon();
}
if !P.deps {
for P.tok != Scanner.EOF {
- p.Decls.Push(P.parseDeclaration());
+ list.Push(P.parseDeclaration());
P.OptSemicolon();
}
}
P.closeScope();
+
+ // convert list
+ p.Decls = make([]AST.Decl, list.Len());
+ for i := 0; i < list.Len(); i++ {
+ p.Decls[i] = list.At(i).(AST.Decl);
+ }
}
p.Comments = P.comments;
diff --git a/usr/gri/pretty/printer.go b/usr/gri/pretty/printer.go
index 64ce715a1..8f270216e 100644
--- a/usr/gri/pretty/printer.go
+++ b/usr/gri/pretty/printer.go
@@ -93,6 +93,7 @@ type Printer struct {
indentation int; // indentation level (may be different from scope level)
// formatting parameters
+ opt_semi bool; // // true if semicolon separator is optional in statement list
separator int; // pending separator
newlines int; // pending newlines
@@ -362,6 +363,7 @@ func (P *Printer) TaggedString(pos int, tag, s, endtag string) {
// --------------------------------
// done
+ P.opt_semi = false;
P.lastpos = pos + len(s); // rough estimate
}
@@ -422,15 +424,15 @@ func (P *Printer) HtmlIdentifier(x *AST.Ident) {
// depending on whether we have a declaration or use, generate different html
// - no need to htmlEscape ident
id := Utils.IntToString(obj.Id, 10);
- if x.Pos() == obj.Pos {
+ if x.Pos_ == obj.Pos {
// probably the declaration of x
- P.TaggedString(x.Pos(), `<a name="id` + id + `">`, obj.Ident, `</a>`);
+ P.TaggedString(x.Pos_, `<a name="id` + id + `">`, obj.Ident, `</a>`);
} else {
// probably not the declaration of x
- P.TaggedString(x.Pos(), `<a href="#id` + id + `">`, obj.Ident, `</a>`);
+ P.TaggedString(x.Pos_, `<a href="#id` + id + `">`, obj.Ident, `</a>`);
}
} else {
- P.String(x.Pos(), obj.Ident);
+ P.String(x.Pos_, obj.Ident);
}
}
@@ -447,167 +449,106 @@ func (P *Printer) HtmlPackageName(pos int, name string) {
// ----------------------------------------------------------------------------
-// Types
+// Support
-func (P *Printer) Type(t *AST.Type) int
func (P *Printer) Expr(x AST.Expr)
-func (P *Printer) Parameters(pos int, list *vector.Vector) {
- P.String(pos, "(");
- if list != nil {
- var prev int;
- for i, n := 0, list.Len(); i < n; i++ {
- x := list.At(i).(AST.Expr);
- tok := Scanner.TYPE;
- if dummy, is_ident := x.(*AST.Ident); is_ident {
- tok = Scanner.IDENT;
- }
+func (P *Printer) Idents(list []*AST.Ident) {
+ for i, x := range list {
+ if i > 0 {
+ P.Token(0, Scanner.COMMA);
+ P.separator = blank;
+ P.state = inside_list;
+ }
+ P.Expr(x);
+ }
+}
+
+
+func (P *Printer) Parameters(list []*AST.Field) {
+ P.Token(0, Scanner.LPAREN);
+ if len(list) > 0 {
+ for i, par := range list {
if i > 0 {
- if prev == tok || prev == Scanner.TYPE {
- P.separator = comma;
- } else {
- P.separator = blank;
- }
+ P.separator = comma;
}
- P.Expr(x);
- prev = tok;
+ if len(par.Idents) > 0 {
+ P.Idents(par.Idents);
+ P.separator = blank
+ };
+ P.Expr(par.Typ);
}
}
- P.String(0, ")");
+ P.Token(0, Scanner.RPAREN);
}
// Returns the separator (semicolon or none) required if
// the type is terminating a declaration or statement.
-func (P *Printer) Signature(t *AST.Type) int {
- assert(t.Form == AST.FUNCTION);
- separator := none;
- P.Parameters(t.Pos, t.List);
- if t.Elt != nil {
+func (P *Printer) Signature(sig *AST.Signature) {
+ P.Parameters(sig.Params);
+ if sig.Result != nil {
P.separator = blank;
- list := t.Elt.List;
- dummy, is_type := list.At(0).(*AST.TypeLit);
- if list.Len() > 1 || is_type && dummy.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
- separator = P.Type(list.At(0).(*AST.TypeLit).Typ);
+
+ if len(sig.Result) == 1 && sig.Result[0].Idents == nil {
+ // single anonymous result
+ // => no parentheses needed unless it's a function type
+ fld := sig.Result[0];
+ if dummy, is_ftyp := fld.Typ.(*AST.FunctionType); !is_ftyp {
+ P.Expr(fld.Typ);
+ return;
+ }
}
+
+ P.Parameters(sig.Result);
}
- return separator;
}
-func (P *Printer) Fields(list *vector.Vector, end int, in_interface bool) {
+func (P *Printer) Fields(list []*AST.Field, end int, is_interface bool) {
P.state = opening_scope;
- P.String(0, "{");
+ P.separator = blank;
+ P.Token(0, Scanner.LBRACE);
- if list.Len() > 0 {
+ if len(list) > 0 {
P.newlines = 1;
- var prev int;
- for i, n := 0, list.Len(); i < n; i++ {
- x := list.At(i).(AST.Expr);
- tok := Scanner.TYPE;
- if dummy, is_ident := x.(*AST.Ident); is_ident {
- tok = Scanner.IDENT;
- } else if dummy, is_lit := x.(*AST.BasicLit); is_lit && dummy.Tok == Scanner.STRING {
- tok = Scanner.STRING;
- }
+ for i, fld := range list {
if i > 0 {
- if prev == Scanner.TYPE && tok != Scanner.STRING || prev == Scanner.STRING {
- P.separator = semicolon;
- P.newlines = 1;
- } else if prev == tok {
- P.separator = comma;
+ P.separator = semicolon;
+ P.newlines = 1;
+ }
+ if len(fld.Idents) > 0 {
+ P.Idents(fld.Idents);
+ P.separator = tab
+ };
+ if is_interface {
+ if ftyp, is_ftyp := fld.Typ.(*AST.FunctionType); is_ftyp {
+ P.Signature(ftyp.Sig);
} else {
- P.separator = tab;
+ P.Expr(fld.Typ);
}
- }
- if in_interface && tok == Scanner.TYPE {
- P.Signature(x.(*AST.TypeLit).Typ);
} else {
- P.Expr(x);
+ P.Expr(fld.Typ);
+ if fld.Tag != nil {
+ P.separator = tab;
+ P.Expr(fld.Tag);
+ }
}
- prev = tok;
}
P.newlines = 1;
}
P.state = closing_scope;
- P.String(end, "}");
-}
-
-
-// Returns the separator (semicolon or none) required if
-// the type is terminating a declaration or statement.
-func (P *Printer) Type(t *AST.Type) int {
- separator := semicolon;
-
- switch t.Form {
- case AST.TYPENAME:
- P.Expr(t.Expr);
-
- case AST.ARRAY:
- P.String(t.Pos, "[");
- if t.Expr != nil {
- P.Expr(t.Expr);
- }
- P.String(0, "]");
- separator = P.Type(t.Elt);
-
- case AST.STRUCT, AST.INTERFACE:
- switch t.Form {
- case AST.STRUCT: P.String(t.Pos, "struct");
- case AST.INTERFACE: P.String(t.Pos, "interface");
- }
- if t.List != nil {
- P.separator = blank;
- P.Fields(t.List, t.End, t.Form == AST.INTERFACE);
- }
- separator = none;
-
- case AST.MAP:
- P.String(t.Pos, "map [");
- P.Type(t.Key);
- P.String(0, "]");
- separator = P.Type(t.Elt);
-
- case AST.CHANNEL:
- var m string;
- switch t.Mode {
- case AST.FULL: m = "chan ";
- case AST.RECV: m = "<-chan ";
- case AST.SEND: m = "chan <- ";
- }
- P.String(t.Pos, m);
- separator = P.Type(t.Elt);
-
- case AST.POINTER:
- P.String(t.Pos, "*");
- separator = P.Type(t.Elt);
-
- case AST.FUNCTION:
- P.Token(0, Scanner.FUNC);
- separator = P.Signature(t);
-
- case AST.ELLIPSIS:
- P.String(t.Pos, "...");
-
- default:
- P.Error(t.Pos, t.Form, "type");
- }
-
- return separator;
+ P.Token(end, Scanner.RBRACE);
+ P.opt_semi = true;
}
// ----------------------------------------------------------------------------
// Expressions
-func (P *Printer) Block(b *AST.Block, indent bool);
-func (P *Printer) Expr1(x AST.Expr, prec1 int);
+func (P *Printer) Block(b *AST.Block, indent bool)
+func (P *Printer) Expr1(x AST.Expr, prec1 int)
func (P *Printer) DoBadExpr(x *AST.BadExpr) {
@@ -624,22 +565,22 @@ func (P *Printer) DoBinaryExpr(x *AST.BinaryExpr) {
if x.Tok == Scanner.COMMA {
// (don't use binary expression printing because of different spacing)
P.Expr(x.X);
- P.String(x.Pos(), ",");
+ P.Token(x.Pos_, Scanner.COMMA);
P.separator = blank;
P.state = inside_list;
P.Expr(x.Y);
} else {
prec := Scanner.Precedence(x.Tok);
if prec < P.prec {
- P.String(0, "(");
+ P.Token(0, Scanner.LPAREN);
}
P.Expr1(x.X, prec);
P.separator = blank;
- P.Token(x.Pos(), x.Tok);
+ P.Token(x.Pos_, x.Tok);
P.separator = blank;
P.Expr1(x.Y, prec);
if prec < P.prec {
- P.String(0, ")");
+ P.Token(0, Scanner.RPAREN);
}
}
}
@@ -648,31 +589,26 @@ func (P *Printer) DoBinaryExpr(x *AST.BinaryExpr) {
func (P *Printer) DoUnaryExpr(x *AST.UnaryExpr) {
prec := Scanner.UnaryPrec;
if prec < P.prec {
- P.String(0, "(");
+ P.Token(0, Scanner.LPAREN);
}
- P.Token(x.Pos(), x.Tok);
+ P.Token(x.Pos_, x.Tok);
if x.Tok == Scanner.RANGE {
P.separator = blank;
}
P.Expr1(x.X, prec);
if prec < P.prec {
- P.String(0, ")");
+ P.Token(0, Scanner.RPAREN);
}
}
func (P *Printer) DoBasicLit(x *AST.BasicLit) {
- P.String(x.Pos(), x.Val);
-}
-
-
-func (P *Printer) DoTypeLit(x *AST.TypeLit) {
- P.Type(x.Typ);
+ P.String(x.Pos_, x.Val);
}
func (P *Printer) DoFunctionLit(x *AST.FunctionLit) {
- P.String(x.Pos(), "func");
+ P.Token(x.Pos_, Scanner.FUNC);
P.Signature(x.Typ);
P.separator = blank;
P.Block(x.Body, true);
@@ -680,35 +616,117 @@ func (P *Printer) DoFunctionLit(x *AST.FunctionLit) {
}
+func (P *Printer) DoGroup(x *AST.Group) {
+ P.Token(x.Pos_, Scanner.LPAREN);
+ P.Expr(x.X);
+ P.Token(0, Scanner.RPAREN);
+}
+
+
func (P *Printer) DoSelector(x *AST.Selector) {
P.Expr1(x.X, Scanner.HighestPrec);
- P.String(x.Pos(), ".");
+ P.Token(x.Pos_, Scanner.PERIOD);
P.Expr1(x.Sel, Scanner.HighestPrec);
}
func (P *Printer) DoTypeGuard(x *AST.TypeGuard) {
P.Expr1(x.X, Scanner.HighestPrec);
- P.String(x.Pos(), ".");
- P.String(0, "(");
- P.Type(x.Typ);
- P.String(0, ")");
+ P.Token(x.Pos_, Scanner.PERIOD);
+ P.Token(0, Scanner.LPAREN);
+ P.Expr(x.Typ);
+ P.Token(0, Scanner.RPAREN);
}
func (P *Printer) DoIndex(x *AST.Index) {
P.Expr1(x.X, Scanner.HighestPrec);
- P.String(x.Pos(), "[");
+ P.Token(x.Pos_, Scanner.LBRACK);
P.Expr1(x.I, 0);
- P.String(0, "]");
+ P.Token(0, Scanner.RBRACK);
}
func (P *Printer) DoCall(x *AST.Call) {
P.Expr1(x.F, Scanner.HighestPrec);
- P.String(x.Pos(), "(");
+ P.Token(x.Pos_, Scanner.LPAREN);
P.Expr(x.Args);
- P.String(0, ")");
+ P.Token(0, Scanner.RPAREN);
+}
+
+
+func (P *Printer) DoEllipsis(x *AST.Ellipsis) {
+ P.Token(x.Pos_, Scanner.ELLIPSIS);
+}
+
+
+func (P *Printer) DoArrayType(x *AST.ArrayType) {
+ P.Token(x.Pos_, Scanner.LBRACK);
+ if x.Len != nil {
+ P.Expr(x.Len);
+ }
+ P.Token(0, Scanner.RBRACK);
+ P.Expr(x.Elt);
+}
+
+
+func (P *Printer) DoStructType(x *AST.StructType) {
+ P.Token(x.Pos_, Scanner.STRUCT);
+ if x.End > 0 {
+ P.Fields(x.Fields, x.End, false);
+ }
+}
+
+
+func (P *Printer) DoPointerType(x *AST.PointerType) {
+ P.Token(x.Pos_, Scanner.MUL);
+ P.Expr(x.Base);
+}
+
+
+func (P *Printer) DoFunctionType(x *AST.FunctionType) {
+ P.Token(x.Pos_, Scanner.FUNC);
+ P.Signature(x.Sig);
+}
+
+
+func (P *Printer) DoInterfaceType(x *AST.InterfaceType) {
+ P.Token(x.Pos_, Scanner.INTERFACE);
+ if x.End > 0 {
+ P.Fields(x.Methods, x.End, true);
+ }
+}
+
+
+func (P *Printer) DoSliceType(x *AST.SliceType) {
+ unimplemented();
+}
+
+
+func (P *Printer) DoMapType(x *AST.MapType) {
+ P.Token(x.Pos_, Scanner.MAP);
+ P.separator = blank;
+ P.Token(0, Scanner.LBRACK);
+ P.Expr(x.Key);
+ P.Token(0, Scanner.RBRACK);
+ P.Expr(x.Val);
+}
+
+
+func (P *Printer) DoChannelType(x *AST.ChannelType) {
+ switch x.Mode {
+ case AST.FULL:
+ P.Token(x.Pos_, Scanner.CHAN);
+ case AST.RECV:
+ P.Token(x.Pos_, Scanner.ARROW);
+ P.Token(0, Scanner.CHAN);
+ case AST.SEND:
+ P.Token(x.Pos_, Scanner.CHAN);
+ P.separator = blank;
+ P.Token(0, Scanner.ARROW);
+ }
+ P.separator = blank;
+ P.Expr(x.Val);
}
@@ -738,9 +756,16 @@ func (P *Printer) Stat(s AST.Stat) {
func (P *Printer) StatementList(list *vector.Vector) {
- for i, n := 0, list.Len(); i < n; i++ {
- P.newlines = 1; // for first entry
- list.At(i).(AST.Stat).Visit(P);
+ for i := 0; i < list.Len(); i++ {
+ if i == 0 {
+ P.newlines = 1;
+ } else { // i > 0
+ if !P.opt_semi {
+ // semicolon is required
+ P.separator = semicolon;
+ }
+ }
+ P.Stat(list.At(i).(AST.Stat));
P.newlines = 1;
P.state = inside_list;
}
@@ -762,15 +787,15 @@ func (P *Printer) Block(b *AST.Block, indent bool) {
}
P.state = closing_scope;
if b.Tok == Scanner.LBRACE {
- P.String(b.End, "}");
+ P.Token(b.End, Scanner.RBRACE);
+ P.opt_semi = true;
} else {
P.String(0, ""); // process closing_scope state transition!
}
}
-func (P *Printer) Declaration(d *AST.Decl, parenthesized bool);
-
+func (P *Printer) Decl(d AST.Decl);
func (P *Printer) DoBadStat(s *AST.BadStat) {
panic();
@@ -780,14 +805,13 @@ func (P *Printer) DoBadStat(s *AST.BadStat) {
func (P *Printer) DoLabelDecl(s *AST.LabelDecl) {
P.indentation--;
P.Expr(s.Label);
- P.String(s.Pos, ":");
+ P.Token(s.Pos, Scanner.COLON);
P.indentation++;
- P.separator = none;
}
func (P *Printer) DoDeclarationStat(s *AST.DeclarationStat) {
- P.Declaration(s.Decl, false);
+ P.Decl(s.Decl);
}
@@ -808,7 +832,6 @@ func (P *Printer) DoExpressionStat(s *AST.ExpressionStat) {
P.Error(s.Pos, s.Tok, "DoExpressionStat");
unreachable();
}
- P.separator = semicolon;
}
@@ -831,14 +854,14 @@ func (P *Printer) ControlClause(isForStat bool, init AST.Stat, expr AST.Expr, po
P.Stat(init);
P.separator = none;
}
- P.String(0, ";");
+ P.Token(0, Scanner.SEMICOLON);
P.separator = blank;
if expr != nil {
P.Expr(expr);
P.separator = none;
}
if isForStat {
- P.String(0, ";");
+ P.Token(0, Scanner.SEMICOLON);
P.separator = blank;
if post != nil {
P.Stat(post);
@@ -879,7 +902,7 @@ func (P *Printer) DoCaseClause(s *AST.CaseClause) {
}
// TODO: try to use P.Block instead
// P.Block(s.Body, true);
- P.String(s.Body.Pos, ":");
+ P.Token(s.Body.Pos, Scanner.COLON);
P.indentation++;
P.StatementList(s.Body.List);
P.indentation--;
@@ -907,114 +930,164 @@ func (P *Printer) DoControlFlowStat(s *AST.ControlFlowStat) {
P.separator = blank;
P.Expr(s.Label);
}
- P.separator = semicolon;
}
func (P *Printer) DoEmptyStat(s *AST.EmptyStat) {
P.String(s.Pos, "");
- P.separator = semicolon;
}
// ----------------------------------------------------------------------------
// Declarations
-func (P *Printer) Declaration(d *AST.Decl, parenthesized bool) {
- if !parenthesized {
- if !*def || d.Tok == Scanner.IMPORT || d.Tok == Scanner.VAR {
- P.Token(d.Pos, d.Tok);
- } else {
- P.String(d.Pos, "def");
- }
+func (P *Printer) DoBadDecl(d *AST.BadDecl) {
+ unimplemented();
+}
+
+
+func (P *Printer) DoImportDecl(d *AST.ImportDecl) {
+ if d.Pos > 0 {
+ P.Token(d.Pos, Scanner.IMPORT);
P.separator = blank;
}
+ if d.Ident != nil {
+ P.Expr(d.Ident);
+ } else {
+ P.String(d.Path.Pos(), ""); // flush pending ';' separator/newlines
+ }
+ P.separator = tab;
+ if lit, is_lit := d.Path.(*AST.BasicLit); is_lit && lit.Tok == Scanner.STRING {
+ P.HtmlPackageName(lit.Pos_, lit.Val);
+ } else {
+ // we should only reach here for strange imports
+ // import "foo" "bar"
+ P.Expr(d.Path);
+ }
+ P.newlines = 2;
+}
- if d.Tok != Scanner.FUNC && d.List != nil {
- // group of parenthesized declarations
- P.state = opening_scope;
- P.String(0, "(");
- if d.List.Len() > 0 {
- P.newlines = 1;
- for i := 0; i < d.List.Len(); i++ {
- P.Declaration(d.List.At(i).(*AST.Decl), true);
- P.separator = semicolon;
- P.newlines = 1;
- }
+
+func (P *Printer) DoConstDecl(d *AST.ConstDecl) {
+ if d.Pos > 0 {
+ P.Token(d.Pos, Scanner.CONST);
+ P.separator = blank;
+ }
+ P.Idents(d.Idents);
+ if d.Typ != nil {
+ P.separator = blank; // TODO switch to tab? (indentation problem with structs)
+ P.Expr(d.Typ);
+ }
+ if d.Vals != nil {
+ P.separator = tab;
+ P.Token(0, Scanner.ASSIGN);
+ P.separator = blank;
+ P.Expr(d.Vals);
+ }
+ P.newlines = 2;
+}
+
+
+func (P *Printer) DoTypeDecl(d *AST.TypeDecl) {
+ if d.Pos > 0 {
+ P.Token(d.Pos, Scanner.TYPE);
+ P.separator = blank;
+ }
+ P.Expr(d.Ident);
+ P.separator = blank; // TODO switch to tab? (but indentation problem with structs)
+ P.Expr(d.Typ);
+ P.newlines = 2;
+}
+
+
+func (P *Printer) DoVarDecl(d *AST.VarDecl) {
+ if d.Pos > 0 {
+ P.Token(d.Pos, Scanner.VAR);
+ P.separator = blank;
+ }
+ P.Idents(d.Idents);
+ if d.Typ != nil {
+ P.separator = blank; // TODO switch to tab? (indentation problem with structs)
+ P.Expr(d.Typ);
+ //P.separator = P.Type(d.Typ);
+ }
+ if d.Vals != nil {
+ P.separator = tab;
+ P.Token(0, Scanner.ASSIGN);
+ P.separator = blank;
+ P.Expr(d.Vals);
+ }
+ P.newlines = 2;
+}
+
+
+func (P *Printer) DoFuncDecl(d *AST.FuncDecl) {
+ P.Token(d.Pos_, Scanner.FUNC);
+ P.separator = blank;
+ if recv := d.Recv; recv != nil {
+ // method: print receiver
+ P.Token(0, Scanner.LPAREN);
+ if len(recv.Idents) > 0 {
+ P.Expr(recv.Idents[0]);
+ P.separator = blank;
}
- P.state = closing_scope;
- P.String(d.End, ")");
+ P.Expr(recv.Typ);
+ P.Token(0, Scanner.RPAREN);
+ P.separator = blank;
+ }
+ P.Expr(d.Ident);
+ P.Signature(d.Sig);
+ if d.Body != nil {
+ P.separator = blank;
+ P.Block(d.Body, true);
+ }
+ P.newlines = 2;
+}
+
+func (P *Printer) DoDeclList(d *AST.DeclList) {
+ if !*def || d.Tok == Scanner.IMPORT || d.Tok == Scanner.VAR {
+ P.Token(d.Pos, d.Tok);
} else {
- // single declaration
- switch d.Tok {
- case Scanner.IMPORT:
- if d.Ident != nil {
- P.Expr(d.Ident);
- } else {
- P.String(d.Val.Pos(), ""); // flush pending ';' separator/newlines
- }
- P.separator = tab;
- if lit, is_lit := d.Val.(*AST.BasicLit); is_lit && lit.Tok == Scanner.STRING {
- P.HtmlPackageName(lit.Pos(), lit.Val);
- } else {
- // we should only reach here for strange imports
- // import "foo" "bar"
- P.Expr(d.Val);
- }
- P.separator = semicolon;
-
- 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);
-
- 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);
- }
- if d.Val != nil {
- P.separator = tab;
- P.String(0, "=");
- P.separator = blank;
- P.Expr(d.Val);
- }
- P.separator = semicolon;
+ P.String(d.Pos, "def");
+ }
+ P.separator = blank;
- case Scanner.FUNC:
- if d.Typ.Key != nil {
- // method: print receiver
- P.Parameters(0, d.Typ.Key.List);
- P.separator = blank;
- }
- P.Expr(d.Ident);
- P.separator = P.Signature(d.Typ);
- if d.Body != nil {
- P.separator = blank;
- P.Block(d.Body, true);
+ // group of parenthesized declarations
+ P.state = opening_scope;
+ P.Token(0, Scanner.LPAREN);
+ if len(d.List) > 0 {
+ P.newlines = 1;
+ for i := 0; i < len(d.List); i++ {
+ if i > 0 {
+ P.separator = semicolon;
}
-
- default:
- P.Error(d.Pos, d.Tok, "decl");
+ P.Decl(d.List[i]);
+ P.newlines = 1;
}
}
-
+ P.state = closing_scope;
+ P.Token(d.End, Scanner.RPAREN);
+ P.opt_semi = true;
P.newlines = 2;
}
+func (P *Printer) Decl(d AST.Decl) {
+ d.Visit(P);
+}
+
+
// ----------------------------------------------------------------------------
// Program
func (P *Printer) Program(p *AST.Program) {
- P.String(p.Pos, "package");
+ P.Token(p.Pos, Scanner.PACKAGE);
P.separator = blank;
P.Expr(p.Ident);
P.newlines = 1;
- for i := 0; i < p.Decls.Len(); i++ {
- P.Declaration(p.Decls.At(i).(*AST.Decl), false);
+ for i := 0; i < len(p.Decls); i++ {
+ P.Decl(p.Decls[i]);
}
P.newlines = 1;
}
diff --git a/usr/gri/pretty/selftest1.go b/usr/gri/pretty/selftest1.go
index dff19ca53..d3597d26c 100644
--- a/usr/gri/pretty/selftest1.go
+++ b/usr/gri/pretty/selftest1.go
@@ -10,7 +10,7 @@ import P2 /* ERROR expected */ 42 /* SYNC */
type S0 struct {
- f0, f1, f2;
+ f0, f1, f2 int;
}
diff --git a/usr/gri/pretty/test.sh b/usr/gri/pretty/test.sh
index 565e869af..d288e20fb 100755
--- a/usr/gri/pretty/test.sh
+++ b/usr/gri/pretty/test.sh
@@ -26,7 +26,7 @@ apply1() {
case `basename $F` in
# files with errors (skip them)
# the following have semantic errors: bug039.go | bug040.go
- method1.go | selftest1.go | func3.go | \
+ calc.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 | bug121.go | bug125.go | bug126.go | bug132.go | bug133.go | bug134.go ) ;;
* ) $1 $2; count $F;;
@@ -43,18 +43,9 @@ applydot() {
}
-# apply to all files in the list
+# apply to all .go files we can find
apply() {
- for F in \
- $GOROOT/usr/gri/pretty/*.go \
- $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
- do
+ for F in `find $GOROOT -name "*.go" | grep -v "OLD"`; do
apply1 $1 $F
done
}
diff --git a/usr/gri/pretty/typechecker.go b/usr/gri/pretty/typechecker.go
index e8e04b32b..a35a5b351 100644
--- a/usr/gri/pretty/typechecker.go
+++ b/usr/gri/pretty/typechecker.go
@@ -52,6 +52,7 @@ func (s *state) CheckType() {
}
+/*
func (s *state) CheckDeclaration(d *AST.Decl) {
if d.Tok != Scanner.FUNC && d.List != nil {
// group of parenthesized declarations
@@ -72,11 +73,12 @@ func (s *state) CheckDeclaration(d *AST.Decl) {
}
}
}
+*/
func (s *state) CheckProgram(p *AST.Program) {
- for i := 0; i < p.Decls.Len(); i++ {
- s.CheckDeclaration(p.Decls.At(i).(*AST.Decl));
+ for i := 0; i < len(p.Decls); i++ {
+ //s.CheckDeclaration(p.Decls[i].(*AST.Decl));
}
}