private String writeCode(CodeGenVisitor generator) throws IOException, MoPaQException, MapFormatException { String outputName = options.outDir.getPath() + "/Andromeda.galaxy"; StringBufferWriter w = new StringBufferWriter(); generator.flushOutCode(w); String code = w.toString(); // Create out directory options.outDir.mkdirs(); // Write to external file BufferedWriter bw = new BufferedWriter(new FileWriter(new File(options.outDir, "Andromeda.galaxy"))); bw.write(code); bw.close(); // If we have an input map, manipulate its mapScript if (map != null || options.mapScriptIn != null) { // Write map script to output folder String mapScript; if (map != null) { mapScript = ScriptInjector.getManipulatedMapScript(map); } else { mapScript = ScriptInjector.getManipulatedMapScript(options.mapScriptIn); } BufferedWriter bw2 = new BufferedWriter(new FileWriter(new File(options.outDir, "MapScript.galaxy"))); bw2.write(mapScript); bw2.close(); // Write to map file if specified if (options.mapOut != null) { ScriptInjector.injectAndromeda(map, mapScript, code); map.save(options.mapOut); outputName = options.mapOut.getName(); } } return outputName; }
public ParseResult compile() { long bytesOut = 0; long time = resetTime(); boolean abort = false; IParser p = null; try { p = createParser(); // *** Do the parsing *** AndromedaFile af = parseAllFiles(p); // Do semantics analysis System.out.print("No syntax errors. Checking semantics..."); Environment env = SemanticAnalysis.analyze(af, options); System.out.println(" DONE (" + getTime() + " ms)"); String outputName = "-NO OUTPUT-"; OutputStats outputStats = null; if (!options.noCodegen) { // Transform code System.out.print("No semantic errors. Doing code transformations..."); CodeTransformationVisitor trans = new CodeTransformationVisitor(options, env.typeProvider, env.nameResolver); trans.visit(af); System.out.println(" DONE (" + getTime() + " ms)"); // Call hierarchy check System.out.print("Checking call hierarchy..."); CallHierarchyVisitor chv = new CallHierarchyVisitor(options, env.nameResolver); chv.visit(af); VirtualCallResolver vcr = new VirtualCallResolver(env, chv); vcr.tryResolve(); // XPilot: completes hierarchy analysis // chv.visitVirtualInvocations(env.getVirtualInvocations()); UnusedFinder.process(options, env); VirtualCallTable.generateVCTs(env); MetaClassInit.init(new SyntaxGenerator(options, env.nameResolver), env); System.out.println(" DONE (" + getTime() + " ms)"); // Names System.out.print("Generating identifiers..."); NameGenerationVisitor snv = new NameGenerationVisitor(options); ClassFieldCalculator cfc = new IndexClassFieldCalculator(env.typeProvider, snv.getNameProvider()); cfc.calcFields(); env.typeProvider.calcFuncPointerIndices(); cfc.generateClassNames(); snv.prepareNameGeneration(); snv.visit(af); System.out.println(" DONE (" + getTime() + " ms)"); // Generate code System.out.print("Generating code..."); CodeGenVisitor c = new CodeGenVisitor(env, options, snv.getNameProvider()); if (!env.typeProvider.getClasses().isEmpty()) { ClassGenerator cg = new IndexClassGenerator(env, c, snv.getNameProvider(), options); cg.generateClasses(env.typeProvider.getClasses()); } c.generateCode(snv, af); c.writeInit(); outputStats = c.getOutputStatistics(); System.out.println(" DONE (" + getTime() + " ms)"); // Output the code to file / map System.out.print("Writing code..."); outputName = writeCode(c); bytesOut = c.getBytesOut(); System.out.println(" DONE (" + getTime() + " ms)"); } // Output structure to xml if desired to if (options.xmlStructure != null) { System.out.print("Writing structure to XML..."); new StructureXMLVisitor(options).genXml(p.getSourceEnvironment(), options.xmlStructure, af); System.out.println(" DONE (" + getTime() + " ms)"); } time = (System.currentTimeMillis() - time); long bytesIn = p.getSourceEnvironment().getBytesRead(); System.out.println( "=> Successfully compiled " + p.getSourceEnvironment().getFileCount() + " files (" + bytesIn + " bytes).\n=> Produced code: " + bytesOut + " bytes.\n=> Time: " + time + " ms (" + (int) (((bytesOut + bytesIn) / (double) (1 << 10)) / (time / 1000.0)) + " KB/s)"); System.out.println( "=> Memory Usage: " + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1 << 20)) + " MB"); if (outputStats != null) { System.out.println("Generated code memory usage:"); System.out.println("=> Global variables: " + outputStats.globalsBytes / 1000f + " KB"); System.out.println("=> String literals: " + outputStats.stringLiteralBytes / 1000f + " KB"); System.out.println( ">>> Total memory usage (without code): " + outputStats.getBytes() / 1000f + " KB (" + (((int) (outputStats.getBytes() / (float) (1 << 21) * 10000)) / 100f) + "%)"); } Program.log.caption( "+++ Compilation successful" + (options.noCodegen ? "" : ", code written to " + outputName) + " +++"); } catch (Throwable e) { reportError(e); if (e instanceof CompilationError) { ((CompilationError) e).setEnvironment(p.getSourceEnvironment()); } if (e instanceof Message) { Program.log.addMessage((Message) e); } else { Program.log.addMessage(new UnlocatedErrorMessage(e.getMessage())); } abort = true; } // Write parse result to xml if desired to and add messages to result List<Message> messages = Program.log.flushMessages(); getResult().addMessages(messages); if (options.xmlErrors != null) { new ResultXMLWriter().genXML(messages, options.xmlErrors); } // If an error occurred abort here if (abort) return getResult(); // If desired, run the map if (options.runMap) { Program.log.println("Running created map..."); try { new MapRunner(Program.platform, options, Program.config).test(options.mapOut); } catch (IOException e) { e.printStackTrace(); System.err.println("--- Map run unsuccessful! ---"); } } return getResult(); }