1 /*
2 * stmt.c
3 *
4 * $Id: stmt.c 5788 2017-01-03 22:23:30Z sezero $
5 *
6 * Copyright (C) 1996-1997 Id Software, Inc.
7 * Copyright (C) 1997-1998 Raven Software Corp.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 *
18 * See the GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25
26 // HEADER FILES ------------------------------------------------------------
27
28 #include "q_stdinc.h"
29 #include "compiler.h"
30 #include "arch_def.h"
31 #include "cmdlib.h"
32 #include "hcc.h"
33
34 // MACROS ------------------------------------------------------------------
35
36 #define MAX_STATEMENT_DEPTH 64
37 #define MAX_CASE 256
38 #define MAX_BREAK 256
39 #define MAX_CONTINUE 128
40
41 // TYPES -------------------------------------------------------------------
42
43 typedef enum
44 {
45 SCONTEXT_FUNCTION,
46 SCONTEXT_IF,
47 SCONTEXT_ELSE,
48 SCONTEXT_DO,
49 SCONTEXT_WHILE,
50 SCONTEXT_UNTIL,
51 SCONTEXT_SWITCH,
52 SCONTEXT_LOOP
53 } scontext_t;
54
55 typedef struct
56 {
57 int level;
58 dstatement_t *patch;
59 } patchInfo_t;
60
61 typedef struct
62 {
63 int level;
64 def_t *value1;
65 def_t *value2;
66 qboolean isDefault;
67 int statement;
68 etype_t type;
69 } caseInfo_t;
70
71 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
72
73 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
74
75 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
76
77 static void ParseStatement(scontext_t owner);
78 static void ParseReturn(void);
79 static void ParseLoop(void);
80 static void ParseWhile(void);
81 static void ParseUntil(void);
82 static void ParseDo(void);
83 static void ParseIf(void);
84 static void ParseLocalDefs(void);
85 static void ParseSwitch(void);
86 static void ParseCase(void);
87 static void ParseBreak(void);
88 static void ParseContinue(void);
89 static void ParseDefault(void);
90 static void ParseThinktime(void);
91 static void AddCase(etype_t type, def_t *value1, def_t *value2, qboolean isDefault);
92 static int GetCaseInfo(caseInfo_t **info);
93 static void AddBreak(void);
94 static qboolean BreakAncestor(void);
95 static void FixBreaks(void);
96 static void AddContinue(void);
97 static qboolean ContinueAncestor(void);
98 static void FixContinues(int statement);
99
100 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
101
102 // PUBLIC DATA DEFINITIONS -------------------------------------------------
103
104 type_t *st_ReturnType;
105 qboolean st_ReturnParsed;
106
107 // PRIVATE DATA DEFINITIONS ------------------------------------------------
108
109 static int CaseIndex;
110 static int BreakIndex;
111 static int ContinueIndex;
112 static int StatementIndex;
113 static int ContextLevel;
114 static scontext_t ContextHistory[MAX_STATEMENT_DEPTH];
115 static caseInfo_t CaseInfo[MAX_CASE];
116 static patchInfo_t BreakInfo[MAX_BREAK];
117 static patchInfo_t ContinueInfo[MAX_CONTINUE];
118
119 static int EnterContext[] =
120 {
121 0, // SCONTEXT_FUNCTION
122 0, // SCONTEXT_IF
123 0, // SCONTEXT_ELSE
124 1, // SCONTEXT_DO
125 1, // SCONTEXT_WHILE
126 1, // SCONTEXT_UNTIL
127 1, // SCONTEXT_SWITCH
128 1 // SCONTEXT_LOOP
129 };
130
131 static qboolean BreakAllowed[] =
132 {
133 false, // SCONTEXT_FUNCTION
134 false, // SCONTEXT_IF
135 false, // SCONTEXT_ELSE
136 true, // SCONTEXT_DO
137 true, // SCONTEXT_WHILE
138 true, // SCONTEXT_UNTIL
139 true, // SCONTEXT_SWITCH
140 true // SCONTEXT_LOOP
141 };
142
143 static qboolean ContinueAllowed[] =
144 {
145 false, // SCONTEXT_FUNCTION
146 false, // SCONTEXT_IF
147 false, // SCONTEXT_ELSE
148 true, // SCONTEXT_DO
149 true, // SCONTEXT_WHILE
150 true, // SCONTEXT_UNTIL
151 false, // SCONTEXT_SWITCH
152 true // SCONTEXT_LOOP
153 };
154
155 // CODE --------------------------------------------------------------------
156
157 //==========================================================================
158 //
159 // ST_ParseStatement
160 //
161 //==========================================================================
162
ST_ParseStatement(void)163 void ST_ParseStatement (void)
164 {
165 CaseIndex = 0;
166 BreakIndex = 0;
167 ContinueIndex = 0;
168 StatementIndex = 0;
169 ContextLevel = 0;
170 ParseStatement(SCONTEXT_FUNCTION);
171 }
172
173 //==========================================================================
174 //
175 // ParseStatement
176 //
177 //==========================================================================
178
ParseStatement(scontext_t owner)179 static void ParseStatement (scontext_t owner)
180 {
181 if (StatementIndex == MAX_STATEMENT_DEPTH)
182 {
183 PR_ParseError("statement overflow");
184 }
185 ContextHistory[StatementIndex++] = owner;
186
187 if (TK_CHECK(TK_LBRACE))
188 {
189 ContextLevel += EnterContext[owner];
190 do
191 {
192 ParseStatement(owner);
193 } while (!TK_CHECK(TK_RBRACE));
194
195 ContextLevel -= EnterContext[owner];
196 StatementIndex--;
197 return;
198 }
199
200 if (TK_CHECK(TK_SEMICOLON))
201 {
202 StatementIndex--;
203 return;
204 }
205 if (LX_CheckFetch("return"))
206 {
207 ParseReturn();
208 StatementIndex--;
209 return;
210 }
211 if (LX_CheckFetch("loop"))
212 {
213 ParseLoop();
214 StatementIndex--;
215 return;
216 }
217 if (LX_CheckFetch("while"))
218 {
219 ParseWhile();
220 StatementIndex--;
221 return;
222 }
223 if (LX_CheckFetch("until"))
224 {
225 ParseUntil();
226 StatementIndex--;
227 return;
228 }
229 if (LX_CheckFetch("do"))
230 {
231 ParseDo();
232 StatementIndex--;
233 return;
234 }
235 if (LX_CheckFetch("switch"))
236 {
237 ParseSwitch();
238 StatementIndex--;
239 return;
240 }
241 if (LX_CheckFetch("case"))
242 {
243 if (owner != SCONTEXT_SWITCH)
244 {
245 PR_ParseError("misplaced case");
246 }
247 ParseCase();
248 StatementIndex--;
249 return;
250 }
251 if (LX_CheckFetch("break"))
252 {
253 if (BreakAncestor() == false)
254 {
255 PR_ParseError("misplaced break");
256 }
257 ParseBreak();
258 StatementIndex--;
259 return;
260 }
261 if (LX_CheckFetch("continue"))
262 {
263 if (ContinueAncestor() == false)
264 {
265 PR_ParseError("misplaced continue");
266 }
267 ParseContinue();
268 StatementIndex--;
269 return;
270 }
271 if (LX_CheckFetch("default"))
272 {
273 ParseDefault();
274 StatementIndex--;
275 return;
276 }
277 if (LX_CheckFetch("thinktime"))
278 {
279 ParseThinktime();
280 StatementIndex--;
281 return;
282 }
283 if (LX_CheckFetch("local"))
284 {
285 ParseLocalDefs();
286 StatementIndex--;
287 return;
288 }
289 if (LX_Check("float") || LX_Check("vector")
290 || LX_Check("entity") || LX_Check("string")
291 || LX_Check("void"))
292 {
293 ParseLocalDefs();
294 StatementIndex--;
295 return;
296 }
297 if (LX_CheckFetch("if"))
298 {
299 ParseIf();
300 StatementIndex--;
301 return;
302 }
303
304 EX_Expression(TOP_PRIORITY);
305 LX_Require(";");
306 StatementIndex--;
307 }
308
309 //==========================================================================
310 //
311 // ParseReturn
312 //
313 //==========================================================================
314
ParseReturn(void)315 static void ParseReturn (void)
316 {
317 def_t *e;
318
319 //if (TK_CHECK(TK_SEMICOLON))
320 if (pr_tokenclass == TK_SEMICOLON)
321 {
322 if (st_ReturnType->type != ev_void)
323 {
324 PR_ParseError("missing return value");
325 }
326 CO_GenCode(&pr_opcodes[OP_RETURN], NULL, NULL);
327 LX_Fetch();
328 return;
329 }
330 e = EX_Expression(TOP_PRIORITY);
331 if (e->type != st_ReturnType)
332 {
333 PR_ParseError("return type mismatch");
334 }
335 LX_Require(";");
336 CO_GenCode(&pr_opcodes[OP_RETURN], e, NULL);
337 st_ReturnParsed = true;
338 }
339
340 //==========================================================================
341 //
342 // ParseLoop
343 //
344 //==========================================================================
345
ParseLoop(void)346 static void ParseLoop (void)
347 {
348 dstatement_t *patch1;
349 def_t tempDef;
350 int contStatement;
351
352 contStatement = numstatements;
353 patch1 = &statements[numstatements];
354 ParseStatement(SCONTEXT_LOOP);
355 tempDef.ofs = patch1 - &statements[numstatements];
356 CO_GenCode(&pr_opcodes[OP_GOTO], &tempDef, NULL);
357 FixContinues(contStatement);
358 FixBreaks();
359 }
360
361 //==========================================================================
362 //
363 // ParseWhile
364 //
365 //==========================================================================
366
ParseWhile(void)367 static void ParseWhile (void)
368 {
369 def_t *e;
370 dstatement_t *patch1, *patch2;
371 def_t tempDef;
372 int contStatement;
373
374 LX_Require("(");
375 contStatement = numstatements;
376 patch2 = &statements[numstatements];
377 e = EX_Expression(TOP_PRIORITY);
378 LX_Require(")");
379 LX_CheckFetch("do");
380 patch1 = &statements[numstatements];
381 CO_GenCode(&pr_opcodes[OP_IFNOT], e, NULL);
382 ParseStatement(SCONTEXT_WHILE);
383 tempDef.ofs = patch2 - &statements[numstatements];
384 CO_GenCode(&pr_opcodes[OP_GOTO], &tempDef, NULL);
385 patch1->b = &statements[numstatements] - patch1;
386 FixContinues(contStatement);
387 FixBreaks();
388 }
389
390 //==========================================================================
391 //
392 // ParseUntil
393 //
394 //==========================================================================
395
ParseUntil(void)396 static void ParseUntil (void)
397 {
398 def_t *e;
399 dstatement_t *patch1, *patch2;
400 def_t tempDef;
401 int contStatement;
402
403 LX_Require("(");
404 contStatement = numstatements;
405 patch2 = &statements[numstatements];
406 e = EX_Expression(TOP_PRIORITY);
407 LX_Require(")");
408 LX_CheckFetch("do");
409 patch1 = &statements[numstatements];
410 CO_GenCode(&pr_opcodes[OP_IF], e, NULL);
411 ParseStatement(SCONTEXT_UNTIL);
412 tempDef.ofs = patch2 - &statements[numstatements];
413 CO_GenCode(&pr_opcodes[OP_GOTO], &tempDef, NULL);
414 patch1->b = &statements[numstatements] - patch1;
415 FixContinues(contStatement);
416 FixBreaks();
417 }
418
419 //==========================================================================
420 //
421 // ParseDo
422 //
423 //==========================================================================
424
ParseDo(void)425 static void ParseDo (void)
426 {
427 def_t *e;
428 dstatement_t *patch1;
429 int ifOpcode;
430 def_t tempDef;
431 int contStatement;
432
433 patch1 = &statements[numstatements];
434 ParseStatement(SCONTEXT_DO);
435 if (LX_CheckFetch("until"))
436 {
437 ifOpcode = OP_IFNOT;
438 }
439 else
440 {
441 LX_Require("while");
442 ifOpcode = OP_IF;
443 }
444 LX_Require("(");
445 contStatement = numstatements;
446 e = EX_Expression(TOP_PRIORITY);
447 LX_Require(")");
448 LX_Require(";");
449 tempDef.ofs = patch1 - &statements[numstatements];
450 CO_GenCode(&pr_opcodes[ifOpcode], e, &tempDef);
451 FixContinues(contStatement);
452 FixBreaks();
453 }
454
455 //==========================================================================
456 //
457 // ParseIf
458 //
459 //==========================================================================
460
ParseIf(void)461 static void ParseIf (void)
462 {
463 def_t *e;
464 dstatement_t *patch1, *patch2;
465 int ifOpcode;
466
467 if (LX_CheckFetch("not"))
468 {
469 ifOpcode = OP_IF;
470 }
471 else
472 {
473 ifOpcode = OP_IFNOT;
474 }
475
476 LX_Require("(");
477 e = EX_Expression(TOP_PRIORITY);
478 LX_Require(")");
479
480 patch1 = &statements[numstatements];
481 CO_GenCode(&pr_opcodes[ifOpcode], e, NULL);
482
483 ParseStatement(SCONTEXT_IF);
484
485 if (LX_CheckFetch("else"))
486 {
487 patch2 = &statements[numstatements];
488 CO_GenCode(&pr_opcodes[OP_GOTO], NULL, NULL);
489 patch1->b = &statements[numstatements] - patch1;
490 ParseStatement(SCONTEXT_ELSE);
491 patch2->a = &statements[numstatements] - patch2;
492 }
493 else
494 {
495 patch1->b = &statements[numstatements] - patch1;
496 }
497 }
498
499 //==========================================================================
500 //
501 // ParseLocalDefs
502 //
503 //==========================================================================
504
ParseLocalDefs(void)505 static void ParseLocalDefs (void)
506 {
507 CO_ParseDefs();
508 locals_end = numpr_globals;
509 }
510
511 //==========================================================================
512 //
513 // ParseSwitch
514 //
515 //==========================================================================
516
ParseSwitch(void)517 static void ParseSwitch (void)
518 {
519 int i;
520 def_t *e;
521 int count;
522 int opcode;
523 def_t tempDef;
524 caseInfo_t *cInfo;
525 dstatement_t *patch;
526 int defaultStatement;
527 etype_t switchType;
528
529 LX_Require("(");
530 e = EX_Expression(TOP_PRIORITY);
531 LX_Require(")");
532 switchType = e->type->type;
533 switch (switchType)
534 {
535 case ev_float:
536 opcode = OP_SWITCH_F;
537 break;
538 case ev_string:
539 opcode = OP_SWITCH_S;
540 break;
541 case ev_vector:
542 opcode = OP_SWITCH_V;
543 break;
544 case ev_entity:
545 opcode = OP_SWITCH_E;
546 break;
547 case ev_function:
548 opcode = OP_SWITCH_FNC;
549 break;
550 default:
551 PR_ParseError("bad type for switch");
552 return; /* silence compiler */
553 }
554 patch = &statements[numstatements];
555 CO_GenCode(&pr_opcodes[opcode], e, NULL);
556 ParseStatement(SCONTEXT_SWITCH);
557
558 // Switch opcode fixup
559 patch->b = &statements[numstatements]-patch;
560
561 if (statements[numstatements-1].op != OP_GOTO)
562 { // Implicit break
563 patch->b++; /* because we are generating an additional op */
564 patch = &statements[numstatements];
565 CO_GenCode(&pr_opcodes[OP_GOTO], NULL, NULL);
566 }
567 else
568 {
569 patch = NULL;
570 }
571
572 count = GetCaseInfo(&cInfo);
573 if (count == 0)
574 {
575 PR_ParseError("switch has no case");
576 }
577 defaultStatement = -1;
578 for (i = 0; i < count; i++, cInfo++)
579 {
580 if (cInfo->isDefault == true)
581 {
582 defaultStatement = cInfo->statement;
583 continue;
584 }
585 if (cInfo->type != switchType)
586 {
587 PR_ParseError("type mismatch within switch");
588 }
589 tempDef.ofs = &statements[cInfo->statement]
590 -&statements[numstatements];
591 if (cInfo->value2 == NULL)
592 {
593 CO_GenCodeDirect(&pr_opcodes[OP_CASE],
594 cInfo->value1, &tempDef, NULL);
595 }
596 else
597 {
598 CO_GenCodeDirect(&pr_opcodes[OP_CASERANGE],
599 cInfo->value1, cInfo->value2, &tempDef);
600 }
601 }
602 if (defaultStatement != -1)
603 {
604 tempDef.ofs = &statements[defaultStatement]
605 -&statements[numstatements];
606 CO_GenCode(&pr_opcodes[OP_GOTO], &tempDef, NULL);
607 }
608
609 if (patch != NULL)
610 { // Implicit break fixup
611 patch->a = &statements[numstatements]-patch;
612 }
613
614 FixBreaks();
615 }
616
617 //==========================================================================
618 //
619 // ParseCase
620 //
621 //==========================================================================
622
ParseCase(void)623 static void ParseCase (void)
624 {
625 def_t *e;
626 def_t *e2;
627
628 do
629 {
630 e = EX_Expression(TOP_PRIORITY);
631 if (TK_CHECK(TK_RANGE))
632 {
633 e2 = EX_Expression(TOP_PRIORITY);
634 if (e->type->type != ev_float || e2->type->type != ev_float)
635 {
636 PR_ParseError("type mismatch for case range");
637 }
638 }
639 else
640 {
641 e2 = NULL;
642 }
643 AddCase(e->type->type, e, e2, false);
644 } while (TK_CHECK(TK_COMMA));
645
646 LX_Require(":");
647 }
648
649 //==========================================================================
650 //
651 // AddCase
652 //
653 //==========================================================================
654
AddCase(etype_t type,def_t * value1,def_t * value2,qboolean isDefault)655 static void AddCase(etype_t type, def_t *value1, def_t *value2, qboolean isDefault)
656 {
657 if (CaseIndex == MAX_CASE)
658 {
659 PR_ParseError("case overflow");
660 }
661 CaseInfo[CaseIndex].level = ContextLevel;
662 CaseInfo[CaseIndex].value1 = value1;
663 CaseInfo[CaseIndex].value2 = value2;
664 CaseInfo[CaseIndex].isDefault = isDefault;
665 CaseInfo[CaseIndex].statement = numstatements;
666 CaseInfo[CaseIndex].type = type;
667 CaseIndex++;
668 }
669
670 //==========================================================================
671 //
672 // GetCaseInfo
673 //
674 //==========================================================================
675
GetCaseInfo(caseInfo_t ** info)676 static int GetCaseInfo (caseInfo_t **info)
677 {
678 int i;
679 int count;
680
681 i = CaseIndex;
682 while (i > 0 && CaseInfo[i-1].level > ContextLevel)
683 {
684 i--;
685 }
686 *info = &CaseInfo[i];
687 count = CaseIndex-i;
688 CaseIndex = i;
689 return count;
690 }
691
692 //==========================================================================
693 //
694 // ParseBreak
695 //
696 //==========================================================================
697
ParseBreak(void)698 static void ParseBreak (void)
699 {
700 LX_Require(";");
701 AddBreak();
702 }
703
704 //==========================================================================
705 //
706 // AddBreak
707 //
708 //==========================================================================
709
AddBreak(void)710 static void AddBreak (void)
711 {
712 if (BreakIndex == MAX_BREAK)
713 {
714 PR_ParseError("break overflow");
715 }
716 BreakInfo[BreakIndex].level = ContextLevel;
717 BreakInfo[BreakIndex].patch = &statements[numstatements];
718 CO_GenCode(&pr_opcodes[OP_GOTO], NULL, NULL);
719 BreakIndex++;
720 }
721
722 //==========================================================================
723 //
724 // FixBreaks
725 //
726 //==========================================================================
727
FixBreaks(void)728 static void FixBreaks (void)
729 {
730 if (BreakIndex == 0)
731 {
732 return;
733 }
734 while (BreakInfo[BreakIndex-1].level > ContextLevel)
735 {
736 BreakIndex--;
737 BreakInfo[BreakIndex].patch->a =
738 &statements[numstatements]-BreakInfo[BreakIndex].patch;
739 if (BreakIndex == 0)
740 {
741 return;
742 }
743 }
744 }
745
746 //==========================================================================
747 //
748 // BreakAncestor
749 //
750 //==========================================================================
751
BreakAncestor(void)752 static qboolean BreakAncestor (void)
753 {
754 int i;
755
756 for (i = 0; i < StatementIndex; i++)
757 {
758 if (BreakAllowed[ContextHistory[i]])
759 {
760 return true;
761 }
762 }
763 return false;
764 }
765
766 //==========================================================================
767 //
768 // ParseDefault
769 //
770 //==========================================================================
771
ParseDefault(void)772 static void ParseDefault (void)
773 {
774 LX_Require(":");
775 AddCase(ev_void, NULL, NULL, true);
776 }
777
778 //==========================================================================
779 //
780 // ParseContinue
781 //
782 //==========================================================================
783
ParseContinue(void)784 static void ParseContinue (void)
785 {
786 LX_Require(";");
787 AddContinue();
788 }
789
790 //==========================================================================
791 //
792 // AddContinue
793 //
794 //==========================================================================
795
AddContinue(void)796 static void AddContinue (void)
797 {
798 if (ContinueIndex == MAX_CONTINUE)
799 {
800 PR_ParseError("continue overflow");
801 }
802 ContinueInfo[ContinueIndex].level = ContextLevel;
803 ContinueInfo[ContinueIndex].patch = &statements[numstatements];
804 CO_GenCode(&pr_opcodes[OP_GOTO], NULL, NULL);
805 ContinueIndex++;
806 }
807
808 //==========================================================================
809 //
810 // FixContinues
811 //
812 //==========================================================================
813
FixContinues(int statement)814 static void FixContinues (int statement)
815 {
816 if (ContinueIndex == 0)
817 {
818 return;
819 }
820 while (ContinueInfo[ContinueIndex-1].level > ContextLevel)
821 {
822 ContinueIndex--;
823 ContinueInfo[ContinueIndex].patch->a =
824 &statements[statement]-ContinueInfo[ContinueIndex].patch;
825 if (ContinueIndex == 0)
826 {
827 return;
828 }
829 }
830 }
831
832 //==========================================================================
833 //
834 // ContinueAncestor
835 //
836 //==========================================================================
837
ContinueAncestor(void)838 static qboolean ContinueAncestor (void)
839 {
840 int i;
841
842 for (i = 0; i < StatementIndex; i++)
843 {
844 if (ContinueAllowed[ContextHistory[i]])
845 {
846 return true;
847 }
848 }
849 return false;
850 }
851
852 //==========================================================================
853 //
854 // ParseThinktime
855 //
856 //==========================================================================
857
ParseThinktime(void)858 static void ParseThinktime (void)
859 {
860 def_t *expr1;
861 def_t *expr2;
862
863 expr1 = EX_Expression(TOP_PRIORITY);
864 LX_Require(":");
865 expr2 = EX_Expression(TOP_PRIORITY);
866 if (expr1->type->type != ev_entity || expr2->type->type != ev_float)
867 {
868 PR_ParseError("type mismatch for thinktime");
869 }
870 LX_Require(";");
871 CO_GenCode(&pr_opcodes[OP_THINKTIME], expr1, expr2);
872 }
873