📄 xvm.cpp
字号:
if ( ResolveOpPntr ( 0 ) == ResolveOpPntr ( 1 ) )
break;
// Copy the source operand into the destination
CopyValue ( & Dest, Source );
break;
// The arithmetic instructions only work with destination types that
// are either integers or floats. They first check for integers and
// assume that anything else is a float. Mod only works with integers.
// Add
case INSTR_ADD:
if ( Dest.iType == OP_TYPE_INT )
Dest.iIntLiteral += ResolveOpAsInt ( 1 );
else
Dest.fFloatLiteral += ResolveOpAsFloat ( 1 );
break;
// Subtract
case INSTR_SUB:
if ( Dest.iType == OP_TYPE_INT )
Dest.iIntLiteral -= ResolveOpAsInt ( 1 );
else
Dest.fFloatLiteral -= ResolveOpAsFloat ( 1 );
break;
// Multiply
case INSTR_MUL:
if ( Dest.iType == OP_TYPE_INT )
Dest.iIntLiteral *= ResolveOpAsInt ( 1 );
else
Dest.fFloatLiteral *= ResolveOpAsFloat ( 1 );
break;
// Divide
case INSTR_DIV:
if ( Dest.iType == OP_TYPE_INT )
Dest.iIntLiteral /= ResolveOpAsInt ( 1 );
else
Dest.fFloatLiteral /= ResolveOpAsFloat ( 1 );
break;
// Modulus
case INSTR_MOD:
// Remember, Mod works with integers only
if ( Dest.iType == OP_TYPE_INT )
Dest.iIntLiteral %= ResolveOpAsInt ( 1 );
break;
// Exponentiate
case INSTR_EXP:
if ( Dest.iType == OP_TYPE_INT )
Dest.iIntLiteral = ( int ) pow ( Dest.iIntLiteral, ResolveOpAsInt ( 1 ) );
else
Dest.fFloatLiteral = ( float ) pow ( Dest.fFloatLiteral, ResolveOpAsFloat ( 1 ) );
break;
// The bitwise instructions only work with integers. They do nothing
// when the destination data type is anything else.
// And
case INSTR_AND:
if ( Dest.iType == OP_TYPE_INT )
Dest.iIntLiteral &= ResolveOpAsInt ( 1 );
break;
// Or
case INSTR_OR:
if ( Dest.iType == OP_TYPE_INT )
Dest.iIntLiteral |= ResolveOpAsInt ( 1 );
break;
// Exclusive Or
case INSTR_XOR:
if ( Dest.iType == OP_TYPE_INT )
Dest.iIntLiteral ^= ResolveOpAsInt ( 1 );
break;
// Shift Left
case INSTR_SHL:
if ( Dest.iType == OP_TYPE_INT )
Dest.iIntLiteral <<= ResolveOpAsInt ( 1 );
break;
// Shift Right
case INSTR_SHR:
if ( Dest.iType == OP_TYPE_INT )
Dest.iIntLiteral >>= ResolveOpAsInt ( 1 );
break;
}
// Use ResolveOpPntr () to get a pointer to the destination Value structure and
// move the result there
* ResolveOpPntr ( 0 ) = Dest;
break;
}
// ---- Unary Operations
// These instructions work much like the binary operations in the sense that
// they only work with integers and floats (except Not, which works with
// integers only). Any other destination data type will be ignored.
case INSTR_NEG:
case INSTR_NOT:
case INSTR_INC:
case INSTR_DEC:
{
// Get the destination type (operand index 0)
int iDestStoreType = GetOpType ( 0 );
// Get a local copy of the destination itself
Value Dest = ResolveOpValue ( 0 );
switch ( iOpcode )
{
// Negate
case INSTR_NEG:
if ( Dest.iType == OP_TYPE_INT )
Dest.iIntLiteral = -Dest.iIntLiteral;
else
Dest.fFloatLiteral = -Dest.fFloatLiteral;
break;
// Not
case INSTR_NOT:
if ( Dest.iType == OP_TYPE_INT )
Dest.iIntLiteral = ~ Dest.iIntLiteral;
break;
// Increment
case INSTR_INC:
if ( Dest.iType == OP_TYPE_INT )
++ Dest.iIntLiteral;
else
++ Dest.fFloatLiteral;
break;
// Decrement
case INSTR_DEC:
if ( Dest.iType == OP_TYPE_INT )
-- Dest.iIntLiteral;
else
-- Dest.fFloatLiteral;
break;
}
// Move the result to the destination
* ResolveOpPntr ( 0 ) = Dest;
break;
}
// ---- String Processing
case INSTR_CONCAT:
{
// Get a local copy of the destination operand (operand index 0)
Value Dest = ResolveOpValue ( 0 );
// Get a local copy of the source string (operand index 1)
char * pstrSourceString = ResolveOpAsString ( 1 );
// If the destination isn't a string, do nothing
if ( Dest.iType != OP_TYPE_STRING )
break;
// Determine the length of the new string and allocate space for it (with a
// null terminator)
int iNewStringLength = strlen ( Dest.pstrStringLiteral ) + strlen ( pstrSourceString );
char * pstrNewString = ( char * ) malloc ( iNewStringLength + 1 );
// Copy the old string to the new one
strcpy ( pstrNewString, Dest.pstrStringLiteral );
// Concatenate the destination with the source
strcat ( pstrNewString, pstrSourceString );
// Free the existing string in the destination structure and replace it
// with the new string
free ( Dest.pstrStringLiteral );
Dest.pstrStringLiteral = pstrNewString;
// Copy the concatenated string pointer to its destination
* ResolveOpPntr ( 0 ) = Dest;
break;
}
case INSTR_GETCHAR:
{
// Get a local copy of the destination operand (operand index 0)
Value Dest = ResolveOpValue ( 0 );
// Get a local copy of the source string (operand index 1)
char * pstrSourceString = ResolveOpAsString ( 1 );
// Find out whether or not the destination is already a string
char * pstrNewString;
if ( Dest.iType == OP_TYPE_STRING )
{
// If it is, we can use it's existing string buffer as long as it's at
// least 1 character
if ( strlen ( Dest.pstrStringLiteral ) >= 1 )
{
pstrNewString = Dest.pstrStringLiteral;
}
else
{
free ( Dest.pstrStringLiteral );
pstrNewString = ( char * ) malloc ( 2 );
}
}
else
{
// Otherwise allocate a new string and set the type
pstrNewString = ( char * ) malloc ( 2 );
Dest.iType = OP_TYPE_STRING;
}
// Get the index of the character (operand index 2)
int iSourceIndex = ResolveOpAsInt ( 2 );
// Copy the character and append a null-terminator
pstrNewString [ 0 ] = pstrSourceString [ iSourceIndex ];
pstrNewString [ 1 ] = '\0';
// Set the string pointer in the destination Value structure
Dest.pstrStringLiteral = pstrNewString;
// Copy the concatenated string pointer to its destination
* ResolveOpPntr ( 0 ) = Dest;
break;
}
case INSTR_SETCHAR:
{
// Get the destination index (operand index 1)
int iDestIndex = ResolveOpAsInt ( 1 );
// If the destination isn't a string, do nothing
if ( ResolveOpType ( 0 ) != OP_TYPE_STRING )
break;
// Get the source character (operand index 2)
char * pstrSourceString = ResolveOpAsString ( 2 );
// Set the specified character in the destination (operand index 0)
ResolveOpPntr ( 0 )->pstrStringLiteral [ iDestIndex ] = pstrSourceString [ 0 ];
break;
}
// ---- Conditional Branching
case INSTR_JMP:
{
// Get the index of the target instruction (opcode index 0)
int iTargetIndex = ResolveOpAsInstrIndex ( 0 );
// Move the instruction pointer to the target
g_Scripts [ g_iCurrThread ].InstrStream.iCurrInstr = iTargetIndex;
break;
}
case INSTR_JE:
case INSTR_JNE:
case INSTR_JG:
case INSTR_JL:
case INSTR_JGE:
case INSTR_JLE:
{
// Get the two operands
Value Op0 = ResolveOpValue ( 0 );
Value Op1 = ResolveOpValue ( 1 );
// Get the index of the target instruction (opcode index 2)
int iTargetIndex = ResolveOpAsInstrIndex ( 2 );
// Perform the specified comparison and jump if it evaluates to true
int iJump = FALSE;
switch ( iOpcode )
{
// Jump if Equal
case INSTR_JE:
{
switch ( Op0.iType )
{
case OP_TYPE_INT:
if ( Op0.iIntLiteral == Op1.iIntLiteral )
iJump = TRUE;
break;
case OP_TYPE_FLOAT:
if ( Op0.fFloatLiteral == Op1.fFloatLiteral )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -