3 import java.util.Vector;
4 import java.util.StringTokenizer;
7 * A generic command-line interface for 6.035 compilers. This class
8 * provides command-line parsing for student projects. It recognizes
9 * the required <tt>-target</tt>, <tt>-debug</tt>, <tt>-opt</tt>, and
10 * <tt>-o</tt> switches, and generates a name for input and output
13 * @author le01, 6.035 Staff (<tt>6.035-staff@mit.edu</tt>)
14 * @version <tt>$Id: CLI.java,v 1.2 2004/04/15 05:41:46 bdemsky Exp $</tt>
18 * Target value indicating that the compiler should produce its
21 public static final int DEFAULT = 0;
24 * Target value indicating that the compiler should scan the input
27 public static final int SCAN = 1;
30 * Target value indicating that the compiler should scan and parse
31 * its input, and stop.
33 public static final int PARSE = 2;
36 * Target value indicating that the compiler should produce a
37 * high-level intermediate representation from its input, and stop.
38 * This is not one of the segment targets for Fall 2000, but you
39 * may wish to use it for your own purposes.
41 public static final int INTER = 3;
44 * Target value indicating that the compiler should produce a
45 * low-level intermediate representation from its input, and stop.
47 public static final int LOWIR = 4;
50 * Target value indicating that the compiler should produce
51 * assembly from its input.
53 public static final int ASSEMBLY = 5;
56 * Array indicating which optimizations should be performed. If
57 * a particular element is true, it indicates that the optimization
58 * named in the optnames[] parameter to parse with the same index
59 * should be performed.
61 public boolean opts[];
64 * Vector of String containing the command-line arguments which could
65 * not otherwise be parsed.
70 * Vector of String containing the optimizations which could not be
71 * parsed. It is okay to complain about anything in this list, even
72 * without the <tt>-debug</tt> flag.
74 public Vector extraopts;
77 * Name of the file to put the output in.
79 public String outfile;
82 * Name of the file to get input from. This is null if the user didn't
83 * provide a file name.
88 * The target stage. This should be one of the integer constants
89 * defined elsewhere in this package.
94 * The debug flag. This is true if <tt>-debug</tt> was passed on
95 * the command line, requesting debugging output.
100 * Native MIPS architecture is specified by "-native". The default
103 public boolean fNative;
106 * Runs IRVis on final node tree.
109 public String visClass;
110 public String visMethod;
113 * Dumps the before and after Node structure to two files that can be diffed.
115 public boolean fDiff;
116 public String diffFile;
119 * Maximum optimization iterations.
121 public int numIterations = 5;
129 * Public constructor. Sets up default values for all of the
130 * result fields. Specifically, sets the input and output files
131 * to null, the target to DEFAULT, and the extras and extraopts
132 * arrays to new empty Vectors.
138 extras = new Vector();
139 extraopts = new Vector();
150 * Parse the command-line arguments. Sets all of the result fields
153 * <li><TT>-target <I>target</I></TT> sets the CLI.target field based
154 * on the <I>target</I> specified. </li>
155 * <li><TT>scan</TT> or <TT>scanner</TT> specifies CLI.SCAN</li>
156 * <li><TT>parse</TT> specifies CLI.PARSE</li>
157 * <li><TT>inter</TT> specifies CLI.INTER</li>
158 * <li><TT>lowir</TT> specifies CLI.LOWIR</li>
159 * <TT>assembly</TT> or <TT>codegen</TT> specifies CLI.ASSEMBLY</li>
161 * The boolean array opts[] indicates which, if any, of the
162 * optimizations in optnames[] should be performed; these arrays
163 * are in the same order.
165 * @param args Array of arguments passed in to the program's Main
167 * @param optnames Ordered array of recognized optimization names. */
168 public void parse(String args[]) {
170 String optnames[] = {};
174 opts = new boolean[optnames.length];
176 for (int i = 0; i < args.length; i++) {
177 if (args[i].equals("-debug")) {
180 } else if (args[i].equals("-native")) {
183 } else if (args[i].equals("-checkonly")) {
184 Compiler.REPAIR=false;
185 } else if (args[i].equals("-vis")) {
188 } else if (args[i].equals("-diff")) {
191 } else if (args[i].equals("-i")) {
193 } else if (args[i].equals("-verbose") || args[i].equals("-v")) {
196 } else if (args[i].equals("-opt"))
198 else if (args[i].equals("-o"))
200 else if (args[i].equals("-target"))
202 else if (context == 1) {
204 for (int j = 0; j < optnames.length; j++) {
205 if (args[i].equals("all") ||
206 (args[i].equals(optnames[j]))) {
210 if (args[i].equals("-" + optnames[j])) {
216 extraopts.addElement(args[i]);
218 else if (context == 2) {
222 else if (context == 3) {
223 // Process case insensitive.
224 String argSansCase = args[i].toLowerCase();
225 // accept "scan" and "scanner" due to handout mistake
226 if (argSansCase.equals("scan") ||
227 argSansCase.equals("scanner"))
229 else if (argSansCase.equals("parse"))
231 else if (argSansCase.equals("inter"))
233 else if (argSansCase.equals("lowir"))
235 else if (argSansCase.equals("assembly") ||
236 argSansCase.equals("codegen"))
239 target = DEFAULT; // Anything else is just default
241 } else if (context == 4) { // -vis
242 StringTokenizer st = new StringTokenizer(args[i], ".");
243 visClass = st.nextToken();
244 visMethod = st.nextToken();
246 } else if (context == 5) { // -diff
247 diffFile = args[i]; // argument following is filename
249 } else if (context == 6) { // -i <iterations>
250 numIterations = Integer.parseInt(args[i]);
254 for (int j = 0; j < optnames.length; j++) {
255 if (args[i].equals("-" + optnames[j])) {
261 extras.addElement(args[i]);
266 // grab infile and lose extra args
268 while (infile == null && i < extras.size()) {
269 String fn = (String) extras.elementAt(i);
271 if (fn.charAt(0) != '-')
274 extras.removeElementAt(i);
279 // create outfile name
302 if (outfile == null && infile != null) {
303 int dot = infile.lastIndexOf('.');
304 int slash = infile.lastIndexOf('/');
305 // Last dot comes after last slash means that the file
306 // has an extention. Note that the base case where dot
307 // or slash are -1 also work.
309 outfile = infile + ext;
311 outfile = infile.substring(0, dot) + ext;