]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - gmqcc.h
Merge branch 'master' into ast-and-ir
[xonotic/gmqcc.git] / gmqcc.h
diff --git a/gmqcc.h b/gmqcc.h
index 09311cc7bdf91d75f19388a0531bbb66a9b7e3e6..583726e4a932cde7a9dfde903dc354211a5fa34d 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -1,6 +1,6 @@
 /*
- * Copyright (C) 2012 
- *     Dale Weiler
+ * Copyright (C) 2012
+ *     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
 #else
 #   define GMQCC_WARN
 #endif
+/*
+ * This is a hack to silent clang regarding empty
+ * body if statements.
+ */
+#define GMQCC_SUPRESS_EMPTY_BODY do { } while (0)
 
 /*
  * stdint.h and inttypes.h -less subset
@@ -86,7 +91,7 @@
     typedef int            int16_t;
     typedef unsigned int   uint16_t;
 #endif
-#if   INT_MAX   == 0x7FFFFFFF 
+#if   INT_MAX   == 0x7FFFFFFF
     typedef int            int32_t;
     typedef unsigned int   uint32_t;
 #elif LONG_MAX  == 0x7FFFFFFF
 #else
     typedef unsigned int   uintptr_t;
     typedef int            intptr_t;
-#endif 
+#endif
 /* Ensure type sizes are correct: */
 typedef char uint8_size_is_correct  [sizeof(uint8_t)  == 1?1:-1];
 typedef char uint16_size_if_correct [sizeof(uint16_t) == 2?1:-1];
 typedef char uint32_size_is_correct [sizeof(uint32_t) == 4?1:-1];
-//typedef char int8_size_is_correct   [sizeof(int8_t)   == 1?1:-1];
 typedef char int16_size_if_correct  [sizeof(int16_t)  == 2?1:-1];
 typedef char int32_size_is_correct  [sizeof(int32_t)  == 4?1:-1];
 /* intptr_t / uintptr_t correct size check */
@@ -114,18 +118,18 @@ typedef char intptr_size_is_correct [sizeof(uintptr_t)== sizeof(int*)?1:-1];
 //===================================================================
 //============================ lex.c ================================
 //===================================================================
-struct lex_file {
+typedef struct lex_file_t {
     FILE *file;        /* file handler */
     char *name;        /* name of file */
-    char  peek  [5];  
+    char  peek  [5];
     char  lastok[8192];
-    
+
     int   last;    /* last token                   */
     int   current; /* current token                */
     int   length;  /* bytes left to parse          */
     int   size;    /* never changes (size of file) */
     int   line;    /* what line are we on?         */
-};
+} lex_file;
 
 /*
  * It's important that this table never exceed 32 keywords, the ascii
@@ -159,17 +163,18 @@ enum {
  * and > the last type token which is TOKEN_VOID
  */
 enum {
-    LEX_COMMENT = 1128, 
+    LEX_COMMENT = 1128,
     LEX_CHRLIT        ,
     LEX_STRLIT        ,
     LEX_IDENT
 };
 
-int              lex_token  (struct lex_file *);
-void             lex_reset  (struct lex_file *);
-void             lex_close  (struct lex_file *);
-struct lex_file *lex_include(struct lex_file *, char *);
-struct lex_file *lex_open   (FILE *);
+int       lex_token  (lex_file *);
+void      lex_reset  (lex_file *);
+void      lex_close  (lex_file *);
+void      lex_parse  (lex_file *);
+lex_file *lex_include(lex_file *, const char *);
+void      lex_init   (const char *, lex_file **);
 
 //===================================================================
 //========================== error.c ================================
@@ -179,12 +184,12 @@ struct lex_file *lex_open   (FILE *);
 #define ERROR_INTERNAL (SHRT_MAX+2)
 #define ERROR_COMPILER (SHRT_MAX+3)
 #define ERROR_PREPRO   (SHRT_MAX+4)
-int error(struct lex_file *, int, const char *, ...);
+int error(lex_file *, int, const char *, ...);
 
 //===================================================================
 //========================== parse.c ================================
 //===================================================================
-int parse_gen(struct lex_file *);
+int parse_gen(lex_file *);
 
 //===================================================================
 //========================== typedef.c ==============================
@@ -196,7 +201,7 @@ typedef struct typedef_node_t {
 void          typedef_init();
 void          typedef_clear();
 typedef_node *typedef_find(const char *);
-int           typedef_add (struct lex_file *file, const char *, const char *);
+int           typedef_add (lex_file *file, const char *, const char *);
 
 
 //===================================================================
@@ -206,14 +211,18 @@ void *util_memory_a      (unsigned int, unsigned int, const char *);
 void  util_memory_d      (void       *, unsigned int, const char *);
 void  util_meminfo       ();
 
+bool  util_strupper      (const char *);
+bool  util_strdigit      (const char *);
 char *util_strdup        (const char *);
-char *util_strrq         (char *);
-char *util_strrnl        (char *);
+char *util_strrq         (const char *);
+char *util_strrnl        (const char *);
+char *util_strsws        (const char *);
+char *util_strchp        (const char *, const char *);
 void  util_debug         (const char *, const char *, ...);
 int   util_getline       (char **, size_t *, FILE *);
 void  util_endianswap    (void *,  int, int);
 
-uint32_t util_crc32(const char *, int, register const short); 
+uint32_t util_crc32(const char *, int, register const short);
 
 #ifdef NOTRACK
 #    define mem_a(x) malloc(x)
@@ -224,6 +233,8 @@ uint32_t util_crc32(const char *, int, register const short);
 #endif
 
 /* Builds vector type (usefull for inside structures) */
+#define VECTOR_SNAP(X,Y) X ## Y
+#define VECTOR_FILL(X,Y) VECTOR_SNAP(X,Y)
 #define VECTOR_TYPE(T,N)                                        \
     T*     N##_data      = NULL;                                \
     long   N##_elements  = 0;                                   \
@@ -254,13 +265,12 @@ uint32_t util_crc32(const char *, int, register const short);
         elements--;                                             \
         while (N##_add(*++elements) != -1 && len--);            \
         return N##_elements;                                    \
-    }
+    }                                                           \
+    typedef char VECTOR_FILL(extra_semicolon_,__COUNTER__)
 /* Builds a full vector inspot */
 #define VECTOR_MAKE(T,N) \
     VECTOR_TYPE(T,N);    \
     VECTOR_CORE(T,N)
-/* Builds a vector add function pointer for inside structures */
-#define VECTOR_IMPL(T,N) int (*N##_add)(T)
 
 //===================================================================
 //=========================== code.c ================================
@@ -273,7 +283,9 @@ enum {
     TYPE_ENTITY   ,
     TYPE_FIELD    ,
     TYPE_FUNCTION ,
-    TYPE_POINTER
+    TYPE_POINTER  ,
+    /* TYPE_INTEGER  , */
+    TYPE_VARIANT  ,
 };
 
 /*
@@ -293,23 +305,23 @@ enum {
 
 typedef struct {
     uint16_t opcode;
-    
+
     /* operand 1 */
     union {
         int16_t  s1; /* signed   */
         uint16_t u1; /* unsigned */
-    };
+    } o1;
     /* operand 2 */
     union {
         int16_t  s2; /* signed   */
         uint16_t u2; /* unsigned */
-    };
+    } o2;
     /* operand 3 */
     union {
         int16_t  s3; /* signed   */
         uint16_t u3; /* unsigned */
-    };
-    
+    } o3;
+
     /*
      * This is the same as the structure in darkplaces
      * {
@@ -351,8 +363,8 @@ typedef struct {
     uint8_t   argsize[8]; /* size of arguments (keep 8 always?)   */
 } prog_section_function;
 
-/* 
- * Instructions 
+/*
+ * Instructions
  * These are the external instructions supported by the interperter
  * this is what things compile to (from the C code).
  */
@@ -435,7 +447,7 @@ enum {
 /*
  * The symbols below are created by the following
  * expanded macros:
- * 
+ *
  * VECTOR_MAKE(prog_section_statement, code_statements);
  * VECTOR_MAKE(prog_section_def,       code_defs      );
  * VECTOR_MAKE(prog_section_field,     code_fields    );
@@ -474,7 +486,7 @@ void code_init  ();
 //===================================================================
 static const struct {
     const char  *m; /* menomic     */
-    const size_t o; /* operands    */ 
+    const size_t o; /* operands    */
     const size_t l; /* menomic len */
 } const asm_instr[] = {
     [INSTR_DONE]       = { "DONE"      , 1, 4 },
@@ -562,4 +574,135 @@ extern bool opts_memchk;
 extern bool opts_darkplaces_stringtablebug;
 extern bool opts_omit_nullcode;
 extern int  opts_compiler;
+//======================================================================
+//============================= ast.c ==================================
+//======================================================================
+#define MEM_VECTOR_PROTO(Towner, Tmem, mem)                   \
+    bool GMQCC_WARN Towner##_##mem##_add(Towner*, Tmem);      \
+    bool GMQCC_WARN Towner##_##mem##_remove(Towner*, size_t)
+
+#define MEM_VECTOR_PROTO_ALL(Towner, Tmem, mem)                    \
+    MEM_VECTOR_PROTO(Towner, Tmem, mem);                           \
+    bool GMQCC_WARN Towner##_##mem##_find(Towner*, Tmem, size_t*); \
+    void Towner##_##mem##_clear(Towner*)
+
+#define MEM_VECTOR_MAKE(Twhat, name) \
+    Twhat  *name;                    \
+    size_t name##_count;             \
+    size_t name##_alloc
+
+#define _MEM_VEC_FUN_ADD(Tself, Twhat, mem)                          \
+bool GMQCC_WARN Tself##_##mem##_add(Tself *self, Twhat f)            \
+{                                                                    \
+    Twhat *reall;                                                    \
+    if (self->mem##_count == self->mem##_alloc) {                    \
+        if (!self->mem##_alloc) {                                    \
+            self->mem##_alloc = 16;                                  \
+        } else {                                                     \
+            self->mem##_alloc *= 2;                                  \
+        }                                                            \
+        reall = (Twhat*)mem_a(sizeof(Twhat) * self->mem##_alloc);    \
+        if (!reall) {                                                \
+            return false;                                            \
+        }                                                            \
+        memcpy(reall, self->mem, sizeof(Twhat) * self->mem##_count); \
+        mem_d(self->mem);                                            \
+        self->mem = reall;                                           \
+    }                                                                \
+    self->mem[self->mem##_count++] = f;                              \
+    return true;                                                     \
+}
+
+#define _MEM_VEC_FUN_REMOVE(Tself, Twhat, mem)                       \
+bool GMQCC_WARN Tself##_##mem##_remove(Tself *self, size_t idx)      \
+{                                                                    \
+    size_t i;                                                        \
+    Twhat *reall;                                                    \
+    if (idx >= self->mem##_count) {                                  \
+        return true; /* huh... */                                    \
+    }                                                                \
+    for (i = idx; i < self->mem##_count-1; ++i) {                    \
+        self->mem[i] = self->mem[i+1];                               \
+    }                                                                \
+    self->mem##_count--;                                             \
+    if (self->mem##_count < self->mem##_count/2) {                   \
+        self->mem##_alloc /= 2;                                      \
+        reall = (Twhat*)mem_a(sizeof(Twhat) * self->mem##_count);    \
+        if (!reall) {                                                \
+            return false;                                            \
+        }                                                            \
+        memcpy(reall, self->mem, sizeof(Twhat) * self->mem##_count); \
+        mem_d(self->mem);                                            \
+        self->mem = reall;                                           \
+    }                                                                \
+    return true;                                                     \
+}
+
+#define _MEM_VEC_FUN_FIND(Tself, Twhat, mem)                    \
+bool GMQCC_WARN Tself##_##mem##_find(Tself *self, Twhat obj, size_t *idx) \
+{                                                               \
+    size_t i;                                                   \
+    for (i = 0; i < self->mem##_count; ++i) {                   \
+        if (self->mem[i] == obj) {                              \
+            if (idx) {                                          \
+                *idx = i;                                       \
+            }                                                   \
+            return true;                                        \
+        }                                                       \
+    }                                                           \
+    return false;                                               \
+}
+
+#define _MEM_VEC_FUN_CLEAR(Tself, mem)  \
+void Tself##_##mem##_clear(Tself *self) \
+{                                       \
+    if (!self->mem)                     \
+        return;                         \
+    mem_d((void*) self->mem);           \
+    self->mem = NULL;                   \
+    self->mem##_count = 0;              \
+    self->mem##_alloc = 0;              \
+}
+
+#define MEM_VECTOR_CLEAR(owner, mem)  \
+    if ((owner)->mem)                 \
+        mem_d((void*)((owner)->mem)); \
+    (owner)->mem = NULL;              \
+    (owner)->mem##_count = 0;         \
+    (owner)->mem##_alloc = 0
+
+#define MEM_VECTOR_INIT(owner, mem) \
+{                                   \
+    (owner)->mem = NULL;            \
+    (owner)->mem##_count = 0;       \
+    (owner)->mem##_alloc = 0;       \
+}
+
+#define MEM_VEC_FUNCTIONS(Tself, Twhat, mem) \
+_MEM_VEC_FUN_REMOVE(Tself, Twhat, mem)       \
+_MEM_VEC_FUN_ADD(Tself, Twhat, mem)
+
+#define MEM_VEC_FUNCTIONS_ALL(Tself, Twhat, mem) \
+MEM_VEC_FUNCTIONS(Tself, Twhat, mem)             \
+_MEM_VEC_FUN_CLEAR(Tself, mem)                   \
+_MEM_VEC_FUN_FIND(Tself, Twhat, mem)
+
+enum store_types {
+    store_global,
+    store_local,  /* local, assignable for now, should get promoted later */
+    store_value,  /* unassignable */
+};
+
+typedef struct {
+    float x, y, z;
+} vector;
+
+/*
+ * 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;
 #endif