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 }