]> de.git.xonotic.org Git - voretournament/voretournament.git/blob - misc/source/fteqcc-src/qcc_pr_comp.c
badefcac4e2ff9b58f8355347db3fab4ee963a72
[voretournament/voretournament.git] / misc / source / fteqcc-src / qcc_pr_comp.c
1 #ifndef MINIMAL
2
3 #include "qcc.h"
4 void QCC_PR_ParseAsm(void);
5
6 #define MEMBERFIELDNAME "__m%s"
7
8 #define STRCMP(s1,s2) (((*s1)!=(*s2)) || strcmp(s1+1,s2+1))     //saves about 2-6 out of 120 - expansion of idea from fastqcc
9 #define STRNCMP(s1,s2,l) (((*s1)!=(*s2)) || strncmp(s1+1,s2+1,l))       //pathetic saving here.
10
11 extern char *compilingfile;
12
13 int conditional;
14
15 //standard qcc keywords
16 #define keyword_do              1
17 #define keyword_return  1
18 #define keyword_if              1
19 #define keyword_else    1
20 #define keyword_local   1
21 #define keyword_while   1
22
23 //extended keywords.
24 pbool keyword_asm;
25 pbool keyword_break;
26 pbool keyword_case;
27 pbool keyword_class;
28 pbool keyword_optional;
29 pbool keyword_const;    //fixme
30 pbool keyword_continue;
31 pbool keyword_default;
32 pbool keyword_entity;   //for skipping the local
33 pbool keyword_float;    //for skipping the local
34 pbool keyword_for;
35 pbool keyword_goto;
36 pbool keyword_int;      //for skipping the local
37 pbool keyword_integer;  //for skipping the local
38 pbool keyword_state;
39 pbool keyword_string;   //for skipping the local
40 pbool keyword_struct;
41 pbool keyword_switch;
42 pbool keyword_thinktime;
43 pbool keyword_var;      //allow it to be initialised and set around the place.
44 pbool keyword_vector;   //for skipping the local
45
46
47 pbool keyword_enum;     //kinda like in c, but typedef not supported.
48 pbool keyword_enumflags;        //like enum, but doubles instead of adds 1.
49 pbool keyword_typedef;  //fixme
50 #define keyword_codesys         flag_acc        //reacc needs this (forces the resultant crc)
51 #define keyword_function        flag_acc        //reacc needs this (reacc has this on all functions, wierd eh?)
52 #define keyword_objdata         flag_acc        //reacc needs this (following defs are fields rather than globals, use var to disable)
53 #define keyword_object          flag_acc        //reacc needs this (an entity)
54 #define keyword_pfunc           flag_acc        //reacc needs this (pointer to function)
55 #define keyword_system          flag_acc        //reacc needs this (potatos)
56 #define keyword_real            flag_acc        //reacc needs this (a float)
57 #define keyword_exit            flag_acc        //emits an OP_DONE opcode.
58 #define keyword_external        flag_acc        //reacc needs this (a builtin)
59 pbool keyword_extern;   //function is external, don't error or warn if the body was not found
60 pbool keyword_shared;   //mark global to be copied over when progs changes (part of FTE_MULTIPROGS)
61 pbool keyword_noref;    //nowhere else references this, don't strip it.
62 pbool keyword_nosave;   //don't write the def to the output.
63 pbool keyword_union;    //you surly know what a union is!
64
65 #define keyword_not                     1       //hexenc support needs this, and fteqcc can optimise without it, but it adds an extra token after the if, so it can cause no namespace conflicts
66
67 pbool keywords_coexist;         //don't disable a keyword simply because a var was made with the same name.
68 pbool output_parms;                     //emit some PARMX fields. confuses decompilers.
69 pbool autoprototype;            //take two passes over the source code. First time round doesn't enter and functions or initialise variables.
70 pbool pr_subscopedlocals;       //causes locals to be valid ONLY within their statement block. (they simply can't be referenced by name outside of it)
71 pbool flag_ifstring;            //makes if (blah) equivelent to if (blah != "") which resolves some issues in multiprogs situations.
72 pbool flag_iffloat;                     //use an op_if_f instruction instead of op_if so if(-0) evaluates to false.
73 pbool flag_acc;                         //reacc like behaviour of src files (finds *.qc in start dir and compiles all in alphabetical order)
74 pbool flag_caseinsensative;     //symbols will be matched to an insensative case if the specified case doesn't exist. This should b usable for any mod
75 pbool flag_laxcasts;            //Allow lax casting. This'll produce loadsa warnings of course. But allows compilation of certain dodgy code.
76 pbool flag_hashonly;            //Allows use of only #constant for precompiler constants, allows certain preqcc using mods to compile
77 pbool flag_fasttrackarrays;     //Faster arrays, dynamically detected, activated only in supporting engines.
78 pbool flag_msvcstyle;           //MSVC style warnings, so msvc's ide works properly
79 pbool flag_assume_integer;      //5 - is that an integer or a float? qcc says float. but we support int too, so maybe we want that instead?
80 pbool flag_filetimes;
81 pbool flag_typeexplicit;        //no implicit type conversions, you must do the casts yourself.
82
83 pbool opt_overlaptemps;         //reduce numpr_globals by reuse of temps. When they are not needed they are freed for reuse. The way this is implemented is better than frikqcc's. (This is the single most important optimisation)
84 pbool opt_assignments;          //STORE_F isn't used if an operation wrote to a temp.
85 pbool opt_shortenifnots;                //if(!var) is made an IF rather than NOT IFNOT
86 pbool opt_noduplicatestrings;   //brute force string check. time consuming but more effective than the equivelent in frikqcc.
87 pbool opt_constantarithmatic;   //3*5 appears as 15 instead of the extra statement.
88 pbool opt_nonvec_parms;                 //store_f instead of store_v on function calls, where possible.
89 pbool opt_constant_names;               //take out the defs and name strings of constants.
90 pbool opt_constant_names_strings;//removes the defs of strings too. plays havok with multiprogs.
91 pbool opt_precache_file;                        //remove the call, the parameters, everything.
92 pbool opt_filenames;                            //strip filenames. hinders older decompilers.
93 pbool opt_unreferenced;                 //strip defs that are not referenced.
94 pbool opt_function_names;               //strip out the names of builtin functions.
95 pbool opt_locals;                               //strip out the names of locals and immediates.
96 pbool opt_dupconstdefs;                 //float X = 5; and float Y = 5; occupy the same global with this.
97 pbool opt_return_only;                  //RETURN; DONE; at the end of a function strips out the done statement if there is no way to get to it.
98 pbool opt_compound_jumps;               //jumps to jump statements jump to the final point.
99 pbool opt_stripfunctions;               //if a functions is only ever called directly or by exe, don't emit the def.
100 pbool opt_locals_marshalling;   //make the local vars of all functions occupy the same globals.
101 pbool opt_logicops;                             //don't make conditions enter functions if the return value will be discarded due to a previous value. (C style if statements)
102 pbool opt_vectorcalls;                  //vectors can be packed into 3 floats, which can yield lower numpr_globals, but cost two more statements per call (only works for q1 calling conventions).
103 pbool opt_simplifiedifs;                //if (f != 0) -> if (f). if (f == 0) -> ifnot (f)
104 //bool opt_comexprremoval;
105
106 //these are the results of the opt_. The values are printed out when compilation is compleate, showing effectivness.
107 int optres_shortenifnots;
108 int optres_assignments;
109 int optres_overlaptemps;
110 int optres_noduplicatestrings;
111 int optres_constantarithmatic;
112 int optres_nonvec_parms;
113 int optres_constant_names;
114 int optres_constant_names_strings;
115 int optres_precache_file;
116 int optres_filenames;
117 int optres_unreferenced;
118 int optres_function_names;
119 int optres_locals;
120 int optres_dupconstdefs;
121 int optres_return_only;
122 int optres_compound_jumps;
123 //int optres_comexprremoval;
124 int optres_stripfunctions;
125 int optres_locals_marshalling;
126 int optres_logicops;
127
128 int optres_test1;
129 int optres_test2;
130
131 void *(*pHash_Get)(hashtable_t *table, const char *name);
132 void *(*pHash_GetNext)(hashtable_t *table, const char *name, void *old);
133 void *(*pHash_Add)(hashtable_t *table, const char *name, void *data, bucket_t *);
134
135 QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int arraysize, unsigned int ofs, int referable, pbool saved);
136 QCC_type_t *QCC_PR_FindType (QCC_type_t *type);
137 QCC_type_t *QCC_PR_PointerType (QCC_type_t *pointsto);
138 QCC_type_t *QCC_PR_FieldType (QCC_type_t *pointsto);
139
140 void QCC_PR_ParseState (void);
141 pbool simplestore;
142 pbool expandedemptymacro;
143
144 QCC_pr_info_t   pr;
145 //QCC_def_t             **pr_global_defs/*[MAX_REGS]*/; // to find def for a global variable
146
147 //keeps track of how many funcs are called while parsing a statement
148 //int qcc_functioncalled;
149
150 //========================================
151
152 QCC_def_t               *pr_scope;              // the function being parsed, or NULL
153 QCC_type_t              *pr_classtype;
154 pbool   pr_dumpasm;
155 QCC_string_t    s_file, s_file2;                        // filename for function definition
156
157 unsigned int                    locals_start;           // for tracking local variables vs temps
158 unsigned int                    locals_end;             // for tracking local variables vs temps
159
160 jmp_buf         pr_parse_abort;         // longjump with this on parse error
161
162 void QCC_PR_ParseDefs (char *classname);
163
164 pbool qcc_usefulstatement;
165
166 int max_breaks;
167 int max_continues;
168 int max_cases;
169 int num_continues;
170 int num_breaks;
171 int num_cases;
172 int *pr_breaks;
173 int *pr_continues;
174 int *pr_cases;
175 QCC_def_t **pr_casesdef;
176 QCC_def_t **pr_casesdef2;
177
178 typedef struct {
179         int statementno;
180         int lineno;
181         char name[256];
182 } gotooperator_t;
183
184 int max_labels;
185 int max_gotos;
186 gotooperator_t *pr_labels;
187 gotooperator_t *pr_gotos;
188 int num_gotos;
189 int num_labels;
190
191 QCC_def_t *extra_parms[MAX_EXTRA_PARMS];
192
193 //#define ASSOC_RIGHT_RESULT ASSOC_RIGHT
194
195 //========================================
196
197 //FIXME: modifiy list so most common GROUPS are first
198 //use look up table for value of first char and sort by first char and most common...?
199
200 //if true, effectivly {b=a; return a;}
201 QCC_opcode_t pr_opcodes[] =
202 {
203  {6, "<DONE>", "DONE", -1, ASSOC_LEFT,                  &type_void, &type_void, &type_void},
204
205  {6, "*", "MUL_F",                      3, ASSOC_LEFT,                          &type_float, &type_float, &type_float},
206  {6, "*", "MUL_V",                      3, ASSOC_LEFT,                          &type_vector, &type_vector, &type_float},
207  {6, "*", "MUL_FV",                     3, ASSOC_LEFT,                          &type_float, &type_vector, &type_vector},
208  {6, "*", "MUL_VF",                     3, ASSOC_LEFT,                          &type_vector, &type_float, &type_vector},
209
210  {6, "/", "DIV_F",                      3, ASSOC_LEFT,                          &type_float, &type_float, &type_float},
211
212  {6, "+", "ADD_F",                      4, ASSOC_LEFT,                          &type_float, &type_float, &type_float},
213  {6, "+", "ADD_V",                      4, ASSOC_LEFT,                          &type_vector, &type_vector, &type_vector},
214
215  {6, "-", "SUB_F",                      4, ASSOC_LEFT,                          &type_float, &type_float, &type_float},
216  {6, "-", "SUB_V",                      4, ASSOC_LEFT,                          &type_vector, &type_vector, &type_vector},
217
218  {6, "==", "EQ_F",                      5, ASSOC_LEFT,                          &type_float, &type_float, &type_float},
219  {6, "==", "EQ_V",                      5, ASSOC_LEFT,                          &type_vector, &type_vector, &type_float},
220  {6, "==", "EQ_S",                      5, ASSOC_LEFT,                          &type_string, &type_string, &type_float},
221  {6, "==", "EQ_E",                      5, ASSOC_LEFT,                          &type_entity, &type_entity, &type_float},
222  {6, "==", "EQ_FNC",            5, ASSOC_LEFT,                          &type_function, &type_function, &type_float},
223
224  {6, "!=", "NE_F",                      5, ASSOC_LEFT,                          &type_float, &type_float, &type_float},
225  {6, "!=", "NE_V",                      5, ASSOC_LEFT,                          &type_vector, &type_vector, &type_float},
226  {6, "!=", "NE_S",                      5, ASSOC_LEFT,                          &type_string, &type_string, &type_float},
227  {6, "!=", "NE_E",                      5, ASSOC_LEFT,                          &type_entity, &type_entity, &type_float},
228  {6, "!=", "NE_FNC",            5, ASSOC_LEFT,                          &type_function, &type_function, &type_float},
229
230  {6, "<=", "LE",                        5, ASSOC_LEFT,                                  &type_float, &type_float, &type_float},
231  {6, ">=", "GE",                        5, ASSOC_LEFT,                                  &type_float, &type_float, &type_float},
232  {6, "<", "LT",                         5, ASSOC_LEFT,                                  &type_float, &type_float, &type_float},
233  {6, ">", "GT",                         5, ASSOC_LEFT,                                  &type_float, &type_float, &type_float},
234
235  {6, ".", "INDIRECT_F",         1, ASSOC_LEFT,                  &type_entity, &type_field, &type_float},
236  {6, ".", "INDIRECT_V",         1, ASSOC_LEFT,                  &type_entity, &type_field, &type_vector},
237  {6, ".", "INDIRECT_S",         1, ASSOC_LEFT,                  &type_entity, &type_field, &type_string},
238  {6, ".", "INDIRECT_E",         1, ASSOC_LEFT,                  &type_entity, &type_field, &type_entity},
239  {6, ".", "INDIRECT_FI",        1, ASSOC_LEFT,                  &type_entity, &type_field, &type_field},
240  {6, ".", "INDIRECT_FU",        1, ASSOC_LEFT,                  &type_entity, &type_field, &type_function},
241
242  {6, ".", "ADDRESS",            1, ASSOC_LEFT,                          &type_entity, &type_field, &type_pointer},
243
244  {6, "=", "STORE_F",            6, ASSOC_RIGHT,                         &type_float, &type_float, &type_float},
245  {6, "=", "STORE_V",            6, ASSOC_RIGHT,                         &type_vector, &type_vector, &type_vector},
246  {6, "=", "STORE_S",            6, ASSOC_RIGHT,                         &type_string, &type_string, &type_string},
247  {6, "=", "STORE_ENT",          6, ASSOC_RIGHT,                         &type_entity, &type_entity, &type_entity},
248  {6, "=", "STORE_FLD",          6, ASSOC_RIGHT,                         &type_field, &type_field, &type_field},
249  {6, "=", "STORE_FNC",          6, ASSOC_RIGHT,                         &type_function, &type_function, &type_function},
250
251  {6, "=", "STOREP_F",           6, ASSOC_RIGHT,                         &type_pointer, &type_float, &type_float},
252  {6, "=", "STOREP_V",           6, ASSOC_RIGHT,                         &type_pointer, &type_vector, &type_vector},
253  {6, "=", "STOREP_S",           6, ASSOC_RIGHT,                         &type_pointer, &type_string, &type_string},
254  {6, "=", "STOREP_ENT",         6, ASSOC_RIGHT,                 &type_pointer, &type_entity, &type_entity},
255  {6, "=", "STOREP_FLD",         6, ASSOC_RIGHT,                 &type_pointer, &type_field, &type_field},
256  {6, "=", "STOREP_FNC",         6, ASSOC_RIGHT,                 &type_pointer, &type_function, &type_function},
257
258  {6, "<RETURN>", "RETURN",      -1, ASSOC_LEFT,         &type_float, &type_void, &type_void},
259
260  {6, "!", "NOT_F",                      -1, ASSOC_LEFT,                         &type_float, &type_void, &type_float},
261  {6, "!", "NOT_V",                      -1, ASSOC_LEFT,                         &type_vector, &type_void, &type_float},
262  {6, "!", "NOT_S",                      -1, ASSOC_LEFT,                         &type_vector, &type_void, &type_float},
263  {6, "!", "NOT_ENT",            -1, ASSOC_LEFT,                         &type_entity, &type_void, &type_float},
264  {6, "!", "NOT_FNC",            -1, ASSOC_LEFT,                         &type_function, &type_void, &type_float},
265
266   {6, "<IF>", "IF",                     -1, ASSOC_RIGHT,                                &type_float, NULL, &type_void},
267   {6, "<IFNOT>", "IFNOT",       -1, ASSOC_RIGHT,                        &type_float, NULL, &type_void},
268
269 // calls returns REG_RETURN
270  {6, "<CALL0>", "CALL0",        -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void},
271  {6, "<CALL1>", "CALL1",        -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void},
272  {6, "<CALL2>", "CALL2",        -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void},
273  {6, "<CALL3>", "CALL3",        -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void},
274  {6, "<CALL4>", "CALL4",        -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void},
275  {6, "<CALL5>", "CALL5",        -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void},
276  {6, "<CALL6>", "CALL6",        -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void},
277  {6, "<CALL7>", "CALL7",        -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void},
278  {6, "<CALL8>", "CALL8",        -1, ASSOC_LEFT,                 &type_function, &type_void, &type_void},
279
280  {6, "<STATE>", "STATE",        -1, ASSOC_LEFT,                 &type_float, &type_float, &type_void},
281
282  {6, "<GOTO>", "GOTO",          -1, ASSOC_RIGHT,                        NULL, &type_void, &type_void},
283
284  {6, "&&", "AND",                       7, ASSOC_LEFT,                                  &type_float,    &type_float, &type_float},
285  {6, "||", "OR",                        7, ASSOC_LEFT,                                  &type_float,    &type_float, &type_float},
286
287  {6, "&", "BITAND",                     3, ASSOC_LEFT,                          &type_float, &type_float, &type_float},
288  {6, "|", "BITOR",                      3, ASSOC_LEFT,                          &type_float, &type_float, &type_float},
289
290  //version 6 are in normal progs.
291
292
293
294 //these are hexen2
295  {7, "*=", "MULSTORE_F",        6, ASSOC_RIGHT_RESULT,                          &type_float, &type_float, &type_float},
296  {7, "*=", "MULSTORE_VF",       6, ASSOC_RIGHT_RESULT,                          &type_vector, &type_float, &type_vector},
297  {7, "*=", "MULSTOREP_F",       6, ASSOC_RIGHT_RESULT,                          &type_pointer, &type_float, &type_float},
298  {7, "*=", "MULSTOREP_VF",      6, ASSOC_RIGHT_RESULT,                          &type_pointer, &type_float, &type_vector},
299
300  {7, "/=", "DIVSTORE_F",        6, ASSOC_RIGHT_RESULT,                          &type_float, &type_float, &type_float},
301  {7, "/=", "DIVSTOREP_F",       6, ASSOC_RIGHT_RESULT,                          &type_pointer, &type_float, &type_float},
302
303  {7, "+=", "ADDSTORE_F",        6, ASSOC_RIGHT_RESULT,                          &type_float, &type_float, &type_float},
304  {7, "+=", "ADDSTORE_V",        6, ASSOC_RIGHT_RESULT,                          &type_vector, &type_vector, &type_vector},
305  {7, "+=", "ADDSTOREP_F",       6, ASSOC_RIGHT_RESULT,                          &type_pointer, &type_float, &type_float},
306  {7, "+=", "ADDSTOREP_V",       6, ASSOC_RIGHT_RESULT,                          &type_pointer, &type_vector, &type_vector},
307
308  {7, "-=", "SUBSTORE_F",        6, ASSOC_RIGHT_RESULT,                          &type_float, &type_float, &type_float},
309  {7, "-=", "SUBSTORE_V",        6, ASSOC_RIGHT_RESULT,                          &type_vector, &type_vector, &type_vector},
310  {7, "-=", "SUBSTOREP_F",       6, ASSOC_RIGHT_RESULT,                          &type_pointer, &type_float, &type_float},
311  {7, "-=", "SUBSTOREP_V",       6, ASSOC_RIGHT_RESULT,                          &type_pointer, &type_vector, &type_vector},
312
313  {7, "<FETCH_GBL_F>", "FETCH_GBL_F",            -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
314  {7, "<FETCH_GBL_V>", "FETCH_GBL_V",            -1, ASSOC_LEFT, &type_vector, &type_float, &type_vector},
315  {7, "<FETCH_GBL_S>", "FETCH_GBL_S",            -1, ASSOC_LEFT, &type_string, &type_float, &type_string},
316  {7, "<FETCH_GBL_E>", "FETCH_GBL_E",            -1, ASSOC_LEFT, &type_entity, &type_float, &type_entity},
317  {7, "<FETCH_GBL_FNC>", "FETCH_GBL_FNC",        -1, ASSOC_LEFT, &type_function, &type_float, &type_function},
318
319  {7, "<CSTATE>", "CSTATE",                                      -1, ASSOC_LEFT, &type_float, &type_float, &type_void},
320
321  {7, "<CWSTATE>", "CWSTATE",                            -1, ASSOC_LEFT, &type_float, &type_float, &type_void},
322
323  {7, "<THINKTIME>", "THINKTIME",                        -1, ASSOC_LEFT, &type_entity, &type_float, &type_void},
324
325  {7, "|=", "BITSET_F",                                          6,      ASSOC_RIGHT,    &type_float, &type_float, &type_float},
326  {7, "|=", "BITSETP_F",                                         6,      ASSOC_RIGHT,    &type_pointer, &type_float, &type_float},
327  {7, "&~=", "BITCLR_F",                                         6,      ASSOC_RIGHT,    &type_float, &type_float, &type_float},
328  {7, "&~=", "BITCLRP_F",                                        6,      ASSOC_RIGHT,    &type_pointer, &type_float, &type_float},
329
330  {7, "<RAND0>", "RAND0",                                        -1, ASSOC_LEFT, &type_void, &type_void, &type_float},
331  {7, "<RAND1>", "RAND1",                                        -1, ASSOC_LEFT, &type_float, &type_void, &type_float},
332  {7, "<RAND2>", "RAND2",                                        -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
333  {7, "<RANDV0>", "RANDV0",                                      -1, ASSOC_LEFT, &type_void, &type_void, &type_vector},
334  {7, "<RANDV1>", "RANDV1",                                      -1, ASSOC_LEFT, &type_vector, &type_void, &type_vector},
335  {7, "<RANDV2>", "RANDV2",                                      -1, ASSOC_LEFT, &type_vector, &type_vector, &type_vector},
336
337  {7, "<SWITCH_F>", "SWITCH_F",                          -1, ASSOC_LEFT, &type_void, NULL, &type_void},
338  {7, "<SWITCH_V>", "SWITCH_V",                          -1, ASSOC_LEFT, &type_void, NULL, &type_void},
339  {7, "<SWITCH_S>", "SWITCH_S",                          -1, ASSOC_LEFT, &type_void, NULL, &type_void},
340  {7, "<SWITCH_E>", "SWITCH_E",                          -1, ASSOC_LEFT, &type_void, NULL, &type_void},
341  {7, "<SWITCH_FNC>", "SWITCH_FNC",                      -1, ASSOC_LEFT, &type_void, NULL, &type_void},
342
343  {7, "<CASE>", "CASE",                                          -1, ASSOC_LEFT, &type_void, NULL, &type_void},
344  {7, "<CASERANGE>", "CASERANGE",                        -1, ASSOC_LEFT, &type_void, &type_void, NULL},
345
346
347 //Later are additions by DMW.
348
349  {7, "<CALL1H>", "CALL1H",      -1, ASSOC_LEFT,                 &type_function, &type_vector, &type_void},
350  {7, "<CALL2H>", "CALL2H",      -1, ASSOC_LEFT,                 &type_function, &type_vector, &type_vector},
351  {7, "<CALL3H>", "CALL3H",      -1, ASSOC_LEFT,                 &type_function, &type_vector, &type_vector},
352  {7, "<CALL4H>", "CALL4H",      -1, ASSOC_LEFT,                 &type_function, &type_vector, &type_vector},
353  {7, "<CALL5H>", "CALL5H",      -1, ASSOC_LEFT,                 &type_function, &type_vector, &type_vector},
354  {7, "<CALL6H>", "CALL6H",      -1, ASSOC_LEFT,                 &type_function, &type_vector, &type_vector},
355  {7, "<CALL7H>", "CALL7H",      -1, ASSOC_LEFT,                 &type_function, &type_vector, &type_vector},
356  {7, "<CALL8H>", "CALL8H",      -1, ASSOC_LEFT,                 &type_function, &type_vector, &type_vector},
357
358  {7, "=",       "STORE_I", 6, ASSOC_RIGHT,                              &type_integer, &type_integer, &type_integer},
359  {7, "=",       "STORE_IF", 6, ASSOC_RIGHT,                     &type_float, &type_integer, &type_integer},
360  {7, "=",       "STORE_FI", 6, ASSOC_RIGHT,                     &type_integer, &type_float, &type_float},
361
362  {7, "+", "ADD_I", 4, ASSOC_LEFT,                               &type_integer, &type_integer, &type_integer},
363  {7, "+", "ADD_FI", 4, ASSOC_LEFT,                              &type_float, &type_integer, &type_float},
364  {7, "+", "ADD_IF", 4, ASSOC_LEFT,                              &type_integer, &type_float, &type_float},
365
366  {7, "-", "SUB_I", 4, ASSOC_LEFT,                               &type_integer, &type_integer, &type_integer},
367  {7, "-", "SUB_FI", 4, ASSOC_LEFT,                              &type_float, &type_integer, &type_float},
368  {7, "-", "SUB_IF", 4, ASSOC_LEFT,                              &type_integer, &type_float, &type_float},
369
370  {7, "<CIF>", "C_ITOF", -1, ASSOC_LEFT,                         &type_integer, &type_void, &type_float},
371  {7, "<CFI>", "C_FTOI", -1, ASSOC_LEFT,                         &type_float, &type_void, &type_integer},
372  {7, "<CPIF>", "CP_ITOF", -1, ASSOC_LEFT,                       &type_pointer, &type_integer, &type_float},
373  {7, "<CPFI>", "CP_FTOI", -1, ASSOC_LEFT,                       &type_pointer, &type_float, &type_integer},
374
375  {7, ".", "INDIRECT", 1, ASSOC_LEFT,                            &type_entity,   &type_field, &type_integer},
376  {7, "=", "STOREP_I", 6, ASSOC_RIGHT,                           &type_pointer,  &type_integer, &type_integer},
377  {7, "=", "STOREP_IF", 6, ASSOC_RIGHT,                          &type_pointer,  &type_float, &type_integer},
378  {7, "=", "STOREP_FI", 6, ASSOC_RIGHT,                          &type_pointer,  &type_integer, &type_float},
379
380  {7, "&", "BITAND_I", 3, ASSOC_LEFT,                            &type_integer,  &type_integer, &type_integer},
381  {7, "|", "BITOR_I", 3, ASSOC_LEFT,                             &type_integer,  &type_integer, &type_integer},
382
383  {7, "*", "MUL_I", 3, ASSOC_LEFT,                               &type_integer,  &type_integer, &type_integer},
384  {7, "/", "DIV_I", 3, ASSOC_LEFT,                               &type_integer,  &type_integer, &type_integer},
385  {7, "==", "EQ_I", 5, ASSOC_LEFT,                               &type_integer,  &type_integer, &type_integer},
386  {7, "!=", "NE_I", 5, ASSOC_LEFT,                               &type_integer,  &type_integer, &type_integer},
387
388  {7, "<IFNOTS>", "IFNOTS", -1, ASSOC_RIGHT,             &type_string,   NULL, &type_void},
389  {7, "<IFS>", "IFS", -1, ASSOC_RIGHT,                           &type_string,   NULL, &type_void},
390
391  {7, "!", "NOT_I", -1, ASSOC_LEFT,                              &type_integer,  &type_void, &type_integer},
392
393  {7, "/", "DIV_VF", 3, ASSOC_LEFT,                              &type_vector,   &type_float, &type_float},
394
395  {7, "^", "XOR_I", 3, ASSOC_LEFT,                               &type_integer,  &type_integer, &type_integer},
396  {7, ">>", "RSHIFT_I", 3, ASSOC_LEFT,                   &type_integer,  &type_integer, &type_integer},
397  {7, "<<", "LSHIFT_I", 3, ASSOC_LEFT,                   &type_integer,  &type_integer, &type_integer},
398
399                                                                                 //var,          offset                  return
400  {7, "<ARRAY>", "GET_POINTER", -1, ASSOC_LEFT,  &type_float,            &type_integer, &type_pointer},
401  {7, "<ARRAY>", "MUL4ADD_I", -1, ASSOC_LEFT,            &type_pointer,  &type_integer, &type_pointer},
402
403  {7, "=", "LOADA_F", 6, ASSOC_LEFT,                     &type_float,    &type_integer, &type_float},
404  {7, "=", "LOADA_V", 6, ASSOC_LEFT,                     &type_vector,   &type_integer, &type_vector},
405  {7, "=", "LOADA_S", 6, ASSOC_LEFT,                     &type_string,   &type_integer, &type_string},
406  {7, "=", "LOADA_ENT", 6, ASSOC_LEFT,           &type_entity,   &type_integer, &type_entity},
407  {7, "=", "LOADA_FLD", 6, ASSOC_LEFT,           &type_field,    &type_integer, &type_field},
408  {7, "=", "LOADA_FNC", 6, ASSOC_LEFT,           &type_function, &type_integer, &type_function},
409  {7, "=", "LOADA_I", 6, ASSOC_LEFT,                     &type_integer,  &type_integer, &type_integer},
410
411  {7, "=", "STORE_P", 6, ASSOC_RIGHT,                    &type_pointer,  &type_pointer, &type_void},
412  {7, ".", "INDIRECT_P", 1, ASSOC_LEFT,                  &type_entity,   &type_field, &type_pointer},
413
414  {7, "=", "LOADP_F", 6, ASSOC_LEFT,                     &type_pointer,  &type_integer, &type_float},
415  {7, "=", "LOADP_V", 6, ASSOC_LEFT,                     &type_pointer,  &type_integer, &type_vector},
416  {7, "=", "LOADP_S", 6, ASSOC_LEFT,                     &type_pointer,  &type_integer, &type_string},
417  {7, "=", "LOADP_ENT", 6, ASSOC_LEFT,           &type_pointer,  &type_integer, &type_entity},
418  {7, "=", "LOADP_FLD", 6, ASSOC_LEFT,           &type_pointer,  &type_integer, &type_field},
419  {7, "=", "LOADP_FNC", 6, ASSOC_LEFT,           &type_pointer,  &type_integer, &type_function},
420  {7, "=", "LOADP_I", 6, ASSOC_LEFT,                     &type_pointer,  &type_integer, &type_integer},
421
422
423  {7, "<=", "LE_I", 5, ASSOC_LEFT,                                       &type_integer, &type_integer, &type_integer},
424  {7, ">=", "GE_I", 5, ASSOC_LEFT,                                       &type_integer, &type_integer, &type_integer},
425  {7, "<", "LT_I", 5, ASSOC_LEFT,                                        &type_integer, &type_integer, &type_integer},
426  {7, ">", "GT_I", 5, ASSOC_LEFT,                                        &type_integer, &type_integer, &type_integer},
427
428  {7, "<=", "LE_IF", 5, ASSOC_LEFT,                                      &type_integer, &type_float, &type_integer},
429  {7, ">=", "GE_IF", 5, ASSOC_LEFT,                                      &type_integer, &type_float, &type_integer},
430  {7, "<", "LT_IF", 5, ASSOC_LEFT,                                       &type_integer, &type_float, &type_integer},
431  {7, ">", "GT_IF", 5, ASSOC_LEFT,                                       &type_integer, &type_float, &type_integer},
432
433  {7, "<=", "LE_FI", 5, ASSOC_LEFT,                                      &type_float, &type_integer, &type_integer},
434  {7, ">=", "GE_FI", 5, ASSOC_LEFT,                                      &type_float, &type_integer, &type_integer},
435  {7, "<", "LT_FI", 5, ASSOC_LEFT,                                       &type_float, &type_integer, &type_integer},
436  {7, ">", "GT_FI", 5, ASSOC_LEFT,                                       &type_float, &type_integer, &type_integer},
437
438  {7, "==", "EQ_IF", 5, ASSOC_LEFT,                              &type_integer,  &type_float, &type_integer},
439  {7, "==", "EQ_FI", 5, ASSOC_LEFT,                              &type_float,    &type_integer, &type_float},
440
441         //-------------------------------------
442         //string manipulation.
443  {7, "+", "ADD_SF",     4, ASSOC_LEFT,                          &type_string,   &type_float, &type_string},
444  {7, "-", "SUB_S",      4, ASSOC_LEFT,                          &type_string,   &type_string, &type_float},
445  {7, "<STOREP_C>", "STOREP_C",  1, ASSOC_RIGHT, &type_string,   &type_float, &type_float},
446  {7, "<LOADP_C>", "LOADP_C",    1, ASSOC_LEFT,  &type_string,   &type_void, &type_float},
447         //-------------------------------------
448
449
450
451 {7, "*", "MUL_IF", 5, ASSOC_LEFT,                               &type_integer,  &type_float,    &type_integer},
452 {7, "*", "MUL_FI", 5, ASSOC_LEFT,                               &type_float,    &type_integer,  &type_float},
453 {7, "*", "MUL_VI", 5, ASSOC_LEFT,                               &type_vector,   &type_integer,  &type_vector},
454 {7, "*", "MUL_IV", 5, ASSOC_LEFT,                               &type_integer,  &type_vector,   &type_vector},
455
456 {7, "/", "DIV_IF", 5, ASSOC_LEFT,                               &type_integer,  &type_float,    &type_integer},
457 {7, "/", "DIV_FI", 5, ASSOC_LEFT,                               &type_float,    &type_integer,  &type_float},
458
459 {7, "&", "BITAND_IF", 5, ASSOC_LEFT,                    &type_integer,  &type_float,    &type_integer},
460 {7, "|", "BITOR_IF", 5, ASSOC_LEFT,                             &type_integer,  &type_float,    &type_integer},
461 {7, "&", "BITAND_FI", 5, ASSOC_LEFT,                    &type_float,    &type_integer,  &type_float},
462 {7, "|", "BITOR_FI", 5, ASSOC_LEFT,                             &type_float,    &type_integer,  &type_float},
463
464 {7, "&&", "AND_I", 7, ASSOC_LEFT,                               &type_integer,  &type_integer,  &type_integer},
465 {7, "||", "OR_I", 7, ASSOC_LEFT,                                &type_integer,  &type_integer,  &type_integer},
466 {7, "&&", "AND_IF", 7, ASSOC_LEFT,                              &type_integer,  &type_float,    &type_integer},
467 {7, "||", "OR_IF", 7, ASSOC_LEFT,                               &type_integer,  &type_float,    &type_integer},
468 {7, "&&", "AND_FI", 7, ASSOC_LEFT,                              &type_float,    &type_integer,  &type_integer},
469 {7, "||", "OR_FI", 7, ASSOC_LEFT,                               &type_float,    &type_integer,  &type_integer},
470 {7, "!=", "NE_IF", 5, ASSOC_LEFT,                               &type_integer,  &type_float,    &type_integer},
471 {7, "!=", "NE_FI", 5, ASSOC_LEFT,                               &type_float,    &type_float,    &type_integer},
472
473
474
475
476
477
478 {7, "<>",       "GSTOREP_I", -1, ASSOC_LEFT,                    &type_float,    &type_float,    &type_float},
479 {7, "<>",       "GSTOREP_F", -1, ASSOC_LEFT,                    &type_float,    &type_float,    &type_float},
480 {7, "<>",       "GSTOREP_ENT", -1, ASSOC_LEFT,                  &type_float,    &type_float,    &type_float},
481 {7, "<>",       "GSTOREP_FLD", -1, ASSOC_LEFT,                  &type_float,    &type_float,    &type_float},
482 {7, "<>",       "GSTOREP_S", -1, ASSOC_LEFT,                    &type_float,    &type_float,    &type_float},
483 {7, "<>",       "GSTOREP_FNC", -1, ASSOC_LEFT,                  &type_float,    &type_float,    &type_float},
484 {7, "<>",       "GSTOREP_V", -1, ASSOC_LEFT,                    &type_float,    &type_float,    &type_float},
485
486 {7, "<>",       "GADDRESS", -1, ASSOC_LEFT,                             &type_float,    &type_float,    &type_float},
487
488 {7, "<>",       "GLOAD_I",              -1, ASSOC_LEFT,                         &type_float,    &type_float,    &type_float},
489 {7, "<>",       "GLOAD_F",              -1, ASSOC_LEFT,                         &type_float,    &type_float,    &type_float},
490 {7, "<>",       "GLOAD_FLD",    -1, ASSOC_LEFT,                         &type_float,    &type_float,    &type_float},
491 {7, "<>",       "GLOAD_ENT",    -1, ASSOC_LEFT,                         &type_float,    &type_float,    &type_float},
492 {7, "<>",       "GLOAD_S",              -1, ASSOC_LEFT,                         &type_float,    &type_float,    &type_float},
493 {7, "<>",       "GLOAD_FNC",    -1, ASSOC_LEFT,                         &type_float,    &type_float,    &type_float},
494
495 {7, "<>",       "BOUNDCHECK",   -1, ASSOC_LEFT,                         &type_integer,  NULL,   NULL},
496
497 {7, "<UNUSED>", "UNUSED",               6,      ASSOC_RIGHT,                            &type_void,     &type_void,     &type_void},
498 {7, "<PUSH>",   "PUSH",         -1, ASSOC_RIGHT,                        &type_float,    &type_void,             &type_pointer},
499 {7, "<POP>",    "POP",          -1, ASSOC_RIGHT,                        &type_float,    &type_void,             &type_void},
500
501 {7, "<SWITCH_I>", "SWITCH_I",                           -1, ASSOC_LEFT, &type_void, NULL, &type_void},
502 {7, "<>",       "GLOAD_S",              -1, ASSOC_LEFT,                         &type_float,    &type_float,    &type_float},
503
504 {6, "<IF_F>",   "IF_F",         -1, ASSOC_RIGHT,                                &type_float, NULL, &type_void},
505 {6, "<IFNOT_F>","IFNOT_F",      -1, ASSOC_RIGHT,                                &type_float, NULL, &type_void},
506
507 /* emulated ops begin here */
508  {7, "<>",      "OP_EMULATED",          -1, ASSOC_LEFT,                         &type_float,    &type_float,    &type_float},
509
510
511  {7, "|=", "BITSET_I",          6,      ASSOC_RIGHT,                            &type_integer, &type_integer, &type_integer},
512  {7, "|=", "BITSETP_I",         6,      ASSOC_RIGHT,                            &type_pointer, &type_integer, &type_integer},
513
514
515  {7, "*=", "MULSTORE_I",        6,      ASSOC_RIGHT_RESULT,             &type_integer, &type_integer, &type_integer},
516  {7, "/=", "DIVSTORE_I",        6,      ASSOC_RIGHT_RESULT,             &type_integer, &type_integer, &type_integer},
517  {7, "+=", "ADDSTORE_I",        6,      ASSOC_RIGHT_RESULT,             &type_integer, &type_integer, &type_integer},
518  {7, "-=", "SUBSTORE_I",        6,      ASSOC_RIGHT_RESULT,             &type_integer, &type_integer, &type_integer},
519
520  {7, "*=", "MULSTOREP_I",       6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_integer, &type_integer},
521  {7, "/=", "DIVSTOREP_I",       6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_integer, &type_integer},
522  {7, "+=", "ADDSTOREP_I",       6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_integer, &type_integer},
523  {7, "-=", "SUBSTOREP_I",       6,      ASSOC_RIGHT_RESULT,             &type_pointer, &type_integer, &type_integer},
524
525  {7, "*=", "MULSTORE_IF",       6,      ASSOC_RIGHT_RESULT,             &type_integer, &type_float, &type_float},
526  {7, "*=", "MULSTOREP_IF",      6,      ASSOC_RIGHT_RESULT,             &type_intpointer, &type_float, &type_float},
527  {7, "/=", "DIVSTORE_IF",       6,      ASSOC_RIGHT_RESULT,             &type_integer, &type_float, &type_float},
528  {7, "/=", "DIVSTOREP_IF",      6,      ASSOC_RIGHT_RESULT,             &type_intpointer, &type_float, &type_float},
529  {7, "+=", "ADDSTORE_IF",       6,      ASSOC_RIGHT_RESULT,             &type_integer, &type_float, &type_float},
530  {7, "+=", "ADDSTOREP_IF",      6,      ASSOC_RIGHT_RESULT,             &type_intpointer, &type_float, &type_float},
531  {7, "-=", "SUBSTORE_IF",       6,      ASSOC_RIGHT_RESULT,             &type_integer, &type_float, &type_float},
532  {7, "-=", "SUBSTOREP_IF",      6,      ASSOC_RIGHT_RESULT,             &type_intpointer, &type_float, &type_float},
533
534  {7, "*=", "MULSTORE_FI",       6,      ASSOC_RIGHT_RESULT,             &type_float, &type_integer, &type_float},
535  {7, "*=", "MULSTOREP_FI",      6,      ASSOC_RIGHT_RESULT,             &type_floatpointer, &type_integer, &type_float},
536  {7, "/=", "DIVSTORE_FI",       6,      ASSOC_RIGHT_RESULT,             &type_float, &type_integer, &type_float},
537  {7, "/=", "DIVSTOREP_FI",      6,      ASSOC_RIGHT_RESULT,             &type_floatpointer, &type_integer, &type_float},
538  {7, "+=", "ADDSTORE_FI",       6,      ASSOC_RIGHT_RESULT,             &type_float, &type_integer, &type_float},
539  {7, "+=", "ADDSTOREP_FI",      6,      ASSOC_RIGHT_RESULT,             &type_floatpointer, &type_integer, &type_float},
540  {7, "-=", "SUBSTORE_FI",       6,      ASSOC_RIGHT_RESULT,             &type_float, &type_integer, &type_float},
541  {7, "-=", "SUBSTOREP_FI",      6,      ASSOC_RIGHT_RESULT,             &type_floatpointer, &type_integer, &type_float},
542
543  {7, "*=", "MULSTORE_VI",       6, ASSOC_RIGHT_RESULT,          &type_vector, &type_integer, &type_vector},
544  {7, "*=", "MULSTOREP_VI",      6, ASSOC_RIGHT_RESULT,          &type_pointer, &type_integer, &type_vector},
545
546  {7, "=", "LOADA_STRUCT",       6, ASSOC_LEFT,                          &type_float,    &type_integer, &type_float},
547
548  {7, "=",       "STOREP_P",             6,      ASSOC_RIGHT,                            &type_pointer,  &type_pointer,  &type_pointer},
549
550  {0, NULL}
551 };
552
553
554 pbool OpAssignsToC(unsigned int op)
555 {
556         // calls, switches and cases DON'T
557         if(pr_opcodes[op].type_c == &type_void)
558                 return false;
559         if(op >= OP_SWITCH_F && op <= OP_CALL8H)
560                 return false;
561         if(op >= OP_RAND0 && op <= OP_RANDV2)
562                 return false;
563         // they use a and b, but have 3 types
564         // safety
565         if(op >= OP_BITSET && op <= OP_BITCLRP)
566                 return false;
567         /*if(op >= OP_STORE_I && op <= OP_STORE_FI)
568           return false; <- add STOREP_*?*/
569         if(op == OP_STOREP_C || op == OP_LOADP_C)
570                 return false;
571         if(op >= OP_MULSTORE_F && op <= OP_SUBSTOREP_V)
572                 return false;
573         return true;
574 }
575 pbool OpAssignsToB(unsigned int op)
576 {
577         if(op >= OP_BITSET && op <= OP_BITCLRP)
578                 return true;
579         if(op >= OP_STORE_I && op <= OP_STORE_FI)
580                 return true;
581         if(op == OP_STOREP_C || op == OP_LOADP_C)
582                 return true;
583         if(op >= OP_MULSTORE_F && op <= OP_SUBSTOREP_V)
584                 return true;
585         if(op >= OP_STORE_F && op <= OP_STOREP_FNC)
586                 return true;
587         return false;
588 }
589 /*pbool OpAssignedTo(QCC_def_t *v, unsigned int op)
590 {
591         if(OpAssignsToC(op))
592         {
593         }
594         else if(OpAssignsToB(op))
595         {
596         }
597         return false;
598 }
599 */
600 #undef ASSOC_RIGHT_RESULT
601
602 #define TOP_PRIORITY    7
603 #define FUNC_PRIORITY   1
604 #define UNARY_PRIORITY  1
605 #define NOT_PRIORITY    5
606 //conditional and/or
607 #define CONDITION_PRIORITY 7
608
609
610 //this system cuts out 10/120
611 //these evaluate as top first.
612 QCC_opcode_t *opcodeprioritized[TOP_PRIORITY+1][128] =
613 {
614         {       //don't use
615 /*              &pr_opcodes[OP_DONE],
616                 &pr_opcodes[OP_RETURN],
617
618                 &pr_opcodes[OP_NOT_F],
619                 &pr_opcodes[OP_NOT_V],
620                 &pr_opcodes[OP_NOT_S],
621                 &pr_opcodes[OP_NOT_ENT],
622                 &pr_opcodes[OP_NOT_FNC],
623
624                 &pr_opcodes[OP_IF],
625                 &pr_opcodes[OP_IFNOT],
626                 &pr_opcodes[OP_CALL0],
627                 &pr_opcodes[OP_CALL1],
628                 &pr_opcodes[OP_CALL2],
629                 &pr_opcodes[OP_CALL3],
630                 &pr_opcodes[OP_CALL4],
631                 &pr_opcodes[OP_CALL5],
632                 &pr_opcodes[OP_CALL6],
633                 &pr_opcodes[OP_CALL7],
634                 &pr_opcodes[OP_CALL8],
635                 &pr_opcodes[OP_STATE],
636                 &pr_opcodes[OP_GOTO],
637
638                 &pr_opcodes[OP_IFNOTS],
639                 &pr_opcodes[OP_IFS],
640
641                 &pr_opcodes[OP_NOT_I],
642 */              NULL
643         }, {    //1
644
645                 &pr_opcodes[OP_LOAD_F],
646                 &pr_opcodes[OP_LOAD_V],
647                 &pr_opcodes[OP_LOAD_S],
648                 &pr_opcodes[OP_LOAD_ENT],
649                 &pr_opcodes[OP_LOAD_FLD],
650                 &pr_opcodes[OP_LOAD_FNC],
651                 &pr_opcodes[OP_LOAD_I],
652                 &pr_opcodes[OP_LOAD_P],
653                 &pr_opcodes[OP_ADDRESS],
654                 NULL
655         }, {    //2
656 /*      //conversion. don't use
657                 &pr_opcodes[OP_C_ITOF],
658                 &pr_opcodes[OP_C_FTOI],
659                 &pr_opcodes[OP_CP_ITOF],
660                 &pr_opcodes[OP_CP_FTOI],
661 */              NULL
662         }, {    //3
663                 &pr_opcodes[OP_MUL_F],
664                 &pr_opcodes[OP_MUL_V],
665                 &pr_opcodes[OP_MUL_FV],
666                 &pr_opcodes[OP_MUL_IV],
667                 &pr_opcodes[OP_MUL_VF],
668                 &pr_opcodes[OP_MUL_VI],
669                 &pr_opcodes[OP_MUL_I],
670                 &pr_opcodes[OP_MUL_FI],
671                 &pr_opcodes[OP_MUL_IF],
672
673                 &pr_opcodes[OP_DIV_F],
674                 &pr_opcodes[OP_DIV_I],
675                 &pr_opcodes[OP_DIV_FI],
676                 &pr_opcodes[OP_DIV_IF],
677                 &pr_opcodes[OP_DIV_VF],
678
679                 &pr_opcodes[OP_BITAND_F],
680                 &pr_opcodes[OP_BITAND_I],
681                 &pr_opcodes[OP_BITAND_IF],
682                 &pr_opcodes[OP_BITAND_FI],
683
684                 &pr_opcodes[OP_BITOR_F],
685                 &pr_opcodes[OP_BITOR_I],
686                 &pr_opcodes[OP_BITOR_IF],
687                 &pr_opcodes[OP_BITOR_FI],
688
689                 &pr_opcodes[OP_XOR_I],
690                 &pr_opcodes[OP_RSHIFT_I],
691                 &pr_opcodes[OP_LSHIFT_I],
692
693                 NULL
694         }, {    //4
695
696                 &pr_opcodes[OP_ADD_F],
697                 &pr_opcodes[OP_ADD_V],
698                 &pr_opcodes[OP_ADD_I],
699                 &pr_opcodes[OP_ADD_FI],
700                 &pr_opcodes[OP_ADD_IF],
701                 &pr_opcodes[OP_ADD_SF],
702
703                 &pr_opcodes[OP_SUB_F],
704                 &pr_opcodes[OP_SUB_V],
705                 &pr_opcodes[OP_SUB_I],
706                 &pr_opcodes[OP_SUB_FI],
707                 &pr_opcodes[OP_SUB_IF],
708                 &pr_opcodes[OP_SUB_S],
709                 NULL
710         }, {    //5
711
712                 &pr_opcodes[OP_EQ_F],
713                 &pr_opcodes[OP_EQ_V],
714                 &pr_opcodes[OP_EQ_S],
715                 &pr_opcodes[OP_EQ_E],
716                 &pr_opcodes[OP_EQ_FNC],
717                 &pr_opcodes[OP_EQ_I],
718                 &pr_opcodes[OP_EQ_IF],
719                 &pr_opcodes[OP_EQ_FI],
720
721                 &pr_opcodes[OP_NE_F],
722                 &pr_opcodes[OP_NE_V],
723                 &pr_opcodes[OP_NE_S],
724                 &pr_opcodes[OP_NE_E],
725                 &pr_opcodes[OP_NE_FNC],
726                 &pr_opcodes[OP_NE_I],
727                 &pr_opcodes[OP_NE_IF],
728                 &pr_opcodes[OP_NE_FI],
729
730                 &pr_opcodes[OP_LE_F],
731                 &pr_opcodes[OP_LE_I],
732                 &pr_opcodes[OP_LE_IF],
733                 &pr_opcodes[OP_LE_FI],
734                 &pr_opcodes[OP_GE_F],
735                 &pr_opcodes[OP_GE_I],
736                 &pr_opcodes[OP_GE_IF],
737                 &pr_opcodes[OP_GE_FI],
738                 &pr_opcodes[OP_LT_F],
739                 &pr_opcodes[OP_LT_I],
740                 &pr_opcodes[OP_LT_IF],
741                 &pr_opcodes[OP_LT_FI],
742                 &pr_opcodes[OP_GT_F],
743                 &pr_opcodes[OP_GT_I],
744                 &pr_opcodes[OP_GT_IF],
745                 &pr_opcodes[OP_GT_FI],
746
747                 NULL
748         }, {    //6
749                 &pr_opcodes[OP_STOREP_P],
750
751                 &pr_opcodes[OP_STORE_F],
752                 &pr_opcodes[OP_STORE_V],
753                 &pr_opcodes[OP_STORE_S],
754                 &pr_opcodes[OP_STORE_ENT],
755                 &pr_opcodes[OP_STORE_FLD],
756                 &pr_opcodes[OP_STORE_FNC],
757                 &pr_opcodes[OP_STORE_I],
758                 &pr_opcodes[OP_STORE_IF],
759                 &pr_opcodes[OP_STORE_FI],
760                 &pr_opcodes[OP_STORE_P],
761
762                 &pr_opcodes[OP_STOREP_F],
763                 &pr_opcodes[OP_STOREP_V],
764                 &pr_opcodes[OP_STOREP_S],
765                 &pr_opcodes[OP_STOREP_ENT],
766                 &pr_opcodes[OP_STOREP_FLD],
767                 &pr_opcodes[OP_STOREP_FNC],
768                 &pr_opcodes[OP_STOREP_I],
769                 &pr_opcodes[OP_STOREP_IF],
770                 &pr_opcodes[OP_STOREP_FI],
771
772                 &pr_opcodes[OP_DIVSTORE_F],
773                 &pr_opcodes[OP_DIVSTORE_I],
774                 &pr_opcodes[OP_DIVSTORE_FI],
775                 &pr_opcodes[OP_DIVSTORE_IF],
776                 &pr_opcodes[OP_DIVSTOREP_F],
777                 &pr_opcodes[OP_DIVSTOREP_I],
778                 &pr_opcodes[OP_DIVSTOREP_IF],
779                 &pr_opcodes[OP_DIVSTOREP_FI],
780                 &pr_opcodes[OP_MULSTORE_F],
781                 &pr_opcodes[OP_MULSTORE_VF],
782                 &pr_opcodes[OP_MULSTORE_VI],
783                 &pr_opcodes[OP_MULSTORE_I],
784                 &pr_opcodes[OP_MULSTORE_IF],
785                 &pr_opcodes[OP_MULSTORE_FI],
786                 &pr_opcodes[OP_MULSTOREP_F],
787                 &pr_opcodes[OP_MULSTOREP_VF],
788                 &pr_opcodes[OP_MULSTOREP_VI],
789                 &pr_opcodes[OP_MULSTOREP_I],
790                 &pr_opcodes[OP_MULSTOREP_IF],
791                 &pr_opcodes[OP_MULSTOREP_FI],
792                 &pr_opcodes[OP_ADDSTORE_F],
793                 &pr_opcodes[OP_ADDSTORE_V],
794                 &pr_opcodes[OP_ADDSTORE_I],
795                 &pr_opcodes[OP_ADDSTORE_IF],
796                 &pr_opcodes[OP_ADDSTORE_FI],
797                 &pr_opcodes[OP_ADDSTOREP_F],
798                 &pr_opcodes[OP_ADDSTOREP_V],
799                 &pr_opcodes[OP_ADDSTOREP_I],
800                 &pr_opcodes[OP_ADDSTOREP_IF],
801                 &pr_opcodes[OP_ADDSTOREP_FI],
802                 &pr_opcodes[OP_SUBSTORE_F],
803                 &pr_opcodes[OP_SUBSTORE_V],
804                 &pr_opcodes[OP_SUBSTORE_I],
805                 &pr_opcodes[OP_SUBSTORE_IF],
806                 &pr_opcodes[OP_SUBSTORE_FI],
807                 &pr_opcodes[OP_SUBSTOREP_F],
808                 &pr_opcodes[OP_SUBSTOREP_V],
809                 &pr_opcodes[OP_SUBSTOREP_I],
810                 &pr_opcodes[OP_SUBSTOREP_IF],
811                 &pr_opcodes[OP_SUBSTOREP_FI],
812
813                 &pr_opcodes[OP_BITSET],
814                 &pr_opcodes[OP_BITSET_I],
815 //              &pr_opcodes[OP_BITSET_IF],
816 //              &pr_opcodes[OP_BITSET_FI],
817                 &pr_opcodes[OP_BITSETP],
818                 &pr_opcodes[OP_BITSETP_I],
819 //              &pr_opcodes[OP_BITSETP_IF],
820 //              &pr_opcodes[OP_BITSETP_FI],
821                 &pr_opcodes[OP_BITCLR],
822                 &pr_opcodes[OP_BITCLRP],
823
824                 NULL
825         }, {    //7
826                 &pr_opcodes[OP_AND_F],
827                 &pr_opcodes[OP_AND_I],
828                 &pr_opcodes[OP_AND_IF],
829                 &pr_opcodes[OP_AND_FI],
830                 &pr_opcodes[OP_OR_F],
831                 &pr_opcodes[OP_OR_I],
832                 &pr_opcodes[OP_OR_IF],
833                 &pr_opcodes[OP_OR_FI],
834                 NULL
835         }
836 };
837
838 pbool QCC_OPCodeValid(QCC_opcode_t *op)
839 {
840         int num;
841         num = op - pr_opcodes;
842
843         switch(qcc_targetformat)
844         {
845         case QCF_STANDARD:
846         case QCF_KK7:
847         case QCF_QTEST:
848                 if (num < OP_MULSTORE_F)
849                         return true;
850                 return false;
851         case QCF_HEXEN2:
852                 if (num >= OP_SWITCH_V && num <= OP_SWITCH_FNC) //these were assigned numbers but were never actually implemtented in standard h2.
853                         return false;
854 //              if (num >= OP_MULSTORE_F && num <= OP_SUBSTOREP_V)
855 //                      return false;
856                 if (num <= OP_CALL8H)   //CALLXH are fixed up. This is to provide more dynamic switching...??
857                         return true;
858                 return false;
859         case QCF_FTE:
860         case QCF_FTEDEBUG:
861                 //no emulated opcodes
862                 if (num >= OP_NUMREALOPS)
863                         return false;
864                 return true;
865         case QCF_DARKPLACES:
866                 //all id opcodes.
867                 if (num < OP_MULSTORE_F)
868                         return true;
869
870                 //no emulated opcodes
871                 if (num >= OP_NUMREALOPS)
872                         return false;
873
874                 //extended opcodes.
875                 //DPFIXME: this is a list of the extended opcodes. I was conservative regarding supported ones.
876                 //         at the time of writing, these are the ones that look like they'll work just fine in Blub\0's patch.
877                 //         the ones that looked too permissive with bounds checks, or would give false positives are disabled.
878                 //         if the DP guys want I can change them as desired.
879                 switch(num)
880                 {
881                 //maths and conditionals (simple opcodes that read from specific globals and write to a global)
882                 case OP_ADD_I:
883                 case OP_ADD_IF:
884                 case OP_ADD_FI:
885                 case OP_SUB_I:
886                 case OP_SUB_IF:
887                 case OP_SUB_FI:
888                 case OP_MUL_I:
889                 case OP_MUL_IF:
890                 case OP_MUL_FI:
891                 case OP_MUL_VI:
892                 case OP_DIV_VF:
893                 case OP_DIV_I:
894                 case OP_DIV_IF:
895                 case OP_DIV_FI:
896                 case OP_BITAND_I:
897                 case OP_BITOR_I:
898                 case OP_BITAND_IF:
899                 case OP_BITOR_IF:
900                 case OP_BITAND_FI:
901                 case OP_BITOR_FI:
902                 case OP_GE_I:
903                 case OP_LE_I:
904                 case OP_GT_I:
905                 case OP_LT_I:
906                 case OP_AND_I:
907                 case OP_OR_I:
908                 case OP_GE_IF:
909                 case OP_LE_IF:
910                 case OP_GT_IF:
911                 case OP_LT_IF:
912                 case OP_AND_IF:
913                 case OP_OR_IF:
914                 case OP_GE_FI:
915                 case OP_LE_FI:
916                 case OP_GT_FI:
917                 case OP_LT_FI:
918                 case OP_AND_FI:
919                 case OP_OR_FI:
920                 case OP_NOT_I:
921                 case OP_EQ_I:
922                 case OP_EQ_IF:
923                 case OP_EQ_FI:
924                 case OP_NE_I:
925                 case OP_NE_IF:
926                 case OP_NE_FI:
927                         return true;
928
929                 //stores into a pointer (generated from 'ent.field=XXX')
930                 case OP_STOREP_I:       //no worse than the other OP_STOREP_X functions
931                 //reads from an entity field
932                 case OP_LOAD_I:         //no worse than the other OP_LOAD_X functions.
933                 case OP_LOAD_P:
934                         return true;
935
936                 //stores into the globals array.
937                 //they can change any global dynamically, but thats no security risk.
938                 //fteqcc will not automatically generate these.
939                 //fteqw does not support them either.
940                 case OP_GSTOREP_I:
941                 case OP_GSTOREP_F:
942                 case OP_GSTOREP_ENT:
943                 case OP_GSTOREP_FLD:
944                 case OP_GSTOREP_S:
945                 case OP_GSTOREP_FNC:
946                 case OP_GSTOREP_V:
947                         return true;
948
949                 //this opcode looks weird
950                 case OP_GADDRESS://floatc = globals[inta + floatb] (fte does not support)
951                         return true;
952
953                 //fteqcc will not automatically generate these
954                 //fteqw does not support them either, for that matter.
955                 case OP_GLOAD_I://c = globals[inta]
956                 case OP_GLOAD_F://note: fte does not support these
957                 case OP_GLOAD_FLD:
958                 case OP_GLOAD_ENT:
959                 case OP_GLOAD_S:
960                 case OP_GLOAD_FNC:
961                         return true;
962                 case OP_GLOAD_V:
963                         return false;   //DPFIXME: this is commented out in the patch I was given a link to... because the opcode wasn't defined.
964
965                 //these are reportedly functional.
966                 case OP_CALL8H:
967                 case OP_CALL7H:
968                 case OP_CALL6H:
969                 case OP_CALL5H:
970                 case OP_CALL4H:
971                 case OP_CALL3H:
972                 case OP_CALL2H:
973                 case OP_CALL1H:
974                         return true;
975
976                 case OP_RAND0:
977                 case OP_RAND1:
978                 case OP_RAND2:
979                 case OP_RANDV0:
980                 case OP_RANDV1:
981                 case OP_RANDV2:
982                         return true;
983
984                 case OP_BITSET: // b |= a
985                 case OP_BITCLR: // b &= ~a
986                 case OP_BITSETP: // *b |= a
987                 case OP_BITCLRP: // *b &= ~a
988                         return false;   //FIXME: I do not fully follow the controversy over these.
989
990                 case OP_SWITCH_F:
991                 case OP_SWITCH_V:
992                 case OP_SWITCH_S:
993                 case OP_SWITCH_E:
994                 case OP_SWITCH_FNC:
995                 case OP_CASE:
996                 case OP_CASERANGE:
997                         return true;
998
999                 //assuming the pointers here are fine, the return values are a little strange.
1000                 //but its fine
1001                 case OP_ADDSTORE_F:
1002                 case OP_ADDSTORE_V:
1003                 case OP_ADDSTOREP_F: // e.f += f
1004                 case OP_ADDSTOREP_V: // e.v += v
1005                 case OP_SUBSTORE_F:
1006                 case OP_SUBSTORE_V:
1007                 case OP_SUBSTOREP_F: // e.f += f
1008                 case OP_SUBSTOREP_V: // e.v += v
1009                         return true;
1010
1011                 case OP_LOADA_I:
1012                 case OP_LOADA_F:
1013                 case OP_LOADA_FLD:
1014                 case OP_LOADA_ENT:
1015                 case OP_LOADA_S:
1016                 case OP_LOADA_FNC:
1017                 case OP_LOADA_V:
1018                         return false;   //DPFIXME: DP does not bounds check these properly. I won't generate them.
1019
1020                 case OP_CONV_ITOF:
1021                 case OP_CONV_FTOI:
1022                         return true;    //these look fine.
1023
1024                 case OP_STOREP_C: // store a char in a string
1025                         return false; //DPFIXME: dp's bounds check may give false positives with expected uses.
1026
1027                 case OP_MULSTORE_F:
1028                 case OP_MULSTORE_VF:
1029                 case OP_MULSTOREP_F:
1030                 case OP_MULSTOREP_VF: // e.v *= f
1031                 case OP_DIVSTORE_F:
1032                 case OP_DIVSTOREP_F:
1033                 case OP_STORE_IF:
1034                 case OP_STORE_FI:
1035                 case OP_STORE_P:
1036                 case OP_STOREP_IF: // store a value to a pointer
1037                 case OP_STOREP_FI:
1038                 case OP_IFNOT_S:
1039                 case OP_IF_S:
1040                         return true;
1041
1042                 case OP_IFNOT_F:        //added, but not in dp yet
1043                 case OP_IF_F:
1044                         return false;
1045
1046                 case OP_CP_ITOF:
1047                 case OP_CP_FTOI:
1048                         return false;   //DPFIXME: These are not bounds checked at all.
1049                 case OP_GLOBALADDRESS:
1050                         return true;    //DPFIXME: DP will reject these pointers if they are ever used.
1051                 case OP_POINTER_ADD:
1052                         return true;    //just maths.
1053
1054                 case OP_ADD_SF: //(char*)c = (char*)a + (float)b
1055                 case OP_SUB_S:  //(float)c = (char*)a - (char*)b
1056                         return true;
1057                 case OP_LOADP_C:        //load character from a string
1058                         return false;   //DPFIXME: DP looks like it'll reject these or wrongly allow.
1059
1060                 case OP_LOADP_I:
1061                 case OP_LOADP_F:
1062                 case OP_LOADP_FLD:
1063                 case OP_LOADP_ENT:
1064                 case OP_LOADP_S:
1065                 case OP_LOADP_FNC:
1066                 case OP_LOADP_V:
1067                         return true;
1068
1069                 case OP_XOR_I:
1070                 case OP_RSHIFT_I:
1071                 case OP_LSHIFT_I:
1072                         return true;
1073
1074                 case OP_FETCH_GBL_F:
1075                 case OP_FETCH_GBL_S:
1076                 case OP_FETCH_GBL_E:
1077                 case OP_FETCH_GBL_FNC:
1078                 case OP_FETCH_GBL_V:
1079                         return false;   //DPFIXME: DP will not bounds check this properly, it is too permissive.
1080                 case OP_CSTATE:
1081                 case OP_CWSTATE:
1082                         return false;   //DP does not support this hexenc opcode.
1083                 case OP_THINKTIME:
1084                         return true;    //but it does support this one.
1085
1086                 default:                        //anything I forgot to mention is new.
1087                         return false;
1088                 }
1089         }
1090         return false;
1091 }
1092
1093 #define EXPR_WARN_ABOVE_1 2
1094 #define EXPR_DISALLOW_COMMA 4
1095 QCC_def_t *QCC_PR_Expression (int priority, int exprflags);
1096 int QCC_AStatementJumpsTo(int targ, int first, int last);
1097 pbool QCC_StatementIsAJump(int stnum, int notifdest);
1098
1099 temp_t *functemps;              //floats/strings/funcs/ents...
1100
1101 //===========================================================================
1102
1103
1104 /*
1105 ============
1106 PR_Statement
1107
1108 Emits a primitive statement, returning the var it places it's value in
1109 ============
1110 */
1111 QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_b, QCC_dstatement_t **outstatement);
1112 static int QCC_ShouldConvert(QCC_def_t *var, etype_t wanted)
1113 {
1114         /*no conversion needed*/
1115         if (var->type->type == wanted)
1116                 return 0;
1117         if (var->type->type == ev_integer && wanted == ev_function)
1118                 return 0;
1119         if (var->type->type == ev_integer && wanted == ev_pointer)
1120                 return 0;
1121         /*stuff needs converting*/
1122         if (var->type->type == ev_pointer && var->type->aux_type)
1123         {
1124                 if (var->type->aux_type->type == ev_float && wanted == ev_integer)
1125                         return OP_CP_FTOI;
1126
1127                 if (var->type->aux_type->type == ev_integer && wanted == ev_float)
1128                         return OP_CP_ITOF;
1129         }
1130         else
1131         {
1132                 if (var->type->type == ev_float && wanted == ev_integer)
1133                         return OP_CONV_FTOI;
1134
1135                 if (var->type->type == ev_integer && wanted == ev_float)
1136                         return OP_CONV_ITOF;
1137         }
1138
1139         /*impossible*/
1140         return -1;
1141 }
1142 QCC_def_t *QCC_SupplyConversion(QCC_def_t *var, etype_t wanted, pbool fatal)
1143 {
1144         extern char *basictypenames[];
1145         int o;
1146
1147         if (pr_classtype && var->type->type == ev_field && wanted != ev_field)
1148         {
1149                 if (pr_classtype)
1150                 {       //load self.var into a temp
1151                         QCC_def_t *self;
1152                         self = QCC_PR_GetDef(type_entity, "self", NULL, true, 0, false);
1153                         switch(wanted)
1154                         {
1155                         case ev_float:
1156                                 return QCC_PR_Statement(pr_opcodes+OP_LOAD_F, self, var, NULL);
1157                         case ev_string:
1158                                 return QCC_PR_Statement(pr_opcodes+OP_LOAD_S, self, var, NULL);
1159                         case ev_function:
1160                                 return QCC_PR_Statement(pr_opcodes+OP_LOAD_FNC, self, var, NULL);
1161                         case ev_vector:
1162                                 return QCC_PR_Statement(pr_opcodes+OP_LOAD_V, self, var, NULL);
1163                         case ev_entity:
1164                                 return QCC_PR_Statement(pr_opcodes+OP_LOAD_ENT, self, var, NULL);
1165                         default:
1166                                 QCC_Error(ERR_INTERNAL, "Inexplicit field load failed, try explicit");
1167                         }
1168                 }
1169         }
1170
1171         o = QCC_ShouldConvert(var, wanted);
1172
1173         if (o == 0) //type already matches
1174                 return var;
1175         if (flag_typeexplicit)
1176                 QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, var, "Implicit type mismatch. Needed %s, got %s.", basictypenames[wanted], var->type->name);
1177         if (o < 0)
1178         {
1179                 if (fatal)
1180                         QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, var, "Implicit type mismatch. Needed %s, got %s.", basictypenames[wanted], var->type->name);
1181                 else
1182                         return var;
1183         }
1184
1185         return QCC_PR_Statement(&pr_opcodes[o], var, NULL, NULL);       //conversion return value
1186 }
1187 QCC_def_t *QCC_MakeTranslateStringConst(char *value);
1188 QCC_def_t *QCC_MakeStringConst(char *value);
1189 QCC_def_t *QCC_MakeFloatConst(float value);
1190 QCC_def_t *QCC_MakeIntConst(int value);
1191 QCC_def_t *QCC_MakeVectorConst(float a, float b, float c);
1192
1193 typedef struct freeoffset_s {
1194         struct freeoffset_s *next;
1195         gofs_t ofs;
1196         unsigned int size;
1197 } freeoffset_t;
1198
1199 freeoffset_t *freeofs;
1200
1201 //assistant functions. This can safly be bipassed with the old method for more complex things.
1202 gofs_t QCC_GetFreeOffsetSpace(unsigned int size)
1203 {
1204         int ofs;
1205         if (opt_locals_marshalling)
1206         {
1207                 freeoffset_t *fofs, *prev;
1208                 for (fofs = freeofs, prev = NULL; fofs; fofs=fofs->next)
1209                 {
1210                         if (fofs->size == size)
1211                         {
1212                                 if (prev)
1213                                         prev->next = fofs->next;
1214                                 else
1215                                         freeofs = fofs->next;
1216
1217                                 return fofs->ofs;
1218                         }
1219                         prev = fofs;
1220                 }
1221                 for (fofs = freeofs, prev = NULL; fofs; fofs=fofs->next)
1222                 {
1223                         if (fofs->size > size)
1224                         {
1225                                 fofs->size -= size;
1226                                 fofs->ofs += size;
1227
1228                                 return fofs->ofs-size;
1229                         }
1230                         prev = fofs;
1231                 }
1232         }
1233
1234         ofs = numpr_globals;
1235         numpr_globals+=size;
1236
1237         if (numpr_globals >= MAX_REGS)
1238         {
1239                 if (!opt_overlaptemps || !opt_locals_marshalling)
1240                         QCC_Error(ERR_TOOMANYGLOBALS, "numpr_globals exceeded MAX_REGS - you'll need to use more optimisations");
1241                 else
1242                         QCC_Error(ERR_TOOMANYGLOBALS, "numpr_globals exceeded MAX_REGS");
1243         }
1244
1245         return ofs;
1246 }
1247
1248 void QCC_FreeOffset(gofs_t ofs, unsigned int size)
1249 {
1250         freeoffset_t *fofs;
1251         if (ofs+size == numpr_globals)
1252         {       //fixme: is this a bug?
1253                 numpr_globals -= size;
1254                 return;
1255         }
1256
1257         for (fofs = freeofs; fofs; fofs=fofs->next)
1258         {
1259                 //fixme: if this means the last block becomes free, free them all.
1260                 if (fofs->ofs == ofs + size)
1261                 {
1262                         fofs->ofs -= size;
1263                         fofs->size += size;
1264                         return;
1265                 }
1266                 if (fofs->ofs+fofs->size == ofs)
1267                 {
1268                         fofs->size += size;
1269                         return;
1270                 }
1271         }
1272
1273         fofs = qccHunkAlloc(sizeof(freeoffset_t));
1274         fofs->next = freeofs;
1275         fofs->ofs = ofs;
1276         fofs->size = size;
1277
1278         freeofs = fofs;
1279         return;
1280 }
1281
1282 static QCC_def_t *QCC_GetTemp(QCC_type_t *type)
1283 {
1284 //#define CRAZYTEMPOPTS //not worth it. saves 2 temps with hexen2 (without even touching numpr_globals)
1285         QCC_def_t *var_c;
1286         temp_t *t;
1287 #ifdef CRAZYTEMPOPTS
1288         temp_t *best = NULL;
1289 #endif
1290
1291         var_c = (void *)qccHunkAlloc (sizeof(QCC_def_t));
1292         memset (var_c, 0, sizeof(QCC_def_t));
1293         var_c->type = type;
1294         var_c->name = "temp";
1295
1296         if (opt_overlaptemps)   //don't exceed. This lets us allocate a huge block, and still be able to compile smegging big funcs.
1297         {
1298                 for (t = functemps; t; t = t->next)
1299                 {
1300                         if (!t->used && t->size == type->size)
1301                         {
1302 #ifdef CRAZYTEMPOPTS
1303                                 best = t;
1304                                 if (t->scope == pr_scope)
1305 #endif
1306                                         break;
1307                         }
1308                 }
1309 #ifdef CRAZYTEMPOPTS
1310                 t = best;
1311 #endif
1312                 if (t && t->scope && t->scope != pr_scope)
1313                         QCC_Error(ERR_INTERNAL, "Internal error temp has scope not equal to current scope");
1314
1315                 if (!t)
1316                 {
1317                         //allocate a new one
1318                         t = qccHunkAlloc(sizeof(temp_t));
1319                         t->size = type->size;
1320                         t->next = functemps;
1321                         functemps = t;
1322
1323                         t->ofs = QCC_GetFreeOffsetSpace(t->size);
1324
1325                         numtemps+=t->size;
1326                 }
1327                 else
1328                         optres_overlaptemps+=t->size;
1329                 //use a previous one.
1330                 var_c->ofs = t->ofs;
1331                 var_c->temp = t;
1332                 t->lastfunc = pr_scope;
1333         }
1334         else if (opt_locals_marshalling)
1335         {
1336                 //allocate a new one
1337                 t = qccHunkAlloc(sizeof(temp_t));
1338                 t->size = type->size;
1339
1340                 t->next = functemps;
1341                 functemps = t;
1342
1343                 t->ofs = QCC_GetFreeOffsetSpace(t->size);
1344
1345                 numtemps+=t->size;
1346
1347                 var_c->ofs = t->ofs;
1348                 var_c->temp = t;
1349                 t->lastfunc = pr_scope;
1350         }
1351         else
1352         {
1353                 // we're not going to reallocate any temps so allocate permanently
1354                 var_c->ofs = QCC_GetFreeOffsetSpace(type->size);
1355                 numtemps+=type->size;
1356         }
1357
1358         var_c->s_file = s_file;
1359         var_c->s_line = pr_source_line;
1360
1361         if (var_c->temp)
1362                 var_c->temp->used = true;
1363
1364         return var_c;
1365 }
1366
1367 //nothing else references this temp.
1368 static void QCC_FreeTemp(QCC_def_t *t)
1369 {
1370         if (t && t->temp)
1371                 t->temp->used = false;
1372 }
1373
1374 static void QCC_UnFreeTemp(QCC_def_t *t)
1375 {
1376         if (t->temp)
1377                 t->temp->used = true;
1378 }
1379
1380 //We've just parsed a statement.
1381 //We can gaurentee that any used temps are now not used.
1382 #ifdef _DEBUG
1383 static void QCC_FreeTemps(void)
1384 {
1385         temp_t *t;
1386
1387         if (def_ret.temp && def_ret.temp->used)
1388         {
1389                 QCC_PR_ParseWarning(WARN_DEBUGGING, "Return value still in use in %s", pr_scope->name);
1390                 def_ret.temp->used = false;
1391         }
1392
1393         t = functemps;
1394         while(t)
1395         {
1396                 if (t->used && !pr_error_count) //don't print this after an error jump out.
1397                         QCC_PR_ParseWarning(WARN_DEBUGGING, "Internal: temp(ofs %i) was not released in %s. This implies miscompilation.", t->ofs, pr_scope->name);
1398                 t->used = false;
1399                 t = t->next;
1400         }
1401 }
1402 #else
1403 #define QCC_FreeTemps()
1404 #endif
1405 void QCC_PurgeTemps(void)
1406 {
1407         functemps = NULL;
1408 }
1409
1410 //temps that are still in use over a function call can be considered dodgy.
1411 //we need to remap these to locally defined temps, on return from the function so we know we got them all.
1412 static void QCC_LockActiveTemps(void)
1413 {
1414         temp_t *t;
1415
1416         t = functemps;
1417         while(t)
1418         {
1419                 if (t->used)
1420                         t->scope = pr_scope;
1421                 t = t->next;
1422         }
1423
1424 }
1425
1426 static void QCC_LockTemp(QCC_def_t *d)
1427 {
1428         if (d->temp && d->temp->used)
1429                 d->temp->scope = pr_scope;
1430 }
1431 static void QCC_ForceLockTempForOffset(int ofs)
1432 {
1433         temp_t *t;
1434         for (t = functemps; t; t = t->next)
1435                 if(t->ofs == ofs /* && t->used */)
1436                         t->scope = pr_scope;
1437 }
1438
1439 static void QCC_RemapLockedTemp(temp_t *t, int firststatement, int laststatement)
1440 {
1441 #ifdef WRITEASM
1442         char buffer[128];
1443 #endif
1444
1445         QCC_def_t *def;
1446         int newofs;
1447         QCC_dstatement_t *st;
1448         int i;
1449
1450         newofs = 0;
1451         for (i = firststatement, st = &statements[i]; i < laststatement; i++, st++)
1452         {
1453                 if (pr_opcodes[st->op].type_a && st->a == t->ofs)
1454                 {
1455                         if (!newofs)
1456                         {
1457                                 newofs = QCC_GetFreeOffsetSpace(t->size);
1458                                 numtemps+=t->size;
1459
1460                                 def = QCC_PR_DummyDef(type_float, NULL, pr_scope, t->size, newofs, false, false);
1461                                 def->nextlocal = pr.localvars;
1462                                 def->constant = false;
1463 #ifdef WRITEASM
1464                                 sprintf(buffer, "locked_%i", t->ofs);
1465                                 def->name = qccHunkAlloc(strlen(buffer)+1);
1466                                 strcpy(def->name, buffer);
1467 #endif
1468                                 pr.localvars = def;
1469                         }
1470                         st->a = newofs;
1471                 }
1472                 if (pr_opcodes[st->op].type_b && st->b == t->ofs)
1473                 {
1474                         if (!newofs)
1475                         {
1476                                 newofs = QCC_GetFreeOffsetSpace(t->size);
1477                                 numtemps+=t->size;
1478
1479                                 def = QCC_PR_DummyDef(type_float, NULL, pr_scope, t->size, newofs, false, false);
1480                                 def->nextlocal = pr.localvars;
1481                                 def->constant = false;
1482 #ifdef WRITEASM
1483                                 sprintf(buffer, "locked_%i", t->ofs);
1484                                 def->name = qccHunkAlloc(strlen(buffer)+1);
1485                                 strcpy(def->name, buffer);
1486 #endif
1487                                 pr.localvars = def;
1488                         }
1489                         st->b = newofs;
1490                 }
1491                 if (pr_opcodes[st->op].type_c && st->c == t->ofs)
1492                 {
1493                         if (!newofs)
1494                         {
1495                                 newofs = QCC_GetFreeOffsetSpace(t->size);
1496                                 numtemps+=t->size;
1497
1498                                 def = QCC_PR_DummyDef(type_float, NULL, pr_scope, t->size, newofs, false, false);
1499                                 def->nextlocal = pr.localvars;
1500                                 def->constant = false;
1501 #ifdef WRITEASM
1502                                 sprintf(buffer, "locked_%i", t->ofs);
1503                                 def->name = qccHunkAlloc(strlen(buffer)+1);
1504                                 strcpy(def->name, buffer);
1505 #endif
1506                                 pr.localvars = def;
1507                         }
1508                         st->c = newofs;
1509                 }
1510         }
1511 }
1512
1513 static void QCC_RemapLockedTemps(int firststatement, int laststatement)
1514 {
1515         temp_t *t;
1516
1517         t = functemps;
1518         while(t)
1519         {
1520                 if (t->scope || opt_locals_marshalling)
1521                 {
1522                         QCC_RemapLockedTemp(t, firststatement, laststatement);
1523                         t->scope = NULL;
1524                         t->lastfunc = NULL;
1525                 }
1526                 t = t->next;
1527         }
1528 }
1529
1530 static void QCC_fprintfLocals(FILE *f, gofs_t paramstart, gofs_t paramend)
1531 {
1532         QCC_def_t       *var;
1533         temp_t *t;
1534         int i;
1535
1536         for (var = pr.localvars; var; var = var->nextlocal)
1537         {
1538                 if (var->ofs >= paramstart && var->ofs < paramend)
1539                         continue;
1540                 if (var->arraysize)
1541                         fprintf(f, "local %s %s[%i];\n", TypeName(var->type), var->name, var->arraysize);
1542                 else
1543                         fprintf(f, "local %s %s;\n", TypeName(var->type), var->name);
1544         }
1545
1546         for (t = functemps, i = 0; t; t = t->next, i++)
1547         {
1548                 if (t->lastfunc == pr_scope)
1549                 {
1550                         fprintf(f, "local %s temp_%i;\n", (t->size == 1)?"float":"vector", i);
1551                 }
1552         }
1553 }
1554
1555 #ifdef WRITEASM
1556 void QCC_WriteAsmFunction(QCC_def_t     *sc, unsigned int firststatement, gofs_t firstparm);
1557 static const char *QCC_VarAtOffset(unsigned int ofs, unsigned int size)
1558 {
1559         static char message[1024];
1560         QCC_def_t       *var;
1561         //check the temps
1562         temp_t *t;
1563         int i;
1564
1565         for (t = functemps, i = 0; t; t = t->next, i++)
1566         {
1567                 if (ofs >= t->ofs && ofs < t->ofs + t->size)
1568                 {
1569                         if (size < t->size)
1570                                 sprintf(message, "temp_%i_%c", t->ofs, 'x' + (ofs-t->ofs)%3);
1571                         else
1572                                 sprintf(message, "temp_%i", t->ofs);
1573                         return message;
1574                 }
1575         }
1576
1577         for (var = pr.localvars; var; var = var->nextlocal)
1578         {
1579                 if (var->scope && var->scope != pr_scope)
1580                         continue;       //this should be an error
1581                 if (ofs >= var->ofs && ofs < var->ofs + var->type->size)
1582                 {
1583                         if (*var->name)
1584                         {
1585                                 if (!STRCMP(var->name, "IMMEDIATE"))    //continue, don't get bogged down by multiple bits of code
1586                                         continue;
1587                                 if (size < var->type->size)
1588                                         sprintf(message, "%s_%c", var->name, 'x' + (ofs-var->ofs)%3);
1589                                 else
1590                                         sprintf(message, "%s", var->name);
1591                                 return message;
1592                         }
1593                 }
1594         }
1595
1596         for (var = pr.def_head.next; var; var = var->next)
1597         {
1598                 if (var->scope && var->scope != pr_scope)
1599                         continue;
1600
1601                 if (ofs >= var->ofs && ofs < var->ofs + var->type->size)
1602                 {
1603                         if (*var->name)
1604                         {
1605                                 if (!STRCMP(var->name, "IMMEDIATE"))
1606                                 {
1607                                         switch(var->type->type)
1608                                         {
1609                                         case ev_string:
1610                                                 sprintf(message, "\"%.1020s\"", &strings[((int *)qcc_pr_globals)[var->ofs]]);
1611                                                 return message;
1612                                         case ev_integer:
1613                                                 sprintf(message, "%i", ((int *)qcc_pr_globals)[var->ofs]);
1614                                                 return message;
1615                                         case ev_float:
1616                                                 sprintf(message, "%f", qcc_pr_globals[var->ofs]);
1617                                                 return message;
1618                                         case ev_vector:
1619                                                 sprintf(message, "'%f %f %f'", qcc_pr_globals[var->ofs], qcc_pr_globals[var->ofs+1], qcc_pr_globals[var->ofs+2]);
1620                                                 return message;
1621                                         default:
1622                                                 sprintf(message, "IMMEDIATE");
1623                                                 return message;
1624                                         }
1625                                 }
1626                                 if (size < var->type->size)
1627                                         sprintf(message, "%s_%c", var->name, 'x' + (ofs-var->ofs)%3);
1628                                 else
1629                                         sprintf(message, "%s", var->name);
1630                                 return message;
1631                         }
1632                 }
1633         }
1634
1635         if (size >= 3)
1636         {
1637                 if (ofs >= OFS_RETURN && ofs < OFS_PARM0)
1638                         sprintf(message, "return");
1639                 else if (ofs >= OFS_PARM0 && ofs < RESERVED_OFS)
1640                         sprintf(message, "parm%i", (ofs-OFS_PARM0)/3);
1641                 else
1642                         sprintf(message, "offset_%i", ofs);
1643         }
1644         else
1645         {
1646                 if (ofs >= OFS_RETURN && ofs < OFS_PARM0)
1647                         sprintf(message, "return_%c", 'x' + ofs-OFS_RETURN);
1648                 else if (ofs >= OFS_PARM0 && ofs < RESERVED_OFS)
1649                         sprintf(message, "parm%i_%c", (ofs-OFS_PARM0)/3, 'x' + (ofs-OFS_PARM0)%3);
1650                 else
1651                         sprintf(message, "offset_%i", ofs);
1652         }
1653         return message;
1654 }
1655 #endif
1656
1657 QCC_dstatement_t *QCC_PR_SimpleStatement( int op, int var_a, int var_b, int var_c, int force);
1658
1659 QCC_def_t *QCC_PR_Statement (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_b, QCC_dstatement_t **outstatement)
1660 {
1661         QCC_dstatement_t        *statement;
1662         QCC_def_t                       *var_c=NULL, *temp=NULL;
1663
1664         if (outstatement == (QCC_dstatement_t **)0xffffffff)
1665                 outstatement = NULL;
1666         else if (op->priority != -1 && op->priority != CONDITION_PRIORITY)
1667         {
1668                 if (op->associative!=ASSOC_LEFT)
1669                 {
1670                         if (op->type_a != &type_pointer)
1671                                 var_b = QCC_SupplyConversion(var_b, (*op->type_a)->type, false);
1672                 }
1673                 else
1674                 {
1675                         if (var_a)
1676                                 var_a = QCC_SupplyConversion(var_a, (*op->type_a)->type, false);
1677                         if (var_b)
1678                                 var_b = QCC_SupplyConversion(var_b, (*op->type_b)->type, false);
1679                 }
1680         }
1681
1682         if (var_a)
1683         {
1684                 var_a->references++;
1685                 QCC_FreeTemp(var_a);
1686         }
1687         if (var_b)
1688         {
1689                 var_b->references++;
1690                 QCC_FreeTemp(var_b);
1691         }
1692
1693         if (keyword_class && var_a && var_b)
1694         {
1695                 if (var_a->type->type == ev_entity && var_b->type->type == ev_entity)
1696                         if (var_a->type != var_b->type)
1697                                 if (strcmp(var_a->type->name, var_b->type->name))
1698                                         QCC_PR_ParseWarning(0, "Implicit cast from '%s' to '%s'", var_a->type->name, var_b->type->name);
1699         }
1700
1701         //maths operators
1702         if (opt_constantarithmatic)
1703         {
1704                 if (var_a && var_a->constant)
1705                 {
1706                         if (var_b && var_b->constant)
1707                         {
1708                                 //both are constants
1709                                 switch (op - pr_opcodes)        //improve some of the maths.
1710                                 {
1711                                 case OP_LOADA_F:
1712                                 case OP_LOADA_V:
1713                                 case OP_LOADA_S:
1714                                 case OP_LOADA_ENT:
1715                                 case OP_LOADA_FLD:
1716                                 case OP_LOADA_FNC:
1717                                 case OP_LOADA_I:
1718                                         {
1719                                                 QCC_def_t *nd;
1720                                                 nd = (void *)qccHunkAlloc (sizeof(QCC_def_t));
1721                                                 memset (nd, 0, sizeof(QCC_def_t));
1722                                                 nd->type = var_a->type;
1723                                                 nd->ofs = var_a->ofs + G_INT(var_b->ofs);
1724                                                 nd->temp = var_a->temp;
1725                                                 nd->constant = true;
1726                                                 nd->name = var_a->name;
1727                                                 return nd;
1728                                         }
1729                                         break;
1730                                 case OP_BITOR_F:
1731                                         optres_constantarithmatic++;
1732                                         return QCC_MakeFloatConst((float)((int)G_FLOAT(var_a->ofs) | (int)G_FLOAT(var_b->ofs)));
1733                                 case OP_BITAND_F:
1734                                         optres_constantarithmatic++;
1735                                         return QCC_MakeFloatConst((float)((int)G_FLOAT(var_a->ofs) & (int)G_FLOAT(var_b->ofs)));
1736                                 case OP_MUL_F:
1737                                         optres_constantarithmatic++;
1738                                         return QCC_MakeFloatConst(G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs));
1739                                 case OP_DIV_F:
1740                                         optres_constantarithmatic++;
1741                                         return QCC_MakeFloatConst(G_FLOAT(var_a->ofs) / G_FLOAT(var_b->ofs));
1742                                 case OP_ADD_F:
1743                                         optres_constantarithmatic++;
1744                                         return QCC_MakeFloatConst(G_FLOAT(var_a->ofs) + G_FLOAT(var_b->ofs));
1745                                 case OP_SUB_F:
1746                                         optres_constantarithmatic++;
1747                                         return QCC_MakeFloatConst(G_FLOAT(var_a->ofs) - G_FLOAT(var_b->ofs));
1748
1749                                 case OP_BITOR_I:
1750                                         optres_constantarithmatic++;
1751                                         return QCC_MakeIntConst(G_INT(var_a->ofs) | G_INT(var_b->ofs));
1752                                 case OP_BITAND_I:
1753                                         optres_constantarithmatic++;
1754                                         return QCC_MakeIntConst(G_INT(var_a->ofs) & G_INT(var_b->ofs));
1755                                 case OP_MUL_I:
1756                                         optres_constantarithmatic++;
1757                                         return QCC_MakeIntConst(G_INT(var_a->ofs) * G_INT(var_b->ofs));
1758                                 case OP_DIV_I:
1759                                         optres_constantarithmatic++;
1760                                         return QCC_MakeIntConst(G_INT(var_a->ofs) / G_INT(var_b->ofs));
1761                                 case OP_ADD_I:
1762                                         optres_constantarithmatic++;
1763                                         return QCC_MakeIntConst(G_INT(var_a->ofs) + G_INT(var_b->ofs));
1764                                 case OP_SUB_I:
1765                                         optres_constantarithmatic++;
1766                                         return QCC_MakeIntConst(G_INT(var_a->ofs) - G_INT(var_b->ofs));
1767
1768                                 case OP_AND_F:
1769                                         optres_constantarithmatic++;
1770                                         return QCC_MakeIntConst(G_INT(var_a->ofs) && G_INT(var_b->ofs));
1771                                 case OP_OR_F:
1772                                         optres_constantarithmatic++;
1773                                         return QCC_MakeIntConst(G_INT(var_a->ofs) || G_INT(var_b->ofs));
1774                                 case OP_MUL_V:  //mul_f is actually a dot-product
1775                                         optres_constantarithmatic++;
1776                                         return QCC_MakeFloatConst(      G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+0) +
1777                                                                                                 G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+1) +
1778                                                                                                 G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+2));
1779                                 case OP_MUL_FV:
1780                                         optres_constantarithmatic++;
1781                                         return QCC_MakeVectorConst(     G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+0),
1782                                                                                                 G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+1),
1783                                                                                                 G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+2));
1784                                 case OP_MUL_VF:
1785                                         optres_constantarithmatic++;
1786                                         return QCC_MakeVectorConst(     G_FLOAT(var_a->ofs+0) * G_FLOAT(var_b->ofs),
1787                                                                                                 G_FLOAT(var_a->ofs+1) * G_FLOAT(var_b->ofs),
1788                                                                                                 G_FLOAT(var_a->ofs+2) * G_FLOAT(var_b->ofs));
1789                                 case OP_ADD_V:
1790                                         optres_constantarithmatic++;
1791                                         return QCC_MakeVectorConst(     G_FLOAT(var_a->ofs+0) + G_FLOAT(var_b->ofs+0),
1792                                                                                                 G_FLOAT(var_a->ofs+1) + G_FLOAT(var_b->ofs+1),
1793                                                                                                 G_FLOAT(var_a->ofs+2) + G_FLOAT(var_b->ofs+2));
1794                                 case OP_SUB_V:
1795                                         optres_constantarithmatic++;
1796                                         return QCC_MakeVectorConst(     G_FLOAT(var_a->ofs+0) - G_FLOAT(var_b->ofs+0),
1797                                                                                                 G_FLOAT(var_a->ofs+1) - G_FLOAT(var_b->ofs+1),
1798                                                                                                 G_FLOAT(var_a->ofs+2) - G_FLOAT(var_b->ofs+2));
1799                                 }
1800                         }
1801                         else
1802                         {
1803                                 //a is const, b is not
1804                                 switch (op - pr_opcodes)
1805                                 {
1806                                 case OP_CONV_FTOI:
1807                                         optres_constantarithmatic++;
1808                                         return QCC_MakeIntConst(G_FLOAT(var_a->ofs));
1809                                 case OP_CONV_ITOF:
1810                                         optres_constantarithmatic++;
1811                                         return QCC_MakeFloatConst(G_INT(var_a->ofs));
1812                                 case OP_BITOR_F:
1813                                 case OP_OR_F:
1814                                 case OP_ADD_F:
1815                                         if (G_FLOAT(var_a->ofs) == 0)
1816                                         {
1817                                                 optres_constantarithmatic++;
1818                                                 QCC_UnFreeTemp(var_b);
1819                                                 return var_b;
1820                                         }
1821                                         break;
1822                                 case OP_MUL_F:
1823                                         if (G_FLOAT(var_a->ofs) == 1)
1824                                         {
1825                                                 optres_constantarithmatic++;
1826                                                 QCC_UnFreeTemp(var_b);
1827                                                 return var_b;
1828                                         }
1829                                         break;
1830                                 case OP_BITAND_F:
1831                                 case OP_AND_F:
1832                                         if (G_FLOAT(var_a->ofs) != 0)
1833                                         {
1834                                                 optres_constantarithmatic++;
1835                                                 QCC_UnFreeTemp(var_b);
1836                                                 return var_b;
1837                                         }
1838                                         break;
1839
1840                                 case OP_BITOR_I:
1841                                 case OP_OR_I:
1842                                 case OP_ADD_I:
1843                                         if (G_INT(var_a->ofs) == 0)
1844                                         {
1845                                                 optres_constantarithmatic++;
1846                                                 QCC_UnFreeTemp(var_b);
1847                                                 return var_b;
1848                                         }
1849                                         break;
1850                                 case OP_MUL_I:
1851                                         if (G_INT(var_a->ofs) == 1)
1852                                         {
1853                                                 optres_constantarithmatic++;
1854                                                 QCC_UnFreeTemp(var_b);
1855                                                 return var_b;
1856                                         }
1857                                         break;
1858                                 case OP_BITAND_I:
1859                                 case OP_AND_I:
1860                                         if (G_INT(var_a->ofs) != 0)
1861                                         {
1862                                                 optres_constantarithmatic++;
1863                                                 QCC_UnFreeTemp(var_b);
1864                                                 return var_b;
1865                                         }
1866                                         break;
1867                                 }
1868                         }
1869                 }
1870                 else if (var_b && var_b->constant)
1871                 {
1872                         //b is const, a is not
1873                         switch (op - pr_opcodes)
1874                         {
1875                         case OP_LOADA_F:
1876                         case OP_LOADA_V:
1877                         case OP_LOADA_S:
1878                         case OP_LOADA_ENT:
1879                         case OP_LOADA_FLD:
1880                         case OP_LOADA_FNC:
1881                         case OP_LOADA_I:
1882                                 {
1883                                         QCC_def_t *nd;
1884                                         nd = (void *)qccHunkAlloc (sizeof(QCC_def_t));
1885                                         memset (nd, 0, sizeof(QCC_def_t));
1886                                         nd->type = var_a->type;
1887                                         nd->ofs = var_a->ofs + G_INT(var_b->ofs);
1888                                         nd->temp = var_a->temp;
1889                                         nd->constant = false;
1890                                         nd->name = var_a->name;
1891                                         return nd;
1892                                 }
1893                                 break;
1894                         case OP_BITOR_F:
1895                         case OP_OR_F:
1896                         case OP_SUB_F:
1897                         case OP_ADD_F:
1898                                 if (G_FLOAT(var_b->ofs) == 0)
1899                                 {
1900                                         optres_constantarithmatic++;
1901                                         QCC_UnFreeTemp(var_a);
1902                                         return var_a;
1903                                 }
1904                                 break;
1905                         case OP_DIV_F:
1906                         case OP_MUL_F:
1907                                 if (G_FLOAT(var_b->ofs) == 1)
1908                                 {
1909                                         optres_constantarithmatic++;
1910                                         QCC_UnFreeTemp(var_a);
1911                                         return var_a;
1912                                 }
1913                                 break;
1914                         //no bitand_f, I don't trust the casts
1915                         case OP_AND_F:
1916                                 if (G_FLOAT(var_b->ofs) != 0)
1917                                 {
1918                                         optres_constantarithmatic++;
1919                                         QCC_UnFreeTemp(var_a);
1920                                         return var_a;
1921                                 }
1922                                 break;
1923
1924                         case OP_BITOR_I:
1925                         case OP_OR_I:
1926                         case OP_SUB_I:
1927                         case OP_ADD_I:
1928                                 if (G_INT(var_b->ofs) == 0)
1929                                 {
1930                                         optres_constantarithmatic++;
1931                                         QCC_UnFreeTemp(var_a);
1932                                         return var_a;
1933                                 }
1934                                 break;
1935                         case OP_DIV_I:
1936                         case OP_MUL_I:
1937                                 if (G_INT(var_b->ofs) == 1)
1938                                 {
1939                                         optres_constantarithmatic++;
1940                                         QCC_UnFreeTemp(var_a);
1941                                         return var_a;
1942                                 }
1943                                 break;
1944                         case OP_BITAND_I:
1945                                 if (G_INT(var_b->ofs) == 0xffffffff)
1946                                 {
1947                                         optres_constantarithmatic++;
1948                                         QCC_UnFreeTemp(var_a);
1949                                         return var_a;
1950                                 }
1951                         case OP_AND_I:
1952                                 if (G_INT(var_b->ofs) == 0)
1953                                 {
1954                                         optres_constantarithmatic++;
1955                                         QCC_UnFreeTemp(var_a);
1956                                         return var_a;
1957                                 }
1958                                 break;
1959                         }
1960                 }
1961         }
1962
1963         switch (op - pr_opcodes)
1964         {
1965         case OP_LOADA_F:
1966         case OP_LOADA_V:
1967         case OP_LOADA_S:
1968         case OP_LOADA_ENT:
1969         case OP_LOADA_FLD:
1970         case OP_LOADA_FNC:
1971         case OP_LOADA_I:
1972                 break;
1973         case OP_AND_F:
1974                 if (var_a->ofs == var_b->ofs)
1975                         QCC_PR_ParseWarning(WARN_CONSTANTCOMPARISON, "Parameter offsets for && are the same");
1976                 if (var_a->constant || var_b->constant)
1977                         QCC_PR_ParseWarning(WARN_CONSTANTCOMPARISON, "Result of comparison is constant");
1978                 break;
1979         case OP_OR_F:
1980                 if (var_a->ofs == var_b->ofs)
1981                         QCC_PR_ParseWarning(WARN_CONSTANTCOMPARISON, "Parameters for || are the same");
1982                 if (var_a->constant || var_b->constant)
1983                         QCC_PR_ParseWarning(WARN_CONSTANTCOMPARISON, "Result of comparison is constant");
1984                 break;
1985         case OP_EQ_F:
1986         case OP_EQ_S:
1987         case OP_EQ_E:
1988         case OP_EQ_FNC:
1989 //              if (opt_shortenifnots)
1990 //                      if (var_b->constant && ((int*)qcc_pr_globals)[var_b->ofs]==0)   // (a == 0) becomes (!a)
1991 //                              op = &pr_opcodes[(op - pr_opcodes) - OP_EQ_F + OP_NOT_F];
1992         case OP_EQ_V:
1993
1994         case OP_NE_F:
1995         case OP_NE_V:
1996         case OP_NE_S:
1997         case OP_NE_E:
1998         case OP_NE_FNC:
1999
2000         case OP_LE_F:
2001         case OP_GE_F:
2002         case OP_LT_F:
2003         case OP_GT_F:
2004                 if ((var_a->constant && var_b->constant && !var_a->temp && !var_b->temp) || var_a->ofs == var_b->ofs)
2005                         QCC_PR_ParseWarning(WARN_CONSTANTCOMPARISON, "Result of comparison is constant");
2006                 break;
2007         case OP_IF_S:
2008         case OP_IFNOT_S:
2009         case OP_IF_F:
2010         case OP_IFNOT_F:
2011         case OP_IF_I:
2012         case OP_IFNOT_I:
2013 //              if (var_a->type->type == ev_function && !var_a->temp)
2014 //                      QCC_PR_ParseWarning(WARN_CONSTANTCOMPARISON, "Result of comparison is constant");
2015                 if (var_a->constant && !var_a->temp)
2016                         QCC_PR_ParseWarning(WARN_CONSTANTCOMPARISON, "Result of comparison is constant");
2017                 break;
2018         default:
2019                 break;
2020         }
2021
2022         if (numstatements)
2023         {       //optimise based on last statement.
2024                 if (op - pr_opcodes == OP_IFNOT_I)
2025                 {
2026                         if (opt_shortenifnots && var_a && (statements[numstatements-1].op == OP_NOT_F || statements[numstatements-1].op == OP_NOT_FNC || statements[numstatements-1].op == OP_NOT_ENT))
2027                         {
2028                                 if (statements[numstatements-1].c == var_a->ofs)
2029                                 {
2030                                         static QCC_def_t nvara;
2031                                         if (statements[numstatements-1].op == OP_NOT_F)
2032                                                 op = &pr_opcodes[OP_IF_F];
2033                                         else
2034                                                 op = &pr_opcodes[OP_IF_I];
2035                                         numstatements--;
2036                                         QCC_FreeTemp(var_a);
2037                                         memcpy(&nvara, var_a, sizeof(nvara));
2038                                         nvara.ofs = statements[numstatements].a;
2039                                         var_a = &nvara;
2040
2041                                         optres_shortenifnots++;
2042                                 }
2043                         }
2044                 }
2045                 else if (op - pr_opcodes == OP_IFNOT_F)
2046                 {
2047                         if (opt_shortenifnots && var_a && statements[numstatements-1].op == OP_NOT_F)
2048                         {
2049                                 if (statements[numstatements-1].c == var_a->ofs)
2050                                 {
2051                                         static QCC_def_t nvara;
2052                                         op = &pr_opcodes[OP_IF_F];
2053                                         numstatements--;
2054                                         QCC_FreeTemp(var_a);
2055                                         memcpy(&nvara, var_a, sizeof(nvara));
2056                                         nvara.ofs = statements[numstatements].a;
2057                                         var_a = &nvara;
2058
2059                                         optres_shortenifnots++;
2060                                 }
2061                         }
2062                 }
2063                 else if (op - pr_opcodes == OP_IFNOT_S)
2064                 {
2065                         if (opt_shortenifnots && var_a && statements[numstatements-1].op == OP_NOT_S)
2066                         {
2067                                 if (statements[numstatements-1].c == var_a->ofs)
2068                                 {
2069                                         static QCC_def_t nvara;
2070                                         op = &pr_opcodes[OP_IF_S];
2071                                         numstatements--;
2072                                         QCC_FreeTemp(var_a);
2073                                         memcpy(&nvara, var_a, sizeof(nvara));
2074                                         nvara.ofs = statements[numstatements].a;
2075                                         var_a = &nvara;
2076
2077                                         optres_shortenifnots++;
2078                                 }
2079                         }
2080                 }
2081                 else if (((unsigned) ((op - pr_opcodes) - OP_STORE_F) < 6) || (op-pr_opcodes) == OP_STORE_P)
2082                 {
2083                         // remove assignments if what should be assigned is the 3rd operand of the previous statement?
2084                         // don't if it's a call, callH, switch or case
2085                         // && var_a->ofs >RESERVED_OFS)
2086                         if (OpAssignsToC(statements[numstatements-1].op) &&
2087                             opt_assignments && var_a && var_a->ofs == statements[numstatements-1].c)
2088                         {
2089                                 if (var_a->type->type == var_b->type->type)
2090                                 {
2091                                         if (var_a->temp)
2092                                         {
2093                                                 statement = &statements[numstatements-1];
2094                                                 statement->c = var_b->ofs;
2095
2096                                                 if (var_a->type->type != var_b->type->type)
2097                                                         QCC_PR_ParseWarning(0, "store type mismatch");
2098                                                 var_b->references++;
2099                                                 var_a->references--;
2100                                                 QCC_FreeTemp(var_a);
2101                                                 optres_assignments++;
2102
2103                                                 simplestore=true;
2104
2105                                                 QCC_UnFreeTemp(var_b);
2106                                                 return var_b;
2107                                         }
2108                                 }
2109                         }
2110                 }
2111         }
2112         simplestore=false;
2113
2114         statement = &statements[numstatements];
2115         numstatements++;
2116
2117         if (!QCC_OPCodeValid(op))
2118         {
2119                 switch(op - pr_opcodes)
2120                 {
2121                 case OP_LOADA_STRUCT:
2122                         /*emit this anyway. if it reaches runtime then you messed up.
2123                         this is valid only if you do &foo[0]*/
2124                         break;
2125
2126
2127                 case OP_IF_S:
2128                         var_c = QCC_PR_GetDef(type_string, "string_null", NULL, true, 0, false);
2129                         numstatements--;
2130                         var_a = QCC_PR_Statement(&pr_opcodes[OP_NE_S], var_a, var_c, NULL);
2131                         statement = &statements[numstatements];
2132                         numstatements++;
2133
2134                         QCC_FreeTemp(var_a);
2135                         op = &pr_opcodes[OP_IF_I];
2136                         break;
2137
2138                 case OP_IFNOT_S:
2139                         var_c = QCC_PR_GetDef(type_string, "string_null", NULL, true, 0, false);
2140                         numstatements--;
2141                         var_a = QCC_PR_Statement(&pr_opcodes[OP_NE_S], var_a, var_c, NULL);
2142                         statement = &statements[numstatements];
2143                         numstatements++;
2144
2145                         QCC_FreeTemp(var_a);
2146                         op = &pr_opcodes[OP_IFNOT_I];
2147                         break;
2148
2149                 case OP_IF_F:
2150                         var_c = QCC_MakeFloatConst(0);
2151                         numstatements--;
2152                         var_a = QCC_PR_Statement(&pr_opcodes[OP_NE_F], var_a, var_c, NULL);
2153                         statement = &statements[numstatements];
2154                         numstatements++;
2155
2156                         QCC_FreeTemp(var_a);
2157                         op = &pr_opcodes[OP_IF_I];
2158                         break;
2159
2160                 case OP_IFNOT_F:
2161                         var_c = QCC_MakeFloatConst(0);
2162                         numstatements--;
2163                         var_a = QCC_PR_Statement(&pr_opcodes[OP_NE_F], var_a, var_c, NULL);
2164                         statement = &statements[numstatements];
2165                         numstatements++;
2166
2167                         QCC_FreeTemp(var_a);
2168                         op = &pr_opcodes[OP_IFNOT_I];
2169                         break;
2170
2171                 case OP_ADDSTORE_F:
2172                         op = &pr_opcodes[OP_ADD_F];
2173                         var_c = var_b;
2174                         var_b = var_a;
2175                         var_a = var_c;
2176                         var_c = var_a;
2177                         break;
2178                 case OP_ADDSTORE_I:
2179                         op = &pr_opcodes[OP_ADD_I];
2180                         var_c = var_b;
2181                         var_b = var_a;
2182                         var_a = var_c;
2183                         var_c = var_a;
2184                         break;
2185                 case OP_ADDSTORE_FI:
2186                         op = &pr_opcodes[OP_ADD_FI];
2187                         var_c = var_b;
2188                         var_b = var_a;
2189                         var_a = var_c;
2190                         var_c = var_a;
2191                         break;
2192                 case OP_ADDSTORE_IF:
2193                         op = &pr_opcodes[OP_ADD_IF];
2194                         var_c = var_b;
2195                         var_b = var_a;
2196                         var_a = var_c;
2197                         var_c = var_a;
2198                         break;
2199
2200                 case OP_SUBSTORE_F:
2201                         op = &pr_opcodes[OP_SUB_F];
2202                         var_c = var_b;
2203                         var_b = var_a;
2204                         var_a = var_c;
2205                         var_c = var_a;
2206                         break;
2207                 case OP_SUBSTORE_FI:
2208                         op = &pr_opcodes[OP_SUB_FI];
2209                         var_c = var_b;
2210                         var_b = var_a;
2211                         var_a = var_c;
2212                         var_c = var_a;
2213                         break;
2214                 case OP_SUBSTORE_IF:
2215                         op = &pr_opcodes[OP_SUB_IF];
2216                         var_c = var_b;
2217                         var_b = var_a;
2218                         var_a = var_c;
2219                         var_c = var_a;
2220                         break;
2221
2222                 case OP_DIVSTORE_F:
2223                         op = &pr_opcodes[OP_DIV_F];
2224                         var_c = var_b;
2225                         var_b = var_a;
2226                         var_a = var_c;
2227                         var_c = var_a;
2228                         break;
2229                 case OP_DIVSTORE_FI:
2230                         op = &pr_opcodes[OP_DIV_FI];
2231                         var_c = var_b;
2232                         var_b = var_a;
2233                         var_a = var_c;
2234                         var_c = var_a;
2235                         break;
2236                 case OP_DIVSTORE_IF:
2237                         op = &pr_opcodes[OP_DIV_IF];
2238                         var_c = var_b;
2239                         var_b = var_a;
2240                         var_a = var_c;
2241                         var_c = var_a;
2242                         break;
2243
2244                 case OP_MULSTORE_F:
2245                         op = &pr_opcodes[OP_MUL_F];
2246                         var_c = var_b;
2247                         var_b = var_a;
2248                         var_a = var_c;
2249                         var_c = var_a;
2250                         break;
2251                 case OP_MULSTORE_IF:
2252                         op = &pr_opcodes[OP_MUL_IF];
2253                         var_c = var_b;
2254                         var_b = var_a;
2255                         var_a = var_c;
2256                         var_c = var_a;
2257                         break;
2258                 case OP_MULSTORE_FI:
2259                         op = &pr_opcodes[OP_MUL_FI];
2260                         var_c = var_b;
2261                         var_b = var_a;
2262                         var_a = var_c;
2263                         var_c = var_a;
2264                         break;
2265
2266                 case OP_ADDSTORE_V:
2267                         op = &pr_opcodes[OP_ADD_V];
2268                         var_c = var_b;
2269                         var_b = var_a;
2270                         var_a = var_c;
2271                         var_c = var_a;
2272                         break;
2273
2274                 case OP_SUBSTORE_V:
2275                         op = &pr_opcodes[OP_SUB_V];
2276                         var_c = var_b;
2277                         var_b = var_a;
2278                         var_a = var_c;
2279                         var_c = var_a;
2280                         break;
2281
2282                 case OP_MULSTORE_VF:
2283                         op = &pr_opcodes[OP_MUL_VF];
2284                         var_c = var_b;
2285                         var_b = var_a;
2286                         var_a = var_c;
2287                         var_c = var_a;
2288                         break;
2289                 case OP_MULSTORE_VI:
2290                         op = &pr_opcodes[OP_MUL_VI];
2291                         var_c = var_b;
2292                         var_b = var_a;
2293                         var_a = var_c;
2294                         var_c = var_a;
2295                         break;
2296
2297                 case OP_BITSET_I:
2298                         op = &pr_opcodes[OP_BITOR_I];
2299                         var_c = var_b;
2300                         var_b = var_a;
2301                         var_a = var_c;
2302                         var_c = var_a;
2303                         break;
2304                 case OP_BITSET:
2305                         op = &pr_opcodes[OP_BITOR_F];
2306                         var_c = var_b;
2307                         var_b = var_a;
2308                         var_a = var_c;
2309                         var_c = var_a;
2310                         break;
2311
2312                 case OP_STOREP_P:
2313                         op = &pr_opcodes[OP_STOREP_I];
2314                         break;
2315
2316                 case OP_BITCLR:
2317                         //b = var, a = bit field.
2318
2319                         QCC_UnFreeTemp(var_a);
2320                         QCC_UnFreeTemp(var_b);
2321
2322                         numstatements--;
2323                         var_c = QCC_PR_Statement(&pr_opcodes[OP_BITAND_F], var_b, var_a, NULL);
2324                         QCC_FreeTemp(var_c);
2325                         statement = &statements[numstatements];
2326                         numstatements++;
2327
2328                         QCC_FreeTemp(var_a);
2329                         QCC_FreeTemp(var_b);
2330
2331                         op = &pr_opcodes[OP_SUB_F];
2332                         var_a = var_b;
2333                         var_b = var_c;
2334                         var_c = var_a;
2335                         break;
2336
2337                 case OP_SUBSTOREP_FI:
2338                 case OP_SUBSTOREP_IF:
2339                 case OP_ADDSTOREP_FI:
2340                 case OP_ADDSTOREP_IF:
2341                 case OP_MULSTOREP_FI:
2342                 case OP_MULSTOREP_IF:
2343                 case OP_DIVSTOREP_FI:
2344                 case OP_DIVSTOREP_IF:
2345
2346                 case OP_MULSTOREP_VF:
2347                 case OP_MULSTOREP_VI:
2348                 case OP_SUBSTOREP_V:
2349                 case OP_ADDSTOREP_V:
2350
2351                 case OP_SUBSTOREP_F:
2352                 case OP_SUBSTOREP_I:
2353                 case OP_ADDSTOREP_I:
2354                 case OP_ADDSTOREP_F:
2355                 case OP_MULSTOREP_F:
2356                 case OP_DIVSTOREP_F:
2357                 case OP_BITSETP:
2358                 case OP_BITSETP_I:
2359                 case OP_BITCLRP:
2360 //                      QCC_PR_ParseWarning(0, "XSTOREP_F emulation is still experimental");
2361                         QCC_UnFreeTemp(var_a);
2362                         QCC_UnFreeTemp(var_b);
2363                         //don't chain these... this expansion is not the same.
2364                         {
2365                                 int st;
2366                                 int need_lock = false;
2367                                 if (var_b->temp)
2368                                 {
2369                                         for (st = numstatements-2; st>=0; st--)
2370                                         {
2371                                                 if (statements[st].op == OP_ADDRESS)
2372                                                         if (statements[st].c == var_b->ofs)
2373                                                                 break;
2374
2375                                                 if ((statements[st].op >= OP_CALL0 && statements[st].op <= OP_CALL8) || (statements[st].op >= OP_CALL1H && statements[st].op <= OP_CALL8H))
2376                                                         need_lock = true;
2377
2378                                                 if (statements[st].c == var_b->ofs)
2379                                                 {
2380                                                         st = -1;
2381                                                         break;
2382                                                 }
2383                                         }
2384                                 }
2385                                 else
2386                                         st = -1;
2387
2388                                 var_c = QCC_GetTemp(*op->type_c);
2389                                 if (st < 0)
2390                                 {
2391                                         /*generate new OP_LOADP instruction*/
2392                                         statement->op = ((*op->type_c)->type==ev_vector)?OP_LOADP_V:OP_LOADP_F;
2393                                         statement->a = var_b->ofs;
2394                                         statement->b = var_c->ofs;
2395                                         statement->c = 0;
2396                                 }
2397                                 else
2398                                 {
2399                                         /*it came from an OP_ADDRESS - st says the instruction*/
2400                                         if (need_lock)
2401                                         {
2402                                                 QCC_ForceLockTempForOffset(statements[st].a);
2403                                                 QCC_ForceLockTempForOffset(statements[st].b);
2404                                                 QCC_LockTemp(var_c); /*that temp needs to be preserved over calls*/
2405                                         }
2406
2407                                         /*generate new OP_ADDRESS instruction - FIXME: the arguments may have changed since the original instruction*/
2408                                         statement_linenums[statement-statements] = statement_linenums[st];
2409                                         statement->op = OP_ADDRESS;
2410                                         statement->a = statements[st].a;
2411                                         statement->b = statements[st].b;
2412                                         statement->c = statements[st].c;
2413
2414                                         /*convert old one to an OP_LOAD*/
2415                                         statement_linenums[st] = pr_source_line;
2416                                         statements[st].op = ((*op->type_c)->type==ev_vector)?OP_LOAD_V:OP_LOAD_F;
2417                                         statements[st].a = statements[st].a;
2418                                         statements[st].b = statements[st].b;
2419                                         statements[st].c = var_c->ofs;
2420                                 }
2421                         }
2422
2423                         statement = &statements[numstatements];
2424                         numstatements++;
2425
2426                         statement_linenums[statement-statements] = pr_source_line;
2427                         switch(op - pr_opcodes)
2428                         {
2429                         case OP_SUBSTOREP_V:
2430                                 statement->op = OP_SUB_V;
2431                                 break;
2432                         case OP_ADDSTOREP_V:
2433                                 statement->op = OP_ADD_V;
2434                                 break;
2435                         case OP_MULSTOREP_VF:
2436                                 statement->op = OP_MUL_VF;
2437                                 break;
2438                         case OP_MULSTOREP_VI:
2439                                 statement->op = OP_MUL_VI;
2440                                 break;
2441                         case OP_SUBSTOREP_F:
2442                                 statement->op = OP_SUB_F;
2443                                 break;
2444                         case OP_SUBSTOREP_I:
2445                                 statement->op = OP_SUB_I;
2446                                 break;
2447                         case OP_SUBSTOREP_IF:
2448                                 statement->op = OP_SUB_IF;
2449                                 break;
2450                         case OP_SUBSTOREP_FI:
2451                                 statement->op = OP_SUB_FI;
2452                                 break;
2453                         case OP_ADDSTOREP_IF:
2454                                 statement->op = OP_ADD_IF;
2455                                 break;
2456                         case OP_ADDSTOREP_FI:
2457                                 statement->op = OP_ADD_FI;
2458                                 break;
2459                         case OP_MULSTOREP_IF:
2460                                 statement->op = OP_MUL_IF;
2461                                 break;
2462                         case OP_MULSTOREP_FI:
2463                                 statement->op = OP_MUL_FI;
2464                                 break;
2465                         case OP_DIVSTOREP_IF:
2466                                 statement->op = OP_DIV_IF;
2467                                 break;
2468                         case OP_DIVSTOREP_FI:
2469                                 statement->op = OP_DIV_FI;
2470                                 break;
2471                         case OP_ADDSTOREP_F:
2472                                 statement->op = OP_ADD_F;
2473                                 break;
2474                         case OP_ADDSTOREP_I:
2475                                 statement->op = OP_ADD_I;
2476                                 break;
2477                         case OP_MULSTOREP_F:
2478                                 statement->op = OP_MUL_F;
2479                                 break;
2480                         case OP_DIVSTOREP_F:
2481                                 statement->op = OP_DIV_F;
2482                                 break;
2483                         case OP_BITSETP:
2484                                 statement->op = OP_BITOR_F;
2485                                 break;
2486                         case OP_BITSETP_I:
2487                                 statement->op = OP_BITOR_I;
2488                                 break;
2489                         case OP_BITCLRP:
2490                                 //float pointer float
2491                                 temp = QCC_GetTemp(type_float);
2492                                 statement->op = OP_BITAND_F;
2493                                 statement->a = var_c ? var_c->ofs : 0;
2494                                 statement->b = var_a ? var_a->ofs : 0;
2495                                 statement->c = temp->ofs;
2496
2497                                 statement = &statements[numstatements];
2498                                 numstatements++;
2499
2500                                 statement_linenums[statement-statements] = pr_source_line;
2501                                 statement->op = OP_SUB_F;
2502
2503                                 //t = c & i
2504                                 //c = c - t
2505                                 break;
2506                         default:        //no way will this be hit...
2507                                 QCC_PR_ParseError(ERR_INTERNAL, "opcode invalid 3 times %i", op - pr_opcodes);
2508                         }
2509                         if (op - pr_opcodes == OP_BITCLRP)
2510                         {
2511                                 statement->a = var_c ? var_c->ofs : 0;
2512                                 statement->b = temp ? temp->ofs : 0;
2513                                 statement->c = var_c->ofs;
2514                                 QCC_FreeTemp(temp);
2515                                 var_b = var_b;  //this is the ptr.
2516                                 QCC_FreeTemp(var_a);
2517                                 var_a = var_c;  //this is the value.
2518                         }
2519                         else
2520                         {
2521                                 statement->a = var_c ? var_c->ofs : 0;
2522                                 statement->b = var_a ? var_a->ofs : 0;
2523                                 statement->c = var_c->ofs;
2524                                 var_b = var_b;  //this is the ptr.
2525                                 QCC_FreeTemp(var_a);
2526                                 var_a = var_c;  //this is the value.
2527                         }
2528
2529                         op = &pr_opcodes[((*op->type_c)->type==ev_vector)?OP_STOREP_V:OP_STOREP_F];
2530                         QCC_FreeTemp(var_c);
2531                         var_c = NULL;
2532                         QCC_FreeTemp(var_b);
2533
2534                         statement = &statements[numstatements];
2535                         numstatements++;
2536                         break;
2537
2538                 default:
2539                         QCC_PR_ParseError(ERR_BADEXTENSION, "Opcode \"%s|%s\" not valid for target", op->name, op->opname);
2540                         break;
2541                 }
2542         }
2543
2544         if (outstatement)
2545                 *outstatement = statement;
2546
2547         statement_linenums[statement-statements] = pr_source_line;
2548         statement->op = op - pr_opcodes;
2549         statement->a = var_a ? var_a->ofs : 0;
2550         statement->b = var_b ? var_b->ofs : 0;
2551         if (var_c != NULL)
2552         {
2553                 statement->c = var_c->ofs;
2554         }
2555         else if (op->type_c == &type_void || op->associative==ASSOC_RIGHT || op->type_c == NULL)
2556         {
2557                 var_c = NULL;
2558                 statement->c = 0;                       // ifs, gotos, and assignments
2559                                                                         // don't need vars allocated
2560         }
2561         else
2562         {       // allocate result space
2563                 var_c = QCC_GetTemp(*op->type_c);
2564                 statement->c = var_c->ofs;
2565                 if (op->type_b == &type_field)
2566                 {
2567                         var_c->name = var_b->name;
2568                         var_c->s_file = var_b->s_file;
2569                         var_c->s_line = var_b->s_line;
2570                 }
2571         }
2572
2573         if ((op - pr_opcodes >= OP_LOAD_F && op - pr_opcodes <= OP_LOAD_FNC) ||
2574                 op - pr_opcodes == OP_LOAD_I)
2575         {
2576                 if (var_b->constant == 2)
2577                         var_c->constant = true;
2578         }
2579
2580         if (!var_c)
2581         {
2582                 if (var_a)
2583                         QCC_UnFreeTemp(var_a);
2584                 return var_a;
2585         }
2586         return var_c;
2587 }
2588
2589 /*
2590 ============
2591 QCC_PR_SimpleStatement
2592
2593 Emits a primitive statement, returning the var it places it's value in
2594 ============
2595 */
2596 QCC_dstatement_t *QCC_PR_SimpleStatement( int op, int var_a, int var_b, int var_c, int force)
2597 {
2598         QCC_dstatement_t        *statement;
2599
2600         if (!force && !QCC_OPCodeValid(pr_opcodes+op))
2601         {
2602                 QCC_PR_ParseError(ERR_BADEXTENSION, "Opcode \"%s|%s\" not valid for target\n", pr_opcodes[op].name, pr_opcodes[op].opname);
2603         }
2604
2605         statement_linenums[numstatements] = pr_source_line;
2606         statement = &statements[numstatements];
2607
2608         numstatements++;
2609         statement->op = op;
2610         statement->a = var_a;
2611         statement->b = var_b;
2612         statement->c = var_c;
2613         return statement;
2614 }
2615
2616 void QCC_PR_Statement3 ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_b, QCC_def_t *var_c, int force)
2617 {
2618         QCC_dstatement_t        *statement;
2619
2620         if (!force && !QCC_OPCodeValid(op))
2621         {
2622 //              outputversion = op->extension;
2623 //              if (noextensions)
2624                 QCC_PR_ParseError(ERR_BADEXTENSION, "Opcode \"%s|%s\" not valid for target\n", op->name, op->opname);
2625         }
2626
2627         statement = &statements[numstatements];
2628         numstatements++;
2629
2630         statement_linenums[statement-statements] = pr_source_line;
2631         statement->op = op - pr_opcodes;
2632         statement->a = var_a ? var_a->ofs : 0;
2633         statement->b = var_b ? var_b->ofs : 0;
2634         statement->c = var_c ? var_c->ofs : 0;
2635 }
2636
2637 /*
2638 ============
2639 PR_ParseImmediate
2640
2641 Looks for a preexisting constant
2642 ============
2643 */
2644 QCC_def_t       *QCC_PR_ParseImmediate (void)
2645 {
2646         QCC_def_t       *cn;
2647
2648         if (pr_immediate_type == type_float)
2649         {
2650                 cn = QCC_MakeFloatConst(pr_immediate._float);
2651                 QCC_PR_Lex ();
2652                 return cn;
2653         }
2654         if (pr_immediate_type == type_integer)
2655         {
2656                 cn = QCC_MakeIntConst(pr_immediate._int);
2657                 QCC_PR_Lex ();
2658                 return cn;
2659         }
2660
2661         if (pr_immediate_type == type_string)
2662         {
2663                 char tmp[8192];
2664                 strcpy(tmp, pr_immediate_string);
2665
2666                 for(;;)
2667                 {
2668                         QCC_PR_Lex ();
2669                         if (pr_token_type == tt_immediate && pr_token_type == tt_immediate)
2670                                 strcat(tmp, pr_immediate_string);
2671                         else
2672                                 break;
2673                 } 
2674
2675                 cn = QCC_MakeStringConst(tmp);
2676                 return cn;
2677         }
2678
2679 // check for a constant with the same value
2680         for (cn=pr.def_head.next ; cn ; cn=cn->next)    //FIXME - hashtable.
2681         {
2682                 if (!cn->initialized)
2683                         continue;
2684                 if (!cn->constant)
2685                         continue;
2686                 if (cn->type != pr_immediate_type)
2687                         continue;
2688                 if (pr_immediate_type == type_string)
2689                 {
2690                         if (!STRCMP(G_STRING(cn->ofs), pr_immediate_string) )
2691                         {
2692                                 QCC_PR_Lex ();
2693                                 return cn;
2694                         }
2695                 }
2696                 else if (pr_immediate_type == type_float)
2697                 {
2698                         if ( G_FLOAT(cn->ofs) == pr_immediate._float )
2699                         {
2700                                 QCC_PR_Lex ();
2701                                 return cn;
2702                         }
2703                 }
2704                 else if (pr_immediate_type == type_integer)
2705                 {
2706                         if ( G_INT(cn->ofs) == pr_immediate._int )
2707                         {
2708                                 QCC_PR_Lex ();
2709                                 return cn;
2710                         }
2711                 }
2712                 else if (pr_immediate_type == type_vector)
2713                 {
2714                         if ( ( G_FLOAT(cn->ofs) == pr_immediate.vector[0] )
2715                         && ( G_FLOAT(cn->ofs+1) == pr_immediate.vector[1] )
2716                         && ( G_FLOAT(cn->ofs+2) == pr_immediate.vector[2] ) )
2717                         {
2718                                 QCC_PR_Lex ();
2719                                 return cn;
2720                         }
2721                 }
2722                 else
2723                         QCC_PR_ParseError (ERR_BADIMMEDIATETYPE, "weird immediate type");
2724         }
2725
2726 // allocate a new one
2727         cn = (void *)qccHunkAlloc (sizeof(QCC_def_t));
2728         cn->next = NULL;
2729         pr.def_tail->next = cn;
2730         pr.def_tail = cn;
2731
2732         cn->type = pr_immediate_type;
2733         cn->name = "IMMEDIATE";
2734         cn->constant = true;
2735         cn->initialized = 1;
2736         cn->scope = NULL;               // always share immediates
2737
2738 // copy the immediate to the global area
2739         cn->ofs = QCC_GetFreeOffsetSpace(type_size[pr_immediate_type->type]);
2740
2741         if (pr_immediate_type == type_string)
2742                 pr_immediate.string = QCC_CopyString (pr_immediate_string);
2743
2744         memcpy (qcc_pr_globals + cn->ofs, &pr_immediate, 4*type_size[pr_immediate_type->type]);
2745
2746         QCC_PR_Lex ();
2747
2748         return cn;
2749 }
2750
2751
2752 void QCC_PrecacheSound (QCC_def_t *e, int ch)
2753 {
2754         char    *n;
2755         int             i;
2756
2757         if (e->type->type != ev_string)
2758                 return;
2759
2760         if (!e->ofs || e->temp || !e->constant)
2761                 return;
2762         n = G_STRING(e->ofs);
2763         if (!*n)
2764                 return;
2765         for (i=0 ; i<numsounds ; i++)
2766                 if (!STRCMP(n, precache_sounds[i]))
2767                         return;
2768         if (numsounds == MAX_SOUNDS)
2769                 return;
2770 //              QCC_Error ("PrecacheSound: numsounds == MAX_SOUNDS");
2771         strcpy (precache_sounds[i], n);
2772         if (ch >= '1'  && ch <= '9')
2773                 precache_sounds_block[i] = ch - '0';
2774         else
2775                 precache_sounds_block[i] = 1;
2776         numsounds++;
2777 }
2778
2779 void QCC_PrecacheModel (QCC_def_t *e, int ch)
2780 {
2781         char    *n;
2782         int             i;
2783
2784         if (e->type->type != ev_string)
2785                 return;
2786
2787         if (!e->ofs || e->temp || !e->constant)
2788                 return;
2789         n = G_STRING(e->ofs);
2790         if (!*n)
2791                 return;
2792         for (i=0 ; i<nummodels ; i++)
2793                 if (!STRCMP(n, precache_models[i]))
2794                 {
2795                         if (!precache_models_block[i])
2796                         {
2797                                 if (ch >= '1'  && ch <= '9')
2798                                         precache_models_block[i] = ch - '0';
2799                                 else
2800                                         precache_models_block[i] = 1;
2801                         }
2802                         return;
2803                 }
2804         if (nummodels == MAX_MODELS)
2805                 return;
2806 //              QCC_Error ("PrecacheModels: nummodels == MAX_MODELS");
2807         strcpy (precache_models[i], n);
2808         if (ch >= '1'  && ch <= '9')
2809                 precache_models_block[i] = ch - '0';
2810         else
2811                 precache_models_block[i] = 1;
2812         nummodels++;
2813 }
2814
2815 void QCC_SetModel (QCC_def_t *e)
2816 {
2817         char    *n;
2818         int             i;
2819
2820         if (e->type->type != ev_string)
2821                 return;
2822
2823         if (!e->ofs || e->temp || !e->constant)
2824                 return;
2825         n = G_STRING(e->ofs);
2826         if (!*n)
2827                 return;
2828         for (i=0 ; i<nummodels ; i++)
2829                 if (!STRCMP(n, precache_models[i]))
2830                 {
2831                         precache_models_used[i]++;
2832                         return;
2833                 }
2834         if (nummodels == MAX_MODELS)
2835                 return;
2836         strcpy (precache_models[i], n);
2837         precache_models_block[i] = 0;
2838         precache_models_used[i]=1;
2839         nummodels++;
2840 }
2841
2842 void QCC_PrecacheTexture (QCC_def_t *e, int ch)
2843 {
2844         char    *n;
2845         int             i;
2846
2847         if (e->type->type != ev_string)
2848                 return;
2849
2850         if (!e->ofs || e->temp || !e->constant)
2851                 return;
2852         n = G_STRING(e->ofs);
2853         if (!*n)
2854                 return;
2855         for (i=0 ; i<numtextures ; i++)
2856                 if (!STRCMP(n, precache_textures[i]))
2857                         return;
2858         if (nummodels == MAX_MODELS)
2859                 return;
2860 //              QCC_Error ("PrecacheTextures: numtextures == MAX_TEXTURES");
2861         strcpy (precache_textures[i], n);
2862         if (ch >= '1'  && ch <= '9')
2863                 precache_textures_block[i] = ch - '0';
2864         else
2865                 precache_textures_block[i] = 1;
2866         numtextures++;
2867 }
2868
2869 void QCC_PrecacheFile (QCC_def_t *e, int ch)
2870 {
2871         char    *n;
2872         int             i;
2873
2874         if (e->type->type != ev_string)
2875                 return;
2876
2877         if (!e->ofs || e->temp || !e->constant)
2878                 return;
2879         n = G_STRING(e->ofs);
2880         if (!*n)
2881                 return;
2882         for (i=0 ; i<numfiles ; i++)
2883                 if (!STRCMP(n, precache_files[i]))
2884                         return;
2885         if (numfiles == MAX_FILES)
2886                 return;
2887 //              QCC_Error ("PrecacheFile: numfiles == MAX_FILES");
2888         strcpy (precache_files[i], n);
2889         if (ch >= '1'  && ch <= '9')
2890                 precache_files_block[i] = ch - '0';
2891         else
2892                 precache_files_block[i] = 1;
2893         numfiles++;
2894 }
2895
2896 void QCC_PrecacheFileOptimised (char *n, int ch)
2897 {
2898         int             i;
2899
2900         for (i=0 ; i<numfiles ; i++)
2901                 if (!STRCMP(n, precache_files[i]))
2902                         return;
2903         if (numfiles == MAX_FILES)
2904                 return;
2905 //              QCC_Error ("PrecacheFile: numfiles == MAX_FILES");
2906         strcpy (precache_files[i], n);
2907         if (ch >= '1'  && ch <= '9')
2908                 precache_files_block[i] = ch - '0';
2909         else
2910                 precache_files_block[i] = 1;
2911         numfiles++;
2912 }
2913
2914 QCC_def_t *QCC_PR_GenerateFunctionCall (QCC_def_t *func, QCC_def_t *arglist[], int argcount)    //warning, the func could have no name set if it's a field call.
2915 {
2916         QCC_def_t               *d, *oldret, *oself;
2917         int                     i;
2918         QCC_type_t              *t;
2919         int extraparms=false;
2920         int np;
2921         int laststatement = numstatements;
2922
2923         int callconvention;
2924         QCC_dstatement_t *st;
2925
2926
2927         func->timescalled++;
2928
2929         if (QCC_OPCodeValid(&pr_opcodes[OP_CALL1H]))
2930                 callconvention = OP_CALL1H;     //FTE extended
2931         else
2932                 callconvention = OP_CALL1;      //standard
2933
2934         t = func->type;
2935
2936         if (t->type == ev_variant)
2937         {
2938                 t->aux_type = type_variant;
2939         }
2940
2941         if (t->type != ev_function && t->type != ev_variant)
2942         {
2943                 QCC_PR_ParseErrorPrintDef (ERR_NOTAFUNCTION, func, "not a function");
2944         }
2945
2946 // copy the arguments to the global parameter variables
2947         if (t->type == ev_variant)
2948         {
2949                 extraparms = true;
2950                 np = 0;
2951         }
2952         else if (t->num_parms < 0)
2953         {
2954                 extraparms = true;
2955                 np = (t->num_parms * -1) - 1;
2956         }
2957         else
2958                 np = t->num_parms;
2959
2960         if (strchr(func->name, ':') && laststatement && statements[laststatement-1].op == OP_LOAD_FNC && statements[laststatement-1].c == func->ofs)
2961         {       //we're entering OO code with a different self.
2962                 //eg: other.touch(self)
2963
2964                 //FIXME: problems could occur with hexen2 calling conventions when parm0/1 is 'self'
2965                 //thiscall. copy the right ent into 'self' (if it's not the same offset)
2966                 d = QCC_PR_GetDef(type_entity, "self", NULL, true, 0, false);
2967                 if (statements[laststatement-1].a != d->ofs)
2968                 {
2969                         oself = QCC_GetTemp(type_entity);
2970                         //oself = self
2971                         QCC_PR_SimpleStatement(OP_STORE_ENT, d->ofs, oself->ofs, 0, false);
2972                         //self = other
2973                         QCC_PR_SimpleStatement(OP_STORE_ENT, statements[laststatement-1].a, d->ofs, 0, false);
2974
2975                         //if the args refered to self, update them to refer to oself instead
2976                         //(as self is now set to 'other')
2977                         for (i = 0; i < argcount; i++)
2978                         {
2979                                 if (arglist[i]->ofs == d->ofs)
2980                                 {
2981                                         arglist[i] = oself;
2982                                 }
2983                         }
2984                 }
2985                 else
2986                 {
2987                         //it was self.func() anyway
2988                         oself = NULL;
2989                         d = NULL;
2990                 }
2991         }
2992         else
2993         {       //regular func call
2994                 oself = NULL;
2995                 d = NULL;
2996         }
2997
2998 //      write the arguments (except for first two if hexenc)
2999         for (i = 0; i < argcount; i++)
3000         {
3001                 if (i>=MAX_PARMS)
3002                         d = extra_parms[i - MAX_PARMS];
3003                 else
3004                         d = &def_parms[i];
3005
3006                 if (callconvention == OP_CALL1H)
3007                         if (i < 2)
3008                         {
3009                                 //first two args are passed in the call opcode, so don't need to be copied
3010                                 arglist[i]->references++;
3011                                 d->references++;
3012                                 /*don't free these temps yet, free them after the return check*/
3013                                 continue;
3014                         }
3015
3016                 if (arglist[i]->type->size == 3 || !opt_nonvec_parms)
3017                         QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_V], arglist[i], d, (QCC_dstatement_t **)0xffffffff));
3018                 else
3019                 {
3020                         d->type = arglist[i]->type;
3021                         QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], arglist[i], d, (QCC_dstatement_t **)0xffffffff));
3022                         optres_nonvec_parms++;
3023                 }
3024         }
3025
3026         //if the return value was in use, save it off now, so that it doesn't get clobbered
3027         if (def_ret.temp->used)
3028                 oldret = QCC_GetTemp(def_ret.type);
3029         else
3030                 oldret = NULL;
3031
3032         /*can free temps used for arguments now*/
3033         if (callconvention == OP_CALL1H)
3034         {
3035                 for (i = 0; i < argcount && i < 2; i++)
3036                         QCC_FreeTemp(arglist[i]);
3037         }
3038
3039         if (oldret && !def_ret.temp->used)
3040         {
3041                 QCC_FreeTemp(oldret);
3042                 oldret = NULL;
3043         }
3044         else if (def_ret.temp->used)
3045         {
3046                 if (def_ret.type->size == 3)
3047                         QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_V], &def_ret, oldret, (void*)0xffffffff));
3048                 else
3049                         QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], &def_ret, oldret, (void*)0xffffffff));
3050                 QCC_UnFreeTemp(oldret);
3051                 QCC_UnFreeTemp(&def_ret);
3052                 QCC_PR_ParseWarning(WARN_FIXEDRETURNVALUECONFLICT, "Return value conflict - output is inefficient");
3053         }
3054         else
3055                 oldret = NULL;
3056
3057         //we dont need to lock the local containing the function index because its thrown away after the call anyway
3058         //(if a function is called in the argument list then it'll be locked as part of that call)
3059         QCC_FreeTemp(func);
3060         QCC_LockActiveTemps();  //any temps before are likly to be used with the return value.
3061         QCC_UnFreeTemp(func);
3062
3063         //generate the call
3064         if (argcount>MAX_PARMS)
3065                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[callconvention-1+MAX_PARMS], func, 0, (QCC_dstatement_t **)&st));
3066         else if (argcount)
3067                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[callconvention-1+argcount], func, 0, (QCC_dstatement_t **)&st));
3068         else
3069                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_CALL0], func, 0, (QCC_dstatement_t **)&st));
3070
3071         if (callconvention == OP_CALL1H)
3072         {
3073                 if (argcount)
3074                 {
3075                         st->b = arglist[0]->ofs;
3076 //                      QCC_FreeTemp(param[0]);
3077                         if (argcount>1)
3078                         {
3079                                 st->c = arglist[1]->ofs;
3080 //                              QCC_FreeTemp(param[1]);
3081                         }
3082                 }
3083         }
3084
3085         //restore the class owner
3086         if (oself)
3087                 QCC_PR_SimpleStatement(OP_STORE_ENT, oself->ofs, d->ofs, 0, false);
3088
3089         if (oldret)
3090         {
3091                 if (oldret->temp && !oldret->temp->used)
3092                         QCC_PR_ParseWarning(0, "Ret was freed\n");
3093
3094                 //if we preserved the ofs_ret global, restore it here
3095                 if (t->type == ev_variant)
3096                 {
3097                         d = QCC_GetTemp(type_variant);
3098                         QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, &def_ret, d, (void*)0xffffffff));
3099                 }
3100                 else
3101                 {
3102                         d = QCC_GetTemp(t->aux_type);
3103                         if (t->aux_type->size == 3)
3104                                 QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_V, &def_ret, d, (void*)0xffffffff));
3105                         else
3106                                 QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, &def_ret, d, (void*)0xffffffff));
3107                 }
3108                 if (def_ret.type->size == 3)
3109                         QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_V, oldret, &def_ret, (void*)0xffffffff));
3110                 else
3111                         QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, oldret, &def_ret, (void*)0xffffffff));
3112                 QCC_FreeTemp(oldret);
3113                 QCC_UnFreeTemp(&def_ret);
3114                 QCC_UnFreeTemp(d);
3115
3116                 return d;
3117         }
3118
3119         if (t->type == ev_variant)
3120                 def_ret.type = type_variant;
3121         else
3122                 def_ret.type = t->aux_type;
3123         if (def_ret.temp->used)
3124                 QCC_PR_ParseWarning(WARN_FIXEDRETURNVALUECONFLICT, "Return value conflict - output is inefficient");
3125         def_ret.temp->used = true;
3126
3127         return &def_ret;
3128 }
3129
3130 /*
3131 ============
3132 PR_ParseFunctionCall
3133 ============
3134 */
3135 QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func)   //warning, the func could have no name set if it's a field call.
3136 {
3137         QCC_def_t               *e, *d, *old = {0}, *oself, *out; // warning: \91old\92 may be used uninitialized in this function
3138         int                     arg;
3139         QCC_type_t              *t, *p;
3140         int extraparms=false;
3141         int np;
3142
3143         int callconvention;
3144
3145         QCC_def_t *param[MAX_PARMS+MAX_EXTRA_PARMS];
3146
3147         func->timescalled++;
3148
3149         if (QCC_OPCodeValid(&pr_opcodes[OP_CALL1H]))
3150                 callconvention = OP_CALL1H;     //FTE extended
3151         else
3152                 callconvention = OP_CALL1;      //standard
3153
3154         t = func->type;
3155
3156         if (t->type == ev_variant)
3157         {
3158                 t->aux_type = type_variant;
3159         }
3160
3161         if (t->type != ev_function && t->type != ev_variant)
3162         {
3163                 QCC_PR_ParseErrorPrintDef (ERR_NOTAFUNCTION, func, "not a function");
3164         }
3165
3166         if (!t->num_parms&&t->type != ev_variant)       //intrinsics. These base functions have variable arguments. I would check for (...) args too, but that might be used for extended builtin functionality. (this code wouldn't compile otherwise)
3167         {
3168                 if (!strcmp(func->name, "sizeof"))
3169                 {
3170                         QCC_type_t *t;
3171                         if (!func->initialized)
3172                                 func->initialized = 3;
3173                         func->references++;
3174                         t = QCC_PR_ParseType(false, false);
3175                         QCC_PR_Expect(")");
3176                         return QCC_MakeIntConst(t->size * 4);
3177                 }
3178                 if (!strcmp(func->name, "_"))
3179                 {
3180                         if (!func->initialized)
3181                                 func->initialized = 3;
3182                         func->references++;
3183                         if (pr_token_type == tt_immediate && pr_immediate_type->type == ev_string)
3184                         {
3185                                 d = QCC_MakeTranslateStringConst(pr_immediate_string);
3186                                 QCC_PR_Lex();
3187                         }
3188                         else
3189                                 QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHPARM, func, "_() intrinsic accepts only a string immediate", 1);
3190                         QCC_PR_Expect(")");
3191                         return d;
3192                 }
3193                 if (!strcmp(func->name, "random"))
3194                 {
3195                         old = NULL;
3196                         if (!func->initialized)
3197                                 func->initialized = 3;
3198                         func->references++;
3199                         if (!QCC_PR_CheckToken(")"))
3200                         {
3201                                 e = QCC_PR_Expression (TOP_PRIORITY, EXPR_DISALLOW_COMMA);
3202                                 if (e->type->type != ev_float)
3203                                         QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHPARM, func, "type mismatch on parm %i", 1);
3204                                 if (!QCC_PR_CheckToken(")"))
3205                                 {
3206                                         QCC_PR_Expect(",");
3207                                         d = QCC_PR_Expression (TOP_PRIORITY, EXPR_DISALLOW_COMMA);
3208                                         if (d->type->type != ev_float)
3209                                                 QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHPARM, func, "type mismatch on parm %i", 2);
3210                                         QCC_PR_Expect(")");
3211                                 }
3212                                 else
3213                                         d = NULL;
3214                         }
3215                         else
3216                         {
3217                                 e = NULL;
3218                                 d = NULL;
3219                         }
3220
3221                         out = &def_ret;
3222                         if (QCC_OPCodeValid(&pr_opcodes[OP_RAND0]))
3223                         {
3224                                 if(qcc_targetformat != QCF_HEXEN2)
3225                                         out = QCC_GetTemp(type_float);
3226                                 else if (out->temp->used)
3227                                 {
3228                                         old = QCC_GetTemp(out->type);
3229                                         if (def_ret.type->size == 3)
3230                                                 QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_V], out, old, NULL));
3231                                         else
3232                                                 QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], out, old, NULL));
3233                                         QCC_UnFreeTemp(old);
3234                                         QCC_UnFreeTemp(out);
3235                                         QCC_PR_ParseWarning(WARN_FIXEDRETURNVALUECONFLICT, "Return value conflict - output is inefficient");
3236                                 }
3237                                 else
3238                                         old = NULL;
3239
3240                                 if (e)
3241                                 {
3242                                         if (d)
3243                                                 QCC_PR_SimpleStatement(OP_RAND2, e->ofs, d->ofs, out->ofs, false);
3244                                         else
3245                                                 QCC_PR_SimpleStatement(OP_RAND1, e->ofs, 0, out->ofs, false);
3246                                 }
3247                                 else
3248                                         QCC_PR_SimpleStatement(OP_RAND0, 0, 0, out->ofs, false);
3249                         }
3250                         else
3251                         {
3252                                 if (out->temp->used)
3253                                 {
3254                                         old = QCC_GetTemp(out->type);
3255                                         if (def_ret.type->size == 3)
3256                                                 QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_V], out, old, NULL));
3257                                         else
3258                                                 QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], out, old, NULL));
3259                                         QCC_UnFreeTemp(old);
3260                                         QCC_UnFreeTemp(out);
3261                                         QCC_PR_ParseWarning(WARN_FIXEDRETURNVALUECONFLICT, "Return value conflict - output is inefficient");
3262                                 }
3263                                 else
3264                                         old = NULL;
3265
3266                                 if (e)
3267                                 {
3268                                         if (d)
3269                                         {
3270                                                 QCC_dstatement_t *st;
3271                                                 QCC_def_t *t;
3272                                                 QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
3273
3274                                                 if ((!d->constant || !e->constant) && G_FLOAT(d->ofs) >= G_FLOAT(d->ofs))
3275                                                 {
3276                                                         t = QCC_PR_Statement(&pr_opcodes[OP_GT_F], d, e, NULL);
3277                                                         QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_IFNOT_I], t, 0, &st));
3278                                                         st->b = 3;
3279
3280                                                         t = QCC_PR_Statement(&pr_opcodes[OP_SUB_F], d, e, NULL);
3281                                                         QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN, false);
3282                                                         QCC_FreeTemp(t);
3283                                                         QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, e->ofs, OFS_RETURN, false);
3284
3285                                                         QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_GOTO], 0, 0, &st));
3286                                                         st->a = 3;
3287                                                 }
3288
3289                                                 t = QCC_PR_Statement(&pr_opcodes[OP_SUB_F], e, d, NULL);
3290                                                 QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN, false);
3291                                                 QCC_FreeTemp(t);
3292                                                 QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, d->ofs, OFS_RETURN, false);
3293                                         }
3294                                         else
3295                                         {
3296                                                 QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
3297                                                 QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, e->ofs, OFS_RETURN, false);
3298                                         }
3299                                 }
3300                                 else
3301                                         QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
3302                         }
3303
3304                         if (e)
3305                         {
3306                                 QCC_FreeTemp(e);
3307                                 e->references++;
3308                         }
3309                         if (d)
3310                         {
3311                                 d->references++;
3312                                 QCC_FreeTemp(d);
3313                         }
3314
3315                         if (old)
3316                         {
3317                                 d = QCC_GetTemp(type_float);
3318                                 QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, &def_ret, d, NULL));
3319                                 if (def_ret.type->size == 3)
3320                                         QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_V, old, &def_ret, NULL));
3321                                 else
3322                                         QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, old, &def_ret, NULL));
3323                                 QCC_FreeTemp(old);
3324                                 QCC_UnFreeTemp(d);
3325                                 QCC_UnFreeTemp(&def_ret);
3326
3327                                 return d;
3328                         }
3329
3330                         if (out == &def_ret)
3331                         {
3332                                 if (out->temp->used)
3333                                         QCC_PR_ParseWarning(0, "Return value conflict - output is likly to be invalid");
3334                                 out->temp->used = true;
3335                                 out->type = type_float;
3336                         }
3337                         return out;
3338
3339                 }
3340                 if (!strcmp(func->name, "randomv"))
3341                 {
3342                         out = NULL;
3343                         if (!func->initialized)
3344                                 func->initialized = 3;
3345                         func->references++;
3346                         if (!QCC_PR_CheckToken(")"))
3347                         {
3348                                 e = QCC_PR_Expression (TOP_PRIORITY, EXPR_DISALLOW_COMMA);
3349                                 if (e->type->type != ev_vector)
3350                                                 QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHPARM, func, "type mismatch on parm %i", 1);
3351                                 if (!QCC_PR_CheckToken(")"))
3352                                 {
3353                                         QCC_PR_Expect(",");
3354                                         d = QCC_PR_Expression (TOP_PRIORITY, EXPR_DISALLOW_COMMA);
3355                                         if (d->type->type != ev_vector)
3356                                                 QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHPARM, func, "type mismatch on parm %i", 2);
3357                                         QCC_PR_Expect(")");
3358                                 }
3359                                 else
3360                                         d = NULL;
3361                         }
3362                         else
3363                         {
3364                                 e = NULL;
3365                                 d = NULL;
3366                         }
3367
3368                         if (QCC_OPCodeValid(&pr_opcodes[OP_RANDV0]))
3369                         {
3370                                 if(def_ret.temp->used)
3371                                         out = QCC_GetTemp(type_vector);
3372                                 else
3373                                         out = &def_ret;
3374
3375                                 if (e)
3376                                 {
3377                                         if (d)
3378                                                 QCC_PR_SimpleStatement(OP_RANDV2, e->ofs, d->ofs, out->ofs, false);
3379                                         else
3380                                                 QCC_PR_SimpleStatement(OP_RANDV1, e->ofs, 0, out->ofs, false);
3381                                 }
3382                                 else
3383                                         QCC_PR_SimpleStatement(OP_RANDV0, 0, 0, out->ofs, false);
3384                         }
3385                         else
3386                         {
3387                                 if (def_ret.temp->used)
3388                                 {
3389                                         old = QCC_GetTemp(def_ret.type);
3390                                         if (def_ret.type->size == 3)
3391                                                 QCC_PR_Statement(&pr_opcodes[OP_STORE_V], &def_ret, old, NULL);
3392                                         else
3393                                                 QCC_PR_Statement(&pr_opcodes[OP_STORE_F], &def_ret, old, NULL);
3394                                         QCC_UnFreeTemp(old);
3395                                         QCC_UnFreeTemp(&def_ret);
3396                                         QCC_PR_ParseWarning(WARN_FIXEDRETURNVALUECONFLICT, "Return value conflict - output is inefficient");
3397                                 }
3398                                 else
3399                                         old = NULL;
3400
3401                                 if (e)
3402                                 {
3403                                         if (d)
3404                                         {
3405                                                 QCC_def_t *t;
3406                                                 QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
3407
3408                                                 if ((!d->constant || !e->constant) && G_FLOAT(d->ofs) >= G_FLOAT(d->ofs))
3409                                                 {
3410                                                         t = QCC_GetTemp(type_float);
3411                                                         QCC_PR_SimpleStatement(OP_GT_F, d->ofs+2, e->ofs+2, t->ofs, false);
3412                                                         QCC_PR_SimpleStatement(OP_IFNOT_I, t->ofs, 3, 0, false);
3413
3414                                                         QCC_PR_SimpleStatement(OP_SUB_F, d->ofs+2, e->ofs+2, t->ofs, false);
3415                                                         QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN+2, false);
3416                                                         QCC_FreeTemp(t);
3417                                                         QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, e->ofs+2, OFS_RETURN+2, false);
3418
3419                                                         QCC_PR_SimpleStatement(OP_GOTO, 3, 0, 0, false);
3420                                                 }
3421
3422                                                 t = QCC_GetTemp(type_float);
3423                                                 QCC_PR_SimpleStatement(OP_SUB_F, d->ofs+2, e->ofs+2, t->ofs, false);
3424                                                 QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN+2, false);
3425                                                 QCC_FreeTemp(t);
3426                                                 QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, d->ofs+2, OFS_RETURN+2, false);
3427
3428
3429
3430                                                 QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
3431
3432                                                 if ((!d->constant || !e->constant) && G_FLOAT(d->ofs) >= G_FLOAT(d->ofs))
3433                                                 {
3434                                                         t = QCC_GetTemp(type_float);
3435                                                         QCC_PR_SimpleStatement(OP_GT_F, d->ofs+1, e->ofs+1, t->ofs, false);
3436                                                         QCC_PR_SimpleStatement(OP_IFNOT_I, t->ofs, 3, 0, false);
3437
3438                                                         QCC_PR_SimpleStatement(OP_SUB_F, d->ofs+1, e->ofs+1, t->ofs, false);
3439                                                         QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN+1, false);
3440                                                         QCC_FreeTemp(t);
3441                                                         QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, e->ofs+1, OFS_RETURN+1, false);
3442
3443                                                         QCC_PR_SimpleStatement(OP_GOTO, 3, 0, 0, false);
3444                                                 }
3445
3446                                                 t = QCC_GetTemp(type_float);
3447                                                 QCC_PR_SimpleStatement(OP_SUB_F, d->ofs+1, e->ofs+1, t->ofs, false);
3448                                                 QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN+1, false);
3449                                                 QCC_FreeTemp(t);
3450                                                 QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, d->ofs+1, OFS_RETURN+1, false);
3451
3452
3453                                                 QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
3454
3455                                                 if ((!d->constant || !e->constant) && G_FLOAT(d->ofs) >= G_FLOAT(d->ofs))
3456                                                 {
3457                                                         t = QCC_GetTemp(type_float);
3458                                                         QCC_PR_SimpleStatement(OP_GT_F, d->ofs, e->ofs, t->ofs, false);
3459                                                         QCC_PR_SimpleStatement(OP_IFNOT_I, t->ofs, 3, 0, false);
3460
3461                                                         QCC_PR_SimpleStatement(OP_SUB_F, d->ofs, e->ofs, t->ofs, false);
3462                                                         QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN, false);
3463                                                         QCC_FreeTemp(t);
3464                                                         QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, e->ofs, OFS_RETURN, false);
3465
3466                                                         QCC_PR_SimpleStatement(OP_GOTO, 3, 0, 0, false);
3467                                                 }
3468
3469                                                 t = QCC_GetTemp(type_float);
3470                                                 QCC_PR_SimpleStatement(OP_SUB_F, d->ofs, e->ofs, t->ofs, false);
3471                                                 QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, t->ofs, OFS_RETURN, false);
3472                                                 QCC_FreeTemp(t);
3473                                                 QCC_PR_SimpleStatement(OP_ADD_F, OFS_RETURN, d->ofs, OFS_RETURN, false);
3474                                         }
3475                                         else
3476                                         {
3477                                                 QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
3478                                                 QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, e->ofs, OFS_RETURN+2, false);
3479                                                 QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
3480                                                 QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, e->ofs, OFS_RETURN+1, false);
3481                                                 QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
3482                                                 QCC_PR_SimpleStatement(OP_MUL_F, OFS_RETURN, e->ofs, OFS_RETURN, false);
3483                                         }
3484                                 }
3485                                 else
3486                                 {
3487                                         QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
3488                                         QCC_PR_SimpleStatement(OP_STORE_F, OFS_RETURN, OFS_RETURN+2, 0, false);
3489                                         QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
3490                                         QCC_PR_SimpleStatement(OP_STORE_F, OFS_RETURN, OFS_RETURN+1, 0, false);
3491                                         QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
3492                                 }
3493                         }
3494
3495
3496                         if (e)
3497                         {
3498                                 QCC_FreeTemp(e);
3499                                 e->references++;
3500                         }
3501                         if (d)
3502                         {
3503                                 d->references++;
3504                                 QCC_FreeTemp(d);
3505                         }
3506
3507                         if (old)
3508                         {
3509                                 d = QCC_GetTemp(type_vector);
3510                                 QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_V, &def_ret, d, NULL));
3511                                 if (def_ret.type->size == 3)
3512                                 {
3513                                         QCC_PR_Statement(pr_opcodes+OP_STORE_V, old, &def_ret, NULL);
3514                                 }
3515                                 else
3516                                 {
3517                                         QCC_PR_Statement(pr_opcodes+OP_STORE_F, old, &def_ret, NULL);
3518                                 }
3519                                 QCC_FreeTemp(old);
3520                                 QCC_UnFreeTemp(d);
3521                                 QCC_UnFreeTemp(&def_ret);
3522
3523                                 return d;
3524                         }
3525
3526                         if (def_ret.temp->used)
3527                                 QCC_PR_ParseWarning(0, "Return value conflict - output is likly to be invalid");
3528                         def_ret.temp->used = true;
3529                         def_ret.type = type_vector;
3530                         return &def_ret;
3531                 }
3532                 else if (!strcmp(func->name, "spawn"))
3533                 {
3534                         QCC_type_t *rettype;
3535                         if (QCC_PR_CheckToken(")"))
3536                         {
3537                                 rettype = type_entity;
3538                         }
3539                         else
3540                         {
3541                                 rettype = QCC_TypeForName(QCC_PR_ParseName());
3542                                 if (!rettype || rettype->type != ev_entity)
3543                                         QCC_PR_ParseError(ERR_NOTANAME, "Spawn operator with undefined class");
3544
3545                                 QCC_PR_Expect(")");
3546                         }
3547
3548
3549                         if (def_ret.temp->used)
3550                         {
3551                                 old = QCC_GetTemp(def_ret.type);
3552                                 if (def_ret.type->size == 3)
3553                                         QCC_PR_Statement(&pr_opcodes[OP_STORE_V], &def_ret, old, NULL);
3554                                 else
3555                                         QCC_PR_Statement(&pr_opcodes[OP_STORE_F], &def_ret, old, NULL);
3556                                 QCC_UnFreeTemp(old);
3557                                 QCC_UnFreeTemp(&def_ret);
3558                                 QCC_PR_ParseWarning(WARN_FIXEDRETURNVALUECONFLICT, "Return value conflict - output is inefficient");
3559                         }
3560                         else
3561                                 old = NULL;
3562                         /*
3563                         if (def_ret.temp->used)
3564                                 QCC_PR_ParseWarning(0, "Return value conflict - output is likly to be invalid");
3565                         def_ret.temp->used = true;
3566                         */
3567
3568                         if (rettype != type_entity)
3569                         {
3570                                 char genfunc[2048];
3571                                 sprintf(genfunc, "Class*%s", rettype->name);
3572                                 func = QCC_PR_GetDef(type_function, genfunc, NULL, true, 0, false);
3573                                 func->references++;
3574                         }
3575                         QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
3576
3577                         if (old)
3578                         {
3579                                 d = QCC_GetTemp(rettype);
3580                                 QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_ENT, &def_ret, d, NULL));
3581                                 if (def_ret.type->size == 3)
3582                                         QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_V, old, &def_ret, NULL));
3583                                 else
3584                                         QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, old, &def_ret, NULL));
3585                                 QCC_FreeTemp(old);
3586                                 QCC_UnFreeTemp(d);
3587                                 QCC_UnFreeTemp(&def_ret);
3588
3589                                 return d;
3590                         }
3591
3592                         def_ret.type = rettype;
3593                         return &def_ret;
3594                 }
3595                 else if (!strcmp(func->name, "entnum") && !QCC_PR_CheckToken(")"))
3596                 {
3597                         //t = (a/%1) / (nextent(world)/%1)
3598                         //a/%1 does a (int)entity to float conversion type thing
3599                         if (!func->initialized)
3600                                 func->initialized = 3;
3601                         func->references++;
3602
3603                         e = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA);
3604                         QCC_PR_Expect(")");
3605                         e = QCC_PR_Statement(&pr_opcodes[OP_DIV_F], e, QCC_MakeIntConst(1), (QCC_dstatement_t **)0xffffffff);
3606
3607                         d = QCC_PR_GetDef(NULL, "nextent", NULL, false, 0, false);
3608                         if (!d)
3609                                 QCC_PR_ParseError(0, "the nextent builtin is not defined");
3610                         QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], e, &def_parms[0], (QCC_dstatement_t **)0xffffffff));
3611                         d = QCC_PR_Statement(&pr_opcodes[OP_CALL0], d, NULL, NULL);
3612                         d = QCC_PR_Statement(&pr_opcodes[OP_DIV_F], d, QCC_MakeIntConst(1), (QCC_dstatement_t **)0xffffffff);
3613
3614                         e = QCC_PR_Statement(&pr_opcodes[OP_DIV_F], e, d, (QCC_dstatement_t **)0xffffffff);
3615
3616                         return e;
3617                 }
3618         }       //so it's not an intrinsic.
3619
3620         if (opt_precache_file)  //should we strip out all precache_file calls?
3621         {
3622                 if (!strncmp(func->name,"precache_file", 13))
3623                 {
3624                         if (pr_token_type == tt_immediate && pr_immediate_type->type == ev_string && pr_scope && !strcmp(pr_scope->name, "main"))
3625                         {
3626                                 optres_precache_file += strlen(pr_immediate_string);
3627                                 QCC_PR_Lex();
3628                                 QCC_PR_Expect(")");
3629                                 QCC_PrecacheFileOptimised (pr_immediate_string, func->name[13]);
3630                                 def_ret.type = type_void;
3631                                 return &def_ret;
3632                         }
3633                 }
3634         }
3635
3636 // copy the arguments to the global parameter variables
3637         arg = 0;
3638         if (t->type == ev_variant)
3639         {
3640                 extraparms = true;
3641                 np = 0;
3642         }
3643         else if (t->num_parms < 0)
3644         {
3645                 extraparms = true;
3646                 np = (t->num_parms * -1) - 1;
3647         }
3648         else
3649                 np = t->num_parms;
3650
3651         //any temps referenced to build the parameters don't need to be locked.
3652         if (!QCC_PR_CheckToken(")"))
3653         {
3654                 p = t->param;
3655                 do
3656                 {
3657                         if (extraparms && arg >= MAX_PARMS)
3658                                 QCC_PR_ParseErrorPrintDef (ERR_TOOMANYPARAMETERSVARARGS, func, "More than %i parameters on varargs function", MAX_PARMS);
3659                         else if (arg >= MAX_PARMS+MAX_EXTRA_PARMS)
3660                                 QCC_PR_ParseErrorPrintDef (ERR_TOOMANYTOTALPARAMETERS, func, "More than %i parameters", MAX_PARMS+MAX_EXTRA_PARMS);
3661                         if (!extraparms && arg >= t->num_parms && !p)
3662                         {
3663                                 QCC_PR_ParseWarning (WARN_TOOMANYPARAMETERSFORFUNC, "too many parameters");
3664                                 QCC_PR_ParsePrintDef(WARN_TOOMANYPARAMETERSFORFUNC, func);
3665                         }
3666
3667
3668                         //with vectorcalls, we store the vector into the args as individual floats
3669                         //this allows better reuse of vector constants.
3670                         //copy it into the offset now, because we can.
3671                         if (opt_vectorcalls && pr_token_type == tt_immediate && pr_immediate_type == type_vector && arg < MAX_PARMS && !def_parms[arg].temp->used)
3672                         {
3673                                 e = &def_parms[arg];
3674
3675                                 e->ofs = OFS_PARM0+0;
3676                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatConst(pr_immediate.vector[0]), e, (QCC_dstatement_t **)0xffffffff));
3677                                 e->ofs = OFS_PARM0+1;
3678                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatConst(pr_immediate.vector[1]), e, (QCC_dstatement_t **)0xffffffff));
3679                                 e->ofs = OFS_PARM0+2;
3680                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatConst(pr_immediate.vector[2]), e, (QCC_dstatement_t **)0xffffffff));
3681                                 e->ofs = OFS_PARM0;
3682                                 e->type = type_vector;
3683
3684                                 QCC_PR_Lex();
3685                         }
3686                         else
3687                                 e = QCC_PR_Expression (TOP_PRIORITY, EXPR_DISALLOW_COMMA);
3688
3689                         if (arg == 0 && func->name)
3690                         {
3691                         // save information for model and sound caching
3692                                 if (!strncmp(func->name,"precache_", 9))
3693                                 {
3694                                         if (!strncmp(func->name+9,"sound", 5))
3695                                                 QCC_PrecacheSound (e, func->name[14]);
3696                                         else if (!strncmp(func->name+9,"model", 5))
3697                                                 QCC_PrecacheModel (e, func->name[14]);
3698                                         else if (!strncmp(func->name+9,"texture", 7))
3699                                                 QCC_PrecacheTexture (e, func->name[16]);
3700                                         else if (!strncmp(func->name+9,"file", 4))
3701                                                 QCC_PrecacheFile (e, func->name[13]);
3702                                 }
3703                         }
3704
3705                         if (arg>=MAX_PARMS)
3706                         {
3707                                 if (!extra_parms[arg - MAX_PARMS])
3708                                 {
3709                                         d = (QCC_def_t *) qccHunkAlloc (sizeof(QCC_def_t));
3710                                         d->name = "extra parm";
3711                                         d->ofs = QCC_GetFreeOffsetSpace (3);
3712                                         extra_parms[arg - MAX_PARMS] = d;
3713                                 }
3714                                 d = extra_parms[arg - MAX_PARMS];
3715                         }
3716                         else
3717                                 d = &def_parms[arg];
3718
3719                         if (pr_classtype && e->type->type == ev_field && p->type != ev_field)
3720                         {       //convert.
3721                                 oself = QCC_PR_GetDef(type_entity, "self", NULL, true, 0, false);
3722                                 switch(e->type->aux_type->type)
3723                                 {
3724                                 case ev_string:
3725                                         e = QCC_PR_Statement(pr_opcodes+OP_LOAD_S, oself, e, NULL);
3726                                         break;
3727                                 case ev_integer:
3728                                         e = QCC_PR_Statement(pr_opcodes+OP_LOAD_I, oself, e, NULL);
3729                                         break;
3730                                 case ev_float:
3731                                         e = QCC_PR_Statement(pr_opcodes+OP_LOAD_F, oself, e, NULL);
3732                                         break;
3733                                 case ev_function:
3734                                         e = QCC_PR_Statement(pr_opcodes+OP_LOAD_FNC, oself, e, NULL);
3735                                         break;
3736                                 case ev_vector:
3737                                         e = QCC_PR_Statement(pr_opcodes+OP_LOAD_V, oself, e, NULL);
3738                                         break;
3739                                 case ev_entity:
3740                                         e = QCC_PR_Statement(pr_opcodes+OP_LOAD_ENT, oself, e, NULL);
3741                                         break;
3742                                 default:
3743                                         QCC_Error(ERR_INTERNAL, "Bad member type. Try forced expansion");
3744                                 }
3745                         }
3746
3747                         if (p)
3748                         {
3749                                 if (typecmp(e->type, p))
3750                                 /*if (e->type->type != ev_integer && p->type != ev_function)
3751                                 if (e->type->type != ev_function && p->type != ev_integer)
3752                                 if ( e->type->type != p->type )*/
3753                                 {
3754                                         if (p->type == ev_integer && e->type->type == ev_float) //convert float -> int... is this a constant?
3755                                                 e = QCC_PR_Statement(pr_opcodes+OP_CONV_FTOI, e, NULL, NULL);
3756                                         else if (p->type == ev_float && e->type->type == ev_integer)    //convert float -> int... is this a constant?
3757                                                 e = QCC_PR_Statement(pr_opcodes+OP_CONV_ITOF, e, NULL, NULL);
3758                                         else if ((p->type == ev_function && p->type == ev_string) && e->type->type == ev_integer && e->constant && !((int*)qcc_pr_globals)[e->ofs])
3759                                         {       //you're allowed to use int 0 to pass a null function pointer
3760                                                 //this is basically because __NULL__ is defined as ~0 (int 0)
3761                                         }
3762                                         else if (p->type != ev_variant && e->type->type != ev_variant)  //can cast to variant whatever happens
3763                                         {
3764                                                 if (flag_laxcasts || (p->type == ev_function && e->type->type == ev_function))
3765                                                 {
3766                                                         QCC_PR_ParseWarning(WARN_LAXCAST, "type mismatch on parm %i - (%s should be %s)", arg+1, TypeName(e->type), TypeName(p));
3767                                                         QCC_PR_ParsePrintDef(WARN_LAXCAST, func);
3768                                                 }
3769                                                 else
3770                                                         QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHPARM, func, "type mismatch on parm %i - (%s should be %s)", arg+1, TypeName(e->type), TypeName(p));
3771                                         }
3772                                 }
3773
3774                                 d->type = p;
3775
3776                                 p=p->next;
3777                         }
3778                 // a vector copy will copy everything
3779                         else
3780                                 d->type = type_void;
3781
3782                         if (arg == 1 && !STRCMP(func->name, "setmodel"))
3783                         {
3784                                 QCC_SetModel(e);
3785                         }
3786
3787                         param[arg] = e;
3788 /*                      if (e->type->size>1)
3789                                 QCC_PR_Statement (&pr_opcodes[OP_STORE_V], e, d, (QCC_dstatement_t **)0xffffffff);
3790                         else
3791                                 QCC_PR_Statement (&pr_opcodes[OP_STORE_F], e, d, (QCC_dstatement_t **)0xffffffff);
3792                                 */
3793                         arg++;
3794                 } while (QCC_PR_CheckToken (","));
3795
3796                 if (t->num_parms != -1 && arg < np)
3797                         QCC_PR_ParseWarning (WARN_TOOFEWPARAMS, "too few parameters on call to %s", func->name);
3798                 QCC_PR_Expect (")");
3799         }
3800         else if (np)
3801         {
3802                 QCC_PR_ParseWarning (WARN_TOOFEWPARAMS, "%s: Too few parameters", func->name);
3803                 QCC_PR_ParsePrintDef (WARN_TOOFEWPARAMS, func);
3804         }
3805
3806         return QCC_PR_GenerateFunctionCall(func, param, arg);
3807 }
3808
3809 int constchecks;
3810 int varchecks;
3811 int typechecks;
3812 QCC_def_t *QCC_MakeIntConst(int value)
3813 {
3814         QCC_def_t       *cn;
3815
3816 // check for a constant with the same value
3817         for (cn=pr.def_head.next ; cn ; cn=cn->next)
3818         {
3819                 varchecks++;
3820                 if (!cn->initialized)
3821                         continue;
3822                 if (!cn->constant)
3823                         continue;
3824                 constchecks++;
3825                 if (cn->type != type_integer)
3826                         continue;
3827                 typechecks++;
3828
3829                 if ( G_INT(cn->ofs) == value )
3830                 {
3831                         return cn;
3832                 }
3833         }
3834
3835 // allocate a new one
3836         cn = (void *)qccHunkAlloc (sizeof(QCC_def_t));
3837         cn->next = NULL;
3838         pr.def_tail->next = cn;
3839         pr.def_tail = cn;
3840
3841         cn->type = type_integer;
3842         cn->name = "IMMEDIATE";
3843         cn->constant = true;
3844         cn->initialized = 1;
3845         cn->scope = NULL;               // always share immediates
3846         cn->arraysize = 0;
3847
3848         if (!value)
3849                 G_INT(cn->ofs) = 0;
3850         else
3851         {
3852         // copy the immediate to the global area
3853                 cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_integer->type]);
3854
3855                 G_INT(cn->ofs) = value;
3856         }
3857
3858
3859         return cn;
3860 }
3861
3862 QCC_def_t *QCC_MakeVectorConst(float a, float b, float c)
3863 {
3864         QCC_def_t       *cn;
3865
3866 // check for a constant with the same value
3867         for (cn=pr.def_head.next ; cn ; cn=cn->next)
3868         {
3869                 varchecks++;
3870                 if (!cn->initialized)
3871                         continue;
3872                 if (!cn->constant)
3873                         continue;
3874                 constchecks++;
3875                 if (cn->type != type_vector)
3876                         continue;
3877                 typechecks++;
3878
3879                 if ( G_FLOAT(cn->ofs+0) == a &&
3880                         G_FLOAT(cn->ofs+1) == b &&
3881                         G_FLOAT(cn->ofs+2) == c)
3882                 {
3883                         return cn;
3884                 }
3885         }
3886
3887 // allocate a new one
3888         cn = (void *)qccHunkAlloc (sizeof(QCC_def_t));
3889         cn->next = NULL;
3890         pr.def_tail->next = cn;
3891         pr.def_tail = cn;
3892
3893         cn->type = type_vector;
3894         cn->name = "IMMEDIATE";
3895         cn->constant = true;
3896         cn->initialized = 1;
3897         cn->scope = NULL;               // always share immediates
3898         cn->arraysize = 0;
3899
3900 // copy the immediate to the global area
3901         cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_vector->type]);
3902
3903         G_FLOAT(cn->ofs+0) = a;
3904         G_FLOAT(cn->ofs+1) = b;
3905         G_FLOAT(cn->ofs+2) = c;
3906
3907         return cn;
3908 }
3909
3910 extern hashtable_t floatconstdefstable;
3911 QCC_def_t *QCC_MakeFloatConst(float value)
3912 {
3913         QCC_def_t       *cn;
3914
3915         union {
3916                 float f;
3917                 int i;
3918         } fi;
3919
3920         fi.f = value;
3921
3922         cn = Hash_GetKey(&floatconstdefstable, fi.i);
3923         if (cn)
3924                 return cn;
3925
3926 // allocate a new one
3927         cn = (void *)qccHunkAlloc (sizeof(QCC_def_t));
3928         cn->next = NULL;
3929         pr.def_tail->next = cn;
3930         pr.def_tail = cn;
3931
3932         cn->s_file = s_file;
3933         cn->s_line = pr_source_line;
3934         cn->type = type_float;
3935         cn->name = "IMMEDIATE";
3936         cn->constant = true;
3937         cn->initialized = 1;
3938         cn->scope = NULL;               // always share immediates
3939         cn->arraysize = 0;
3940
3941 // copy the immediate to the global area
3942         cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_integer->type]);
3943
3944         Hash_AddKey(&floatconstdefstable, fi.i, cn, qccHunkAlloc(sizeof(bucket_t)));
3945
3946         G_FLOAT(cn->ofs) = value;
3947
3948
3949         return cn;
3950 }
3951
3952 extern hashtable_t stringconstdefstable, stringconstdefstable_trans;
3953 int dotranslate_count;
3954 static QCC_def_t *QCC_MakeStringConstInternal(char *value, pbool translate)
3955 {
3956         QCC_def_t       *cn;
3957         int string;
3958
3959         cn = pHash_Get(translate?&stringconstdefstable_trans:&stringconstdefstable, value);
3960         if (cn)
3961                 return cn;
3962
3963 // allocate a new one
3964         if(translate)
3965         {
3966                 char buf[64];
3967                 sprintf(buf, "dotranslate_%i", ++dotranslate_count);
3968                 cn = (void *)qccHunkAlloc (sizeof(QCC_def_t) + strlen(buf)+1);
3969                 cn->name = (char*)(cn+1);
3970                 strcpy(cn->name, buf);
3971         }
3972         else
3973         {
3974                 cn = (void *)qccHunkAlloc (sizeof(QCC_def_t));
3975                 cn->name = "IMMEDIATE";
3976         }
3977         cn->next = NULL;
3978         pr.def_tail->next = cn;
3979         pr.def_tail = cn;
3980
3981         cn->type = type_string;
3982         cn->constant = true;
3983         cn->initialized = 1;
3984         cn->scope = NULL;               // always share immediates
3985         cn->arraysize = 0;
3986
3987 // copy the immediate to the global area
3988         cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_integer->type]);
3989
3990         string = QCC_CopyString (value);
3991
3992         pHash_Add(translate?&stringconstdefstable_trans:&stringconstdefstable, strings+string, cn, qccHunkAlloc(sizeof(bucket_t)));
3993
3994         G_INT(cn->ofs) = string;
3995
3996         return cn;
3997 }
3998
3999 QCC_def_t *QCC_MakeStringConst(char *value)
4000 {
4001         return QCC_MakeStringConstInternal(value, false);
4002 }
4003 QCC_def_t *QCC_MakeTranslateStringConst(char *value)
4004 {
4005         return QCC_MakeStringConstInternal(value, true);
4006 }
4007
4008 QCC_type_t *QCC_PointerTypeTo(QCC_type_t *type)
4009 {
4010         QCC_type_t *newtype;
4011         newtype = QCC_PR_NewType("ptr", ev_pointer, false);
4012         newtype->aux_type = type;
4013         return newtype;
4014 }
4015
4016 int basictypefield[ev_union+1];
4017 char *basictypenames[] = {
4018         "void",
4019         "string",
4020         "float",
4021         "vector",
4022         "entity",
4023         "field",
4024         "function",
4025         "pointer",
4026         "integer",
4027         "struct",
4028         "union"
4029 };
4030
4031 QCC_def_t *QCC_MemberInParentClass(char *name, QCC_type_t *clas)
4032 {       //if a member exists, return the member field (rather than mapped-to field)
4033         QCC_type_t *mt;
4034         QCC_def_t *def;
4035         int p, np;
4036         char membername[2048];
4037
4038         if (!clas)
4039         {
4040                 def = QCC_PR_GetDef(NULL, name, NULL, 0, 0, false);
4041                 if (def && def->type->type == ev_field) //the member existed as a normal entity field.
4042                         return def;
4043                 return NULL;
4044         }
4045
4046         np = clas->num_parms;
4047         for (p = 0, mt = clas->param; p < np; p++, mt = mt->next)
4048         {
4049                 if (strcmp(mt->name, name))
4050                         continue;
4051
4052                 //the parent has it.
4053
4054                 sprintf(membername, "%s::"MEMBERFIELDNAME, clas->name, mt->name);
4055                 def = QCC_PR_GetDef(NULL, membername, NULL, false, 0, false);
4056                 return def;
4057         }
4058
4059         return QCC_MemberInParentClass(name, clas->parentclass);
4060 }
4061
4062 //create fields for the types, instanciate the members to the fields.
4063 //we retouch the parents each time to guarentee polymorphism works.
4064 //FIXME: virtual methods will not work properly. Need to trace down to see if a parent already defined it
4065 void QCC_PR_EmitFieldsForMembers(QCC_type_t *clas)
4066 {
4067 //we created fields for each class when we defined the actual classes.
4068 //we need to go through each member and match it to the offset of it's parent class, if overloaded, or create a new field if not..
4069
4070 //basictypefield is cleared before we do this
4071 //we emit the parent's fields first (every time), thus ensuring that we don't reuse parent fields on a child class.
4072
4073         char membername[2048];
4074         int p, np, a;
4075         unsigned int o;
4076         QCC_type_t *mt, *ft;
4077         QCC_def_t *f, *m;
4078         if (clas->parentclass != type_entity)   //parents MUST have all their fields set or inheritance would go crazy.
4079                 QCC_PR_EmitFieldsForMembers(clas->parentclass);
4080
4081         np = clas->num_parms;
4082         mt = clas->param;
4083         for (p = 0; p < np; p++, mt = mt->next)
4084         {
4085                 sprintf(membername, "%s::"MEMBERFIELDNAME, clas->name, mt->name);
4086                 m = QCC_PR_GetDef(NULL, membername, NULL, false, 0, false);
4087
4088                 f = QCC_MemberInParentClass(mt->name, clas->parentclass);
4089                 if (f)
4090                 {
4091                         if (m->arraysize)
4092                                 QCC_Error(ERR_INTERNAL, "FTEQCC does not support overloaded arrays of members");
4093                         a=0;
4094                         for (o = 0; o < m->type->size; o++)
4095                                 ((int *)qcc_pr_globals)[o+a*mt->size+m->ofs] = ((int *)qcc_pr_globals)[o+f->ofs];
4096                         continue;
4097                 }
4098
4099                 for (a = 0; a < (m->arraysize?m->arraysize:1); a++)
4100                 {
4101                         /*if it was already set, don't go recursive and generate 500 fields for a one-member class that was intheritted from 500 times*/
4102                         if (((int *)qcc_pr_globals)[o+a*mt->size+m->ofs])
4103                                 continue;
4104
4105                         //we need the type in here so saved games can still work without saving ints as floats. (would be evil)
4106                         ft = QCC_PR_NewType(basictypenames[mt->type], ev_field, false);
4107                         ft->aux_type = QCC_PR_NewType(basictypenames[mt->type], mt->type, false);
4108                         ft->aux_type->aux_type = type_void;
4109                         ft->size = ft->aux_type->size;
4110                         ft = QCC_PR_FindType(ft);
4111                         sprintf(membername, "__f_%s_%i", ft->name, ++basictypefield[mt->type]);
4112                         f = QCC_PR_GetDef(ft, membername, NULL, true, 0, true);
4113
4114                         for (o = 0; o < m->type->size; o++)
4115                                 ((int *)qcc_pr_globals)[o+a*mt->size+m->ofs] = ((int *)qcc_pr_globals)[o+f->ofs];
4116
4117                         f->references++;
4118                 }
4119         }
4120 }
4121
4122 void QCC_PR_EmitClassFunctionTable(QCC_type_t *clas, QCC_type_t *childclas, QCC_def_t *ed, QCC_def_t **constructor)
4123 {       //go through clas, do the virtual thing only if the child class does not override.
4124
4125         char membername[2048];
4126         QCC_type_t *type;
4127         QCC_type_t *oc;
4128         int p;
4129
4130         QCC_def_t *point, *member;
4131         QCC_def_t *virt;
4132
4133         if (clas->parentclass)
4134                 QCC_PR_EmitClassFunctionTable(clas->parentclass, childclas, ed, constructor);
4135
4136         type = clas->param;
4137         for (p = 0; p < clas->num_parms; p++, type = type->next)
4138         {
4139                 for (oc = childclas; oc != clas; oc = oc->parentclass)
4140                 {
4141                         sprintf(membername, "%s::"MEMBERFIELDNAME, oc->name, type->name);
4142                         if (QCC_PR_GetDef(NULL, membername, NULL, false, 0, false))
4143                                 break;  //a child class overrides.
4144                 }
4145                 if (oc != clas)
4146                         continue;
4147
4148                 if (type->type == ev_function)  //FIXME: inheritance will not install all the member functions.
4149                 {
4150                         sprintf(membername, "%s::"MEMBERFIELDNAME, clas->name, type->name);
4151                         member = QCC_PR_GetDef(NULL, membername, NULL, false, 0, false);
4152                         if (!member)
4153                         {
4154                                 QCC_PR_Warning(0, NULL, 0, "Member function %s was not defined", membername);
4155                                 continue;
4156                         }
4157                         if (!strcmp(type->name, clas->name))
4158                         {
4159                                 *constructor = member;
4160                         }
4161                         point = QCC_PR_Statement(&pr_opcodes[OP_ADDRESS], ed, member, NULL);
4162                         sprintf(membername, "%s::%s", clas->name, type->name);
4163                         virt = QCC_PR_GetDef(type, membername, NULL, false, 0, false);
4164                         QCC_PR_Statement(&pr_opcodes[OP_STOREP_FNC], virt, point, NULL);
4165                 }
4166         }
4167 }
4168
4169 //take all functions in the type, and parent types, and make sure the links all work properly.
4170 void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, char *tname)
4171 {
4172         QCC_type_t *basetype;
4173
4174         QCC_dfunction_t *df;
4175
4176         QCC_def_t *virt;
4177         QCC_def_t *ed, *oself, *self;
4178         QCC_def_t *constructor = NULL;
4179
4180 //      int func;
4181
4182         basetype = QCC_TypeForName(tname);
4183         if (!basetype)
4184                 QCC_PR_ParseError(ERR_INTERNAL, "Type %s was not defined...", tname);
4185
4186         if (numfunctions >= MAX_FUNCTIONS)
4187                 QCC_Error(ERR_INTERNAL, "Too many function defs");
4188
4189         pr_scope = NULL;
4190         memset(basictypefield, 0, sizeof(basictypefield));
4191         QCC_PR_EmitFieldsForMembers(basetype);
4192
4193
4194
4195
4196         pr_scope = scope;
4197
4198         df = &functions[numfunctions];
4199         numfunctions++;
4200
4201         df->s_file = 0;
4202         df->s_name = 0;
4203         df->first_statement = numstatements;
4204         df->parm_size[0] = 1;
4205         df->numparms = 0;
4206         df->parm_start = numpr_globals;
4207
4208         G_FUNCTION(scope->ofs) = df - functions;
4209
4210         //locals here...
4211         ed = QCC_PR_GetDef(type_entity, "ent", pr_scope, true, 0, false);
4212
4213         virt = QCC_PR_GetDef(type_function, "spawn", NULL, false, 0, false);
4214         if (!virt)
4215                 QCC_Error(ERR_INTERNAL, "spawn function was not defined\n");
4216         QCC_PR_SimpleStatement(OP_CALL0, virt->ofs, 0, 0, false);       //calling convention doesn't come into it.
4217
4218         QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], &def_ret, ed, NULL));
4219
4220         ed->references = 1;     //there may be no functions.
4221
4222
4223         QCC_PR_EmitClassFunctionTable(basetype, basetype, ed, &constructor);
4224
4225         if (constructor)
4226         {       //self = ent;
4227                 self = QCC_PR_GetDef(type_entity, "self", NULL, false, 0, false);
4228                 oself = QCC_PR_GetDef(type_entity, "oself", scope, true, 0, false);
4229                 QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], self, oself, NULL));
4230                 QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], ed, self, NULL));      //return to our old self. boom boom.
4231                 QCC_PR_SimpleStatement(OP_CALL0, constructor->ofs, 0, 0, false);
4232                 QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], oself, self, NULL));
4233         }
4234
4235         QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_RETURN], ed, NULL, NULL)); //apparently we do actually have to return something. *sigh*...
4236         QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_DONE], NULL, NULL, NULL));
4237
4238
4239
4240         QCC_WriteAsmFunction(scope, df->first_statement, df->parm_start);
4241         pr.localvars = NULL;
4242
4243
4244         locals_end = numpr_globals + basetype->size;
4245         df->locals = locals_end - df->parm_start;
4246 }
4247
4248 QCC_def_t *QCC_PR_ParseArrayPointer (QCC_def_t *d, pbool allowarrayassign)
4249 {
4250         QCC_type_t *t;
4251         QCC_def_t *idx;
4252         QCC_def_t *tmp;
4253         QCC_dstatement_t *st;
4254         pbool allowarray;
4255
4256         t = d->type;
4257         idx = NULL;
4258         while(1)
4259         {
4260                 allowarray = false;
4261                 if (idx)
4262                         allowarray = t->arraysize>0;
4263                 else if (!idx)
4264                 {
4265                         allowarray = d->arraysize ||
4266                                                 (d->type->type == ev_pointer) ||
4267                                                 (d->type->type == ev_string) ||
4268                                                 (d->type->type == ev_vector);
4269                 }
4270
4271                 if (allowarray && QCC_PR_CheckToken("["))
4272                 {
4273                         tmp = QCC_PR_Expression (TOP_PRIORITY, 0);
4274                         QCC_PR_Expect("]");
4275
4276                         /*if its a pointer that got dereferenced, follow the type*/
4277                         if (!idx && t->type == ev_pointer && !d->arraysize)
4278                                 t = t->aux_type;
4279
4280                         if (!idx && d->type->type == ev_pointer)
4281                         {
4282                                 /*no bounds checks on pointer dereferences*/
4283                         }
4284                         else if (!idx && d->type->type == ev_string && !d->arraysize)
4285                         {
4286                                 /*automatic runtime bounds checks on strings, I'm not going to check this too much...*/
4287                         }
4288                         else if (!idx && d->type->type == ev_vector && !d->arraysize)
4289                         {
4290                                 if (tmp->constant)
4291                                 {
4292                                         unsigned int i;
4293                                         if (tmp->type->type == ev_integer)
4294                                                 i = G_INT(tmp->ofs);
4295                                         else if (tmp->type->type == ev_float)
4296                                                 i = G_FLOAT(tmp->ofs);
4297                                         if (i < 0 || i >= 3)
4298                                                 QCC_PR_ParseErrorPrintDef(0, d, "(vector) array index out of bounds");
4299                                 }
4300                                 else if (QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F]))
4301                                 {
4302                                         tmp = QCC_SupplyConversion(tmp, ev_integer, true);
4303                                         QCC_PR_SimpleStatement (OP_BOUNDCHECK, tmp->ofs, 3, 0, false);
4304                                 }
4305                                 t = type_float;
4306                         }
4307                         else if (!((!idx)?d->arraysize:t->arraysize))
4308                         {
4309                                 QCC_PR_ParseErrorPrintDef(0, d, "array index on non-array");
4310                         }
4311                         else if (tmp->constant)
4312                         {
4313                                 unsigned int i;
4314                                 if (tmp->type->type == ev_integer)
4315                                         i = G_INT(tmp->ofs);
4316                                 else if (tmp->type->type == ev_float)
4317                                         i = G_FLOAT(tmp->ofs);
4318                                 if (i < 0 || i >= ((!idx)?d->arraysize:t->arraysize))
4319                                         QCC_PR_ParseErrorPrintDef(0, d, "(constant) array index out of bounds");
4320                         }
4321                         else
4322                         {
4323                                 if (QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F]))
4324                                 {
4325                                         tmp = QCC_SupplyConversion(tmp, ev_integer, true);
4326                                         QCC_PR_SimpleStatement (OP_BOUNDCHECK, tmp->ofs, ((!idx)?d->arraysize:t->arraysize), 0, false);
4327                                 }
4328                         }
4329                         if (t->size != 1 && (idx || QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F]))) /*don't multiply by type size if the instruction/emulation will do that instead*/
4330                         {
4331                                 if (tmp->type->type == ev_float)
4332                                         tmp = QCC_PR_Statement(&pr_opcodes[OP_MUL_F], tmp, QCC_MakeFloatConst(t->size), NULL);
4333                                 else
4334                                         tmp = QCC_PR_Statement(&pr_opcodes[OP_MUL_I], tmp, QCC_MakeIntConst(t->size), NULL);
4335                         }
4336
4337                         /*calc the new index*/
4338                         if (idx)
4339                                 idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], idx, QCC_SupplyConversion(tmp, ev_integer, true), NULL);
4340                         else
4341                                 idx = tmp;
4342                 }
4343                 else if ((t->type == ev_pointer || t->type == ev_struct || t->type == ev_union) && (QCC_PR_CheckToken(".") || QCC_PR_CheckToken("->")))
4344                 {
4345                         if (!idx && t->type == ev_pointer && !d->arraysize)
4346                                 t = t->aux_type;
4347
4348                         for (t = t->param; t; t = t->next)
4349                         {
4350                                 if (QCC_PR_CheckName(t->name))
4351                                 {
4352                                         break;
4353                                 }
4354                         
4355                         }
4356                         if (!t)
4357                                 QCC_PR_ParseError(0, "%s is not a member", pr_token);
4358
4359                         tmp = QCC_MakeIntConst(t->ofs);
4360                         if (idx)
4361                                 idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], idx, tmp, NULL);
4362                         else
4363                                 idx = tmp;
4364                 }
4365                 else
4366                         break;
4367         }
4368
4369         if (idx)
4370         {
4371                 if (d->type->type == ev_pointer)
4372                 {
4373                         switch (t->type)
4374                         {
4375                         case ev_pointer:
4376                                 d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_I], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
4377                                 break;
4378                         case ev_float:
4379                                 d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_F], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
4380                                 break;
4381                         case ev_integer:
4382                                 d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_I], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
4383                                 break;
4384                         case ev_string:
4385                                 d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_S], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
4386                                 break;
4387                         case ev_vector:
4388                                 d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_V], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
4389                                 break;
4390                         case ev_entity:
4391                                 d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_ENT], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
4392                                 break;
4393                         case ev_field:
4394                                 d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_FLD], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
4395                                 break;
4396                         case ev_function:
4397                                 d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_FNC], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
4398                                 break;
4399                         case ev_struct:
4400                         case ev_union:
4401                                 d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_I], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
4402                                 break;
4403
4404                         default:
4405                                 QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler");
4406                         }
4407                         d->type = t;
4408                 }
4409                 else if (d->type->type == ev_string && d->arraysize == 0)
4410                 {
4411                         d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_C], d, QCC_SupplyConversion(idx, ev_float, true), NULL);
4412                 }
4413                 else if (d->type->type == ev_vector && d->arraysize == 0)
4414                 {
4415                         d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_F], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
4416                         d->type = type_float;
4417                 }
4418                 else if (QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F]))
4419                 {
4420                         /*don't care about assignments. the code can convert an OP_LOADA_F to an OP_ADDRESS on assign*/
4421                         /*source type is a struct, or its an array, or something that can otherwise be directly accessed*/
4422                         switch(t->type)
4423                         {
4424                         case ev_pointer:
4425                                 d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_I], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
4426                                 break;
4427                         case ev_float:
4428                                 d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_F], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
4429                                 break;
4430                         case ev_integer:
4431                                 d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_I], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
4432                                 break;
4433                         case ev_string:
4434                                 d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_S], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
4435                                 break;
4436                         case ev_vector:
4437                                 d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_V], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
4438                                 break;
4439                         case ev_entity:
4440                                 d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_ENT], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
4441                                 break;
4442                         case ev_field:
4443                                 d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FLD], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
4444                                 break;
4445                         case ev_function:
4446                                 d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FNC], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
4447                                 break;
4448                         case ev_struct:
4449                         case ev_union:
4450                                 //FIXME...
4451                                 d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_STRUCT], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
4452                                 break;
4453                         default:
4454                                 QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler");
4455                         }
4456                         d->type = t;
4457                 }
4458                 else if (idx->constant)
4459                 {
4460                         int cidx;
4461                         idx = QCC_SupplyConversion(idx, ev_integer, true);
4462                         cidx = G_INT(idx->ofs);
4463
4464                         d->references++;
4465                         tmp = (void *)qccHunkAlloc (sizeof(QCC_def_t));
4466                         memcpy (tmp, d, sizeof(QCC_def_t));
4467                         tmp->arraysize = 0;
4468                         tmp->ofs = d->ofs + (cidx * type_size[d->type->type]);
4469                         d = tmp;
4470
4471                         //d can be assigned to freely
4472                 }
4473                 else if (allowarrayassign && QCC_PR_CheckToken("="))
4474                 {
4475                         /*if its assigned to, generate a functioncall to do the store*/
4476                         QCC_def_t *args[2], *funcretr, *rhs;
4477
4478                         d->references++;
4479                         funcretr = QCC_PR_GetDef(type_function, qcva("ArraySet*%s", d->name), NULL, true, 0, false);
4480
4481                         rhs = QCC_PR_Expression(TOP_PRIORITY, 0);
4482                         if (rhs->type->type != d->type->type)
4483                                 QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, d, "Type Mismatch on array assignment");
4484
4485                         args[0] = QCC_SupplyConversion(idx, ev_float, true);
4486                         args[1] = rhs;
4487                         qcc_usefulstatement=true;
4488                         d = QCC_PR_GenerateFunctionCall(funcretr, args, 2);
4489                         d->type = t;
4490
4491                         return d;
4492                 }
4493                 else if (QCC_OPCodeValid(&pr_opcodes[OP_FETCH_GBL_F]))
4494                 {
4495                         if (!d->arraysize)
4496                                 QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, d, "array lookup on non-array");
4497
4498                         if (d->temp)
4499                                 QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, d, "array lookup on a temp");
4500
4501                         /*hexen2 format has opcodes to read arrays (but has no way to write)*/
4502                         switch(t->type)
4503                         {
4504                         case ev_float:
4505                                 d = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_F], d, QCC_SupplyConversion(idx, ev_float, true), &st);   //get pointer to precise def.
4506 //                              st->a = d->ofs;
4507                                 break;
4508                         case ev_vector:
4509                                 d = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_V], d, QCC_SupplyConversion(idx, ev_float, true), &st);   //get pointer to precise def.
4510 //                              st->a = d->ofs;
4511                                 break;
4512                         case ev_string:
4513                                 d = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_S], d, QCC_SupplyConversion(idx, ev_float, true), &st);   //get pointer to precise def.
4514 //                              st->a = d->ofs;
4515                                 break;
4516                         case ev_entity:
4517                                 d = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_E], d, QCC_SupplyConversion(idx, ev_float, true), &st);   //get pointer to precise def.
4518 //                              st->a = d->ofs;
4519                                 break;
4520                         case ev_function:
4521                                 d = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_FNC], d, QCC_SupplyConversion(idx, ev_float, true), &st); //get pointer to precise def.
4522 //                              st->a = d->ofs;
4523                                 break;
4524                         default:
4525                                 QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler");
4526                                 d = NULL;
4527                                 break;
4528                         }
4529                         d->type = t;
4530                 }
4531                 else
4532                 {
4533                         /*emulate the array access using a function call to do the read for us*/
4534                         QCC_def_t *args[1], *funcretr;
4535
4536                         d->references++;
4537
4538                         /*make sure the function type that we're calling exists*/
4539                         def_parms[0].type = type_float;
4540                         funcretr = QCC_PR_GetDef(type_function, qcva("ArrayGet*%s", d->name), NULL, true, 0, false);
4541
4542                         args[0] = QCC_SupplyConversion(idx, ev_float, true);
4543                         d = QCC_PR_GenerateFunctionCall(funcretr, args, 1);
4544                         d->type = t;
4545                 }
4546
4547                 /*parse recursively*/
4548                 d = QCC_PR_ParseArrayPointer(d, allowarrayassign);
4549         }
4550
4551         return d;
4552 }
4553
4554 /*
4555 ============
4556 PR_ParseValue
4557
4558 Returns the global ofs for the current token
4559 ============
4560 */
4561 QCC_def_t       *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
4562 {
4563         QCC_def_t               *d, *od, *tmp;
4564         QCC_type_t              *t;
4565         char            *name;
4566
4567         char membername[2048];
4568
4569 // if the token is an immediate, allocate a constant for it
4570         if (pr_token_type == tt_immediate)
4571                 return QCC_PR_ParseImmediate ();
4572
4573         if (QCC_PR_CheckToken("["))     //reacc support
4574         {       //looks like a funky vector. :)
4575                 vec3_t v;
4576                 pr_immediate_type = type_vector;
4577                 v[0] = pr_immediate._float;
4578                 QCC_PR_Lex();
4579                 v[1] = pr_immediate._float;
4580                 QCC_PR_Lex();
4581                 v[2] = pr_immediate._float;
4582                 pr_immediate.vector[0] = v[0];
4583                 pr_immediate.vector[1] = v[1];
4584                 pr_immediate.vector[2] = v[2];
4585                 pr_immediate_type = type_vector;
4586                 d = QCC_PR_ParseImmediate();
4587                 QCC_PR_Expect("]");
4588                 return d;
4589         }
4590         name = QCC_PR_ParseName ();
4591
4592         if (assumeclass && assumeclass->parentclass)    // 'testvar' becomes 'self::testvar'
4593         {       //try getting a member.
4594                 QCC_type_t *type;
4595                 type = assumeclass;
4596                 d = NULL;
4597                 while(type != type_entity && type)
4598                 {
4599                         sprintf(membername, "%s::"MEMBERFIELDNAME, type->name, name);
4600                         d = QCC_PR_GetDef (NULL, membername, pr_scope, false, 0, false);
4601                         if (d)
4602                                 break;
4603
4604                         type = type->parentclass;
4605                 }
4606                 if (!d)
4607                         d = QCC_PR_GetDef (NULL, name, pr_scope, false, 0, false);
4608         }
4609         else
4610         {
4611                 // look through the defs
4612                 d = QCC_PR_GetDef (NULL, name, pr_scope, false, 0, false);
4613         }
4614
4615         if (!d)
4616         {
4617                 if (    (!strcmp(name, "random" ))      ||
4618                                 (!strcmp(name, "randomv"))      ||
4619                                 (!strcmp(name, "sizeof"))       ||
4620                                 (!strcmp(name, "entnum"))       ||
4621                                 (!strcmp(name, "_")))   //intrinsics, any old function with no args will do.
4622                 {
4623                         d = QCC_PR_GetDef (type_function, name, NULL, true, 0, false);
4624                         d->initialized = 0;
4625                 }
4626                 else if (keyword_class && !strcmp(name, "this"))
4627                 {
4628                         if (!pr_classtype)
4629                                 QCC_PR_ParseError(ERR_NOTANAME, "Cannot use 'this' outside of an OO function\n");
4630                         od = QCC_PR_GetDef(NULL, "self", NULL, true, 0, false);
4631                         d = QCC_PR_DummyDef(pr_classtype, "this", pr_scope, 0, od->ofs, true, false);
4632                 }
4633                 else if (keyword_class && !strcmp(name, "super"))
4634                 {
4635                         if (!pr_classtype)
4636                                 QCC_PR_ParseError(ERR_NOTANAME, "Cannot use 'super' outside of an OO function\n");
4637                         od = QCC_PR_GetDef(NULL, "self", NULL, true, 0, false);
4638                         d = QCC_PR_DummyDef(pr_classtype, "super", pr_scope, 0, od->ofs, true, false);
4639                 }
4640                 else
4641                 {
4642                         d = QCC_PR_GetDef (type_variant, name, pr_scope, true, 0, false);
4643                         if (!d)
4644                                 QCC_PR_ParseError (ERR_UNKNOWNVALUE, "Unknown value \"%s\"", name);
4645                         else
4646                         {
4647                                 QCC_PR_ParseWarning (ERR_UNKNOWNVALUE, "Unknown value \"%s\".", name);
4648                         }
4649                 }
4650         }
4651
4652         d = QCC_PR_ParseArrayPointer(d, allowarrayassign);
4653
4654         t = d->type;
4655         if (keyword_class && t->type == ev_entity && t->parentclass && (QCC_PR_CheckToken(".") || QCC_PR_CheckToken("->")))
4656         {
4657                 QCC_def_t *field;
4658                 if (QCC_PR_CheckToken("("))
4659                 {
4660                         field = QCC_PR_Expression(TOP_PRIORITY, 0);
4661                         QCC_PR_Expect(")");
4662                 }
4663                 else
4664                         field = QCC_PR_ParseValue(d->type, false);
4665                 if (field->type->type == ev_field)
4666                 {
4667                         if (!field->type->aux_type)
4668                         {
4669                                 QCC_PR_ParseWarning(ERR_INTERNAL, "Field with null aux_type");
4670                                 d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_FLD], d, field, NULL);
4671                         }
4672                         else
4673                         {
4674                                 switch(field->type->aux_type->type)
4675                                 {
4676                                 default:
4677                                         QCC_PR_ParseError(ERR_INTERNAL, "Bad field type");
4678                                         break;
4679                                 case ev_integer:
4680                                         d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_I], d, field, NULL);
4681                                         break;
4682                                 case ev_field:
4683                                         d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_FLD], d, field, NULL);
4684                                         tmp = (void *)qccHunkAlloc (sizeof(QCC_def_t));
4685                                         memset (tmp, 0, sizeof(QCC_def_t));
4686                                         tmp->type = field->type->aux_type;
4687                                         tmp->ofs = d->ofs;
4688                                         tmp->temp = d->temp;
4689                                         tmp->constant = false;
4690                                         tmp->name = d->name;
4691                                         d = tmp;
4692                                         break;
4693                                 case ev_float:
4694                                         d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_F], d, field, NULL);
4695                                         break;
4696                                 case ev_string:
4697                                         d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_S], d, field, NULL);
4698                                         break;
4699                                 case ev_vector:
4700                                         d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_V], d, field, NULL);
4701                                         break;
4702                                 case ev_function:
4703                                         d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_FNC], d, field, NULL);
4704                                         tmp = (void *)qccHunkAlloc (sizeof(QCC_def_t));
4705                                         memset (tmp, 0, sizeof(QCC_def_t));
4706                                         tmp->type = field->type->aux_type;
4707                                         tmp->ofs = d->ofs;
4708                                         tmp->temp = d->temp;
4709                                         tmp->constant = false;
4710                                         tmp->name = d->name;
4711                                         d = tmp;
4712                                         break;
4713                                 case ev_entity:
4714                                         d = QCC_PR_Statement(&pr_opcodes[OP_LOAD_ENT], d, field, NULL);
4715                                         break;
4716                                 }
4717                         }
4718                 }
4719                 else
4720                         QCC_PR_IncludeChunk(".", false, NULL);
4721         }
4722
4723         return d;
4724 }
4725
4726
4727 /*
4728 ============
4729 PR_Term
4730 ============
4731 */
4732 QCC_def_t *QCC_PR_Term (void)
4733 {
4734         QCC_def_t       *e, *e2;
4735         etype_t t;
4736         if (pr_token_type == tt_punct)  //a little extra speed...
4737         {
4738                 if (QCC_PR_CheckToken("++"))
4739                 {
4740                         qcc_usefulstatement=true;
4741                         e = QCC_PR_Term ();
4742                         if (e->constant)
4743                                 QCC_PR_ParseWarning(WARN_ASSIGNMENTTOCONSTANT, "Assignment to constant %s", e->name);
4744                         if (e->temp)
4745                                 QCC_PR_ParseWarning(WARN_ASSIGNMENTTOCONSTANT, "Hey! That's a temp! ++ operators cannot work on temps!");
4746                         switch (e->type->type)
4747                         {
4748                         case ev_integer:
4749                                 QCC_PR_Statement3(&pr_opcodes[OP_ADD_I], e, QCC_MakeIntConst(1), e, false);
4750                                 break;
4751                         case ev_float:
4752                                 QCC_PR_Statement3(&pr_opcodes[OP_ADD_F], e, QCC_MakeFloatConst(1), e, false);
4753                                 break;
4754                         default:
4755                                 QCC_PR_ParseError(ERR_BADPLUSPLUSOPERATOR, "++ operator on unsupported type");
4756                                 break;
4757                         }
4758                         return e;
4759                 }
4760                 else if (QCC_PR_CheckToken("--"))
4761                 {
4762                         qcc_usefulstatement=true;
4763                         e = QCC_PR_Term ();
4764                         if (e->constant)
4765                                 QCC_PR_ParseWarning(WARN_ASSIGNMENTTOCONSTANT, "Assignment to constant %s", e->name);
4766                         if (e->temp)
4767                                 QCC_PR_ParseWarning(WARN_ASSIGNMENTTOCONSTANT, "Hey! That's a temp! -- operators cannot work on temps!");
4768                         switch (e->type->type)
4769                         {
4770                         case ev_integer:
4771                                 QCC_PR_Statement3(&pr_opcodes[OP_SUB_I], e, QCC_MakeIntConst(1), e, false);
4772                                 break;
4773                         case ev_float:
4774                                 QCC_PR_Statement3(&pr_opcodes[OP_SUB_F], e, QCC_MakeFloatConst(1), e, false);
4775                                 break;
4776                         default:
4777                                 QCC_PR_ParseError(ERR_BADPLUSPLUSOPERATOR, "-- operator on unsupported type");
4778                                 break;
4779                         }
4780                         return e;
4781                 }
4782
4783                 if (QCC_PR_CheckToken ("!"))
4784                 {
4785                         e = QCC_PR_Expression (NOT_PRIORITY, EXPR_DISALLOW_COMMA|EXPR_WARN_ABOVE_1);
4786                         t = e->type->type;
4787                         if (t == ev_float)
4788                                 e2 = QCC_PR_Statement (&pr_opcodes[OP_NOT_F], e, 0, NULL);
4789                         else if (t == ev_string)
4790                                 e2 = QCC_PR_Statement (&pr_opcodes[OP_NOT_S], e, 0, NULL);
4791                         else if (t == ev_entity)
4792                                 e2 = QCC_PR_Statement (&pr_opcodes[OP_NOT_ENT], e, 0, NULL);
4793                         else if (t == ev_vector)
4794                                 e2 = QCC_PR_Statement (&pr_opcodes[OP_NOT_V], e, 0, NULL);
4795                         else if (t == ev_function)
4796                                 e2 = QCC_PR_Statement (&pr_opcodes[OP_NOT_FNC], e, 0, NULL);
4797                         else if (t == ev_integer)
4798                                 e2 = QCC_PR_Statement (&pr_opcodes[OP_NOT_FNC], e, 0, NULL);    //functions are integer values too.
4799                         else if (t == ev_pointer)
4800                                 e2 = QCC_PR_Statement (&pr_opcodes[OP_NOT_FNC], e, 0, NULL);    //Pointers are too.
4801                         else
4802                         {
4803                                 e2 = NULL;              // shut up compiler warning;
4804                                 QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch for !");
4805                         }
4806                         return e2;
4807                 }
4808
4809                 else if (QCC_PR_CheckToken ("&"))
4810                 {
4811                         int st = numstatements;
4812                         e = QCC_PR_Expression (UNARY_PRIORITY, EXPR_DISALLOW_COMMA);
4813                         t = e->type->type;
4814
4815                         if (st != numstatements)
4816                                 //woo, something like ent.field?
4817                         {
4818                                 if ((OP_LOAD_F <= statements[numstatements-1].op && statements[numstatements-1].op <= OP_LOAD_FNC) || statements[numstatements-1].op == OP_LOAD_I || statements[numstatements-1].op == OP_LOAD_P)
4819                                 {
4820                                         statements[numstatements-1].op = OP_ADDRESS;
4821                                         e->type = QCC_PR_PointerType(e->type);
4822                                         return e;
4823                                 }
4824                                 else if (OP_LOADA_F <= statements[numstatements-1].op && statements[numstatements-1].op <= OP_LOADA_I)
4825                                 {
4826                                         statements[numstatements-1].op = OP_GLOBALADDRESS;
4827                                         e->type = QCC_PR_PointerType(e->type);
4828                                         return e;
4829                                 }
4830                                 else if (OP_LOADP_F <= statements[numstatements-1].op && statements[numstatements-1].op <= OP_LOADP_I)
4831                                 {
4832                                         statements[numstatements-1].op = OP_POINTER_ADD;
4833                                         e->type = QCC_PR_PointerType(e->type);
4834                                         return e;
4835                                 }
4836                                 else    //this is a restriction that could be lifted, I just want to make sure that I got all the bits first.
4837                                 {
4838                                         QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch for '&' Must be singular expression or field reference");
4839                                         return e;
4840                                 }
4841                         }
4842 //                      QCC_PR_ParseWarning(0, "debug: &global");
4843
4844                         if (!QCC_OPCodeValid(&pr_opcodes[OP_GLOBALADDRESS]))
4845                                 QCC_PR_ParseError (ERR_BADEXTENSION, "Cannot use addressof operator ('&') on a global. Please use the FTE target.");
4846
4847                         e2 = QCC_PR_Statement (&pr_opcodes[OP_GLOBALADDRESS], e, 0, NULL);
4848                         e2->type = QCC_PR_PointerType(e->type);
4849                         return e2;
4850                 }
4851                 else if (QCC_PR_CheckToken ("*"))
4852                 {
4853                         e = QCC_PR_Expression (UNARY_PRIORITY, EXPR_DISALLOW_COMMA);
4854                         t = e->type->type;
4855
4856                         if (t == ev_string)
4857                                 e2 = QCC_PR_Statement(&pr_opcodes[OP_LOADP_C], e, QCC_MakeFloatConst(0), NULL);
4858                         else if (t == ev_pointer)
4859                         {
4860                                 switch(e->type->aux_type->type)
4861                                 {
4862                                 case ev_float:
4863                                         e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_F], e, 0, NULL);
4864                                         break;
4865                                 case ev_string:
4866                                         e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_S], e, 0, NULL);
4867                                         break;
4868                                 case ev_vector:
4869                                         e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_V], e, 0, NULL);
4870                                         break;
4871                                 case ev_entity:
4872                                         e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_ENT], e, 0, NULL);
4873                                         break;
4874                                 case ev_field:
4875                                         e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_FLD], e, 0, NULL);
4876                                         break;
4877                                 case ev_function:
4878                                         e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_FLD], e, 0, NULL);
4879                                         break;
4880                                 case ev_integer:
4881                                         e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_I], e, 0, NULL);
4882                                         break;
4883                                 case ev_pointer:
4884                                         e2 = QCC_PR_Statement (&pr_opcodes[OP_LOADP_I], e, 0, NULL);
4885                                         break;
4886
4887                                 default:
4888                                         QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch for * (unrecognised type)");
4889                                         e2 = NULL;
4890                                         break;
4891                                 }
4892                                 e2->type = e->type->aux_type;
4893                         }
4894                         else
4895                                 QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch for *");
4896                         return e2;
4897                 }
4898                 else if (QCC_PR_CheckToken ("-"))
4899                 {
4900                         e = QCC_PR_Expression (UNARY_PRIORITY, EXPR_DISALLOW_COMMA);
4901
4902                         switch(e->type->type)
4903                         {
4904                         case ev_float:
4905                                 e2 = QCC_PR_Statement (&pr_opcodes[OP_SUB_F], QCC_MakeFloatConst(0), e, NULL);
4906                                 break;
4907                         case ev_vector:
4908                                 e2 = QCC_PR_Statement (&pr_opcodes[OP_SUB_V], QCC_MakeVectorConst(0, 0, 0), e, NULL);
4909                                 break;
4910                         case ev_integer:
4911                                 e2 = QCC_PR_Statement (&pr_opcodes[OP_SUB_I], QCC_MakeIntConst(0), e, NULL);
4912                                 break;
4913                         default:
4914                                 QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch for -");
4915                                 e2 = NULL;
4916                                 break;
4917                         }
4918                         return e2;
4919                 }
4920                 else if (QCC_PR_CheckToken ("+"))
4921                 {
4922                         e = QCC_PR_Expression (UNARY_PRIORITY, EXPR_DISALLOW_COMMA);
4923
4924                         switch(e->type->type)
4925                         {
4926                         case ev_float:
4927                                 e2 = e;
4928                                 break;
4929                         case ev_vector:
4930                                 e2 = e;
4931                                 break;
4932                         case ev_integer:
4933                                 e2 = e;
4934                                 break;
4935                         default:
4936                                 QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch for +");
4937                                 e2 = NULL;
4938                                 break;
4939                         }
4940                         return e2;
4941                 }
4942
4943                 if (QCC_PR_CheckToken ("("))
4944                 {
4945                         QCC_type_t *newtype;
4946                         newtype = QCC_PR_ParseType(false, true);
4947                         if (newtype)
4948                         {
4949                                 QCC_PR_Expect (")");
4950                                 e = QCC_PR_Expression (UNARY_PRIORITY, EXPR_DISALLOW_COMMA);
4951
4952                                 /*you may cast from a type to itself*/
4953                                 if (!typecmp(e->type, newtype))
4954                                 {
4955                                 }
4956                                 /*you may cast from const 0 to any type of same size for free (from either int or float for simplicity)*/
4957                                 else if (newtype->size == e->type->size && (e->type->type == ev_integer || e->type->type == ev_float) && e->constant && !G_INT(e->ofs))
4958                                 {
4959                                         //direct cast
4960                                         e2 = (void *)qccHunkAlloc (sizeof(QCC_def_t));
4961                                         memset (e2, 0, sizeof(QCC_def_t));
4962
4963                                         e2->type = newtype;
4964                                         e2->ofs = e->ofs;
4965                                         e2->constant = true;
4966                                         e2->temp = e->temp;
4967                                         return e2;
4968                                 }
4969                                 /*cast from int->float will convert*/
4970                                 else if (newtype->type == ev_float && e->type->type == ev_integer)
4971                                         return QCC_PR_Statement (&pr_opcodes[OP_CONV_ITOF], e, 0, NULL);
4972                                 /*cast from float->int will convert*/
4973                                 else if (newtype->type == ev_integer && e->type->type == ev_float)
4974                                         return QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], e, 0, NULL);
4975                                 /*you may freely cast between pointers (and ints, as this is explicit) (strings count as pointers - WARNING: some strings may not be expressable as pointers)*/
4976                                 else if (
4977                                         //pointers
4978                                         ((newtype->type == ev_pointer || newtype->type == ev_string || newtype->type == ev_integer) && (e->type->type == ev_pointer || e->type->type == ev_string || e->type->type == ev_integer))
4979                                         //ents/classs
4980                                         || (newtype->type == ev_entity && e->type->type == ev_entity)
4981                                         //variants are fine too
4982                                         || (newtype->type == ev_variant || e->type->type == ev_variant)
4983                                         )
4984                                 {
4985                                         //direct cast
4986                                         e2 = (void *)qccHunkAlloc (sizeof(QCC_def_t));
4987                                         memset (e2, 0, sizeof(QCC_def_t));
4988
4989                                         e2->type = newtype;
4990                                         e2->ofs = e->ofs;
4991                                         e2->constant = true;
4992                                         e2->temp = e->temp;
4993                                         return e2;
4994                                 }
4995                                 else
4996                                         QCC_PR_ParseError(0, "Bad type cast\n");
4997                         }
4998 /*                      else if (QCC_PR_CheckToken("*"))
4999                         {
5000                                 QCC_PR_Expect (")");
5001                                 e = QCC_PR_Term();
5002                                 e2 = (void *)qccHunkAlloc (sizeof(QCC_def_t));
5003                                 memset (e2, 0, sizeof(QCC_def_t));
5004                                 e2->type = type_pointer;
5005                                 e2->ofs = e->ofs;
5006                                 e2->constant = true;
5007                                 e2->temp = e->temp;
5008                                 return e2;
5009                         }
5010                         else if (QCC_PR_CheckKeyword(keyword_float, "float"))   //check for type casts
5011                         {
5012                                 QCC_PR_Expect (")");
5013                                 e = QCC_PR_Term();
5014                                 if (e->type->type == ev_float)
5015                                         return e;
5016                                 else if (e->type->type == ev_integer)
5017                                         return QCC_PR_Statement (&pr_opcodes[OP_CONV_ITOF], e, 0, NULL);
5018                                 else if (e->type->type == ev_function)
5019                                         return e;
5020         //                      else
5021         //                              QCC_PR_ParseError ("invalid typecast");
5022
5023                                 QCC_PR_ParseWarning (0, "Not all vars make sence as floats");
5024
5025                                 e2 = (void *)qccHunkAlloc (sizeof(QCC_def_t));
5026                                 memset (e2, 0, sizeof(QCC_def_t));
5027                                 e2->type = type_float;
5028                                 e2->ofs = e->ofs;
5029                                 e2->constant = true;
5030                                 e2->temp = e->temp;
5031                                 return e2;
5032                         }
5033                         else if (QCC_PR_CheckKeyword(keyword_class, "class"))
5034                         {
5035                                 QCC_type_t *classtype = QCC_TypeForName(QCC_PR_ParseName());
5036                                 if (!classtype)
5037                                         QCC_PR_ParseError(ERR_NOTANAME, "Class not defined for cast");
5038
5039                                 QCC_PR_Expect (")");
5040                                 e = QCC_PR_Term();
5041                                 e2 = (void *)qccHunkAlloc (sizeof(QCC_def_t));
5042                                 memset (e2, 0, sizeof(QCC_def_t));
5043                                 e2->type = classtype;
5044                                 e2->ofs = e->ofs;
5045                                 e2->constant = true;
5046                                 e2->temp = e->temp;
5047                                 return e2;
5048                         }
5049                         else if (QCC_PR_CheckKeyword(keyword_integer, "integer"))       //check for type casts
5050                         {
5051                                 QCC_PR_Expect (")");
5052                                 e = QCC_PR_Term();
5053                                 if (e->type->type == ev_integer)
5054                                         return e;
5055                                 else if (e->type->type == ev_float)
5056                                         return QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], e, 0, NULL);
5057                                 else
5058                                         QCC_PR_ParseError (ERR_BADTYPECAST, "invalid typecast");
5059                         }
5060                         else if (QCC_PR_CheckKeyword(keyword_int, "int"))       //check for type casts
5061                         {
5062                                 QCC_PR_Expect (")");
5063                                 e = QCC_PR_Term();
5064                                 if (e->type->type == ev_integer)
5065                                         return e;
5066                                 else if (e->type->type == ev_float)
5067                                         return QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], e, 0, NULL);
5068                                 else
5069                                         QCC_PR_ParseError (ERR_BADTYPECAST, "invalid typecast");
5070                         }
5071 */                      else
5072                         {
5073                                 pbool oldcond = conditional;
5074                                 conditional = conditional?2:0;
5075                                 e =     QCC_PR_Expression (TOP_PRIORITY, 0);
5076                                 QCC_PR_Expect (")");
5077                                 conditional = oldcond;
5078                         }
5079                         return e;
5080                 }
5081         }
5082         return QCC_PR_ParseValue (pr_classtype, true);
5083 }
5084
5085
5086 int QCC_canConv(QCC_def_t *from, etype_t to)
5087 {
5088         if (from->type->type == to)
5089                 return 0;
5090
5091         if (from->type->type == ev_vector && to == ev_float)
5092                 return 4;
5093
5094         if (pr_classtype)
5095         {
5096                 if (from->type->type == ev_field)
5097                 {
5098                         if (from->type->aux_type->type == to)
5099                                 return 1;
5100                 }
5101         }
5102
5103         if (from->type->type == ev_variant)
5104                 return 3;
5105
5106 /*      if (from->type->type == ev_pointer && from->type->aux_type->type == to)
5107                 return 1;
5108
5109         if (QCC_ShouldConvert(from, to)>=0)
5110                 return 1;
5111 */
5112         if (from->type->type == ev_integer && to == ev_function)
5113                 return 1;
5114
5115         if (from->constant && from->arraysize == 0 && (from->type->type == ev_integer || from->type->type == ev_float) && !G_INT(from->ofs))
5116                 return 2;
5117
5118         return -100;
5119 }
5120 /*
5121 ==============
5122 PR_Expression
5123 ==============
5124 */
5125
5126 QCC_def_t *QCC_PR_Expression (int priority, int exprflags)
5127 {
5128         QCC_dstatement32_t      *st;
5129         QCC_opcode_t    *op, *oldop;
5130
5131         QCC_opcode_t *bestop;
5132         int numconversions, c;
5133
5134         int opnum;
5135
5136         QCC_def_t               *e, *e2;
5137         etype_t         type_a, type_b, type_c;
5138
5139         if (priority == 0)
5140                 return QCC_PR_Term ();
5141
5142         e = QCC_PR_Expression (priority-1, exprflags);
5143
5144         while (1)
5145         {
5146                 if (priority == FUNC_PRIORITY)
5147                 {
5148                         if (QCC_PR_CheckToken ("(") )
5149                         {
5150                                 qcc_usefulstatement=true;
5151                                 e = QCC_PR_ParseFunctionCall (e);
5152                         }
5153                         if (QCC_PR_CheckToken ("?"))
5154                         {
5155                                 QCC_dstatement32_t *fromj, *elsej;
5156                                 QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_IFNOT_I], e, NULL, &fromj));
5157                                 e = QCC_PR_Expression(TOP_PRIORITY, 0);
5158                                 e2 = QCC_GetTemp(e->type);
5159                                 QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[(e2->type->size>=3)?OP_STORE_V:OP_STORE_F], e, e2, NULL));
5160                                 //e2 can be stomped upon until its reused anyway
5161                                 QCC_UnFreeTemp(e2);
5162
5163                                 QCC_PR_Expect(":");
5164                                 QCC_PR_Statement(&pr_opcodes[OP_GOTO], NULL, NULL, &elsej);
5165                                 fromj->b = &statements[numstatements] - fromj;
5166                                 e = QCC_PR_Expression(TOP_PRIORITY, 0);
5167
5168                                 if (typecmp(e->type, e2->type) != 0)
5169                                         QCC_PR_ParseError(0, "Ternary operator with mismatching types\n");
5170                                 QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[(e2->type->size>=3)?OP_STORE_V:OP_STORE_F], e, e2, NULL));
5171                                 QCC_UnFreeTemp(e2);
5172
5173                                 elsej->a = &statements[numstatements] - elsej;
5174                                 return e2;
5175                         }
5176                 }
5177
5178                 opnum=0;
5179
5180                 if (pr_token_type == tt_immediate)
5181                 {
5182                         if ((pr_immediate_type->type == ev_float && pr_immediate._float < 0) ||
5183                                 (pr_immediate_type->type == ev_integer && pr_immediate._int < 0))       //hehehe... was a minus all along...
5184                                 {
5185                                         QCC_PR_IncludeChunk(pr_token, true, NULL);
5186                                         strcpy(pr_token, "+");//two negatives would make a positive.
5187                                         pr_token_type = tt_punct;
5188                                 }
5189                 }
5190
5191                 if (pr_token_type != tt_punct)
5192                 {
5193                         QCC_PR_ParseWarning(WARN_UNEXPECTEDPUNCT, "Expected punctuation");
5194                 }
5195
5196                 //go straight for the correct priority.
5197                 for (op = opcodeprioritized[priority][opnum]; op; op = opcodeprioritized[priority][++opnum])
5198 //              for (op=pr_opcodes ; op->name ; op++)
5199                 {
5200 //                      if (op->priority != priority)
5201 //                              continue;
5202                         if (!QCC_PR_CheckToken (op->name))
5203                                 continue;
5204                         st = NULL;
5205                         if ( op->associative!=ASSOC_LEFT )
5206                         {
5207                         // if last statement is an indirect, change it to an address of
5208                                 if (!simplestore && ((unsigned)(statements[numstatements-1].op - OP_LOAD_F) < 6 || statements[numstatements-1].op == OP_LOAD_I || statements[numstatements-1].op == OP_LOAD_P) && statements[numstatements-1].c == e->ofs)
5209                                 {
5210                                         qcc_usefulstatement=true;
5211                                         statements[numstatements-1].op = OP_ADDRESS;
5212                                         type_pointer->aux_type->type = e->type->type;
5213                                         e->type = type_pointer;
5214                                 }
5215                                 //if last statement retrieved a value, switch it to retrieve a usable pointer.
5216                                 if ( !simplestore && (unsigned)(statements[numstatements-1].op - OP_LOADA_F) < 7)// || statements[numstatements-1].op == OP_LOADA_C)
5217                                 {
5218                                         statements[numstatements-1].op = OP_GLOBALADDRESS;
5219                                         type_pointer->aux_type->type = e->type->type;
5220                                         e->type = type_pointer;
5221                                 }
5222                                 if ( !simplestore && (unsigned)(statements[numstatements-1].op - OP_LOADP_F) < 7 && statements[numstatements-1].c == e->ofs)
5223                                 {
5224                                         if (!statements[numstatements-1].b)
5225                                         {
5226                                                 //if the loadp has no offset, remove the instruction and convert the dest of this instruction directly to the pointer's load address
5227                                                 //this kills the add 0.
5228                                                 e->ofs = statements[numstatements-1].a;
5229                                                 numstatements--;
5230                                         }
5231                                         else
5232                                         {
5233                                                 statements[numstatements-1].op = OP_POINTER_ADD;
5234                                         }
5235                                         if (e->type != type_pointer)
5236                                         {
5237                                                 type_pointer->aux_type->type = e->type->type;
5238                                                 e->type = type_pointer;
5239                                         }
5240                                 }
5241                                 if ( !simplestore && statements[numstatements-1].op == OP_LOADP_C && e->ofs == statements[numstatements-1].c)
5242                                 {
5243                                         statements[numstatements-1].op = OP_ADD_SF;
5244                                         e->type = type_string;
5245
5246                                         //now we want to make sure that string = float can't work without it being a dereferenced pointer. (we don't want to allow storep_c without dereferece)
5247                                         e2 = QCC_PR_Expression (priority, exprflags);
5248                                         if (e2->type->type == ev_float)
5249                                                 op = &pr_opcodes[OP_STOREP_C];
5250                                 }
5251                                 else
5252                                         e2 = QCC_PR_Expression (priority, exprflags);
5253                         }
5254                         else
5255                         {
5256                                 if (op->priority == 7 && opt_logicops)
5257                                 {
5258                                         optres_logicops++;
5259                                         st = &statements[numstatements];
5260                                         if (*op->name == '&')   //statement 3 because we don't want to optimise this into if from not ifnot
5261                                                 QCC_PR_Statement3(&pr_opcodes[OP_IFNOT_I], e, NULL, NULL, false);
5262                                         else
5263                                                 QCC_PR_Statement3(&pr_opcodes[OP_IF_I], e, NULL, NULL, false);
5264                                 }
5265
5266                                 e2 = QCC_PR_Expression (priority-1, exprflags);
5267                         }
5268
5269                 // type check
5270                         type_a = e->type->type;
5271                         type_b = e2->type->type;
5272
5273 //                      if (type_a == ev_pointer && type_b == ev_pointer)
5274 //                              QCC_PR_ParseWarning(0, "Debug: pointer op pointer");
5275
5276                         if (op->name[0] == '.')// field access gets type from field
5277                         {
5278                                 if (e2->type->aux_type)
5279                                         type_c = e2->type->aux_type->type;
5280                                 else
5281                                         type_c = -1;    // not a field
5282                         }
5283                         else
5284                                 type_c = ev_void;
5285
5286                         oldop = op;
5287                         bestop = NULL;
5288                         numconversions = 32767;
5289                         while (op)
5290                         {
5291                                 if (!(type_c != ev_void && type_c != (*op->type_c)->type))
5292                                 {
5293                                         if (!STRCMP (op->name , oldop->name))   //matches
5294                                         {
5295                                                 //return values are never converted - what to?
5296         //                                      if (type_c != ev_void && type_c != op->type_c->type->type)
5297         //                                      {
5298         //                                              op++;
5299         //                                              continue;
5300         //                                      }
5301
5302                                                 if (op->associative!=ASSOC_LEFT)
5303                                                 {//assignment
5304                                                         if (op->type_a == &type_pointer)        //ent var
5305                                                         {
5306                                                                 /*FIXME: I don't like this code*/
5307                                                                 if (e->type->type != ev_pointer)
5308                                                                         c = -200;       //don't cast to a pointer.
5309                                                                 else if ((*op->type_c)->type == ev_void && op->type_b == &type_pointer && e2->type->type == ev_pointer)
5310                                                                         c = 0;  //generic pointer... fixme: is this safe? make sure both sides are equivelent
5311                                                                 else if (e->type->aux_type->type != (*op->type_b)->type)        //if e isn't a pointer to a type_b
5312                                                                         c = -200;       //don't let the conversion work
5313                                                                 else
5314                                                                         c = QCC_canConv(e2, (*op->type_c)->type);
5315                                                         }
5316                                                         else
5317                                                         {
5318                                                                 c=QCC_canConv(e2, (*op->type_b)->type);
5319                                                                 if (type_a != (*op->type_a)->type)      //in this case, a is the final assigned value
5320                                                                         c = -300;       //don't use this op, as we must not change var b's type
5321                                                                 else if ((*op->type_a)->type == ev_pointer && e->type->aux_type->type != (*op->type_a)->aux_type->type)
5322                                                                         c = -300;       //don't use this op if its a pointer to a different type
5323                                                         }
5324                                                 }
5325                                                 else
5326                                                 {
5327                                                         if (op->type_a == &type_pointer)        //ent var
5328                                                         {
5329                                                                 if (e2->type->type != ev_pointer || e2->type->aux_type->type != (*op->type_b)->type)    //if e isn't a pointer to a type_b
5330                                                                         c = -200;       //don't let the conversion work
5331                                                                 else
5332                                                                         c = 0;
5333                                                         }
5334                                                         else
5335                                                         {
5336                                                                 c=QCC_canConv(e, (*op->type_a)->type);
5337                                                                 c+=QCC_canConv(e2, (*op->type_b)->type);
5338                                                         }
5339                                                 }
5340
5341                                                 if (c>=0 && c < numconversions)
5342                                                 {
5343                                                         bestop = op;
5344                                                         numconversions=c;
5345                                                         if (c == 0)//can't get less conversions than 0...
5346                                                                 break;
5347                                                 }
5348                                         }
5349                                         else
5350                                                 break;
5351                                 }
5352                                 op = opcodeprioritized[priority][++opnum];
5353                         }
5354                         if (bestop == NULL)
5355                         {
5356                                 if (oldop->priority == CONDITION_PRIORITY)
5357                                         op = oldop;
5358                                 else
5359                                 {
5360                                         if (flag_laxcasts)
5361                                         {
5362                                                 op = oldop;
5363                                                 QCC_PR_ParseWarning(WARN_LAXCAST, "type mismatch for %s (%s and %s)", oldop->name, e->type->name, e2->type->name);
5364                                         }
5365                                         else
5366                                                 QCC_PR_ParseError (ERR_TYPEMISMATCH, "type mismatch for %s (%s and %s)", oldop->name, e->type->name, e2->type->name);
5367                                 }
5368                         }
5369                         else
5370                         {
5371                                 if (numconversions>3)
5372                                         QCC_PR_ParseWarning(WARN_IMPLICITCONVERSION, "Implicit conversion");
5373                                 op = bestop;
5374                         }
5375
5376 //                      if (type_a == ev_pointer && type_b != e->type->aux_type->type)
5377 //                              QCC_PR_ParseError ("type mismatch for %s", op->name);
5378
5379                         if (st)
5380                                 st->b = &statements[numstatements] - st;
5381
5382
5383                         if (op->associative!=ASSOC_LEFT)
5384                         {
5385                                 qcc_usefulstatement = true;
5386                                 if (e->constant || e->ofs < OFS_PARM0)
5387                                 {
5388                                         if (e->type->type == ev_function)
5389                                         {
5390                                                 QCC_PR_ParseWarning(WARN_ASSIGNMENTTOCONSTANTFUNC, "Assignment to function %s", e->name);
5391                                                 QCC_PR_ParsePrintDef(WARN_ASSIGNMENTTOCONSTANTFUNC, e);
5392                                         }
5393                                         else
5394                                         {
5395                                                 QCC_PR_ParseWarning(WARN_ASSIGNMENTTOCONSTANT, "Assignment to constant %s", e->name);
5396                                                 QCC_PR_ParsePrintDef(WARN_ASSIGNMENTTOCONSTANT, e);
5397                                         }
5398 #ifndef QCC
5399                                         editbadfile(strings+s_file, pr_source_line);
5400 #endif
5401                                 }
5402                                 if (conditional&1)
5403                                         QCC_PR_ParseWarning(WARN_ASSIGNMENTINCONDITIONAL, "Assignment in conditional");
5404
5405                                 e = QCC_PR_Statement (op, e2, e, NULL);
5406                         }
5407                         else
5408                                 e = QCC_PR_Statement (op, e, e2, NULL);
5409
5410                         if (type_c != ev_void/* && type_c != ev_string*/)       // field access gets type from field
5411                                 e->type = e2->type->aux_type;
5412
5413                         if (priority > 1 && exprflags & EXPR_WARN_ABOVE_1)
5414                                 QCC_PR_ParseWarning(0, "You may wish to add brackets after that ! operator");
5415
5416                         break;
5417                 }
5418                 if (!op)
5419                 {
5420                         if (e == NULL)
5421                                 QCC_PR_ParseError(ERR_INTERNAL, "e == null");
5422
5423
5424                         if (!STRCMP(pr_token, "++"))
5425                         {
5426                                 //if the last statement was an ent.float (or something)
5427                                 if (((unsigned)(statements[numstatements-1].op - OP_LOAD_F) < 6 || statements[numstatements-1].op == OP_LOAD_I) && statements[numstatements-1].c == e->ofs)
5428                                 {       //we have our load.
5429                                         QCC_def_t               *e3;
5430 //the only inefficiency here is with an extra temp (we can't reuse the original)
5431 //this is not a problem, as the optimise temps or locals marshalling can clean these up for us
5432                                         qcc_usefulstatement=true;
5433 //load
5434 //add to temp
5435 //store temp to offset
5436 //return original loaded (which is not at the same offset as the pointer we store to)
5437                                         e2 = QCC_GetTemp(type_float);
5438                                         e3 = QCC_GetTemp(type_pointer);
5439                                         QCC_PR_SimpleStatement(OP_ADDRESS, statements[numstatements-1].a, statements[numstatements-1].b, e3->ofs, false);
5440                                         if (e->type->type == ev_float)
5441                                         {
5442                                                 QCC_PR_Statement3(&pr_opcodes[OP_ADD_F], e, QCC_MakeFloatConst(1), e2, false);
5443                                                 QCC_PR_Statement3(&pr_opcodes[OP_STOREP_F], e2, e3, NULL, false);
5444                                         }
5445                                         else if (e->type->type == ev_integer)
5446                                         {
5447                                                 QCC_PR_Statement3(&pr_opcodes[OP_ADD_I], e, QCC_MakeIntConst(1), e2, false);
5448                                                 QCC_PR_Statement3(&pr_opcodes[OP_STOREP_I], e2, e3, NULL, false);
5449                                         }
5450                                         else
5451                                         {
5452                                                 QCC_PR_ParseError(ERR_PARSEERRORS, "-- suffix operator results in nonstandard behaviour. Use -=1 or prefix form instead");
5453                                                 QCC_PR_IncludeChunk("-=1", false, NULL);
5454                                         }
5455                                         QCC_FreeTemp(e2);
5456                                         QCC_FreeTemp(e3);
5457                                 }
5458                                 else if (e->type->type == ev_float)
5459                                 {
5460 //copy to temp
5461 //add to original
5462 //return temp (which == original)
5463                                         QCC_PR_ParseWarning(WARN_INEFFICIENTPLUSPLUS, "++ suffix operator results in inefficient behaviour. Use +=1 or prefix form instead");
5464                                         qcc_usefulstatement=true;
5465
5466                                         e2 = QCC_GetTemp(type_float);
5467                                         QCC_PR_Statement3(&pr_opcodes[OP_STORE_F], e, e2, NULL, false);
5468                                         QCC_PR_Statement3(&pr_opcodes[OP_ADD_F], e, QCC_MakeFloatConst(1), e, false);
5469                                         QCC_FreeTemp(e);
5470                                         e = e2;
5471                                 }
5472                                 else if (e->type->type == ev_integer)
5473                                 {
5474                                         QCC_PR_ParseWarning(WARN_INEFFICIENTPLUSPLUS, "++ suffix operator results in inefficient behaviour. Use +=1 or prefix form instead");
5475                                         qcc_usefulstatement=true;
5476
5477                                         e2 = QCC_GetTemp(type_integer);
5478                                         QCC_PR_Statement3(&pr_opcodes[OP_STORE_I], e, e2, NULL, false);
5479                                         QCC_PR_Statement3(&pr_opcodes[OP_ADD_I], e, QCC_MakeIntConst(1), e, false);
5480                                         QCC_FreeTemp(e);
5481                                         e = e2;
5482                                 }
5483                                 else
5484                                 {
5485                                         QCC_PR_ParseWarning(WARN_NOTSTANDARDBEHAVIOUR, "++ suffix operator results in nonstandard behaviour. Use +=1 or prefix form instead");
5486                                         QCC_PR_IncludeChunk("+=1", false, NULL);
5487                                 }
5488                                 QCC_PR_Lex();
5489                         }
5490                         else if (!STRCMP(pr_token, "--"))
5491                         {
5492                                 if (((unsigned)(statements[numstatements-1].op - OP_LOAD_F) < 6 || statements[numstatements-1].op == OP_LOAD_I) && statements[numstatements-1].c == e->ofs)
5493                                 {       //we have our load.
5494                                         QCC_def_t               *e3;
5495 //load
5496 //add to temp
5497 //store temp to offset
5498 //return original loaded (which is not at the same offset as the pointer we store to)
5499                                         e2 = QCC_GetTemp(type_float);
5500                                         e3 = QCC_GetTemp(type_pointer);
5501                                         QCC_PR_SimpleStatement(OP_ADDRESS, statements[numstatements-1].a, statements[numstatements-1].b, e3->ofs, false);
5502                                         if (e->type->type == ev_float)
5503                                         {
5504                                                 QCC_PR_Statement3(&pr_opcodes[OP_SUB_F], e, QCC_MakeFloatConst(1), e2, false);
5505                                                 QCC_PR_Statement3(&pr_opcodes[OP_STOREP_F], e2, e3, NULL, false);
5506                                         }
5507                                         else if (e->type->type == ev_integer)
5508                                         {
5509                                                 QCC_PR_Statement3(&pr_opcodes[OP_SUB_I], e, QCC_MakeIntConst(1), e2, false);
5510                                                 QCC_PR_Statement3(&pr_opcodes[OP_STOREP_I], e2, e3, NULL, false);
5511                                         }
5512                                         else
5513                                         {
5514                                                 QCC_PR_ParseError(ERR_PARSEERRORS, "-- suffix operator results in nonstandard behaviour. Use -=1 or prefix form instead");
5515                                                 QCC_PR_IncludeChunk("-=1", false, NULL);
5516                                         }
5517                                         QCC_FreeTemp(e2);
5518                                         QCC_FreeTemp(e3);
5519                                 }
5520                                 else if (e->type->type == ev_float)
5521                                 {
5522                                         QCC_PR_ParseWarning(WARN_INEFFICIENTPLUSPLUS, "-- suffix operator results in inefficient behaviour. Use -=1 or prefix form instead");
5523                                         qcc_usefulstatement=true;
5524
5525                                         e2 = QCC_GetTemp(type_float);
5526                                         QCC_PR_Statement3(&pr_opcodes[OP_STORE_F], e, e2, NULL, false);
5527                                         QCC_PR_Statement3(&pr_opcodes[OP_SUB_F], e, QCC_MakeFloatConst(1), e, false);
5528                                         QCC_FreeTemp(e);
5529                                         e = e2;
5530                                 }
5531                                 else if (e->type->type == ev_integer)
5532                                 {
5533                                         QCC_PR_ParseWarning(WARN_INEFFICIENTPLUSPLUS, "-- suffix operator results in inefficient behaviour. Use -=1 or prefix form instead");
5534                                         qcc_usefulstatement=true;
5535
5536                                         e2 = QCC_GetTemp(type_integer);
5537                                         QCC_PR_Statement3(&pr_opcodes[OP_STORE_I], e, e2, NULL, false);
5538                                         QCC_PR_Statement3(&pr_opcodes[OP_SUB_I], e, QCC_MakeIntConst(1), e, false);
5539                                         QCC_FreeTemp(e);
5540                                         e = e2;
5541                                 }
5542                                 else
5543                                 {
5544                                         QCC_PR_ParseWarning(WARN_NOTSTANDARDBEHAVIOUR, "-- suffix operator results in nonstandard behaviour. Use -=1 or prefix form instead");
5545                                         QCC_PR_IncludeChunk("-=1", false, NULL);
5546                                 }
5547                                 QCC_PR_Lex();
5548                         }
5549                         break;  // next token isn't at this priority level
5550                 }
5551         }
5552         if (e == NULL)
5553                 QCC_PR_ParseError(ERR_INTERNAL, "e == null");
5554
5555         if (!(exprflags&EXPR_DISALLOW_COMMA) && priority == TOP_PRIORITY && QCC_PR_CheckToken (","))
5556         {
5557                 if (!qcc_usefulstatement)
5558                         QCC_PR_ParseWarning(WARN_POINTLESSSTATEMENT, "Effectless statement");
5559
5560                 QCC_FreeTemp(e);
5561                 qcc_usefulstatement = false;
5562                 e = QCC_PR_Expression(TOP_PRIORITY, exprflags);
5563         }
5564
5565         return e;
5566 }
5567
5568 int QCC_PR_IntConstExpr(void)
5569 {
5570         QCC_def_t *def = QCC_PR_Expression(TOP_PRIORITY, 0);
5571         if (def->constant)
5572         {
5573                 def->references++;
5574                 if (def->type->type == ev_integer)
5575                         return G_INT(def->ofs);
5576                 if (def->type->type == ev_float)
5577                 {
5578                         int i = G_FLOAT(def->ofs);
5579                         if ((float)i == G_FLOAT(def->ofs))
5580                                 return i;
5581                 }
5582         }
5583         QCC_PR_ParseError(ERR_NOTACONSTANT, "Value is not an integer constant");
5584         return true;
5585 }
5586
5587 void QCC_PR_GotoStatement (QCC_dstatement_t *patch2, char *labelname)
5588 {
5589         if (num_gotos >= max_gotos)
5590         {
5591                 max_gotos += 8;
5592                 pr_gotos = realloc(pr_gotos, sizeof(*pr_gotos)*max_gotos);
5593         }
5594
5595         strncpy(pr_gotos[num_gotos].name, labelname, sizeof(pr_gotos[num_gotos].name) -1);
5596         pr_gotos[num_gotos].lineno = pr_source_line;
5597         pr_gotos[num_gotos].statementno = patch2 - statements;
5598
5599         num_gotos++;
5600 }
5601
5602 pbool QCC_PR_StatementBlocksMatch(QCC_dstatement_t *p1, int p1count, QCC_dstatement_t *p2, int p2count)
5603 {
5604         if (p1count != p2count)
5605                 return false;
5606
5607         while(p1count>0)
5608         {
5609                 if (p1->op != p2->op)
5610                         return false;
5611                 if (p1->a != p2->a)
5612                         return false;
5613                 if (p1->b != p2->b)
5614                         return false;
5615                 if (p1->c != p2->c)
5616                         return false;
5617                 p1++;
5618                 p2++;
5619                 p1count--;
5620         }
5621
5622         return true;
5623 }
5624
5625 /*
5626 ============
5627 PR_ParseStatement
5628
5629 ============
5630 */
5631 void QCC_PR_ParseStatement (void)
5632 {
5633         int continues;
5634         int breaks;
5635         int cases;
5636         int i;
5637         QCC_def_t                               *e, *e2;
5638         QCC_dstatement_t                *patch1, *patch2, *patch3;
5639         int statementstart = pr_source_line;
5640
5641         if (QCC_PR_CheckToken ("{"))
5642         {
5643                 e = pr.localvars;
5644                 while (!QCC_PR_CheckToken("}"))
5645                         QCC_PR_ParseStatement ();
5646
5647                 if (pr_subscopedlocals)
5648                 {
5649                         for (e2 = pr.localvars; e2 != e; e2 = e2->nextlocal)
5650                         {
5651                                 if (!e2->subscoped_away)
5652                                 {
5653                                         Hash_RemoveData(&localstable, e2->name, e2);
5654                                         e2->subscoped_away = true;
5655                                 }
5656                         }
5657                 }
5658                 return;
5659         }
5660
5661         if (QCC_PR_CheckKeyword(keyword_return, "return"))
5662         {
5663                 /*if (pr_classtype)
5664                 {
5665                         e = QCC_PR_GetDef(NULL, "__oself", pr_scope, false, 0);
5666                         e2 = QCC_PR_GetDef(NULL, "self", NULL, false, 0);
5667                         QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], e, QCC_PR_DummyDef(pr_classtype, "self", pr_scope, 0, e2->ofs, false), NULL));
5668                 }*/
5669
5670                 if (QCC_PR_CheckToken (";"))
5671                 {
5672                         if (pr_scope->type->aux_type->type != ev_void)
5673                                 QCC_PR_ParseWarning(WARN_MISSINGRETURNVALUE, "\'%s\' should return %s", pr_scope->name, pr_scope->type->aux_type->name);
5674                         if (opt_return_only)
5675                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_DONE], 0, 0, NULL));
5676                         else
5677                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_RETURN], 0, 0, NULL));
5678                         return;
5679                 }
5680                 e = QCC_PR_Expression (TOP_PRIORITY, 0);
5681                 e2 = QCC_SupplyConversion(e, pr_scope->type->aux_type->type, true);
5682                 if (e != e2)
5683                 {
5684                         QCC_PR_ParseWarning(WARN_CORRECTEDRETURNTYPE, "\'%s\' returned %s, expected %s, conversion supplied", pr_scope->name, e->type->name, pr_scope->type->aux_type->name);
5685                         e = e2;
5686                 }
5687                 QCC_PR_Expect (";");
5688                 if (pr_scope->type->aux_type->type != e->type->type)
5689                         QCC_PR_ParseWarning(WARN_WRONGRETURNTYPE, "\'%s\' returned %s, expected %s", pr_scope->name, e->type->name, pr_scope->type->aux_type->name);
5690                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_RETURN], e, 0, NULL));
5691                 return;
5692         }
5693         if (QCC_PR_CheckKeyword(keyword_exit, "exit"))
5694         {
5695                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_DONE], 0, 0, NULL));
5696                 QCC_PR_Expect (";");
5697                 return;
5698         }
5699
5700         if (QCC_PR_CheckKeyword(keyword_while, "while"))
5701         {
5702                 continues = num_continues;
5703                 breaks = num_breaks;
5704
5705                 QCC_PR_Expect ("(");
5706                 patch2 = &statements[numstatements];
5707                 conditional = 1;
5708                 e = QCC_PR_Expression (TOP_PRIORITY, 0);
5709                 conditional = 0;
5710                 if (((e->constant && !e->temp) || !STRCMP(e->name, "IMMEDIATE")) && opt_compound_jumps)
5711                 {
5712                         optres_compound_jumps++;
5713                         if (!G_INT(e->ofs))
5714                         {
5715                                 QCC_PR_ParseWarning(0, "while(0)?");
5716                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_GOTO], 0, 0, &patch1));
5717                         }
5718                         else
5719                         {
5720                                 patch1 = NULL;
5721                         }
5722                 }
5723                 else
5724                 {
5725                         if (e->constant && !e->temp)
5726                         {
5727                                 if (!G_FLOAT(e->ofs))
5728                                         QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_GOTO], 0, 0, &patch1));
5729                                 else
5730                                         patch1 = NULL;
5731                         }
5732                         else if (!typecmp( e->type, type_string) && flag_ifstring)      //special case, as strings are now pointers, not offsets from string table
5733                         {
5734                                 QCC_PR_ParseWarning(WARN_IFSTRING_USED, "while(string) can result in bizzare behaviour");
5735                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_S], e, 0, &patch1));
5736                         }
5737                         else if (!typecmp( e->type, type_float) && (flag_iffloat||QCC_OPCodeValid(&pr_opcodes[OP_IFNOT_F])))    //special case, as negative 0 is also zero
5738                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_F], e, 0, &patch1));
5739                         else
5740                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_I], e, 0, &patch1));
5741                 }
5742                 QCC_PR_Expect (")");    //after the line number is noted..
5743                 QCC_PR_ParseStatement ();
5744                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_GOTO], NULL, 0, &patch3));
5745                 patch3->a = patch2 - patch3;
5746                 if (patch1)
5747                 {
5748                         if (patch1->op == OP_GOTO)
5749                                 patch1->a = &statements[numstatements] - patch1;
5750                         else
5751                                 patch1->b = &statements[numstatements] - patch1;
5752                 }
5753
5754                 if (breaks != num_breaks)
5755                 {
5756                         for(i = breaks; i < num_breaks; i++)
5757                         {
5758                                 patch1 = &statements[pr_breaks[i]];
5759                                 statements[pr_breaks[i]].a = &statements[numstatements] - patch1;       //jump to after the return-to-top goto
5760                         }
5761                         num_breaks = breaks;
5762                 }
5763                 if (continues != num_continues)
5764                 {
5765                         for(i = continues; i < num_continues; i++)
5766                         {
5767                                 patch1 = &statements[pr_continues[i]];
5768                                 statements[pr_continues[i]].a = patch2 - patch1;        //jump back to top
5769                         }
5770                         num_continues = continues;
5771                 }
5772                 return;
5773         }
5774         if (QCC_PR_CheckKeyword(keyword_for, "for"))
5775         {
5776                 int old_numstatements;
5777                 int numtemp, i;
5778
5779                 int                                     linenum[32];
5780                 QCC_dstatement_t                temp[sizeof(linenum)/sizeof(linenum[0])];
5781
5782                 continues = num_continues;
5783                 breaks = num_breaks;
5784
5785                 QCC_PR_Expect("(");
5786                 if (!QCC_PR_CheckToken(";"))
5787                 {
5788                         QCC_FreeTemp(QCC_PR_Expression(TOP_PRIORITY, 0));
5789                         QCC_PR_Expect(";");
5790                 }
5791
5792                 patch2 = &statements[numstatements];
5793                 if (!QCC_PR_CheckToken(";"))
5794                 {
5795                         conditional = 1;
5796                         e = QCC_PR_Expression(TOP_PRIORITY, 0);
5797                         conditional = 0;
5798                         QCC_PR_Expect(";");
5799                 }
5800                 else
5801                         e = NULL;
5802
5803                 if (!QCC_PR_CheckToken(")"))
5804                 {
5805                         old_numstatements = numstatements;
5806                         QCC_FreeTemp(QCC_PR_Expression(TOP_PRIORITY, 0));
5807
5808                         numtemp = numstatements - old_numstatements;
5809                         if (numtemp > sizeof(linenum)/sizeof(linenum[0]))
5810                                 QCC_PR_ParseError(ERR_TOOCOMPLEX, "Update expression too large");
5811                         numstatements = old_numstatements;
5812                         for (i = 0 ; i < numtemp ; i++)
5813                         {
5814                                 linenum[i] = statement_linenums[numstatements + i];
5815                                 temp[i] = statements[numstatements + i];
5816                         }
5817
5818                         QCC_PR_Expect(")");
5819                 }
5820                 else
5821                         numtemp = 0;
5822
5823                 if (e)
5824                         QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_IFNOT_I], e, 0, &patch1));
5825                 else
5826                         patch1 = NULL;
5827                 if (!QCC_PR_CheckToken(";"))
5828                         QCC_PR_ParseStatement();        //don't give the hanging ';' warning.
5829                 patch3 = &statements[numstatements];
5830                 for (i = 0 ; i < numtemp ; i++)
5831                 {
5832                         statement_linenums[numstatements] = linenum[i];
5833                         statements[numstatements++] = temp[i];
5834                 }
5835                 QCC_PR_SimpleStatement(OP_GOTO, patch2 - &statements[numstatements], 0, 0, false);
5836                 if (patch1)
5837                         patch1->b = &statements[numstatements] - patch1;
5838
5839                 if (breaks != num_breaks)
5840                 {
5841                         for(i = breaks; i < num_breaks; i++)
5842                         {
5843                                 patch1 = &statements[pr_breaks[i]];
5844                                 statements[pr_breaks[i]].a = &statements[numstatements] - patch1;
5845                         }
5846                         num_breaks = breaks;
5847                 }
5848                 if (continues != num_continues)
5849                 {
5850                         for(i = continues; i < num_continues; i++)
5851                         {
5852                                 patch1 = &statements[pr_continues[i]];
5853                                 statements[pr_continues[i]].a = patch3 - patch1;
5854                         }
5855                         num_continues = continues;
5856                 }
5857
5858                 return;
5859         }
5860         if (QCC_PR_CheckKeyword(keyword_do, "do"))
5861         {
5862                 continues = num_continues;
5863                 breaks = num_breaks;
5864
5865                 patch1 = &statements[numstatements];
5866                 QCC_PR_ParseStatement ();
5867                 QCC_PR_Expect ("while");
5868                 QCC_PR_Expect ("(");
5869                 conditional = 1;
5870                 e = QCC_PR_Expression (TOP_PRIORITY, 0);
5871                 conditional = 0;
5872
5873                 if (e->constant && !e->temp)
5874                 {
5875                         if (G_FLOAT(e->ofs))
5876                         {
5877                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_GOTO], NULL, 0, &patch2));
5878                                 patch2->a = patch1 - patch2;
5879                         }
5880                 }
5881                 else
5882                 {
5883                         if (!typecmp( e->type, type_string) && flag_ifstring)
5884                         {
5885                                 QCC_PR_ParseWarning(WARN_IFSTRING_USED, "do {} while(string) can result in bizzare behaviour");
5886                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_S], e, NULL, &patch2));
5887                         }
5888                         else if (!typecmp( e->type, type_float) && (flag_iffloat||QCC_OPCodeValid(&pr_opcodes[OP_IFNOT_F])))
5889                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_F], e, NULL, &patch2));
5890                         else
5891                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_I], e, NULL, &patch2));
5892
5893                         patch2->b = patch1 - patch2;
5894                 }
5895
5896                 QCC_PR_Expect (")");
5897                 QCC_PR_Expect (";");
5898
5899                 if (breaks != num_breaks)
5900                 {
5901                         for(i = breaks; i < num_breaks; i++)
5902                         {
5903                                 patch2 = &statements[pr_breaks[i]];
5904                                 statements[pr_breaks[i]].a = &statements[numstatements] - patch2;
5905                         }
5906                         num_breaks = breaks;
5907                 }
5908                 if (continues != num_continues)
5909                 {
5910                         for(i = continues; i < num_continues; i++)
5911                         {
5912                                 patch2 = &statements[pr_continues[i]];
5913                                 statements[pr_continues[i]].a = patch1 - patch2;
5914                         }
5915                         num_continues = continues;
5916                 }
5917
5918                 return;
5919         }
5920
5921         if (QCC_PR_CheckKeyword(keyword_local, "local"))
5922         {
5923                 QCC_type_t *functionsclasstype = pr_classtype;
5924 //              if (locals_end != numpr_globals)        //is this breaking because of locals?
5925 //                      QCC_PR_ParseWarning("local vars after temp vars\n");
5926                 QCC_PR_ParseDefs (NULL);
5927                 pr_classtype = functionsclasstype;
5928                 locals_end = numpr_globals;
5929                 return;
5930         }
5931
5932         if (pr_token_type == tt_name)
5933         if ((keyword_var && !STRCMP ("var", pr_token)) ||
5934                 (keyword_string && !STRCMP ("string", pr_token)) ||
5935                 (keyword_float && !STRCMP ("float", pr_token)) ||
5936                 (keyword_entity && !STRCMP ("entity", pr_token)) ||
5937                 (keyword_vector && !STRCMP ("vector", pr_token)) ||
5938                 (keyword_integer && !STRCMP ("integer", pr_token)) ||
5939                 (keyword_int && !STRCMP ("int", pr_token)) ||
5940                 (keyword_class && !STRCMP ("class", pr_token)) ||
5941                 (keyword_const && !STRCMP ("const", pr_token)))
5942         {
5943 //              if (locals_end != numpr_globals)        //is this breaking because of locals?
5944 //                      QCC_PR_ParseWarning("local vars after temp vars\n");
5945                 QCC_PR_ParseDefs (NULL);
5946                 locals_end = numpr_globals;
5947                 return;
5948         }
5949
5950         if (QCC_PR_CheckKeyword(keyword_state, "state"))
5951         {
5952                 QCC_PR_Expect("[");
5953                 QCC_PR_ParseState();
5954                 QCC_PR_Expect(";");
5955                 return;
5956         }
5957         if (QCC_PR_CheckToken("#"))
5958         {
5959                 char *name;
5960                 float frame = pr_immediate._float;
5961                 QCC_PR_Lex();
5962                 name = QCC_PR_ParseName();
5963                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STATE], QCC_MakeFloatConst(frame), QCC_PR_GetDef(type_function, name, NULL, false, 0, false), NULL));
5964                 QCC_PR_Expect(";");
5965                 return;
5966         }
5967
5968         if (QCC_PR_CheckKeyword(keyword_if, "if"))
5969         {
5970                 pbool negate = QCC_PR_CheckKeyword(keyword_not, "not");
5971
5972                 QCC_PR_Expect ("(");
5973                 conditional = 1;
5974                 e = QCC_PR_Expression (TOP_PRIORITY, 0);
5975                 conditional = 0;
5976
5977 //              negate = negate != 0;
5978
5979                 if (negate)
5980                 {
5981                         if (!typecmp( e->type, type_string) && flag_ifstring)
5982                         {
5983                                 QCC_PR_ParseWarning(WARN_IFSTRING_USED, "if not(string) can result in bizzare behaviour");
5984                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_S], e, 0, &patch1));
5985                         }
5986                         else if (!typecmp( e->type, type_float) && (flag_iffloat||QCC_OPCodeValid(&pr_opcodes[OP_IFNOT_F])))
5987                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_F], e, 0, &patch1));
5988                         else
5989                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_I], e, 0, &patch1));
5990                 }
5991                 else
5992                 {
5993                         if (!typecmp( e->type, type_string) && flag_ifstring)
5994                         {
5995                                 QCC_PR_ParseWarning(WARN_IFSTRING_USED, "if (string) can result in bizzare behaviour");
5996                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_S], e, 0, &patch1));
5997                         }
5998                         else if (!typecmp( e->type, type_float) && (flag_iffloat||QCC_OPCodeValid(&pr_opcodes[OP_IFNOT_F])))
5999                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_F], e, 0, &patch1));
6000                         else
6001                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_I], e, 0, &patch1));
6002                 }
6003
6004                 QCC_PR_Expect (")");    //close bracket is after we save the statement to mem (so debugger does not show the if statement as being on the line after
6005
6006                 QCC_PR_ParseStatement ();
6007
6008                 if (QCC_PR_CheckKeyword (keyword_else, "else"))
6009                 {
6010                         int lastwasreturn;
6011                         lastwasreturn = statements[numstatements-1].op == OP_RETURN || statements[numstatements-1].op == OP_DONE ||
6012                                 statements[numstatements-1].op == OP_GOTO;
6013
6014                         //the last statement of the if was a return, so we don't need the goto at the end
6015                         if (lastwasreturn && opt_compound_jumps && !QCC_AStatementJumpsTo(numstatements, patch1-statements, numstatements))
6016                         {
6017 //                              QCC_PR_ParseWarning(0, "optimised the else");
6018                                 optres_compound_jumps++;
6019                                 patch1->b = &statements[numstatements] - patch1;
6020                                 QCC_PR_ParseStatement ();
6021                         }
6022                         else
6023                         {
6024 //                              QCC_PR_ParseWarning(0, "using the else");
6025                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_GOTO], 0, 0, &patch2));
6026                                 patch1->b = &statements[numstatements] - patch1;
6027                                 QCC_PR_ParseStatement ();
6028                                 patch2->a = &statements[numstatements] - patch2;
6029
6030                                 if (QCC_PR_StatementBlocksMatch(patch1+1, patch2-patch1, patch2+1, &statements[numstatements] - patch2))
6031                                         QCC_PR_ParseWarning(0, "Two identical blocks each side of an else");
6032                         }
6033                 }
6034                 else
6035                         patch1->b = &statements[numstatements] - patch1;
6036
6037                 return;
6038         }
6039         if (QCC_PR_CheckKeyword(keyword_switch, "switch"))
6040         {
6041                 int op;
6042                 int hcstyle;
6043                 int defaultcase = -1;
6044                 temp_t *et;
6045                 int oldst;
6046                 QCC_type_t *switchtype;
6047
6048                 breaks = num_breaks;
6049                 cases = num_cases;
6050
6051
6052                 QCC_PR_Expect ("(");
6053
6054                 conditional = 1;
6055                 e = QCC_PR_Expression (TOP_PRIORITY, 0);
6056                 conditional = 0;
6057
6058                 if (e == &def_ret)
6059                 {       //copy it out, so our hack just below doesn't crash us
6060 /*                      if (e->type->type == ev_vector)
6061                                 e = QCC_PR_Statement(pr_opcodes+OP_STORE_V, e, QCC_GetTemp(type_vector), NULL);
6062                         else
6063                                 e = QCC_PR_Statement(pr_opcodes+OP_STORE_F, e, QCC_GetTemp(type_float), NULL);
6064
6065                         if (e == &def_ret)      //this shouldn't be happening
6066                                 QCC_Error(ERR_INTERNAL, "internal error: switch: e == &def_ret");
6067 */
6068                         et = NULL;
6069                 }
6070                 else
6071                 {
6072                         et = e->temp;
6073                         e->temp = NULL; //so noone frees it until we finish this loop
6074                 }
6075
6076                 //expands
6077
6078                 //switch (CONDITION)
6079                 //{
6080                 //case 1:
6081                 //      break;
6082                 //case 2:
6083                 //default:
6084                 //      break;
6085                 //}
6086
6087                 //to
6088
6089                 // x = CONDITION, goto start
6090                 // l1:
6091                 //      goto end
6092                 // l2:
6093                 // def:
6094                 //      goto end
6095                 //      goto end                        P1
6096                 // start:
6097                 //      if (x == 1) goto l1;
6098                 //      if (x == 2) goto l2;
6099                 //      goto def
6100                 // end:
6101
6102                 //x is emitted in an opcode, stored as a register that we cannot access later.
6103                 //it should be possible to nest these.
6104
6105                 switchtype = e->type;
6106                 switch(switchtype->type)
6107                 {
6108                 case ev_float:
6109                         op = OP_SWITCH_F;
6110                         break;
6111                 case ev_entity: //whu???
6112                         op = OP_SWITCH_E;
6113                         break;
6114                 case ev_vector:
6115                         op = OP_SWITCH_V;
6116                         break;
6117                 case ev_string:
6118                         op = OP_SWITCH_S;
6119                         break;
6120                 case ev_function:
6121                         op = OP_SWITCH_FNC;
6122                         break;
6123                 default:        //err hmm.
6124                         op = 0;
6125                         break;
6126                 }
6127
6128                 if (op)
6129                         hcstyle = QCC_OPCodeValid(&pr_opcodes[op]);
6130                 else
6131                         hcstyle = false;
6132
6133
6134                 if (hcstyle)
6135                         QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[op], e, 0, &patch1));
6136                 else
6137                         QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_GOTO], e, 0, &patch1));
6138
6139                 QCC_PR_Expect (")");    //close bracket is after we save the statement to mem (so debugger does not show the if statement as being on the line after
6140
6141                 oldst = numstatements;
6142                 QCC_PR_ParseStatement ();
6143
6144                 //this is so that a missing goto at the end of your switch doesn't end up in the jumptable again
6145                 if (oldst == numstatements || !QCC_StatementIsAJump(numstatements-1, numstatements-1))
6146                 {
6147                         QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_GOTO], 0, 0, &patch2));   //the P1 statement/the theyforgotthebreak statement.
6148 //                      QCC_PR_ParseWarning(0, "emitted goto");
6149                 }
6150                 else
6151                 {
6152                         patch2 = NULL;
6153 //                      QCC_PR_ParseWarning(0, "No goto");
6154                 }
6155
6156                 if (hcstyle)
6157                         patch1->b = &statements[numstatements] - patch1;        //the goto start part
6158                 else
6159                         patch1->a = &statements[numstatements] - patch1;        //the goto start part
6160
6161                 if (e == &def_ret)
6162                         e->type = switchtype;   //set it back to the type it was actually meant to be.
6163
6164                 for (i = cases; i < num_cases; i++)
6165                 {
6166                         if (!pr_casesdef[i])
6167                         {
6168                                 if (defaultcase >= 0)
6169                                         QCC_PR_ParseError(ERR_MULTIPLEDEFAULTS, "Duplicated default case");
6170                                 defaultcase = i;
6171                         }
6172                         else
6173                         {
6174                                 if (pr_casesdef[i]->type->type != e->type->type)
6175                                 {
6176                                         if (e->type->type == ev_integer && pr_casesdef[i]->type->type == ev_float)
6177                                                 pr_casesdef[i] = QCC_MakeIntConst((int)qcc_pr_globals[pr_casesdef[i]->ofs]);
6178                                         else
6179                                                 QCC_PR_ParseWarning(WARN_SWITCHTYPEMISMATCH, "switch case type mismatch");
6180                                 }
6181                                 if (pr_casesdef2[i])
6182                                 {
6183                                         if (pr_casesdef2[i]->type->type != e->type->type)
6184                                         {
6185                                                 if (e->type->type == ev_integer && pr_casesdef[i]->type->type == ev_float)
6186                                                         pr_casesdef2[i] = QCC_MakeIntConst((int)qcc_pr_globals[pr_casesdef2[i]->ofs]);
6187                                                 else
6188                                                         QCC_PR_ParseWarning(WARN_SWITCHTYPEMISMATCH, "switch caserange type mismatch");
6189                                         }
6190
6191                                         if (hcstyle)
6192                                         {
6193                                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_CASERANGE], pr_casesdef[i], pr_casesdef2[i], &patch3));
6194                                                 patch3->c = &statements[pr_cases[i]] - patch3;
6195                                         }
6196                                         else
6197                                         {
6198                                                 QCC_def_t *e3;
6199
6200                                                 if (e->type->type == ev_float)
6201                                                 {
6202                                                         e2 = QCC_PR_Statement (&pr_opcodes[OP_GE_F], e, pr_casesdef[i], NULL);
6203                                                         e3 = QCC_PR_Statement (&pr_opcodes[OP_LE_F], e, pr_casesdef2[i], NULL);
6204                                                         e2 = QCC_PR_Statement (&pr_opcodes[OP_AND_F], e2, e3, NULL);
6205                                                         QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_I], e2, 0, &patch3));
6206                                                         patch3->b = &statements[pr_cases[i]] - patch3;
6207                                                 }
6208                                                 else if (e->type->type == ev_integer)
6209                                                 {
6210                                                         e2 = QCC_PR_Statement (&pr_opcodes[OP_GE_I], e, pr_casesdef[i], NULL);
6211                                                         e3 = QCC_PR_Statement (&pr_opcodes[OP_LE_I], e, pr_casesdef2[i], NULL);
6212                                                         e2 = QCC_PR_Statement (&pr_opcodes[OP_AND_I], e2, e3, NULL);
6213                                                         QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_I], e2, 0, &patch3));
6214                                                         patch3->b = &statements[pr_cases[i]] - patch3;
6215                                                 }
6216                                                 else
6217                                                         QCC_PR_ParseWarning(WARN_SWITCHTYPEMISMATCH, "switch caserange MUST be a float or integer");
6218                                         }
6219                                 }
6220                                 else
6221                                 {
6222                                         if (hcstyle)
6223                                         {
6224                                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_CASE], pr_casesdef[i], 0, &patch3));
6225                                                 patch3->b = &statements[pr_cases[i]] - patch3;
6226                                         }
6227                                         else
6228                                         {
6229                                                 if (!pr_casesdef[i]->constant || G_INT(pr_casesdef[i]->ofs))
6230                                                 {
6231                                                         switch(e->type->type)
6232                                                         {
6233                                                         case ev_float:
6234                                                                 e2 = QCC_PR_Statement (&pr_opcodes[OP_EQ_F], e, pr_casesdef[i], NULL);
6235                                                                 break;
6236                                                         case ev_entity: //whu???
6237                                                                 e2 = QCC_PR_Statement (&pr_opcodes[OP_EQ_E], e, pr_casesdef[i], &patch1);
6238                                                                 break;
6239                                                         case ev_vector:
6240                                                                 e2 = QCC_PR_Statement (&pr_opcodes[OP_EQ_V], e, pr_casesdef[i], &patch1);
6241                                                                 break;
6242                                                         case ev_string:
6243                                                                 e2 = QCC_PR_Statement (&pr_opcodes[OP_EQ_S], e, pr_casesdef[i], &patch1);
6244                                                                 break;
6245                                                         case ev_function:
6246                                                                 e2 = QCC_PR_Statement (&pr_opcodes[OP_EQ_FNC], e, pr_casesdef[i], &patch1);
6247                                                                 break;
6248                                                         case ev_field:
6249                                                                 e2 = QCC_PR_Statement (&pr_opcodes[OP_EQ_FNC], e, pr_casesdef[i], &patch1);
6250                                                                 break;
6251                                                         case ev_integer:
6252                                                                 e2 = QCC_PR_Statement (&pr_opcodes[OP_EQ_I], e, pr_casesdef[i], &patch1);
6253                                                                 break;
6254                                                         default:
6255                                                                 QCC_PR_ParseError(ERR_BADSWITCHTYPE, "Bad switch type");
6256                                                                 e2 = NULL;
6257                                                                 break;
6258                                                         }
6259                                                         QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_I], e2, 0, &patch3));
6260                                                 }
6261                                                 else
6262                                                 {
6263                                                         if (e->type->type == ev_string)
6264                                                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_S], e, 0, &patch3));
6265                                                         else if (e->type->type == ev_float)
6266                                                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_F], e, 0, &patch3));
6267                                                         else
6268                                                                 QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_I], e, 0, &patch3));
6269                                                 }
6270                                                 patch3->b = &statements[pr_cases[i]] - patch3;
6271                                         }
6272                                 }
6273                         }
6274                 }
6275                 if (defaultcase>=0)
6276                 {
6277                         QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_GOTO], 0, 0, &patch3));
6278                         patch3->a = &statements[pr_cases[defaultcase]] - patch3;
6279                 }
6280
6281                 num_cases = cases;
6282
6283
6284                 patch3 = &statements[numstatements];
6285                 if (patch2)
6286                         patch2->a = patch3 - patch2;    //set P1 jump
6287
6288                 if (breaks != num_breaks)
6289                 {
6290                         for(i = breaks; i < num_breaks; i++)
6291                         {
6292                                 patch2 = &statements[pr_breaks[i]];
6293                                 patch2->a = patch3 - patch2;
6294                         }
6295                         num_breaks = breaks;
6296                 }
6297
6298                 if (et)
6299                 {
6300                         e->temp = et;
6301                         QCC_FreeTemp(e);
6302                 }
6303                 return;
6304         }
6305
6306         if (QCC_PR_CheckKeyword(keyword_asm, "asm"))
6307         {
6308                 if (QCC_PR_CheckToken("{"))
6309                 {
6310                         while (!QCC_PR_CheckToken("}"))
6311                                 QCC_PR_ParseAsm ();
6312                 }
6313                 else
6314                         QCC_PR_ParseAsm ();
6315                 return;
6316         }
6317
6318         if (QCC_PR_CheckToken(":"))
6319         {
6320                 if (pr_token_type != tt_name)
6321                 {
6322                         QCC_PR_ParseError(ERR_BADLABELNAME, "invalid label name \"%s\"", pr_token);
6323                         return;
6324                 }
6325
6326                 for (i = 0; i < num_labels; i++)
6327                         if (!STRNCMP(pr_labels[i].name, pr_token, sizeof(pr_labels[num_labels].name) -1))
6328                         {
6329                                 QCC_PR_ParseWarning(WARN_DUPLICATELABEL, "Duplicate label %s", pr_token);
6330                                 QCC_PR_Lex();
6331                                 return;
6332                         }
6333
6334                 if (num_labels >= max_labels)
6335                 {
6336                         max_labels += 8;
6337                         pr_labels = realloc(pr_labels, sizeof(*pr_labels)*max_labels);
6338                 }
6339
6340                 strncpy(pr_labels[num_labels].name, pr_token, sizeof(pr_labels[num_labels].name) -1);
6341                 pr_labels[num_labels].lineno = pr_source_line;
6342                 pr_labels[num_labels].statementno = numstatements;
6343
6344                 num_labels++;
6345
6346 //              QCC_PR_ParseWarning("Gotos are evil");
6347                 QCC_PR_Lex();
6348                 return;
6349         }
6350         if (QCC_PR_CheckKeyword(keyword_goto, "goto"))
6351         {
6352                 if (pr_token_type != tt_name)
6353                 {
6354                         QCC_PR_ParseError(ERR_NOLABEL, "invalid label name \"%s\"", pr_token);
6355                         return;
6356                 }
6357
6358                 QCC_PR_Statement (&pr_opcodes[OP_GOTO], 0, 0, &patch2);
6359
6360                 QCC_PR_GotoStatement (patch2, pr_token);
6361
6362 //              QCC_PR_ParseWarning("Gotos are evil");
6363                 QCC_PR_Lex();
6364                 QCC_PR_Expect(";");
6365                 return;
6366         }
6367
6368         if (QCC_PR_CheckKeyword(keyword_break, "break"))
6369         {
6370                 if (!STRCMP ("(", pr_token))
6371                 {       //make sure it wasn't a call to the break function.
6372                         QCC_PR_IncludeChunk("break(", true, NULL);
6373                         QCC_PR_Lex();   //so it sees the break.
6374                 }
6375                 else
6376                 {
6377                         if (num_breaks >= max_breaks)
6378                         {
6379                                 max_breaks += 8;
6380                                 pr_breaks = realloc(pr_breaks, sizeof(*pr_breaks)*max_breaks);
6381                         }
6382                         pr_breaks[num_breaks] = numstatements;
6383                         QCC_PR_Statement (&pr_opcodes[OP_GOTO], 0, 0, NULL);
6384                         num_breaks++;
6385                         QCC_PR_Expect(";");
6386                         return;
6387                 }
6388         }
6389         if (QCC_PR_CheckKeyword(keyword_continue, "continue"))
6390         {
6391                 if (num_continues >= max_continues)
6392                 {
6393                         max_continues += 8;
6394                         pr_continues = realloc(pr_continues, sizeof(*pr_continues)*max_continues);
6395                 }
6396                 pr_continues[num_continues] = numstatements;
6397                 QCC_PR_Statement (&pr_opcodes[OP_GOTO], 0, 0, NULL);
6398                 num_continues++;
6399                 QCC_PR_Expect(";");
6400                 return;
6401         }
6402         if (QCC_PR_CheckKeyword(keyword_case, "case"))
6403         {
6404                 if (num_cases >= max_cases)
6405                 {
6406                         max_cases += 8;
6407                         pr_cases = realloc(pr_cases, sizeof(*pr_cases)*max_cases);
6408                         pr_casesdef = realloc(pr_casesdef, sizeof(*pr_casesdef)*max_cases);
6409                         pr_casesdef2 = realloc(pr_casesdef2, sizeof(*pr_casesdef2)*max_cases);
6410                 }
6411                 pr_cases[num_cases] = numstatements;
6412                 pr_casesdef[num_cases] = QCC_PR_Expression (TOP_PRIORITY, EXPR_DISALLOW_COMMA);
6413                 if (QCC_PR_CheckToken(".."))
6414                 {
6415                         pr_casesdef2[num_cases] = QCC_PR_Expression (TOP_PRIORITY, EXPR_DISALLOW_COMMA);
6416                         if (pr_casesdef[num_cases]->constant && pr_casesdef2[num_cases]->constant &&
6417                                 !pr_casesdef[num_cases]->temp && !pr_casesdef2[num_cases]->temp)
6418                                 if (G_FLOAT(pr_casesdef[num_cases]->ofs) >= G_FLOAT(pr_casesdef2[num_cases]->ofs))
6419                                         QCC_PR_ParseError(ERR_CASENOTIMMEDIATE, "Caserange statement uses backwards range\n");
6420                 }
6421                 else
6422                         pr_casesdef2[num_cases] = NULL;
6423
6424                 if (numstatements != pr_cases[num_cases])
6425                         QCC_PR_ParseError(ERR_CASENOTIMMEDIATE, "Case statements may not use formulas\n");
6426                 num_cases++;
6427                 QCC_PR_Expect(":");
6428                 return;
6429         }
6430         if (QCC_PR_CheckKeyword(keyword_default, "default"))
6431         {
6432                 if (num_cases >= max_cases)
6433                 {
6434                         max_cases += 8;
6435                         pr_cases = realloc(pr_cases, sizeof(*pr_cases)*max_cases);
6436                         pr_casesdef = realloc(pr_casesdef, sizeof(*pr_casesdef)*max_cases);
6437                         pr_casesdef2 = realloc(pr_casesdef2, sizeof(*pr_casesdef2)*max_cases);
6438                 }
6439                 pr_cases[num_cases] = numstatements;
6440                 pr_casesdef[num_cases] = NULL;
6441                 pr_casesdef2[num_cases] = NULL;
6442                 num_cases++;
6443                 QCC_PR_Expect(":");
6444                 return;
6445         }
6446
6447         if (QCC_PR_CheckKeyword(keyword_thinktime, "thinktime"))
6448         {
6449                 QCC_def_t *nextthink;
6450                 QCC_def_t *time;
6451                 e = QCC_PR_Expression (TOP_PRIORITY, 0);
6452                 QCC_PR_Expect(":");
6453                 e2 = QCC_PR_Expression (TOP_PRIORITY, 0);
6454                 if (e->type->type != ev_entity || e2->type->type != ev_float)
6455                         QCC_PR_ParseError(ERR_THINKTIMETYPEMISMATCH, "thinktime type mismatch");
6456
6457                 if (QCC_OPCodeValid(&pr_opcodes[OP_THINKTIME]))
6458                         QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_THINKTIME], e, e2, NULL));
6459                 else
6460                 {
6461                         nextthink = QCC_PR_GetDef(NULL, "nextthink", NULL, false, 0, false);
6462                         if (!nextthink)
6463                                 QCC_PR_ParseError (ERR_UNKNOWNVALUE, "Unknown value \"%s\"", "nextthink");
6464                         time = QCC_PR_GetDef(type_float, "time", NULL, false, 0, false);
6465                         if (!time)
6466                                 QCC_PR_ParseError (ERR_UNKNOWNVALUE, "Unknown value \"%s\"", "time");
6467                         nextthink = QCC_PR_Statement(&pr_opcodes[OP_ADDRESS], e, nextthink, NULL);
6468                         time = QCC_PR_Statement(&pr_opcodes[OP_ADD_F], time, e2, NULL);
6469                         QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STOREP_F], time, nextthink, NULL));
6470                 }
6471                 QCC_PR_Expect(";");
6472                 return;
6473         }
6474         if (QCC_PR_CheckToken(";"))
6475         {
6476                 int osl = pr_source_line;
6477                 pr_source_line = statementstart;
6478                 if (!expandedemptymacro)
6479                         QCC_PR_ParseWarning(WARN_POINTLESSSTATEMENT, "Hanging ';'");
6480                 pr_source_line = osl;
6481                 return;
6482         }
6483
6484 //      qcc_functioncalled=0;
6485
6486         qcc_usefulstatement = false;
6487         e = QCC_PR_Expression (TOP_PRIORITY, 0);
6488         expandedemptymacro = false;
6489         QCC_PR_Expect (";");
6490
6491         if (e->type->type != ev_void && !qcc_usefulstatement)
6492         {
6493                 int osl = pr_source_line;
6494                 pr_source_line = statementstart;
6495                 QCC_PR_ParseWarning(WARN_POINTLESSSTATEMENT, "Effectless statement");
6496                 pr_source_line = osl;
6497         }
6498
6499         QCC_FreeTemp(e);
6500
6501 //      qcc_functioncalled=false;
6502 }
6503
6504
6505 /*
6506 ==============
6507 PR_ParseState
6508
6509 States are special functions made for convenience.  They automatically
6510 set frame, nextthink (implicitly), and think (allowing forward definitions).
6511
6512 // void() name = [framenum, nextthink] {code}
6513 // expands to:
6514 // function void name ()
6515 // {
6516 //              self.frame=framenum;
6517 //              self.nextthink = time + 0.1;
6518 //              self.think = nextthink
6519 //              <code>
6520 // };
6521 ==============
6522 */
6523 void QCC_PR_ParseState (void)
6524 {
6525         char    *name;
6526         QCC_def_t       *s1, *def, *sc = pr_scope;
6527         char f;
6528
6529         f = *pr_token;
6530         if (QCC_PR_CheckToken("++") || QCC_PR_CheckToken("--"))
6531         {
6532                 s1 = QCC_PR_ParseImmediate ();
6533                 QCC_PR_Expect("..");
6534                 def = QCC_PR_ParseImmediate ();
6535                 QCC_PR_Expect ("]");
6536
6537                 if (s1->type->type != ev_float || def->type->type != ev_float)
6538                         QCC_PR_ParseError(ERR_STATETYPEMISMATCH, "state type mismatch");
6539
6540
6541                 if (QCC_OPCodeValid(&pr_opcodes[OP_CSTATE]))
6542                         QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_CSTATE], s1, def, NULL));
6543                 else
6544                 {
6545                         QCC_def_t *t1, *t2;
6546                         QCC_def_t *framef, *frame;
6547                         QCC_def_t *self;
6548                         QCC_def_t *cycle_wrapped;
6549                         temp_t *ftemp;
6550
6551                         self = QCC_PR_GetDef(type_entity, "self", NULL, false, 0, false);
6552                         framef = QCC_PR_GetDef(NULL, "frame", NULL, false, 0, false);
6553                         cycle_wrapped = QCC_PR_GetDef(type_float, "cycle_wrapped", NULL, false, 0, false);
6554
6555                         frame = QCC_PR_Statement(&pr_opcodes[OP_LOAD_F], self, framef, NULL);
6556                         if (cycle_wrapped)
6557                                 QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], QCC_MakeFloatConst(0), cycle_wrapped, NULL));
6558                         QCC_UnFreeTemp(frame);
6559
6560                         //make sure the frame is within the bounds given.
6561                         ftemp = frame->temp;
6562                         frame->temp = NULL;
6563                         t1 = QCC_PR_Statement(&pr_opcodes[OP_LT_F], frame, s1, NULL);
6564                         t2 = QCC_PR_Statement(&pr_opcodes[OP_GT_F], frame, def, NULL);
6565                         t1 = QCC_PR_Statement(&pr_opcodes[OP_OR_F], t1, t2, NULL);
6566                         QCC_PR_SimpleStatement(OP_IFNOT_I, t1->ofs, 2, 0, false);
6567                         QCC_FreeTemp(t1);
6568                                 QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], s1, frame, NULL));
6569                           QCC_PR_SimpleStatement(OP_GOTO, t1->ofs, 13, 0, false);
6570
6571                         t1 = QCC_PR_Statement(&pr_opcodes[OP_GE_F], def, s1, NULL);
6572                         QCC_PR_SimpleStatement(OP_IFNOT_I, t1->ofs, 7, 0, false);
6573                         QCC_FreeTemp(t1);       //this block is the 'it's in a forwards direction'
6574                                 QCC_PR_SimpleStatement(OP_ADD_F, frame->ofs, QCC_MakeFloatConst(1)->ofs, frame->ofs, false);
6575                                 t1 = QCC_PR_Statement(&pr_opcodes[OP_GT_F], frame, def, NULL);
6576                                 QCC_PR_SimpleStatement(OP_IFNOT_I, t1->ofs,2, 0, false);
6577                                 QCC_FreeTemp(t1);
6578                                         QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], s1, frame, NULL));
6579                                         QCC_UnFreeTemp(frame);
6580                                         if (cycle_wrapped)
6581                                                 QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], QCC_MakeFloatConst(1), cycle_wrapped, NULL));
6582
6583                         QCC_PR_SimpleStatement(OP_GOTO, 6, 0, 0, false);
6584                                 //reverse animation.
6585                                 QCC_PR_SimpleStatement(OP_SUB_F, frame->ofs, QCC_MakeFloatConst(1)->ofs, frame->ofs, false);
6586                                 t1 = QCC_PR_Statement(&pr_opcodes[OP_LT_F], frame, s1, NULL);
6587                                 QCC_PR_SimpleStatement(OP_IFNOT_I, t1->ofs,2, 0, false);
6588                                 QCC_FreeTemp(t1);
6589                                         QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], def, frame, NULL));
6590                                         QCC_UnFreeTemp(frame);
6591                                         if (cycle_wrapped)
6592                                                 QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], QCC_MakeFloatConst(1), cycle_wrapped, NULL));
6593
6594                         //self.frame = frame happens with the normal state opcode.
6595                         QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STATE], frame, pr_scope, NULL));
6596
6597                         frame->temp = ftemp;
6598                         QCC_FreeTemp(frame);
6599                 }
6600                 return;
6601         }
6602
6603         if (pr_token_type != tt_immediate || pr_immediate_type != type_float)
6604                 QCC_PR_ParseError (ERR_STATETYPEMISMATCH, "state frame must be a number");
6605         s1 = QCC_PR_ParseImmediate ();
6606
6607         QCC_PR_CheckToken (",");
6608
6609         name = QCC_PR_ParseName ();
6610         pr_scope = NULL;
6611         def = QCC_PR_GetDef (type_function, name, NULL, true, 0, false);
6612         pr_scope = sc;
6613
6614         QCC_PR_Expect ("]");
6615
6616         QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STATE], s1, def, NULL));
6617 }
6618
6619 void QCC_PR_ParseAsm(void)
6620 {
6621         QCC_dstatement_t *patch1;
6622         int op, p;
6623         QCC_def_t *a, *b, *c;
6624
6625         if (QCC_PR_CheckKeyword(keyword_local, "local"))
6626         {
6627                 QCC_PR_ParseDefs (NULL);
6628                 locals_end = numpr_globals;
6629                 return;
6630         }
6631
6632         for (op = 0; op < OP_NUMOPS; op++)
6633         {
6634                 if (!STRCMP(pr_token, pr_opcodes[op].opname))
6635                 {
6636                         QCC_PR_Lex();
6637                         if (pr_opcodes[op].priority==-1 && pr_opcodes[op].associative!=ASSOC_LEFT)
6638                         {
6639                                 if (pr_opcodes[op].type_a==NULL)
6640                                 {
6641                                         patch1 = &statements[numstatements];
6642
6643                                         QCC_PR_Statement3(&pr_opcodes[op], NULL, NULL, NULL, true);
6644
6645                                         if (pr_token_type == tt_name)
6646                                         {
6647                                                 QCC_PR_GotoStatement(patch1, QCC_PR_ParseName());
6648                                         }
6649                                         else
6650                                         {
6651                                                 p = (int)pr_immediate._float;
6652                                                 patch1->a = (int)p;
6653                                         }
6654
6655                                         QCC_PR_Lex();
6656                                 }
6657                                 else if (pr_opcodes[op].type_b==NULL)
6658                                 {
6659                                         patch1 = &statements[numstatements];
6660
6661                                         a = QCC_PR_ParseValue(pr_classtype, false);
6662                                         QCC_PR_Statement3(&pr_opcodes[op], a, NULL, NULL, true);
6663
6664                                         if (pr_token_type == tt_name)
6665                                         {
6666                                                 QCC_PR_GotoStatement(patch1, QCC_PR_ParseName());
6667                                         }
6668                                         else
6669                                         {
6670                                                 p = (int)pr_immediate._float;
6671                                                 patch1->b = (int)p;
6672                                         }
6673
6674                                         QCC_PR_Lex();
6675                                 }
6676                                 else
6677                                 {
6678                                         patch1 = &statements[numstatements];
6679
6680                                         a = QCC_PR_ParseValue(pr_classtype, false);
6681                                         b = QCC_PR_ParseValue(pr_classtype, false);
6682                                         QCC_PR_Statement3(&pr_opcodes[op], a, b, NULL, true);
6683
6684                                         if (pr_token_type == tt_name)
6685                                         {
6686                                                 QCC_PR_GotoStatement(patch1, QCC_PR_ParseName());
6687                                         }
6688                                         else
6689                                         {
6690                                                 p = (int)pr_immediate._float;
6691                                                 patch1->c = (int)p;
6692                                         }
6693
6694                                         QCC_PR_Lex();
6695                                 }
6696                         }
6697                         else
6698                         {
6699                                 if (pr_opcodes[op].type_a != &type_void)
6700                                         a = QCC_PR_ParseValue(pr_classtype, false);
6701                                 else
6702                                         a=NULL;
6703                                 if (pr_opcodes[op].type_b != &type_void)
6704                                         b = QCC_PR_ParseValue(pr_classtype, false);
6705                                 else
6706                                         b=NULL;
6707                                 if (pr_opcodes[op].associative==ASSOC_LEFT && pr_opcodes[op].type_c != &type_void)
6708                                         c = QCC_PR_ParseValue(pr_classtype, false);
6709                                 else
6710                                         c=NULL;
6711
6712                                 QCC_PR_Statement3(&pr_opcodes[op], a, b, c, true);
6713                         }
6714
6715                         QCC_PR_Expect(";");
6716                         return;
6717                 }
6718         }
6719         QCC_PR_ParseError(ERR_BADOPCODE, "Bad op code name %s", pr_token);
6720 }
6721
6722 pbool QCC_FuncJumpsTo(int first, int last, int statement)
6723 {
6724         int st;
6725         for (st = first; st < last; st++)
6726         {
6727                 if (pr_opcodes[statements[st].op].type_a == NULL)
6728                 {
6729                         if (st + (signed)statements[st].a == statement)
6730                         {
6731                                 if (st != first)
6732                                 {
6733                                         if (statements[st-1].op == OP_RETURN)
6734                                                 continue;
6735                                         if (statements[st-1].op == OP_DONE)
6736                                                 continue;
6737                                         return true;
6738                                 }
6739                         }
6740                 }
6741                 if (pr_opcodes[statements[st].op].type_b == NULL)
6742                 {
6743                         if (st + (signed)statements[st].b == statement)
6744                         {
6745                                 if (st != first)
6746                                 {
6747                                         if (statements[st-1].op == OP_RETURN)
6748                                                 continue;
6749                                         if (statements[st-1].op == OP_DONE)
6750                                                 continue;
6751                                         return true;
6752                                 }
6753                         }
6754                 }
6755                 if (pr_opcodes[statements[st].op].type_c == NULL)
6756                 {
6757                         if (st + (signed)statements[st].c == statement)
6758                         {
6759                                 if (st != first)
6760                                 {
6761                                         if (statements[st-1].op == OP_RETURN)
6762                                                 continue;
6763                                         if (statements[st-1].op == OP_DONE)
6764                                                 continue;
6765                                         return true;
6766                                 }
6767                         }
6768                 }
6769         }
6770         return false;
6771 }
6772
6773 pbool QCC_FuncJumpsToRange(int first, int last, int firstr, int lastr)
6774 {
6775         int st;
6776         for (st = first; st < last; st++)
6777         {
6778                 if (pr_opcodes[statements[st].op].type_a == NULL)
6779                 {
6780                         if (st + (signed)statements[st].a >= firstr && st + (signed)statements[st].a <= lastr)
6781                         {
6782                                 if (st != first)
6783                                 {
6784                                         if (statements[st-1].op == OP_RETURN)
6785                                                 continue;
6786                                         if (statements[st-1].op == OP_DONE)
6787                                                 continue;
6788                                         return true;
6789                                 }
6790                         }
6791                 }
6792                 if (pr_opcodes[statements[st].op].type_b == NULL)
6793                 {
6794                         if (st + (signed)statements[st].b >= firstr && st + (signed)statements[st].b <= lastr)
6795                         {
6796                                 if (st != first)
6797                                 {
6798                                         if (statements[st-1].op == OP_RETURN)
6799                                                 continue;
6800                                         if (statements[st-1].op == OP_DONE)
6801                                                 continue;
6802                                         return true;
6803                                 }
6804                         }
6805                 }
6806                 if (pr_opcodes[statements[st].op].type_c == NULL)
6807                 {
6808                         if (st + (signed)statements[st].c >= firstr && st + (signed)statements[st].c <= lastr)
6809                         {
6810                                 if (st != first)
6811                                 {
6812                                         if (statements[st-1].op == OP_RETURN)
6813                                                 continue;
6814                                         if (statements[st-1].op == OP_DONE)
6815                                                 continue;
6816                                         return true;
6817                                 }
6818                         }
6819                 }
6820         }
6821         return false;
6822 }
6823
6824 #if 0
6825 void QCC_CompoundJumps(int first, int last)
6826 {
6827         //jumps to jumps are reordered so they become jumps to the final target.
6828         int statement;
6829         int st;
6830         for (st = first; st < last; st++)
6831         {
6832                 if (pr_opcodes[statements[st].op].type_a == NULL)
6833                 {
6834                         statement = st + (signed)statements[st].a;
6835                         if (statements[statement].op == OP_RETURN || statements[statement].op == OP_DONE)
6836                         {       //goto leads to return. Copy the command out to remove the goto.
6837                                 statements[st].op = statements[statement].op;
6838                                 statements[st].a = statements[statement].a;
6839                                 statements[st].b = statements[statement].b;
6840                                 statements[st].c = statements[statement].c;
6841                                 optres_compound_jumps++;
6842                         }
6843                         while (statements[statement].op == OP_GOTO)
6844                         {
6845                                 statements[st].a = statement+statements[statement].a - st;
6846                                 statement = st + (signed)statements[st].a;
6847                                 optres_compound_jumps++;
6848                         }
6849                 }
6850                 if (pr_opcodes[statements[st].op].type_b == NULL)
6851                 {
6852                         statement = st + (signed)statements[st].b;
6853                         while (statements[statement].op == OP_GOTO)
6854                         {
6855                                 statements[st].b = statement+statements[statement].a - st;
6856                                 statement = st + (signed)statements[st].b;
6857                                 optres_compound_jumps++;
6858                         }
6859                 }
6860                 if (pr_opcodes[statements[st].op].type_c == NULL)
6861                 {
6862                         statement = st + (signed)statements[st].c;
6863                         while (statements[statement].op == OP_GOTO)
6864                         {
6865                                 statements[st].c = statement+statements[statement].a - st;
6866                                 statement = st + (signed)statements[st].c;
6867                                 optres_compound_jumps++;
6868                         }
6869                 }
6870         }
6871 }
6872 #else
6873 void QCC_CompoundJumps(int first, int last)
6874 {
6875         //jumps to jumps are reordered so they become jumps to the final target.
6876         int statement;
6877         int st;
6878         int infloop;
6879         for (st = first; st < last; st++)
6880         {
6881                 if (pr_opcodes[statements[st].op].type_a == NULL)
6882                 {
6883                         statement = st + (signed)statements[st].a;
6884                         if (statements[statement].op == OP_RETURN || statements[statement].op == OP_DONE)
6885                         {       //goto leads to return. Copy the command out to remove the goto.
6886                                 statements[st].op = statements[statement].op;
6887                                 statements[st].a = statements[statement].a;
6888                                 statements[st].b = statements[statement].b;
6889                                 statements[st].c = statements[statement].c;
6890                                 optres_compound_jumps++;
6891                         }
6892                         infloop = 1000;
6893                         while (statements[statement].op == OP_GOTO)
6894                         {
6895                                 if (!infloop--)
6896                                 {
6897                                         QCC_PR_ParseWarning(0, "Infinate loop detected");
6898                                         break;
6899                                 }
6900                                 statements[st].a = (statement+statements[statement].a - st);
6901                                 statement = st + (signed)statements[st].a;
6902                                 optres_compound_jumps++;
6903                         }
6904                 }
6905                 if (pr_opcodes[statements[st].op].type_b == NULL)
6906                 {
6907                         statement = st + (signed)statements[st].b;
6908                         infloop = 1000;
6909                         while (statements[statement].op == OP_GOTO)
6910                         {
6911                                 if (!infloop--)
6912                                 {
6913                                         QCC_PR_ParseWarning(0, "Infinate loop detected");
6914                                         break;
6915                                 }
6916                                 statements[st].b = (statement+statements[statement].a - st);
6917                                 statement = st + (signed)statements[st].b;
6918                                 optres_compound_jumps++;
6919                         }
6920                 }
6921                 if (pr_opcodes[statements[st].op].type_c == NULL)
6922                 {
6923                         statement = st + (signed)statements[st].c;
6924                         infloop = 1000;
6925                         while (statements[statement].op == OP_GOTO)
6926                         {
6927                                 if (!infloop--)
6928                                 {
6929                                         QCC_PR_ParseWarning(0, "Infinate loop detected");
6930                                         break;
6931                                 }
6932                                 statements[st].c = (statement+statements[statement].a - st);
6933                                 statement = st + (signed)statements[st].c;
6934                                 optres_compound_jumps++;
6935                         }
6936                 }
6937         }
6938 }
6939 #endif
6940
6941 void QCC_CheckForDeadAndMissingReturns(int first, int last, int rettype)
6942 {
6943         int st, st2;
6944
6945         if (statements[last-1].op == OP_DONE)
6946                 last--; //don't want the done
6947
6948         if (rettype != ev_void)
6949                 if (statements[last-1].op != OP_RETURN)
6950                 {
6951                         if (statements[last-1].op != OP_GOTO || (signed)statements[last-1].a > 0)
6952                         {
6953                                 QCC_PR_ParseWarning(WARN_MISSINGRETURN, "%s: not all control paths return a value", pr_scope->name );
6954                                 return;
6955                         }
6956                 }
6957
6958         for (st = first; st < last; st++)
6959         {
6960                 if (statements[st].op == OP_RETURN || statements[st].op == OP_GOTO)
6961                 {
6962                         st++;
6963                         if (st == last)
6964                                 continue;       //erm... end of function doesn't count as unreachable.
6965
6966                         if (!opt_compound_jumps)
6967                         {       //we can ignore single statements like these without compound jumps (compound jumps correctly removes all).
6968                                 if (statements[st].op == OP_GOTO)       //inefficient compiler, we can ignore this.
6969                                         continue;
6970                                 if (statements[st].op == OP_DONE)       //inefficient compiler, we can ignore this.
6971                                         continue;
6972                                 if (statements[st].op == OP_RETURN)     //inefficient compiler, we can ignore this.
6973                                         continue;
6974                         }
6975
6976                         //make sure something goes to just after this return.
6977                         for (st2 = first; st2 < last; st2++)
6978                         {
6979                                 if (pr_opcodes[statements[st2].op].type_a == NULL)
6980                                 {
6981                                         if (st2 + (signed)statements[st2].a == st)
6982                                                 break;
6983                                 }
6984                                 if (pr_opcodes[statements[st2].op].type_b == NULL)
6985                                 {
6986                                         if (st2 + (signed)statements[st2].b == st)
6987                                                 break;
6988                                 }
6989                                 if (pr_opcodes[statements[st2].op].type_c == NULL)
6990                                 {
6991                                         if (st2 + (signed)statements[st2].c == st)
6992                                                 break;
6993                                 }
6994                         }
6995                         if (st2 == last)
6996                         {
6997                                 QCC_PR_ParseWarning(WARN_UNREACHABLECODE, "%s: contains unreachable code", pr_scope->name );
6998                         }
6999                         continue;
7000                 }
7001                 if (rettype != ev_void)
7002                 {
7003                         if (pr_opcodes[statements[st].op].type_a == NULL)
7004                         {
7005                                 if (st + (signed)statements[st].a == last)
7006                                 {
7007                                         QCC_PR_ParseWarning(WARN_MISSINGRETURN, "%s: not all control paths return a value", pr_scope->name );
7008                                         return;
7009                                 }
7010                         }
7011                         if (pr_opcodes[statements[st].op].type_b == NULL)
7012                         {
7013                                 if (st + (signed)statements[st].b == last)
7014                                 {
7015                                         QCC_PR_ParseWarning(WARN_MISSINGRETURN, "%s: not all control paths return a value", pr_scope->name );
7016                                         return;
7017                                 }
7018                         }
7019                         if (pr_opcodes[statements[st].op].type_c == NULL)
7020                         {
7021                                 if (st + (signed)statements[st].c == last)
7022                                 {
7023                                         QCC_PR_ParseWarning(WARN_MISSINGRETURN, "%s: not all control paths return a value", pr_scope->name );
7024                                         return;
7025                                 }
7026                         }
7027                 }
7028         }
7029 }
7030
7031 pbool QCC_StatementIsAJump(int stnum, int notifdest)    //only the unconditionals.
7032 {
7033         if (statements[stnum].op == OP_RETURN)
7034                 return true;
7035         if (statements[stnum].op == OP_DONE)
7036                 return true;
7037         if (statements[stnum].op == OP_GOTO)
7038                 if ((int)statements[stnum].a != notifdest)
7039                         return true;
7040         return false;
7041 }
7042
7043 int QCC_AStatementJumpsTo(int targ, int first, int last)
7044 {
7045         int st;
7046         for (st = first; st < last; st++)
7047         {
7048                 if (pr_opcodes[statements[st].op].type_a == NULL)
7049                 {
7050                         if (st + (signed)statements[st].a == targ && statements[st].a)
7051                         {
7052                                 return true;
7053                         }
7054                 }
7055                 if (pr_opcodes[statements[st].op].type_b == NULL)
7056                 {
7057                         if (st + (signed)statements[st].b == targ)
7058                         {
7059                                 return true;
7060                         }
7061                 }
7062                 if (pr_opcodes[statements[st].op].type_c == NULL)
7063                 {
7064                         if (st + (signed)statements[st].c == targ)
7065                         {
7066                                 return true;
7067                         }
7068                 }
7069         }
7070
7071         for (st = 0; st < num_labels; st++)     //assume it's used.
7072         {
7073                 if (pr_labels[st].statementno == targ)
7074                         return true;
7075         }
7076
7077
7078         return false;
7079 }
7080 /*
7081 //goes through statements, if it sees a matching statement earlier, it'll strim out the current.
7082 void QCC_CommonSubExpressionRemoval(int first, int last)
7083 {
7084         int cur;        //the current
7085         int prev;       //the earlier statement
7086         for (cur = last-1; cur >= first; cur--)
7087         {
7088                 if (pr_opcodes[statements[cur].op].priority == -1)
7089                         continue;
7090                 for (prev = cur-1; prev >= first; prev--)
7091                 {
7092                         if (statements[prev].op >= OP_CALL0 && statements[prev].op <= OP_CALL8)
7093                         {
7094                                 optres_test1++;
7095                                 break;
7096                         }
7097                         if (statements[prev].op >= OP_CALL1H && statements[prev].op <= OP_CALL8H)
7098                         {
7099                                 optres_test1++;
7100                                 break;
7101                         }
7102                         if (pr_opcodes[statements[prev].op].right_associative)
7103                         {       //make sure no changes to var_a occur.
7104                                 if (statements[prev].b == statements[cur].a)
7105                                 {
7106                                         optres_test2++;
7107                                         break;
7108                                 }
7109                                 if (statements[prev].b == statements[cur].b && !pr_opcodes[statements[cur].op].right_associative)
7110                                 {
7111                                         optres_test2++;
7112                                         break;
7113                                 }
7114                         }
7115                         else
7116                         {
7117                                 if (statements[prev].c == statements[cur].a)
7118                                 {
7119                                         optres_test2++;
7120                                         break;
7121                                 }
7122                                 if (statements[prev].c == statements[cur].b && !pr_opcodes[statements[cur].op].right_associative)
7123                                 {
7124                                         optres_test2++;
7125                                         break;
7126                                 }
7127                         }
7128
7129                         if (statements[prev].op == statements[cur].op)
7130                                 if (statements[prev].a == statements[cur].a)
7131                                         if (statements[prev].b == statements[cur].b)
7132                                                 if (statements[prev].c == statements[cur].c)
7133                                                 {
7134                                                         if (!QCC_FuncJumpsToRange(first, last, prev, cur))
7135                                                         {
7136                                                                 statements[cur].op = OP_STORE_F;
7137                                                                 statements[cur].a = 28;
7138                                                                 statements[cur].b = 28;
7139                                                                 optres_comexprremoval++;
7140                                                         }
7141                                                         else
7142                                                                 optres_test1++;
7143                                                         break;
7144                                                 }
7145                 }
7146         }
7147 }
7148 */
7149
7150 void QCC_RemapOffsets(unsigned int firststatement, unsigned int laststatement, unsigned int min, unsigned int max, unsigned int newmin)
7151 {
7152         QCC_dstatement_t *st;
7153         unsigned int i;
7154
7155         for (i = firststatement, st = &statements[i]; i < laststatement; i++, st++)
7156         {
7157                 if (pr_opcodes[st->op].type_a && st->a >= min && st->a < max)
7158                         st->a = st->a - min + newmin;
7159                 if (pr_opcodes[st->op].type_b && st->b >= min && st->b < max)
7160                         st->b = st->b - min + newmin;
7161                 if (pr_opcodes[st->op].type_c && st->c >= min && st->c < max)
7162                         st->c = st->c - min + newmin;
7163         }
7164 }
7165
7166 void QCC_Marshal_Locals(int first, int laststatement)
7167 {
7168         QCC_def_t *local;
7169         unsigned int newofs;
7170         int size;
7171
7172 //      if (!opt_overlaptemps)  //clear these after each function. we arn't overlapping them so why do we need to keep track of them?
7173 //      {
7174 //              temp_t *t;
7175 //              for (t = functemps; t; t = t->next)
7176 //                      QCC_FreeOffset(t->ofs, t->size);
7177 //              functemps = NULL;
7178 //      }
7179
7180         if (!pr.localvars)      //nothing to marshal
7181         {
7182                 locals_start = numpr_globals;
7183                 locals_end = numpr_globals;
7184                 return;
7185         }
7186
7187         if (!opt_locals_marshalling)
7188         {
7189                 pr.localvars = NULL;
7190                 return;
7191         }
7192
7193         //initial backwards bounds.
7194         locals_start = MAX_REGS;
7195         locals_end = 0;
7196
7197         newofs = MAX_REGS;      //this is a handy place to put it. :)
7198
7199         //the params need to be in the order that they were allocated
7200         //so we allocate in a backwards order.
7201         for (local = pr.localvars; local; local = local->nextlocal)
7202         {
7203                 if (local->constant)
7204                         continue;
7205
7206                 size = local->type->size*(local->arraysize?local->arraysize:1);
7207                 if (local->arraysize)
7208                         size++;
7209
7210                 newofs += size;
7211         }
7212
7213         locals_start = MAX_REGS;
7214         locals_end = newofs;
7215
7216
7217         optres_locals_marshalling+=newofs-MAX_REGS;
7218
7219         for (local = pr.localvars; local; local = local->nextlocal)
7220         {
7221                 if (local->constant)
7222                         continue;
7223
7224                 if (((int*)qcc_pr_globals)[local->ofs])
7225                         QCC_PR_ParseError(ERR_INTERNAL, "Marshall of a set value");
7226
7227                 size = local->type->size*(local->arraysize?local->arraysize:1);
7228                 if (local->arraysize)
7229                         size++;
7230
7231                 newofs -= size;
7232
7233                 QCC_RemapOffsets(first, laststatement, local->ofs, local->ofs+size, newofs);
7234                 QCC_FreeOffset(local->ofs, size);
7235
7236                 local->ofs = newofs;
7237         }
7238
7239
7240         pr.localvars = NULL;
7241 }
7242
7243 #ifdef WRITEASM
7244 void QCC_WriteAsmFunction(QCC_def_t     *sc, unsigned int firststatement, gofs_t firstparm)
7245 {
7246         unsigned int                    i;
7247         unsigned int p;
7248         gofs_t o;
7249         QCC_type_t *type;
7250         QCC_def_t *param;
7251
7252         if (!asmfile)
7253                 return;
7254
7255         type = sc->type;
7256         fprintf(asmfile, "%s(", TypeName(type->aux_type));
7257         p = type->num_parms;
7258         for (o = firstparm, i = 0, type = type->param; i < p; i++, type = type->next)
7259         {
7260                 if (i)
7261                         fprintf(asmfile, ", ");
7262
7263                 for (param = pr.localvars; param; param = param->nextlocal)
7264                 {
7265                         if (param->ofs == o)
7266                                 break;
7267                 }
7268                 if (param)
7269                         fprintf(asmfile, "%s %s", TypeName(type), param->name);
7270                 else
7271                         fprintf(asmfile, "%s", TypeName(type));
7272
7273                 o += type->size;
7274         }
7275
7276         fprintf(asmfile, ") %s = asm\n{\n", sc->name);
7277
7278         QCC_fprintfLocals(asmfile, firstparm, o);
7279
7280         for (i = firststatement; i < (unsigned int)numstatements; i++)
7281         {
7282                 fprintf(asmfile, "\t%s", pr_opcodes[statements[i].op].opname);
7283                 if (pr_opcodes[statements[i].op].type_a != &type_void)
7284                 {
7285                         if (strlen(pr_opcodes[statements[i].op].opname)<6)
7286                                 fprintf(asmfile, "\t");
7287                         if (pr_opcodes[statements[i].op].type_a)
7288                                 fprintf(asmfile, "\t%s", QCC_VarAtOffset(statements[i].a, (*pr_opcodes[statements[i].op].type_a)->size));
7289                         else
7290                                 fprintf(asmfile, "\t%i", statements[i].a);
7291                         if (pr_opcodes[statements[i].op].type_b != &type_void)
7292                         {
7293                                 if (pr_opcodes[statements[i].op].type_b)
7294                                         fprintf(asmfile, ",\t%s", QCC_VarAtOffset(statements[i].b, (*pr_opcodes[statements[i].op].type_b)->size));
7295                                 else
7296                                         fprintf(asmfile, ",\t%i", statements[i].b);
7297                                 if (pr_opcodes[statements[i].op].type_c != &type_void && pr_opcodes[statements[i].op].associative==ASSOC_LEFT)
7298                                 {
7299                                         if (pr_opcodes[statements[i].op].type_c)
7300                                                 fprintf(asmfile, ",\t%s", QCC_VarAtOffset(statements[i].c, (*pr_opcodes[statements[i].op].type_c)->size));
7301                                         else
7302                                                 fprintf(asmfile, ",\t%i", statements[i].c);
7303                                 }
7304                         }
7305                         else
7306                         {
7307                                 if (pr_opcodes[statements[i].op].type_c != &type_void)
7308                                 {
7309                                         if (pr_opcodes[statements[i].op].type_c)
7310                                                 fprintf(asmfile, ",\t%s", QCC_VarAtOffset(statements[i].c, (*pr_opcodes[statements[i].op].type_c)->size));
7311                                         else
7312                                                 fprintf(asmfile, ",\t%i", statements[i].c);
7313                                 }
7314                         }
7315                 }
7316                 fprintf(asmfile, "; /*%i*/\n", statement_linenums[i]);
7317         }
7318
7319         fprintf(asmfile, "}\n\n");
7320 }
7321 #endif
7322
7323 /*
7324 ============
7325 PR_ParseImmediateStatements
7326
7327 Parse a function body
7328 ============
7329 */
7330 QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_type_t *type)
7331 {
7332         int                     i;
7333         QCC_function_t  *f;
7334         QCC_def_t               *defs[MAX_PARMS+MAX_EXTRA_PARMS], *e2;
7335
7336         QCC_type_t *parm;
7337         pbool needsdone=false;
7338         freeoffset_t *oldfofs;
7339
7340         conditional = 0;
7341
7342         expandedemptymacro = false;
7343
7344
7345         f = (void *)qccHunkAlloc (sizeof(QCC_function_t));
7346
7347 //
7348 // check for builtin function definition #1, #2, etc
7349 //
7350 // hexenC has void name() : 2;
7351         if (QCC_PR_CheckToken ("#") || QCC_PR_CheckToken (":"))
7352         {
7353                 int binum = 0;
7354                 if (pr_token_type == tt_immediate
7355                 && pr_immediate_type == type_float
7356                 && pr_immediate._float == (int)pr_immediate._float)
7357                         binum = (int)pr_immediate._float;
7358                 else if (pr_token_type == tt_immediate && pr_immediate_type == type_integer)
7359                         binum = pr_immediate._int;
7360                 else
7361                         QCC_PR_ParseError (ERR_BADBUILTINIMMEDIATE, "Bad builtin immediate");
7362                 f->builtin = binum;
7363                 QCC_PR_Lex ();
7364
7365                 locals_start = locals_end = OFS_PARM0; //hmm...
7366                 return f;
7367         }
7368         if (QCC_PR_CheckKeyword(keyword_external, "external"))
7369         {       //reacc style builtin
7370                 if (pr_token_type != tt_immediate
7371                 || pr_immediate_type != type_float
7372                 || pr_immediate._float != (int)pr_immediate._float)
7373                         QCC_PR_ParseError (ERR_BADBUILTINIMMEDIATE, "Bad builtin immediate");
7374                 f->builtin = (int)-pr_immediate._float;
7375                 QCC_PR_Lex ();
7376                 QCC_PR_Expect(";");
7377
7378                 locals_start = locals_end = OFS_PARM0; //hmm...
7379                 return f;
7380         }
7381
7382         if (type->num_parms < 0)
7383                 QCC_PR_ParseError (ERR_FUNCTIONWITHVARGS, "QC function with variable arguments and function body");
7384
7385         f->builtin = 0;
7386 //
7387 // define the parms
7388 //
7389
7390         locals_start = locals_end = numpr_globals;
7391
7392         oldfofs = freeofs;
7393         freeofs = NULL;
7394
7395         parm = type->param;
7396         for (i=0 ; i<type->num_parms ; i++)
7397         {
7398                 if (!*pr_parm_names[i])
7399                         QCC_PR_ParseError(ERR_PARAMWITHNONAME, "Parameter is not named");
7400                 defs[i] = QCC_PR_GetDef (parm, pr_parm_names[i], pr_scope, true, 0, false);
7401
7402                 defs[i]->references++;
7403                 if (i < MAX_PARMS)
7404                 {
7405                         f->parm_ofs[i] = defs[i]->ofs;
7406                         if (i > 0 && f->parm_ofs[i] < f->parm_ofs[i-1])
7407                                 QCC_Error (ERR_BADPARAMORDER, "bad parm order");
7408                         if (i > 0 && f->parm_ofs[i] != f->parm_ofs[i-1]+defs[i-1]->type->size)
7409                                 QCC_Error (ERR_BADPARAMORDER, "parms not packed");
7410                 }
7411                 parm = parm->next;
7412         }
7413
7414         if (type->num_parms)
7415                 locals_start = locals_end = defs[0]->ofs;
7416
7417         freeofs = oldfofs;
7418
7419         f->code = numstatements;
7420
7421         if (type->num_parms > MAX_PARMS)
7422         {
7423                 for (i = MAX_PARMS; i < type->num_parms; i++)
7424                 {
7425                         if (!extra_parms[i - MAX_PARMS])
7426                         {
7427                                 e2 = (QCC_def_t *) qccHunkAlloc (sizeof(QCC_def_t));
7428                                 e2->name = "extra parm";
7429                                 e2->ofs = QCC_GetFreeOffsetSpace(3);
7430                                 extra_parms[i - MAX_PARMS] = e2;
7431                         }
7432                         extra_parms[i - MAX_PARMS]->type = defs[i]->type;
7433                         if (defs[i]->type->type != ev_vector)
7434                                 QCC_PR_Statement (&pr_opcodes[OP_STORE_F], extra_parms[i - MAX_PARMS], defs[i], NULL);
7435                         else
7436                                 QCC_PR_Statement (&pr_opcodes[OP_STORE_V], extra_parms[i - MAX_PARMS], defs[i], NULL);
7437                 }
7438         }
7439
7440         QCC_RemapLockedTemps(-1, -1);
7441
7442         /*if (pr_classtype)
7443         {
7444                 QCC_def_t *e, *e2;
7445                 e = QCC_PR_GetDef(pr_classtype, "__oself", pr_scope, true, 0);
7446                 e2 = QCC_PR_GetDef(type_entity, "self", NULL, true, 0);
7447                 QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], QCC_PR_DummyDef(pr_classtype, "self", pr_scope, 0, e2->ofs, false), e, NULL));
7448         }*/
7449
7450 //
7451 // check for a state opcode
7452 //
7453         if (QCC_PR_CheckToken ("["))
7454                 QCC_PR_ParseState ();
7455
7456         if (QCC_PR_CheckKeyword (keyword_asm, "asm"))
7457         {
7458                 QCC_PR_Expect ("{");
7459                 while (!QCC_PR_CheckToken("}"))
7460                         QCC_PR_ParseAsm ();
7461         }
7462         else
7463         {
7464                 if (QCC_PR_CheckKeyword (keyword_var, "var"))   //reacc support
7465                 {       //parse lots of locals
7466                         char *name;
7467                         do {
7468                                 name = QCC_PR_ParseName();
7469                                 QCC_PR_Expect(":");
7470                                 e2 = QCC_PR_GetDef(QCC_PR_ParseType(false, false), name, pr_scope, true, 0, false);
7471                                 QCC_PR_Expect(";");
7472                         } while(!QCC_PR_CheckToken("{"));
7473                 }
7474                 else
7475                         QCC_PR_Expect ("{");
7476 //
7477 // parse regular statements
7478 //
7479                 while (!QCC_PR_CheckToken("}"))
7480                 {
7481                         QCC_PR_ParseStatement ();
7482                         QCC_FreeTemps();
7483                 }
7484         }
7485         QCC_FreeTemps();
7486
7487         // this is cheap
7488 //      if (type->aux_type->type)
7489 //              if (statements[numstatements - 1].op != OP_RETURN)
7490 //                      QCC_PR_ParseWarning(WARN_MISSINGRETURN, "%s: not all control paths return a value", pr_scope->name );
7491
7492         if (f->code == numstatements)
7493                 needsdone = true;
7494         else if (statements[numstatements - 1].op != OP_RETURN && statements[numstatements - 1].op != OP_DONE)
7495                 needsdone = true;
7496
7497         if (num_gotos)
7498         {
7499                 int j;
7500                 for (i = 0; i < num_gotos; i++)
7501                 {
7502                         for (j = 0; j < num_labels; j++)
7503                         {
7504                                 if (!strcmp(pr_gotos[i].name, pr_labels[j].name))
7505                                 {
7506                                         if (!pr_opcodes[statements[pr_gotos[i].statementno].op].type_a)
7507                                                 statements[pr_gotos[i].statementno].a += pr_labels[j].statementno - pr_gotos[i].statementno;
7508                                         else if (!pr_opcodes[statements[pr_gotos[i].statementno].op].type_b)
7509                                                 statements[pr_gotos[i].statementno].b += pr_labels[j].statementno - pr_gotos[i].statementno;
7510                                         else
7511                                                 statements[pr_gotos[i].statementno].c += pr_labels[j].statementno - pr_gotos[i].statementno;
7512                                         break;
7513                                 }
7514                         }
7515                         if (j == num_labels)
7516                         {
7517                                 num_gotos = 0;
7518                                 QCC_PR_ParseError(ERR_NOLABEL, "Goto statement with no matching label \"%s\"", pr_gotos[i].name);
7519                         }
7520                 }
7521                 num_gotos = 0;
7522         }
7523
7524         if (opt_return_only && !needsdone)
7525                 needsdone = QCC_FuncJumpsTo(f->code, numstatements, numstatements);
7526
7527         // emit an end of statements opcode
7528         if (!opt_return_only || needsdone)
7529         {
7530                 /*if (pr_classtype)
7531                 {
7532                         QCC_def_t *e, *e2;
7533                         e = QCC_PR_GetDef(NULL, "__oself", pr_scope, false, 0);
7534                         e2 = QCC_PR_GetDef(NULL, "self", NULL, false, 0);
7535                         QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], e, QCC_PR_DummyDef(pr_classtype, "self", pr_scope, 0, e2->ofs, false), NULL));
7536                 }*/
7537
7538                 QCC_PR_Statement (pr_opcodes, 0,0, NULL);
7539         }
7540         else
7541                 optres_return_only++;
7542
7543         QCC_CheckForDeadAndMissingReturns(f->code, numstatements, type->aux_type->type);
7544
7545         if (opt_compound_jumps)
7546                 QCC_CompoundJumps(f->code, numstatements);
7547 //      if (opt_comexprremoval)
7548 //              QCC_CommonSubExpressionRemoval(f->code, numstatements);
7549
7550
7551         QCC_RemapLockedTemps(f->code, numstatements);
7552         locals_end = numpr_globals;
7553
7554         QCC_WriteAsmFunction(pr_scope, f->code, locals_start);
7555
7556         QCC_Marshal_Locals(f->code, numstatements);
7557
7558         if (num_labels)
7559                 num_labels = 0;
7560
7561
7562         if (num_continues)
7563         {
7564                 num_continues=0;
7565                 QCC_PR_ParseError(ERR_ILLEGALCONTINUES, "%s: function contains illegal continues", pr_scope->name);
7566         }
7567         if (num_breaks)
7568         {
7569                 num_breaks=0;
7570                 QCC_PR_ParseError(ERR_ILLEGALBREAKS, "%s: function contains illegal breaks", pr_scope->name);
7571         }
7572         if (num_cases)
7573         {
7574                 num_cases = 0;
7575                 QCC_PR_ParseError(ERR_ILLEGALCASES, "%s: function contains illegal cases", pr_scope->name);
7576         }
7577
7578         return f;
7579 }
7580
7581 void QCC_PR_ArrayRecurseDivideRegular(QCC_def_t *array, QCC_def_t *index, int min, int max)
7582 {
7583         QCC_dstatement_t *st;
7584         QCC_def_t *eq;
7585         if (min == max || min+1 == max)
7586         {
7587                 eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatConst(min+0.5f), NULL);
7588                 QCC_UnFreeTemp(index);
7589                 QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
7590                 st->b = 2;
7591                 QCC_PR_Statement(pr_opcodes+OP_RETURN, 0, 0, &st);
7592                 st->a = array->ofs + min*array->type->size;
7593         }
7594         else
7595         {
7596                 int mid = min + (max-min)/2;
7597
7598                 if (max-min>4)
7599                 {
7600                         eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatConst(mid+0.5f), NULL);
7601                         QCC_UnFreeTemp(index);
7602                         QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
7603                 }
7604                 else
7605                         st = NULL;
7606                 QCC_PR_ArrayRecurseDivideRegular(array, index, min, mid);
7607                 if (st)
7608                         st->b = numstatements - (st-statements);
7609                 QCC_PR_ArrayRecurseDivideRegular(array, index, mid, max);
7610         }
7611 }
7612
7613 //the idea here is that we return a vector, the caller then figures out the extra 3rd.
7614 //This is useful when we have a load of indexes.
7615 void QCC_PR_ArrayRecurseDivideUsingVectors(QCC_def_t *array, QCC_def_t *index, int min, int max)
7616 {
7617         QCC_dstatement_t *st;
7618         QCC_def_t *eq;
7619         if (min == max || min+1 == max)
7620         {
7621                 eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatConst(min+0.5f), NULL);
7622                 QCC_UnFreeTemp(index);
7623                 QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
7624                 st->b = 2;
7625                 QCC_PR_Statement(pr_opcodes+OP_RETURN, 0, 0, &st);
7626                 st->a = array->ofs + min*3;
7627         }
7628         else
7629         {
7630                 int mid = min + (max-min)/2;
7631
7632                 if (max-min>4)
7633                 {
7634                         eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatConst(mid+0.5f), NULL);
7635                         QCC_UnFreeTemp(index);
7636                         QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
7637                 }
7638                 else
7639                         st = NULL;
7640                 QCC_PR_ArrayRecurseDivideUsingVectors(array, index, min, mid);
7641                 if (st)
7642                         st->b = numstatements - (st-statements);
7643                 QCC_PR_ArrayRecurseDivideUsingVectors(array, index, mid, max);
7644         }
7645 }
7646
7647 //returns a vector overlapping the result needed.
7648 QCC_def_t *QCC_PR_EmitArrayGetVector(QCC_def_t *array)
7649 {
7650         QCC_dfunction_t *df;
7651         QCC_def_t *temp, *index, *func;
7652
7653         func = QCC_PR_GetDef(type_function, qcva("ArrayGetVec*%s", array->name), NULL, true, 0, false);
7654
7655         pr_scope = func;
7656
7657         if (numfunctions >= MAX_FUNCTIONS)
7658                 QCC_Error(ERR_INTERNAL, "Too many function defs");
7659
7660         df = &functions[numfunctions];
7661         numfunctions++;
7662
7663         df->s_file = 0;
7664         df->s_name = QCC_CopyString(func->name);
7665         df->first_statement = numstatements;
7666         df->parm_size[0] = 1;
7667         df->numparms = 1;
7668         df->parm_start = numpr_globals;
7669         index = QCC_PR_GetDef(type_float, "index___", func, true, 0, false);
7670         index->references++;
7671         temp = QCC_PR_GetDef(type_float, "div3___", func, true, 0, false);
7672         locals_end = numpr_globals;
7673         df->locals = locals_end - df->parm_start;
7674         QCC_PR_Statement3(pr_opcodes+OP_DIV_F, index, QCC_MakeFloatConst(3), temp, false);
7675         QCC_PR_Statement3(pr_opcodes+OP_BITAND_F, temp, temp, temp, false);//round down to int
7676
7677         QCC_PR_ArrayRecurseDivideUsingVectors(array, temp, 0, (array->arraysize+2)/3);  //round up
7678
7679         QCC_PR_Statement(pr_opcodes+OP_RETURN, QCC_MakeFloatConst(0), 0, NULL); //err... we didn't find it, give up.
7680         QCC_PR_Statement(pr_opcodes+OP_DONE, 0, 0, NULL);       //err... we didn't find it, give up.
7681
7682         G_FUNCTION(func->ofs) = df - functions;
7683         func->initialized = 1;
7684         return func;
7685 }
7686
7687 void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
7688 {
7689         QCC_def_t *vectortrick;
7690         QCC_dfunction_t *df;
7691         QCC_def_t *def, *index;
7692
7693         QCC_dstatement_t *st;
7694         QCC_def_t *eq;
7695
7696         QCC_def_t *fasttrackpossible;
7697
7698         if (flag_fasttrackarrays)
7699                 fasttrackpossible = QCC_PR_GetDef(type_float, "__ext__fasttrackarrays", NULL, true, 0, false);
7700         else
7701                 fasttrackpossible = NULL;
7702
7703         def = QCC_PR_GetDef(NULL, arrayname, NULL, false, 0, false);
7704
7705         if (def->arraysize >= 15 && def->type->size == 1)
7706         {
7707                 vectortrick = QCC_PR_EmitArrayGetVector(def);
7708         }
7709         else
7710                 vectortrick = NULL;
7711
7712         pr_scope = scope;
7713
7714         if (numfunctions >= MAX_FUNCTIONS)
7715                 QCC_Error(ERR_INTERNAL, "Too many function defs");
7716
7717         df = &functions[numfunctions];
7718         numfunctions++;
7719
7720         df->s_file = 0;
7721         df->s_name = QCC_CopyString(scope->name);
7722         df->first_statement = numstatements;
7723         df->parm_size[0] = 1;
7724         df->numparms = 1;
7725         df->parm_start = numpr_globals;
7726         index = QCC_PR_GetDef(type_float, "indexg___", def, true, 0, false);
7727
7728         G_FUNCTION(scope->ofs) = df - functions;
7729
7730         if (fasttrackpossible)
7731         {
7732                 QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, fasttrackpossible, NULL, &st);
7733                 //fetch_gbl takes: (float size, variant array[]), float index, variant pos
7734                 //note that the array size is coded into the globals, one index before the array.
7735
7736                 if (def->type->size >= 3)
7737                         QCC_PR_Statement3(&pr_opcodes[OP_FETCH_GBL_V], def, index, &def_ret, true);
7738                 else
7739                         QCC_PR_Statement3(&pr_opcodes[OP_FETCH_GBL_F], def, index, &def_ret, true);
7740
7741                 QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_RETURN], &def_ret, NULL, NULL));
7742
7743                 //finish the jump
7744                 st->b = &statements[numstatements] - st;
7745         }
7746
7747         if (vectortrick)
7748         {
7749                 QCC_def_t *div3, *intdiv3, *ret;
7750
7751                 //okay, we've got a function to retrieve the var as part of a vector.
7752                 //we need to work out which part, x/y/z that it's stored in.
7753                 //0,1,2 = i - ((int)i/3 *) 3;
7754
7755                 div3 = QCC_PR_GetDef(type_float, "div3___", def, true, 0, false);
7756                 intdiv3 = QCC_PR_GetDef(type_float, "intdiv3___", def, true, 0, false);
7757
7758                 eq = QCC_PR_Statement(pr_opcodes+OP_GE_F, index, QCC_MakeFloatConst((float)def->arraysize), NULL);      //escape clause - should call some sort of error function instead.. that'd rule!
7759                 QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
7760                 st->b = 2;
7761                 QCC_PR_Statement(pr_opcodes+OP_RETURN, QCC_MakeFloatConst(0), 0, &st);
7762
7763                 div3->references++;
7764                 QCC_PR_Statement3(pr_opcodes+OP_BITAND_F, index, index, index, false);
7765                 QCC_PR_Statement3(pr_opcodes+OP_DIV_F, index, QCC_MakeFloatConst(3), div3, false);
7766                 QCC_PR_Statement3(pr_opcodes+OP_BITAND_F, div3, div3, intdiv3, false);
7767
7768                 QCC_PR_Statement3(pr_opcodes+OP_STORE_F, index, &def_parms[0], NULL, false);
7769                 QCC_PR_Statement3(pr_opcodes+OP_CALL1, vectortrick, NULL, NULL, false);
7770                 vectortrick->references++;
7771                 ret = QCC_PR_GetDef(type_vector, "vec__", pr_scope, true, 0, false);
7772                 ret->references+=4;
7773                 QCC_PR_Statement3(pr_opcodes+OP_STORE_V, &def_ret, ret, NULL, false);
7774                 QCC_FreeTemp(&def_ret);
7775
7776                 div3 = QCC_PR_Statement(pr_opcodes+OP_MUL_F, intdiv3, QCC_MakeFloatConst(3), NULL);
7777                 QCC_PR_Statement3(pr_opcodes+OP_SUB_F, index, div3, index, false);
7778                 QCC_FreeTemp(div3);
7779
7780                 eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatConst(0+0.5f), NULL);
7781                 QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
7782                 st->b = 2;
7783                 QCC_PR_Statement(pr_opcodes+OP_RETURN, 0, 0, &st);
7784                 st->a = ret->ofs + 0;
7785
7786                 eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatConst(1+0.5f), NULL);
7787                 QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
7788                 st->b = 2;
7789                 QCC_PR_Statement(pr_opcodes+OP_RETURN, 0, 0, &st);
7790                 st->a = ret->ofs + 1;
7791
7792                 eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatConst(2+0.5), NULL);
7793                 QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
7794                 st->b = 2;
7795                 QCC_PR_Statement(pr_opcodes+OP_RETURN, 0, 0, &st);
7796                 st->a = ret->ofs + 2;
7797                 QCC_FreeTemp(ret);
7798                 QCC_FreeTemp(index);
7799         }
7800         else
7801         {
7802                 QCC_PR_Statement3(pr_opcodes+OP_BITAND_F, index, index, index, false);
7803                 QCC_PR_ArrayRecurseDivideRegular(def, index, 0, def->arraysize);
7804         }
7805
7806         QCC_PR_Statement(pr_opcodes+OP_RETURN, QCC_MakeFloatConst(0), 0, NULL);
7807
7808         QCC_PR_Statement(pr_opcodes+OP_DONE, 0, 0, NULL);
7809
7810         locals_end = numpr_globals;
7811         df->locals = locals_end - df->parm_start;
7812
7813
7814         QCC_WriteAsmFunction(pr_scope, df->first_statement, df->parm_start);
7815
7816         QCC_FreeTemps();
7817 }
7818
7819 void QCC_PR_ArraySetRecurseDivide(QCC_def_t *array, QCC_def_t *index, QCC_def_t *value, int min, int max)
7820 {
7821         QCC_dstatement_t *st;
7822         QCC_def_t *eq;
7823         if (min == max || min+1 == max)
7824         {
7825                 eq = QCC_PR_Statement(pr_opcodes+OP_EQ_F, index, QCC_MakeFloatConst((float)min), NULL);
7826                 QCC_UnFreeTemp(index);
7827                 QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
7828                 st->b = 3;
7829                 if (array->type->size == 3)
7830                         QCC_PR_Statement(pr_opcodes+OP_STORE_V, value, array, &st);
7831                 else
7832                         QCC_PR_Statement(pr_opcodes+OP_STORE_F, value, array, &st);
7833                 st->b = array->ofs + min*array->type->size;
7834                 QCC_PR_Statement(pr_opcodes+OP_RETURN, 0, 0, &st);
7835         }
7836         else
7837         {
7838                 int mid = min + (max-min)/2;
7839
7840                 if (max-min>4)
7841                 {
7842                         eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatConst((float)mid), NULL);
7843                         QCC_UnFreeTemp(index);
7844                         QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
7845                 }
7846                 else
7847                         st = NULL;
7848                 QCC_PR_ArraySetRecurseDivide(array, index, value, min, mid);
7849                 if (st)
7850                         st->b = numstatements - (st-statements);
7851                 QCC_PR_ArraySetRecurseDivide(array, index, value, mid, max);
7852         }
7853 }
7854
7855 void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, char *arrayname)
7856 {
7857         QCC_dfunction_t *df;
7858         QCC_def_t *def, *index, *value;
7859
7860         QCC_def_t *fasttrackpossible;
7861
7862         if (flag_fasttrackarrays)
7863                 fasttrackpossible = QCC_PR_GetDef(type_float, "__ext__fasttrackarrays", NULL, true, 0, false);
7864         else
7865                 fasttrackpossible = NULL;
7866
7867         def = QCC_PR_GetDef(NULL, arrayname, NULL, false, 0, false);
7868         pr_scope = scope;
7869
7870         if (numfunctions >= MAX_FUNCTIONS)
7871                 QCC_Error(ERR_INTERNAL, "Too many function defs");
7872
7873         df = &functions[numfunctions];
7874         numfunctions++;
7875
7876         df->s_file = 0;
7877         df->s_name = QCC_CopyString(scope->name);
7878         df->first_statement = numstatements;
7879         df->parm_size[0] = 1;
7880         df->parm_size[1] = def->type->size;
7881         df->numparms = 2;
7882         df->parm_start = numpr_globals;
7883         index = QCC_PR_GetDef(type_float, "indexs___", def, true, 0, false);
7884         value = QCC_PR_GetDef(def->type, "value___", def, true, 0, false);
7885         locals_end = numpr_globals;
7886         df->locals = locals_end - df->parm_start;
7887
7888         G_FUNCTION(scope->ofs) = df - functions;
7889
7890         if (fasttrackpossible)
7891         {
7892                 QCC_dstatement_t *st;
7893
7894                 QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, fasttrackpossible, NULL, &st);
7895                 //note that the array size is coded into the globals, one index before the array.
7896
7897                 QCC_PR_Statement3(&pr_opcodes[OP_CONV_FTOI], index, NULL, index, true); //address stuff is integer based, but standard qc (which this accelerates in supported engines) only supports floats
7898                 QCC_PR_SimpleStatement (OP_BOUNDCHECK, index->ofs, ((int*)qcc_pr_globals)[def->ofs-1]+1, 0, true);//annoy the programmer. :p
7899                 if (def->type->size != 1)//shift it upwards for larger types
7900                         QCC_PR_Statement3(&pr_opcodes[OP_MUL_I], index, QCC_MakeIntConst(def->type->size), index, true);
7901                 QCC_PR_Statement3(&pr_opcodes[OP_GLOBALADDRESS], def, index, index, true);      //comes with built in add
7902                 if (def->type->size >= 3)
7903                         QCC_PR_Statement3(&pr_opcodes[OP_STOREP_V], value, index, NULL, true);  //*b = a
7904                 else
7905                         QCC_PR_Statement3(&pr_opcodes[OP_STOREP_F], value, index, NULL, true);
7906                 QCC_PR_Statement(&pr_opcodes[OP_RETURN], value, NULL, NULL);
7907
7908                 //finish the jump
7909                 st->b = &statements[numstatements] - st;
7910         }
7911
7912         QCC_PR_Statement3(pr_opcodes+OP_BITAND_F, index, index, index, false);
7913         QCC_PR_ArraySetRecurseDivide(def, index, value, 0, def->arraysize);
7914
7915         QCC_PR_Statement(pr_opcodes+OP_DONE, 0, 0, NULL);
7916
7917
7918
7919         QCC_WriteAsmFunction(pr_scope, df->first_statement, df->parm_start);
7920
7921         QCC_FreeTemps();
7922 }
7923
7924 //register a def, and all of it's sub parts.
7925 //only the main def is of use to the compiler.
7926 //the subparts are emitted to the compiler and allow correct saving/loading
7927 //be careful with fields, this doesn't allocated space, so will it allocate fields. It only creates defs at specified offsets.
7928 QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int arraysize, unsigned int ofs, int referable, pbool saved)
7929 {
7930         char array[64];
7931         char newname[256];
7932         int a;
7933         QCC_def_t *def, *first=NULL;
7934
7935 #define KEYWORD(x) if (!STRCMP(name, #x) && keyword_##x) {if (keyword_##x)QCC_PR_ParseWarning(WARN_KEYWORDDISABLED, "\""#x"\" keyword used as variable name%s", keywords_coexist?" - coexisting":" - disabling");keyword_##x=keywords_coexist;}
7936         if (name)
7937         {
7938                 KEYWORD(var);
7939                 KEYWORD(thinktime);
7940                 KEYWORD(for);
7941                 KEYWORD(switch);
7942                 KEYWORD(case);
7943                 KEYWORD(default);
7944                 KEYWORD(goto);
7945                 if (type->type != ev_function)
7946                         KEYWORD(break);
7947                 KEYWORD(continue);
7948                 KEYWORD(state);
7949                 KEYWORD(string);
7950                 if (qcc_targetformat != QCF_HEXEN2)
7951                         KEYWORD(float); //hmm... hexen2 requires this...
7952                 KEYWORD(entity);
7953                 KEYWORD(vector);
7954                 KEYWORD(const);
7955                 KEYWORD(asm);
7956         }
7957
7958         for (a = 0; a < (arraysize?arraysize:1); a++)
7959         {
7960                 if (a == 0)
7961                         *array = '\0';
7962                 else
7963                         sprintf(array, "[%i]", a);
7964
7965                 if (name)
7966                         sprintf(newname, "%s%s", name, array);
7967                 else
7968                         *newname = *"";
7969
7970                 // allocate a new def
7971                 def = (void *)qccHunkAlloc (sizeof(QCC_def_t));
7972                 memset (def, 0, sizeof(*def));
7973                 def->next = NULL;
7974                 def->arraysize = a?0:arraysize;
7975                 if (name)
7976                 {
7977                         pr.def_tail->next = def;
7978                         pr.def_tail = def;
7979                 }
7980
7981                 if (a > 0)
7982                         def->references++;
7983
7984                 def->s_line = pr_source_line;
7985                 def->s_file = s_file;
7986                 if (a)
7987                         def->initialized = 1;
7988
7989                 def->name = (void *)qccHunkAlloc (strlen(newname)+1);
7990                 strcpy (def->name, newname);
7991                 def->type = type;
7992
7993                 def->scope = scope;
7994                 def->saved = saved;
7995
7996                 //if (type->type = ev_field)
7997                         def->constant = true;
7998
7999                 if (ofs + type->size*a >= MAX_REGS)
8000                         QCC_Error(ERR_TOOMANYGLOBALS, "MAX_REGS is too small");
8001                 def->ofs = ofs + type->size*a;
8002                 if (!first)
8003                         first = def;
8004
8005 //      printf("Emited %s\n", newname);
8006
8007                 if (type->type == ev_struct)
8008                 {
8009                         int partnum;
8010                         QCC_type_t *parttype;
8011                         parttype = type->param;
8012                         for (partnum = 0; partnum < type->num_parms; partnum++)
8013                         {
8014                                 switch (parttype->type)
8015                                 {
8016                                 case ev_vector:
8017                                         sprintf(newname, "%s%s.%s", name, array, parttype->name);
8018                                         QCC_PR_DummyDef(parttype, newname, scope, 0, ofs + type->size*a + parttype->ofs, false, saved);
8019
8020                                         sprintf(newname, "%s%s.%s_x", name, array, parttype->name);
8021                                         QCC_PR_DummyDef(type_float, newname, scope, 0, ofs + type->size*a + parttype->ofs, false, false);
8022                                         sprintf(newname, "%s%s.%s_y", name, array, parttype->name);
8023                                         QCC_PR_DummyDef(type_float, newname, scope, 0, ofs + type->size*a + parttype->ofs+1, false, false);
8024                                         sprintf(newname, "%s%s.%s_z", name, array, parttype->name);
8025                                         QCC_PR_DummyDef(type_float, newname, scope, 0, ofs + type->size*a + parttype->ofs+2, false, false);
8026                                         break;
8027
8028                                 case ev_float:
8029                                 case ev_string:
8030                                 case ev_entity:
8031                                 case ev_field:
8032                                 case ev_pointer:
8033                                 case ev_integer:
8034                                 case ev_struct:
8035                                 case ev_union:
8036                                 case ev_variant:        //for lack of any better alternative
8037                                         sprintf(newname, "%s%s.%s", name, array, parttype->name);
8038                                         QCC_PR_DummyDef(parttype, newname, scope, 0, ofs + type->size*a + parttype->ofs, false, saved);
8039                                         break;
8040
8041                                 case ev_function:
8042                                         sprintf(newname, "%s%s.%s", name, array, parttype->name);
8043                                         QCC_PR_DummyDef(parttype, newname, scope, 0, ofs + type->size*a +parttype->ofs, false, saved)->initialized = true;
8044                                         break;
8045                                 case ev_void:
8046                                         break;
8047                                 }
8048                                 parttype=parttype->next;
8049                         }
8050                 }
8051                 else if (type->type == ev_vector)
8052                 {       //do the vector thing.
8053                         sprintf(newname, "%s%s_x", name, array);
8054                         QCC_PR_DummyDef(type_float, newname, scope, 0, ofs + type->size*a+0, referable, false);
8055                         sprintf(newname, "%s%s_y", name, array);
8056                         QCC_PR_DummyDef(type_float, newname, scope, 0, ofs + type->size*a+1, referable, false);
8057                         sprintf(newname, "%s%s_z", name, array);
8058                         QCC_PR_DummyDef(type_float, newname, scope, 0, ofs + type->size*a+2, referable, false);
8059                 }
8060                 else if (type->type == ev_field)
8061                 {
8062                         if (type->aux_type->type == ev_vector)
8063                         {
8064                                 //do the vector thing.
8065                                 sprintf(newname, "%s%s_x", name, array);
8066                                 QCC_PR_DummyDef(type_floatfield, newname, scope, 0, ofs + type->size*a+0, referable, false);
8067                                 sprintf(newname, "%s%s_y", name, array);
8068                                 QCC_PR_DummyDef(type_floatfield, newname, scope, 0, ofs + type->size*a+1, referable, false);
8069                                 sprintf(newname, "%s%s_z", name, array);
8070                                 QCC_PR_DummyDef(type_floatfield, newname, scope, 0, ofs + type->size*a+2, referable, false);
8071                         }
8072                 }
8073                 first->deftail = pr.def_tail;
8074         }
8075
8076         if (referable)
8077         {
8078                 if (!pHash_Get(&globalstable, "end_sys_fields"))
8079                         first->references++;    //anything above needs to be left in, and so warning about not using it is just going to pee people off.
8080                 if (!arraysize && first->type->type != ev_field)
8081                         first->constant = false;
8082                 if (scope)
8083                         pHash_Add(&localstable, first->name, first, qccHunkAlloc(sizeof(bucket_t)));
8084                 else
8085                         pHash_Add(&globalstable, first->name, first, qccHunkAlloc(sizeof(bucket_t)));
8086
8087                 if (!scope && asmfile)
8088                         fprintf(asmfile, "%s %s;\n", TypeName(first->type), first->name);
8089         }
8090
8091         return first;
8092 }
8093
8094 /*
8095 ============
8096 PR_GetDef
8097
8098 If type is NULL, it will match any type
8099 If allocate is true, a new def will be allocated if it can't be found
8100 If arraysize=0, its not an array and has 1 element.
8101 If arraysize>0, its an array and requires array notation
8102 If arraysize<0, its an array with undefined size - GetDef will fail if its not already allocated.
8103 ============
8104 */
8105
8106 QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool allocate, int arraysize, pbool saved)
8107 {
8108         int ofs;
8109         QCC_def_t               *def;
8110 //      char element[MAX_NAME];
8111         unsigned int i;
8112         QCC_def_t *foundstatic = NULL;
8113
8114         if (!allocate)
8115                 arraysize = -1;
8116
8117         if (scope)
8118         {
8119                 def = Hash_Get(&localstable, name);
8120
8121                 while(def)
8122                 {
8123                         if ( def->scope && def->scope != scope)
8124                         {
8125                                 def = Hash_GetNext(&localstable, name, def);
8126                                 continue;               // in a different function
8127                         }
8128
8129                         if (type && typecmp(def->type, type))
8130                                 QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Type mismatch on redeclaration of %s. %s, should be %s",name, TypeName(type), TypeName(def->type));
8131                         if (def->arraysize != arraysize && arraysize>=0)
8132                                 QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHARRAYSIZE, def, "Array sizes for redecleration of %s do not match",name);
8133                         if (allocate && scope)
8134                         {
8135                                 QCC_PR_ParseWarning (WARN_DUPLICATEDEFINITION, "%s duplicate definition ignored", name);
8136                                 QCC_PR_ParsePrintDef(WARN_DUPLICATEDEFINITION, def);
8137 //                              if (!scope)
8138 //                                      QCC_PR_ParsePrintDef(def);
8139                         }
8140                         return def;
8141                 }
8142         }
8143
8144
8145         def = Hash_Get(&globalstable, name);
8146
8147         while(def)
8148         {
8149                 if ( def->scope && def->scope != scope)
8150                 {
8151                         def = Hash_GetNext(&globalstable, name, def);
8152                         continue;               // in a different function
8153                 }
8154
8155                 if (def->isstatic && def->s_file != s_file)
8156                 {       //warn? or would that be pointless?
8157                         foundstatic = def;
8158                         def = Hash_GetNext(&globalstable, name, def);
8159                         continue;               // in a different function
8160                 }
8161
8162                 if (type && typecmp(def->type, type))
8163                 {
8164                         if (!pr_scope)
8165                                 QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Type mismatch on redeclaration of %s. %s, should be %s",name, TypeName(type), TypeName(def->type));
8166                 }
8167                 if (def->arraysize != arraysize && arraysize>=0)
8168                         QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCHARRAYSIZE, def, "Array sizes for redecleration of %s do not match",name);
8169                 if (allocate && scope)
8170                 {
8171                         if (pr_scope)
8172                         {       //warn? or would that be pointless?
8173                                 def = Hash_GetNext(&globalstable, name, def);
8174                                 continue;               // in a different function
8175                         }
8176
8177                         QCC_PR_ParseWarning (WARN_DUPLICATEDEFINITION, "%s duplicate definition ignored", name);
8178                         QCC_PR_ParsePrintDef(WARN_DUPLICATEDEFINITION, def);
8179 //                      if (!scope)
8180 //                              QCC_PR_ParsePrintDef(def);
8181                 }
8182                 return def;
8183         }
8184
8185         if (pHash_Get != &Hash_Get && !allocate)        //do we want to try case insensative too?
8186         {
8187                 if (scope)
8188                 {
8189                         def = pHash_Get(&localstable, name);
8190
8191                         while(def)
8192                         {
8193                                 if ( def->scope && def->scope != scope)
8194                                 {
8195                                         def = pHash_GetNext(&localstable, name, def);
8196                                         continue;               // in a different function
8197                                 }
8198
8199                                 if (type && typecmp(def->type, type))
8200                                         QCC_PR_ParseError (ERR_TYPEMISMATCHREDEC, "Type mismatch on redeclaration of %s. %s, should be %s",name, TypeName(type), TypeName(def->type));
8201                                 if (def->arraysize != arraysize && arraysize>=0)
8202                                         QCC_PR_ParseError (ERR_TYPEMISMATCHARRAYSIZE, "Array sizes for redecleration of %s do not match",name);
8203                                 if (allocate && scope)
8204                                 {
8205                                         QCC_PR_ParseWarning (WARN_DUPLICATEDEFINITION, "%s duplicate definition ignored", name);
8206                                         QCC_PR_ParsePrintDef(WARN_DUPLICATEDEFINITION, def);
8207         //                              if (!scope)
8208         //                                      QCC_PR_ParsePrintDef(def);
8209                                 }
8210                                 return def;
8211                         }
8212                 }
8213
8214
8215                 def = pHash_Get(&globalstable, name);
8216
8217                 while(def)
8218                 {
8219                         if ( def->scope && def->scope != scope)
8220                         {
8221                                 def = pHash_GetNext(&globalstable, name, def);
8222                                 continue;               // in a different function
8223                         }
8224
8225                         if (def->isstatic && def->s_file != s_file)
8226                         {       //warn? or would that be pointless?
8227                                 foundstatic = def;
8228                                 def = Hash_GetNext(&globalstable, name, def);
8229                                 continue;               // in a different function
8230                         }
8231
8232                         if (type && typecmp(def->type, type))
8233                         {
8234                                 if (!pr_scope)
8235                                         QCC_PR_ParseError (ERR_TYPEMISMATCHREDEC, "Type mismatch on redeclaration of %s. %s, should be %s",name, TypeName(type), TypeName(def->type));
8236                         }
8237                         if (def->arraysize != arraysize && arraysize>=0)
8238                                 QCC_PR_ParseError (ERR_TYPEMISMATCHARRAYSIZE, "Array sizes for redecleration of %s do not match",name);
8239                         if (allocate && scope)
8240                         {
8241                                 if (pr_scope)
8242                                 {       //warn? or would that be pointless?
8243                                         def = pHash_GetNext(&globalstable, name, def);
8244                                         continue;               // in a different function
8245                                 }
8246
8247                                 QCC_PR_ParseWarning (WARN_DUPLICATEDEFINITION, "%s duplicate definition ignored", name);
8248                                 QCC_PR_ParsePrintDef(WARN_DUPLICATEDEFINITION, def);
8249         //                      if (!scope)
8250         //                              QCC_PR_ParsePrintDef(def);
8251                         }
8252                         return def;
8253                 }
8254         }
8255
8256         if (foundstatic && !allocate)
8257         {
8258                 QCC_PR_ParseWarning (WARN_DUPLICATEDEFINITION, "%s defined static", name);
8259                 QCC_PR_ParsePrintDef(WARN_DUPLICATEDEFINITION, foundstatic);
8260         }
8261
8262         if (!allocate)
8263                 return NULL;
8264
8265         if (arraysize < 0)
8266         {
8267                 QCC_PR_ParseError (ERR_ARRAYNEEDSSIZE, "First declaration of array %s with no size",name);
8268         }
8269
8270         if (scope)
8271         {
8272                 if (QCC_PR_GetDef(type, name, NULL, false, arraysize, false))
8273                         QCC_PR_ParseWarning(WARN_SAMENAMEASGLOBAL, "Local \"%s\" defined with name of a global", name);
8274         }
8275
8276         ofs = numpr_globals;
8277         if (arraysize)
8278         {       //write the array size
8279                 ofs = QCC_GetFreeOffsetSpace(1 + (type->size    * arraysize));
8280
8281                 ((int *)qcc_pr_globals)[ofs] = arraysize-1;     //An array needs the size written first. This is a hexen2 opcode thing.
8282                 ofs++;
8283         }
8284         else
8285                 ofs = QCC_GetFreeOffsetSpace(type->size);
8286
8287         def = QCC_PR_DummyDef(type, name, scope, arraysize, ofs, true, saved);
8288
8289         //fix up fields.
8290         if (type->type == ev_field && allocate != 2)
8291         {
8292                 for (i = 0; i < type->size*(arraysize?arraysize:1); i++)        //make arrays of fields work.
8293                         *(int *)&qcc_pr_globals[def->ofs+i] = pr.size_fields+i;
8294
8295                 pr.size_fields += i;
8296         }
8297
8298         if (scope)
8299         {
8300                 def->nextlocal = pr.localvars;
8301                 pr.localvars = def;
8302         }
8303
8304         return def;
8305 }
8306
8307 QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, char *name, QCC_def_t *scope, int arraysize, unsigned int *fieldofs, pbool saved)
8308 {
8309         char array[64];
8310         char newname[256];
8311         int a, parms;
8312         QCC_def_t *def, *first=NULL;
8313         unsigned int maxfield, startfield;
8314         QCC_type_t *ftype;
8315         pbool isunion;
8316         startfield = *fieldofs;
8317         maxfield = startfield;
8318
8319         for (a = 0; a < (arraysize?arraysize:1); a++)
8320         {
8321                 if (a == 0)
8322                         *array = '\0';
8323                 else
8324                         sprintf(array, "[%i]", a);
8325
8326                 if (*name)
8327                 {
8328                         sprintf(newname, "%s%s", name, array);
8329
8330                         // allocate a new def
8331                         def = (void *)qccHunkAlloc (sizeof(QCC_def_t));
8332                         memset (def, 0, sizeof(*def));
8333                         def->next = NULL;
8334                         def->arraysize = arraysize;
8335
8336                         pr.def_tail->next = def;
8337                         pr.def_tail = def;
8338
8339                         def->s_line = pr_source_line;
8340                         def->s_file = s_file;
8341
8342                         def->name = (void *)qccHunkAlloc (strlen(newname)+1);
8343                         strcpy (def->name, newname);
8344                         def->type = type;
8345
8346                         def->scope = scope;
8347
8348                         def->ofs = QCC_GetFreeOffsetSpace(1);
8349                         ((int *)qcc_pr_globals)[def->ofs] = *fieldofs;
8350                         fieldofs++;
8351                         if (!first)
8352                                 first = def;
8353                 }
8354                 else
8355                 {
8356                         def=NULL;
8357                 }
8358
8359 //      printf("Emited %s\n", newname);
8360
8361                 if ((type)->type == ev_struct||(type)->type == ev_union)
8362                 {
8363                         int partnum;
8364                         QCC_type_t *parttype;
8365                         if (def)
8366                                 def->references++;
8367                         parttype = (type)->param;
8368                         isunion = ((type)->type == ev_union);
8369                         for (partnum = 0, parms = (type)->num_parms; partnum < parms; partnum++)
8370                         {
8371                                 switch (parttype->type)
8372                                 {
8373                                 case ev_union:
8374                                 case ev_struct:
8375                                         if (*name)
8376                                                 sprintf(newname, "%s%s.%s", name, array, parttype->name);
8377                                         else
8378                                                 sprintf(newname, "%s%s", parttype->name, array);
8379                                         def = QCC_PR_DummyFieldDef(parttype, newname, scope, 1, fieldofs, saved);
8380                                         break;
8381                                 case ev_float:
8382                                 case ev_string:
8383                                 case ev_vector:
8384                                 case ev_entity:
8385                                 case ev_field:
8386                                 case ev_pointer:
8387                                 case ev_integer:
8388                                 case ev_variant:
8389                                         if (*name)
8390                                                 sprintf(newname, "%s%s.%s", name, array, parttype->name);
8391                                         else
8392                                                 sprintf(newname, "%s%s", parttype->name, array);
8393                                         ftype = QCC_PR_NewType("FIELD TYPE", ev_field, false);
8394                                         ftype->aux_type = parttype;
8395                                         if (parttype->type == ev_vector)
8396                                                 ftype->size = parttype->size;   //vector fields create a _y and _z too, so we need this still.
8397                                         def = QCC_PR_GetDef(NULL, newname, scope, false, 0, saved);
8398                                         if (!def)
8399                                         {
8400                                                 def = QCC_PR_GetDef(ftype, newname, scope, true, 0, saved);
8401                                         }
8402                                         else
8403                                         {
8404                                                 QCC_PR_ParseWarning(WARN_CONFLICTINGUNIONMEMBER, "conflicting offsets for union/struct expansion of %s. Ignoring new def.", newname);
8405                                                 QCC_PR_ParsePrintDef(WARN_CONFLICTINGUNIONMEMBER, def);
8406                                         }
8407                                         break;
8408
8409                                 case ev_function:
8410                                         if (*name)
8411                                                 sprintf(newname, "%s%s.%s", name, array, parttype->name);
8412                                         else
8413                                                 sprintf(newname, "%s%s", parttype->name, array);
8414                                         ftype = QCC_PR_NewType("FIELD TYPE", ev_field, false);
8415                                         ftype->aux_type = parttype;
8416                                         def = QCC_PR_GetDef(ftype, newname, scope, true, 0, saved);
8417                                         def->initialized = true;
8418                                         ((int *)qcc_pr_globals)[def->ofs] = *fieldofs;
8419                                         *fieldofs += parttype->size;
8420                                         break;
8421                                 case ev_void:
8422                                         break;
8423                                 }
8424                                 if (*fieldofs > maxfield)
8425                                         maxfield = *fieldofs;
8426                                 if (isunion)
8427                                         *fieldofs = startfield;
8428
8429                                 type = parttype;
8430                                 parttype=parttype->next;
8431                         }
8432                 }
8433         }
8434
8435         *fieldofs = maxfield;   //final size of the union.
8436         return first;
8437 }
8438
8439
8440
8441 void QCC_PR_ExpandUnionToFields(QCC_type_t *type, int *fields)
8442 {
8443         QCC_type_t *pass = type->aux_type;
8444         QCC_PR_DummyFieldDef(pass, "", pr_scope, 1, fields, true);
8445 }
8446
8447
8448 void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *def, QCC_type_t *type, int offset)
8449 {
8450         QCC_def_t *tmp;
8451         int i;
8452
8453         if (arraysize)
8454         {
8455                 //arrays go recursive
8456                 QCC_PR_Expect("{");
8457                 for (i = 0; i < arraysize; i++)
8458                 {
8459                         QCC_PR_ParseInitializerType(0, def, type, offset + i*type->size);
8460                         if (!QCC_PR_CheckToken(","))
8461                                 break;
8462                 }
8463                 QCC_PR_Expect("}");
8464         }
8465         else
8466         {
8467                 if (type->type == ev_function && pr_token_type == tt_punct)
8468                 {
8469                         /*begin function special case*/
8470                         QCC_def_t *parentfunc = pr_scope;
8471                         QCC_function_t *f;
8472                         QCC_dfunction_t *df;
8473                         QCC_type_t *parm;
8474
8475                         tmp = NULL;
8476
8477                         def->references++;
8478                         pr_scope = def;
8479                         if (QCC_PR_CheckToken ("#") || QCC_PR_CheckToken (":"))
8480                         {
8481                                 int binum = 0;
8482                                 if (pr_token_type == tt_immediate
8483                                 && pr_immediate_type == type_float
8484                                 && pr_immediate._float == (int)pr_immediate._float)
8485                                         binum = (int)pr_immediate._float;
8486                                 else if (pr_token_type == tt_immediate && pr_immediate_type == type_integer)
8487                                         binum = pr_immediate._int;
8488                                 else
8489                                         QCC_PR_ParseError (ERR_BADBUILTINIMMEDIATE, "Bad builtin immediate");
8490                                 QCC_PR_Lex();
8491
8492                                 if (def->initialized)
8493                                 for (i = 0; i < numfunctions; i++)
8494                                 {
8495                                         if (functions[i].first_statement == -binum)
8496                                         {
8497                                                 tmp = QCC_MakeIntConst(i);
8498                                                 break;
8499                                         }
8500                                 }
8501
8502                                 if (!tmp)
8503                                 {
8504                                         f = (void *)qccHunkAlloc (sizeof(QCC_function_t));
8505                                         f->builtin = binum;
8506
8507                                         locals_start = locals_end = OFS_PARM0; //hmm...
8508                                 }
8509                                 else
8510                                         f = NULL;
8511                         }
8512                         else
8513                                 f = QCC_PR_ParseImmediateStatements (type);
8514                         if (!tmp)
8515                         {
8516                                 pr_scope = parentfunc;
8517                                 tmp = QCC_MakeIntConst(numfunctions);
8518                                 f->def = def;
8519
8520                                 if (numfunctions >= MAX_FUNCTIONS)
8521                                         QCC_Error(ERR_INTERNAL, "Too many function defs");
8522
8523                 // fill in the dfunction
8524                                 df = &functions[numfunctions];
8525                                 numfunctions++;
8526                                 if (f->builtin)
8527                                         df->first_statement = -f->builtin;
8528                                 else
8529                                         df->first_statement = f->code;
8530
8531                                 if (f->builtin && opt_function_names)
8532                                         optres_function_names += strlen(f->def->name);
8533                                 else
8534                                         df->s_name = QCC_CopyString (f->def->name);
8535                                 df->s_file = s_file2;
8536                                 df->numparms =  f->def->type->num_parms;
8537                                 df->locals = locals_end - locals_start;
8538                                 df->parm_start = locals_start;
8539                                 for (i=0,parm = type->param ; i<df->numparms ; i++, parm = parm->next)
8540                                 {
8541                                         df->parm_size[i] = parm->size;
8542                                 }
8543                                 /*end function special case*/
8544                         }
8545                 }
8546                 else if (type->type == ev_string && QCC_PR_CheckName("_"))
8547                 {
8548                         char trname[128];
8549                         QCC_PR_Expect("(");
8550                         if (pr_token_type != tt_immediate || pr_immediate_type->type != ev_string)
8551                                 QCC_PR_ParseError(0, "_() intrinsic accepts only a string immediate");
8552                         tmp = QCC_MakeStringConst(pr_immediate_string);
8553                         QCC_PR_Lex();
8554                         QCC_PR_Expect(")");
8555
8556                         if (!pr_scope || def->constant)
8557                         {
8558                                 QCC_def_t *dt;
8559                                 sprintf(trname, "dotranslate_%i", ++dotranslate_count);
8560                                 dt = QCC_PR_DummyDef(type_string, trname, pr_scope, 0, offset, true, true);
8561                                 dt->references = 1;
8562                                 dt->constant = 1;
8563                                 dt->initialized = 1;
8564                         }
8565                 }
8566                 else if (type->type == ev_struct || type->type == ev_union)
8567                 {
8568                         //structs go recursive
8569                         QCC_type_t *parttype;
8570                         int partnum;
8571                         int parms;
8572                         pbool isunion;
8573                         QCC_PR_Expect("{");
8574
8575                         isunion = ((type)->type == ev_union);
8576                         for (partnum = 0, parttype = (type)->param, parms = (type)->num_parms; partnum < parms; partnum++, parttype = parttype->next)
8577                         {
8578                                 QCC_PR_ParseInitializerType(parttype->arraysize, def, parttype, offset + parttype->ofs);
8579                                 if (isunion || !QCC_PR_CheckToken(","))
8580                                         break;
8581                         }
8582                         QCC_PR_Expect("}");
8583                         return;
8584                 }
8585                 else
8586                 {
8587                         tmp = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA);
8588                         if (typecmp(type, tmp->type))
8589                         {
8590                                 /*you can cast from const 0 to anything*/
8591                                 if (tmp->type->size == type->size && (tmp->type->type == ev_integer || tmp->type->type == ev_float) && tmp->constant && !G_INT(tmp->ofs))
8592                                 {
8593                                 }
8594                                 /*cast from int->float will convert*/
8595                                 else if (type->type == ev_float && tmp->type->type == ev_integer)
8596                                         tmp = QCC_PR_Statement (&pr_opcodes[OP_CONV_ITOF], tmp, 0, NULL);
8597                                 /*cast from float->int will convert*/
8598                                 else if (type->type == ev_integer && tmp->type->type == ev_float)
8599                                         tmp = QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], tmp, 0, NULL);
8600                                 else
8601                                         QCC_PR_ParseErrorPrintDef (ERR_BADIMMEDIATETYPE, def, "wrong initializer type");
8602                         }
8603                 }
8604
8605                 if (!pr_scope || def->constant)
8606                 {
8607                         if (!tmp->constant)
8608                                 QCC_PR_ParseErrorPrintDef (ERR_BADIMMEDIATETYPE, def, "initializer is not constant");
8609
8610                         if (def->initialized)
8611                         {
8612                                 for (i = 0; (unsigned)i < type->size; i++)
8613                                         if (G_INT(offset+i) != G_INT(tmp->ofs+i))
8614                                                 QCC_PR_ParseErrorPrintDef (ERR_REDECLARATION, def, "incompatible redeclaration");
8615                         }
8616                         else
8617                         {
8618                                 for (i = 0; (unsigned)i < type->size; i++)
8619                                         G_INT(offset+i) = G_INT(tmp->ofs+i);
8620                         }
8621                 }
8622                 else
8623                 {
8624                         QCC_def_t lhs, rhs;
8625                         if (def->initialized)
8626                                 QCC_PR_ParseErrorPrintDef (ERR_REDECLARATION, def, "%s initialised twice", def->name);
8627
8628                         memset(&lhs, 0, sizeof(lhs));
8629                         memset(&rhs, 0, sizeof(rhs));
8630                         def->references++;
8631                         for (i = 0; (unsigned)i < type->size; )
8632                         {
8633                                 rhs.type = lhs.type = type_float;
8634                                 lhs.ofs = offset+i;
8635                                 tmp->references++;
8636                                 rhs.ofs = tmp->ofs+i;
8637
8638                                 if (type->size - i >= 3)
8639                                 {
8640                                         QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_V], &rhs, &lhs, NULL));
8641                                         i+=3;
8642                                 }
8643                                 else
8644                                 {
8645                                         QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], &rhs, &lhs, NULL));
8646                                         i++;
8647                                 }
8648                         }
8649                 }
8650                 QCC_FreeTemp(tmp);
8651         }
8652 }
8653
8654 void QCC_PR_ParseInitializerDef(QCC_def_t *def, pbool isvar, pbool isconst)
8655 {
8656         def->constant = (isconst || (!isvar && !pr_scope));
8657         QCC_PR_ParseInitializerType(def->arraysize, def, def->type, def->ofs);
8658         if (!def->initialized)
8659                 def->initialized = 1;
8660 }
8661
8662 int accglobalsblock;    //0 = error, 1 = var, 2 = function, 3 = objdata
8663 /*
8664 ================
8665 PR_ParseDefs
8666
8667 Called at the outer layer and when a local statement is hit
8668 ================
8669 */
8670 void QCC_PR_ParseDefs (char *classname)
8671 {
8672         char            *name;
8673         QCC_type_t              *type, *parm;
8674         QCC_def_t               *def, *d;
8675         QCC_function_t  *f;
8676         QCC_dfunction_t *df;
8677         int                     i = 0; // warning: \91i\92 may be used uninitialized in this function
8678         pbool shared=false;
8679         pbool isstatic=defaultstatic;
8680         pbool externfnc=false;
8681         pbool isconstant = false;
8682         pbool isvar = false;
8683         pbool noref = defaultnoref;
8684         pbool nosave = false;
8685         pbool allocatenew = true;
8686         pbool inlinefunction = false;
8687         gofs_t oldglobals;
8688         int arraysize;
8689
8690         while (QCC_PR_CheckToken(";"))
8691                 ;
8692
8693         if (QCC_PR_CheckKeyword(keyword_enum, "enum"))
8694         {
8695                 if (QCC_PR_CheckKeyword(keyword_integer, "integer") || QCC_PR_CheckKeyword(keyword_int, "int"))
8696                 {
8697                         int iv = 0;
8698                         QCC_PR_Expect("{");
8699                         i = 0;
8700                         d = NULL;
8701                         while(1)
8702                         {
8703                                 name = QCC_PR_ParseName();
8704                                 if (QCC_PR_CheckToken("="))
8705                                 {
8706                                         if (pr_token_type != tt_immediate && pr_immediate_type->type != ev_integer)
8707                                         {
8708                                                 def = QCC_PR_GetDef(NULL, QCC_PR_ParseName(), NULL, false, 0, false);
8709                                                 if (def)
8710                                                 {
8711                                                         if (!def->constant)
8712                                                                 QCC_PR_ParseError(ERR_NOTANUMBER, "enum - %s is not a constant", def->name);
8713                                                         else
8714                                                                 iv = G_INT(def->ofs);
8715                                                 }
8716                                                 else
8717                                                         QCC_PR_ParseError(ERR_NOTANUMBER, "enum - not a number");
8718                                         }
8719                                         else
8720                                         {
8721                                                 iv = pr_immediate._int;
8722                                                 QCC_PR_Lex();
8723                                         }
8724                                 }
8725                                 def = QCC_MakeIntConst(iv);
8726                                 pHash_Add(&globalstable, name, def, qccHunkAlloc(sizeof(bucket_t)));
8727                                 iv++;
8728
8729                                 if (QCC_PR_CheckToken("}"))
8730                                         break;
8731                                 QCC_PR_Expect(",");
8732                                 if (QCC_PR_CheckToken("}"))
8733                                         break; // accept trailing comma
8734                         }
8735                 }
8736                 else
8737                 {
8738                         float fv = 0;
8739                         QCC_PR_CheckKeyword(keyword_float, "float");
8740                         QCC_PR_Expect("{");
8741                         i = 0;
8742                         d = NULL;
8743                         while(1)
8744                         {
8745                                 name = QCC_PR_ParseName();
8746                                 if (QCC_PR_CheckToken("="))
8747                                 {
8748                                         if (pr_token_type != tt_immediate && pr_immediate_type->type != ev_float)
8749                                         {
8750                                                 def = QCC_PR_GetDef(NULL, QCC_PR_ParseName(), NULL, false, 0, false);
8751                                                 if (def)
8752                                                 {
8753                                                         if (!def->constant)
8754                                                                 QCC_PR_ParseError(ERR_NOTANUMBER, "enum - %s is not a constant", def->name);
8755                                                         else
8756                                                                 fv = G_FLOAT(def->ofs);
8757                                                 }
8758                                                 else
8759                                                         QCC_PR_ParseError(ERR_NOTANUMBER, "enum - not a number");
8760                                         }
8761                                         else
8762                                         {
8763                                                 fv = pr_immediate._float;
8764                                                 QCC_PR_Lex();
8765                                         }
8766                                 }
8767                                 def = QCC_MakeFloatConst(fv);
8768                                 pHash_Add(&globalstable, name, def, qccHunkAlloc(sizeof(bucket_t)));
8769                                 fv++;
8770
8771                                 if (QCC_PR_CheckToken("}"))
8772                                         break;
8773                                 QCC_PR_Expect(",");
8774                                 if (QCC_PR_CheckToken("}"))
8775                                         break; // accept trailing comma
8776                         }
8777                 }
8778                 QCC_PR_Expect(";");
8779                 return;
8780         }
8781
8782         if (QCC_PR_CheckKeyword(keyword_enumflags, "enumflags"))
8783         {
8784                 int bits;
8785
8786                 if (QCC_PR_CheckKeyword(keyword_integer, "integer") || QCC_PR_CheckKeyword(keyword_int, "int"))
8787                 {
8788                         int iv = 1;
8789                         QCC_PR_Expect("{");
8790                         i = 0;
8791                         d = NULL;
8792                         while(1)
8793                         {
8794                                 name = QCC_PR_ParseName();
8795                                 if (QCC_PR_CheckToken("="))
8796                                 {
8797                                         if (pr_token_type != tt_immediate && pr_immediate_type->type != ev_integer)
8798                                         {
8799                                                 def = QCC_PR_GetDef(NULL, QCC_PR_ParseName(), NULL, false, 0, false);
8800                                                 if (def)
8801                                                 {
8802                                                         if (!def->constant)
8803                                                                 QCC_PR_ParseError(ERR_NOTANUMBER, "enumflags - %s is not a constant", def->name);
8804                                                         else
8805                                                                 iv = G_INT(def->ofs);
8806                                                 }
8807                                                 else
8808                                                         QCC_PR_ParseError(ERR_NOTANUMBER, "enumflags - not a number");
8809                                         }
8810                                         else
8811                                         {
8812                                                 iv = pr_immediate._int;
8813                                                 QCC_PR_Lex();
8814                                         }
8815                                 }
8816
8817                                 bits = 0;
8818                                 i = (int)iv;
8819                                 if (i != iv)
8820                                         QCC_PR_ParseWarning(WARN_ENUMFLAGS_NOTINTEGER, "enumflags - %f not an integer", iv);
8821                                 else
8822                                 {
8823                                         while(i)
8824                                         {
8825                                                 if (((i>>1)<<1) != i)
8826                                                         bits++;
8827                                                 i>>=1;
8828                                         }
8829                                         if (bits > 1)
8830                                                 QCC_PR_ParseWarning(WARN_ENUMFLAGS_NOTBINARY, "enumflags - value %i not a single bit", (int)iv);
8831                                 }
8832
8833                                 def = QCC_MakeIntConst(iv);
8834                                 pHash_Add(&globalstable, name, def, qccHunkAlloc(sizeof(bucket_t)));
8835
8836                                 iv*=2;
8837
8838                                 if (QCC_PR_CheckToken("}"))
8839                                         break;
8840                                 QCC_PR_Expect(",");
8841                         }
8842                 }
8843                 else
8844                 {
8845                         float fv = 1;
8846                         QCC_PR_CheckKeyword(keyword_float, "float");
8847
8848                         QCC_PR_Expect("{");
8849                         i = 0;
8850                         d = NULL;
8851                         while(1)
8852                         {
8853                                 name = QCC_PR_ParseName();
8854                                 if (QCC_PR_CheckToken("="))
8855                                 {
8856                                         if (pr_token_type != tt_immediate && pr_immediate_type->type != ev_float)
8857                                         {
8858                                                 def = QCC_PR_GetDef(NULL, QCC_PR_ParseName(), NULL, false, 0, false);
8859                                                 if (def)
8860                                                 {
8861                                                         if (!def->constant)
8862                                                                 QCC_PR_ParseError(ERR_NOTANUMBER, "enumflags - %s is not a constant", def->name);
8863                                                         else
8864                                                                 fv = G_FLOAT(def->ofs);
8865                                                 }
8866                                                 else
8867                                                         QCC_PR_ParseError(ERR_NOTANUMBER, "enumflags - not a number");
8868                                         }
8869                                         else
8870                                         {
8871                                                 fv = pr_immediate._float;
8872                                                 QCC_PR_Lex();
8873                                         }
8874                                 }
8875
8876                                 bits = 0;
8877                                 i = (int)fv;
8878                                 if (i != fv)
8879                                         QCC_PR_ParseWarning(WARN_ENUMFLAGS_NOTINTEGER, "enumflags - %f not an integer", fv);
8880                                 else
8881                                 {
8882                                         while(i)
8883                                         {
8884                                                 if (((i>>1)<<1) != i)
8885                                                         bits++;
8886                                                 i>>=1;
8887                                         }
8888                                         if (bits > 1)
8889                                                 QCC_PR_ParseWarning(WARN_ENUMFLAGS_NOTBINARY, "enumflags - value %i not a single bit", (int)fv);
8890                                 }
8891
8892                                 def = QCC_MakeFloatConst(fv);
8893                                 pHash_Add(&globalstable, name, def, qccHunkAlloc(sizeof(bucket_t)));
8894
8895                                 fv*=2;
8896
8897                                 if (QCC_PR_CheckToken("}"))
8898                                         break;
8899                                 QCC_PR_Expect(",");
8900                         }
8901                 }
8902                 QCC_PR_Expect(";");
8903                 return;
8904         }
8905
8906         if (QCC_PR_CheckKeyword (keyword_typedef, "typedef"))
8907         {
8908                 type = QCC_PR_ParseType(true, false);
8909                 if (!type)
8910                 {
8911                         QCC_PR_ParseError(ERR_NOTANAME, "typedef found unexpected tokens");
8912                 }
8913                 type->name = QCC_CopyString(pr_token)+strings;
8914                 type->typedefed = true;
8915                 QCC_PR_Lex();
8916                 QCC_PR_Expect(";");
8917                 return;
8918         }
8919
8920         if (flag_acc)
8921         {
8922                 char *oldp;
8923                 if (QCC_PR_CheckKeyword (keyword_codesys, "CodeSys"))   //reacc support.
8924                 {
8925                         if (ForcedCRC)
8926                                 QCC_PR_ParseError(ERR_BADEXTENSION, "progs crc was already specified - only one is allowed");
8927                         ForcedCRC = (int)pr_immediate._float;
8928                         QCC_PR_Lex();
8929                         QCC_PR_Expect(";");
8930                         return;
8931                 }
8932
8933                 oldp = pr_file_p;
8934                 if (QCC_PR_CheckKeyword (keyword_var, "var"))   //reacc support.
8935                 {
8936                         if (accglobalsblock == 3)
8937                         {
8938                                 if (!QCC_PR_GetDef(type_void, "end_sys_fields", NULL, false, 0, false))
8939                                         QCC_PR_GetDef(type_void, "end_sys_fields", NULL, true, 0, false);
8940                         }
8941
8942                         QCC_PR_ParseName();
8943                         if (QCC_PR_CheckToken(":"))
8944                                 accglobalsblock = 1;
8945                         pr_file_p = oldp;
8946                         QCC_PR_Lex();
8947                 }
8948
8949                 if (QCC_PR_CheckKeyword (keyword_function, "function")) //reacc support.
8950                 {
8951                         accglobalsblock = 2;
8952                 }
8953                 if (QCC_PR_CheckKeyword (keyword_objdata, "objdata"))   //reacc support.
8954                 {
8955                         if (accglobalsblock == 3)
8956                         {
8957                                 if (!QCC_PR_GetDef(type_void, "end_sys_fields", NULL, false, 0, false))
8958                                         QCC_PR_GetDef(type_void, "end_sys_fields", NULL, true, 0, false);
8959                         }
8960                         else
8961                                 if (!QCC_PR_GetDef(type_void, "end_sys_globals", NULL, false, 0, false))
8962                                         QCC_PR_GetDef(type_void, "end_sys_globals", NULL, true, 0, false);
8963                         accglobalsblock = 3;
8964                 }
8965         }
8966
8967         if (!pr_scope)
8968         switch(accglobalsblock)//reacc support.
8969         {
8970         case 1:
8971                 {
8972                 char *oldp = pr_file_p;
8973                 name = QCC_PR_ParseName();
8974                 if (!QCC_PR_CheckToken(":"))    //nope, it wasn't!
8975                 {
8976                         QCC_PR_IncludeChunk(name, true, NULL);
8977                         QCC_PR_Lex();
8978                         QCC_PR_UnInclude();
8979                         pr_file_p = oldp;
8980                         break;
8981                 }
8982                 if (QCC_PR_CheckKeyword(keyword_object, "object"))
8983                         QCC_PR_GetDef(type_entity, name, NULL, true, 0, true);
8984                 else if (QCC_PR_CheckKeyword(keyword_string, "string"))
8985                         QCC_PR_GetDef(type_string, name, NULL, true, 0, true);
8986                 else if (QCC_PR_CheckKeyword(keyword_real, "real"))
8987                 {
8988                         def = QCC_PR_GetDef(type_float, name, NULL, true, 0, true);
8989                         if (QCC_PR_CheckToken("="))
8990                         {
8991                                 G_FLOAT(def->ofs) = pr_immediate._float;
8992                                 QCC_PR_Lex();
8993                         }
8994                 }
8995                 else if (QCC_PR_CheckKeyword(keyword_vector, "vector"))
8996                 {
8997                         def = QCC_PR_GetDef(type_vector, name, NULL, true, 0, true);
8998                         if (QCC_PR_CheckToken("="))
8999                         {
9000                                 QCC_PR_Expect("[");
9001                                 G_FLOAT(def->ofs+0) = pr_immediate._float;
9002                                 QCC_PR_Lex();
9003                                 G_FLOAT(def->ofs+1) = pr_immediate._float;
9004                                 QCC_PR_Lex();
9005                                 G_FLOAT(def->ofs+2) = pr_immediate._float;
9006                                 QCC_PR_Lex();
9007                                 QCC_PR_Expect("]");
9008                         }
9009                 }
9010                 else if (QCC_PR_CheckKeyword(keyword_pfunc, "pfunc"))
9011                         QCC_PR_GetDef(type_function, name, NULL, true, 0, true);
9012                 else
9013                         QCC_PR_ParseError(ERR_BADNOTTYPE, "Bad type\n");
9014                 QCC_PR_Expect (";");
9015
9016                 if (QCC_PR_CheckKeyword (keyword_system, "system"))
9017                         QCC_PR_Expect (";");
9018                 return;
9019                 }
9020         case 2:
9021                 name = QCC_PR_ParseName();
9022                 QCC_PR_GetDef(type_function, name, NULL, true, 1, true);
9023                 QCC_PR_CheckToken (";");
9024                 return;
9025         case 3:
9026                 {
9027                 char *oldp = pr_file_p;
9028                 name = QCC_PR_ParseName();
9029                 if (!QCC_PR_CheckToken(":"))    //nope, it wasn't!
9030                 {
9031                         QCC_PR_IncludeChunk(name, true, NULL);
9032                         QCC_PR_Lex();
9033                         QCC_PR_UnInclude();
9034                         pr_file_p = oldp;
9035                         break;
9036                 }
9037                 if (QCC_PR_CheckKeyword(keyword_object, "object"))
9038                         QCC_PR_GetDef(QCC_PR_FieldType(type_entity), name, NULL, true, 0, true);
9039                 else if (QCC_PR_CheckKeyword(keyword_string, "string"))
9040                         QCC_PR_GetDef(QCC_PR_FieldType(type_string), name, NULL, true, 0, true);
9041                 else if (QCC_PR_CheckKeyword(keyword_real, "real"))
9042                         QCC_PR_GetDef(QCC_PR_FieldType(type_float), name, NULL, true, 0, true);
9043                 else if (QCC_PR_CheckKeyword(keyword_vector, "vector"))
9044                         QCC_PR_GetDef(QCC_PR_FieldType(type_vector), name, NULL, true, 0, true);
9045                 else if (QCC_PR_CheckKeyword(keyword_pfunc, "pfunc"))
9046                         QCC_PR_GetDef(QCC_PR_FieldType(type_function), name, NULL, true, 0, true);
9047                 else
9048                         QCC_PR_ParseError(ERR_BADNOTTYPE, "Bad type\n");
9049                 QCC_PR_Expect (";");
9050                 return;
9051                 }
9052         }
9053
9054         while(1)
9055         {
9056                 if (QCC_PR_CheckKeyword(keyword_extern, "extern"))
9057                         externfnc=true;
9058                 else if (QCC_PR_CheckKeyword(keyword_shared, "shared"))
9059                 {
9060                         shared=true;
9061                         if (pr_scope)
9062                                 QCC_PR_ParseError (ERR_NOSHAREDLOCALS, "Cannot have shared locals");
9063                 }
9064                 else if (QCC_PR_CheckKeyword(keyword_const, "const"))
9065                         isconstant = true;
9066                 else if (QCC_PR_CheckKeyword(keyword_var, "var"))
9067                         isvar = true;
9068                 else if (!pr_scope && QCC_PR_CheckKeyword(keyword_var, "static"))
9069                         isstatic = true;
9070                 else if (!pr_scope && QCC_PR_CheckKeyword(keyword_var, "nonstatic"))
9071                         isstatic = false;
9072                 else if (QCC_PR_CheckKeyword(keyword_noref, "noref"))
9073                         noref=true;
9074                 else if (QCC_PR_CheckKeyword(keyword_nosave, "nosave"))
9075                         nosave = true;
9076                 else
9077                         break;
9078         }
9079
9080         type = QCC_PR_ParseType (false, false);
9081         if (type == NULL)       //ignore
9082                 return;
9083
9084         inlinefunction = type_inlinefunction;
9085
9086         if (externfnc && type->type != ev_function)
9087         {
9088                 printf ("Only functions may be defined as external (yet)\n");
9089                 externfnc=false;
9090         }
9091
9092         if (!pr_scope && QCC_PR_CheckKeyword(keyword_function, "function"))     //reacc support.
9093         {
9094                 name = QCC_PR_ParseName ();
9095                 QCC_PR_Expect("(");
9096                 type = QCC_PR_ParseFunctionTypeReacc(false, type);
9097                 QCC_PR_Expect(";");
9098                 def = QCC_PR_GetDef (type, name, NULL, true, 0, false);
9099
9100                 if (autoprototype)
9101                 {       //ignore the code and stuff
9102
9103                         if (QCC_PR_CheckKeyword(keyword_external, "external"))
9104                         {       //builtin
9105                                 QCC_PR_Lex();
9106                                 QCC_PR_Expect(";");
9107                         }
9108                         else
9109                         {
9110                                 int blev = 1;
9111
9112                                 while (!QCC_PR_CheckToken("{")) //skip over the locals.
9113                                 {
9114                                         if (pr_token_type == tt_eof)
9115                                         {
9116                                                 QCC_PR_ParseError(0, "Unexpected EOF");
9117                                                 break;
9118                                         }
9119                                         QCC_PR_Lex();
9120                                 }
9121
9122                                 //balance out the { and }
9123                                 while(blev)
9124                                 {
9125                                         if (pr_token_type == tt_eof)
9126                                                 break;
9127                                         if (QCC_PR_CheckToken("{"))
9128                                                 blev++;
9129                                         else if (QCC_PR_CheckToken("}"))
9130                                                 blev--;
9131                                         else
9132                                                 QCC_PR_Lex();   //ignore it.
9133                                 }
9134                         }
9135                         return;
9136                 }
9137
9138                 def->references++;
9139
9140                 pr_scope = def;
9141                 f = QCC_PR_ParseImmediateStatements (type);
9142                 pr_scope = NULL;
9143                 def->initialized = 1;
9144                 def->isstatic = isstatic;
9145                 G_FUNCTION(def->ofs) = numfunctions;
9146                 f->def = def;
9147 //                              if (pr_dumpasm)
9148 //                                      PR_PrintFunction (def);
9149
9150                 if (numfunctions >= MAX_FUNCTIONS)
9151                         QCC_Error(ERR_INTERNAL, "Too many function defs");
9152
9153 // fill in the dfunction
9154                 df = &functions[numfunctions];
9155                 numfunctions++;
9156                 if (f->builtin)
9157                         df->first_statement = -f->builtin;
9158                 else
9159                         df->first_statement = f->code;
9160
9161                 if (f->builtin && opt_function_names)
9162                         optres_function_names += strlen(f->def->name);
9163                 else
9164                         df->s_name = QCC_CopyString (f->def->name);
9165                 df->s_file = s_file2;
9166                 df->numparms =  f->def->type->num_parms;
9167                 df->locals = locals_end - locals_start;
9168                 df->parm_start = locals_start;
9169                 for (i=0,parm = type->param ; i<df->numparms ; i++, parm = parm->next)
9170                 {
9171                         df->parm_size[i] = parm->size;
9172                 }
9173
9174                 return;
9175         }
9176
9177 //      if (pr_scope && (type->type == ev_field) )
9178 //              QCC_PR_ParseError ("Fields must be global");
9179
9180         do
9181         {               
9182                 if (QCC_PR_CheckToken (";"))
9183                 {
9184                         if (type->type == ev_field && (type->aux_type->type == ev_union || type->aux_type->type == ev_struct))
9185                         {
9186                                 QCC_PR_ExpandUnionToFields(type, &pr.size_fields);
9187                                 return;
9188                         }
9189 //                      if (type->type == ev_union)
9190 //                      {
9191 //                              return;
9192 //                      }
9193                         QCC_PR_ParseError (ERR_TYPEWITHNONAME, "type with no name");
9194                         name = NULL;
9195                 }
9196                 else
9197                 {
9198                         name = QCC_PR_ParseName ();
9199                 }
9200
9201                 if (QCC_PR_CheckToken("::") && !classname)
9202                 {
9203                         classname = name;
9204                         name = QCC_PR_ParseName();
9205                 }
9206
9207 //check for an array
9208
9209                 if ( QCC_PR_CheckToken ("[") )
9210                 {
9211                         char *oldprfile = pr_file_p;
9212                         arraysize = 0;
9213                         if (QCC_PR_CheckToken("]"))
9214                         {
9215                                 QCC_PR_Expect("=");
9216                                 QCC_PR_Expect("{");
9217                                 QCC_PR_Lex();
9218                                 arraysize++;
9219                                 while(1)
9220                                 {
9221                                         if(pr_token_type == tt_eof)
9222                                                 break;
9223                                         if (QCC_PR_CheckToken(","))
9224                                                 arraysize++;
9225                                         if (QCC_PR_CheckToken("}"))
9226                                                 break;
9227                                         QCC_PR_Lex();
9228                                 }
9229                                 pr_file_p = oldprfile;
9230                                 QCC_PR_Lex();
9231                         }
9232                         else
9233                         {
9234                                 arraysize = QCC_PR_IntConstExpr();
9235                                 QCC_PR_Expect("]");
9236                         }
9237
9238                         if (arraysize < 1)
9239                         {
9240                                 QCC_PR_ParseError (ERR_BADARRAYSIZE, "Definition of array (%s) size is not of a numerical value", name);
9241                                 arraysize=1;    //grrr...
9242                         }
9243                 }
9244                 else
9245                         arraysize = 0;
9246
9247                 if (QCC_PR_CheckToken("("))
9248                 {
9249                         if (inlinefunction)
9250                                 QCC_PR_ParseWarning(WARN_UNSAFEFUNCTIONRETURNTYPE, "Function returning function. Is this what you meant? (suggestion: use typedefs)");
9251                         inlinefunction = false;
9252                         type = QCC_PR_ParseFunctionType(false, type);
9253                 }
9254
9255                 if (classname)
9256                 {
9257                         char *membername = name;
9258                         name = qccHunkAlloc(strlen(classname) + strlen(name) + 3);
9259                         sprintf(name, "%s::"MEMBERFIELDNAME, classname, membername);
9260                         if (!QCC_PR_GetDef(NULL, name, NULL, false, 0, false))
9261                                 QCC_PR_ParseError(ERR_NOTANAME, "%s %s is not a member of class %s\n", TypeName(type), membername, classname);
9262                         sprintf(name, "%s::%s", classname, membername);
9263
9264                         pr_classtype = QCC_TypeForName(classname);
9265                         if (!pr_classtype || !pr_classtype->parentclass)
9266                                 QCC_PR_ParseError(ERR_NOTANAME, "%s is not a class\n", classname);
9267                 }
9268                 else
9269                         pr_classtype = NULL;
9270
9271                 oldglobals = numpr_globals;
9272
9273                 def = QCC_PR_GetDef (type, name, pr_scope, allocatenew, arraysize, !nosave);
9274
9275                 if (!def)
9276                         QCC_PR_ParseError(ERR_NOTANAME, "%s is not part of class %s", name, classname);
9277
9278                 if (noref)
9279                         def->references++;
9280
9281                 if (!def->initialized && shared)        //shared count as initiialised
9282                 {
9283                         def->shared = shared;
9284                         def->initialized = true;
9285                 }
9286                 if (externfnc)
9287                         def->initialized = 2;
9288
9289                 if (isstatic)
9290                 {
9291                         if (def->s_file == s_file)
9292                                 def->isstatic = isstatic;
9293                         else //if (type->type != ev_function && defaultstatic)  //functions don't quite consitiute a definition
9294                                 QCC_PR_ParseErrorPrintDef (ERR_REDECLARATION, def, "can't redefine non-static as static");
9295                 }
9296
9297 // check for an initialization
9298                 if (type->type == ev_function && (pr_scope))
9299                 {
9300                         if ( QCC_PR_CheckToken ("=") )
9301                         {
9302                                 QCC_PR_ParseError (ERR_INITIALISEDLOCALFUNCTION, "local functions may not be initialised");
9303                         }
9304
9305                         d = def;
9306                         while (d != def->deftail)
9307                         {
9308                                 d = d->next;
9309                                 d->initialized = 1;     //fake function
9310                                 G_FUNCTION(d->ofs) = 0;
9311                         }
9312
9313                         continue;
9314                 }
9315
9316                 if (type->type == ev_field && QCC_PR_CheckName ("alias"))
9317                 {
9318                         QCC_PR_ParseError(ERR_INTERNAL, "FTEQCC does not support this variant of decompiled hexenc\nPlease obtain the original version released by Raven Software instead.");
9319                         name = QCC_PR_ParseName();
9320                 }
9321                 else if ( QCC_PR_CheckToken ("=") || ((type->type == ev_function) && (pr_token[0] == '{' || pr_token[0] == '[' || pr_token[0] == ':'))) //this is an initialisation (or a function)
9322                 {
9323                         if (def->shared)
9324                                 QCC_PR_ParseError (ERR_SHAREDINITIALISED, "shared values may not be assigned an initial value", name);
9325                         if (def->initialized == 1)
9326                         {
9327 //                              if (def->type->type == ev_function)
9328 //                              {
9329 //                                      i = G_FUNCTION(def->ofs);
9330 //                                      df = &functions[i];
9331 //                                      QCC_PR_ParseErrorPrintDef (ERR_REDECLARATION, def, "%s redeclared, prev instance is in %s", name, strings+df->s_file);
9332 //                              }
9333 //                              else
9334 //                                      QCC_PR_ParseErrorPrintDef(ERR_REDECLARATION, def, "%s redeclared", name);
9335                         }
9336
9337                         if (autoprototype)
9338                         {       //ignore the code and stuff
9339                                 if (QCC_PR_CheckToken("["))
9340                                 {
9341                                         while (!QCC_PR_CheckToken("]"))
9342                                         {
9343                                                 if (pr_token_type == tt_eof)
9344                                                         break;
9345                                                 QCC_PR_Lex();
9346                                         }
9347                                 }
9348                                 if (QCC_PR_CheckToken("{"))
9349                                 {
9350                                         int blev = 1;
9351                                         //balance out the { and }
9352                                         while(blev)
9353                                         {
9354                                                 if (pr_token_type == tt_eof)
9355                                                         break;
9356                                                 if (QCC_PR_CheckToken("{"))
9357                                                         blev++;
9358                                                 else if (QCC_PR_CheckToken("}"))
9359                                                         blev--;
9360                                                 else
9361                                                         QCC_PR_Lex();   //ignore it.
9362                                         }
9363                                 }
9364                                 else
9365                                 {
9366                                         QCC_PR_CheckToken("#");
9367                                         QCC_PR_Lex();
9368                                 }
9369                                 continue;
9370                         }
9371
9372                         QCC_PR_ParseInitializerDef(def, isvar, isconstant);
9373                 }
9374                 else
9375                 {
9376                         if (type->type == ev_function && isvar)
9377                         {
9378                                 isconstant = !isvar;
9379                                 def->initialized = 1;
9380                         }
9381
9382                         if (type->type == ev_field)
9383                         {
9384                                 if (isconstant)
9385                                         def->constant = 2;      //special flag on fields, 2, makes the pointer obtained from them also constant.
9386                                 else if (isvar)
9387                                         def->constant = 0;
9388                                 else
9389                                         def->constant = 1;
9390                         }
9391                         else
9392                                 def->constant = isconstant;
9393                 }
9394
9395                 d = def;
9396                 while (d != def->deftail)
9397                 {
9398                         d = d->next;
9399                         d->constant = def->constant;
9400                         d->initialized = def->initialized;
9401                 }
9402         } while (QCC_PR_CheckToken (","));
9403
9404         if (type->type == ev_function)
9405                 QCC_PR_CheckToken (";");
9406         else
9407         {
9408                 if (!QCC_PR_CheckToken (";"))
9409                         QCC_PR_ParseWarning(WARN_UNDESIRABLECONVENTION, "Missing semicolon at end of definition");
9410         }
9411 }
9412
9413 /*
9414 ============
9415 PR_CompileFile
9416
9417 compiles the 0 terminated text, adding defintions to the pr structure
9418 ============
9419 */
9420 pbool   QCC_PR_CompileFile (char *string, char *filename)
9421 {
9422         jmp_buf oldjb;
9423         if (!pr.memory)
9424                 QCC_Error (ERR_INTERNAL, "PR_CompileFile: Didn't clear");
9425
9426         QCC_PR_ClearGrabMacros ();      // clear the frame macros
9427
9428         compilingfile = filename;
9429
9430         if (opt_filenames)
9431         {
9432                 optres_filenames += strlen(filename);
9433                 pr_file_p = qccHunkAlloc(strlen(filename)+1);
9434                 strcpy(pr_file_p, filename);
9435                 s_file = pr_file_p - strings;
9436                 s_file2 = 0;
9437         }
9438         else
9439         {
9440                 s_file = s_file2 = QCC_CopyString (filename);
9441         }
9442         pr_file_p = string;
9443
9444         pr_source_line = 0;
9445
9446         memcpy(&oldjb, &pr_parse_abort, sizeof(oldjb));
9447
9448         if( setjmp( pr_parse_abort ) ) {
9449                 // dont count it as error
9450         } else {
9451                 //clock up the first line
9452                 QCC_PR_NewLine (false);
9453
9454                 QCC_PR_Lex ();  // read first token
9455         }
9456
9457         while (pr_token_type != tt_eof)
9458         {
9459                 if (setjmp(pr_parse_abort))
9460                 {
9461                         if (++pr_error_count > MAX_ERRORS)
9462                         {
9463                                 memcpy(&pr_parse_abort, &oldjb, sizeof(oldjb));
9464                                 return false;
9465                         }
9466                         num_continues = 0;
9467                         num_breaks = 0;
9468                         num_cases = 0;
9469                         QCC_PR_SkipToSemicolon ();
9470                         if (pr_token_type == tt_eof)
9471                         {
9472                                 memcpy(&pr_parse_abort, &oldjb, sizeof(oldjb));
9473                                 return false;
9474                         }
9475                 }
9476
9477                 pr_scope = NULL;        // outside all functions
9478
9479                 QCC_PR_ParseDefs (NULL);
9480         }
9481         memcpy(&pr_parse_abort, &oldjb, sizeof(oldjb));
9482
9483         return (pr_error_count == 0);
9484 }
9485
9486 pbool QCC_Include(char *filename)
9487 {
9488         char *newfile;
9489         char fname[512];
9490         char *opr_file_p;
9491         QCC_string_t os_file, os_file2;
9492         int opr_source_line;
9493         char *ocompilingfile;
9494         struct qcc_includechunk_s *oldcurrentchunk;
9495
9496         ocompilingfile = compilingfile;
9497         os_file = s_file;
9498         os_file2 = s_file2;
9499         opr_source_line = pr_source_line;
9500         opr_file_p = pr_file_p;
9501         oldcurrentchunk = currentchunk;
9502
9503         strcpy(fname, filename);
9504         QCC_LoadFile(fname, (void*)&newfile);
9505         currentchunk = NULL;
9506         pr_file_p = newfile;
9507         QCC_PR_CompileFile(newfile, fname);
9508         currentchunk = oldcurrentchunk;
9509
9510         compilingfile = ocompilingfile;
9511         s_file = os_file;
9512         s_file2 = os_file2;
9513         pr_source_line = opr_source_line;
9514         pr_file_p = opr_file_p;
9515
9516 //      QCC_PR_IncludeChunk(newfile, false, fname);
9517
9518         return true;
9519 }
9520
9521 #endif