]> de.git.xonotic.org Git - xonotic/gmqcc.git/blob - gmqcc.h
this can be a move
[xonotic/gmqcc.git] / gmqcc.h
1 #ifndef GMQCC_HDR
2 #define GMQCC_HDR
3 #include <vector>
4 #include <stdarg.h>
5 #include <stddef.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <time.h>
9
10 #define GMQCC_VERSION_MAJOR 0
11 #define GMQCC_VERSION_MINOR 3
12 #define GMQCC_VERSION_PATCH 6
13 #define GMQCC_VERSION ((GMQCC_VERSION_MAJOR<<16)|(GMQCC_VERSION_MINOR<<8)|GMQCC_VERSION_PATCH)
14
15 #ifdef GMQCC_VERSION_TYPE_RELEASE
16 #    ifdef GMQCC_GITINFO
17 #        define GMQCC_DEV_VERSION_STRING "git build: " GMQCC_GITINFO "\n"
18 #    elif defined(GMQCC_VERSION_TYPE_DEVEL)
19 #        define GMQCC_DEV_VERSION_STRING "development build\n"
20 #    else
21 #        define GMQCC_DEV_VERSION_STRING
22 #    endif /*! GMQCC_GITINGO */
23 #else
24 #    define GMQCC_DEV_VERSION_STRING
25 #endif
26
27 #define GMQCC_STRINGIFY(x) #x
28 #define GMQCC_IND_STRING(x) GMQCC_STRINGIFY(x)
29 #define GMQCC_FULL_VERSION_STRING \
30 "GMQCC " \
31 GMQCC_IND_STRING(GMQCC_VERSION_MAJOR) "." \
32 GMQCC_IND_STRING(GMQCC_VERSION_MINOR) "." \
33 GMQCC_IND_STRING(GMQCC_VERSION_PATCH) \
34 " Built " __DATE__ " " __TIME__ \
35 "\n" GMQCC_DEV_VERSION_STRING
36
37 #ifndef __cplusplus
38 #   define false (unsigned char)(0)
39 #   define true  (unsigned char)(1)
40     typedef unsigned char bool;
41 #endif
42
43 #if defined(__GNUC__) || defined(__CLANG__)
44 #   include <stdint.h>
45 #   if (__GNUC__ >= 2) || defined(__CLANG__)
46 #       define GMQCC_NORETURN    __attribute__((noreturn))
47 #       define GMQCC_FORCEINLINE __attribute__((always_inline))
48 #       define GMQCC_INLINE      __inline
49 #   endif
50 #   define GMQCC_LIKELY(X)   __builtin_expect((X), 1)
51 #   define GMQCC_UNLIKELY(X) __builtin_expect((X), 0)
52 #   define GMQCC_WARN        __attribute__((warn_unused_result))
53 #   define GMQCC_USED        __attribute__((used))
54 #   define GMQCC_RESTRICT    __restrict__
55 #else
56 #   ifdef _MSC_VER
57         /* conversion from 'int' to 'float', possible loss of data */
58 #       pragma warning(disable : 4244)
59
60         typedef unsigned __int8  uint8_t;
61         typedef unsigned __int16 uint16_t;
62         typedef unsigned __int32 uint32_t;
63         typedef unsigned __int64 uint64_t;
64         typedef __int16          int16_t;
65         typedef __int32          int32_t;
66         typedef __int64          int64_t;
67 #       define GMQCC_NORETURN    __declspec(noreturn)
68 #       define GMQCC_FORCEINLINE __forceinline
69 #       define GMQCC_INLINE      __inline
70 #       define GMQCC_RESTRICT    __restrict
71 #   else
72 #       define GMQCC_NORETURN
73 #       define GMQCC_FORCEINLINE
74 #       define GMQCC_INLINE
75 #       define GMQCC_RESTRICT
76 #   endif
77 #   define GMQCC_LIKELY(X)   (X)
78 #   define GMQCC_UNLIKELY(X) (X)
79 #   define GMQCC_WARN
80 #   define GMQCC_USED
81 #endif
82
83 #define GMQCC_BYTE_ORDER_LITTLE 1234
84 #define GMQCC_BYTE_ORDER_BIG    4321
85
86 #if defined (__GNUC__) || defined (__GNU_LIBRARY__)
87 #   if defined (__FreeBSD__) || defined (__OpenBSD__)
88 #       include <sys/endian.h>
89 #   elif defined (BSD) && (BSD >= 199103) || defined (__DJGPP__) || defined (__CYGWIN32__)
90 #       include <machine/endian.h>
91 #   elif defined (__APPLE__)
92 #       if defined (__BIG_ENDIAN__) && !defined(BIG_ENDIAN)
93 #           define BIG_ENDIAN
94 #       elif defined (__LITTLE_ENDIAN__) && !defined (LITTLE_ENDIAN)
95 #           define LITTLE_ENDIAN
96 #       endif /*! defined (__BIG_ENDIAN__) && !defined(BIG_ENDIAN) */
97 #   elif !defined (__MINGW32__)
98 #       include <endian.h>
99 #       if !defined (__BEOS__)
100 #           include <byteswap.h>
101 #       endif /*! !definde (__BEOS__) */
102 #   endif /*! defined (__FreeBSD__) || defined (__OpenBSD__) */
103 #endif /*! defined (__GNUC__) || defined (__GNU_LIBRARY__) */
104 #if !defined(PLATFORM_BYTE_ORDER)
105 #   if defined (LITTLE_ENDIAN) || defined (BIG_ENDIAN)
106 #       if defined (LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
107 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
108 #       elif !defined (LITTLE_ENDIAN) && defined (BIG_ENDIAN)
109 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
110 #       elif defined (BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)
111 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
112 #       elif defined (BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
113 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
114 #       endif /*! defined (LITTLE_ENDIAN) && !defined(BIG_ENDIAN) */
115 #   elif defined (_LITTLE_ENDIAN) || defined (_BIG_ENDIAN)
116 #       if defined (_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
117 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
118 #       elif !defined (_LITTLE_ENDIAN) && defined (_BIG_ENDIAN)
119 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
120 #       elif defined (_BYTE_ORDER) && (_BYTE_ORDER == _LITTLE_ENDIAN)
121 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
122 #       elif defined (_BYTE_ORDER) && (_BYTE_ORDER == _BIG_ENDIAN)
123 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
124 #       endif /*! defined (_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) */
125 #   elif defined (__LITTLE_ENDIAN__) || defined (__BIG_ENDIAN__)
126 #       if defined (__LITTLE_ENDIAN__) && !defined (__BIG_ENDIAN__)
127 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
128 #       elif !defined (__LITTLE_ENDIAN__) && defined (__BIG_ENDIAN__)
129 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
130 #       elif defined (__BYTE_ORDER__) && (__BYTE_ORDER__ == __LITTLE_ENDIAN__)
131 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
132 #       elif defined (__BYTE_ORDER__) && (__BYTE_ORDER__ == __BIG_ENDIAN__)
133 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
134 #       endif /*! defined (__LITTLE_ENDIAN__) && !defined (__BIG_ENDIAN__) */
135 #   endif /*! defined(LITTLE_ENDIAN) || defined (BIG_ENDIAN) */
136 #endif /*! !defined(PLATFORM_BYTE_ORDER) */
137 #if !defined (PLATFORM_BYTE_ORDER)
138 #   if   defined (__alpha__) || defined (__alpha)    || defined (i386)       || \
139          defined (__i386__)  || defined (_M_I86)     || defined (_M_IX86)    || \
140          defined (__OS2__)   || defined (sun386)     || defined (__TURBOC__) || \
141          defined (vax)       || defined (vms)        || defined (VMS)        || \
142          defined (__VMS)     || defined (__x86_64__) || defined (_M_IA64)    || \
143          defined (_M_X64)    || defined (__i386)     || defined (__x86_64)
144 #       define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
145 #   elif defined (AMIGA)     || defined (applec)     || defined (__AS400__)  || \
146          defined (_CRAY)     || defined (__hppa)     || defined (__hp9000)   || \
147          defined (ibm370)    || defined (mc68000)    || defined (m68k)       || \
148          defined (__MRC__)   || defined (__MVS__)    || defined (__MWERKS__) || \
149          defined (sparc)     || defined (__sparc)    || defined (SYMANTEC_C) || \
150          defined (__TANDEM)  || defined (THINK_C)    || defined (__VMCMS__)  || \
151          defined (__PPC__)   || defined (__PPC)      || defined (PPC)
152 #       define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
153 #   else
154 #       define PLATFORM_BYTE_ORDER -1
155 #   endif
156 #endif
157
158 #define GMQCC_ARRAY_COUNT(X) (sizeof(X) / sizeof((X)[0]))
159
160 /* stat.c */
161 char *stat_mem_strdup(const char *, bool);
162
163 #define mem_a(SIZE)              malloc(SIZE)
164 #define mem_d(PTRN)              free((void*)PTRN)
165 #define mem_r(PTRN, SIZE)        realloc((void*)PTRN, SIZE)
166
167 #define util_strdup(SRC)         stat_mem_strdup((char*)(SRC), false)
168 #define util_strdupe(SRC)        stat_mem_strdup((char*)(SRC), true)
169
170 #define util_isalpha(a) ((((unsigned)(a)|32)-'a') < 26)
171 #define util_isdigit(a) (((unsigned)(a)-'0') < 10)
172 #define util_islower(a) (((unsigned)(a)-'a') < 26)
173 #define util_isupper(a) (((unsigned)(a)-'A') < 26)
174 #define util_isprint(a) (((unsigned)(a)-0x20) < 0x5F)
175 #define util_isspace(a) (((a) >= 9 && (a) <= 13) || (a) == ' ')
176
177 bool  util_strupper(const char *);
178 bool  util_strdigit(const char *);
179
180 void  util_endianswap(void *, size_t, unsigned int);
181
182 size_t util_strtocmd         (const char *, char *, size_t);
183 size_t util_strtononcmd      (const char *, char *, size_t);
184 size_t util_optimizationtostr(const char *, char *, size_t);
185
186 uint16_t util_crc16(uint16_t crc, const char *data, size_t len);
187
188 void     util_seed(uint32_t);
189 uint32_t util_rand(void);
190
191 int      util_asprintf (char **ret, const char *fmt, ...);
192 int      util_sscanf   (const char *str, const char *format, ...);
193 char    *util_strncpy  (char *dest, const char *src, size_t n);
194 char    *util_strncat  (char *dest, const char *src, size_t n);
195 char    *util_strcat   (char *dest, const char *src);
196 const char *util_strerror(int err);
197
198 const struct tm *util_localtime(const time_t *timer);
199 const char      *util_ctime    (const time_t *timer);
200
201 bool             util_isatty(FILE *);
202 size_t           hash(const char *key);
203
204 /*
205  * A flexible vector implementation: all vector pointers contain some
206  * data about themselfs exactly - sizeof(vector_t) behind the pointer
207  * this data is represented in the structure below.  Doing this allows
208  * us to use the array [] to access individual elements from the vector
209  * opposed to using set/get methods.
210  */
211 struct vector_t {
212     size_t  allocated;
213     size_t  used;
214
215     /* can be extended now! whoot */
216 };
217
218 /* hidden interface */
219 void _util_vec_grow(void **a, size_t i, size_t s);
220 void _util_vec_delete(void *vec);
221
222 #define GMQCC_VEC_WILLGROW(X, Y) ( \
223     ((!(X) || vec_meta(X)->used + Y >= vec_meta(X)->allocated)) ? \
224         (void)_util_vec_grow(((void**)&(X)), (Y), sizeof(*(X))) : \
225         (void)0                                                   \
226 )
227
228 /* exposed interface */
229 #define vec_meta(A)       ((vector_t*)(((char *)(A)) - sizeof(vector_t)))
230 #define vec_free(A)       ((void)((A) ? (_util_vec_delete((void *)(A)), (A) = nullptr) : 0))
231 #define vec_push(A,V)     (GMQCC_VEC_WILLGROW((A),1), (A)[vec_meta(A)->used++] = (V))
232 #define vec_size(A)       ((A) ? vec_meta(A)->used : 0)
233 #define vec_add(A,N)      (GMQCC_VEC_WILLGROW((A),(N)), vec_meta(A)->used += (N), &(A)[vec_meta(A)->used-(N)])
234 #define vec_last(A)       ((A)[vec_meta(A)->used - 1])
235 #define vec_pop(A)        ((void)(vec_meta(A)->used -= 1))
236 #define vec_shrinkto(A,N) ((void)(vec_meta(A)->used  = (N)))
237 #define vec_shrinkby(A,N) ((void)(vec_meta(A)->used -= (N)))
238 #define vec_append(A,N,S) ((void)(memcpy(vec_add((A), (N)), (S), (N) * sizeof(*(S)))))
239 #define vec_remove(A,I,N) ((void)(memmove((A)+(I),(A)+((I)+(N)),sizeof(*(A))*(vec_meta(A)->used-(I)-(N))),vec_meta(A)->used-=(N)))
240
241 typedef struct hash_table_s {
242     size_t                size;
243     struct hash_node_t **table;
244 } hash_table_t, *ht;
245
246 hash_table_t *util_htnew (size_t size);
247 void util_htrem(hash_table_t *ht, void (*callback)(void *data));
248 void util_htset(hash_table_t *ht, const char *key, void *value);
249 void util_htdel(hash_table_t *ht);
250 size_t util_hthash(hash_table_t *ht, const char *key);
251 void util_htseth(hash_table_t *ht, const char *key, size_t hash, void *value);
252 void util_htrmh(hash_table_t *ht, const char *key, size_t bin, void (*cb)(void*));
253 void util_htrm(hash_table_t *ht, const char *key, void (*cb)(void*));
254 void *util_htget(hash_table_t *ht, const char *key);
255 void *util_htgeth(hash_table_t *ht, const char *key, size_t hash);
256 int util_snprintf(char *str, size_t, const char *fmt, ...);
257 int util_getline(char  **, size_t *, FILE *);
258
259 /* code.c */
260
261 /* Note: if you change the order, fix type_sizeof in ir.c */
262 enum {
263     TYPE_VOID     ,
264     TYPE_STRING   ,
265     TYPE_FLOAT    ,
266     TYPE_VECTOR   ,
267     TYPE_ENTITY   ,
268     TYPE_FIELD    ,
269     TYPE_FUNCTION ,
270     TYPE_POINTER  ,
271     TYPE_INTEGER  ,
272     TYPE_VARIANT  ,
273     TYPE_STRUCT   ,
274     TYPE_UNION    ,
275     TYPE_ARRAY    ,
276
277     TYPE_NIL      , /* it's its own type / untyped */
278     TYPE_NOEXPR   , /* simply invalid in expressions */
279
280     TYPE_COUNT
281 };
282
283 /* const/var qualifiers */
284 #define CV_NONE   0
285 #define CV_CONST  1
286 #define CV_VAR   -1
287 #define CV_WRONG  0x8000 /* magic number to help parsing */
288
289 extern const char    *type_name        [TYPE_COUNT];
290 extern const uint16_t type_store_instr [TYPE_COUNT];
291 extern const uint16_t field_store_instr[TYPE_COUNT];
292
293 /*
294  * could use type_store_instr + INSTR_STOREP_F - INSTR_STORE_F
295  * but this breaks when TYPE_INTEGER is added, since with the enhanced
296  * instruction set, the old ones are left untouched, thus the _I instructions
297  * are at a seperate place.
298  */
299 extern const uint16_t type_storep_instr[TYPE_COUNT];
300 extern const uint16_t type_eq_instr    [TYPE_COUNT];
301 extern const uint16_t type_ne_instr    [TYPE_COUNT];
302 extern const uint16_t type_not_instr   [TYPE_COUNT];
303
304 struct prog_section_t {
305     uint32_t offset;      /* Offset in file of where data begins  */
306     uint32_t length;      /* Length of section (how many of)      */
307 };
308
309 struct prog_header_t {
310     uint32_t       version;      /* Program version (6)     */
311     uint16_t       crc16;
312     uint16_t       skip;
313
314     prog_section_t statements;   /* prog_section_statement  */
315     prog_section_t defs;         /* prog_section_def        */
316     prog_section_t fields;       /* prog_section_field      */
317     prog_section_t functions;    /* prog_section_function   */
318     prog_section_t strings;
319     prog_section_t globals;
320     uint32_t       entfield;     /* Number of entity fields */
321 };
322
323 /*
324  * Each paramater incerements by 3 since vector types hold
325  * 3 components (x,y,z).
326  */
327 #define OFS_NULL      0
328 #define OFS_RETURN    1
329 #define OFS_PARM0     (OFS_RETURN+3)
330 #define OFS_PARM1     (OFS_PARM0 +3)
331 #define OFS_PARM2     (OFS_PARM1 +3)
332 #define OFS_PARM3     (OFS_PARM2 +3)
333 #define OFS_PARM4     (OFS_PARM3 +3)
334 #define OFS_PARM5     (OFS_PARM4 +3)
335 #define OFS_PARM6     (OFS_PARM5 +3)
336 #define OFS_PARM7     (OFS_PARM6 +3)
337
338 union operand_t {
339     int16_t s1;
340     uint16_t u1;
341 };
342
343 struct prog_section_statement_t {
344     uint16_t opcode;
345     operand_t o1;
346     operand_t o2;
347     operand_t o3;
348 };
349
350 struct prog_section_both_t {
351     /*
352      * The types:
353      * 0 = ev_void
354      * 1 = ev_string
355      * 2 = ev_float
356      * 3 = ev_vector
357      * 4 = ev_entity
358      * 5 = ev_field
359      * 6 = ev_function
360      * 7 = ev_pointer -- engine only
361      * 8 = ev_bad     -- engine only
362      */
363     uint16_t type;
364     uint16_t offset;
365     uint32_t name;
366 };
367
368 typedef prog_section_both_t prog_section_def_t;
369 typedef prog_section_both_t prog_section_field_t;
370
371 /* this is ORed to the type */
372 #define DEF_SAVEGLOBAL (1<<15)
373 #define DEF_TYPEMASK   ((1<<15)-1)
374
375 struct prog_section_function_t {
376     int32_t   entry;      /* in statement table for instructions  */
377     uint32_t  firstlocal; /* First local in local table           */
378     uint32_t  locals;     /* Total ints of params + locals        */
379     uint32_t  profile;    /* Always zero (engine uses this)       */
380     uint32_t  name;       /* name of function in string table     */
381     uint32_t  file;       /* file of the source file              */
382     int32_t   nargs;      /* number of arguments                  */
383     uint8_t   argsize[8]; /* size of arguments (keep 8 always?)   */
384 };
385
386 /*
387  * Instructions
388  * These are the external instructions supported by the interperter
389  * this is what things compile to (from the C code).
390  */
391 enum {
392     INSTR_DONE,
393     INSTR_MUL_F,
394     INSTR_MUL_V,
395     INSTR_MUL_FV, /* NOTE: the float operands must NOT be at the same locations: A != C */
396     INSTR_MUL_VF, /* and here: B != C */
397     INSTR_DIV_F,
398     INSTR_ADD_F,
399     INSTR_ADD_V,
400     INSTR_SUB_F,
401     INSTR_SUB_V,
402     INSTR_EQ_F,
403     INSTR_EQ_V,
404     INSTR_EQ_S,
405     INSTR_EQ_E,
406     INSTR_EQ_FNC,
407     INSTR_NE_F,
408     INSTR_NE_V,
409     INSTR_NE_S,
410     INSTR_NE_E,
411     INSTR_NE_FNC,
412     INSTR_LE,
413     INSTR_GE,
414     INSTR_LT,
415     INSTR_GT,
416     INSTR_LOAD_F,
417     INSTR_LOAD_V,
418     INSTR_LOAD_S,
419     INSTR_LOAD_ENT,
420     INSTR_LOAD_FLD,
421     INSTR_LOAD_FNC,
422     INSTR_ADDRESS,
423     INSTR_STORE_F,
424     INSTR_STORE_V,
425     INSTR_STORE_S,
426     INSTR_STORE_ENT,
427     INSTR_STORE_FLD,
428     INSTR_STORE_FNC,
429     INSTR_STOREP_F,
430     INSTR_STOREP_V,
431     INSTR_STOREP_S,
432     INSTR_STOREP_ENT,
433     INSTR_STOREP_FLD,
434     INSTR_STOREP_FNC,
435     INSTR_RETURN,
436     INSTR_NOT_F,
437     INSTR_NOT_V,
438     INSTR_NOT_S,
439     INSTR_NOT_ENT,
440     INSTR_NOT_FNC,
441     INSTR_IF,
442     INSTR_IFNOT,
443     INSTR_CALL0,
444     INSTR_CALL1,
445     INSTR_CALL2,
446     INSTR_CALL3,
447     INSTR_CALL4,
448     INSTR_CALL5,
449     INSTR_CALL6,
450     INSTR_CALL7,
451     INSTR_CALL8,
452     INSTR_STATE,
453     INSTR_GOTO,
454     INSTR_AND,
455     INSTR_OR,
456     INSTR_BITAND,
457     INSTR_BITOR,
458
459     /*
460      * Virtual instructions used by the IR
461      * Keep at the end!
462      */
463     VINSTR_END,
464     VINSTR_PHI,
465     VINSTR_JUMP,
466     VINSTR_COND,
467
468     /* A never returning CALL.
469      * Creating this causes IR blocks to be marked as 'final'.
470      * No-Return-Call
471      */
472     VINSTR_NRCALL,
473
474     /* Emulated instructions. */
475     VINSTR_BITAND_V, /* BITAND_V must be the first emulated bitop */
476     VINSTR_BITAND_VF,
477     VINSTR_BITOR_V,
478     VINSTR_BITOR_VF,
479     VINSTR_BITXOR,
480     VINSTR_BITXOR_V,
481     VINSTR_BITXOR_VF,
482     VINSTR_CROSS,
483     VINSTR_NEG_F,
484     VINSTR_NEG_V
485 };
486
487 /* TODO: elide */
488 extern const char *util_instr_str[VINSTR_END];
489
490 void util_swap_header(prog_header_t &code_header);
491 void util_swap_statements(std::vector<prog_section_statement_t> &statements);
492 void util_swap_defs_fields(std::vector<prog_section_both_t> &section);
493 void util_swap_functions(std::vector<prog_section_function_t> &functions);
494 void util_swap_globals(std::vector<int32_t> &globals);
495
496 typedef float qcfloat_t;
497 typedef int32_t qcint_t;
498 typedef uint32_t qcuint_t;
499
500 struct code_t {
501     std::vector<prog_section_statement_t> statements;
502     std::vector<int> linenums;
503     std::vector<int> columnnums;
504     std::vector<prog_section_def_t> defs;
505     std::vector<prog_section_field_t> fields;
506     std::vector<prog_section_function_t> functions;
507     std::vector<int> globals;
508     std::vector<char> chars;
509     uint16_t crc;
510     uint32_t entfields;
511     ht string_cache;
512     qcint_t string_cached_empty;
513 };
514
515 /*
516  * A shallow copy of a lex_file to remember where which ast node
517  * came from.
518  */
519 struct lex_ctx_t {
520     const char *file;
521     size_t line;
522     size_t column;
523 };
524
525 /*
526  * code_write          -- writes out the compiled file
527  * code_init           -- prepares the code file
528  * code_genstrin       -- generates string for code
529  * code_alloc_field    -- allocated a field
530  * code_push_statement -- keeps statements and linenumbers together
531  * code_pop_statement  -- keeps statements and linenumbers together
532  */
533 bool      code_write         (code_t *, const char *filename, const char *lno);
534 GMQCC_WARN
535 code_t   *code_init          (void);
536 void      code_cleanup       (code_t *);
537 uint32_t  code_genstring     (code_t *, const char *string);
538 qcint_t   code_alloc_field   (code_t *, size_t qcsize);
539 void      code_push_statement(code_t *, prog_section_statement_t *stmt, lex_ctx_t ctx);
540 void      code_pop_statement (code_t *);
541
542
543 /* conout.c */
544 enum {
545     CON_BLACK   = 30,
546     CON_RED,
547     CON_GREEN,
548     CON_BROWN,
549     CON_BLUE,
550     CON_MAGENTA,
551     CON_CYAN ,
552     CON_WHITE
553 };
554
555 /* message level */
556 enum {
557     LVL_MSG,
558     LVL_WARNING,
559     LVL_ERROR
560 };
561
562 FILE *con_default_out(void);
563 FILE *con_default_err(void);
564
565 void con_vprintmsg (int level, const char *name, size_t line, size_t column, const char *msgtype, const char *msg, va_list ap);
566 void con_printmsg  (int level, const char *name, size_t line, size_t column, const char *msgtype, const char *msg, ...);
567 void con_cvprintmsg(lex_ctx_t ctx, int lvl, const char *msgtype, const char *msg, va_list ap);
568 void con_cprintmsg (lex_ctx_t ctx, int lvl, const char *msgtype, const char *msg, ...);
569
570 void con_close (void);
571 void con_init  (void);
572 void con_reset (void);
573 void con_color (int);
574 int  con_verr  (const char *, va_list);
575 int  con_vout  (const char *, va_list);
576 int  con_err   (const char *, ...);
577 int  con_out   (const char *, ...);
578
579 /* error/warning interface */
580 extern size_t compile_errors;
581 extern size_t compile_Werrors;
582 extern size_t compile_warnings;
583
584 void /********/ compile_error   (lex_ctx_t ctx, /*LVL_ERROR*/ const char *msg, ...);
585 void /********/ vcompile_error  (lex_ctx_t ctx, /*LVL_ERROR*/ const char *msg, va_list ap);
586 bool GMQCC_WARN compile_warning (lex_ctx_t ctx, int warntype, const char *fmt, ...);
587 bool GMQCC_WARN vcompile_warning(lex_ctx_t ctx, int warntype, const char *fmt, va_list ap);
588 void            compile_show_werrors(void);
589
590 /* ir.c */
591 /* TODO: cleanup */
592 enum store_types {
593     store_global,
594     store_local,  /* local, assignable for now, should get promoted later */
595     store_param,  /* parameters, they are locals with a fixed position */
596     store_value,  /* unassignable */
597     store_return  /* unassignable, at OFS_RETURN */
598 };
599
600 struct vec3_t {
601     qcfloat_t x, y, z;
602 };
603
604 /* exec.c */
605
606 /* TODO: cleanup */
607 /*
608  * Darkplaces has (or will have) a 64 bit prog loader
609  * where the 32 bit qc program is autoconverted on load.
610  * Since we may want to support that as well, let's redefine
611  * float and int here.
612  */
613 typedef union {
614     qcint_t   _int;
615     qcint_t    string;
616     qcint_t    function;
617     qcint_t    edict;
618     qcfloat_t _float;
619     qcfloat_t vector[3];
620     qcint_t   ivector[3];
621 } qcany_t;
622
623 typedef char qcfloat_t_size_is_correct [sizeof(qcfloat_t) == 4 ?1:-1];
624 typedef char qcint_t_size_is_correct   [sizeof(qcint_t)   == 4 ?1:-1];
625
626 enum {
627     VMERR_OK,
628     VMERR_TEMPSTRING_ALLOC,
629     VMERR_END
630 };
631
632 #define VM_JUMPS_DEFAULT 1000000
633
634 /* execute-flags */
635 #define VMXF_DEFAULT 0x0000     /* default flags - nothing */
636 #define VMXF_TRACE   0x0001     /* trace: print statements before executing */
637 #define VMXF_PROFILE 0x0002     /* profile: increment the profile counters */
638
639 struct qc_program_t;
640 typedef int (*prog_builtin_t)(qc_program_t *prog);
641
642 struct qc_exec_stack_t {
643     qcint_t stmt;
644     size_t localsp;
645     prog_section_function_t *function;
646 };
647
648 struct qc_program_t {
649     char *filename;
650     std::vector<prog_section_statement_t> code;
651     std::vector<prog_section_def_t> defs;
652     std::vector<prog_section_def_t> fields;
653     std::vector<prog_section_function_t> functions;
654     std::vector<char> strings;
655     std::vector<qcint_t> globals;
656     qcint_t *entitydata;
657     bool *entitypool;
658
659     const char* *function_stack;
660
661     uint16_t crc16;
662
663     size_t tempstring_start;
664     size_t tempstring_at;
665
666     qcint_t  vmerror;
667
668     size_t *profile;
669
670     prog_builtin_t *builtins;
671     size_t          builtins_count;
672
673     /* size_t ip; */
674     qcint_t  entities;
675     size_t entityfields;
676     bool   allowworldwrites;
677
678     qcint_t         *localstack;
679     qc_exec_stack_t *stack;
680     size_t statement;
681
682     size_t xflags;
683
684     int    argc; /* current arg count for debugging */
685
686     /* cached fields */
687     struct {
688         qcint_t frame;
689         qcint_t nextthink;
690         qcint_t think;
691     } cached_fields;
692
693     struct {
694         qcint_t self;
695         qcint_t time;
696     } cached_globals;
697
698     bool supports_state; /* is INSTR_STATE supported? */
699 };
700
701 qc_program_t*       prog_load      (const char *filename, bool ignoreversion);
702 void                prog_delete    (qc_program_t *prog);
703 bool                prog_exec      (qc_program_t *prog, prog_section_function_t *func, size_t flags, long maxjumps);
704 const char*         prog_getstring (qc_program_t *prog, qcint_t str);
705 prog_section_def_t* prog_entfield  (qc_program_t *prog, qcint_t off);
706 prog_section_def_t* prog_getdef    (qc_program_t *prog, qcint_t off);
707 qcany_t*            prog_getedict  (qc_program_t *prog, qcint_t e);
708 qcint_t             prog_tempstring(qc_program_t *prog, const char *_str);
709
710
711 /* parser.c */
712 struct parser_t;
713 parser_t *parser_create(void);
714 bool parser_compile_file(parser_t *parser, const char *);
715 bool parser_compile_string(parser_t *parser, const char *, const char *, size_t);
716 bool parser_finish(parser_t *parser, const char *);
717 void parser_cleanup(parser_t *parser);
718
719 /* ftepp.c */
720 struct ftepp_t;
721 ftepp_t *ftepp_create           (void);
722 bool ftepp_preprocess_file  (ftepp_t *ftepp, const char *filename);
723 bool ftepp_preprocess_string(ftepp_t *ftepp, const char *name, const char *str);
724 void ftepp_finish(ftepp_t *ftepp);
725 const char *ftepp_get(ftepp_t *ftepp);
726 void ftepp_flush(ftepp_t *ftepp);
727 void ftepp_add_define(ftepp_t *ftepp, const char *source, const char *name);
728 void ftepp_add_macro(ftepp_t *ftepp, const char *name,   const char *value);
729
730 /* main.c */
731
732 #if 1
733 /* Helpers to allow for a whole lot of flags. Otherwise we'd limit
734  * to 32 or 64 -f options...
735  */
736 struct longbit {
737     size_t  idx; /* index into an array of 32 bit words */
738     uint8_t bit; /* bit index for the 8 bit group idx points to */
739 };
740 #define LONGBIT(bit) { ((bit)/32), ((bit)%32) }
741 #define LONGBIT_SET(B, I) ((B).idx = (I)/32, (B).bit = ((I)%32))
742 #else
743 typedef uint32_t longbit;
744 #define LONGBIT(bit) (bit)
745 #define LONGBIT_SET(B, I) ((B) = (I))
746 #endif
747
748 /* utf.8 */
749 typedef long utf8ch_t;
750 int utf8_from(char *, utf8ch_t);
751 int utf8_to(utf8ch_t *, const unsigned char *, size_t);
752
753 /* opts.c */
754 struct opts_flag_def_t {
755     const char *name;
756     longbit     bit;
757 };
758
759 bool opts_setflag  (const char *, bool);
760 bool opts_setwarn  (const char *, bool);
761 bool opts_setwerror(const char *, bool);
762 bool opts_setoptim (const char *, bool);
763
764 void opts_init         (const char *, int, size_t);
765 void opts_set          (uint32_t   *, size_t, bool);
766 void opts_setoptimlevel(unsigned int);
767 void opts_ini_init     (const char *);
768
769 /* Saner flag handling */
770 void opts_backup_non_Wall(void);
771 void opts_restore_non_Wall(void);
772 void opts_backup_non_Werror_all(void);
773 void opts_restore_non_Werror_all(void);
774
775
776 enum {
777 # define GMQCC_TYPE_FLAGS
778 # define GMQCC_DEFINE_FLAG(X) X,
779 #  include "opts.def"
780     COUNT_FLAGS
781 };
782
783 enum {
784 # define GMQCC_TYPE_WARNS
785 # define GMQCC_DEFINE_FLAG(X) WARN_##X,
786 #  include "opts.def"
787     COUNT_WARNINGS
788 };
789
790 enum {
791 # define GMQCC_TYPE_OPTIMIZATIONS
792 # define GMQCC_DEFINE_FLAG(NAME, MIN_O) OPTIM_##NAME,
793 #  include "opts.def"
794     COUNT_OPTIMIZATIONS
795 };
796
797 enum {
798 #   define GMQCC_TYPE_OPTIONS
799 #   define GMQCC_DEFINE_FLAG(X) OPTION_##X,
800 #   include "opts.def"
801     OPTION_COUNT
802 };
803
804 extern const opts_flag_def_t opts_flag_list[COUNT_FLAGS+1];
805 extern const opts_flag_def_t opts_warn_list[COUNT_WARNINGS+1];
806 extern const opts_flag_def_t opts_opt_list[COUNT_OPTIMIZATIONS+1];
807 extern const unsigned int    opts_opt_oflag[COUNT_OPTIMIZATIONS+1];
808 extern unsigned int          opts_optimizationcount[COUNT_OPTIMIZATIONS];
809
810 /* other options: */
811 enum {
812     COMPILER_QCC,     /* circa  QuakeC */
813     COMPILER_FTEQCC,  /* fteqcc QuakeC */
814     COMPILER_QCCX,    /* qccx   QuakeC */
815     COMPILER_GMQCC    /* this   QuakeC */
816 };
817
818 struct opt_value_t {
819     union {
820         bool b;
821         uint16_t u16;
822         uint32_t u32;
823         union {
824             char *p;
825             const char *c;
826         } str;
827     } data;
828     bool allocated;
829 };
830
831 struct opts_cmd_t {
832     opt_value_t  options      [OPTION_COUNT];
833     uint32_t     flags        [1 + (COUNT_FLAGS         / 32)];
834     uint32_t     warn         [1 + (COUNT_WARNINGS      / 32)];
835     uint32_t     werror       [1 + (COUNT_WARNINGS      / 32)];
836     uint32_t     warn_backup  [1 + (COUNT_WARNINGS      / 32)];
837     uint32_t     werror_backup[1 + (COUNT_WARNINGS      / 32)];
838     uint32_t     optimization [1 + (COUNT_OPTIMIZATIONS / 32)];
839     bool         optimizeoff; /* True when -O0 */
840 };
841
842 extern opts_cmd_t opts;
843
844 #define OPTS_GENERIC(f,i)    (!! (((f)[(i)/32]) & (1U << (unsigned)((i)%32))))
845
846 #define OPTS_FLAG(i)         OPTS_GENERIC(opts.flags,        (i))
847 #define OPTS_WARN(i)         OPTS_GENERIC(opts.warn,         (i))
848 #define OPTS_WERROR(i)       OPTS_GENERIC(opts.werror,       (i))
849 #define OPTS_OPTIMIZATION(i) OPTS_GENERIC(opts.optimization, (i))
850
851 #define OPTS_OPTION_DUPED(X) (opts.options[X].allocated)
852 #define OPTS_OPTION_BOOL(X)  (opts.options[X].data.b)
853 #define OPTS_OPTION_U16(X)   (opts.options[X].data.u16)
854 #define OPTS_OPTION_U32(X)   (opts.options[X].data.u32)
855 #define OPTS_OPTION_STR(X)   (opts.options[X].data.str.c)
856 #define OPTS_OPTION_DUP(X)  *(OPTS_OPTION_DUPED(X)=true, &(opts.options[X].data.str.p))
857
858 #endif /*! GMQCC_HDR */