Add \y00 for non adapted characters in s" or p" string literals
This commit is contained in:
parent
2435797bd1
commit
6b3c5249cf
|
@ -10709,6 +10709,16 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
|
|||
pblock->mIns.Push(mIns[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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1349,20 +1349,63 @@ static inline char p2s(char ch)
|
|||
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)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case 'a':
|
||||
case 'p':
|
||||
case 'P':
|
||||
case 's':
|
||||
case 'S':
|
||||
break;
|
||||
default:
|
||||
Error("Invalid string literal mode");
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
|
||||
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++];
|
||||
switch (mTokenChar)
|
||||
ch = mLine[mOffset++];
|
||||
switch (ch)
|
||||
{
|
||||
case '0':
|
||||
mTokenChar = '\0';
|
||||
|
@ -1390,6 +1433,17 @@ void Scanner::StringToken(char terminator, char mode)
|
|||
char c0 = 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))
|
||||
mTokenChar = 16 * HexValue(c0) + HexValue(c1);
|
||||
else
|
||||
|
@ -1397,9 +1451,12 @@ void Scanner::StringToken(char terminator, char mode)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
;
|
||||
mTokenChar = transchar(mode, ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
mTokenChar = transchar(mode, ch);
|
||||
|
||||
mTokenString[n++] = mTokenChar;
|
||||
}
|
||||
|
@ -1408,42 +1465,6 @@ void Scanner::StringToken(char terminator, char mode)
|
|||
|
||||
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;
|
||||
mOffset++;
|
||||
NextChar();
|
||||
|
@ -1459,14 +1480,26 @@ void Scanner::StringToken(char terminator, 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;
|
||||
|
||||
mTokenChar = mLine[mOffset++];
|
||||
char ch = mLine[mOffset++];
|
||||
|
||||
if (mTokenChar == '\\' && mLine[mOffset])
|
||||
if (ch == '\\' && mLine[mOffset])
|
||||
{
|
||||
mTokenChar = mLine[mOffset++];
|
||||
switch (mTokenChar)
|
||||
ch = mLine[mOffset++];
|
||||
switch (ch)
|
||||
{
|
||||
case '0':
|
||||
mTokenChar = '\0';
|
||||
|
@ -1494,6 +1527,17 @@ void Scanner::CharToken(char mode)
|
|||
char c0 = 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))
|
||||
mTokenChar = 16 * HexValue(c0) + HexValue(c1);
|
||||
else
|
||||
|
@ -1501,25 +1545,11 @@ void Scanner::CharToken(char mode)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
;
|
||||
mTokenChar = transchar(mode, ch);
|
||||
}
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
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");
|
||||
}
|
||||
else
|
||||
mTokenChar = transchar(mode, ch);
|
||||
|
||||
mTokenInteger = mTokenChar;
|
||||
|
||||
|
|
Loading…
Reference in New Issue