Advertisement
Guest User

Untitled

a guest
Jul 21st, 2017
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 26.06 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <sstream>
  5. #include <algorithm>
  6.  
  7. using namespace std;
  8.  
  9. const vector<string> terminals = {"BOF", "BECOMES", "COMMA", "ELSE", "EOF", "EQ", "GE", "GT", "ID", "IF", "INT", "LBRACE", "LE", "LPAREN", "LT", "MINUS", "NE", "NUM", "PCT", "PLUS", "PRINTLN", "RBRACE", "RETURN", "RPAREN", "SEMI", "SLASH", "STAR", "WAIN", "WHILE", "AMP", "LBRACK", "RBRACK", "NEW", "DELETE", "NULL"};
  10. int globalLabelCount =0;
  11.  
  12. struct Node {
  13. string rule;
  14. vector<string> tokens;
  15. vector<Node*> nodes;
  16. bool ifTerminal;
  17.  
  18. Node(bool terminal): ifTerminal(terminal) {}
  19. ~Node() {
  20. for (int a=0; a < nodes.size(); a++) {
  21. delete nodes[a];
  22. }
  23. }
  24. };
  25.  
  26. Node* createTree() {
  27. Node* currNode = new Node(false);
  28.  
  29. string line;
  30. getline(cin, line);
  31. currNode->rule = line;
  32. istringstream iss(line);
  33.  
  34. string word;
  35. iss >> word; // remove first part of rule
  36. while (iss >> word) {
  37. if (find(terminals.begin(), terminals.end(), word) != terminals.end()) {
  38. getline(cin, line);
  39. istringstream terminalstream(line);
  40.  
  41. Node* terminalNode = new Node(true);
  42. terminalstream >> word;
  43. terminalNode->tokens.emplace_back(word);
  44. terminalstream >> word;
  45. terminalNode->tokens.emplace_back(word);
  46. currNode->nodes.emplace_back(terminalNode);
  47. }
  48. else {
  49. Node* ruleNode = createTree();
  50. currNode->nodes.emplace_back(ruleNode);
  51. }
  52. }
  53.  
  54. return currNode;
  55. }
  56.  
  57. int derivationScan(Node* Tree, vector<vector<string>>* table) {
  58. // 0: type int, 1: type int*
  59. string rule = Tree->rule;
  60. istringstream iss(rule);
  61. string word;
  62. iss >> word;
  63. if (word == "expr") {
  64. if (rule == "expr term") {
  65. return derivationScan(Tree->nodes[0], table);
  66. }
  67. else if (rule == "expr expr MINUS term") {
  68. int check1 = derivationScan(Tree->nodes[0], table);
  69. int check2 = derivationScan(Tree->nodes[2], table);
  70. if (check1 == 0 && check2 == 1) {// if either variable in MINUS is not int
  71. throw(string("subtract with int - int*"));
  72. }
  73. if (check1 == 1 && check2 == 0) { // int* and int variables
  74. return 1;
  75. }
  76. else { // two int variables
  77. return 0;
  78. }
  79. }
  80. else {
  81. int check1 = derivationScan(Tree->nodes[0], table);
  82. int check2 = derivationScan(Tree->nodes[2], table);
  83. if (check1 == 1 && check2 == 1) {// if either variable in PLUS is not int
  84. throw(string("plus with two int* variable"));
  85. }
  86. if (check1 == 1 || check2 == 1) { // int* and int variables
  87. return 1;
  88. }
  89. else { // two int variables
  90. return 0;
  91. }
  92. }
  93. }
  94. else if (word == "lvalue") {
  95. if (rule == "lvalue ID") {
  96. for (int i=1; i < (*table).size(); i++) {
  97. if ((*table)[i][0] == Tree->nodes[0]->tokens[1]) {
  98. if ((*table)[i][1] == "int") {
  99. return 0;
  100. }
  101. return 1;
  102. }
  103. }
  104. }
  105. else if (rule == "lvalue STAR factor") {
  106. int check = derivationScan(Tree->nodes[1], table);
  107. if (check != 1) {
  108. throw(string("STAR factor rule, factor does not have type int* to dereference"));
  109. }
  110. else {
  111. return 0;
  112. }
  113. }
  114. else {
  115. return derivationScan(Tree->nodes[1], table);
  116. }
  117. }
  118. else if (word == "term") {
  119. if (rule == "term factor") {
  120. return derivationScan(Tree->nodes[0], table);
  121. }
  122. else {
  123. int check1 = derivationScan(Tree->nodes[0], table);
  124. int check2 = derivationScan(Tree->nodes[2], table);
  125. if (check1 != 0 || check2 != 0) {// if either variable in mult/div/mod is not int
  126. throw(string("mult/div/mod with non int variable"));
  127. }
  128. return 0;
  129. }
  130. }
  131. else if (word == "factor") {
  132. if (rule == "factor ID") {
  133. for (int i=1; i < (*table).size(); i++) {
  134. if ((*table)[i][0] == Tree->nodes[0]->tokens[1]) {
  135. if ((*table)[i][1] == "int") {
  136. return 0;
  137. }
  138. return 1;
  139. }
  140. }
  141. }
  142. else if (rule == "factor NUM") {
  143. return 0;
  144. }
  145. else if (rule == "factor NULL") {
  146. return 1;
  147. }
  148. else if (rule == "factor LPAREN expr RPAREN") {
  149. return derivationScan(Tree->nodes[1], table);
  150. }
  151. else if (rule == "factor AMP lvalue") {
  152. int check = derivationScan(Tree->nodes[1], table);
  153. if (check != 0) {
  154. throw(string("Ampersand ID rule, ID does not have type int"));
  155. }
  156. else {
  157. return 1;
  158. }
  159. }
  160. else if (rule == "factor STAR factor") {
  161. int check = derivationScan(Tree->nodes[1], table);
  162. if (check != 1) {
  163. throw(string("STAR ID rule, ID does not have type int* to dereference"));
  164. }
  165. else {
  166. return 0;
  167. }
  168. }
  169. else if (rule == "factor NEW INT LBRACK expr RBRACK") {
  170. int check = derivationScan(Tree->nodes[3], table);
  171. if (check != 0) {
  172. throw(string("NEW expr rule, expr does not have type int"));
  173. }
  174. else {
  175. return 1;
  176. }
  177. }
  178. else { // factor is function call
  179. return 0;
  180. }
  181. }
  182. else if (word == "type") {
  183. if (rule == "type INT") {
  184. return 0;
  185. }
  186. return 1;
  187. }
  188. else if (word == "dcl") {
  189. return derivationScan(Tree->nodes[0], table);
  190. }
  191. else if (word == "test") {
  192. int check1 = derivationScan(Tree->nodes[0], table);
  193. int check2 = derivationScan(Tree->nodes[2], table);
  194. //cout << "check1: " << check1 << " check2: " << check2 << endl;
  195. if (check1 != check2) {// if either variable in mult/div/mod is not int
  196. throw(string("Comparison operation between int and int*"));
  197. }
  198. }
  199. else if (rule == "statement DELETE LBRACK RBRACK expr SEMI") {
  200. int check = derivationScan(Tree->nodes[3], table);
  201. if (check != 1) {
  202. throw(string("Delete operation called on non int*"));
  203. }
  204. }
  205. else if (rule == "statement PRINTLN LPAREN expr RPAREN SEMI") {
  206. int check = derivationScan(Tree->nodes[2], table);
  207. if (check != 0) {
  208. throw(string("Print operation called on non int"));
  209. }
  210. }
  211. else if (rule == "statement lvalue BECOMES expr SEMI") {
  212. int check1 = derivationScan(Tree->nodes[0], table);
  213. int check2 = derivationScan(Tree->nodes[2], table);
  214. if (check1 != check2) {
  215. throw(string("Assignment operation between int and int*"));
  216. }
  217. }
  218. else if (rule == "dcls dcls dcl BECOMES NUM SEMI") {
  219. derivationScan(Tree->nodes[0], table);
  220. int check = derivationScan(Tree->nodes[1], table);
  221. if (check != 0) {
  222. throw(string("Setting type int* to NUM"));
  223. }
  224. }
  225. else if (rule == "dcls dcls dcl BECOMES NULL SEMI") {
  226. derivationScan(Tree->nodes[0], table);
  227. int check = derivationScan(Tree->nodes[1], table);
  228. if (check != 1) {
  229. throw(string("Setting type int to NULL"));
  230. }
  231. }
  232. else if (rule == "main INT WAIN LPAREN dcl COMMA dcl RPAREN LBRACE dcls statements RETURN expr SEMI RBRACE") {
  233. int check1 = derivationScan(Tree->nodes[5], table);
  234. int check2 = derivationScan(Tree->nodes[11], table);
  235. //cout << Tree->nodes[5]->nodes[0]->rule;
  236. if (check1 != 0) {
  237. throw(string("Second parameter of Wain is not type int"));
  238. }
  239. if (check2 != 0) {
  240. throw(string("Return value of Wain is not type int"));
  241. }
  242. derivationScan(Tree->nodes[8], table); // check dcls
  243. derivationScan(Tree->nodes[9], table); // check statements
  244. }
  245. else if (rule == "procedure INT ID LPAREN params RPAREN LBRACE dcls statements RETURN expr SEMI RBRACE") {
  246. int check = derivationScan(Tree->nodes[9], table);
  247. if (check != 0) {
  248. throw(string("Return value of a function is not type int"));
  249. }
  250. derivationScan(Tree->nodes[6], table); // check dcls
  251. derivationScan(Tree->nodes[7], table); // check statements
  252. }
  253. else {
  254. for (int i=0; i < Tree->nodes.size(); i++) {
  255. if (!(Tree->nodes[i]->ifTerminal)) {
  256. derivationScan(Tree->nodes[i], table);
  257. }
  258. }
  259. }
  260. }
  261.  
  262. void declarationScan(Node* Tree, vector<vector<string>>* table, vector<string> functionList) {
  263. if (!(Tree->ifTerminal) && (Tree->rule == "factor ID LPAREN RPAREN" || Tree->rule == "factor ID LPAREN arglist RPAREN")) {
  264. string functionID = Tree->nodes[0]->tokens[1];
  265. //if (functionID != (*table)[0][0]) { // if not a recursive function call
  266. bool inTable = false;
  267. for (int i=1; i < table->size(); i++) { // Check if function ID is used as a local variable, thus cannot be called
  268. if ((*table)[i][0] == functionID) {
  269. inTable = true;
  270. }
  271. }
  272. if (inTable) {
  273. throw("Function ID " + functionID + " is declared as a local variable");
  274. }
  275. //}
  276. inTable = false;
  277. if (functionID != "wain") { // Check if function ID has been defined previously in functionList
  278. //cout<< "check wain for id: " << functionID << endl;
  279. for (int i=0; i < functionList.size(); i++) {
  280. if (functionList[i] == functionID) {
  281. inTable = true;
  282. }
  283. }
  284. }
  285. if (!inTable) { // Check if ID has already been declared
  286. throw("ID " + functionID + " has not been declared");
  287. }
  288. }
  289. else if (!(Tree->ifTerminal)) {
  290. //cout << "rule:" << Tree->rule << endl;
  291. if (Tree->rule == "dcl type ID") {
  292.  
  293. bool inTable = false;
  294. for (int i=1; i < table->size(); i++) {
  295. if ((*table)[i][0] == Tree->nodes[1]->tokens[1]) {
  296. inTable = true;
  297. }
  298. }
  299.  
  300. if (inTable) { // Check if ID has already been declared
  301. throw("Redeclaration of ID " + Tree->nodes[1]->tokens[1]);
  302. }
  303. //cout << "ID:" << Tree->nodes[1]->tokens[1] << endl;
  304.  
  305. vector<string> newDec;
  306. newDec.emplace_back(Tree->nodes[1]->tokens[1]);
  307. if (Tree->nodes[0]->rule == "type INT") {
  308. newDec.emplace_back("int");
  309. }
  310. else {
  311. newDec.emplace_back("int*");
  312. }
  313. table->emplace_back(newDec);
  314. }
  315. else {
  316. for (int a=0; a < Tree->nodes.size(); a++) {
  317. declarationScan(Tree->nodes[a], table, functionList);
  318. }
  319. }
  320. }
  321. else if (Tree->tokens[0] == "ID") {
  322. //cout << "ID:" << Tree->tokens[1] << endl;
  323. bool inTable = false;
  324. for (int i=0; i < table->size(); i++) {
  325. if ((*table)[i][0] == Tree->tokens[1]) {
  326. inTable = true;
  327. }
  328. }
  329. if (!inTable) { // Check if ID has already been declared
  330. throw("ID " + Tree->tokens[1] + " has not been declared");
  331. }
  332. }
  333. }
  334.  
  335. void treeParse(Node* Tree, vector<Node*>* vec) {
  336. if (!(Tree->ifTerminal)) {
  337. istringstream iss(Tree->rule);
  338. string word1;
  339. string word2;
  340. iss >> word1 >> word2;
  341. if ((word1 == "procedures" && word2 == "main") || (word1 == "procedure" && word2 == "INT")) {
  342. vec->emplace_back(Tree);
  343. }
  344. else {
  345. for (int i=0; i < Tree->nodes.size() ; i++) {
  346. treeParse(Tree->nodes[i], vec);
  347. }
  348. }
  349. }
  350. }
  351.  
  352. vector<string> generateFunctions(vector<Node*>* procedures) {
  353. vector<string> functionList;
  354. string function;
  355. for (int i=0; i < procedures->size(); i++) {
  356. if ((*procedures)[i]->rule == "procedures main") {
  357. function = "wain";
  358. }
  359. else {
  360. function = (*procedures)[i]->nodes[1]->tokens[1];
  361. }
  362.  
  363. if (find(functionList.begin(), functionList.end(), function) != functionList.end()) {
  364. throw("redeclaration of function " + function);
  365. }
  366. else {
  367. functionList.emplace_back(function);
  368. }
  369. }
  370. return functionList;
  371. }
  372.  
  373. vector<string> generateWainParameters(vector<Node*>* procedures) {
  374. vector<string> wainParameters;
  375. string parameterType;
  376. Node* wain;
  377. for (int i=0; i < procedures->size(); i++) {
  378. if ((*procedures)[i]->rule == "procedures main") {
  379. wain = (*procedures)[i]->nodes[0];
  380. }
  381. }
  382. if (wain->nodes[3]->nodes[0]->rule == "type INT") {
  383. parameterType = "int";
  384. wainParameters.emplace_back(parameterType);
  385. }
  386. else {
  387. parameterType = "int*";
  388. wainParameters.emplace_back(parameterType);
  389. }
  390. if (wain->nodes[5]->nodes[0]->rule == "type INT") {
  391. parameterType = "int";
  392. wainParameters.emplace_back(parameterType);
  393. }
  394. else {
  395. parameterType = "int*";
  396. wainParameters.emplace_back(parameterType);
  397. }
  398.  
  399. wainParameters.emplace_back(wain->nodes[3]->nodes[1]->tokens[1]);
  400. wainParameters.emplace_back(wain->nodes[5]->nodes[1]->tokens[1]);
  401. return wainParameters;
  402. }
  403.  
  404. vector<string> generateFuncParameters(vector<Node*>* procedures, string functionName) {
  405. vector<string> funcParameters;
  406. funcParameters.emplace_back(functionName);
  407. string parameterType;
  408. Node* func;
  409. for (int i=0; i < procedures->size(); i++) {
  410. if ((*procedures)[i]->nodes.size() != 1 && // if not wain
  411. (*procedures)[i]->nodes[1]->tokens[1] == functionName) { // if same function name
  412. func = (*procedures)[i]->nodes[3]; // set func to function parameters node
  413. if (func->nodes.size() ==0) {
  414. return funcParameters;
  415. }
  416. }
  417. }
  418.  
  419. Node* paramList = func->nodes[0];
  420. while (paramList->nodes.size() == 3) { // while paramList is recursively defining parameters
  421. if (paramList->nodes[0]->nodes[0]->nodes.size() == 1) {
  422. parameterType = "int";
  423. funcParameters.emplace_back(parameterType);
  424. }
  425. else {
  426. parameterType = "int*";
  427. funcParameters.emplace_back(parameterType);
  428. }
  429. paramList = paramList->nodes[2];
  430. }
  431. if (paramList->nodes[0]->nodes[0]->nodes.size() == 1) {
  432. parameterType = "int";
  433. funcParameters.emplace_back(parameterType);
  434. }
  435. else {
  436. parameterType = "int*";
  437. funcParameters.emplace_back(parameterType);
  438. }
  439.  
  440. return funcParameters;
  441. }
  442.  
  443. void printTable(vector<vector<vector<string>>*> tables, vector<Node*>* procedures) {
  444. for (int i=0; i < tables.size() ; i++) {
  445. if (i != 0) {
  446. cerr << endl;
  447. }
  448. if ((*(tables[i]))[0][0] == "wain") { // if Wain procedure print this way
  449. vector<string> wainParameters = generateWainParameters(procedures);
  450. cerr << "wain " << wainParameters[0] << " " << wainParameters[1] << endl;
  451. for (int j=1; j < tables[i]->size() ; j++) {
  452. cerr << (*(tables[i]))[j][0] << " " << (*(tables[i]))[j][1] << endl;
  453. }
  454. }
  455. else { // if any other procedure print this way
  456. string functionName = (*(tables[i]))[0][0];
  457. vector<string> functionParameters = generateFuncParameters(procedures,functionName);
  458. // print all function parameters
  459. for (int j=0; j < functionParameters.size() ; j++) {
  460. if (j !=0 ) {cerr << " ";}
  461. cerr << functionParameters[j];
  462. }
  463. cerr << endl;
  464. for (int j=1; j < tables[i]->size() ; j++) {
  465. cerr << (*(tables[i]))[j][0] << " " << (*(tables[i]))[j][1] << endl;
  466. }
  467. }
  468. }
  469. }
  470.  
  471. void push(string registerNum = "$3") {
  472. cout << "sw " + registerNum + ",-4($30)" << endl;
  473. cout << "sub $30,$30,$4" << endl;
  474. }
  475.  
  476. void pop() {
  477. cout << "add $30,$30,$4" << endl;
  478. cout << "lw $5, -4($30)" << endl;
  479. }
  480.  
  481. void compileRecurse(Node* Tree, vector<vector<string>> newTable, vector<vector<vector<string>>*> tables, vector<Node*>* procedures) {
  482. if (Tree->rule == "factor LPAREN expr RPAREN") {
  483. compileRecurse(Tree->nodes[1], newTable, tables, procedures);
  484. }
  485. else if (Tree->rule == "factor ID") {
  486. string location;
  487. string returnVar = Tree->nodes[0]->tokens[1];
  488. //cout << "returnVar: " << returnVar;
  489. for (int i=0; i < newTable.size(); i++) {
  490. //cout << "varname :" << newTable[i][0] << endl;
  491. if (newTable[i][0] == returnVar) {
  492. location = newTable[i][2];
  493. }
  494. }
  495.  
  496. cout << "lw $3, -" + location + "($29)" << endl;
  497. }
  498. else if (Tree->rule == "expr term" || Tree->rule == "term factor") {
  499. compileRecurse(Tree->nodes[0], newTable, tables, procedures);
  500. }
  501. else if (Tree->rule == "expr expr PLUS term") {
  502. compileRecurse(Tree->nodes[0], newTable, tables, procedures);
  503. push("$3");
  504. compileRecurse(Tree->nodes[2], newTable, tables, procedures);
  505. pop();
  506. cout << "add $3, $5, $3" << endl;
  507. }
  508. else if (Tree->rule == "expr expr MINUS term") {
  509. compileRecurse(Tree->nodes[0], newTable, tables, procedures);
  510. push("$3");
  511. compileRecurse(Tree->nodes[2], newTable, tables, procedures);
  512. pop();
  513. cout << "sub $3, $5, $3" << endl;
  514. }
  515. else if (Tree->rule == "term term STAR factor") {
  516. compileRecurse(Tree->nodes[0], newTable, tables, procedures);
  517. push("$3");
  518. compileRecurse(Tree->nodes[2], newTable, tables, procedures);
  519. pop();
  520. cout << "mult $3, $5" << endl;
  521. cout << "mflo $3" << endl;
  522. }
  523. else if (Tree->rule == "term term SLASH factor") {
  524. compileRecurse(Tree->nodes[0], newTable, tables, procedures);
  525. push("$3");
  526. compileRecurse(Tree->nodes[2], newTable, tables, procedures);
  527. pop();
  528. cout << "div $5, $3" << endl;
  529. cout << "mflo $3" << endl;
  530. }
  531. else if (Tree->rule == "term term PCT factor") {
  532. compileRecurse(Tree->nodes[0], newTable, tables, procedures);
  533. push("$3");
  534. compileRecurse(Tree->nodes[2], newTable, tables, procedures);
  535. pop();
  536. cout << "div $5, $3" << endl;
  537. cout << "mfhi $3" << endl;
  538. }
  539. else if (Tree->rule == "factor NUM") {
  540. string NUM = Tree->nodes[0]->tokens[1];
  541. cout << "lis $3" << endl;
  542. cout << ".word " + NUM << endl;
  543. }
  544. else if (Tree->ifTerminal && Tree->tokens[0] == "NUM") {
  545. cout << "lis $3" << endl;
  546. cout << ".word " << Tree->tokens[1] << endl;
  547. }
  548. else if (Tree->rule == "test expr LT expr") {
  549. compileRecurse(Tree->nodes[0], newTable, tables, procedures);
  550. push("$3");
  551. compileRecurse(Tree->nodes[2], newTable, tables, procedures);
  552. pop();
  553. cout << "slt $3, $5, $3" << endl;
  554. }
  555. else if (Tree->rule == "test expr GT expr") {
  556. compileRecurse(Tree->nodes[0], newTable, tables, procedures);
  557. push("$3");
  558. compileRecurse(Tree->nodes[2], newTable, tables, procedures);
  559. pop();
  560. cout << "slt $3, $3, $5" << endl;
  561. }
  562. else if (Tree->rule == "test expr LE expr") {
  563. compileRecurse(Tree->nodes[0], newTable, tables, procedures);
  564. push("$3");
  565. compileRecurse(Tree->nodes[2], newTable, tables, procedures);
  566. pop();
  567. cout << "slt $3, $3, $5" << endl;
  568. cout << "sub $3, $11, $3" << endl;
  569. }
  570. else if (Tree->rule == "test expr GE expr") {
  571. compileRecurse(Tree->nodes[0], newTable, tables, procedures);
  572. push("$3");
  573. compileRecurse(Tree->nodes[2], newTable, tables, procedures);
  574. pop();
  575. cout << "slt $3, $5, $3" << endl;
  576. cout << "sub $3, $11, $3" << endl;
  577. }
  578. else if (Tree->rule == "test expr NE expr") {
  579. compileRecurse(Tree->nodes[0], newTable, tables, procedures);
  580. push("$3");
  581. compileRecurse(Tree->nodes[2], newTable, tables, procedures);
  582. pop();
  583. cout << "slt $6, $3, $5" << endl;
  584. cout << "slt $7, $5, $3" << endl;
  585. cout << "add $3, $6, $7" << endl;
  586. }
  587. else if (Tree->rule == "test expr EQ expr") {
  588. compileRecurse(Tree->nodes[0], newTable, tables, procedures);
  589. push("$3");
  590. compileRecurse(Tree->nodes[2], newTable, tables, procedures);
  591. pop();
  592. cout << "slt $6, $3, $5" << endl;
  593. cout << "slt $7, $5, $3" << endl;
  594. cout << "add $3, $6, $7" << endl;
  595. cout << "sub $3, $11, $3" << endl;
  596. }
  597. }
  598.  
  599. void compileDcls(Node* Tree, vector<vector<string>> newTable, vector<vector<vector<string>>*> tables, vector<Node*>* procedures) {
  600. if (Tree->rule == "dcls dcls dcl BECOMES NUM SEMI") {
  601. compileDcls(Tree->nodes[0], newTable, tables, procedures);
  602. string varname = Tree->nodes[1]->nodes[1]->tokens[1];
  603. compileRecurse(Tree->nodes[3], newTable, tables, procedures);
  604.  
  605. string location;
  606. for (int i=0; i < newTable.size(); i++) {
  607. if (newTable[i][0] == varname) {
  608. location = newTable[i][2];
  609. }
  610. }
  611.  
  612. cout << "sw $3, -" + location + "($29)" << endl;
  613. }
  614. }
  615.  
  616. void compileStatement(Node* Tree, vector<vector<string>> newTable, vector<vector<vector<string>>*> tables, vector<Node*>* procedures) {
  617. if (Tree->rule == "statements statements statement") {
  618. compileStatement(Tree->nodes[0], newTable, tables, procedures);
  619. compileStatement(Tree->nodes[1], newTable, tables, procedures);
  620. }
  621. else if (Tree->rule == "statement PRINTLN LPAREN expr RPAREN SEMI") {
  622. cout << "sw $1, -4($30)" << endl;
  623. cout << "sw $31, -8($30)" << endl;
  624. cout << "sub $30, $30, $4" << endl;
  625. cout << "sub $30, $30, $4" << endl;
  626. compileRecurse(Tree->nodes[2], newTable, tables, procedures);
  627. cout << "add $1, $3, $0" << endl;
  628. cout << "lis $10" << endl;
  629. cout << ".word print" << endl;
  630. cout << "jalr $10" << endl; // call print
  631. cout << "add $30, $30, $4" << endl;
  632. cout << "add $30, $30, $4" << endl;
  633. cout << "lw $1, -4($30)" << endl;
  634. cout << "lw $31, -8($30)" << endl;
  635. }
  636. else if (Tree->rule == "statement lvalue BECOMES expr SEMI") {
  637. Node* lvalue = Tree->nodes[0];
  638. while(lvalue->rule == "lvalue LPAREN lvalue RPAREN") {
  639. lvalue = lvalue->nodes[1];
  640. }
  641. string varname = lvalue->nodes[0]->tokens[1];
  642.  
  643. compileRecurse(Tree->nodes[2], newTable, tables, procedures); // set $3 to result of expr
  644. string location;
  645. for (int i=0; i < newTable.size(); i++) {
  646. if (newTable[i][0] == varname) {
  647. location = newTable[i][2];
  648. }
  649. }
  650. cout << "sw $3, -" + location + "($29)" << endl;
  651. }
  652. else if (Tree->rule == "statement WHILE LPAREN test RPAREN LBRACE statements RBRACE") {
  653. int tempCount = ::globalLabelCount;
  654. globalLabelCount++;
  655. cout << "sw" << to_string(tempCount) << ":" << endl;
  656. compileRecurse(Tree->nodes[2], newTable, tables, procedures);
  657. cout << "beq $3, $0, ew" << to_string(tempCount) << endl;
  658. compileStatement(Tree->nodes[5], newTable, tables, procedures);
  659. cout << "beq $0, $0, sw" << to_string(tempCount) << endl;
  660. cout << "ew" << to_string(tempCount) << ":" << endl;
  661. }
  662. else if (Tree->rule == "statement IF LPAREN test RPAREN LBRACE statements RBRACE ELSE LBRACE statements RBRACE") {
  663. int tempCount = ::globalLabelCount;
  664. globalLabelCount++;
  665. compileRecurse(Tree->nodes[2], newTable, tables, procedures);
  666. cout << "beq $3, $0, se" << to_string(tempCount) << endl;
  667. compileStatement(Tree->nodes[5], newTable, tables, procedures);
  668. cout << "beq $0, $0, ee" << to_string(tempCount) << endl;
  669. cout << "se" << to_string(tempCount) << ":" << endl;
  670. compileStatement(Tree->nodes[9], newTable, tables, procedures);
  671. cout << "ee" << to_string(tempCount) << ":" << endl;
  672. }
  673. }
  674.  
  675. void compileWain(vector<vector<vector<string>>*> tables, vector<Node*>* procedures) {
  676. vector<vector<string>> newTable;
  677. for (int i=0; i < tables.size() ; i++) {
  678. if ((*(tables[i]))[0][0] == "wain") {
  679. newTable = *(tables[i]);
  680. break;
  681. }
  682. }
  683.  
  684. Node* Tree;
  685. for (int i=0; i < procedures->size(); i++) {
  686. if ((*procedures)[i]->rule == "procedures main") {
  687. Tree = (*procedures)[i];
  688. break;
  689. }
  690. }
  691.  
  692. int count = 4;
  693. for (int i=1; i < newTable.size(); i++) {
  694. newTable[i].emplace_back(to_string(count));
  695. //cout << newTable[i][0] << " " << newTable[i][1] <<" "<< newTable[i][2]<<endl;
  696. count += 4;
  697. }
  698.  
  699. // prolog, push stack frame
  700. cout << ".import print" << endl;
  701. cout << "lis $4" << endl;
  702. cout << ".word 4" << endl;
  703. cout << "lis $11" << endl;
  704. cout << ".word 1" << endl;
  705. cout << "sw $31,-4($30)" << endl;
  706. cout << "sub $30, $30, $4" << endl;
  707.  
  708. // push space for all parameters and local vars
  709. cout << "add $29, $0, $30" << endl;
  710. cout << "sw $1, -4($30)" << endl;
  711. cout << "sw $2, -8($30)" << endl;
  712. cout << "sub $30, $30, $4" << endl; // param 1
  713. cout << "sub $30, $30, $4" << endl; // param 2
  714.  
  715. int sizeLocalVars = newTable.size() - 3;
  716. for (int i=0; i < sizeLocalVars; i++) { // local vars
  717. cout << "sub $30, $30, $4" << endl;
  718. }
  719.  
  720. // body
  721. Node* dcls = Tree->nodes[0]->nodes[8];
  722. compileDcls(dcls, newTable, tables, procedures);
  723. Node* statements = Tree->nodes[0]->nodes[9];
  724. compileStatement(statements, newTable, tables, procedures);
  725.  
  726. Node* expr = Tree->nodes[0]->nodes[11];
  727. compileRecurse(expr, newTable, tables, procedures);
  728.  
  729. // epilog, pop stack frame
  730. //cout << "lis $12" << endl;
  731. //cout << ".word 12" << endl;
  732. //cout << "add $30, $30, $12" << endl;
  733. cout << "add $30,$30,$4" << endl; // param 1
  734. cout << "add $30,$30,$4" << endl; // param 2
  735. for (int i=0; i < sizeLocalVars; i++) { // local vars
  736. cout << "add $30, $30, $4" << endl;
  737. }
  738. cout << "add $30,$30,$4" << endl;
  739. cout << "lw $31,-4($30)" << endl;
  740. cout << "jr $31" << endl;
  741. }
  742.  
  743. int main() {
  744. Node* Tree = createTree();
  745. vector<Node*>* procedures = new vector<Node*>;
  746. treeParse(Tree, procedures);
  747.  
  748. vector<vector<vector<string>>*> tables;
  749. try {
  750. vector<string> functionList = generateFunctions(procedures); // generate function list and check for function redeclarations
  751.  
  752. for (int i=0; i < procedures->size(); i++) {
  753. vector<vector<string>>* table = new vector<vector<string>>;
  754. Tree = (*procedures)[i];
  755. // Add functions names to table before scanning
  756. vector<string> functionSignature;
  757. string signatureID;
  758. if (Tree->rule != "procedures main") {
  759. signatureID = Tree->nodes[1]->tokens[1];
  760. functionSignature.emplace_back(signatureID);
  761. table->emplace_back(functionSignature);
  762. }
  763. else {
  764. signatureID = "wain";
  765. functionSignature.emplace_back(signatureID);
  766. table->emplace_back(functionSignature);
  767. }
  768.  
  769. vector<string> currentFunctions;
  770. for (int k=0; k < functionList.size(); k++) {
  771. if (functionList[k] == signatureID) {
  772. currentFunctions.emplace_back(functionList[k]);
  773. break;
  774. }
  775. currentFunctions.emplace_back(functionList[k]);
  776. }
  777. declarationScan(Tree, table, currentFunctions);
  778. derivationScan(Tree, table);
  779. tables.emplace_back(table);
  780. }
  781.  
  782. compileWain(tables, procedures);
  783. // printTable(tables, procedures);
  784. }
  785. catch (string msg) { cerr << "ERROR: " << msg << endl; }
  786.  
  787. delete Tree;
  788. delete procedures;
  789. for (int j=0; j < tables.size() ; j++) {
  790. delete tables[j];
  791. }
  792. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement