Exemplo n.º 1
0
char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer, Value::ValueType integerType ) {
    *integer = ddl_nullptr;
    if( ddl_nullptr == in || in == end ) {
        return in;
    }

    if( !(isIntegerType( integerType ) || isUnsignedIntegerType(integerType)) ) {
        return in;
    }

    in = lookForNextToken( in, end );
    char *start( in );
    while( !isSeparator( *in ) && in != end ) {
        ++in;
    }

    if( isNumeric( *start ) ) {
#ifdef OPENDDL_NO_USE_CPP11
        const int64 value( atol( start ) ); // maybe not really 64bit as atoll is but exists without c++11
        const uint64 uvalue( strtoul( start,ddl_nullptr,10 ) );
#else
        const int64 value( atoll( start ) );
        const uint64 uvalue( strtoull( start,ddl_nullptr,10 ) );
#endif
        *integer = ValueAllocator::allocPrimData( integerType );
        switch( integerType ) {
            case Value::ddl_int8:
                ( *integer )->setInt8( (int8) value );
                break;
            case Value::ddl_int16:
                ( *integer )->setInt16( ( int16 ) value );
                break;
            case Value::ddl_int32:
                ( *integer )->setInt32( ( int32 ) value );
                break;
            case Value::ddl_int64:
                ( *integer )->setInt64( ( int64 ) value );
                break;
            case Value::ddl_unsigned_int8:
                ( *integer )->setUnsignedInt8( (uint8) uvalue );
                break;
            case Value::ddl_unsigned_int16:
                ( *integer )->setUnsignedInt16( ( uint16 ) uvalue );
                break;
            case Value::ddl_unsigned_int32:
                ( *integer )->setUnsignedInt32( ( uint32 ) uvalue );
                break;
            case Value::ddl_unsigned_int64:
                ( *integer )->setUnsignedInt64( ( uint64 ) uvalue );
                break;
            default:
                break;
        }
    }

    return in;
}
Exemplo n.º 2
0
llvm::Value* genFloatPrimitiveMethodCall(Function& function, const SEM::Type* type, const String& methodName, const SEM::FunctionType functionType,
        llvm::ArrayRef<SEM::Value> templateArgs, PendingResultArray args, llvm::Value* const hintResultValue) {
    auto& module = function.module();
    auto& builder = function.getBuilder();

    const auto& typeName = type->getObjectType()->name().first();

    const auto methodID = module.context().getMethodID(CanonicalizeMethodName(methodName));

    const auto methodOwner = methodID.isConstructor() ? nullptr : args[0].resolveWithoutBind(function);

    if (methodName == "__move_to") {
        const auto moveToPtr = args[1].resolve(function);
        const auto moveToPosition = args[2].resolve(function);

        const auto destPtr = builder.CreateInBoundsGEP(moveToPtr, moveToPosition);
        const auto castedDestPtr = builder.CreatePointerCast(destPtr, genPointerType(module, type));

        genMoveStore(function, methodOwner, castedDestPtr, type);
        return ConstantGenerator(module).getVoidUndef();
    } else if (methodName == "create") {
        return ConstantGenerator(module).getPrimitiveFloat(typeName, 0.0);
    } else if (methodName == "__setdead" || methodName == "__set_dead") {
        // Do nothing.
        return ConstantGenerator(module).getVoidUndef();
    } else if (methodName == "__islive" || methodName == "__is_live") {
        return ConstantGenerator(module).getI1(true);
    } else if (methodName.starts_with("implicit_cast_") || methodName.starts_with("cast_")) {
        const auto argType = functionType.parameterTypes().front();
        const auto operand = args[0].resolve(function);
        const auto selfType = genType(module, type);
        if (isFloatType(module, argType)) {
            if (methodName.starts_with("implicit_cast_")) {
                return builder.CreateFPExt(operand, selfType);
            } else {
                return builder.CreateFPTrunc(operand, selfType);
            }
        } else if (isUnsignedIntegerType(module, argType)) {
            return builder.CreateUIToFP(operand, selfType);
        } else if (isSignedIntegerType(module, argType)) {
            return builder.CreateSIToFP(operand, selfType);
        } else {
            llvm_unreachable("Unknown float cast source type.");
        }
    } else if (isUnaryOp(methodName)) {
        const auto zero = ConstantGenerator(module).getPrimitiveFloat(typeName, 0.0);

        if (methodName == "implicit_cast" || methodName == "cast") {
            return callCastMethod(function, methodOwner, type, methodName, templateArgs.front().typeRefType(), hintResultValue);
        } else if (methodName == "implicit_copy" || methodName == "copy" || methodName == "plus") {
            return methodOwner;
        } else if (methodName == "minus") {
            return builder.CreateFNeg(methodOwner);
        } else if (methodName == "isZero") {
            return builder.CreateFCmpOEQ(methodOwner, zero);
        } else if (methodName == "isPositive") {
            return builder.CreateFCmpOGT(methodOwner, zero);
        } else if (methodName == "isNegative") {
            return builder.CreateFCmpOLT(methodOwner, zero);
        } else if (methodName == "abs") {
            // Generates: (value < 0) ? -value : value.
            const auto lessThanZero = builder.CreateFCmpOLT(methodOwner, zero);
            return builder.CreateSelect(lessThanZero, builder.CreateFNeg(methodOwner), methodOwner);
        } else if (methodName == "sqrt") {
            llvm::Type* const intrinsicTypes[] = { methodOwner->getType() };
            const auto sqrtIntrinsic = llvm::Intrinsic::getDeclaration(module.getLLVMModulePtr(), llvm::Intrinsic::sqrt, intrinsicTypes);
            llvm::Value* const sqrtArgs[] = { methodOwner };
            return builder.CreateCall(sqrtIntrinsic, sqrtArgs);
        } else {
            llvm_unreachable("Unknown primitive unary op.");
        }
    } else if (isBinaryOp(methodName)) {
        const auto operand = args[1].resolveWithoutBind(function);

        if (methodName == "add") {
            return builder.CreateFAdd(methodOwner, operand);
        } else if (methodName == "subtract") {
            return builder.CreateFSub(methodOwner, operand);
        } else if (methodName == "multiply") {
            return builder.CreateFMul(methodOwner, operand);
        } else if (methodName == "divide") {
            return builder.CreateFDiv(methodOwner, operand);
        } else if (methodName == "modulo") {
            return builder.CreateFRem(methodOwner, operand);
        } else if (methodName == "equal") {
            return builder.CreateFCmpOEQ(methodOwner, operand);
        } else if (methodName == "not_equal") {
            return builder.CreateFCmpONE(methodOwner, operand);
        } else if (methodName == "less_than") {
            return builder.CreateFCmpOLT(methodOwner, operand);
        } else if (methodName == "less_than_or_equal") {
            return builder.CreateFCmpOLE(methodOwner, operand);
        } else if (methodName == "greater_than") {
            return builder.CreateFCmpOGT(methodOwner, operand);
        } else if (methodName == "greater_than_or_equal") {
            return builder.CreateFCmpOGE(methodOwner, operand);
        } else if (methodName == "compare") {
            const auto isLessThan = builder.CreateFCmpOLT(methodOwner, operand);
            const auto isGreaterThan = builder.CreateFCmpOGT(methodOwner, operand);
            const auto minusOne = ConstantGenerator(module).getI8(-1);
            const auto zero = ConstantGenerator(module).getI8(0);
            const auto plusOne = ConstantGenerator(module).getI8(1);
            return builder.CreateSelect(isLessThan, minusOne,
                                        builder.CreateSelect(isGreaterThan, plusOne, zero));
        } else {
            llvm_unreachable("Unknown primitive binary op.");
        }
    } else {
        printf("%s\n", methodName.c_str());
        llvm_unreachable("Unknown primitive method.");
    }
}