Improve C const declaration compatibility

This commit is contained in:
drmortalwombat 2022-01-21 14:42:49 +01:00
parent 8b4eff3ee1
commit cc927d778f
9 changed files with 145 additions and 15 deletions

View File

@ -776,7 +776,7 @@ void mat4_mmul(Matrix4 * md, const Matrix4 * ms)
for(char j=0; j<4; j++)
ma[j] = md->m[i + 0] * ms->m[4 * j] + md->m[i + 4] * ms->m[4 * j + 1] + md->m[i + 8] * ms->m[4 * j + 2] + md->m[i + 12] * ms->m[4 * j + 3];
for(char j=0; j<4; j++)
md->m[(char)(i + 4 * j)] = ma[j];
md->m[i + 4 * j] = ma[j];
}
}

View File

@ -377,6 +377,21 @@ Declaration::~Declaration(void)
delete[] mData;
}
Declaration* Declaration::ToConstType(void)
{
if (mFlags & DTF_CONST)
return this;
Declaration* ndec = new Declaration(mLocation, mType);
ndec->mSize = mSize;
ndec->mBase = mBase;
ndec->mFlags = mFlags | DTF_CONST;
ndec->mScope = mScope;
ndec->mParams = mParams;
return ndec;
}
bool Declaration::IsSubType(const Declaration* dec) const
{
if (this == dec)
@ -403,6 +418,8 @@ bool Declaration::IsSubType(const Declaration* dec) const
return true;
else if (mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_VOID)
return true;
else if (mType == DT_TYPE_STRUCT && dec->mType == DT_TYPE_STRUCT)
return mScope == dec->mScope;
else if (mType == DT_TYPE_STRUCT || mType == DT_TYPE_ENUM || mType == DT_TYPE_UNION)
return false;
else if (mType == DT_TYPE_ARRAY)
@ -457,6 +474,8 @@ bool Declaration::IsSame(const Declaration* dec) const
}
else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
return mBase->IsSame(dec->mBase);
else if (mType == DT_TYPE_STRUCT && dec->mType == DT_TYPE_STRUCT)
return mScope == dec->mScope;
else if (mType == DT_TYPE_FUNCTION)
{
if (!mBase->IsSame(dec->mBase))
@ -491,6 +510,8 @@ bool Declaration::CanAssign(const Declaration* fromType) const
if (fromType->IsNumericType())
return true;
}
else if (mType == DT_TYPE_STRUCT && fromType->mType == DT_TYPE_STRUCT)
return mScope == fromType->mScope;
else if (mType == DT_TYPE_POINTER)
{
if (fromType->mType == DT_TYPE_POINTER || fromType->mType == DT_TYPE_ARRAY)

View File

@ -105,6 +105,7 @@ enum ExpressionType
EX_CONSTANT,
EX_VARIABLE,
EX_ASSIGNMENT,
EX_INITIALIZATION,
EX_BINARY,
EX_RELATIONAL,
EX_PREINCDEC,
@ -187,6 +188,8 @@ public:
bool IsIntegerType(void) const;
bool IsNumericType(void) const;
bool IsSimpleType(void) const;
Declaration* ToConstType(void);
};
void InitDeclarations(void);

View File

@ -279,6 +279,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
}
}
return exp->mDecValue;
case EX_INITIALIZATION:
case EX_ASSIGNMENT:
ldec = Analyze(exp->mLeft, procDec);
rdec = Analyze(exp->mRight, procDec);

View File

