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