gitweb on Svarog

projekti pod git sistemom za održavanje verzija -- projects under the git version control system
minor: ant build - antcontrib definition is simplified a bit
[mjc2wsl.git] / src / mjc2wsl.java
1 import java.io.*;
2 import java.util.*;
4 /**
5 * This program converts file from compiled MicroJava bytecode to WSL language
6 * which is a part of the FermaT Transformation system. MicroJava is a subset
7 * used in Compiler Construction courses by Hanspeter Moessenboeck, not
8 * "Java ME".
9 *
10 * @author Doni Pracner, http://perun.dmi.rs/pracner http://quemaster.com
11 */
12 public class mjc2wsl{
13 public static String versionN = "0.1.2";
15 /** Constant used for marking a regular comment from the original file */
16 public static final char C_REG = ' ';
17 /**
18 * Constant used for marking when original code is inserted in the file,
19 * next to the translations
20 */
21 public static final char C_OC = '#';
22 /** Constant used for marking special messages from the translator */
23 public static final char C_SPEC = '&';
24 /** Constant used for marking error messages from the translator */
25 public static final char C_ERR = '!';
27 /** instruction code in MicroJava bytecode. */
28 public static final int
29 load = 1,
30 load_0 = 2,
31 load_1 = 3,
32 load_2 = 4,
33 load_3 = 5,
34 store = 6,
35 store_0 = 7,
36 store_1 = 8,
37 store_2 = 9,
38 store_3 = 10,
39 getstatic = 11,
40 putstatic = 12,
41 getfield = 13,
42 putfield = 14,
43 const_0 = 15,
44 const_1 = 16,
45 const_2 = 17,
46 const_3 = 18,
47 const_4 = 19,
48 const_5 = 20,
49 const_m1 = 21,
50 const_ = 22,
51 add = 23,
52 sub = 24,
53 mul = 25,
54 div = 26,
55 rem = 27,
56 neg = 28,
57 shl = 29,
58 shr = 30,
59 inc = 31,
60 new_ = 32,
61 newarray = 33,
62 aload = 34,
63 astore = 35,
64 baload = 36,
65 bastore = 37,
66 arraylength = 38,
67 pop = 39,
68 dup = 40,
69 dup2 = 41,
70 jmp = 42,
71 jeq = 43,
72 jne = 44,
73 jlt = 45,
74 jle = 46,
75 jgt = 47,
76 jge = 48,
77 call = 49,
78 return_ = 50,
79 enter = 51,
80 exit = 52,
81 read = 53,
82 print = 54,
83 bread = 55,
84 bprint = 56,
85 trap = 57;
87 public String getStandardStart(){
88 StringBuilder ret = new StringBuilder(
89 "C:\" This file automatically converted from microjava bytecode\";\n"
90 +"C:\" with mjc2wsl v "+versionN+"\";\n");
92 ret.append("VAR < tempa := 0, tempb := 0, tempres :=0,\n");
93 for (int i = 0; i <= 3; i++)
94 ret.append("loc" + i + " := 0, ");
95 ret.append("\n estack := < >, t_e_m_p := 0 > :");
97 return ret.toString();
98 }
100 public String getStandardEnd(){
101 return "SKIP\nENDVAR";
104 private boolean originalInComments = false;
106 private InputStream mainIn;
107 private PrintWriter out = null;
108 private int counter = -1;
110 private void pr(int i){
111 out.print(i);
114 private void pr(char i){
115 out.print(i);
118 private void pr(String i){
119 out.print(i);
122 private void prl(String i){
123 out.println(i);
126 private int get() {
127 int res = -1;
128 try {
129 res = mainIn.read();
130 if (res >= 0)
131 res = res << 24 >>> 24;
132 } catch (IOException ex) {
133 ex.printStackTrace();
135 counter++;
136 return res;
139 private int get2() {
140 return (get() * 256 + get()) << 16 >> 16;
143 private int get4() {
144 return (get2() << 16) + (get2() << 16 >>> 16);
147 private String loc(int i){
148 return "loc" + i;
151 /**
152 * Creates a WSL comment with care to quote chars.
153 */
154 public static String createComment(String str){
155 return createComment(str, C_REG);
158 /**
159 * Creates a WSL comment with care to quote chars, of the
160 * given type. Types are given as char constants. They can be
161 * default comments, comments that contain the original code
162 * in them, or additional comments regarding the translation
163 * process.
164 */
165 public static String createComment(String str, char type) {
166 return "C:\"" + type + str.replace("\"", "''") + "\";";
169 private String cmdToEStack(int i) {
170 return "estack := <" + i + " > ++ estack;";
173 private String cmdToEStack(String i) {
174 return "estack := <" + i + " > ++ estack;";
177 private String cmdFromEStack(String st) {
178 return st + " := HEAD(estack); estack := TAIL(estack);";
181 private String getTopTwo(){
182 return cmdFromEStack("tempa") + "\n" + cmdFromEStack("tempb");
185 private String getTop() {
186 return cmdFromEStack("tempa");
189 public void convertStream(InputStream ins){
190 mainIn = ins;
191 //skip start TODO make better
192 for (int i = 0; i < 14; i++)
193 get();
195 prl(getStandardStart());
196 prl("SKIP;\n ACTIONS A_S_start:\n A_S_start == CALL a14 END");
197 int op = get();
198 while (op >= 0) {
199 if (originalInComments)
200 prl(createComment("" + op, C_OC));
201 prl("a" + counter + " == ");
202 switch (op) {
203 case load: {
204 prl(cmdToEStack(loc(get())));
205 break;
207 case load_0:
208 case load_1:
209 case load_2:
210 case load_3: {
211 prl(cmdToEStack(loc(op - load_0)));
212 break;
214 case store: {
215 prl(cmdFromEStack(loc(get())));
216 break;
218 case store_0:
219 case store_1:
220 case store_2:
221 case store_3: {
222 prl(cmdFromEStack(loc(op - store_0)));
223 break;
225 case const_: {
226 prl(cmdToEStack(get4()));
227 break;
230 case const_0:
231 case const_1:
232 case const_2:
233 case const_3:
234 case const_4:
235 case const_5: {
236 prl(cmdToEStack(op - const_0));
237 break;
240 case jmp: {
241 prl("CALL a" + (counter + get2()) + ";");
242 break;
245 case jeq:
246 case jne:
247 case jlt:
248 case jle:
249 case jgt:
250 case jge: {
251 prl(getTopTwo());
252 prl("IF tempb >= tempa THEN CALL a" + (counter + get2())
253 + " FI;");
254 break;
257 case add: {
258 prl(getTopTwo());
259 prl("tempres := tempb + tempa;");
260 prl(cmdToEStack("tempres"));
261 break;
263 case div: {
264 prl(getTopTwo());
265 prl("tempres := tempb / tempa;");
266 prl(cmdToEStack("tempres"));
267 break;
270 case enter: {
271 prl(createComment("enter not fully procesed yet"));
272 get();
273 get();
274 break;
276 case return_: {
277 prl(createComment("return not fully procesed yet"));
278 break;
280 case exit: {
281 prl(createComment("exit not fully procesed yet"));
282 break;
285 // the prints
286 case bprint: {
287 prl(getTopTwo());
288 prl("PRINT(tempb);");
289 break;
291 case print: {
292 // TODO need to make it a char
293 prl(getTopTwo());
294 prl("PRINT(tempb);");
295 break;
297 default:
298 prl(createComment("unknown op error: " + op, C_ERR));
299 break;
302 op = get();
303 if (op >= 0)
304 prl("CALL a" + counter + " END");
306 prl("CALL Z;\nSKIP END\nENDACTIONS;\n");
307 prl(getStandardEnd());
311 public void convertFile(File f) {
312 try {
313 convertStream(new FileInputStream(f));
314 } catch (Exception ex) {
315 ex.printStackTrace();
319 public void printHelp() {
320 System.out.println("MicroJava bytecode to WSL converter. v " + versionN
321 + ", by Doni Pracner");
322 System.out.println("usage:\n\t {options} mjc2wsl filename [outfile]");
323 System.out.println("options:\n\t--screen print output to screen");
324 System.out.println("\t-o --oc include original code in comments");
327 public String makeDefaultOutName(String inname){
328 String rez = inname;
329 if (inname.endsWith(".obj"))
330 rez = rez.substring(0, rez.length() - 4);
331 return rez + ".wsl";
334 public void run(String[] args) {
335 if (args.length == 0) {
336 printHelp();
337 } else {
338 int i = 0;
339 while (i < args.length && args[i].charAt(0) == '-') {
340 if (args[i].compareTo("-h") == 0) {
341 printHelp();
342 return;
343 } else if (args[i].compareTo("-o") == 0
344 || args[i].startsWith("--oc")) {
345 if (args[i].length() == 2)
346 originalInComments = true;
347 else if (args[i].length() == 5)
348 originalInComments = args[i].charAt(4) == '+';
349 else
350 originalInComments = true;
351 } else if (args[i].startsWith("--screen")) {
352 out = new PrintWriter(System.out);
354 i++;
357 if (i >= args.length) {
358 System.out.println("no filename supplied");
359 System.exit(2);
361 File f = new File(args[i]);
363 if (i + 1 < args.length) {
364 try {
365 out = new PrintWriter(args[i + 1]);
366 } catch (Exception e) {
367 System.err.println("error in opening out file:");
368 e.printStackTrace();
371 if (out == null) {
372 // if not set to screen, or a file, make a default filename
373 try {
374 out = new PrintWriter(makeDefaultOutName(args[i]));
375 } catch (Exception e) {
376 System.err.println("error in opening out file:");
377 e.printStackTrace();
380 if (f.exists()) {
381 Calendar now = Calendar.getInstance();
382 convertFile(f);
383 long mili = Calendar.getInstance().getTimeInMillis()
384 - now.getTimeInMillis();
385 System.out.println("conversion time:" + mili + " ms");
386 out.close();
387 } else
388 System.out.println("file does not exist");
392 public static void main(String[] args) {
393 new mjc2wsl().run(args);
Svarog.pmf.uns.ac.rs/gitweb maintanance Doni Pracner