diff options
author | Martin Odersky <odersky@gmail.com> | 2003-02-13 14:41:36 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2003-02-13 14:41:36 +0000 |
commit | 4177daab2f54bdb20c71f623296a8bb32616fd12 (patch) | |
tree | 23f08b43f3758e825d5965b336030603a65bbcf7 /sources/scalac/Global.java | |
parent | 33d6e170c97ca7b2f991896a0729941a7240b6d6 (diff) | |
download | scala-4177daab2f54bdb20c71f623296a8bb32616fd12.tar.gz scala-4177daab2f54bdb20c71f623296a8bb32616fd12.tar.bz2 scala-4177daab2f54bdb20c71f623296a8bb32616fd12.zip |
Initial version.
Diffstat (limited to 'sources/scalac/Global.java')
-rw-r--r-- | sources/scalac/Global.java | 354 |
1 files changed, 354 insertions, 0 deletions
diff --git a/sources/scalac/Global.java b/sources/scalac/Global.java new file mode 100644 index 0000000000..3c3d73c0e6 --- /dev/null +++ b/sources/scalac/Global.java @@ -0,0 +1,354 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +** ** +** $Id$ +\* */ + +package scalac; + +import java.io.*; +import java.util.*; +import scalac.util.*; +import scalac.ast.*; +import scalac.ast.parser.*; +import scalac.symtab.Definitions; +import scalac.ast.printer.*; + + +/** The global environment of a compiler run + * + * @author Matthias Zenger + * @version 1.0 + */ +public class Global { + + public static Global instance; + + /** global options + */ + public final boolean noimports; + //public final boolean optimize; + public final boolean debug; + public final boolean uniqid; + + public final boolean printtypes; + public final boolean printtokens; + + public final String outpath; + public final String target; + + public final String jacoDebug; + + /** the message reporter + */ + public final Reporter reporter; + + /** a stack for maintaining timestamps + */ + private final Stack startTimes = new Stack(); + + /** all compilation units + */ + public Unit[] units; + + /** the class path + */ + public final ClassPath classPath; + + /** the global tree factory + */ + public final TreeFactory make; + + /** the fresh name creator + */ + public final FreshNameCreator freshNameCreator; + + /** the tree generator + */ + public final TreeGen treeGen; + + /** the unique-id generator + */ + public final UniqueID uniqueID; + + /** the global tree printer + */ + public final TreePrinter printer; + public OutputStream printStream; + public final TreePrinter debugPrinter; + + /** the current phase + */ + public PhaseDescriptor currentPhase; + + /** the global definitions + */ + public Definitions definitions; + + /** the global primitives + */ + //public Primitives primitives; + + /** compilation phases. + */ + public final PhaseRepository PHASE; + public final PhaseDescriptor[] phases; + + public final int POST_ANALYZER_PHASE_ID = 3; + + /** compilation targets + */ + public static final String TARGET_INT; + public static final String TARGET_JAVA; + public static final String TARGET_JVM; + public static final String TARGET_MSIL; + + public static final String[] TARGETS = new String[] { + TARGET_INT = "int".intern(), + TARGET_JAVA = "java".intern(), + TARGET_JVM = "jvm".intern(), + TARGET_MSIL = "msil".intern(), + }; + + /** tree printers + */ + public static final String PRINTER_TEXT; + public static final String PRINTER_HTML; + + public static final String[] PRINTERS = new String[] { + PRINTER_TEXT = "text".intern(), + PRINTER_HTML = "html".intern(), + }; + + public Global(CompilerCommand args) { + this(args, false); + } + + public Global(CompilerCommand args, boolean interpret) { + if (Global.instance != null) { // jaco bug: can't use assert here + new Error("Duplicate creation of Global").printStackTrace(); + System.exit(1); + }; + Global.instance = this; + this.reporter = args.reporter(); + this.start(); // timestamp to compute the total time + this.noimports = args.noimports.value; + //this.optimize = args.optimize.optimize; + this.debug = args.debug.value; + this.uniqid = args.uniqid.value; + this.printtypes = args.types.value; + this.printtokens = args.print.tokens; + this.classPath = args.classpath(); + this.outpath = args.outpath(); + this.target = interpret ? TARGET_INT : args.target.value.intern(); + this.jacoDebug = args.jaco.value; + this.uniqueID = new UniqueID(); + String printFile = args.printfile.value; + try { + this.printStream = "-".equals(printFile) + ? System.out + : new FileOutputStream(printFile); + } catch (FileNotFoundException e) { + error("unable to open file " + printFile + ". Printing on console"); + this.printStream = System.out; + } + String printerName = args.printer.value.intern(); + if (printerName == PRINTER_TEXT) + this.printer = new TextTreePrinter(printStream); + else + this.printer = new HTMLTreePrinter(printStream); + this.debugPrinter = new TextTreePrinter(System.err); + this.freshNameCreator = new FreshNameCreator(); + this.make = new TreeCreator(); + this.currentPhase = PhaseDescriptor.INITIAL; + this.definitions = new Definitions(this); + //this.primitives = new Primitives(this); + this.treeGen = new TreeGen(this, make); + this.PHASE = args.phases; + List phases = new ArrayList(); + phases.add(PHASE.INITIAL); + phases.add(PHASE.PARSER); + phases.add(PHASE.ANALYZER); + phases.add(PHASE.REFCHECK); + phases.add(PHASE.UNCURRY); + /* + if (optimize) { + phases.add(PHASE.OPTIMIZE); + } + phases.add(PHASE.TRANSMATCH); + */ + //phases.add(PHASE.LAMBDALIFT); + /* + phases.add(PHASE.EXPLICITOUTER); + phases.add(PHASE.ADDACCESSORS); + phases.add(PHASE.ADDINTERFACES); + phases.add(PHASE.EXPANDMIXIN); + phases.add(PHASE.ERASURE); + if (target == TARGET_INT || target == TARGET_MSIL || target == TARGET_JVM) { + phases.add(PHASE.ADDCONSTRUCTORS); + } + if (target == TARGET_JAVA) phases.add(PHASE.GENJAVA); + if (target == TARGET_MSIL) phases.add(PHASE.GENMSIL); + if (target == TARGET_JVM) phases.add(PHASE.GENJVM); + */ + phases.add(PHASE.TERMINAL); + this.phases = new PhaseDescriptor[phases.size()]; + for (int i = 0; i < phases.size(); i++) { + PhaseDescriptor phase = (PhaseDescriptor)phases.get(i); + this.phases[i] = phase; + if (i > 0) this.phases[i - 1].flags |= phase.flags >>> 16; + phase.initialize(this, i); + assert phase.id == i; + } + assert PHASE.ANALYZER.id + 1 == POST_ANALYZER_PHASE_ID; + } + + /** Move to next phase + */ + public void nextPhase() { + currentPhase = phases[currentPhase.id + 1]; + } + + /** Move to previous phase + */ + public void prevPhase() { + currentPhase = phases[currentPhase.id - 1]; + } + + /** the top-level compilation process + */ + public void compile(String[] files, boolean console) { + reporter.resetCounters(); + // parse files + List units = new ArrayList(files.length); + for (int i = 0; i < files.length; i++) { + String file = files[i]; + try { + units.add(new Unit(this, new Sourcefile(file, console))); + } catch (FileNotFoundException e) { + error("file " + file + " not found"); + } catch (IOException e) { + error(e.toString()); + } + } + this.units = (Unit[])units.toArray(new Unit[units.size()]); + compile(); + } + + /** the top-level compilation process + */ + public void compile(String input, boolean console) { + reporter.resetCounters(); + Sourcefile source = new Sourcefile(input.getBytes(), console); + units = new Unit[]{new Unit(this, source)}; + compile(); + } + + /** compile all compilation units + */ + private void compile() { + printer.begin(); + + // apply successive phases and pray that it works + for (int i = 0; i < phases.length && reporter.errors() == 0; ++i) { + currentPhase = phases[i]; + if ((currentPhase.flags & PhaseDescriptor.SKIP) != 0) { + operation("skipping phase " + currentPhase.name()); + } else { + currentPhase.apply(this); + } + if ((currentPhase.flags & PhaseDescriptor.PRINT) != 0) + currentPhase.print(this); + if ((currentPhase.flags & PhaseDescriptor.GRAPH) != 0) + currentPhase.graph(this); + if ((currentPhase.flags & PhaseDescriptor.CHECK) != 0) + currentPhase.check(this); + if ((currentPhase.flags & PhaseDescriptor.STOP) != 0) { + operation("stopped after phase " + currentPhase.name()); + break; + } + } + + printer.end(); + } + + /** stop the compilation process immediately + */ + public Error fail() { + throw new ApplicationError(); + } + + /** stop the compilation process immediately + */ + public Error fail(String message) { + throw new ApplicationError(message); + } + + /** stop the compilation process immediately + */ + public Error fail(String message, Object object) { + throw new ApplicationError(message, object); + } + + /** stop the compilation process immediately + */ + public Error fail(Object value) { + throw new ApplicationError(value); + } + + /** issue a global error + */ + public void error(String message) { + reporter.error("error: " + message); + } + + /** issue a global warning + */ + public void warning(String message) { + reporter.warning("warning: " + message); + } + + /** issue a global note (if in verbose mode) + */ + public void note(String message) { + reporter.note("note: " + message); + } + + /** issue an operation note + */ + public void operation(String message) { + reporter.inform("[" + message + "]"); + } + + /** issue a debug message from currentPhase + */ + // the boolean return value is here to let one write "assert log( ... )" + public boolean log(String message) { + if (log()) { + reporter.report("[log " + currentPhase.name() + "] " + message); + } + return true; + } + + /** return true if logging is switched on for the current phase + */ + public boolean log() { + return (currentPhase.flags & PhaseDescriptor.LOG) != 0; + } + + /** start a new timer + */ + public void start() { + startTimes.push(new Long(System.currentTimeMillis())); + } + + /** issue timing information + */ + public void stop(String message) { + long start = ((Long)startTimes.pop()).longValue(); + reporter.inform("[" + message + " in " + + (System.currentTimeMillis() - start) + "ms]"); + } +} |