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:
parent
41861ca7bb
commit
c3e9c7d106
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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++;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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";
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user