1
0
mirror of https://github.com/golang/go synced 2024-11-22 17:35:19 -07:00

- more front-end stuff: hooking up packages, preparing for exports

SVN=127931
This commit is contained in:
Robert Griesemer 2008-07-17 18:02:10 -07:00
parent 41861ca7bb
commit c3e9c7d106
6 changed files with 109 additions and 65 deletions

View File

@ -15,7 +15,7 @@ import Export "export"
func BaseName(s string) string {
// TODO this is not correct for non-ASCII strings!
i := len(s);
i := len(s) - 1;
for i >= 0 && s[i] != '/' {
if s[i] > 128 {
panic "non-ASCII string"
@ -31,43 +31,40 @@ func FixExt(s string) string {
if s[i : len(s)] == ".go" {
s = s[0 : i];
}
return s + ".7"
}
func Import(C *Globals.Compilation, pkg_name string) (pno int) {
panic "UNIMPLEMENTED";
}
func Export(C *Globals.Compilation) {
file_name := FixExt(BaseName(C.src_name)); // strip src dir
Export.Export(file_name/*, C */);
return s + ".7";
}
export Compile
func Compile(src_name string, verbose int) {
comp := new(Globals.Compilation);
comp.src_name = src_name;
comp.pkg = nil;
comp.nimports = 0;
src, ok := sys.readfile(src_name);
func Compile(file_name string, verbose int) {
src, ok := sys.readfile(file_name);
if !ok {
print "cannot open ", src_name, "\n"
print "cannot open ", file_name, "\n"
return;
}
Universe.Init();
S := new(Scanner.Scanner);
S.Open(src_name, src);
P := new(Parser.Parser);
P.Open(S, verbose);
Universe.Init(); // TODO eventually this should be only needed once
print "parsing ", src_name, "\n";
P.ParseProgram();
//comp.Export();
comp := Globals.NewCompilation();
pkg := Globals.NewPackage(file_name);
comp.Insert(pkg);
if comp.npkgs != 1 {
panic "should have exactly one package now";
}
scanner := new(Scanner.Scanner);
scanner.Open(file_name, src);
parser := new(Parser.Parser);
parser.Open(comp, scanner, verbose);
print "parsing ", file_name, "\n";
parser.ParseProgram();
if parser.S.nerrors > 0 {
return;
}
// export
export_file_name := FixExt(BaseName(file_name)); // strip file dir
Export.Export(comp, export_file_name);
}

View File

@ -252,7 +252,7 @@ func (E *Exporter) WritePackage(pkg *Globals.Package) {
pkg.ref = E.pkg_ref;
E.pkg_ref++;
E.WriteString(pkg.ident);
E.WriteString(pkg.obj.ident);
E.WriteString(pkg.file_name);
E.WriteString(pkg.key);
}
@ -294,7 +294,7 @@ func (E *Exporter) Export(/*Compilation* comp, BBuffer* buf*/) {
export Export
func Export(file_name string /*comp *Compilation.Compilation*/) {
func Export(comp *Globals.Compilation, file_name string) {
/*
Exporter exp;
exp.Export(comp, buf);

View File

@ -34,7 +34,17 @@ type Type struct {
obj *Object; // primary type object or NULL
key *Object; // maps
elt *Object; // arrays, maps, channels, pointers, references
scope *Scope; // incomplete types, structs, interfaces, functions, packages
scope *Scope; // structs, interfaces, functions
}
export Package
type Package struct {
ref int; // for exporting only: >= 0 means already exported
file_name string;
key string;
obj *Object;
scope *Scope;
}
@ -46,6 +56,7 @@ type Elem struct {
str string;
obj *Object;
typ *Type;
pkg *Package;
}
@ -64,23 +75,11 @@ type Scope struct {
}
export Package
type Package struct {
ref int; // for exporting only: >= 0 means already exported
file_name string;
ident string;
key string;
scope *Scope;
pno int;
}
export Compilation
type Compilation struct {
src_name string;
pkg *Object;
imports [256] *Package; // TODO need open arrays
nimports int;
// TODO use open arrays eventually
pkgs [256] *Package; // pkgs[0] is the current package
npkgs int;
}
@ -103,11 +102,21 @@ func NewObject(pos, kind int, ident string) *Object {
export NewType
func NewType(form int) *Type {
typ := new(Type);
typ.ref = -1;
typ.form = form;
return typ;
}
export NewPackage;
func NewPackage(file_name string) *Package {
pkg := new(Package);
pkg.ref = -1;
pkg.file_name = file_name;
return pkg;
}
export NewList
func NewList() *List {
return new(List);
@ -123,10 +132,10 @@ func NewScope(parent *Scope) *Scope {
}
export NewPackage;
func NewPackage() *Package {
pkg := new(Package);
return pkg;
export NewCompilation;
func NewCompilation() *Compilation {
comp := new(Compilation);
return comp;
}
@ -241,8 +250,8 @@ func (scope *Scope) Print() {
// Compilation methods
func (C *Compilation) Lookup(file_name string) *Package {
for i := 0; i < C.nimports; i++ {
pkg := C.imports[i];
for i := 0; i < C.npkgs; i++ {
pkg := C.pkgs[i];
if pkg.file_name == file_name {
return pkg;
}
@ -255,9 +264,8 @@ func (C *Compilation) Insert(pkg *Package) {
if C.Lookup(pkg.file_name) != nil {
panic "package already inserted";
}
pkg.pno = C.nimports;
C.imports[C.nimports] = pkg;
C.nimports++;
C.pkgs[C.npkgs] = pkg;
C.npkgs++;
}

View File

@ -17,12 +17,14 @@ const EnableSemanticTests = false;
export Parser
type Parser struct {
comp *Globals.Compilation;
verbose, indent int;
S *Scanner.Scanner;
tok int; // one token look-ahead
beg, end int; // token position
ident string; // last ident seen
top_scope *Globals.Scope;
exports *Globals.List;
}
@ -66,12 +68,14 @@ func (P *Parser) Next() {
}
func (P *Parser) Open(S *Scanner.Scanner, verbose int) {
func (P *Parser) Open(comp *Globals.Compilation, S *Scanner.Scanner, verbose int) {
P.comp = comp;
P.verbose = verbose;
P.indent = 0;
P.S = S;
P.Next();
P.top_scope = Universe.scope;
P.exports = Globals.NewList();
}
@ -1238,15 +1242,15 @@ func (P *Parser) ParseExportDecl() {
if P.tok == Scanner.LPAREN {
P.Next();
for P.tok != Scanner.RPAREN {
P.ParseIdent();
P.exports.AddStr(P.ParseIdent());
P.Optional(Scanner.COMMA); // TODO this seems wrong
}
P.Next();
} else {
P.ParseIdent();
P.exports.AddStr(P.ParseIdent());
for P.tok == Scanner.COMMA {
P.Next();
P.ParseIdent();
P.exports.AddStr(P.ParseIdent());
}
}
@ -1284,14 +1288,46 @@ func (P *Parser) ParseDeclaration() {
// ----------------------------------------------------------------------------
// Program
func (P *Parser) MarkExports() {
if !EnableSemanticTests {
return;
}
scope := P.top_scope;
for p := P.exports.first; p != nil; p = p.next {
obj := scope.Lookup(p.str);
if obj != nil {
obj.mark = true;
// For now we export deep
// TODO this should change eventually - we need selective export
if obj.kind == Object.TYPE {
typ := obj.typ;
if typ.form == Type.STRUCT || typ.form == Type.INTERFACE {
scope := typ.scope;
for p := scope.entries.first; p != nil; p = p.next {
p.obj.mark = true;
}
}
}
} else {
// TODO need to report proper src position
P.Error(0, `"` + p.str + `" is not declared - cannot be exported`);
}
}
}
func (P *Parser) ParseProgram() {
P.Trace("Program");
P.OpenScope();
P.Expect(Scanner.PACKAGE);
P.ParseIdent();
pkg := P.comp.pkgs[0];
pkg.obj = P.ParseIdentDecl(Object.PACKAGE);
P.Optional(Scanner.SEMICOLON);
{ P.OpenScope();
pkg.scope = P.top_scope;
for P.tok == Scanner.IMPORT {
P.ParseImportDecl();
P.Optional(Scanner.SEMICOLON);
@ -1301,6 +1337,8 @@ func (P *Parser) ParseProgram() {
P.ParseDeclaration();
P.Optional(Scanner.SEMICOLON);
}
P.MarkExports();
P.CloseScope();
}

View File

@ -415,7 +415,8 @@ func (S *Scanner) LineCol(pos int) (line, col int) {
func (S *Scanner) Error(pos int, msg string) {
const errdist = 10;
if pos > S.errpos + errdist || S.nerrors == 0 {
delta := pos - S.errpos; // may be negative!
if delta < errdist || delta > errdist || S.nerrors == 0 {
line, col := S.LineCol(pos);
if VerboseMsgs {
print S.filename, ":", line, ":", col, ": ", msg, "\n";

View File

@ -14,7 +14,7 @@ func Parse(filename, src string, verbose int) {
S.Open(filename, src);
P := new(Parser.Parser);
P.Open(S, verbose);
P.Open(nil, S, verbose);
P.ParseProgram();
}