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;
}
Exemple #2
0
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;
	}
}
Exemple #4
0
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:;
	}
}
Exemple #5
0
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;
    }
}