blob: 6052aca77f5ae16bb33610222303aa12d001440a [file] [log] [blame]
package Mini;
import java.util.Vector;
import java.io.*;
import org.apache.bcel.classfile.*;
import org.apache.bcel.generic.*;
public class MiniC implements org.apache.bcel.Constants {
private static Vector errors = null;
private static Vector warnings = null;
private static String file = null;
private static int pass = 0;
public static void main(String[] argv) {
String[] file_name = new String[argv.length];
int files=0;
MiniParser parser=null;
String base_name=null;
boolean byte_code=true;
try {
/* Parse command line arguments.
*/
for(int i=0; i < argv.length; i++) {
if(argv[i].charAt(0) == '-') { // command line switch
if(argv[i].equals("-java"))
byte_code=false;
else if(argv[i].equals("-bytecode"))
byte_code=true;
else
throw new Exception("Unknown option: " + argv[i]);
}
else { // add file name to list
file_name[files++] = argv[i];
}
}
if(files == 0)
System.err.println("Nothing to compile.");
for(int j=0; j < files; j++) {
errors = new Vector();
warnings = new Vector();
pass = 0;
if(j == 0)
parser = new MiniParser(new java.io.FileInputStream(file_name[0]));
else
parser.ReInit(new java.io.FileInputStream(file_name[j]));
int index = file_name[j].lastIndexOf('.');
if(index > 0)
base_name = file_name[j].substring(0, index);
else
base_name = file_name[j];
if((index = base_name.lastIndexOf(File.separatorChar)) > 0)
base_name = base_name.substring(index + 1);
file = file_name[j];
System.out.println("Parsing ...");
parser.Program();
ASTProgram program = (ASTProgram)parser.jjtree.rootNode();
System.out.println("Pass 1: Optimizing parse tree ...");
pass = 1;
program = program.traverse();
// program.dump(">");
if(errors.size() == 0) {
System.out.println("Pass 2: Type checking (I) ...");
program.eval(pass=2);
}
if(errors.size() == 0) {
System.out.println("Pass 3: Type checking (II) ...");
program.eval(pass=3);
}
for(int i=0; i < errors.size(); i++)
System.out.println(errors.elementAt(i));
for(int i=0; i < warnings.size(); i++)
System.out.println(warnings.elementAt(i));
if(errors.size() == 0) {
if(byte_code) {
System.out.println("Pass 5: Generating byte code ...");
ClassGen class_gen = new ClassGen(base_name, "java.lang.Object",
file_name[j],
ACC_PUBLIC | ACC_FINAL |
ACC_SUPER, null);
ConstantPoolGen cp = class_gen.getConstantPool();
program.byte_code(class_gen, cp);
JavaClass clazz = class_gen.getJavaClass();
clazz.dump(base_name + ".class");
}
else {
System.out.println("Pass 5: Generating Java code ...");
PrintWriter out = new PrintWriter(new FileOutputStream(base_name + ".java"));
program.code(out, base_name);
out.close();
System.out.println("Pass 6: Compiling Java code ...");
String[] args = { "javac", base_name + ".java" };
//sun.tools.javac.Main compiler = new sun.tools.javac.Main(System.err, "javac");
try {
Process p = Runtime.getRuntime().exec(args);
p.waitFor();
} catch(Exception e) {System.out.println(e); }
//compiler.compile(args);
}
}
if((errors.size() > 0) || (warnings.size() > 0))
System.out.println(errors.size() + " errors and " + warnings.size() +
" warnings.");
}
} catch(Exception e) { e.printStackTrace(); }
}
final static void addError(int line, int column, String err) {
if(pass != 2)
errors.addElement(file + ":" + fillup(line, 3) + "," + fillup(column, 2) +
": " + err);
}
final static void addWarning(int line, int column, String err) {
warnings.addElement("Warning: " + file + ":" + fillup(line, 3) + "," +
fillup(column, 3) + ": " + err);
}
final static String fillup(int n, int len) {
String str = Integer.toString(n);
int diff = len - str.length();
if(diff > 0) {
char[] chs = new char[diff];
for(int i=0; i < diff; i++)
chs[i] = ' ';
return new String(chs) + str;
}
else
return str;
}
final static void addWarning(String err) { warnings.addElement(err); }
}