mirror of
				https://github.com/golang/go.git
				synced 2025-10-31 08:40:55 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			198 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			198 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // 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
 | |
| 
 | |
| import (
 | |
| 	"vector";
 | |
| 	"utf8";
 | |
| 	"fmt";
 | |
| 	"os";
 | |
| 	Utils "utils";
 | |
| 	Platform "platform";
 | |
| 	"scanner";
 | |
| 	Parser "parser";
 | |
| 	AST "ast";
 | |
| 	TypeChecker "typechecker";
 | |
| )
 | |
| 
 | |
| 
 | |
| func assert(b bool) {
 | |
| 	if !b {
 | |
| 		panic("assertion failed");
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| type Flags struct {
 | |
| 	Verbose bool;
 | |
| 	Deps bool;
 | |
| 	Columns bool;
 | |
| }
 | |
| 
 | |
| 
 | |
| type errorHandler struct {
 | |
| 	filename string;
 | |
| 	src []byte;
 | |
| 	columns bool;
 | |
| 	errline int;
 | |
| 	nerrors int;
 | |
| }
 | |
| 
 | |
| 
 | |
| func (h *errorHandler) Init(filename string, src []byte, columns bool) {
 | |
| 	h.filename = filename;
 | |
| 	h.src = src;
 | |
| 	h.columns = columns;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
| // Compute (line, column) information for a given source position.
 | |
| func (h *errorHandler) LineCol(pos int) (line, col int) {
 | |
| 	line = 1;
 | |
| 	lpos := 0;
 | |
| 
 | |
| 	src := h.src;
 | |
| 	if pos > len(src) {
 | |
| 		pos = len(src);
 | |
| 	}
 | |
| 
 | |
| 	for i := 0; i < pos; i++ {
 | |
| 		if src[i] == '\n' {
 | |
| 			line++;
 | |
| 			lpos = i;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return line, utf8.RuneCount(src[lpos : pos]);
 | |
| }
 | |
| */
 | |
| 
 | |
| 
 | |
| func (h *errorHandler) ErrorMsg(loc scanner.Location, msg string) {
 | |
| 	fmt.Printf("%s:%d:", h.filename, loc.Line);
 | |
| 	if h.columns {
 | |
| 		fmt.Printf("%d:", loc.Col);
 | |
| 	}
 | |
| 	fmt.Printf(" %s\n", msg);
 | |
| 
 | |
| 	h.errline = loc.Line;
 | |
| 
 | |
| 	h.nerrors++;
 | |
| 	if h.nerrors >= 10 {
 | |
| 		sys.Exit(1);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| func (h *errorHandler) Error(loc scanner.Location, msg string) {
 | |
| 	// only report errors that are on a new line 
 | |
| 	// in the hope to avoid most follow-up errors
 | |
| 	if loc.Line != h.errline {
 | |
| 		h.ErrorMsg(loc, msg);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| func Compile(src_file string, flags *Flags) (*AST.Program, int) {
 | |
| 	src, ok := Platform.ReadSourceFile(src_file);
 | |
| 	if !ok {
 | |
| 		print("cannot open ", src_file, "\n");
 | |
| 		return nil, 1;
 | |
| 	}
 | |
| 
 | |
| 	var err errorHandler;
 | |
| 	err.Init(src_file, src, flags.Columns);
 | |
| 
 | |
| 	var scanner scanner.Scanner;
 | |
| 	scanner.Init(src, &err, true);
 | |
| 
 | |
| 	var parser Parser.Parser;
 | |
| 	parser.Init(&scanner, &err, flags.Verbose);
 | |
| 
 | |
| 	prog := parser.ParseProgram();
 | |
| 
 | |
| 	if err.nerrors == 0 {
 | |
| 		TypeChecker.CheckProgram(&err, prog);
 | |
| 	}
 | |
| 
 | |
| 	return prog, err.nerrors;
 | |
| }
 | |
| 
 | |
| 
 | |
| func fileExists(name string) bool {
 | |
| 	dir, err := os.Stat(name);
 | |
| 	return err == nil;
 | |
| }
 | |
| 
 | |
| /*
 | |
| func printDep(localset map [string] bool, wset *vector.Vector, decl AST.Decl2) {
 | |
| 	src := decl.Val.(*AST.BasicLit).Val;
 | |
| 	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");
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| */
 | |
| 
 | |
| 
 | |
| func addDeps(globalset map [string] bool, wset *vector.Vector, 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 := len(prog.Decls);
 | |
| 		if nimports > 0 {
 | |
| 			fmt.Printf("%s.6:\t", src_file);
 | |
| 
 | |
| 			localset := make(map [string] bool);
 | |
| 			for i := 0; i < nimports; i++ {
 | |
| 				decl := prog.Decls[i];
 | |
| 				panic();
 | |
| 				/*
 | |
| 				assert(decl.Tok == scanner.IMPORT);
 | |
| 				if decl.List == nil {
 | |
| 					printDep(localset, wset, decl);
 | |
| 				} else {
 | |
| 					for j := 0; j < decl.List.Len(); j++ {
 | |
| 						printDep(localset, wset, decl.List.At(j).(*AST.Decl));
 | |
| 					}
 | |
| 				}
 | |
| 				*/
 | |
| 			}
 | |
| 			print("\n\n");
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| func ComputeDeps(src_file string, flags *Flags) {
 | |
| 	panic("dependency printing currently disabled");
 | |
| 	globalset := make(map [string] bool);
 | |
| 	wset := vector.New(0);
 | |
| 	wset.Push(Utils.TrimExt(src_file, ".go"));
 | |
| 	for wset.Len() > 0 {
 | |
| 		addDeps(globalset, wset, wset.Pop().(string), flags);
 | |
| 	}
 | |
| }
 | 
