Пример #1
0
void Script_v6::o6_assign(FuncParams &params) {
	uint8 type = peekUint8();
	uint16 var_0, var_4;
	std::string varIndex = readVarIndex(&var_0, &var_4);

	if (var_0 != 0) {
		std::string varIndex2;
		uint16 var_6;

		uint32 savedPos = getPos();

		varIndex2 = readVarIndex(&var_6, 0);

		printIndent();
		print("memcpy(%s, %s, %d);\n", varIndex.c_str(), varIndex2.c_str(), var_6 * 4);

		seek(savedPos);
		skipExpr(99);

		return;
	}

	if (peekUint8() == 98) {
		skip(1);
		uint8 loopCount = readUint8();

		uint32 off = 0;
		for (uint16 i = 0; i < loopCount; i++) {
			uint8 c = readUint8();
			uint16 n = readUint16();

			printIndent();
			print("memset(%s + %d, %d, %d);\n", varIndex.c_str(), off, c, n);

			off += n;
		}
	} else if (peekUint8() == 99) {
		skip(1);
		uint8 loopCount = readUint8();

		for (uint16 i = 0; i < loopCount; i++) {
			std::string expr = readExpr();
			printIndent();
			print("%s[%d] = %s;\n", varIndex.c_str(), (type == 24) ? (i * 2) : i, expr.c_str());
		}
	} else {
		std::string expr = readExpr();

		printIndent();
		print("%s = %s;\n", varIndex.c_str(), expr.c_str());
	}
}
Пример #2
0
void Parse::skipExpr(char stopToken) {
	int16 dimCount;
	char operation;
	int16 num;
	int16 dim;

	num = 0;
	while (1) {
		operation = *_vm->_global->_inter_execPtr++;

		if (operation >= 16 && operation <= 29) {
			switch (operation) {
			case 17:
			case 18:
			case 20:
			case 23:
			case 24:
				_vm->_global->_inter_execPtr += 2;
				break;

			case 19:
				_vm->_global->_inter_execPtr += 4;
				break;

			case 21:
				_vm->_global->_inter_execPtr += 1;
				break;

			case 22:
				_vm->_global->_inter_execPtr += strlen(_vm->_global->_inter_execPtr) + 1;
				break;

			case 25:
				_vm->_global->_inter_execPtr += 2;
				if (*_vm->_global->_inter_execPtr == 13) {
					_vm->_global->_inter_execPtr++;
					skipExpr(12);
				}
				break;

			case 16:
			case 26:
			case 27:
			case 28:
				dimCount = _vm->_global->_inter_execPtr[2];
				// skip header and dimensions
				_vm->_global->_inter_execPtr += 3 + dimCount;
				// skip indices
				for (dim = 0; dim < dimCount; dim++)
					skipExpr(12);

				if (operation == 28 && *_vm->_global->_inter_execPtr == 13) {
					_vm->_global->_inter_execPtr++;
					skipExpr(12);
				}
				break;

			case 29:
				_vm->_global->_inter_execPtr++;
				skipExpr(10);
			}
			continue;
		}		// if (operation >= 16 && operation <= 29)

		if (operation == 9) {
			num++;
			continue;
		}

		if (operation == 11 || (operation >= 1 && operation <= 8))
			continue;

		if (operation >= 30 && operation <= 37)
			continue;

		if (operation == 10)
			num--;

		if (operation != stopToken)
			continue;

		if (stopToken != 10 || num < 0)
			return;
	}
}
Пример #3
0
void Expression::skipExpr(char stopToken) {
	int16 dimCount;
	byte operation;
	int16 num;
	int16 dim;

	num = 0;
	while (true) {
		operation = _vm->_game->_script->readByte();

		if ((operation >= 14) && (operation <= OP_FUNC)) {
			switch (operation) {
			case 14:
				_vm->_game->_script->skip(4);
				if (_vm->_game->_script->peekByte() == 97)
					_vm->_game->_script->skip(1);
				break;

			case OP_LOAD_VAR_INT16:
			case OP_LOAD_VAR_INT8:
			case OP_LOAD_IMM_INT16:
			case OP_LOAD_VAR_INT32:
			case OP_LOAD_VAR_INT32_AS_INT16:
				_vm->_game->_script->skip(2);
				break;

			case OP_LOAD_IMM_INT32:
				_vm->_game->_script->skip(4);
				break;

			case OP_LOAD_IMM_INT8:
				_vm->_game->_script->skip(1);
				break;

			case OP_LOAD_IMM_STR:
				_vm->_game->_script->skip(strlen(_vm->_game->_script->peekString()) + 1);
				break;

			case OP_LOAD_VAR_STR:
				_vm->_game->_script->skip(2);
				if (_vm->_game->_script->peekByte() == 13) {
					_vm->_game->_script->skip(1);
					skipExpr(OP_END_MARKER);
				}
				break;

			case 15:
				_vm->_game->_script->skip(2);

			case OP_ARRAY_INT8:
			case OP_ARRAY_INT32:
			case OP_ARRAY_INT16:
			case OP_ARRAY_STR:
				dimCount = _vm->_game->_script->peekByte(2);
				// skip header and dimensions
				_vm->_game->_script->skip(3 + dimCount);
				// skip indices
				for (dim = 0; dim < dimCount; dim++)
					skipExpr(OP_END_MARKER);

				if ((operation == OP_ARRAY_STR) && (_vm->_game->_script->peekByte() == 13)) {
					_vm->_game->_script->skip(1);
					skipExpr(OP_END_MARKER);
				}
				break;

			case OP_FUNC:
				_vm->_game->_script->skip(1);
				skipExpr(OP_END_EXPR);
			}
			continue;
		} // if ((operation >= OP_ARRAY_INT8) && (operation <= OP_FUNC))

		if (operation == OP_BEGIN_EXPR) {
			num++;
			continue;
		}

		if ((operation == OP_NOT) || ((operation >= OP_NEG) && (operation <= 8)))
			continue;

		if ((operation >= OP_OR) && (operation <= OP_NEQ))
			continue;

		if (operation == OP_END_EXPR)
			num--;

		if (operation != stopToken)
			continue;

		if ((stopToken != OP_END_EXPR) || (num < 0))
			return;
	}
}
Пример #4
0
int16 Expression::parseExpr(byte stopToken, byte *type) {
	Stack stack;
	StackFrame stackFrame(stack);
	byte operation;
	int16 brackStart;
	uint32 varBase;

	while (true) {
		getVarBase(varBase);

		stackFrame.push();

		operation = _vm->_game->_script->readByte();
		if ((operation >= OP_ARRAY_INT8) && (operation <= OP_FUNC)) {

			loadValue(operation, varBase, stackFrame);

			if ((stackFrame.pos > 0) && ((stackFrame.opers[-1] == OP_NEG) || (stackFrame.opers[-1] == OP_NOT))) {
				stackFrame.pop();

				if (*stackFrame.opers == OP_NEG) {
					*stackFrame.opers = OP_LOAD_IMM_INT16;
					stackFrame.values[0] = -stackFrame.values[1];
				} else
					*stackFrame.opers = (stackFrame.opers[1] == GOB_FALSE) ? GOB_TRUE : GOB_FALSE;
			}

			if (stackFrame.pos <= 0)
				continue;

			simpleArithmetic1(stackFrame);

			continue;
		} // (op >= OP_ARRAY_INT8) && (op <= OP_FUNC)

		if ((operation == stopToken) || (operation == OP_OR) ||
				(operation == OP_AND) || (operation == OP_END_EXPR)) {
			while (stackFrame.pos >= 2) {
				if ((stackFrame.opers[-2] == OP_BEGIN_EXPR) &&
						((operation == OP_END_EXPR) || (operation == stopToken))) {
					stackFrame.opers[-2] = stackFrame.opers[-1];
					if ((stackFrame.opers[-2] == OP_LOAD_IMM_INT16) || (stackFrame.opers[-2] == OP_LOAD_IMM_STR))
						stackFrame.values[-2] = stackFrame.values[-1];

					stackFrame.pop();

					simpleArithmetic2(stackFrame);

					if (operation != stopToken)
						break;
				}	// if ((stackFrame.opers[-2] == OP_BEGIN_EXPR) && ...)

				for (brackStart = (stackFrame.pos - 2); (brackStart > 0) &&
				    (stack.opers[brackStart] < OP_OR) && (stack.opers[brackStart] != OP_BEGIN_EXPR);
						brackStart--)
					;

				if ((stack.opers[brackStart] >= OP_OR) || (stack.opers[brackStart] == OP_BEGIN_EXPR))
					brackStart++;

				if (complexArithmetic(stack, stackFrame, brackStart))
					break;

			}	// while (stackFrame.pos >= 2)

			if ((operation == OP_OR) || (operation == OP_AND)) {
				if (stackFrame.opers[-1] == OP_LOAD_IMM_INT16) {
					if (stackFrame.values[-1] != 0)
						stackFrame.opers[-1] = GOB_TRUE;
					else
						stackFrame.opers[-1] = GOB_FALSE;
				}

				if (((operation == OP_OR) && (stackFrame.opers[-1] == GOB_TRUE)) ||
				    ((operation == OP_AND) && (stackFrame.opers[-1] == GOB_FALSE))) {
					if ((stackFrame.pos > 1) && (stackFrame.opers[-2] == OP_BEGIN_EXPR)) {
						skipExpr(OP_END_EXPR);
						stackFrame.opers[-2] = stackFrame.opers[-1];
						stackFrame.pop(2);
					} else {
						skipExpr(stopToken);
					}
					operation = _vm->_game->_script->peekByte(-1);
					if ((stackFrame.pos > 0) && (stackFrame.opers[-1] == OP_NOT)) {
						if (stackFrame.opers[0] == GOB_FALSE)
							stackFrame.opers[-1] = GOB_TRUE;
						else
							stackFrame.opers[-1] = GOB_FALSE;

						stackFrame.pop();
					}
				} else
					stackFrame.opers[0] = operation;
			} else
				stackFrame.pop();

			if (operation != stopToken)
				continue;

			getResult(stack.opers[0], stack.values[0], type);

			return 0;
		}		// (operation == stopToken) || (operation == OP_OR) || (operation == OP_AND) || (operation == OP_END_EXPR)

		if ((operation < OP_NEG) || (operation > OP_NOT)) {
			if ((operation < OP_LESS) || (operation > OP_NEQ))
				continue;

			if (stackFrame.pos > 2) {
				if (stackFrame.opers[-2] == OP_ADD) {
					if (stackFrame.opers[-3] == OP_LOAD_IMM_INT16) {
						stackFrame.values[-3] += stackFrame.values[-1];
					} else if (stackFrame.opers[-3] == OP_LOAD_IMM_STR) {
						if ((char *)decodePtr(stackFrame.values[-3]) != _resultStr) {
							strcpy(_resultStr, (char *)decodePtr(stackFrame.values[-3]));
							stackFrame.values[-3] = encodePtr((byte *)_resultStr, kResStr);
						}
						strcat(_resultStr, (char *)decodePtr(stackFrame.values[-1]));
					}
					stackFrame.pop(2);

				} else if (stackFrame.opers[-2] == OP_SUB) {
					stackFrame.values[-3] -= stackFrame.values[-1];
					stackFrame.pop(2);
				} else if (stackFrame.opers[-2] == OP_BITOR) {
					stackFrame.values[-3] |= stackFrame.values[-1];
					stackFrame.pop(2);
				}
			}
		}
		*stackFrame.opers = operation;
	}
}