Add bounded integer class

This commit is contained in:
drmortalwombat 2024-12-26 14:57:23 +01:00
parent 8e46ae95ec
commit e37de95079
9 changed files with 231 additions and 10 deletions

45
include/opp/boundint.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef OPP_BOUNDINT_H
#define OPP_BOUNDINT_H
namespace opp {
template<int tmin, int tmax>
constexpr auto boundinttype(void)
{
if constexpr (tmin >= 0 && tmax <= 255)
return (char)0;
else if constexpr (tmin >= -128 && tmax <= 127)
return (signed char)0;
else
return (int)0;
}
template<int tmin, int tmax>
class boundint
{
protected:
decltype(boundinttype<tmin, tmax>()) v;
public:
boundint(int i)
: v(i)
{
}
void operator=(int k)
{
__assume(k >= tmin && k <= tmax);
v = k;
}
operator int() const
{
int k = v;
__assume(k >= tmin && k <= tmax);
return k;
}
};
}
#endif

View File

@ -754,6 +754,9 @@ bool ConstexprInterpreter::AddParam(int& pos, Expression* pex, Declaration* dec)
Expression* ConstexprInterpreter::EvalCall(Expression* exp) Expression* ConstexprInterpreter::EvalCall(Expression* exp)
{ {
if (!exp->mLeft->mDecValue || !exp->mLeft->mDecValue->mValue)
return exp;
mProcType = exp->mLeft->mDecType; mProcType = exp->mLeft->mDecType;
Expression* pex = exp->mRight; Expression* pex = exp->mRight;

View File

@ -491,6 +491,47 @@ Expression* Expression::LogicInvertExpression(void)
} }
} }
Expression* Expression::ToAlternateThis(Declaration* pthis, Declaration* nthis)
{
Expression* left = mLeft ? mLeft->ToAlternateThis(pthis, nthis) : nullptr;
Expression* right = mRight ? mRight->ToAlternateThis(pthis, nthis) : nullptr;
Declaration* decType = mDecType, * decValue = mDecValue;
if (decType == pthis->mBase)
decType = nthis->mBase;
else if (decType == pthis->mBase->mBase)
decType = nthis->mBase->mBase;
if (decValue == pthis)
decValue = nthis;
if (mType == EX_QUALIFY && mLeft->mDecType != left->mDecType)
{
Declaration* pe = mLeft->mDecType->mParams, * ne = left->mDecType->mParams;
while (pe && ne && pe != mDecValue)
{
pe = pe->mNext;
ne = ne->mNext;
}
decValue = ne;
decType = ne->mBase;
}
if (left == mLeft && right == mRight && decType == mDecType && decValue == mDecValue)
return this;
else
{
Expression* nexp = new Expression(mLocation, mType);
nexp->mLeft = left;
nexp->mRight = right;
nexp->mDecType = decType;
nexp->mDecValue = decValue;
nexp->mToken = mToken;
nexp->mConst = mConst;
return nexp;
}
}
Expression* Expression::ConstantDereference(Errors* errors, LinkerSection* dataSection) Expression* Expression::ConstantDereference(Errors* errors, LinkerSection* dataSection)
{ {
if (mType == EX_VARIABLE) if (mType == EX_VARIABLE)
@ -1034,6 +1075,26 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
} }
} }
else if (mType == EX_LOGICAL_AND && mLeft->mType == EX_CONSTANT)
{
if (mLeft->mDecValue->mType == DT_CONST_INTEGER)
{
if (mLeft->mDecValue->mInteger == 0)
return mLeft;
else
return mRight->ConstantFold(errors, dataSection);
}
}
else if (mType == EX_LOGICAL_OR && mLeft->mType == EX_CONSTANT)
{
if (mLeft->mDecValue->mType == DT_CONST_INTEGER)
{
if (mLeft->mDecValue->mInteger != 0)
return mLeft;
else
return mRight->ConstantFold(errors, dataSection);
}
}
else if (mType == EX_CONDITIONAL && mLeft->mType == EX_CONSTANT) else if (mType == EX_CONDITIONAL && mLeft->mType == EX_CONSTANT)
{ {
if (mLeft->mDecValue->mType == DT_CONST_INTEGER) if (mLeft->mDecValue->mType == DT_CONST_INTEGER)
@ -2058,6 +2119,7 @@ Declaration* Declaration::Clone(void)
ndec->mMaxValue = mMaxValue; ndec->mMaxValue = mMaxValue;
ndec->mCompilerOptions = mCompilerOptions; ndec->mCompilerOptions = mCompilerOptions;
ndec->mParser = mParser; ndec->mParser = mParser;
ndec->mNumVars = mNumVars;
return ndec; return ndec;
} }
@ -2136,6 +2198,23 @@ Declaration* Declaration::ToStriped(int stripe)
prev = pnec; prev = pnec;
p = p->mNext; p = p->mNext;
} }
Declaration* pndec = ndec->BuildPointer(mLocation);
mScope->Iterate([=](const Ident* ident, Declaration* vdec) {
if (vdec->mType == DT_CONST_FUNCTION)
{
ndec->mScope->Insert(ident, vdec->ToAlternateThis(pndec));
}
});
ndec->mDestructor = mDestructor ? mDestructor->ToAlternateThis(pndec) : nullptr;
ndec->mDefaultConstructor = mDefaultConstructor ? mDefaultConstructor->ToAlternateThis(pndec) : nullptr;
ndec->mCopyConstructor = mCopyConstructor ? mCopyConstructor->ToAlternateThis(pndec) : nullptr;
ndec->mMoveConstructor = mMoveConstructor ? mMoveConstructor->ToAlternateThis(pndec) : nullptr;
ndec->mVectorConstructor = mVectorConstructor ? mVectorConstructor->ToAlternateThis(pndec, 2) : nullptr;
ndec->mVectorDestructor = mVectorDestructor ? mVectorDestructor->ToAlternateThis(pndec, 2) : nullptr;
ndec->mVectorCopyConstructor = mVectorCopyConstructor ? mVectorCopyConstructor->ToAlternateThis(pndec, 2) : nullptr;
} }
else if (mType == DT_TYPE_FUNCTION) else if (mType == DT_TYPE_FUNCTION)
{ {
@ -2244,6 +2323,34 @@ Declaration* Declaration::ToConstType(void)
return mConst; return mConst;
} }
Declaration* Declaration::ToAlternateThis(Declaration* pthis, int nthis)
{
Declaration* ndec = this->Clone();
if (mType == DT_CONST_FUNCTION)
{
ndec->mBase = mBase->ToAlternateThis(pthis, nthis);
if (mValue)
ndec->mValue = mValue->ToAlternateThis(mBase->mParams, ndec->mBase->mParams);
}
else
{
Declaration* nparam = ndec->mParams->Clone();
nparam->mBase = pthis;
if (nthis == 2)
{
Declaration* nparam2 = ndec->mParams->mNext->Clone();
nparam2->mBase = pthis;
nparam->mNext = nparam2;
nparam2->mNext = ndec->mParams->mNext->mNext;
}
else
nparam->mNext = ndec->mParams->mNext;
ndec->mParams = nparam;
}
return ndec;
}
Declaration* Declaration::ToMutableType(void) Declaration* Declaration::ToMutableType(void)
{ {
if (!(mFlags & DTF_CONST)) if (!(mFlags & DTF_CONST))

View File

@ -264,6 +264,7 @@ public:
Expression* ConstantDereference(Errors* errors, LinkerSection* dataSection); Expression* ConstantDereference(Errors* errors, LinkerSection* dataSection);
bool HasSideEffects(void) const; bool HasSideEffects(void) const;
Expression* ListAppend(Expression* lexp); Expression* ListAppend(Expression* lexp);
Expression* ToAlternateThis(Declaration* pthis, Declaration* nthis);
bool IsSame(const Expression* exp) const; bool IsSame(const Expression* exp) const;
bool IsRValue(void) const; bool IsRValue(void) const;
@ -271,6 +272,7 @@ public:
bool IsConstRef(void) const; bool IsConstRef(void) const;
bool IsVolatile(void) const; bool IsVolatile(void) const;
void Dump(int ident) const; void Dump(int ident) const;
}; };
@ -335,6 +337,7 @@ public:
Declaration* ToConstType(void); Declaration* ToConstType(void);
Declaration* ToMutableType(void); Declaration* ToMutableType(void);
Declaration* ToVolatileType(void); Declaration* ToVolatileType(void);
Declaration* ToAlternateThis(Declaration* pthis, int nthis = 1);
Declaration* ToStriped(int stripe); Declaration* ToStriped(int stripe);
Declaration* ToStriped(Errors* errors); Declaration* ToStriped(Errors* errors);

