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