1 
2 #include "qcc.h"
3 #include "hash.h"
4 
5 pr_info_t	pr;
6 boolean		pr_system;
7 def_t		*pr_global_defs[MAX_REGS];	// to find def for a global variable
8 int		pr_edict_size;
9 boolean expectint;
10 
11 int shortened_store = 0;
12 char *typenames[] = {"void", "string", "float", "vector", "entity", "field", "function", "pointer", "int", "bad"};
13 
14 
15 //========================================
16 
17 def_t		*pr_scope;		// the function being parsed, or NULL
18 boolean	pr_dumpasm;
19 string_t	s_file;			// filename for function definition
20 
21 int		locals_end;		// for tracking local variables vs temps
22 
23 jmp_buf		pr_parse_abort;		// longjump with this on parse error
24 
25 void PR_ParseDefs (void);
26 void PR_ParseState (void);
27 
28 //========================================
29 
30 opcode_t pr_opcodes[] =
31 {
32  {"<DONE>", OP2_DONE, -1, false, &def_entity, &def_field, &def_void},
33 
34  {"*", OP2_MUL_F, 2, false, &def_float, &def_float, &def_float},
35  {"*", OP2_MUL_V, 2, false, &def_vector, &def_vector, &def_float},
36  {"*", OP2_MUL_FV, 2, false, &def_float, &def_vector, &def_vector},
37  {"*", OP2_MUL_VF, 2, false, &def_vector, &def_float, &def_vector},
38 
39  {"/", OP2_DIV_F, 2, false, &def_float, &def_float, &def_float},
40 
41  {"+", OP2_ADD_F, 3, false, &def_float, &def_float, &def_float},
42  {"+", OP2_ADD_V, 3, false, &def_vector, &def_vector, &def_vector},
43 
44  {"-", OP2_SUB_F, 3, false, &def_float, &def_float, &def_float},
45  {"-", OP2_SUB_V, 3, false, &def_vector, &def_vector, &def_vector},
46 
47  {"==", OP2_EQ_F, 4, false, &def_float, &def_float, &def_float},
48  {"==", OP2_EQ_V, 4, false, &def_vector, &def_vector, &def_float},
49  {"==", OP2_EQ_S, 4, false, &def_string, &def_string, &def_float},
50  {"==", OP2_EQ_E, 4, false, &def_entity, &def_entity, &def_float},
51  {"==", OP2_EQ_FNC, 4, false, &def_function, &def_function, &def_float},
52 
53  {"!=", OP2_NE_F, 4, false, &def_float, &def_float, &def_float},
54  {"!=", OP2_NE_V, 4, false, &def_vector, &def_vector, &def_float},
55  {"!=", OP2_NE_S, 4, false, &def_string, &def_string, &def_float},
56  {"!=", OP2_NE_E, 4, false, &def_entity, &def_entity, &def_float},
57  {"!=", OP2_NE_FNC, 4, false, &def_function, &def_function, &def_float},
58 
59  {"<=", OP2_LE, 4, false, &def_float, &def_float, &def_float},
60  {">=", OP2_GE, 4, false, &def_float, &def_float, &def_float},
61  {"<", OP2_LT, 4, false, &def_float, &def_float, &def_float},
62  {">", OP2_GT, 4, false, &def_float, &def_float, &def_float},
63 
64  {".", OP2_LOAD_F, 1, false, &def_entity, &def_field, &def_float},
65  {".", OP2_LOAD_V, 1, false, &def_entity, &def_field, &def_vector},
66  {".", OP2_LOAD_S, 1, false, &def_entity, &def_field, &def_string},
67  {".", OP2_LOAD_ENT, 1, false, &def_entity, &def_field, &def_entity},
68  {".", OP2_LOAD_FLD, 1, false, &def_entity, &def_field, &def_field},
69  {".", OP2_LOAD_FNC, 1, false, &def_entity, &def_field, &def_function},
70 
71  {".", OP2_ADDRESS, 1, false, &def_entity, &def_field, &def_pointer},
72 
73  {"=", OP2_STORE_F, 5, true, &def_float, &def_float, &def_float},
74  {"=", OP2_STORE_V, 5, true, &def_vector, &def_vector, &def_vector},
75  {"=", OP2_STORE_S, 5, true, &def_string, &def_string, &def_string},
76  {"=", OP2_STORE_ENT, 5, true, &def_entity, &def_entity, &def_entity},
77  {"=", OP2_STORE_FLD, 5, true, &def_field, &def_field, &def_field},
78  {"=", OP2_STORE_FNC, 5, true, &def_function, &def_function, &def_function},
79 
80  {"=", OP2_STOREP_F, 5, true, &def_pointer, &def_float, &def_float},
81  {"=", OP2_STOREP_V, 5, true, &def_pointer, &def_vector, &def_vector},
82  {"=", OP2_STOREP_S, 5, true, &def_pointer, &def_string, &def_string},
83  {"=", OP2_STOREP_ENT, 5, true, &def_pointer, &def_entity, &def_entity},
84  {"=", OP2_STOREP_FLD, 5, true, &def_pointer, &def_field, &def_field},
85  {"=", OP2_STOREP_FNC, 5, true, &def_pointer, &def_function, &def_function},
86 
87  {"<RETURN>", OP2_RETURN, -1, false, &def_void, &def_void, &def_void},
88 
89  {"!", OP2_NOT_F, -1, false, &def_float, &def_void, &def_float},
90  {"!", OP2_NOT_V, -1, false, &def_vector, &def_void, &def_float},
91  {"!", OP2_NOT_S, -1, false, &def_vector, &def_void, &def_float},
92  {"!", OP2_NOT_ENT, -1, false, &def_entity, &def_void, &def_float},
93  {"!", OP2_NOT_FNC, -1, false, &def_function, &def_void, &def_float},
94 
95   {"<IF>", OP2_IF, -1, false, &def_float, &def_float, &def_void},
96   {"<IFNOT>", OP2_IFNOT, -1, false, &def_float, &def_float, &def_void},
97 
98  {"<STATE>", OP2_STATE, -1, false, &def_float, &def_float, &def_void},
99 
100  {"<GOTO>", OP2_GOTO, -1, false, &def_float, &def_void, &def_void},
101  // extra conditional crap FrikaC
102  // I must be nuts :)
103  {"&&", OP2_AND, 6, false, &def_float, &def_float, &def_float},
104  {"&&", OP2_AND, 6, false, &def_entity, &def_float, &def_float},
105  {"&&", OP2_AND, 6, false, &def_float, &def_entity, &def_float},
106  {"&&", OP2_AND, 6, false, &def_entity, &def_entity, &def_float},
107 
108  {"||", OP2_OR, 6, false, &def_float, &def_float, &def_float},
109  {"||", OP2_OR, 6, false, &def_entity, &def_float, &def_float},
110  {"||", OP2_OR, 6, false, &def_float, &def_entity, &def_float},
111  {"||", OP2_OR, 6, false, &def_entity, &def_entity, &def_float},
112 
113  {"&", OP2_BITAND, 2, false, &def_float, &def_float, &def_float},
114 
115  {"|", OP2_BITOR, 2, false, &def_float, &def_float, &def_float},
116 
117  {"[", OP2_LOAD_F, 1, false, &def_void, &def_float, &def_float},
118  {"[", OP2_LOAD_F, 1, false, &def_entity, &def_float, &def_float},
119  {"[", OP2_LOAD_S, 1, false, &def_void, &def_float, &def_string},
120  {"[", OP2_LOAD_ENT, 1, false, &def_void, &def_float, &def_entity},
121  {"[", OP2_ADD_F, 1, false, &def_string, &def_float, &def_string},
122  {"[", OP2_LOAD_V, 1, false, &def_void, &def_float, &def_vector},
123  {"[", OP2_LOAD_FLD, 1, false, &def_void, &def_float, &def_field},
124  {"[", OP2_LOAD_FNC, 1, false, &def_void, &def_float, &def_function},
125 
126  {"+=", OP_ADD_F, 5, true, &def_float, &def_float, &def_float},
127  {"+=", OP_ADD_V, 5, true, &def_vector, &def_vector, &def_vector},
128  {"+=", OP_ADD_F, 5, true, &def_pointer, &def_float, &def_float},
129  {"+=", OP_ADD_V, 5, true, &def_pointer, &def_vector, &def_vector},
130  {"-=", OP_SUB_F, 5, true, &def_float, &def_float, &def_float},
131  {"-=", OP_SUB_V, 5, true, &def_vector, &def_vector, &def_vector},
132  {"-=", OP_SUB_F, 5, true, &def_pointer, &def_float, &def_float},
133  {"-=", OP_SUB_V, 5, true, &def_pointer, &def_vector, &def_vector},
134 
135  {"*=", OP_MUL_F, 5, true, &def_float, &def_float, &def_float},
136  {"*=", OP_MUL_F, 5, true, &def_pointer, &def_float, &def_float},
137 
138  {"/=", OP_DIV_F, 5, true, &def_float, &def_float, &def_float},
139  {"/=", OP_DIV_F, 5, true, &def_pointer, &def_float, &def_float},
140  {"&=", OP_BITAND, 5, true, &def_float, &def_float, &def_float},
141  {"&=", OP_BITAND, 5, true, &def_pointer, &def_float, &def_float},
142  {"|=", OP_BITOR, 5, true, &def_float, &def_float, &def_float},
143  {"|=", OP_BITOR, 5, true, &def_pointer, &def_float, &def_float},
144 
145  {"++", OP2_ADD_F, 1, false, &def_float, &def_float, &def_float},
146  {"--", OP2_SUB_F, 1, false, &def_float, &def_float, &def_float},
147 
148  {NULL}
149 };
150 
151 
152 char *opnames[] =
153 {
154 "<DONE>", "MUL_F", "MUL_V", "MUL_FV", "MUL_VF", "DIV_F", "ADD_F", "ADD_V", "SUB_F",
155  "SUB_V", "EQ_F", "EQ_V", "EQ_S", "EQ_E", "EQ_FNC", "NE_F", "NE_V", "NE_S", "NE_F",
156  "NE_FNC", "LE", "GE", "LT", "GT", "LOAD_F", "LOAD_V", "LOAD_S", "LOAD_ENT", "LOAD_FLD",
157  "LOAD_FNC",
158  "ADDRESS", "STORE_F", "STORE_V", "STORE_S", "STORE_ENT", "STORE_FLD", "STORE_FNC",
159  "STOREP_F", "STOREP_V", "STOREP_S", "STOREP_ENT", "STOREP_FLD", "STOREP_FUNC", "RETURN",
160  "NOT_F", "NOT_V", "NOT_S", "NOT_ENT", "NOT_FNC", "IF", "IFNOT", "CALL0", "CALL1", "CALL2",
161  "CALL3", "CALL4", "CALL5", "CALL6", "CALL7", "CALL8", "STATE", "GOTO", "AND", "OR",
162  "BITAND", "BITOR"
163 };
164 
165 #define	TOP_PRIORITY	6
166 #define	NOT_PRIORITY	4
167 
168 def_t *PR_Expression (int priority, boolean returnused);
169 //===========================================================================
170 
171 
PR_GetType(def_t * def)172 etype_t PR_GetType (def_t *def)
173 {
174 	etype_t type = def->type->type;
175 
176 	if (def->cast)
177 	{
178 		type = def->cast;
179 		def->cast = ev_void;
180 	}
181 	return type;
182 }
183 
184 unsigned char used_temps[MAX_REGS];
185 
GimmeATempFoo(int size)186 def_t *GimmeATempFoo (int size)
187 {
188 	def_t *d;
189 
190 	if (!pr_scope)
191 		PR_ParseError("WTF?! This should be impossible");
192 	//veri tas
193 	if (pr_optimize_recycle)
194 	{
195 		d = pr_scope->tempnext;
196 
197 		while (d)
198 		{
199 			if (!used_temps[d->ofs])
200 			{
201 				if (type_size[d->type->type] == size)
202 				{
203 					num_recycled += size;
204 					return d;
205 				}
206 			}
207 			d = d->tempnext;
208 		}
209 	}
210 
211 	d = (struct def_s *) PR_Malloc (sizeof(def_t));
212 	d->ofs = numpr_globals;
213 	d->tempnext = pr_scope->tempnext;
214 	pr_scope->tempnext = d;
215 	if (pr_optimize_recycle)
216 		locals_end = numpr_globals; // bad
217 	pr_global_defs[numpr_globals] = d;
218 	numpr_globals += size;
219 	return d;
220 }
221 
222 def_t	*PR_ParseImmediate (void);
ConstantArithmetic(opcode_t * op,def_t * var_a,def_t * var_b)223 def_t *ConstantArithmetic (opcode_t *op, def_t *var_a, def_t *var_b)
224 {
225 	def_t *d;
226 	switch(op->op)
227 	{
228 	case OP2_ADD_F:
229 		if (var_a->constant && var_b->constant)
230 		{
231 			pr_immediate_type = &type_float;
232 			pr_immediate._float = G_FLOAT(var_a->ofs) + G_FLOAT(var_b->ofs);
233 			d = PR_ParseImmediate();
234 			HashImmediate();
235 			return d;
236 		}
237 		break;
238 	case OP2_SUB_F:
239 		if (var_a->constant && var_b->constant)
240 		{
241 			pr_immediate_type = &type_float;
242 			pr_immediate._float = G_FLOAT(var_a->ofs) - G_FLOAT(var_b->ofs);
243 			d = PR_ParseImmediate();
244 			HashImmediate();
245 			return d;
246 		}
247 		break;
248 	case OP2_SUB_V:
249 		if (var_a->constant && var_b->constant)
250 		{
251 			pr_immediate_type = &type_vector;
252 			pr_immediate.vector[0] = G_VECTOR(var_a->ofs, 0) - G_VECTOR(var_b->ofs, 0);
253 			pr_immediate.vector[1] = G_VECTOR(var_a->ofs, 1) - G_VECTOR(var_b->ofs, 1);
254 			pr_immediate.vector[2] = G_VECTOR(var_a->ofs, 2) - G_VECTOR(var_b->ofs, 2);
255 			d = PR_ParseImmediate();
256 			HashImmediate();
257 			return d;
258 		}
259 		break;
260 	case OP2_ADD_V:
261 		if (var_a->constant && var_b->constant)
262 		{
263 			pr_immediate_type = &type_vector;
264 			pr_immediate.vector[0] = G_VECTOR(var_a->ofs, 0) + G_VECTOR(var_b->ofs, 0);
265 			pr_immediate.vector[1] = G_VECTOR(var_a->ofs, 1) + G_VECTOR(var_b->ofs, 1);
266 			pr_immediate.vector[2] = G_VECTOR(var_a->ofs, 2) + G_VECTOR(var_b->ofs, 2);
267 			d = PR_ParseImmediate();
268 			HashImmediate();
269 			return d;
270 		}
271 		break;
272 	case OP2_MUL_F:
273 		if (var_a->constant && var_b->constant)
274 		{
275 			pr_immediate_type = &type_float;
276 			pr_immediate._float = G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs);
277 			d = PR_ParseImmediate();
278 			HashImmediate();
279 			return d;
280 		}
281 		break;
282 	case OP2_MUL_V:
283 		if (var_a->constant && var_b->constant)
284 		{
285 			pr_immediate_type = &type_float;
286 
287 			pr_immediate._float = G_VECTOR(var_a->ofs, 0) * G_VECTOR(var_b->ofs, 0)+
288 				G_VECTOR(var_a->ofs, 1) * G_VECTOR(var_b->ofs, 1) +
289 				G_VECTOR(var_a->ofs, 2) * G_VECTOR(var_b->ofs, 2);
290 			d = PR_ParseImmediate();
291 			HashImmediate();
292 			return d;
293 		}
294 		break;
295 
296 	case OP2_MUL_FV:
297 		if (var_a->constant && var_b->constant)
298 		{
299 			pr_immediate_type = &type_vector;
300 			pr_immediate.vector[0] = G_FLOAT(var_a->ofs) * G_VECTOR(var_b->ofs, 0);
301 			pr_immediate.vector[1] = G_FLOAT(var_a->ofs) * G_VECTOR(var_b->ofs, 1);
302 			pr_immediate.vector[2] = G_FLOAT(var_a->ofs) * G_VECTOR(var_b->ofs, 2);
303 			d = PR_ParseImmediate();
304 			HashImmediate();
305 			return d;
306 		}
307 		break;
308 
309 	case OP2_MUL_VF:
310 		if (var_a->constant && var_b->constant)
311 		{
312 			pr_immediate_type = &type_vector;
313 			pr_immediate.vector[0] = G_FLOAT(var_b->ofs) * G_VECTOR(var_a->ofs, 0);
314 			pr_immediate.vector[1] = G_FLOAT(var_b->ofs) * G_VECTOR(var_a->ofs, 1);
315 			pr_immediate.vector[2] = G_FLOAT(var_b->ofs) * G_VECTOR(var_a->ofs, 2);
316 			d = PR_ParseImmediate();
317 			HashImmediate();
318 			return d;
319 		}
320 
321 		break;
322 	case OP2_DIV_F:
323 		if (var_a->constant && var_b->constant)
324 		{
325 			pr_immediate_type = &type_float;
326 			pr_immediate._float = G_FLOAT(var_a->ofs) / G_FLOAT(var_b->ofs);
327 			d = PR_ParseImmediate();
328 			HashImmediate();
329 			return d;
330 		}
331 		break;
332 	case OP2_BITAND:
333 		if (var_a->constant && var_b->constant)
334 		{
335 			pr_immediate_type = &type_float;
336 			pr_immediate._float = G_INT(var_a->ofs) & G_INT(var_b->ofs);
337 			d = PR_ParseImmediate();
338 			HashImmediate();
339 			return d;
340 		}
341 		break;
342 	case OP2_BITOR:
343 		if (var_a->constant && var_b->constant)
344 		{
345 			pr_immediate_type = &type_float;
346 			pr_immediate._float = (int)G_FLOAT(var_a->ofs) | (int)G_FLOAT(var_b->ofs);
347 			d = PR_ParseImmediate();
348 			HashImmediate();
349 			return d;
350 		}
351 		break;
352 	case OP2_GE:
353 		if (var_a->constant && var_b->constant)
354 		{
355 			pr_immediate_type = &type_float;
356 			pr_immediate._float = G_FLOAT(var_a->ofs) >= G_FLOAT(var_b->ofs);
357 			d = PR_ParseImmediate();
358 			HashImmediate();
359 			return d;
360 		}
361 		break;
362 	case OP2_LE:
363 		if (var_a->constant && var_b->constant)
364 		{
365 			pr_immediate_type = &type_float;
366 			pr_immediate._float = G_FLOAT(var_a->ofs) <= G_FLOAT(var_b->ofs);
367 			d = PR_ParseImmediate();
368 			HashImmediate();
369 			return d;
370 		}
371 		break;
372 	case OP2_LT:
373 		if (var_a->constant && var_b->constant)
374 		{
375 			pr_immediate_type = &type_float;
376 			pr_immediate._float = G_FLOAT(var_a->ofs) < G_FLOAT(var_b->ofs);
377 			d = PR_ParseImmediate();
378 			HashImmediate();
379 			return d;
380 		}
381 		break;
382 	case OP2_GT:
383 		if (var_a->constant && var_b->constant)
384 		{
385 			pr_immediate_type = &type_float;
386 			pr_immediate._float = G_FLOAT(var_a->ofs) > G_FLOAT(var_b->ofs);
387 			d = PR_ParseImmediate();
388 			HashImmediate();
389 			return d;
390 		}
391 		break;
392 	case OP2_OR:
393 		if (var_a->constant && var_b->constant)
394 		{
395 			pr_immediate_type = &type_float;
396 			pr_immediate._float = G_FLOAT(var_a->ofs) || G_FLOAT(var_b->ofs);
397 			d = PR_ParseImmediate();
398 			HashImmediate();
399 			return d;
400 		}
401 		break;
402 	case OP2_AND:
403 		if (var_a->constant && var_b->constant)
404 		{
405 			pr_immediate_type = &type_float;
406 			pr_immediate._float = G_FLOAT(var_a->ofs) && G_FLOAT(var_b->ofs);
407 			d = PR_ParseImmediate();
408 			HashImmediate();
409 			return d;
410 		}
411 		break;
412 	case OP2_NOT_F:
413 		if (var_a->constant)
414 		{
415 			pr_immediate_type = &type_float;
416 			pr_immediate._float = !G_FLOAT(var_a->ofs);
417 			d = PR_ParseImmediate();
418 			HashImmediate();
419 			return d;
420 		}
421 		break;
422 	case OP2_NOT_V:
423 		if (var_a->constant)
424 		{
425 			pr_immediate_type = &type_float;
426 			pr_immediate._float = !G_VECTOR(var_a->ofs, 0) && !G_VECTOR(var_a->ofs, 1) && !G_VECTOR(var_a->ofs, 2);
427 			d = PR_ParseImmediate();
428 			HashImmediate();
429 			return d;
430 		}
431 		break;
432 	case OP_EQ_F:
433 		if (var_a->constant && var_b->constant)
434 		{
435 			pr_immediate_type = &type_float;
436 			pr_immediate._float = G_FLOAT(var_a->ofs) == G_FLOAT(var_b->ofs);
437 			d = PR_ParseImmediate();
438 			HashImmediate();
439 			return d;
440 		}
441 		break;
442 	case OP_NE_F:
443 		if (var_a->constant && var_b->constant)
444 		{
445 			pr_immediate_type = &type_float;
446 			pr_immediate._float = G_FLOAT(var_a->ofs) != G_FLOAT(var_b->ofs);
447 			d = PR_ParseImmediate();
448 			HashImmediate();
449 			return d;
450 		}
451 		break;
452 	}
453 	return NULL;
454 }
455 
456 
457 /*
458 ============
459 PR_Statement
460 
461 Emits a primitive statement, returning the var it places it's value in
462 ============
463 */
SimpleStatement(int op,int var_a,int var_b,int var_c)464 dstatement_t *SimpleStatement( int op, int var_a, int var_b, int var_c)
465 {
466 	dstatement_t	*statement;
467 
468 	statement_linenums[numstatements] = pr_source_line;
469 	statement = &statements[numstatements];
470 
471 	numstatements++;
472 	statement->op = op;
473 	statement->a = var_a;
474 	statement->b = var_b;
475 	statement->c = var_c;
476 	return statement;
477 }
478 
PR_Statement(opcode_t * op,def_t * var_a,def_t * var_b)479 def_t *PR_Statement ( opcode_t *op, def_t *var_a, def_t *var_b)
480 {
481 	dstatement_t	*statement, *sprev;
482 	def_t			*var_c;
483 	boolean		templast;
484 
485 	if (var_a)
486 		if (var_a->ofs >= 0)
487 			used_temps[var_a->ofs] = 0;
488 	if (var_b)
489 		if (var_b->ofs >= 0)
490 			used_temps[var_b->ofs] = 0;
491 
492 	templast = false;
493 
494 	if (numstatements)
495 	{
496 		sprev = &statements[numstatements - 1];
497 		if (sprev->c)
498 			if (!pr_global_defs[sprev->c]->name)
499 					templast = true;
500 	}
501 	if (pr_optimize_constant_arithmetic)
502 	{
503 		var_c = ConstantArithmetic(op, var_a, var_b);
504 		if (var_c)
505 		{
506 			num_constant_ops_saved++;
507 			return var_c;
508 		}
509 		if (sprev->op == op->op)
510 		{
511 			var_c = pr_global_defs[sprev->b];
512 			if (var_a && var_b && var_c)
513 			{
514 				if (var_b->constant && var_c->constant)
515 				{
516 					if (sprev->c == var_a->ofs && !var_a->name)
517 					{
518 						var_c = ConstantArithmetic(op, var_c, var_b);
519 						if (var_c)
520 						{
521 							sprev->b = var_c->ofs;
522 							num_constant_ops_saved++;
523 							return pr_global_defs[sprev->c];
524 						}
525 					}
526 				}
527 			}
528 		}
529 	}
530 
531 	statement = SimpleStatement(op->op, var_a ? var_a->ofs : 0, var_b ? var_b->ofs : 0, 0);
532 	shortened_store = 0;
533 
534 	if (op->type_c == &def_void || op->right_associative)
535 	{
536 		var_c = NULL;
537 		statement->c = 0;			// ifs, gotos, and assignments
538 									// don't need vars allocated
539 
540 		if (templast)
541 		{
542 			if (pr_optimize_eliminate_temps && ((unsigned) (statement->op - OP2_STORE_F) < 6) && (statement->a == sprev->c))
543 			{
544 				sprev->c = statement->b;
545 				numstatements--;
546 				num_stores_shortened++;
547 				shortened_store = 1;
548 				return var_b;
549 			}
550 			else if (pr_optimize_shorten_ifs && (statement->op == OP2_IFNOT))
551 			{
552 				if (sprev->op == OP2_NOT_F || sprev->op == OP2_NOT_FNC || sprev->op == OP2_NOT_ENT)
553 				{
554 					sprev->op = OP2_IF;
555 					numstatements--;
556 					num_ifs_shortened++;
557 				}
558 			}
559 			else if (pr_optimize_shorten_ifs && (statement->op == OP2_IF))
560 			{
561 				if (sprev->op == OP2_NOT_F || sprev->op == OP2_NOT_FNC || sprev->op == OP2_NOT_ENT)
562 				{
563 					sprev->op = OP2_IFNOT;
564 					numstatements--;
565 					num_ifs_shortened++;
566 				}
567 			}
568 		}
569 	}
570 	else
571 	{	// allocate result space
572 		var_c = GimmeATempFoo(type_size[op->type_c->type->type]);;
573 		var_c->type = op->type_c->type;
574 		var_c->cast = ev_void;
575 		statement->c = var_c->ofs;
576 
577 		if (var_c)
578 			used_temps[var_c->ofs] = 1;
579 	}
580 
581 
582 	if (op->right_associative)
583 		return var_a;
584 	return var_c;
585 }
586 
587 /*
588 ============
589 PR_GetImmediate
590 
591 Looks for a preexisting constant; return NULL if none exists
592 ============
593 */
PR_GetImmediate(void)594 def_t *PR_GetImmediate (void)
595 {
596 	def_t *cn = NULL;
597 	struct hash_element *cell = NULL;
598 
599 	for (cell = htable[pr_immediate_index]; cell != NULL; cell = cell->next)
600 	{
601 		cn = cell->def;
602 		if (!cn->constant || (cn->type != pr_immediate_type))
603 			continue;
604 		if (pr_immediate_type == &type_string)
605 		{
606 			if (memcmp(G_STRING(cn->ofs), pr_immediate_string, pr_immediate_strlen))
607 				continue;
608 		}
609 		else if (pr_immediate_type == &type_vector)
610 		{
611 			if ((G_FLOAT(cn->ofs) != pr_immediate.vector[0]) || (G_FLOAT(cn->ofs+1) != pr_immediate.vector[1]) || (G_FLOAT(cn->ofs+2) != pr_immediate.vector[2]))
612 				continue;
613 		}
614 		else
615 		{
616 			if (G_INT(cn->ofs) != pr_immediate._int)
617 				continue;
618 		}
619 
620 		return cn;
621 	}
622 	return NULL;
623 }
624 
625 /*
626 ============
627 PR_ParseImmediate
628 
629 Looks for a preexisting constant; allocates a new one if none is found
630 ============
631 */
PR_ParseImmediate(void)632 def_t	*PR_ParseImmediate (void)
633 {
634 	def_t *cn = NULL;
635 	struct hash_element *cell = NULL;
636 
637 	if (cn = PR_GetImmediate())
638 	{
639 		return cn;
640 	}
641 
642 // allocate a new one
643 	cn = (struct def_s *) PR_Malloc (sizeof(def_t));
644 
645 	cn->next = NULL;
646 	pr.def_tail->next = cn;
647 	pr.def_tail = cn;
648 
649 	cell = (struct hash_element *) PR_Malloc (sizeof(struct hash_element));
650 	cell->next = htable[pr_immediate_index];
651 	cell->def = cn;
652 	htable[pr_immediate_index] = cell;
653 	stats[pr_immediate_index]++;
654 
655 	cn->type = pr_immediate_type;
656 	cn->name = "IMMEDIATE";
657 	cn->constant = 1;
658 	cn->defined = 1;
659 	cn->save = 0;
660 	cn->scope = NULL;		// always share immediates
661 	cn->cast = ev_void;
662 
663 // copy the immediate to the global area
664 	cn->ofs = numpr_globals;
665 	pr_global_defs[cn->ofs] = cn;
666 	numpr_globals += type_size[pr_immediate_type->type];
667 	if (pr_immediate_type == &type_string)
668 		pr_immediate.string = CopyString (pr_immediate_string, pr_immediate_strlen);
669 
670 	memcpy (pr_globals + cn->ofs, &pr_immediate, 4*type_size[pr_immediate_type->type]);
671 
672 	return cn;
673 }
674 
PrecacheSound(def_t * e,int ch)675 void PrecacheSound (def_t *e, int ch)
676 {
677 	char	*n;
678 	int		i;
679 
680 	if (!e->ofs)
681 		return;
682 	n = G_STRING(e->ofs);
683 	for (i=0 ; i<numsounds ; i++)
684 		if (!STRCMP(n, precache_sounds[i]))
685 			return;
686 	if (numsounds == MAX_SOUNDS)
687 		Sys_Error("PrecacheSound: numsounds == MAX_SOUNDS");
688 	strcpy (precache_sounds[i], n);
689 	if (ch >= '1'  && ch <= '9')
690 		precache_sounds_block[i] = ch - '0';
691 	else
692 		precache_sounds_block[i] = 1;
693 	numsounds++;
694 }
695 
PrecacheModel(def_t * e,int ch)696 void PrecacheModel (def_t *e, int ch)
697 {
698 	char	*n;
699 	int		i;
700 
701 	if (!e->ofs)
702 		return;
703 	n = G_STRING(e->ofs);
704 	for (i=0 ; i<nummodels ; i++)
705 		if (!STRCMP(n, precache_models[i]))
706 			return;
707 	if (numsounds == MAX_SOUNDS)
708 		Sys_Error("PrecacheModels: numsounds == MAX_SOUNDS");
709 	strcpy (precache_models[i], n);
710 	if (ch >= '1'  && ch <= '9')
711 		precache_models_block[i] = ch - '0';
712 	else
713 		precache_models_block[i] = 1;
714 	nummodels++;
715 }
716 
PrecacheFile(def_t * e,int ch)717 void PrecacheFile (def_t *e, int ch)
718 {
719 	char	*n;
720 	int		i;
721 
722 	if (!e->ofs)
723 		return;
724 	n = G_STRING(e->ofs);
725 	for (i=0 ; i<numfiles ; i++)
726 		if (!STRCMP(n, precache_files[i]))
727 			return;
728 	if (numfiles == MAX_FILES)
729 		Sys_Error("PrecacheFile: numfiles == MAX_FILES");
730 	strcpy (precache_files[i], n);
731 	if (ch >= '1'  && ch <= '9')
732 		precache_files_block[i] = ch - '0';
733 	else
734 		precache_files_block[i] = 1;
735 	numfiles++;
736 }
737 
738 /*
739 ============
740 PR_ParseFunctionCall
741 ============
742 */
743 
744 // more than 8 parms keyword - locutus
745 def_t *extra_parms[MAX_EXTRA_PARMS];
746 
747 def_t *ecorrection;
748 
PR_ParseFunctionCall(def_t * func)749 def_t *PR_ParseFunctionCall (def_t *func)
750 {
751 	def_t		*e, *e2;
752 	int			arg, numtypes, i, returnused = 0;
753 	type_t		*t;
754 	def_t		*parms[MAX_PARMS + MAX_EXTRA_PARMS];
755 
756 	t = func->type;
757 
758 	if (t->type != ev_function)
759 		PR_ParseError ("%s is not a function", t->def->name);
760 
761 // copy the arguments to the global parameter variables
762 	arg = 0;
763 	numtypes = t->num_parms >= 0 ? t->num_parms : -1 - t->num_parms;
764 	if (!PR_Check(")"))
765 	{
766 		do
767 		{
768 			if (t->num_parms >= 0 && arg >= t->num_parms)
769 			{
770 				if (func->name)
771 					PR_ParseWarning (1, "%s: too many parameters, see definition %s(%i)", func->name, func->s_file, func->line);
772 				else
773 					PR_ParseWarning (1, "Indirect function: too many parameters");
774 
775 			}
776 			if (t->num_parms < 0 && arg > MAX_PARMS)
777 				PR_ParseWarning (1, "%s: vararg func cannot have more than %i parms", func->name, MAX_PARMS);
778 
779 			if (!PR_Check("#"))
780 			{
781 				if (t->parm_types[arg])
782 					expectint = t->parm_types[arg]->type == ev_int;
783 				e = PR_Expression (TOP_PRIORITY, returnused);
784 				if (ecorrection)
785 				{
786 					parms[returnused] = ecorrection;
787 					ecorrection = NULL;
788 				}
789 				if (e->ofs == OFS_RETURN)
790 					returnused = arg;
791 
792 				if (arg == 0 && func->name)
793 				{
794 				// save information for model and sound caching
795 					if (!strncmp(func->name,"precache_sound", 14))
796 						PrecacheSound (e, func->name[14]);
797 					else if (!strncmp(func->name,"precache_model", 14))
798 						PrecacheModel (e, func->name[14]);
799 					else if (!strncmp(func->name,"precache_file", 13))
800 						PrecacheFile (e, func->name[13]);
801 				}
802 				if (e->cast)
803 				{
804 					if ((arg < numtypes) && ( e->cast != t->parm_types[arg]->type ) )
805 					{
806 						PR_ParseWarning (1, "%s: type mismatch on parm %i. Expected %s, found %s. See definition %s(%i)",
807 						func->name, arg, typenames[t->parm_types[arg]->type], typenames[e->cast], func->s_file, func->line);
808 					}
809 					e->cast = ev_void;
810 				}
811 				else if ((arg < numtypes) && ( e->type != t->parm_types[arg] ) )
812 				{
813 					PR_ParseWarning (1, "%s: type mismatch on parm %i. Expected %s, found %s. See definition %s(%i)",
814 					func->name, arg, typenames[t->parm_types[arg]->type], typenames[e->type->type], func->s_file, func->line);
815 				}
816 				// a vector copy will copy everything
817 				parms[arg] = e;
818 				if (arg < MAX_PARMS)
819 					def_parms[arg].type = t->parm_types[arg];
820 				else
821 				{
822 					if (!extra_parms[arg - MAX_PARMS])
823 					{
824 						e2 = (struct def_s *) PR_Malloc (sizeof(def_t));
825 						e2->ofs = numpr_globals;
826 						e2->name = "extra parm";
827 						pr_global_defs[numpr_globals] = e2;
828 						numpr_globals += 3;
829 						extra_parms[arg - MAX_PARMS] = e2;
830 					}
831 				}
832 			}
833 			else
834 				parms[arg] = NULL;
835 			arg++;
836 		}
837 		while (PR_Check (","));
838 
839 		PR_Expect (")");
840 	}
841 	// FrikaC store all the parms *NOW*
842 	if (arg > (MAX_PARMS + MAX_EXTRA_PARMS))
843 		PR_ParseError ("%s: more than %i parameters illegal", func->name, MAX_PARMS + MAX_EXTRA_PARMS);
844 	for (i = 0; i < arg; i++)
845 	{
846 		if (!parms[i])
847 			continue;
848 		if (i < MAX_PARMS)
849 		{
850 			if (pr_optimize_nonvec_parms && t->parm_types[i] != &type_vector)
851 			{
852 				PR_Statement (&pr_opcodes[OP_STORE_F], parms[i], &def_parms[i]);
853 				num_nonvec_parms++;
854 			}
855 			else
856 				PR_Statement (&pr_opcodes[OP_STORE_V], parms[i], &def_parms[i]);
857 		}
858 		else
859 		{
860 			if (!extra_parms[i - MAX_PARMS])
861 			{
862 				e2 = (struct def_s *) PR_Malloc (sizeof(def_t));
863 				e2->ofs = numpr_globals;
864 				e2->name = "extra parm";
865 				pr_global_defs[numpr_globals] = e2;
866 				numpr_globals += 3;
867 				extra_parms[i - MAX_PARMS] = e2;
868 			}
869 			if (t->parm_types[i] != &type_vector)
870 				PR_Statement (&pr_opcodes[OP_STORE_F], parms[i], extra_parms[i - MAX_PARMS]);
871 			else
872 				PR_Statement (&pr_opcodes[OP_STORE_V], parms[i], extra_parms[i - MAX_PARMS]);
873 		}
874 	}
875 	if (arg < numtypes)
876 		PR_ParseWarning (1, "%s: Too few parameters. See definition %s(%i)", func->name, func->s_file, func->line);
877 
878 	SimpleStatement (OP2_CALL0+ (arg > MAX_PARMS ? MAX_PARMS : arg), func->ofs, 0, 0);
879 	def_ret.type = t->aux_type;
880 	return &def_ret;
881 }
882 
883 /*
884 ============
885 PR_ParseValue
886 
887 Returns the global ofs for the current token
888 ============
889 */
PR_ParseValue(void)890 def_t	*PR_ParseValue (void)
891 {
892 	def_t		*d;
893 	char		*name;
894 
895 // if the token is an immediate, allocate a constant for it
896 	if (pr_token_type == tt_immediate)
897 	{
898 		 d = PR_ParseImmediate ();
899 		 PR_Lex();
900 		 return d;
901 	}
902 
903 	name = PR_ParseName ();
904 
905 // look through the defs
906 	d = PR_GetDef (NULL, name, pr_scope, false, 0, 0);
907 	if (!d)
908 		PR_ParseError ("Unknown value \"%s\"", name);
909 	return d;
910 }
911 
912 /*
913 ============
914 PR_Cast
915 ============
916 */
PR_Cast(def_t * e,type_t * type)917 def_t *PR_Cast (def_t *e, type_t *type)
918 {
919 	def_t *cast;
920 
921 	cast = (struct def_s *) PR_Malloc (sizeof(def_t));
922 	memcpy (cast, e, sizeof(def_t));
923 	cast->type = type;
924 	return cast;
925 }
926 
927 /*
928 ============
929 PR_Term
930 ============
931 */
PR_Term(void)932 def_t *PR_Term (void)
933 {
934 	def_t	*e, *e2;
935 	etype_t t;
936 	type_t *ty;
937 
938 	if (pr_token_type == tt_punct)
939 	{
940 		if (PR_Check("++"))
941 		{
942 
943 			e = PR_Expression (1, false);
944 			t = PR_GetType(e);
945 			if (t == ev_int)
946 			{
947 				pr_immediate_type = &type_int;
948 				pr_immediate._int = 1;
949 			}
950 			else
951 			{
952 				pr_immediate_type = &type_float;
953 				pr_immediate._float = 1;
954 			}
955 			e2 = PR_ParseImmediate();
956 			HashImmediate();
957 			if (t != ev_float && t != ev_int)
958 				PR_ParseError("Type mismatch for ++, %s not allowed", typenames[t]);
959 			SimpleStatement(pr_opcodes[OP_INC_F].op, e->ofs, e2->ofs, e->ofs);
960 			dontcomplain = true;
961 			return e;
962 		}
963 		if (PR_Check("--"))
964 		{
965 			e = PR_Expression (1, false);
966 			t = PR_GetType(e);
967 			if (t == ev_int)
968 			{
969 				pr_immediate_type = &type_int;
970 				pr_immediate._int = 1;
971 			}
972 			else
973 			{
974 				pr_immediate_type = &type_float;
975 				pr_immediate._float = 1;
976 			}
977 			e2 = PR_ParseImmediate();
978 			HashImmediate();
979 			if (t != ev_float && t != ev_int)
980 				PR_ParseError("Type mismatch for --, %s not allowed", typenames[t]);
981 
982 			SimpleStatement(pr_opcodes[OP_DEC_F].op, e->ofs, e2->ofs, e->ofs);
983 			dontcomplain = true;
984 			return e;
985 		}
986 
987 		if (PR_Check ("!"))
988 		{
989 			e = PR_Expression (NOT_PRIORITY, false);
990 			t = PR_GetType(e);
991 			if (t == ev_float || t == ev_int)
992 				e2 = PR_Statement (&pr_opcodes[OP_NOT_F], e, 0);
993 			else if (t == ev_string)
994 				e2 = PR_Statement (&pr_opcodes[OP_NOT_S], e, 0);
995 			else if (t == ev_entity)
996 				e2 = PR_Statement (&pr_opcodes[OP_NOT_ENT], e, 0);
997 			else if (t == ev_vector)
998 				e2 = PR_Statement (&pr_opcodes[OP_NOT_V], e, 0);
999 			else if (t == ev_function)
1000 				e2 = PR_Statement (&pr_opcodes[OP_NOT_FNC], e, 0);
1001 			else
1002 			{
1003 				e2 = NULL;		// shut up compiler warning;
1004 				PR_ParseError ("type mismatch for ! %s not allowed", typenames[t]);
1005 			}
1006 			return e2;
1007 		}
1008 
1009 
1010 		if (PR_Check("&"))
1011 		{
1012 			e = PR_Expression(1, false);
1013 			t = e->type->type;
1014 			if (t == ev_string || t == ev_field || t == ev_entity || t == ev_function)
1015 				return PR_Cast(e, &type_float);
1016 				//e->cast = ev_float;
1017 			else if ((t == ev_float) || (t== ev_int))
1018 				return PR_Cast(e, &type_pointer);
1019 				//e->cast = ev_pointer;
1020 			else
1021 				PR_ParseError ("bad type for &. %s not allowed", typenames[t]);
1022 			return e;
1023 		}
1024 
1025 		if (PR_Check("*"))
1026 		{
1027 			e = PR_Expression(1, false);
1028 			t = e->type->type;
1029 			if ((t == ev_float) || (t== ev_int))
1030 				return PR_Cast(e, &type_entity);
1031 				//e->cast = ev_entity;
1032 			else
1033 				PR_ParseError ("bad type for *. %s not allowed", typenames[t]);
1034 			return e;
1035 		}
1036 
1037 		if (PR_Check("@"))
1038 		{
1039 			e = PR_Expression(1, false);
1040 			t = e->type->type;
1041 			if ((t == ev_float) || (t== ev_int))
1042 				return PR_Cast(e, &type_string);
1043 				//e->cast = ev_string;
1044 			else
1045 				PR_ParseError ("bad type for @. %s not allowed", typenames[t]);
1046 			return e;
1047 		}
1048 
1049 
1050 		if (PR_Check("("))
1051 		{
1052 			// this ought to slow it down...
1053 			if (!STRCMP("float", pr_token) || !STRCMP("vector", pr_token) || !STRCMP("int", pr_token)
1054 		|| !STRCMP("string", pr_token) || !STRCMP("entity", pr_token) || !STRCMP(".", pr_token) || !STRCMP("void", pr_token))
1055 			{
1056 				ty = PR_ParseType();
1057 				PR_Expect(")");
1058 				e = PR_Expression(1, false);
1059 				return PR_Cast(e, ty);
1060 			}
1061 			e = PR_Expression (TOP_PRIORITY, false);
1062 			PR_Expect (")");
1063 			return e;
1064 		}
1065 	}
1066 	return PR_ParseValue ();
1067 }
1068 
1069 
1070 /*
1071 ==============
1072 PR_Expression
1073 ==============
1074 */
1075 
PR_Expression(int priority,boolean returnused)1076 def_t *PR_Expression (int priority, boolean returnused)
1077 {
1078 	opcode_t	*op, *oldop;
1079 	def_t		*e, *e2, *e3, *e4;
1080 	etype_t		type_a, type_b, type_c;
1081 	dstatement_t		*patch1, *patch2;
1082 	int i;
1083 	int index=0;
1084 
1085 	if (priority == 0)
1086 		return PR_Term ();
1087 
1088 	ecorrection = NULL;
1089 	e = PR_Expression (priority-1, returnused);
1090 	if (e->type->type == ev_int)
1091 		expectint = true;
1092 	e4 = e;
1093 	while (1)
1094 	{
1095 
1096 		if (priority == 1 && PR_Check ("(") )
1097 		{
1098 			dontcomplain = true;
1099 			e3 = NULL;
1100 			if (returnused)
1101 			{
1102 				e3 = GimmeATempFoo(3);
1103 				e3->type = def_ret.type;
1104 				PR_Statement(&pr_opcodes[OP_STORE_V], &def_ret, e3);
1105 			}
1106 			e = PR_ParseFunctionCall (e);
1107 
1108 			if (e3 != NULL)
1109 				ecorrection = e3;
1110 			return e;
1111 		}
1112 				// FrikaC : not good CHEDDAR
1113 		if (pr_token[0] == '?' && !pr_token[1])
1114 		{
1115 			if (priority != 6)
1116 				break;
1117 			PR_Lex();
1118 			PR_Statement(&pr_opcodes[OP_IFNOT], e, 0);
1119 			patch1 = &statements[numstatements - 1];
1120 			e = PR_Expression(TOP_PRIORITY, false);
1121 			if (type_size[e->type->type] == 3)
1122 			{
1123 				e2 = GimmeATempFoo(3);
1124 				PR_Statement (&pr_opcodes[OP_STORE_V], e, e2);
1125 			}
1126 			else
1127 			{
1128 				e2 = GimmeATempFoo(1);
1129 				PR_Statement (&pr_opcodes[OP_STORE_F], e, e2);
1130 			}
1131 			PR_Expect(":");
1132 			patch2 = &statements[numstatements];
1133 			SimpleStatement(OP2_GOTO, 0, 0, 0);
1134 			patch1->b = &statements[numstatements] - patch1;
1135 			e = PR_Expression(TOP_PRIORITY, false);
1136 			if (type_size[e->type->type] == 3)
1137 				PR_Statement (&pr_opcodes[OP_STORE_V], e, e2);
1138 			else
1139 				PR_Statement (&pr_opcodes[OP_STORE_F], e, e2);
1140 			patch2->a = &statements[numstatements] - patch2;
1141 			return e2;
1142 			// ugh!
1143 		}
1144 
1145 
1146 		index = (pr_token[0] + pr_token[1]) & (OPTABLESIZE - 1);
1147 		op = pr_opcodes + optable[index];
1148 		type_c = ev_void;
1149 
1150 		if (op->priority != priority || STRCMP(op->name, pr_token))
1151 			break;
1152 		if ((unsigned)(optable[index] - OP_ARRAY_F) < 7)
1153 			expectint = true;
1154 		PR_Lex();
1155 
1156 		if (pr_optimize_logicops && conditional)
1157 		{
1158 			if (op->op == OP2_AND)
1159 			{
1160 				patch1 = &statements[numstatements];
1161 				SimpleStatement(OP2_IFNOT, e->ofs,0,0);
1162 
1163 			}
1164 			else if (op->op == OP2_OR)
1165 			{
1166 				patch1 = &statements[numstatements];
1167 				SimpleStatement(OP2_IF, e->ofs,0,0);
1168 			}
1169 		}
1170 		else if ( optable[index] >= OP_INC_F )
1171 		{
1172 			if (e->constant)
1173 				PR_ParseWarning(1, "Assignment to constant");
1174 			if (e->type->type != ev_float && e->type->type != ev_int)
1175 				PR_ParseError("Type mismatch for %s", op->name);
1176 			if (e->type->type == ev_int)
1177 			{
1178 				pr_immediate_type = &type_int;
1179 				pr_immediate._int = 1;
1180 				expectint = true;
1181 			}
1182 			else
1183 			{
1184 				pr_immediate_type = &type_float;
1185 				pr_immediate._float = 1;
1186 				expectint = false;
1187 			}
1188 			e2 = PR_ParseImmediate();
1189 			dontcomplain = true;
1190 			SimpleStatement(op->op, e->ofs, e2->ofs, e->ofs);
1191 			return e;
1192 		}
1193 
1194 		if ( op->right_associative )
1195 		{
1196 			// if last statement is an indirect, change it to an address of
1197 			if (!shortened_store && ((unsigned)(statements[numstatements-1].op - OP2_LOAD_F) < 6))
1198 			{
1199 				statements[numstatements-1].op = OP2_ADDRESS;
1200 				if (e->type->arraysize)
1201 				{
1202 					def_pointer.type->aux_type = e->type->aux_type;
1203 					e->type = def_pointer.type;
1204 				}
1205 				else
1206 				{
1207 					def_pointer.type->aux_type = e->type;
1208 					e->type = def_pointer.type;
1209 				}
1210 			}
1211 			e2 = PR_Expression (priority, e->ofs == OFS_RETURN);
1212 			if (ecorrection)
1213 			{
1214 				e = ecorrection;
1215 				ecorrection = NULL;
1216 			}
1217 		}
1218 		else
1219 		{
1220 			if ((unsigned)(optable[index] - OP_ARRAY_F) < 7)
1221 			{
1222 				e2 = PR_Expression (TOP_PRIORITY, e->ofs == OFS_RETURN);
1223 				if (e2->type->type != ev_int)
1224 					PR_ParseWarning(1, "Array index should be type int");
1225 				if (ecorrection)
1226 				{
1227 					e = ecorrection;
1228 					ecorrection = NULL;
1229 				}
1230 				PR_Expect("]");
1231 				if (e->type->arraysize)
1232 					type_c = e->type->aux_type->type;
1233 			}
1234 			else
1235 			{
1236 				e2 = PR_Expression (priority-1, e->ofs == OFS_RETURN);
1237 				if (ecorrection)
1238 				{
1239 					e = ecorrection;
1240 					ecorrection = NULL;
1241 				}
1242 			}
1243 		}
1244 		newop:
1245 		// type check
1246 		type_a = PR_GetType(e);
1247 		type_b = PR_GetType(e2);
1248 
1249 
1250 		// to keep the op count low, we'll lie
1251 
1252 		if ((type_a == ev_int && type_b == ev_float) || (type_a == ev_float && type_b == ev_int))
1253 			PR_ParseWarning(1, "Mixed float and int types");
1254 		if (op->type_a->type->type == ev_float && type_a == ev_float && expectint)
1255 			PR_ParseWarning(1, "Expecting int, float a parameter found");
1256 		if (op->type_b->type->type == ev_float && type_b == ev_float && expectint)
1257 			PR_ParseWarning(1, "Expecting int, floar parameter b found");
1258 
1259 		if (op->name[0] == '.')// field access gets type from field
1260 		{
1261 			if (e2->type->aux_type)
1262 				type_c = e2->type->aux_type->type;
1263 			else
1264 				type_c = ev_bad;	// not a field
1265 		}
1266 
1267 		if (type_a == ev_int)
1268 		{
1269 			type_a = ev_float;
1270 			expectint = true;
1271 		}
1272 		if (type_b == ev_int)
1273 		{
1274 			type_b = ev_float;
1275 			expectint = true;
1276 		}
1277 		if (type_c == ev_int)
1278 			type_c = ev_float; // blarg
1279 
1280 		oldop = op;
1281 		while (type_a != op->type_a->type->type || type_b != op->type_b->type->type || (type_c != ev_void && type_c != op->type_c->type->type) )
1282 		{
1283 			op++;
1284 			if (!op->name || STRCMP(op->name, oldop->name))
1285 				PR_ParseError ("type mismatch for %s. Types %s and %s not allowed", oldop->name, typenames[type_a], typenames[type_b]);
1286 		}
1287 
1288 		if (type_a == ev_pointer && statements[numstatements-1].op == OP2_ADDRESS && type_b != e->type->aux_type->type)
1289 			PR_ParseError ("type mismatch for %s", op->name);
1290 
1291 		if (optable[index] >= OP_ADD_STORE_F)
1292 		{
1293 			dontcomplain = true;
1294 
1295 			if (e->constant)
1296 				PR_ParseWarning(1, "Assignment to constant");
1297 
1298 		//	SimpleStatement(op->op, e->ofs, e2->ofs, e->ofs);
1299 			e = PR_Statement(&pr_opcodes[op->op], e, e2); // hack hack hack
1300 			e2 = e4;
1301 			op = &pr_opcodes[OP_STORE_F];
1302 			index = 0;
1303 			goto newop;
1304 		}
1305 
1306 		if (pr_optimize_logicops && conditional)
1307 		{
1308 			if (op->op == OP2_AND || op->op == OP2_OR)
1309 			{
1310 				patch1->b = &statements[numstatements] - patch1;
1311 				num_logic_jumps++;
1312 			}
1313 		}
1314 
1315 		if (op->right_associative)
1316 		{
1317 			if ((unsigned)(op->op - OP2_STORE_F) < 6)
1318 			{
1319 				if (e->constant)
1320 					PR_ParseWarning(1, "Assignment to constant");
1321 			}
1322 			dontcomplain = true;
1323 			if (conditional)
1324 				PR_ParseWarning(2, "Assignment in conditional");
1325 			e = PR_Statement (op, e2, e);
1326 		}
1327 		else
1328 			e = PR_Statement (op, e, e2);
1329 		if (e4->type->arraysize)
1330 			e->type = e4->type->aux_type;
1331 		else if (type_c != ev_void)	// field access gets type from field
1332 			e->type = e2->type->aux_type;
1333 
1334 		else if (op->type_c->type->type == ev_float && expectint)
1335 			e->type = &type_int;
1336 		if (e->type && e->type->type == ev_int)
1337 			expectint = true;
1338 		else
1339 			expectint = false;
1340 
1341 	}
1342 	expectint = false;
1343 
1344 	return e;
1345 
1346 }
1347 /* ---------------
1348 
1349 FrikaC ---- Label Stuff
1350 
1351 ------------------- */
1352 
1353 int num_continues;
1354 int num_breaks;
1355 int	 pr_continues[32];
1356 int  pr_breaks[32];
1357 
1358 extern int PR_FindDefine (char *name);
1359 
GetLabelDef(char * tname,boolean makenew)1360 int GetLabelDef (char *tname, boolean makenew)
1361 {
1362 	dstatement_t		*curpos;
1363 	int i;
1364 
1365 	curpos = &statements[numstatements];
1366 	i = PR_FindDefine(tname);
1367 
1368 	if (i)
1369 	{
1370 		if(makenew)
1371 		{
1372 			if(pr_defines[i].defined)
1373 				PR_ParseWarning(1, "redifinition of label %s", tname);
1374 			pr_defines[i].defined = true;
1375 			statements[pr_defines[i].value._int].a = curpos
1376 				  - &statements[pr_defines[i].value._int] ;
1377 			pr_defines[i].value._int = numstatements;
1378 			return &statements[pr_defines[i].value._int] - curpos;
1379 		}
1380 		else
1381 		{
1382 			if(pr_defines[i].defined)
1383 				return &statements[pr_defines[i].value._int] - curpos;
1384 		}
1385 	}
1386 	num_defines++;
1387 	pr_defines[num_defines].name = (char *)PR_Malloc(strlen(tname) + 1);
1388 	strcpy(pr_defines[num_defines].name, tname);
1389 	macrohash[hash(tname)] = num_defines;
1390 	pr_defines[num_defines].value._int = numstatements;
1391 	pr_defines[num_defines].label = true;
1392 	if (makenew)
1393 		pr_defines[num_defines].defined = true;
1394 	else
1395 		pr_defines[num_defines].defined = false;
1396 
1397 	return &statements[pr_defines[num_defines].value._int] - curpos;
1398 
1399 }
1400 
1401 
1402 /*
1403 ============
1404 PR_ParseStatement
1405 
1406 ============
1407 */
1408 
PR_ParseStatement(void)1409 void PR_ParseStatement (void)
1410 {
1411 	def_t				*e;
1412 	dstatement_t		*patch1, *patch2, *patch3;
1413 	int					old_numstatements, numtemp;
1414 	dstatement_t		temp[32];
1415 	int					linenum[32];
1416 	int					breaks, continues;
1417 	int i;
1418 
1419 	// FrikaC: clean up temps
1420 	memset(used_temps, 0, sizeof(used_temps));
1421 
1422 	if (PR_Check ("{"))
1423 	{
1424 		while (!PR_Check ("}"))
1425 			PR_ParseStatement ();
1426 		return;
1427 	}
1428 
1429 	if (PR_Check("return"))
1430 	{
1431 		if (PR_Check (";"))
1432 		{
1433 			if(pr_scope->type->aux_type != &type_void)
1434 				PR_ParseWarning(2, "%s must return a value", pr_scope->name);
1435 			PR_Statement (&pr_opcodes[OP_RETURN], 0, 0);
1436 			return;
1437 		}
1438 		e = PR_Expression (TOP_PRIORITY, false);
1439 		PR_Expect (";");
1440 		if(pr_scope->type->aux_type != e->type)
1441 		{
1442 			if (pr_scope->type->aux_type == &type_void)
1443 				PR_ParseWarning(2, "%s does not return a value", pr_scope->name);
1444 			else
1445 			{
1446 				PR_ParseWarning(2, "%s: Type mismatch on return. Expected %s found %s", pr_scope->name,
1447 				typenames[pr_scope->type->aux_type->type], typenames[e->type->type]);
1448 			}
1449 		}
1450 		PR_Statement (&pr_opcodes[OP_RETURN], e, 0);
1451 		return;
1452 	}
1453 
1454 	if (PR_Check("while"))
1455 	{
1456 		PR_Expect ("(");
1457 		patch2 = &statements[numstatements];
1458 		continues = num_continues;
1459 		breaks = num_breaks;
1460 		conditional = true;
1461 		e = PR_Expression (TOP_PRIORITY, false);
1462 		conditional = false;
1463 		PR_Expect (")");
1464 		PR_Statement (&pr_opcodes[OP_IFNOT], e, 0);
1465 		patch1 = &statements[numstatements-1];
1466 		PR_ParseStatement ();
1467 		SimpleStatement(OP2_GOTO, patch2 - &statements[numstatements], 0, 0);
1468 		patch1->b = &statements[numstatements] - patch1;
1469 		if (breaks != num_breaks)
1470 		{
1471 			for(i = breaks; i < num_breaks; i++)
1472 			{
1473 				patch1 = &statements[pr_breaks[i]];
1474 				statements[pr_breaks[i]].a = &statements[numstatements] - patch1;
1475 			}
1476 			num_breaks = breaks;
1477 		}
1478 		if (continues != num_continues)
1479 		{
1480 			for(i = continues; i < num_continues; i++)
1481 			{
1482 				statements[pr_continues[i]].a = patch2 - &statements[pr_continues[i]];
1483 			}
1484 			num_continues = continues;
1485 		}
1486 		return;
1487 	}
1488 	if (PR_Check("for"))
1489 	{
1490 		PR_Expect("(");
1491 		if (!PR_Check(";"))
1492 		{
1493 			PR_Expression(TOP_PRIORITY, false);
1494 			PR_Expect(";");
1495 		}
1496 
1497 		patch2 = &statements[numstatements];
1498 		conditional = true;
1499 		e = PR_Expression(TOP_PRIORITY, false);
1500 		conditional = false;
1501 		PR_Expect(";");
1502 		// I dunno -- do you know?
1503 		continues = num_continues;
1504 		breaks = num_breaks;
1505 
1506 		old_numstatements = numstatements;
1507 		PR_Expression(TOP_PRIORITY, false);
1508 		numtemp = numstatements - old_numstatements;
1509 		if (numtemp > 32)
1510 			PR_ParseError("Update expression too large");
1511 		numstatements = old_numstatements;
1512 		for (i = 0 ; i < numtemp ; i++)
1513 		{
1514 			linenum[i] = statement_linenums[numstatements + i];
1515 			temp[i] = statements[numstatements + i];
1516 		}
1517 
1518 		PR_Expect(")");
1519 		PR_Statement(&pr_opcodes[OP_IFNOT], e, 0);
1520 		patch1 = &statements[numstatements-1];
1521 		PR_ParseStatement();
1522 		patch3 = &statements[numstatements];
1523 		for (i = 0 ; i < numtemp ; i++)
1524 		{
1525 			statement_linenums[numstatements] = linenum[i];
1526 			statements[numstatements++] = temp[i];
1527 		}
1528 		SimpleStatement(OP2_GOTO, patch2 - &statements[numstatements], 0, 0);
1529 		patch1->b = &statements[numstatements] - patch1;
1530 		if (breaks != num_breaks)
1531 		{
1532 			for(i = breaks; i < num_breaks; i++)
1533 			{
1534 				patch1 = &statements[pr_breaks[i]];
1535 				statements[pr_breaks[i]].a = &statements[numstatements] - patch1;
1536 			}
1537 			num_breaks = breaks;
1538 		}
1539 		if (continues != num_continues)
1540 		{
1541 			for(i = continues; i < num_continues; i++)
1542 			{
1543 				patch1 = &statements[pr_continues[i]];
1544 				statements[pr_continues[i]].a = patch3 - patch1;
1545 			}
1546 			num_continues = continues;
1547 		}
1548 		return;
1549 	}
1550 	if (PR_Check("do"))
1551 	{
1552 		patch1 = &statements[numstatements];
1553 		continues = num_continues;
1554 		breaks = num_breaks;
1555 		PR_ParseStatement ();
1556 		PR_Expect ("while");
1557 		PR_Expect ("(");
1558 		conditional = true;
1559 		e = PR_Expression (TOP_PRIORITY, false);
1560 		conditional = false;
1561 		PR_Expect (")");
1562 		PR_Expect (";");
1563 		PR_Statement (&pr_opcodes[OP_IF], e, 0);
1564 		patch2 = &statements[numstatements - 1];
1565 		patch2->b = patch1 - patch2;
1566 
1567 		// God I mucked a lot of stuff up...
1568 		if (breaks != num_breaks)
1569 		{
1570 			for(i = breaks; i < num_breaks; i++)
1571 			{
1572 				patch2 = &statements[pr_breaks[i]];
1573 				statements[pr_breaks[i]].a = &statements[numstatements] - patch2;
1574 			}
1575 			num_breaks = breaks;
1576 		}
1577 		if (continues != num_continues)
1578 		{
1579 			for(i = continues; i < num_continues; i++)
1580 			{
1581 				patch2 = &statements[pr_continues[i]];
1582 				statements[pr_continues[i]].a = patch1 - patch2;
1583 			}
1584 			num_continues = continues;
1585 		}
1586 		return;
1587 	}
1588 
1589 	if (PR_Check("local"))
1590 	{
1591 
1592 		PR_ParseDefs ();
1593 		locals_end = numpr_globals;
1594 		return;
1595 	}
1596 
1597 	if (PR_Check("goto"))
1598 	{
1599 		//PR_Lex();
1600 		if (pr_token_type != tt_name)
1601 		{
1602 			PR_ParseError("invalid label name \"%s\"", pr_token);
1603 			return;
1604 		}
1605 		SimpleStatement(OP2_GOTO, GetLabelDef(pr_token, false), 0, 0);
1606 		PR_Lex();
1607 		PR_Expect(";");
1608 		return;
1609 	}
1610 	if (PR_Check("state"))
1611 	{
1612 		PR_Expect("[");
1613 		PR_ParseState();
1614 		PR_Expect(";");
1615 		return;
1616 	}
1617 	if (PR_Check(":")) //labels
1618 	{
1619 		if (pr_token_type != tt_name)
1620 		{
1621 			PR_ParseError("invalid label name \"%s\"", pr_token);
1622 			return;
1623 		}
1624 		GetLabelDef(pr_token, true);
1625 		PR_Lex();
1626 		return;
1627 	}
1628 
1629 	if (PR_Check("if"))
1630 	{
1631 		PR_Expect ("(");
1632 		conditional = true;
1633 		e = PR_Expression (TOP_PRIORITY, false);
1634 		conditional = false;
1635 		PR_Expect (")");
1636 
1637 		PR_Statement (&pr_opcodes[OP_IFNOT], e, 0);
1638 		patch1 = &statements[numstatements-1];
1639 
1640 		PR_ParseStatement ();
1641 
1642 		if (PR_Check ("else"))
1643 		{
1644 			patch2 = &statements[numstatements];
1645 			if((&statements[numstatements] - patch1) == 1)
1646 				PR_ParseWarning(1, "Null 'if' statement");
1647 			PR_Statement (&pr_opcodes[OP_GOTO], 0, 0);
1648 			patch1->b = &statements[numstatements] - patch1;
1649 			PR_ParseStatement ();
1650 			patch2->a = &statements[numstatements] - patch2;
1651 			if((&statements[numstatements] - patch2) == 1)
1652 				PR_ParseWarning(1, "Null 'else' statement");
1653 
1654 		}
1655 		else
1656 		{
1657 			if((&statements[numstatements] - patch1) == 1)
1658 				PR_ParseWarning(1, "Null 'if' statement");
1659 
1660 			patch1->b = &statements[numstatements] - patch1;
1661 		}
1662 		return;
1663 	}
1664 	if (PR_Check("break"))
1665 	{
1666 		if (num_breaks > 32)
1667 			PR_ParseError("Cannot have more than 32 breaks in a loop");
1668 		pr_breaks[num_breaks] = numstatements;
1669 		PR_Statement (&pr_opcodes[OP_GOTO], 0, 0);
1670 		num_breaks++;
1671 		PR_Expect(";");
1672 		return;
1673 	}
1674 	if (PR_Check("continue"))
1675 	{
1676 		if (num_continues > 32)
1677 			PR_ParseError("Cannot have more than 32 continues in a loop");
1678 		pr_continues[num_continues] = numstatements;
1679 		PR_Statement (&pr_opcodes[OP_GOTO], 0, 0);
1680 		num_continues++;
1681 		PR_Expect(";");
1682 		return;
1683 	}
1684 	//FrikaC begin
1685 
1686 
1687 	if (!STRCMP("float", pr_token) || !STRCMP("vector", pr_token) || !STRCMP("int", pr_token)
1688 		|| !STRCMP("string", pr_token) || !STRCMP("entity", pr_token) || !STRCMP("const", pr_token) || !STRCMP("var", pr_token))
1689 	{
1690 
1691 		PR_ParseDefs ();
1692 		locals_end = numpr_globals;
1693 		return;
1694 	}
1695 
1696 	// FrikaC end
1697 	dontcomplain = false;
1698 	e = PR_Expression (TOP_PRIORITY, false);
1699 	if ((e->type->type != ev_void) && !dontcomplain)
1700 		PR_ParseWarning(2, "No operation performed");
1701 	PR_Expect (";");
1702 }
1703 
1704 
1705 /*
1706 ==============
1707 PR_ParseState
1708 
1709 States are special functions made for convenience.  They automatically
1710 set frame, nextthink (implicitly), and think (allowing forward definitions).
1711 
1712 // void() name = [framenum, nextthink] {code}
1713 // expands to:
1714 // function void name ()
1715 // {
1716 //		self.frame=framenum;
1717 //		self.nextthink = time + 0.1;
1718 //		self.think = nextthink
1719 //		<code>
1720 // };
1721 ==============
1722 */
PR_ParseState(void)1723 void PR_ParseState (void)
1724 {
1725 	char	*name;
1726 	def_t	*s1, *def;
1727 
1728 	if (pr_token_type != tt_immediate || pr_immediate_type != &type_float)
1729 		PR_ParseError ("state frame must be a number");
1730 	s1 = PR_ParseImmediate ();
1731 	PR_Lex();
1732 	PR_Expect (",");
1733 
1734 	name = PR_ParseName ();
1735 	def = PR_GetDef (&type_function, name,0, true, 1, 0);
1736 
1737 	PR_Expect ("]");
1738 
1739 	PR_Statement (&pr_opcodes[OP_STATE], s1, def);
1740 }
1741 
1742 /*
1743 ============
1744 PR_ParseImmediateStatements
1745 
1746 Parse a function body
1747 ============
1748 */
PR_ParseImmediateStatements(type_t * type)1749 function_t *PR_ParseImmediateStatements (type_t *type)
1750 {
1751 	int			i;
1752 	function_t	*f;
1753 	def_t		*defs[MAX_PARMS + MAX_EXTRA_PARMS];
1754 	def_t		*e2;
1755 	f = (struct function_s *) PR_Malloc (sizeof(function_t));
1756 
1757 //
1758 // check for builtin function definition #1, #2, etc
1759 //
1760 	if (PR_Check ("#"))
1761 	{
1762 		if (pr_token_type != tt_immediate || pr_immediate_type != &type_float || pr_immediate._float != (int)pr_immediate._float)
1763 			PR_ParseError("Bad builtin immediate");
1764 		f->builtin = (int) pr_immediate._float;
1765 		PR_Lex();
1766 		return f;
1767 	}
1768 
1769 	f->builtin = 0;
1770 //
1771 // define the parms
1772 //
1773 	for (i=0 ; i<type->num_parms ; i++)
1774 	{
1775 		defs[i] = PR_GetDef (type->parm_types[i], pr_parm_names[i], pr_scope, true, -1, -1);
1776 		if (i > MAX_PARMS)
1777 			continue;
1778 		f->parm_ofs[i] = defs[i]->ofs;
1779 		if (i > 0 && f->parm_ofs[i] < f->parm_ofs[i-1])
1780 			Sys_Error("bad parm order");
1781 	}
1782 
1783 	f->code = numstatements;
1784 	if (type->num_parms > MAX_PARMS) // locutus
1785 	{
1786 		for (i = MAX_PARMS; i < type->num_parms; i++)
1787 		{
1788 			if (!extra_parms[i - MAX_PARMS])
1789 			{
1790 				e2 = (struct def_s *) PR_Malloc (sizeof(def_t));
1791 				e2->ofs = numpr_globals;
1792 				e2->name = "extra parm";
1793 				pr_global_defs[numpr_globals] = e2;
1794 				numpr_globals += 3;
1795 				extra_parms[i - MAX_PARMS] = e2;
1796 			}
1797 			if (defs[i]->type->type != ev_vector)
1798 				PR_Statement (&pr_opcodes[OP_STORE_F], extra_parms[i - MAX_PARMS], defs[i]);
1799 			else
1800 				PR_Statement (&pr_opcodes[OP_STORE_V], extra_parms[i - MAX_PARMS], defs[i]);
1801 		}
1802 	}
1803 //
1804 // check for a state opcode
1805 //
1806 	if (PR_Check ("["))
1807 		PR_ParseState ();
1808 
1809 //
1810 // parse regular statements
1811 //
1812 	PR_Expect ("{");
1813 
1814 	while (!PR_Check("}"))
1815 		PR_ParseStatement ();
1816 	// this is cheap
1817 	if (type->aux_type != &type_void)
1818 		if (statements[numstatements - 1].op != OP2_RETURN)
1819 			PR_ParseWarning(2, "%s: not all control paths return a value", pr_scope->name );
1820 // emit an end of statements opcode
1821 	PR_Statement (pr_opcodes, 0,0);
1822 
1823 
1824 	return f;
1825 }
1826 
1827 
PR_DefineElements(def_t * def,int save)1828 int PR_DefineElements(def_t *def, int save)
1829 {
1830 	def_t	*elem;
1831 	int i, flag = true, start;
1832 	char element[MAX_NAME];
1833 	if (!def->constant)
1834 		def->defined = true;
1835 
1836 	start = numpr_globals;
1837 	for (i = 0; i < def->type->arraysize; i++)
1838 	{
1839 		sprintf(element, "%s_%i", def->name, i);
1840 
1841 		if (def->type->aux_type->arraysize)
1842 		{
1843 			elem = PR_GetDef(def->type->aux_type, element, def->scope, false, -1, save);
1844 			if (elem)
1845 			{
1846 				flag = PR_DefineElements(elem, save);
1847 				start = def->arraystart;
1848 			}
1849 			else
1850 			{
1851 				elem = PR_GetDef(&type_void, element, def->scope, true, -1, save);
1852 				elem->type = def->type->aux_type;
1853 				elem->constant = true;
1854 				elem->defined = true;
1855 				elem->save = false;
1856 				flag = false;
1857 			}
1858 		}
1859 		else
1860 			elem = PR_GetDef(def->type->aux_type, element, def->scope, true, -1, save);
1861 		elem->defined = true;
1862 	}
1863 	def->arraystart = start;
1864 	return flag;
1865 }
PR_GetArray(def_t * def,int save)1866 void PR_GetArray (def_t *def, int save)
1867 {
1868 	while(!PR_DefineElements(def, save));
1869 };
1870 
1871 /*
1872 ============
1873 PR_GetDef
1874 
1875 If type is NULL, it will match any type
1876 If allocate is true, a new def will be allocated if it can't be found
1877 ============
1878 */
1879 
PR_GetDef(type_t * type,char * name,def_t * scope,boolean allocate,int constant,int save)1880 def_t *PR_GetDef (type_t *type, char *name, def_t *scope, boolean allocate, int constant, int save)
1881 {
1882 	def_t	*def, *elem;
1883 	char element[MAX_NAME];
1884 
1885 	int index, i, m;
1886 	struct hash_element *cell;
1887 
1888 	index = hash(name);
1889 	for (cell = htable[index]; cell != NULL; cell = cell->next)
1890 	{
1891 		def = cell->def;
1892 		if ( !STRCMP(def->name, name) )
1893 		{
1894 			if (def->scope && (def->scope != scope))
1895 			{
1896 				if (!scope && allocate)
1897 					PR_ParseWarning(3, "%s defined as local in %s", def->name, def->scope->name);
1898 				continue;
1899 			}
1900 			if (type && def->type->type != type->type)
1901 			{
1902 
1903 				if (scope == def->scope)
1904 					PR_ParseError ("Type mismatch on redeclaration of %s (see original definition %s(%i))", name, def->s_file, def->line);
1905 				else
1906 				{
1907 					PR_ParseWarning(2, "%s redeclared on different scope (see original definition %s(%i))", name, def->s_file, def->line);
1908 					continue;
1909 				}
1910 			}
1911 			else if (type && (def->type->type == ev_field))
1912 			{
1913 				if (type->aux_type->type != def->type->aux_type->type)
1914 				{
1915 					if (scope == def->scope)
1916 						PR_ParseWarning (1, "Type mismatch on redeclaration of %s (see original definition %s(%i))", name, def->s_file, def->line);
1917 					else
1918 					{
1919 						PR_ParseWarning(2, "%s redeclared on different scope (see original definition %s(%i))", name, def->s_file, def->line);
1920 						continue;
1921 					}
1922 				}
1923 			}
1924 			else if (type && (def->type->type == ev_function))
1925 			{
1926 				if (type->aux_type->type != def->type->aux_type->type)
1927 						PR_ParseWarning (1, "Type mismatch on redeclaration of %s (see original definition %s(%i))", name, def->s_file, def->line);
1928 				else if (type->num_parms != def->type->num_parms)
1929 						PR_ParseWarning (1, "%s redeclared with different number of parms (see original definition %s(%i))", name, def->s_file, def->line);
1930 				else
1931 				{
1932 					for (i = 0; i < type->num_parms; i++)
1933 						if (type->parm_types[i]->type != def->type->parm_types[i]->type)
1934 							PR_ParseWarning (1, "%s rededeclared with different parms (see original definition %s(%i))", name, def->s_file, def->line);
1935 				}
1936 			}
1937 			if (scope && allocate)
1938 				PR_ParseWarning(1, "%s redeclared", name);
1939 
1940  			pr_global_refs[def->ofs]++;
1941 			return def;
1942 		}
1943 	}
1944 
1945 	if (!allocate)
1946 		return NULL;
1947 
1948 
1949 // allocate a new def
1950 	def = (struct def_s *) PR_Malloc (sizeof(def_t));
1951 	def->next = NULL;
1952 	pr.def_tail->next = def;
1953 	pr.def_tail = def;
1954 
1955 	cell = (struct hash_element *) PR_Malloc (sizeof(struct hash_element));
1956 	cell->next = htable[index];
1957 	cell->def = def;
1958 	htable[index] = cell;
1959 	stats[index]++;
1960 
1961 	def->name = (char *) PR_Malloc(strlen(name)+1);
1962 	strcpy(def->name, name);
1963 	def->type = type;
1964 
1965 
1966 	if (constant == 1)
1967 		def->constant = 1;
1968 	else if (constant == -1)
1969 		def->constant = 0;
1970 	else if (type->arraysize)
1971 		def->constant = 0;
1972 	else if (scope)
1973 		def->constant = 0;
1974 	else if ((type->type == ev_field) || (type->type == ev_function))
1975 		def->constant = 1;
1976 	else
1977 		def->constant = 0;
1978 
1979 	if (save == 1)
1980 		def->save = 1;
1981 	else if (save == -1)
1982 		def->save = 0;
1983 	else if (scope)
1984 		def->save = 0;
1985 	else if ((type->type == ev_field) && (def->constant == 1))
1986 		def->save = 1;
1987 	else if (def->constant)
1988 		def->save = 0;
1989 	else
1990 		def->save = 1;
1991 
1992 	def->s_file = s_file + strings;
1993 	def->line = pr_source_line;
1994 	def->scope = scope;
1995 	def->tempnext = NULL;
1996 
1997 	def->ofs = numpr_globals;
1998 	pr_global_defs[numpr_globals] = def;
1999 
2000 	if (!pr_system) // pr_sytem == true means system defs are done
2001 		pr_global_refs[numpr_globals] = 1;
2002 	if(!STRCMP(def->name, "end_sys_fields"))
2003 		pr_system = true;
2004 //
2005 // make automatic defs for the vectors elements
2006 // .origin can be accessed as .origin_x, .origin_y, and .origin_z
2007 //
2008 	if (type->type == ev_vector)
2009 	{
2010 		sprintf (element, "%s_x",name);
2011 		elem = PR_GetDef (&type_float, element, scope, true, constant, save);
2012 		elem->defined = true; // hack
2013 		pr_global_refs[numpr_globals]++;// FrikaC
2014 
2015 		sprintf (element, "%s_y",name);
2016 		elem = PR_GetDef (&type_float, element, scope, true, constant, save);
2017 		elem->defined = true;
2018 		pr_global_refs[numpr_globals]++;// FrikaC
2019 
2020 		sprintf (element, "%s_z",name);
2021 		elem = PR_GetDef (&type_float, element, scope, true, constant, save);
2022 		elem->defined = true;
2023 		pr_global_refs[numpr_globals]++;// FrikaC
2024 
2025 	}
2026 	else
2027 		numpr_globals += type_size[type->type];
2028 
2029 	if ((type->type == ev_field) && def->constant)
2030 	{
2031 		*(int *)&pr_globals[def->ofs] = pr.size_fields;
2032 		def->defined = true;
2033 
2034 		if (type->aux_type->type == ev_vector)
2035 		{
2036 			sprintf (element, "%s_x",name);
2037 			PR_GetDef (&type_floatfield, element, scope, true, constant, save);
2038 
2039 			sprintf (element, "%s_y",name);
2040 			PR_GetDef (&type_floatfield, element, scope, true, constant, save);
2041 
2042 			sprintf (element, "%s_z",name);
2043 			PR_GetDef (&type_floatfield, element, scope, true, constant, save);
2044 		}
2045 		else
2046 			pr.size_fields += type_size[type->aux_type->type];
2047 	}
2048 	else if (type->arraysize)
2049 		PR_GetArray(def, save);
2050 //	if (pr_dumpasm)
2051 //		PR_PrintOfs (def->ofs);
2052 
2053 	return def;
2054 }
2055 
2056 /*
2057 ================
2058 PR_ParseDefs
2059 
2060 Called at the outer layer and when a local statement is hit
2061 ================
2062 */
2063 int constmode = 0;
2064 
PR_ParseDefs(void)2065 void PR_ParseDefs (void)
2066 {
2067 	char		*name;
2068 	type_t		*type, *check;
2069 	def_t		*def, *odef;
2070 	function_t	*f;
2071 	dfunction_t	*df;
2072 	int			i, size;
2073 	int			locals_start, test;
2074 	int constant = 0;
2075 	int save = 0;
2076 	static char	ident[MAX_NAME];
2077 
2078 	struct hash_element *cell = NULL;
2079 	if (PR_Check("nosave"))
2080 		save = -1;
2081 	if (PR_Check("var"))
2082 		constant = -1;
2083 	else if (PR_Check("const"))
2084 	{
2085 		constmode = 1;
2086 		constant = 1;
2087 	}
2088 	else if (constmode)
2089 		constant = -1;
2090 
2091 	type = PR_ParseType ();
2092 
2093 	do
2094 	{
2095 		strcpy(ident, PR_ParseName());
2096 
2097 		if (PR_Check("(") && type->type != ev_function)
2098 		{
2099 			// HexenC/C/C++ style function declaration
2100 			type = PR_ParseTypeFunction(type);
2101 		}
2102 		if (!STRCMP(pr_token, "="))
2103 		{
2104 			if (constant == 0)
2105 				constant = 1;
2106 			if (type->type == ev_int)
2107 				expectint = true;
2108 		}
2109 		def = PR_GetDef (type, ident, pr_scope, true, constant, save);
2110 // check for an initialization
2111 		if ( PR_Check ("=") || ((type->type == ev_function) && (pr_token[0] == '{')))
2112 		{
2113 
2114 			if (def->defined)
2115 				PR_ParseError ("%s redeclared (see previous declaration %s(%i))", ident, def->s_file, def->line);
2116 
2117 			def->s_file = s_file + strings;
2118 			def->line = pr_source_line;
2119 			def->defined = true;
2120 
2121 			if (type->type == ev_function)
2122 			{
2123 				locals_start = locals_end = numpr_globals;
2124 				pr_scope = def;
2125 				test = numstatements;
2126 				f = PR_ParseImmediateStatements (type);
2127 				pr_scope = NULL;
2128 				G_FUNCTION(def->ofs) = numfunctions;
2129 				f->def = def;
2130 //				if (pr_dumpasm)
2131 //					PR_PrintFunction (def);
2132 
2133 		// fill in the dfunction
2134 				df = &functions[numfunctions];
2135 				numfunctions++;
2136 				if (f->builtin)
2137 				{
2138 					if (pr_optimize_function_names)
2139 						df->s_name = f->def->name - strings;
2140 					else
2141 						df->s_name = CopyString (f->def->name, 0);
2142 					num_funcs_saved += strlen(f->def->name) + 1;
2143 					df->first_statement = -f->builtin;
2144 				}
2145 				else
2146 				{
2147 					df->s_name = CopyString (f->def->name, 0);
2148 					df->first_statement = f->code;
2149 				}
2150 
2151 				df->s_file = s_file;
2152 				df->numparms =  f->def->type->num_parms;
2153 				for (i = 0 ; i < df->numparms ; i++)
2154 					df->parm_size[i] = type_size[f->def->type->parm_types[i]->type];
2155 
2156 				if (warninglevel >= 3)
2157 				for(i = locals_end; i >= locals_start; i--)
2158 				{
2159 					if (pr_global_defs[i])
2160 					{
2161 						if (pr_global_defs[i]->scope == def)
2162 						{
2163 							if (pr_global_refs[i] == 0)
2164 							{
2165 								PR_ParseWarning(3, "Unreferenced local variable %s", pr_global_defs[i]->name);
2166 							}
2167 							else if (pr_global_defs[i]->type->type == ev_vector)
2168 							{
2169 								// vector types are weird..
2170 								if (pr_global_refs[i] + pr_global_refs[i+1] + pr_global_refs[i+2] == 3)
2171 									PR_ParseWarning(3, "Unreferenced local variable %s", pr_global_defs[i]->name);
2172 							}
2173 						}
2174 					}
2175 				}
2176 				df->locals = locals_end - locals_start;
2177 				df->parm_start = locals_start;
2178 				if (num_breaks != 0)
2179 				{
2180 					num_breaks = 0;//shup up compiler
2181 					PR_ParseError("Illegal break in function %s", strings + df->s_name);
2182 				}
2183 				if (num_continues != 0)
2184 				{
2185 					num_continues = 0;
2186 					PR_ParseError("Illegal continue in function %s", strings + df->s_name);
2187 				}
2188 
2189 
2190 				continue;
2191 			}
2192 			else if (type->arraysize)
2193 			{
2194 				i = 1;
2195 				check = type->aux_type;
2196 				while(check->arraysize)
2197 				{
2198 					i *= check->arraysize;
2199 					check = check->aux_type;
2200 				}
2201 				size = i * def->type->arraysize + def->arraystart;
2202 				if (i == 1)
2203 					i = def->arraystart;
2204 				else
2205 					i += def->arraystart;
2206 				if (pr_immediate_type != check)
2207 					PR_ParseError ("Wrong immediate type for %s, Expected %s found %s", ident, typenames[check->type], typenames[pr_immediate_type->type]);
2208 			}
2209 			else if (pr_immediate_type != type)
2210 				PR_ParseError ("Wrong immediate type for %s, Expected %s found %s", ident, typenames[type->type], typenames[pr_immediate_type->type]);
2211 			if (type->arraysize)
2212 			{
2213 
2214 				do
2215 				{
2216 					if (pr_token_type != tt_name)
2217 						if (pr_immediate_type == &type_string)
2218 							pr_immediate.string = CopyString (pr_immediate_string, pr_immediate_strlen);
2219 					memcpy (&(pr_globals[i]), &pr_immediate, 4*type_size[pr_immediate_type->type]);
2220 					PR_Lex();
2221 					i+=type_size[pr_immediate_type->type];
2222 					if (i > size)
2223 						PR_ParseWarning(1, "%s: too many initializers", def->name);
2224 				}
2225 				while (PR_Check(","));
2226 
2227 			}
2228 			else if (pr_optimize_defs && (odef = PR_GetImmediate()))
2229 			{
2230 				PR_GetImmediate();
2231 				if (def->ofs == numpr_globals - 1)
2232 				{
2233 					numpr_globals--;
2234 					def->ofs = odef->ofs;
2235 					num_defs += 1;
2236 
2237 				}
2238 				else
2239 				{
2240 					memcpy (pr_globals + def->ofs, pr_globals + odef->ofs, 4*type_size[pr_immediate_type->type]);
2241 				}
2242 			}
2243 			else
2244 			{
2245 				cell = (struct hash_element *) PR_Malloc (sizeof(struct hash_element));
2246 				cell->next = htable[pr_immediate_index];
2247 				cell->def = def;
2248 				htable[pr_immediate_index] = cell;
2249 				stats[pr_immediate_index]++;
2250 				if (pr_token_type != tt_name)
2251 					if (pr_immediate_type == &type_string)
2252 						pr_immediate.string = CopyString (pr_immediate_string, pr_immediate_strlen);
2253 
2254 				memcpy (pr_globals + def->ofs, &pr_immediate, 4*type_size[pr_immediate_type->type]);
2255 			}
2256 			PR_Lex ();
2257 		}
2258 		def->s_file = s_file + strings;
2259 		def->line = pr_source_line;
2260 		expectint = false;
2261 
2262 	} while (PR_Check (","));
2263 
2264 //	PR_Expect (";");
2265 	PR_Check(";");
2266 
2267 
2268 }
2269 
2270 /*
2271 ============
2272 PR_CompileFile
2273 
2274 compiles the 0 terminated text, adding defintions to the pr structure
2275 ============
2276 */
2277 
2278 
PR_CompileFile(char * string,char * filename)2279 boolean	PR_CompileFile (char *string, char *filename)
2280 {
2281 	char *k;
2282 	if (!pr.memory)
2283 		Sys_Error("PR_CompileFile: Didn't clear");
2284 
2285 	PR_ClearGrabMacros ();	// clear the frame macros
2286 	pr_file_p = string;
2287 	if (pr_optimize_filenames)
2288 	{
2289 		k = (char *)PR_Malloc(strlen(filename) + 1);
2290 		strcpy(k, filename);
2291 		s_file = k - strings;
2292 		num_files_saved += strlen(filename) + 1;
2293 	}
2294 	else
2295 		s_file = CopyString (filename, 0);
2296 
2297 	pr_source_line = 0;
2298 
2299 	PR_NewLine ();
2300 
2301 	PR_Lex ();	// read first token
2302 
2303 	while (pr_token_type != tt_eof)
2304 	{
2305 		if (setjmp(pr_parse_abort))
2306 		{
2307 			if (++pr_error_count > MAX_ERRORS)
2308 				return false;
2309 			PR_SkipToSemicolon ();
2310 			if (pr_token_type == tt_eof)
2311 				return false;
2312 		}
2313 
2314 		pr_scope = NULL;	// outside all functions
2315 
2316 		PR_ParseDefs ();
2317 	}
2318 
2319 	return (pr_error_count == 0) ? true: false;
2320 }