X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=gmqcc.h;h=d28452659c2398f762f92c2773067f2cb68b435f;hb=1d6594a4913ee02c25e352391ed0a1d353a3a7de;hp=e16b4954859f80bce2b78de72bd5cc42350b077d;hpb=69173876f11da6ea695f7d518d5036ddcf5179a6;p=xonotic%2Fgmqcc.git diff --git a/gmqcc.h b/gmqcc.h index e16b495..d284526 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 - * Dale Weiler + * 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 @@ -58,6 +58,17 @@ # endif # endif /* !__cplusplus */ +/* + * Of some functions which are generated we want to make sure + * that the result isn't ignored. To find such function calls, + * we use this macro. + */ +#if defined(__GNUC__) || defined(__CLANG__) +# define GMQCC_WARN __attribute__((warn_unused_result)) +#else +# define GMQCC_WARN +#endif + /* * stdint.h and inttypes.h -less subset * for systems that don't have it, which we must @@ -93,7 +104,6 @@ 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 */ @@ -103,7 +113,7 @@ 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]; @@ -114,7 +124,7 @@ struct lex_file { 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 @@ -154,11 +164,12 @@ enum { 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 ================================ @@ -168,12 +179,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 ============================== @@ -185,7 +196,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 *); //=================================================================== @@ -195,9 +206,13 @@ 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); @@ -213,6 +228,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; \ @@ -243,7 +260,8 @@ 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); \ @@ -262,7 +280,9 @@ enum { TYPE_ENTITY , TYPE_FIELD , TYPE_FUNCTION , - TYPE_POINTER + TYPE_POINTER , + /* TYPE_INTEGER , */ + TYPE_VARIANT , }; /* @@ -287,17 +307,17 @@ typedef struct { 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 @@ -551,4 +571,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; \ + free((void*) self->mem); \ + self->mem = NULL; \ + self->mem##_count = 0; \ + self->mem##_alloc = 0; \ +} + +#define MEM_VECTOR_CLEAR(owner, mem) \ + if ((owner)->mem) \ + free((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