mirror of https://github.com/golang/go.git
- made initial export work
- added code for importing (not tested) - various fixes SVN=128061
This commit is contained in:
parent
bce1c3f09a
commit
dead164cc0
|
|
@ -65,6 +65,8 @@ func Compile(file_name string, verbose int) {
|
|||
}
|
||||
|
||||
// export
|
||||
export_file_name := FixExt(BaseName(file_name)); // strip file dir
|
||||
Export.Export(comp, export_file_name);
|
||||
/*
|
||||
exp := new(Export.Exporter);
|
||||
exp.Export(comp, FixExt(BaseName(file_name)));
|
||||
*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,13 +7,12 @@ package Exporter
|
|||
import Globals "globals"
|
||||
import Object "object"
|
||||
import Type "type"
|
||||
//import Compilation "compilation"
|
||||
import Universe "universe"
|
||||
|
||||
|
||||
export Exporter // really only want to export Export()
|
||||
type Exporter struct {
|
||||
/*
|
||||
Compilation* comp;
|
||||
*/
|
||||
comp *Globals.Compilation;
|
||||
debug bool;
|
||||
buf [4*1024] byte;
|
||||
pos int;
|
||||
|
|
@ -24,22 +23,26 @@ type Exporter struct {
|
|||
|
||||
func (E *Exporter) WriteType(typ *Globals.Type);
|
||||
func (E *Exporter) WriteObject(obj *Globals.Object);
|
||||
func (E *Exporter) WritePackage(pkg *Globals.Package) ;
|
||||
func (E *Exporter) WritePackage(pkg *Globals.Package);
|
||||
|
||||
|
||||
func (E *Exporter) WriteByte(x byte) {
|
||||
E.buf[E.pos] = x;
|
||||
E.pos++;
|
||||
/*
|
||||
if E.debug {
|
||||
print " ", x;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
func (E *Exporter) WriteInt(x int) {
|
||||
/*
|
||||
if E.debug {
|
||||
print " #", x;
|
||||
}
|
||||
*/
|
||||
for x < -64 || x >= 64 {
|
||||
E.WriteByte(byte(x & 127));
|
||||
x = int(uint(x >> 7)); // arithmetic shift
|
||||
|
|
@ -51,7 +54,7 @@ func (E *Exporter) WriteInt(x int) {
|
|||
|
||||
func (E *Exporter) WriteString(s string) {
|
||||
if E.debug {
|
||||
print `"`, s, `"`;
|
||||
print ` "`, s, `"`;
|
||||
}
|
||||
n := len(s);
|
||||
E.WriteInt(n);
|
||||
|
|
@ -66,7 +69,7 @@ func (E *Exporter) WriteObjTag(tag int) {
|
|||
panic "tag < 0";
|
||||
}
|
||||
if E.debug {
|
||||
print "\nO: ", tag; // obj kind
|
||||
print "\nObj: ", tag; // obj kind
|
||||
}
|
||||
E.WriteInt(tag);
|
||||
}
|
||||
|
|
@ -75,9 +78,9 @@ func (E *Exporter) WriteObjTag(tag int) {
|
|||
func (E *Exporter) WriteTypeTag(tag int) {
|
||||
if E.debug {
|
||||
if tag > 0 {
|
||||
print "\nT", E.type_ref, ": ", tag; // type form
|
||||
print "\nTyp ", E.type_ref, ": ", tag; // type form
|
||||
} else {
|
||||
print " [T", -tag, "]"; // type ref
|
||||
print " [Typ ", -tag, "]"; // type ref
|
||||
}
|
||||
}
|
||||
E.WriteInt(tag);
|
||||
|
|
@ -87,9 +90,9 @@ func (E *Exporter) WriteTypeTag(tag int) {
|
|||
func (E *Exporter) WritePackageTag(tag int) {
|
||||
if E.debug {
|
||||
if tag > 0 {
|
||||
print "\nP", E.pkg_ref, ": ", tag; // package no
|
||||
print "\nPkg ", E.pkg_ref, ": ", tag; // package no
|
||||
} else {
|
||||
print " [P", -tag, "]"; // package ref
|
||||
print " [Pkg ", -tag, "]"; // package ref
|
||||
}
|
||||
}
|
||||
E.WriteInt(tag);
|
||||
|
|
@ -146,8 +149,7 @@ func (E *Exporter) WriteObject(obj *Globals.Object) {
|
|||
E.WriteObjTag(obj.kind);
|
||||
E.WriteString(obj.ident);
|
||||
E.WriteType(obj.typ);
|
||||
panic "UNIMPLEMENTED";
|
||||
//E.WritePackage(E.comp.packages[obj.pnolev]);
|
||||
E.WritePackage(E.comp.pkgs[obj.pnolev]);
|
||||
|
||||
switch obj.kind {
|
||||
case Object.BAD: fallthrough;
|
||||
|
|
@ -192,8 +194,7 @@ func (E *Exporter) WriteType(typ *Globals.Type) {
|
|||
panic "typ.obj.type() != typ"; // primary type
|
||||
}
|
||||
E.WriteString(typ.obj.ident);
|
||||
panic "UNIMPLEMENTED";
|
||||
//WritePackage(E.comp.packages[typ.obj.pnolev]);
|
||||
E.WritePackage(E.comp.pkgs[typ.obj.pnolev]);
|
||||
} else {
|
||||
E.WriteString("");
|
||||
}
|
||||
|
|
@ -258,27 +259,30 @@ func (E *Exporter) WritePackage(pkg *Globals.Package) {
|
|||
}
|
||||
|
||||
|
||||
func (E *Exporter) Export(/*Compilation* comp, BBuffer* buf*/) {
|
||||
panic "UNIMPLEMENTED";
|
||||
|
||||
/*
|
||||
func (E *Exporter) Export(comp* Globals.Compilation, file_name string) {
|
||||
E.comp = comp;
|
||||
E.buf = buf;
|
||||
E.pak_ref = 0;
|
||||
E.nbytes = 0;
|
||||
*/
|
||||
E.debug = true;
|
||||
E.pos = 0;
|
||||
E.pkg_ref = 0;
|
||||
E.type_ref = 0;
|
||||
|
||||
if E.debug {
|
||||
print "exporting to ", file_name;
|
||||
}
|
||||
|
||||
// Predeclared types are "pre-exported".
|
||||
/*
|
||||
#ifdef DEBUG
|
||||
for (int i = 0; i < Universe.types.len(); i++) {
|
||||
ASSERT(Universe.types[i].ref == i);
|
||||
// TODO run the loop below only in debug mode
|
||||
{ i := 0;
|
||||
for p := Universe.types.first; p != nil; p = p.next {
|
||||
if p.typ.ref != i {
|
||||
panic "incorrect ref for predeclared type";
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
E.type_ref = Universe.types.len();
|
||||
*/
|
||||
E.type_ref = Universe.types.len_;
|
||||
|
||||
var pkg *Globals.Package = nil; // comp.packages[0];
|
||||
pkg := comp.pkgs[0];
|
||||
E.WritePackage(pkg);
|
||||
for p := pkg.scope.entries.first; p != nil; p = p.next {
|
||||
if p.obj.mark {
|
||||
|
|
@ -288,15 +292,9 @@ func (E *Exporter) Export(/*Compilation* comp, BBuffer* buf*/) {
|
|||
E.WriteObjTag(0);
|
||||
|
||||
if E.debug {
|
||||
print "\n(", E.pos, ")\n";
|
||||
print "\n(", E.pos, " bytes)\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export Export
|
||||
func Export(comp *Globals.Compilation, file_name string) {
|
||||
/*
|
||||
Exporter exp;
|
||||
exp.Export(comp, buf);
|
||||
*/
|
||||
|
||||
data := string(E.buf)[0 : E.pos];
|
||||
ok := sys.writefile(file_name, data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ func NewPackage(file_name string) *Package {
|
|||
pkg := new(Package);
|
||||
pkg.ref = -1;
|
||||
pkg.file_name = file_name;
|
||||
pkg.key = "<the package key>"; // TODO fix this
|
||||
return pkg;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,314 @@
|
|||
// 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 Importer
|
||||
|
||||
import Globals "globals"
|
||||
import Object "object"
|
||||
import Type "type"
|
||||
import Universe "universe"
|
||||
|
||||
|
||||
type Importer struct {
|
||||
comp *Globals.Compilation;
|
||||
debug bool;
|
||||
buf string;
|
||||
pos int;
|
||||
pkgs [256] *Globals.Package;
|
||||
npkgs int;
|
||||
types [1024] *Globals.Type;
|
||||
ntypes int;
|
||||
};
|
||||
|
||||
|
||||
func (I *Importer) ReadType() *Globals.Type;
|
||||
func (I *Importer) ReadObject(tag int) *Globals.Object;
|
||||
func (I *Importer) ReadPackage() *Globals.Package;
|
||||
|
||||
|
||||
func (I *Importer) ReadByte() byte {
|
||||
x := I.buf[I.pos];
|
||||
I.pos++;
|
||||
/*
|
||||
if E.debug {
|
||||
print " ", x;
|
||||
}
|
||||
*/
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
func (I *Importer) ReadInt() int {
|
||||
x := 0;
|
||||
s := 0; // TODO eventually Go will require this to be a uint!
|
||||
b := I.ReadByte();
|
||||
for b < 128 {
|
||||
x |= int(b) << s;
|
||||
s += 7;
|
||||
b = I.ReadByte();
|
||||
}
|
||||
// b >= 128
|
||||
x |= ((int(b) - 192) << s);
|
||||
/*
|
||||
if I.debug {
|
||||
print " #", x;
|
||||
}
|
||||
*/
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
func (I *Importer) ReadString() string {
|
||||
var buf [256] byte; // TODO this needs to be fixed
|
||||
n := I.ReadInt();
|
||||
for i := 0; i < n; i++ {
|
||||
buf[i] = I.ReadByte();
|
||||
}
|
||||
s := string(buf)[0 : n];
|
||||
if I.debug {
|
||||
print ` "`, s, `"`;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
func (I *Importer) ReadObjTag() int {
|
||||
tag := I.ReadInt();
|
||||
if tag < 0 {
|
||||
panic "tag < 0";
|
||||
}
|
||||
if I.debug {
|
||||
print "\nObj: ", tag; // obj kind
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
func (I *Importer) ReadTypeTag() int {
|
||||
tag := I.ReadInt();
|
||||
if I.debug {
|
||||
if tag > 0 {
|
||||
print "\nTyp ", I.ntypes, ": ", tag; // type form
|
||||
} else {
|
||||
print " [Typ ", -tag, "]"; // type ref
|
||||
}
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
func (I *Importer) ReadPackageTag() int {
|
||||
tag := I.ReadInt();
|
||||
if I.debug {
|
||||
if tag > 0 {
|
||||
print "\nPkg ", I.npkgs, ": ", tag; // package tag
|
||||
} else {
|
||||
print " [Pkg ", -tag, "]"; // package ref
|
||||
}
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
func (I *Importer) ReadTypeField() *Globals.Object {
|
||||
fld := Globals.NewObject(0, Object.VAR, "");
|
||||
fld.typ = I.ReadType();
|
||||
return fld;
|
||||
}
|
||||
|
||||
|
||||
func (I *Importer) ReadScope() *Globals.Scope {
|
||||
if I.debug {
|
||||
print " {";
|
||||
}
|
||||
|
||||
scope := Globals.NewScope(nil);
|
||||
for n := I.ReadInt(); n > 0; n-- {
|
||||
tag := I.ReadObjTag();
|
||||
scope.Insert(I.ReadObject(tag));
|
||||
}
|
||||
|
||||
if I.debug {
|
||||
print " }";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (I *Importer) ReadObject(tag int) *Globals.Object {
|
||||
if tag == Object.PTYPE {
|
||||
// primary type object - handled entirely by ReadType()
|
||||
typ := I.ReadType();
|
||||
if typ.obj.typ != typ {
|
||||
panic "incorrect primary type";
|
||||
}
|
||||
return typ.obj;
|
||||
|
||||
} else {
|
||||
ident := I.ReadString();
|
||||
obj := Globals.NewObject(0, tag, ident);
|
||||
obj.typ = I.ReadType();
|
||||
obj.pnolev = I.ReadPackage().obj.pnolev;
|
||||
|
||||
switch (tag) {
|
||||
default: fallthrough;
|
||||
case Object.BAD: fallthrough;
|
||||
case Object.PACKAGE: fallthrough;
|
||||
case Object.PTYPE:
|
||||
panic "UNREACHABLE";
|
||||
|
||||
case Object.CONST:
|
||||
I.ReadInt(); // should set the value field
|
||||
|
||||
case Object.TYPE:
|
||||
// nothing to do
|
||||
|
||||
case Object.VAR:
|
||||
I.ReadInt(); // should set the address/offset field
|
||||
|
||||
case Object.FUNC:
|
||||
I.ReadInt(); // should set the address/offset field
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (I *Importer) ReadType() *Globals.Type {
|
||||
tag := I.ReadTypeTag();
|
||||
|
||||
if tag <= 0 {
|
||||
return I.types[-tag]; // type already imported
|
||||
}
|
||||
|
||||
typ := Globals.NewType(tag);
|
||||
ptyp := typ; // primary type
|
||||
ident := I.ReadString();
|
||||
if (len(ident) > 0) {
|
||||
// primary type
|
||||
obj := Globals.NewObject(0, Object.TYPE, ident);
|
||||
obj.typ = typ;
|
||||
typ.obj = obj;
|
||||
|
||||
// canonicalize type
|
||||
pkg := I.ReadPackage();
|
||||
obj.pnolev = pkg.obj.pnolev;
|
||||
obj = pkg.scope.InsertImport(obj);
|
||||
|
||||
ptyp = obj.typ;
|
||||
}
|
||||
I.types[I.ntypes] = ptyp;
|
||||
I.ntypes++;
|
||||
|
||||
switch (tag) {
|
||||
default: fallthrough;
|
||||
case Type.UNDEF: fallthrough;
|
||||
case Type.BAD: fallthrough;
|
||||
case Type.NIL: fallthrough;
|
||||
case Type.BOOL: fallthrough;
|
||||
case Type.UINT: fallthrough;
|
||||
case Type.INT: fallthrough;
|
||||
case Type.FLOAT: fallthrough;
|
||||
case Type.STRING: fallthrough;
|
||||
case Type.ANY:
|
||||
panic "UNREACHABLE";
|
||||
|
||||
case Type.ARRAY:
|
||||
typ.len_ = I.ReadInt();
|
||||
typ.elt = I.ReadTypeField();
|
||||
|
||||
case Type.MAP:
|
||||
typ.key = I.ReadTypeField();
|
||||
typ.elt = I.ReadTypeField();
|
||||
|
||||
case Type.CHANNEL:
|
||||
typ.flags = I.ReadInt();
|
||||
typ.elt = I.ReadTypeField();
|
||||
|
||||
case Type.FUNCTION:
|
||||
typ.flags = I.ReadInt();
|
||||
fallthrough;
|
||||
case Type.STRUCT: fallthrough;
|
||||
case Type.INTERFACE:
|
||||
typ.scope = I.ReadScope();
|
||||
|
||||
case Type.POINTER: fallthrough;
|
||||
case Type.REFERENCE:
|
||||
typ.elt = I.ReadTypeField();
|
||||
}
|
||||
|
||||
return ptyp; // only use primary type
|
||||
}
|
||||
|
||||
|
||||
func (I *Importer) ReadPackage() *Globals.Package {
|
||||
tag := I.ReadPackageTag();
|
||||
|
||||
if (tag <= 0) {
|
||||
return I.pkgs[-tag]; // package already imported
|
||||
}
|
||||
|
||||
ident := I.ReadString();
|
||||
file_name := I.ReadString();
|
||||
key := I.ReadString();
|
||||
pkg := I.comp.Lookup(file_name);
|
||||
|
||||
if pkg == nil {
|
||||
// new package
|
||||
pkg = Globals.NewPackage(file_name);
|
||||
pkg.scope = Globals.NewScope(nil);
|
||||
pkg = I.comp.InsertImport(pkg);
|
||||
|
||||
} else if (key != pkg.key) {
|
||||
// package inconsistency
|
||||
panic "package key inconsistency";
|
||||
}
|
||||
I.pkgs[I.npkgs] = pkg;
|
||||
I.npkgs++;
|
||||
|
||||
return pkg;
|
||||
}
|
||||
|
||||
|
||||
func (I *Importer) Import(comp* Globals.Compilation, file_name string) {
|
||||
if I.debug {
|
||||
print "importing from ", file_name;
|
||||
}
|
||||
|
||||
buf, ok := sys.readfile(file_name);
|
||||
if !ok {
|
||||
panic "import failed";
|
||||
}
|
||||
|
||||
I.comp = comp;
|
||||
I.debug = true;
|
||||
I.buf = buf;
|
||||
I.pos = 0;
|
||||
I.npkgs = 0;
|
||||
I.ntypes = 0;
|
||||
|
||||
// Predeclared types are "pre-exported".
|
||||
for p := Universe.types.first; p != nil; p = p.next {
|
||||
if p.typ.ref != I.ntypes {
|
||||
panic "incorrect ref for predeclared type";
|
||||
}
|
||||
I.types[I.ntypes] = p.typ;
|
||||
I.ntypes++;
|
||||
}
|
||||
|
||||
pkg := I.ReadPackage();
|
||||
for {
|
||||
tag := I.ReadObjTag();
|
||||
if tag == 0 {
|
||||
break;
|
||||
}
|
||||
obj := I.ReadObject(tag);
|
||||
obj.pnolev = pkg.obj.pnolev;
|
||||
pkg.scope.InsertImport(obj);
|
||||
}
|
||||
|
||||
if I.debug {
|
||||
print "\n(", I.pos, " bytes)\n";
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ import Type "type"
|
|||
|
||||
export
|
||||
scope,
|
||||
types,
|
||||
undef_t, bad_t, nil_t,
|
||||
bool_t,
|
||||
uint8_t, uint16_t, uint32_t, uint64_t,
|
||||
|
|
@ -27,6 +28,7 @@ export
|
|||
|
||||
var (
|
||||
scope *Globals.Scope;
|
||||
types *Globals.List;
|
||||
|
||||
// internal types
|
||||
undef_t,
|
||||
|
|
@ -90,19 +92,19 @@ func DeclType(form int, ident string, size int) *Globals.Type {
|
|||
|
||||
|
||||
func Register(typ *Globals.Type) *Globals.Type {
|
||||
/*
|
||||
type->ref = Universe::types.len(); // >= 0
|
||||
Universe::types.Add(type);
|
||||
*/
|
||||
if types.len_ < 0 {
|
||||
panic "types.len_ < 0";
|
||||
}
|
||||
typ.ref = types.len_;
|
||||
types.AddTyp(typ);
|
||||
return typ;
|
||||
}
|
||||
|
||||
|
||||
export Init
|
||||
func Init() {
|
||||
// print "initializing universe\n";
|
||||
|
||||
scope = Globals.NewScope(nil); // universe has no parent
|
||||
types = Globals.NewList();
|
||||
|
||||
// Interal types
|
||||
undef_t = Globals.NewType(Type.UNDEF);
|
||||
|
|
|
|||
Loading…
Reference in New Issue