gitweb on Svarog

projekti pod git sistemom za održavanje verzija -- projects under the git version control system
minor: a lot of (auto)formating
[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 //regular comments from the original file
16 //OC when original code is inserted in the file, next to the translations
17 //SPEC special messages from the translator
18 //ERR error messages from the translator
19 public static final char C_REG = ' ', C_OC = '#', C_SPEC = '&', C_ERR = '!';
21 /** instruction code */
22 public static final int
23 load = 1,
24 load_0 = 2,
25 load_1 = 3,
26 load_2 = 4,
27 load_3 = 5,
28 store = 6,
29 store_0 = 7,
30 store_1 = 8,
31 store_2 = 9,
32 store_3 = 10,
33 getstatic = 11,
34 putstatic = 12,
35 getfield = 13,
36 putfield = 14,
37 const_0 = 15,
38 const_1 = 16,
39 const_2 = 17,
40 const_3 = 18,
41 const_4 = 19,
42 const_5 = 20,
43 const_m1 = 21,
44 const_ = 22,
45 add = 23,
46 sub = 24,
47 mul = 25,
48 div = 26,
49 rem = 27,
50 neg = 28,
51 shl = 29,
52 shr = 30,
53 inc = 31,
54 new_ = 32,
55 newarray = 33,
56 aload = 34,
57 astore = 35,
58 baload = 36,
59 bastore = 37,
60 arraylength = 38,
61 pop = 39,
62 dup = 40,
63 dup2 = 41,
64 jmp = 42,
65 jeq = 43,
66 jne = 44,
67 jlt = 45,
68 jle = 46,
69 jgt = 47,
70 jge = 48,
71 call = 49,
72 return_ = 50,
73 enter = 51,
74 exit = 52,
75 read = 53,
76 print = 54,
77 bread = 55,
78 bprint = 56,
79 trap = 57;
81 public String getStandardStart(){
82 StringBuilder ret = new StringBuilder(
83 "C:\" This file automatically converted from microjava bytecode\";\n"
84 +"C:\" with mjc2wsl v "+versionN+"\";\n");
86 ret.append("VAR < tempa := 0, tempb := 0, tempres :=0,\n");
87 for (int i = 0; i <= 3; i++)
88 ret.append("loc" + i + " := 0, ");
89 ret.append("\n estack := < >, t_e_m_p := 0 > :");
91 return ret.toString();
92 }
94 public String getStandardEnd(){
95 return "SKIP\nENDVAR";
96 }
98 private boolean originalInComments = false;
100 private InputStream mainIn;
101 private PrintWriter out = null;
102 private int counter = -1;
104 private void pr(int i){
105 out.print(i);
108 private void pr(char i){
109 out.print(i);
112 private void pr(String i){
113 out.print(i);
116 private void prl(String i){
117 out.println(i);
120 private int get() {
121 int res = -1;
122 try {
123 res = mainIn.read();
124 if (res >= 0)
125 res = res << 24 >>> 24;
126 } catch (IOException ex) {
127 ex.printStackTrace();
129 counter++;
130 return res;
133 private int get2() {
134 return (get() * 256 + get()) << 16 >> 16;
137 private int get4() {
138 return (get2() << 16) + (get2() << 16 >>> 16);
141 private String loc(int i){
142 return "loc" + i;
145 /**
146 * Creates a WSL comment with care to quote chars.
147 */
148 public static String createComment(String str){
149 return createComment(str, C_REG);
152 /**
153 * Creates a WSL comment with care to quote chars, of the
154 * given type. Types are given as char constants. They can be
155 * default comments, comments that contain the original code
156 * in them, or additional comments regarding the translation
157 * process.
158 */
159 public static String createComment(String str, char type) {
160 return "C:\"" + type + str.replace("\"", "''") + "\";";
163 private String cmdToEStack(int i) {
164 return "estack := <" + i + " > ++ estack;";
167 private String cmdToEStack(String i) {
168 return "estack := <" + i + " > ++ estack;";
171 private String cmdFromEStack(String st) {
172 return st + " := HEAD(estack); estack := TAIL(estack);";
175 private String getTopTwo(){
176 return cmdFromEStack("tempa") + "\n" + cmdFromEStack("tempb");
179 private String getTop() {
180 return cmdFromEStack("tempa");
183 public void convertStream(InputStream ins){
184 mainIn = ins;
185 //skip start TODO make better
186 for (int i = 0; i < 14; i++)
187 get();
189 prl(getStandardStart());
190 prl("SKIP;\n ACTIONS A_S_start:\n A_S_start == CALL a14 END");
191 int op = get();
192 while (op >= 0) {
193 if (originalInComments)
194 prl(createComment("" + op, C_OC));
195 prl("a" + counter + " == ");
196 switch (op) {
197 case load: {
198 prl(cmdToEStack(loc(get())));
199 break;
201 case load_0:
202 case load_1:
203 case load_2:
204 case load_3: {
205 prl(cmdToEStack(loc(op - load_0)));
206 break;
208 case store: {
209 prl(cmdFromEStack(loc(get())));
210 break;
212 case store_0:
213 case store_1:
214 case store_2:
215 case store_3: {
216 prl(cmdFromEStack(loc(op - store_0)));
217 break;
219 case const_: {
220 prl(cmdToEStack(get4()));
221 break;
224 case const_0:
225 case const_1:
226 case const_2:
227 case const_3:
228 case const_4:
229 case const_5: {
230 prl(cmdToEStack(op - const_0));
231 break;
234 case jmp: {
235 prl("CALL a" + (counter + get2()) + ";");
236 break;
239 case jeq:
240 case jne:
241 case jlt:
242 case jle:
243 case jgt:
244 case jge: {
245 prl(getTopTwo());
246 prl("IF tempb >= tempa THEN CALL a" + (counter + get2())
247 + " FI;");
248 break;
251 case add: {
252 prl(getTopTwo());
253 prl("tempres := tempb + tempa;");
254 prl(cmdToEStack("tempres"));
255 break;
257 case div: {
258 prl(getTopTwo());
259 prl("tempres := tempb / tempa;");
260 prl(cmdToEStack("tempres"));
261 break;
264 case enter: {
265 prl(createComment("enter not fully procesed yet"));
266 get();
267 get();
268 break;
270 case return_: {
271 prl(createComment("return not fully procesed yet"));
272 break;
274 case exit: {
275 prl(createComment("exit not fully procesed yet"));
276 break;
279 // the prints
280 case bprint: {
281 prl(getTopTwo());
282 prl("PRINT(tempb);");
283 break;
285 case print: {
286 // TODO need to make it a char
287 prl(getTopTwo());
288 prl("PRINT(tempb);");
289 break;
291 default:
292 prl(createComment("unknown op error: " + op, C_ERR));
293 break;
296 op = get();
297 if (op >= 0)
298 prl("CALL a" + counter + " END");
300 prl("CALL Z;\nSKIP END\nENDACTIONS;\n");
301 prl(getStandardEnd());
305 public void convertFile(File f) {
306 try {
307 convertStream(new FileInputStream(f));
308 } catch (Exception ex) {
309 ex.printStackTrace();
313 public void printHelp() {
314 System.out.println("MicroJava bytecode to WSL converter. v " + versionN
315 + ", by Doni Pracner");
316 System.out.println("usage:\n\t {options} mjc2wsl filename [outfile]");
317 System.out.println("options:\n\t--screen print output to screen");
318 System.out.println("\t-o --oc include original code in comments");
321 public String makeDefaultOutName(String inname){
322 String rez = inname;
323 if (inname.endsWith(".obj"))
324 rez = rez.substring(0, rez.length() - 4);
325 return rez + ".wsl";
328 public void run(String[] args) {
329 if (args.length == 0) {
330 printHelp();
331 } else {
332 int i = 0;
333 while (i < args.length && args[i].charAt(0) == '-') {
334 if (args[i].compareTo("-h") == 0) {
335 printHelp();
336 return;
337 } else if (args[i].compareTo("-o") == 0
338 || args[i].startsWith("--oc")) {
339 if (args[i].length() == 2)
340 originalInComments = true;
341 else if (args[i].length() == 5)
342 originalInComments = args[i].charAt(4) == '+';
343 else
344 originalInComments = true;
345 } else if (args[i].startsWith("--screen")) {
346 out = new PrintWriter(System.out);
348 i++;
351 if (i >= args.length) {
352 System.out.println("no filename supplied");
353 System.exit(2);
355 File f = new File(args[i]);
357 if (i + 1 < args.length) {
358 try {
359 out = new PrintWriter(args[i + 1]);
360 } catch (Exception e) {
361 System.err.println("error in opening out file:");
362 e.printStackTrace();
365 if (out == null) {
366 // if not set to screen, or a file, make a default filename
367 try {
368 out = new PrintWriter(makeDefaultOutName(args[i]));
369 } catch (Exception e) {
370 System.err.println("error in opening out file:");
371 e.printStackTrace();
374 if (f.exists()) {
375 Calendar now = Calendar.getInstance();
376 convertFile(f);
377 long mili = Calendar.getInstance().getTimeInMillis()
378 - now.getTimeInMillis();
379 System.out.println("conversion time:" + mili + " ms");
380 out.close();
381 } else
382 System.out.println("file does not exist");
386 public static void main(String[] args) {
387 new mjc2wsl().run(args);
Svarog.pmf.uns.ac.rs/gitweb maintanance Doni Pracner