#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include <stdarg.h>
#include <ctype.h>
+/*
+ * Disable some over protective warnings in visual studio because fixing them is a waste
+ * of my time.
+ */
+#ifdef _MSC_VER
+# pragma warning(disable : 4244 ) // conversion from 'int' to 'float', possible loss of data
+# pragma warning(disable : 4018 ) // signed/unsigned mismatch
+# pragma warning(disable : 4996 ) // This function or variable may be unsafe
+# pragma warning(disable : 4700 ) // uninitialized local variable used
+#endif
+
#define GMQCC_VERSION_MAJOR 0
#define GMQCC_VERSION_MINOR 1
#define GMQCC_VERSION_PATCH 0
#if INT_MAX == 0x7FFFFFFF
typedef int int32_t;
typedef unsigned int uint32_t;
- typedef long int64_t;
- typedef unsigned long uint64_t;
#elif LONG_MAX == 0x7FFFFFFF
typedef long int32_t;
typedef unsigned long uint32_t;
+#endif
+
+#if defined(__GNUC__) || defined (__CLANG__)
+ 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
/*
- * It's nearly impossible to figure out a 64bit type at
- * this point without making assumptions about the build
- * enviroment. So if clang or gcc is detected use some
- * compiler builtins to create a 64 signed and unsigned
- * type.
- */
-# if defined(__GNUC__) || defined (__CLANG__)
- typedef int int64_t __attribute__((__mode__(__DI__)));
- typedef unsigned int uint64_t __attribute__((__mode__(__DI__)));
-# else
- /*
- * Incoorectly 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.
- */
- typedef struct { char _fail : 0; } int64_t;
- typedef struct { char _fail : 0; } uint64_t;
-# endif
+ * Incoorectly 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.
+ */
+ typedef struct { char _fail : 0; } int64_t;
+ typedef struct { char _fail : 0; } uint64_t;
#endif
#ifdef _LP64 /* long pointer == 64 */
typedef unsigned long uintptr_t;
typedef char uint64_size_is_correct [sizeof(uint64_t) == 8?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];
-typedef char int64_size_is_correct [sizeof(int64_t) == 8?1:-1];
+typedef char int64_size_is_correct [sizeof(int64_t) >= 8?1:-1];
/* intptr_t / uintptr_t correct size check */
typedef char uintptr_size_is_correct[sizeof(intptr_t) == sizeof(int*)?1:-1];
typedef char intptr_size_is_correct [sizeof(uintptr_t)== sizeof(int*)?1:-1];
-/*===================================================================*/
-/*============================ lex.c ================================*/
-/*===================================================================*/
-typedef struct lex_file_t {
- FILE *file; /* file handler */
- char *name; /* name of file */
- 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
- * table starts at 33 (and we don't want conflicts)
- */
-enum {
- TOKEN_DO ,
- TOKEN_ELSE ,
- TOKEN_IF ,
- TOKEN_WHILE ,
- TOKEN_BREAK ,
- TOKEN_CONTINUE ,
- TOKEN_RETURN ,
- TOKEN_GOTO ,
- TOKEN_FOR , /* extension */
- TOKEN_TYPEDEF , /* extension */
-
- /* ensure the token types are out of the */
- /* bounds of anyothers that may conflict. */
- TOKEN_FLOAT = 110,
- TOKEN_VECTOR ,
- TOKEN_STRING ,
- TOKEN_ENTITY ,
- TOKEN_VOID
-};
-
-/*
- * Lexer state constants, these are numbers for where exactly in
- * the lexing the lexer is at. Or where it decided to stop if a lexer
- * error occurs. These numbers must be > where the ascii-table ends
- * and > the last type token which is TOKEN_VOID
- */
-enum {
- LEX_COMMENT = 1128,
- LEX_CHRLIT ,
- LEX_STRLIT ,
- LEX_IDENT
-};
-
-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 ================================*/
-/*===================================================================*/
-#define ERROR_LEX (SHRT_MAX+0)
-#define ERROR_PARSE (SHRT_MAX+1)
-#define ERROR_INTERNAL (SHRT_MAX+2)
-#define ERROR_COMPILER (SHRT_MAX+3)
-#define ERROR_PREPRO (SHRT_MAX+4)
-int error(lex_file *, int, const char *, ...);
-
-/*===================================================================*/
-/*========================== parse.c ================================*/
-/*===================================================================*/
-int parse_gen(lex_file *);
-
-/*===================================================================*/
-/*========================== typedef.c ==============================*/
-/*===================================================================*/
-typedef struct typedef_node_t {
- char *name;
-} typedef_node;
-
-void typedef_init();
-void typedef_clear();
-typedef_node *typedef_find(const char *);
-int typedef_add (lex_file *file, const char *, const char *);
-
-
/*===================================================================*/
/*=========================== util.c ================================*/
/*===================================================================*/
+FILE *util_fopen(const char *filename, const char *mode);
+
void *util_memory_a (unsigned int, unsigned int, const char *);
void util_memory_d (void *, unsigned int, const char *);
void util_meminfo ();
TYPE_FIELD ,
TYPE_FUNCTION ,
TYPE_POINTER ,
- /* TYPE_INTEGER , */
+ TYPE_INTEGER ,
TYPE_VARIANT ,
TYPE_COUNT
};
+extern const char *type_name[TYPE_COUNT];
+
extern size_t type_sizeof[TYPE_COUNT];
extern uint16_t type_store_instr[TYPE_COUNT];
/* could use type_store_instr + INSTR_STOREP_F - INSTR_STORE_F
* are at a seperate place.
*/
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];
typedef struct {
uint32_t offset; /* Offset in file of where data begins */
{ "OR" , 0, 2 },
{ "BITAND" , 0, 6 },
{ "BITOR" , 0, 5 },
+
{ "END" , 0, 3 } /* virtual assembler instruction */
};
(owner)->mem##_alloc = 0; \
}
+#define MEM_VECTOR_MOVE(from, mem, to, tm) \
+{ \
+ (to)->tm = (from)->mem; \
+ (to)->tm##_count = (from)->mem##_count; \
+ (to)->tm##_alloc = (from)->mem##_alloc; \
+ (from)->mem = NULL; \
+ (from)->mem##_count = 0; \
+ (from)->mem##_alloc = 0; \
+}
+
#define MEM_VEC_FUNCTIONS(Tself, Twhat, mem) \
MEM_VEC_FUN_REMOVE(Tself, Twhat, mem) \
MEM_VEC_FUN_ADD(Tself, Twhat, mem)
};
typedef struct {
- float x, y, z;
+ qcfloat x, y, z;
} vector;
+vector vec3_add (vector, vector);
+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.
MEM_VECTOR_MAKE(char, strings);
MEM_VECTOR_MAKE(qcint, globals);
MEM_VECTOR_MAKE(qcint, entitydata);
+ MEM_VECTOR_MAKE(bool, entitypool);
size_t tempstring_start;
size_t tempstring_at;
qcany* prog_getedict (qc_program *prog, qcint e);
qcint prog_tempstring(qc_program *prog, const char *_str);
+/*===================================================================*/
+/*===================== error.c message printer =====================*/
+/*===================================================================*/
+
+#ifndef WIN32
+enum {
+ CON_BLACK = 30,
+ CON_RED,
+ CON_GREEN,
+ CON_BROWN,
+ CON_BLUE,
+ CON_MAGENTA,
+ CON_CYAN ,
+ CON_WHITE
+};
+#endif
+enum {
+ LVL_MSG,
+ LVL_WARNING,
+ LVL_ERROR
+};
+
+void vprintmsg (int level, const char *name, size_t line, const char *msgtype, const char *msg, va_list ap);
+void printmsg (int level, const char *name, size_t line, const char *msgtype, const char *msg, ...);
+void cvprintmsg(lex_ctx ctx, int lvl, const char *msgtype, const char *msg, va_list ap);
+void cprintmsg (lex_ctx ctx, int lvl, const char *msgtype, const char *msg, ...);
+
+/*===================================================================*/
+/*===================== parser.c commandline ========================*/
+/*===================================================================*/
+
+bool parser_init ();
+bool parser_compile(const char *filename);
+bool parser_finish (const char *output);
+void parser_cleanup();
+
/*===================================================================*/
/*======================= main.c commandline ========================*/
/*===================================================================*/
};
enum {
-# define GMQCC_DEFINE_FLAG(X) X,
+# define GMQCC_DEFINE_FLAG(X) WARN_##X,
# include "warns.def"
# undef GMQCC_DEFINE_FLAG
COUNT_WARNINGS
};
static const opts_flag_def opts_warn_list[] = {
-# define GMQCC_DEFINE_FLAG(X) { #X, LONGBIT(X) },
+# define GMQCC_DEFINE_FLAG(X) { #X, LONGBIT(WARN_##X) },
# include "warns.def"
# undef GMQCC_DEFINE_FLAG
{ NULL, LONGBIT(0) }
extern int opts_standard;
extern bool opts_debug;
extern bool opts_memchk;
+extern bool opts_dump;
/*===================================================================*/
#define OPTS_FLAG(i) (!! (opts_flags[(i)/32] & (1<< ((i)%32))))