1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 package Mini; 19 import java.io.File; 20 import java.io.FileOutputStream; 21 import java.io.PrintWriter; 22 import java.util.Vector; 23 24 import org.apache.bcel.classfile.JavaClass; 25 import org.apache.bcel.generic.ClassGen; 26 import org.apache.bcel.generic.ConstantPoolGen; 27 28 public class MiniC implements org.apache.bcel.Constants { 29 private static Vector<String> errors = null; 30 private static Vector<String> warnings = null; 31 private static String file = null; 32 private static int pass = 0; 33 main(String[] argv)34 public static void main(String[] argv) { 35 String[] file_name = new String[argv.length]; 36 int files=0; 37 MiniParser parser=null; 38 String base_name=null; 39 boolean byte_code=true; 40 41 try { 42 /* Parse command line arguments. 43 */ 44 for(int i=0; i < argv.length; i++) { 45 if(argv[i].charAt(0) == '-') { // command line switch 46 if(argv[i].equals("-java")) { 47 byte_code=false; 48 } else if(argv[i].equals("-bytecode")) { 49 byte_code=true; 50 } else { 51 throw new Exception("Unknown option: " + argv[i]); 52 } 53 } 54 else { // add file name to list 55 file_name[files++] = argv[i]; 56 } 57 } 58 59 if(files == 0) { 60 System.err.println("Nothing to compile."); 61 } 62 63 for(int j=0; j < files; j++) { 64 errors = new Vector<String>(); 65 warnings = new Vector<String>(); 66 pass = 0; 67 68 if(j == 0) { 69 parser = new MiniParser(new java.io.FileInputStream(file_name[0])); 70 } else { 71 MiniParser.ReInit(new java.io.FileInputStream(file_name[j])); 72 } 73 74 int index = file_name[j].lastIndexOf('.'); 75 if(index > 0) { 76 base_name = file_name[j].substring(0, index); 77 } else { 78 base_name = file_name[j]; 79 } 80 81 if((index = base_name.lastIndexOf(File.separatorChar)) > 0) { 82 base_name = base_name.substring(index + 1); 83 } 84 85 file = file_name[j]; 86 87 System.out.println("Parsing ..."); 88 MiniParser.Program(); 89 ASTProgram program = (ASTProgram)MiniParser.jjtree.rootNode(); 90 91 System.out.println("Pass 1: Optimizing parse tree ..."); 92 pass = 1; 93 program = program.traverse(); 94 // program.dump(">"); 95 96 if(errors.size() == 0) { 97 System.out.println("Pass 2: Type checking (I) ..."); 98 program.eval(pass=2); 99 } 100 101 if(errors.size() == 0) { 102 System.out.println("Pass 3: Type checking (II) ..."); 103 program.eval(pass=3); 104 } 105 106 for(int i=0; i < errors.size(); i++) { 107 System.out.println(errors.elementAt(i)); 108 } 109 110 for(int i=0; i < warnings.size(); i++) { 111 System.out.println(warnings.elementAt(i)); 112 } 113 114 if(errors.size() == 0) { 115 if(byte_code) { 116 System.out.println("Pass 5: Generating byte code ..."); 117 ClassGen class_gen = new ClassGen(base_name, "java.lang.Object", 118 file_name[j], 119 ACC_PUBLIC | ACC_FINAL | 120 ACC_SUPER, null); 121 ConstantPoolGen cp = class_gen.getConstantPool(); 122 123 program.byte_code(class_gen, cp); 124 JavaClass clazz = class_gen.getJavaClass(); 125 clazz.dump(base_name + ".class"); 126 } 127 else { 128 System.out.println("Pass 5: Generating Java code ..."); 129 PrintWriter out = new PrintWriter(new FileOutputStream(base_name + ".java")); 130 program.code(out, base_name); 131 out.close(); 132 133 System.out.println("Pass 6: Compiling Java code ..."); 134 135 String[] args = { "javac", base_name + ".java" }; 136 //sun.tools.javac.Main compiler = new sun.tools.javac.Main(System.err, "javac"); 137 try { 138 Process p = Runtime.getRuntime().exec(args); 139 p.waitFor(); 140 } catch(Exception e) {System.out.println(e); } 141 142 //compiler.compile(args); 143 } 144 } 145 146 if((errors.size() > 0) || (warnings.size() > 0)) { 147 System.out.println(errors.size() + " errors and " + warnings.size() + 148 " warnings."); 149 } 150 } 151 } catch(Exception e) { e.printStackTrace(); } 152 } 153 154 addError(int line, int column, String err)155 final static void addError(int line, int column, String err) { 156 if(pass != 2) { 157 errors.addElement(file + ":" + fillup(line, 3) + "," + fillup(column, 2) + 158 ": " + err); 159 } 160 } 161 addWarning(int line, int column, String err)162 final static void addWarning(int line, int column, String err) { 163 warnings.addElement("Warning: " + file + ":" + fillup(line, 3) + "," + 164 fillup(column, 3) + ": " + err); 165 } 166 fillup(int n, int len)167 final static String fillup(int n, int len) { 168 String str = Integer.toString(n); 169 int diff = len - str.length(); 170 171 if(diff > 0) { 172 char[] chs = new char[diff]; 173 174 for(int i=0; i < diff; i++) { 175 chs[i] = ' '; 176 } 177 178 return new String(chs) + str; 179 } else { 180 return str; 181 } 182 } 183 addWarning(String err)184 final static void addWarning(String err) { warnings.addElement(err); } 185 } 186