| 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); } |
| } |