1 
2 #include "qcc.h"
3 #include "hash.h"
4 
5 pr_info_t	pr;
6 def_t		*pr_global_defs[MAX_REGS];	// to find def for a global variable
7 int		pr_edict_size;
8 
9 int shortened_store = 0;
10 
11 //========================================
12 
13 def_t		*pr_scope;		// the function being parsed, or NULL
14 boolean	pr_dumpasm;
15 string_t	s_file;			// filename for function definition
16 
17 int		locals_end;		// for tracking local variables vs temps
18 
19 jmp_buf		pr_parse_abort;		// longjump with this on parse error
20 
21 void PR_ParseDefs (void);
22 
23 //========================================
24 
25 
26 opcode_t pr_opcodes[] =
27 {
28  {"<DONE>", "DONE", OP2_DONE, -1, false, &def_entity, &def_field, &def_void},
29 
30  {"*", "MUL_F", OP2_MUL_F, 2, false, &def_float, &def_float, &def_float},
31  {"*", "MUL_V", OP2_MUL_V, 2, false, &def_vector, &def_vector, &def_float},
32  {"*", "MUL_FV", OP2_MUL_FV, 2, false, &def_float, &def_vector, &def_vector},
33  {"*", "MUL_VF", OP2_MUL_VF, 2, false, &def_vector, &def_float, &def_vector},
34 
35  {"/", "DIV", OP2_DIV_F, 2, false, &def_float, &def_float, &def_float},
36 
37  {"+", "ADD_F", OP2_ADD_F, 3, false, &def_float, &def_float, &def_float},
38  {"+", "ADD_V", OP2_ADD_V, 3, false, &def_vector, &def_vector, &def_vector},
39  {"+", "ADD_EF", OP2_ADD_F, 3, false, &def_entity, &def_float, &def_entity},
40  {"+", "ADD_FE", OP2_ADD_F, 3, false, &def_float, &def_entity, &def_entity},
41 
42  {"-", "SUB_F", OP2_SUB_F, 3, false, &def_float, &def_float, &def_float},
43  {"-", "SUB_V", OP2_SUB_V, 3, false, &def_vector, &def_vector, &def_vector},
44 
45  {"==", "EQ_F", OP2_EQ_F, 4, false, &def_float, &def_float, &def_float},
46  {"==", "EQ_V", OP2_EQ_V, 4, false, &def_vector, &def_vector, &def_float},
47  {"==", "EQ_S", OP2_EQ_S, 4, false, &def_string, &def_string, &def_float},
48  {"==", "EQ_ENT", OP2_EQ_E, 4, false, &def_entity, &def_entity, &def_float},
49  {"==", "EQ_FNC", OP2_EQ_FNC, 4, false, &def_function, &def_function, &def_float},
50 
51  {"!=", "NE_F", OP2_NE_F, 4, false, &def_float, &def_float, &def_float},
52  {"!=", "NE_V", OP2_NE_V, 4, false, &def_vector, &def_vector, &def_float},
53  {"!=", "NE_S", OP2_NE_S, 4, false, &def_string, &def_string, &def_float},
54  {"!=", "NE_ENT", OP2_NE_E, 4, false, &def_entity, &def_entity, &def_float},
55  {"!=", "NE_FNC", OP2_NE_FNC, 4, false, &def_function, &def_function, &def_float},
56 
57  {"<=", "LE", OP2_LE, 4, false, &def_float, &def_float, &def_float},
58  {">=", "GE", OP2_GE, 4, false, &def_float, &def_float, &def_float},
59  {"<", "LT", OP2_LT, 4, false, &def_float, &def_float, &def_float},
60  {">", "GT", OP2_GT, 4, false, &def_float, &def_float, &def_float},
61 
62  {".", "LOAD_F", OP2_LOAD_F, 1, false, &def_entity, &def_field, &def_float},
63  {".", "LOAD_V", OP2_LOAD_V, 1, false, &def_entity, &def_field, &def_vector},
64  {".", "LOAD_S", OP2_LOAD_S, 1, false, &def_entity, &def_field, &def_string},
65  {".", "LOAD_ENT", OP2_LOAD_ENT, 1, false, &def_entity, &def_field, &def_entity},
66  {".", "LOAD_FLD", OP2_LOAD_FLD, 1, false, &def_entity, &def_field, &def_field},
67  {".", "LOAD_FNC", OP2_LOAD_FNC, 1, false, &def_entity, &def_field, &def_function},
68 
69  {".", "ADDRESS", OP2_ADDRESS, 1, false, &def_entity, &def_field, &def_pointer},
70 
71  {"=", "STORE_F", OP2_STORE_F, 5, true, &def_float, &def_float, &def_float},
72  {"=", "STORE_V", OP2_STORE_V, 5, true, &def_vector, &def_vector, &def_vector},
73  {"=", "STORE_S", OP2_STORE_S, 5, true, &def_string, &def_string, &def_string},
74  {"=", "STORE_ENT", OP2_STORE_ENT, 5, true, &def_entity, &def_entity, &def_entity},
75  {"=", "STORE_FLD", OP2_STORE_FLD, 5, true, &def_field, &def_field, &def_field},
76  {"=", "STORE_FNC", OP2_STORE_FNC, 5, true, &def_function, &def_function, &def_function},
77 
78  {"=", "STOREP_F", OP2_STOREP_F, 5, true, &def_pointer, &def_float, &def_float},
79  {"=", "STOREP_V", OP2_STOREP_V, 5, true, &def_pointer, &def_vector, &def_vector},
80  {"=", "STOREP_S", OP2_STOREP_S, 5, true, &def_pointer, &def_string, &def_string},
81  {"=", "STOREP_ENT", OP2_STOREP_ENT, 5, true, &def_pointer, &def_entity, &def_entity},
82  {"=", "STOREP_FLD", OP2_STOREP_FLD, 5, true, &def_pointer, &def_field, &def_field},
83  {"=", "STOREP_FNC", OP2_STOREP_FNC, 5, true, &def_pointer, &def_function, &def_function},
84 
85  {"<RETURN>", "RETURN", OP2_RETURN, -1, false, &def_void, &def_void, &def_void},
86 
87  {"!", "NOT_F", OP2_NOT_F, -1, false, &def_float, &def_void, &def_float},
88  {"!", "NOT_V", OP2_NOT_V, -1, false, &def_vector, &def_void, &def_float},
89  {"!", "NOT_S", OP2_NOT_S, -1, false, &def_vector, &def_void, &def_float},
90  {"!", "NOT_ENT", OP2_NOT_ENT, -1, false, &def_entity, &def_void, &def_float},
91  {"!", "NOT_FNC", OP2_NOT_FNC, -1, false, &def_function, &def_void, &def_float},
92 
93   {"<IF>", "IF", OP2_IF, -1, false, &def_float, &def_float, &def_void},
94   {"<IFNOT>", "IFNOT", OP2_IFNOT, -1, false, &def_float, &def_float, &def_void},
95 
96 // calls returns REG_RETURN
97  {"<CALL0>", "CALL0", OP2_CALL0, -1, false, &def_function, &def_void, &def_void},
98  {"<CALL1>", "CALL1", OP2_CALL1, -1, false, &def_function, &def_void, &def_void},
99  {"<CALL2>", "CALL2", OP2_CALL2, -1, false, &def_function, &def_void, &def_void},
100  {"<CALL3>", "CALL3", OP2_CALL3, -1, false, &def_function, &def_void, &def_void},
101  {"<CALL4>", "CALL4", OP2_CALL4, -1, false, &def_function, &def_void, &def_void},
102  {"<CALL5>", "CALL5", OP2_CALL5, -1, false, &def_function, &def_void, &def_void},
103  {"<CALL6>", "CALL6", OP2_CALL6, -1, false, &def_function, &def_void, &def_void},
104  {"<CALL7>", "CALL7", OP2_CALL7, -1, false, &def_function, &def_void, &def_void},
105  {"<CALL8>", "CALL8", OP2_CALL8, -1, false, &def_function, &def_void, &def_void},
106 
107  {"<STATE>", "STATE", OP2_STATE, -1, false, &def_float, &def_float, &def_void},
108 
109  {"<GOTO>", "GOTO", OP2_GOTO, -1, false, &def_float, &def_void, &def_void},
110 
111  {"&&", "AND", OP2_AND, 6, false, &def_float, &def_float, &def_float},
112  {"||", "OR", OP2_OR, 6, false, &def_float, &def_float, &def_float},
113 
114  {"&", "BITAND", OP2_BITAND, 2, false, &def_float, &def_float, &def_float},
115  {"|", "BITOR", OP2_BITOR, 2, false, &def_float, &def_float, &def_float},
116 
117  {"[", "ARRAY_F", OP2_LOAD_F, 1, false, &def_entity, &def_float, &def_float},
118  {"[", "ARRAY_S", OP2_ADD_F, 1, false, &def_string, &def_float, &def_string},
119  {"^[", "ARRAY_V", OP2_LOAD_V, 1, false, &def_entity, &def_float, &def_vector},
120 
121  {NULL}
122 };
123 
124 #define	TOP_PRIORITY	6
125 #define	NOT_PRIORITY	4
126 
127 def_t *PR_Expression (int priority);
128 
129 def_t	junkdef;
130 
131 //===========================================================================
132 
133 
PR_GetType(def_t * def)134 etype_t PR_GetType (def_t *def)
135 {
136 	etype_t type = def->type->type;
137 	if (def->cast)
138 	{
139 		type = def->cast;
140 		def->cast = ev_void;
141 	}
142 	return type;
143 }
144 
145 int freefloat = 0;
146 int freevec = 0;
147 int ofstemp = 0;
148 def_t *dtemp;
149 
150 
151 /*
152 ============
153 PR_Statement
154 
155 Emits a primitive statement, returning the var it places it's value in
156 ============
157 */
PR_Statement(opcode_t * op,def_t * var_a,def_t * var_b)158 def_t *PR_Statement ( opcode_t *op, def_t *var_a, def_t *var_b)
159 {
160 	dstatement_t	*statement, *sprev;
161 	def_t			*var_c;
162 	static int		generated_temp = 0;
163 	static etype_t	tprev = ev_void;
164 
165 	statement_linenums[numstatements] = pr_source_line;
166 	statement = &statements[numstatements];
167 	if (numstatements)
168 		sprev = &statements[numstatements - 1];
169 	numstatements++;
170 
171 	shortened_store = 0;
172 
173 	//printf("%s\n", op->name);
174 	statement->op = op->op;
175 	statement->a = var_a ? var_a->ofs : 0;
176 	statement->b = var_b ? var_b->ofs : 0;
177 	if (pr_optimize_eliminate_temps && generated_temp)
178 	{
179 		if (!ofstemp)
180 		{
181 			ofstemp = numpr_globals;
182 			pr_global_defs[ofstemp] = &def_void;
183 			numpr_globals += 3;
184 
185 			dtemp = (struct def_s *) malloc (sizeof(def_t));
186 		}
187 		if (!((sprev->op == OP2_MUL_FV && sprev->a == ofstemp) || (sprev->op == OP2_MUL_VF && sprev->b == ofstemp)))
188 		{
189 			if (statement->a == sprev->c)
190 			{
191 				if (tprev == ev_vector)
192 				{
193 					if (freevec)
194 						PR_ParseError("freevec not zero");
195 					freevec = statement->a;
196 				}
197 				else
198 				{
199 					if (freefloat)
200 						PR_ParseError("freefloat not zero");
201 					freefloat = statement->a;
202 				}
203 				statement->a = sprev->c = ofstemp;
204 				num_temps_removed += type_size[op->type_a->type->type];
205 				if (op->right_associative)
206 				{
207 					memcpy(dtemp, var_a, sizeof(def_t));
208 					dtemp->ofs = ofstemp;
209 					var_a = dtemp;
210 				}
211 			}
212 			else if (statement->b == sprev->c)
213 			{
214 				if (tprev == ev_vector)
215 				{
216 					if (freevec)
217 						PR_ParseError("freevec not zero");
218 					freevec = statement->b;
219 				}
220 				else
221 				{
222 					if (freefloat)
223 						PR_ParseError("freefloat not zero");
224 					freefloat = statement->b;
225 				}
226 				statement->b = sprev->c = ofstemp;
227 				num_temps_removed += type_size[op->type_a->type->type];
228 			}
229 		}
230 	}
231 	if (op->type_c == &def_void || op->right_associative)
232 	{
233 		var_c = NULL;
234 		statement->c = 0;			// ifs, gotos, and assignments
235 									// don't need vars allocated
236 		tprev = ev_void;
237 
238 		if ((numstatements > 1) && generated_temp)
239 		{
240 			if (pr_optimize_eliminate_temps && ((unsigned) (statement->op - OP2_STORE_F) < 6) && (statement->a == sprev->c))
241 			{
242 				sprev->c = statement->b;
243 				numstatements--;
244 				num_stores_shortened++;
245 				shortened_store = 1;
246 				//printf("removed!\n");
247 				generated_temp = 0;
248 				tprev = ev_void;
249 				return var_b;
250 			}
251 			else if (pr_optimize_shorten_ifs && (statement->op == OP2_IFNOT))
252 			{
253 				if (sprev->op == OP2_NOT_F || sprev->op == OP2_NOT_FNC || sprev->op == OP2_NOT_ENT)
254 				{
255 					sprev->op = OP2_IF;
256 					numstatements--;
257 					num_ifs_shortened++;
258 				}
259 			}
260 		}
261 		generated_temp = 0;
262 	}
263 	else
264 	{	// allocate result space
265 		var_c = (struct def_s *) malloc (sizeof(def_t));
266 		memset (var_c, 0, sizeof(def_t));
267 		var_c->type = op->type_c->type;
268 		var_c->cast = ev_void;
269 
270 		tprev = op->type_c->type->type;
271 		if ((tprev == ev_vector) && freevec)
272 		{
273 			var_c->ofs = freevec;
274 			freevec = 0;
275 		}
276 		else if ((tprev != ev_vector) && freefloat)
277 		{
278 			var_c->ofs = freefloat;
279 			freefloat = 0;
280 		}
281 		else
282 		{
283 			var_c->ofs = numpr_globals;
284 			numpr_globals += type_size[tprev];
285 		}
286 		statement->c = var_c->ofs;
287 
288 		generated_temp = 1;
289 	}
290 
291 	if (op->right_associative)
292 		return var_a;
293 	return var_c;
294 }
295 
296 /*
297 ============
298 PR_GetImmediate
299 
300 Looks for a preexisting constant; return NULL if none exists
301 ============
302 */
PR_GetImmediate(void)303 def_t *PR_GetImmediate (void)
304 {
305 	def_t *cn = NULL;
306 	struct hash_element *cell = NULL;
307 
308 	for (cell = htable[pr_immediate_index]; cell != NULL; cell = cell->next)
309 	{
310 		cn = cell->def;
311 		if (!cn->initialized || (cn->type != pr_immediate_type))
312 			continue;
313 		if (pr_immediate_type == &type_string)
314 		{
315 			if (memcmp(G_STRING(cn->ofs), pr_immediate_string, pr_immediate_strlen))
316 				continue;
317 		}
318 		else if (pr_immediate_type == &type_float)
319 		{
320 			if (G_INT(cn->ofs) != pr_immediate._int)
321 				continue;
322 		}
323 		else
324 		{
325 			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]))
326 				continue;
327 		}
328 		return cn;
329 	}
330 	return NULL;
331 }
332 
333 /*
334 ============
335 PR_ParseImmediate
336 
337 Looks for a preexisting constant; allocates a new one if none is found
338 ============
339 */
PR_ParseImmediate(void)340 def_t	*PR_ParseImmediate (void)
341 {
342 	def_t *cn = NULL;
343 	struct hash_element *cell = NULL;
344 
345 	if (cn = PR_GetImmediate())
346 	{
347 		PR_Lex ();
348 		return cn;
349 	}
350 
351 // allocate a new one
352 	cn = (struct def_s *) malloc (sizeof(def_t));
353 
354 	cn->next = NULL;
355 	pr.def_tail->next = cn;
356 	pr.def_tail = cn;
357 
358 	cell = (struct hash_element *) malloc (sizeof(struct hash_element));
359 	cell->next = htable[pr_immediate_index];
360 	cell->def = cn;
361 	htable[pr_immediate_index] = cell;
362 	stats[pr_immediate_index]++;
363 
364 	cn->type = pr_immediate_type;
365 	cn->name = "IMMEDIATE";
366 	cn->initialized = 1;
367 	cn->scope = NULL;		// always share immediates
368 	cn->cast = ev_void;
369 
370 // copy the immediate to the global area
371 	cn->ofs = numpr_globals;
372 	pr_global_defs[cn->ofs] = cn;
373 	numpr_globals += type_size[pr_immediate_type->type];
374 	if (pr_immediate_type == &type_string)
375 		pr_immediate.string = CopyString (pr_immediate_string, pr_immediate_strlen);
376 
377 	memcpy (pr_globals + cn->ofs, &pr_immediate, 4*type_size[pr_immediate_type->type]);
378 
379 	PR_Lex ();
380 
381 	return cn;
382 }
383 
PrecacheSound(def_t * e,int ch)384 void PrecacheSound (def_t *e, int ch)
385 {
386 	char	*n;
387 	int		i;
388 
389 	if (!e->ofs)
390 		return;
391 	n = G_STRING(e->ofs);
392 	for (i=0 ; i<numsounds ; i++)
393 		if (!strcmp(n, precache_sounds[i]))
394 			return;
395 	if (numsounds == MAX_SOUNDS)
396 		Error ("PrecacheSound: numsounds == MAX_SOUNDS");
397 	strcpy (precache_sounds[i], n);
398 	if (ch >= '1'  && ch <= '9')
399 		precache_sounds_block[i] = ch - '0';
400 	else
401 		precache_sounds_block[i] = 1;
402 	numsounds++;
403 }
404 
PrecacheModel(def_t * e,int ch)405 void PrecacheModel (def_t *e, int ch)
406 {
407 	char	*n;
408 	int		i;
409 
410 	if (!e->ofs)
411 		return;
412 	n = G_STRING(e->ofs);
413 	for (i=0 ; i<nummodels ; i++)
414 		if (!strcmp(n, precache_models[i]))
415 			return;
416 	if (numsounds == MAX_SOUNDS)
417 		Error ("PrecacheModels: numsounds == MAX_SOUNDS");
418 	strcpy (precache_models[i], n);
419 	if (ch >= '1'  && ch <= '9')
420 		precache_models_block[i] = ch - '0';
421 	else
422 		precache_models_block[i] = 1;
423 	nummodels++;
424 }
425 
PrecacheFile(def_t * e,int ch)426 void PrecacheFile (def_t *e, int ch)
427 {
428 	char	*n;
429 	int		i;
430 
431 	if (!e->ofs)
432 		return;
433 	n = G_STRING(e->ofs);
434 	for (i=0 ; i<numfiles ; i++)
435 		if (!strcmp(n, precache_files[i]))
436 			return;
437 	if (numfiles == MAX_FILES)
438 		Error ("PrecacheFile: numfiles == MAX_FILES");
439 	strcpy (precache_files[i], n);
440 	if (ch >= '1'  && ch <= '9')
441 		precache_files_block[i] = ch - '0';
442 	else
443 		precache_files_block[i] = 1;
444 	numfiles++;
445 }
446 
447 /*
448 ============
449 PR_ParseFunctionCall
450 ============
451 */
PR_ParseFunctionCall(def_t * func)452 def_t *PR_ParseFunctionCall (def_t *func)
453 {
454 	def_t		*e;
455 	int			arg, numtypes;
456 	type_t		*t;
457 
458 	t = func->type;
459 
460 	if (t->type != ev_function)
461 		PR_ParseError ("not a function");
462 
463 // copy the arguments to the global parameter variables
464 	arg = 0;
465 	numtypes = t->num_parms >= 0 ? t->num_parms : -1 - t->num_parms;
466 	if (!PR_Check(")"))
467 	{
468 		do
469 		{
470 			if (t->num_parms >= 0 && arg >= t->num_parms)
471 				PR_ParseError ("too many parameters");
472 
473 			if (!PR_Check("#"))
474 			{
475 				e = PR_Expression (TOP_PRIORITY);
476 
477 				if (arg == 0 && func->name)
478 				{
479 				// save information for model and sound caching
480 					if (!strncmp(func->name,"precache_sound", 14))
481 						PrecacheSound (e, func->name[14]);
482 					else if (!strncmp(func->name,"precache_model", 14))
483 						PrecacheModel (e, func->name[14]);
484 					else if (!strncmp(func->name,"precache_file", 13))
485 						PrecacheFile (e, func->name[13]);
486 				}
487 
488 				if (e->cast)
489 				{
490 					if ((arg < numtypes) && ( e->cast != t->parm_types[arg]->type ) )
491 						PR_ParseError ("type mismatch on parm %i", arg);
492 					e->cast = ev_void;
493 				}
494 				else if ((arg < numtypes) && ( e->type != t->parm_types[arg] ) )
495 					PR_ParseError ("type mismatch on parm %i", arg);
496 			// a vector copy will copy everything
497 				def_parms[arg].type = t->parm_types[arg];
498 				if (pr_optimize_nonvec_parms && t->parm_types[arg] != &type_vector)
499 				{
500 					PR_Statement (&pr_opcodes[OP_STORE_F], e, &def_parms[arg]);
501 					num_nonvec_parms++;
502 				}
503 				else
504 					PR_Statement (&pr_opcodes[OP_STORE_V], e, &def_parms[arg]);
505 			}
506 			arg++;
507 		} while (PR_Check (","));
508 
509 		PR_Expect (")");
510 	}
511 	if (arg < numtypes)
512 		PR_ParseError ("too few parameters");
513 	if (arg >8)
514 		PR_ParseError ("More than eight parameters");
515 
516 
517 	PR_Statement (&pr_opcodes[OP_CALL0+arg], func, 0);
518 
519 	def_ret.type = t->aux_type;
520 	return &def_ret;
521 }
522 
523 /*
524 ============
525 PR_ParseValue
526 
527 Returns the global ofs for the current token
528 ============
529 */
PR_ParseValue(void)530 def_t	*PR_ParseValue (void)
531 {
532 	def_t		*d;
533 	char		*name;
534 
535 // if the token is an immediate, allocate a constant for it
536 	if (pr_token_type == tt_immediate)
537 		return PR_ParseImmediate ();
538 
539 	name = PR_ParseName ();
540 
541 // look through the defs
542 	d = PR_GetDef (NULL, name, pr_scope, false);
543 	if (!d)
544 		PR_ParseError ("Unknown value \"%s\"", name);
545 	return d;
546 }
547 
548 /*
549 ============
550 PR_Cast
551 ============
552 */
PR_Cast(def_t * e,type_t * type)553 def_t *PR_Cast (def_t *e, type_t *type)
554 {
555 	def_t *cast;
556 
557 	cast = (struct def_s *) malloc (sizeof(def_t));
558 	memcpy (cast, e, sizeof(def_t));
559 	cast->type = type;
560 	return cast;
561 }
562 
563 /*
564 ============
565 PR_Term
566 ============
567 */
PR_Term(void)568 def_t *PR_Term (void)
569 {
570 	def_t	*e, *e2;
571 	etype_t	t;
572 
573 	if (PR_Check ("!"))
574 	{
575 		e = PR_Expression (NOT_PRIORITY);
576 		t = PR_GetType(e);
577 		if (t == ev_float)
578 			e2 = PR_Statement (&pr_opcodes[OP_NOT_F], e, 0);
579 		else if (t == ev_string)
580 			e2 = PR_Statement (&pr_opcodes[OP_NOT_S], e, 0);
581 		else if (t == ev_entity)
582 			e2 = PR_Statement (&pr_opcodes[OP_NOT_ENT], e, 0);
583 		else if (t == ev_vector)
584 			e2 = PR_Statement (&pr_opcodes[OP_NOT_V], e, 0);
585 		else if (t == ev_function)
586 			e2 = PR_Statement (&pr_opcodes[OP_NOT_FNC], e, 0);
587 		else
588 		{
589 			e2 = NULL;		// shut up compiler warning;
590 			PR_ParseError ("type mismatch for !");
591 		}
592 		return e2;
593 	}
594 
595 	if (PR_Check("&"))
596 	{
597 		e = PR_Expression(1);
598 		t = e->type->type;
599 		if (t == ev_string || t == ev_field || t == ev_entity || t == ev_function)
600 			return PR_Cast(e, &type_float);
601 			//e->cast = ev_float;
602 		else if (t == ev_float)
603 			return PR_Cast(e, &type_pointer);
604 			//e->cast = ev_pointer;
605 		else
606 			PR_ParseError ("bad type for &");
607 		return e;
608 	}
609 
610 	if (PR_Check("*"))
611 	{
612 		e = PR_Expression(1);
613 		t = e->type->type;
614 		if (t == ev_float)
615 			return PR_Cast(e, &type_entity);
616 			//e->cast = ev_entity;
617 		else
618 			PR_ParseError ("bad type for *");
619 		return e;
620 	}
621 
622 	if (PR_Check("@"))
623 	{
624 		e = PR_Expression(1);
625 		t = e->type->type;
626 		if (t == ev_float)
627 			return PR_Cast(e, &type_string);
628 			//e->cast = ev_string;
629 		else
630 			PR_ParseError ("bad type for @");
631 		return e;
632 	}
633 
634 	if (PR_Check ("("))
635 	{
636 		e = PR_Expression (TOP_PRIORITY);
637 		PR_Expect (")");
638 		return e;
639 	}
640 
641 	return PR_ParseValue ();
642 }
643 
644 /*
645 ==============
646 PR_Expression
647 ==============
648 */
649 
PR_Expression(int priority)650 def_t *PR_Expression (int priority)
651 {
652 	opcode_t	*op, *oldop;
653 	def_t		*e, *e2;
654 	etype_t		type_a, type_b, type_c;
655 
656 	int index=0;
657 
658 	if (priority == 0)
659 		return PR_Term ();
660 
661 	e = PR_Expression (priority-1);
662 
663 	while (1)
664 	{
665 		if (priority == 1 && PR_Check ("(") )
666 			return PR_ParseFunctionCall (e);
667 
668 		index = (pr_token[0] + pr_token[1]) & (OPTABLESIZE - 1);
669 		op = pr_opcodes + optable[index];
670 
671 
672 		if (op->priority != priority || !PR_Check(op->name))
673 			break;
674 
675 		if ( op->right_associative )
676 		{
677 			// if last statement is an indirect, change it to an address of
678 			if (!shortened_store && ((unsigned)(statements[numstatements-1].op - OP2_LOAD_F) < 6))
679 			{
680 				statements[numstatements-1].op = OP2_ADDRESS;
681 				def_pointer.type->aux_type = e->type;
682 				e->type = def_pointer.type;
683 			}
684 			e2 = PR_Expression (priority);
685 		}
686 		else
687 		{
688 			if (optable[index] >= OP_ARRAY_F)
689 			{
690 				e2 = PR_Expression (TOP_PRIORITY);
691 				PR_Expect("]");
692 			}
693 			else
694 				e2 = PR_Expression (priority-1);
695 		}
696 
697 		// type check
698 		type_a = PR_GetType(e);
699 		type_b = PR_GetType(e2);
700 
701 		if (op->name[0] == '.')// field access gets type from field
702 		{
703 			if (e2->type->aux_type)
704 				type_c = e2->type->aux_type->type;
705 			else
706 				type_c = ev_bad;	// not a field
707 		}
708 		else
709 			type_c = ev_void;
710 
711 		oldop = op;
712 		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) )
713 		{
714 			op++;
715 			if (!op->name || STRCMP(op->name, oldop->name))
716 				PR_ParseError ("type mismatch for %s", oldop->name);
717 		}
718 
719 		if (type_a == ev_pointer && statements[numstatements-1].op == OP2_ADDRESS && type_b != e->type->aux_type->type)
720 			PR_ParseError ("type mismatch for %s", op->name);
721 
722 		if (op->right_associative)
723 		{
724 			if ((op->op - OP2_STORE_F < 6) && e->initialized)
725 				PR_ParseError("Assignment to constant");
726 			e = PR_Statement (op, e2, e);
727 		}
728 		else
729 			e = PR_Statement (op, e, e2);
730 
731 		if (type_c != ev_void)	// field access gets type from field
732 			e->type = e2->type->aux_type;
733 	}
734 
735 	return e;
736 }
737 
738 
739 /*
740 ============
741 PR_ParseStatement
742 
743 ============
744 */
PR_ParseStatement(void)745 void PR_ParseStatement (void)
746 {
747 	def_t				*e;
748 	dstatement_t		*patch1, *patch2;
749 	int					old_numstatements, numtemp;
750 	dstatement_t		temp[32];
751 	int					linenum[32];
752 
753 	if (PR_Check ("{"))
754 	{
755 		while (!PR_Check ("}"))
756 			PR_ParseStatement ();
757 		return;
758 	}
759 
760 	if (PR_Check("return"))
761 	{
762 		if (PR_Check (";"))
763 		{
764 			PR_Statement (&pr_opcodes[OP_RETURN], 0, 0);
765 			return;
766 		}
767 		e = PR_Expression (TOP_PRIORITY);
768 		PR_Expect (";");
769 		PR_Statement (&pr_opcodes[OP_RETURN], e, 0);
770 		return;
771 	}
772 
773 	if (PR_Check("while"))
774 	{
775 		PR_Expect ("(");
776 		patch2 = &statements[numstatements];
777 		e = PR_Expression (TOP_PRIORITY);
778 		PR_Expect (")");
779 		PR_Statement (&pr_opcodes[OP_IFNOT], e, 0);
780 		patch1 = &statements[numstatements-1];
781 		PR_ParseStatement ();
782 		junkdef.ofs = patch2 - &statements[numstatements];
783 		PR_Statement (&pr_opcodes[OP_GOTO], &junkdef, 0);
784 		patch1->b = &statements[numstatements] - patch1;
785 		return;
786 	}
787 	if (PR_Check("for"))
788 	{
789 		PR_Expect("(");
790 		if (!PR_Check(";"))
791 		{
792 			PR_Expression(TOP_PRIORITY);
793 			PR_Expect(";");
794 		}
795 		patch2 = &statements[numstatements];
796 		e = PR_Expression(TOP_PRIORITY);
797 		PR_Expect(";");
798 
799 		old_numstatements = numstatements;
800 		PR_Expression(TOP_PRIORITY);
801 		numtemp = numstatements - old_numstatements;
802 		if (numtemp > 32)
803 			PR_ParseError("Update expression too large");
804 		numstatements = old_numstatements;
805 		for (int i = 0 ; i < numtemp ; i++)
806 		{
807 			linenum[i] = statement_linenums[numstatements + i];
808 			temp[i] = statements[numstatements + i];
809 		}
810 
811 		PR_Expect(")");
812 		PR_Statement(&pr_opcodes[OP_IFNOT], e, 0);
813 		patch1 = &statements[numstatements-1];
814 		PR_ParseStatement();
815 		for (int i = 0 ; i < numtemp ; i++)
816 		{
817 			statement_linenums[numstatements] = linenum[i];
818 			statements[numstatements++] = temp[i];
819 		}
820 		junkdef.ofs = patch2 - &statements[numstatements];
821 		PR_Statement (&pr_opcodes[OP_GOTO], &junkdef, 0);
822 		patch1->b = &statements[numstatements] - patch1;
823 		return;
824 	}
825 	if (PR_Check("do"))
826 	{
827 		patch1 = &statements[numstatements];
828 		PR_ParseStatement ();
829 		PR_Expect ("while");
830 		PR_Expect ("(");
831 		e = PR_Expression (TOP_PRIORITY);
832 		PR_Expect (")");
833 		PR_Expect (";");
834 		junkdef.ofs = patch1 - &statements[numstatements];
835 		PR_Statement (&pr_opcodes[OP_IF], e, &junkdef);
836 		return;
837 	}
838 
839 	if (PR_Check("local"))
840 	{
841 		PR_ParseDefs ();
842 		locals_end = numpr_globals;
843 		return;
844 	}
845 
846 	if (PR_Check("if"))
847 	{
848 		PR_Expect ("(");
849 		e = PR_Expression (TOP_PRIORITY);
850 		PR_Expect (")");
851 
852 		PR_Statement (&pr_opcodes[OP_IFNOT], e, 0);
853 		patch1 = &statements[numstatements-1];
854 
855 		PR_ParseStatement ();
856 
857 		if (PR_Check ("else"))
858 		{
859 			patch2 = &statements[numstatements];
860 			PR_Statement (&pr_opcodes[OP_GOTO], 0, 0);
861 			patch1->b = &statements[numstatements] - patch1;
862 			PR_ParseStatement ();
863 			patch2->a = &statements[numstatements] - patch2;
864 		}
865 		else
866 			patch1->b = &statements[numstatements] - patch1;
867 
868 		return;
869 	}
870 
871 	PR_Expression (TOP_PRIORITY);
872 	PR_Expect (";");
873 }
874 
875 
876 /*
877 ==============
878 PR_ParseState
879 
880 States are special functions made for convenience.  They automatically
881 set frame, nextthink (implicitly), and think (allowing forward definitions).
882 
883 // void() name = [framenum, nextthink] {code}
884 // expands to:
885 // function void name ()
886 // {
887 //		self.frame=framenum;
888 //		self.nextthink = time + 0.1;
889 //		self.think = nextthink
890 //		<code>
891 // };
892 ==============
893 */
PR_ParseState(void)894 void PR_ParseState (void)
895 {
896 	char	*name;
897 	def_t	*s1, *def;
898 
899 	if (pr_token_type != tt_immediate || pr_immediate_type != &type_float)
900 		PR_ParseError ("state frame must be a number");
901 	s1 = PR_ParseImmediate ();
902 
903 	PR_Expect (",");
904 
905 	name = PR_ParseName ();
906 	def = PR_GetDef (&type_function, name,0, true);
907 
908 	PR_Expect ("]");
909 
910 	PR_Statement (&pr_opcodes[OP_STATE], s1, def);
911 }
912 
913 /*
914 ============
915 PR_ParseImmediateStatements
916 
917 Parse a function body
918 ============
919 */
PR_ParseImmediateStatements(type_t * type)920 function_t *PR_ParseImmediateStatements (type_t *type)
921 {
922 	int			i;
923 	function_t	*f;
924 	def_t		*defs[MAX_PARMS];
925 
926 	f = (struct function_s *) malloc (sizeof(function_t));
927 
928 //
929 // check for builtin function definition #1, #2, etc
930 //
931 	if (PR_Check ("#"))
932 	{
933 		if (pr_token_type != tt_immediate || pr_immediate_type != &type_float || pr_immediate._float != (int)pr_immediate._float)
934 			PR_ParseError("Bad builtin immediate");
935 		f->builtin = (int) pr_immediate._float;
936 		PR_Lex();
937 		return f;
938 	}
939 
940 	f->builtin = 0;
941 //
942 // define the parms
943 //
944 	for (i=0 ; i<type->num_parms ; i++)
945 	{
946 		defs[i] = PR_GetDef (type->parm_types[i], pr_parm_names[i], pr_scope, true);
947 		f->parm_ofs[i] = defs[i]->ofs;
948 		if (i > 0 && f->parm_ofs[i] < f->parm_ofs[i-1])
949 			Error ("bad parm order");
950 	}
951 
952 	f->code = numstatements;
953 
954 //
955 // check for a state opcode
956 //
957 	if (PR_Check ("["))
958 		PR_ParseState ();
959 
960 //
961 // parse regular statements
962 //
963 	PR_Expect ("{");
964 
965 	while (!PR_Check("}"))
966 		PR_ParseStatement ();
967 
968 // emit an end of statements opcode
969 	PR_Statement (pr_opcodes, 0,0);
970 
971 
972 	return f;
973 }
974 
975 /*
976 ============
977 PR_GetDef
978 
979 If type is NULL, it will match any type
980 If allocate is true, a new def will be allocated if it can't be found
981 ============
982 */
PR_GetDef(type_t * type,char * name,def_t * scope,boolean allocate)983 def_t *PR_GetDef (type_t *type, char *name, def_t *scope, boolean allocate)
984 {
985 	def_t	*def;
986 	char element[MAX_NAME];
987 
988 	int index;
989 	struct hash_element *cell;
990 
991 	index = hash(name);
992 	for (cell = htable[index]; cell != NULL; cell = cell->next)
993 	{
994 		def = cell->def;
995 		if ( !STRCMP(def->name, name) )
996 		{
997 			if (def->scope && (def->scope != scope))
998 				continue;
999 
1000 			if (type && def->type != type)
1001 				PR_ParseError ("Type mismatch on redeclaration of %s", name);
1002 
1003 			return def;
1004 		}
1005 	}
1006 
1007 	if (!allocate)
1008 		return NULL;
1009 
1010 // allocate a new def
1011 	def = (struct def_s *) malloc (sizeof(def_t));
1012 	memset (def, 0, sizeof(*def));
1013 	def->next = NULL;
1014 	pr.def_tail->next = def;
1015 	pr.def_tail = def;
1016 
1017 	cell = (struct hash_element *) malloc (sizeof(struct hash_element));
1018 	cell->next = htable[index];
1019 	cell->def = def;
1020 	htable[index] = cell;
1021 	stats[index]++;
1022 
1023 	def->name = (char *) malloc(strlen(name)+1);
1024 	strcpy(def->name, name);
1025 	def->type = type;
1026 
1027 	def->scope = scope;
1028 
1029 	def->ofs = numpr_globals;
1030 	pr_global_defs[numpr_globals] = def;
1031 
1032 //
1033 // make automatic defs for the vectors elements
1034 // .origin can be accessed as .origin_x, .origin_y, and .origin_z
1035 //
1036 	if (type->type == ev_vector)
1037 	{
1038 		sprintf (element, "%s_x",name);
1039 		PR_GetDef (&type_float, element, scope, true);
1040 
1041 		sprintf (element, "%s_y",name);
1042 		PR_GetDef (&type_float, element, scope, true);
1043 
1044 		sprintf (element, "%s_z",name);
1045 		PR_GetDef (&type_float, element, scope, true);
1046 	}
1047 	else
1048 		numpr_globals += type_size[type->type];
1049 
1050 	if (type->type == ev_field)
1051 	{
1052 		*(int *)&pr_globals[def->ofs] = pr.size_fields;
1053 
1054 		if (type->aux_type->type == ev_vector)
1055 		{
1056 			sprintf (element, "%s_x",name);
1057 			PR_GetDef (&type_floatfield, element, scope, true);
1058 
1059 			sprintf (element, "%s_y",name);
1060 			PR_GetDef (&type_floatfield, element, scope, true);
1061 
1062 			sprintf (element, "%s_z",name);
1063 			PR_GetDef (&type_floatfield, element, scope, true);
1064 		}
1065 		else
1066 			pr.size_fields += type_size[type->aux_type->type];
1067 	}
1068 
1069 
1070 //	if (pr_dumpasm)
1071 //		PR_PrintOfs (def->ofs);
1072 
1073 	return def;
1074 }
1075 
1076 /*
1077 ================
1078 PR_ParseDefs
1079 
1080 Called at the outer layer and when a local statement is hit
1081 ================
1082 */
PR_ParseDefs(void)1083 void PR_ParseDefs (void)
1084 {
1085 	char		*name;
1086 	type_t		*type;
1087 	def_t		*def, *odef;
1088 	function_t	*f;
1089 	dfunction_t	*df;
1090 	int			i;
1091 	int			locals_start;
1092 
1093 	struct hash_element *cell = NULL;
1094 
1095 	type = PR_ParseType ();
1096 
1097 	if (pr_scope && (type->type == ev_field || type->type == ev_function) )
1098 		PR_ParseError ("Fields and functions must be global");
1099 
1100 	do
1101 	{
1102 		name = PR_ParseName ();
1103 
1104 		def = PR_GetDef (type, name, pr_scope, true);
1105 
1106 // check for an initialization
1107 		if ( PR_Check ("=") )
1108 		{
1109 			if (def->initialized)
1110 				PR_ParseError ("%s redeclared", name);
1111 
1112 			if (type->type == ev_function)
1113 			{
1114 				locals_start = locals_end = numpr_globals;
1115 				pr_scope = def;
1116 				f = PR_ParseImmediateStatements (type);
1117 				pr_scope = NULL;
1118 				def->initialized = 1;
1119 				G_FUNCTION(def->ofs) = numfunctions;
1120 				f->def = def;
1121 //				if (pr_dumpasm)
1122 //					PR_PrintFunction (def);
1123 
1124 		// fill in the dfunction
1125 				df = &functions[numfunctions];
1126 				numfunctions++;
1127 				if (f->builtin)
1128 					df->first_statement = -f->builtin;
1129 				else
1130 					df->first_statement = f->code;
1131 				df->s_name = CopyString (f->def->name);
1132 				df->s_file = s_file;
1133 				df->numparms =  f->def->type->num_parms;
1134 				df->locals = locals_end - locals_start;
1135 				df->parm_start = locals_start;
1136 				for (i = 0 ; i < df->numparms ; i++)
1137 					df->parm_size[i] = type_size[f->def->type->parm_types[i]->type];
1138 
1139 				continue;
1140 			}
1141 			else if (pr_immediate_type != type)
1142 				PR_ParseError ("wrong immediate type for %s", name);
1143 
1144 			def->initialized = 1;
1145 
1146 			if (pr_optimize_defs && (odef = PR_GetImmediate()))
1147 			{
1148 				PR_GetImmediate();
1149 				if (def->ofs == numpr_globals - 1)
1150 				{
1151 					numpr_globals--;
1152 					def->ofs = odef->ofs;
1153 					num_defs += 4;
1154 					if (def->type->type == ev_string)
1155 						num_defs += pr_immediate_strlen;
1156 				}
1157 				else
1158 				{
1159 					memcpy (pr_globals + def->ofs, pr_globals + odef->ofs, 4*type_size[pr_immediate_type->type]);
1160 					if (def->type->type == ev_string)
1161 						num_defs += pr_immediate_strlen;
1162 				}
1163 			}
1164 			else
1165 			{
1166 				cell = (struct hash_element *) malloc (sizeof(struct hash_element));
1167 				cell->next = htable[pr_immediate_index];
1168 				cell->def = def;
1169 				htable[pr_immediate_index] = cell;
1170 				stats[pr_immediate_index]++;
1171 
1172 				if (pr_immediate_type == &type_string)
1173 					pr_immediate.string = CopyString (pr_immediate_string, pr_immediate_strlen);
1174 
1175 				memcpy (pr_globals + def->ofs, &pr_immediate, 4*type_size[pr_immediate_type->type]);
1176 			}
1177 			PR_Lex ();
1178 		}
1179 
1180 	} while (PR_Check (","));
1181 
1182 	PR_Expect (";");
1183 }
1184 
1185 /*
1186 ============
1187 PR_CompileFile
1188 
1189 compiles the 0 terminated text, adding defintions to the pr structure
1190 ============
1191 */
PR_CompileFile(char * string,char * filename)1192 boolean	PR_CompileFile (char *string, char *filename)
1193 {
1194 	if (!pr.memory)
1195 		Error ("PR_CompileFile: Didn't clear");
1196 
1197 	PR_ClearGrabMacros ();	// clear the frame macros
1198 
1199 	pr_file_p = string;
1200 	s_file = CopyString (filename);
1201 
1202 	pr_source_line = 0;
1203 
1204 	PR_NewLine ();
1205 
1206 	PR_Lex ();	// read first token
1207 
1208 	while (pr_token_type != tt_eof)
1209 	{
1210 		if (setjmp(pr_parse_abort))
1211 		{
1212 			if (++pr_error_count > MAX_ERRORS)
1213 				return false;
1214 			PR_SkipToSemicolon ();
1215 			if (pr_token_type == tt_eof)
1216 				return false;
1217 		}
1218 
1219 		pr_scope = NULL;	// outside all functions
1220 
1221 		PR_ParseDefs ();
1222 	}
1223 
1224 	return (pr_error_count == 0) ? true : false;
1225 }