summaryrefslogtreecommitdiff
path: root/usr/gri/pretty/ast.go
diff options
context:
space:
mode:
Diffstat (limited to 'usr/gri/pretty/ast.go')
-rw-r--r--usr/gri/pretty/ast.go268
1 files changed, 170 insertions, 98 deletions
diff --git a/usr/gri/pretty/ast.go b/usr/gri/pretty/ast.go
index 5cc5308f1..142b87501 100644
--- a/usr/gri/pretty/ast.go
+++ b/usr/gri/pretty/ast.go
@@ -15,17 +15,13 @@ type (
Block struct;
Expr interface;
Decl interface;
+ ExprVisitor interface;
+ Signature struct;
)
-// ----------------------------------------------------------------------------
-// Support
-
-func assert(pred bool) {
- if !pred {
- panic("assertion failed");
- }
-}
+// TODO rename scanner.Location to scanner.Position, possibly factor out
+type Position scanner.Location
// ----------------------------------------------------------------------------
@@ -44,90 +40,157 @@ type CommentGroup []*Comment
// ----------------------------------------------------------------------------
-// Expressions
+// Expressions and types
-const /* channel mode */ (
- FULL = iota;
- SEND;
- RECV;
-)
+
+// All expression nodes implement the Expr interface.
+type Expr interface {
+ // For a (dynamic) node type X, calling Visit with an expression
+ // visitor v invokes the node-specific DoX function of the visitor.
+ //
+ Visit(v ExprVisitor);
+
+ // Pos returns the (beginning) position of the expression.
+ Pos() Position;
+};
+// An expression is represented by a tree consisting of one
+// or several of the following concrete expression nodes.
+//
type (
- ExprVisitor interface;
- Signature struct;
-
- Expr interface {
- Loc() scanner.Location;
- Visit(v ExprVisitor);
- };
-
+ // A BadExpr node is a placeholder node for expressions containing
+ // syntax errors for which not correct expression tree can be created.
+ //
BadExpr struct {
- Loc_ scanner.Location;
+ Pos_ Position; // bad expression position
};
+
+ // An Ident node represents an identifier (identifier).
Ident struct {
- Loc_ scanner.Location;
- Str string;
+ Str string; // identifier string (e.g. foobar)
+ Pos_ Position; // identifier position
};
- BinaryExpr struct {
- Loc_ scanner.Location;
- Tok int;
- X, Y Expr;
- };
- UnaryExpr struct {
- Loc_ scanner.Location;
- Tok int;
- X Expr;
+ // An basic literal is represented by a BasicLit node.
+ BasicLit struct {
+ Tok int; // literal token
+ Lit []byte; // literal string
+ Pos_ Position; // literal string position
};
- // TODO this should probably just be a list instead
- ConcatExpr struct {
- X, Y Expr;
- };
- BasicLit struct {
- Loc_ scanner.Location;
- Tok int;
- Val []byte;
+ // A sequence of string literals (StringLit) is represented
+ // by a StringLit node.
+ //
+ StringLit struct {
+ Strings []*BasicLit; // sequence of strings
};
+
+ // A function literal (FunctionLit) is represented by a FunctionLit node.
FunctionLit struct {
- Loc_ scanner.Location; // location of "func"
- Typ *Signature;
- Body *Block;
+ Typ *Signature; // function signature
+ Body *Block; // function body
+ Func Position; // position of "func" keyword
};
-
+
+
+ // A composite literal (CompositeLit) is represented by a CompositeLit node.
+ CompositeLit struct {
+ Typ Expr; // literal type
+ Elts []Expr; // list of composite elements
+ Lbrace, Rbrace Position; // positions of "{" and "}"
+ };
+
+
+ // A parenthesized expression is represented by a Group node.
Group struct {
- Loc_ scanner.Location; // location of "("
- X Expr;
+ X Expr; // parenthesized expression
+ Lparen, Rparen Position; // positions of "(" and ")"
};
+
+ // A primary expression followed by a selector is represented
+ // by a Selector node.
+ //
Selector struct {
- Loc_ scanner.Location; // location of "."
- X Expr;
- Sel *Ident;
+ X Expr; // primary expression
+ Sel *Ident; // field selector
+ Period Position; // position of "."
};
- TypeGuard struct {
- Loc_ scanner.Location; // location of "."
- X Expr;
- Typ Expr;
- };
+ // A primary expression followed by an index is represented
+ // by an Index node.
+ //
Index struct {
- Loc_ scanner.Location; // location of "["
- X, I Expr;
+ X Expr; // primary expression
+ Index Expr; // index expression
+ Lbrack, Rbrack Position; // positions of "[" and "]"
};
-
+
+
+ // A primary expression followed by a slice is represented
+ // by a Slice node.
+ //
+ Slice struct {
+ X Expr; // primary expression
+ Beg, End Expr; // slice range
+ Lbrack, Colon, Rbrack Position; // positions of "[", ":", and "]"
+ };
+
+
+ // A primary expression followed by a type assertion is represented
+ // by a TypeAssertion node.
+ //
+ TypeAssertion struct {
+ X Expr; // primary expression
+ Typ Expr; // asserted type
+ Period, Lparen, Rparen Position; // positions of ".", "(", and ")"
+ };
+
+
+ // A primary expression followed by an argument list is represented
+ // by a Call node.
+ //
Call struct {
- Loc_ scanner.Location; // location of "(" or "{"
- Tok int;
- F, Args Expr
+ Fun Expr; // function expression
+ Args []Expr; // function arguments
+ Lparen, Rparen Position; // positions of "(" and ")"
+ };
+
+
+ // A unary expression (UnaryExpr) is represented by a UnaryExpr node.
+ UnaryExpr struct {
+ Op int; // operator token
+ X Expr; // operand
+ Pos_ Position; // operator position
+ };
+
+
+ // A binary expression (BinaryExpr) is represented by a BinaryExpr node.
+ BinaryExpr struct {
+ Op int; // operator token
+ X, Y Expr; // left and right operand
+ Pos_ Position; // operator position
};
+)
+
+// The direction of a channel type is indicated by one
+// of the following constants.
+//
+const /* channel direction */ (
+ FULL = iota;
+ SEND;
+ RECV;
+)
+
+
+type (
// Type literals are treated like expressions.
Ellipsis struct { // neither a type nor an expression
Loc_ scanner.Location;
@@ -189,26 +252,30 @@ type (
ChannelType struct {
Loc_ scanner.Location; // location of "chan" or "<-"
- Mode int;
+ Dir int;
Val Expr;
};
)
type ExprVisitor interface {
+ // Expressions
DoBadExpr(x *BadExpr);
DoIdent(x *Ident);
- DoBinaryExpr(x *BinaryExpr);
- DoUnaryExpr(x *UnaryExpr);
- DoConcatExpr(x *ConcatExpr);
DoBasicLit(x *BasicLit);
+ DoStringLit(x *StringLit);
DoFunctionLit(x *FunctionLit);
+ DoCompositeLit(x *CompositeLit);
DoGroup(x *Group);
DoSelector(x *Selector);
- DoTypeGuard(x *TypeGuard);
DoIndex(x *Index);
+ DoSlice(x *Slice);
+ DoTypeAssertion(x *TypeAssertion);
DoCall(x *Call);
-
+ DoUnaryExpr(x *UnaryExpr);
+ DoBinaryExpr(x *BinaryExpr);
+
+ // Types
DoEllipsis(x *Ellipsis);
DoTypeType(x *TypeType);
DoArrayType(x *ArrayType);
@@ -222,44 +289,47 @@ type ExprVisitor interface {
}
-// TODO replace these with an embedded field
-func (x *BadExpr) Loc() scanner.Location { return x.Loc_; }
-func (x *Ident) Loc() scanner.Location { return x.Loc_; }
-func (x *BinaryExpr) Loc() scanner.Location { return x.Loc_; }
-func (x *UnaryExpr) Loc() scanner.Location { return x.Loc_; }
-func (x *ConcatExpr) Loc() scanner.Location { return x.X.Loc(); }
-func (x *BasicLit) Loc() scanner.Location { return x.Loc_; }
-func (x *FunctionLit) Loc() scanner.Location { return x.Loc_; }
-func (x *Group) Loc() scanner.Location { return x.Loc_; }
-func (x *Selector) Loc() scanner.Location { return x.Loc_; }
-func (x *TypeGuard) Loc() scanner.Location { return x.Loc_; }
-func (x *Index) Loc() scanner.Location { return x.Loc_; }
-func (x *Call) Loc() scanner.Location { return x.Loc_; }
-
-func (x *Ellipsis) Loc() scanner.Location { return x.Loc_; }
-func (x *TypeType) Loc() scanner.Location { return x.Loc_; }
-func (x *ArrayType) Loc() scanner.Location { return x.Loc_; }
-func (x *StructType) Loc() scanner.Location { return x.Loc_; }
-func (x *PointerType) Loc() scanner.Location { return x.Loc_; }
-func (x *FunctionType) Loc() scanner.Location { return x.Loc_; }
-func (x *InterfaceType) Loc() scanner.Location { return x.Loc_; }
-func (x *SliceType) Loc() scanner.Location { return x.Loc_; }
-func (x *MapType) Loc() scanner.Location { return x.Loc_; }
-func (x *ChannelType) Loc() scanner.Location { return x.Loc_; }
+func (x *BadExpr) Pos() Position { return x.Pos_; }
+func (x *Ident) Pos() Position { return x.Pos_; }
+func (x *BasicLit) Pos() Position { return x.Pos_; }
+func (x *StringLit) Pos() Position { return x.Strings[0].Pos(); }
+func (x *FunctionLit) Pos() Position { return x.Func; }
+func (x *CompositeLit) Pos() Position { return x.Typ.Pos(); }
+func (x *Group) Pos() Position { return x.Lparen; }
+func (x *Selector) Pos() Position { return x.X.Pos(); }
+func (x *Index) Pos() Position { return x.X.Pos(); }
+func (x *Slice) Pos() Position { return x.X.Pos(); }
+func (x *TypeAssertion) Pos() Position { return x.X.Pos(); }
+func (x *Call) Pos() Position { return x.Fun.Pos(); }
+func (x *UnaryExpr) Pos() Position { return x.Pos_; }
+func (x *BinaryExpr) Pos() Position { return x.X.Pos(); }
+
+func (x *Ellipsis) Pos() Position { return x.Loc_; }
+func (x *TypeType) Pos() Position { return x.Loc_; }
+func (x *ArrayType) Pos() Position { return x.Loc_; }
+func (x *StructType) Pos() Position { return x.Loc_; }
+func (x *PointerType) Pos() Position { return x.Loc_; }
+func (x *FunctionType) Pos() Position { return x.Loc_; }
+func (x *InterfaceType) Pos() Position { return x.Loc_; }
+func (x *SliceType) Pos() Position { return x.Loc_; }
+func (x *MapType) Pos() Position { return x.Loc_; }
+func (x *ChannelType) Pos() Position { return x.Loc_; }
func (x *BadExpr) Visit(v ExprVisitor) { v.DoBadExpr(x); }
func (x *Ident) Visit(v ExprVisitor) { v.DoIdent(x); }
-func (x *BinaryExpr) Visit(v ExprVisitor) { v.DoBinaryExpr(x); }
-func (x *UnaryExpr) Visit(v ExprVisitor) { v.DoUnaryExpr(x); }
-func (x *ConcatExpr) Visit(v ExprVisitor) { v.DoConcatExpr(x); }
func (x *BasicLit) Visit(v ExprVisitor) { v.DoBasicLit(x); }
+func (x *StringLit) Visit(v ExprVisitor) { v.DoStringLit(x); }
func (x *FunctionLit) Visit(v ExprVisitor) { v.DoFunctionLit(x); }
+func (x *CompositeLit) Visit(v ExprVisitor) { v.DoCompositeLit(x); }
func (x *Group) Visit(v ExprVisitor) { v.DoGroup(x); }
func (x *Selector) Visit(v ExprVisitor) { v.DoSelector(x); }
-func (x *TypeGuard) Visit(v ExprVisitor) { v.DoTypeGuard(x); }
func (x *Index) Visit(v ExprVisitor) { v.DoIndex(x); }
+func (x *Slice) Visit(v ExprVisitor) { v.DoSlice(x); }
+func (x *TypeAssertion) Visit(v ExprVisitor) { v.DoTypeAssertion(x); }
func (x *Call) Visit(v ExprVisitor) { v.DoCall(x); }
+func (x *UnaryExpr) Visit(v ExprVisitor) { v.DoUnaryExpr(x); }
+func (x *BinaryExpr) Visit(v ExprVisitor) { v.DoBinaryExpr(x); }
func (x *Ellipsis) Visit(v ExprVisitor) { v.DoEllipsis(x); }
func (x *TypeType) Visit(v ExprVisitor) { v.DoTypeType(x); }
@@ -290,7 +360,9 @@ type Block struct {
func NewBlock(loc scanner.Location, tok int) *Block {
- assert(tok == token.LBRACE || tok == token.COLON);
+ if tok != token.LBRACE && tok != token.COLON {
+ panic();
+ }
var end scanner.Location;
return &Block{loc, tok, vector.New(0), end};
}
@@ -322,7 +394,7 @@ type (
ExpressionStat struct {
Loc scanner.Location; // location of Tok
- Tok int; // INC, DEC, RETURN, GO, DEFER
+ Tok int; // GO, DEFER
Expr Expr;
};