Add \y00 for non adapted characters in s" or p" string literals

This commit is contained in:
drmortalwombat 2022-04-04 16:35:37 +02:00
parent 2435797bd1
commit 6b3c5249cf
2 changed files with 103 additions and 63 deletions

View File

@ -10709,6 +10709,16 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
pblock->mIns.Push(mIns[0]); pblock->mIns.Push(mIns[0]);
mIns.Remove(0); mIns.Remove(0);
changed = true;
}
else if (lblock->mIns[ls - 1].mType == ASMIT_LDA && lblock->mIns[ls - 1].mMode == ASMIM_ZERO_PAGE && lblock->mIns[ls - 1].mAddress == mIns[0].mAddress &&
!(lblock->mIns[ls - 1].mLive & LIVE_CPU_REG_A))
{
lblock->mIns[ls - 1].mType = ASMIT_LDY; lblock->mIns[ls - 1].mLive |= LIVE_CPU_REG_Y;
pblock->mIns.Push(mIns[0]);
mIns.Remove(0);
changed = true; changed = true;
} }
} }

View File

@ -1349,20 +1349,63 @@ static inline char p2s(char ch)
return (ch & 0x1f) | p2smap[ch >> 5]; return (ch & 0x1f) | p2smap[ch >> 5];
} }
static inline char transchar(char mode, char ch)
{
switch (mode)
{
case 'a':
return ch;
case 'p':
if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')
return ch ^ 0x20;
else
return ch;
break;
case 'P':
if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')
return (ch ^ 0x20) & 0xdf;
else
return ch;
break;
case 's':
if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')
return p2s(ch ^ 0x20);
else
return p2s(ch);
break;
case 'S':
if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')
return p2s((ch ^ 0x20) & 0xdf);
else
return p2s(ch);
break;
}
}
void Scanner::StringToken(char terminator, char mode) void Scanner::StringToken(char terminator, char mode)
{ {
switch (mode)
{
case 'a':
case 'p':
case 'P':
case 's':
case 'S':
break;
default:
Error("Invalid string literal mode");
}
int n = 0; int n = 0;
while (mLine[mOffset] && mLine[mOffset] != terminator && mLine[mOffset] != '\n') while (mLine[mOffset] && mLine[mOffset] != terminator && mLine[mOffset] != '\n')
{ {
mTokenChar = mLine[mOffset++]; char ch = mLine[mOffset++];
if (mTokenChar == '\\' && mLine[mOffset]) if (ch == '\\' && mLine[mOffset])
{ {
mTokenChar = mLine[mOffset++]; ch = mLine[mOffset++];
switch (mTokenChar) switch (ch)
{ {
case '0': case '0':
mTokenChar = '\0'; mTokenChar = '\0';
@ -1390,6 +1433,17 @@ void Scanner::StringToken(char terminator, char mode)
char c0 = mLine[mOffset++]; char c0 = mLine[mOffset++];
char c1 = mLine[mOffset++]; char c1 = mLine[mOffset++];
if (IsHex(c0) && IsHex(c1))
mTokenChar = transchar(mode, 16 * HexValue(c0) + HexValue(c1));
else
mErrors->Error(mLocation, EERR_SYNTAX, "Invalid hex escape code");
}
break;
case 'y':
{
char c0 = mLine[mOffset++];
char c1 = mLine[mOffset++];
if (IsHex(c0) && IsHex(c1)) if (IsHex(c0) && IsHex(c1))
mTokenChar = 16 * HexValue(c0) + HexValue(c1); mTokenChar = 16 * HexValue(c0) + HexValue(c1);
else else
@ -1397,9 +1451,12 @@ void Scanner::StringToken(char terminator, char mode)
} }
break; break;
default: default:
; mTokenChar = transchar(mode, ch);
break;
} }
} }
else
mTokenChar = transchar(mode, ch);
mTokenString[n++] = mTokenChar; mTokenString[n++] = mTokenChar;
} }
@ -1408,42 +1465,6 @@ void Scanner::StringToken(char terminator, char mode)
if (mLine[mOffset] && mLine[mOffset] == terminator) if (mLine[mOffset] && mLine[mOffset] == terminator)
{ {
switch (mode)
{
case 'a':
break;
case 'p':
for (int i = 0; i < n; i++)
{
if (mTokenString[i] >= 'A' && mTokenString[i] <= 'Z' || mTokenString[i] >= 'a' && mTokenString[i] <= 'z')
mTokenString[i] = mTokenString[i] ^ 0x20;
}
break;
case 'P':
for (int i = 0; i < n; i++)
{
if (mTokenString[i] >= 'A' && mTokenString[i] <= 'Z' || mTokenString[i] >= 'a' && mTokenString[i] <= 'z')
mTokenString[i] = (mTokenString[i] ^ 0x20) & 0xdf;
}
break;
case 's':
for (int i = 0; i < n; i++)
{
if (mTokenString[i] >= 'A' && mTokenString[i] <= 'Z' || mTokenString[i] >= 'a' && mTokenString[i] <= 'z')
mTokenString[i] = p2s(mTokenString[i] ^ 0x20);
}
break;
case 'S':
for (int i = 0; i < n; i++)
{
if (mTokenString[i] >= 'A' && mTokenString[i] <= 'Z' || mTokenString[i] >= 'a' && mTokenString[i] <= 'z')
mTokenString[i] = p2s((mTokenString[i] ^ 0x20) & 0xdf);
}
break;
default:
Error("Invalid string literal mode");
}
mToken = TK_STRING; mToken = TK_STRING;
mOffset++; mOffset++;
NextChar(); NextChar();
@ -1459,14 +1480,26 @@ void Scanner::StringToken(char terminator, char mode)
void Scanner::CharToken(char mode) void Scanner::CharToken(char mode)
{ {
switch (mode)
{
case 'a':
case 'p':
case 'P':
case 's':
case 'S':
break;
default:
Error("Invalid string literal mode");
}
int n = 0; int n = 0;
mTokenChar = mLine[mOffset++]; char ch = mLine[mOffset++];
if (mTokenChar == '\\' && mLine[mOffset]) if (ch == '\\' && mLine[mOffset])
{ {
mTokenChar = mLine[mOffset++]; ch = mLine[mOffset++];
switch (mTokenChar) switch (ch)
{ {
case '0': case '0':
mTokenChar = '\0'; mTokenChar = '\0';
@ -1494,6 +1527,17 @@ void Scanner::CharToken(char mode)
char c0 = mLine[mOffset++]; char c0 = mLine[mOffset++];
char c1 = mLine[mOffset++]; char c1 = mLine[mOffset++];
if (IsHex(c0) && IsHex(c1))
mTokenChar = transchar(mode, 16 * HexValue(c0) + HexValue(c1));
else
mErrors->Error(mLocation, EERR_SYNTAX, "Invalid hex escape code");
}
break;
case 'y':
{
char c0 = mLine[mOffset++];
char c1 = mLine[mOffset++];
if (IsHex(c0) && IsHex(c1)) if (IsHex(c0) && IsHex(c1))
mTokenChar = 16 * HexValue(c0) + HexValue(c1); mTokenChar = 16 * HexValue(c0) + HexValue(c1);
else else
@ -1501,25 +1545,11 @@ void Scanner::CharToken(char mode)
} }
break; break;
default: default:
; mTokenChar = transchar(mode, ch);
} }
} }
else
switch (mode) mTokenChar = transchar(mode, ch);
{
case 'a':
break;
case 'p':
if (mTokenChar >= 'A' && mTokenChar <= 'Z' || mTokenChar >= 'a' && mTokenChar <= 'z')
mTokenChar = mTokenChar ^ 0x20;
break;
case 'P':
if (mTokenChar >= 'A' && mTokenChar <= 'Z' || mTokenChar >= 'a' && mTokenChar <= 'z')
mTokenChar = (mTokenChar ^ 0x20) & 0xdf;
break;
default:
Error("Invalid string literal mode");
}
mTokenInteger = mTokenChar; mTokenInteger = mTokenChar;