Guest User

Untitled

a guest
Oct 22nd, 2017
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.80 KB | None | 0 0
  1. package visitor;
  2.  
  3. import java.io.PrintWriter;
  4. import absyn.*;
  5. import table.*;
  6. import types.ArrayType;
  7. import types.ParamTypeList;
  8. import types.PrimitiveType;
  9. import types.Type;
  10. import codegen.*;
  11.  
  12. public class CodegenVisitor extends DoNothingVisitor {
  13.  
  14. int nextReg;
  15. Table symTab;
  16. int label;
  17. static PrintWriter outWriter;
  18. int newLabel = 0;
  19. private final int LASTREG = 23;
  20. boolean paramRef = false;
  21.  
  22. public CodegenVisitor(int reg, Table t, PrintWriter ow) {
  23. nextReg = reg;
  24. symTab = t;
  25. outWriter = ow;
  26. }
  27.  
  28. CodegenVisitor(int reg, Table t, int Label) {
  29. this(reg, t, outWriter);
  30. this.label = Label;
  31. }
  32.  
  33. public CodegenVisitor() {
  34.  
  35. }
  36.  
  37. public CodegenVisitor(int i, Table symTab2, PrintWriter ow, int label) {
  38. nextReg = i;
  39. symTab = symTab2;
  40. outWriter = ow;
  41. this.label = label;
  42. }
  43.  
  44. @Override
  45. public void visit(ArrayTy arrayTy) {
  46. regCheck(nextReg);
  47. // TODO regcheck
  48. outWriter.format("; ArrayTy \n");
  49. }
  50.  
  51. @Override
  52. public void visit(ArrayVar arrayVar) {
  53. regCheck(nextReg + 2);
  54. arrayVar.var.accept(this);
  55. SimpleVar sVar = (SimpleVar) varNameFinden(arrayVar.var);
  56. VarEntry vEnt = (VarEntry) symTab.lookup(sVar.name);
  57.  
  58. arrayVar.index.accept(new CodegenVisitor(nextReg + 1, symTab,
  59. outWriter, label));
  60. ArrayType aType = (ArrayType) vEnt.type;
  61. emitrrs("add", nextReg + 2, 0, aType.size,
  62. " ArrayVar: Arraygroeße in Reg. " + (nextReg + 2)
  63. + " schreiben.");
  64. emitrrb("bgeu", nextReg + 1, nextReg + 2, "_indexError",
  65. " ArrayVar: Indexcheck. ");
  66. emitrrs("mul", nextReg + 1, nextReg + 1, 4,
  67. " ArrayVar: Index mit 4 multiplizieren und in " + (nextReg + 1)
  68. + " schreiben.");
  69. emitrrr("add", nextReg, nextReg, nextReg + 1,
  70. " ArrayVar: Schreibt korrekte Adresse des Elements in Reg."
  71. + nextReg);
  72. }
  73.  
  74. @Override
  75. public void visit(AssignStm assignStm) {
  76. regCheck(nextReg + 1);
  77. assignStm.var.accept(this);
  78. assignStm.exp.accept(new CodegenVisitor(nextReg + 1, symTab, outWriter,
  79. label));
  80. emitrrs("stw", nextReg + 1, nextReg, 0,
  81. "AssignStm: Schreiben des Wertes aus " + (nextReg + 1)
  82. + " in Register " + nextReg);
  83. nextReg--;
  84. }
  85.  
  86. @Override
  87. public void visit(CallStm callStm) {
  88. regCheck(nextReg);
  89. ProcEntry pEnt = (ProcEntry) symTab.lookup(callStm.name);
  90. ExpList expList = callStm.args;
  91. int counter = 0;
  92. ParamTypeList paramTypes = pEnt.paramTypes;
  93.  
  94. while (expList.isEmpty == false) {
  95. if (paramTypes.isRef == true) {
  96. paramRef = true;
  97. }
  98. expList.head.accept(this);
  99. paramRef = false;
  100. emitrrs("stw", nextReg, 29, counter, " : Arguemnt Nr. " + counter
  101. / 4 + " eintragen");
  102. counter = counter + 4;
  103. expList = expList.tail;
  104. paramTypes = paramTypes.next;
  105. }
  106. outWriter.format("jal " + callStm.name.toString() + "\n");
  107. }
  108.  
  109. @Override
  110. public void visit(CompStm compStm) {
  111. regCheck(nextReg);
  112. compStm.stms.accept(this);
  113. }
  114.  
  115. @Override
  116. public void visit(DecList decList) {
  117. regCheck(nextReg);
  118. decList.head.accept(this);
  119. if (decList.tail.isEmpty == false) {
  120. decList.tail.accept(this);
  121. }
  122. }
  123.  
  124. @Override
  125. public void visit(EmptyStm emptyStm) {
  126. regCheck(nextReg);
  127. outWriter.format("; EmptyStm \n");
  128.  
  129. }
  130.  
  131. @Override
  132. public void visit(ExpList expList) {
  133. regCheck(nextReg + 1);
  134. if (expList.head != null) {
  135. expList.head.accept(this);
  136. }
  137. if (expList.tail != null) {
  138. expList.tail.accept(new CodegenVisitor(nextReg + 1, symTab,
  139. outWriter, label));
  140. }
  141.  
  142. }
  143.  
  144. @Override
  145. public void visit(IfStm ifStm) {
  146. regCheck(nextReg + 1);
  147. if (ifStm.elsePart instanceof EmptyStm) {
  148. ifStm.test.accept(this);
  149. OpExp opExp = (OpExp) ifStm.test;
  150.  
  151. switch (opExp.op) {
  152.  
  153. case OpExp.EQU:
  154. emitrrb("bne", nextReg, nextReg + 1, "L" + label,
  155. "OpExp: gleich");
  156. break;
  157. case OpExp.LST:
  158. emitrrb("bge", nextReg, nextReg + 1, "L" + label,
  159. "OpExp: kleiner");
  160. break;
  161. case OpExp.LSE:
  162. emitrrb("bgt", nextReg, nextReg + 1, "L" + label,
  163. "OpExp: kleiner-gleich");
  164. break;
  165. case OpExp.GRT:
  166. emitrrb("ble", nextReg, nextReg + 1, "L" + label,
  167. "OpExp: größer");
  168. break;
  169. case OpExp.GRE:
  170. emitrrb("blt", nextReg, nextReg + 1, "L" + label,
  171. "OpExp: größer-gleich");
  172. break;
  173. case OpExp.NEQ:
  174. emitrrb("beq", nextReg, nextReg + 1, "L" + label,
  175. "OpExp: größer-gleich");
  176. break;
  177. }
  178. ifStm.thenPart.accept(this);
  179. outWriter.format("L" + label++ + ": \n");
  180. }
  181.  
  182. else {
  183.  
  184. ifStm.test.accept(this);
  185. OpExp opExp = (OpExp) ifStm.test;
  186.  
  187. switch (opExp.op) {
  188.  
  189. case OpExp.EQU:
  190. emitrrb("bne", nextReg, nextReg + 1, emitLabel(),
  191. "OpExp: gleich");
  192. break;
  193. case OpExp.LST:
  194. emitrrb("bge", nextReg, nextReg + 1, emitLabel(),
  195. "OpExp: kleiner");
  196. break;
  197. case OpExp.LSE:
  198. emitrrb("bgt", nextReg, nextReg + 1, emitLabel(),
  199. "OpExp: kleiner-gleich");
  200. break;
  201. case OpExp.GRT:
  202. emitrrb("ble", nextReg, nextReg + 1, emitLabel(),
  203. "OpExp: größer");
  204. break;
  205. case OpExp.GRE:
  206. emitrrb("blt", nextReg, nextReg + 1, emitLabel(),
  207. "OpExp: größer-gleich");
  208. break;
  209. case OpExp.NEQ:
  210. emitrrb("beq", nextReg, nextReg + 1, emitLabel(),
  211. "OpExp: größer-gleich");
  212. break;
  213. }
  214. ifStm.thenPart.accept(this);
  215. emitJump("L" + (label + 1));
  216. outWriter.format("L" + label + ": \n");
  217. ifStm.elsePart.accept(new CodegenVisitor(nextReg + 1, symTab,
  218. outWriter, label));
  219. outWriter.format("L" + (label + 1) + ": \n");
  220. }
  221. }
  222.  
  223. @Override
  224. public void visit(IntExp intExp) {
  225. regCheck(nextReg);
  226. emitrrs("add", nextReg, 0, intExp.val, " IntExp : " + intExp.val);
  227. }
  228.  
  229. @Override
  230. public void visit(NameTy nameTy) {
  231. regCheck(nextReg);
  232. outWriter.format("; NameTy \n");
  233.  
  234. }
  235.  
  236. @Override
  237. public void visit(OpExp opExp) {
  238. regCheck(nextReg + 1);
  239. opExp.left.accept(this);
  240. opExp.right.accept(new CodegenVisitor(nextReg + 1, symTab, outWriter,
  241. label));
  242.  
  243. switch (opExp.op) {
  244.  
  245. case OpExp.ADD:
  246. emitrrr("add", nextReg, nextReg, nextReg + 1, "OpExp: add");
  247. break;
  248. case OpExp.SUB:
  249. emitrrr("sub", nextReg, nextReg, nextReg + 1, "OpExp: sub");
  250. break;
  251. case OpExp.MUL:
  252. emitrrr("mul", nextReg, nextReg, nextReg + 1, "OpExp: mul");
  253. break;
  254. case OpExp.DIV:
  255. emitrrr("div", nextReg, nextReg, nextReg + 1, "OpExp: div");
  256. break;
  257. case OpExp.EQU:
  258. // emitrrr("equ", nextReg, nextReg, nextReg + 1, "OpExp: gleich");
  259. break;
  260. case OpExp.LST:
  261. // emitrrr("equ", nextReg, nextReg, nextReg + 1, "OpExp: kleiner");
  262. break;
  263. case OpExp.LSE:
  264. // emitrrr("equ", nextReg, nextReg, nextReg + 1,
  265. // "OpExp: kleiner-gleich");
  266. break;
  267. case OpExp.GRT:
  268. // emitrrr("equ", nextReg, nextReg, nextReg + 1, "OpExp: größer");
  269. break;
  270. case OpExp.GRE:
  271. // emitrrr("equ", nextReg, nextReg, nextReg + 1,
  272. // "OpExp: größer-gleich");
  273. break;
  274. case OpExp.NEQ:
  275. // emitrrr("equ", nextReg, nextReg, nextReg + 1, "OpExp: ungleich");
  276. break;
  277. }
  278. }
  279.  
  280. @Override
  281. public void visit(ParDec parDec) {
  282. regCheck(nextReg);
  283. outWriter.format("; ParDec \n");
  284.  
  285. }
  286.  
  287. @Override
  288. public void visit(ProcDec procDec) {
  289. regCheck(nextReg);
  290. ProcEntry pE = (ProcEntry) symTab.lookup(procDec.name);
  291. Table lokTab = pE.localTable;
  292. int aufruf = 0;
  293.  
  294. // Wenn Rücksprungadresse gespeichert werden muss, dann Platz für RA
  295. // speichern:
  296. if (pE.ruftAuf == true) {
  297. aufruf = 4;
  298. }
  299.  
  300. outWriter.format(procDec.name.toString() + ":\n");
  301. // Prolog:
  302. emitrrs("sub", 29, 29, pE.groeßeLokVars + 4 + aufruf
  303. + pE.groeßeAusgehenderBereich, " Prolog: Frame aufbauen");
  304. // TODO pE.groeßeLokVars+4 korrekt?
  305. emitrrs("stw", 25, 29, aufruf + pE.groeßeAusgehenderBereich,
  306. " Prolog: Framepointer sichern");
  307. emitrrs("add", 25, 29, pE.groeßeLokVars + 4 + aufruf
  308. + pE.groeßeAusgehenderBereich,
  309. " Prolog: Framepointer neu setzen");
  310. if (aufruf != 0) {
  311. emitrrs("stw", 31, 25,
  312. // -(pE.groeßeLokVars + aufruf + pE.groeßeAusgehenderBereich),
  313. -(pE.groeßeLokVars + 8), " Prolog: RA speichern");
  314. }
  315.  
  316. // Prolog Ende
  317. if (procDec.body.isEmpty != true) {
  318. procDec.body.accept(new CodegenVisitor(nextReg, lokTab, outWriter,
  319. label));
  320. }
  321.  
  322. // Epilog:
  323. if (aufruf != 0) {
  324. emitrrs("ldw", 31, 25, -(pE.groeßeLokVars + 8),
  325. " Prolog: RA wiederherstellen");
  326. }
  327. emitrrs("ldw", 25, 29, aufruf + pE.groeßeAusgehenderBereich,
  328. " Epilog: Alten Framepointer wieder herstellen");
  329. emitrrs("add", 29, 29, pE.groeßeLokVars + 4 + aufruf
  330. + pE.groeßeAusgehenderBereich, " Epilog: Frame abbauen");
  331. outWriter.format("jr $31 ; return zur Rücksprungadresse \n");
  332. }
  333.  
  334. @Override
  335. public void visit(SimpleVar simpleVar) {
  336. regCheck(nextReg);
  337. VarEntry vEnt = (VarEntry) symTab.lookup(simpleVar.name);
  338. int offset = -vEnt.offsetSize;
  339. emitrrs("add", nextReg, 25, offset, " SimpleVar: " + simpleVar.name);
  340. }
  341.  
  342. @Override
  343. public void visit(StmList stmList) {
  344. regCheck(nextReg + 1);
  345. stmList.head.accept(this);
  346. if (stmList.tail.isEmpty == false) {
  347. stmList.tail.accept(new CodegenVisitor(nextReg + 1, symTab,
  348. outWriter, label));
  349. }
  350. }
  351.  
  352. @Override
  353. public void visit(TypeDec typeDec) {
  354. regCheck(nextReg);
  355. }
  356.  
  357. @Override
  358. public void visit(VarDec varDec) {
  359. regCheck(nextReg);
  360. outWriter.format("; VarDec \n");
  361. }
  362.  
  363. @Override
  364. public void visit(VarExp varExp) {
  365. regCheck(nextReg);
  366. varExp.var.accept(this);
  367. SimpleVar sVar = (SimpleVar) varNameFinden(varExp.var);
  368. if (paramRef == false) {
  369. emitrrs("ldw", nextReg, nextReg, 0,
  370. "VarExp: Ablegen des Wertes an Adresse " + nextReg);
  371. }
  372. }
  373.  
  374. @Override
  375. public void visit(WhileStm whileStm) {
  376. regCheck(nextReg + 2);
  377. outWriter.format("L" + label++);
  378. whileStm.test.accept(this);
  379. OpExp opExp = (OpExp) whileStm.test;
  380.  
  381. switch (opExp.op) {
  382.  
  383. case OpExp.EQU:
  384. emitrrb("bne", nextReg, nextReg + 1, "L" + label, "OpExp: gleich");
  385. break;
  386. case OpExp.LST:
  387. emitrrb("bge", nextReg, nextReg + 1, "L" + label, "OpExp: kleiner");
  388. break;
  389. case OpExp.LSE:
  390. emitrrb("bgt", nextReg, nextReg + 1, "L" + label,
  391. "OpExp: kleiner-gleich");
  392. break;
  393. case OpExp.GRT:
  394. emitrrb("ble", nextReg, nextReg + 1, "L" + label, "OpExp: größer");
  395. break;
  396. case OpExp.GRE:
  397. emitrrb("blt", nextReg, nextReg + 1, "L" + label,
  398. "OpExp: größer-gleich");
  399. break;
  400. case OpExp.NEQ:
  401. emitrrb("beq", nextReg, nextReg + 1, "L" + label,
  402. "OpExp: größer-gleich");
  403. break;
  404. }
  405. whileStm.body.accept(this);
  406. emitJump("J" + (label - 1));
  407. }
  408.  
  409. private void emitrrs(String string, int nextReg2, int nextReg3, int i,
  410. String string2) {
  411. outWriter.format(string + " $" + nextReg2 + ",$" + nextReg3 + "," + i
  412. + " ; " + string2 + " \n");
  413. }
  414.  
  415. private void emitrrr(String string, int nextReg2, int nextReg3,
  416. int nextReg4, String string2) {
  417. outWriter.format(string + " $" + nextReg2 + ",$" + nextReg3 + ",$"
  418. + nextReg4 + " ; " + string2 + " \n");
  419. }
  420.  
  421. private void emitrrb(String string, int nextReg2, int nextReg3,
  422. String string2, String string3) {
  423. outWriter.format(string + " $" + nextReg2 + ",$" + nextReg3 + ","
  424. + string2 + " ; " + string3 + " \n");
  425. }
  426.  
  427. private Var varNameFinden(Var var) {
  428. SimpleVar sVar;
  429. ArrayVar aVar;
  430.  
  431. if (var instanceof ArrayVar) {
  432. aVar = (ArrayVar) var;
  433.  
  434. return varNameFinden(aVar.var);
  435. }
  436.  
  437. if (var instanceof SimpleVar) {
  438. sVar = (SimpleVar) var;
  439. return sVar;
  440. }
  441. return null;
  442. }
  443.  
  444. private void regCheck(int reg) {
  445. try {
  446. if (reg > LASTREG) {
  447. throw new Exception("Register: FULL");
  448. }
  449. } catch (Exception e) {
  450.  
  451. }
  452. }
  453.  
  454. private int nextLabel() {
  455. return newLabel++;
  456. }
  457.  
  458. private String emitLabel() {
  459. return "L" + nextLabel();
  460. }
  461.  
  462. private void emitJump(String string) {
  463. outWriter.format("j " + string + " \n");
  464. }
  465. }
Add Comment
Please, Sign In to add comment