- fixed import bug (import "...")
- better debugging support
- removed dead code
R=r
OCL=13680
CL=13680
diff --git a/usr/gri/gosrc/compilation.go b/usr/gri/gosrc/compilation.go
index 33d5029..a7d1c9a 100644
--- a/usr/gri/gosrc/compilation.go
+++ b/usr/gri/gosrc/compilation.go
@@ -14,6 +14,7 @@
import Parser "parser"
import Export "export"
import Printer "printer"
+import Verifier "verifier"
export Compile
@@ -36,9 +37,15 @@
return;
}
- // export
- if comp.flags.semantic_checks {
- Printer.PrintObject(comp, comp.pkgs[0].obj, false);
- Export.Export(comp, file_name);
+ if !comp.flags.semantic_checks {
+ return;
}
+
+ Verifier.Verify(comp);
+
+ if comp.flags.print_export {
+ Printer.PrintObject(comp, comp.pkgs[0].obj, false);
+ }
+
+ Export.Export(comp, file_name);
}
diff --git a/usr/gri/gosrc/decls.go b/usr/gri/gosrc/decls.go
index f8e70d5..37b261e 100755
--- a/usr/gri/gosrc/decls.go
+++ b/usr/gri/gosrc/decls.go
@@ -6,7 +6,7 @@
package decls
-// import "base" // this fails
+import "base"
import base "base"
import base2 "base"
diff --git a/usr/gri/gosrc/export.go b/usr/gri/gosrc/export.go
index 17e4145..441e68a 100755
--- a/usr/gri/gosrc/export.go
+++ b/usr/gri/gosrc/export.go
@@ -15,7 +15,7 @@
comp *Globals.Compilation;
debug bool;
buf [4*1024] byte;
- pos int;
+ buf_pos int;
pkg_ref int;
type_ref int;
};
@@ -27,8 +27,8 @@
func (E *Exporter) WriteByte(x byte) {
- E.buf[E.pos] = x;
- E.pos++;
+ E.buf[E.buf_pos] = x;
+ E.buf_pos++;
/*
if E.debug {
print " ", x;
@@ -71,7 +71,7 @@
}
E.WriteInt(tag);
if E.debug {
- print "\nObj: ", tag; // obj kind
+ print "\n", Object.KindStr(tag);
}
}
@@ -79,10 +79,10 @@
func (E *Exporter) WriteTypeTag(tag int) {
E.WriteInt(tag);
if E.debug {
- if tag > 0 {
- print "\nTyp ", E.type_ref, ": ", tag; // type form
+ if tag >= 0 {
+ print " [T", tag, "]"; // type ref
} else {
- print " [Typ ", -tag, "]"; // type ref
+ print "\nT", E.type_ref, ": ", Type.FormStr(-tag);
}
}
}
@@ -91,23 +91,15 @@
func (E *Exporter) WritePackageTag(tag int) {
E.WriteInt(tag);
if E.debug {
- if tag > 0 {
- print "\nPkg ", E.pkg_ref, ": ", tag; // package no
+ if tag >= 0 {
+ print " [P", tag, "]"; // package ref
} else {
- print " [Pkg ", -tag, "]"; // package ref
+ print "\nP", E.pkg_ref, ": ", -tag; // package no
}
}
}
-func (E *Exporter) WriteTypeField(fld *Globals.Object) {
- if fld.kind != Object.VAR {
- panic "fld.kind != Object.VAR";
- }
- E.WriteType(fld.typ);
-}
-
-
func (E *Exporter) WriteScope(scope *Globals.Scope) {
if E.debug {
print " {";
@@ -118,7 +110,7 @@
E.WriteObject(p.obj);
}
}
- E.WriteObjectTag(0); // terminator
+ E.WriteObjectTag(Object.EOS);
if E.debug {
print " }";
@@ -127,8 +119,8 @@
func (E *Exporter) WriteObject(obj *Globals.Object) {
- if obj == nil || !obj.exported {
- panic "obj == nil || !obj.exported";
+ if !obj.exported {
+ panic "!obj.exported";
}
if obj.kind == Object.TYPE && obj.typ.obj == obj {
@@ -156,7 +148,6 @@
E.WriteInt(0); // should be the correct address/offset
default:
- print "obj.kind = ", obj.kind, "\n";
panic "UNREACHABLE";
}
}
@@ -164,19 +155,16 @@
func (E *Exporter) WriteType(typ *Globals.Type) {
- if typ == nil {
- panic "typ == nil";
- }
-
if typ.ref >= 0 {
- E.WriteTypeTag(-typ.ref); // type already exported
+ E.WriteTypeTag(typ.ref); // type already exported
return;
}
- if typ.form <= 0 {
- panic "typ.form <= 0";
+ if -typ.form >= 0 {
+ panic "-typ.form >= 0"; // conflict with ref numbers
}
- E.WriteTypeTag(typ.form);
+
+ E.WriteTypeTag(-typ.form);
typ.ref = E.type_ref;
E.type_ref++;
@@ -214,7 +202,6 @@
E.WriteType(typ.elt);
default:
- print "typ.form = ", typ.form, "\n";
panic "UNREACHABLE";
}
}
@@ -222,14 +209,15 @@
func (E *Exporter) WritePackage(pkg *Globals.Package) {
if pkg.ref >= 0 {
- E.WritePackageTag(-pkg.ref); // package already exported
+ E.WritePackageTag(pkg.ref); // package already exported
return;
}
- if Object.PACKAGE <= 0 {
- panic "Object.PACKAGE <= 0";
+ if -Object.PACKAGE >= 0 {
+ panic "-Object.PACKAGE >= 0"; // conflict with ref numbers
}
- E.WritePackageTag(Object.PACKAGE);
+
+ E.WritePackageTag(-Object.PACKAGE);
pkg.ref = E.pkg_ref;
E.pkg_ref++;
@@ -242,7 +230,7 @@
func (E *Exporter) Export(comp* Globals.Compilation, file_name string) {
E.comp = comp;
E.debug = comp.flags.debug;
- E.pos = 0;
+ E.buf_pos = 0;
E.pkg_ref = 0;
E.type_ref = 0;
@@ -267,10 +255,10 @@
E.WriteScope(pkg.scope);
if E.debug {
- print "\n(", E.pos, " bytes)\n";
+ print "\n(", E.buf_pos, " bytes)\n";
}
- data := string(E.buf)[0 : E.pos];
+ data := string(E.buf)[0 : E.buf_pos];
ok := sys.writefile(file_name, data);
if !ok {
diff --git a/usr/gri/gosrc/globals.go b/usr/gri/gosrc/globals.go
index 6e872df..3474355 100644
--- a/usr/gri/gosrc/globals.go
+++ b/usr/gri/gosrc/globals.go
@@ -78,8 +78,10 @@
export Flags;
type Flags struct {
debug bool;
+ print_export bool;
semantic_checks bool;
verbose int;
+ sixg bool;
}
@@ -102,7 +104,7 @@
obj.pos = pos;
obj.kind = kind;
obj.ident = ident;
- obj.typ = nil; // Universe::undef_t;
+ obj.typ = nil; // Universe::undef_t; (cyclic import...)
obj.pnolev = 0;
return obj;
}
diff --git a/usr/gri/gosrc/go.go b/usr/gri/gosrc/go.go
index 85b4a9f..31f1b87 100644
--- a/usr/gri/gosrc/go.go
+++ b/usr/gri/gosrc/go.go
@@ -18,9 +18,11 @@
print "usage:\n";
print " go { flag | file }\n";
print " -d print debug information\n";
+ print " -p print export\n";
print " -s enable semantic checks\n";
print " -v verbose mode\n";
print " -vv very verbose mode\n";
+ print " -6g 6g compatibility mode\n";
}
@@ -36,9 +38,11 @@
for i := 1; i < sys.argc(); i++ {
switch arg := sys.argv(i); arg {
case "-d": flags.debug = true;
+ case "-p": flags.print_export = true;
case "-s": flags.semantic_checks = true;
case "-v": flags.verbose = 1;
case "-vv": flags.verbose = 2;
+ case "-6g": flags.sixg = true;
default: files.AddStr(arg);
}
}
diff --git a/usr/gri/gosrc/import.go b/usr/gri/gosrc/import.go
index 77b0f30..66c6e2f 100755
--- a/usr/gri/gosrc/import.go
+++ b/usr/gri/gosrc/import.go
@@ -15,11 +15,11 @@
comp *Globals.Compilation;
debug bool;
buf string;
- pos int;
+ buf_pos int;
pkgs [256] *Globals.Package;
- npkgs int;
+ pkg_ref int;
types [1024] *Globals.Type;
- ntypes int;
+ type_ref int;
};
@@ -29,8 +29,8 @@
func (I *Importer) ReadByte() byte {
- x := I.buf[I.pos];
- I.pos++;
+ x := I.buf[I.buf_pos];
+ I.buf_pos++;
/*
if E.debug {
print " ", x;
@@ -80,7 +80,7 @@
panic "tag < 0";
}
if I.debug {
- print "\nObj: ", tag; // obj kind
+ print "\n", Object.KindStr(tag);
}
return tag;
}
@@ -89,10 +89,10 @@
func (I *Importer) ReadTypeTag() int {
tag := I.ReadInt();
if I.debug {
- if tag > 0 {
- print "\nTyp ", I.ntypes, ": ", tag; // type form
+ if tag >= 0 {
+ print " [T", tag, "]"; // type ref
} else {
- print " [Typ ", -tag, "]"; // type ref
+ print "\nT", I.type_ref, ": ", Type.FormStr(-tag);
}
}
return tag;
@@ -102,23 +102,16 @@
func (I *Importer) ReadPackageTag() int {
tag := I.ReadInt();
if I.debug {
- if tag > 0 {
- print "\nPkg ", I.npkgs, ": ", tag; // package tag
+ if tag >= 0 {
+ print " [P", tag, "]"; // package ref
} else {
- print " [Pkg ", -tag, "]"; // package ref
+ print "\nP", I.pkg_ref, ": ", -tag; // package tag
}
}
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 " {";
@@ -127,7 +120,7 @@
scope := Globals.NewScope(nil);
for {
tag := I.ReadObjectTag();
- if tag == 0 {
+ if tag == Object.EOS { // terminator
break;
}
// InsertImport only needed for package scopes
@@ -159,12 +152,6 @@
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
@@ -176,6 +163,9 @@
case Object.FUNC:
I.ReadInt(); // should set the address/offset field
+
+ default:
+ panic "UNREACHABLE";
}
return obj;
@@ -186,14 +176,14 @@
func (I *Importer) ReadType() *Globals.Type {
tag := I.ReadTypeTag();
- if tag <= 0 {
- return I.types[-tag]; // type already imported
+ if tag >= 0 {
+ return I.types[tag]; // type already imported
}
- typ := Globals.NewType(tag);
+ typ := Globals.NewType(-tag);
ptyp := typ; // primary type
ident := I.ReadString();
- if (len(ident) > 0) {
+ if len(ident) > 0 {
// primary type
obj := Globals.NewObject(0, Object.TYPE, ident);
obj.typ = typ;
@@ -206,22 +196,11 @@
ptyp = obj.typ;
}
- I.types[I.ntypes] = ptyp;
- I.ntypes++;
+ I.types[I.type_ref] = ptyp;
+ I.type_ref++;
- switch (tag) {
+ switch (typ.form) {
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.ReadType();
@@ -243,6 +222,9 @@
case Type.POINTER, Type.REFERENCE:
typ.elt = I.ReadType();
+
+ default:
+ panic "UNREACHABLE";
}
return ptyp; // only use primary type
@@ -252,10 +234,14 @@
func (I *Importer) ReadPackage() *Globals.Package {
tag := I.ReadPackageTag();
- if (tag <= 0) {
- return I.pkgs[-tag]; // package already imported
+ 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();
@@ -268,12 +254,12 @@
pkg.scope = Globals.NewScope(nil);
pkg = I.comp.InsertImport(pkg);
- } else if (key != pkg.key) {
+ } else if key != pkg.key {
// package inconsistency
panic "package key inconsistency";
}
- I.pkgs[I.npkgs] = pkg;
- I.npkgs++;
+ I.pkgs[I.pkg_ref] = pkg;
+ I.pkg_ref++;
return pkg;
}
@@ -283,9 +269,9 @@
I.comp = comp;
I.debug = comp.flags.debug;
I.buf = "";
- I.pos = 0;
- I.npkgs = 0;
- I.ntypes = 0;
+ I.buf_pos = 0;
+ I.pkg_ref = 0;
+ I.type_ref = 0;
if I.debug {
print "importing from ", file_name, "\n";
@@ -299,17 +285,17 @@
// Predeclared types are "pre-imported".
for p := Universe.types.first; p != nil; p = p.next {
- if p.typ.ref != I.ntypes {
+ if p.typ.ref != I.type_ref {
panic "incorrect ref for predeclared type";
}
- I.types[I.ntypes] = p.typ;
- I.ntypes++;
+ I.types[I.type_ref] = p.typ;
+ I.type_ref++;
}
pkg := I.ReadPackage();
for {
tag := I.ReadObjectTag();
- if tag == 0 {
+ if tag == Object.EOS {
break;
}
obj := I.ReadObject(tag);
@@ -318,7 +304,7 @@
}
if I.debug {
- print "\n(", I.pos, " bytes)\n";
+ print "\n(", I.buf_pos, " bytes)\n";
}
return pkg;
diff --git a/usr/gri/gosrc/object.go b/usr/gri/gosrc/object.go
index bef5fbc..aab80cc 100755
--- a/usr/gri/gosrc/object.go
+++ b/usr/gri/gosrc/object.go
@@ -7,14 +7,32 @@
import Globals "globals"
-export BAD, CONST, TYPE, VAR, FUNC, PACKAGE, LABEL, PTYPE
+export BAD, CONST, TYPE, VAR, FUNC, PACKAGE, LABEL, PTYPE, EOS
const /* kind */ (
BAD = iota; // error handling
CONST; TYPE; VAR; FUNC; PACKAGE; LABEL;
PTYPE; // primary type (import/export only)
+ EOS; // end of scope (import/export only)
)
// The 'Object' declaration should be here as well, but 6g cannot handle
// this due to cross-package circular references. For now it's all in
// globals.go.
+
+
+export KindStr
+func KindStr(kind int) string {
+ switch kind {
+ case BAD: return "BAD";
+ case CONST: return "CONST";
+ case TYPE: return "TYPE";
+ case VAR: return "VAR";
+ case FUNC: return "FUNC";
+ case PACKAGE: return "PACKAGE";
+ case LABEL: return "LABEL";
+ case PTYPE: return "PTYPE";
+ case EOS: return "EOS";
+ }
+ return "<unknown Object kind>";
+}
diff --git a/usr/gri/gosrc/parser.go b/usr/gri/gosrc/parser.go
index d12ce76..45b529d 100644
--- a/usr/gri/gosrc/parser.go
+++ b/usr/gri/gosrc/parser.go
@@ -27,7 +27,7 @@
val string; // token value (for IDENT, NUMBER, STRING only)
// Semantic analysis
- level int; // 0 = global scope, -1 = function scope of global functions, etc.
+ level int; // 0 = global scope, -1 = function/struct scope of global functions/structs, etc.
top_scope *Globals.Scope;
undef_types *Globals.List;
exports *Globals.List;
@@ -486,6 +486,7 @@
P.Trace("AnonymousSignature");
P.OpenScope();
+ P.level--;
sig := P.top_scope;
p0 := 0;
@@ -505,6 +506,7 @@
r0 := sig.entries.len_;
P.TryResult();
+ P.level++;
P.CloseScope();
P.Ecart();
@@ -525,6 +527,7 @@
P.Trace("NamedSignature");
P.OpenScope();
+ P.level--;
sig := P.top_scope;
p0 := 0;
@@ -546,6 +549,7 @@
r0 := sig.entries.len_;
P.TryResult();
+ P.level++;
P.CloseScope();
P.Ecart();
@@ -569,11 +573,13 @@
P.ParseIdent();
P.OpenScope();
+ P.level--;
sig := P.top_scope;
p0 := 0;
P.ParseParameters();
r0 := sig.entries.len_;
P.TryResult();
+ P.level++;
P.CloseScope();
P.Optional(Scanner.SEMICOLON);
@@ -587,11 +593,13 @@
P.Expect(Scanner.INTERFACE);
P.Expect(Scanner.LBRACE);
P.OpenScope();
+ P.level--;
typ := Globals.NewType(Type.INTERFACE);
typ.scope = P.top_scope;
for P.tok == Scanner.IDENT {
P.ParseMethodDecl();
}
+ P.level++;
P.CloseScope();
P.Expect(Scanner.RBRACE);
@@ -628,6 +636,7 @@
P.Expect(Scanner.STRUCT);
P.Expect(Scanner.LBRACE);
P.OpenScope();
+ P.level--;
typ := Globals.NewType(Type.STRUCT);
typ.scope = P.top_scope;
for P.tok == Scanner.IDENT {
@@ -637,6 +646,7 @@
}
}
P.Optional(Scanner.SEMICOLON);
+ P.level++;
P.CloseScope();
P.Expect(Scanner.RBRACE);
@@ -745,8 +755,12 @@
if sig != nil {
P.level--;
// add function parameters to scope
+ // TODO do we need to make a copy? what if we change obj fields?
scope := P.top_scope;
for p := sig.entries.first; p != nil; p = p.next {
+ if p.obj.pnolev != P.level {
+ panic "incorrect level";
+ }
scope.Insert(p.obj)
}
}
@@ -1560,12 +1574,13 @@
pkg_name := P.val[1 : len(P.val) - 1]; // strip quotes
pkg := Import.Import(P.comp, pkg_name);
if pkg != nil {
+ pno := pkg.obj.pnolev; // preserve pno
if obj == nil {
// use original package name
obj = pkg.obj;
- P.Declare(obj);
+ P.Declare(obj); // this changes (pkg.)obj.pnolev!
}
- obj.pnolev = pkg.obj.pnolev;
+ obj.pnolev = pno; // correct pno
} else {
P.Error(P.pos, `import of "` + pkg_name + `" failed`);
}
@@ -1836,7 +1851,10 @@
}
P.Optional(Scanner.SEMICOLON);
- { P.OpenScope();
+ { if P.level != 0 {
+ panic "incorrect scope level";
+ }
+ P.OpenScope();
pkg.scope = P.top_scope;
for P.tok == Scanner.IMPORT {
P.ParseDecl(false, Scanner.IMPORT);
@@ -1851,6 +1869,9 @@
P.ResolveUndefTypes();
P.MarkExports();
P.CloseScope();
+ if P.level != 0 {
+ panic "incorrect scope level";
+ }
}
P.CloseScope();
diff --git a/usr/gri/gosrc/type.go b/usr/gri/gosrc/type.go
index f46f58d..ea08779 100644
--- a/usr/gri/gosrc/type.go
+++ b/usr/gri/gosrc/type.go
@@ -34,3 +34,28 @@
// The 'Type' declaration should be here as well, but 6g cannot handle
// this due to cross-package circular references. For now it's all in
// globals.go.
+
+
+export FormStr
+func FormStr(form int) string {
+ switch form {
+ case UNDEF: return "UNDEF";
+ case BAD: return "BAD";
+ case NIL: return "NIL";
+ case BOOL: return "BOOL";
+ case UINT: return "UINT";
+ case INT: return "INT";
+ case FLOAT: return "FLOAT";
+ case STRING: return "STRING";
+ case ANY: return "ANY";
+ case ARRAY: return "ARRAY";
+ case STRUCT: return "STRUCT";
+ case INTERFACE: return "INTERFACE";
+ case MAP: return "MAP";
+ case CHANNEL: return "CHANNEL";
+ case FUNCTION: return "FUNCTION";
+ case POINTER: return "POINTER";
+ case REFERENCE: return "REFERENCE";
+ }
+ return "<unknown Type form>";
+}