mirror of
https://github.com/golang/go
synced 2024-11-23 00:40:08 -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 {
|
func BaseName(s string) string {
|
||||||
// TODO this is not correct for non-ASCII strings!
|
// TODO this is not correct for non-ASCII strings!
|
||||||
i := len(s);
|
i := len(s) - 1;
|
||||||
for i >= 0 && s[i] != '/' {
|
for i >= 0 && s[i] != '/' {
|
||||||
if s[i] > 128 {
|
if s[i] > 128 {
|
||||||
panic "non-ASCII string"
|
panic "non-ASCII string"
|
||||||
@ -31,43 +31,40 @@ func FixExt(s string) string {
|
|||||||
if s[i : len(s)] == ".go" {
|
if s[i : len(s)] == ".go" {
|
||||||
s = s[0 : i];
|
s = s[0 : i];
|
||||||
}
|
}
|
||||||
return s + ".7"
|
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 */);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export Compile
|
export Compile
|
||||||
func Compile(src_name string, verbose int) {
|
func Compile(file_name string, verbose int) {
|
||||||
comp := new(Globals.Compilation);
|
src, ok := sys.readfile(file_name);
|
||||||
comp.src_name = src_name;
|
|
||||||
comp.pkg = nil;
|
|
||||||
comp.nimports = 0;
|
|
||||||
|
|
||||||
src, ok := sys.readfile(src_name);
|
|
||||||
if !ok {
|
if !ok {
|
||||||
print "cannot open ", src_name, "\n"
|
print "cannot open ", file_name, "\n"
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Universe.Init();
|
Universe.Init(); // TODO eventually this should be only needed once
|
||||||
|
|
||||||
S := new(Scanner.Scanner);
|
comp := Globals.NewCompilation();
|
||||||
S.Open(src_name, src);
|
pkg := Globals.NewPackage(file_name);
|
||||||
|
comp.Insert(pkg);
|
||||||
|
if comp.npkgs != 1 {
|
||||||
|
panic "should have exactly one package now";
|
||||||
|
}
|
||||||
|
|
||||||
P := new(Parser.Parser);
|
scanner := new(Scanner.Scanner);
|
||||||
P.Open(S, verbose);
|
scanner.Open(file_name, src);
|
||||||
|
|
||||||
print "parsing ", src_name, "\n";
|
parser := new(Parser.Parser);
|
||||||
P.ParseProgram();
|
parser.Open(comp, scanner, verbose);
|
||||||
//comp.Export();
|
|
||||||
|
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;
|
pkg.ref = E.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.file_name);
|
||||||
E.WriteString(pkg.key);
|
E.WriteString(pkg.key);
|
||||||
}
|
}
|
||||||
@ -294,7 +294,7 @@ func (E *Exporter) Export(/*Compilation* comp, BBuffer* buf*/) {
|
|||||||
|
|
||||||
|
|
||||||
export Export
|
export Export
|
||||||
func Export(file_name string /*comp *Compilation.Compilation*/) {
|
func Export(comp *Globals.Compilation, file_name string) {
|
||||||
/*
|
/*
|
||||||
Exporter exp;
|
Exporter exp;
|
||||||
exp.Export(comp, buf);
|
exp.Export(comp, buf);
|
||||||
|
@ -34,7 +34,17 @@ type Type struct {
|
|||||||
obj *Object; // primary type object or NULL
|
obj *Object; // primary type object or NULL
|
||||||
key *Object; // maps
|
key *Object; // maps
|
||||||
elt *Object; // arrays, maps, channels, pointers, references
|
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;
|
str string;
|
||||||
obj *Object;
|
obj *Object;
|
||||||
typ *Type;
|
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
|
export Compilation
|
||||||
type Compilation struct {
|
type Compilation struct {
|
||||||
src_name string;
|
// TODO use open arrays eventually
|
||||||
pkg *Object;
|
pkgs [256] *Package; // pkgs[0] is the current package
|
||||||
imports [256] *Package; // TODO need open arrays
|
npkgs int;
|
||||||
nimports int;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -103,11 +102,21 @@ func NewObject(pos, kind int, ident string) *Object {
|
|||||||
export NewType
|
export NewType
|
||||||
func NewType(form int) *Type {
|
func NewType(form int) *Type {
|
||||||
typ := new(Type);
|
typ := new(Type);
|
||||||
|
typ.ref = -1;
|
||||||
typ.form = form;
|
typ.form = form;
|
||||||
return typ;
|
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
|
export NewList
|
||||||
func NewList() *List {
|
func NewList() *List {
|
||||||
return new(List);
|
return new(List);
|
||||||
@ -123,10 +132,10 @@ func NewScope(parent *Scope) *Scope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export NewPackage;
|
export NewCompilation;
|
||||||
func NewPackage() *Package {
|
func NewCompilation() *Compilation {
|
||||||
pkg := new(Package);
|
comp := new(Compilation);
|
||||||
return pkg;
|
return comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -241,8 +250,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.nimports; i++ {
|
for i := 0; i < C.npkgs; i++ {
|
||||||
pkg := C.imports[i];
|
pkg := C.pkgs[i];
|
||||||
if pkg.file_name == file_name {
|
if pkg.file_name == file_name {
|
||||||
return pkg;
|
return pkg;
|
||||||
}
|
}
|
||||||
@ -255,9 +264,8 @@ 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.pno = C.nimports;
|
C.pkgs[C.npkgs] = pkg;
|
||||||
C.imports[C.nimports] = pkg;
|
C.npkgs++;
|
||||||
C.nimports++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,12 +17,14 @@ const EnableSemanticTests = false;
|
|||||||
|
|
||||||
export Parser
|
export Parser
|
||||||
type Parser struct {
|
type Parser struct {
|
||||||
|
comp *Globals.Compilation;
|
||||||
verbose, indent int;
|
verbose, indent int;
|
||||||
S *Scanner.Scanner;
|
S *Scanner.Scanner;
|
||||||
tok int; // one token look-ahead
|
tok int; // one token look-ahead
|
||||||
beg, end int; // token position
|
beg, end int; // token position
|
||||||
ident string; // last ident seen
|
ident string; // last ident seen
|
||||||
top_scope *Globals.Scope;
|
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.verbose = verbose;
|
||||||
P.indent = 0;
|
P.indent = 0;
|
||||||
P.S = S;
|
P.S = S;
|
||||||
P.Next();
|
P.Next();
|
||||||
P.top_scope = Universe.scope;
|
P.top_scope = Universe.scope;
|
||||||
|
P.exports = Globals.NewList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1238,15 +1242,15 @@ func (P *Parser) ParseExportDecl() {
|
|||||||
if P.tok == Scanner.LPAREN {
|
if P.tok == Scanner.LPAREN {
|
||||||
P.Next();
|
P.Next();
|
||||||
for P.tok != Scanner.RPAREN {
|
for P.tok != Scanner.RPAREN {
|
||||||
P.ParseIdent();
|
P.exports.AddStr(P.ParseIdent());
|
||||||
P.Optional(Scanner.COMMA); // TODO this seems wrong
|
P.Optional(Scanner.COMMA); // TODO this seems wrong
|
||||||
}
|
}
|
||||||
P.Next();
|
P.Next();
|
||||||
} else {
|
} else {
|
||||||
P.ParseIdent();
|
P.exports.AddStr(P.ParseIdent());
|
||||||
for P.tok == Scanner.COMMA {
|
for P.tok == Scanner.COMMA {
|
||||||
P.Next();
|
P.Next();
|
||||||
P.ParseIdent();
|
P.exports.AddStr(P.ParseIdent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1284,14 +1288,46 @@ func (P *Parser) ParseDeclaration() {
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Program
|
// 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() {
|
func (P *Parser) ParseProgram() {
|
||||||
P.Trace("Program");
|
P.Trace("Program");
|
||||||
|
|
||||||
P.OpenScope();
|
P.OpenScope();
|
||||||
P.Expect(Scanner.PACKAGE);
|
P.Expect(Scanner.PACKAGE);
|
||||||
P.ParseIdent();
|
pkg := P.comp.pkgs[0];
|
||||||
|
pkg.obj = P.ParseIdentDecl(Object.PACKAGE);
|
||||||
P.Optional(Scanner.SEMICOLON);
|
P.Optional(Scanner.SEMICOLON);
|
||||||
|
|
||||||
{ P.OpenScope();
|
{ P.OpenScope();
|
||||||
|
pkg.scope = P.top_scope;
|
||||||
for P.tok == Scanner.IMPORT {
|
for P.tok == Scanner.IMPORT {
|
||||||
P.ParseImportDecl();
|
P.ParseImportDecl();
|
||||||
P.Optional(Scanner.SEMICOLON);
|
P.Optional(Scanner.SEMICOLON);
|
||||||
@ -1301,6 +1337,8 @@ func (P *Parser) ParseProgram() {
|
|||||||
P.ParseDeclaration();
|
P.ParseDeclaration();
|
||||||
P.Optional(Scanner.SEMICOLON);
|
P.Optional(Scanner.SEMICOLON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
P.MarkExports();
|
||||||
P.CloseScope();
|
P.CloseScope();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,7 +415,8 @@ func (S *Scanner) LineCol(pos int) (line, col int) {
|
|||||||
|
|
||||||
func (S *Scanner) Error(pos int, msg string) {
|
func (S *Scanner) Error(pos int, msg string) {
|
||||||
const errdist = 10;
|
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);
|
line, col := S.LineCol(pos);
|
||||||
if VerboseMsgs {
|
if VerboseMsgs {
|
||||||
print S.filename, ":", line, ":", col, ": ", msg, "\n";
|
print S.filename, ":", line, ":", col, ": ", msg, "\n";
|
||||||
|
@ -14,7 +14,7 @@ func Parse(filename, src string, verbose int) {
|
|||||||
S.Open(filename, src);
|
S.Open(filename, src);
|
||||||
|
|
||||||
P := new(Parser.Parser);
|
P := new(Parser.Parser);
|
||||||
P.Open(S, verbose);
|
P.Open(nil, S, verbose);
|
||||||
|
|
||||||
P.ParseProgram();
|
P.ParseProgram();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user