Пример #1
0
ExprNode* Parser :: ParseMember(ExprNode* left){
    SymbolType *type = left->getType();
    if ( dynamic_cast<TypedefSymbol*>(type))
        type = type->getType();
    StructSymbol *struct_type = 0;
    if(dynamic_cast<PointerSymbol*>(type))
        struct_type = dynamic_cast<StructSymbol*>(dynamic_cast<PointerSymbol*>(type)->pointer);
    else
        struct_type = dynamic_cast<StructSymbol*>(type);
    errorIf(!struct_type, "Left operand of . or -> must be a structure", scan.Get());
    Token* opTok = scan.Get();
    Token* token =scan.GetNext();
    errorIf(token->Type != _IDENTIFIER , "Right operand of . or -> must be a identifier", token);
    string fieldName = token->Value;
    if (!struct_type->m_fields->exists(fieldName))
        fieldName = '%' + fieldName;
    errorIf(!struct_type->m_fields->exists(fieldName), "Undefined field in structure",token);
    scan.Next();
    ExprNode* right = new IdentifierNode(token, dynamic_cast<VarSymbol*>(struct_type->m_fields->find_symbol(fieldName)));
    return new BinOpNode(opTok, left, right);

}
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);

	}

}