View File

@ -46583,6 +46583,32 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerIterate4(int i, int pass)
return true; return true;
} }
else if (
mIns[i + 0].mType == ASMIT_STA &&
mIns[i + 1].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDX, mIns[i + 1].mMode) &&
mIns[i + 2].mType == ASMIT_STA && HasAsmInstructionMode(ASMIT_STX, mIns[i + 2].mMode) &&
mIns[i + 3].mType == ASMIT_LDX && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]))
{
mIns[i + 0].mLive |= LIVE_CPU_REG_A;
mIns[i + 1].mType = ASMIT_LDX; mIns[i + 1].mLive |= LIVE_CPU_REG_X;
mIns[i + 2].mType = ASMIT_STX; mIns[i + 2].mLive |= LIVE_CPU_REG_A;
mIns[i + 3].mType = ASMIT_TAX; mIns[i + 3].mMode = ASMIM_IMPLIED;
return true;
}
else if (
mIns[i + 0].mType == ASMIT_STA &&
mIns[i + 1].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDY, mIns[i + 1].mMode) &&
mIns[i + 2].mType == ASMIT_STA && HasAsmInstructionMode(ASMIT_STY, mIns[i + 2].mMode) &&
mIns[i + 3].mType == ASMIT_LDY && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]))
{
mIns[i + 0].mLive |= LIVE_CPU_REG_A;
mIns[i + 1].mType = ASMIT_LDY; mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
mIns[i + 2].mType = ASMIT_STY; mIns[i + 2].mLive |= LIVE_CPU_REG_A;
mIns[i + 3].mType = ASMIT_TAY; mIns[i + 3].mMode = ASMIM_IMPLIED;
return true;
}
else if ( else if (
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 1].mType == ASMIT_LDY && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mType == ASMIT_LDY && mIns[i + 1].mMode == ASMIM_IMMEDIATE &&

View File

@ -869,6 +869,14 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified, Decl
mScanner->NextToken(); mScanner->NextToken();
break; break;
case TK_DECLTYPE:
{
mScanner->NextToken();
Expression* exp = ParseExpression(true);
dec = exp->mDecType;
}
break;
case TK_IDENT: case TK_IDENT:
pident = mScanner->mTokenIdent; pident = mScanner->mTokenIdent;
mScanner->NextToken(); mScanner->NextToken();
@ -5321,7 +5329,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
if (pdec) if (pdec)
{ {
if (!ndec->mBase->IsSame(pdec->mBase)) if (!ndec->mBase->IsSame(pdec->mBase) && !(ndec->mBase->mBase->mType == DT_TYPE_AUTO && ndec->mBase->IsSameParams(pdec->mBase)))
{ {
ndec->mBase->IsSameParams(pdec->mBase); ndec->mBase->IsSameParams(pdec->mBase);
ndec->mBase->IsSame(pdec->mBase); ndec->mBase->IsSame(pdec->mBase);
@ -6384,6 +6392,7 @@ Expression* Parser::ParseSimpleExpression(bool lhs, bool tid)
case TK_STATIC: case TK_STATIC:
case TK_AUTO: case TK_AUTO:
case TK_STRIPED: case TK_STRIPED:
case TK_DECLTYPE:
exp = ParseDeclarationExpression(nullptr); exp = ParseDeclarationExpression(nullptr);
break; break;
@ -7461,6 +7470,7 @@ Expression* Parser::CoerceExpression(Expression* exp, Declaration* type)
nexp->mLeft->mDecType = fexp->mBase; nexp->mLeft->mDecType = fexp->mBase;
nexp->mLeft->mDecValue = fexp; nexp->mLeft->mDecValue = fexp;
nexp->mRight = aexp; nexp->mRight = aexp;
nexp->mDecType = fexp->mBase->mBase;
return nexp; return nexp;
} }
@ -9349,6 +9359,9 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
Declaration* tdec = exp->mLeft->mDecType; Declaration* tdec = exp->mLeft->mDecType;
while (tdec->mType == DT_TYPE_REFERENCE || tdec->mType == DT_TYPE_RVALUEREF) while (tdec->mType == DT_TYPE_REFERENCE || tdec->mType == DT_TYPE_RVALUEREF)
tdec = tdec->mBase; tdec = tdec->mBase;
Declaration* rtdec = exp->mRight->mDecType;
while (rtdec->mType == DT_TYPE_REFERENCE || rtdec->mType == DT_TYPE_RVALUEREF)
rtdec = rtdec->mBase;
if (tdec->mType == DT_TYPE_STRUCT) if (tdec->mType == DT_TYPE_STRUCT)
{ {
@ -9383,6 +9396,18 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
exp = nexp; exp = nexp;
} }
} }
if (exp->mType != EX_CALL && !nexp2 && (tdec->mType == DT_TYPE_STRUCT || rtdec->mType == DT_TYPE_STRUCT))
{
if ((exp->mLeft->mDecType->IsIntegerType() || CanCoerceExpression(exp->mLeft, TheSignedIntTypeDeclaration)) &&
(exp->mRight->mDecType->IsIntegerType() || CanCoerceExpression(exp->mRight, TheSignedIntTypeDeclaration)))
{
exp->mLeft = CoerceExpression(exp->mLeft, TheSignedIntTypeDeclaration);
exp->mRight = CoerceExpression(exp->mRight, TheSignedIntTypeDeclaration);
if (exp->mType == EX_BINARY)
exp->mDecType = TheSignedIntTypeDeclaration;
}
}
} }
} }
else if (exp->mType == EX_PREFIX) else if (exp->mType == EX_PREFIX)
@ -9781,6 +9806,12 @@ void Parser::SkipStatement(void)
mScanner->NextToken(); mScanner->NextToken();
} }
} }
else if (ConsumeTokenIf(TK_IF))
{
SkipStatement();
if (ConsumeTokenIf(TK_ELSE))
SkipStatement();
}
else else
{ {
while (!ConsumeTokenIf(TK_SEMICOLON)) while (!ConsumeTokenIf(TK_SEMICOLON))
@ -12540,6 +12571,7 @@ bool Parser::IsTypeToken(void)
case TK_STATIC: case TK_STATIC:
case TK_AUTO: case TK_AUTO:
case TK_STRIPED: case TK_STRIPED:
case TK_DECLTYPE:
return true; return true;
case TK_IDENT: case TK_IDENT:
{ {

View File

@ -173,6 +173,7 @@ const char* TokenNames[] =
"'friend'", "'friend'",
"'constexpr'", "'constexpr'",
"'typename'", "'typename'",
"'decltype'",
}; };
@ -355,7 +356,7 @@ Scanner::Scanner(Errors* errors, Preprocessor* preprocessor)
mToken = TK_NONE; mToken = TK_NONE;
mUngetToken = TK_NONE; mUngetToken = TK_NONE;
mReplay = nullptr; mReplay = nullptr;
mRecord = mRecordLast = nullptr; mRecord = mRecordLast = mRecordPrev = nullptr;
mOnceDict = new MacroDict(); mOnceDict = new MacroDict();
@ -372,13 +373,13 @@ Scanner::~Scanner(void)
void Scanner::BeginRecord(void) void Scanner::BeginRecord(void)
{ {
mRecord = mRecordLast = new TokenSequence(this); mRecord = mRecordLast = mRecordPrev = new TokenSequence(this);
} }
TokenSequence* Scanner::CompleteRecord(void) TokenSequence* Scanner::CompleteRecord(void)
{ {
TokenSequence* seq = mRecord; TokenSequence* seq = mRecord;
mRecord = mRecordLast = nullptr; mRecord = mRecordLast = mRecordPrev = nullptr;
return seq; return seq;
} }
@ -483,6 +484,8 @@ void Scanner::UngetToken(Token token)
{ {
mUngetToken = mToken; mUngetToken = mToken;
mToken = token; mToken = token;
if (mRecord)
mRecordLast = mRecordPrev;
} }
void Scanner::NextToken(void) void Scanner::NextToken(void)
@ -491,10 +494,8 @@ void Scanner::NextToken(void)
{ {
mToken = mUngetToken; mToken = mUngetToken;
mUngetToken = TK_NONE; mUngetToken = TK_NONE;
return;
} }
else if (mReplay)
if (mReplay)
{ {
mLocation = mReplay->mLocation; mLocation = mReplay->mLocation;
mToken = mReplay->mToken; mToken = mReplay->mToken;
@ -515,6 +516,7 @@ void Scanner::NextToken(void)
if (mRecord) if (mRecord)
{ {
mRecordPrev = mRecordLast;
mRecordLast->mNext = new TokenSequence(this); mRecordLast->mNext = new TokenSequence(this);
mRecordLast = mRecordLast->mNext; mRecordLast = mRecordLast->mNext;
} }
@ -1846,6 +1848,8 @@ void Scanner::NextRawToken(void)
mToken = TK_CONSTEXPR; mToken = TK_CONSTEXPR;
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "typename")) else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "typename"))
mToken = TK_TYPENAME; mToken = TK_TYPENAME;
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "decltype"))
mToken = TK_DECLTYPE;
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "operator")) else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "operator"))
{ {
NextRawToken(); NextRawToken();

View File

@ -172,6 +172,7 @@ enum Token
TK_FRIEND, TK_FRIEND,
TK_CONSTEXPR, TK_CONSTEXPR,
TK_TYPENAME, TK_TYPENAME,
TK_DECLTYPE,
NUM_TOKENS NUM_TOKENS
}; };
@ -315,7 +316,7 @@ protected:
Token mUngetToken; Token mUngetToken;
const TokenSequence* mReplay; const TokenSequence* mReplay;
TokenSequence* mRecord, * mRecordLast; TokenSequence* mRecord, * mRecordLast, * mRecordPrev;
void StringToken(char terminator, char mode); void StringToken(char terminator, char mode);
void CharToken(char mode); void CharToken(char mode);