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) { ...@@ -31,7 +31,6 @@ func Compile(comp *Globals.Compilation, file_name string) {
parser := new(Parser.Parser); parser := new(Parser.Parser);
parser.Open(comp, scanner); parser.Open(comp, scanner);
print "parsing ", file_name, "\n";
parser.ParseProgram(); parser.ParseProgram();
if parser.S.nerrors > 0 { if parser.S.nerrors > 0 {
return; return;
...@@ -44,7 +43,7 @@ func Compile(comp *Globals.Compilation, file_name string) { ...@@ -44,7 +43,7 @@ func Compile(comp *Globals.Compilation, file_name string) {
Verifier.Verify(comp); Verifier.Verify(comp);
if comp.flags.print_export { 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); Export.Export(comp, file_name);
......
...@@ -137,7 +137,6 @@ func (E *Exporter) WriteObject(obj *Globals.Object) { ...@@ -137,7 +137,6 @@ func (E *Exporter) WriteObject(obj *Globals.Object) {
E.WriteString(obj.ident); E.WriteString(obj.ident);
E.WriteType(obj.typ); E.WriteType(obj.typ);
E.WritePackage(obj.pnolev);
switch obj.kind { switch obj.kind {
case Object.CONST: case Object.CONST:
...@@ -164,21 +163,32 @@ func (E *Exporter) WriteType(typ *Globals.Type) { ...@@ -164,21 +163,32 @@ func (E *Exporter) WriteType(typ *Globals.Type) {
if -typ.form >= 0 { if -typ.form >= 0 {
panic "-typ.form >= 0"; // conflict with ref numbers panic "-typ.form >= 0"; // conflict with ref numbers
} }
E.WriteTypeTag(-typ.form); E.WriteTypeTag(-typ.form);
typ.ref = E.type_ref; typ.ref = E.type_ref;
E.type_ref++; E.type_ref++;
// if we have a primary type, export the type identifier and package
ident := "";
if typ.obj != nil { if typ.obj != nil {
// primary type
if typ.obj.typ != typ { 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); E.WritePackage(typ.obj.pnolev);
} else {
E.WriteString("");
} }
switch typ.form { switch typ.form {
case Type.ALIAS: case Type.ALIAS:
E.WriteType(typ.elt); E.WriteType(typ.elt);
...@@ -215,7 +225,7 @@ func (E *Exporter) WritePackage(pno int) { ...@@ -215,7 +225,7 @@ func (E *Exporter) WritePackage(pno int) {
if pno < 0 { if pno < 0 {
pno = 0; pno = 0;
} }
pkg := E.comp.pkgs[pno]; pkg := E.comp.pkg_list[pno];
if pkg.ref >= 0 { if pkg.ref >= 0 {
E.WritePackageTag(pkg.ref); // package already exported E.WritePackageTag(pkg.ref); // package already exported
return; return;
...@@ -254,7 +264,7 @@ func (E *Exporter) Export(comp* Globals.Compilation, file_name string) { ...@@ -254,7 +264,7 @@ func (E *Exporter) Export(comp* Globals.Compilation, file_name string) {
} }
E.type_ref = Universe.types.len_; E.type_ref = Universe.types.len_;
pkg := comp.pkgs[0]; pkg := comp.pkg_list[0];
E.WritePackage(0); E.WritePackage(0);
E.WriteScope(pkg.scope, false); E.WriteScope(pkg.scope, false);
......
...@@ -13,20 +13,17 @@ package Globals ...@@ -13,20 +13,17 @@ package Globals
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
export Object export type Object struct {
type Object struct {
exported bool; exported bool;
pos int; // source position (< 0 if unknown position) pos int; // source position (< 0 if unknown position)
kind int; kind int;
ident string; ident string;
typ *Type; typ *Type; // nil for packages
pnolev int; // >= 0: package no., <= 0: level, 0: global level of compilation pnolev int; // >= 0: package no., <= 0: function nesting level, 0: global level
scope *Scope; // which contains the object
} }
export Type export type Type struct {
type Type struct {
ref int; // for exporting only: >= 0 means already exported ref int; // for exporting only: >= 0 means already exported
form int; form int;
flags int; // channels, functions flags int; // channels, functions
...@@ -39,13 +36,12 @@ type Type struct { ...@@ -39,13 +36,12 @@ type Type struct {
} }
export Package export type Package struct {
type Package struct {
ref int; // for exporting only: >= 0 means already exported ref int; // for exporting only: >= 0 means already exported
file_name string; file_name string;
key string; key string;
obj *Object; obj *Object;
scope *Scope; scope *Scope; // holds the (global) objects in this package
} }
...@@ -61,23 +57,20 @@ type Elem struct { ...@@ -61,23 +57,20 @@ type Elem struct {
} }
export List export type List struct {
type List struct {
len_ int; len_ int;
first, last *Elem; first, last *Elem;
}; };
export Scope export type Scope struct {
type Scope struct {
parent *Scope; parent *Scope;
entries *List; entries *List;
// entries *map[string] *Object; // doesn't work properly // entries *map[string] *Object; // doesn't work properly
} }
export Flags; export type Flags struct {
type Flags struct {
debug bool; debug bool;
print_export bool; print_export bool;
semantic_checks bool; semantic_checks bool;
...@@ -86,24 +79,21 @@ type Flags struct { ...@@ -86,24 +79,21 @@ type Flags struct {
} }
export Compilation export type Compilation struct {
type Compilation struct {
flags *Flags; flags *Flags;
// TODO use open arrays eventually // TODO use open arrays eventually
pkgs [256] *Package; // pkgs[0] is the current package pkg_list [256] *Package; // pkg_list[0] is the current package
npkgs int; pkg_ref int;
} }
export Expr export type Expr interface {
type Expr interface {
typ() *Type; typ() *Type;
// ... more to come here // ... more to come here
} }
export Stat export type Stat interface {
type Stat interface {
// ... more to come here // ... more to come here
} }
...@@ -111,8 +101,7 @@ type Stat interface { ...@@ -111,8 +101,7 @@ type Stat interface {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Creation // Creation
export Universe_undef_t export var Universe_undef_t *Type // initialized by Universe to Universe.undef_t
var Universe_undef_t *Type // initialized by Universe to Universe.undef_t
export NewObject export NewObject
func NewObject(pos, kind int, ident string) *Object { func NewObject(pos, kind int, ident string) *Object {
...@@ -123,7 +112,6 @@ func NewObject(pos, kind int, ident string) *Object { ...@@ -123,7 +112,6 @@ func NewObject(pos, kind int, ident string) *Object {
obj.ident = ident; obj.ident = ident;
obj.typ = Universe_undef_t; obj.typ = Universe_undef_t;
obj.pnolev = 0; obj.pnolev = 0;
obj.scope = nil;
return obj; return obj;
} }
...@@ -138,11 +126,12 @@ func NewType(form int) *Type { ...@@ -138,11 +126,12 @@ func NewType(form int) *Type {
export NewPackage; export NewPackage;
func NewPackage(file_name string) *Package { func NewPackage(file_name string, obj *Object) *Package {
pkg := new(Package); pkg := new(Package);
pkg.ref = -1; // not yet exported pkg.ref = -1; // not yet exported
pkg.file_name = file_name; pkg.file_name = file_name;
pkg.key = "<the package key>"; // TODO fix this pkg.key = "<the package key>"; // TODO fix this
pkg.obj = obj;
return pkg; return pkg;
} }
...@@ -181,7 +170,6 @@ func (obj *Object) Copy() *Object { ...@@ -181,7 +170,6 @@ func (obj *Object) Copy() *Object {
copy.ident = obj.ident; copy.ident = obj.ident;
copy.typ = obj.typ; copy.typ = obj.typ;
copy.pnolev = obj.pnolev; copy.pnolev = obj.pnolev;
copy.scope = nil; // cannot be in the same scope (same ident!)
return copy; return copy;
} }
...@@ -272,9 +260,6 @@ func (L *List) AddTyp(typ *Type) { ...@@ -272,9 +260,6 @@ func (L *List) AddTyp(typ *Type) {
func (scope *Scope) Lookup(ident string) *Object { func (scope *Scope) Lookup(ident string) *Object {
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.ident == ident {
if p.obj.scope != scope {
panic "incorrect scope for object";
}
return p.obj; return p.obj;
} }
} }
...@@ -286,11 +271,7 @@ func (scope *Scope) Insert(obj *Object) { ...@@ -286,11 +271,7 @@ func (scope *Scope) Insert(obj *Object) {
if scope.Lookup(obj.ident) != nil { if scope.Lookup(obj.ident) != nil {
panic "obj already inserted"; panic "obj already inserted";
} }
if obj.scope != nil {
panic "obj already in a scope";
}
scope.entries.AddObj(obj); scope.entries.AddObj(obj);
obj.scope = scope;
} }
...@@ -317,8 +298,8 @@ func (scope *Scope) Print() { ...@@ -317,8 +298,8 @@ func (scope *Scope) Print() {
// Compilation methods // Compilation methods
func (C *Compilation) Lookup(file_name string) *Package { func (C *Compilation) Lookup(file_name string) *Package {
for i := 0; i < C.npkgs; i++ { for i := 0; i < C.pkg_ref; i++ {
pkg := C.pkgs[i]; pkg := C.pkg_list[i];
if pkg.file_name == file_name { if pkg.file_name == file_name {
return pkg; return pkg;
} }
...@@ -331,9 +312,9 @@ func (C *Compilation) Insert(pkg *Package) { ...@@ -331,9 +312,9 @@ func (C *Compilation) Insert(pkg *Package) {
if C.Lookup(pkg.file_name) != nil { if C.Lookup(pkg.file_name) != nil {
panic "package already inserted"; panic "package already inserted";
} }
pkg.obj.pnolev = C.npkgs; pkg.obj.pnolev = C.pkg_ref;
C.pkgs[C.npkgs] = pkg; C.pkg_list[C.pkg_ref] = pkg;
C.npkgs++; C.pkg_ref++;
} }
......
...@@ -16,9 +16,9 @@ type Importer struct { ...@@ -16,9 +16,9 @@ type Importer struct {
debug bool; debug bool;
buf string; buf string;
buf_pos int; buf_pos int;
pkgs [256] *Globals.Package; pkg_list [256] *Globals.Package;
pkg_ref int; pkg_ref int;
types [1024] *Globals.Type; type_list [1024] *Globals.Type;
type_ref int; type_ref int;
}; };
...@@ -120,8 +120,6 @@ func (I *Importer) ReadScope() *Globals.Scope { ...@@ -120,8 +120,6 @@ func (I *Importer) ReadScope() *Globals.Scope {
scope := Globals.NewScope(nil); scope := Globals.NewScope(nil);
obj := I.ReadObject(); obj := I.ReadObject();
for obj != nil { for obj != nil {
// InsertImport only needed for package scopes
// but ok to use always
scope.InsertImport(obj); scope.InsertImport(obj);
obj = I.ReadObject(); obj = I.ReadObject();
} }
...@@ -153,7 +151,6 @@ func (I *Importer) ReadObject() *Globals.Object { ...@@ -153,7 +151,6 @@ func (I *Importer) ReadObject() *Globals.Object {
ident := I.ReadString(); ident := I.ReadString();
obj := Globals.NewObject(0, tag, ident); obj := Globals.NewObject(0, tag, ident);
obj.typ = I.ReadType(); obj.typ = I.ReadType();
obj.pnolev = I.ReadPackage().obj.pnolev;
switch (tag) { switch (tag) {
case Object.CONST: case Object.CONST:
...@@ -176,26 +173,31 @@ func (I *Importer) ReadObject() *Globals.Object { ...@@ -176,26 +173,31 @@ func (I *Importer) ReadObject() *Globals.Object {
func (I *Importer) ReadType() *Globals.Type { func (I *Importer) ReadType() *Globals.Type {
tag := I.ReadTypeTag(); tag := I.ReadTypeTag();
if tag >= 0 { if tag >= 0 {
return I.types[tag]; // type already imported return I.type_list[tag]; // type already imported
} }
typ := Globals.NewType(-tag); typ := Globals.NewType(-tag);
ptyp := typ; // primary type ptyp := typ; // primary type
ident := I.ReadString(); ident := I.ReadString();
if len(ident) > 0 { if len(ident) > 0 {
// primary type // primary type
pkg := I.ReadPackage();
// create corresponding type object
obj := Globals.NewObject(0, Object.TYPE, ident); obj := Globals.NewObject(0, Object.TYPE, ident);
obj.exported = true;
obj.typ = typ; obj.typ = typ;
obj.pnolev = pkg.obj.pnolev;
typ.obj = obj; typ.obj = obj;
// canonicalize type // canonicalize type
pkg := I.ReadPackage(); // (if the type was seen before, use primary instance!)
obj.pnolev = pkg.obj.pnolev; ptyp = pkg.scope.InsertImport(obj).typ;
obj = pkg.scope.InsertImport(obj);
ptyp = 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++; I.type_ref++;
switch (typ.form) { switch (typ.form) {
...@@ -235,7 +237,7 @@ func (I *Importer) ReadType() *Globals.Type { ...@@ -235,7 +237,7 @@ func (I *Importer) ReadType() *Globals.Type {
func (I *Importer) ReadPackage() *Globals.Package { func (I *Importer) ReadPackage() *Globals.Package {
tag := I.ReadPackageTag(); tag := I.ReadPackageTag();
if tag >= 0 { if tag >= 0 {
return I.pkgs[tag]; // package already imported return I.pkg_list[tag]; // package already imported
} }
ident := I.ReadString(); ident := I.ReadString();
...@@ -245,8 +247,8 @@ func (I *Importer) ReadPackage() *Globals.Package { ...@@ -245,8 +247,8 @@ func (I *Importer) ReadPackage() *Globals.Package {
if pkg == nil { if pkg == nil {
// new package // new package
pkg = Globals.NewPackage(file_name); obj := Globals.NewObject(-1, Object.PACKAGE, ident);
pkg.obj = Globals.NewObject(-1, Object.PACKAGE, ident); pkg = Globals.NewPackage(file_name, obj);
pkg.scope = Globals.NewScope(nil); pkg.scope = Globals.NewScope(nil);
pkg = I.comp.InsertImport(pkg); pkg = I.comp.InsertImport(pkg);
...@@ -254,7 +256,7 @@ func (I *Importer) ReadPackage() *Globals.Package { ...@@ -254,7 +256,7 @@ func (I *Importer) ReadPackage() *Globals.Package {
// package inconsistency // package inconsistency
panic "package key inconsistency"; panic "package key inconsistency";
} }
I.pkgs[I.pkg_ref] = pkg; I.pkg_list[I.pkg_ref] = pkg;
I.pkg_ref++; I.pkg_ref++;
return pkg; return pkg;
...@@ -284,7 +286,7 @@ func (I *Importer) Import(comp* Globals.Compilation, file_name string) *Globals. ...@@ -284,7 +286,7 @@ func (I *Importer) Import(comp* Globals.Compilation, file_name string) *Globals.
if p.typ.ref != I.type_ref { if p.typ.ref != I.type_ref {
panic "incorrect ref for predeclared type"; panic "incorrect ref for predeclared type";
} }
I.types[I.type_ref] = p.typ; I.type_list[I.type_ref] = p.typ;
I.type_ref++; I.type_ref++;
} }
......
...@@ -7,8 +7,7 @@ package Object ...@@ -7,8 +7,7 @@ package Object
import Globals "globals" import Globals "globals"
export BAD, CONST, TYPE, VAR, FUNC, PACKAGE, LABEL, END export const /* kind */ (
const /* kind */ (
BAD = iota; // error handling BAD = iota; // error handling
CONST; TYPE; VAR; FUNC; PACKAGE; LABEL; CONST; TYPE; VAR; FUNC; PACKAGE; LABEL;
END; // end of scope (import/export only) END; // end of scope (import/export only)
......
...@@ -306,7 +306,7 @@ func (P *Parser) ParseQualifiedIdent(pos int, ident string) *Globals.Object { ...@@ -306,7 +306,7 @@ func (P *Parser) ParseQualifiedIdent(pos int, ident string) *Globals.Object {
if obj.pnolev < 0 { if obj.pnolev < 0 {
panic "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 { //if pkg.obj.ident != ident {
// panic "pkg.obj.ident != ident"; // panic "pkg.obj.ident != ident";
//} //}
...@@ -1916,10 +1916,10 @@ func (P *Parser) ParseProgram() { ...@@ -1916,10 +1916,10 @@ func (P *Parser) ParseProgram() {
P.OpenScope(); P.OpenScope();
P.Expect(Scanner.PACKAGE); P.Expect(Scanner.PACKAGE);
pkg := Globals.NewPackage(P.S.filename); obj := P.ParseIdentDecl(Object.PACKAGE);
pkg.obj = P.ParseIdentDecl(Object.PACKAGE); pkg := Globals.NewPackage(P.S.filename, obj);
P.comp.Insert(pkg); P.comp.Insert(pkg);
if P.comp.npkgs != 1 { if P.comp.pkg_ref != 1 {
panic "should have exactly one package now"; panic "should have exactly one package now";
} }
P.Optional(Scanner.SEMICOLON); P.Optional(Scanner.SEMICOLON);
......
...@@ -164,7 +164,7 @@ func (P *Printer) PrintObjectStruct(obj *Globals.Object) { ...@@ -164,7 +164,7 @@ func (P *Printer) PrintObjectStruct(obj *Globals.Object) {
print "package "; print "package ";
P.PrintObject(obj); P.PrintObject(obj);
print " "; print " ";
P.PrintScope(P.comp.pkgs[obj.pnolev].scope, 0); P.PrintScope(P.comp.pkg_list[obj.pnolev].scope, 0);
default: default:
panic "UNREACHABLE"; panic "UNREACHABLE";
...@@ -178,7 +178,7 @@ func (P *Printer) PrintObjectStruct(obj *Globals.Object) { ...@@ -178,7 +178,7 @@ func (P *Printer) PrintObjectStruct(obj *Globals.Object) {
func (P *Printer) PrintObject(obj *Globals.Object) { func (P *Printer) PrintObject(obj *Globals.Object) {
if obj.pnolev > 0 { if obj.pnolev > 0 {
print P.comp.pkgs[obj.pnolev].obj.ident, "."; print P.comp.pkg_list[obj.pnolev].obj.ident, ".";
} }
print obj.ident; print obj.ident;
} }
......
...@@ -6,27 +6,7 @@ package Scanner ...@@ -6,27 +6,7 @@ package Scanner
import Utils "utils" import Utils "utils"
export const (
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 (
ILLEGAL = iota; ILLEGAL = iota;
EOF; EOF;
IDENT; IDENT;
...@@ -270,8 +250,7 @@ func digit_val(ch int) int { ...@@ -270,8 +250,7 @@ func digit_val(ch int) int {
} }
export Scanner export type Scanner struct {
type Scanner struct {
filename string; // error reporting only filename string; // error reporting only
nerrors int; // number of errors nerrors int; // number of errors
errpos int; // last error position errpos int; // last error position
......
...@@ -4,13 +4,7 @@ ...@@ -4,13 +4,7 @@
package Type package Type
export export const /* form */ (
UNDEF, BAD, NIL,
BOOL, UINT, INT, FLOAT, STRING,
ANY,
ALIAS, ARRAY, STRUCT, INTERFACE, MAP, CHANNEL, FUNCTION, POINTER, REFERENCE
const /* form */ (
// internal types // internal types
UNDEF = iota; BAD; NIL; UNDEF = iota; BAD; NIL;
// basic types // basic types
...@@ -22,10 +16,7 @@ const /* form */ ( ...@@ -22,10 +16,7 @@ const /* form */ (
) )
export export const /* flag */ (
SEND, RECV
const /* flag */ (
SEND = 1 << iota; // chan> SEND = 1 << iota; // chan>
RECV; // chan< or method RECV; // chan< or method
) )
......
...@@ -106,7 +106,7 @@ func VerifyPackage(pkg *Globals.Package, pno int) { ...@@ -106,7 +106,7 @@ func VerifyPackage(pkg *Globals.Package, pno int) {
export Verify export Verify
func Verify(comp *Globals.Compilation) { func Verify(comp *Globals.Compilation) {
for i := 0; i < comp.npkgs; i++ { for i := 0; i < comp.pkg_ref; i++ {
VerifyPackage(comp.pkgs[i], 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