[Scummvm-cvs-logs] SF.net SVN: scummvm:[41773] scummvm/trunk/engines/gob

drmccoy at users.sourceforge.net drmccoy at users.sourceforge.net
Mon Jun 22 18:30:35 CEST 2009


Revision: 41773
          http://scummvm.svn.sourceforge.net/scummvm/?rev=41773&view=rev
Author:   drmccoy
Date:     2009-06-22 16:30:35 +0000 (Mon, 22 Jun 2009)

Log Message:
-----------
Renaming parse.h and parse.cpp to expression.h and expression.cpp

Modified Paths:
--------------
    scummvm/trunk/engines/gob/gob.cpp
    scummvm/trunk/engines/gob/inter.cpp
    scummvm/trunk/engines/gob/inter_v1.cpp
    scummvm/trunk/engines/gob/inter_v2.cpp
    scummvm/trunk/engines/gob/inter_v6.cpp
    scummvm/trunk/engines/gob/module.mk
    scummvm/trunk/engines/gob/script.cpp

Added Paths:
-----------
    scummvm/trunk/engines/gob/expression.cpp
    scummvm/trunk/engines/gob/expression.h

Removed Paths:
-------------
    scummvm/trunk/engines/gob/parse.cpp
    scummvm/trunk/engines/gob/parse.h

