summaryrefslogtreecommitdiffstats
path: root/src/cmd/compile/internal/syntax/nodes.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/syntax/nodes.go')
-rw-r--r--src/cmd/compile/internal/syntax/nodes.go469
1 files changed, 469 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/syntax/nodes.go b/src/cmd/compile/internal/syntax/nodes.go
new file mode 100644
index 0000000..815630f
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/nodes.go
@@ -0,0 +1,469 @@
+// Copyright 2016 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.
+
+package syntax
+
+// ----------------------------------------------------------------------------
+// Nodes
+
+type Node interface {
+ // Pos() returns the position associated with the node as follows:
+ // 1) The position of a node representing a terminal syntax production
+ // (Name, BasicLit, etc.) is the position of the respective production
+ // in the source.
+ // 2) The position of a node representing a non-terminal production
+ // (IndexExpr, IfStmt, etc.) is the position of a token uniquely
+ // associated with that production; usually the left-most one
+ // ('[' for IndexExpr, 'if' for IfStmt, etc.)
+ Pos() Pos
+ aNode()
+}
+
+type node struct {
+ // commented out for now since not yet used
+ // doc *Comment // nil means no comment(s) attached
+ pos Pos
+}
+
+func (n *node) Pos() Pos { return n.pos }
+func (*node) aNode() {}
+
+// ----------------------------------------------------------------------------
+// Files
+
+// package PkgName; DeclList[0], DeclList[1], ...
+type File struct {
+ Pragma Pragma
+ PkgName *Name
+ DeclList []Decl
+ Lines uint
+ node
+}
+
+// ----------------------------------------------------------------------------
+// Declarations
+
+type (
+ Decl interface {
+ Node
+ aDecl()
+ }
+
+ // Path
+ // LocalPkgName Path
+ ImportDecl struct {
+ Group *Group // nil means not part of a group
+ Pragma Pragma
+ LocalPkgName *Name // including "."; nil means no rename present
+ Path *BasicLit
+ decl
+ }
+
+ // NameList
+ // NameList = Values
+ // NameList Type = Values
+ ConstDecl struct {
+ Group *Group // nil means not part of a group
+ Pragma Pragma
+ NameList []*Name
+ Type Expr // nil means no type
+ Values Expr // nil means no values
+ decl
+ }
+
+ // Name Type
+ TypeDecl struct {
+ Group *Group // nil means not part of a group
+ Pragma Pragma
+ Name *Name
+ Alias bool
+ Type Expr
+ decl
+ }
+
+ // NameList Type
+ // NameList Type = Values
+ // NameList = Values
+ VarDecl struct {
+ Group *Group // nil means not part of a group
+ Pragma Pragma
+ NameList []*Name
+ Type Expr // nil means no type
+ Values Expr // nil means no values
+ decl
+ }
+
+ // func Name Type { Body }
+ // func Name Type
+ // func Receiver Name Type { Body }
+ // func Receiver Name Type
+ FuncDecl struct {
+ Pragma Pragma
+ Recv *Field // nil means regular function
+ Name *Name
+ Type *FuncType
+ Body *BlockStmt // nil means no body (forward declaration)
+ decl
+ }
+)
+
+type decl struct{ node }
+
+func (*decl) aDecl() {}
+
+// All declarations belonging to the same group point to the same Group node.
+type Group struct {
+ dummy int // not empty so we are guaranteed different Group instances
+}
+
+// ----------------------------------------------------------------------------
+// Expressions
+
+type (
+ Expr interface {
+ Node
+ aExpr()
+ }
+
+ // Placeholder for an expression that failed to parse
+ // correctly and where we can't provide a better node.
+ BadExpr struct {
+ expr
+ }
+
+ // Value
+ Name struct {
+ Value string
+ expr
+ }
+
+ // Value
+ BasicLit struct {
+ Value string
+ Kind LitKind
+ Bad bool // true means the literal Value has syntax errors
+ expr
+ }
+
+ // Type { ElemList[0], ElemList[1], ... }
+ CompositeLit struct {
+ Type Expr // nil means no literal type
+ ElemList []Expr
+ NKeys int // number of elements with keys
+ Rbrace Pos
+ expr
+ }
+
+ // Key: Value
+ KeyValueExpr struct {
+ Key, Value Expr
+ expr
+ }
+
+ // func Type { Body }
+ FuncLit struct {
+ Type *FuncType
+ Body *BlockStmt
+ expr
+ }
+
+ // (X)
+ ParenExpr struct {
+ X Expr
+ expr
+ }
+
+ // X.Sel
+ SelectorExpr struct {
+ X Expr
+ Sel *Name
+ expr
+ }
+
+ // X[Index]
+ IndexExpr struct {
+ X Expr
+ Index Expr
+ expr
+ }
+
+ // X[Index[0] : Index[1] : Index[2]]
+ SliceExpr struct {
+ X Expr
+ Index [3]Expr
+ // Full indicates whether this is a simple or full slice expression.
+ // In a valid AST, this is equivalent to Index[2] != nil.
+ // TODO(mdempsky): This is only needed to report the "3-index
+ // slice of string" error when Index[2] is missing.
+ Full bool
+ expr
+ }
+
+ // X.(Type)
+ AssertExpr struct {
+ X Expr
+ Type Expr
+ expr
+ }
+
+ // X.(type)
+ // Lhs := X.(type)
+ TypeSwitchGuard struct {
+ Lhs *Name // nil means no Lhs :=
+ X Expr // X.(type)
+ expr
+ }
+
+ Operation struct {
+ Op Operator
+ X, Y Expr // Y == nil means unary expression
+ expr
+ }
+
+ // Fun(ArgList[0], ArgList[1], ...)
+ CallExpr struct {
+ Fun Expr
+ ArgList []Expr // nil means no arguments
+ HasDots bool // last argument is followed by ...
+ expr
+ }
+
+ // ElemList[0], ElemList[1], ...
+ ListExpr struct {
+ ElemList []Expr
+ expr
+ }
+
+ // [Len]Elem
+ ArrayType struct {
+ // TODO(gri) consider using Name{"..."} instead of nil (permits attaching of comments)
+ Len Expr // nil means Len is ...
+ Elem Expr
+ expr
+ }
+
+ // []Elem
+ SliceType struct {
+ Elem Expr
+ expr
+ }
+
+ // ...Elem
+ DotsType struct {
+ Elem Expr
+ expr
+ }
+
+ // struct { FieldList[0] TagList[0]; FieldList[1] TagList[1]; ... }
+ StructType struct {
+ FieldList []*Field
+ TagList []*BasicLit // i >= len(TagList) || TagList[i] == nil means no tag for field i
+ expr
+ }
+
+ // Name Type
+ // Type
+ Field struct {
+ Name *Name // nil means anonymous field/parameter (structs/parameters), or embedded interface (interfaces)
+ Type Expr // field names declared in a list share the same Type (identical pointers)
+ node
+ }
+
+ // interface { MethodList[0]; MethodList[1]; ... }
+ InterfaceType struct {
+ MethodList []*Field
+ expr
+ }
+
+ FuncType struct {
+ ParamList []*Field
+ ResultList []*Field
+ expr
+ }
+
+ // map[Key]Value
+ MapType struct {
+ Key, Value Expr
+ expr
+ }
+
+ // chan Elem
+ // <-chan Elem
+ // chan<- Elem
+ ChanType struct {
+ Dir ChanDir // 0 means no direction
+ Elem Expr
+ expr
+ }
+)
+
+type expr struct{ node }
+
+func (*expr) aExpr() {}
+
+type ChanDir uint
+
+const (
+ _ ChanDir = iota
+ SendOnly
+ RecvOnly
+)
+
+// ----------------------------------------------------------------------------
+// Statements
+
+type (
+ Stmt interface {
+ Node
+ aStmt()
+ }
+
+ SimpleStmt interface {
+ Stmt
+ aSimpleStmt()
+ }
+
+ EmptyStmt struct {
+ simpleStmt
+ }
+
+ LabeledStmt struct {
+ Label *Name
+ Stmt Stmt
+ stmt
+ }
+
+ BlockStmt struct {
+ List []Stmt
+ Rbrace Pos
+ stmt
+ }
+
+ ExprStmt struct {
+ X Expr
+ simpleStmt
+ }
+
+ SendStmt struct {
+ Chan, Value Expr // Chan <- Value
+ simpleStmt
+ }
+
+ DeclStmt struct {
+ DeclList []Decl
+ stmt
+ }
+
+ AssignStmt struct {
+ Op Operator // 0 means no operation
+ Lhs, Rhs Expr // Rhs == ImplicitOne means Lhs++ (Op == Add) or Lhs-- (Op == Sub)
+ simpleStmt
+ }
+
+ BranchStmt struct {
+ Tok token // Break, Continue, Fallthrough, or Goto
+ Label *Name
+ // Target is the continuation of the control flow after executing
+ // the branch; it is computed by the parser if CheckBranches is set.
+ // Target is a *LabeledStmt for gotos, and a *SwitchStmt, *SelectStmt,
+ // or *ForStmt for breaks and continues, depending on the context of
+ // the branch. Target is not set for fallthroughs.
+ Target Stmt
+ stmt
+ }
+
+ CallStmt struct {
+ Tok token // Go or Defer
+ Call *CallExpr
+ stmt
+ }
+
+ ReturnStmt struct {
+ Results Expr // nil means no explicit return values
+ stmt
+ }
+
+ IfStmt struct {
+ Init SimpleStmt
+ Cond Expr
+ Then *BlockStmt
+ Else Stmt // either nil, *IfStmt, or *BlockStmt
+ stmt
+ }
+
+ ForStmt struct {
+ Init SimpleStmt // incl. *RangeClause
+ Cond Expr
+ Post SimpleStmt
+ Body *BlockStmt
+ stmt
+ }
+
+ SwitchStmt struct {
+ Init SimpleStmt
+ Tag Expr // incl. *TypeSwitchGuard
+ Body []*CaseClause
+ Rbrace Pos
+ stmt
+ }
+
+ SelectStmt struct {
+ Body []*CommClause
+ Rbrace Pos
+ stmt
+ }
+)
+
+type (
+ RangeClause struct {
+ Lhs Expr // nil means no Lhs = or Lhs :=
+ Def bool // means :=
+ X Expr // range X
+ simpleStmt
+ }
+
+ CaseClause struct {
+ Cases Expr // nil means default clause
+ Body []Stmt
+ Colon Pos
+ node
+ }
+
+ CommClause struct {
+ Comm SimpleStmt // send or receive stmt; nil means default clause
+ Body []Stmt
+ Colon Pos
+ node
+ }
+)
+
+type stmt struct{ node }
+
+func (stmt) aStmt() {}
+
+type simpleStmt struct {
+ stmt
+}
+
+func (simpleStmt) aSimpleStmt() {}
+
+// ----------------------------------------------------------------------------
+// Comments
+
+// TODO(gri) Consider renaming to CommentPos, CommentPlacement, etc.
+// Kind = Above doesn't make much sense.
+type CommentKind uint
+
+const (
+ Above CommentKind = iota
+ Below
+ Left
+ Right
+)
+
+type Comment struct {
+ Kind CommentKind
+ Text string
+ Next *Comment
+}