Commit f6faa9de authored by Robert Griesemer's avatar Robert Griesemer

more cleanup

parent 0d17ebde
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This is the datafmt format file for printing AST nodes.
// It is used by go/ast/format.go. It assumes that the output
// is fed through a tabwriter.Writer for proper alignment.
// Form feed chars ('\f') are used to control the tabwriter's
// column formatting.
// TODO change these to "go/ast", "go/token" once
// the full path is returned by reflection
ast "ast";
token "token";
// ----------------------------------------------------------------------------
// Custom formatters
//
// TODO should be able to reduce this number/find better primitives
// The following formatters are defined in go/ast/format.go:
//
// allCode
// setComments
// isVisible (currently not used)
// isValidPos
// isParenResult
// isSend
// isRecv
// writeComment
// clearOptSemi
// setOptSemi
// optSemi
// token.Position
// ----------------------------------------------------------------------------
// Basic types, support rules
array =
*;
bytes =
{*};
char =
"%c";
interface =
*;
ptr =
*;
string =
"%s";
empty =
;
exists =
*:empty;
// ----------------------------------------------------------------------------
// Tokens and comments
token.Token =
@:string;
ast.Comment =
Position Text:writeComment;
ast.Comments =
{*};
// ----------------------------------------------------------------------------
// Expressions & Types
ast.Field =
[Names:exists {Names / ", "} "\t"] Type ["\t" Tag];
ast.Expr =
*;
ast.BadExpr =
Position "BAD EXPR";
ast.Ident =
Position Value;
ast.Ellipsis =
Position "...";
ast.IntLit =
Position Value:string;
ast.FloatLit =
Position Value:string;
ast.CharLit =
Position Value:string;
ast.StringLit =
Position Value:string;
ast.StringList =
{Strings / "\n"};
ast.FuncLit =
Type " " Body @:clearOptSemi; // no optional ; after a func literal body
ast.CompositeLit =
Type Lbrace "{" {Elts / ", "} Rbrace "}";
ast.ParenExpr =
Position "(" X ")";
ast.SelectorExpr =
X "." Sel;
ast.IndexExpr =
X "[" Index [" : " End] "]";
ast.TypeAssertExpr =
X ".(" Type ")";
ast.CallExpr =
Fun Lparen "(" {Args / ", "} Rparen ")";
ast.StarExpr =
Position "*" X;
ast.UnaryExpr =
Position Op X;
ast.BinaryExpr =
X " " OpPos Op " " Y;
ast.KeyValueExpr =
Key Colon ": " Value;
ast.ArrayType =
Position "[" [Len] "]" Elt;
ast.StructType =
Position "struct"
[Lbrace:isValidPos " " Lbrace "{"]
[ Fields:exists
( "\t" >> "\f"
{Fields / ";\n"}
) "\n"
]
[Rbrace:isValidPos Rbrace "}"];
signature =
"(" {Params / ", "} ")"
[ Results:exists " "
( Results:isParenResult "(" {Results / ", "} ")"
| {Results}
)
];
funcSignature =
*:signature;
ast.FuncType =
[Position:isValidPos Position "func"] @:signature;
ast.InterfaceType =
Position "interface"
[Lbrace:isValidPos " " Lbrace "{"]
[ Methods:exists
( "\t" >> "\f"
{Methods / ";\n"}
) "\n"
]
[Rbrace:isValidPos Rbrace "}"];
ast.MapType =
Position "map[" Key "]" Value;
ast.ChanType =
Position
( Dir:isSend Dir:isRecv
"chan "
| Dir:isSend
"chan <- "
| "<-chan "
)
Value;
// ----------------------------------------------------------------------------
// Statements
ast.Stmt =
*;
ast.BadStmt =
Position "BAD STMT";
ast.DeclStmt =
Decl;
ast.EmptyStmt =
Position ;
ast.LabeledStmt =
Label ":\t" Stmt;
ast.ExprStmt =
X;
ast.IncDecStmt =
X Tok;
ast.AssignStmt =
{Lhs / ", "} " " TokPos Tok " " {Rhs / ", "};
ast.GoStmt =
Position "go " Call;
ast.DeferStmt =
Position "defer " Call;
ast.ReturnStmt =
Position "return" {" " Results / ","};
ast.BranchStmt =
Position Tok [" " Label];
stmtList =
{@ / @:optSemi "\n"};
blockStmt = // like ast.BlockStmt but w/o indentation
"{"
[List:exists
"\f"
List:stmtList
"\n"
]
"}" @:setOptSemi;
blockStmtPtr =
*:blockStmt;
ast.BlockStmt =
Position "{"
[List:exists
( "\t" >> "\f"
List:stmtList
) "\n"
]
Rbrace "}" @:setOptSemi;
ast.IfStmt =
Position "if " [Init "; "] [Cond " "] Body [" else " Else];
ast.CaseClause =
// TODO the code below should work with () instead of []
// but doesn't (after first case, always default is
// selected).
Position
[ Values:exists "case " {Values / ", "}
| "default"
]
Colon ":"
[Body:exists
( "\t" >> "\n"
Body:stmtList
)
];
ast.SwitchStmt =
Position "switch " [Init "; "] [Tag " "]
Body:blockStmtPtr;
ast.TypeCaseClause =
Position
( Type:exists "case " Type
| "default"
)
Colon ":"
[Body:exists
( "\t" >> "\n"
Body:stmtList
)
];
ast.TypeSwitchStmt =
Position "switch " Assign " "
Body:blockStmtPtr;
ast.CommClause =
Position
( "case " [Lhs " " Tok " "] Rhs
| "default"
)
Colon ":"
[Body:exists
( "\t" >> "\n"
Body:stmtList
)
];
ast.SelectStmt =
Position "select "
Body:blockStmtPtr;
ast.ForStmt =
"for "
[ (Init:exists | Post:exists)
[Init] "; " [Cond] "; " [Post " "]
| Cond " "
]
Body;
ast.RangeStmt =
Position "for " Key [", " Value] " " TokPos Tok " range " X
" "
Body;
// ----------------------------------------------------------------------------
// Declarations
ast.Spec =
*;
ast.ImportSpec =
[@:allCode Doc]
[Name] "\t" {Path};
ast.ValueSpec =
{Names / ", "} ["\t" Type] [Values:exists "\t= " {Values / ", "}];
ast.TypeSpec =
Name "\t" Type;
ast.Decl =
*;
ast.BadDecl =
Position "BAD DECL";
ast.GenDecl =
[@:allCode Doc]
Position Tok " "
( Lparen:isValidPos Lparen "("
[Specs:exists
( "\t" >> "\f"
{Specs / ";\n"}
) "\n"
]
Rparen ")" @:setOptSemi
| {Specs / ";\n"}
);
funcKeyword =
Position "func ";
funcTypePtr =
*:funcKeyword;
ast.FuncDecl =
[@:allCode Doc]
Type:funcTypePtr ["(" Recv ") "] Name Type:funcSignature
[@:allCode " " Body]
"\n";
// ----------------------------------------------------------------------------
// Program
ast.Program =
Comments:setComments
""
[@:allCode Doc]
Position "package " Name "\n\n"
{Decls / "\n\n"}
"\n"; // TODO necessary because tabwriter.Flush doesn't format last line correctly - fix this
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