void BinOpNode::generateLvalue(AsmCode& code){
	string value = token->Value;
	if (value == "+"){
		
			SymbolType *type = left->getType();
		if (dynamic_cast<ArraySymbol*>(type))
			left->generateLvalue(code);
		else if (dynamic_cast<PointerSymbol*>(type))
			left->generate(code);
		SymbolType *t = type->upType();
			right->generate(code);
		
			code.add(_POP, _EAX)
				.add(_MOV, _EBX, to_string(t->byteSize()))
				.add(_IMUL, _EAX, _EBX)
				.add(_POP, _EBX)
				.add(_ADD, _EAX, _EBX)
				.add(_PUSH, _EAX);
			t = t->upType();
		
		
	}
	else	if (isAssing(token)){ 
		generate(code);
		code.add(_POP, _EAX);
		left->generateLvalue(code);
	}
	else
		throw MyException("Compiler error");
}
void FuncCallNode::generate(AsmCode& code){
	code.add(_SUB, _ESP, to_string(symbol->value->byteSize()));
	for (int i = args.size() - 1; i > -1; i--)
		args[i]->generate(code);
	code.add(_CALL, new AsmLabelArg("f_" + name->token->Value))
		.add(_ADD, _ESP, to_string(symbol->params->byteSize()));
}
void UnOpNode::generate(AsmCode & code) {
	SymbolType* type = operand->getType();


	string op = token->Value;

	if (op == "++" || op == "--" || op == "*" || op == "&") 
		operand->generateLvalue(code);
	else 
		operand->generate(code);

	if (token->Value == "*"){
		if (dynamic_cast<PointerSymbol*>(type))
			code.add(_POP, _EAX)
				.add(_MOV, new AsmRegArg(_EBX), new AsmIndirectArg(_EAX))
				.add(_PUSH, _EBX);
		else
			code.add(_POP, _EAX)
				.add(_MOV, new AsmRegArg(_EBX), new AsmIndirectArg(_EAX))
				.add(_PUSH, new AsmIndirectArg(_EBX));
		
	}



	else if (token->Value == "!"){

		code.add(_POP, _EAX)
			.add(_XOR, _EBX, _EBX)
			.add(_CMP, _EAX, 0)
			.add(_SETE, _BL)
			.add(_PUSH, _EBX);

	}


	else if (token->Value == "+"){

	}

	else if (token->Value == "-"){
		code.add(_POP, _EAX)
			.add(_NEG, _EAX)
			.add(_PUSH, _EAX);

	}

	else if (token->Value == "++"){
		generateOperationIncDec(type, code, _INC);

	}

	else if (token->Value == "--"){
		generateOperationIncDec(type, code, _DEC);


	}
}
void FuncSymbol::generate(AsmCode &code, const string &str) const {
	code.add(new AsmLabelArg("f_" + str))
		.add(_PUSH, _EBP)
		.add(_MOV, _EBP, _ESP);
	body->generate(code);
	code.add(_MOV, _ESP, _EBP)
		.add(_POP, _EBP)
		.add(_RET, new AsmIntArg("0"));
}
Пример #5
0
void IdentifierNode::generateLvalue(AsmCode &code) {
	if(var->global)
		code.add(cmdPUSH, makeArgMemory("var_" + var->name, true));
	else
		code.add(cmdMOV, EAX, EBP)
			.add(cmdMOV, EBX, var->offset)
			.add(cmdADD, EAX, EBX)
			.add(cmdPUSH, EAX);
}
void IdentifierNode::generateLvalue(AsmCode &code) {
	if (var->global)
		code.add(_PUSH, new AsmMemoryArg("var_" + var->name, true));
	else
		code.add(_MOV, _EAX, _EBP)
		.add(_MOV, _EBX, to_string(var->offset))
		.add(_ADD, _EAX, _EBX);
        code.add(_PUSH, _EAX);
}
Пример #7
0
void IdentifierNode::generate(AsmCode &code) {
	int size = var->byteSize();
	int steps = size / 4 + (size % 4 != 0);
	if (var->global)
		for (int i = 0; i < steps; i++)
			code.add(cmdPUSH, makeArgMemory("dword ptr [var_" + var->name + " + " + to_string(4 * (steps - i - 1)) +"]"));
	else
		for (int i = 0; i < steps; i++)
			code.add(cmdPUSH, makeIndirectArg(EBP, var->offset + 4 * (steps - i - 1)));
}
static void generateOperationAssing(SymbolType * type, AsmCode & code, Commands cmd, Registers reg = _EAX) {
	code.add(_POP, _EBX)
		.add(_POP, _ECX);

	if (type->getType() == CharType) {
		code.add(_XOR, _EAX, _EAX)
			.add(_MOV, new AsmRegArg(_AL), new AsmIndirectArg(_ECX));

	}
	else {
		code.add(_MOV, new AsmRegArg(_EAX), new AsmIndirectArg(_ECX));
	}

	code.add(_XOR, _EDX, _EDX);

	if (cmd == _IDIV || cmd == _IMUL) code.add(cmd, _EBX);
	else code.add(cmd, _EAX, _EBX);
	if (type->getType() == CharType) {
	Registers byteReg = reg == _EAX ? _AL : _DL;
		code.add(_MOV, new AsmIndirectArg(_ECX), new AsmRegArg(byteReg))
			.add(_XOR, reg, reg)
			.add(_MOV, new AsmRegArg(byteReg), new AsmIndirectArg(_ECX));

	}
	else {
		code.add(_MOV, new AsmIndirectArg(_ECX), new AsmRegArg(reg));
	}

	code.add(_PUSH, reg);
}
static void generateOperation(AsmCode & code, Commands cmd, Registers reg = _EAX) {
	code.add(_POP, _EBX)
		.add(_POP, _EAX)

		.add(_XOR, _EDX, _EDX);

	if (cmd == _IDIV || cmd == _IMUL) code.add(cmd, _EBX);
	else code.add(cmd, _EAX, _EBX);

	code.add(_PUSH, reg);
}
static void generateOperationShift(AsmCode & code, Commands cmd) {
	code.add(_POP, _EAX)
		.add(_POP, _EBX)
		.add(_MOV, _ECX, _EAX)
		.add(cmd, _EBX, _CL)
		.add(_PUSH, _EBX);
}
void ArrNode::generate(AsmCode &code){
    generateLvalue(code);
	code.add(_PUSH, new AsmIndirectArg(_EAX))
		.add(_POP, _EAX)
		.add(_POP, _ECX)
		.add(_PUSH, new AsmRegArg(_EAX));

}
static void generateCmp(AsmCode & code, Commands cmd) {
	code.add(_POP, _EBX)
		.add(_POP, _EAX)
		.add(_XOR, _ECX, _ECX)
		.add(_CMP, _EAX, _EBX)
		.add(cmd, _CL)
		.add(_PUSH, _ECX);
}
static void generateOperationIncDec(SymbolType* type, AsmCode & code, Commands cmd) {
	code.add(_POP, _EAX);

	if (type->getType() == CharType) {
		code.add(_XOR, _EBX, _EBX)
			.add(_MOV, new AsmRegArg(_BL), new AsmIndirectArg(_EAX));

	}
	else {
		code.add(_MOV, new AsmRegArg(_EBX), new AsmIndirectArg(_EAX));
	}

	code.add(cmd, _EBX);

	if (type->getType() == CharType) {
		code.add(_MOV, new AsmIndirectArg(_EAX), new AsmRegArg(_BL))
			.add(_XOR, _EBX, _EBX)
			.add(_MOV, new AsmRegArg(_BL), new AsmIndirectArg(_EAX))
			.add(_PUSH, new AsmRegArg(_EAX));


	}
	else {
		code.add(_MOV, new AsmIndirectArg(_EAX), new AsmRegArg(_EBX));
	}

	code.add(_PUSH, _EBX);
}
void IONode::generate(AsmCode& code){
	int size = 0;

	for (int i = args.size() - 1; i >= 0; i--) {
		size += args[i]->getType()->byteSize();
		size = (size / 4 + (size % 4 != 0)) * 4;

		args[i]->generate(code);
	}

	format->generate(code);

	size += format->getType()->byteSize();
	size = (size / 4 + (size % 4 != 0)) * 4 ;
	code.add(_CALL, new AsmMemoryArg("dword ptr __imp__printf"));

	code.add(_ADD, _ESP, to_string(size));
}
void Block::generate(AsmCode &code){
    for(int i = 0; i < size(); i++){
        body[i]->generate(code);
        if(body[i]->isExpression()){
            SymbolType *type = body[i]->getType();
            if(type && type->byteSize())
                code.add(_POP, _EAX);
        }
    }
}
static void generateOperationPointer(AsmCode & code, Commands cmd, int shift, bool rightPointerFlag) {
	Registers reg1 = _EAX, reg2 = _EBX;
	if (rightPointerFlag) {
		reg1 = _EBX;
		reg2 = _EAX;
	}

	code.add(_POP, _EAX)
		.add(_POP, _EBX)
		.add(_MOV, _ECX, to_string(shift))
		.add(_IMUL, reg1, _ECX)
		.add(cmd, reg2, reg1)
		.add(_PUSH, reg2);
}
void ArrNode::generateLvalue(AsmCode &code){
    SymbolType *type = name->getType();
    if(dynamic_cast<ArraySymbol*>(type))
        name->generateLvalue(code);
    else if(dynamic_cast<PointerSymbol*>(type))
        name->generate(code);
    SymbolType *t = type->upType();
    for(int i = 0; i < args.size(); i++){
        args[i]->generate(code);
        code.add(_POP, _EAX)
        .add(_MOV, _EBX, to_string(t->byteSize()))
        .add(_IMUL, _EAX, _EBX)
        .add(_POP, _EBX)
        .add(_ADD, _EAX, _EBX)
        .add(_PUSH, _EAX);
        t = t->upType();
    }
}
static void generateOperationLogic(AsmCode & code, Commands cmd) {
	code.add(_POP, _EBX)
		.add(_POP, _EAX)

		.add(_CMP, _EAX, 0)
		.add(_MOV, _EAX, 0)
		.add(_SETNE, _AL)

		.add(_CMP, _EBX, 0)
		.add(_MOV, _EBX, 0)
		.add(_SETNE, _BL)

		.add(cmd, _EAX, _EBX)

		.add(_CMP, _EAX, 0)
		.add(_MOV, _EAX, 0)
		.add(_SETNE, _AL)
		.add(_PUSH, _EAX);
}
void VarSymbol::generate(AsmCode &code) const {
    int size = type->byteSize();
    code.add(_DD, new AsmMemoryArg("var_" + name), new AsmDup(size / 4 + (size % 4 != 0)));
}
void FloatNode::generate(AsmCode &code){
    code.add(_PUSH, new AsmMemoryArg(constName()));
}
Пример #21
0
void FloatNode::generateLvalue(AsmCode &code){
	code.add(cmdPUSH, makeArgMemory(constName(), true));
}
void StringNode::generate(AsmCode &code){
	code.add(_PUSH, new AsmMemoryArg("offset str" + to_string(index), true));
}
void StringNode::generateData(AsmCode &code){


	code.add(_DB, new AsmMemoryArg("str" + to_string(index)), makeString("\"" + token->Value + "\""));
}
void IntNode::generate(AsmCode &code){
    code.add(_PUSH, new AsmIntArg(token->Value));
}
void CharNode::generate(AsmCode &code){
		code.add(_PUSH, new AsmCharArg(token->Value));
	}
