// 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. // Format file for printing AST nodes (package "ast"). // ---------------------------------------------------------------------------- // Elementary types token.Token = ^:string; array = *; pointer = *; string = "%s"; char = "%c"; bytes = {*}; empty = ; exists = *:empty; // ---------------------------------------------------------------------------- // TODO these are implicit - only here for debugging ast.Expr = *; ast.Stmt = *; ast.Decl = *; // ---------------------------------------------------------------------------- // Comments ast.Comment = Text:string [Text:isMultiLineComment "\n"]; ast.Comments = {*}; // ---------------------------------------------------------------------------- // Expressions & Types ast.Field = [Names:exists {Names / ", "} " "] Type; ast.BadExpr = "BAD EXPR"; ast.Ident = Value; ast.Ellipsis = "..."; ast.IntLit = Value:string; ast.FloatLit = Value:string; ast.CharLit = Value:string; ast.StringLit = Value:string; ast.StringList = {Strings / "\n"}; ast.FuncLit = Type " " Body; ast.CompositeLit = Type "{" {Elts / ", "} "}"; ast.ParenExpr = "(" X ")"; ast.SelectorExpr = X "." Sel; ast.IndexExpr = X "[" Index [":" End] "]"; ast.TypeAssertExpr = X ".(" Type ")"; ast.CallExpr = Fun "(" {Args / ", "} ")"; ast.StarExpr = "*" X; ast.UnaryExpr = Op X; ast.BinaryExpr = X " " Op " " Y; ast.KeyValueExpr = Key ": " Value; ast.ArrayType = "[" [Len] "]" Elt; ast.StructType = "struct" [Lbrace:isValidPos " {"] [ Fields:exists >> "\t" "\n" {Fields / ";\n"} << "\n" ] [Rbrace:isValidPos "}"]; signature = "(" {Params / ", "} ")" [Results:exists " (" {Results / ", "} ")"]; funcSignature = *:signature; ast.FuncType = [Position:isValidPos "func"] ^:signature; ast.InterfaceType = "interface" [Lbrace:isValidPos " {"] [ Methods:exists >> "\t" "\n" {Methods / ";\n"} << "\n" ] [Rbrace:isValidPos "}"]; ast.MapType = "map[" Key "]" Value; ast.ChanType = ( Dir:isSend Dir:isRecv "chan " | Dir:isSend "chan <- " | "<-chan " ) Value; // ---------------------------------------------------------------------------- // Statements ast.BadStmt = "BAD STMT"; ast.DeclStmt = Decl; ast.EmptyStmt = ; ast.LabeledStmt = Label ":\t" Stmt; ast.ExprStmt = X; ast.IncDecStmt = X Tok; ast.AssignStmt = {Lhs / ", "} " " Tok " " {Rhs / ", "}; ast.GoStmt = "go " Call; ast.DeferStmt = "defer " Call; ast.ReturnStmt = "return" {" " Results / ","}; ast.BranchStmt = Tok [" " Label]; blockStmt = // like ast.BlockStmt but w/o indentation "{" [List:exists "\n" {List / ";\n"} "\n" ] "}"; blockStmtPtr = *:blockStmt; ast.BlockStmt = "{" [List:exists >> "\t" "\n" {List / ";\n"} << "\n" ] "}"; ast.IfStmt = "if " [Init "; "] [Cond " "] Body [" else " Else]; ast.CaseClause = ( Values:exists "case " {Values / ", "} | "default" ) ":" [Body:exists >> "\t" "\n" {Body / ";\n"} << ]; ast.SwitchStmt = "switch " [Init "; "] [Tag " "] Body:blockStmtPtr; ast.TypeCaseClause = ( Type:exists "case " Type | "default" ) ":" [Body:exists >> "\t" "\n" {Body / ";\n"} << ]; ast.TypeSwitchStmt = "switch " Assign " " Body:blockStmtPtr; ast.CommClause = ( "case " [Lhs " " Tok " "] Rhs | "default" ) ":" [Body:exists >> "\t" "\n" {Body / ";\n"} << ]; ast.SelectStmt = "select " Body:blockStmtPtr; ast.ForStmt = "for " [ (Init:exists | Post:exists) [Init] "; " [Cond] "; " [Post " "] | Cond " " ] Body; ast.RangeStmt = "for " Key [", " Value] " " Tok " range " X " " Body; // ---------------------------------------------------------------------------- // Declarations ast.Spec = *; ast.ImportSpec = Doc [Name] "\t" {Path}; ast.ValueSpec = {Names / ", "} [" " Type] [Values:exists " = " {Values / ", "}]; ast.TypeSpec = Name " " // TODO using "\t" instead of " " screws up struct field alignment Type; ast.BadDecl = "BAD DECL"; ast.GenDecl = Doc Tok " " ( Lparen:isValidPos >> "\t" "(\n" {Specs / ";\n"} << "\n)" | {Specs / ";\n"} ); ast.FuncDecl = "func " ["(" Recv ") "] Name Type:funcSignature [" " Body] "\n"; // ---------------------------------------------------------------------------- // Program ast.Program = Doc "package " Name "\n\n" {Decls / "\n\n"};