"README.md" did not exist on "2fca1a4049ad96cecaa1c35a44d11265cd2f7e45"
compilation.go 3.77 KB
Newer Older
Robert Griesemer's avatar
Robert Griesemer committed
1 2 3 4 5 6
// 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

7
import (
8
	"vector";
9
	"utf8";
10 11
	"fmt";
	"os";
Robert Griesemer's avatar
Robert Griesemer committed
12 13
	"utils";
	"platform";
14
	"token";
15
	"scanner";
16
	"parser";
Robert Griesemer's avatar
Robert Griesemer committed
17 18 19
	"ast";
	"typechecker";
	"sort";
20
)
Robert Griesemer's avatar
Robert Griesemer committed
21 22


23 24 25 26 27 28
func assert(b bool) {
	if !b {
		panic("assertion failed");
	}
}

Robert Griesemer's avatar
Robert Griesemer committed
29

Russ Cox's avatar
Russ Cox committed
30
type Flags struct {
Robert Griesemer's avatar
Robert Griesemer committed
31 32 33
	Verbose bool;
	Deps bool;
	Columns bool;
Robert Griesemer's avatar
Robert Griesemer committed
34 35 36
}


Robert Griesemer's avatar
Robert Griesemer committed
37
type Error struct {
38
	Pos token.Position;
Robert Griesemer's avatar
Robert Griesemer committed
39 40 41 42 43 44 45
	Msg string;
}


type ErrorList []Error

func (list ErrorList) Len() int { return len(list); }
46
func (list ErrorList) Less(i, j int) bool { return list[i].Pos.Offset < list[j].Pos.Offset; }
Robert Griesemer's avatar
Robert Griesemer committed
47 48 49
func (list ErrorList) Swap(i, j int) { list[i], list[j] = list[j], list[i]; }


Robert Griesemer's avatar
Robert Griesemer committed
50
type errorHandler struct {
51 52
	filename string;
	columns bool;
53
	errline int;
Robert Griesemer's avatar
Robert Griesemer committed
54
	errors vector.Vector;
55 56 57
}


58
func (h *errorHandler) Init(filename string, columns bool) {
59 60
	h.filename = filename;
	h.columns = columns;
Robert Griesemer's avatar
Robert Griesemer committed
61
	h.errors.Init(0);
62 63 64
}


65
func (h *errorHandler) Error(pos token.Position, msg string) {
Robert Griesemer's avatar
Robert Griesemer committed
66 67
	// only report errors that are on a new line 
	// in the hope to avoid most follow-up errors
68
	if pos.Line == h.errline {
Robert Griesemer's avatar
Robert Griesemer committed
69
		return;
70
	}
71

Robert Griesemer's avatar
Robert Griesemer committed
72
	// report error
73
	fmt.Printf("%s:%d:", h.filename, pos.Line);
74
	if h.columns {
75
		fmt.Printf("%d:", pos.Column);
76
	}
77
	fmt.Printf(" %s\n", msg);
78

Robert Griesemer's avatar
Robert Griesemer committed
79
	// collect the error
80 81
	h.errors.Push(Error{pos, msg});
	h.errline = pos.Line;
82 83 84
}


Robert Griesemer's avatar
Robert Griesemer committed
85
func Compile(filename string, flags *Flags) (*ast.Program, ErrorList) {
86 87 88 89
	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());
Robert Griesemer's avatar
Robert Griesemer committed
90
		return nil, nil;
91
	}
92

Robert Griesemer's avatar
Robert Griesemer committed
93
	var err errorHandler;
94
	err.Init(filename, flags.Columns);
Robert Griesemer's avatar
Robert Griesemer committed
95

96
	mode := parser.ParseComments;
97
	if flags.Verbose {
Robert Griesemer's avatar
Robert Griesemer committed
98
		mode |= parser.Trace;
99
	}
100
	prog, ok2 := parser.Parse(src, &err, mode);
101

102
	if ok2 {
103
		TypeChecker.CheckProgram(&err, prog);
Robert Griesemer's avatar
Robert Griesemer committed
104
	}
Robert Griesemer's avatar
Robert Griesemer committed
105 106 107 108 109 110 111
	
	// 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);
112

Robert Griesemer's avatar
Robert Griesemer committed
113
	return prog, errors;
114 115
}

Robert Griesemer's avatar
Robert Griesemer committed
116

Robert Griesemer's avatar
Robert Griesemer committed
117
func fileExists(name string) bool {
Russ Cox's avatar
Russ Cox committed
118
	dir, err := os.Stat(name);
119 120 121
	return err == nil;
}

122
/*
Robert Griesemer's avatar
Robert Griesemer committed
123 124
func printDep(localset map [string] bool, wset *vector.Vector, decl ast.Decl2) {
	src := decl.Val.(*ast.BasicLit).Val;
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
	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");
		}
142 143
	}
}
144
*/
145 146


147
func addDeps(globalset map [string] bool, wset *vector.Vector, src_file string, flags *Flags) {
148 149 150
	dummy, found := globalset[src_file];
	if !found {
		globalset[src_file] = true;
151

Robert Griesemer's avatar
Robert Griesemer committed
152 153
		prog, errors := Compile(src_file, flags);
		if errors == nil || len(errors) > 0 {
154 155
			return;
		}
156

157
		nimports := len(prog.Decls);
158
		if nimports > 0 {
159
			fmt.Printf("%s.6:\t", src_file);
160

161
			localset := make(map [string] bool);
162
			for i := 0; i < nimports; i++ {
163 164 165
				decl := prog.Decls[i];
				panic();
				/*
166
				assert(decl.Tok == scanner.IMPORT);
167 168 169 170
				if decl.List == nil {
					printDep(localset, wset, decl);
				} else {
					for j := 0; j < decl.List.Len(); j++ {
Robert Griesemer's avatar
Robert Griesemer committed
171
						printDep(localset, wset, decl.List.At(j).(*ast.Decl));
172 173
					}
				}
174
				*/
175 176 177 178 179 180 181
			}
			print("\n\n");
		}
	}
}


Russ Cox's avatar
Russ Cox committed
182
func ComputeDeps(src_file string, flags *Flags) {
183
	panic("dependency printing currently disabled");
184
	globalset := make(map [string] bool);
185
	wset := vector.New(0);
Robert Griesemer's avatar
Robert Griesemer committed
186
	wset.Push(Utils.TrimExt(src_file, ".go"));
187
	for wset.Len() > 0 {
Robert Griesemer's avatar
Robert Griesemer committed
188
		addDeps(globalset, wset, wset.Pop().(string), flags);
189
	}
Robert Griesemer's avatar
Robert Griesemer committed
190
}