mirror of https://github.com/golang/go.git
parent
9cf8312a57
commit
6acdf3edff
|
|
@ -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);
|
||||
*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
Loading…
Reference in New Issue