Copied: scummvm/trunk/engines/gob/expression.cpp (from rev 41772, scummvm/trunk/engines/gob/parse.cpp)
===================================================================
--- scummvm/trunk/engines/gob/expression.cpp	                        (rev 0)
+++ scummvm/trunk/engines/gob/expression.cpp	2009-06-22 16:30:35 UTC (rev 41773)
@@ -0,0 +1,1145 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/endian.h"
+
+#include "gob/gob.h"
+#include "gob/expression.h"
+#include "gob/global.h"
+#include "gob/game.h"
+#include "gob/script.h"
+#include "gob/inter.h"
+
+namespace Gob {
+
+Expression::Stack::Stack(size_t size) {
+	opers  = new byte[size];
+	values = new int32[size];
+	memset(opers , 0, size * sizeof(byte ));
+	memset(values, 0, size * sizeof(int32));
+}
+
+Expression::Stack::~Stack() {
+	delete[] opers;
+	delete[] values;
+}
+
+Expression::StackFrame::StackFrame(const Stack &stack) {
+	opers = stack.opers - 1;
+	values = stack.values - 1;
+	pos = -1;
+}
+
+void Expression::StackFrame::push(int count) {
+	opers  += count;
+	values += count;
+	pos    += count;
+}
+
+void Expression::StackFrame::pop(int count) {
+	opers  -= count;
+	values -= count;
+	pos    -= count;
+}
+
+Expression::Expression(GobEngine *vm) : _vm(vm) {
+	_resultStr[0] = 0;
+	_resultInt = 0;
+}
+
+int32 Expression::encodePtr(byte *ptr, int type) {
+	int32 offset = 0;
+
+	switch (type) {
+	case kExecPtr:
+		offset = _vm->_game->_script->getOffset(ptr);
+		break;
+	case kInterVar:
+		offset = ptr - ((byte *) _vm->_inter->_variables->getAddressOff8(0));
+		break;
+	case kResStr:
+		offset = ptr - ((byte *) _resultStr);
+		break;
+	default:
+		error("Expression::encodePtr(): Unknown pointer type");
+	}
+	assert((offset & 0xF0000000) == 0);
+	return (type << 28) | offset;
+}
+
+byte *Expression::decodePtr(int32 n) {
+	byte *ptr;
+
+	switch (n >> 28) {
+	case kExecPtr:
+		ptr = _vm->_game->_script->getData();
+		break;
+	case kInterVar:
+		ptr = (byte *) _vm->_inter->_variables->getAddressOff8(0);
+		break;
+	case kResStr:
+		ptr = (byte *) _resultStr;
+		break;
+	default:
+		error("Expression::decodePtr(): Unknown pointer type");
+	}
+	return ptr + (n & 0x0FFFFFFF);
+}
+
+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;
+	}
+}
+
+void Expression::printExpr(char stopToken) {
+	// Expression printing disabled by default
+	return;
+
+	int32 savedPos = _vm->_game->_script->pos();
+	printExpr_internal(stopToken);
+
+	// restore IP to start of expression
+	_vm->_game->_script->seek(savedPos);
+}
+
+void Expression::printExpr_internal(char stopToken) {
+	int16 dimCount;
+	byte operation;
+	int16 num;
+	int16 dim;
+	byte *arrDesc;
+	byte func;
+
+	num = 0;
+	while (true) {
+		operation = _vm->_game->_script->readByte();
+
+		if ((operation >= OP_ARRAY_INT8) && (operation <= OP_FUNC)) {
+			// operands
+
+			switch (operation) {
+			case OP_LOAD_VAR_INT16: // int16 variable load
+				debugN(5, "var16_%d", _vm->_game->_script->readUint16());
+				break;
+
+			case OP_LOAD_VAR_INT8: // int8 variable load:
+				debugN(5, "var8_%d", _vm->_game->_script->readUint16());
+				break;
+
+			case OP_LOAD_IMM_INT32: // int32/uint32 immediate
+				debugN(5, "%d", _vm->_game->_script->readInt32());
+				break;
+
+			case OP_LOAD_IMM_INT16: // int16 immediate
+				debugN(5, "%d", _vm->_game->_script->readInt16());
+				break;
+
+			case OP_LOAD_IMM_INT8: // int8 immediate
+				debugN(5, "%d",  _vm->_game->_script->readInt8());
+				break;
+
+			case OP_LOAD_IMM_STR: // string immediate
+				debugN(5, "\42%s\42", _vm->_game->_script->readString());
+				break;
+
+			case OP_LOAD_VAR_INT32:
+			case OP_LOAD_VAR_INT32_AS_INT16:
+				debugN(5, "var_%d", _vm->_game->_script->readUint16());
+				break;
+
+			case OP_LOAD_VAR_STR: // string variable load
+				debugN(5, "(&var_%d)", _vm->_game->_script->readUint16());
+				if (_vm->_game->_script->peekByte() == 13) {
+					_vm->_game->_script->skip(1);
+					debugN(5, "{");
+					printExpr_internal(OP_END_MARKER); // this also prints the closing }
+				}
+				break;
+
+			case OP_ARRAY_INT8:  // int8 array access
+			case OP_ARRAY_INT32: // int32 array access
+			case OP_ARRAY_INT16: // int16 array access
+			case OP_ARRAY_STR:   // string array access
+				debugN(5, "\n");
+				if (operation == OP_ARRAY_STR)
+					debugN(5, "(&");
+
+				debugN(5, "var_%d[", _vm->_game->_script->readInt16());
+				dimCount = _vm->_game->_script->readByte();
+				arrDesc = _vm->_game->_script->getData() + _vm->_game->_script->pos();
+				_vm->_game->_script->skip(dimCount);
+				for (dim = 0; dim < dimCount; dim++) {
+					printExpr_internal(OP_END_MARKER);
+					debugN(5, " of %d", (int16) arrDesc[dim]);
+					if (dim != dimCount - 1)
+						debugN(5, ",");
+				}
+				debugN(5, "]");
+				if (operation == OP_ARRAY_STR)
+					debugN(5, ")");
+
+				if ((operation == OP_ARRAY_STR) && (_vm->_game->_script->peekByte() == 13)) {
+					_vm->_game->_script->skip(1);
+					debugN(5, "{");
+					printExpr_internal(OP_END_MARKER); // this also prints the closing }
+				}
+				break;
+
+			case OP_FUNC: // function
+				func = _vm->_game->_script->readByte();
+				if (func == FUNC_SQR)
+					debugN(5, "sqr(");
+				else if (func == FUNC_RAND)
+					debugN(5, "rand(");
+				else if (func == FUNC_ABS)
+					debugN(5, "abs(");
+				else if ((func == FUNC_SQRT1) || (func == FUNC_SQRT2) || (func == FUNC_SQRT3))
+					debugN(5, "sqrt(");
+				else
+					debugN(5, "id(");
+				printExpr_internal(OP_END_EXPR);
+				break;
+			}
+			continue;
+		}		// if ((operation >= OP_ARRAY_INT8) && (operation <= OP_FUNC))
+
+		// operators
+		switch (operation) {
+		case OP_BEGIN_EXPR:
+			debugN(5, "(");
+			break;
+
+		case OP_NOT:
+			debugN(5, "!");
+			break;
+
+		case OP_END_EXPR:
+			debugN(5, ")");
+			break;
+
+		case OP_NEG:
+			debugN(5, "-");
+			break;
+
+		case OP_ADD:
+			debugN(5, "+");
+			break;
+
+		case OP_SUB:
+			debugN(5, "-");
+			break;
+
+		case OP_BITOR:
+			debugN(5, "|");
+			break;
+
+		case OP_MUL:
+			debugN(5, "*");
+			break;
+
+		case OP_DIV:
+			debugN(5, "/");
+			break;
+
+		case OP_MOD:
+			debugN(5, "%%");
+			break;
+
+		case OP_BITAND:
+			debugN(5, "&");
+			break;
+
+		case OP_OR:
+			debugN(5, "||");
+			break;
+
+		case 31:
+			debugN(5, "&&");
+			break;
+
+		case OP_LESS:
+			debugN(5, "<");
+			break;
+
+		case OP_LEQ:
+			debugN(5, "<=");
+			break;
+
+		case OP_GREATER:
+			debugN(5, ">");
+			break;
+
+		case OP_GEQ:
+			debugN(5, ">=");
+			break;
+
+		case OP_EQ:
+			debugN(5, "==");
+			break;
+
+		case OP_NEQ:
+			debugN(5, "!=");
+			break;
+
+		case 99:
+			debugN(5, "\n");
+			break;
+
+		case OP_END_MARKER:
+			debugN(5, "}");
+			if (stopToken != OP_END_MARKER) {
+				debugN(5, "Closing paren without opening?");
+			}
+			break;
+
+		default:
+			debugN(5, "<%d>", (int16) operation);
+			error("Expression::printExpr(): invalid operator in expression");
+			break;
+		}
+
+		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) {
+			if ((stopToken != OP_END_EXPR) || (num < 0)) {
+				return;
+			}
+		}
+	}
+}
+
+
+void Expression::printVarIndex() {
+	byte *arrDesc;
+	int16 dim;
+	int16 dimCount;
+	int16 operation;
+	int16 temp;
+
+	int32 pos = _vm->_game->_script->pos();
+
+	operation = _vm->_game->_script->readByte();
+	switch (operation) {
+	case OP_LOAD_VAR_INT32:
+	case OP_LOAD_VAR_STR:
+		temp = _vm->_game->_script->readUint16() * 4;
+		debugN(5, "&var_%d", temp);
+		if ((operation == OP_LOAD_VAR_STR) && (_vm->_game->_script->peekByte() == 13)) {
+			_vm->_game->_script->skip(1);
+			debugN(5, "+");
+			printExpr(OP_END_MARKER);
+		}
+		break;
+
+	case OP_ARRAY_INT32:
+	case OP_ARRAY_STR:
+		debugN(5, "&var_%d[", _vm->_game->_script->readUint16());
+		dimCount = _vm->_game->_script->readByte();
+		arrDesc = _vm->_game->_script->getData() + _vm->_game->_script->pos();
+		_vm->_game->_script->skip(dimCount);
+		for (dim = 0; dim < dimCount; dim++) {
+			printExpr(OP_END_MARKER);
+			debugN(5, " of %d", (int16) arrDesc[dim]);
+			if (dim != dimCount - 1)
+				debugN(5, ",");
+		}
+		debugN(5, "]");
+
+		if ((operation == OP_ARRAY_STR) && (_vm->_game->_script->peekByte() == 13)) {
+			_vm->_game->_script->skip(1);
+			debugN(5, "+");
+			printExpr(OP_END_MARKER);
+		}
+		break;
+
+	default:
+		debugN(5, "var_0");
+		break;
+	}
+	debugN(5, "\n");
+
+	_vm->_game->_script->seek(pos);
+	return;
+}
+
+int Expression::cmpHelper(const StackFrame &stackFrame) {
+	byte type = stackFrame.opers[-3];
+	int cmpTemp = 0;
+
+	if (type == OP_LOAD_IMM_INT16) {
+		cmpTemp = (int)stackFrame.values[-3] - (int)stackFrame.values[-1];
+	} else if (type == 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);
+		}
+		cmpTemp = strcmp(_resultStr, (char *)decodePtr(stackFrame.values[-1]));
+	}
+
+	return cmpTemp;
+}
+
+bool Expression::getVarBase(uint32 &varBase, bool mindStop,
+		uint16 *size, uint16 *type) {
+
+	varBase = 0;
+
+	byte operation = _vm->_game->_script->peekByte();
+	while ((operation == 14) || (operation == 15)) {
+		_vm->_game->_script->skip(1);
+
+		if (operation == 14) {
+			// Add a direct offset
+
+			varBase += _vm->_game->_script->readInt16() * 4;
+
+			if (size)
+				*size = _vm->_game->_script->peekUint16();
+			if (type)
+				*type = 14;
+
+			_vm->_game->_script->skip(2);
+
+			debugC(2, kDebugParser, "varBase: %d, by %d", varBase, operation);
+
+			if (_vm->_game->_script->peekByte() != 97) {
+				if (mindStop)
+					return true;
+			} else
+				_vm->_game->_script->skip(1);
+
+		} else if (operation == 15) {
+			// Add an offset from an array
+
+			varBase += _vm->_game->_script->readInt16() * 4;
+
+			uint16 offset1 = _vm->_game->_script->readUint16();
+
+			if (size)
+				*size = offset1;
+			if (type)
+				*type = 15;
+
+			uint8 dimCount = _vm->_game->_script->readByte();
+			byte *dimArray = _vm->_game->_script->getData() + _vm->_game->_script->pos();
+
+			_vm->_game->_script->skip(dimCount);
+
+			uint16 offset2 = 0;
+			for (int i = 0; i < dimCount; i++) {
+				int16 dim = CLIP<int>(parseValExpr(OP_END_MARKER), 0, dimArray[i] - 1);
+
+				offset2 = offset2 * dimArray[i] + dim;
+			}
+
+			varBase += offset2 * offset1 * 4;
+
+			debugC(2, kDebugParser, "varBase: %d, by %d", varBase, operation);
+
+			if (_vm->_game->_script->peekByte() != 97) {
+				if (mindStop)
+					return true;
+			} else
+				_vm->_game->_script->skip(1);
+		}
+
+		operation = _vm->_game->_script->peekByte();
+	}
+
+	return false;
+}
+
+int16 Expression::parseVarIndex(uint16 *size, uint16 *type) {
+	int16 temp2;
+	byte *arrDesc;
+	int16 dim;
+	int16 dimCount;
+	int16 operation;
+	int16 temp;
+	int16 offset;
+	int16 val;
+	uint32 varBase;
+
+	if (getVarBase(varBase, true, size, type))
+		return varBase;
+
+	operation = _vm->_game->_script->readByte();
+
+	if (size)
+		*size = 0;
+	if (type)
+		*type = operation;
+
+	debugC(5, kDebugParser, "var parse = %d", operation);
+	switch (operation) {
+	case OP_ARRAY_INT8:
+	case OP_ARRAY_INT32:
+	case OP_ARRAY_INT16:
+	case OP_ARRAY_STR:
+		temp = _vm->_game->_script->readInt16();
+		dimCount = _vm->_game->_script->readByte();
+		arrDesc = _vm->_game->_script->getData() + _vm->_game->_script->pos();
+		_vm->_game->_script->skip(dimCount);
+		offset = 0;
+		for (dim = 0; dim < dimCount; dim++) {
+			temp2 = parseValExpr(OP_END_MARKER);
+			offset = arrDesc[dim] * offset + temp2;
+		}
+		if (operation == OP_ARRAY_INT8)
+			return varBase + temp + offset;
+		if (operation == OP_ARRAY_INT32)
+			return varBase + (temp + offset) * 4;
+		if (operation == OP_ARRAY_INT16)
+			return varBase + (temp + offset) * 2;
+		temp *= 4;
+		offset *= 4;
+		if (_vm->_game->_script->peekByte() == 13) {
+			_vm->_game->_script->skip(1);
+			temp += parseValExpr(OP_END_MARKER);
+		}
+		return varBase + offset * _vm->_global->_inter_animDataSize + temp;
+
+	case OP_LOAD_VAR_INT16:
+		return varBase + _vm->_game->_script->readInt16() * 2;
+
+	case OP_LOAD_VAR_INT8:
+		return varBase + _vm->_game->_script->readInt16();
+
+	case OP_LOAD_VAR_INT32:
+	case OP_LOAD_VAR_INT32_AS_INT16:
+	case OP_LOAD_VAR_STR:
+		temp = _vm->_game->_script->readInt16() * 4;
+		debugC(5, kDebugParser, "oper = %d", _vm->_game->_script->peekInt16());
+		if ((operation == OP_LOAD_VAR_STR) && (_vm->_game->_script->peekByte() == 13)) {
+			_vm->_game->_script->skip(1);
+			val = parseValExpr(OP_END_MARKER);
+			temp += val;
+			debugC(5, kDebugParser, "parse subscript = %d", val);
+		}
+		return varBase + temp;
+
+	default:
+		return 0;
+	}
+}
+
+int16 Expression::parseValExpr(byte stopToken) {
+	parseExpr(stopToken, 0);
+
+	return _resultInt;
+}
+
+// Load a value according to the operation
+void Expression::loadValue(byte operation, uint32 varBase, const StackFrame &stackFrame) {
+	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:
+		*stackFrame.opers = (operation == OP_ARRAY_STR) ? OP_LOAD_IMM_STR : OP_LOAD_IMM_INT16;
+		temp = _vm->_game->_script->readInt16();
+		dimCount = _vm->_game->_script->readByte();
+		arrDescPtr = _vm->_game->_script->getData() + _vm->_game->_script->pos();
+		_vm->_game->_script->skip(dimCount);
+		offset = 0;
+		for (dim = 0; dim < dimCount; dim++) {
+			temp2 = parseValExpr(OP_END_MARKER);
+			offset = offset * arrDescPtr[dim] + temp2;
+		}
+		if (operation == OP_ARRAY_INT8)
+			*stackFrame.values = (int8) READ_VARO_UINT8(varBase + temp + offset);
+		else if (operation == OP_ARRAY_INT32)
+			*stackFrame.values = READ_VARO_UINT32(varBase + temp * 4 + offset * 4);
+		else if (operation == OP_ARRAY_INT16)
+			*stackFrame.values = (int16) READ_VARO_UINT16(varBase + temp * 2 + offset * 2);
+		else if (operation == OP_ARRAY_STR) {
+			*stackFrame.values = encodePtr(_vm->_inter->_variables->getAddressOff8(
+						varBase + temp * 4 + offset * _vm->_global->_inter_animDataSize * 4),
+					kInterVar);
+			if (_vm->_game->_script->peekByte() == 13) {
+				_vm->_game->_script->skip(1);
+				temp2 = parseValExpr(OP_END_MARKER);
+				*stackFrame.opers = OP_LOAD_IMM_INT16;
+				*stackFrame.values = READ_VARO_UINT8(varBase + temp * 4 +
+						offset * 4 * _vm->_global->_inter_animDataSize + temp2);
+			}
+		}
+		break;
+
+	case OP_LOAD_VAR_INT16:
+		*stackFrame.opers = OP_LOAD_IMM_INT16;
+		*stackFrame.values = (int16) READ_VARO_UINT16(varBase + _vm->_game->_script->readInt16() * 2);
+		break;
+
+	case OP_LOAD_VAR_INT8:
+		*stackFrame.opers = OP_LOAD_IMM_INT16;
+		*stackFrame.values = (int8) READ_VARO_UINT8(varBase + _vm->_game->_script->readInt16());
+		break;
+
+	case OP_LOAD_IMM_INT32:
+		*stackFrame.opers = OP_LOAD_IMM_INT16;
+		*stackFrame.values = _vm->_game->_script->readInt32();
+		break;
+
+	case OP_LOAD_IMM_INT16:
+		*stackFrame.opers = OP_LOAD_IMM_INT16;
+		*stackFrame.values = _vm->_game->_script->readInt16();
+		break;
+
+	case OP_LOAD_IMM_INT8:
+		*stackFrame.opers = OP_LOAD_IMM_INT16;
+		*stackFrame.values = _vm->_game->_script->readInt8();
+		break;
+
+	case OP_LOAD_IMM_STR:
+		*stackFrame.opers = OP_LOAD_IMM_STR;
+		*stackFrame.values = encodePtr((byte *) _vm->_game->_script->readString(), kExecPtr);
+		break;
+
+	case OP_LOAD_VAR_INT32:
+		*stackFrame.opers = OP_LOAD_IMM_INT16;
+		*stackFrame.values = READ_VARO_UINT32(varBase + _vm->_game->_script->readInt16() * 4);
+		break;
+
+	case OP_LOAD_VAR_INT32_AS_INT16:
+		*stackFrame.opers = OP_LOAD_IMM_INT16;
+		*stackFrame.values = (int16) READ_VARO_UINT16(varBase + _vm->_game->_script->readInt16() * 4);
+		break;
+
+	case OP_LOAD_VAR_STR:
+		*stackFrame.opers = OP_LOAD_IMM_STR;
+		temp = _vm->_game->_script->readInt16() * 4;
+		*stackFrame.values = encodePtr(_vm->_inter->_variables->getAddressOff8(varBase + temp), kInterVar);
+		if (_vm->_game->_script->peekByte() == 13) {
+			_vm->_game->_script->skip(1);
+			temp += parseValExpr(OP_END_MARKER);
+			*stackFrame.opers = OP_LOAD_IMM_INT16;
+			*stackFrame.values = READ_VARO_UINT8(varBase + temp);
+		}
+		break;
+
+	case OP_FUNC:
+		operation = _vm->_game->_script->readByte();
+		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 + _resultInt / curVal) / 2;
+			} while ((curVal != prevVal) && (curVal != prevPrevVal));
+			_resultInt = curVal;
+			break;
+
+		case FUNC_SQR:
+			_resultInt =
+				_resultInt * _resultInt;
+			break;
+
+		case FUNC_ABS:
+			if (_resultInt < 0)
+				_resultInt = -_resultInt;
+			break;
+
+		case FUNC_RAND:
+			_resultInt =
+				_vm->_util->getRandom(_resultInt);
+			break;
+		}
+
+		*stackFrame.opers = OP_LOAD_IMM_INT16;
+		*stackFrame.values = _resultInt;
+		break;
+	}
+}
+
+void Expression::simpleArithmetic1(StackFrame &stackFrame) {
+	switch (stackFrame.opers[-1]) {
+	case OP_ADD:
+		if (stackFrame.opers[-2] == OP_LOAD_IMM_STR) {
+			if ((char *) decodePtr(stackFrame.values[-2]) != _resultStr) {
+				strcpy(_resultStr, (char *) decodePtr(stackFrame.values[-2]));
+				stackFrame.values[-2] = encodePtr((byte *) _resultStr, kResStr);
+			}
+			strcat(_resultStr, (char *) decodePtr(stackFrame.values[0]));
+			stackFrame.pop(2);
+		}
+		break;
+
+	case OP_MUL:
+		stackFrame.values[-2] *= stackFrame.values[0];
+		stackFrame.pop(2);
+		break;
+
+	case OP_DIV:
+		stackFrame.values[-2] /= stackFrame.values[0];
+		stackFrame.pop(2);
+		break;
+
+	case OP_MOD:
+		stackFrame.values[-2] %= stackFrame.values[0];
+		stackFrame.pop(2);
+		break;
+
+	case OP_BITAND:
+		stackFrame.values[-2] &= stackFrame.values[0];
+		stackFrame.pop(2);
+		break;
+	}
+}
+
+void Expression::simpleArithmetic2(StackFrame &stackFrame) {
+	if (stackFrame.pos > 1) {
+		if (stackFrame.opers[-2] == OP_NEG) {
+			stackFrame.opers[-2] = OP_LOAD_IMM_INT16;
+			stackFrame.values[-2] = -stackFrame.values[-1];
+			stackFrame.pop();
+		} else if (stackFrame.opers[-2] == OP_NOT) {
+			stackFrame.opers[-2] = (stackFrame.opers[-1] == GOB_FALSE) ? GOB_TRUE : GOB_FALSE;
+			stackFrame.pop();
+		}
+	}
+
+	if (stackFrame.pos > 2) {
+		switch (stackFrame.opers[-2]) {
+		case OP_MUL:
+			stackFrame.values[-3] *= stackFrame.values[-1];
+			stackFrame.pop(2);
+			break;
+
+		case OP_DIV:
+			stackFrame.values[-3] /= stackFrame.values[-1];
+			stackFrame.pop(2);
+			break;
+
+		case OP_MOD:
+			stackFrame.values[-3] %= stackFrame.values[-1];
+			stackFrame.pop(2);
+			break;
+
+		case OP_BITAND:
+			stackFrame.values[-3] &= stackFrame.values[-1];
+			stackFrame.pop(2);
+			break;
+		}
+	}
+
+}
+
+// Complex arithmetics with brackets
+bool Expression::complexArithmetic(Stack &stack, StackFrame &stackFrame, int16 brackStart) {
+	switch (stackFrame.opers[-2]) {
+	case OP_ADD:
+		if (stack.opers[brackStart] == OP_LOAD_IMM_INT16) {
+			stack.values[brackStart] += stackFrame.values[-1];
+		} else if (stack.opers[brackStart] == OP_LOAD_IMM_STR) {
+			if ((char *) decodePtr(stack.values[brackStart]) != _resultStr) {
+				strcpy(_resultStr, (char *) decodePtr(stack.values[brackStart]));
+				stack.values[brackStart] =
+					encodePtr((byte *) _resultStr, kResStr);
+			}
+			strcat(_resultStr, (char *) decodePtr(stackFrame.values[-1]));
+		}
+		stackFrame.pop(2);
+		break;
+
+	case OP_SUB:
+		stack.values[brackStart] -= stackFrame.values[-1];
+		stackFrame.pop(2);
+		break;
+
+	case OP_BITOR:
+		stack.values[brackStart] |= stackFrame.values[-1];
+		stackFrame.pop(2);
+		break;
+
+	case OP_MUL:
+		stackFrame.values[-3] *= stackFrame.values[-1];
+		stackFrame.pop(2);
+		break;
+
+	case OP_DIV:
+		stackFrame.values[-3] /= stackFrame.values[-1];
+		stackFrame.pop(2);
+		break;
+
+	case OP_MOD:
+		stackFrame.values[-3] %= stackFrame.values[-1];
+		stackFrame.pop(2);
+		break;
+
+	case OP_BITAND:
+		stackFrame.values[-3] &= stackFrame.values[-1];
+		stackFrame.pop(2);
+		break;
+
+	case OP_OR:
+		// (x OR false) == x
+		// (x OR true) == true
+		if (stackFrame.opers[-3] == GOB_FALSE)
+			stackFrame.opers[-3] = stackFrame.opers[-1];
+		stackFrame.pop(2);
+		break;
+
+	case OP_AND:
+		// (x AND false) == false
+		// (x AND true) == x
+		if (stackFrame.opers[-3] == GOB_TRUE)
+			stackFrame.opers[-3] = stackFrame.opers[-1];
+		stackFrame.pop(2);
+		break;
+
+	case OP_LESS:
+		stackFrame.opers[-3] = (cmpHelper(stackFrame) < 0) ? GOB_TRUE : GOB_FALSE;
+		stackFrame.pop(2);
+		break;
+
+	case OP_LEQ:
+		stackFrame.opers[-3] = (cmpHelper(stackFrame) <= 0) ? GOB_TRUE : GOB_FALSE;
+		stackFrame.pop(2);
+		break;
+
+	case OP_GREATER:
+		stackFrame.opers[-3] = (cmpHelper(stackFrame) > 0) ? GOB_TRUE : GOB_FALSE;
+		stackFrame.pop(2);
+		break;
+
+	case OP_GEQ:
+		stackFrame.opers[-3] = (cmpHelper(stackFrame) >= 0) ? GOB_TRUE : GOB_FALSE;
+		stackFrame.pop(2);
+		break;
+
+	case OP_EQ:
+		stackFrame.opers[-3] = (cmpHelper(stackFrame) == 0) ? GOB_TRUE : GOB_FALSE;
+		stackFrame.pop(2);
+		break;
+
+	case OP_NEQ:
+		stackFrame.opers[-3] = (cmpHelper(stackFrame) != 0) ? GOB_TRUE : GOB_FALSE;
+		stackFrame.pop(2);
+		break;
+
+	default:
+		return true;
+	}
+
+	return false;
+}
+
+// Assign the result to the appropriate _result variable
+void Expression::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:
+		_resultInt = value;
+		break;
+
+	case OP_LOAD_IMM_STR:
+		if ((char *) decodePtr(value) != _resultStr)
+			strcpy(_resultStr, (char *) decodePtr(value));
+		break;
+
+	case OP_LOAD_VAR_INT32:
+	case OP_LOAD_VAR_INT32_AS_INT16:
+		break;
+
+	default:
+		_resultInt = 0;
+		if (type != 0)
+			*type = OP_LOAD_IMM_INT16;
+		break;
+	}
+}
+
+int16 Expression::parseExpr(byte stopToken, byte *type) {
+	Stack stack;
+	StackFrame stackFrame(stack);
+	byte operation;
+	bool escape;
+	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) {
+				escape = false;
+				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;
+	}
+}
+
+int32 Expression::getResultInt() {
+	return _resultInt;
+}
+
+char *Expression::getResultStr() {
+	return _resultStr;
+}
+
+} // End of namespace Gob


