1 
2 #include "qcc.h"
3 
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 //========================================
10 
11 def_t		*pr_scope;		// the function being parsed, or NULL
12 boolean	pr_dumpasm;
13 string_t	s_file;			// filename for function definition
14 
15 int			locals_end;		// for tracking local variables vs temps
16 
17 jmp_buf		pr_parse_abort;		// longjump with this on parse error
18 
19 void PR_ParseDefs (void);
20 
21 //========================================
22 
23 
24 opcode_t pr_opcodes[] =
25 {
26  {"<DONE>", "DONE", -1, false, &def_entity, &def_field, &def_void},
27 
28  {"*", "MUL_F", 2, false, &def_float, &def_float, &def_float},
29  {"*", "MUL_V", 2, false, &def_vector, &def_vector, &def_float},
30  {"*", "MUL_FV", 2, false, &def_float, &def_vector, &def_vector},
31  {"*", "MUL_VF", 2, false, &def_vector, &def_float, &def_vector},
32 
33  {"/", "DIV", 2, false, &def_float, &def_float, &def_float},
34 
35  {"+", "ADD_F", 3, false, &def_float, &def_float, &def_float},
36  {"+", "ADD_V", 3, false, &def_vector, &def_vector, &def_vector},
37 
38  {"-", "SUB_F", 3, false, &def_float, &def_float, &def_float},
39  {"-", "SUB_V", 3, false, &def_vector, &def_vector, &def_vector},
40 
41  {"==", "EQ_F", 4, false, &def_float, &def_float, &def_float},
42  {"==", "EQ_V", 4, false, &def_vector, &def_vector, &def_float},
43  {"==", "EQ_S", 4, false, &def_string, &def_string, &def_float},
44  {"==", "EQ_E", 4, false, &def_entity, &def_entity, &def_float},
45  {"==", "EQ_FNC", 4, false, &def_function, &def_function, &def_float},
46 
47  {"!=", "NE_F", 4, false, &def_float, &def_float, &def_float},
48  {"!=", "NE_V", 4, false, &def_vector, &def_vector, &def_float},
49  {"!=", "NE_S", 4, false, &def_string, &def_string, &def_float},
50  {"!=", "NE_E", 4, false, &def_entity, &def_entity, &def_float},
51  {"!=", "NE_FNC", 4, false, &def_function, &def_function, &def_float},
52 
53  {"<=", "LE", 4, false, &def_float, &def_float, &def_float},
54  {">=", "GE", 4, false, &def_float, &def_float, &def_float},
55  {"<", "LT", 4, false, &def_float, &def_float, &def_float},
56  {">", "GT", 4, false, &def_float, &def_float, &def_float},
57 
58  {".", "INDIRECT", 1, false, &def_entity, &def_field, &def_float},
59  {".", "INDIRECT", 1, false, &def_entity, &def_field, &def_vector},
60  {".", "INDIRECT", 1, false, &def_entity, &def_field, &def_string},
61  {".", "INDIRECT", 1, false, &def_entity, &def_field, &def_entity},
62  {".", "INDIRECT", 1, false, &def_entity, &def_field, &def_field},
63  {".", "INDIRECT", 1, false, &def_entity, &def_field, &def_function},
64 
65  {".", "ADDRESS", 1, false, &def_entity, &def_field, &def_pointer},
66 
67  {"=", "STORE_F", 5, true, &def_float, &def_float, &def_float},
68  {"=", "STORE_V", 5, true, &def_vector, &def_vector, &def_vector},
69  {"=", "STORE_S", 5, true, &def_string, &def_string, &def_string},
70  {"=", "STORE_ENT", 5, true, &def_entity, &def_entity, &def_entity},
71  {"=", "STORE_FLD", 5, true, &def_field, &def_field, &def_field},
72  {"=", "STORE_FNC", 5, true, &def_function, &def_function, &def_function},
73 
74  {"=", "STOREP_F", 5, true, &def_pointer, &def_float, &def_float},
75  {"=", "STOREP_V", 5, true, &def_pointer, &def_vector, &def_vector},
76  {"=", "STOREP_S", 5, true, &def_pointer, &def_string, &def_string},
77  {"=", "STOREP_ENT", 5, true, &def_pointer, &def_entity, &def_entity},
78  {"=", "STOREP_FLD", 5, true, &def_pointer, &def_field, &def_field},
79  {"=", "STOREP_FNC", 5, true, &def_pointer, &def_function, &def_function},
80 
81  {"<RETURN>", "RETURN", -1, false, &def_void, &def_void, &def_void},
82 
83  {"!", "NOT_F", -1, false, &def_float, &def_void, &def_float},
84  {"!", "NOT_V", -1, false, &def_vector, &def_void, &def_float},
85  {"!", "NOT_S", -1, false, &def_vector, &def_void, &def_float},
86  {"!", "NOT_ENT", -1, false, &def_entity, &def_void, &def_float},
87  {"!", "NOT_FNC", -1, false, &def_function, &def_void, &def_float},
88 
89   {"<IF>", "IF", -1, false, &def_float, &def_float, &def_void},
90   {"<IFNOT>", "IFNOT", -1, false, &def_float, &def_float, &def_void},
91 
92 // calls returns REG_RETURN
93  {"<CALL0>", "CALL0", -1, false, &def_function, &def_void, &def_void},
94  {"<CALL1>", "CALL1", -1, false, &def_function, &def_void, &def_void},
95  {"<CALL2>", "CALL2", -1, false, &def_function, &def_void, &def_void},
96  {"<CALL3>", "CALL3", -1, false, &def_function, &def_void, &def_void},
97  {"<CALL4>", "CALL4", -1, false, &def_function, &def_void, &def_void},
98  {"<CALL5>", "CALL5", -1, false, &def_function, &def_void, &def_void},
99  {"<CALL6>", "CALL6", -1, false, &def_function, &def_void, &def_void},
100  {"<CALL7>", "CALL7", -1, false, &def_function, &def_void, &def_void},
101  {"<CALL8>", "CALL8", -1, false, &def_function, &def_void, &def_void},
102 
103  {"<STATE>", "STATE", -1, false, &def_float, &def_float, &def_void},
104 
105  {"<GOTO>", "GOTO", -1, false, &def_float, &def_void, &def_void},
106 
107  {"&&", "AND", 6, false, &def_float, &def_float, &def_float},
108  {"||", "OR", 6, false, &def_float, &def_float, &def_float},
109 
110  {"&", "BITAND", 2, false, &def_float, &def_float, &def_float},
111  {"|", "BITOR", 2, false, &def_float, &def_float, &def_float},
112 
113  {NULL}
114 };
115 
116 #define	TOP_PRIORITY	6
117 #define	NOT_PRIORITY	4
118 
119 def_t *PR_Expression (int priority);
120 
121 def_t	junkdef;
122 
123 //===========================================================================
124 
125 
126 /*
127 ============
128 PR_Statement
129 
130 Emits a primitive statement, returning the var it places it's value in
131 ============
132 */
PR_Statement(opcode_t * op,def_t * var_a,def_t * var_b)133 def_t *PR_Statement ( opcode_t *op, def_t *var_a, def_t *var_b)
134 {
135 	dstatement_t	*statement;
136 	def_t			*var_c;
137 
138 	statement = &statements[numstatements];
139 	numstatements++;
140 
141 	statement_linenums[statement-statements] = pr_source_line;
142 	statement->op = op - pr_opcodes;
143 	statement->a = var_a ? var_a->ofs : 0;
144 	statement->b = var_b ? var_b->ofs : 0;
145 	if (op->type_c == &def_void || op->right_associative)
146 	{
147 		var_c = NULL;
148 		statement->c = 0;			// ifs, gotos, and assignments
149 									// don't need vars allocated
150 	}
151 	else
152 	{	// allocate result space
153 		var_c = malloc (sizeof(def_t));
154 		memset (var_c, 0, sizeof(def_t));
155 		var_c->ofs = numpr_globals;
156 		var_c->type = op->type_c->type;
157 
158 		statement->c = numpr_globals;
159 		numpr_globals += type_size[op->type_c->type->type];
160 	}
161 
162 	if (op->right_associative)
163 		return var_a;
164 	return var_c;
165 }
166 
167 /*
168 ============
169 PR_ParseImmediate
170 
171 Looks for a preexisting constant
172 ============
173 */
PR_ParseImmediate(void)174 def_t	*PR_ParseImmediate (void)
175 {
176 	def_t	*cn;
177 
178 // check for a constant with the same value
179 	for (cn=pr.def_head.next ; cn ; cn=cn->next)
180 	{
181 		if (!cn->initialized)
182 			continue;
183 		if (cn->type != pr_immediate_type)
184 			continue;
185 		if (pr_immediate_type == &type_string)
186 		{
187 			if (!strcmp(G_STRING(cn->ofs), pr_immediate_string) )
188 			{
189 				PR_Lex ();
190 				return cn;
191 			}
192 		}
193 		else if (pr_immediate_type == &type_float)
194 		{
195 			if ( G_FLOAT(cn->ofs) == pr_immediate._float )
196 			{
197 				PR_Lex ();
198 				return cn;
199 			}
200 		}
201 		else if	(pr_immediate_type == &type_vector)
202 		{
203 			if ( ( G_FLOAT(cn->ofs) == pr_immediate.vector[0] )
204 			&& ( G_FLOAT(cn->ofs+1) == pr_immediate.vector[1] )
205 			&& ( G_FLOAT(cn->ofs+2) == pr_immediate.vector[2] ) )
206 			{
207 				PR_Lex ();
208 				return cn;
209 			}
210 		}
211 		else
212 			PR_ParseError ("weird immediate type");
213 	}
214 
215 // allocate a new one
216 	cn = malloc (sizeof(def_t));
217 	cn->next = NULL;
218 	pr.def_tail->next = cn;
219 	pr.def_tail = cn;
220 	cn->type = pr_immediate_type;
221 	cn->name = "IMMEDIATE";
222 	cn->initialized = 1;
223 	cn->scope = NULL;		// always share immediates
224 
225 // copy the immediate to the global area
226 	cn->ofs = numpr_globals;
227 	pr_global_defs[cn->ofs] = cn;
228 	numpr_globals += type_size[pr_immediate_type->type];
229 	if (pr_immediate_type == &type_string)
230 		pr_immediate.string = CopyString (pr_immediate_string);
231 
232 	memcpy (pr_globals + cn->ofs, &pr_immediate, 4*type_size[pr_immediate_type->type]);
233 
234 	PR_Lex ();
235 
236 	return cn;
237 }
238 
239 
PrecacheSound(def_t * e,int ch)240 void PrecacheSound (def_t *e, int ch)
241 {
242 	char	*n;
243 	int		i;
244 
245 	if (!e->ofs)
246 		return;
247 	n = G_STRING(e->ofs);
248 	for (i=0 ; i<numsounds ; i++)
249 		if (!strcmp(n, precache_sounds[i]))
250 			return;
251 	if (numsounds == MAX_SOUNDS)
252 		Error ("PrecacheSound: numsounds == MAX_SOUNDS");
253 	strcpy (precache_sounds[i], n);
254 	if (ch >= '1'  && ch <= '9')
255 		precache_sounds_block[i] = ch - '0';
256 	else
257 		precache_sounds_block[i] = 1;
258 	numsounds++;
259 }
260 
PrecacheModel(def_t * e,int ch)261 void PrecacheModel (def_t *e, int ch)
262 {
263 	char	*n;
264 	int		i;
265 
266 	if (!e->ofs)
267 		return;
268 	n = G_STRING(e->ofs);
269 	for (i=0 ; i<nummodels ; i++)
270 		if (!strcmp(n, precache_models[i]))
271 			return;
272 	if (numsounds == MAX_SOUNDS)
273 		Error ("PrecacheModels: numsounds == MAX_SOUNDS");
274 	strcpy (precache_models[i], n);
275 	if (ch >= '1'  && ch <= '9')
276 		precache_models_block[i] = ch - '0';
277 	else
278 		precache_models_block[i] = 1;
279 	nummodels++;
280 }
281 
PrecacheFile(def_t * e,int ch)282 void PrecacheFile (def_t *e, int ch)
283 {
284 	char	*n;
285 	int		i;
286 
287 	if (!e->ofs)
288 		return;
289 	n = G_STRING(e->ofs);
290 	for (i=0 ; i<numfiles ; i++)
291 		if (!strcmp(n, precache_files[i]))
292 			return;
293 	if (numfiles == MAX_FILES)
294 		Error ("PrecacheFile: numfiles == MAX_FILES");
295 	strcpy (precache_files[i], n);
296 	if (ch >= '1'  && ch <= '9')
297 		precache_files_block[i] = ch - '0';
298 	else
299 		precache_files_block[i] = 1;
300 	numfiles++;
301 }
302 
303 /*
304 ============
305 PR_ParseFunctionCall
306 ============
307 */
PR_ParseFunctionCall(def_t * func)308 def_t *PR_ParseFunctionCall (def_t *func)
309 {
310 	def_t		*e;
311 	int			arg;
312 	type_t		*t;
313 
314 	t = func->type;
315 
316 	if (t->type != ev_function)
317 		PR_ParseError ("not a function");
318 
319 // copy the arguments to the global parameter variables
320 	arg = 0;
321 	if (!PR_Check(")"))
322 	{
323 		do
324 		{
325 			if (t->num_parms != -1 && arg >= t->num_parms)
326 				PR_ParseError ("too many parameters");
327 			e = PR_Expression (TOP_PRIORITY);
328 
329 			if (arg == 0 && func->name)
330 			{
331 			// save information for model and sound caching
332 				if (!strncmp(func->name,"precache_sound", 14))
333 					PrecacheSound (e, func->name[14]);
334 				else if (!strncmp(func->name,"precache_model", 14))
335 					PrecacheModel (e, func->name[14]);
336 				else if (!strncmp(func->name,"precache_file", 13))
337 					PrecacheFile (e, func->name[13]);
338 			}
339 
340 			if (t->num_parms != -1 && ( e->type != t->parm_types[arg] ) )
341 				PR_ParseError ("type mismatch on parm %i", arg);
342 		// a vector copy will copy everything
343 			def_parms[arg].type = t->parm_types[arg];
344 			PR_Statement (&pr_opcodes[OP_STORE_V], e, &def_parms[arg]);
345 			arg++;
346 		} while (PR_Check (","));
347 
348 		if (t->num_parms != -1 && arg != t->num_parms)
349 			PR_ParseError ("too few parameters");
350 		PR_Expect (")");
351 	}
352 	if (arg >8)
353 		PR_ParseError ("More than eight parameters");
354 
355 
356 	PR_Statement (&pr_opcodes[OP_CALL0+arg], func, 0);
357 
358 	def_ret.type = t->aux_type;
359 	return &def_ret;
360 }
361 
362 /*
363 ============
364 PR_ParseValue
365 
366 Returns the global ofs for the current token
367 ============
368 */
PR_ParseValue(void)369 def_t	*PR_ParseValue (void)
370 {
371 	def_t		*d;
372 	char		*name;
373 
374 // if the token is an immediate, allocate a constant for it
375 	if (pr_token_type == tt_immediate)
376 		return PR_ParseImmediate ();
377 
378 	name = PR_ParseName ();
379 
380 // look through the defs
381 	d = PR_GetDef (NULL, name, pr_scope, false);
382 	if (!d)
383 		PR_ParseError ("Unknown value \"%s\"", name);
384 	return d;
385 }
386 
387 
388 /*
389 ============
390 PR_Term
391 ============
392 */
PR_Term(void)393 def_t *PR_Term (void)
394 {
395 	def_t	*e, *e2;
396 	etype_t	t;
397 
398 	if (PR_Check ("!"))
399 	{
400 		e = PR_Expression (NOT_PRIORITY);
401 		t = e->type->type;
402 		if (t == ev_float)
403 			e2 = PR_Statement (&pr_opcodes[OP_NOT_F], e, 0);
404 		else if (t == ev_string)
405 			e2 = PR_Statement (&pr_opcodes[OP_NOT_S], e, 0);
406 		else if (t == ev_entity)
407 			e2 = PR_Statement (&pr_opcodes[OP_NOT_ENT], e, 0);
408 		else if (t == ev_vector)
409 			e2 = PR_Statement (&pr_opcodes[OP_NOT_V], e, 0);
410 		else if (t == ev_function)
411 			e2 = PR_Statement (&pr_opcodes[OP_NOT_FNC], e, 0);
412 		else
413 		{
414 			e2 = NULL;		// shut up compiler warning;
415 			PR_ParseError ("type mismatch for !");
416 		}
417 		return e2;
418 	}
419 
420 	if (PR_Check ("("))
421 	{
422 		e = PR_Expression (TOP_PRIORITY);
423 		PR_Expect (")");
424 		return e;
425 	}
426 
427 	return PR_ParseValue ();
428 }
429 
430 /*
431 ==============
432 PR_Expression
433 ==============
434 */
435 
PR_Expression(int priority)436 def_t *PR_Expression (int priority)
437 {
438 	opcode_t	*op, *oldop;
439 	def_t		*e, *e2;
440 	etype_t		type_a, type_b, type_c;
441 
442 	if (priority == 0)
443 		return PR_Term ();
444 
445 	e = PR_Expression (priority-1);
446 
447 	while (1)
448 	{
449 		if (priority == 1 && PR_Check ("(") )
450 			return PR_ParseFunctionCall (e);
451 
452 		for (op=pr_opcodes ; op->name ; op++)
453 		{
454 			if (op->priority != priority)
455 				continue;
456 			if (!PR_Check (op->name))
457 				continue;
458 			if ( op->right_associative )
459 			{
460 			// if last statement is an indirect, change it to an address of
461 				if ( (unsigned)(statements[numstatements-1].op - OP_LOAD_F) < 6 )
462 				{
463 					statements[numstatements-1].op = OP_ADDRESS;
464 					def_pointer.type->aux_type = e->type;
465 					e->type = def_pointer.type;
466 				}
467 				e2 = PR_Expression (priority);
468 			}
469 			else
470 				e2 = PR_Expression (priority-1);
471 
472 		// type check
473 			type_a = e->type->type;
474 			type_b = e2->type->type;
475 
476 			if (op->name[0] == '.')// field access gets type from field
477 			{
478 				if (e2->type->aux_type)
479 					type_c = e2->type->aux_type->type;
480 				else
481 					type_c = -1;	// not a field
482 			}
483 			else
484 				type_c = ev_void;
485 
486 			oldop = op;
487 			while (type_a != op->type_a->type->type
488 			|| type_b != op->type_b->type->type
489 			|| (type_c != ev_void && type_c != op->type_c->type->type) )
490 			{
491 				op++;
492 				if (!op->name || strcmp (op->name , oldop->name))
493 					PR_ParseError ("type mismatch for %s", oldop->name);
494 			}
495 
496 			if (type_a == ev_pointer && type_b != e->type->aux_type->type)
497 				PR_ParseError ("type mismatch for %s", op->name);
498 
499 
500 			if (op->right_associative)
501 				e = PR_Statement (op, e2, e);
502 			else
503 				e = PR_Statement (op, e, e2);
504 
505 			if (type_c != ev_void)	// field access gets type from field
506 				e->type = e2->type->aux_type;
507 
508 			break;
509 		}
510 		if (!op->name)
511 			break;	// next token isn't at this priority level
512 	}
513 
514 	return e;
515 }
516 
517 
518 /*
519 ============
520 PR_ParseStatement
521 
522 ============
523 */
PR_ParseStatement(void)524 void PR_ParseStatement (void)
525 {
526 	def_t				*e;
527 	dstatement_t		*patch1, *patch2;
528 
529 	if (PR_Check ("{"))
530 	{
531 		do
532 		{
533 			PR_ParseStatement ();
534 		} while (!PR_Check ("}"));
535 		return;
536 	}
537 
538 	if (PR_Check("return"))
539 	{
540 		if (PR_Check (";"))
541 		{
542 			PR_Statement (&pr_opcodes[OP_RETURN], 0, 0);
543 			return;
544 		}
545 		e = PR_Expression (TOP_PRIORITY);
546 		PR_Expect (";");
547 		PR_Statement (&pr_opcodes[OP_RETURN], e, 0);
548 		return;
549 	}
550 
551 	if (PR_Check("while"))
552 	{
553 		PR_Expect ("(");
554 		patch2 = &statements[numstatements];
555 		e = PR_Expression (TOP_PRIORITY);
556 		PR_Expect (")");
557 		patch1 = &statements[numstatements];
558 		PR_Statement (&pr_opcodes[OP_IFNOT], e, 0);
559 		PR_ParseStatement ();
560 		junkdef.ofs = patch2 - &statements[numstatements];
561 		PR_Statement (&pr_opcodes[OP_GOTO], &junkdef, 0);
562 		patch1->b = &statements[numstatements] - patch1;
563 		return;
564 	}
565 
566 	if (PR_Check("do"))
567 	{
568 		patch1 = &statements[numstatements];
569 		PR_ParseStatement ();
570 		PR_Expect ("while");
571 		PR_Expect ("(");
572 		e = PR_Expression (TOP_PRIORITY);
573 		PR_Expect (")");
574 		PR_Expect (";");
575 		junkdef.ofs = patch1 - &statements[numstatements];
576 		PR_Statement (&pr_opcodes[OP_IF], e, &junkdef);
577 		return;
578 	}
579 
580 	if (PR_Check("local"))
581 	{
582 		PR_ParseDefs ();
583 		locals_end = numpr_globals;
584 		return;
585 	}
586 
587 	if (PR_Check("if"))
588 	{
589 		PR_Expect ("(");
590 		e = PR_Expression (TOP_PRIORITY);
591 		PR_Expect (")");
592 
593 		patch1 = &statements[numstatements];
594 		PR_Statement (&pr_opcodes[OP_IFNOT], e, 0);
595 
596 		PR_ParseStatement ();
597 
598 		if (PR_Check ("else"))
599 		{
600 			patch2 = &statements[numstatements];
601 			PR_Statement (&pr_opcodes[OP_GOTO], 0, 0);
602 			patch1->b = &statements[numstatements] - patch1;
603 			PR_ParseStatement ();
604 			patch2->a = &statements[numstatements] - patch2;
605 		}
606 		else
607 			patch1->b = &statements[numstatements] - patch1;
608 
609 		return;
610 	}
611 
612 	PR_Expression (TOP_PRIORITY);
613 	PR_Expect (";");
614 }
615 
616 
617 /*
618 ==============
619 PR_ParseState
620 
621 States are special functions made for convenience.  They automatically
622 set frame, nextthink (implicitly), and think (allowing forward definitions).
623 
624 // void() name = [framenum, nextthink] {code}
625 // expands to:
626 // function void name ()
627 // {
628 //		self.frame=framenum;
629 //		self.nextthink = time + 0.1;
630 //		self.think = nextthink
631 //		<code>
632 // };
633 ==============
634 */
PR_ParseState(void)635 void PR_ParseState (void)
636 {
637 	char	*name;
638 	def_t	*s1, *def;
639 
640 	if (pr_token_type != tt_immediate || pr_immediate_type != &type_float)
641 		PR_ParseError ("state frame must be a number");
642 	s1 = PR_ParseImmediate ();
643 
644 	PR_Expect (",");
645 
646 	name = PR_ParseName ();
647 	def = PR_GetDef (&type_function, name,0, true);
648 
649 	PR_Expect ("]");
650 
651 	PR_Statement (&pr_opcodes[OP_STATE], s1, def);
652 }
653 
654 /*
655 ============
656 PR_ParseImmediateStatements
657 
658 Parse a function body
659 ============
660 */
PR_ParseImmediateStatements(type_t * type)661 function_t *PR_ParseImmediateStatements (type_t *type)
662 {
663 	int			i;
664 	function_t	*f;
665 	def_t		*defs[MAX_PARMS];
666 
667 	f = malloc (sizeof(function_t));
668 
669 //
670 // check for builtin function definition #1, #2, etc
671 //
672 	if (PR_Check ("#"))
673 	{
674 		if (pr_token_type != tt_immediate
675 		|| pr_immediate_type != &type_float
676 		|| pr_immediate._float != (int)pr_immediate._float)
677 			PR_ParseError ("Bad builtin immediate");
678 		f->builtin = (int)pr_immediate._float;
679 		PR_Lex ();
680 		return f;
681 	}
682 
683 	f->builtin = 0;
684 //
685 // define the parms
686 //
687 	for (i=0 ; i<type->num_parms ; i++)
688 	{
689 		defs[i] = PR_GetDef (type->parm_types[i], pr_parm_names[i], pr_scope, true);
690 		f->parm_ofs[i] = defs[i]->ofs;
691 		if (i > 0 && f->parm_ofs[i] < f->parm_ofs[i-1])
692 			Error ("bad parm order");
693 	}
694 
695 	f->code = numstatements;
696 
697 //
698 // check for a state opcode
699 //
700 	if (PR_Check ("["))
701 		PR_ParseState ();
702 
703 //
704 // parse regular statements
705 //
706 	PR_Expect ("{");
707 
708 	while (!PR_Check("}"))
709 		PR_ParseStatement ();
710 
711 // emit an end of statements opcode
712 	PR_Statement (pr_opcodes, 0,0);
713 
714 
715 	return f;
716 }
717 
718 /*
719 ============
720 PR_GetDef
721 
722 If type is NULL, it will match any type
723 If allocate is true, a new def will be allocated if it can't be found
724 ============
725 */
PR_GetDef(type_t * type,char * name,def_t * scope,boolean allocate)726 def_t *PR_GetDef (type_t *type, char *name, def_t *scope, boolean allocate)
727 {
728 	def_t		*def;
729 	char element[MAX_NAME];
730 
731 // see if the name is already in use
732 	for (def = pr.def_head.next ; def ; def = def->next)
733 		if (!strcmp(def->name,name) )
734 		{
735 			if ( def->scope && def->scope != scope)
736 				continue;		// in a different function
737 
738 			if (type && def->type != type)
739 				PR_ParseError ("Type mismatch on redeclaration of %s",name);
740 			return def;
741 		}
742 
743 	if (!allocate)
744 		return NULL;
745 
746 // allocate a new def
747 	def = malloc (sizeof(def_t));
748 	memset (def, 0, sizeof(*def));
749 	def->next = NULL;
750 	pr.def_tail->next = def;
751 	pr.def_tail = def;
752 
753 	def->name = malloc (strlen(name)+1);
754 	strcpy (def->name, name);
755 	def->type = type;
756 
757 	def->scope = scope;
758 
759 	def->ofs = numpr_globals;
760 	pr_global_defs[numpr_globals] = def;
761 
762 //
763 // make automatic defs for the vectors elements
764 // .origin can be accessed as .origin_x, .origin_y, and .origin_z
765 //
766 	if (type->type == ev_vector)
767 	{
768 		sprintf (element, "%s_x",name);
769 		PR_GetDef (&type_float, element, scope, true);
770 
771 		sprintf (element, "%s_y",name);
772 		PR_GetDef (&type_float, element, scope, true);
773 
774 		sprintf (element, "%s_z",name);
775 		PR_GetDef (&type_float, element, scope, true);
776 	}
777 	else
778 		numpr_globals += type_size[type->type];
779 
780 	if (type->type == ev_field)
781 	{
782 		*(int *)&pr_globals[def->ofs] = pr.size_fields;
783 
784 		if (type->aux_type->type == ev_vector)
785 		{
786 			sprintf (element, "%s_x",name);
787 			PR_GetDef (&type_floatfield, element, scope, true);
788 
789 			sprintf (element, "%s_y",name);
790 			PR_GetDef (&type_floatfield, element, scope, true);
791 
792 			sprintf (element, "%s_z",name);
793 			PR_GetDef (&type_floatfield, element, scope, true);
794 		}
795 		else
796 			pr.size_fields += type_size[type->aux_type->type];
797 	}
798 
799 //	if (pr_dumpasm)
800 //		PR_PrintOfs (def->ofs);
801 
802 	return def;
803 }
804 
805 /*
806 ================
807 PR_ParseDefs
808 
809 Called at the outer layer and when a local statement is hit
810 ================
811 */
PR_ParseDefs(void)812 void PR_ParseDefs (void)
813 {
814 	char		*name;
815 	type_t		*type;
816 	def_t		*def;
817 	function_t	*f;
818 	dfunction_t	*df;
819 	int			i;
820 	int			locals_start;
821 
822 	type = PR_ParseType ();
823 
824 	if (pr_scope && (type->type == ev_field || type->type == ev_function) )
825 		PR_ParseError ("Fields and functions must be global");
826 
827 	do
828 	{
829 		name = PR_ParseName ();
830 
831 		def = PR_GetDef (type, name, pr_scope, true);
832 
833 // check for an initialization
834 		if ( PR_Check ("=") )
835 		{
836 			if (def->initialized)
837 				PR_ParseError ("%s redeclared", name);
838 
839 			if (type->type == ev_function)
840 			{
841 				locals_start = locals_end = numpr_globals;
842 				pr_scope = def;
843 				f = PR_ParseImmediateStatements (type);
844 				pr_scope = NULL;
845 				def->initialized = 1;
846 				G_FUNCTION(def->ofs) = numfunctions;
847 				f->def = def;
848 //				if (pr_dumpasm)
849 //					PR_PrintFunction (def);
850 
851 		// fill in the dfunction
852 				df = &functions[numfunctions];
853 				numfunctions++;
854 				if (f->builtin)
855 					df->first_statement = -f->builtin;
856 				else
857 					df->first_statement = f->code;
858 				df->s_name = CopyString (f->def->name);
859 				df->s_file = s_file;
860 				df->numparms =  f->def->type->num_parms;
861 				df->locals = locals_end - locals_start;
862 				df->parm_start = locals_start;
863 				for (i=0 ; i<df->numparms ; i++)
864 					df->parm_size[i] = type_size[f->def->type->parm_types[i]->type];
865 
866 				continue;
867 			}
868 			else if (pr_immediate_type != type)
869 				PR_ParseError ("wrong immediate type for %s", name);
870 
871 			def->initialized = 1;
872 			memcpy (pr_globals + def->ofs, &pr_immediate, 4*type_size[pr_immediate_type->type]);
873 			PR_Lex ();
874 		}
875 
876 	} while (PR_Check (","));
877 
878 	PR_Expect (";");
879 }
880 
881 /*
882 ============
883 PR_CompileFile
884 
885 compiles the 0 terminated text, adding defintions to the pr structure
886 ============
887 */
PR_CompileFile(char * string,char * filename)888 boolean	PR_CompileFile (char *string, char *filename)
889 {
890 	if (!pr.memory)
891 		Error ("PR_CompileFile: Didn't clear");
892 
893 	PR_ClearGrabMacros ();	// clear the frame macros
894 
895 	pr_file_p = string;
896 	s_file = CopyString (filename);
897 
898 	pr_source_line = 0;
899 
900 	PR_NewLine ();
901 
902 	PR_Lex ();	// read first token
903 
904 	while (pr_token_type != tt_eof)
905 	{
906 		if (setjmp(pr_parse_abort))
907 		{
908 			if (++pr_error_count > MAX_ERRORS)
909 				return false;
910 			PR_SkipToSemicolon ();
911 			if (pr_token_type == tt_eof)
912 				return false;
913 		}
914 
915 		pr_scope = NULL;	// outside all functions
916 
917 		PR_ParseDefs ();
918 	}
919 
920 	return (pr_error_count == 0);
921 }
922 
923