2008-10-24 15:08:01 -06:00
|
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package Compilation
|
|
|
|
|
2009-01-14 16:19:34 -07:00
|
|
|
import (
|
2009-02-13 16:07:56 -07:00
|
|
|
"vector";
|
2009-01-14 16:19:34 -07:00
|
|
|
"utf8";
|
2009-02-06 12:10:25 -07:00
|
|
|
"fmt";
|
|
|
|
"os";
|
2009-03-13 17:59:51 -06:00
|
|
|
"utils";
|
|
|
|
"platform";
|
2009-03-26 17:10:07 -06:00
|
|
|
"token";
|
2009-03-11 13:52:11 -06:00
|
|
|
"scanner";
|
2009-03-26 17:10:07 -06:00
|
|
|
"parser";
|
2009-03-13 17:59:51 -06:00
|
|
|
"ast";
|
|
|
|
"typechecker";
|
|
|
|
"sort";
|
2009-01-14 16:19:34 -07:00
|
|
|
)
|
2008-10-24 15:08:01 -06:00
|
|
|
|
|
|
|
|
2008-10-26 22:32:30 -06:00
|
|
|
func assert(b bool) {
|
|
|
|
if !b {
|
|
|
|
panic("assertion failed");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-24 15:08:01 -06:00
|
|
|
|
2009-01-20 15:40:40 -07:00
|
|
|
type Flags struct {
|
2009-01-16 16:31:34 -07:00
|
|
|
Verbose bool;
|
|
|
|
Deps bool;
|
|
|
|
Columns bool;
|
2008-10-24 15:08:01 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-03-13 17:59:51 -06:00
|
|
|
type Error struct {
|
2009-03-26 17:10:07 -06:00
|
|
|
Pos token.Position;
|
2009-03-13 17:59:51 -06:00
|
|
|
Msg string;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type ErrorList []Error
|
|
|
|
|
|
|
|
func (list ErrorList) Len() int { return len(list); }
|
2009-03-26 17:10:07 -06:00
|
|
|
func (list ErrorList) Less(i, j int) bool { return list[i].Pos.Offset < list[j].Pos.Offset; }
|
2009-03-13 17:59:51 -06:00
|
|
|
func (list ErrorList) Swap(i, j int) { list[i], list[j] = list[j], list[i]; }
|
|
|
|
|
|
|
|
|
2009-01-15 18:16:41 -07:00
|
|
|
type errorHandler struct {
|
2008-11-24 19:24:21 -07:00
|
|
|
filename string;
|
|
|
|
columns bool;
|
2009-03-11 13:52:11 -06:00
|
|
|
errline int;
|
2009-03-13 17:59:51 -06:00
|
|
|
errors vector.Vector;
|
2008-11-24 19:24:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-03-31 14:28:01 -06:00
|
|
|
func (h *errorHandler) Init(filename string, columns bool) {
|
2008-11-24 19:24:21 -07:00
|
|
|
h.filename = filename;
|
|
|
|
h.columns = columns;
|
2009-03-13 17:59:51 -06:00
|
|
|
h.errors.Init(0);
|
2008-11-24 19:24:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-03-26 17:10:07 -06:00
|
|
|
func (h *errorHandler) Error(pos token.Position, msg string) {
|
2009-03-13 17:59:51 -06:00
|
|
|
// only report errors that are on a new line
|
|
|
|
// in the hope to avoid most follow-up errors
|
2009-03-26 17:10:07 -06:00
|
|
|
if pos.Line == h.errline {
|
2009-03-13 17:59:51 -06:00
|
|
|
return;
|
2008-11-24 19:24:21 -07:00
|
|
|
}
|
2008-12-19 04:05:37 -07:00
|
|
|
|
2009-03-13 17:59:51 -06:00
|
|
|
// report error
|
2009-03-26 17:10:07 -06:00
|
|
|
fmt.Printf("%s:%d:", h.filename, pos.Line);
|
2009-03-11 13:52:11 -06:00
|
|
|
if h.columns {
|
2009-03-26 17:10:07 -06:00
|
|
|
fmt.Printf("%d:", pos.Column);
|
2008-11-24 19:24:21 -07:00
|
|
|
}
|
2009-03-11 13:52:11 -06:00
|
|
|
fmt.Printf(" %s\n", msg);
|
2008-12-19 04:05:37 -07:00
|
|
|
|
2009-03-13 17:59:51 -06:00
|
|
|
// collect the error
|
2009-03-26 17:10:07 -06:00
|
|
|
h.errors.Push(Error{pos, msg});
|
|
|
|
h.errline = pos.Line;
|
2008-11-24 19:24:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-03-31 17:53:58 -06:00
|
|
|
func Compile(filename string, flags *Flags) (*ast.Program, ErrorList) {
|
2009-03-31 14:28:01 -06:00
|
|
|
src, os_err := os.Open(filename, os.O_RDONLY, 0);
|
|
|
|
defer src.Close();
|
|
|
|
if os_err != nil {
|
|
|
|
fmt.Printf("cannot open %s (%s)\n", filename, os_err.String());
|
2009-03-13 17:59:51 -06:00
|
|
|
return nil, nil;
|
2008-10-26 22:32:30 -06:00
|
|
|
}
|
2008-12-19 04:05:37 -07:00
|
|
|
|
2009-01-15 18:16:41 -07:00
|
|
|
var err errorHandler;
|
2009-03-31 14:28:01 -06:00
|
|
|
err.Init(filename, flags.Columns);
|
2008-10-24 15:08:01 -06:00
|
|
|
|
2009-03-31 14:28:01 -06:00
|
|
|
mode := parser.ParseComments;
|
2009-03-26 17:10:07 -06:00
|
|
|
if flags.Verbose {
|
2009-03-27 20:27:09 -06:00
|
|
|
mode |= parser.Trace;
|
2009-03-26 17:10:07 -06:00
|
|
|
}
|
2009-03-31 14:28:01 -06:00
|
|
|
prog, ok2 := parser.Parse(src, &err, mode);
|
2008-12-19 04:05:37 -07:00
|
|
|
|
2009-03-31 14:28:01 -06:00
|
|
|
if ok2 {
|
2009-01-06 15:54:18 -07:00
|
|
|
TypeChecker.CheckProgram(&err, prog);
|
2008-12-16 19:02:22 -07:00
|
|
|
}
|
2009-03-13 17:59:51 -06:00
|
|
|
|
|
|
|
// convert error list and sort it
|
|
|
|
errors := make(ErrorList, err.errors.Len());
|
|
|
|
for i := 0; i < err.errors.Len(); i++ {
|
|
|
|
errors[i] = err.errors.At(i).(Error);
|
|
|
|
}
|
|
|
|
sort.Sort(errors);
|
2008-12-19 04:05:37 -07:00
|
|
|
|
2009-03-13 17:59:51 -06:00
|
|
|
return prog, errors;
|
2008-10-26 22:32:30 -06:00
|
|
|
}
|
|
|
|
|
2008-10-24 15:08:01 -06:00
|
|
|
|
2009-01-15 18:16:41 -07:00
|
|
|
func fileExists(name string) bool {
|
2009-03-11 13:51:10 -06:00
|
|
|
dir, err := os.Stat(name);
|
2009-02-06 12:10:25 -07:00
|
|
|
return err == nil;
|
|
|
|
}
|
|
|
|
|
2009-02-27 16:40:17 -07:00
|
|
|
/*
|
2009-03-13 17:59:51 -06:00
|
|
|
func printDep(localset map [string] bool, wset *vector.Vector, decl ast.Decl2) {
|
|
|
|
src := decl.Val.(*ast.BasicLit).Val;
|
2009-02-06 12:10:25 -07:00
|
|
|
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.Push(src);
|
|
|
|
fmt.Printf(" %s.6", src);
|
|
|
|
} 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");
|
|
|
|
}
|
2008-10-26 22:32:30 -06:00
|
|
|
}
|
|
|
|
}
|
2009-02-27 16:40:17 -07:00
|
|
|
*/
|
2008-10-26 22:32:30 -06:00
|
|
|
|
|
|
|
|
2009-02-13 16:07:56 -07:00
|
|
|
func addDeps(globalset map [string] bool, wset *vector.Vector, src_file string, flags *Flags) {
|
2008-10-26 22:32:30 -06:00
|
|
|
dummy, found := globalset[src_file];
|
|
|
|
if !found {
|
|
|
|
globalset[src_file] = true;
|
2008-12-19 04:05:37 -07:00
|
|
|
|
2009-03-13 17:59:51 -06:00
|
|
|
prog, errors := Compile(src_file, flags);
|
|
|
|
if errors == nil || len(errors) > 0 {
|
2008-10-26 22:32:30 -06:00
|
|
|
return;
|
|
|
|
}
|
2008-12-19 04:05:37 -07:00
|
|
|
|
2009-02-27 16:40:17 -07:00
|
|
|
nimports := len(prog.Decls);
|
2008-10-26 22:32:30 -06:00
|
|
|
if nimports > 0 {
|
2009-02-06 12:10:25 -07:00
|
|
|
fmt.Printf("%s.6:\t", src_file);
|
2008-12-19 04:05:37 -07:00
|
|
|
|
2009-01-06 16:01:04 -07:00
|
|
|
localset := make(map [string] bool);
|
2008-10-26 22:32:30 -06:00
|
|
|
for i := 0; i < nimports; i++ {
|
2009-02-27 16:40:17 -07:00
|
|
|
decl := prog.Decls[i];
|
|
|
|
panic();
|
|
|
|
/*
|
2009-03-11 13:52:11 -06:00
|
|
|
assert(decl.Tok == scanner.IMPORT);
|
2009-02-06 12:10:25 -07:00
|
|
|
if decl.List == nil {
|
|
|
|
printDep(localset, wset, decl);
|
|
|
|
} else {
|
|
|
|
for j := 0; j < decl.List.Len(); j++ {
|
2009-03-13 17:59:51 -06:00
|
|
|
printDep(localset, wset, decl.List.At(j).(*ast.Decl));
|
2008-10-26 22:32:30 -06:00
|
|
|
}
|
|
|
|
}
|
2009-02-27 16:40:17 -07:00
|
|
|
*/
|
2008-10-26 22:32:30 -06:00
|
|
|
}
|
|
|
|
print("\n\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-20 15:40:40 -07:00
|
|
|
func ComputeDeps(src_file string, flags *Flags) {
|
2009-03-05 18:15:36 -07:00
|
|
|
panic("dependency printing currently disabled");
|
2009-01-06 16:01:04 -07:00
|
|
|
globalset := make(map [string] bool);
|
2009-02-13 16:07:56 -07:00
|
|
|
wset := vector.New(0);
|
2009-02-06 16:26:30 -07:00
|
|
|
wset.Push(Utils.TrimExt(src_file, ".go"));
|
2008-11-19 17:49:50 -07:00
|
|
|
for wset.Len() > 0 {
|
2009-01-15 18:16:41 -07:00
|
|
|
addDeps(globalset, wset, wset.Pop().(string), flags);
|
2008-10-26 22:32:30 -06:00
|
|
|
}
|
2008-10-24 15:08:01 -06:00
|
|
|
}
|