gitweb on Svarog
projekti pod git sistemom za održavanje verzija -- projects under
the git version control system
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
10 * @author Doni Pracner, http://perun.dmi.rs/pracner http://quemaster.com
13 public static String versionN
= "0.1.2";
15 public static final int M_ERR
= 2, M_WAR
= 1;
17 private int printLevel
= 0;
19 private int[] messageCounters
= new int[M_ERR
+1];
21 private void message(String mes
, int level
){
23 System
.out
.println(mes
);
24 messageCounters
[level
]++;
27 private void printMessageCounters(){
28 printMessageCounters(System
.out
);
31 private void printMessageCounters(PrintStream out
){
32 out
.println("total errors:"+messageCounters
[M_ERR
]+" warnings:"+messageCounters
[M_WAR
]);
35 /** Constant used for marking a regular comment from the original file */
36 public static final char C_REG
= ' ';
38 * Constant used for marking when original code is inserted in the file,
39 * next to the translations
41 public static final char C_OC
= '#';
42 /** Constant used for marking special messages from the translator */
43 public static final char C_SPEC
= '&';
44 /** Constant used for marking error messages from the translator */
45 public static final char C_ERR
= '!';
47 /** instruction code in MicroJava bytecode. */
48 public static final int
107 public String
getStandardStart(){
108 StringBuilder ret
= new StringBuilder(
109 "C:\" This file automatically converted from microjava bytecode\";\n"
110 +"C:\" with mjc2wsl v "+versionN
+"\";\n");
112 ret
.append("VAR < tempa := 0, tempb := 0, tempres :=0,\n");
113 for (int i
= 0; i
<= 3; i
++)
114 ret
.append("loc" + i
+ " := 0, ");
115 ret
.append("\n estack := < >, t_e_m_p := 0 > :");
117 return ret
.toString();
120 public String
getStandardEnd(){
121 return "SKIP\nENDVAR";
124 private boolean originalInComments
= false;
126 private InputStream mainIn
;
127 private PrintWriter out
= null;
128 private int counter
= -1;
130 private void pr(int i
){
134 private void pr(char i
){
138 private void pr(String i
){
142 private void prl(String i
){
151 res
= res
<< 24 >>> 24;
152 } catch (IOException ex
) {
153 ex
.printStackTrace();
160 return (get() * 256 + get()) << 16 >> 16;
164 return (get2() << 16) + (get2() << 16 >>> 16);
167 private String
loc(int i
){
172 * Creates a WSL comment with care to quote chars.
174 public static String
createComment(String str
){
175 return createComment(str
, C_REG
);
179 * Creates a WSL comment with care to quote chars, of the
180 * given type. Types are given as char constants. They can be
181 * default comments, comments that contain the original code
182 * in them, or additional comments regarding the translation
185 public static String
createComment(String str
, char type
) {
186 return "C:\"" + type
+ str
.replace("\"", "''") + "\";";
189 private String
cmdToEStack(int i
) {
190 return "estack := <" + i
+ " > ++ estack;";
193 private String
cmdToEStack(String i
) {
194 return "estack := <" + i
+ " > ++ estack;";
197 private String
cmdFromEStack(String st
) {
198 return st
+ " := HEAD(estack); estack := TAIL(estack);";
201 private String
getTopTwo(){
202 return cmdFromEStack("tempa") + "\n" + cmdFromEStack("tempb");
205 private String
getTop() {
206 return cmdFromEStack("tempa");
209 private String
getRelationFor(int opcode
) throws Exception
{
211 case jeq
: return "=";
212 case jne
: return "<>";
213 case jlt
: return "<";
214 case jle
: return "<=";
215 case jgt
: return ">";
216 case jge
: return ">=";
218 throw new Exception("Wrong opcode for a relation");
221 public void convertStream(InputStream ins
) throws Exception
{
223 //skip start TODO make better
224 for (int i
= 0; i
< 14; i
++)
227 prl(getStandardStart());
228 prl("SKIP;\n ACTIONS A_S_start:\n A_S_start == CALL a14 END");
231 if (originalInComments
)
232 prl(createComment("" + op
, C_OC
));
233 prl("a" + counter
+ " == ");
236 prl(cmdToEStack(loc(get())));
243 prl(cmdToEStack(loc(op
- load_0
)));
247 prl(cmdFromEStack(loc(get())));
254 prl(cmdFromEStack(loc(op
- store_0
)));
258 prl(cmdToEStack(get4()));
268 prl(cmdToEStack(op
- const_0
));
273 prl("CALL a" + (counter
+ get2()) + ";");
284 prl("IF tempb "+ getRelationFor(op
)
285 +" tempa THEN CALL a" + (counter
+ get2())
292 prl("tempres := tempb + tempa;");
293 prl(cmdToEStack("tempres"));
298 prl("tempres := tempb - tempa;");
299 prl(cmdToEStack("tempres"));
304 prl("tempres := tempb * tempa;");
305 prl(cmdToEStack("tempres"));
310 prl("IF tempa = 0 THEN ERROR(\"division by zero\") FI;");
311 prl("tempres := tempb DIV tempa;");
312 prl(cmdToEStack("tempres"));
317 prl("IF tempa = 0 THEN ERROR(\"division by zero\") FI;");
318 prl("tempres := tempb MOD tempa;");
319 prl(cmdToEStack("tempres"));
324 prl(createComment("enter not fully procesed yet"));
325 message("enter not fully procesed yet", M_WAR
);
331 prl(createComment("return not fully procesed yet"));
332 message("return not fully procesed yet", M_WAR
);
336 prl(createComment("exit not fully procesed yet"));
337 message("exit not fully procesed yet", M_WAR
);
344 prl("PRINT(tempb);");
348 // TODO need to make it a char
350 prl("PRINT(tempb);");
354 prl(createComment("unknown op error: " + op
, C_ERR
));
355 message("unknown op error: "+ op
, M_ERR
);
361 prl("CALL a" + counter
+ " END");
363 prl("CALL Z;\nSKIP END\nENDACTIONS;\n");
364 prl(getStandardEnd());
368 public void convertFile(File f
) {
370 convertStream(new FileInputStream(f
));
371 } catch (Exception ex
) {
372 ex
.printStackTrace();
376 public void printHelp() {
377 System
.out
.println("MicroJava bytecode to WSL converter. v " + versionN
378 + ", by Doni Pracner");
379 System
.out
.println("usage:\n\t {options} mjc2wsl filename [outfile]");
380 System
.out
.println("options:\n\t--screen print output to screen");
381 System
.out
.println("\t-o --oc include original code in comments");
384 public String
makeDefaultOutName(String inname
){
386 if (inname
.endsWith(".obj"))
387 rez
= rez
.substring(0, rez
.length() - 4);
391 public void run(String
[] args
) {
392 if (args
.length
== 0) {
396 while (i
< args
.length
&& args
[i
].charAt(0) == '-') {
397 if (args
[i
].compareTo("-h") == 0) {
400 } else if (args
[i
].compareTo("-o") == 0
401 || args
[i
].startsWith("--oc")) {
402 if (args
[i
].length() == 2)
403 originalInComments
= true;
404 else if (args
[i
].length() == 5)
405 originalInComments
= args
[i
].charAt(4) == '+';
407 originalInComments
= true;
408 } else if (args
[i
].startsWith("--screen")) {
409 out
= new PrintWriter(System
.out
);
414 if (i
>= args
.length
) {
415 System
.out
.println("no filename supplied");
418 File f
= new File(args
[i
]);
420 if (i
+ 1 < args
.length
) {
422 out
= new PrintWriter(args
[i
+ 1]);
423 } catch (Exception e
) {
424 System
.err
.println("error in opening out file:");
429 // if not set to screen, or a file, make a default filename
431 out
= new PrintWriter(makeDefaultOutName(args
[i
]));
432 } catch (Exception e
) {
433 System
.err
.println("error in opening out file:");
438 Calendar now
= Calendar
.getInstance();
441 long mili
= Calendar
.getInstance().getTimeInMillis()
442 - now
.getTimeInMillis();
443 System
.out
.println("conversion time:" + mili
+ " ms");
444 printMessageCounters();
447 System
.out
.println("file does not exist");
451 public static void main(String
[] args
) {
452 new mjc2wsl().run(args
);
Svarog.pmf.uns.ac.rs/gitweb
maintanance
Doni Pracner