gitweb on Svarog

projekti pod git sistemom za održavanje verzija -- projects under the git version control system
77d1c2816e49705fcc0f29cd1f363ca0891025e6
[mjc2wsl.git] / src / mjc2wsl.java
1 import java.io.*;
2 import java.util.*;
4 /**
5 * This program converts file from compiled MicroJava bytecode (a subset used
6 * in Compiler Construction courses by H. Moessenboeck, not "Java ME")
7 * to WSL language which is a part of the FermaT Transformation system.
8 *
9 * @author Doni Pracner, http://perun.dmi.rs/pracner http://quemaster.com
10 */
11 public class mjc2wsl{
12 public static String versionN = "0.1.2";
14 //regular comments from the original file
15 //OC when original code is inserted in the file, next to the translations
16 //SPEC special messages from the translator
17 //ERR error messages from the transnlator
18 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("C:\" This file automatically converted from microjava bytecode\";\n"
83 +"C:\" with mjc2wsl v "+versionN+"\";\n");
85 ret.append("VAR < tempa := 0, tempb := 0, tempres :=0,\n");
86 for (int i=0;i<=3;i++) ret.append("loc"+i+" := 0, ");
87 ret.append("\n estack := < >, t_e_m_p := 0 > :");
89 return ret.toString();
90 }
92 public String getStandardEnd(){
93 return "SKIP\nENDVAR";
94 }
96 private boolean originalInComments = false;
98 private InputStream mainIn;
99 private PrintWriter out = null;
100 private int counter = -1;
102 private void pr(int i){
103 out.print(i);
106 private void pr(char i){
107 out.print(i);
110 private void pr(String i){
111 out.print(i);
114 private void prl(String i){
115 out.println(i);
118 private int get() {
119 int res = -1;
120 try{
121 res = mainIn.read();
122 if (res>=0) res = res<<24>>>24;
123 }catch (IOException ex){
124 ex.printStackTrace();
126 counter++;
127 return res;
130 private int get2() {
131 return (get()*256 + get())<<16>>16;
134 private int get4() {
135 return (get2()<<16) + (get2()<<16>>>16);
138 private String loc(int i){
139 return "loc"+i;
142 /**
143 * Creates a WSL comment with care to quote chars.
144 */
145 public static String createComment(String str){
146 return createComment(str, C_REG);
149 /**
150 * Creates a WSL comment with care to quote chars, of the
151 * given type. Types are given as char constants. They can be
152 * default comments, comments that contain the original code
153 * in them, or additional comments regarding the translation
154 * process.
155 */
156 public static String createComment(String str, char type){
157 return "C:\""+type+str.replace("\"", "''")+"\";";
160 private String cmdToEStack(int i){
161 return "estack := <"+i+" > ++ estack;";
164 private String cmdToEStack(String i){
165 return "estack := <"+i+" > ++ estack;";
168 private String cmdFromEStack(String st){
169 return st+" := HEAD(estack); estack := TAIL(estack);";
172 private String getTopTwo(){
173 return cmdFromEStack("tempa")+"\n"+cmdFromEStack("tempb");
176 private String getTop(){
177 return cmdFromEStack("tempa");
180 public void convertStream(InputStream ins){
181 mainIn = ins;
182 //skip start TODO make better
183 for (int i=0;i<14;i++) get();
185 prl(getStandardStart());
186 prl("SKIP;\n ACTIONS A_S_start:\n A_S_start == CALL a14 END");
187 int op = get();
188 while (op>=0){
189 if (originalInComments) prl(createComment(""+op,C_OC));
190 prl("a"+counter+" == ");
191 switch(op) {
192 case load: {
193 prl(cmdToEStack(loc(get())));
194 break;
196 case load_0: case load_1: case load_2: case load_3: {
197 prl(cmdToEStack(loc(op-load_0)));
198 break;
200 case store: {
201 prl(cmdFromEStack(loc(get())));
202 break;
204 case store_0: case store_1: case store_2: case store_3: {
205 prl(cmdFromEStack(loc(op-store_0)));
206 break;
208 case const_: {
209 prl(cmdToEStack(get4()));
210 break;
213 case const_0: case const_1: case const_2:
214 case const_3: case const_4: case const_5:{
215 prl(cmdToEStack(op-const_0));
216 break;
219 case jmp: {
220 prl("CALL a"+(counter+get2())+";");
221 break;
224 case jeq: case jne: case jlt:
225 case jle: case jgt: case jge: {
226 prl(getTopTwo());
227 prl("IF tempb >= tempa THEN CALL a"+(counter+get2())+" FI;");
228 break;
231 case add: {
232 prl(getTopTwo());
233 prl("tempres := tempb + tempa;");
234 prl(cmdToEStack("tempres"));
235 break;
236 }
237 case div: {
238 prl(getTopTwo());
239 prl("tempres := tempb / tempa;");
240 prl(cmdToEStack("tempres"));
241 break;
244 case enter: {
245 prl(createComment("enter not fully procesed yet"));
246 get();get();
247 break;
249 case return_: {
250 prl(createComment("return not fully procesed yet"));
251 break;
253 case exit: {
254 prl(createComment("exit not fully procesed yet"));
255 break;
258 //the prints
259 case bprint: {
260 prl(getTopTwo());
261 prl("PRINT(tempb);");
262 break;
264 case print: {
265 //TODO need to make it a char
266 prl(getTopTwo());
267 prl("PRINT(tempb);");
268 break;
271 default: prl(createComment("unknown op error: "+op,C_ERR)); break;
274 op = get();
275 if (op>=0) prl("CALL a"+counter+" END");
277 prl("CALL Z;\nSKIP END\nENDACTIONS;\n");
278 prl(getStandardEnd());
282 public void convertFile(File f){
283 try{
284 convertStream(new FileInputStream(f));
285 }catch (Exception ex){
286 ex.printStackTrace();
290 public void printHelp(){
291 System.out.println("MicroJava bytecode to WSL converter. v "+versionN+", by Doni Pracner");
292 System.out.println("usage:\n\t {options} mjc2wsl filename [outfile]");
293 System.out.println("options:\n\t--screen print output to screen");
294 System.out.println("\t-o --oc include original code in comments");
297 public String makeDefaultOutName(String inname){
298 String rez = inname;
299 if (inname.endsWith(".obj"))
300 rez = rez.substring(0,rez.length()-4);
301 return rez+".wsl";
304 public void run(String[] args){
305 if (args.length == 0){
306 printHelp();
307 }else{
308 int i=0;
309 while (i<args.length && args[i].charAt(0)=='-'){
310 if (args[i].compareTo("-h")==0){
311 printHelp();return;
312 }else
313 if (args[i].compareTo("-o")==0 || args[i].startsWith("--oc")){
314 if (args[i].length()==2) originalInComments = true;
315 else if (args[i].length()==5)
316 originalInComments = args[i].charAt(4)=='+';
317 else originalInComments = true;
318 }else
319 if (args[i].startsWith("--screen")){
320 out = new PrintWriter(System.out);
322 i++;
325 if (i>=args.length) {System.out.println("no filename supplied");System.exit(2);}
326 File f = new File(args[i]);
328 if (i+1<args.length) {
329 try{out = new PrintWriter(args[i+1]);}catch (Exception e) {
330 System.err.println("error in opening out file:");
331 e.printStackTrace();
334 if (out == null){
335 //if not set to screen, or a file, make a default filename
336 try{out = new PrintWriter(makeDefaultOutName(args[i]));}catch (Exception e) {
337 System.err.println("error in opening out file:");
338 e.printStackTrace();
341 if (f.exists()){
342 Calendar now = Calendar.getInstance();
343 convertFile(f);
344 long mili = Calendar.getInstance().getTimeInMillis() - now.getTimeInMillis();
345 System.out.println("conversion time:"+mili+" ms");
346 out.close();
347 }else
348 System.out.println("file does not exist");
352 public static void main(String[] args){
353 new mjc2wsl().run(args);
Svarog.pmf.uns.ac.rs/gitweb maintanance Doni Pracner