Exemple #1
0
    public static ESIR_CastExpression CastExpression(ESIR_Expression expression, ESIR_TypeNode destType)
    {
        var node = ESIR_NodeCache.Shared.TryGetNode(ESIR_NodeKind.CastExpression, expression, destType, out var hash);

        if (node is not null)
        {
            return((ESIR_CastExpression)node);
        }

        var ret = new ESIR_CastExpression(expression, destType);

        if (hash >= 0)
        {
            ESIR_NodeCache.Shared.AddNode(ret, hash);
        }

        return(ret);
    }
Exemple #2
0
    private static ExpressionData CompileExpression_Cast(
        ref PassData passData,
        ref FunctionData funcData,
        ESIR_CastExpression expr
        )
    {
        var origExpr = CompileExpression(ref passData, ref funcData, expr.Expression);
        var destType = StripFirstConst(expr.DestType.Pointer);

        StripFirstConst(ref origExpr);

        var origVal = origExpr.Value !;

        Debug.Assert(origVal is not null);

        ES_TypeInfo *    retType;
        ExpressionSyntax retValue;

        if (IsTypeEquivalent(origExpr.Type, destType))
        {
            retType = destType;

            var origTypeRoslyn = GetRoslynType(origExpr.Type);
            var destTypeRoslyn = GetRoslynType(destType);
            if (!origTypeRoslyn.IsEquivalentTo(destTypeRoslyn))
            {
                retValue = CastExpression(destTypeRoslyn, origVal);
            }
            else
            {
                retValue = origVal;
            }
        }
        else
        {
            switch (origExpr.Type->TypeTag)
            {
            case ES_TypeTag.Int: {
                var intSrc = (ES_IntTypeData *)origExpr.Type;

                if (destType->TypeTag == ES_TypeTag.Int)
                {
                    var intDest = (ES_IntTypeData *)destType;

                    if (intDest->IntSize == intSrc->IntSize && intDest->Unsigned == intSrc->Unsigned)
                    {
                        origExpr.Writable = false;
                        return(origExpr);
                    }

                    var roslynDestType = GetIntType(intDest->IntSize, intDest->Unsigned);
                    retValue = CastExpression(roslynDestType, origVal);
                }
                else if (destType->TypeTag == ES_TypeTag.Float)
                {
                    var floatDest = (ES_FloatTypeData *)destType;

                    var roslynDestType = GetFloatType(floatDest->FloatSize);
                    retValue = CastExpression(roslynDestType, origVal);
                }
                else
                {
                    throw new CompilationException(ES_BackendErrors.FrontendError);
                }

                retType = destType;

                break;
            }

            case ES_TypeTag.Float: {
                var floatSrc = (ES_FloatTypeData *)origExpr.Type;

                if (destType->TypeTag == ES_TypeTag.Float)
                {
                    var floatDest = (ES_FloatTypeData *)destType;

                    if (floatSrc->FloatSize == floatDest->FloatSize)
                    {
                        origExpr.Writable = false;
                        return(origExpr);
                    }

                    var roslynDestType = GetFloatType(floatDest->FloatSize);
                    retValue = CastExpression(roslynDestType, origVal);
                }
                else if (destType->TypeTag == ES_TypeTag.Int)
                {
                    var intDest = (ES_IntTypeData *)destType;

                    var roslynDestType = GetIntType(intDest->IntSize, intDest->Unsigned);
                    retValue = CastExpression(roslynDestType, origVal);
                }
                else
                {
                    throw new CompilationException(ES_BackendErrors.FrontendError);
                }

                retType = destType;

                break;
            }

            default:
                throw new NotImplementedException("Cast not implemented.");
            }
        }

        return(new ExpressionData {
            Type = retType, Value = retValue,
        });
    }