- added simple facility to print Makefile dependency rules given a Go source file

(e.g.: pretty -d pretty.go will print the Makefile dep. rules of the involved
  Go files that are not part of the installed library)
- minor fix in pretty printer (tested against ken's test files)

R=r
OCL=17872
CL=17872
This commit is contained in:
Robert Griesemer 2008-10-26 21:32:30 -07:00
parent e8278bcb29
commit eba73552d2
7 changed files with 142 additions and 55 deletions

View File

@ -17,17 +17,19 @@ install: pretty
clean: clean:
rm -f pretty *.6 *~ rm -f pretty *.6 *~
pretty.6: printer.6 platform.6 compilation.6 pretty.6: platform.6 printer.6 compilation.6
compilation.6: scanner.6 parser.6 ast.6 compilation.6: platform.6 scanner.6 parser.6 ast.6
printer.6: ast.6 scanner.6
parser.6: scanner.6 utils.6 printer.6 ast.6
ast.6: scanner.6 ast.6: scanner.6
scanner.6: utils.6 platform.6 scanner.6: utils.6
parser.6: scanner.6 ast.6
platform.6: utils.6
printer.6: scanner.6 ast.6
%.6: %.go %.6: %.go
$(G) $(F) $< $(G) $(F) $<

View File

@ -33,17 +33,19 @@ clean:
rm -f pretty *.o *~ rm -f pretty *.o *~
pretty.o: printer.o platform.o compilation.o pretty.o: platform.o printer.o compilation.o
compilation.o: scanner.o parser.o ast.o compilation.o: platform.o scanner.o parser.o ast.o
printer.o: ast.o scanner.o
parser.o: scanner.o utils.o printer.o ast.o
ast.o: scanner.o ast.o: scanner.o
scanner.o: utils.o platform.o scanner.o: utils.o
parser.o: scanner.o ast.o
platform.o: utils.o
printer.o: scanner.o ast.o
flag.o: fmt.o flag.o: fmt.o

View File

@ -43,7 +43,7 @@ func (p *List) set(i int, x Any) {
} }
func (p *List) Add (x Any) { func (p *List) Add(x Any) {
a := p.a; a := p.a;
n := len(a); n := len(a);
@ -61,6 +61,23 @@ func (p *List) Add (x Any) {
} }
func (p *List) Pop() Any {
a := p.a;
n := len(a);
var x Any;
if n > 0 {
x = a[n - 1];
a = a[0 : n - 1];
p.a = a;
} else {
panic("pop from empty list");
}
return x;
}
export func NewList() *List { export func NewList() *List {
p := new(List); p := new(List);
p.a = new([] Any, 10) [0 : 0]; p.a = new([] Any, 10) [0 : 0];

View File

@ -4,11 +4,19 @@
package Compilation package Compilation
import OS "os"
import Platform "platform"
import Scanner "scanner" import Scanner "scanner"
import Parser "parser" import Parser "parser"
import AST "ast" import AST "ast"
func assert(b bool) {
if !b {
panic("assertion failed");
}
}
export type Flags struct { export type Flags struct {
verbose bool; verbose bool;
@ -20,13 +28,13 @@ export type Flags struct {
} }
type Compilation struct { export func Compile(src_file string, flags *Flags) (*AST.Program, int) {
prog *AST.Program; src, ok := Platform.ReadSourceFile(src_file);
nerrors int; if !ok {
} print("cannot open ", src_file, "\n");
return nil, 1;
}
export func Compile(src_file, src string, flags *Flags) *Compilation {
var scanner Scanner.Scanner; var scanner Scanner.Scanner;
scanner.Open(src_file, src, flags.columns, flags.testmode); scanner.Open(src_file, src, flags.columns, flags.testmode);
@ -36,11 +44,72 @@ export func Compile(src_file, src string, flags *Flags) *Compilation {
} }
var parser Parser.Parser; var parser Parser.Parser;
parser.Open(flags.verbose, flags.sixg, &scanner, tstream); parser.Open(flags.verbose, flags.sixg, flags.deps, &scanner, tstream);
C := new(Compilation); prog := parser.ParseProgram();
C.prog = parser.ParseProgram(); return prog, scanner.nerrors;
C.nerrors = scanner.nerrors; }
return C;
func FileExists(name string) bool {
fd, err := OS.Open(name, OS.O_RDONLY, 0);
if err == nil {
fd.Close();
return true;
}
return false;
}
func AddDeps(globalset *map [string] bool, wset *AST.List, src_file string, flags *Flags) {
dummy, found := globalset[src_file];
if !found {
globalset[src_file] = true;
prog, nerrors := Compile(src_file, flags);
if nerrors > 0 {
return;
}
nimports := prog.decls.len();
if nimports > 0 {
print(src_file, ".6:\t");
localset := new(map [string] bool);
for i := 0; i < nimports; i++ {
decl := prog.decls.at(i).(*AST.Decl);
assert(decl.tok == Scanner.IMPORT && decl.val.tok == Scanner.STRING);
src := decl.val.s;
src = src[1 : len(src) - 1]; // strip "'s
// ignore files when they are seen a 2nd time
dummy, found := localset[src];
if !found {
localset[src] = true;
if FileExists(src + ".go") {
wset.Add(src);
print(" ", src, ".6");
} else if
FileExists(Platform.GOROOT + "/pkg/" + src + ".6") ||
FileExists(Platform.GOROOT + "/pkg/" + src + ".a") {
} else {
// TODO should collect these and print later
//print("missing file: ", src, "\n");
}
}
}
print("\n\n");
}
}
}
export func ComputeDeps(src_file string, flags *Flags) {
globalset := new(map [string] bool);
wset := AST.NewList();
wset.Add(src_file);
for wset.len() > 0 {
AddDeps(globalset, wset, wset.Pop().(string), flags);
}
} }

View File

@ -10,7 +10,7 @@ import AST "ast"
export type Parser struct { export type Parser struct {
// Tracing/debugging // Tracing/debugging
verbose, sixg bool; verbose, sixg, deps bool;
indent uint; indent uint;
// Scanner // Scanner
@ -83,9 +83,10 @@ func (P *Parser) Next() {
} }
func (P *Parser) Open(verbose, sixg bool, scanner *Scanner.Scanner, tokchan *<-chan *Scanner.Token) { func (P *Parser) Open(verbose, sixg, deps bool, scanner *Scanner.Scanner, tokchan *<-chan *Scanner.Token) {
P.verbose = verbose; P.verbose = verbose;
P.sixg = sixg; P.sixg = sixg;
P.deps = deps;
P.indent = 0; P.indent = 0;
P.scanner = scanner; P.scanner = scanner;
@ -1187,9 +1188,12 @@ func (P *Parser) ParseCommCase() *AST.Stat {
if P.tok == Scanner.ASSIGN || P.tok == Scanner.DEFINE { if P.tok == Scanner.ASSIGN || P.tok == Scanner.DEFINE {
pos, tok := P.pos, P.tok; pos, tok := P.pos, P.tok;
P.Next(); P.Next();
P.Expect(Scanner.ARROW); if P.tok == Scanner.ARROW {
y := P.ParseExpression(1); y := P.ParseExpression(1);
x = AST.NewExpr(pos, tok, x, y); x = AST.NewExpr(pos, tok, x, y);
} else {
P.Expect(Scanner.ARROW); // use Expect() error handling
}
} }
s.expr = x; s.expr = x;
} else { } else {
@ -1527,10 +1531,12 @@ func (P *Parser) ParseProgram() *AST.Program {
P.OptSemicolon(); P.OptSemicolon();
} }
if !P.deps {
for P.tok != Scanner.EOF { for P.tok != Scanner.EOF {
p.decls.Add(P.ParseDeclaration()); p.decls.Add(P.ParseDeclaration());
P.OptSemicolon(); P.OptSemicolon();
} }
}
p.comments = P.comments; p.comments = P.comments;

View File

@ -41,7 +41,7 @@ func init() {
// I/O // I/O
export const ( export const (
MAGIC_obj_file = "@gri-go.7@v0"; // make it clear thar it cannot be a source file MAGIC_obj_file = "@gri-go.7@v0"; // make it clear that it cannot be a source file
src_file_ext = ".go"; src_file_ext = ".go";
obj_file_ext = ".7"; obj_file_ext = ".7";
) )

View File

@ -40,27 +40,18 @@ func main() {
for i := 0; i < Flag.NArg(); i++ { for i := 0; i < Flag.NArg(); i++ {
src_file := Flag.Arg(i); src_file := Flag.Arg(i);
src, ok := Platform.ReadSourceFile(src_file);
if !ok {
print("cannot open ", src_file, "\n");
sys.exit(1);
}
C := Compilation.Compile(src_file, src, &flags);
if C.nerrors > 0 {
sys.exit(1);
}
if flags.deps { if flags.deps {
print("deps\n"); Compilation.ComputeDeps(src_file, &flags);
panic("UNIMPLEMENTED");
} else {
prog, nerrors := Compilation.Compile(src_file, &flags);
if nerrors > 0 {
return; return;
} }
if !silent.BVal() && !flags.testmode { if !silent.BVal() && !flags.testmode {
var P Printer.Printer; var P Printer.Printer;
(&P).Program(C.prog); (&P).Program(prog);
}
} }
} }
} }