Improve compatibility with some C quirks

This commit is contained in:
drmortalwombat 2024-02-16 21:39:35 +01:00
parent 8fc382c11e
commit b84cce7609
8 changed files with 157 additions and 87 deletions

View File

@ -123,6 +123,7 @@ The compiler is command line driven, and creates an executable .prg file.
* -xz : extended zero page usage, more zero page space, but no return to basic
* -cid : cartridge type ID, used by vice emulator
* -pp : compile in C++ mode
* -psci : use PETSCII encoding for all strings without prefix
A list of source files can be provided.

View File

@ -38,6 +38,7 @@ static const uint64 COPT_VERBOSE3 = 1ULL << 50;
static const uint64 COPT_DEBUGINFO = 1ULL << 51;
static const uint64 COPT_CPLUSPLUS = 1ULL << 52;
static const uint64 COPT_PETSCII = 1ULL << 53;

View File

@ -19931,7 +19931,7 @@ void InterCodeProcedure::Close(void)
{
GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "clear");
CheckFunc = !strcmp(mIdent->mString, "KeyExpansion");
CheckCase = false;
mEntryBlock = mBlocks[0];

View File

@ -12515,7 +12515,7 @@ void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const
if (ins->mSrc[0].IsUByte())
mIns.Push(NativeCodeInstruction(ins, iop, ASMIM_IMMEDIATE, 0));
else if ((ins->mSrc[1].mIntConst == 0 || ins->mSrc[0].IsUnsigned()) &&
(ins->mSrc[1].mLinkerObject->mSize < 256 || (addrvalid && ins->mSrc[1].mLinkerObject->mSize <= 256)))
(ins->mSrc[1].mLinkerObject->mSize - ins->mSrc[1].mIntConst < 256 || (addrvalid && ins->mSrc[1].mLinkerObject->mSize - ins->mSrc[1].mIntConst <= 256)))
mIns.Push(NativeCodeInstruction(ins, iop, ASMIM_IMMEDIATE, 0));
else
#endif
@ -21117,7 +21117,7 @@ bool NativeCodeBasicBlock::MoveLoadZeroStoreIndirectUp(int at)
if (mIns[j].mMode == ASMIM_INDIRECT_Y && mIns[j].mAddress == mIns[at + 2].mAddress)
{
if (yval == -1 || yval == mIns[at].mAddress)
if (yval == -1 || yval == mIns[at + 1].mAddress)
return false;
}
else if (mIns[j].MayBeSameAddress(mIns[at + 2]))
@ -45696,7 +45696,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{
mInterProc = proc;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "manager_print_at");
CheckFunc = !strcmp(mInterProc->mIdent->mString, "KeyExpansion");
int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks];
@ -47206,6 +47206,7 @@ void NativeCodeProcedure::Optimize(void)
else
cnt++;
} while (changed);
#if 1

View File

