| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| package Mini; |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.PrintWriter; |
| import java.util.Vector; |
| |
| import org.apache.bcel.classfile.JavaClass; |
| import org.apache.bcel.generic.ClassGen; |
| import org.apache.bcel.generic.ConstantPoolGen; |
| |
| public class MiniC implements org.apache.bcel.Constants { |
| private static Vector<String> errors = null; |
| private static Vector<String> warnings = null; |
| private static String file = null; |
| private static int pass = 0; |
| |
| public static void main(final String[] argv) { |
| final 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 (String element : argv) { |
| if(element.charAt(0) == '-') { // command line switch |
| if(element.equals("-java")) { |
| byte_code=false; |
| } else if(element.equals("-bytecode")) { |
| byte_code=true; |
| } else { |
| throw new Exception("Unknown option: " + element); |
| } |
| } |
| else { // add file name to list |
| file_name[files++] = element; |
| } |
| } |
| |
| 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 { |
| MiniParser.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 ..."); |
| MiniParser.Program(); |
| ASTProgram program = (ASTProgram)MiniParser.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 ..."); |
| final ClassGen class_gen = new ClassGen(base_name, "java.lang.Object", |
| file_name[j], |
| ACC_PUBLIC | ACC_FINAL | |
| ACC_SUPER, null); |
| final ConstantPoolGen cp = class_gen.getConstantPool(); |
| |
| program.byte_code(class_gen, cp); |
| final JavaClass clazz = class_gen.getJavaClass(); |
| clazz.dump(base_name + ".class"); |
| } |
| else { |
| System.out.println("Pass 5: Generating Java code ..."); |
| final PrintWriter out = new PrintWriter(new FileOutputStream(base_name + ".java")); |
| program.code(out, base_name); |
| out.close(); |
| |
| System.out.println("Pass 6: Compiling Java code ..."); |
| |
| final String[] args = { "javac", base_name + ".java" }; |
| //sun.tools.javac.Main compiler = new sun.tools.javac.Main(System.err, "javac"); |
| try { |
| final Process p = Runtime.getRuntime().exec(args); |
| p.waitFor(); |
| } catch(final 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(final Exception e) { e.printStackTrace(); } |
| } |
| |
| |
| final static void addError(final int line, final int column, final String err) { |
| if(pass != 2) { |
| errors.addElement(file + ":" + fillup(line, 3) + "," + fillup(column, 2) + |
| ": " + err); |
| } |
| } |
| |
| final static void addWarning(final int line, final int column, final String err) { |
| warnings.addElement("Warning: " + file + ":" + fillup(line, 3) + "," + |
| fillup(column, 3) + ": " + err); |
| } |
| |
| final static String fillup(final int n, final int len) { |
| final String str = Integer.toString(n); |
| final int diff = len - str.length(); |
| |
| if(diff > 0) { |
| final 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(final String err) { warnings.addElement(err); } |
| } |