]> Cypherpunks repositories - gostls13.git/commitdiff
- addded interface pretty printer
authorRobert Griesemer <gri@golang.org>
Wed, 30 Jul 2008 20:01:28 +0000 (13:01 -0700)
committerRobert Griesemer <gri@golang.org>
Wed, 30 Jul 2008 20:01:28 +0000 (13:01 -0700)
R=r
OCL=13646
CL=13646

usr/gri/gosrc/compilation.go
usr/gri/gosrc/decls.go
usr/gri/gosrc/parser.go
usr/gri/gosrc/printer.go [new file with mode: 0755]

index 14aebba49804f4cfe03018ca279e848edee17745..4ed09baebf38368dd2342557e937340fd8a260d5 100644 (file)
@@ -13,6 +13,7 @@ import Scanner "scanner"
 import AST "ast"
 import Parser "parser"
 import Export "export"
+import Printer "printer"
 
 
 export Compile
@@ -39,7 +40,12 @@ func Compile(file_name string, verbose int) {
                return;
        }
        
+       /*
        // export
        exp := new(Export.Exporter);
        exp.Export(comp, Utils.FixExt(Utils.BaseName(file_name)));
+       
+       // print export
+       Printer.PrintObject(comp, comp.pkgs[0].obj, false);
+       */
 }
index 1910d2544d9f80877a9ee3aa9fca9890d1d5ecf6..833e2277908a448f4a45976a732804fe78a0365e 100755 (executable)
@@ -120,4 +120,5 @@ func (p *T4) m5(a, b int, c float) (z T5, ok bool) {
 }
 
 export c0, c1, v2, v3
-export T0, T1, T4, T4, T4, M0, M5, I2, f0, f1, Node0, Node1
+export T0, T1, T4, T4, T4, M0, M5, I2, f0, f1
+// export Node0, Node1 // this fails
index 67caa6a972900235fdfb874ced4f7eaf17bdd0d3..6372a1d05d14fc6f8ca9e6676fe2c1b5d359ce32 100644 (file)
@@ -169,54 +169,54 @@ func MakeFunctionType(sig *Globals.Scope, p0, r0 int, check_recv bool) *Globals.
 }
 
 
