if tag >= 0 {
print " [P", tag, "]"; // package ref
} else {
- print "\nP", E.pkg_ref, ": ", -tag; // package no
+ print "\nP", E.pkg_ref, ":";
}
}
}
-func (E *Exporter) WriteScope(scope *Globals.Scope) {
+func (E *Exporter) WriteScope(scope *Globals.Scope, export_all bool) {
if E.debug {
print " {";
}
for p := scope.entries.first; p != nil; p = p.next {
- if p.obj.exported {
+ if export_all || p.obj.exported {
E.WriteObject(p.obj);
}
}
- E.WriteObjectTag(Object.EOS);
+ E.WriteObject(nil);
if E.debug {
print " }";
func (E *Exporter) WriteObject(obj *Globals.Object) {
- if !obj.exported {
- panic "!obj.exported";
+ if obj == nil {
+ E.WriteObjectTag(Object.EOS);
+ return;
}
if obj.kind == Object.TYPE && obj.typ.obj == obj {
case Type.FUNCTION:
E.WriteInt(typ.flags);
- E.WriteScope(typ.scope);
+ E.WriteScope(typ.scope, true);
case Type.STRUCT, Type.INTERFACE:
- E.WriteScope(typ.scope);
+ E.WriteScope(typ.scope, true); // for now
case Type.POINTER, Type.REFERENCE:
E.WriteType(typ.elt);
return;
}
- if -Object.PACKAGE >= 0 {
- panic "-Object.PACKAGE >= 0"; // conflict with ref numbers
- }
-
- E.WritePackageTag(-Object.PACKAGE);
+ E.WritePackageTag(-1);
pkg.ref = E.pkg_ref;
E.pkg_ref++;
pkg := comp.pkgs[0];
E.WritePackage(0);
- E.WriteScope(pkg.scope);
+ E.WriteScope(pkg.scope, false);
if E.debug {
print "\n(", E.buf_pos, " bytes)\n";
export Object
type Object struct {
exported bool;
- pos int; // source position
+ pos int; // source position (< 0 if unknown position)
kind int;
ident string;
typ *Type;
// Scope methods
func (scope *Scope) Lookup(ident string) *Object {
- var p *Elem;
- for p = scope.entries.first; p != nil; p = p.next {
+ for p := scope.entries.first; p != nil; p = p.next {
if p.obj.ident == ident {
if p.obj.scope != scope {
panic "incorrect scope for object";
func (scope *Scope) Print() {
print "scope {";
- var p* Elem;
- for p = scope.entries.first; p != nil; p = p.next {
+ for p := scope.entries.first; p != nil; p = p.next {
print "\n ", p.obj.ident;
}
print "\n}\n";
func (I *Importer) ReadType() *Globals.Type;
-func (I *Importer) ReadObject(tag int) *Globals.Object;
+func (I *Importer) ReadObject() *Globals.Object;
func (I *Importer) ReadPackage() *Globals.Package;
if tag >= 0 {
print " [P", tag, "]"; // package ref
} else {
- print "\nP", I.pkg_ref, ": ", -tag; // package tag
+ print "\nP", I.pkg_ref, ":";
}
}
return tag;
}
scope := Globals.NewScope(nil);
- for {
- tag := I.ReadObjectTag();
- if tag == Object.EOS { // terminator
- break;
- }
+ obj := I.ReadObject();
+ for obj != nil {
// InsertImport only needed for package scopes
// but ok to use always
- scope.InsertImport(I.ReadObject(tag));
+ scope.InsertImport(obj);
+ obj = I.ReadObject();
}
if I.debug {
}
-func (I *Importer) ReadObject(tag int) *Globals.Object {
+func (I *Importer) ReadObject() *Globals.Object {
+ tag := I.ReadObjectTag();
+ if tag == Object.EOS {
+ return nil;
+ }
+
if tag == Object.PTYPE {
// primary type object - handled entirely by ReadType()
typ := I.ReadType();
func (I *Importer) ReadType() *Globals.Type {
tag := I.ReadTypeTag();
-
if tag >= 0 {
return I.types[tag]; // type already imported
}
func (I *Importer) ReadPackage() *Globals.Package {
tag := I.ReadPackageTag();
-
if tag >= 0 {
return I.pkgs[tag]; // package already imported
}
- if -tag != Object.PACKAGE {
- panic "incorrect package tag";
- }
-
ident := I.ReadString();
file_name := I.ReadString();
key := I.ReadString();
}
pkg := I.ReadPackage();
- for {
- tag := I.ReadObjectTag();
- if tag == Object.EOS {
- break;
- }
- obj := I.ReadObject(tag);
+ obj := I.ReadObject();
+ for obj != nil {
obj.pnolev = pkg.obj.pnolev;
pkg.scope.InsertImport(obj);
+ obj = I.ReadObject();
}
if I.debug {
}
-func (P *Parser) ParseMethodDecl() {
+func (P *Parser) ParseMethodDecl(recv_typ *Globals.Type) {
P.Trace("MethodDecl");
pos := P.pos;
P.OpenScope();
P.level--;
sig := P.top_scope;
+
// dummy receiver (give it a name so it won't conflict with unnamed result)
- sig.Insert(Globals.NewObject(pos, Object.VAR, ".recv"));
+ recv := Globals.NewObject(pos, Object.VAR, ".recv");
+ recv.typ = recv_typ;
+ sig.Insert(recv);
+
P.ParseParameters();
+
r0 := sig.entries.len_;
P.TryResult();
P.level++;
typ := Globals.NewType(Type.INTERFACE);
typ.scope = P.top_scope;
for P.tok == Scanner.IDENT {
- P.ParseMethodDecl();
+ P.ParseMethodDecl(typ);
}
P.level++;
P.CloseScope();
any_t = Register(DeclType(Type.ANY, "any", 8));
// All but 'byte' should be platform-dependent, eventually.
- byte_t = DeclAlias("byte", uint8_t);
- ushort_t = DeclAlias("ushort", uint16_t);
- uint_t = DeclAlias("uint", uint32_t);
- ulong_t = DeclAlias("ulong", uint32_t);
- short_t = DeclAlias("short", int16_t);
- int_t = DeclAlias("int", int32_t);
- long_t = DeclAlias("long", int32_t);
- float_t = DeclAlias("float", float32_t);
- double_t = DeclAlias("double", float64_t);
- ptrint_t = DeclAlias("ptrint", uint64_t);
+ byte_t = Register(DeclAlias("byte", uint8_t));
+ ushort_t = Register(DeclAlias("ushort", uint16_t));
+ uint_t = Register(DeclAlias("uint", uint32_t));
+ ulong_t = Register(DeclAlias("ulong", uint32_t));
+ short_t = Register(DeclAlias("short", int16_t));
+ int_t = Register(DeclAlias("int", int32_t));
+ long_t = Register(DeclAlias("long", int32_t));
+ float_t = Register(DeclAlias("float", float32_t));
+ double_t = Register(DeclAlias("double", float64_t));
+ ptrint_t = Register(DeclAlias("ptrint", uint64_t));
// Predeclared constants
true_ = DeclObj(Object.CONST, "true", bool_t);