Commit 71d50b8b authored by Robert Griesemer's avatar Robert Griesemer

- more import/export stuff

- use new export syntax

R=r
OCL=13807
CL=13807
parent 0cc772cb
......@@ -31,7 +31,6 @@ func Compile(comp *Globals.Compilation, file_name string) {
parser := new(Parser.Parser);
parser.Open(comp, scanner);
print "parsing ", file_name, "\n";
parser.ParseProgram();
if parser.S.nerrors > 0 {
return;
......@@ -44,7 +43,7 @@ func Compile(comp *Globals.Compilation, file_name string) {
Verifier.Verify(comp);
if comp.flags.print_export {
Printer.PrintObject(comp, comp.pkgs[0].obj, false);
Printer.PrintObject(comp, comp.pkg_list[0].obj, false);
}
Export.Export(comp, file_name);
......
......@@ -137,7 +137,6 @@ func (E *Exporter) WriteObject(obj *Globals.Object) {
E.WriteString(obj.ident);
E.WriteType(obj.typ);
E.WritePackage(obj.pnolev);
switch obj.kind {
case Object.CONST:
......@@ -164,21 +163,32 @@ func (E *Exporter) WriteType(typ *Globals.Type) {
if -typ.form >= 0 {
panic "-typ.form >= 0"; // conflict with ref numbers
}
E.WriteTypeTag(-typ.form);
typ.ref = E.type_ref;
E.type_ref++;
// if we have a primary type, export the type identifier and package
ident := "";
if typ.obj != nil {
// primary type
if typ.obj.typ != typ {
panic "typ.obj.type() != typ"; // primary type
panic "inconsistent primary type";
}
ident = typ.obj.ident;
if !typ.obj.exported {
// the type is invisible (it's identifier is not exported)
// prepend "." to the identifier to make it an illegal
// identifier and thus invisible in Go source code
ident = "." + ident;
}
E.WriteString(typ.obj.ident);
}
E.WriteString(ident);
if len(ident) > 0 {
// primary type
E.WritePackage(typ.obj.pnolev);
} else {
E.WriteString("");
}
switch typ.form {
case Type.ALIAS:
E.WriteType(typ.elt);
......@@ -215,7 +225,7 @@ func (E *Exporter) WritePackage(pno int) {
if pno < 0 {
pno = 0;
}
pkg := E.comp.pkgs[pno];
pkg := E.comp.pkg_list[pno];
if pkg.ref >= 0 {
E.WritePackageTag(pkg.ref); // package already exported
return;
......@@ -254,7 +264,7 @@ func (E *Exporter) Export(comp* Globals.Compilation, file_name string) {
}
E.type_ref = Universe.types.len_;
pkg := comp.pkgs[0];
pkg := comp.pkg_list[0];
E.WritePackage(0);
E.WriteScope(pkg.scope, false);
......
......@@ -13,20 +13,17 @@ package Globals
// ----------------------------------------------------------------------------
export Object
type Object struct {
export type Object struct {
exported bool;
pos int; // source position (< 0 if unknown position)
kind int;
ident string;
typ *Type;
pnolev int; // >= 0: package no., <= 0: level, 0: global level of compilation
scope *Scope; // which contains the object
typ *Type; // nil for packages
pnolev int; // >= 0: package no., <= 0: function nesting level, 0: global level
}
export Type
type Type struct {
export type Type struct {
ref int; // for exporting only: >= 0 means already exported
form int;
flags int; // channels, functions
......@@ -39,13 +36,12 @@ type Type struct {
}
export Package
type Package struct {
export type Package struct {
ref int; // for exporting only: >= 0 means already exported
file_name string;
key string;
obj *Object;
scope *Scope;
scope *Scope; // holds the (global) objects in this package
}
......@@ -61,23 +57,20 @@ type Elem struct {
}
export List
type List struct {
export type List struct {
len_ int;
first, last *Elem;
};
export Scope
type Scope struct {
export type Scope struct {
parent *Scope;
entries *List;
// entries *map[string] *Object; // doesn't work properly
}
export Flags;
type Flags struct {
export type Flags struct {
debug bool;
print_export bool;
semantic_checks bool;
......@@ -86,24 +79,21 @@ type Flags struct {
}
export Compilation
type Compilation struct {
export type Compilation struct {
flags *Flags;
// TODO use open arrays eventually
pkgs [256] *Package; // pkgs[0] is the current package
npkgs int;
pkg_list [256] *Package; // pkg_list[0] is the current package
pkg_ref int;
}
export Expr
type Expr interface {
export type Expr interface {
typ() *Type;
// ... more to come here
}
export Stat
type Stat interface {
export type Stat interface {
// ... more to come here
}
......@@ -111,8 +101,7 @@ type Stat interface {
// ----------------------------------------------------------------------------
// Creation
export Universe_undef_t
var Universe_undef_t *Type // initialized by Universe to Universe.undef_t
export var Universe_undef_t *Type // initialized by Universe to Universe.undef_t
export NewObject
func NewObject(pos, kind int, ident string) *Object {
......@@ -123,7 +112,6 @@ func NewObject(pos, kind int, ident string) *Object {
obj.ident = ident;
obj.typ = Universe_undef_t;
obj.pnolev = 0;
obj.scope = nil;
return obj;
}
......@@ -138,11 +126,12 @@ func NewType(form int) *Type {
export NewPackage;
func NewPackage(file_name string) *Package {
func NewPackage(file_name string, obj *Object) *Package {
pkg := new(Package);
pkg.ref = -1; // not yet exported
pkg.file_name = file_name;
pkg.key = "<the package key>"; // TODO fix this
pkg.obj = obj;
return pkg;
}
......@@ -181,7 +170,6 @@ func (obj *Object) Copy() *Object {
copy.ident = obj.ident;
copy.typ = obj.typ;
copy.pnolev = obj.pnolev;
copy.scope = nil; // cannot be in the same scope (same ident!)
return copy;
}
......@@ -272,9 +260,6 @@ func (L *List) AddTyp(typ *Type) {
func (scope *Scope) Lookup(ident string) *Object {
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";
}
return p.obj;
}
}
......@@ -286,11 +271,7 @@ func (scope *Scope) Insert(obj *Object) {
if scope.Lookup(obj.ident) != nil {
panic "obj already inserted";
}
if obj.scope != nil {
panic "obj already in a scope";
}
scope.entries.AddObj(obj);
obj.scope = scope;
}
......@@ -317,8 +298,8 @@ func (scope *Scope) Print() {
// Compilation methods
func (C *Compilation) Lookup(file_name string) *Package {
for i := 0; i < C.npkgs; i++ {
pkg := C.pkgs[i];
for i := 0; i < C.pkg_ref; i++ {
pkg := C.pkg_list[i];
if pkg.file_name == file_name {
return pkg;
}
......@@ -331,9 +312,9 @@ func (C *Compilation) Insert(pkg *Package) {
if C.Lookup(pkg.file_name) != nil {
panic "package already inserted";
}
pkg.obj.pnolev = C.npkgs;
C.pkgs[C.npkgs] = pkg;
C.npkgs++;
pkg.obj.pnolev = C.pkg_ref;
C.pkg_list[C.pkg_ref] = pkg;
C.pkg_ref++;
}
......
......@@ -16,9 +16,9 @@ type Importer struct {
debug bool;
buf string;
buf_pos int;
pkgs [256] *Globals.Package;
pkg_list [256] *Globals.Package;
pkg_ref int;
types [1024] *Globals.Type;
type_list [1024] *Globals.Type;
type_ref int;
};
......@@ -120,8 +120,6 @@ func (I *Importer) ReadScope() *Globals.Scope {
scope := Globals.NewScope(nil);
obj := I.ReadObject();
for obj != nil {
// InsertImport only needed for package scopes
// but ok to use always
scope.InsertImport(obj);
obj = I.ReadObject();
}
......@@ -153,7 +151,6 @@ func (I *Importer) ReadObject() *Globals.Object {
ident := I.ReadString();
obj := Globals.NewObject(0, tag, ident);
obj.typ = I.ReadType();
obj.pnolev = I.ReadPackage().obj.pnolev;
switch (tag) {
case Object.CONST:
......@@ -176,26 +173,31 @@ func (I *Importer) ReadObject() *Globals.Object {
func (I *Importer) ReadType() *Globals.Type {
tag := I.ReadTypeTag();
if tag >= 0 {
return I.types[tag]; // type already imported
return I.type_list[tag]; // type already imported
}
typ := Globals.NewType(-tag);
ptyp := typ; // primary type
ident := I.ReadString();
if len(ident) > 0 {
// primary type
pkg := I.ReadPackage();
// create corresponding type object
obj := Globals.NewObject(0, Object.TYPE, ident);
obj.exported = true;
obj.typ = typ;
obj.pnolev = pkg.obj.pnolev;
typ.obj = obj;
// canonicalize type
pkg := I.ReadPackage();
obj.pnolev = pkg.obj.pnolev;
obj = pkg.scope.InsertImport(obj);
ptyp = obj.typ;
// (if the type was seen before, use primary instance!)
ptyp = pkg.scope.InsertImport(obj).typ;
}
I.types[I.type_ref] = ptyp;
// insert the primary type into the type table but
// keep filling in the current type fields
I.type_list[I.type_ref] = ptyp;
I.type_ref++;
switch (typ.form) {
......@@ -235,7 +237,7 @@ func (I *Importer) ReadType() *Globals.Type {
func (I *Importer) ReadPackage() *Globals.Package {
tag := I.ReadPackageTag();
if tag >= 0 {
return I.pkgs[tag]; // package already imported
return I.pkg_list[tag]; // package already imported
}
ident := I.ReadString();
......@@ -245,8 +247,8 @@ func (I *Importer) ReadPackage() *Globals.Package {
if pkg == nil {
// new package
pkg = Globals.NewPackage(file_name);
pkg.obj = Globals.NewObject(-1, Object.PACKAGE, ident);
obj := Globals.NewObject(-1, Object.PACKAGE, ident);
pkg = Globals.NewPackage(file_name, obj);
pkg.scope = Globals.NewScope(nil);
pkg = I.comp.InsertImport(pkg);
......@@ -254,7 +256,7 @@ func (I *Importer) ReadPackage() *Globals.Package {
// package inconsistency
panic "package key inconsistency";
}
I.pkgs[I.pkg_ref] = pkg;
I.pkg_list[I.pkg_ref] = pkg;
I.pkg_ref++;
return pkg;
......@@ -284,7 +286,7 @@ func (I *Importer) Import(comp* Globals.Compilation, file_name string) *Globals.
if p.typ.ref != I.type_ref {
panic "incorrect ref for predeclared type";
}
I.types[I.type_ref] = p.typ;
I.type_list[I.type_ref] = p.typ;
I.type_ref++;
}
......
......@@ -7,8 +7,7 @@ package Object
import Globals "globals"
export BAD, CONST, TYPE, VAR, FUNC, PACKAGE, LABEL, END
const /* kind */ (
export const /* kind */ (
BAD = iota; // error handling
CONST; TYPE; VAR; FUNC; PACKAGE; LABEL;
END; // end of scope (import/export only)
......
......@@ -306,7 +306,7 @@ func (P *Parser) ParseQualifiedIdent(pos int, ident string) *Globals.Object {
if obj.pnolev < 0 {
panic "obj.pnolev < 0";
}
pkg := P.comp.pkgs[obj.pnolev];
pkg := P.comp.pkg_list[obj.pnolev];
//if pkg.obj.ident != ident {
// panic "pkg.obj.ident != ident";
//}
......@@ -1916,10 +1916,10 @@ func (P *Parser) ParseProgram() {
P.OpenScope();
P.Expect(Scanner.PACKAGE);
pkg := Globals.NewPackage(P.S.filename);
pkg.obj = P.ParseIdentDecl(Object.PACKAGE);
obj := P.ParseIdentDecl(Object.PACKAGE);
pkg := Globals.NewPackage(P.S.filename, obj);
P.comp.Insert(pkg);
if P.comp.npkgs != 1 {
if P.comp.pkg_ref != 1 {
panic "should have exactly one package now";
}
P.Optional(Scanner.SEMICOLON);
......
......@@ -164,7 +164,7 @@ func (P *Printer) PrintObjectStruct(obj *Globals.Object) {
print "package ";
P.PrintObject(obj);
print " ";
P.PrintScope(P.comp.pkgs[obj.pnolev].scope, 0);
P.PrintScope(P.comp.pkg_list[obj.pnolev].scope, 0);
default:
panic "UNREACHABLE";
......@@ -178,7 +178,7 @@ func (P *Printer) PrintObjectStruct(obj *Globals.Object) {
func (P *Printer) PrintObject(obj *Globals.Object) {
if obj.pnolev > 0 {
print P.comp.pkgs[obj.pnolev].obj.ident, ".";
print P.comp.pkg_list[obj.pnolev].obj.ident, ".";
}
print obj.ident;
}
......
......@@ -6,27 +6,7 @@ package Scanner
import Utils "utils"
export
ILLEGAL, EOF, IDENT, STRING, NUMBER,
COMMA, COLON, SEMICOLON, PERIOD,
LPAREN, RPAREN, LBRACK, RBRACK, LBRACE, RBRACE,
ASSIGN, DEFINE,
INC, DEC, NOT,
AND, OR, XOR,
ADD, SUB, MUL, QUO, REM,
EQL, NEQ, LSS, LEQ, GTR, GEQ,
SHL, SHR,
SEND, RECV,
ADD_ASSIGN, SUB_ASSIGN, MUL_ASSIGN, QUO_ASSIGN, REM_ASSIGN,
AND_ASSIGN, OR_ASSIGN, XOR_ASSIGN, SHL_ASSIGN, SHR_ASSIGN,
LAND, LOR,
BREAK, CASE, CHAN, CONST, CONTINUE, DEFAULT, ELSE, EXPORT, FALLTHROUGH, FALSE,
FOR, FUNC, GO, GOTO, IF, IMPORT, INTERFACE, IOTA, MAP, NEW, NIL, PACKAGE, RANGE,
RETURN, SELECT, STRUCT, SWITCH, TRUE, TYPE, VAR
const (
export const (
ILLEGAL = iota;
EOF;
IDENT;
......@@ -270,8 +250,7 @@ func digit_val(ch int) int {
}
export Scanner
type Scanner struct {
export type Scanner struct {
filename string; // error reporting only
nerrors int; // number of errors
errpos int; // last error position
......
......@@ -4,13 +4,7 @@
package Type
export
UNDEF, BAD, NIL,
BOOL, UINT, INT, FLOAT, STRING,
ANY,
ALIAS, ARRAY, STRUCT, INTERFACE, MAP, CHANNEL, FUNCTION, POINTER, REFERENCE
const /* form */ (
export const /* form */ (
// internal types
UNDEF = iota; BAD; NIL;
// basic types
......@@ -22,10 +16,7 @@ const /* form */ (
)
export
SEND, RECV
const /* flag */ (
export const /* flag */ (
SEND = 1 << iota; // chan>
RECV; // chan< or method
)
......
......@@ -106,7 +106,7 @@ func VerifyPackage(pkg *Globals.Package, pno int) {
export Verify
func Verify(comp *Globals.Compilation) {
for i := 0; i < comp.npkgs; i++ {
VerifyPackage(comp.pkgs[i], i);
for i := 0; i < comp.pkg_ref; i++ {
VerifyPackage(comp.pkg_list[i], i);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment