package Compiler;
import GUI.Output;
import java.awt.Desktop;
import java.io.File;
import java.net.URI;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import javax.swing.SwingUtilities;
import main.PseuCoCo;
import codeGen.Code;
import codeGen.CodeGen;
import codeGen.MainCode;
import codeGen.MainCodeGen;
import debugger.DebuggerHandler;
public class Pseuco {
private static ThreadGroup runningThreads = new ThreadGroup("Running Pseuco Agents");
public static String includeDir = CompilerUtils.getIncludeDirectory();
public static File includeDirFile = new File(CompilerUtils.getIncludeDirectory());
public static boolean debugging = false;
private static Runnable onProgramFinished = null;
private static Thread pseuCoThread;
public static void joinThreadGroup(ThreadGroup tg) throws InterruptedException{
Thread current = Thread.currentThread();
Thread[] threads = new Thread[2];
while (true){
int c = tg.enumerate(threads);
if (c==0){ return; }
else if (c==1 && threads[0] == current){ return; }
else if (threads[0] != current) threads[0].join();
else threads[1].join();
}
}
public static void joinExternalThreadGroup(ThreadGroup tg) throws InterruptedException{
Thread[] threads = new Thread[1];
while (tg.enumerate(threads) > 0){
threads[0].join();
}
}
public static void run(final String path) {
stopThreadGroup(runningThreads);
programStarted();
pseuCoThread = new PseuCoThread(new String[] {"-i", new File(path).getAbsolutePath() });
pseuCoThread.start();
}
private static String lastProg = null;
public static void debug(final String path) {
stopThreadGroup(runningThreads);
lastProg = path;
programStarted();
debugging = true;
debugger.makeFrame();
pseuCoThread = new PseuCoThread(new String[] {"-i", new File(path).getAbsolutePath() }, true);
pseuCoThread.start();
}
public static void debug(){
debug(lastProg);
}
public static DebuggerHandler debugger = new DebuggerHandler();
public static void stop() {
stopThreadGroup(runningThreads);
}
@SuppressWarnings("deprecation")
private static void stopThreadGroup(ThreadGroup tg){
Output.disableErr();
stopping = true;
try{
if (tg.activeCount() > 0) {
tg.stop();
try {
joinExternalThreadGroup(tg);
if (pseuCoThread != null) pseuCoThread.join();
} catch (InterruptedException e) {}
}
}finally{
Output.enableErr();
}
}
public static int getActiveThreadCount() {
return runningThreads.activeCount();
}
public static void export(final String inputPath, final String outputPath) {
stopThreadGroup(runningThreads);
programStarted();
pseuCoThread = new PseuCoThread(new String[] {"-i", new File(inputPath).getAbsolutePath(),
"-e", new File(outputPath).getAbsolutePath() });
pseuCoThread.start();
}
/**
* Reseting code
*/
private static void init() {
MainCodeGen.rootNode = null;
MainCodeGen.output = true;
MainCodeGen.generatedCode = null;
MainCodeGen.isJavaCodeGeneration = true;
MainCodeGen.listOfExternJavaFiles = new LinkedList<String>();
CodeGen.mainCodeObject = new MainCode();
CodeGen.monitors = new HashMap<String, Code>();
CodeGen.structs = new HashMap<String, Code>();
CodeGen.usedVariableNames = new HashSet<String>();
CodeGen.mainPackageName = savedMainPackageName;
CodeGen.monitorPackageName = savedMonitorPackageName;
CodeGen.structPackageName = savedStructPackageName;
}
private final static String savedMainPackageName = CodeGen.mainPackageName;
private final static String savedMonitorPackageName = CodeGen.monitorPackageName;
private final static String savedStructPackageName = CodeGen.structPackageName;
public static Runnable getOnProgramFinished() {
return onProgramFinished;
}
/**
* This method is called when the program finishes - if it terminates
* or if it was stopped forcefully. Method is called in EDT.
* @param onProgramFinished
*/
public static void setOnProgramFinished(Runnable onProgramFinished) {
Pseuco.onProgramFinished = onProgramFinished;
}
/**
* Should be called after terminating the PseuCo program
*/
private static void programFinished(){
debugging = false;
if (onProgramFinished != null)
SwingUtilities.invokeLater(onProgramFinished);
}
private static void programStarted(){
debugging = false;
debugger.clear();
stopping = false;
if (onProgramStarted != null){
if (SwingUtilities.isEventDispatchThread()) onProgramStarted.run();
else SwingUtilities.invokeLater(onProgramStarted);
}
}
private static Runnable onProgramStarted = null;
public static Runnable getOnProgramStarted() {
return onProgramStarted;
}
public static void setOnProgramStarted(Runnable onProgramStarted) {
Pseuco.onProgramStarted = onProgramStarted;
}
private static boolean stopping = false;
public static boolean isStopping(){
return stopping;
}
private static class PseuCoThread extends Thread {
private final String[] argv;
private final boolean export;
private final boolean usedebugger;
public PseuCoThread(String[] argv) {
this.argv = argv;
this.export = argv.length==4;
setDaemon(true);
usedebugger = false;
}
public PseuCoThread(String[] argv, boolean usedebugger) {
this.argv = argv;
this.export = argv.length==4;
setDaemon(true);
this.usedebugger = usedebugger;
}
@Override
public void run() {
try {
CompilerUtils.del(includeDirFile);
if (usedebugger)
CompilerUtils.unZipIt(CompilerUtils.INCLUDE_DEBUG_FILE, includeDir);
else
CompilerUtils.unZipIt(CompilerUtils.INCLUDE_FILE, includeDir);
if (export)
CompilerUtils.unZipIt(CompilerUtils.INCLUDE_FILE, "include");
init();
if (export)
Output.con.println("Starting export...");
else
Output.con.println("Starting PseuCo Compiler...");
Thread mainThread = new Thread(runningThreads, "mainAgent"){
@Override
public void run() {
try{
PseuCoCo.main(argv);
} catch (ThreadDeath e) {
} catch (Exception e) {
CompilerUtils.handleException(e);
} finally{
if (usedebugger) debugger.threadFinished.run(this);
}
}
};
mainThread.start();
mainThread.join();
joinExternalThreadGroup(runningThreads);
} catch (ThreadDeath e) {
} catch (Exception e) {
CompilerUtils.handleException(e);
} finally {
programFinished();
CompilerUtils.del(includeDirFile);
CompilerUtils.del(new File("include"));
if (!isStopping()){
if (export) {
Output.con.println("...Exporting finished!");
try {
if (Desktop.isDesktopSupported())
Desktop.getDesktop().browse(new URI(argv[3].replace('\\','/')));
} catch (Throwable e) {
CompilerUtils.handleException(e);
}
}
else {
Output.con.println("All agents terminated!");
}
}
}
}
}
}