@ -940,6 +940,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
case EX_ASSIGNMENT:
case EX_INITIALIZATION:
{
if (exp->mLeft->mDecType && exp->mLeft->mDecType->mType == DT_TYPE_STRUCT)
{
@ -958,7 +959,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types");
}
if (vl.mType->mFlags & DTF_CONST)
if (exp->mType != EX_INITIALIZATION && (vl.mType->mFlags & DTF_CONST))
mErrors->Error(exp->mLocation, EERR_CONST_ASSIGN, "Cannot assign to const type");
if (vl.mType->mType == DT_TYPE_STRUCT || vl.mType->mType == DT_TYPE_ARRAY || vl.mType->mType == DT_TYPE_UNION)

View File

@ -2628,18 +2628,25 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block)
block->PutByte(mParam);
}
if (mMode == ASMIM_IMMEDIATE_ADDRESS)
AsmInsMode mode = mMode;
if (mode == ASMIM_ABSOLUTE && !mLinkerObject && mAddress < 256 && HasAsmInstructionMode(mType, ASMIM_ZERO_PAGE))
mode = ASMIM_ZERO_PAGE;
else if (mode == ASMIM_ABSOLUTE_X && !mLinkerObject && mAddress < 256 && HasAsmInstructionMode(mType, ASMIM_ZERO_PAGE_X))
mode = ASMIM_ZERO_PAGE_X;
if (mode == ASMIM_IMMEDIATE_ADDRESS)
{
assert(HasAsmInstructionMode(mType, ASMIM_IMMEDIATE));
block->PutByte(AsmInsOpcodes[mType][ASMIM_IMMEDIATE]);
}
else
{
assert(HasAsmInstructionMode(mType, mMode));
block->PutByte(AsmInsOpcodes[mType][mMode]);
assert(HasAsmInstructionMode(mType, mode));
block->PutByte(AsmInsOpcodes[mType][mode]);
}
switch (mMode)
switch (mode)
{
case ASMIM_IMPLIED:
break;
@ -12802,20 +12809,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
progress = true;
}
#if 1
else if (
mIns[i + 0].mType == ASMIT_TXA &&
mIns[i + 1].mType == ASMIT_CMP && (mIns[i + 1].mMode == ASMIM_IMMEDIATE || mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE))
{
mIns[i + 1].mType = ASMIT_CPX;
mIns[i + 0].mLive |= CPU_REG_X;
mIns[i + 0].mLive |= LIVE_CPU_REG_X;
progress = true;
}
#endif
else if (
mIns[i + 0].mType == ASMIT_TYA &&
mIns[i + 1].mType == ASMIT_CMP && (mIns[i + 1].mMode == ASMIM_IMMEDIATE || mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE))
{
mIns[i + 1].mType = ASMIT_CPY;
mIns[i + 0].mLive |= CPU_REG_Y;
mIns[i + 0].mLive |= LIVE_CPU_REG_Y;
progress = true;
}
else if (

View File

@ -235,6 +235,16 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags)
ndec->mBase = dec->mBase;
dec = ndec;
}
else if (dec->mType == DT_TYPE_STRUCT && (flags & ~dec->mFlags))
{
Declaration* ndec = new Declaration(dec->mLocation, dec->mType);
ndec->mFlags = dec->mFlags | flags;
ndec->mSize = dec->mSize;
ndec->mBase = dec->mBase;
ndec->mScope = dec->mScope;
ndec->mParams = dec->mParams;
dec = ndec;
}
mScanner->NextToken();
}
else if (!dec)
@ -345,6 +355,12 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags)
dec->mFlags |= DTF_DEFINED;
}
if (mScanner->mToken == TK_CONST)
{
dec = dec->ToConstType();
mScanner->NextToken();
}
return dec;
}
@ -356,11 +372,18 @@ Declaration* Parser::ParsePostfixDeclaration(void)
if (mScanner->mToken == TK_MUL)
{
mScanner->NextToken();
Declaration* dec = ParsePostfixDeclaration();
Declaration* ndec = new Declaration(mScanner->mLocation, DT_TYPE_POINTER);
ndec->mBase = dec;
ndec->mSize = 2;
ndec->mFlags |= DTF_DEFINED;
if (mScanner->mToken == TK_CONST)
{
ndec->mFlags |= DTF_CONST;
mScanner->NextToken();
}
Declaration* dec = ParsePostfixDeclaration();
ndec->mBase = dec;
return ndec;
}
else if (mScanner->mToken == TK_OPEN_PARENTHESIS)
@ -648,6 +671,23 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
Declaration* mdec = dtype->mParams;
while (mdec)
{
if (ConsumeTokenIf(TK_DOT))
{
if (mScanner->mToken == TK_IDENT)
{
Declaration* ndec = dtype->mScope->Lookup(mScanner->mTokenIdent);
if (ndec)
mdec = ndec;
else
mErrors->Error(mScanner->mLocation, EERR_CONSTANT_INITIALIZER, "Struct member not found");
mScanner->NextToken();
ConsumeToken(TK_ASSIGN);
}
else
mErrors->Error(mScanner->mLocation, EERR_CONSTANT_INITIALIZER, "Identifier expected");
}
Expression* texp = ParseInitExpression(mdec->mBase);
Declaration* cdec = CopyConstantInitializer(mdec->mOffset, mdec->mBase, texp);
@ -907,10 +947,31 @@ Declaration* Parser::ParseDeclaration(bool variable)
ndec = pdec;
}
else if ((ndec->mFlags & DTF_EXTERN) || (pdec->mFlags & DTF_EXTERN))
else if (ndec->mFlags & DTF_EXTERN)
{
if (!ndec->mBase->IsSame(pdec->mBase))
{
if (ndec->mBase->mType == DT_TYPE_ARRAY && pdec->mBase->mType == DT_TYPE_ARRAY && ndec->mBase->mBase->IsSame(pdec->mBase->mBase) && ndec->mBase->mSize == 0)
;
else if (ndec->mBase->mType == DT_TYPE_POINTER && pdec->mBase->mType == DT_TYPE_ARRAY && ndec->mBase->mBase->IsSame(pdec->mBase->mBase))
;
else
mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Variable declaration differs");
}
ndec = pdec;
}
else if (pdec->mFlags & DTF_EXTERN)
{
if (!ndec->mBase->IsSame(pdec->mBase))
{
if (ndec->mBase->mType == DT_TYPE_ARRAY && pdec->mBase->mType == DT_TYPE_ARRAY && ndec->mBase->mBase->IsSame(pdec->mBase->mBase) && pdec->mBase->mSize == 0)
pdec->mBase->mSize = ndec->mBase->mSize;
else if (pdec->mBase->mType == DT_TYPE_POINTER && ndec->mBase->mType == DT_TYPE_ARRAY && ndec->mBase->mBase->IsSame(pdec->mBase->mBase))
{
pdec->mBase = ndec->mBase;
}
else
mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Variable declaration differs");
}
@ -991,9 +1052,9 @@ Expression* Parser::ParseDeclarationExpression(void)
{
while (dec)
{
if (dec->mValue)
if (dec->mValue && !(dec->mFlags & DTF_GLOBAL))
{
Expression* nexp = new Expression(dec->mValue->mLocation, EX_ASSIGNMENT);
Expression* nexp = new Expression(dec->mValue->mLocation, EX_INITIALIZATION);
nexp->mToken = TK_ASSIGN;
nexp->mLeft = new Expression(dec->mLocation, EX_VARIABLE);
nexp->mLeft->mDecValue = dec;
@ -1125,7 +1186,7 @@ Expression* Parser::ParseSimpleExpression(void)
dec->mBase->mSize = dec->mSize;
dec->mBase->mBase = TheConstCharTypeDeclaration;
dec->mBase->mFlags |= DTF_DEFINED;
uint8* d = new uint8[dec->mSize];
uint8* d = new uint8[dec->mSize + 1];
dec->mData = d;
int i = 0;

View File

@ -123,6 +123,7 @@ const char* TokenNames[] =
"embedded",
"'#define'",
"'#undef'",
"'#include'",
"'#if'",
"'#elif'",
@ -241,6 +242,26 @@ void MacroDict::Insert(Macro * macro)
}
}
void MacroDict::Remove(const Ident* ident)
{
if (mHashSize > 0)
{
int hm = mHashSize - 1;
int hi = ident->mHash & hm;
while (mHash[hi])
{
if (ident == mHash[hi]->mIdent)
{
mHash[hi]->mIdent = nullptr;
return;
}
hi = (hi + 1) & hm;
}
}
}
Macro* MacroDict::Lookup(const Ident* ident)
{
if (mHashSize > 0)
@ -512,6 +533,15 @@ void Scanner::NextToken(void)
mOffset += slen;
}
}
else if (mToken == TK_PREP_UNDEF)
{
NextRawToken();
if (mToken == TK_IDENT)
{
mDefines->Remove(mTokenIdent);
}
}
else if (mToken == TK_PREP_IFDEF)
{
NextRawToken();
@ -1045,6 +1075,8 @@ void Scanner::NextRawToken(void)
if (!strcmp(tkprep, "define"))
mToken = TK_PREP_DEFINE;
else if (!strcmp(tkprep, "undef"))
mToken = TK_PREP_UNDEF;
else if (!strcmp(tkprep, "include"))
mToken = TK_PREP_INCLUDE;
else if (!strcmp(tkprep, "if"))

View File

@ -121,6 +121,7 @@ enum Token
TK_EMBEDDED,
TK_PREP_DEFINE,
TK_PREP_UNDEF,
TK_PREP_INCLUDE,
TK_PREP_IF,
TK_PREP_ELIF,
@ -165,6 +166,7 @@ public:
~MacroDict(void);
void Insert(Macro * macro);
void Remove(const Ident* ident);
Macro* Lookup(const Ident* ident);
protected: