]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - gmqcc.h
Keep track of the beginning of a block
[xonotic/gmqcc.git] / gmqcc.h
diff --git a/gmqcc.h b/gmqcc.h
index 1ea2ceff8bb472286c8bc3982d1f785fdb4dcc9e..33346cef93e091c9f4f8c71736cc5f15218bdd09 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2012
- *     Dale Weiler, Wolfgang Bumiller
+ *     Dale Weiler
+ *     Wolfgang Bumiller
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy of
  * this software and associated documentation files (the "Software"), to deal in
@@ -41,7 +42,7 @@
 #endif
 
 #define GMQCC_VERSION_MAJOR 0
-#define GMQCC_VERSION_MINOR 1
+#define GMQCC_VERSION_MINOR 2
 #define GMQCC_VERSION_PATCH 0
 #define GMQCC_VERSION_BUILD(J,N,P) (((J)<<16)|((N)<<8)|(P))
 #define GMQCC_VERSION \
 #    else
 #       define GMQCC_INLINE inline
 #    endif
+/*
+ * Visual studio has __forcinline we can use.  So lets use that
+ * I suspect it also has just __inline of some sort, but our use
+ * of inline is correct (not guessed), WE WANT IT TO BE INLINE
+ */
+#elseif defined(_MSC_VER)
+#    define GMQCC_INLINE __forceinline
 #else
 #    define GMQCC_INLINE
 #endif /* !__STDC_VERSION__ */
 
 
 #if defined(__GNUC__) || defined (__CLANG__)
-       typedef int          int64_t  __attribute__((__mode__(__DI__)));
-       typedef unsigned int uint64_t __attribute__((__mode__(__DI__)));
+       typedef int              int64_t  __attribute__((__mode__(__DI__)));
+       typedef unsigned int     uint64_t __attribute__((__mode__(__DI__)));
 #elif defined(_MSC_VER)
        typedef __int64          int64_t;
        typedef unsigned __int64 uint64_t;
 #else
     /*
-    * Incoorectly size the types so static assertions below will
+    * Incorrectly size the types so static assertions below will
     * fail.  There is no valid way to get a 64bit type at this point
     * without making assumptions of too many things.
     */
@@ -196,6 +204,7 @@ void  util_memory_d      (void       *, unsigned int, const char *);
 void *util_memory_r      (void       *, size_t,       unsigned int, const char *);
 void  util_meminfo       ();
 
+bool  util_filexists     (const char *);
 bool  util_strupper      (const char *);
 bool  util_strdigit      (const char *);
 bool  util_strncmpexact  (const char *, const char *, size_t);
@@ -233,27 +242,69 @@ uint32_t util_crc32(uint32_t crc, const char *data, size_t len);
 #define INT2FLT(Y) *((float  *)&(Y))
 
 /* New flexible vector implementation from Dale */
-#define _vec_raw(A) (((size_t*)(A)) - 2)
+#define _vec_raw(A) (((size_t*)(void*)(A)) - 2)
 #define _vec_beg(A) (_vec_raw(A)[0])
 #define _vec_end(A) (_vec_raw(A)[1])
 #define _vec_needsgrow(A,N) ((!(A)) || (_vec_end(A) + (N) >= _vec_beg(A)))
-#define _vec_mightgrow(A,N) (_vec_needsgrow((A), (N)) ? _vec_forcegrow((A),(N)) : 0)
-#define _vec_forcegrow(A,N) _util_vec_grow((void**)&(A), (N), sizeof(*(A)))
-#define _vec_remove(A,S,I,N) (memmove((char*)(A)+(I)*(S),(char*)(A)+((I)+(N))*(S),(S)*(vec_size(A)-(I)-(N))), _vec_end(A)-=(N))
+#define _vec_mightgrow(A,N) (_vec_needsgrow((A), (N)) ? (void)_vec_forcegrow((A),(N)) : (void)0)
+#define _vec_forcegrow(A,N) _util_vec_grow(((void**)&(A)), (N), sizeof(*(A)))
+#define _vec_remove(A,S,I,N) (memmove((char*)(A)+(I)*(S),(char*)(A)+((I)+(N))*(S),(S)*(_vec_end(A)-(I)-(N))), _vec_end(A)-=(N))
 void _util_vec_grow(void **a, size_t i, size_t s);
 /* exposed interface */
