1
0
mirror of https://github.com/golang/go synced 2024-11-12 05:30:21 -07:00

AST for Go programs

R=rsc,r
DELTA=309  (67 added, 51 deleted, 191 changed)
OCL=26611
CL=26745
This commit is contained in:
Robert Griesemer 2009-03-25 12:44:18 -07:00
parent 21d03496e7
commit bafd8c390a

View File

@ -17,13 +17,6 @@ import (
type Position scanner.Location type Position scanner.Location
// TODO try to get rid of these
type (
Block struct;
Signature struct;
)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Interfaces // Interfaces
// //
@ -43,12 +36,13 @@ type (
// TODO: For comment positioning only the byte position and not // TODO: For comment positioning only the byte position and not
// a complete Position field is needed. May be able to trim node // a complete Position field is needed. May be able to trim node
// sizes a bit. // sizes a bit. Then, embed Position field so we can get rid of
// most of the Pos() methods.
type ( type (
ExprVisitor interface; ExprVisitor interface;
StatVisitor interface; StmtVisitor interface;
DeclVisitor interface; DeclVisitor interface;
) )
@ -65,12 +59,12 @@ type Expr interface {
} }
// All statement nodes implement the Stat interface. // All statement nodes implement the Stmt interface.
type Stat interface { type Stmt interface {
// For a (dynamic) node type X, calling Visit with a statement // For a (dynamic) node type X, calling Visit with a statement
// visitor v invokes the node-specific DoX function of the visitor. // visitor v invokes the node-specific DoX function of the visitor.
// //
Visit(v StatVisitor); Visit(v StmtVisitor);
// Pos returns the (beginning) position of the statement. // Pos returns the (beginning) position of the statement.
Pos() Position; Pos() Position;
@ -109,6 +103,25 @@ type Comments []*Comment
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Expressions and types // Expressions and types
// Support types.
type (
Ident struct;
StringLit struct;
FunctionType struct;
BlockStmt struct;
// A Field represents a Field declaration list in a struct type,
// a method in an interface type, or a parameter/result declaration
// in a signature.
Field struct {
Doc Comments; // associated documentation; or nil
Names []*Ident; // field/method/parameter names; nil if anonymous field
Type Expr; // field/method/parameter type
Tag []*StringLit; // field tag; nil if no tag
};
)
// An expression is represented by a tree consisting of one // An expression is represented by a tree consisting of one
// or more of the following concrete expression nodes. // or more of the following concrete expression nodes.
// //
@ -127,28 +140,55 @@ type (
Lit []byte; // identifier string (e.g. foobar) Lit []byte; // identifier string (e.g. foobar)
}; };
// A BasicLit node represents a basic literal. // An Ellipsis node stands for the "..." type in a
BasicLit struct { // parameter list or the "..." length in an array type.
Pos_ Position; // literal string position //
Tok int; // literal token (INT, FLOAT, CHAR, STRING) Ellipsis struct {
Lit []byte; // literal string Pos_ Position; // position of "..."
}; };
// A StringLit node represents a sequence of string literals. // An IntLit node represents an integer literal.
IntLit struct {
Pos_ Position; // literal string position
Lit []byte; // literal string; e.g. 42 or 0x7f
};
// A FloatLit node represents a floating-point literal.
FloatLit struct {
Pos_ Position; // literal string position
Lit []byte; // literal string; e.g. 3.14 or 1e-9
};
// A CharLit node represents a character literal.
CharLit struct {
Pos_ Position; // literal string position
Lit []byte; // literal string, including quotes; e.g. 'a' or '\x7f'
};
// A StringLit node represents a string literal.
StringLit struct { StringLit struct {
Strings []*BasicLit; // sequence of strings Pos_ Position; // literal string position
Lit []byte; // literal string, including quotes; e.g. "foo" or `\m\n\o`
};
// A StringList node represents a sequence of adjacent string literals.
// A single string literal (common case) is represented by a StringLit
// node; StringList nodes are used only if there are two or more string
// literals in a sequence.
//
StringList struct {
Strings []*StringLit; // list of strings, len(Strings) > 1
}; };
// A FunctionLit node represents a function literal. // A FunctionLit node represents a function literal.
FunctionLit struct { FunctionLit struct {
Func Position; // position of "func" keyword Type *FunctionType; // function type
Typ *Signature; // function signature Body *BlockStmt; // function body
Body *Block; // function body
}; };
// A CompositeLit node represents a composite literal. // A CompositeLit node represents a composite literal.
CompositeLit struct { CompositeLit struct {
Typ Expr; // literal type Type Expr; // literal type
Lbrace Position; // position of "{" Lbrace Position; // position of "{"
Elts []Expr; // list of composite elements Elts []Expr; // list of composite elements
Rbrace Position; // position of "}" Rbrace Position; // position of "}"
@ -161,33 +201,33 @@ type (
Rparen Position; // position of ")" Rparen Position; // position of ")"
}; };
// A SelectorExpr node represents a primary expression followed by a selector. // A SelectorExpr node represents an expression followed by a selector.
SelectorExpr struct { SelectorExpr struct {
X Expr; // primary expression X Expr; // expression
Sel *Ident; // field selector Sel *Ident; // field selector
}; };
// An IndexExpr node represents a primary expression followed by an index. // An IndexExpr node represents an expression followed by an index.
IndexExpr struct { IndexExpr struct {
X Expr; // primary expression X Expr; // expression
Index Expr; // index expression Index Expr; // index expression
}; };
// A SliceExpr node represents a primary expression followed by a slice. // A SliceExpr node represents an expression followed by a slice.
SliceExpr struct { SliceExpr struct {
X Expr; // primary expression X Expr; // expression
Begin, End Expr; // slice range Begin, End Expr; // slice range
}; };
// A TypeAssertExpr node represents a primary expression followed by a // A TypeAssertExpr node represents an expression followed by a
// type assertion. // type assertion.
// //
TypeAssertExpr struct { TypeAssertExpr struct {
X Expr; // primary expression X Expr; // expression
Typ Expr; // asserted type Type Expr; // asserted type
}; };
// A CallExpr node represents a primary expression followed by an argument list. // A CallExpr node represents an expression followed by an argument list.
CallExpr struct { CallExpr struct {
Fun Expr; // function expression Fun Expr; // function expression
Lparen Position; // position of "(" Lparen Position; // position of "("
@ -236,17 +276,10 @@ const (
// nodes. // nodes.
// //
type ( type (
// An Ellipsis node stands for the "..." type in a
// parameter list or the "..." length in an array type.
//
Ellipsis struct { // neither a type nor an expression
Pos_ Position; // position of "..."
};
// An ArrayType node represents an array type. // An ArrayType node represents an array type.
ArrayType struct { ArrayType struct {
Lbrack Position; // position of "[" Lbrack Position; // position of "["
Len Expr; // an Ellipsis node for [...]T array types Len Expr; // possibly an Ellipsis node for [...]T array types
Elt Expr; // element type Elt Expr; // element type
}; };
@ -256,16 +289,6 @@ type (
Elt Expr; // element type Elt Expr; // element type
}; };
// A Field represents a Field declaration list in a struct type,
// a method in an interface type, or a parameter declaration in
// a signature.
Field struct {
Doc Comments; // associated documentation (struct types only)
Names []*Ident; // field/method/parameter names; nil if anonymous field
Typ Expr; // field/method/parameter type
Tag Expr; // field tag; nil if no tag
};
// A StructType node represents a struct type. // A StructType node represents a struct type.
StructType struct { StructType struct {
Struct, Lbrace Position; // positions of "struct" keyword, "{" Struct, Lbrace Position; // positions of "struct" keyword, "{"
@ -273,20 +296,13 @@ type (
Rbrace Position; // position of "}" Rbrace Position; // position of "}"
}; };
// Note: pointer types are represented via StarExpr nodes. // Pointer types are represented via StarExpr nodes.
// A signature node represents the parameter and result
// sections of a function type only.
//
Signature struct {
Params []*Field;
Result []*Field;
};
// A FunctionType node represents a function type. // A FunctionType node represents a function type.
FunctionType struct { FunctionType struct {
Func Position; // position of "func" keyword Func Position; // position of "func" keyword
Sig *Signature; Params []*Field; // (incoming) parameters
Results []*Field; // (outgoing) results
}; };
// An InterfaceType node represents an interface type. // An InterfaceType node represents an interface type.
@ -306,7 +322,7 @@ type (
// A ChannelType node represents a channel type. // A ChannelType node represents a channel type.
ChannelType struct { ChannelType struct {
Pos_ Position; // position of "chan" keyword or "<-" (whichever comes first) Pos_ Position; // position of "chan" keyword or "<-" (whichever comes first)
Dir ChanDir; Dir ChanDir; // channel direction
Value Expr; // value type Value Expr; // value type
}; };
) )
@ -316,10 +332,13 @@ type (
// //
func (x *BadExpr) Pos() Position { return x.Pos_; } func (x *BadExpr) Pos() Position { return x.Pos_; }
func (x *Ident) Pos() Position { return x.Pos_; } func (x *Ident) Pos() Position { return x.Pos_; }
func (x *BasicLit) Pos() Position { return x.Pos_; } func (x *IntLit) Pos() Position { return x.Pos_; }
func (x *StringLit) Pos() Position { return x.Strings[0].Pos(); } func (x *FloatLit) Pos() Position { return x.Pos_; }
func (x *FunctionLit) Pos() Position { return x.Func; } func (x *CharLit) Pos() Position { return x.Pos_; }
func (x *CompositeLit) Pos() Position { return x.Typ.Pos(); } func (x *StringLit) Pos() Position { return x.Pos_; }
func (x *StringList) Pos() Position { return x.Strings[0].Pos(); }
func (x *FunctionLit) Pos() Position { return x.Type.Func; }
func (x *CompositeLit) Pos() Position { return x.Type.Pos(); }
func (x *ParenExpr) Pos() Position { return x.Lparen; } func (x *ParenExpr) Pos() Position { return x.Lparen; }
func (x *SelectorExpr) Pos() Position { return x.X.Pos(); } func (x *SelectorExpr) Pos() Position { return x.X.Pos(); }
func (x *IndexExpr) Pos() Position { return x.X.Pos(); } func (x *IndexExpr) Pos() Position { return x.X.Pos(); }
@ -349,8 +368,11 @@ type ExprVisitor interface {
// Expressions // Expressions
DoBadExpr(x *BadExpr); DoBadExpr(x *BadExpr);
DoIdent(x *Ident); DoIdent(x *Ident);
DoBasicLit(x *BasicLit); DoIntLit(x *IntLit);
DoFloatLit(x *FloatLit);
DoCharLit(x *CharLit);
DoStringLit(x *StringLit); DoStringLit(x *StringLit);
DoStringList(x *StringList);
DoFunctionLit(x *FunctionLit); DoFunctionLit(x *FunctionLit);
DoCompositeLit(x *CompositeLit); DoCompositeLit(x *CompositeLit);
DoParenExpr(x *ParenExpr); DoParenExpr(x *ParenExpr);
@ -379,8 +401,12 @@ type ExprVisitor interface {
// //
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); }
func (x *BasicLit) Visit(v ExprVisitor) { v.DoBasicLit(x); } func (x *Ellipsis) Visit(v ExprVisitor) { v.DoEllipsis(x); }
func (x *IntLit) Visit(v ExprVisitor) { v.DoIntLit(x); }
func (x *FloatLit) Visit(v ExprVisitor) { v.DoFloatLit(x); }
func (x *CharLit) Visit(v ExprVisitor) { v.DoCharLit(x); }
func (x *StringLit) Visit(v ExprVisitor) { v.DoStringLit(x); } func (x *StringLit) Visit(v ExprVisitor) { v.DoStringLit(x); }
func (x *StringList) Visit(v ExprVisitor) { v.DoStringList(x); }
func (x *FunctionLit) Visit(v ExprVisitor) { v.DoFunctionLit(x); } func (x *FunctionLit) Visit(v ExprVisitor) { v.DoFunctionLit(x); }
func (x *CompositeLit) Visit(v ExprVisitor) { v.DoCompositeLit(x); } func (x *CompositeLit) Visit(v ExprVisitor) { v.DoCompositeLit(x); }
func (x *ParenExpr) Visit(v ExprVisitor) { v.DoParenExpr(x); } func (x *ParenExpr) Visit(v ExprVisitor) { v.DoParenExpr(x); }
@ -393,7 +419,6 @@ func (x *StarExpr) Visit(v ExprVisitor) { v.DoStarExpr(x); }
func (x *UnaryExpr) Visit(v ExprVisitor) { v.DoUnaryExpr(x); } func (x *UnaryExpr) Visit(v ExprVisitor) { v.DoUnaryExpr(x); }
func (x *BinaryExpr) Visit(v ExprVisitor) { v.DoBinaryExpr(x); } func (x *BinaryExpr) Visit(v ExprVisitor) { v.DoBinaryExpr(x); }
func (x *Ellipsis) Visit(v ExprVisitor) { v.DoEllipsis(x); }
func (x *ArrayType) Visit(v ExprVisitor) { v.DoArrayType(x); } func (x *ArrayType) Visit(v ExprVisitor) { v.DoArrayType(x); }
func (x *SliceType) Visit(v ExprVisitor) { v.DoSliceType(x); } func (x *SliceType) Visit(v ExprVisitor) { v.DoSliceType(x); }
func (x *StructType) Visit(v ExprVisitor) { v.DoStructType(x); } func (x *StructType) Visit(v ExprVisitor) { v.DoStructType(x); }
@ -403,22 +428,6 @@ func (x *MapType) Visit(v ExprVisitor) { v.DoMapType(x); }
func (x *ChannelType) Visit(v ExprVisitor) { v.DoChannelType(x); } func (x *ChannelType) Visit(v ExprVisitor) { v.DoChannelType(x); }
// ----------------------------------------------------------------------------
// Blocks
// A Block represents syntactic constructs of the form:
//
// "{" StatementList "}"
// ":" StatementList
//
type Block struct {
Pos_ Position;
Tok int;
List []Stat;
Rparen Position; // position of closing "}" if present
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Statements // Statements
@ -426,236 +435,244 @@ type Block struct {
// or more of the following concrete statement nodes. // or more of the following concrete statement nodes.
// //
type ( type (
// A BadStat node is a placeholder for statements containing // A BadStmt node is a placeholder for statements containing
// syntax errors for which no correct statement nodes can be // syntax errors for which no correct statement nodes can be
// created. // created.
// //
BadStat struct { BadStmt struct {
Pos_ Position; // beginning position of bad statement Pos_ Position; // beginning position of bad statement
}; };
// A DeclStat node represents a declaration in a statement list. // A DeclStmt node represents a declaration in a statement list.
DeclStat struct { DeclStmt struct {
Decl Decl; Decl Decl;
}; };
// An EmptyStat node represents an empty statement. // An EmptyStmt node represents an empty statement.
// The "position" of the empty statement is the position // The "position" of the empty statement is the position
// of the immediately preceeding semicolon. // of the immediately preceeding semicolon.
// //
EmptyStat struct { EmptyStmt struct {
Semicolon Position; // position of preceeding ";" Semicolon Position; // position of preceeding ";"
}; };
// A LabeledStat node represents a labeled statement. // A LabeledStmt node represents a labeled statement.
LabeledStat struct { LabeledStmt struct {
Label *Ident; Label *Ident;
Stat Stat; Stmt Stmt;
}; };
// An ExprStat node represents a (stand-alone) expression // An ExprStmt node represents a (stand-alone) expression
// in a statement list. // in a statement list.
// //
ExprStat struct { ExprStmt struct {
X Expr; // expression X Expr; // expression
}; };
// An IncDecStat node represents an increment or decrement statement. // An IncDecStmt node represents an increment or decrement statement.
IncDecStat struct { IncDecStmt struct {
X Expr; X Expr;
Tok int; // INC or DEC Tok int; // INC or DEC
}; };
// An AssignmentStat node represents an assignment or // An AssignStmt node represents an assignment or
// a short variable declaration. // a short variable declaration.
AssignmentStat struct { AssignStmt struct {
Lhs []Expr; Lhs []Expr;
Pos_ Position; // token position Pos_ Position; // token position
Tok int; // assignment token, DEFINE Tok int; // assignment token, DEFINE
Rhs []Expr; Rhs []Expr;
}; };
// A GoStat node represents a go statement. // A GoStmt node represents a go statement.
GoStat struct { GoStmt struct {
Go Position; // position of "go" keyword Go Position; // position of "go" keyword
Call Expr; Call *CallExpr;
}; };
// A DeferStat node represents a defer statement. // A DeferStmt node represents a defer statement.
DeferStat struct { DeferStmt struct {
Defer Position; // position of "defer" keyword Defer Position; // position of "defer" keyword
Call Expr; Call *CallExpr;
}; };
// A ReturnStat node represents a return statement. // A ReturnStmt node represents a return statement.
ReturnStat struct { ReturnStmt struct {
Return Position; // position of "return" keyword Return Position; // position of "return" keyword
Results []Expr; Results []Expr;
}; };
// A ControlFlowStat node represents a break, continue, goto, // A BranchStmt node represents a break, continue, goto,
// or fallthrough statement. // or fallthrough statement.
// //
ControlFlowStat struct { BranchStmt struct {
Pos_ Position; // position of keyword Pos_ Position; // position of keyword
Tok int; // keyword token (BREAK, CONTINUE, GOTO, FALLTHROUGH) Tok int; // keyword token (BREAK, CONTINUE, GOTO, FALLTHROUGH)
Label *Ident; Label *Ident;
}; };
// A CompositeStat node represents a braced statement list. // A BlockStmt node represents a braced statement list.
CompositeStat struct { BlockStmt struct {
Body *Block; Lbrace Position;
List []Stmt;
Rbrace Position;
}; };
// An IfStat node represents an if statement. // An IfStmt node represents an if statement.
IfStat struct { IfStmt struct {
If Position; // position of "if" keyword If Position; // position of "if" keyword
Init Stat; Init Stmt;
Cond Expr; Cond Expr;
Body *Block; Body *BlockStmt;
Else Stat; Else Stmt;
}; };
// A CaseClause represents a case of an expression switch statement. // A CaseClause represents a case of an expression switch statement.
CaseClause struct { CaseClause struct {
Case Position; // position of "case" or "default" keyword Case Position; // position of "case" or "default" keyword
Values []Expr; // nil means default case Values []Expr; // nil means default case
Body *Block; Colon Position; // position of ":"
Body []Stmt; // statement list; or nil
}; };
// A SwitchStat node represents an expression switch statement. // A SwitchStmt node represents an expression switch statement.
SwitchStat struct { SwitchStmt struct {
Switch Position; // position of "switch" keyword Switch Position; // position of "switch" keyword
Init Stat; Init Stmt;
Tag Expr; Tag Expr;
Body *Block; // CaseClauses only Body *BlockStmt; // CaseClauses only
}; };
// A TypeCaseClause represents a case of a type switch statement. // A TypeCaseClause represents a case of a type switch statement.
TypeCaseClause struct { TypeCaseClause struct {
Case Position; // position of "case" or "default" keyword Case Position; // position of "case" or "default" keyword
Typ Expr; // nil means default case Type Expr; // nil means default case
Body *Block; Colon Position; // position of ":"
Body []Stmt; // statement list; or nil
}; };
// An TypeSwitchStat node represents a type switch statement. // An TypeSwitchStmt node represents a type switch statement.
TypeSwitchStat struct { TypeSwitchStmt struct {
Switch Position; // position of "switch" keyword Switch Position; // position of "switch" keyword
Init Stat; Init Stmt;
Assign Stat; // x := y.(type) Assign Stmt; // x := y.(type)
Body *Block; // TypeCaseClauses only Body *BlockStmt; // TypeCaseClauses only
}; };
// A CommClause node represents a case of a select statement. // A CommClause node represents a case of a select statement.
CommClause struct { CommClause struct {
Case Position; // position of "case" or "default" keyword Case Position; // position of "case" or "default" keyword
Tok int; // ASSIGN, DEFINE (valid only if Lhs != nil) Tok int; // ASSIGN or DEFINE (valid only if Lhs != nil)
Lhs, Rhs Expr; // Rhs == nil means default case Lhs, Rhs Expr; // Rhs == nil means default case
Body *Block; Colon Position; // position of ":"
Body []Stmt; // statement list; or nil
}; };
// An SelectStat node represents a select statement. // An SelectStmt node represents a select statement.
SelectStat struct { SelectStmt struct {
Select Position; // position of "select" keyword Select Position; // position of "select" keyword
Body *Block; // CommClauses only Body *BlockStmt; // CommClauses only
}; };
// A ForStat represents a for statement. // A ForStmt represents a for statement.
ForStat struct { ForStmt struct {
For Position; // position of "for" keyword For Position; // position of "for" keyword
Init Stat; Init Stmt;
Cond Expr; Cond Expr;
Post Stat; Post Stmt;
Body *Block; Body *BlockStmt;
}; };
// A RangeStat represents a for statement with a range clause. // A RangeStmt represents a for statement with a range clause.
RangeStat struct { RangeStmt struct {
For Position; // position of "for" keyword For Position; // position of "for" keyword
Range Stat; Key, Value Expr; // Value may be nil
Body *Block; Pos_ Position; // token position
Tok int; // ASSIGN or DEFINE
X Expr; // value to range over
Body *BlockStmt;
}; };
) )
// Pos() implementations for all statement nodes. // Pos() implementations for all statement nodes.
// //
func (s *BadStat) Pos() Position { return s.Pos_; } func (s *BadStmt) Pos() Position { return s.Pos_; }
func (s *DeclStat) Pos() Position { return s.Decl.Pos(); } func (s *DeclStmt) Pos() Position { return s.Decl.Pos(); }
func (s *EmptyStat) Pos() Position { return s.Semicolon; } func (s *EmptyStmt) Pos() Position { return s.Semicolon; }
func (s *LabeledStat) Pos() Position { return s.Label.Pos(); } func (s *LabeledStmt) Pos() Position { return s.Label.Pos(); }
func (s *ExprStat) Pos() Position { return s.X.Pos(); } func (s *ExprStmt) Pos() Position { return s.X.Pos(); }
func (s *IncDecStat) Pos() Position { return s.X.Pos(); } func (s *IncDecStmt) Pos() Position { return s.X.Pos(); }
func (s *AssignmentStat) Pos() Position { return s.Lhs[0].Pos(); } func (s *AssignStmt) Pos() Position { return s.Lhs[0].Pos(); }
func (s *GoStat) Pos() Position { return s.Go; } func (s *GoStmt) Pos() Position { return s.Go; }
func (s *DeferStat) Pos() Position { return s.Defer; } func (s *DeferStmt) Pos() Position { return s.Defer; }
func (s *ReturnStat) Pos() Position { return s.Return; } func (s *ReturnStmt) Pos() Position { return s.Return; }
func (s *ControlFlowStat) Pos() Position { return s.Pos_; } func (s *BranchStmt) Pos() Position { return s.Pos_; }
func (s *CompositeStat) Pos() Position { return s.Body.Pos_; } func (s *BlockStmt) Pos() Position { return s.Lbrace; }
func (s *IfStat) Pos() Position { return s.If; } func (s *IfStmt) Pos() Position { return s.If; }
func (s *CaseClause) Pos() Position { return s.Case; } func (s *CaseClause) Pos() Position { return s.Case; }
func (s *SwitchStat) Pos() Position { return s.Switch; } func (s *SwitchStmt) Pos() Position { return s.Switch; }
func (s *TypeCaseClause) Pos() Position { return s.Case; } func (s *TypeCaseClause) Pos() Position { return s.Case; }
func (s *TypeSwitchStat) Pos() Position { return s.Switch; } func (s *TypeSwitchStmt) Pos() Position { return s.Switch; }
func (s *CommClause) Pos() Position { return s.Case; } func (s *CommClause) Pos() Position { return s.Case; }
func (s *SelectStat) Pos() Position { return s.Select; } func (s *SelectStmt) Pos() Position { return s.Select; }
func (s *ForStat) Pos() Position { return s.For; } func (s *ForStmt) Pos() Position { return s.For; }
func (s *RangeStat) Pos() Position { return s.For; } func (s *RangeStmt) Pos() Position { return s.For; }
// All statement nodes implement a Visit method which takes // All statement nodes implement a Visit method which takes
// a StatVisitor as argument. For a given node x of type X, and // a StmtVisitor as argument. For a given node x of type X, and
// an implementation v of a StatVisitor, calling x.Visit(v) will // an implementation v of a StmtVisitor, calling x.Visit(v) will
// result in a call of v.DoX(x) (through a double-dispatch). // result in a call of v.DoX(x) (through a double-dispatch).
// //
type StatVisitor interface { type StmtVisitor interface {
DoBadStat(s *BadStat); DoBadStmt(s *BadStmt);
DoDeclStat(s *DeclStat); DoDeclStmt(s *DeclStmt);
DoEmptyStat(s *EmptyStat); DoEmptyStmt(s *EmptyStmt);
DoLabeledStat(s *LabeledStat); DoLabeledStmt(s *LabeledStmt);
DoExprStat(s *ExprStat); DoExprStmt(s *ExprStmt);
DoIncDecStat(s *IncDecStat); DoIncDecStmt(s *IncDecStmt);
DoAssignmentStat(s *AssignmentStat); DoAssignStmt(s *AssignStmt);
DoGoStat(s *GoStat); DoGoStmt(s *GoStmt);
DoDeferStat(s *DeferStat); DoDeferStmt(s *DeferStmt);
DoReturnStat(s *ReturnStat); DoReturnStmt(s *ReturnStmt);
DoControlFlowStat(s *ControlFlowStat); DoBranchStmt(s *BranchStmt);
DoCompositeStat(s *CompositeStat); DoBlockStmt(s *BlockStmt);
DoIfStat(s *IfStat); DoIfStmt(s *IfStmt);
DoCaseClause(s *CaseClause); DoCaseClause(s *CaseClause);
DoSwitchStat(s *SwitchStat); DoSwitchStmt(s *SwitchStmt);
DoTypeCaseClause(s *TypeCaseClause); DoTypeCaseClause(s *TypeCaseClause);
DoTypeSwitchStat(s *TypeSwitchStat); DoTypeSwitchStmt(s *TypeSwitchStmt);
DoCommClause(s *CommClause); DoCommClause(s *CommClause);
DoSelectStat(s *SelectStat); DoSelectStmt(s *SelectStmt);
DoForStat(s *ForStat); DoForStmt(s *ForStmt);
DoRangeStat(s *RangeStat); DoRangeStmt(s *RangeStmt);
} }
// Visit() implementations for all statement nodes. // Visit() implementations for all statement nodes.
// //
func (s *BadStat) Visit(v StatVisitor) { v.DoBadStat(s); } func (s *BadStmt) Visit(v StmtVisitor) { v.DoBadStmt(s); }
func (s *DeclStat) Visit(v StatVisitor) { v.DoDeclStat(s); } func (s *DeclStmt) Visit(v StmtVisitor) { v.DoDeclStmt(s); }
func (s *EmptyStat) Visit(v StatVisitor) { v.DoEmptyStat(s); } func (s *EmptyStmt) Visit(v StmtVisitor) { v.DoEmptyStmt(s); }
func (s *LabeledStat) Visit(v StatVisitor) { v.DoLabeledStat(s); } func (s *LabeledStmt) Visit(v StmtVisitor) { v.DoLabeledStmt(s); }
func (s *ExprStat) Visit(v StatVisitor) { v.DoExprStat(s); } func (s *ExprStmt) Visit(v StmtVisitor) { v.DoExprStmt(s); }
func (s *IncDecStat) Visit(v StatVisitor) { v.DoIncDecStat(s); } func (s *IncDecStmt) Visit(v StmtVisitor) { v.DoIncDecStmt(s); }
func (s *AssignmentStat) Visit(v StatVisitor) { v.DoAssignmentStat(s); } func (s *AssignStmt) Visit(v StmtVisitor) { v.DoAssignStmt(s); }
func (s *GoStat) Visit(v StatVisitor) { v.DoGoStat(s); } func (s *GoStmt) Visit(v StmtVisitor) { v.DoGoStmt(s); }
func (s *DeferStat) Visit(v StatVisitor) { v.DoDeferStat(s); } func (s *DeferStmt) Visit(v StmtVisitor) { v.DoDeferStmt(s); }
func (s *ReturnStat) Visit(v StatVisitor) { v.DoReturnStat(s); } func (s *ReturnStmt) Visit(v StmtVisitor) { v.DoReturnStmt(s); }
func (s *ControlFlowStat) Visit(v StatVisitor) { v.DoControlFlowStat(s); } func (s *BranchStmt) Visit(v StmtVisitor) { v.DoBranchStmt(s); }
func (s *CompositeStat) Visit(v StatVisitor) { v.DoCompositeStat(s); } func (s *BlockStmt) Visit(v StmtVisitor) { v.DoBlockStmt(s); }
func (s *IfStat) Visit(v StatVisitor) { v.DoIfStat(s); } func (s *IfStmt) Visit(v StmtVisitor) { v.DoIfStmt(s); }
func (s *CaseClause) Visit(v StatVisitor) { v.DoCaseClause(s); } func (s *CaseClause) Visit(v StmtVisitor) { v.DoCaseClause(s); }
func (s *SwitchStat) Visit(v StatVisitor) { v.DoSwitchStat(s); } func (s *SwitchStmt) Visit(v StmtVisitor) { v.DoSwitchStmt(s); }
func (s *TypeCaseClause) Visit(v StatVisitor) { v.DoTypeCaseClause(s); } func (s *TypeCaseClause) Visit(v StmtVisitor) { v.DoTypeCaseClause(s); }
func (s *TypeSwitchStat) Visit(v StatVisitor) { v.DoTypeSwitchStat(s); } func (s *TypeSwitchStmt) Visit(v StmtVisitor) { v.DoTypeSwitchStmt(s); }
func (s *CommClause) Visit(v StatVisitor) { v.DoCommClause(s); } func (s *CommClause) Visit(v StmtVisitor) { v.DoCommClause(s); }
func (s *SelectStat) Visit(v StatVisitor) { v.DoSelectStat(s); } func (s *SelectStmt) Visit(v StmtVisitor) { v.DoSelectStmt(s); }
func (s *ForStat) Visit(v StatVisitor) { v.DoForStat(s); } func (s *ForStmt) Visit(v StmtVisitor) { v.DoForStmt(s); }
func (s *RangeStat) Visit(v StatVisitor) { v.DoRangeStat(s); } func (s *RangeStmt) Visit(v StmtVisitor) { v.DoRangeStmt(s); }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -673,46 +690,45 @@ type (
}; };
ImportDecl struct { ImportDecl struct {
Doc Comments; // associated documentation Doc Comments; // associated documentation; or nil
Import Position; // position of "import" keyword Import Position; // position of "import" keyword
Name *Ident; // local package name or nil Name *Ident; // local package name or nil
Path *StringLit; // package path Path []*StringLit; // package path
}; };
ConstDecl struct { ConstDecl struct {
Doc Comments; // associated documentation Doc Comments; // associated documentation; or nil
Const Position; // position of "const" keyword Const Position; // position of "const" keyword
Names []*Ident; Names []*Ident;
Typ Expr; // constant type or nil Type Expr; // constant type or nil
Values []Expr; Values []Expr;
}; };
TypeDecl struct { TypeDecl struct {
Doc Comments; // associated documentation Doc Comments; // associated documentation; or nil
Type Position; // position of "type" keyword Pos_ Position; // position of "type" keyword
Name *Ident; Name *Ident;
Typ Expr; Type Expr;
}; };
VarDecl struct { VarDecl struct {
Doc Comments; // associated documentation Doc Comments; // associated documentation; or nil
Var Position; // position of "var" keyword Var Position; // position of "var" keyword
Names []*Ident; Names []*Ident;
Typ Expr; // variable type or nil Type Expr; // variable type or nil
Values []Expr; Values []Expr;
}; };
FuncDecl struct { FuncDecl struct {
Doc Comments; // associated documentation Doc Comments; // associated documentation; or nil
Func Position; // position of "func" keyword
Recv *Field; // receiver (methods) or nil (functions) Recv *Field; // receiver (methods) or nil (functions)
Name *Ident; // function/method name Name *Ident; // function/method name
Sig *Signature; // parameters and results Type *FunctionType; // position of Func keyword, parameters and results
Body *Block; // function body or nil (forward declaration) Body *BlockStmt; // function body or nil (forward declaration)
}; };
DeclList struct { DeclList struct {
Doc Comments; // associated documentation Doc Comments; // associated documentation; or nil
Pos_ Position; // position of token Pos_ Position; // position of token
Tok int; // IMPORT, CONST, VAR, TYPE Tok int; // IMPORT, CONST, VAR, TYPE
Lparen Position; // position of '(' Lparen Position; // position of '('
@ -727,9 +743,9 @@ type (
func (d *BadDecl) Pos() Position { return d.Pos_; } func (d *BadDecl) Pos() Position { return d.Pos_; }
func (d *ImportDecl) Pos() Position { return d.Import; } func (d *ImportDecl) Pos() Position { return d.Import; }
func (d *ConstDecl) Pos() Position { return d.Const; } func (d *ConstDecl) Pos() Position { return d.Const; }
func (d *TypeDecl) Pos() Position { return d.Type; } func (d *TypeDecl) Pos() Position { return d.Pos_; }
func (d *VarDecl) Pos() Position { return d.Var; } func (d *VarDecl) Pos() Position { return d.Var; }
func (d *FuncDecl) Pos() Position { return d.Func; } func (d *FuncDecl) Pos() Position { return d.Type.Func; }
func (d *DeclList) Pos() Position { return d.Lparen; } func (d *DeclList) Pos() Position { return d.Lparen; }
@ -765,7 +781,7 @@ func (d *DeclList) Visit(v DeclVisitor) { v.DoDeclList(d); }
// A Package node represents the root node of an AST. // A Package node represents the root node of an AST.
type Package struct { type Package struct {
Doc Comments; // associated documentation Doc Comments; // associated documentation; or nil
Package Position; // position of "package" keyword Package Position; // position of "package" keyword
Name *Ident; // package name Name *Ident; // package name
Decls []Decl; // top-level declarations Decls []Decl; // top-level declarations