From: Robert Griesemer Date: Wed, 30 Jul 2008 20:01:28 +0000 (-0700) Subject: - addded interface pretty printer X-Git-Tag: weekly.2009-11-06~3401 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=6acdf3edff349e966a4928dac91101379ff5b225;p=gostls13.git - 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 14aebba498..4ed09baebf 100644 --- a/usr/gri/gosrc/compilation.go +++ b/usr/gri/gosrc/compilation.go @@ -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); + */ } diff --git a/usr/gri/gosrc/decls.go b/usr/gri/gosrc/decls.go index 1910d2544d..833e227790 100755 --- a/usr/gri/gosrc/decls.go +++ b/usr/gri/gosrc/decls.go @@ -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 diff --git a/usr/gri/gosrc/parser.go b/usr/gri/gosrc/parser.go index 67caa6a972..6372a1d05d 100644 --- a/usr/gri/gosrc/parser.go +++ b/usr/gri/gosrc/parser.go @@ -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 index 0000000000..d2dafd4ecf --- /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 ""; + + case Type.BAD: + print ""; + + 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); +}