void BinOpNode::generate(AsmCode & code) {
	SymbolType * leftType = left->getType();
	SymbolType * rightType = right->getType();

	ArraySymbol* leftTypeArray = dynamic_cast<ArraySymbol *>(leftType);
	ArraySymbol* rightTypeArray = dynamic_cast<ArraySymbol *>(rightType);
	PointerSymbol* leftTypePointer = dynamic_cast<PointerSymbol *>(leftType);
	PointerSymbol* rightTypePointer = dynamic_cast<PointerSymbol *>(rightType);



	if (isAssing(token)) {
		left->generateLvalue(code);
		right->generate(code);

	}
	else {
		left->generate(code);
		right->generate(code);
	}

	if (token->Value == "+"){
		if (leftTypePointer || rightTypeArray || leftTypeArray || rightTypePointer) {
			int shift;

			if (leftTypeArray) shift = leftTypeArray->getType()->offset;
			if (rightTypeArray) shift = rightTypeArray->getType()->offset;
			if (leftTypePointer) shift = leftTypePointer->getType()->offset;
			if (rightTypePointer) shift = rightTypePointer->getType()->offset;

			if (leftTypePointer) generateOperationPointer(code, _ADD, shift, false);
			else generateOperationPointer(code, _ADD, shift, true);

		}

		generateOperation(code, _ADD);

	}
	else if (token->Value == "-"){
		if (leftTypePointer || rightTypeArray || leftTypeArray || rightTypePointer) {
			int shift;

			if (leftTypeArray) shift = leftTypeArray->getType()->offset;
			if (rightTypeArray) shift = rightTypeArray->getType()->offset;
			if (leftTypePointer) shift = leftTypePointer->getType()->offset;
			if (rightTypePointer) shift = rightTypePointer->getType()->offset;

			if (leftTypePointer && !rightTypePointer) generateOperationPointer(code, _SUB, shift, false);


		}

		generateOperation(code, _SUB);

	}

	else if (token->Value == "*"){
		generateOperation(code, _IMUL);

	}

	else if (token->Value == "/"){

		generateOperation(code, _IDIV);

	}

	else if (token->Value == "%"){

		generateOperation(code, _IDIV, _EDX);

	}

	else if (token->Value == "&"){
		generateOperation(code, _AND);
	}

	else if (token->Value == "|"){
		generateOperation(code, _OR);
	}

	else if (token->Value == "^"){
		generateOperation(code, _XOR);

	}

	else if (token->Value == "<<"){
		generateOperationShift(code, _SHL);

	}

	else if (token->Value == ">>"){
		generateOperationShift(code, _SHR);

	}

	else if (token->Value == "=="){

		generateCmp(code, _SETE);

	}

	else if (token->Value == ">="){

		generateCmp(code, _SETGE);
	}

	else if (token->Value == "<="){
		generateCmp(code, _SETLE);
	}

	else if (token->Value == "!="){

		generateCmp(code, _SETNE);

	}

	else if (token->Value == ">"){
		generateCmp(code, _SETG);
	}

	else if (token->Value == "<"){

		generateCmp(code, _SETL);
	}

	else if (token->Value == "&&"){
		generateOperationLogic(code, _AND);

	}

	else if (token->Value == "||"){

		generateOperationLogic(code, _OR);
	}

	else if (token->Value == "="){
		code.add(_POP, _EBX)
			.add(_POP, _EAX);

		if (!(leftTypePointer || leftTypeArray) && leftType->getType() == CharType) {
			code.add(_MOV, new AsmIndirectArg(_EAX), new AsmRegArg(_BL))
				.add(_XOR, _EBX, _EBX)
				.add(_MOV, new AsmRegArg(_BL), new AsmIndirectArg(_EAX))
				.add(_PUSH, new AsmRegArg(_EAX));
		}
		else {
			code.add(_MOV, new AsmIndirectArg(_EAX), new AsmRegArg(_EBX));
		}

		code.add(_PUSH, _EBX);


	}

	else if (token->Value == "+="){
		if ((leftTypePointer || leftTypeArray)) {
			int shift;
			if (leftTypeArray) shift = leftTypeArray->getType()->offset;
			if (rightTypeArray) shift = rightTypeArray->getType()->offset;
			if (leftTypePointer) shift = leftTypePointer->getType()->offset;
			if (rightTypePointer) shift = rightTypePointer->getType()->offset;
			generateOperationPointer(code, _ADD, shift, false);
		}

		generateOperationAssing(leftType, code, _ADD);

	}

	else if (token->Value == "-="){
		generateOperationAssing(leftType, code, _SUB);

	}

	else if (token->Value == "*="){
		generateOperationAssing(leftType, code, _IMUL);

	}

	else if (token->Value == "/="){
		generateOperationAssing(leftType, code, _IDIV);

	}

	else if (token->Value == "%="){
		generateOperationAssing(leftType, code, _IDIV, _EDX);

	}

	else if (token->Value == "&="){
		generateOperationAssing(leftType, code, _AND);

	}

	else if (token->Value == "|="){

		generateOperationAssing(leftType, code, _OR);

	}

	else if (token->Value == "^="){
		generateOperationAssing(leftType, code, _XOR);

	}

	else if (token->Value == ","){
		code.add(_POP, _EAX)
			.add(_POP, _EBX)
			.add(_PUSH, _EAX);

	}

}