/**
* Copyright (c) 2009-2011, The HATS Consortium. All rights reserved.
* This file is licensed under the terms of the Modified BSD License.
*/
package abs.backend.maude;
import java.io.File;
import java.io.InputStream;
import java.io.PrintStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.ArrayList;
import java.util.List;
import com.google.common.io.ByteStreams;
import abs.common.NotImplementedYetException;
import abs.frontend.ast.Model;
import abs.frontend.parser.Main;
public class MaudeCompiler extends Main {
public enum SIMULATOR {
RL(SIMULATOR_RL), EQ_TIMED(SIMULATOR_EQ_TIMED);
private final String module;
SIMULATOR(String arg) {
this.module = arg;
}
public String getModule() {
return module;
}
};
private static final String SIMULATOR_RL = "ABS-SIMULATOR-RL";
private static final String SIMULATOR_EQ_TIMED = "ABS-SIMULATOR-EQ-TIMED";
private static final String RUNTIME_INTERPRETER_PATH
= "abs/backend/maude/abs-interpreter.maude";
SIMULATOR module = SIMULATOR.RL;
private File outputfile;
private String mainBlock;
private int clocklimit = 100;
private int defaultResources = 0;
private static boolean debug = false;
public static void main(final String... args) {
/* Maude has build-in AwaitAsyncCall support */
Model.doAACrewrite = false;
try {
new MaudeCompiler().compile(args);
} catch (NotImplementedYetException e) {
System.err.println(e.getMessage());
System.exit(0);
} catch (Exception e) {
System.err.println("An error occurred during compilation:\n" + e.getMessage());
if (debug) {
e.printStackTrace();
}
System.exit(1);
}
}
@Override
public List<String> parseArgs(String[] args) {
List<String> restArgs = super.parseArgs(args);
List<String> remainingArgs = new ArrayList<String>();
for (int i = 0; i < restArgs.size(); i++) {
String arg = restArgs.get(i);
if (arg.equals("-timed")) {
module = SIMULATOR.EQ_TIMED;
} else if (arg.equals("-o")) {
i++;
if (i == restArgs.size()) {
System.err.println("Please provide an output file");
System.exit(1);
} else {
outputfile = new File(restArgs.get(i));
}
} else if (arg.startsWith("-main=")) {
mainBlock = arg.split("=")[1];
} else if (arg.startsWith("-limit=")) {
// -limit implies -timed
module = SIMULATOR.EQ_TIMED;
clocklimit = Integer.parseInt(arg.split("=")[1]);
} else if (arg.startsWith("-defaultcost=")) {
defaultResources = Integer.parseInt(arg.split("=")[1]);
} else if (arg.startsWith("-debug")) {
debug = true;
} else if (arg.equals("-maude")) {
// nothing to do
} else {
remainingArgs.add(arg);
}
}
return remainingArgs;
}
/**
* @param args
* @throws Exception
*/
public void compile(String[] args) throws Exception {
if (verbose) System.out.println("Generating Erlang code...");
final Model model = parse(args);
if (model.hasParserErrors()
|| model.hasErrors()
|| model.hasTypeErrors())
printParserErrorAndExit();
PrintStream stream = System.out;
if (outputfile != null) {
stream = new PrintStream(outputfile);
}
InputStream is = ClassLoader.getSystemResourceAsStream(RUNTIME_INTERPRETER_PATH);
if (is == null)
throw new RuntimeException("Could not locate abs-interpreter.maude");
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
stream.println("*** Generated " + dateFormat.format(new Date()));
ByteStreams.copy(is, stream);
model.generateMaude(stream, module, mainBlock, clocklimit, defaultResources);
if (verbose) System.out.println("Finished. Start `maude " + outputfile.toString() + "' to run the model.");
}
protected void printUsage() {
super.printUsage();
System.out.println("Maude Backend:\n"
+ " -main=<ModuleName> \n"
+ " sets the main block to execute\n"
+ " -o <file> write output to <file> instead of standard output\n"
+ " -timed generate code for timed interpreter\n"
+ " -limit=n set clock limit for timed interpreter to n (default 100)\n"
+ " (implies -timed)\n"
+ " -defaultcost=n set default statement execution cost (default 0)\n"
+ " -debug print stacktrace on exception\n"
);
}
}
// Local Variables:
// tab-width: 4
// End: