mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +02:00
Improvements to overflow arithmetic
This commit is contained in:
parent
eb375362a1
commit
bf97431cdb
12 changed files with 91 additions and 45 deletions
|
@ -73,7 +73,7 @@ namespace System
|
||||||
}
|
}
|
||||||
while (valLeft < 0)
|
while (valLeft < 0)
|
||||||
{
|
{
|
||||||
strChars[char8Idx] = (char8)('0' - (valLeft % 10));
|
strChars[char8Idx] = (char8)('0' &- (valLeft % 10));
|
||||||
valLeft /= 10;
|
valLeft /= 10;
|
||||||
char8Idx--;
|
char8Idx--;
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ namespace System
|
||||||
}
|
}
|
||||||
while ((valLeft < 0) || (minNumeralsLeft > 0))
|
while ((valLeft < 0) || (minNumeralsLeft > 0))
|
||||||
{
|
{
|
||||||
strChars[char8Idx] = (char8)('0' - (valLeft % 10));
|
strChars[char8Idx] = (char8)('0' &- (valLeft % 10));
|
||||||
valLeft /= 10;
|
valLeft /= 10;
|
||||||
char8Idx--;
|
char8Idx--;
|
||||||
minNumeralsLeft--;
|
minNumeralsLeft--;
|
||||||
|
|
|
@ -80,7 +80,7 @@ namespace System
|
||||||
{
|
{
|
||||||
for (int32 i = 1; i < 56; i++)
|
for (int32 i = 1; i < 56; i++)
|
||||||
{
|
{
|
||||||
SeedArray[i] -= SeedArray[1 + (i + 30) % 55];
|
SeedArray[i] &-= SeedArray[1 + (i + 30) % 55];
|
||||||
if (SeedArray[i] < 0) SeedArray[i] += MBIG;
|
if (SeedArray[i] < 0) SeedArray[i] += MBIG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,27 +129,27 @@ namespace System.Security.Cryptography
|
||||||
// The MD5 transformation for all four rounds.
|
// The MD5 transformation for all four rounds.
|
||||||
mixin STEP_F(var a, var b, var c, var d, var x, var t, var s)
|
mixin STEP_F(var a, var b, var c, var d, var x, var t, var s)
|
||||||
{
|
{
|
||||||
a += F!(b, c, d) + x + t;
|
a &+= F!(b, c, d) &+ x &+ t;
|
||||||
a = ((a << s) | ((a & 0xffffffff) >> (32 - s)));
|
a = ((a << s) | ((a & 0xffffffff) >> (32 - s)));
|
||||||
a += b;
|
a &+= b;
|
||||||
}
|
}
|
||||||
mixin STEP_G(var a, var b, var c, var d, var x, var t, var s)
|
mixin STEP_G(var a, var b, var c, var d, var x, var t, var s)
|
||||||
{
|
{
|
||||||
a += G!(b, c, d) + x + t;
|
a &+= G!(b, c, d) &+ x &+ t;
|
||||||
a = ((a << s) | ((a & 0xffffffff) >> (32 - s)));
|
a = ((a << s) | ((a & 0xffffffff) >> (32 - s)));
|
||||||
a += b;
|
a &+= b;
|
||||||
}
|
}
|
||||||
mixin STEP_H(var a, var b, var c, var d, var x, var t, var s)
|
mixin STEP_H(var a, var b, var c, var d, var x, var t, var s)
|
||||||
{
|
{
|
||||||
a += H!(b, c, d) + x + t;
|
a &+= H!(b, c, d) &+ x &+ t;
|
||||||
a = ((a << s) | ((a & 0xffffffff) >> (32 - s)));
|
a = ((a << s) | ((a & 0xffffffff) >> (32 - s)));
|
||||||
a += b;
|
a &+= b;
|
||||||
}
|
}
|
||||||
mixin STEP_I(var a, var b, var c, var d, var x, var t, var s)
|
mixin STEP_I(var a, var b, var c, var d, var x, var t, var s)
|
||||||
{
|
{
|
||||||
a += I!(b, c, d) + x + t;
|
a &+= I!(b, c, d) &+ x &+ t;
|
||||||
a = ((a << s) | ((a & 0xffffffff) >> (32 - s)));
|
a = ((a << s) | ((a & 0xffffffff) >> (32 - s)));
|
||||||
a += b;
|
a &+= b;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SET reads 4 input bytes in little-endian byte order and stores them
|
// SET reads 4 input bytes in little-endian byte order and stores them
|
||||||
|
@ -249,10 +249,10 @@ namespace System.Security.Cryptography
|
||||||
STEP_I!(c, d, a, b, GET!(2), 0x2ad7d2bb, 15);
|
STEP_I!(c, d, a, b, GET!(2), 0x2ad7d2bb, 15);
|
||||||
STEP_I!(b, c, d, a, GET!(9), 0xeb86d391, 21);
|
STEP_I!(b, c, d, a, GET!(9), 0xeb86d391, 21);
|
||||||
|
|
||||||
a += saved_a;
|
a &+= saved_a;
|
||||||
b += saved_b;
|
b &+= saved_b;
|
||||||
c += saved_c;
|
c &+= saved_c;
|
||||||
d += saved_d;
|
d &+= saved_d;
|
||||||
|
|
||||||
ptr += 64;
|
ptr += 64;
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,7 +142,7 @@ namespace System.Security.Cryptography
|
||||||
for (i = 0, j = 0; i < 16; ++i, j += 4)
|
for (i = 0, j = 0; i < 16; ++i, j += 4)
|
||||||
m[i] = ((uint32)mData[j] << 24) | ((uint32)mData[j + 1] << 16) | ((uint32)mData[j + 2] << 8) | ((uint32)mData[j + 3]);
|
m[i] = ((uint32)mData[j] << 24) | ((uint32)mData[j + 1] << 16) | ((uint32)mData[j + 2] << 8) | ((uint32)mData[j + 3]);
|
||||||
for ( ; i < 64; ++i)
|
for ( ; i < 64; ++i)
|
||||||
m[i] = SIG1!(m[i - 2]) + m[i - 7] + SIG0!(m[i - 15]) + m[i - 16];
|
m[i] = SIG1!(m[i - 2]) &+ m[i - 7] &+ SIG0!(m[i - 15]) &+ m[i - 16];
|
||||||
|
|
||||||
a = mState[0];
|
a = mState[0];
|
||||||
b = mState[1];
|
b = mState[1];
|
||||||
|
@ -155,26 +155,26 @@ namespace System.Security.Cryptography
|
||||||
|
|
||||||
for (i = 0; i < 64; ++i)
|
for (i = 0; i < 64; ++i)
|
||||||
{
|
{
|
||||||
t1 = h + EP1!(e) + CH!(e,f,g) + k[i] + m[i];
|
t1 = h &+ EP1!(e) &+ CH!(e,f,g) &+ k[i] &+ m[i];
|
||||||
t2 = EP0!(a) + MAJ!(a,b,c);
|
t2 = EP0!(a) &+ MAJ!(a,b,c);
|
||||||
h = g;
|
h = g;
|
||||||
g = f;
|
g = f;
|
||||||
f = e;
|
f = e;
|
||||||
e = d + t1;
|
e = d &+ t1;
|
||||||
d = c;
|
d = c;
|
||||||
c = b;
|
c = b;
|
||||||
b = a;
|
b = a;
|
||||||
a = t1 + t2;
|
a = t1 &+ t2;
|
||||||
}
|
}
|
||||||
|
|
||||||
mState[0] += a;
|
mState[0] &+= a;
|
||||||
mState[1] += b;
|
mState[1] &+= b;
|
||||||
mState[2] += c;
|
mState[2] &+= c;
|
||||||
mState[3] += d;
|
mState[3] &+= d;
|
||||||
mState[4] += e;
|
mState[4] &+= e;
|
||||||
mState[5] += f;
|
mState[5] &+= f;
|
||||||
mState[6] += g;
|
mState[6] &+= g;
|
||||||
mState[7] += h;
|
mState[7] &+= h;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(Span<uint8> data)
|
public void Update(Span<uint8> data)
|
||||||
|
|
|
@ -397,14 +397,14 @@ namespace System
|
||||||
let intSize = sizeof(int);
|
let intSize = sizeof(int);
|
||||||
while (charsLeft >= intSize)
|
while (charsLeft >= intSize)
|
||||||
{
|
{
|
||||||
hash = (hash ^ *((int*)curPtr)) + (hash * 16777619);
|
hash = (hash ^ *((int*)curPtr)) &+ (hash &* 16777619);
|
||||||
charsLeft -= intSize;
|
charsLeft -= intSize;
|
||||||
curPtr += intSize;
|
curPtr += intSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (charsLeft > 1)
|
while (charsLeft > 1)
|
||||||
{
|
{
|
||||||
hash = ((hash ^ (int)*curPtr) << 5) - hash;
|
hash = ((hash ^ (int)*curPtr) << 5) &- hash;
|
||||||
charsLeft--;
|
charsLeft--;
|
||||||
curPtr++;
|
curPtr++;
|
||||||
}
|
}
|
||||||
|
@ -1774,8 +1774,8 @@ namespace System
|
||||||
//Contract.Assert((char8A | char8B) <= 0x7F, "strings have to be ASCII");
|
//Contract.Assert((char8A | char8B) <= 0x7F, "strings have to be ASCII");
|
||||||
|
|
||||||
// uppercase both chars - notice that we need just one compare per char
|
// uppercase both chars - notice that we need just one compare per char
|
||||||
if ((uint32)(charA - 'a') <= (uint32)('z' - 'a')) charA -= 0x20;
|
if ((uint32)(charA &- 'a') <= (uint32)('z' - 'a')) charA -= 0x20;
|
||||||
if ((uint32)(charB - 'a') <= (uint32)('z' - 'a')) charB -= 0x20;
|
if ((uint32)(charB &- 'a') <= (uint32)('z' - 'a')) charB -= 0x20;
|
||||||
|
|
||||||
//Return the (case-insensitive) difference between them.
|
//Return the (case-insensitive) difference between them.
|
||||||
if (charA != charB)
|
if (charA != charB)
|
||||||
|
@ -1807,8 +1807,8 @@ namespace System
|
||||||
//Contract.Assert((char8A | char8B) <= 0x7F, "strings have to be ASCII");
|
//Contract.Assert((char8A | char8B) <= 0x7F, "strings have to be ASCII");
|
||||||
|
|
||||||
// uppercase both chars - notice that we need just one compare per char
|
// uppercase both chars - notice that we need just one compare per char
|
||||||
if ((uint32)(charA - 'a') <= (uint32)('z' - 'a')) charA -= 0x20;
|
if ((uint32)(charA &- 'a') <= (uint32)('z' - 'a')) charA -= 0x20;
|
||||||
if ((uint32)(charB - 'a') <= (uint32)('z' - 'a')) charB -= 0x20;
|
if ((uint32)(charB &- 'a') <= (uint32)('z' - 'a')) charB -= 0x20;
|
||||||
|
|
||||||
//Return the (case-insensitive) difference between them.
|
//Return the (case-insensitive) difference between them.
|
||||||
if (charA != charB)
|
if (charA != charB)
|
||||||
|
@ -1835,8 +1835,8 @@ namespace System
|
||||||
|
|
||||||
//Contract.Assert((char8A | char8B) <= 0x7F, "strings have to be ASCII");
|
//Contract.Assert((char8A | char8B) <= 0x7F, "strings have to be ASCII");
|
||||||
// uppercase both chars - notice that we need just one compare per char
|
// uppercase both chars - notice that we need just one compare per char
|
||||||
if ((uint32)(charA - 'a') <= (uint32)('z' - 'a')) charA -= 0x20;
|
if ((uint32)(charA &- 'a') <= (uint32)('z' - 'a')) charA -= 0x20;
|
||||||
if ((uint32)(charB - 'a') <= (uint32)('z' - 'a')) charB -= 0x20;
|
if ((uint32)(charB &- 'a') <= (uint32)('z' - 'a')) charB -= 0x20;
|
||||||
|
|
||||||
//Return the (case-insensitive) difference between them.
|
//Return the (case-insensitive) difference between them.
|
||||||
if (charA != charB)
|
if (charA != charB)
|
||||||
|
|
|
@ -9226,7 +9226,7 @@ bool BeMCContext::DoLegalization()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool addCanBeLEA =
|
bool addCanBeLEA =
|
||||||
((inst->mKind == BeMCInstKind_Sub) || (inst->mKind == BeMCInstKind_Add)) &&
|
((inst->mKind == BeMCInstKind_Sub) || (inst->mKind == BeMCInstKind_Add)) && (!inst->mDisableShortForm) &&
|
||||||
(arg0Type->mSize >= 2) && // Int8s don't have an LEA
|
(arg0Type->mSize >= 2) && // Int8s don't have an LEA
|
||||||
(GetFixedOperand(inst->mResult).IsNativeReg()) && (arg0.IsNativeReg()) && (arg1.IsImmediateInt());
|
(GetFixedOperand(inst->mResult).IsNativeReg()) && (arg0.IsNativeReg()) && (arg1.IsImmediateInt());
|
||||||
|
|
||||||
|
@ -10209,7 +10209,7 @@ bool BeMCContext::DoLegalization()
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handled)
|
if (!handled)
|
||||||
{
|
{
|
||||||
if (inst->mResult)
|
if (inst->mResult)
|
||||||
{
|
{
|
||||||
|
@ -14338,6 +14338,7 @@ void BeMCContext::DoCodeEmission()
|
||||||
{
|
{
|
||||||
if ((inst->mResult) && (inst->mResult != inst->mArg0))
|
if ((inst->mResult) && (inst->mResult != inst->mArg0))
|
||||||
{
|
{
|
||||||
|
BF_ASSERT(!inst->mDisableShortForm);
|
||||||
BF_ASSERT(inst->mResult.IsNativeReg());
|
BF_ASSERT(inst->mResult.IsNativeReg());
|
||||||
BF_ASSERT(inst->mArg0.IsNativeReg());
|
BF_ASSERT(inst->mArg0.IsNativeReg());
|
||||||
BF_ASSERT(inst->mArg1.IsImmediate());
|
BF_ASSERT(inst->mArg1.IsImmediate());
|
||||||
|
@ -14538,9 +14539,9 @@ void BeMCContext::DoCodeEmission()
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
BF_ASSERT(inst->mArg1.IsImmediate());
|
BF_ASSERT(inst->mArg1.IsImmediate());
|
||||||
if ((inst->mArg0.IsNativeReg()) &&
|
if ((inst->mArg0.IsNativeReg()) && (!inst->mDisableShortForm) &&
|
||||||
((inst->mArg1.mImmediate == 2) || (inst->mArg1.mImmediate == 4) || (inst->mArg1.mImmediate == 8)))
|
((inst->mArg1.mImmediate == 2) || (inst->mArg1.mImmediate == 4) || (inst->mArg1.mImmediate == 8)))
|
||||||
{
|
{
|
||||||
// LEA form
|
// LEA form
|
||||||
auto resultType = GetType(inst->mArg0);
|
auto resultType = GetType(inst->mArg0);
|
||||||
if (resultType->mTypeCode != BeTypeCode_Int8)
|
if (resultType->mTypeCode != BeTypeCode_Int8)
|
||||||
|
@ -16030,6 +16031,7 @@ BeMCOperand BeMCContext::AllocBinaryOp(BeMCInstKind instKind, const BeMCOperand&
|
||||||
|
|
||||||
if (overflowCheckKind != BeMCOverflowCheckKind_None)
|
if (overflowCheckKind != BeMCOverflowCheckKind_None)
|
||||||
{
|
{
|
||||||
|
mcInst->mDisableShortForm = true;
|
||||||
AllocInst(BeMCInstKind_CondBr, BeMCOperand::FromImmediate(1), BeMCOperand::FromCmpKind((overflowCheckKind == BeMCOverflowCheckKind_B) ? BeCmpKind_NB : BeCmpKind_NO));
|
AllocInst(BeMCInstKind_CondBr, BeMCOperand::FromImmediate(1), BeMCOperand::FromCmpKind((overflowCheckKind == BeMCOverflowCheckKind_B) ? BeCmpKind_NB : BeCmpKind_NO));
|
||||||
AllocInst(BeMCInstKind_DbgBreak);
|
AllocInst(BeMCInstKind_DbgBreak);
|
||||||
}
|
}
|
||||||
|
|
|
@ -564,6 +564,7 @@ class BeMCInst
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BeMCInstKind mKind;
|
BeMCInstKind mKind;
|
||||||
|
bool mDisableShortForm;
|
||||||
|
|
||||||
BeMCOperand mResult;
|
BeMCOperand mResult;
|
||||||
BeMCOperand mArg0;
|
BeMCOperand mArg0;
|
||||||
|
|
|
@ -1513,6 +1513,12 @@ const char* Beefy::BfTokenToString(BfToken token)
|
||||||
return "&+";
|
return "&+";
|
||||||
case BfToken_AndStar:
|
case BfToken_AndStar:
|
||||||
return "&*";
|
return "&*";
|
||||||
|
case BfToken_AndMinusEquals:
|
||||||
|
return "&-=";
|
||||||
|
case BfToken_AndPlusEquals:
|
||||||
|
return "&+=";
|
||||||
|
case BfToken_AndStarEquals:
|
||||||
|
return "&*=";
|
||||||
case BfToken_OrEquals:
|
case BfToken_OrEquals:
|
||||||
return "|=";
|
return "|=";
|
||||||
case BfToken_XorEquals:
|
case BfToken_XorEquals:
|
||||||
|
@ -1620,6 +1626,12 @@ BfBinaryOp Beefy::BfAssignOpToBinaryOp(BfAssignmentOp assignmentOp)
|
||||||
return BfBinaryOp_Multiply;
|
return BfBinaryOp_Multiply;
|
||||||
case BfAssignmentOp_Divide:
|
case BfAssignmentOp_Divide:
|
||||||
return BfBinaryOp_Divide;
|
return BfBinaryOp_Divide;
|
||||||
|
case BfAssignmentOp_OverflowAdd:
|
||||||
|
return BfBinaryOp_OverflowAdd;
|
||||||
|
case BfAssignmentOp_OverflowSubtract:
|
||||||
|
return BfBinaryOp_OverflowSubtract;
|
||||||
|
case BfAssignmentOp_OverflowMultiply:
|
||||||
|
return BfBinaryOp_OverflowMultiply;
|
||||||
case BfAssignmentOp_Modulus:
|
case BfAssignmentOp_Modulus:
|
||||||
return BfBinaryOp_Modulus;
|
return BfBinaryOp_Modulus;
|
||||||
case BfAssignmentOp_ShiftLeft:
|
case BfAssignmentOp_ShiftLeft:
|
||||||
|
@ -1898,7 +1910,13 @@ BfAssignmentOp Beefy::BfTokenToAssignmentOp(BfToken token)
|
||||||
case BfToken_MinusEquals:
|
case BfToken_MinusEquals:
|
||||||
return BfAssignmentOp_Subtract;
|
return BfAssignmentOp_Subtract;
|
||||||
case BfToken_MultiplyEquals:
|
case BfToken_MultiplyEquals:
|
||||||
return BfAssignmentOp_Multiply;
|
return BfAssignmentOp_Multiply;
|
||||||
|
case BfToken_AndPlusEquals:
|
||||||
|
return BfAssignmentOp_OverflowAdd;
|
||||||
|
case BfToken_AndMinusEquals:
|
||||||
|
return BfAssignmentOp_OverflowSubtract;
|
||||||
|
case BfToken_AndStarEquals:
|
||||||
|
return BfAssignmentOp_OverflowMultiply;
|
||||||
case BfToken_DivideEquals:
|
case BfToken_DivideEquals:
|
||||||
return BfAssignmentOp_Divide;
|
return BfAssignmentOp_Divide;
|
||||||
case BfToken_ModulusEquals:
|
case BfToken_ModulusEquals:
|
||||||
|
|
|
@ -205,7 +205,6 @@ enum BfToken : uint8
|
||||||
BfToken_PlusEquals,
|
BfToken_PlusEquals,
|
||||||
BfToken_MinusEquals,
|
BfToken_MinusEquals,
|
||||||
BfToken_MultiplyEquals,
|
BfToken_MultiplyEquals,
|
||||||
|
|
||||||
BfToken_DivideEquals,
|
BfToken_DivideEquals,
|
||||||
BfToken_ModulusEquals,
|
BfToken_ModulusEquals,
|
||||||
BfToken_ShiftLeftEquals,
|
BfToken_ShiftLeftEquals,
|
||||||
|
@ -214,6 +213,9 @@ enum BfToken : uint8
|
||||||
BfToken_AndMinus,
|
BfToken_AndMinus,
|
||||||
BfToken_AndPlus,
|
BfToken_AndPlus,
|
||||||
BfToken_AndStar,
|
BfToken_AndStar,
|
||||||
|
BfToken_AndMinusEquals,
|
||||||
|
BfToken_AndPlusEquals,
|
||||||
|
BfToken_AndStarEquals,
|
||||||
BfToken_OrEquals,
|
BfToken_OrEquals,
|
||||||
BfToken_XorEquals,
|
BfToken_XorEquals,
|
||||||
BfToken_NullCoalsceEquals,
|
BfToken_NullCoalsceEquals,
|
||||||
|
@ -1843,6 +1845,9 @@ enum BfAssignmentOp
|
||||||
BfAssignmentOp_Add,
|
BfAssignmentOp_Add,
|
||||||
BfAssignmentOp_Subtract,
|
BfAssignmentOp_Subtract,
|
||||||
BfAssignmentOp_Multiply,
|
BfAssignmentOp_Multiply,
|
||||||
|
BfAssignmentOp_OverflowAdd,
|
||||||
|
BfAssignmentOp_OverflowSubtract,
|
||||||
|
BfAssignmentOp_OverflowMultiply,
|
||||||
BfAssignmentOp_Divide,
|
BfAssignmentOp_Divide,
|
||||||
BfAssignmentOp_Modulus,
|
BfAssignmentOp_Modulus,
|
||||||
BfAssignmentOp_ShiftLeft,
|
BfAssignmentOp_ShiftLeft,
|
||||||
|
|
|
@ -22667,6 +22667,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
|
||||||
|
|
||||||
auto _GetOverflowKind = [&](bool wantOverflow)
|
auto _GetOverflowKind = [&](bool wantOverflow)
|
||||||
{
|
{
|
||||||
|
if (resultType->IsFloat())
|
||||||
|
return BfOverflowCheckKind_None;
|
||||||
if (!wantOverflow)
|
if (!wantOverflow)
|
||||||
return BfOverflowCheckKind_None;
|
return BfOverflowCheckKind_None;
|
||||||
if (mModule->GetDefaultCheckedKind() != BfCheckedKind_Checked)
|
if (mModule->GetDefaultCheckedKind() != BfCheckedKind_Checked)
|
||||||
|
|
|
@ -1559,17 +1559,35 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
|
||||||
}
|
}
|
||||||
else if (mSrc[mSrcIdx] == '+')
|
else if (mSrc[mSrcIdx] == '+')
|
||||||
{
|
{
|
||||||
mToken = BfToken_AndPlus;
|
if (mSrc[mSrcIdx + 1] == '=')
|
||||||
|
{
|
||||||
|
mToken = BfToken_AndPlusEquals;
|
||||||
|
++mSrcIdx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mToken = BfToken_AndPlus;
|
||||||
mTokenEnd = ++mSrcIdx;
|
mTokenEnd = ++mSrcIdx;
|
||||||
}
|
}
|
||||||
else if (mSrc[mSrcIdx] == '-')
|
else if (mSrc[mSrcIdx] == '-')
|
||||||
{
|
{
|
||||||
mToken = BfToken_AndMinus;
|
if (mSrc[mSrcIdx + 1] == '=')
|
||||||
|
{
|
||||||
|
mToken = BfToken_AndMinusEquals;
|
||||||
|
++mSrcIdx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mToken = BfToken_AndMinus;
|
||||||
mTokenEnd = ++mSrcIdx;
|
mTokenEnd = ++mSrcIdx;
|
||||||
}
|
}
|
||||||
else if (mSrc[mSrcIdx] == '*')
|
else if (mSrc[mSrcIdx] == '*')
|
||||||
{
|
{
|
||||||
mToken = BfToken_AndStar;
|
if (mSrc[mSrcIdx + 1] == '=')
|
||||||
|
{
|
||||||
|
mToken = BfToken_AndStarEquals;
|
||||||
|
++mSrcIdx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mToken = BfToken_AndStar;
|
||||||
mTokenEnd = ++mSrcIdx;
|
mTokenEnd = ++mSrcIdx;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue