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  * Based on the original sources
23  *   Faery Tale II -- The Halls of the Dead
24  *   (c) 1993-1996 The Wyrmkeep Entertainment Co.
25  */
26 
27 #ifndef SAGA2_CODE_H
28 #define SAGA2_CODE_H
29 
30 namespace Saga2 {
31 
32 // types of operations for code generation
33 // note that the macros listed below depend on the ordering of this
34 // table to determine things like unary-op, binary-op, etc.
35 
36 enum op_types {
37 	op_undefined = 0,
38 
39 	//  internal operations
40 
41 	op_nextblock,                           // continue execution at next block
42 	op_dup,                                 // duplicate 16-bit value on stack
43 	op_drop,                                // drop 16-bit value on stack
44 
45 	//  primary values
46 
47 	op_zero,                                // push a zero on the stack
48 	op_one,                                 // push a one on the stack
49 	op_constint,                            // constant integer
50 	op_constid,                             // constant id reference
51 	op_strlit,                              // string literal
52 	op_sym,                                 // symbol address
53 	op_symref,                              // symbol contents
54 	op_classref,                            // reference to "this"
55 	op_deref,                               // dereference of an ID
56 
57 	//  references within this module
58 
59 	op_getflag,                             // read from flag bit (mode)
60 	op_getbyte,                             // read from byte field (mode)
61 	op_getint,                              // read from integer field (mode)
62 	op_getstr,                              // read from string field (mode)
63 	op_getid,                               // read from id field (mode)
64 
65 	op_putflag,                             // put to flag bit (mode)
66 	op_putbyte,                             // put to byte field (mode)
67 	op_putint,                              // put to integer field (mode)
68 	op_putstr,                              // put to string field (mode)
69 	op_putid,                               // put to id field (mode)
70 
71 	op_pea,                                 // push effective address onto stack
72 
73 	//  'void' versions consume their arguments
74 
75 	op_putflag_v,                           // put to flag bit (mode)
76 	op_putbyte_v,                           // put to byte field (mode)
77 	op_putint_v,                            // put to integer field (mode)
78 	op_putstr_v,                            // put to string field (mode)
79 	op_putid_v,                             // put to id field (mode)
80 
81 	//  function call
82 
83 	op_call_near,                           // call function in same segment
84 	op_call_far,                            // call function in other segment
85 	op_ccall,                               // call C function
86 	op_ccall_v,                             // call C function (void)
87 	op_call_member,                         // call member function
88 	op_call_member_v,                       // call member function (void)
89 
90 	op_enter,                               // enter a function
91 	op_return,                              // return from function
92 	op_return_v,                            // return nothing from function
93 
94 	//  branches
95 
96 	op_jmp,
97 	op_jmp_true_v,                          // test arg and consume
98 	op_jmp_false_v,                         // test arg and consume
99 	op_jmp_true,                            // test arg and don't consume
100 	op_jmp_false,                           // test arg and don't consume
101 	op_jmp_switch,                          // switch statement (integer)
102 	op_jmp_strswitch,                       // switch statement (string)
103 	op_jmp_random,                          // random jump
104 
105 	//  unary operators
106 
107 	op_negate,
108 	op_not,
109 	op_compl,
110 
111 	op_inc_v,                               // increment, don't push
112 	op_dec_v,                               // decrement, don't push
113 	op_postinc,
114 	op_postdec,
115 
116 	// arithmetic
117 
118 	op_add,
119 	op_sub,
120 	op_mul,
121 	op_div,
122 	op_mod,
123 
124 	//  conditional
125 
126 	op_conditional,
127 	op_comma,
128 
129 	//  comparison
130 
131 	op_eq,
132 	op_ne,
133 	op_gt,
134 	op_lt,
135 	op_ge,
136 	op_le,
137 
138 	//  string comparison
139 
140 	op_str_eq,
141 	op_str_ne,
142 	op_str_gt,
143 	op_str_lt,
144 	op_str_ge,
145 	op_str_le,
146 
147 	//  shift
148 
149 	op_rsh,
150 	op_lsh,
151 
152 	//  bitwise
153 
154 	op_and,
155 	op_or,
156 	op_xor,
157 
158 	//  logical
159 
160 	op_land,
161 	op_lor,
162 	op_lxor,
163 
164 	//  string functions
165 
166 	op_strcat,                  // string concatenation
167 	op_strformat,               // string formatting
168 
169 	// assignment operators -- none of these are actually compiled into
170 	// code (they become get/put type operations)
171 
172 	op_assign,
173 	// none of these are even used currently...
174 	op_asplus,
175 	op_asminus,
176 	op_astimes,
177 	op_asdiv,
178 	op_asmod,
179 	op_asrshift,
180 	op_aslshift,
181 	op_asand,
182 	op_asor,
183 
184 	//  Special ops
185 
186 	op_speak,
187 	op_dialog_begin,
188 	op_dialog_end,
189 	op_reply,
190 	op_animate,
191 
192 // New opcodes
193 
194 	op_jmp_seedrandom,                      // seeded random jump
195 	op_symref_x,                            // get the export number of the symbol
196 
197 	op_last         /* about 90 so far */
198 };
199 
200 // addressing modes for get and put
201 
202 enum addr_types {
203 
204 	//  Offset reference to the thread structure
205 
206 	addr_thread = 0,
207 
208 	//  Offset reference to the stack
209 
210 	addr_stack,
211 
212 	//  Implicit reference to the currently executing segment
213 
214 	addr_near,
215 
216 	//  Implicit reference to data segment
217 
218 	addr_data,
219 
220 	//  This addressing mode references any external segment
221 	//  using a 16-bit segment number and a 16-bit segment offset
222 	//  which immediately follow the instruction.
223 
224 	addr_far,
225 
226 	//  This addressing mode is used for segment-array addressing
227 	//  it's a 16-bit segment followed by a 16-bit object number,
228 	//  followed by a (byte or bit) offset within the object
229 
230 	addr_array,
231 
232 	//  This addressing mode uses a 16-bit segment number
233 	//  and a 16-bit offset which have been put on the stack.
234 
235 //	addr_indirect,                           // use SEG:offset on stack
236 //	addr_indirect_index,                 // use SEG:index:offset on stack
237 
238 	//  This addressing mode is used for dereferencing objects.
239 	//  It consists of an _embedded_ address for retrieving the
240 	//  object number, followed by a 16-bit segment number for
241 	//  the dereferenced objects, followed by a 16-bit index
242 	//  into the dereferenced object.
243 
244 	//  REM: We also need a "far deref" for computing the
245 	//  dereferenced object's segment number.
246 
247 	addr_deref,
248 
249 	//  Addressing mode used for class member functions. It
250 	//  specified that the address is relative to whatever
251 	//  object the 1st argument is referrring to.
252 
253 	addr_this                              // relative to arg 1
254 };
255 
256 #define IS_CONST(x)     ((x) >= op_constint && (x) <= op_conststr)
257 #define IS_ADDRESS(x)   ((x) == op_sym)
258 #define IS_UNOP(x)      ((x) >= op_negate && (x) <= op_postdec)
259 
260 #define IS_BINOP(x)     ((x) >= op_add && (x) <= op_strcat)
261 #define IS_ASOP(x)      ((x) >= op_assign && (x) <= op_asor)
262 
263 // #define IS_UNOP2(x)      ((x) == op_getarray || (x) == op_putarray)
264 // #define CONST(op)        ((op) >= op_constflag && (op) <= op_conststr)
265 
266 //  Flags for special statements
267 
268 #define SPEAKF_NOANIMATE (1<<0)             // speaker should animate
269 #define SPEAKF_ASYNC    (1<<1)              // async speech.
270 
271 #define REPLYF_ONCE     (1<<0)              // 'once' flag
272 #define REPLYF_SUMMARY  (1<<1)              // response is only a summary
273 #define REPLYF_CONDITION (1<<2)             // response has a condition
274 
275 #define ANIMATEF_REPEAT (1<<0)
276 
277 //  BasicBlock describes a block of generated code
278 
279 #ifdef COMPILE_H
280 
281 typedef struct _BasicBlock {
282 	struct _BasicBlock  *next;              // pointer to next block
283 
284 	short               label;              // label for this block
285 
286 	struct _BasicBlock  *from[2],           // where we could have come from
287 			       *jumpto,            // where to go if jump
288 			       *fallto;            // where to go if fall through
289 
290 		struct _Statement   *first_st,          // statement list for this bblock
291 			       *last_st;           // it's a circular list
292 
293 		ENode               *test_expr;         // test expression for jump
294 		char                in_flags,           // flags for entering this block
295 		                    jump_type;          // where to go after this block
296 
297 		uint16              start_offset,       // offset in module of this block
298 		                    jump_offset;        // offset of module of jump at end
299 
300 		int16               source_file,        // source line of statement
301 		                    source_line;        // source file of statement
302 	} BasicBlock;
303 
304 //  Various flags for the block
305 
306 #define BBLOCK_CLABEL   (1<<0)              /* bblock begins with a 'C' label */
307 #define BBLOCK_INTLABEL (1<<1)              /* bblock begins with internal label */
308 #define BBLOCK_FIRST    (1<<2)              /* first bblock in the function */
309 #define BBLOCK_MANY     (1<<3)              /* many guys jump to here       */
310 #define BBLOCK_CASE     (1<<4)              /* case stmts might not have 'from' ptr */
311 
312 //  Jump types
313 
314 enum jump_types {
315 	jump_never = 0,                         /* never jump                   */
316 	jump_false,                             /* jump on expression if false  */
317 	jump_true,                              /* jump on expression if true   */
318 	jump_always,                            /* jump always                  */
319 	jump_cjump,                             /* 'c' goto stm, jumpto is a label # */
320 	jump_return,                            /* block ends with a 'return' statement */
321 	jump_switch,                            /* jumps to lots of places      */
322 };
323 #endif
324 /*
325     //  Module describes all the code associated with a particular
326     //  compilation unit.
327 
328 struct Module {
329     uint16              exportCount,        // number of symbols exported
330                         importCount;        // number of symbols imported
331     uint16              exportOffset,       // start of export table
332                         importOffset;       // start of import table
333 
334         // Q: Should ModuleName be somewhere else, like in the main program?
335 
336     uint16              staticSize;         // size of static data
337     uint16              stringOffset;       // unused in this version
338 //  int16               moduleName;         // offset to name of module
339 
340         //  Followed by list of exports
341         //  Followed by list of imports
342         //  Followed by symbol names, each NULL-terminated
343         //  Followed by actual code blocks
344 
345 };
346 
347     //  Exports: Each Export contains the offset to find the name of
348     //  the object. After that is the offset to find the object itself.
349 
350     //  The first Export is always the module entry point
351 
352 struct ModuleExport {                       // an exported symbol
353     uint16              symbolOffset,       // offset in module of symbol name
354                         objectOffset;       // where to find object
355 };
356 
357     //  Imports: Each Import contains the offset to find the name of
358     //  the object. After that is a blank pointer, which will be filled
359     //  in with the real address of the object. When addressing the
360     //  imported object, the code in this module will refer to this
361     //  ModuleImport entry, and indirectly locate the referenced object.
362 
363 struct ModuleImport {                       // a module xref
364     uint16              symbolOffset;       // where, from here, to find name
365     void                *objectPointer;     // NULL pointer, filled in on load
366 };
367 */
368 
369 } // end of namespace Saga2
370 
371 #endif
372