@ -4520,8 +4520,32 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
ndec = pdec;
}
else
else if ((mCompilerOptions & COPT_CPLUSPLUS) || mScope->mLevel >= SLEVEL_FUNCTION)
mErrors->Error(ndec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate variable declaration", ndec->mIdent);
else
{
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", ndec->mIdent);
}
pdec->mSection = ndec->mSection;
pdec->mFlags |= ndec->mFlags & DTF_ZEROPAGE;
if (pdec->mValue)
mErrors->Error(ndec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate variable declaration", ndec->mIdent);
ndec = pdec;
}
}
}
@ -5571,7 +5595,12 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
if (/*(dec->mFlags & DTF_STATIC) &&*/ (dec->mFlags & DTF_CONST) && dec->mValue)
{
if (dec->mBase->IsNumericType())
exp = dec->mValue;
{
if (dec->mValue->mType == EX_CONSTANT)
{
exp = dec->mValue;
}
}
else if (dec->mBase->mType == DT_TYPE_POINTER)
{
if (dec->mValue->mType == EX_CONSTANT)

View File

@ -1385,10 +1385,16 @@ void Scanner::NextRawToken(void)
break;
case '\'':
CharToken('a');
if (mCompilerOptions & COPT_PETSCII)
CharToken('p');
else
CharToken('a');
break;
case '"':
StringToken(mTokenChar, 'a');
if (mCompilerOptions & COPT_PETSCII)
StringToken(mTokenChar, 'p');
else
StringToken(mTokenChar, 'a');
break;
case '#':
@ -2136,8 +2142,14 @@ void Scanner::ParseNumberToken(void)
NextChar();
mToken = TK_INTEGERL;
}
else if (mant < 65536)
{
mToken = TK_INTEGERU;
}
else
mToken = TK_INTEGER;
{
mToken = TK_INTEGERUL;
}
}
mTokenInteger = mant;
@ -2175,8 +2187,14 @@ void Scanner::ParseNumberToken(void)
NextChar();
mToken = TK_INTEGERL;
}
else
else if (mant < 32768)
mToken = TK_INTEGER;
else if (mant < 65536)
mToken = TK_INTEGERU;
else if (mant < 0x80000000)
mToken = TK_INTEGERL;
else
mToken = TK_INTEGERUL;
}
mTokenInteger = mant;
}
@ -2216,8 +2234,10 @@ void Scanner::ParseNumberToken(void)
NextChar();
mToken = TK_INTEGERL;
}
else
else if (mant < 32768)
mToken = TK_INTEGER;
else
mToken = TK_INTEGERL;
}
mTokenInteger = mant;
}
@ -2275,7 +2295,7 @@ void Scanner::ParseNumberToken(void)
}
int64 Scanner::PrepParseSimple(void)
int64 Scanner::PrepParseSimple(bool skip)
{
int64 v = 0;
@ -2291,19 +2311,19 @@ int64 Scanner::PrepParseSimple(void)
break;
case TK_SUB:
NextPreToken();
v = -PrepParseSimple();
v = -PrepParseSimple(skip);
break;
case TK_LOGICAL_NOT:
NextPreToken();
v = !PrepParseSimple();
v = !PrepParseSimple(skip);
break;
case TK_BINARY_NOT:
NextPreToken();
v = ~PrepParseSimple();
v = ~PrepParseSimple(skip);
break;
case TK_OPEN_PARENTHESIS:
NextPreToken();
v = PrepParseConditional();
v = PrepParseConditional(skip);
if (mToken == TK_CLOSE_PARENTHESIS)
NextPreToken();
else
@ -2312,33 +2332,43 @@ int64 Scanner::PrepParseSimple(void)
case TK_IDENT:
if (strcmp(mTokenIdent->mString, "defined") == 0)
{
NextPreToken();
bool parenthesis = false;
NextRawToken();
if (mToken == TK_OPEN_PARENTHESIS)
{
NextRawToken();
if (mToken == TK_IDENT)
{
Macro* def = nullptr;
if (mDefineArguments)
def = mDefineArguments->Lookup(mTokenIdent);
if (!def)
def = mDefines->Lookup(mTokenIdent);
if (def)
v = 1;
else
v = 0;
NextPreToken();
}
else
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Identifier expected");
parenthesis = true;
}
if (mToken == TK_IDENT)
{
Macro* def = nullptr;
if (mDefineArguments)
def = mDefineArguments->Lookup(mTokenIdent);
if (!def)
def = mDefines->Lookup(mTokenIdent);
if (def)
v = 1;
else
v = 0;
NextPreToken();
}
else
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Identifier expected");
if (parenthesis)
{
if (mToken == TK_CLOSE_PARENTHESIS)
NextPreToken();
else
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "')' expected");
}
else
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "'(' expected");
}
else if (skip)
{
NextPreToken();
v = 0;
}
else
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Invalid preprocessor symbol", mTokenIdent);
@ -2352,9 +2382,9 @@ int64 Scanner::PrepParseSimple(void)
return v;
}
int64 Scanner::PrepParseMul(void)
int64 Scanner::PrepParseMul(bool skip)
{
int64 v = PrepParseSimple();
int64 v = PrepParseSimple(skip);
int64 u;
for (;;)
{
@ -2362,19 +2392,23 @@ int64 Scanner::PrepParseMul(void)
{
case TK_MUL:
NextPreToken();
v *= PrepParseSimple();
v *= PrepParseSimple(skip);
break;
case TK_DIV:
NextPreToken();
u = PrepParseSimple();
if (u == 0)
u = PrepParseSimple(skip);
if (skip)
;
else if (u == 0)
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Division by zero");
else
v /= u;
break;
case TK_MOD:
u = PrepParseSimple();
if (u == 0)
u = PrepParseSimple(skip);
if (skip)
;
else if (u == 0)
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Division by zero");
else
v %= u;
@ -2385,20 +2419,20 @@ int64 Scanner::PrepParseMul(void)
}
}
int64 Scanner::PrepParseAdd(void)
int64 Scanner::PrepParseAdd(bool skip)
{
int64 v = PrepParseMul();
int64 v = PrepParseMul(skip);
for (;;)
{
switch (mToken)
{
case TK_ADD:
NextPreToken();
v += PrepParseMul();
v += PrepParseMul(skip);
break;
case TK_SUB:
NextPreToken();
v -= PrepParseMul();
v -= PrepParseMul(skip);
break;
default:
return v;
@ -2406,20 +2440,20 @@ int64 Scanner::PrepParseAdd(void)
}
}
int64 Scanner::PrepParseShift(void)
int64 Scanner::PrepParseShift(bool skip)
{
int64 v = PrepParseAdd();
int64 v = PrepParseAdd(skip);
for (;;)
{
switch (mToken)
{
case TK_LEFT_SHIFT:
NextPreToken();
v <<= PrepParseAdd();
v <<= PrepParseAdd(skip);
break;
case TK_RIGHT_SHIFT:
NextPreToken();
v >>= PrepParseAdd();
v >>= PrepParseAdd(skip);
break;
default:
return v;
@ -2427,36 +2461,36 @@ int64 Scanner::PrepParseShift(void)
}
}
int64 Scanner::PrepParseRel(void)
int64 Scanner::PrepParseRel(bool skip)
{
int64 v = PrepParseShift();
int64 v = PrepParseShift(skip);
for (;;)
{
switch (mToken)
{
case TK_LESS_THAN:
NextPreToken();
v = v < PrepParseShift();
v = v < PrepParseShift(skip);
break;
case TK_GREATER_THAN:
NextPreToken();
v = v > PrepParseShift();
v = v > PrepParseShift(skip);
break;
case TK_LESS_EQUAL:
NextPreToken();
v = v <= PrepParseShift();
v = v <= PrepParseShift(skip);
break;
case TK_GREATER_EQUAL:
NextPreToken();
v = v >= PrepParseShift();
v = v >= PrepParseShift(skip);
break;
case TK_EQUAL:
NextPreToken();
v = v == PrepParseShift();
v = v == PrepParseShift(skip);
break;
case TK_NOT_EQUAL:
NextPreToken();
v = v != PrepParseShift();
v = v != PrepParseShift(skip);
break;
default:
return v;
@ -2465,75 +2499,75 @@ int64 Scanner::PrepParseRel(void)
}
int64 Scanner::PrepParseBinaryAnd(void)
int64 Scanner::PrepParseBinaryAnd(bool skip)
{
int64 v = PrepParseRel();
int64 v = PrepParseRel(skip);
while (mToken == TK_BINARY_AND)
{
NextPreToken();
v &= PrepParseRel();
v &= PrepParseRel(skip);
}
return v;
}
int64 Scanner::PrepParseBinaryXor(void)
int64 Scanner::PrepParseBinaryXor(bool skip)
{
int64 v = PrepParseBinaryAnd();
int64 v = PrepParseBinaryAnd(skip);
while (mToken == TK_BINARY_XOR)
{
NextPreToken();
v ^= PrepParseBinaryAnd();
v ^= PrepParseBinaryAnd(skip);
}
return v;
}
int64 Scanner::PrepParseBinaryOr(void)
int64 Scanner::PrepParseBinaryOr(bool skip)
{
int64 v = PrepParseBinaryXor();
int64 v = PrepParseBinaryXor(skip);
while (mToken == TK_BINARY_OR)
{
NextPreToken();
v |= PrepParseBinaryXor();
v |= PrepParseBinaryXor(skip);
}
return v;
}
int64 Scanner::PrepParseLogicalAnd(void)
int64 Scanner::PrepParseLogicalAnd(bool skip)
{
int64 v = PrepParseBinaryOr();
int64 v = PrepParseBinaryOr(skip);
while (mToken == TK_LOGICAL_AND)
{
NextPreToken();
if (!PrepParseBinaryOr())
if (!PrepParseBinaryOr(skip || !v))
v = 0;
}
return v;
}
int64 Scanner::PrepParseLogicalOr(void)
int64 Scanner::PrepParseLogicalOr(bool skip)
{
int64 v = PrepParseLogicalAnd();
int64 v = PrepParseLogicalAnd(skip);
while (mToken == TK_LOGICAL_OR)
{
NextPreToken();
if (PrepParseLogicalAnd())
if (PrepParseLogicalAnd(skip || v))
v = 1;
}
return v;
}
int64 Scanner::PrepParseConditional(void)
int64 Scanner::PrepParseConditional(bool skip)
{
int64 v = PrepParseLogicalOr();
int64 v = PrepParseLogicalOr(skip);
if (mToken == TK_QUESTIONMARK)
{
NextPreToken();
int64 vt = PrepParseConditional();
int64 vt = PrepParseConditional(skip || v);
if (mToken == TK_COLON)
NextPreToken();
else
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "':' expected");
int64 vf = PrepParseConditional();
int64 vf = PrepParseConditional(skip || !v);
if (v)
v = vt;
else

View File

@ -311,16 +311,16 @@ protected:
bool NextChar(void);
void ParseNumberToken(void);
int64 PrepParseSimple(void);
int64 PrepParseMul(void);
int64 PrepParseAdd(void);
int64 PrepParseShift(void);
int64 PrepParseRel(void);
int64 PrepParseBinaryAnd(void);
int64 PrepParseBinaryXor(void);
int64 PrepParseBinaryOr(void);
int64 PrepParseLogicalAnd(void);
int64 PrepParseLogicalOr(void);
int64 PrepParseConditional(void);
int64 PrepParseSimple(bool skip);
int64 PrepParseMul(bool skip);
int64 PrepParseAdd(bool skip);
int64 PrepParseShift(bool skip);
int64 PrepParseRel(bool skip);
int64 PrepParseBinaryAnd(bool skip);
int64 PrepParseBinaryXor(bool skip);
int64 PrepParseBinaryOr(bool skip);
int64 PrepParseLogicalAnd(bool skip);
int64 PrepParseLogicalOr(bool skip);
int64 PrepParseConditional(bool skip = false);
};

View File

@ -186,6 +186,10 @@ int main2(int argc, const char** argv)
{
compiler->mCompilerOptions &= ~COPT_NATIVE;
}
else if (arg[1] == 'p' && arg[2] == 's' && arg[3] == 'c' && arg[4] == 'i')
{
compiler->mCompilerOptions |= COPT_PETSCII;
}
else if (arg[1] == 'O')
{
if (arg[2] == '0')