1 //----------------------------------------------------------------------
2 //  COAL LOCAL DEFS
3 //----------------------------------------------------------------------
4 //
5 //  Copyright (C)      2009  Andrew Apted
6 //  Copyright (C) 1996-1997  Id Software, Inc.
7 //
8 //  Coal is free software; you can redistribute it and/or modify
9 //  it under the terms of the GNU General Public License as
10 //  published by the Free Software Foundation; either version 2
11 //  of the License, or (at your option) any later version.
12 //
13 //  Coal is distributed in the hope that it will be useful, but
14 //  WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
16 //  the GNU General Public License for more details.
17 //
18 //----------------------------------------------------------------------
19 //
20 //  Based on QCC (the Quake-C Compiler) and the corresponding
21 //  execution engine from the Quake source code.
22 //
23 //----------------------------------------------------------------------
24 
25 #ifndef __COAL_LOCAL_DEFS_H__
26 #define __COAL_LOCAL_DEFS_H__
27 
28 #include "c_memory.h"
29 
30 typedef unsigned char byte;
31 
32 typedef int	func_t;
33 typedef int	string_t;
34 
35 
36 #define	MAX_NAME	64
37 
38 #define	MAX_PARMS	16
39 
40 
41 typedef enum
42 {
43 	ev_INVALID = -1,
44 
45 	ev_void = 0,
46 	ev_string,
47 	ev_float,
48 	ev_vector,
49 	ev_entity,
50 	ev_field,
51 	ev_function,
52 	ev_module,
53 	ev_pointer
54 }
55 etype_t;
56 
57 
58 typedef struct
59 {
60 	short op;
61 	short line;  // offset from start of function
62 
63 	int a, b, c;
64 }
65 statement_t;
66 
67 
68 enum
69 {
70 	OP_NULL = 0,
71 
72 	OP_CALL,
73 	OP_RET,
74 
75 	OP_PARM_F,
76 	OP_PARM_V,
77 
78 	OP_IF,
79 	OP_IFNOT,
80 	OP_GOTO,
81 	OP_ERROR,
82 
83 	OP_MOVE_F,
84 	OP_MOVE_V,
85 	OP_MOVE_S,
86 	OP_MOVE_FNC,
87 
88 	// ---- mathematical ops from here on --->
89 
90 	OP_NOT_F,
91 	OP_NOT_V,
92 	OP_NOT_S,
93 	OP_NOT_FNC,
94 
95 	OP_INC,
96 	OP_DEC,
97 
98 	OP_POWER_F,
99 	OP_MUL_F,
100 	OP_MUL_V,
101 	OP_MUL_FV,
102 	OP_MUL_VF,
103 
104 	OP_DIV_F,
105 	OP_DIV_V,
106 	OP_MOD_F,
107 
108 	OP_ADD_F,
109 	OP_ADD_V,
110 	OP_ADD_S,
111 	OP_ADD_SF,
112 	OP_ADD_SV,
113 
114 	OP_SUB_F,
115 	OP_SUB_V,
116 
117 	OP_EQ_F,
118 	OP_EQ_V,
119 	OP_EQ_S,
120 	OP_EQ_FNC,
121 
122 	OP_NE_F,
123 	OP_NE_V,
124 	OP_NE_S,
125 	OP_NE_FNC,
126 
127 	OP_LE,
128 	OP_GE,
129 	OP_LT,
130 	OP_GT,
131 
132 	OP_AND,
133 	OP_OR,
134 	OP_BITAND,
135 	OP_BITOR,
136 
137 	NUM_OPERATIONS
138 };
139 
140 
141 typedef struct
142 {
143 	const char *name;
144 
145 	// where it was defined (last)
146 	const char *source_file;
147 	int source_line;
148 
149 	int		return_size;
150 
151 	int		parm_num;
152 	short	parm_ofs[MAX_PARMS];
153 	short	parm_size[MAX_PARMS];
154 
155 	int		locals_ofs;
156 	int		locals_size;
157 	int		locals_end;
158 
159 	int		first_statement;	// negative numbers are builtins
160 	int		last_statement;
161 }
162 function_t;
163 
164 // offset in global data block (if > 0)
165 // when < 0, it is offset into local stack frame
166 typedef int	gofs_t;
167 
168 
169 
170 //=============================================================================
171 
172 
173 #define OFS_NULL		0
174 #define OFS_RETURN		1
175 #define OFS_DEFAULT		4
176 
177 
178 #define REF_OP(ofs)      ((statement_t *)op_mem.deref(ofs))
179 #define REF_GLOBAL(ofs)  ((double *)global_mem.deref(ofs))
180 #define REF_STRING(ofs)  ((ofs)==0 ? "" :   \
181                           (ofs) < 0 ? (char *)temp_strings.deref(-(1+(ofs))) :   \
182                           (char *)string_mem.deref(ofs))
183 
184 #define	G_FLOAT(ofs)    (* REF_GLOBAL(ofs))
185 #define	G_VECTOR(ofs)   REF_GLOBAL(ofs)
186 #define	G_STRING(ofs)   REF_STRING((int) G_FLOAT(ofs))
187 
188 
189 class parse_error_x
190 {
191 public:
192 	int foo;
193 
parse_error_x()194 	 parse_error_x() { }
~parse_error_x()195 	~parse_error_x() { }
196 };
197 
198 
199 
200 class exec_error_x
201 {
202 public:
203 	int foo;
204 
exec_error_x()205 	 exec_error_x() { }
~exec_error_x()206 	~exec_error_x() { }
207 };
208 
209 
210 typedef struct
211 {
212 	const char *name;
213 	native_func_t func;
214 }
215 reg_native_func_t;
216 
217 
218 //============================================================//
219 
220 #include "c_compile.h"
221 #include "c_execute.h"
222 
223 
224 class real_vm_c : public vm_c
225 {
226 public:
227 	/* API functions */
228 
229 	 real_vm_c();
230 	~real_vm_c();
231 
232 	void SetPrinter(print_func_t func);
233 
234 	void AddNativeModule(const char *name);
235 	void AddNativeFunction(const char *name, native_func_t func);
236 
237 	bool CompileFile(char *buffer, const char *filename);
238 	void ShowStats();
239 
240 	void SetAsmDump(bool enable);
241 	void SetTrace  (bool enable);
242 
243 	int FindFunction(const char *name);
244 	int FindVariable(const char *name);
245 
246 	int Execute(int func_id);
247 
248 	double     * AccessParam(int p);
249 	const char * AccessParamString(int p);
250 
251 	void ReturnFloat(double f);
252 	void ReturnVector(double *v);
253 	void ReturnString(const char *s, int len = -1);
254 
255 private:
256 	print_func_t printer;
257 
258 	bmaster_c op_mem;
259 	bmaster_c global_mem;
260 	bmaster_c string_mem;
261 	bmaster_c temp_strings;
262 
263 	std::vector< function_t* > functions;
264 	std::vector< reg_native_func_t* > native_funcs;
265 
266 	compiling_c comp;
267 	execution_c exec;
268 
269 	// c_compile.cc
270 private:
271 	void GLOB_Globals();
272 	void GLOB_Module();
273 	void GLOB_Constant();
274 	void GLOB_Variable();
275 	void GLOB_Function();
276 	int  GLOB_FunctionBody(def_t *func_def, type_t *type, const char *func_name);
277 
278 	void STAT_Statement(bool allow_def);
279 	void STAT_Assignment(def_t *e);
280 	void STAT_If_Else();
281 	void STAT_Assert();
282 	void STAT_WhileLoop();
283 	void STAT_RepeatLoop();
284 	void STAT_ForLoop();
285 	void STAT_Return();
286 
287 	def_t * EXP_Expression(int priority, bool *lvalue = NULL);
288 	def_t * EXP_FieldQuery(def_t *e, bool lvalue);
289 	def_t * EXP_ShortCircuit(def_t *e, int n);
290 	def_t * EXP_Term();
291 	def_t * EXP_VarValue();
292 	def_t * EXP_FunctionCall(def_t *func);
293 	def_t * EXP_Literal();
294 
295 	def_t * DeclareDef(type_t *type, char *name, scope_c *scope);
296 	def_t * FindDef   (type_t *type, char *name, scope_c *scope);
297 
298 	void StoreLiteral(int ofs);
299 	def_t * FindLiteral();
300 
301 	def_t * NewTemporary(type_t *type);
302 	void FreeTemporaries();
303 
304 	def_t * NewGlobal(type_t *type);
305 	def_t * NewLocal(type_t *type);
306 
307 	char *   ParseName();
308 	type_t * ParseType();
309 	type_t * FindType(type_t *type);
310 
311 	int EmitCode(short op, int a=0, int b=0, int c=0);
312 	int EmitMove(type_t *type, int a, int b);
313 
314 
315 	void LEX_Next();
316 	void LEX_Whitespace();
317 	void LEX_NewLine();
318 	void LEX_SkipPastError();
319 
320 	bool LEX_Check (const char *str);
321 	void LEX_Expect(const char *str);
322 
323 	void LEX_String();
324 	float LEX_Number();
325 	void LEX_Vector();
326 	void LEX_Name();
327 	void LEX_Punctuation();
328 
329 	void CompileError(const char *error, ...);
330 
331 
332 	// c_execute.cc
333 private:
334 	void DoExecute(int func_id);
335 
336 	void EnterNative  (int func, int argc);
337 	void EnterFunction(int func);
338 	void LeaveFunction();
339 
340 	int GetNativeFunc(const char *name, const char *module);
341 	int	InternaliseString(const char *new_s);
342 
343 	int STR_Concat(const char * s1, const char * s2);
344 	int STR_ConcatFloat (const char * s, double f);
345 	int STR_ConcatVector(const char * s, double *v);
346 
347 	void RunError(const char *error, ...);
348 
349 	void StackTrace();
350 	void PrintStatement(function_t *f, int s);
351 	const char * RegString(statement_t *st, int who);
352 
353 	void ASM_DumpFunction(function_t *f);
354 	void ASM_DumpAll();
355 
356 	static void default_printer(const char *msg, ...);
357 	static void default_aborter(const char *msg, ...);
358 };
359 
360 
361 #endif /* __COAL_LOCAL_DEFS_H__ */
362 
363 //--- editor settings ---
364 // vi:ts=4:sw=4:noexpandtab
365