]> Cypherpunks repositories - gostls13.git/commitdiff
- snapshot before making larger change
authorRobert Griesemer <gri@golang.org>
Fri, 23 Jan 2009 21:50:14 +0000 (13:50 -0800)
committerRobert Griesemer <gri@golang.org>
Fri, 23 Jan 2009 21:50:14 +0000 (13:50 -0800)
R=r
OCL=23403
CL=23403

usr/gri/pretty/ast.go
usr/gri/pretty/parser.go

index 0a6d3485c5bb8300be61accefc571a0818092d89..3b6c79322ce602ff7403fd17cfd676e6a68462b2 100644 (file)
@@ -17,6 +17,7 @@ type (
        Type struct;
 
        Block struct;
+       Lit struct;
        Expr struct;
        Stat struct;
        Decl struct;
@@ -88,6 +89,18 @@ func (obj *Object) IsExported() bool {
 }
 
 
+func (obj* Object) String() string {
+       if obj != nil {
+               return
+                       "Object(" +
+                       KindStr(obj.Kind) + ", " +
+                       obj.Ident +
+                       ")";
+       }
+       return "nil";
+}
+
+
 var Universe_void_typ *Type  // initialized by Universe to Universe.void_typ
 var objectId int;
 
@@ -99,13 +112,42 @@ func NewObject(pos, kind int, ident string) *Object {
        obj.Pos = pos;
        obj.Kind = kind;
        obj.Ident = ident;
-       obj.Typ = Universe_void_typ;
+       obj.Typ = Universe_void_typ;  // TODO would it be better to use nil instead?
        obj.Pnolev = 0;
 
        return obj;
 }
 
 
+// ----------------------------------------------------------------------------
+// All nodes have a source position and a token.
+
+type Node struct {
+       Pos int;  // source position (< 0 => unknown position)
+       Tok int;  // identifying token
+}
+
+
+// ----------------------------------------------------------------------------
+// Literals
+
+type Lit struct {
+       Node;
+       
+       // Identifiers
+       Obj *Object;
+       
+       // Constant literals
+       
+       // Type literals
+       Len *Expr;  // array length
+       Dir int;  // channel direction
+       Key *Type;  // receiver or map key type
+       Elt *Type;  // array, map, channel, pointer element, or function result type
+       List *array.Array; End int;  // struct fields, interface methods, function parameters
+}
+
+
 // ----------------------------------------------------------------------------
 // Scopes
 
@@ -176,15 +218,6 @@ func (scope *Scope) Print() {
 }
 
 
-// ----------------------------------------------------------------------------
-// All nodes have a source position and and token.
-
-type Node struct {
-       Pos int;  // source position (< 0 => unknown position)
-       Tok int;  // identifying token
-}
-
-
 // ----------------------------------------------------------------------------
 // Blocks
 //
@@ -258,7 +291,7 @@ func NewExpr(pos, tok int, x, y *Expr) *Expr {
 // TODO probably don't need the tok parameter eventually
 func NewLit(tok int, obj *Object) *Expr {
        e := new(Expr);
-       e.Pos, e.Tok, e.Obj = obj.Pos, tok, obj;
+       e.Pos, e.Tok, e.Obj, e.Typ = obj.Pos, tok, obj, obj.Typ;
        return e;
 }
 
@@ -350,7 +383,7 @@ type Type struct {
        Ref int;  // for exporting only: >= 0 means already exported
        Form int;  // type form
        Size int;  // size in bytes
-       Obj *Object;  // primary type object or NULL
+       Obj *Object;  // primary type object or nil
        Scope *Scope;  // locals, fields & methods
 
        // syntactic components
@@ -358,7 +391,7 @@ type Type struct {
        Expr *Expr;  // type name, array length
        Mode int;  // channel mode
        Key *Type;  // receiver type or map key
-       Elt *Type;  // array, map, channel or pointer element type, function result type
+       Elt *Type;  // type name type, array, map, channel or pointer element type, function result type
        List *array.Array; End int;  // struct fields, interface methods, function parameters
 }
 
@@ -397,6 +430,17 @@ func (t *Type) Nfields() int {
 }
 
 
+func (typ* Type) String() string {
+       if typ != nil {
+               return
+                       "Type(" +
+                       FormStr(typ.Form) +
+                       ")";
+       }
+       return "nil";
+}
+
+
 // requires complete Type.Pos access
 func NewTypeExpr(typ *Type) *Expr {
        e := new(Expr);
@@ -405,6 +449,22 @@ func NewTypeExpr(typ *Type) *Expr {
 }
 
 
+// requires complete Type.String access
+func (x *Expr) String() string {
+       if x != nil {
+               return
+                       "Expr(" +
+                       Scanner.TokenString(x.Tok) + ", " +
+                       x.X.String() + ", " +
+                       x.Y.String() + ", " +
+                       x.Obj.String() + ", " +
+                       x.Typ.String() +
+                       ")";
+       }
+       return "nil";
+}
+
+
 var BadType = NewType(0, Scanner.ILLEGAL);
 
 
@@ -416,7 +476,7 @@ type Stat struct {
        Init, Post *Stat;
        Expr *Expr;
        Body *Block;  // composite statement body
-       Decl *Decl;
+       Decl *Decl;  // declaration statement
 }
 
 
index fbea1fcdab5e4bdf1e174995e3425f08e56d2390..fc20c2fbea019a3fc51c61e311c432c96ba8a34a 100644 (file)
@@ -5,6 +5,7 @@
 package Parser
 
 import (
+       "fmt";
        "array";
        Scanner "scanner";
        AST "ast";
@@ -170,7 +171,7 @@ func (P *Parser) CloseScope() {
 }
 
 
-func (P *Parser) DeclareInScope(scope *AST.Scope, x *AST.Expr, kind int) {
+func (P *Parser) DeclareInScope(scope *AST.Scope, x *AST.Expr, kind int, typ *AST.Type) {
        if P.scope_lev < 0 {
                panic("cannot declare objects in other packages");
        }
@@ -178,10 +179,16 @@ func (P *Parser) DeclareInScope(scope *AST.Scope, x *AST.Expr, kind int) {
                assert(x.Tok == Scanner.IDENT);
                obj := x.Obj;
                obj.Kind = kind;
+               obj.Typ = typ;
                obj.Pnolev = P.scope_lev;
-               if scope.LookupLocal(obj.Ident) == nil {
+               switch {
+               case scope.LookupLocal(obj.Ident) == nil:
                        scope.Insert(obj);
-               } else {
+               case kind == AST.TYPE:
+                       // possibly a forward declaration
+               case kind == AST.FUNC:
+                       // possibly a forward declaration
+               default:
                        P.Error(obj.Pos, `"` + obj.Ident + `" is declared already`);
                }
        }
@@ -189,12 +196,12 @@ func (P *Parser) DeclareInScope(scope *AST.Scope, x *AST.Expr, kind int) {
 
 
 // Declare a comma-separated list of idents or a single ident.
-func (P *Parser) Declare(p *AST.Expr, kind int) {
+func (P *Parser) Declare(p *AST.Expr, kind int, typ *AST.Type) {
        for p.Tok == Scanner.COMMA {
-               P.DeclareInScope(P.top_scope, p.X, kind);
+               P.DeclareInScope(P.top_scope, p.X, kind, typ);
                p = p.Y;
        }
-       P.DeclareInScope(P.top_scope, p, kind);
+       P.DeclareInScope(P.top_scope, p, kind, typ);
 }
 
 
@@ -344,6 +351,7 @@ func (P *Parser) ParseTypeName() *AST.Type {
 
        t := AST.NewType(P.pos, AST.TYPENAME);
        t.Expr = P.ParseQualifiedIdent();
+       t.Elt = t.Expr.Typ;
 
        P.Ecart();
        return t;
@@ -652,7 +660,7 @@ func (P *Parser) ParseStructType() *AST.Type {
                for i, n := 0, t.List.Len(); i < n; i++ {
                        x := t.List.At(i).(*AST.Expr);
                        if x.Tok == Scanner.IDENT {
-                               P.DeclareInScope(t.Scope, x, AST.FIELD);
+                               P.DeclareInScope(t.Scope, x, AST.FIELD, nil);
                        }
                }
        }
@@ -741,7 +749,7 @@ func (P *Parser) ParseBlock(ftyp *AST.Type, tok int) *AST.Block {
                        for i, n := 0, ftyp.List.Len(); i < n; i++ {
                                x := ftyp.List.At(i).(*AST.Expr);
                                if x.Tok == Scanner.IDENT {
-                                       P.DeclareInScope(P.top_scope, x, AST.VAR);
+                                       P.DeclareInScope(P.top_scope, x, AST.VAR, nil);
                                }
                        }
                }
@@ -858,8 +866,8 @@ func (P *Parser) ParseSelectorOrTypeGuard(x *AST.Expr) *AST.Expr {
        if P.tok == Scanner.IDENT {
                // TODO should always guarantee x.Typ != nil
                var scope *AST.Scope;
-               if x.Typ != nil {
-                       scope = x.Typ.Scope;
+               if x.X.Typ != nil {
+                       scope = x.X.Typ.Scope;
                }
                x.Y = P.ParseIdent(scope);
                x.Typ = x.Y.Obj.Typ;
@@ -1478,10 +1486,6 @@ func (P *Parser) ParseImportSpec(d *AST.Decl) {
                P.Expect(Scanner.STRING);  // use Expect() error handling
        }
 
-       if d.Ident != nil {
-               P.Declare(d.Ident, AST.PACKAGE);
-       }
-
        P.Ecart();
 }
 
@@ -1496,8 +1500,6 @@ func (P *Parser) ParseConstSpec(d *AST.Decl) {
                d.Val = P.ParseExpressionList();
        }
 
-       P.Declare(d.Ident, AST.CONST);
-
        P.Ecart();
 }
 
@@ -1528,28 +1530,28 @@ func (P *Parser) ParseVarSpec(d *AST.Decl) {
                }
        }
 
-       P.Declare(d.Ident, AST.VAR);
-
        P.Ecart();
 }
 
 
 func (P *Parser) ParseSpec(d *AST.Decl) {
+       kind := AST.NONE;
+       
        switch d.Tok {
-       case Scanner.IMPORT: P.ParseImportSpec(d);
-       case Scanner.CONST: P.ParseConstSpec(d);
-       case Scanner.TYPE: P.ParseTypeSpec(d);
-       case Scanner.VAR: P.ParseVarSpec(d);
+       case Scanner.IMPORT: P.ParseImportSpec(d); kind = AST.PACKAGE;
+       case Scanner.CONST: P.ParseConstSpec(d); kind = AST.CONST;
+       case Scanner.TYPE: P.ParseTypeSpec(d); kind = AST.TYPE;
+       case Scanner.VAR: P.ParseVarSpec(d); kind = AST.VAR;
        default: unreachable();
        }
-       
+
        // semantic checks
        if d.Tok == Scanner.IMPORT {
-               // TODO
-       } else {
-               if d.Typ != nil {
-                       // apply type to all variables
+               if d.Ident != nil {
+                       P.Declare(d.Ident, kind, nil);
                }
+       } else {
+               P.Declare(d.Ident, kind, d.Typ);
                if d.Val != nil {
                        // initialization/assignment
                        llen := d.Ident.Len();