]> de.git.xonotic.org Git - voretournament/voretournament.git/blob - misc/source/fteqcc-src/qcc.h
Better comment on my last change
[voretournament/voretournament.git] / misc / source / fteqcc-src / qcc.h
1 #define COMPILER
2 #define PROGSUSED
3
4 //#define COMMONINLINES
5 //#define inline _inline
6
7 #include "cmdlib.h"
8 #include <setjmp.h>
9 /*
10 #include <stdio.h>
11 #include <conio.h>
12
13
14 #include "pr_comp.h"
15 */
16
17 //this is for testing
18 #define WRITEASM
19
20 #ifdef __MINGW32_VERSION
21 #define MINGW
22 #endif
23
24 #define progfuncs qccprogfuncs
25 extern progfuncs_t *qccprogfuncs;
26
27 #ifndef _WIN32
28 #define stricmp strcasecmp
29 #define strnicmp strncasecmp
30 #endif
31
32 void *qccHunkAlloc(size_t mem);
33 void qccClearHunk(void);
34
35 extern short   (*PRBigShort) (short l);
36 extern short   (*PRLittleShort) (short l);
37 extern int     (*PRBigLong) (int l);
38 extern int     (*PRLittleLong) (int l);
39 extern float   (*PRBigFloat) (float l);
40 extern float   (*PRLittleFloat) (float l);
41
42
43 #define MAX_ERRORS              10
44
45 #define MAX_NAME                128             // chars long
46
47 extern unsigned int MAX_REGS;
48
49 extern int      MAX_STRINGS;
50 extern int      MAX_GLOBALS;
51 extern int      MAX_FIELDS;
52 extern int      MAX_STATEMENTS;
53 extern int      MAX_FUNCTIONS;
54
55 #define MAX_SOUNDS              1024    //convert to int?
56 #define MAX_TEXTURES    1024    //convert to int?
57 #define MAX_MODELS              1024    //convert to int?
58 #define MAX_FILES               1024    //convert to int?
59 #define MAX_DATA_PATH   64
60
61 extern int MAX_CONSTANTS;
62 #define MAXCONSTANTLENGTH 64
63 #define MAXCONSTANTPARAMLENGTH 32
64 #define MAXCONSTANTPARAMS 32
65
66 typedef enum {QCF_STANDARD, QCF_HEXEN2, QCF_DARKPLACES, QCF_FTE, QCF_FTEDEBUG, QCF_KK7, QCF_QTEST} qcc_targetformat_t;
67 extern qcc_targetformat_t qcc_targetformat;
68
69
70 /*
71
72 TODO:
73
74 "stopped at 10 errors"
75
76 other pointer types for models and clients?
77
78 compact string heap?
79
80 always initialize all variables to something safe
81
82 the def->type->type arrangement is really silly.
83
84 return type checking
85
86 parm count type checking
87
88 immediate overflow checking
89
90 pass the first two parms in call->b and call->c
91
92 */
93
94 /*
95
96 comments
97 --------
98 // comments discard text until the end of line
99 / *  * / comments discard all enclosed text (spaced out on this line because this documentation is in a regular C comment block, and typing them in normally causes a parse error)
100
101 code structure
102 --------------
103 A definition is:
104         <type> <name> [ = <immediate>] {, <name> [ = <immediate>] };
105
106
107 types
108 -----
109 simple types: void, float, vector, string, or entity
110         float           width, height;
111         string          name;
112         entity          self, other;
113
114 vector types:
115         vector          org;    // also creates org_x, org_y, and org_z float defs
116         
117         
118 A function type is specified as:        simpletype ( type name {,type name} )
119 The names are ignored except when the function is initialized.  
120         void()          think;
121         entity()        FindTarget;
122         void(vector destination, float speed, void() callback)  SUB_CalcMove;
123         void(...)       dprint;         // variable argument builtin
124
125 A field type is specified as:  .type
126         .vector         origin;
127         .string         netname;
128         .void()         think, touch, use;
129         
130
131 names
132 -----
133 Names are a maximum of 64 characters, must begin with A-Z,a-z, or _, and can continue with those characters or 0-9.
134
135 There are two levels of scoping: global, and function.  The parameter list of a function and any vars declared inside a function with the "local" statement are only visible within that function, 
136
137
138 immediates
139 ----------
140 Float immediates must begin with 0-9 or minus sign.  .5 is illegal.
141         
142 A parsing ambiguity is present with negative constants. "a-5" will be parsed as "a", then "-5", causing an error.  Seperate the - from the digits with a space "a - 5" to get the proper behavior.
143         12
144         1.6
145         0.5
146         -100
147
148 Vector immediates are three float immediates enclosed in single quotes.
149         '0 0 0'
150         '20.5 -10 0.00001'
151         
152 String immediates are characters enclosed in double quotes.  The string cannot contain explicit newlines, but the escape character \n can embed one.  The \" escape can be used to include a quote in the string.
153         "maps/jrwiz1.bsp"
154         "sound/nin/pain.wav"
155         "ouch!\n"
156
157 Code immediates are statements enclosed in {} braces.
158 statement:
159         { <multiple statements> }
160         <expression>;
161         local <type> <name> [ = <immediate>] {, <name> [ = <immediate>] };
162         return <expression>;
163         if ( <expression> ) <statement> [ else <statement> ];
164         while ( <expression> ) <statement>;
165         do <statement> while ( <expression> );
166         <function name> ( <function parms> );
167         
168 expression:
169         combiations of names and these operators with standard C precedence:
170         "&&", "||", "<=", ">=","==", "!=", "!", "*", "/", "-", "+", "=", ".", "<", ">", "&", "|"
171         Parenthesis can be used to alter order of operation.
172         The & and | operations perform integral bit ops on floats
173         
174 A built in function immediate is a number sign followed by an integer.
175         #1
176         #12
177
178
179 compilation
180 -----------
181 Source files are processed sequentially without dumping any state, so if a defs file is the first one processed, the definitions will be available to all other files.
182
183 The language is strongly typed and there are no casts.
184
185 Anything that is initialized is assumed to be constant, and will have immediates folded into it.  If you change the value, your program will malfunction.  All uninitialized globals will be saved to savegame files.
186
187 Functions cannot have more than eight parameters.
188
189 Error recovery during compilation is minimal.  It will skip to the next global definition, so you will never see more than one error at a time in a given function.  All compilation aborts after ten error messages.
190
191 Names can be defined multiple times until they are defined with an initialization, allowing functions to be prototyped before their definition.
192
193 void()  MyFunction;                     // the prototype
194
195 void()  MyFunction =            // the initialization
196 {
197         dprint ("we're here\n");
198 };
199
200
201 entities and fields
202 -------------------
203
204
205 execution
206 ---------
207 Code execution is initiated by C code in quake from two main places:  the timed think routines for periodic control, and the touch function when two objects impact each other.
208
209 There are three global variables that are set before beginning code execution:
210         entity  world;          // the server's world object, which holds all global
211                                                 // state for the server, like the deathmatch flags
212                                                 // and the body ques.
213         entity  self;           // the entity the function is executing for
214         entity  other;          // the other object in an impact, not used for thinks
215         float   time;           // the current game time.  Note that because the
216                                                 // entities in the world are simulated sequentially,
217                                                 // time is NOT strictly increasing.  An impact late
218                                                 // in one entity's time slice may set time higher
219                                                 // than the think function of the next entity. 
220                                                 // The difference is limited to 0.1 seconds.
221 Execution is also caused by a few uncommon events, like the addition of a new client to an existing server.
222         
223 There is a runnaway counter that stops a program if 100000 statements are executed, assuming it is in an infinite loop.
224
225 It is acceptable to change the system set global variables.  This is usually done to pose as another entity by changing self and calling a function.
226
227 The interpretation is fairly efficient, but it is still over an order of magnitude slower than compiled C code.  All time consuming operations should be made into built in functions.
228
229 A profile counter is kept for each function, and incremented for each interpreted instruction inside that function.  The "profile" console command in Quake will dump out the top 10 functions, then clear all the counters.  The "profile all" command will dump sorted stats for every function that has been executed.
230
231
232 afunc ( 4, bfunc(1,2,3));
233 will fail because there is a shared parameter marshaling area, which will cause the 1 from bfunc to overwrite the 4 already placed in parm0.  When a function is called, it copies the parms from the globals into it's privately scoped variables, so there is no collision when calling another function.
234
235 total = factorial(3) + factorial(4);
236 Will fail because the return value from functions is held in a single global area.  If this really gets on your nerves, tell me and I can work around it at a slight performance and space penalty by allocating a new register for the function call and copying it out.
237
238
239 built in functions
240 ------------------
241 void(string text)       dprint;
242 Prints the string to the server console.
243
244 void(entity client, string text)        cprint;
245 Prints a message to a specific client.
246
247 void(string text)       bprint;
248 Broadcast prints a message to all clients on the current server.
249
250 entity()        spawn;
251 Returns a totally empty entity.  You can manually set everything up, or just set the origin and call one of the existing entity setup functions.
252
253 entity(entity start, .string field, string match) find;
254 Searches the server entity list beginning at start, looking for an entity that has entity.field = match.  To start at the beginning of the list, pass world.  World is returned when the end of the list is reached.
255
256 <FIXME: define all the other functions...>
257
258
259 gotchas
260 -------
261
262 The && and || operators DO NOT EARLY OUT like C!
263
264 Don't confuse single quoted vectors with double quoted strings
265
266 The function declaration syntax takes a little getting used to.
267
268 Don't forget the ; after the trailing brace of a function initialization.
269
270 Don't forget the "local" before defining local variables.
271
272 There are no ++ / -- operators, or operate/assign operators.
273
274 */
275
276
277 #if 1
278 #include "hash.h"
279 extern hashtable_t compconstantstable;
280 extern hashtable_t globalstable, localstable;
281 #endif
282
283 #ifdef WRITEASM
284 FILE *asmfile;
285 #endif
286 //=============================================================================
287
288 // offsets are always multiplied by 4 before using
289 typedef unsigned int    gofs_t;                         // offset in global data block
290 typedef struct QCC_function_s QCC_function_t;
291
292 #define MAX_PARMS       8
293
294 typedef struct QCC_type_s
295 {
296         etype_t                 type;
297
298         struct QCC_type_s       *parentclass;   //type_entity...
299         struct QCC_type_s       *next;
300 // function types are more complex
301         struct QCC_type_s       *aux_type;      // return type or field type
302         struct QCC_type_s       *param;
303         int                             num_parms;      // -1 = variable args
304 //      struct QCC_type_s       *parm_types[MAX_PARMS]; // only [num_parms] allocated   
305
306         unsigned int ofs;       //inside a structure.
307         unsigned int size;
308         char *name;
309 } QCC_type_t;
310 int typecmp(QCC_type_t *a, QCC_type_t *b);
311
312 typedef struct temp_s {
313         gofs_t ofs;
314         struct QCC_def_s        *scope;
315 #ifdef WRITEASM
316         struct QCC_def_s        *lastfunc;
317 #endif
318         struct temp_s   *next;
319         pbool used;
320         unsigned int size;
321 } temp_t;
322 void QCC_PurgeTemps(void);
323
324 //not written
325 typedef struct QCC_def_s
326 {
327         QCC_type_t              *type;
328         char            *name;
329         struct QCC_def_s        *next;
330         struct QCC_def_s        *nextlocal;     //provides a chain of local variables for the opt_locals_marshalling optimisation.
331         gofs_t          ofs;
332         struct QCC_def_s        *scope;         // function the var was defined in, or NULL
333         int                     initialized;    // 1 when a declaration included "= immediate"
334         int                     constant;               // 1 says we can use the value over and over again
335
336         int references;
337         int timescalled;        //part of the opt_stripfunctions optimisation.
338
339         int s_file;
340         int s_line;
341
342         int arraysize;
343         pbool shared;
344         pbool saved;
345         pbool isstatic;
346         pbool subscoped_away;
347
348         temp_t *temp;
349 } QCC_def_t;
350
351 //============================================================================
352
353 // pr_loc.h -- program local defs
354
355
356 //=============================================================================
357 extern char QCC_copyright[1024];
358 extern char QCC_Packname[5][128];
359 extern int QCC_packid;
360
361 typedef union QCC_eval_s
362 {
363         QCC_string_t                    string;
364         float                           _float;
365         float                           vector[3];
366         func_t                          function;
367         int                                     _int;
368         union QCC_eval_s                *ptr;
369 } QCC_eval_t;
370
371 const extern    unsigned int            type_size[];
372 //extern        QCC_def_t       *def_for_type[9];
373
374 extern  QCC_type_t      *type_void, *type_string, *type_float, *type_vector, *type_entity, *type_field, *type_function, *type_pointer, *type_integer, *type_variant, *type_floatfield;
375
376 struct QCC_function_s
377 {
378         int                                     builtin;        // if non 0, call an internal function
379         int                                     code;           // first statement
380         char                            *file;          // source file with definition
381         int                                     file_line;
382         struct QCC_def_s                *def;
383         unsigned int            parm_ofs[MAX_PARMS];    // always contiguous, right?
384 };
385
386
387 //
388 // output generated by prog parsing
389 //
390 typedef struct
391 {
392         char            *memory;
393         int                     max_memory;
394         int                     current_memory;
395         QCC_type_t              *types;
396         
397         QCC_def_t               def_head;               // unused head of linked list
398         QCC_def_t               *def_tail;              // add new defs after this and move it
399         QCC_def_t               *localvars;             // chain of variables which need to be pushed and stuff.
400         
401         int                     size_fields;
402 } QCC_pr_info_t;
403
404 extern  QCC_pr_info_t   pr;
405
406
407 typedef struct
408 {
409         char name[MAXCONSTANTLENGTH];
410         char *value;
411         char params[MAXCONSTANTPARAMS][MAXCONSTANTPARAMLENGTH];
412         int numparams;
413         pbool used;
414         pbool inside;
415
416         int namelen;
417 } CompilerConstant_t;
418 extern CompilerConstant_t *CompilerConstant;
419
420 //============================================================================
421
422 extern  pbool   pr_dumpasm;
423
424 //extern        QCC_def_t               **pr_global_defs;       // to find def for a global variable
425
426 typedef enum {
427 tt_eof,                 // end of file reached
428 tt_name,                // an alphanumeric name token
429 tt_punct,               // code punctuation
430 tt_immediate,   // string, float, vector
431 } token_type_t;
432
433 extern  char            pr_token[8192];
434 extern  token_type_t    pr_token_type;
435 extern  QCC_type_t              *pr_immediate_type;
436 extern  QCC_eval_t              pr_immediate;
437
438 extern pbool keyword_asm;
439 extern pbool keyword_break;
440 extern pbool keyword_case;
441 extern pbool keyword_class;
442 extern pbool keyword_const;
443 extern pbool keyword_continue;
444 extern pbool keyword_default;
445 extern pbool keyword_do;
446 extern pbool keyword_entity;
447 extern pbool keyword_float;
448 extern pbool keyword_for;
449 extern pbool keyword_goto;
450 extern pbool keyword_int;
451 extern pbool keyword_integer;
452 extern pbool keyword_state;
453 extern pbool keyword_string;
454 extern pbool keyword_struct;
455 extern pbool keyword_switch;
456 extern pbool keyword_thinktime;
457 extern pbool keyword_var;
458 extern pbool keyword_vector;
459 extern pbool keyword_union;
460 extern pbool keyword_enum;      //kinda like in c, but typedef not supported.
461 extern pbool keyword_enumflags; //like enum, but doubles instead of adds 1.
462 extern pbool keyword_typedef;   //fixme
463 extern pbool keyword_extern;    //function is external, don't error or warn if the body was not found
464 extern pbool keyword_shared;    //mark global to be copied over when progs changes (part of FTE_MULTIPROGS)
465 extern pbool keyword_noref;     //nowhere else references this, don't strip it.
466 extern pbool keyword_nosave;    //don't write the def to the output.
467 extern pbool keyword_union;     //you surly know what a union is!
468
469
470 extern pbool keywords_coexist;
471 extern pbool output_parms;
472 extern pbool autoprototype;
473 extern pbool pr_subscopedlocals;
474 extern pbool flag_ifstring;
475 extern pbool flag_iffloat;
476 extern pbool flag_acc;
477 extern pbool flag_caseinsensative;
478 extern pbool flag_laxcasts;
479 extern pbool flag_hashonly;
480 extern pbool flag_fasttrackarrays;
481 extern pbool flag_assume_integer;
482 extern pbool flag_msvcstyle;
483 extern pbool flag_filetimes;
484
485 extern pbool opt_overlaptemps;
486 extern pbool opt_shortenifnots;
487 extern pbool opt_noduplicatestrings;
488 extern pbool opt_constantarithmatic;
489 extern pbool opt_nonvec_parms;
490 extern pbool opt_constant_names;
491 extern pbool opt_precache_file;
492 extern pbool opt_filenames;
493 extern pbool opt_assignments;
494 extern pbool opt_unreferenced;
495 extern pbool opt_function_names;
496 extern pbool opt_locals;
497 extern pbool opt_dupconstdefs;
498 extern pbool opt_constant_names_strings;
499 extern pbool opt_return_only;
500 extern pbool opt_compound_jumps;
501 //extern pbool opt_comexprremoval;
502 extern pbool opt_stripfunctions;
503 extern pbool opt_locals_marshalling;
504 extern pbool opt_logicops;
505 extern pbool opt_vectorcalls;
506
507 extern int optres_shortenifnots;
508 extern int optres_overlaptemps;
509 extern int optres_noduplicatestrings;
510 extern int optres_constantarithmatic;
511 extern int optres_nonvec_parms;
512 extern int optres_constant_names;
513 extern int optres_precache_file;
514 extern int optres_filenames;
515 extern int optres_assignments;
516 extern int optres_unreferenced;
517 extern int optres_function_names;
518 extern int optres_locals;
519 extern int optres_dupconstdefs;
520 extern int optres_constant_names_strings;
521 extern int optres_return_only;
522 extern int optres_compound_jumps;
523 //extern int optres_comexprremoval;
524 extern int optres_stripfunctions;
525 extern int optres_locals_marshalling;
526 extern int optres_logicops;
527
528 pbool CompileParams(progfuncs_t *progfuncs, int doall, int nump, char **parms);
529
530 void QCC_PR_PrintStatement (QCC_dstatement_t *s);
531
532 void QCC_PR_Lex (void);
533 // reads the next token into pr_token and classifies its type
534
535 QCC_type_t *QCC_PR_NewType (char *name, int basictype);
536 QCC_type_t *QCC_PR_ParseType (int newtype); extern pbool type_inlinefunction;
537 QCC_type_t *QCC_TypeForName(char *name);
538 QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype);
539 QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype);
540 char *QCC_PR_ParseName (void);
541 CompilerConstant_t *QCC_PR_DefineName(char *name);
542
543 void QCC_RemapOffsets(unsigned int firststatement, unsigned int laststatement, unsigned int min, unsigned int max, unsigned int newmin);
544
545 #ifndef COMMONINLINES
546 pbool QCC_PR_CheckImmediate (char *string);
547 pbool QCC_PR_CheckToken (char *string);
548 pbool QCC_PR_CheckName (char *string);
549 void QCC_PR_Expect (char *string);
550 pbool QCC_PR_CheckKeyword(int keywordenabled, char *string);
551 #endif
552 void VARGS QCC_PR_ParseError (int errortype, char *error, ...);
553 void VARGS QCC_PR_ParseWarning (int warningtype, char *error, ...);
554 void VARGS QCC_PR_Warning (int type, char *file, int line, char *error, ...);
555 void VARGS QCC_PR_Note (int type, char *file, int line, char *error, ...);
556 void QCC_PR_ParsePrintDef (int warningtype, QCC_def_t *def);
557 void VARGS QCC_PR_ParseErrorPrintDef (int errortype, QCC_def_t *def, char *error, ...);
558
559 int QCC_WarningForName(char *name);
560
561 //QccMain.c must be changed if this is changed.
562 enum {
563         WARN_DEBUGGING,
564         WARN_ERROR,
565         WARN_NOTREFERENCED,
566         WARN_NOTREFERENCEDCONST,
567         WARN_CONFLICTINGRETURNS,
568         WARN_TOOFEWPARAMS,
569         WARN_TOOMANYPARAMS,
570         WARN_UNEXPECTEDPUNCT,
571         WARN_ASSIGNMENTTOCONSTANT,
572         WARN_ASSIGNMENTTOCONSTANTFUNC,
573         WARN_MISSINGRETURNVALUE,
574         WARN_WRONGRETURNTYPE,
575         WARN_CORRECTEDRETURNTYPE,
576         WARN_POINTLESSSTATEMENT,
577         WARN_MISSINGRETURN,
578         WARN_DUPLICATEDEFINITION,
579         WARN_UNDEFNOTDEFINED,
580         WARN_PRECOMPILERMESSAGE,
581         WARN_TOOMANYPARAMETERSFORFUNC,
582         WARN_STRINGTOOLONG,
583         WARN_BADTARGET,
584         WARN_BADPRAGMA,
585         WARN_HANGINGSLASHR,
586         WARN_NOTDEFINED,
587         WARN_NOTCONSTANT,
588         WARN_SWITCHTYPEMISMATCH,
589         WARN_CONFLICTINGUNIONMEMBER,
590         WARN_KEYWORDDISABLED,
591         WARN_ENUMFLAGS_NOTINTEGER,
592         WARN_ENUMFLAGS_NOTBINARY,
593         WARN_CASEINSENSATIVEFRAMEMACRO,
594         WARN_DUPLICATELABEL,
595         WARN_DUPLICATEMACRO,
596         WARN_ASSIGNMENTINCONDITIONAL,
597         WARN_MACROINSTRING,
598         WARN_BADPARAMS,
599         WARN_IMPLICITCONVERSION,
600         WARN_FIXEDRETURNVALUECONFLICT,
601         WARN_EXTRAPRECACHE,
602         WARN_NOTPRECACHED,
603         WARN_DEADCODE,
604         WARN_UNREACHABLECODE,
605         WARN_NOTSTANDARDBEHAVIOUR,
606         WARN_INEFFICIENTPLUSPLUS,
607         WARN_DUPLICATEPRECOMPILER,
608         WARN_IDENTICALPRECOMPILER,
609         WARN_FTE_SPECIFIC,      //extension that only FTEQCC will have a clue about.
610         WARN_EXTENSION_USED,    //extension that frikqcc also understands
611         WARN_IFSTRING_USED,
612         WARN_LAXCAST,   //some errors become this with a compiler flag
613         WARN_UNDESIRABLECONVENTION,
614         WARN_SAMENAMEASGLOBAL,
615         WARN_CONSTANTCOMPARISON,
616         WARN_UNSAFEFUNCTIONRETURNTYPE,
617
618         ERR_PARSEERRORS,        //caused by qcc_pr_parseerror being called.
619
620         //these are definatly my fault...
621         ERR_INTERNAL,
622         ERR_TOOCOMPLEX,
623         ERR_BADOPCODE,
624         ERR_TOOMANYSTATEMENTS,
625         ERR_TOOMANYSTRINGS,
626         ERR_BADTARGETSWITCH,
627         ERR_TOOMANYTYPES,
628         ERR_TOOMANYPAKFILES,
629         ERR_PRECOMPILERCONSTANTTOOLONG,
630         ERR_MACROTOOMANYPARMS,
631         ERR_TOOMANYFRAMEMACROS,
632
633         //limitations, some are imposed by compiler, some arn't.
634         ERR_TOOMANYGLOBALS,
635         ERR_TOOMANYGOTOS,
636         ERR_TOOMANYBREAKS,
637         ERR_TOOMANYCONTINUES,
638         ERR_TOOMANYCASES,
639         ERR_TOOMANYLABELS,
640         ERR_TOOMANYOPENFILES,
641         ERR_TOOMANYPARAMETERSVARARGS,
642         ERR_TOOMANYTOTALPARAMETERS,
643
644         //these are probably yours, or qcc being fussy.
645         ERR_BADEXTENSION,
646         ERR_BADIMMEDIATETYPE,
647         ERR_NOOUTPUT,
648         ERR_NOTAFUNCTION,
649         ERR_FUNCTIONWITHVARGS,
650         ERR_BADHEX,
651         ERR_UNKNOWNPUCTUATION,
652         ERR_EXPECTED,
653         ERR_NOTANAME,
654         ERR_NAMETOOLONG,
655         ERR_NOFUNC,
656         ERR_COULDNTOPENFILE,
657         ERR_NOTFUNCTIONTYPE,
658         ERR_TOOFEWPARAMS,
659         ERR_TOOMANYPARAMS,
660         ERR_CONSTANTNOTDEFINED,
661         ERR_BADFRAMEMACRO,
662         ERR_TYPEMISMATCH,
663         ERR_TYPEMISMATCHREDEC,
664         ERR_TYPEMISMATCHPARM,
665         ERR_TYPEMISMATCHARRAYSIZE,
666         ERR_UNEXPECTEDPUNCTUATION,
667         ERR_NOTACONSTANT,
668         ERR_REDECLARATION,
669         ERR_INITIALISEDLOCALFUNCTION,
670         ERR_NOTDEFINED,
671         ERR_ARRAYNEEDSSIZE,
672         ERR_ARRAYNEEDSBRACES,
673         ERR_TOOMANYINITIALISERS,
674         ERR_TYPEINVALIDINSTRUCT,
675         ERR_NOSHAREDLOCALS,
676         ERR_TYPEWITHNONAME,
677         ERR_BADARRAYSIZE,
678         ERR_NONAME,
679         ERR_SHAREDINITIALISED,
680         ERR_UNKNOWNVALUE,
681         ERR_BADARRAYINDEXTYPE,
682         ERR_NOVALIDOPCODES,
683         ERR_MEMBERNOTVALID,
684         ERR_BADPLUSPLUSOPERATOR,
685         ERR_BADNOTTYPE,
686         ERR_BADTYPECAST,
687         ERR_MULTIPLEDEFAULTS,
688         ERR_CASENOTIMMEDIATE,
689         ERR_BADSWITCHTYPE,
690         ERR_BADLABELNAME,
691         ERR_NOLABEL,
692         ERR_THINKTIMETYPEMISMATCH,
693         ERR_STATETYPEMISMATCH,
694         ERR_BADBUILTINIMMEDIATE,
695         ERR_PARAMWITHNONAME,
696         ERR_BADPARAMORDER,
697         ERR_ILLEGALCONTINUES,
698         ERR_ILLEGALBREAKS,
699         ERR_ILLEGALCASES,
700         ERR_NOTANUMBER,
701         ERR_WRONGSUBTYPE,
702         ERR_EOF,
703         ERR_NOPRECOMPILERIF,
704         ERR_NOENDIF,
705         ERR_HASHERROR,
706         ERR_NOTATYPE,
707         ERR_TOOMANYPACKFILES,
708         ERR_INVALIDVECTORIMMEDIATE,
709         ERR_INVALIDSTRINGIMMEDIATE,
710         ERR_BADCHARACTERCODE,
711         ERR_BADPARMS,
712         ERR_WERROR,
713
714         WARN_MAX
715 };
716
717 #define FLAG_KILLSDEBUGGERS     1
718 #define FLAG_ASDEFAULT          2
719 #define FLAG_SETINGUI           4
720 #define FLAG_HIDDENINGUI        8
721 #define FLAG_MIDCOMPILE         16      //option can be changed mid-compile with the special pragma
722 typedef struct {
723         pbool *enabled;
724         char *abbrev;
725         int optimisationlevel;
726         int flags;      //1: kills debuggers. 2: applied as default.
727         char *fullname;
728         char *description;
729         void *guiinfo;
730 } optimisations_t;
731 extern optimisations_t optimisations[];
732
733 typedef struct {
734         pbool *enabled;
735         int flags;      //2 applied as default
736         char *abbrev;
737         char *fullname;
738         char *description;
739         void *guiinfo;
740 } compiler_flag_t;
741 extern compiler_flag_t compiler_flag[];
742
743 extern pbool qccwarningdisabled[WARN_MAX];
744
745 extern  jmp_buf         pr_parse_abort;         // longjump with this on parse error
746 extern  int                     pr_source_line;
747 extern  char            *pr_file_p;
748
749 void *QCC_PR_Malloc (int size);
750
751
752 #define OFS_NULL                0
753 #define OFS_RETURN              1
754 #define OFS_PARM0               4               // leave 3 ofs for each parm to hold vectors
755 #define OFS_PARM1               7
756 #define OFS_PARM2               10
757 #define OFS_PARM3               13
758 #define OFS_PARM4               16
759 #define RESERVED_OFS    28
760
761
762 extern  QCC_def_t       *pr_scope;
763 extern  int             pr_error_count, pr_warning_count;
764
765 void QCC_PR_NewLine (pbool incomment);
766 QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool allocate, int arraysize, pbool saved);
767
768 void QCC_PR_PrintDefs (void);
769
770 void QCC_PR_SkipToSemicolon (void);
771
772 #define MAX_EXTRA_PARMS 128
773 #ifdef MAX_EXTRA_PARMS
774 extern  char            pr_parm_names[MAX_PARMS+MAX_EXTRA_PARMS][MAX_NAME];
775 extern QCC_def_t *extra_parms[MAX_EXTRA_PARMS];
776 #else
777 extern  char            pr_parm_names[MAX_PARMS][MAX_NAME];
778 #endif
779 extern  pbool   pr_trace;
780
781 #define G_FLOAT(o) (qcc_pr_globals[o])
782 #define G_INT(o) (*(int *)&qcc_pr_globals[o])
783 #define G_VECTOR(o) (&qcc_pr_globals[o])
784 #define G_STRING(o) (strings + *(QCC_string_t *)&qcc_pr_globals[o])
785 #define G_FUNCTION(o) (*(func_t *)&qcc_pr_globals[o])
786
787 char *QCC_PR_ValueString (etype_t type, void *val);
788
789 void QCC_PR_ClearGrabMacros (void);
790
791 pbool   QCC_PR_CompileFile (char *string, char *filename);
792 void QCC_PR_ResetErrorScope(void);
793
794 extern  pbool   pr_dumpasm;
795
796 extern  QCC_string_t    s_file;                 // filename for function definition
797
798 extern  QCC_def_t       def_ret, def_parms[MAX_PARMS];
799
800 void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname);
801 void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, char *arrayname);
802 void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, char *tname);
803
804 void PostCompile(void);
805 pbool PreCompile(void);
806
807 //=============================================================================
808
809 extern char     pr_immediate_string[8192];
810
811 extern float            *qcc_pr_globals;
812 extern unsigned int     numpr_globals;
813
814 extern char             *strings;
815 extern int                      strofs;
816
817 extern QCC_dstatement_t *statements;
818 extern int                      numstatements;
819 extern int                      *statement_linenums;
820
821 extern QCC_dfunction_t  *functions;
822 extern int                      numfunctions;
823
824 extern QCC_ddef_t               *qcc_globals;
825 extern int                      numglobaldefs;
826
827 extern QCC_def_t                *activetemps;
828
829 extern QCC_ddef_t               *fields;
830 extern int                      numfielddefs;
831
832 extern QCC_type_t *qcc_typeinfo;
833 extern int numtypeinfos;
834 extern int maxtypeinfos;
835
836 extern int ForcedCRC;
837 extern pbool defaultnoref;
838 extern pbool defaultstatic;
839
840 extern int *qcc_tempofs;
841 extern int max_temps;
842 //extern int qcc_functioncalled;        //unuse temps if this is true - don't want to reuse the same space.
843
844 extern int tempsstart;
845 extern int numtemps;
846
847 typedef char PATHSTRING[MAX_DATA_PATH];
848
849 PATHSTRING              *precache_sounds;
850 int                     *precache_sounds_block;
851 int                     *precache_sounds_used;
852 int                     numsounds;
853
854 PATHSTRING              *precache_textures;
855 int                     *precache_textures_block;
856 int                     numtextures;
857
858 PATHSTRING              *precache_models;
859 int                     *precache_models_block;
860 int                     *precache_models_used;
861 int                     nummodels;
862
863 PATHSTRING              *precache_files;
864 int                     *precache_files_block;
865 int                     numfiles;
866
867 int     QCC_CopyString (char *str);
868
869
870
871
872 typedef struct qcc_cachedsourcefile_s {
873         char filename[128];
874         int size;
875         char *file;
876         enum{FT_CODE, FT_DATA} type;    //quakec source file or not.
877         struct qcc_cachedsourcefile_s *next;
878 } qcc_cachedsourcefile_t;
879 extern qcc_cachedsourcefile_t *qcc_sourcefile;
880
881
882
883
884
885 #ifdef COMMONINLINES
886 static bool inline QCC_PR_CheckToken (char *string)
887 {
888         if (pr_token_type != tt_punct)
889                 return false;
890
891         if (STRCMP (string, pr_token))
892                 return false;
893
894         QCC_PR_Lex ();
895         return true;
896 }
897
898 static void inline QCC_PR_Expect (char *string)
899 {
900         if (strcmp (string, pr_token))
901                 QCC_PR_ParseError ("expected %s, found %s",string, pr_token);
902         QCC_PR_Lex ();
903 }
904 #endif
905
906 void editbadfile(char *fname, int line);
907 char *TypeName(QCC_type_t *type);
908 void QCC_PR_IncludeChunk (char *data, pbool duplicate, char *filename);
909 void QCC_PR_IncludeChunkEx(char *data, pbool duplicate, char *filename, CompilerConstant_t *cnst);
910 pbool QCC_PR_UnInclude(void);
911 extern void *(*pHash_Get)(hashtable_t *table, const char *name);
912 extern void *(*pHash_GetNext)(hashtable_t *table, const char *name, void *old);
913 extern void *(*pHash_Add)(hashtable_t *table, const char *name, void *data, bucket_t *);