1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef GOB_EXPRESSION_H
24 #define GOB_EXPRESSION_H
25 
26 #include "common/scummsys.h"
27 
28 namespace Gob {
29 
30 class GobEngine;
31 
32 enum {
33 	OP_NEG        =  1,
34 	OP_ADD        =  2,
35 	OP_SUB        =  3,
36 	OP_BITOR      =  4,
37 	OP_MUL        =  5,
38 	OP_DIV        =  6,
39 	OP_MOD        =  7,
40 	OP_BITAND     =  8,
41 	OP_BEGIN_EXPR =  9,
42 	OP_END_EXPR   = 10,
43 	OP_NOT        = 11,
44 
45 	OP_END_MARKER = 12, // Marks end of an array or string
46 
47 
48 	OP_ARRAY_INT8              = 16,
49 	OP_LOAD_VAR_INT16          = 17,
50 	OP_LOAD_VAR_INT8           = 18,
51 	OP_LOAD_IMM_INT32          = 19,
52 	OP_LOAD_IMM_INT16          = 20,
53 	OP_LOAD_IMM_INT8           = 21,
54 	OP_LOAD_IMM_STR            = 22,
55 	OP_LOAD_VAR_INT32          = 23,
56 	OP_LOAD_VAR_INT32_AS_INT16 = 24,
57 	OP_LOAD_VAR_STR            = 25,
58 	OP_ARRAY_INT32             = 26,
59 	OP_ARRAY_INT16             = 27,
60 	OP_ARRAY_STR               = 28,
61 
62 	OP_FUNC = 29,
63 
64 	OP_OR      = 30, // Logical OR
65 	OP_AND     = 31, // Logical AND
66 	OP_LESS    = 32,
67 	OP_LEQ     = 33,
68 	OP_GREATER = 34,
69 	OP_GEQ     = 35,
70 	OP_EQ      = 36,
71 	OP_NEQ     = 37
72 };
73 
74 enum {
75 	FUNC_SQRT1 =  0,
76 	FUNC_SQRT2 =  1,
77 	FUNC_SQRT3 =  6,
78 
79 	FUNC_SQR   =  5,
80 	FUNC_ABS   =  7,
81 	FUNC_RAND  = 10
82 };
83 
84 enum {
85 	TYPE_IMM_INT8           = OP_LOAD_IMM_INT8,          // 21
86 	TYPE_IMM_INT32          = OP_LOAD_IMM_INT32,         // 19
87 	TYPE_IMM_INT16          = OP_LOAD_IMM_INT16,         // 20
88 	TYPE_IMM_STR            = OP_LOAD_IMM_STR,           // 22
89 	TYPE_VAR_INT8           = OP_LOAD_VAR_INT8,          // 18
90 	TYPE_VAR_INT16          = OP_LOAD_VAR_INT16,         // 17
91 	TYPE_VAR_INT32          = OP_LOAD_VAR_INT32,         // 23
92 	TYPE_VAR_STR            = OP_LOAD_VAR_STR,           // 25
93 	TYPE_ARRAY_INT8         = OP_ARRAY_INT8,             // 16
94 	TYPE_ARRAY_INT16        = OP_ARRAY_INT16,            // 27
95 	TYPE_ARRAY_INT32        = OP_ARRAY_INT32,            // 26
96 	TYPE_ARRAY_STR          = OP_ARRAY_STR,              // 28
97 	TYPE_VAR_INT32_AS_INT16 = OP_LOAD_VAR_INT32_AS_INT16 // 24
98 };
99 
100 enum {
101 	// FIXME: The following two 'truth values' are stored inside the list
102 	// of "operators". So they somehow coincide with OP_LOAD_VAR_INT32
103 	// and OP_LOAD_VAR_INT32_AS_INT16. I haven't yet quite understood
104 	// how, resp. what that means. You have been warned.
105 	GOB_TRUE  = 24,
106 	GOB_FALSE = 23
107 };
108 
109 class Expression {
110 public:
111 	Expression(GobEngine *vm);
~Expression()112 	virtual ~Expression() {}
113 
114 	void skipExpr(char stopToken);
115 	void printExpr(char stopToken);
116 	void printVarIndex();
117 
118 	int16 parseVarIndex(uint16 *size = 0, uint16 *type = 0);
119 	int16 parseValExpr(byte stopToken = 99);
120 	int16 parseExpr(byte stopToken, byte *type);
121 
122 	int32 getResultInt();
123 	char *getResultStr();
124 
125 private:
126 	class Stack {
127 	public:
128 		byte *opers;
129 		int32 *values;
130 
131 		Stack(size_t size = 20);
132 		~Stack();
133 	};
134 	class StackFrame {
135 	public:
136 		byte *opers;
137 		int32 *values;
138 		int16 pos;
139 
140 		StackFrame(const Stack &stack);
141 
142 		void push(int count = 1);
143 		void pop(int count = 1);
144 	};
145 
146 	enum PointerType {
147 		kExecPtr  = 0,
148 		kInterVar = 1,
149 		kResStr   = 2
150 	};
151 
152 	GobEngine *_vm;
153 
154 	int32 _resultInt;
155 	char _resultStr[200];
156 
157 	int32 encodePtr(byte *ptr, int type);
158 	byte *decodePtr(int32 n);
159 
160 	void printExpr_internal(char stopToken);
161 
162 	bool getVarBase(uint32 &varBase, bool mindStop = false,
163 			uint16 *size = 0, uint16 *type = 0);
164 	int cmpHelper(const StackFrame &stackFrame);
165 	void loadValue(byte operation, uint32 varBase, const StackFrame &stackFrame);
166 
167 	void simpleArithmetic1(StackFrame &stackFrame);
168 	void simpleArithmetic2(StackFrame &stackFrame);
169 	bool complexArithmetic(Stack &stack, StackFrame &stackFrame, int16 brackStart);
170 	void getResult(byte operation, int32 value, byte *type);
171 };
172 
173 } // End of namespace Gob
174 
175 #endif // GOB_EXPRESSION_H
176