Commit eba73552 authored by Robert Griesemer's avatar Robert Griesemer

- 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
parent e8278bcb
...@@ -17,17 +17,19 @@ install: pretty ...@@ -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 ast.6: scanner.6
parser.6: scanner.6 utils.6 printer.6 ast.6 scanner.6: utils.6
ast.6: scanner.6 parser.6: scanner.6 ast.6
scanner.6: utils.6 platform.6 platform.6: utils.6
printer.6: scanner.6 ast.6
%.6: %.go %.6: %.go
$(G) $(F) $< $(G) $(F) $<
...@@ -33,17 +33,19 @@ clean: ...@@ -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 ast.o: scanner.o
parser.o: scanner.o utils.o printer.o ast.o scanner.o: utils.o
ast.o: scanner.o parser.o: scanner.o ast.o
scanner.o: utils.o platform.o platform.o: utils.o
printer.o: scanner.o ast.o
flag.o: fmt.o flag.o: fmt.o
......
...@@ -43,7 +43,7 @@ func (p *List) set(i int, x Any) { ...@@ -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) { ...@@ -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];
......
...@@ -4,11 +4,19 @@ ...@@ -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 { ...@@ -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 { ...@@ -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);
prog := parser.ParseProgram();
return prog, scanner.nerrors;
}
C := new(Compilation); func FileExists(name string) bool {
C.prog = parser.ParseProgram(); fd, err := OS.Open(name, OS.O_RDONLY, 0);
C.nerrors = scanner.nerrors; if err == nil {
fd.Close();
return C; 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);
}
} }
...@@ -10,7 +10,7 @@ import AST "ast" ...@@ -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() { ...@@ -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 { ...@@ -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 {
...@@ -1526,10 +1530,12 @@ func (P *Parser) ParseProgram() *AST.Program { ...@@ -1526,10 +1530,12 @@ func (P *Parser) ParseProgram() *AST.Program {
p.decls.Add(P.ParseDecl(false, Scanner.IMPORT)); p.decls.Add(P.ParseDecl(false, Scanner.IMPORT));
P.OptSemicolon(); P.OptSemicolon();
} }
for P.tok != Scanner.EOF { if !P.deps {
p.decls.Add(P.ParseDeclaration()); for P.tok != Scanner.EOF {
P.OptSemicolon(); p.decls.Add(P.ParseDeclaration());
P.OptSemicolon();
}
} }
p.comments = P.comments; p.comments = P.comments;
......
...@@ -41,7 +41,7 @@ func init() { ...@@ -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";
) )
......
...@@ -40,27 +40,18 @@ func main() { ...@@ -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");
return; } else {
} prog, nerrors := Compilation.Compile(src_file, &flags);
if nerrors > 0 {
if !silent.BVal() && !flags.testmode { return;
var P Printer.Printer; }
(&P).Program(C.prog); if !silent.BVal() && !flags.testmode {
var P Printer.Printer;
(&P).Program(prog);
}
} }
} }
} }
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