-#define vec_free(A)          ((A) ? (mem_d(_vec_raw(A)), (A) = NULL) : 0)
+#define vec_free(A)          ((A) ? (mem_d((void*)_vec_raw(A)), (A) = NULL) : 0)
 #define vec_push(A,V)        (_vec_mightgrow((A),1), (A)[_vec_end(A)++] = (V))
 #define vec_size(A)          ((A) ? _vec_end(A) : 0)
 #define vec_add(A,N)         (_vec_mightgrow((A),(N)), _vec_end(A)+=(N), &(A)[_vec_end(A)-(N)])
 #define vec_last(A)          ((A)[_vec_end(A)-1])
 #define vec_append(A,N,S)    memcpy(vec_add((A), (N)), (S), N * sizeof(*(S)))
 #define vec_remove(A,I,N)    _vec_remove((A), sizeof(*(A)), (I), (N))
-#define vec_pop(A)           vec_remove((A), _vec_end(A)-1, 1)
+#define vec_pop(A)           (_vec_end(A)-=1)
 /* these are supposed to NOT reallocate */
 #define vec_shrinkto(A,N)    (_vec_end(A) = (N))
 #define vec_shrinkby(A,N)    (_vec_end(A) -= (N))
 
+typedef struct hash_table_t {
+    size_t                size;
+    struct hash_node_t **table;
+} hash_table_t, *ht;
+
+/*
+ * hashtable implementation:
+ *
+ * Note:
+ *      This was designed for pointers:  you manage the life of the object yourself
+ *      if you do use this for non-pointers please be warned that the object may not
+ *      be valid if the duration of it exceeds (i.e on stack).  So you need to allocate
+ *      yourself, or put those in global scope to ensure duration is for the whole
+ *      runtime.
+ *
+ * util_htnew(size)                             -- to make a new hashtable
+ * util_htset(table, key, value, sizeof(value)) -- to set something in the table
+ * util_htget(table, key)                       -- to get something from the table
+ * util_htdel(table)                            -- to delete the table
+ *
+ * example of use:
+ *
+ * ht    foo  = util_htnew(1024);
+ * int   data = 100;
+ * char *test = "hello world\n";
+ * util_htset(foo, "foo", (void*)&data);
+ * util_gtset(foo, "bar", (void*)test);
+ *
+ * printf("foo: %d, bar %s",
+ *     *((int *)util_htget(foo, "foo")),
+ *      ((char*)util_htget(foo, "bar"))
+ * );
+ *
+ * util_htdel(foo);
+ */
+hash_table_t *util_htnew (size_t size);
+void          util_htset (hash_table_t *ht, const char *key, void *value);
+void         *util_htget (hash_table_t *ht, const char *key);
+void          util_htdel (hash_table_t *ht);
+size_t        util_hthash(hash_table_t *ht, const char *key);
+void         *util_htgeth(hash_table_t *ht, const char *key, size_t hash);
+void          util_htseth(hash_table_t *ht, const char *key, size_t hash, void *value);
 /*===================================================================*/
 /*=========================== code.c ================================*/
 /*===================================================================*/
@@ -277,6 +328,11 @@ enum {
     TYPE_COUNT
 };
 
+/* const/var qualifiers */
+#define CV_NONE  0
+#define CV_CONST 1
+#define CV_VAR  -1
+
 extern const char *type_name[TYPE_COUNT];
 
 extern size_t type_sizeof[TYPE_COUNT];
@@ -291,6 +347,7 @@ extern uint16_t type_storep_instr[TYPE_COUNT];
 /* other useful lists */
 extern uint16_t type_eq_instr[TYPE_COUNT];
 extern uint16_t type_ne_instr[TYPE_COUNT];
+extern uint16_t type_not_instr[TYPE_COUNT];
 
 typedef struct {
     uint32_t offset;      /* Offset in file of where data begins  */
@@ -500,6 +557,16 @@ uint32_t code_genstring   (const char *string);
 uint32_t code_cachedstring(const char *string);
 qcint    code_alloc_field (size_t qcsize);
 
+/*
+ * A shallow copy of a lex_file to remember where which ast node
+ * came from.
+ */
+typedef struct {
+    const char *file;
+    size_t      line;
+} lex_ctx;
+
+
 /*===================================================================*/
 /*============================ con.c ================================*/
 /*===================================================================*/
@@ -537,6 +604,13 @@ int  con_vout  (const char *fmt, va_list va);
 int  con_err   (const char *fmt, ...);
 int  con_out   (const char *fmt, ...);
 
+/* error/warning interface */
+extern size_t compile_errors;
+extern size_t compile_warnings;
+
+void compile_error(lex_ctx ctx, const char *msg, ...);
+bool GMQCC_WARN compile_warning(lex_ctx ctx, int warntype, const char *fmt, ...);
+
 /*===================================================================*/
 /*========================= assembler.c =============================*/
 /*===================================================================*/
@@ -635,15 +709,6 @@ vector  vec3_sub  (vector, vector);
 qcfloat vec3_mulvv(vector, vector);
 vector  vec3_mulvf(vector, float);
 
-/*
- * A shallow copy of a lex_file to remember where which ast node
- * came from.
- */
-typedef struct {
-    const char *file;
-    size_t      line;
-} lex_ctx;
-
 /*===================================================================*/
 /*============================= exec.c ==============================*/
 /*===================================================================*/
@@ -763,6 +828,7 @@ bool ftepp_preprocess_string(const char *name, const char *str);
 void ftepp_finish           ();
 const char *ftepp_get       ();
 void ftepp_flush            ();
+void ftepp_add_define       (const char *source, const char *name);
 
 /*===================================================================*/
 /*======================= main.c commandline ========================*/
@@ -816,6 +882,26 @@ static const opts_flag_def opts_warn_list[] = {
     { NULL, LONGBIT(0) }
 };
 
+enum {
+# define GMQCC_TYPE_OPTIMIZATIONS
+# define GMQCC_DEFINE_FLAG(NAME, MIN_O) OPTIM_##NAME,
+#  include "opts.def"
+    COUNT_OPTIMIZATIONS
+};
+static const opts_flag_def opts_opt_list[] = {
+# define GMQCC_TYPE_OPTIMIZATIONS
+# define GMQCC_DEFINE_FLAG(NAME, MIN_O) { #NAME, LONGBIT(OPTIM_##NAME) },
+#  include "opts.def"
+    { NULL, LONGBIT(0) }
+};
+static const unsigned int opts_opt_oflag[] = {
+# define GMQCC_TYPE_OPTIMIZATIONS
+# define GMQCC_DEFINE_FLAG(NAME, MIN_O) MIN_O,
+#  include "opts.def"
+    0
+};
+extern unsigned int optimization_count[COUNT_OPTIMIZATIONS];
+
 /* other options: */
 enum {
     COMPILER_QCC,     /* circa  QuakeC */
@@ -828,6 +914,7 @@ extern const char *opts_output; /* -o file */
 extern int         opts_standard;
 extern bool        opts_debug;
 extern bool        opts_memchk;
+extern bool        opts_dumpfin;
 extern bool        opts_dump;
 extern bool        opts_werror;
 extern bool        opts_forcecrc;
@@ -840,5 +927,7 @@ extern size_t      opts_max_array_size;
 extern uint32_t opts_flags[1 + (COUNT_FLAGS / 32)];
 #define OPTS_WARN(i) (!! (opts_warn[(i)/32] & (1<< ((i)%32))))
 extern uint32_t opts_warn[1 + (COUNT_WARNINGS / 32)];
+#define OPTS_OPTIMIZATION(i) (!! (opts_optimization[(i)/32] & (1<< ((i)%32))))
+extern uint32_t opts_optimization[1 + (COUNT_OPTIMIZATIONS / 32)];
 
 #endif