- addded interface pretty printer

R=r
OCL=13646
CL=13646
diff --git a/usr/gri/gosrc/compilation.go b/usr/gri/gosrc/compilation.go
index 14aebba..4ed09ba 100644
--- a/usr/gri/gosrc/compilation.go
+++ b/usr/gri/gosrc/compilation.go
@@ -13,6 +13,7 @@
 import AST "ast"
 import Parser "parser"
 import Export "export"
+import Printer "printer"
 
 
 export Compile
@@ -39,7 +40,12 @@
 		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);
+	*/
 }
diff --git a/usr/gri/gosrc/decls.go b/usr/gri/gosrc/decls.go
index 1910d25..833e227 100755
--- a/usr/gri/gosrc/decls.go
+++ b/usr/gri/gosrc/decls.go
@@ -120,4 +120,5 @@
 }
 
 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
diff --git a/usr/gri/gosrc/parser.go b/usr/gri/gosrc/parser.go
index 67caa6a..6372a1d 100644
--- a/usr/gri/gosrc/parser.go
+++ b/usr/gri/gosrc/parser.go
@@ -169,54 +169,54 @@
 }
 
 
-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 @@
 	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 @@
 	
 	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
index 0000000..d2dafd4
--- /dev/null
+++ b/usr/gri/gosrc/printer.go
@@ -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);
+}