Property changes on: scummvm/trunk/engines/gob/expression.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Copied: scummvm/trunk/engines/gob/expression.h (from rev 41772, scummvm/trunk/engines/gob/parse.h)
===================================================================
--- scummvm/trunk/engines/gob/expression.h	                        (rev 0)
+++ scummvm/trunk/engines/gob/expression.h	2009-06-22 16:30:35 UTC (rev 41773)
@@ -0,0 +1,178 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef GOB_EXPRESSION_H
+#define GOB_EXPRESSION_H
+
+#include "common/scummsys.h"
+
+namespace Gob {
+
+class GobEngine;
+
+enum {
+	OP_NEG        =  1,
+	OP_ADD        =  2,
+	OP_SUB        =  3,
+	OP_BITOR      =  4,
+	OP_MUL        =  5,
+	OP_DIV        =  6,
+	OP_MOD        =  7,
+	OP_BITAND     =  8,
+	OP_BEGIN_EXPR =  9,
+	OP_END_EXPR   = 10,
+	OP_NOT        = 11,
+
+	OP_END_MARKER = 12, // Marks end of an array or string
+
+
+	OP_ARRAY_INT8              = 16,
+	OP_LOAD_VAR_INT16          = 17,
+	OP_LOAD_VAR_INT8           = 18,
+	OP_LOAD_IMM_INT32          = 19,
+	OP_LOAD_IMM_INT16          = 20,
+	OP_LOAD_IMM_INT8           = 21,
+	OP_LOAD_IMM_STR            = 22,
+	OP_LOAD_VAR_INT32          = 23,
+	OP_LOAD_VAR_INT32_AS_INT16 = 24,
+	OP_LOAD_VAR_STR            = 25,
+	OP_ARRAY_INT32             = 26,
+	OP_ARRAY_INT16             = 27,
+	OP_ARRAY_STR               = 28,
+
+	OP_FUNC = 29,
+
+	OP_OR      = 30, // Logical OR
+	OP_AND     = 31, // Logical AND
+	OP_LESS    = 32,
+	OP_LEQ     = 33,
+	OP_GREATER = 34,
+	OP_GEQ     = 35,
+	OP_EQ      = 36,
+	OP_NEQ     = 37
+};
+
+enum {
+	FUNC_SQRT1 =  0,
+	FUNC_SQRT2 =  1,
+	FUNC_SQRT3 =  6,
+
+	FUNC_SQR   =  5,
+	FUNC_ABS   =  7,
+	FUNC_RAND  = 10
+};
+
+enum {
+	TYPE_IMM_INT8           = OP_LOAD_IMM_INT8,          // 21
+	TYPE_IMM_INT32          = OP_LOAD_IMM_INT32,         // 19
+	TYPE_IMM_INT16          = OP_LOAD_IMM_INT16,         // 20
+	TYPE_IMM_STR            = OP_LOAD_IMM_STR,           // 22
+	TYPE_VAR_INT8           = OP_LOAD_VAR_INT8,          // 18
+	TYPE_VAR_INT16          = OP_LOAD_VAR_INT16,         // 17
+	TYPE_VAR_INT32          = OP_LOAD_VAR_INT32,         // 23
+	TYPE_VAR_STR            = OP_LOAD_VAR_STR,           // 25
+	TYPE_ARRAY_INT8         = OP_ARRAY_INT8,             // 16
+	TYPE_ARRAY_INT16        = OP_ARRAY_INT16,            // 27
+	TYPE_ARRAY_INT32        = OP_ARRAY_INT32,            // 26
+	TYPE_ARRAY_STR          = OP_ARRAY_STR,              // 28
+	TYPE_VAR_INT32_AS_INT16 = OP_LOAD_VAR_INT32_AS_INT16 // 24
+};
+
+enum {
+	// FIXME: The following two 'truth values' are stored inside the list
+	// of "operators". So they somehow coincide with OP_LOAD_VAR_INT32
+	// and OP_LOAD_VAR_INT32_AS_INT16. I haven't yet quite understood
+	// how, resp. what that means. You have been warned.
+	GOB_TRUE  = 24,
+	GOB_FALSE = 23
+};
+
+class Expression {
+public:
+	Expression(GobEngine *vm);
+	virtual ~Expression() {}
+
+	void skipExpr(char stopToken);
+	void printExpr(char stopToken);
+	void printVarIndex(void);
+
+	int16 parseVarIndex(uint16 *size = 0, uint16 *type = 0);
+	int16 parseValExpr(byte stopToken = 99);
+	int16 parseExpr(byte stopToken, byte *type);
+
+	int32 getResultInt();
+	char *getResultStr();
+
+private:
+	class Stack {
+	public:
+		byte *opers;
+		int32 *values;
+
+		Stack(size_t size = 20);
+		~Stack();
+	};
+	class StackFrame {
+	public:
+		byte *opers;
+		int32 *values;
+		int16 pos;
+
+		StackFrame(const Stack &stack);
+
+		void push(int count = 1);
+		void pop(int count = 1);
+	};
+
+	enum PointerType {
+		kExecPtr  = 0,
+		kInterVar = 1,
+		kResStr   = 2
+	};
+
+	GobEngine *_vm;
+
+	int32 _resultInt;
+	char _resultStr[200];
+
+	int32 encodePtr(byte *ptr, int type);
+	byte *decodePtr(int32 n);
+
+	void printExpr_internal(char stopToken);
+
+	bool getVarBase(uint32 &varBase, bool mindStop = false,
+			uint16 *size = 0, uint16 *type = 0);
+	int cmpHelper(const StackFrame &stackFrame);
+	void loadValue(byte operation, uint32 varBase, const StackFrame &stackFrame);
+
+	void simpleArithmetic1(StackFrame &stackFrame);
+	void simpleArithmetic2(StackFrame &stackFrame);
+	bool complexArithmetic(Stack &stack, StackFrame &stackFrame, int16 brackStart);
+	void getResult(byte operation, int32 value, byte *type);
+};
+
+} // End of namespace Gob
+
+#endif // GOB_EXPRESSION_H