-func (P *Parser) DeclareFunc(exported bool, ident string, typ *Globals.Type) *Globals.Object {
-  // Determine scope.
+func (P *Parser) DeclareFunc(ident string, typ *Globals.Type) *Globals.Object {
+  // determine scope
   scope := P.top_scope;
   if typ.flags & Type.RECV != 0 {
     // method - declare in corresponding struct
        if typ.scope.entries.len_ < 1 {
                panic "no recv in signature?";
        }
-    trecv := typ.scope.entries.first.typ;
-    if trecv.form == Type.POINTER {
-      trecv = trecv.elt;
+    recv_typ := typ.scope.entries.first.obj.typ;
+    if recv_typ.form == Type.POINTER {
+      recv_typ = recv_typ.elt;
     }
-    scope = trecv.scope;
+    scope = recv_typ.scope;
   }
   
-  // Declare the function.
-  fun := scope.Lookup(ident);
-  if fun == nil {
-    fun = Globals.NewObject(-1, Object.FUNC, ident);
-       fun.typ = typ;
-       // TODO do we need to set the prymary type? probably...
-    P.DeclareInScope(scope, fun);
-    return fun;
+  // declare the function
+  obj := scope.Lookup(ident);
+  if obj == nil {
+    obj = Globals.NewObject(-1, Object.FUNC, ident);
+       obj.typ = typ;
+       // TODO do we need to set the primary type? probably...
+    P.DeclareInScope(scope, obj);
+    return obj;
   }
   
-  // fun != NULL: possibly a forward declaration.
-  if (fun.kind != Object.FUNC) {
+  // obj != NULL: possibly a forward declaration.
+  if (obj.kind != Object.FUNC) {
     P.Error(-1, `"` + ident + `" is declared already`);
     // Continue but do not insert this function into the scope.
-    fun = Globals.NewObject(-1, Object.FUNC, ident);
-       fun.typ = typ;
+    obj = Globals.NewObject(-1, Object.FUNC, ident);
+       obj.typ = typ;
        // TODO do we need to set the prymary type? probably...
-    return fun;
+    return obj;
   }
   
   // We have a function with the same name.
   /*
-  if (!EqualTypes(type, fun->type())) {
+  if (!EqualTypes(type, obj->type())) {
     this->Error("type of \"%s\" does not match its forward declaration", name.cstr());
     // Continue but do not insert this function into the scope.
     NewObject(Object::FUNC, name);
-    fun->set_type(type);
-    return fun;    
+    obj->set_type(type);
+    return obj;    
   }
   */
   
   // We have a matching forward declaration. Use it.
-  return fun;
+  return obj;
 }
 
 
@@ -1510,7 +1510,7 @@ func (P *Parser) TryStatement() bool {
        case Scanner.FUNC:
                // for now we do not allow local function declarations
                fallthrough;
-       case Scanner.MUL, Scanner.SEND, Scanner.RECV, Scanner.IDENT:
+       case Scanner.MUL, Scanner.SEND, Scanner.RECV, Scanner.IDENT, Scanner.LPAREN:
                P.ParseSimpleStat();
        case Scanner.GO:
                P.ParseGoStat();
@@ -1695,7 +1695,8 @@ func (P *Parser) ParseFuncDecl(exported bool) {
        
        P.Expect(Scanner.FUNC);
        ident, typ := P.ParseNamedSignature();
-       obj := P.DeclareFunc(exported, ident, typ);  // need obj later for statements
+       obj := P.DeclareFunc(ident, typ);  // need obj later for statements
+       obj.exported = exported;
        if P.tok == Scanner.SEMICOLON {
                // forward declaration
                P.Next();
diff --git a/usr/gri/gosrc/printer.go b/usr/gri/gosrc/printer.go
new file mode 100755 (executable)
index 0000000..d2dafd4
--- /dev/null
@@ -0,0 +1,265 @@
+// 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.
+
+package Printer
+
+import Globals "globals"
+import Object "object"
+import Type "type"
+import Universe "universe"
+
+
+type Printer struct {
+       comp *Globals.Compilation;
+       print_all bool;
+       level int;
+};
+
+
+func (P *Printer) PrintObjectStruct(obj *Globals.Object);
+func (P *Printer) PrintObject(obj *Globals.Object);
+
+func (P *Printer) PrintTypeStruct(typ *Globals.Type);
+func (P *Printer) PrintType(typ *Globals.Type);
+
+
+
+func (P *Printer) Init(comp *Globals.Compilation, print_all bool) {
+       P.comp = comp;
+       P.print_all = print_all;
+       P.level = 0;
+}
+
+
+func IsAnonymous(name string) bool {
+       return len(name) == 0 || name[0] == '.';
+}
+
+
+func (P *Printer) PrintSigRange(typ *Globals.Type, a, b int) {
+       scope := typ.scope;
+       if a + 1 == b && IsAnonymous(scope.entries.ObjAt(a).ident) {
+               P.PrintType(scope.entries.TypAt(a));  // result type only
+       } else {
+               print "(";
+               for i := a; i < b; i++ {
+                       par := scope.entries.ObjAt(i);
+                       if i > a {
+                               print ", ";
+                       }
+                       print par.ident, " ";
+                       P.PrintType(par.typ);
+               }
+               print ")";
+       }
+}
+
+
+func (P *Printer) PrintSignature(typ *Globals.Type, fun *Globals.Object) {
+       if typ.form != Type.FUNCTION {
+               panic "typ.form != Type.FUNCTION";
+       }
+       
+       p0 := 0;
+       if typ.flags & Type.RECV != 0 {
+               p0 = 1;
+       }
+       r0 := p0 + typ.len_;
+       l0 := typ.scope.entries.len_;
+       
+       if P.level == 0 {
+               print "func ";
+
+               if 0 < p0 {
+                       P.PrintSigRange(typ, 0, p0);
+                       print " ";
+               }
+       }
+       
+       if fun != nil {
+               P.PrintObject(fun);
+               print " ";
+       } else if p0 > 0 {
+               print ". ";
+       }
+       
+       P.PrintSigRange(typ, p0, r0);
+
+       if r0 < l0 {
+               print " ";
+               P.PrintSigRange(typ, r0, l0);
+       }
+}
+
+
+func (P *Printer) PrintIndent() {
+       const scale = 4;
+       print "\n";
+       for i := P.level * scale; i > 0; i-- {
+               print " ";
+       }
+}
+
+
+func (P *Printer) PrintScope(scope *Globals.Scope, delta int) {
+       // determine the number of scope entries to print
+       var n int;
+       if P.print_all {
+               n = scope.entries.len_;
+       } else {
+               n = 0;
+               for p := scope.entries.first; p != nil; p = p.next {
+                       if p.obj.exported {
+                               n++;
+                       }
+               }
+       }
+       
+       // print the scope
+       const scale = 2;
+       if n > 0 {
+               P.level += delta;
+               for p := scope.entries.first; p != nil; p = p.next {
+                       if P.print_all || p.obj.exported {
+                               P.PrintIndent();
+                               P.PrintObjectStruct(p.obj);
+                       }
+               }
+               P.level -= delta;
+               P.PrintIndent();
+       }
+}
+
+       
+func (P *Printer) PrintObjectStruct(obj *Globals.Object) {
+       switch obj.kind {
+       case Object.BAD:
+               print "bad ";
+               P.PrintObject(obj);
+
+       case Object.CONST:
+               print "const ";
+               P.PrintObject(obj);
+               print " ";
+               P.PrintType(obj.typ);
+
+       case Object.TYPE:
+               print "type ";
+               P.PrintObject(obj);
+               print " ";
+               P.PrintTypeStruct(obj.typ);
+
+       case Object.VAR:
+               if P.level == 0 {
+                       print "var ";
+               }
+               P.PrintObject(obj);
+               print " ";
+               P.PrintType(obj.typ);
+
+       case Object.FUNC:
+               P.PrintSignature(obj.typ, obj);
+
+       case Object.PACKAGE:
+               print "package ";
+               P.PrintObject(obj);
+               print " ";
+               P.PrintScope(P.comp.pkgs[obj.pnolev].scope, 0);
+
+       default:
+               panic "UNREACHABLE";
+       }
+       
+       if P.level > 0 {
+               print ";";
+       }
+}
+
+
+func (P *Printer) PrintObject(obj *Globals.Object) {
+       if obj.pnolev > 0 {
+               print P.comp.pkgs[obj.pnolev].obj.ident, ".";
+       }
+       print obj.ident;
+}
+
+
+func (P *Printer) PrintTypeStruct(typ *Globals.Type) {
+       switch typ.form {
+       case Type.UNDEF:
+               print "<undef type>";
+
+       case Type.BAD:
+               print "<bad type>";
+
+       case Type.NIL, Type.BOOL, Type.UINT, Type.INT, Type.FLOAT, Type.STRING, Type.ANY:
+               if typ.obj == nil {
+                       panic "typ.obj == nil";
+               }
+               P.PrintType(typ);
+
+       case Type.ARRAY:
+               print "[]";
+               P.PrintType(typ.elt);
+
+       case Type.STRUCT:
+               print "struct {";
+               P.PrintScope(typ.scope, 1);
+               print "}";
+
+       case Type.INTERFACE:
+               print "interface {";
+               P.PrintScope(typ.scope, 1);
+               print "}";
+
+       case Type.MAP:
+               print "map [";
+               P.PrintType(typ.key);
+               print "] ";
+               P.PrintType(typ.elt);
+
+       case Type.CHANNEL:
+               print "chan";
+               switch typ.flags {
+               case Type.SEND: print " -<";
+               case Type.RECV: print " <-";
+               case Type.SEND + Type.RECV:  // nothing to print
+               default: panic "UNREACHABLE";
+               }
+               print " ";
+               P.PrintType(typ.elt);
+
+       case Type.FUNCTION:
+               P.PrintSignature(typ, nil);
+
+       case Type.POINTER:
+               print "*";
+               P.PrintType(typ.elt);
+
+       case Type.REFERENCE:
+               print "&";
+               P.PrintType(typ.elt);
+
+       default:
+               panic "UNREACHABLE";
+               
+       }
+}
+
+
+func (P *Printer) PrintType(typ *Globals.Type) {
+       if typ.obj != nil {
+               P.PrintObject(typ.obj);
+       } else {
+               P.PrintTypeStruct(typ);
+       }
+}
+
+
+export PrintObject
+func PrintObject(comp *Globals.Compilation, obj *Globals.Object, print_all bool) {
+       var P Printer;
+       (&P).Init(comp, print_all);
+       (&P).PrintObjectStruct(obj);
+}