| 15704 | } |
| 15705 | |
| 15706 | void asCCompiler::CompileMathOperator(asCScriptNode *node, asCExprContext *lctx, asCExprContext *rctx, asCExprContext *ctx, eTokenType op) |
| 15707 | { |
| 15708 | // TODO: If a constant is only using 32bits, then a 32bit operation is preferred |
| 15709 | |
| 15710 | // TODO: clean up: This initial part is identical to CompileComparisonOperator. Make a common function out of it |
| 15711 | |
| 15712 | // If either operand is a non-primitive then use the primitive type |
| 15713 | if( !lctx->type.dataType.IsPrimitive() ) |
| 15714 | { |
| 15715 | int l = int(reservedVariables.GetLength()); |
| 15716 | rctx->bc.GetVarsUsed(reservedVariables); |
| 15717 | ImplicitConvObjectToBestMathType(lctx, node); |
| 15718 | reservedVariables.SetLength(l); |
| 15719 | } |
| 15720 | if( !rctx->type.dataType.IsPrimitive() ) |
| 15721 | { |
| 15722 | int l = int(reservedVariables.GetLength()); |
| 15723 | lctx->bc.GetVarsUsed(reservedVariables); |
| 15724 | ImplicitConvObjectToBestMathType(rctx, node); |
| 15725 | reservedVariables.SetLength(l); |
| 15726 | } |
| 15727 | |
| 15728 | // Both types must now be primitives. Implicitly convert them so they match |
| 15729 | asCDataType to; |
| 15730 | if( lctx->type.dataType.IsDoubleType() || rctx->type.dataType.IsDoubleType() ) |
| 15731 | to.SetTokenType(ttDouble); |
| 15732 | else if( lctx->type.dataType.IsFloatType() || rctx->type.dataType.IsFloatType() ) |
| 15733 | to.SetTokenType(ttFloat); |
| 15734 | else if( lctx->type.dataType.GetSizeInMemoryDWords() == 2 || rctx->type.dataType.GetSizeInMemoryDWords() == 2 ) |
| 15735 | { |
| 15736 | // Convert to int64 if both are signed or if one is non-constant and signed |
| 15737 | if( (lctx->type.dataType.IsIntegerType() && !lctx->type.isConstant) || |
| 15738 | (rctx->type.dataType.IsIntegerType() && !rctx->type.isConstant) ) |
| 15739 | to.SetTokenType(ttInt64); |
| 15740 | else if( lctx->type.dataType.IsUnsignedType() || rctx->type.dataType.IsUnsignedType() ) |
| 15741 | to.SetTokenType(ttUInt64); |
| 15742 | else |
| 15743 | to.SetTokenType(ttInt64); |
| 15744 | } |
| 15745 | else |
| 15746 | { |
| 15747 | // Convert to int32 if both are signed or if one is non-constant and signed |
| 15748 | if( (lctx->type.dataType.IsIntegerType() && !lctx->type.isConstant) || |
| 15749 | (rctx->type.dataType.IsIntegerType() && !rctx->type.isConstant) ) |
| 15750 | to.SetTokenType(ttInt); |
| 15751 | else if( lctx->type.dataType.IsUnsignedType() || rctx->type.dataType.IsUnsignedType() ) |
| 15752 | to.SetTokenType(ttUInt); |
| 15753 | else |
| 15754 | to.SetTokenType(ttInt); |
| 15755 | } |
| 15756 | |
| 15757 | // If doing an operation with double constant and float variable, the constant should be converted to float |
| 15758 | if( (lctx->type.isConstant && lctx->type.dataType.IsDoubleType() && !rctx->type.isConstant && rctx->type.dataType.IsFloatType()) || |
| 15759 | (rctx->type.isConstant && rctx->type.dataType.IsDoubleType() && !lctx->type.isConstant && lctx->type.dataType.IsFloatType()) ) |
| 15760 | to.SetTokenType(ttFloat); |
| 15761 | |
| 15762 | if( op == ttUnrecognizedToken ) |
| 15763 | op = node->tokenType; |
nothing calls this directly
no test coverage detected