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