Commit 3689e221 authored by Robert Griesemer's avatar Robert Griesemer

Steps towards a general scanner/parser library for Go:

- converted more of AST and parser to use interfaces and explicit
structs for individual Go constructs (can be replaced now with
interface calls such that the parser becomes AST structure
independent, as suggested by rsc)
- added more tests (find all .go files under GOROOT)
- (temporarily) lost html links for identifiers when generating
html output
- TODO: lots of cleanups

R=r
OCL=25518
CL=25518
parent df3183f5
...@@ -14,7 +14,7 @@ import ( ...@@ -14,7 +14,7 @@ import (
type ( type (
Block struct; Block struct;
Expr interface; Expr interface;
Decl struct; Decl interface;
) )
...@@ -38,41 +38,7 @@ type Node struct { ...@@ -38,41 +38,7 @@ type Node struct {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Types // Expressions
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>";
}
const /* channel mode */ ( const /* channel mode */ (
FULL = iota; FULL = iota;
...@@ -81,62 +47,15 @@ const /* channel mode */ ( ...@@ -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 ( type (
ExprVisitor interface; ExprVisitor interface;
Signature struct;
Expr interface { Expr interface {
Pos() int; Pos() int;
Visit(v ExprVisitor); Visit(v ExprVisitor);
}; };
BadExpr struct { BadExpr struct {
Pos_ int; Pos_ int;
}; };
...@@ -147,28 +66,32 @@ type ( ...@@ -147,28 +66,32 @@ type (
}; };
BinaryExpr struct { BinaryExpr struct {
Pos_, Tok int; Pos_ int;
Tok int;
X, Y Expr; X, Y Expr;
}; };
UnaryExpr struct { UnaryExpr struct {
Pos_, Tok int; Pos_ int;
Tok int;
X Expr; X Expr;
}; };
BasicLit struct { BasicLit struct {
Pos_, Tok int; Pos_ int;
Tok int;
Val string Val string
}; };
FunctionLit struct { FunctionLit struct {
Pos_ int; // position of "func" Pos_ int; // position of "func"
Typ *Type; Typ *Signature;
Body *Block; Body *Block;
}; };
TypeLit struct { Group struct {
Typ *Type; Pos_ int; // position of "("
X Expr;
}; };
Selector struct { Selector struct {
...@@ -180,7 +103,7 @@ type ( ...@@ -180,7 +103,7 @@ type (
TypeGuard struct { TypeGuard struct {
Pos_ int; // position of "." Pos_ int; // position of "."
X Expr; X Expr;
Typ *Type; Typ Expr;
}; };
Index struct { Index struct {
...@@ -192,6 +115,66 @@ type ( ...@@ -192,6 +115,66 @@ type (
Pos_ int; // position of "(" Pos_ int; // position of "("
F, Args Expr 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 { ...@@ -202,26 +185,47 @@ type ExprVisitor interface {
DoUnaryExpr(x *UnaryExpr); DoUnaryExpr(x *UnaryExpr);
DoBasicLit(x *BasicLit); DoBasicLit(x *BasicLit);
DoFunctionLit(x *FunctionLit); DoFunctionLit(x *FunctionLit);
DoTypeLit(x *TypeLit); DoGroup(x *Group);
DoSelector(x *Selector); DoSelector(x *Selector);
DoTypeGuard(x *TypeGuard); DoTypeGuard(x *TypeGuard);
DoIndex(x *Index); DoIndex(x *Index);
DoCall(x *Call); 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 *BadExpr) Pos() int { return x.Pos_; }
func (x *Ident) Pos() int { return x.Pos_; } func (x *Ident) Pos() int { return x.Pos_; }
func (x *BinaryExpr) Pos() int { return x.Pos_; } func (x *BinaryExpr) Pos() int { return x.Pos_; }
func (x *UnaryExpr) Pos() int { return x.Pos_; } func (x *UnaryExpr) Pos() int { return x.Pos_; }
func (x *BasicLit) Pos() int { return x.Pos_; } func (x *BasicLit) Pos() int { return x.Pos_; }
func (x *FunctionLit) 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 *Selector) Pos() int { return x.Pos_; }
func (x *TypeGuard) Pos() int { return x.Pos_; } func (x *TypeGuard) Pos() int { return x.Pos_; }
func (x *Index) Pos() int { return x.Pos_; } func (x *Index) Pos() int { return x.Pos_; }
func (x *Call) 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 *BadExpr) Visit(v ExprVisitor) { v.DoBadExpr(x); }
func (x *Ident) Visit(v ExprVisitor) { v.DoIdent(x); } func (x *Ident) Visit(v ExprVisitor) { v.DoIdent(x); }
...@@ -229,12 +233,22 @@ func (x *BinaryExpr) Visit(v ExprVisitor) { v.DoBinaryExpr(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 *UnaryExpr) Visit(v ExprVisitor) { v.DoUnaryExpr(x); }
func (x *BasicLit) Visit(v ExprVisitor) { v.DoBasicLit(x); } func (x *BasicLit) Visit(v ExprVisitor) { v.DoBasicLit(x); }
func (x *FunctionLit) Visit(v ExprVisitor) { v.DoFunctionLit(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 *Selector) Visit(v ExprVisitor) { v.DoSelector(x); }
func (x *TypeGuard) Visit(v ExprVisitor) { v.DoTypeGuard(x); } func (x *TypeGuard) Visit(v ExprVisitor) { v.DoTypeGuard(x); }
func (x *Index) Visit(v ExprVisitor) { v.DoIndex(x); } func (x *Index) Visit(v ExprVisitor) { v.DoIndex(x); }
func (x *Call) Visit(v ExprVisitor) { v.DoCall(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. // Length of a comma-separated expression list.
...@@ -267,25 +281,6 @@ func ExprAt(x Expr, i int) Expr { ...@@ -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 // Blocks
// //
...@@ -329,7 +324,7 @@ type ( ...@@ -329,7 +324,7 @@ type (
}; };
DeclarationStat struct { DeclarationStat struct {
Decl *Decl; Decl Decl;
}; };
ExpressionStat struct { ExpressionStat struct {
...@@ -421,25 +416,79 @@ func (s *EmptyStat) Visit(v StatVisitor) { v.DoEmptyStat(s); } ...@@ -421,25 +416,79 @@ func (s *EmptyStat) Visit(v StatVisitor) { v.DoEmptyStat(s); }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Declarations // Declarations
type Decl struct { type (
Node; DeclVisitor interface;
Ident Expr; // nil for ()-style declarations
Typ *Type; Decl interface {
Val Expr; Visit(v DeclVisitor);
Body *Block; };
// list of *Decl for ()-style declarations
List *vector.Vector; End int; 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 { type DeclVisitor interface {
d := new(Decl); DoBadDecl(d *BadDecl);
d.Pos, d.Tok = pos, tok; DoImportDecl(d *ImportDecl);
return d; 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 { ...@@ -461,7 +510,7 @@ func NewComment(pos int, text string) *Comment {
type Program struct { type Program struct {
Pos int; // tok is Scanner.PACKAGE Pos int; // tok is Scanner.PACKAGE
Ident Expr; Ident Expr;
Decls *vector.Vector; Decls []Decl;
Comments *vector.Vector; Comments *vector.Vector;
} }
......
...@@ -150,7 +150,8 @@ func fileExists(name string) bool { ...@@ -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 := decl.Val.(*AST.BasicLit).Val;
src = src[1 : len(src) - 1]; // strip "'s src = src[1 : len(src) - 1]; // strip "'s
...@@ -171,6 +172,7 @@ func printDep(localset map [string] bool, wset *vector.Vector, decl *AST.Decl) { ...@@ -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) { 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, ...@@ -183,13 +185,15 @@ func addDeps(globalset map [string] bool, wset *vector.Vector, src_file string,
return; return;
} }
nimports := prog.Decls.Len(); nimports := len(prog.Decls);
if nimports > 0 { if nimports > 0 {
fmt.Printf("%s.6:\t", src_file); fmt.Printf("%s.6:\t", src_file);
localset := make(map [string] bool); localset := make(map [string] bool);
for i := 0; i < nimports; i++ { for i := 0; i < nimports; i++ {
decl := prog.Decls.At(i).(*AST.Decl); decl := prog.Decls[i];
panic();
/*
assert(decl.Tok == Scanner.IMPORT); assert(decl.Tok == Scanner.IMPORT);
if decl.List == nil { if decl.List == nil {
printDep(localset, wset, decl); printDep(localset, wset, decl);
...@@ -198,6 +202,7 @@ func addDeps(globalset map [string] bool, wset *vector.Vector, src_file string, ...@@ -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)); printDep(localset, wset, decl.List.At(j).(*AST.Decl));
} }
} }
*/
} }
print("\n\n"); print("\n\n");
} }
......
...@@ -29,7 +29,7 @@ type Parser struct { ...@@ -29,7 +29,7 @@ type Parser struct {
val string; // token value (for IDENT, NUMBER, STRING only) val string; // token value (for IDENT, NUMBER, STRING only)
// Non-syntactic parser control // 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 // Nesting levels
scope_lev int; // 0 = global scope, 1 = function scope of global functions, etc. scope_lev int; // 0 = global scope, 1 = function scope of global functions, etc.
...@@ -170,6 +170,7 @@ func (P *Parser) closeScope() { ...@@ -170,6 +170,7 @@ func (P *Parser) closeScope() {
} }
/*
func (P *Parser) declareInScope(scope *SymbolTable.Scope, x AST.Expr, kind int, typ *AST.Type) { func (P *Parser) declareInScope(scope *SymbolTable.Scope, x AST.Expr, kind int, typ *AST.Type) {
if P.scope_lev < 0 { if P.scope_lev < 0 {
panic("cannot declare objects in other packages"); panic("cannot declare objects in other packages");
...@@ -207,15 +208,16 @@ func (P *Parser) declare(x AST.Expr, kind int, typ *AST.Type) { ...@@ -207,15 +208,16 @@ func (P *Parser) declare(x AST.Expr, kind int, typ *AST.Type) {
} }
P.declareInScope(P.top_scope, x, kind, typ); P.declareInScope(P.top_scope, x, kind, typ);
} }
*/
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Common productions // 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) parseExpression(prec int) AST.Expr;
func (P *Parser) parseStatement() AST.Stat; 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. // If scope != nil, lookup identifier in scope. Otherwise create one.
...@@ -270,10 +272,34 @@ func (P *Parser) parseIdentList(x AST.Expr) AST.Expr { ...@@ -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 // Types
func (P *Parser) parseType() *AST.Type { func (P *Parser) parseType() AST.Expr {
if P.trace { if P.trace {
defer un(trace(P, "Type")); defer un(trace(P, "Type"));
} }
...@@ -281,14 +307,14 @@ func (P *Parser) parseType() *AST.Type { ...@@ -281,14 +307,14 @@ func (P *Parser) parseType() *AST.Type {
t := P.tryType(); t := P.tryType();
if t == nil { if t == nil {
P.error(P.pos, "type expected"); P.error(P.pos, "type expected");
t = AST.BadType; t = &AST.BadExpr(P.pos);
} }
return t; return t;
} }
func (P *Parser) parseVarType() *AST.Type { func (P *Parser) parseVarType() AST.Expr {
if P.trace { if P.trace {
defer un(trace(P, "VarType")); defer un(trace(P, "VarType"));
} }
...@@ -314,88 +340,90 @@ func (P *Parser) parseQualifiedIdent() AST.Expr { ...@@ -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 { if P.trace {
defer un(trace(P, "TypeName")); defer un(trace(P, "TypeName"));
} }
t := AST.NewType(P.pos, AST.TYPENAME); return P.parseQualifiedIdent();
t.Expr = P.parseQualifiedIdent();
return t;
} }
func (P *Parser) parseArrayType() *AST.Type { func (P *Parser) parseArrayType() *AST.ArrayType {
if P.trace { if P.trace {
defer un(trace(P, "ArrayType")); defer un(trace(P, "ArrayType"));
} }
t := AST.NewType(P.pos, AST.ARRAY); pos := P.pos;
P.expect(Scanner.LBRACK); P.expect(Scanner.LBRACK);
var len AST.Expr;
if P.tok == Scanner.ELLIPSIS { if P.tok == Scanner.ELLIPSIS {
t.Expr = &AST.BinaryExpr(P.pos, Scanner.ELLIPSIS, nil, nil); len = &AST.Ellipsis(P.pos);
P.next(); P.next();
} else if P.tok != Scanner.RBRACK { } else if P.tok != Scanner.RBRACK {
t.Expr = P.parseExpression(1); len = P.parseExpression(1);
} }
P.expect(Scanner.RBRACK); 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 { if P.trace {
defer un(trace(P, "ChannelType")); defer un(trace(P, "ChannelType"));
} }
t := AST.NewType(P.pos, AST.CHANNEL); pos := P.pos;
t.Mode = AST.FULL; mode := AST.FULL;
if P.tok == Scanner.CHAN { if P.tok == Scanner.CHAN {
P.next(); P.next();
if P.tok == Scanner.ARROW { if P.tok == Scanner.ARROW {
P.next(); P.next();
t.Mode = AST.SEND; mode = AST.SEND;
} }
} else { } else {
P.expect(Scanner.ARROW); P.expect(Scanner.ARROW);
P.expect(Scanner.CHAN); 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 { func (P *Parser) tryParameterType() AST.Expr {
t := AST.BadType; if P.tok == Scanner.ELLIPSIS {
if expect_ident { pos := P.tok;
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);
P.next(); P.next();
} else { return &AST.Ellipsis(pos);
t = P.parseType();
} }
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 { 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
// (a list of identifiers looks like a list of type names) list := vector.New(0);
i0 := list.Len();
for { 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 { if P.tok == Scanner.COMMA {
P.next(); P.next();
} else { } else {
...@@ -404,115 +432,87 @@ func (P *Parser) parseVarList(list *vector.Vector, ellipsis_ok bool) { ...@@ -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 // if we had a list of identifiers, it must be followed by a type
typ := P.tryType(); typ := P.tryParameterType();
if typ == nil && P.tok == Scanner.ELLIPSIS {
typ = AST.NewType(P.pos, AST.ELLIPSIS); return list, typ;
P.next(); }
}
if ellipsis_ok /* param list */ && i0 > 0 && typ == nil {
// not the first parameter section; we must have a type func (P *Parser) parseParameterList(ellipsis_ok bool) []*AST.Field {
P.error(P.pos, "type expected"); if P.trace {
typ = AST.BadType; defer un(trace(P, "ParameterList"));
} }
// convert the list into a list of (type) expressions list, typ := P.parseParameterDecl(false);
if typ != nil { if typ != nil {
// all list entries must be identifiers // IdentifierList Type
// convert the type entries into identifiers // convert list of identifiers into []*Ident
for i, n := i0, list.Len(); i < n; i++ { idents := make([]*AST.Ident, list.Len());
t := list.At(i).(*AST.Type); for i := 0; i < list.Len(); i++ {
if t.Form == AST.TYPENAME { idents[i] = list.At(i).(*AST.Ident);
if ident, ok := t.Expr.(*AST.Ident); ok { }
list.Set(i, ident); list.Init(0);
continue; list.Push(&AST.Field(idents, typ, nil));
}
} for P.tok == Scanner.COMMA {
list.Set(i, &AST.BadExpr(0)); P.next();
P.error(t.Pos, "identifier expected"); idents := P.parseIdentList2(nil);
typ := P.parseParameterType();
list.Push(&AST.Field(idents, typ, nil));
} }
// add type
list.Push(&AST.TypeLit(typ));
} else { } else {
// all list entries are types // Type { "," Type }
// convert all type entries into type expressions // convert list of types into list of *Param
for i, n := i0, list.Len(); i < n; i++ { for i := 0; i < list.Len(); i++ {
t := list.At(i).(*AST.Type); list.Set(i, &AST.Field(nil, list.At(i).(AST.Expr), nil));
list.Set(i, &AST.TypeLit(t));
} }
} }
}
func (P *Parser) parseParameterList(ellipsis_ok bool) *vector.Vector { // convert list
if P.trace { params := make([]*AST.Field, list.Len());
defer un(trace(P, "ParameterList")); for i := 0; i < list.Len(); i++ {
params[i] = list.At(i).(*AST.Field);
} }
list := vector.New(0); return params;
P.parseVarList(list, ellipsis_ok);
for P.tok == Scanner.COMMA {
P.next();
P.parseVarList(list, ellipsis_ok);
}
return list;
} }
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 { if P.trace {
defer un(trace(P, "Parameters")); defer un(trace(P, "Parameters"));
} }
t := AST.NewType(P.pos, AST.STRUCT); var params []*AST.Field;
P.expect(Scanner.LPAREN); P.expect(Scanner.LPAREN);
if P.tok != Scanner.RPAREN { if P.tok != Scanner.RPAREN {
t.List = P.parseParameterList(ellipsis_ok); params = P.parseParameterList(ellipsis_ok);
} }
t.End = P.pos;
P.expect(Scanner.RPAREN); P.expect(Scanner.RPAREN);
return t; return params;
} }
func (P *Parser) parseResultList() { func (P *Parser) parseResult() []*AST.Field {
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 {
if P.trace { if P.trace {
defer un(trace(P, "Result")); defer un(trace(P, "Result"));
} }
var t *AST.Type; var result []*AST.Field;
if P.tok == Scanner.LPAREN { if P.tok == Scanner.LPAREN {
t = P.parseParameters(false); result = P.parseParameters(false);
} else if P.tok != Scanner.FUNC { } 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); result = make([]*AST.Field, 1);
t.List = vector.New(0); result[0] = &AST.Field(nil, typ, nil);
t.List.Push(&AST.TypeLit(typ));
t.End = P.pos;
} }
} }
return t; return result;
} }
...@@ -522,120 +522,189 @@ func (P *Parser) parseResult(ftyp *AST.Type) *AST.Type { ...@@ -522,120 +522,189 @@ func (P *Parser) parseResult(ftyp *AST.Type) *AST.Type {
// (params) type // (params) type
// (params) (results) // (params) (results)
func (P *Parser) parseSignature() *AST.Type { func (P *Parser) parseSignature() *AST.Signature {
if P.trace { if P.trace {
defer un(trace(P, "Signature")); defer un(trace(P, "Signature"));
} }
P.openScope(); //P.openScope();
P.scope_lev++; //P.scope_lev++;
t := AST.NewType(P.pos, AST.FUNCTION); //t.Scope = P.top_scope;
t.Scope = P.top_scope; params := P.parseParameters(true); // TODO find better solution
t.List = P.parseParameters(true).List; // TODO find better solution //t.End = P.pos;
t.End = P.pos; result := P.parseResult();
t.Elt = P.parseResult(t);
P.scope_lev--; //P.scope_lev--;
P.closeScope(); //P.closeScope();
return t; return &AST.Signature(params, result);
} }
func (P *Parser) parseFunctionType() *AST.Type { func (P *Parser) parseFunctionType() *AST.FunctionType {
if P.trace { if P.trace {
defer un(trace(P, "FunctionType")); defer un(trace(P, "FunctionType"));
} }
pos := P.pos;
P.expect(Scanner.FUNC); 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 { if P.trace {
defer un(trace(P, "MethodOrInterfaceSpec")); defer un(trace(P, "MethodSpec"));
} }
var idents []*AST.Ident;
var typ AST.Expr;
x := P.parseQualifiedIdent(); x := P.parseQualifiedIdent();
if tmp, is_ident := x.(*AST.Ident); is_ident && (P.tok == Scanner.COMMA || P.tok == Scanner.LPAREN) { if tmp, is_ident := x.(*AST.Ident); is_ident && (P.tok == Scanner.COMMA || P.tok == Scanner.LPAREN) {
// method(s) // method(s)
list.Push(P.parseIdentList(x)); idents = P.parseIdentList2(x);
list.Push(&AST.TypeLit(P.parseSignature())); typ = &AST.FunctionType(0, P.parseSignature());
} else { } else {
// embedded interface // 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 { if P.trace {
defer un(trace(P, "InterfaceType")); 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); P.expect(Scanner.INTERFACE);
if P.tok == Scanner.LBRACE { if P.tok == Scanner.LBRACE {
P.next(); P.next();
P.openScope(); //P.openScope();
P.scope_lev++; //P.scope_lev++;
t.List = vector.New(0); list := vector.New(0);
for P.tok == Scanner.IDENT { for P.tok == Scanner.IDENT {
P.parseMethodOrInterfaceSpec(t.List); list.Push(P.parseMethodSpec());
if P.tok != Scanner.RBRACE { if P.tok != Scanner.RBRACE {
P.expect(Scanner.SEMICOLON); P.expect(Scanner.SEMICOLON);
} }
} }
t.End = P.pos; //t.End = P.pos;
P.scope_lev--; //P.scope_lev--;
P.closeScope(); //P.closeScope();
end = P.pos;
P.expect(Scanner.RBRACE); 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 { if P.trace {
defer un(trace(P, "MapType")); defer un(trace(P, "MapType"));
} }
t := AST.NewType(P.pos, AST.MAP); pos := P.pos;
P.expect(Scanner.MAP); P.expect(Scanner.MAP);
P.expect(Scanner.LBRACK); P.expect(Scanner.LBRACK);
t.Key = P.parseVarType(); key := P.parseVarType();
P.expect(Scanner.RBRACK); 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) 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 { if P.trace {
defer un(trace(P, "StructType")); 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); P.expect(Scanner.STRUCT);
if P.tok == Scanner.LBRACE { if P.tok == Scanner.LBRACE {
P.next(); P.next();
t.List = vector.New(0); list := vector.New(0);
t.Scope = SymbolTable.NewScope(nil);
for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF { for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
P.parseVarList(t.List, false); list.Push(P.parseFieldDecl());
if P.tok == Scanner.STRING {
// ParseOperand takes care of string concatenation
t.List.Push(P.parseOperand());
}
if P.tok == Scanner.SEMICOLON { if P.tok == Scanner.SEMICOLON {
P.next(); P.next();
} else { } else {
...@@ -643,36 +712,36 @@ func (P *Parser) parseStructType() *AST.Type { ...@@ -643,36 +712,36 @@ func (P *Parser) parseStructType() *AST.Type {
} }
} }
P.OptSemicolon(); P.OptSemicolon();
t.End = P.pos;
end = P.pos;
P.expect(Scanner.RBRACE); P.expect(Scanner.RBRACE);
P.opt_semi = true;
// enter fields into struct scope // convert vector
for i, n := 0, t.List.Len(); i < n; i++ { fields = make([]*AST.Field, list.Len());
if x, ok := t.List.At(i).(*AST.Ident); ok { for i := list.Len() - 1; i >= 0; i-- {
P.declareInScope(t.Scope, x, SymbolTable.FIELD, nil); 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 { if P.trace {
defer un(trace(P, "PointerType")); defer un(trace(P, "PointerType"));
} }
t := AST.NewType(P.pos, AST.POINTER); pos := P.pos;
P.expect(Scanner.MUL); 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 { if P.trace {
defer un(trace(P, "Type (try)")); defer un(trace(P, "Type (try)"));
} }
...@@ -687,10 +756,11 @@ func (P *Parser) tryType() *AST.Type { ...@@ -687,10 +756,11 @@ func (P *Parser) tryType() *AST.Type {
case Scanner.STRUCT: return P.parseStructType(); case Scanner.STRUCT: return P.parseStructType();
case Scanner.MUL: return P.parsePointerType(); case Scanner.MUL: return P.parsePointerType();
case Scanner.LPAREN: case Scanner.LPAREN:
pos := P.pos;
P.next(); P.next();
t := P.parseType(); t := P.parseType();
P.expect(Scanner.RPAREN); P.expect(Scanner.RPAREN);
return t; return &AST.Group(pos, t);
} }
// no type found // no type found
...@@ -725,7 +795,7 @@ func (P *Parser) parseStatementList(list *vector.Vector) { ...@@ -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 { if P.trace {
defer un(trace(P, "Block")); defer un(trace(P, "Block"));
} }
...@@ -733,6 +803,7 @@ func (P *Parser) parseBlock(ftyp *AST.Type, tok int) *AST.Block { ...@@ -733,6 +803,7 @@ func (P *Parser) parseBlock(ftyp *AST.Type, tok int) *AST.Block {
b := AST.NewBlock(P.pos, tok); b := AST.NewBlock(P.pos, tok);
P.expect(tok); P.expect(tok);
/*
P.openScope(); P.openScope();
// enter recv and parameters into function scope // enter recv and parameters into function scope
if ftyp != nil { if ftyp != nil {
...@@ -747,9 +818,13 @@ func (P *Parser) parseBlock(ftyp *AST.Type, tok int) *AST.Block { ...@@ -747,9 +818,13 @@ func (P *Parser) parseBlock(ftyp *AST.Type, tok int) *AST.Block {
} }
} }
} }
*/
P.parseStatementList(b.List); P.parseStatementList(b.List);
/*
P.closeScope(); P.closeScope();
*/
if tok == Scanner.LBRACE { if tok == Scanner.LBRACE {
b.End = P.pos; b.End = P.pos;
...@@ -795,7 +870,7 @@ func (P *Parser) parseFunctionLit() AST.Expr { ...@@ -795,7 +870,7 @@ func (P *Parser) parseFunctionLit() AST.Expr {
P.expect(Scanner.FUNC); P.expect(Scanner.FUNC);
typ := P.parseSignature(); typ := P.parseSignature();
P.scope_lev++; P.scope_lev++;
body := P.parseBlock(typ, Scanner.LBRACE); body := P.parseBlock(Scanner.LBRACE);
P.scope_lev--; P.scope_lev--;
return &AST.FunctionLit(pos, typ, body); return &AST.FunctionLit(pos, typ, body);
...@@ -812,10 +887,11 @@ func (P *Parser) parseOperand() AST.Expr { ...@@ -812,10 +887,11 @@ func (P *Parser) parseOperand() AST.Expr {
return P.parseIdent(P.top_scope); return P.parseIdent(P.top_scope);
case Scanner.LPAREN: case Scanner.LPAREN:
pos := P.pos;
P.next(); P.next();
x := P.parseExpression(1); x := P.parseExpression(1);
P.expect(Scanner.RPAREN); P.expect(Scanner.RPAREN);
return x; return &AST.Group(pos, x);
case Scanner.INT, Scanner.FLOAT, Scanner.STRING: case Scanner.INT, Scanner.FLOAT, Scanner.STRING:
x := &AST.BasicLit(P.pos, P.tok, P.val); x := &AST.BasicLit(P.pos, P.tok, P.val);
...@@ -835,7 +911,7 @@ func (P *Parser) parseOperand() AST.Expr { ...@@ -835,7 +911,7 @@ func (P *Parser) parseOperand() AST.Expr {
default: default:
t := P.tryType(); t := P.tryType();
if t != nil { if t != nil {
return &AST.TypeLit(t); return t;
} else { } else {
P.error(P.pos, "operand expected"); P.error(P.pos, "operand expected");
P.next(); // make progress P.next(); // make progress
...@@ -978,6 +1054,8 @@ func (P *Parser) parseUnaryExpr() AST.Expr { ...@@ -978,6 +1054,8 @@ func (P *Parser) parseUnaryExpr() AST.Expr {
pos, tok := P.pos, P.tok; pos, tok := P.pos, P.tok;
P.next(); P.next();
y := P.parseUnaryExpr(); y := P.parseUnaryExpr();
return &AST.UnaryExpr(pos, tok, y);
/*
if lit, ok := y.(*AST.TypeLit); ok && tok == Scanner.MUL { if lit, ok := y.(*AST.TypeLit); ok && tok == Scanner.MUL {
// pointer type // pointer type
t := AST.NewType(pos, AST.POINTER); t := AST.NewType(pos, AST.POINTER);
...@@ -986,6 +1064,7 @@ func (P *Parser) parseUnaryExpr() AST.Expr { ...@@ -986,6 +1064,7 @@ func (P *Parser) parseUnaryExpr() AST.Expr {
} else { } else {
return &AST.UnaryExpr(pos, tok, y); return &AST.UnaryExpr(pos, tok, y);
} }
*/
} }
return P.parsePrimaryExpr(); return P.parsePrimaryExpr();
...@@ -1180,7 +1259,7 @@ func (P *Parser) parseIfStat() *AST.IfStat { ...@@ -1180,7 +1259,7 @@ func (P *Parser) parseIfStat() *AST.IfStat {
pos := P.pos; pos := P.pos;
P.expect(Scanner.IF); P.expect(Scanner.IF);
init, cond, dummy := P.parseControlClause(false); init, cond, dummy := P.parseControlClause(false);
body := P.parseBlock(nil, Scanner.LBRACE); body := P.parseBlock(Scanner.LBRACE);
var else_ AST.Stat; var else_ AST.Stat;
if P.tok == Scanner.ELSE { if P.tok == Scanner.ELSE {
P.next(); P.next();
...@@ -1211,7 +1290,7 @@ func (P *Parser) parseForStat() *AST.ForStat { ...@@ -1211,7 +1290,7 @@ func (P *Parser) parseForStat() *AST.ForStat {
pos := P.pos; pos := P.pos;
P.expect(Scanner.FOR); P.expect(Scanner.FOR);
init, cond, post := P.parseControlClause(true); init, cond, post := P.parseControlClause(true);
body := P.parseBlock(nil, Scanner.LBRACE); body := P.parseBlock(Scanner.LBRACE);
P.closeScope(); P.closeScope();
return &AST.ForStat(pos, init, cond, post, body); return &AST.ForStat(pos, init, cond, post, body);
...@@ -1233,7 +1312,7 @@ func (P *Parser) parseCaseClause() *AST.CaseClause { ...@@ -1233,7 +1312,7 @@ func (P *Parser) parseCaseClause() *AST.CaseClause {
P.expect(Scanner.DEFAULT); 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 { ...@@ -1286,7 +1365,7 @@ func (P *Parser) parseCommClause() *AST.CaseClause {
P.expect(Scanner.DEFAULT); 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 { ...@@ -1337,7 +1416,7 @@ func (P *Parser) parseStatement() AST.Stat {
case Scanner.BREAK, Scanner.CONTINUE, Scanner.GOTO, Scanner.FALLTHROUGH: case Scanner.BREAK, Scanner.CONTINUE, Scanner.GOTO, Scanner.FALLTHROUGH:
return P.parseControlFlowStat(P.tok); return P.parseControlFlowStat(P.tok);
case Scanner.LBRACE: case Scanner.LBRACE:
return &AST.CompositeStat(P.parseBlock(nil, Scanner.LBRACE)); return &AST.CompositeStat(P.parseBlock(Scanner.LBRACE));
case Scanner.IF: case Scanner.IF:
return P.parseIfStat(); return P.parseIfStat();
case Scanner.FOR: case Scanner.FOR:
...@@ -1360,90 +1439,105 @@ func (P *Parser) parseStatement() AST.Stat { ...@@ -1360,90 +1439,105 @@ func (P *Parser) parseStatement() AST.Stat {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Declarations // Declarations
func (P *Parser) parseImportSpec(d *AST.Decl) { func (P *Parser) parseImportSpec(pos int) *AST.ImportDecl {
if P.trace { if P.trace {
defer un(trace(P, "ImportSpec")); defer un(trace(P, "ImportSpec"));
} }
var ident *AST.Ident;
if P.tok == Scanner.PERIOD { if P.tok == Scanner.PERIOD {
P.error(P.pos, `"import ." not yet handled properly`); P.error(P.pos, `"import ." not yet handled properly`);
P.next(); P.next();
} else if P.tok == Scanner.IDENT { } else if P.tok == Scanner.IDENT {
d.Ident = P.parseIdent(nil); ident = P.parseIdent(nil);
} }
var path AST.Expr;
if P.tok == Scanner.STRING { if P.tok == Scanner.STRING {
// TODO eventually the scanner should strip the quotes // 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(); P.next();
} else { } else {
P.expect(Scanner.STRING); // use expect() error handling 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 { if P.trace {
defer un(trace(P, "ConstSpec")); defer un(trace(P, "ConstSpec"));
} }
d.Ident = P.parseIdentList(nil); idents := P.parseIdentList2(nil);
d.Typ = P.tryType(); typ := P.tryType();
var vals AST.Expr;
if P.tok == Scanner.ASSIGN { if P.tok == Scanner.ASSIGN {
P.next(); 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 { if P.trace {
defer un(trace(P, "TypeSpec")); defer un(trace(P, "TypeSpec"));
} }
d.Ident = P.parseIdent(nil); ident := P.parseIdent(nil);
d.Typ = P.parseType(); typ := P.parseType();
P.opt_semi = true;
return &AST.TypeDecl(pos, ident, typ);
} }
func (P *Parser) parseVarSpec(d *AST.Decl) { func (P *Parser) parseVarSpec(pos int) *AST.VarDecl {
if P.trace { if P.trace {
defer un(trace(P, "VarSpec")); 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 { if P.tok == Scanner.ASSIGN {
P.next(); P.next();
d.Val = P.parseExpressionList(); vals = P.parseExpressionList();
} else { } else {
d.Typ = P.parseVarType(); typ = P.parseVarType();
if P.tok == Scanner.ASSIGN { if P.tok == Scanner.ASSIGN {
P.next(); 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; kind := SymbolTable.NONE;
switch d.Tok { switch keyword {
case Scanner.IMPORT: P.parseImportSpec(d); kind = SymbolTable.PACKAGE; case Scanner.IMPORT: return P.parseImportSpec(pos);
case Scanner.CONST: P.parseConstSpec(d); kind = SymbolTable.CONST; case Scanner.CONST: return P.parseConstSpec(pos);
case Scanner.TYPE: P.parseTypeSpec(d); kind = SymbolTable.TYPE; case Scanner.TYPE: return P.parseTypeSpec(pos);
case Scanner.VAR: P.parseVarSpec(d); kind = SymbolTable.VAR; case Scanner.VAR: return P.parseVarSpec(pos);
default: unreachable();
} }
unreachable();
return nil;
/*
// semantic checks // semantic checks
if d.Tok == Scanner.IMPORT { if d.Tok == Scanner.IMPORT {
if d.Ident != nil { if d.Ident != nil {
P.declare(d.Ident, kind, nil); //P.declare(d.Ident, kind, nil);
} }
} else { } else {
P.declare(d.Ident, kind, d.Typ); //P.declare(d.Ident, kind, d.Typ);
if d.Val != nil { if d.Val != nil {
// initialization/assignment // initialization/assignment
llen := AST.ExprLen(d.Ident); llen := AST.ExprLen(d.Ident);
...@@ -1463,38 +1557,42 @@ func (P *Parser) parseSpec(d *AST.Decl) { ...@@ -1463,38 +1557,42 @@ func (P *Parser) parseSpec(d *AST.Decl) {
// TODO // TODO
} }
} }
*/
} }
func (P *Parser) parseDecl(keyword int) *AST.Decl { func (P *Parser) parseDecl(keyword int) AST.Decl {
if P.trace { if P.trace {
defer un(trace(P, "Decl")); defer un(trace(P, "Decl"));
} }
d := AST.NewDecl(P.pos, keyword); pos := P.pos;
P.expect(keyword); P.expect(keyword);
if P.tok == Scanner.LPAREN { if P.tok == Scanner.LPAREN {
P.next(); P.next();
d.List = vector.New(0); list := vector.New(0);
for P.tok != Scanner.RPAREN && P.tok != Scanner.EOF { for P.tok != Scanner.RPAREN && P.tok != Scanner.EOF {
d1 := AST.NewDecl(P.pos, keyword); list.Push(P.parseSpec(0, keyword));
P.parseSpec(d1);
d.List.Push(d1);
if P.tok == Scanner.SEMICOLON { if P.tok == Scanner.SEMICOLON {
P.next(); P.next();
} else { } else {
break; break;
} }
} }
d.End = P.pos; end := P.pos;
P.expect(Scanner.RPAREN); P.expect(Scanner.RPAREN);
P.opt_semi = true; P.opt_semi = true;
} else { // convert vector
P.parseSpec(d); 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 { ...@@ -1507,54 +1605,53 @@ func (P *Parser) parseDecl(keyword int) *AST.Decl {
// func (recv) ident (params) type // func (recv) ident (params) type
// func (recv) ident (params) (results) // func (recv) ident (params) (results)
func (P *Parser) parseFunctionDecl() *AST.Decl { func (P *Parser) parseFunctionDecl() *AST.FuncDecl {
if P.trace { if P.trace {
defer un(trace(P, "FunctionDecl")); defer un(trace(P, "FunctionDecl"));
} }
d := AST.NewDecl(P.pos, Scanner.FUNC); pos := P.pos;
P.expect(Scanner.FUNC); P.expect(Scanner.FUNC);
var recv *AST.Type; var recv *AST.Field;
if P.tok == Scanner.LPAREN { if P.tok == Scanner.LPAREN {
pos := P.pos; pos := P.pos;
recv = P.parseParameters(true); tmp := P.parseParameters(true);
if recv.Nfields() != 1 { if len(tmp) == 1 {
recv = tmp[0];
} else {
P.error(pos, "must have exactly one receiver"); P.error(pos, "must have exactly one receiver");
} }
} }
ident := P.parseIdent(nil); ident := P.parseIdent(nil);
d.Ident = ident; sig := P.parseSignature();
d.Typ = P.parseSignature();
d.Typ.Key = recv;
var body *AST.Block;
if P.tok == Scanner.LBRACE { 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 { if P.trace {
defer un(trace(P, "Declaration")); defer un(trace(P, "Declaration"));
} }
d := AST.BadDecl;
switch P.tok { switch P.tok {
case Scanner.CONST, Scanner.TYPE, Scanner.VAR: case Scanner.CONST, Scanner.TYPE, Scanner.VAR:
d = P.parseDecl(P.tok); return P.parseDecl(P.tok);
case Scanner.FUNC: case Scanner.FUNC:
d = P.parseFunctionDecl(); return P.parseFunctionDecl();
default:
P.error(P.pos, "declaration expected");
P.next(); // make progress
} }
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 { ...@@ -1573,18 +1670,24 @@ func (P *Parser) ParseProgram() *AST.Program {
// package body // package body
{ P.openScope(); { P.openScope();
p.Decls = vector.New(0); list := vector.New(0);
for P.tok == Scanner.IMPORT { for P.tok == Scanner.IMPORT {
p.Decls.Push(P.parseDecl(Scanner.IMPORT)); list.Push(P.parseDecl(Scanner.IMPORT));
P.OptSemicolon(); P.OptSemicolon();
} }
if !P.deps { if !P.deps {
for P.tok != Scanner.EOF { for P.tok != Scanner.EOF {
p.Decls.Push(P.parseDeclaration()); list.Push(P.parseDeclaration());
P.OptSemicolon(); P.OptSemicolon();
} }
} }
P.closeScope(); 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; p.Comments = P.comments;
......
...@@ -93,6 +93,7 @@ type Printer struct { ...@@ -93,6 +93,7 @@ type Printer struct {
indentation int; // indentation level (may be different from scope level) indentation int; // indentation level (may be different from scope level)
// formatting parameters // formatting parameters
opt_semi bool; // // true if semicolon separator is optional in statement list
separator int; // pending separator separator int; // pending separator
newlines int; // pending newlines newlines int; // pending newlines
...@@ -362,6 +363,7 @@ func (P *Printer) TaggedString(pos int, tag, s, endtag string) { ...@@ -362,6 +363,7 @@ func (P *Printer) TaggedString(pos int, tag, s, endtag string) {
// -------------------------------- // --------------------------------
// done // done
P.opt_semi = false;
P.lastpos = pos + len(s); // rough estimate P.lastpos = pos + len(s); // rough estimate
} }
...@@ -422,15 +424,15 @@ func (P *Printer) HtmlIdentifier(x *AST.Ident) { ...@@ -422,15 +424,15 @@ func (P *Printer) HtmlIdentifier(x *AST.Ident) {
// depending on whether we have a declaration or use, generate different html // depending on whether we have a declaration or use, generate different html
// - no need to htmlEscape ident // - no need to htmlEscape ident
id := Utils.IntToString(obj.Id, 10); id := Utils.IntToString(obj.Id, 10);
if x.Pos() == obj.Pos { if x.Pos_ == obj.Pos {
// probably the declaration of x // 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 { } else {
// probably not the declaration of x // 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 { } 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) { ...@@ -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) Expr(x AST.Expr)
func (P *Printer) Parameters(pos int, list *vector.Vector) { func (P *Printer) Idents(list []*AST.Ident) {
P.String(pos, "("); for i, x := range list {
if list != nil { if i > 0 {
var prev int; P.Token(0, Scanner.COMMA);
for i, n := 0, list.Len(); i < n; i++ { P.separator = blank;
x := list.At(i).(AST.Expr); P.state = inside_list;
tok := Scanner.TYPE; }
if dummy, is_ident := x.(*AST.Ident); is_ident { P.Expr(x);
tok = Scanner.IDENT; }
} }
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 i > 0 {
if prev == tok || prev == Scanner.TYPE { P.separator = comma;
P.separator = comma;
} else {
P.separator = blank;
}
} }
P.Expr(x); if len(par.Idents) > 0 {
prev = tok; 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 // 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) Signature(t *AST.Type) int { func (P *Printer) Signature(sig *AST.Signature) {
assert(t.Form == AST.FUNCTION); P.Parameters(sig.Params);
separator := none; if sig.Result != nil {
P.Parameters(t.Pos, t.List);
if t.Elt != nil {
P.separator = blank; P.separator = blank;
list := t.Elt.List;
dummy, is_type := list.At(0).(*AST.TypeLit); if len(sig.Result) == 1 && sig.Result[0].Idents == nil {
if list.Len() > 1 || is_type && dummy.Typ.Form == AST.FUNCTION { // single anonymous result
// single, anonymous result types which are functions must // => no parentheses needed unless it's a function type
// be parenthesized as well fld := sig.Result[0];
P.Parameters(0, list); if dummy, is_ftyp := fld.Typ.(*AST.FunctionType); !is_ftyp {
} else { P.Expr(fld.Typ);
// single, anonymous result type return;
separator = P.Type(list.At(0).(*AST.TypeLit).Typ); }
} }
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.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; P.newlines = 1;
var prev int; for i, fld := range list {
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;
}
if i > 0 { if i > 0 {
if prev == Scanner.TYPE && tok != Scanner.STRING || prev == Scanner.STRING { P.separator = semicolon;
P.separator = semicolon; P.newlines = 1;
P.newlines = 1; }
} else if prev == tok { if len(fld.Idents) > 0 {
P.separator = comma; 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 { } else {
P.separator = tab; P.Expr(fld.Typ);
} }
}
if in_interface && tok == Scanner.TYPE {
P.Signature(x.(*AST.TypeLit).Typ);
} else { } 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.newlines = 1;
} }
P.state = closing_scope; P.state = closing_scope;
P.String(end, "}"); P.Token(end, Scanner.RBRACE);
} P.opt_semi = true;
// 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;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Expressions // Expressions
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)
func (P *Printer) DoBadExpr(x *AST.BadExpr) { func (P *Printer) DoBadExpr(x *AST.BadExpr) {
...@@ -624,22 +565,22 @@ func (P *Printer) DoBinaryExpr(x *AST.BinaryExpr) { ...@@ -624,22 +565,22 @@ func (P *Printer) DoBinaryExpr(x *AST.BinaryExpr) {
if x.Tok == Scanner.COMMA { if x.Tok == Scanner.COMMA {
// (don't use binary expression printing because of different spacing) // (don't use binary expression printing because of different spacing)
P.Expr(x.X); P.Expr(x.X);
P.String(x.Pos(), ","); P.Token(x.Pos_, Scanner.COMMA);
P.separator = blank; P.separator = blank;
P.state = inside_list; P.state = inside_list;
P.Expr(x.Y); P.Expr(x.Y);
} else { } else {
prec := Scanner.Precedence(x.Tok); prec := Scanner.Precedence(x.Tok);
if prec < P.prec { if prec < P.prec {
P.String(0, "("); P.Token(0, Scanner.LPAREN);
} }
P.Expr1(x.X, prec); P.Expr1(x.X, prec);
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);
if prec < P.prec { if prec < P.prec {
P.String(0, ")"); P.Token(0, Scanner.RPAREN);
} }
} }
} }
...@@ -648,31 +589,26 @@ func (P *Printer) DoBinaryExpr(x *AST.BinaryExpr) { ...@@ -648,31 +589,26 @@ func (P *Printer) DoBinaryExpr(x *AST.BinaryExpr) {
func (P *Printer) DoUnaryExpr(x *AST.UnaryExpr) { func (P *Printer) DoUnaryExpr(x *AST.UnaryExpr) {
prec := Scanner.UnaryPrec; prec := Scanner.UnaryPrec;
if prec < P.prec { 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 { if x.Tok == Scanner.RANGE {
P.separator = blank; P.separator = blank;
} }
P.Expr1(x.X, prec); P.Expr1(x.X, prec);
if prec < P.prec { if prec < P.prec {
P.String(0, ")"); P.Token(0, Scanner.RPAREN);
} }
} }
func (P *Printer) DoBasicLit(x *AST.BasicLit) { func (P *Printer) DoBasicLit(x *AST.BasicLit) {
P.String(x.Pos(), x.Val); P.String(x.Pos_, x.Val);
}
func (P *Printer) DoTypeLit(x *AST.TypeLit) {
P.Type(x.Typ);
} }
func (P *Printer) DoFunctionLit(x *AST.FunctionLit) { func (P *Printer) DoFunctionLit(x *AST.FunctionLit) {
P.String(x.Pos(), "func"); P.Token(x.Pos_, Scanner.FUNC);
P.Signature(x.Typ); P.Signature(x.Typ);
P.separator = blank; P.separator = blank;
P.Block(x.Body, true); P.Block(x.Body, true);
...@@ -680,35 +616,117 @@ func (P *Printer) DoFunctionLit(x *AST.FunctionLit) { ...@@ -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) { func (P *Printer) DoSelector(x *AST.Selector) {
P.Expr1(x.X, Scanner.HighestPrec); P.Expr1(x.X, Scanner.HighestPrec);
P.String(x.Pos(), "."); P.Token(x.Pos_, Scanner.PERIOD);
P.Expr1(x.Sel, Scanner.HighestPrec); P.Expr1(x.Sel, Scanner.HighestPrec);
} }
func (P *Printer) DoTypeGuard(x *AST.TypeGuard) { func (P *Printer) DoTypeGuard(x *AST.TypeGuard) {
P.Expr1(x.X, Scanner.HighestPrec); P.Expr1(x.X, Scanner.HighestPrec);
P.String(x.Pos(), "."); P.Token(x.Pos_, Scanner.PERIOD);
P.String(0, "("); P.Token(0, Scanner.LPAREN);
P.Type(x.Typ); P.Expr(x.Typ);
P.String(0, ")"); P.Token(0, Scanner.RPAREN);
} }
func (P *Printer) DoIndex(x *AST.Index) { func (P *Printer) DoIndex(x *AST.Index) {
P.Expr1(x.X, Scanner.HighestPrec); P.Expr1(x.X, Scanner.HighestPrec);
P.String(x.Pos(), "["); P.Token(x.Pos_, Scanner.LBRACK);
P.Expr1(x.I, 0); P.Expr1(x.I, 0);
P.String(0, "]"); P.Token(0, Scanner.RBRACK);
} }
func (P *Printer) DoCall(x *AST.Call) { func (P *Printer) DoCall(x *AST.Call) {
P.Expr1(x.F, Scanner.HighestPrec); P.Expr1(x.F, Scanner.HighestPrec);
P.String(x.Pos(), "("); P.Token(x.Pos_, Scanner.LPAREN);
P.Expr(x.Args); 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) { ...@@ -738,9 +756,16 @@ func (P *Printer) Stat(s AST.Stat) {
func (P *Printer) StatementList(list *vector.Vector) { func (P *Printer) StatementList(list *vector.Vector) {
for i, n := 0, list.Len(); i < n; i++ { for i := 0; i < list.Len(); i++ {
P.newlines = 1; // for first entry if i == 0 {
list.At(i).(AST.Stat).Visit(P); 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.newlines = 1;
P.state = inside_list; P.state = inside_list;
} }
...@@ -762,15 +787,15 @@ func (P *Printer) Block(b *AST.Block, indent bool) { ...@@ -762,15 +787,15 @@ func (P *Printer) Block(b *AST.Block, indent bool) {
} }
P.state = closing_scope; P.state = closing_scope;
if b.Tok == Scanner.LBRACE { if b.Tok == Scanner.LBRACE {
P.String(b.End, "}"); P.Token(b.End, Scanner.RBRACE);
P.opt_semi = true;
} else { } else {
P.String(0, ""); // process closing_scope state transition! 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) { func (P *Printer) DoBadStat(s *AST.BadStat) {
panic(); panic();
...@@ -780,14 +805,13 @@ func (P *Printer) DoBadStat(s *AST.BadStat) { ...@@ -780,14 +805,13 @@ func (P *Printer) DoBadStat(s *AST.BadStat) {
func (P *Printer) DoLabelDecl(s *AST.LabelDecl) { func (P *Printer) DoLabelDecl(s *AST.LabelDecl) {
P.indentation--; P.indentation--;
P.Expr(s.Label); P.Expr(s.Label);
P.String(s.Pos, ":"); P.Token(s.Pos, Scanner.COLON);
P.indentation++; P.indentation++;
P.separator = none;
} }
func (P *Printer) DoDeclarationStat(s *AST.DeclarationStat) { 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) { ...@@ -808,7 +832,6 @@ func (P *Printer) DoExpressionStat(s *AST.ExpressionStat) {
P.Error(s.Pos, s.Tok, "DoExpressionStat"); P.Error(s.Pos, s.Tok, "DoExpressionStat");
unreachable(); unreachable();
} }
P.separator = semicolon;
} }
...@@ -831,14 +854,14 @@ func (P *Printer) ControlClause(isForStat bool, init AST.Stat, expr AST.Expr, po ...@@ -831,14 +854,14 @@ func (P *Printer) ControlClause(isForStat bool, init AST.Stat, expr AST.Expr, po
P.Stat(init); P.Stat(init);
P.separator = none; P.separator = none;
} }
P.String(0, ";"); P.Token(0, Scanner.SEMICOLON);
P.separator = blank; P.separator = blank;
if expr != nil { if expr != nil {
P.Expr(expr); P.Expr(expr);
P.separator = none; P.separator = none;
} }
if isForStat { if isForStat {
P.String(0, ";"); P.Token(0, Scanner.SEMICOLON);
P.separator = blank; P.separator = blank;
if post != nil { if post != nil {
P.Stat(post); P.Stat(post);
...@@ -879,7 +902,7 @@ func (P *Printer) DoCaseClause(s *AST.CaseClause) { ...@@ -879,7 +902,7 @@ func (P *Printer) DoCaseClause(s *AST.CaseClause) {
} }
// TODO: try to use P.Block instead // TODO: try to use P.Block instead
// P.Block(s.Body, true); // P.Block(s.Body, true);
P.String(s.Body.Pos, ":"); P.Token(s.Body.Pos, Scanner.COLON);
P.indentation++; P.indentation++;
P.StatementList(s.Body.List); P.StatementList(s.Body.List);
P.indentation--; P.indentation--;
...@@ -907,114 +930,164 @@ func (P *Printer) DoControlFlowStat(s *AST.ControlFlowStat) { ...@@ -907,114 +930,164 @@ func (P *Printer) DoControlFlowStat(s *AST.ControlFlowStat) {
P.separator = blank; P.separator = blank;
P.Expr(s.Label); P.Expr(s.Label);
} }
P.separator = semicolon;
} }
func (P *Printer) DoEmptyStat(s *AST.EmptyStat) { func (P *Printer) DoEmptyStat(s *AST.EmptyStat) {
P.String(s.Pos, ""); P.String(s.Pos, "");
P.separator = semicolon;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Declarations // Declarations
func (P *Printer) Declaration(d *AST.Decl, parenthesized bool) { func (P *Printer) DoBadDecl(d *AST.BadDecl) {
if !parenthesized { unimplemented();
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) DoImportDecl(d *AST.ImportDecl) {
} if d.Pos > 0 {
P.Token(d.Pos, Scanner.IMPORT);
P.separator = blank; 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 func (P *Printer) DoConstDecl(d *AST.ConstDecl) {
P.state = opening_scope; if d.Pos > 0 {
P.String(0, "("); P.Token(d.Pos, Scanner.CONST);
if d.List.Len() > 0 { P.separator = blank;
P.newlines = 1; }
for i := 0; i < d.List.Len(); i++ { P.Idents(d.Idents);
P.Declaration(d.List.At(i).(*AST.Decl), true); if d.Typ != nil {
P.separator = semicolon; P.separator = blank; // TODO switch to tab? (indentation problem with structs)
P.newlines = 1; 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.Expr(recv.Typ);
P.String(d.End, ")"); 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 { } else {
// single declaration P.String(d.Pos, "def");
switch d.Tok { }
case Scanner.IMPORT: P.separator = blank;
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;
case Scanner.FUNC: // group of parenthesized declarations
if d.Typ.Key != nil { P.state = opening_scope;
// method: print receiver P.Token(0, Scanner.LPAREN);
P.Parameters(0, d.Typ.Key.List); if len(d.List) > 0 {
P.separator = blank; P.newlines = 1;
} for i := 0; i < len(d.List); i++ {
P.Expr(d.Ident); if i > 0 {
P.separator = P.Signature(d.Typ); P.separator = semicolon;
if d.Body != nil {
P.separator = blank;
P.Block(d.Body, true);
} }
P.Decl(d.List[i]);
default: P.newlines = 1;
P.Error(d.Pos, d.Tok, "decl");
} }
} }
P.state = closing_scope;
P.Token(d.End, Scanner.RPAREN);
P.opt_semi = true;
P.newlines = 2; P.newlines = 2;
} }
func (P *Printer) Decl(d AST.Decl) {
d.Visit(P);
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Program // Program
func (P *Printer) Program(p *AST.Program) { func (P *Printer) Program(p *AST.Program) {
P.String(p.Pos, "package"); P.Token(p.Pos, Scanner.PACKAGE);
P.separator = blank; P.separator = blank;
P.Expr(p.Ident); P.Expr(p.Ident);
P.newlines = 1; P.newlines = 1;
for i := 0; i < p.Decls.Len(); i++ { for i := 0; i < len(p.Decls); i++ {
P.Declaration(p.Decls.At(i).(*AST.Decl), false); P.Decl(p.Decls[i]);
} }
P.newlines = 1; P.newlines = 1;
} }
......
...@@ -10,7 +10,7 @@ import P2 /* ERROR expected */ 42 /* SYNC */ ...@@ -10,7 +10,7 @@ import P2 /* ERROR expected */ 42 /* SYNC */
type S0 struct { type S0 struct {
f0, f1, f2; f0, f1, f2 int;
} }
......
...@@ -26,7 +26,7 @@ apply1() { ...@@ -26,7 +26,7 @@ apply1() {
case `basename $F` in case `basename $F` in
# files with errors (skip them) # files with errors (skip them)
# the following have semantic errors: bug039.go | bug040.go # 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 | \ 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 ) ;; 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;;
...@@ -43,18 +43,9 @@ applydot() { ...@@ -43,18 +43,9 @@ applydot() {
} }
# apply to all files in the list # apply to all .go files we can find
apply() { apply() {
for F in \ for F in `find $GOROOT -name "*.go" | grep -v "OLD"`; do
$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
apply1 $1 $F apply1 $1 $F
done done
} }
......
...@@ -52,6 +52,7 @@ func (s *state) CheckType() { ...@@ -52,6 +52,7 @@ func (s *state) CheckType() {
} }
/*
func (s *state) CheckDeclaration(d *AST.Decl) { func (s *state) CheckDeclaration(d *AST.Decl) {
if d.Tok != Scanner.FUNC && d.List != nil { if d.Tok != Scanner.FUNC && d.List != nil {
// group of parenthesized declarations // group of parenthesized declarations
...@@ -72,11 +73,12 @@ func (s *state) CheckDeclaration(d *AST.Decl) { ...@@ -72,11 +73,12 @@ func (s *state) CheckDeclaration(d *AST.Decl) {
} }
} }
} }
*/
func (s *state) CheckProgram(p *AST.Program) { func (s *state) CheckProgram(p *AST.Program) {
for i := 0; i < p.Decls.Len(); i++ { for i := 0; i < len(p.Decls); i++ {
s.CheckDeclaration(p.Decls.At(i).(*AST.Decl)); //s.CheckDeclaration(p.Decls[i].(*AST.Decl));
} }
} }
......
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