• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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