const std::string UlamType::getUlamTypeMangledType() { // e.g. parsing overloaded functions, may not be complete. std::ostringstream mangled; s32 bitsize = getBitSize(); s32 arraysize = getArraySize(); if(isReference()) //includes ALT_ARRAYITEM (t3147); not isAltRefType (t3114) mangled << "r"; //e.g. t3114 if(arraysize > 0) mangled << ToLeximitedNumber(arraysize); // else if(arraysize == 0) // mangled << ToLeximitedNumber(-1); //distinct from scalar else mangled << 10; //scalar NONARRAYSIZE if(bitsize > 0) mangled << ToLeximitedNumber(bitsize); else mangled << 10; std::string ecode(UlamType::getUlamTypeEnumCodeChar(getUlamTypeEnum())); mangled << ToLeximited(ecode).c_str(); return mangled.str(); } //getUlamTypeMangledType
s32 UlamTypePrimitiveInt::bitsizeToConvertTypeTo(ULAMTYPE tobUT) { s32 bitsize = getBitSize(); s32 tobitsize = UNKNOWNSIZE; s32 wordsize = getTotalWordSize(); switch(tobUT) { case Unsigned: tobitsize = bitsize; //unsafe break; case Unary: tobitsize = getMax(); break; case Bool: tobitsize = 1; break; case Int: case Bits: tobitsize = bitsize; //self break; case Void: tobitsize = 0; break; case UAtom: case Class: break; default: m_state.abortUndefinedUlamType(); //std::cerr << "UlamTypePrimitiveInt (convertTo) error! " << tobUT << std::endl; }; return (tobitsize > wordsize ? wordsize : tobitsize); } //bitsizeToConvertTypeTo
bool UlamTypePrimitiveInt::cast(UlamValue & val, UTI typidx) { bool brtn = true; assert(m_state.getUlamTypeByIndex(typidx) == this); UTI valtypidx = val.getUlamValueTypeIdx(); if(UlamType::safeCast(valtypidx) != CAST_CLEAR) //bad|hazy return false; u32 wordsize = getTotalWordSize(); u32 valwordsize = m_state.getTotalWordSize(valtypidx); if(wordsize <= MAXBITSPERINT) { if(valwordsize <= MAXBITSPERINT) brtn = castTo32(val, typidx); else if(valwordsize <= MAXBITSPERLONG) brtn = castTo64(val, typidx); //downcast else m_state.abortGreaterThanMaxBitsPerLong(); } else if(wordsize <= MAXBITSPERLONG) brtn = castTo64(val, typidx); else { std::ostringstream msg; msg << "Casting to an unsupported word size: " << wordsize; msg << ", Value Type and bit size was: "; msg << valtypidx << "," << m_state.getBitSize(valtypidx); msg << " TO: "; msg << typidx << "," << getBitSize(); MSG(m_state.getFullLocationAsString(m_state.m_locOfNextLineText).c_str(), msg.str().c_str(), DEBUG); brtn = false; } return brtn; } //cast
u64 UlamTypeInt::getDataAsCu64(const u64 data) { s32 bitsize = getBitSize(); assert(bitsize > 0); u64 cdata = _Int64ToUnsigned64(data, (u32) bitsize, (u32) bitsize); return _Unsigned64ToCu64(cdata, (u32) bitsize); }
u32 UlamTypeInt::getDataAsCu32(const u32 data) { s32 bitsize = getBitSize(); assert(bitsize > 0); u32 cdata = _Int32ToUnsigned32(data, (u32) bitsize, (u32) bitsize); return _Unsigned32ToCu32(cdata, (u32) bitsize); }
const std::string UlamType::getTmpStorageTypeAsString(s32 sizebyints) { std::string ctype; switch(sizebyints) { case 0: //e.g. empty quarks case 32: ctype = "u32"; break; case 64: ctype = "u64"; break; case 96: ctype = "BV96"; break; default: { assert(!isScalar()); //ctype = getTmpStorageTypeAsString(getItemWordSize()); //u32, u64 (inf loop) std::ostringstream cstr; if(sizebyints == (s32) getItemWordSize()) cstr << "BitVector<" << getBitSize() << ">"; else cstr << "BitVector<" << getTotalBitSize() << ">"; //entire array ctype = cstr.str(); } }; return ctype; } //getTmpStorageTypeAsString
const std::string UlamTypePrimitive::getUlamTypeMangledType() { // e.g. parsing overloaded functions, may not be complete. std::ostringstream mangled; s32 bitsize = getBitSize(); s32 arraysize = getArraySize(); if(isReference()) //includes ALT_ARRAYITEM (t3147) mangled << "r"; if(arraysize > 0) mangled << ToLeximitedNumber(arraysize); else mangled << 10; if(bitsize > 0) mangled << ToLeximitedNumber(bitsize); else mangled << 10; std::string ecode(UlamTypePrimitive::getUlamTypeEnumCodeChar(getUlamTypeEnum())); mangled << ToLeximited(ecode).c_str(); return mangled.str(); } //getUlamTypeMangledType
u32 UlamType::getTotalBitSize() { s32 arraysize = getArraySize(); arraysize = (arraysize > NONARRAYSIZE ? arraysize : 1); s32 bitsize = getBitSize(); bitsize = (bitsize != UNKNOWNSIZE ? bitsize : 0); return bitsize * arraysize; // >= 0 }
bool UlamTypeInt::castTo64(UlamValue & val, UTI typidx) { bool brtn = true; UTI valtypidx = val.getUlamValueTypeIdx(); u32 valwordsize = m_state.getTotalWordSize(valtypidx); u64 data; if(valwordsize == MAXBITSPERINT) data = (u64) val.getImmediateData(m_state); else if(valwordsize == MAXBITSPERLONG) data = val.getImmediateDataLong(m_state); else assert(0); u64 sdata = 0; s32 bitsize = getBitSize(); s32 valbitsize = m_state.getBitSize(valtypidx); ULAMTYPE valtypEnum = m_state.getUlamTypeByIndex(valtypidx)->getUlamTypeEnum(); switch(valtypEnum) { case Int: // casting Int to Int to change bits size sdata = _Int64ToInt64(data, valbitsize, bitsize); break; case Unsigned: // casting Unsigned to Int to change type sdata = _Unsigned64ToInt64(data, valbitsize, bitsize); break; case Bits: // casting Bits to Int to change type sdata = _Bits64ToInt64(data, valbitsize, bitsize); break; case Unary: sdata = _Unary64ToInt64(data, valbitsize, bitsize); break; case Bool: sdata = _Bool64ToInt64(data, valbitsize, bitsize); break; case Void: default: //std::cerr << "UlamTypeInt (cast) error! Value Type was: " << valtypidx << std::endl; brtn = false; }; if(brtn) { u32 wordsize = getTotalWordSize(); //tobe if(wordsize == MAXBITSPERINT) //downcast val = UlamValue::makeImmediate(typidx, (u32) sdata, m_state); //overwrite val else if(wordsize == MAXBITSPERLONG) val = UlamValue::makeImmediateLong(typidx, sdata, m_state); //overwrite val else assert(0); } return brtn; } //castTo64
bool UlamTypePrimitiveUnary::castTo64(UlamValue & val, UTI typidx) { bool brtn = true; UTI valtypidx = val.getUlamValueTypeIdx(); u32 valwordsize = m_state.getTotalWordSize(valtypidx); u64 data; if(valwordsize <= MAXBITSPERINT) data = (u64) val.getImmediateData(m_state); else if(valwordsize <= MAXBITSPERLONG) data = val.getImmediateDataLong(m_state); else m_state.abortGreaterThanMaxBitsPerLong(); s32 bitsize = getBitSize(); s32 valbitsize = m_state.getBitSize(valtypidx); //base types e.g. Int, Bool, Unary, Foo, Bar.. ULAMTYPE valtypEnum = m_state.getUlamTypeByIndex(valtypidx)->getUlamTypeEnum(); switch(valtypEnum) { case Int: // cast from Int->Unary, OR Bool->Unary (same as Bool->Int) data = _Int64ToUnary64(data, valbitsize, bitsize); break; case Unsigned: data = _Unsigned64ToUnary64(data, valbitsize, bitsize); break; case Bool: // Bool -> Unary is the same as Bool -> Int data = _Bool64ToUnary64(data, valbitsize, bitsize); break; case Unary: data = _Unary64ToUnary64(data, valbitsize, bitsize); break; case Bits: break; case Void: default: //std::cerr << "UlamTypePrimitiveUnary (cast) error! Value Type was: " << valtypidx << std::endl; brtn = false; }; if(brtn) { u32 wordsize = getTotalWordSize(); //tobe if(wordsize <= MAXBITSPERINT) //downcast val = UlamValue::makeImmediate(typidx, data, m_state); //overwrite val else if(wordsize <= MAXBITSPERLONG) val = UlamValue::makeImmediateLong(typidx, data, m_state); //overwrite val else m_state.abortGreaterThanMaxBitsPerLong(); } return brtn; } //castTo64
FORECAST UlamTypeInt::safeCast(UTI typidx) { FORECAST scr = UlamType::safeCast(typidx); if(scr != CAST_CLEAR) return scr; bool brtn = true; UlamType * vut = m_state.getUlamTypeByIndex(typidx); s32 valbitsize = m_state.getBitSize(typidx); s32 bitsize = getBitSize(); ULAMTYPE valtypEnum = vut->getUlamTypeEnum(); switch(valtypEnum) { case Int: brtn = (bitsize >= valbitsize); break; case Unsigned: brtn = (bitsize > valbitsize); break; case Unary: brtn = (bitsize > (s32) _getLogBase2(valbitsize) + 1); break; case Bool: case Bits: case Void: case UAtom: brtn = false; break; case Class: { //must be Quark! treat as Int if it has a toInt method if(vut->isNumericType()) brtn = (bitsize >= MAXBITSPERINT); else { std::ostringstream msg; msg << "Class: "; msg << m_state.getUlamTypeNameBriefByIndex(typidx).c_str(); msg << " is not a numeric type and cannot be safely cast to an Int"; MSG(m_state.getFullLocationAsString(m_state.m_locOfNextLineText).c_str(),msg.str().c_str(), ERR); brtn = false; } } break; default: assert(0); //std::cerr << "UlamTypeInt (cast) error! Value Type was: " << valtypidx << std::endl; brtn = false; }; return brtn ? CAST_CLEAR : CAST_BAD; } //safeCast
FORECAST UlamTypePrimitiveInt::safeCast(UTI typidx) { FORECAST scr = UlamType::safeCast(typidx); if(scr != CAST_CLEAR) return scr; bool brtn = true; UlamType * vut = m_state.getUlamTypeByIndex(typidx); s32 valbitsize = m_state.getBitSize(typidx); s32 bitsize = getBitSize(); ULAMTYPE valtypEnum = vut->getUlamTypeEnum(); switch(valtypEnum) { case Int: brtn = (bitsize >= valbitsize); break; case Unsigned: brtn = (bitsize > valbitsize); break; case Unary: brtn = (bitsize > (s32) _getLogBase2(valbitsize) + 1); break; case Bool: case Bits: case Void: case UAtom: brtn = false; break; case Class: { //must be Quark! treat as Int if it has a toInt method if(vut->isNumericType()) brtn = (bitsize >= MAXBITSPERINT); else brtn = false; //t41131 called by matching args (no error msg please) } break; default: m_state.abortUndefinedUlamType(); //std::cerr << "UlamTypePrimitiveInt (cast) error! Value Type was: " << valtypidx << std::endl; brtn = false; }; return brtn ? CAST_CLEAR : CAST_BAD; } //safeCast
FORECAST UlamType::safeCast(UTI typidx) { // initial tests for completeness and scalars if(!isComplete() || !m_state.isComplete(typidx)) { std::ostringstream msg; msg << "Casting UNKNOWN sizes; " << getBitSize(); msg << ", Value Type and size was: " << typidx << "," << m_state.getBitSize(typidx); MSG(m_state.getFullLocationAsString(m_state.m_locOfNextLineText).c_str(), msg.str().c_str(), DEBUG); return CAST_HAZY; //includes Navs & Hzy's } //let packable arrays of same size pass... if(!checkArrayCast(typidx)) return CAST_BAD; if((m_state.getReferenceType(typidx)==ALT_CONSTREF) && (getReferenceType()==ALT_REF)) return CAST_BAD; //bad cast from const ref to non-const ref return CAST_CLEAR; } //safeCast
FORECAST UlamTypePrimitiveUnary::safeCast(UTI typidx) { FORECAST scr = UlamType::safeCast(typidx); if(scr != CAST_CLEAR) return scr; bool brtn = true; UlamType * vut = m_state.getUlamTypeByIndex(typidx); s32 valbitsize = vut->getBitSize(); s32 bitsize = getBitSize(); ULAMTYPE valtypEnum = vut->getUlamTypeEnum(); switch(valtypEnum) { case Unsigned: { u32 vwordsize = vut->getTotalWordSize(); if(vwordsize <= MAXBITSPERINT) brtn = ((u32) bitsize >= (u32) vut->getMax()); else brtn = ((u64) bitsize >= vut->getMax()); } break; case Unary: brtn = (bitsize >= valbitsize); break; case Int: case Bool: case Bits: case Void: case UAtom: case Class: brtn = false; break; default: m_state.abortUndefinedUlamType(); //std::cerr << "UlamTypePrimitiveUnary (cast) error! Value Type was: " << valtypidx << std::endl; brtn = false; }; return brtn ? CAST_CLEAR : CAST_BAD; } //safeCast
bool UlamTypeInt::castTo32(UlamValue & val, UTI typidx) { bool brtn = true; UTI valtypidx = val.getUlamValueTypeIdx(); s32 bitsize = getBitSize(); s32 valbitsize = m_state.getBitSize(valtypidx); u32 data = val.getImmediateData(m_state); u32 sdata = 0; ULAMTYPE valtypEnum = m_state.getUlamTypeByIndex(valtypidx)->getUlamTypeEnum(); switch(valtypEnum) { case Int: // casting Int to Int to change bits size sdata = _Int32ToInt32(data, valbitsize, bitsize); break; case Unsigned: // casting Unsigned to Int to change type sdata = _Unsigned32ToInt32(data, valbitsize, bitsize); break; case Bits: // casting Bits to Int to change type sdata = _Bits32ToInt32(data, valbitsize, bitsize); break; case Unary: sdata = _Unary32ToInt32(data, valbitsize, bitsize); break; case Bool: sdata = _Bool32ToInt32(data, valbitsize, bitsize); break; case Void: default: //std::cerr << "UlamTypeInt (cast) error! Value Type was: " << valtypidx << std::endl; brtn = false; }; if(brtn) val = UlamValue::makeImmediate(typidx, sdata, m_state); //overwrite val return brtn; } //castTo32
bool UlamTypePrimitiveUnary::castTo32(UlamValue & val, UTI typidx) { bool brtn = true; UTI valtypidx = val.getUlamValueTypeIdx(); u32 data = val.getImmediateData(m_state); s32 bitsize = getBitSize(); s32 valbitsize = m_state.getBitSize(valtypidx); //base types e.g. Int, Bool, Unary, Foo, Bar.. ULAMTYPE valtypEnum = m_state.getUlamTypeByIndex(valtypidx)->getUlamTypeEnum(); switch(valtypEnum) { case Int: // cast from Int->Unary, OR Bool->Unary (same as Bool->Int) data = _Int32ToUnary32(data, valbitsize, bitsize); break; case Unsigned: data = _Unsigned32ToUnary32(data, valbitsize, bitsize); break; case Bool: // Bool -> Unary is the same as Bool -> Int data = _Bool32ToUnary32(data, valbitsize, bitsize); break; case Unary: data = _Unary32ToUnary32(data, valbitsize, bitsize); break; case Bits: break; case Void: default: //std::cerr << "UlamTypePrimitiveUnary (cast) error! Value Type was: " << valtypidx << std::endl; brtn = false; }; if(brtn) val = UlamValue::makeImmediate(typidx, data, m_state); //overwrite val, same data return brtn; } //castTo32
UlamTypePrimitiveUnary::UlamTypePrimitiveUnary(const UlamKeyTypeSignature key, CompilerState & state) : UlamTypePrimitive(key, state) { s32 bitsize = getBitSize(); if(bitsize <= 0) { m_max = m_min = 0; } else if(bitsize <= MAXBITSPERINT) { m_wordLengthTotal = calcWordSize(getTotalBitSize()); m_wordLengthItem = calcWordSize(bitsize); m_max = _GetNOnes32((u32) bitsize); m_min = 0; } else if(bitsize <= MAXBITSPERLONG) { m_wordLengthTotal = calcWordSize(getTotalBitSize()); m_wordLengthItem = calcWordSize(bitsize); m_max = _GetNOnes64((u64) bitsize); m_min = 0; } else m_state.abortGreaterThanMaxBitsPerLong(); }
UlamTypePrimitiveInt::UlamTypePrimitiveInt(const UlamKeyTypeSignature key, CompilerState & state) : UlamTypePrimitive(key, state) { s32 bitsize = getBitSize(); if(bitsize <= 0) { m_max = m_min = 0; } else if(bitsize <= MAXBITSPERINT) { m_wordLengthTotal = calcWordSize(getTotalBitSize()); m_wordLengthItem = calcWordSize(bitsize); m_max = calcBitsizeSignedMax(bitsize); m_min = calcBitsizeSignedMin(bitsize); } else if(bitsize <= MAXBITSPERLONG) { m_wordLengthTotal = calcWordSize(getTotalBitSize()); m_wordLengthItem = calcWordSize(bitsize); m_max = calcBitsizeSignedMaxLong(bitsize); m_min = calcBitsizeSignedMinLong(bitsize); } else m_state.abortGreaterThanMaxBitsPerLong(); }
UlamTypeInt::UlamTypeInt(const UlamKeyTypeSignature key, CompilerState & state) : UlamType(key, state) { s32 bitsize = getBitSize(); if(bitsize <= 0) { m_max = m_min = 0; } else if(bitsize <= MAXBITSPERINT) { m_wordLengthTotal = calcWordSize(getTotalBitSize()); m_wordLengthItem = calcWordSize(bitsize); m_max = calcBitsizeSignedMax(bitsize); m_min = calcBitsizeSignedMin(bitsize); } else if(bitsize <= MAXBITSPERLONG) { m_wordLengthTotal = calcWordSizeLong(getTotalBitSize()); m_wordLengthItem = calcWordSizeLong(bitsize); m_max = calcBitsizeSignedMaxLong(bitsize); m_min = calcBitsizeSignedMinLong(bitsize); } else assert(0); }
u64 UlamTypePrimitiveUnary::getDataAsCu64(const u64 data) { return _Unary64ToCu64(data, getBitSize()); }
u32 UlamTypePrimitiveUnary::getDataAsCu32(const u32 data) { return _Unary32ToCu32(data, getBitSize()); }
s64 UlamTypeInt::getDataAsCs64(const u64 data) { return _Int64ToCs64(data, getBitSize()); }
s32 UlamTypeInt::getDataAsCs32(const u32 data) { return _Int32ToCs32(data, getBitSize()); }