Property changes on: scummvm/trunk/engines/gob/expression.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Modified: scummvm/trunk/engines/gob/gob.cpp
===================================================================
--- scummvm/trunk/engines/gob/gob.cpp	2009-06-22 16:30:06 UTC (rev 41772)
+++ scummvm/trunk/engines/gob/gob.cpp	2009-06-22 16:30:35 UTC (rev 41773)
@@ -47,7 +47,6 @@
 #include "gob/map.h"
 #include "gob/mult.h"
 #include "gob/palanim.h"
-#include "gob/parse.h"
 #include "gob/scenery.h"
 #include "gob/videoplayer.h"
 #include "gob/save/saveload.h"

Modified: scummvm/trunk/engines/gob/inter.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter.cpp	2009-06-22 16:30:06 UTC (rev 41772)
+++ scummvm/trunk/engines/gob/inter.cpp	2009-06-22 16:30:35 UTC (rev 41773)
@@ -33,10 +33,10 @@
 #include "gob/util.h"
 #include "gob/draw.h"
 #include "gob/game.h"
+#include "gob/expression.h"
 #include "gob/script.h"
 #include "gob/scenery.h"
 #include "gob/sound/sound.h"
-#include "gob/parse.h"
 
 namespace Gob {
 

Modified: scummvm/trunk/engines/gob/inter_v1.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter_v1.cpp	2009-06-22 16:30:06 UTC (rev 41772)
+++ scummvm/trunk/engines/gob/inter_v1.cpp	2009-06-22 16:30:35 UTC (rev 41773)
@@ -34,8 +34,8 @@
 #include "gob/dataio.h"
 #include "gob/draw.h"
 #include "gob/game.h"
+#include "gob/expression.h"
 #include "gob/script.h"
-#include "gob/parse.h"
 #include "gob/goblin.h"
 #include "gob/inter.h"
 #include "gob/map.h"

Modified: scummvm/trunk/engines/gob/inter_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter_v2.cpp	2009-06-22 16:30:06 UTC (rev 41772)
+++ scummvm/trunk/engines/gob/inter_v2.cpp	2009-06-22 16:30:35 UTC (rev 41773)
@@ -36,8 +36,8 @@
 #include "gob/dataio.h"
 #include "gob/draw.h"
 #include "gob/game.h"
+#include "gob/expression.h"
 #include "gob/script.h"
-#include "gob/parse.h"
 #include "gob/goblin.h"
 #include "gob/map.h"
 #include "gob/mult.h"

Modified: scummvm/trunk/engines/gob/inter_v6.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter_v6.cpp	2009-06-22 16:30:06 UTC (rev 41772)
+++ scummvm/trunk/engines/gob/inter_v6.cpp	2009-06-22 16:30:35 UTC (rev 41773)
@@ -32,8 +32,8 @@
 #include "gob/helper.h"
 #include "gob/global.h"
 #include "gob/game.h"
+#include "gob/expression.h"
 #include "gob/script.h"
-#include "gob/parse.h"
 #include "gob/draw.h"
 #include "gob/sound/sound.h"
 #include "gob/videoplayer.h"

Modified: scummvm/trunk/engines/gob/module.mk
===================================================================
--- scummvm/trunk/engines/gob/module.mk	2009-06-22 16:30:06 UTC (rev 41772)
+++ scummvm/trunk/engines/gob/module.mk	2009-06-22 16:30:35 UTC (rev 41773)
@@ -9,6 +9,7 @@
 	draw_bargon.o \
 	draw_fascin.o \
 	driver_vga.o \
+	expression.o \
 	game.o \
 	game_v1.o \
 	game_v2.o \
@@ -43,7 +44,6 @@
 	mult_v1.o \
 	mult_v2.o \
 	palanim.o \
-	parse.o \
 	scenery.o \
 	scenery_v1.o \
 	scenery_v2.o \

Deleted: scummvm/trunk/engines/gob/parse.cpp
===================================================================
--- scummvm/trunk/engines/gob/parse.cpp	2009-06-22 16:30:06 UTC (rev 41772)
+++ scummvm/trunk/engines/gob/parse.cpp	2009-06-22 16:30:35 UTC (rev 41773)
@@ -1,1145 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/endian.h"
-
-#include "gob/gob.h"
-#include "gob/parse.h"
-#include "gob/global.h"
-#include "gob/game.h"
-#include "gob/script.h"
-#include "gob/inter.h"
-
-namespace Gob {
-
-Expression::Stack::Stack(size_t size) {
-	opers  = new byte[size];
-	values = new int32[size];
-	memset(opers , 0, size * sizeof(byte ));
-	memset(values, 0, size * sizeof(int32));
-}
-
-Expression::Stack::~Stack() {
-	delete[] opers;
-	delete[] values;
-}
-
-Expression::StackFrame::StackFrame(const Stack &stack) {
-	opers = stack.opers - 1;
-	values = stack.values - 1;
-	pos = -1;
-}
-
-void Expression::StackFrame::push(int count) {
-	opers  += count;
-	values += count;
-	pos    += count;
-}
-
-void Expression::StackFrame::pop(int count) {
-	opers  -= count;
-	values -= count;
-	pos    -= count;
-}
-
-Expression::Expression(GobEngine *vm) : _vm(vm) {
-	_resultStr[0] = 0;
-	_resultInt = 0;
-}
-
-int32 Expression::encodePtr(byte *ptr, int type) {
-	int32 offset = 0;
-
-	switch (type) {
-	case kExecPtr:
-		offset = _vm->_game->_script->getOffset(ptr);
-		break;
-	case kInterVar:
-		offset = ptr - ((byte *) _vm->_inter->_variables->getAddressOff8(0));
-		break;
-	case kResStr:
-		offset = ptr - ((byte *) _resultStr);
-		break;
-	default:
-		error("Expression::encodePtr(): Unknown pointer type");
-	}
-	assert((offset & 0xF0000000) == 0);
-	return (type << 28) | offset;
-}
-
-byte *Expression::decodePtr(int32 n) {
-	byte *ptr;
-
-	switch (n >> 28) {
-	case kExecPtr:
-		ptr = _vm->_game->_script->getData();
-		break;
-	case kInterVar:
-		ptr = (byte *) _vm->_inter->_variables->getAddressOff8(0);
-		break;
-	case kResStr:
-		ptr = (byte *) _resultStr;
-		break;
-	default:
-		error("Expression::decodePtr(): Unknown pointer type");
-	}
-	return ptr + (n & 0x0FFFFFFF);
-}
-
-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;
-	}
-}
-
-void Expression::printExpr(char stopToken) {
-	// Expression printing disabled by default
-	return;
-
-	int32 savedPos = _vm->_game->_script->pos();
-	printExpr_internal(stopToken);
-
-	// restore IP to start of expression
-	_vm->_game->_script->seek(savedPos);
-}
-
-void Expression::printExpr_internal(char stopToken) {
-	int16 dimCount;
-	byte operation;
-	int16 num;
-	int16 dim;
-	byte *arrDesc;
-	byte func;
-
-	num = 0;
-	while (true) {
-		operation = _vm->_game->_script->readByte();
-
-		if ((operation >= OP_ARRAY_INT8) && (operation <= OP_FUNC)) {
-			// operands
-
-			switch (operation) {
-			case OP_LOAD_VAR_INT16: // int16 variable load
-				debugN(5, "var16_%d", _vm->_game->_script->readUint16());
-				break;
-
-			case OP_LOAD_VAR_INT8: // int8 variable load:
-				debugN(5, "var8_%d", _vm->_game->_script->readUint16());
-				break;
-
-			case OP_LOAD_IMM_INT32: // int32/uint32 immediate
-				debugN(5, "%d", _vm->_game->_script->readInt32());
-				break;
-
-			case OP_LOAD_IMM_INT16: // int16 immediate
-				debugN(5, "%d", _vm->_game->_script->readInt16());
-				break;
-
-			case OP_LOAD_IMM_INT8: // int8 immediate
-				debugN(5, "%d",  _vm->_game->_script->readInt8());
-				break;
-
-			case OP_LOAD_IMM_STR: // string immediate
-				debugN(5, "\42%s\42", _vm->_game->_script->readString());
-				break;
-
-			case OP_LOAD_VAR_INT32:
-			case OP_LOAD_VAR_INT32_AS_INT16:
-				debugN(5, "var_%d", _vm->_game->_script->readUint16());
-				break;
-
-			case OP_LOAD_VAR_STR: // string variable load
-				debugN(5, "(&var_%d)", _vm->_game->_script->readUint16());
-				if (_vm->_game->_script->peekByte() == 13) {
-					_vm->_game->_script->skip(1);
-					debugN(5, "{");
-					printExpr_internal(OP_END_MARKER); // this also prints the closing }
-				}
-				break;
-
-			case OP_ARRAY_INT8:  // int8 array access
-			case OP_ARRAY_INT32: // int32 array access
-			case OP_ARRAY_INT16: // int16 array access
-			case OP_ARRAY_STR:   // string array access
-				debugN(5, "\n");
-				if (operation == OP_ARRAY_STR)
-					debugN(5, "(&");
-
-				debugN(5, "var_%d[", _vm->_game->_script->readInt16());
-				dimCount = _vm->_game->_script->readByte();
-				arrDesc = _vm->_game->_script->getData() + _vm->_game->_script->pos();
-				_vm->_game->_script->skip(dimCount);
-				for (dim = 0; dim < dimCount; dim++) {
-					printExpr_internal(OP_END_MARKER);
-					debugN(5, " of %d", (int16) arrDesc[dim]);
-					if (dim != dimCount - 1)
-						debugN(5, ",");
-				}
-				debugN(5, "]");
-				if (operation == OP_ARRAY_STR)
-					debugN(5, ")");
-
-				if ((operation == OP_ARRAY_STR) && (_vm->_game->_script->peekByte() == 13)) {
-					_vm->_game->_script->skip(1);
-					debugN(5, "{");
-					printExpr_internal(OP_END_MARKER); // this also prints the closing }
-				}
-				break;
-
-			case OP_FUNC: // function
-				func = _vm->_game->_script->readByte();
-				if (func == FUNC_SQR)
-					debugN(5, "sqr(");
-				else if (func == FUNC_RAND)
-					debugN(5, "rand(");
-				else if (func == FUNC_ABS)
-					debugN(5, "abs(");
-				else if ((func == FUNC_SQRT1) || (func == FUNC_SQRT2) || (func == FUNC_SQRT3))
-					debugN(5, "sqrt(");
-				else
-					debugN(5, "id(");
-				printExpr_internal(OP_END_EXPR);
-				break;
-			}
-			continue;
-		}		// if ((operation >= OP_ARRAY_INT8) && (operation <= OP_FUNC))
-
-		// operators
-		switch (operation) {
-		case OP_BEGIN_EXPR:
-			debugN(5, "(");
-			break;
-
-		case OP_NOT:
-			debugN(5, "!");
-			break;
-
-		case OP_END_EXPR:
-			debugN(5, ")");
-			break;
-
-		case OP_NEG:
-			debugN(5, "-");
-			break;
-
-		case OP_ADD:
-			debugN(5, "+");
-			break;
-
-		case OP_SUB:
-			debugN(5, "-");
-			break;
-
-		case OP_BITOR:
-			debugN(5, "|");
-			break;
-
-		case OP_MUL:
-			debugN(5, "*");
-			break;
-
-		case OP_DIV:
-			debugN(5, "/");
-			break;
-
-		case OP_MOD:
-			debugN(5, "%%");
-			break;
-
-		case OP_BITAND:
-			debugN(5, "&");
-			break;
-
-		case OP_OR:
-			debugN(5, "||");
-			break;
-
-		case 31:
-			debugN(5, "&&");
-			break;
-
-		case OP_LESS:
-			debugN(5, "<");
-			break;
-
-		case OP_LEQ:
-			debugN(5, "<=");
-			break;
-
-		case OP_GREATER:
-			debugN(5, ">");
-			break;
-
-		case OP_GEQ:
-			debugN(5, ">=");
-			break;
-
-		case OP_EQ:
-			debugN(5, "==");
-			break;
-
-		case OP_NEQ:
-			debugN(5, "!=");
-			break;
-
-		case 99:
-			debugN(5, "\n");
-			break;
-
-		case OP_END_MARKER:
-			debugN(5, "}");
-			if (stopToken != OP_END_MARKER) {
-				debugN(5, "Closing paren without opening?");
-			}
-			break;
-
-		default:
-			debugN(5, "<%d>", (int16) operation);
-			error("Expression::printExpr(): invalid operator in expression");
-			break;
-		}
-
-		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) {
-			if ((stopToken != OP_END_EXPR) || (num < 0)) {
-				return;
-			}
-		}
-	}
-}
-
-
-void Expression::printVarIndex() {
-	byte *arrDesc;
-	int16 dim;
-	int16 dimCount;
-	int16 operation;
-	int16 temp;
-
-	int32 pos = _vm->_game->_script->pos();
-
-	operation = _vm->_game->_script->readByte();
-	switch (operation) {
-	case OP_LOAD_VAR_INT32:
-	case OP_LOAD_VAR_STR:
-		temp = _vm->_game->_script->readUint16() * 4;
-		debugN(5, "&var_%d", temp);
-		if ((operation == OP_LOAD_VAR_STR) && (_vm->_game->_script->peekByte() == 13)) {
-			_vm->_game->_script->skip(1);
-			debugN(5, "+");
-			printExpr(OP_END_MARKER);
-		}
-		break;
-
-	case OP_ARRAY_INT32:
-	case OP_ARRAY_STR:
-		debugN(5, "&var_%d[", _vm->_game->_script->readUint16());
-		dimCount = _vm->_game->_script->readByte();
-		arrDesc = _vm->_game->_script->getData() + _vm->_game->_script->pos();
-		_vm->_game->_script->skip(dimCount);
-		for (dim = 0; dim < dimCount; dim++) {
-			printExpr(OP_END_MARKER);
-			debugN(5, " of %d", (int16) arrDesc[dim]);
-			if (dim != dimCount - 1)
-				debugN(5, ",");
-		}
-		debugN(5, "]");
-
-		if ((operation == OP_ARRAY_STR) && (_vm->_game->_script->peekByte() == 13)) {
-			_vm->_game->_script->skip(1);
-			debugN(5, "+");
-			printExpr(OP_END_MARKER);
-		}
-		break;
-
-	default:
-		debugN(5, "var_0");
-		break;
-	}
-	debugN(5, "\n");
-
-	_vm->_game->_script->seek(pos);
-	return;
-}
-
-int Expression::cmpHelper(const StackFrame &stackFrame) {
-	byte type = stackFrame.opers[-3];
-	int cmpTemp = 0;
-
-	if (type == OP_LOAD_IMM_INT16) {
-		cmpTemp = (int)stackFrame.values[-3] - (int)stackFrame.values[-1];
-	} else if (type == 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);
-		}
-		cmpTemp = strcmp(_resultStr, (char *)decodePtr(stackFrame.values[-1]));
-	}
-
-	return cmpTemp;
-}
-
-bool Expression::getVarBase(uint32 &varBase, bool mindStop,
-		uint16 *size, uint16 *type) {
-
-	varBase = 0;
-
-	byte operation = _vm->_game->_script->peekByte();
-	while ((operation == 14) || (operation == 15)) {
-		_vm->_game->_script->skip(1);
-
-		if (operation == 14) {
-			// Add a direct offset
-
-			varBase += _vm->_game->_script->readInt16() * 4;
-
-			if (size)
-				*size = _vm->_game->_script->peekUint16();
-			if (type)
-				*type = 14;
-
-			_vm->_game->_script->skip(2);
-
-			debugC(2, kDebugParser, "varBase: %d, by %d", varBase, operation);
-
-			if (_vm->_game->_script->peekByte() != 97) {
-				if (mindStop)
-					return true;
-			} else
-				_vm->_game->_script->skip(1);
-
-		} else if (operation == 15) {
-			// Add an offset from an array
-
-			varBase += _vm->_game->_script->readInt16() * 4;
-
-			uint16 offset1 = _vm->_game->_script->readUint16();
-
-			if (size)
-				*size = offset1;
-			if (type)
-				*type = 15;
-
-			uint8 dimCount = _vm->_game->_script->readByte();
-			byte *dimArray = _vm->_game->_script->getData() + _vm->_game->_script->pos();
-
-			_vm->_game->_script->skip(dimCount);
-
-			uint16 offset2 = 0;
-			for (int i = 0; i < dimCount; i++) {
-				int16 dim = CLIP<int>(parseValExpr(OP_END_MARKER), 0, dimArray[i] - 1);
-
-				offset2 = offset2 * dimArray[i] + dim;
-			}
-
-			varBase += offset2 * offset1 * 4;
-
-			debugC(2, kDebugParser, "varBase: %d, by %d", varBase, operation);
-
-			if (_vm->_game->_script->peekByte() != 97) {
-				if (mindStop)
-					return true;
-			} else
-				_vm->_game->_script->skip(1);
-		}
-
-		operation = _vm->_game->_script->peekByte();
-	}
-
-	return false;
-}
-
-int16 Expression::parseVarIndex(uint16 *size, uint16 *type) {
-	int16 temp2;
-	byte *arrDesc;
-	int16 dim;
-	int16 dimCount;
-	int16 operation;
-	int16 temp;
-	int16 offset;
-	int16 val;
-	uint32 varBase;
-
-	if (getVarBase(varBase, true, size, type))
-		return varBase;
-
-	operation = _vm->_game->_script->readByte();
-
-	if (size)
-		*size = 0;
-	if (type)
-		*type = operation;
-
-	debugC(5, kDebugParser, "var parse = %d", operation);
-	switch (operation) {
-	case OP_ARRAY_INT8:
-	case OP_ARRAY_INT32:
-	case OP_ARRAY_INT16:
-	case OP_ARRAY_STR:
-		temp = _vm->_game->_script->readInt16();
-		dimCount = _vm->_game->_script->readByte();
-		arrDesc = _vm->_game->_script->getData() + _vm->_game->_script->pos();
-		_vm->_game->_script->skip(dimCount);
-		offset = 0;
-		for (dim = 0; dim < dimCount; dim++) {
-			temp2 = parseValExpr(OP_END_MARKER);
-			offset = arrDesc[dim] * offset + temp2;
-		}
-		if (operation == OP_ARRAY_INT8)
-			return varBase + temp + offset;
-		if (operation == OP_ARRAY_INT32)
-			return varBase + (temp + offset) * 4;
-		if (operation == OP_ARRAY_INT16)
-			return varBase + (temp + offset) * 2;
-		temp *= 4;
-		offset *= 4;
-		if (_vm->_game->_script->peekByte() == 13) {
-			_vm->_game->_script->skip(1);
-			temp += parseValExpr(OP_END_MARKER);
-		}
-		return varBase + offset * _vm->_global->_inter_animDataSize + temp;
-
-	case OP_LOAD_VAR_INT16:
-		return varBase + _vm->_game->_script->readInt16() * 2;
-
-	case OP_LOAD_VAR_INT8:
-		return varBase + _vm->_game->_script->readInt16();
-
-	case OP_LOAD_VAR_INT32:
-	case OP_LOAD_VAR_INT32_AS_INT16:
-	case OP_LOAD_VAR_STR:
-		temp = _vm->_game->_script->readInt16() * 4;
-		debugC(5, kDebugParser, "oper = %d", _vm->_game->_script->peekInt16());
-		if ((operation == OP_LOAD_VAR_STR) && (_vm->_game->_script->peekByte() == 13)) {
-			_vm->_game->_script->skip(1);
-			val = parseValExpr(OP_END_MARKER);
-			temp += val;
-			debugC(5, kDebugParser, "parse subscript = %d", val);
-		}
-		return varBase + temp;
-
-	default:
-		return 0;
-	}
-}
-
-int16 Expression::parseValExpr(byte stopToken) {
-	parseExpr(stopToken, 0);
-
-	return _resultInt;
-}
-
-// Load a value according to the operation
-void Expression::loadValue(byte operation, uint32 varBase, const StackFrame &stackFrame) {
-	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:
-		*stackFrame.opers = (operation == OP_ARRAY_STR) ? OP_LOAD_IMM_STR : OP_LOAD_IMM_INT16;
-		temp = _vm->_game->_script->readInt16();
-		dimCount = _vm->_game->_script->readByte();
-		arrDescPtr = _vm->_game->_script->getData() + _vm->_game->_script->pos();
-		_vm->_game->_script->skip(dimCount);
-		offset = 0;
-		for (dim = 0; dim < dimCount; dim++) {
-			temp2 = parseValExpr(OP_END_MARKER);
-			offset = offset * arrDescPtr[dim] + temp2;
-		}
-		if (operation == OP_ARRAY_INT8)
-			*stackFrame.values = (int8) READ_VARO_UINT8(varBase + temp + offset);
-		else if (operation == OP_ARRAY_INT32)
-			*stackFrame.values = READ_VARO_UINT32(varBase + temp * 4 + offset * 4);
-		else if (operation == OP_ARRAY_INT16)
-			*stackFrame.values = (int16) READ_VARO_UINT16(varBase + temp * 2 + offset * 2);
-		else if (operation == OP_ARRAY_STR) {
-			*stackFrame.values = encodePtr(_vm->_inter->_variables->getAddressOff8(
-						varBase + temp * 4 + offset * _vm->_global->_inter_animDataSize * 4),
-					kInterVar);
-			if (_vm->_game->_script->peekByte() == 13) {
-				_vm->_game->_script->skip(1);
-				temp2 = parseValExpr(OP_END_MARKER);
-				*stackFrame.opers = OP_LOAD_IMM_INT16;
-				*stackFrame.values = READ_VARO_UINT8(varBase + temp * 4 +
-						offset * 4 * _vm->_global->_inter_animDataSize + temp2);
-			}
-		}
-		break;
-
-	case OP_LOAD_VAR_INT16:
-		*stackFrame.opers = OP_LOAD_IMM_INT16;
-		*stackFrame.values = (int16) READ_VARO_UINT16(varBase + _vm->_game->_script->readInt16() * 2);
-		break;
-
-	case OP_LOAD_VAR_INT8:
-		*stackFrame.opers = OP_LOAD_IMM_INT16;
-		*stackFrame.values = (int8) READ_VARO_UINT8(varBase + _vm->_game->_script->readInt16());
-		break;
-
-	case OP_LOAD_IMM_INT32:
-		*stackFrame.opers = OP_LOAD_IMM_INT16;
-		*stackFrame.values = _vm->_game->_script->readInt32();
-		break;
-
-	case OP_LOAD_IMM_INT16:
-		*stackFrame.opers = OP_LOAD_IMM_INT16;
-		*stackFrame.values = _vm->_game->_script->readInt16();
-		break;
-
-	case OP_LOAD_IMM_INT8:
-		*stackFrame.opers = OP_LOAD_IMM_INT16;
-		*stackFrame.values = _vm->_game->_script->readInt8();
-		break;
-
-	case OP_LOAD_IMM_STR:
-		*stackFrame.opers = OP_LOAD_IMM_STR;
-		*stackFrame.values = encodePtr((byte *) _vm->_game->_script->readString(), kExecPtr);
-		break;
-
-	case OP_LOAD_VAR_INT32:
-		*stackFrame.opers = OP_LOAD_IMM_INT16;
-		*stackFrame.values = READ_VARO_UINT32(varBase + _vm->_game->_script->readInt16() * 4);
-		break;
-
-	case OP_LOAD_VAR_INT32_AS_INT16:
-		*stackFrame.opers = OP_LOAD_IMM_INT16;
-		*stackFrame.values = (int16) READ_VARO_UINT16(varBase + _vm->_game->_script->readInt16() * 4);
-		break;
-
-	case OP_LOAD_VAR_STR:
-		*stackFrame.opers = OP_LOAD_IMM_STR;
-		temp = _vm->_game->_script->readInt16() * 4;
-		*stackFrame.values = encodePtr(_vm->_inter->_variables->getAddressOff8(varBase + temp), kInterVar);
-		if (_vm->_game->_script->peekByte() == 13) {
-			_vm->_game->_script->skip(1);
-			temp += parseValExpr(OP_END_MARKER);
-			*stackFrame.opers = OP_LOAD_IMM_INT16;
-			*stackFrame.values = READ_VARO_UINT8(varBase + temp);
-		}
-		break;
-
-	case OP_FUNC:
-		operation = _vm->_game->_script->readByte();
-		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 + _resultInt / curVal) / 2;
-			} while ((curVal != prevVal) && (curVal != prevPrevVal));
-			_resultInt = curVal;
-			break;
-
-		case FUNC_SQR:
-			_resultInt =
-				_resultInt * _resultInt;
-			break;
-
-		case FUNC_ABS:
-			if (_resultInt < 0)
-				_resultInt = -_resultInt;
-			break;
-
-		case FUNC_RAND:
-			_resultInt =
-				_vm->_util->getRandom(_resultInt);
-			break;
-		}
-
-		*stackFrame.opers = OP_LOAD_IMM_INT16;
-		*stackFrame.values = _resultInt;
-		break;
-	}
-}
-
-void Expression::simpleArithmetic1(StackFrame &stackFrame) {
-	switch (stackFrame.opers[-1]) {
-	case OP_ADD:
-		if (stackFrame.opers[-2] == OP_LOAD_IMM_STR) {
-			if ((char *) decodePtr(stackFrame.values[-2]) != _resultStr) {
-				strcpy(_resultStr, (char *) decodePtr(stackFrame.values[-2]));
-				stackFrame.values[-2] = encodePtr((byte *) _resultStr, kResStr);
-			}
-			strcat(_resultStr, (char *) decodePtr(stackFrame.values[0]));
-			stackFrame.pop(2);
-		}
-		break;
-
-	case OP_MUL:
-		stackFrame.values[-2] *= stackFrame.values[0];
-		stackFrame.pop(2);
-		break;
-
-	case OP_DIV:
-		stackFrame.values[-2] /= stackFrame.values[0];
-		stackFrame.pop(2);
-		break;
-
-	case OP_MOD:
-		stackFrame.values[-2] %= stackFrame.values[0];
-		stackFrame.pop(2);
-		break;
-
-	case OP_BITAND:
-		stackFrame.values[-2] &= stackFrame.values[0];
-		stackFrame.pop(2);
-		break;
-	}
-}
-
-void Expression::simpleArithmetic2(StackFrame &stackFrame) {
-	if (stackFrame.pos > 1) {
-		if (stackFrame.opers[-2] == OP_NEG) {
-			stackFrame.opers[-2] = OP_LOAD_IMM_INT16;
-			stackFrame.values[-2] = -stackFrame.values[-1];
-			stackFrame.pop();
-		} else if (stackFrame.opers[-2] == OP_NOT) {
-			stackFrame.opers[-2] = (stackFrame.opers[-1] == GOB_FALSE) ? GOB_TRUE : GOB_FALSE;
-			stackFrame.pop();
-		}
-	}
-
-	if (stackFrame.pos > 2) {
-		switch (stackFrame.opers[-2]) {
-		case OP_MUL:
-			stackFrame.values[-3] *= stackFrame.values[-1];
-			stackFrame.pop(2);
-			break;
-
-		case OP_DIV:
-			stackFrame.values[-3] /= stackFrame.values[-1];
-			stackFrame.pop(2);
-			break;
-
-		case OP_MOD:
-			stackFrame.values[-3] %= stackFrame.values[-1];
-			stackFrame.pop(2);
-			break;
-
-		case OP_BITAND:
-			stackFrame.values[-3] &= stackFrame.values[-1];
-			stackFrame.pop(2);
-			break;
-		}
-	}
-
-}
-
-// Complex arithmetics with brackets
-bool Expression::complexArithmetic(Stack &stack, StackFrame &stackFrame, int16 brackStart) {
-	switch (stackFrame.opers[-2]) {
-	case OP_ADD:
-		if (stack.opers[brackStart] == OP_LOAD_IMM_INT16) {
-			stack.values[brackStart] += stackFrame.values[-1];
-		} else if (stack.opers[brackStart] == OP_LOAD_IMM_STR) {
-			if ((char *) decodePtr(stack.values[brackStart]) != _resultStr) {
-				strcpy(_resultStr, (char *) decodePtr(stack.values[brackStart]));
-				stack.values[brackStart] =
-					encodePtr((byte *) _resultStr, kResStr);
-			}
-			strcat(_resultStr, (char *) decodePtr(stackFrame.values[-1]));
-		}
-		stackFrame.pop(2);
-		break;
-
-	case OP_SUB:
-		stack.values[brackStart] -= stackFrame.values[-1];
-		stackFrame.pop(2);
-		break;
-
-	case OP_BITOR:
-		stack.values[brackStart] |= stackFrame.values[-1];
-		stackFrame.pop(2);
-		break;
-
-	case OP_MUL:
-		stackFrame.values[-3] *= stackFrame.values[-1];
-		stackFrame.pop(2);
-		break;
-
-	case OP_DIV:
-		stackFrame.values[-3] /= stackFrame.values[-1];
-		stackFrame.pop(2);
-		break;
-
-	case OP_MOD:
-		stackFrame.values[-3] %= stackFrame.values[-1];
-		stackFrame.pop(2);
-		break;
-
-	case OP_BITAND:
-		stackFrame.values[-3] &= stackFrame.values[-1];
-		stackFrame.pop(2);
-		break;
-
-	case OP_OR:
-		// (x OR false) == x
-		// (x OR true) == true
-		if (stackFrame.opers[-3] == GOB_FALSE)
-			stackFrame.opers[-3] = stackFrame.opers[-1];
-		stackFrame.pop(2);
-		break;
-
-	case OP_AND:
-		// (x AND false) == false
-		// (x AND true) == x
-		if (stackFrame.opers[-3] == GOB_TRUE)
-			stackFrame.opers[-3] = stackFrame.opers[-1];
-		stackFrame.pop(2);
-		break;
-
-	case OP_LESS:
-		stackFrame.opers[-3] = (cmpHelper(stackFrame) < 0) ? GOB_TRUE : GOB_FALSE;
-		stackFrame.pop(2);
-		break;
-
-	case OP_LEQ:
-		stackFrame.opers[-3] = (cmpHelper(stackFrame) <= 0) ? GOB_TRUE : GOB_FALSE;
-		stackFrame.pop(2);
-		break;
-
-	case OP_GREATER:
-		stackFrame.opers[-3] = (cmpHelper(stackFrame) > 0) ? GOB_TRUE : GOB_FALSE;
-		stackFrame.pop(2);
-		break;
-
-	case OP_GEQ:
-		stackFrame.opers[-3] = (cmpHelper(stackFrame) >= 0) ? GOB_TRUE : GOB_FALSE;
-		stackFrame.pop(2);
-		break;
-
-	case OP_EQ:
-		stackFrame.opers[-3] = (cmpHelper(stackFrame) == 0) ? GOB_TRUE : GOB_FALSE;
-		stackFrame.pop(2);
-		break;
-
-	case OP_NEQ:
-		stackFrame.opers[-3] = (cmpHelper(stackFrame) != 0) ? GOB_TRUE : GOB_FALSE;
-		stackFrame.pop(2);
-		break;
-
-	default:
-		return true;
-	}
-
-	return false;
-}
-
-// Assign the result to the appropriate _result variable
-void Expression::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:
-		_resultInt = value;
-		break;
-
-	case OP_LOAD_IMM_STR:
-		if ((char *) decodePtr(value) != _resultStr)
-			strcpy(_resultStr, (char *) decodePtr(value));
-		break;
-
-	case OP_LOAD_VAR_INT32:
-	case OP_LOAD_VAR_INT32_AS_INT16:
-		break;
-
-	default:
-		_resultInt = 0;
-		if (type != 0)
-			*type = OP_LOAD_IMM_INT16;
-		break;
-	}
-}
-
-int16 Expression::parseExpr(byte stopToken, byte *type) {
-	Stack stack;
-	StackFrame stackFrame(stack);
-	byte operation;
-	bool escape;
-	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) {
-				escape = false;
-				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;
-	}
-}
-
-int32 Expression::getResultInt() {
-	return _resultInt;
-}
-
-char *Expression::getResultStr() {
-	return _resultStr;
-}
-
-} // End of namespace Gob

