diff options
author | Sven Hesse | 2009-06-15 23:10:27 +0000 |
---|---|---|
committer | Sven Hesse | 2009-06-15 23:10:27 +0000 |
commit | 58fbca49f56684b4460af9e5b89de9777b364dbf (patch) | |
tree | 612716753e2c2d212b4e6f0f64cb96d9eeb0cbc2 /engines/gob | |
parent | 221953344175d81396675f96c3f51e3d52491cbb (diff) | |
download | scummvm-rg350-58fbca49f56684b4460af9e5b89de9777b364dbf.tar.gz scummvm-rg350-58fbca49f56684b4460af9e5b89de9777b364dbf.tar.bz2 scummvm-rg350-58fbca49f56684b4460af9e5b89de9777b364dbf.zip |
Splitting up parseExpr a bit
svn-id: r41572
Diffstat (limited to 'engines/gob')
-rw-r--r-- | engines/gob/parse.cpp | 784 | ||||
-rw-r--r-- | engines/gob/parse.h | 10 |
2 files changed, 415 insertions, 379 deletions
diff --git a/engines/gob/parse.cpp b/engines/gob/parse.cpp index 420fdebd29..31c05bc39a 100644 --- a/engines/gob/parse.cpp +++ b/engines/gob/parse.cpp @@ -624,21 +624,414 @@ int16 Parse::parseValExpr(byte stopToken) { return _vm->_global->_inter_resVal; } -int16 Parse::parseExpr(byte stopToken, byte *type) { - int32 values[20]; - byte operStack[20]; +// Load a value according to the operation +void Parse::loadValue(byte operation, uint32 varBase, byte *operPtr, int32 *valPtr) { + int16 dimCount; + int16 temp; + int16 temp2; + int16 offset; + int16 dim; + byte *arrDescPtr; int32 prevPrevVal; int32 prevVal; int32 curVal; + + switch (operation) { + case OP_ARRAY_INT8: + case OP_ARRAY_INT32: + case OP_ARRAY_INT16: + case OP_ARRAY_STR: + *operPtr = (operation == OP_ARRAY_STR) ? OP_LOAD_IMM_STR : OP_LOAD_IMM_INT16; + temp = _vm->_inter->load16(); + dimCount = *_vm->_global->_inter_execPtr++; + arrDescPtr = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr += dimCount; + offset = 0; + for (dim = 0; dim < dimCount; dim++) { + temp2 = parseValExpr(OP_END_MARKER); + offset = offset * arrDescPtr[dim] + temp2; + } + if (operation == OP_ARRAY_INT8) + *valPtr = (int8) READ_VARO_UINT8(varBase + temp + offset); + else if (operation == OP_ARRAY_INT32) + *valPtr = READ_VARO_UINT32(varBase + temp * 4 + offset * 4); + else if (operation == OP_ARRAY_INT16) + *valPtr = (int16) READ_VARO_UINT16(varBase + temp * 2 + offset * 2); + else if (operation == OP_ARRAY_STR) { + *valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8( + varBase + temp * 4 + offset * _vm->_global->_inter_animDataSize * 4), + kInterVar); + if (*_vm->_global->_inter_execPtr == 13) { + _vm->_global->_inter_execPtr++; + temp2 = parseValExpr(OP_END_MARKER); + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = READ_VARO_UINT8(varBase + temp * 4 + + offset * 4 * _vm->_global->_inter_animDataSize + temp2); + } + } + break; + + case OP_LOAD_VAR_INT16: + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = (int16) READ_VARO_UINT16(varBase + _vm->_inter->load16() * 2); + break; + + case OP_LOAD_VAR_INT8: + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = (int8) READ_VARO_UINT8(varBase + _vm->_inter->load16()); + break; + + case OP_LOAD_IMM_INT32: + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = READ_LE_UINT32(varBase + _vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += 4; + break; + + case OP_LOAD_IMM_INT16: + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = _vm->_inter->load16(); + break; + + case OP_LOAD_IMM_INT8: + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = (int8) *_vm->_global->_inter_execPtr++; + break; + + case OP_LOAD_IMM_STR: + *operPtr = OP_LOAD_IMM_STR; + *valPtr = encodePtr(_vm->_global->_inter_execPtr, kExecPtr); + _vm->_global->_inter_execPtr += + strlen((char *) _vm->_global->_inter_execPtr) + 1; + break; + + case OP_LOAD_VAR_INT32: + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = READ_VARO_UINT32(varBase + _vm->_inter->load16() * 4); + break; + + case OP_LOAD_VAR_INT32_AS_INT16: + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = (int16) READ_VARO_UINT16(varBase + _vm->_inter->load16() * 4); + break; + + case OP_LOAD_VAR_STR: + *operPtr = OP_LOAD_IMM_STR; + temp = _vm->_inter->load16() * 4; + *valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8(varBase + temp), kInterVar); + if (*_vm->_global->_inter_execPtr == 13) { + _vm->_global->_inter_execPtr++; + temp += parseValExpr(OP_END_MARKER); + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = READ_VARO_UINT8(varBase + temp); + } + break; + + case OP_FUNC: + operation = *_vm->_global->_inter_execPtr++; + parseExpr(OP_END_EXPR, 0); + + switch (operation) { + case FUNC_SQRT1: + case FUNC_SQRT2: + case FUNC_SQRT3: + curVal = 1; + prevVal = 1; + + do { + prevPrevVal = prevVal; + prevVal = curVal; + curVal = (curVal + _vm->_global->_inter_resVal / curVal) / 2; + } while ((curVal != prevVal) && (curVal != prevPrevVal)); + _vm->_global->_inter_resVal = curVal; + break; + + case FUNC_SQR: + _vm->_global->_inter_resVal = + _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; + break; + + case FUNC_ABS: + if (_vm->_global->_inter_resVal < 0) + _vm->_global->_inter_resVal = -_vm->_global->_inter_resVal; + break; + + case FUNC_RAND: + _vm->_global->_inter_resVal = + _vm->_util->getRandom(_vm->_global->_inter_resVal); + break; + } + + *operPtr = OP_LOAD_IMM_INT16; + *valPtr = _vm->_global->_inter_resVal; + break; + } +} + +void Parse::simpleArithmetic1(byte *&operPtr, int32 *&valPtr, int16 &stkPos) { + switch (operPtr[-1]) { + case OP_ADD: + if (operPtr[-2] == OP_LOAD_IMM_STR) { + if ((char *) decodePtr(valPtr[-2]) != _vm->_global->_inter_resStr) { + strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-2])); + valPtr[-2] = encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); + } + strcat(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[0])); + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + } + break; + + case OP_MUL: + valPtr[-2] *= valPtr[0]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_DIV: + valPtr[-2] /= valPtr[0]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_MOD: + valPtr[-2] %= valPtr[0]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_BITAND: + valPtr[-2] &= valPtr[0]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + } +} + +void Parse::simpleArithmetic2(byte *&operPtr, int32 *&valPtr, int16 &stkPos) { + if (stkPos > 1) { + if (operPtr[-2] == OP_NEG) { + operPtr[-2] = OP_LOAD_IMM_INT16; + valPtr[-2] = -valPtr[-1]; + stkPos--; + operPtr--; + valPtr--; + } else if (operPtr[-2] == OP_NOT) { + operPtr[-2] = (operPtr[-1] == GOB_FALSE) ? GOB_TRUE : GOB_FALSE; + stkPos--; + operPtr--; + valPtr--; + } + } + + if (stkPos > 2) { + switch (operPtr[-2]) { + case OP_MUL: + valPtr[-3] *= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_DIV: + valPtr[-3] /= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_MOD: + valPtr[-3] %= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_BITAND: + valPtr[-3] &= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + } + } + +} + +// Complex arithmetics with brackets +bool Parse::complexArithmetic(byte *&operPtr, int32 *&valPtr, int16 &stkPos, + byte *operStack, int32 *values, int16 brackStart) { + + switch (operPtr[-2]) { + case OP_ADD: + if (operStack[brackStart] == OP_LOAD_IMM_INT16) { + values[brackStart] += valPtr[-1]; + } else if (operStack[brackStart] == OP_LOAD_IMM_STR) { + if ((char *) decodePtr(values[brackStart]) != _vm->_global->_inter_resStr) { + strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(values[brackStart])); + values[brackStart] = + encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); + } + strcat(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-1])); + } + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_SUB: + values[brackStart] -= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_BITOR: + values[brackStart] |= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_MUL: + valPtr[-3] *= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_DIV: + valPtr[-3] /= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_MOD: + valPtr[-3] %= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_BITAND: + valPtr[-3] &= valPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_OR: + // (x OR false) == x + // (x OR true) == true + if (operPtr[-3] == GOB_FALSE) + operPtr[-3] = operPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_AND: + // (x AND false) == false + // (x AND true) == x + if (operPtr[-3] == GOB_TRUE) + operPtr[-3] = operPtr[-1]; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_LESS: + operPtr[-3] = (cmpHelper(operPtr, valPtr) < 0) ? GOB_TRUE : GOB_FALSE; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_LEQ: + operPtr[-3] = (cmpHelper(operPtr, valPtr) <= 0) ? GOB_TRUE : GOB_FALSE; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_GREATER: + operPtr[-3] = (cmpHelper(operPtr, valPtr) > 0) ? GOB_TRUE : GOB_FALSE; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_GEQ: + operPtr[-3] = (cmpHelper(operPtr, valPtr) >= 0) ? GOB_TRUE : GOB_FALSE; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_EQ: + operPtr[-3] = (cmpHelper(operPtr, valPtr) == 0) ? GOB_TRUE : GOB_FALSE; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + case OP_NEQ: + operPtr[-3] = (cmpHelper(operPtr, valPtr) != 0) ? GOB_TRUE : GOB_FALSE; + stkPos -= 2; + operPtr -= 2; + valPtr -= 2; + break; + + default: + return true; + } + + return false; +} + +// Assign the result to the appropriate _inter_res* variable +void Parse::getResult(byte operation, int32 value, byte *type) { + if (type != 0) + *type = operation; + + switch (operation) { + case OP_NOT: + if (type != 0) + *type ^= 1; + break; + + case OP_LOAD_IMM_INT16: + _vm->_global->_inter_resVal = value; + break; + + case OP_LOAD_IMM_STR: + if ((char *) decodePtr(value) != _vm->_global->_inter_resStr) + strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(value)); + break; + + case OP_LOAD_VAR_INT32: + case OP_LOAD_VAR_INT32_AS_INT16: + break; + + default: + _vm->_global->_inter_resVal = 0; + if (type != 0) + *type = OP_LOAD_IMM_INT16; + break; + } +} + +int16 Parse::parseExpr(byte stopToken, byte *type) { + int32 values[20]; + byte operStack[20]; int32 *valPtr; byte *operPtr; - byte *arrDescPtr; byte operation; - int16 dimCount; - int16 temp; - int16 temp2; - int16 offset; - int16 dim; bool escape; int16 stkPos; int16 brackStart; @@ -659,135 +1052,8 @@ int16 Parse::parseExpr(byte stopToken, byte *type) { operation = *_vm->_global->_inter_execPtr++; if ((operation >= OP_ARRAY_INT8) && (operation <= OP_FUNC)) { - switch (operation) { - case OP_ARRAY_INT8: - case OP_ARRAY_INT32: - case OP_ARRAY_INT16: - case OP_ARRAY_STR: - *operPtr = (operation == OP_ARRAY_STR) ? OP_LOAD_IMM_STR : OP_LOAD_IMM_INT16; - temp = _vm->_inter->load16(); - dimCount = *_vm->_global->_inter_execPtr++; - arrDescPtr = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += dimCount; - offset = 0; - for (dim = 0; dim < dimCount; dim++) { - temp2 = parseValExpr(OP_END_MARKER); - offset = offset * arrDescPtr[dim] + temp2; - } - if (operation == OP_ARRAY_INT8) - *valPtr = (int8) READ_VARO_UINT8(varBase + temp + offset); - else if (operation == OP_ARRAY_INT32) - *valPtr = READ_VARO_UINT32(varBase + temp * 4 + offset * 4); - else if (operation == OP_ARRAY_INT16) - *valPtr = (int16) READ_VARO_UINT16(varBase + temp * 2 + offset * 2); - else if (operation == OP_ARRAY_STR) { - *valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8( - varBase + temp * 4 + offset * _vm->_global->_inter_animDataSize * 4), - kInterVar); - if (*_vm->_global->_inter_execPtr == 13) { - _vm->_global->_inter_execPtr++; - temp2 = parseValExpr(OP_END_MARKER); - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = READ_VARO_UINT8(varBase + temp * 4 + - offset * 4 * _vm->_global->_inter_animDataSize + temp2); - } - } - break; - - case OP_LOAD_VAR_INT16: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = (int16) READ_VARO_UINT16(varBase + _vm->_inter->load16() * 2); - break; - - case OP_LOAD_VAR_INT8: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = (int8) READ_VARO_UINT8(varBase + _vm->_inter->load16()); - break; - - case OP_LOAD_IMM_INT32: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = READ_LE_UINT32(varBase + _vm->_global->_inter_execPtr); - _vm->_global->_inter_execPtr += 4; - break; - - case OP_LOAD_IMM_INT16: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = _vm->_inter->load16(); - break; - - case OP_LOAD_IMM_INT8: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = (int8) *_vm->_global->_inter_execPtr++; - break; - - case OP_LOAD_IMM_STR: - *operPtr = OP_LOAD_IMM_STR; - *valPtr = encodePtr(_vm->_global->_inter_execPtr, kExecPtr); - _vm->_global->_inter_execPtr += - strlen((char *) _vm->_global->_inter_execPtr) + 1; - break; - - case OP_LOAD_VAR_INT32: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = READ_VARO_UINT32(varBase + _vm->_inter->load16() * 4); - break; - - case OP_LOAD_VAR_INT32_AS_INT16: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = (int16) READ_VARO_UINT16(varBase + _vm->_inter->load16() * 4); - break; - - case OP_LOAD_VAR_STR: - *operPtr = OP_LOAD_IMM_STR; - temp = _vm->_inter->load16() * 4; - *valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8(varBase + temp), kInterVar); - if (*_vm->_global->_inter_execPtr == 13) { - _vm->_global->_inter_execPtr++; - temp += parseValExpr(OP_END_MARKER); - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = READ_VARO_UINT8(varBase + temp); - } - break; - - case OP_FUNC: - operation = *_vm->_global->_inter_execPtr++; - parseExpr(OP_END_EXPR, 0); - - switch (operation) { - case FUNC_SQRT1: - case FUNC_SQRT2: - case FUNC_SQRT3: - curVal = 1; - prevVal = 1; - - do { - prevPrevVal = prevVal; - prevVal = curVal; - curVal = (curVal + _vm->_global->_inter_resVal / curVal) / 2; - } while ((curVal != prevVal) && (curVal != prevPrevVal)); - _vm->_global->_inter_resVal = curVal; - break; - - case FUNC_SQR: - _vm->_global->_inter_resVal = - _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; - break; - case FUNC_ABS: - if (_vm->_global->_inter_resVal < 0) - _vm->_global->_inter_resVal = -_vm->_global->_inter_resVal; - break; - - case FUNC_RAND: - _vm->_global->_inter_resVal = - _vm->_util->getRandom(_vm->_global->_inter_resVal); - break; - } - - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = _vm->_global->_inter_resVal; - break; - } + loadValue(operation, varBase, operPtr, valPtr); if ((stkPos > 0) && ((operPtr[-1] == OP_NEG) || (operPtr[-1] == OP_NOT))) { stkPos--; @@ -804,48 +1070,8 @@ int16 Parse::parseExpr(byte stopToken, byte *type) { if (stkPos <= 0) continue; - switch (operPtr[-1]) { - case OP_ADD: - if (operPtr[-2] == OP_LOAD_IMM_STR) { - if ((char *) decodePtr(valPtr[-2]) != _vm->_global->_inter_resStr) { - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-2])); - valPtr[-2] = encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); - } - strcat(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[0])); - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - } - break; - - case OP_MUL: - valPtr[-2] *= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_DIV: - valPtr[-2] /= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; + simpleArithmetic1(operPtr, valPtr, stkPos); - case OP_MOD: - valPtr[-2] %= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_BITAND: - valPtr[-2] &= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - } continue; } // (op >= OP_ARRAY_INT8) && (op <= OP_FUNC) @@ -863,52 +1089,7 @@ int16 Parse::parseExpr(byte stopToken, byte *type) { operPtr--; valPtr--; - if (stkPos > 1) { - if (operPtr[-2] == OP_NEG) { - operPtr[-2] = OP_LOAD_IMM_INT16; - valPtr[-2] = -valPtr[-1]; - stkPos--; - operPtr--; - valPtr--; - } else if (operPtr[-2] == OP_NOT) { - operPtr[-2] = (operPtr[-1] == GOB_FALSE) ? GOB_TRUE : GOB_FALSE; - stkPos--; - operPtr--; - valPtr--; - } - } // stkPos > 1 - - if (stkPos > 2) { - switch (operPtr[-2]) { - case OP_MUL: - valPtr[-3] *= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_DIV: - valPtr[-3] /= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_MOD: - valPtr[-3] %= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_BITAND: - valPtr[-3] &= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - } // switch - } // stkPos > 2 + simpleArithmetic2(operPtr, valPtr, stkPos); if (operation != stopToken) break; @@ -922,134 +1103,9 @@ int16 Parse::parseExpr(byte stopToken, byte *type) { if ((operStack[brackStart] >= OP_OR) || (operStack[brackStart] == OP_BEGIN_EXPR)) brackStart++; - switch (operPtr[-2]) { - case OP_ADD: - if (operStack[brackStart] == OP_LOAD_IMM_INT16) { - values[brackStart] += valPtr[-1]; - } else if (operStack[brackStart] == OP_LOAD_IMM_STR) { - if ((char *) decodePtr(values[brackStart]) != _vm->_global->_inter_resStr) { - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(values[brackStart])); - values[brackStart] = - encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); - } - strcat(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-1])); - } - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - continue; - - case OP_SUB: - values[brackStart] -= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - continue; - - case OP_BITOR: - values[brackStart] |= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - continue; - - case OP_MUL: - valPtr[-3] *= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_DIV: - valPtr[-3] /= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_MOD: - valPtr[-3] %= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_BITAND: - valPtr[-3] &= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_OR: - // (x OR false) == x - // (x OR true) == true - if (operPtr[-3] == GOB_FALSE) - operPtr[-3] = operPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_AND: - // (x AND false) == false - // (x AND true) == x - if (operPtr[-3] == GOB_TRUE) - operPtr[-3] = operPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_LESS: - operPtr[-3] = (cmpHelper(operPtr, valPtr) < 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; + if (complexArithmetic(operPtr, valPtr, stkPos, operStack, values, brackStart)) break; - case OP_LEQ: - operPtr[-3] = (cmpHelper(operPtr, valPtr) <= 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_GREATER: - operPtr[-3] = (cmpHelper(operPtr, valPtr) > 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_GEQ: - operPtr[-3] = (cmpHelper(operPtr, valPtr) >= 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_EQ: - operPtr[-3] = (cmpHelper(operPtr, valPtr) == 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_NEQ: - operPtr[-3] = (cmpHelper(operPtr, valPtr) != 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - default: - escape = true; - break; - } // switch - - if (escape) - break; } // while (stkPos >= 2) if ((operation == OP_OR) || (operation == OP_AND)) { @@ -1093,34 +1149,8 @@ int16 Parse::parseExpr(byte stopToken, byte *type) { if (operation != stopToken) continue; - if (type != 0) - *type = operStack[0]; - - switch (operStack[0]) { - case OP_NOT: - if (type != 0) - *type ^= 1; - break; + getResult(operStack[0], values[0], type); - case OP_LOAD_IMM_INT16: - _vm->_global->_inter_resVal = values[0]; - break; - - case OP_LOAD_IMM_STR: - if ((char *) decodePtr(values[0]) != _vm->_global->_inter_resStr) - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(values[0])); - break; - - case OP_LOAD_VAR_INT32: - case OP_LOAD_VAR_INT32_AS_INT16: - break; - - default: - _vm->_global->_inter_resVal = 0; - if (type != 0) - *type = OP_LOAD_IMM_INT16; - break; - } return 0; } // (operation == stopToken) || (operation == OP_OR) || (operation == OP_AND) || (operation == OP_END_EXPR) diff --git a/engines/gob/parse.h b/engines/gob/parse.h index 51a56cd228..40f87b333a 100644 --- a/engines/gob/parse.h +++ b/engines/gob/parse.h @@ -132,10 +132,16 @@ private: void printExpr_internal(char stopToken); - int cmpHelper(byte *operPtr, int32 *valPtr); - bool getVarBase(uint32 &varBase, bool mindStop = false, uint16 *size = 0, uint16 *type = 0); + int cmpHelper(byte *operPtr, int32 *valPtr); + + void loadValue(byte operation, uint32 varBase, byte *operPtr, int32 *valPtr); + void simpleArithmetic1(byte *&operPtr, int32 *&valPtr, int16 &stkPos); + void simpleArithmetic2(byte *&operPtr, int32 *&valPtr, int16 &stkPos); + bool complexArithmetic(byte *&operPtr, int32 *&valPtr, int16 &stkPos, + byte *operStack, int32 *values, int16 brackStart); + void getResult(byte operation, int32 value, byte *type); }; } // End of namespace Gob |