- 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);
+}