Deleted: scummvm/trunk/engines/gob/parse.h
===================================================================
--- scummvm/trunk/engines/gob/parse.h	2009-06-22 16:30:06 UTC (rev 41772)
+++ scummvm/trunk/engines/gob/parse.h	2009-06-22 16:30:35 UTC (rev 41773)
@@ -1,178 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef GOB_EXPRESSION_H
-#define GOB_EXPRESSION_H
-
-#include "common/scummsys.h"
-
-namespace Gob {
-
-class GobEngine;
-
-enum {
-	OP_NEG        =  1,
-	OP_ADD        =  2,
-	OP_SUB        =  3,
-	OP_BITOR      =  4,
-	OP_MUL        =  5,
-	OP_DIV        =  6,
-	OP_MOD        =  7,
-	OP_BITAND     =  8,
-	OP_BEGIN_EXPR =  9,
-	OP_END_EXPR   = 10,
-	OP_NOT        = 11,
-
-	OP_END_MARKER = 12, // Marks end of an array or string
-
-
-	OP_ARRAY_INT8              = 16,
-	OP_LOAD_VAR_INT16          = 17,
-	OP_LOAD_VAR_INT8           = 18,
-	OP_LOAD_IMM_INT32          = 19,
-	OP_LOAD_IMM_INT16          = 20,
-	OP_LOAD_IMM_INT8           = 21,
-	OP_LOAD_IMM_STR            = 22,
-	OP_LOAD_VAR_INT32          = 23,
-	OP_LOAD_VAR_INT32_AS_INT16 = 24,
-	OP_LOAD_VAR_STR            = 25,
-	OP_ARRAY_INT32             = 26,
-	OP_ARRAY_INT16             = 27,
-	OP_ARRAY_STR               = 28,
-
-	OP_FUNC = 29,
-
-	OP_OR      = 30, // Logical OR
-	OP_AND     = 31, // Logical AND
-	OP_LESS    = 32,
-	OP_LEQ     = 33,
-	OP_GREATER = 34,
-	OP_GEQ     = 35,
-	OP_EQ      = 36,
-	OP_NEQ     = 37
-};
-
-enum {
-	FUNC_SQRT1 =  0,
-	FUNC_SQRT2 =  1,
-	FUNC_SQRT3 =  6,
-
-	FUNC_SQR   =  5,
-	FUNC_ABS   =  7,
-	FUNC_RAND  = 10
-};
-
-enum {
-	TYPE_IMM_INT8           = OP_LOAD_IMM_INT8,          // 21
-	TYPE_IMM_INT32          = OP_LOAD_IMM_INT32,         // 19
-	TYPE_IMM_INT16          = OP_LOAD_IMM_INT16,         // 20
-	TYPE_IMM_STR            = OP_LOAD_IMM_STR,           // 22
-	TYPE_VAR_INT8           = OP_LOAD_VAR_INT8,          // 18
-	TYPE_VAR_INT16          = OP_LOAD_VAR_INT16,         // 17
-	TYPE_VAR_INT32          = OP_LOAD_VAR_INT32,         // 23
-	TYPE_VAR_STR            = OP_LOAD_VAR_STR,           // 25
-	TYPE_ARRAY_INT8         = OP_ARRAY_INT8,             // 16
-	TYPE_ARRAY_INT16        = OP_ARRAY_INT16,            // 27
-	TYPE_ARRAY_INT32        = OP_ARRAY_INT32,            // 26
-	TYPE_ARRAY_STR          = OP_ARRAY_STR,              // 28
-	TYPE_VAR_INT32_AS_INT16 = OP_LOAD_VAR_INT32_AS_INT16 // 24
-};
-
-enum {
-	// FIXME: The following two 'truth values' are stored inside the list
-	// of "operators". So they somehow coincide with OP_LOAD_VAR_INT32
-	// and OP_LOAD_VAR_INT32_AS_INT16. I haven't yet quite understood
-	// how, resp. what that means. You have been warned.
-	GOB_TRUE  = 24,
-	GOB_FALSE = 23
-};
-
-class Expression {
-public:
-	Expression(GobEngine *vm);
-	virtual ~Expression() {}
-
-	void skipExpr(char stopToken);
-	void printExpr(char stopToken);
-	void printVarIndex(void);
-
-	int16 parseVarIndex(uint16 *size = 0, uint16 *type = 0);
-	int16 parseValExpr(byte stopToken = 99);
-	int16 parseExpr(byte stopToken, byte *type);
-
-	int32 getResultInt();
-	char *getResultStr();
-
-private:
-	class Stack {
-	public:
-		byte *opers;
-		int32 *values;
-
-		Stack(size_t size = 20);
-		~Stack();
-	};
-	class StackFrame {
-	public:
-		byte *opers;
-		int32 *values;
-		int16 pos;
-
-		StackFrame(const Stack &stack);
-
-		void push(int count = 1);
-		void pop(int count = 1);
-	};
-
-	enum PointerType {
-		kExecPtr  = 0,
-		kInterVar = 1,
-		kResStr   = 2
-	};
-
-	GobEngine *_vm;
-
-	int32 _resultInt;
-	char _resultStr[200];
-
-	int32 encodePtr(byte *ptr, int type);
-	byte *decodePtr(int32 n);
-
-	void printExpr_internal(char stopToken);
-
-	bool getVarBase(uint32 &varBase, bool mindStop = false,
-			uint16 *size = 0, uint16 *type = 0);
-	int cmpHelper(const StackFrame &stackFrame);
-	void loadValue(byte operation, uint32 varBase, const StackFrame &stackFrame);
-
-	void simpleArithmetic1(StackFrame &stackFrame);
-	void simpleArithmetic2(StackFrame &stackFrame);
-	bool complexArithmetic(Stack &stack, StackFrame &stackFrame, int16 brackStart);
-	void getResult(byte operation, int32 value, byte *type);
-};
-
-} // End of namespace Gob
-
-#endif // GOB_EXPRESSION_H

Modified: scummvm/trunk/engines/gob/script.cpp
===================================================================
--- scummvm/trunk/engines/gob/script.cpp	2009-06-22 16:30:06 UTC (rev 41772)
+++ scummvm/trunk/engines/gob/script.cpp	2009-06-22 16:30:35 UTC (rev 41773)
@@ -29,7 +29,7 @@
 #include "gob/gob.h"
 #include "gob/script.h"
 #include "gob/dataio.h"
-#include "gob/parse.h"
+#include "gob/expression.h"
 #include "gob/videoplayer.h"
 
 namespace Gob {


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list