CodeGenerator::CodeGenerator(ISymtable* symtable, TreeObject* tree, wchar_t* file) { wb = new WriteBuffer(file); str = new char[200]; s = symtable; makeCode(tree); wb->writeLine("\0"); delete wb; delete[] str; }
constexpr Code makeCode(const char* str, std::uint64_t index) { // TODO: compressionTable[static_cast<unsigned char>(*s)] should go into its own function return *str == 0 ? Code{0, 0} : (index >= 20 || compressionTable[static_cast<unsigned char>(*str)] == 99 ? throw IdentifierTooLongOrWrongChar() : orBits(makeCode(str + 1, index + 1), Code{ index < 10 ? compressionTable[static_cast<unsigned char>(*str)] << (index * 6) : 0u, index >= 10 ? compressionTable[static_cast<unsigned char>(*str)] << ((index - 10) * 6) : 0u })); }
void CodeGenerator::makeCode(TreeObject* node) { static unsigned long markeCount = 0; unsigned long marke; switch ((TreeNode::Type)(node->getType())) { case TreeNode::PROG: makeCode(node->getChild(0)); // DECLS makeCode(node->getChild(1)); // STATEMENTS wb->writeLine("STP\n"); // Programm Stopp break; case TreeNode::DECLS_DECL: makeCode(node->getChild(0)); // DECL makeCode(node->getChild(1)); // DECLS break; case TreeNode::DECLS_e: break; case TreeNode::DECL: wb->writeLine("DS "); // makeCode(node->getChild(0)); // TYPE makeTerminal(node->getChild(2)); // identifier makeCode(node->getChild(1)); // ARRAY wb->writeLine("\n"); break; case TreeNode::TYPE_int: break; case TreeNode::TYPE_float: break; case TreeNode::ARRAY_Index: makeTerminal(node->getChild(0)); break; case TreeNode::ARRAY_e: wb->writeLine("1"); break; case TreeNode::STATEMENTS_STATEMENT: makeCode(node->getChild(0)); // Statement makeCode(node->getChild(1)); // Statements break; case TreeNode::STATEMENTS_e: wb->writeLine("NOP\n"); break; case TreeNode::STATEMENT_identifier: makeCode(node->getChild(2)); wb->writeLine("LA "); makeTerminal(node->getChild(0)); makeCode(node->getChild(1)); wb->writeLine("\nSTR\n"); break; case TreeNode::STATEMENT_write: makeCode(node->getChild(0)); if(node->getChild(0)->getSemanticType() == TreeObject::intType){ wb->writeLine("PRI\n"); }else wb->writeLine("PRF\n"); break; case TreeNode::STATEMENT_read: if(s->lookup(node->getChild(0)->getToken()->getLexeme()) ->getSemanticType() == TreeObject::intType || s->lookup(node->getChild(0)->getToken()->getLexeme()) ->getSemanticType() == TreeObject::arrayIntType){ wb->writeLine("RDI\n"); } else wb->writeLine("RDF\n"); wb->writeLine("LA "); makeTerminal(node->getChild(0)); makeCode(node->getChild(1)); wb->writeLine("\nSTR\n"); break; case TreeNode::STATEMENT_Brackets: makeCode(node->getChild(0)); break; case TreeNode::STATEMENT_if: marke = markeCount; // aktuelle Marke (2 Marken) lokal merken markeCount += 2; // 2 Marken überspringen makeCode(node->getChild(0)); sprintf_s(str, 200, "JIN *IF%i\n", marke); //marke 1?? wb->writeLine(str); makeCode(node->getChild(1)); sprintf_s(str, 200, "JMP *IF%i\n*IF%i NOP\n", marke + 1, marke); //marke 2?? wb->writeLine(str); makeCode(node->getChild(2)); sprintf_s(str, 200, "*IF%i NOP\n", marke + 1); wb->writeLine(str); break; case TreeNode::STATEMENT_while: marke = markeCount; // aktuelle Marke (2 Marken) lokal merken markeCount += 2; // 2 Marken überspringen sprintf_s(str, 200, "*W%i NOP\n", marke); //marke 1?? wb->writeLine(str); makeCode(node->getChild(0)); sprintf_s(str, 200, "JIN *W%i\n", marke + 1); wb->writeLine(str); makeCode(node->getChild(1)); sprintf_s(str, 200, "JMP *W%i\n*W%i NOP\n", marke, marke + 1); wb->writeLine(str); break; case TreeNode::EXP: makeCode(node->getChild(0)); if(node->getChild(1)->getSemanticType() == TreeObject::noType){ break; } makeCode(node->getChild(1)); if (node->getChild(0)->getType() != TreeNode::OP_AND) { if(node->getChild(1)->getSemanticType() == TreeObject::intType) wb->writeLine("I\n"); else wb->writeLine("F\n"); } break; case TreeNode::EXP2_Brackets: makeCode(node->getChild(0)); break; case TreeNode::EXP2_identifier: wb->writeLine("LA "); makeTerminal(node->getChild(0)); makeCode(node->getChild(1)); wb->writeLine("\nLV\n"); break; case TreeNode::EXP2_integer: wb->writeLine("LC "); makeTerminal(node->getChild(0)); wb->writeLine("\n"); break; case TreeNode::EXP2_real: wb->writeLine("LC "); makeTerminal(node->getChild(0)); wb->writeLine("\n"); break; case TreeNode::EXP2_Minus: wb->writeLine("LC "); if(node->getChild(0)->getSemanticType() == TreeObject::intType) wb->writeLine("0\n"); else wb->writeLine("0.0\n"); makeCode(node->getChild(0)); if(node->getChild(0)->getSemanticType() == TreeObject::intType) wb->writeLine("SBI\n"); else wb->writeLine("SBF\n"); break; case TreeNode::EXP2_EM: // Exclamation Mark makeCode(node->getChild(0)); wb->writeLine("NOT\n"); break; case TreeNode::EXP2_float: makeCode(node->getChild(0)); if(node->getChild(0)->getSemanticType() == TreeObject::intType) { wb->writeLine("FLT\n"); } break; case TreeNode::INDEX_Brackets: makeCode(node->getChild(0)); wb->writeLine("ADI\n"); break; case TreeNode::INDEX_e: break; case TreeNode::OP_EXP_OP: makeCode(node->getChild(1)); makeCode(node->getChild(0)); break; case TreeNode::OP_EXP_e: break; case TreeNode::OP_PLUS: wb->writeLine("AD"); break; case TreeNode::OP_MINUS: wb->writeLine("SB"); break; case TreeNode::OP_MULTIPLY: wb->writeLine("ML"); break; case TreeNode::OP_DEVIDE: wb->writeLine("DV"); break; case TreeNode::OP_LT: wb->writeLine("LS"); break; case TreeNode::OP_EQ: wb->writeLine("EQ"); break; case TreeNode::OP_AND: wb->writeLine("AND"); break; } }
void MenuScreen::handleEvent(SDL_Event &e) { if (e.type != SDL_KEYDOWN) return; if (pwdMode) { if (e.key.keysym.sym >= SDLK_a && e.key.keysym.sym <= SDLK_z) { if (pwdLen == 6) { playSample(findSample(makeCode("slct"))); return; } playSample(findSample(makeCode("tick"))); pwd[pwdLen++] = 'a'+(e.key.keysym.sym-SDLK_a); return; } if (e.key.keysym.sym == SDLK_BACKSPACE) { if (!pwdLen) { playSample(findSample(makeCode("slct"))); return; } playSample(findSample(makeCode("tick"))); pwdLen--; return; } if (e.key.keysym.sym == SDLK_RETURN) { playSample(findSample(makeCode("tick"))); if (pwdLen == 6) { pwd[6] = 0; game->newGame(pwd); e.key.keysym.sym = SDLK_a; game->activate(); } pwdMode = false; return; } if (e.key.keysym.sym == SDLK_ESCAPE) pwdMode = false; return; } switch (e.key.keysym.sym) { case SDLK_DOWN: if (opt == 3) opt = 0; else opt++; playSample(findSample(makeCode("slct"))); break; case SDLK_UP: if (opt) opt--; else opt = 3; playSample(findSample(makeCode("slct"))); break; case SDLK_SPACE: case SDLK_RETURN: { playSample(findSample(makeCode("tick"))); switch (opt) { case 0: game->newGame(); game->activate(); break; case 1: pwdLen = 0; pwdMode = true; break; case 2: imageScreen->showImage(this, "data/objects/credits.ut"); break; case 3: running = false; break; } break; } case SDLK_ESCAPE: if (game->playing) game->activate(); break; default:; } }
void ParseTree::makeCode(Node* node) { if (!node) return; switch (node->getRule()) { // ROOT ::= PROG case ParseEnums::ROOT: makeCode(node->getChildNode(0)); break; // PROG ::= DECLS STATEMENTS case ParseEnums::PROG: makeCode(node->getChildNode(0)); makeCode(node->getChildNode(1)); buffer->addchars("STP\r\n"); break; // DECLS ::= DECL; DECLS case ParseEnums::DECLS: makeCode(node->getChildNode(0)); if (node->getChildNode(2)) makeCode(node->getChildNode(2)); break; // DECL ::= int ARRAY identifier case ParseEnums::DECL: buffer->addchars("DS $"); buffer->addchars(node->getChildNode(2)->getToken()->getEntry()->getLexem()); buffer->addchars(" "); makeCode(node->getChildNode(1)); break; // ARRAY ::= [ integer ] case ParseEnums::ARRAY: if (node->getChildNodesCount() != 1) { buffer->addchars(node->getChildNode(1)->getToken()->getValue()); buffer->addchars("\r\n"); } else { buffer->addchars("1\r\n"); } break; // STATEMENTS ::= STATEMENT; STATEMENTS case ParseEnums::STATEMENTS: makeCode(node->getChildNode(0)); if (node->getChildNode(2)) makeCode(node->getChildNode(2)); else buffer->addchars("NOP\r\n"); break; // STATEMENT case ParseEnums::STATEMENT: int m1, m2; switch (node->getChildNode(0)->getToken()->getType()) { // STATEMENT ::= identifier INDEX = EXP case IDENTIFIER: makeCode(node->getChildNode(3)); buffer->addchars("LA $"); buffer->addchars(node->getChildNode(0)->getToken()->getEntry()->getLexem()); buffer->addchars("\r\n"); makeCode(node->getChildNode(1)); buffer->addchars("STR\r\n"); break; // STATEMENT ::= print ( EXP ) case PRINT: makeCode(node->getChildNode(2)); buffer->addchars("PRI\r\n"); break; // STATEMENT ::= read ( identifier INDEX ) case T_READ: buffer->addchars("REA\r\n"); buffer->addchars("LA $"); buffer->addchars(node->getChildNode(2)->getToken()->getEntry()->getLexem()); buffer->addchars("\r\n"); makeCode(node->getChildNode(3)); buffer->addchars("STR\r\n"); break; // STATEMENT ::= { STATEMENTS } case SIGN_LEFTANGLEBRACKET: makeCode(node->getChildNode(1)); break; // STATEMENT ::= if ( EXP ) STATEMENT else STATEMENT case IF: m1 = marker++; m2 = marker++; makeCode(node->getChildNode(2)); buffer->addchars("JIN #m"); buffer->addchars(m1); buffer->addchars("\r\n"); makeCode(node->getChildNode(4)); buffer->addchars("JMP #m"); buffer->addchars(m2); buffer->addchars("\r\n"); buffer->addchars("#m"); buffer->addchars(m1); buffer->addchars(" NOP\r\n"); makeCode(node->getChildNode(6)); buffer->addchars("#m"); buffer->addchars(m2); buffer->addchars(" NOP\r\n"); break; // STATEMENT ::= while ( EXP ) STATEMENT case WHILE: m1 = marker++; m2 = marker++; buffer->addchars("#m"); buffer->addchars(m1); buffer->addchars(" NOP\r\n"); makeCode(node->getChildNode(2)); buffer->addchars("JIN #m"); buffer->addchars(m2); buffer->addchars("\r\n"); makeCode(node->getChildNode(4)); buffer->addchars("JMP #m"); buffer->addchars(m1); buffer->addchars("\r\n"); buffer->addchars("#m"); buffer->addchars(m2); buffer->addchars(" NOP\r\n"); break; default: break; } break; // EXP ::= EXP2 OP_EXP case ParseEnums::EXP: if(node->getChildNode(1)->getType() == ParseEnums::NOTYPE) { makeCode(node->getChildNode(0)); } else if (node->getChildNode(1)->getChildNode(0)->getType() == ParseEnums::OPGREATER) { makeCode(node->getChildNode(1)); makeCode(node->getChildNode(0)); buffer->addchars("LES\r\n"); } else if (node->getChildNode(1)->getChildNode(0)->getType() == ParseEnums::OPUNEQUAL) { makeCode(node->getChildNode(0)); makeCode(node->getChildNode(1)); buffer->addchars("NOT\r\n"); } else { makeCode(node->getChildNode(0)); makeCode(node->getChildNode(1)); } break; // INDEX ::= [ EXP ] | empty case ParseEnums::INDEX: if (node->getChildNodesCount() > 1) { makeCode(node->getChildNode(1)); buffer->addchars("ADD\r\n"); } break; // EXP2 case ParseEnums::EXP2: switch (node->getChildNode(0)->getToken()->getType()) { // EXP2 ::= ( EXP ) case SIGN_LEFTBRACKET: makeCode(node->getChildNode(1)); break; // EXP2 ::= identifier INDEX case IDENTIFIER: buffer->addchars("LA $"); buffer->addchars(node->getChildNode(0)->getToken()->getEntry()->getLexem()); buffer->addchars("\r\n"); makeCode(node->getChildNode(1)); buffer->addchars("LV\r\n"); break; // EXP2 ::= integer case INTEGER: buffer->addchars("LC "); buffer->addchars(node->getChildNode(0)->getToken()->getValue()); buffer->addchars("\r\n"); break; // EXP2 ::= - EXP2 case SIGN_SUBTRACTION: buffer->addchars("LC 0\r\n"); makeCode(node->getChildNode(1)); buffer->addchars("SUB\r\n"); break; // EXP2 ::= ! EXP2 case SIGN_EXCLAMATION: makeCode(node->getChildNode(1)); buffer->addchars("NOT\r\n"); break; default: break; } break; // OP_EXP ::= OP EXP | empty case ParseEnums::OP_EXP: if (node->getChildNodesCount() > 1) { makeCode(node->getChildNode(1)); makeCode(node->getChildNode(0)); } break; // OP case ParseEnums::OP: switch (node->getChildNode(0)->getToken()->getType()) { // OP ::= + case SIGN_ADDITITON: buffer->addchars("ADD\r\n"); break; // OP ::= - case SIGN_SUBTRACTION: buffer->addchars("SUB\r\n"); break; // OP ::= * case SIGN_MULTIPLICATION: buffer->addchars("MUL\r\n"); break; // OP ::= / case SIGN_DIVISION: buffer->addchars("DIV\r\n"); break; // OP ::= < case SIGN_LT: buffer->addchars("LES\r\n"); break; // OP ::= > case SIGN_GT: break; // OP ::= = case SIGN_ASSIGN: buffer->addchars("EQU\r\n"); break; // OP ::= <=> case SIGN_NE: buffer->addchars("EQU\r\n"); break; // OP ::= & case SIGN_AMPERSAND: buffer->addchars("AND\r\n"); break; default: break; } break; default: break; } }