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.go65
1 files changed, 56 insertions, 9 deletions
diff --git a/usr/gri/pretty/ast.go b/usr/gri/pretty/ast.go
index 788ac74b1..0a6d3485c 100644
--- a/usr/gri/pretty/ast.go
+++ b/usr/gri/pretty/ast.go
@@ -16,6 +16,7 @@ type (
Object struct;
Type struct;
+ Block struct;
Expr struct;
Stat struct;
Decl struct;
@@ -23,6 +24,16 @@ type (
// ----------------------------------------------------------------------------
+// Support
+
+func assert(pred bool) {
+ if !pred {
+ panic("assertion failed");
+ }
+}
+
+
+// ----------------------------------------------------------------------------
// Objects
// Object represents a language object, such as a constant, variable, type, etc.
@@ -63,7 +74,7 @@ type Object struct {
Pnolev int; // >= 0: package no., <= 0: function nesting level, 0: global level
// attached values
- Block *array.Array; End int; // stats for function literals; end of block pos
+ Body *Block; // function body
}
@@ -175,15 +186,40 @@ type Node struct {
// ----------------------------------------------------------------------------
+// Blocks
+//
+// Syntactic constructs of the form:
+//
+// "{" StatementList "}"
+// ":" StatementList
+
+type Block struct {
+ Node;
+ List *array.Array;
+ End int; // position of closing "}" if present
+}
+
+
+func NewBlock(pos, tok int) *Block {
+ assert(tok == Scanner.LBRACE || tok == Scanner.COLON);
+ b := new(Block);
+ b.Pos, b.Tok, b.List = pos, tok, array.New(0);
+ return b;
+}
+
+
+// ----------------------------------------------------------------------------
// Expressions
type Expr struct {
Node;
X, Y *Expr; // binary (X, Y) and unary (Y) expressions
- Obj *Object;
+ Obj *Object; // identifiers, literals
+ Typ *Type;
}
+// Length of a comma-separated expression list.
func (x *Expr) Len() int {
if x == nil {
return 0;
@@ -196,6 +232,19 @@ func (x *Expr) Len() int {
}
+// The i'th expression in a comma-separated expression list.
+func (x *Expr) At(i int) *Expr {
+ for j := 0; j < i; j++ {
+ assert(x.Tok == Scanner.COMMA);
+ x = x.Y;
+ }
+ if x.Tok == Scanner.COMMA {
+ x = x.X;
+ }
+ return x;
+}
+
+
func NewExpr(pos, tok int, x, y *Expr) *Expr {
if x != nil && x.Tok == Scanner.TYPE || y != nil && y.Tok == Scanner.TYPE {
panic("no type expression allowed");
@@ -302,7 +351,7 @@ type Type struct {
Form int; // type form
Size int; // size in bytes
Obj *Object; // primary type object or NULL
- Scope *Scope; // forwards, structs, interfaces, functions
+ Scope *Scope; // locals, fields & methods
// syntactic components
Pos int; // source position (< 0 if unknown position)
@@ -311,7 +360,6 @@ type Type struct {
Key *Type; // receiver type or map key
Elt *Type; // array, map, channel or pointer element type, function result type
List *array.Array; End int; // struct fields, interface methods, function parameters
- Scope *Scope; // struct fields, methods
}
@@ -351,9 +399,9 @@ func (t *Type) Nfields() int {
// requires complete Type.Pos access
func NewTypeExpr(typ *Type) *Expr {
- obj := NewObject(typ.Pos, TYPE, "");
- obj.Typ = typ;
- return NewLit(Scanner.TYPE, obj);
+ e := new(Expr);
+ e.Pos, e.Tok, e.Typ = typ.Pos, Scanner.TYPE, typ;
+ return e;
}
@@ -367,7 +415,7 @@ type Stat struct {
Node;
Init, Post *Stat;
Expr *Expr;
- Block *array.Array; End int; // block end position
+ Body *Block; // composite statement body
Decl *Decl;
}
@@ -391,7 +439,6 @@ type Decl struct {
Typ *Type;
Val *Expr;
// list of *Decl for ()-style declarations
- // list of *Stat for func declarations (or nil for forward decl)
List *array.Array; End int;
}