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 * -xz : extended zero page usage, more zero page space, but no return to basic
* -cid : cartridge type ID, used by vice emulator * -cid : cartridge type ID, used by vice emulator
* -pp : compile in C++ mode * -pp : compile in C++ mode
* -psci : use PETSCII encoding for all strings without prefix
A list of source files can be provided. 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_DEBUGINFO = 1ULL << 51;
static const uint64 COPT_CPLUSPLUS = 1ULL << 52; 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); GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "clear"); CheckFunc = !strcmp(mIdent->mString, "KeyExpansion");
CheckCase = false; CheckCase = false;
mEntryBlock = mBlocks[0]; mEntryBlock = mBlocks[0];

View File

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

View File

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

View File

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

View File

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

View File

@ -186,6 +186,10 @@ int main2(int argc, const char** argv)
{ {
compiler->mCompilerOptions &= ~COPT_NATIVE; 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') else if (arg[1] == 'O')
{ {
if (arg[2] == '0') if (arg[2] == '0')