Commit 6acdf3ed authored by Robert Griesemer's avatar Robert Griesemer

- addded interface pretty printer

R=r
OCL=13646
CL=13646
parent 9cf8312a
...@@ -13,6 +13,7 @@ import Scanner "scanner" ...@@ -13,6 +13,7 @@ import Scanner "scanner"
import AST "ast" import AST "ast"
import Parser "parser" import Parser "parser"
import Export "export" import Export "export"
import Printer "printer"
export Compile export Compile
...@@ -39,7 +40,12 @@ func Compile(file_name string, verbose int) { ...@@ -39,7 +40,12 @@ func Compile(file_name string, verbose int) {
return; return;
} }
/*
// export // export
exp := new(Export.Exporter); exp := new(Export.Exporter);
exp.Export(comp, Utils.FixExt(Utils.BaseName(file_name))); exp.Export(comp, Utils.FixExt(Utils.BaseName(file_name)));
// print export
Printer.PrintObject(comp, comp.pkgs[0].obj, false);
*/
} }
...@@ -120,4 +120,5 @@ func (p *T4) m5(a, b int, c float) (z T5, ok bool) { ...@@ -120,4 +120,5 @@ func (p *T4) m5(a, b int, c float) (z T5, ok bool) {
} }
export c0, c1, v2, v3 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
...@@ -169,54 +169,54 @@ func MakeFunctionType(sig *Globals.Scope, p0, r0 int, check_recv bool) *Globals. ...@@ -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 { func (P *Parser) DeclareFunc(ident string, typ *Globals.Type) *Globals.Object {
// Determine scope. // determine scope
scope := P.top_scope; scope := P.top_scope;
if typ.flags & Type.RECV != 0 { if typ.flags & Type.RECV != 0 {
// method - declare in corresponding struct // method - declare in corresponding struct
if typ.scope.entries.len_ < 1 { if typ.scope.entries.len_ < 1 {
panic "no recv in signature?"; panic "no recv in signature?";
} }
trecv := typ.scope.entries.first.typ; recv_typ := typ.scope.entries.first.obj.typ;
if trecv.form == Type.POINTER { if recv_typ.form == Type.POINTER {
trecv = trecv.elt; recv_typ = recv_typ.elt;
} }
scope = trecv.scope; scope = recv_typ.scope;
} }
// Declare the function. // declare the function
fun := scope.Lookup(ident); obj := scope.Lookup(ident);
if fun == nil { if obj == nil {
fun = Globals.NewObject(-1, Object.FUNC, ident); obj = Globals.NewObject(-1, Object.FUNC, ident);
fun.typ = typ; obj.typ = typ;
// TODO do we need to set the prymary type? probably... // TODO do we need to set the primary type? probably...
P.DeclareInScope(scope, fun); P.DeclareInScope(scope, obj);
return fun; return obj;
} }
// fun != NULL: possibly a forward declaration. // obj != NULL: possibly a forward declaration.
if (fun.kind != Object.FUNC) { if (obj.kind != Object.FUNC) {
P.Error(-1, `"` + ident + `" is declared already`); P.Error(-1, `"` + ident + `" is declared already`);
// Continue but do not insert this function into the scope. // Continue but do not insert this function into the scope.
fun = Globals.NewObject(-1, Object.FUNC, ident); obj = Globals.NewObject(-1, Object.FUNC, ident);
fun.typ = typ; obj.typ = typ;
// TODO do we need to set the prymary type? probably... // TODO do we need to set the prymary type? probably...
return fun; return obj;
} }
// We have a function with the same name. // 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()); this->Error("type of \"%s\" does not match its forward declaration", name.cstr());
// Continue but do not insert this function into the scope. // Continue but do not insert this function into the scope.
NewObject(Object::FUNC, name); NewObject(Object::FUNC, name);
fun->set_type(type); obj->set_type(type);
return fun; return obj;
} }
*/ */
// We have a matching forward declaration. Use it. // We have a matching forward declaration. Use it.
return fun; return obj;
} }
...@@ -1510,7 +1510,7 @@ func (P *Parser) TryStatement() bool { ...@@ -1510,7 +1510,7 @@ func (P *Parser) TryStatement() bool {
case Scanner.FUNC: case Scanner.FUNC:
// for now we do not allow local function declarations // for now we do not allow local function declarations
fallthrough; fallthrough;
case Scanner.MUL, Scanner.SEND, Scanner.RECV, Scanner.IDENT: case Scanner.MUL, Scanner.SEND, Scanner.RECV, Scanner.IDENT, Scanner.LPAREN:
P.ParseSimpleStat(); P.ParseSimpleStat();
case Scanner.GO: case Scanner.GO:
P.ParseGoStat(); P.ParseGoStat();
...@@ -1695,7 +1695,8 @@ func (P *Parser) ParseFuncDecl(exported bool) { ...@@ -1695,7 +1695,8 @@ func (P *Parser) ParseFuncDecl(exported bool) {
P.Expect(Scanner.FUNC); P.Expect(Scanner.FUNC);
ident, typ := P.ParseNamedSignature(); 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 { if P.tok == Scanner.SEMICOLON {
// forward declaration // forward declaration
P.Next(); P.Next();
......
// 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment