From 3e7a8c0e78468a18933bccd3af9c338986556d7a Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Sat, 28 Apr 2012 18:56:09 -0400 Subject: [PATCH] All code is now C89/C90 compat --- Makefile | 2 +- asm.c | 38 ++++----- ast.c | 15 ++-- code.c | 138 +++++++++++++++++++------------- gmqcc.h | 233 +++++++++++++++++++++++++++++++------------------------ ir.c | 15 ++-- lex.c | 6 +- main.c | 50 +++++++----- parse.c | 95 +++++++++++++---------- util.c | 34 ++++---- 10 files changed, 362 insertions(+), 264 deletions(-) diff --git a/Makefile b/Makefile index d9626a0..d73c641 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC ?= clang -CFLAGS += -Wall -pedantic-errors -std=c99 +CFLAGS += -Wall -pedantic-errors -std=c90 OBJ = main.o \ lex.o \ error.o \ diff --git a/asm.c b/asm.c index bb571e4..0ce110a 100644 --- a/asm.c +++ b/asm.c @@ -77,7 +77,7 @@ void asm_clear() { * globals with no assignments are globals. Function body types * are locals. */ -static inline bool asm_parse_type(const char *skip, size_t line, asm_state *state) { +static GMQCC_INLINE bool asm_parse_type(const char *skip, size_t line, asm_state *state) { if (!(strstr(skip, "FLOAT:") == &skip[0]) && (strstr(skip, "VECTOR:") == &skip[0]) && (strstr(skip, "ENTITY:") == &skip[0]) && @@ -141,7 +141,7 @@ static inline bool asm_parse_type(const char *skip, size_t line, asm_state *stat * names among other things. Ensures valid name as well, and even * internal engine function selection. */ -static inline bool asm_parse_func(const char *skip, size_t line, asm_state *state) { +static GMQCC_INLINE bool asm_parse_func(const char *skip, size_t line, asm_state *state) { if (*state == ASM_FUNCTION && (strstr(skip, "FUNCTION:") == &skip[0])) return false; @@ -169,6 +169,9 @@ static inline bool asm_parse_func(const char *skip, size_t line, asm_state *stat * to determine this. */ if (strchr(name, ',')) { + prog_section_function function; + prog_section_def def; + char *find = strchr(name, ',') + 1; /* skip whitespace */ @@ -197,21 +200,20 @@ static inline bool asm_parse_func(const char *skip, size_t line, asm_state *stat * global (optional) * name */ - code_functions_add((prog_section_function){ - -atoi(find), /* needs to be negated */ - 0, 0, 0, - .name = code_chars_elements, - 0, 0,{0} - }); - code_defs_add((prog_section_def){ - .type = TYPE_FUNCTION, - .offset = code_globals_elements, - .name = code_chars_elements - }); - code_globals_add(code_chars_elements); - - code_chars_put(name, strlen(name)); - code_chars_add('\0'); + function.entry = -atoi(find); + function.firstlocal = 0; + function.profile = 0; + function.name = code_chars_elements; + function.file = 0; + function.nargs = 0; + def.type = TYPE_FUNCTION; + def.offset = code_globals_elements; + def.name = code_chars_elements; + code_functions_add(function); + code_defs_add (def); + code_globals_add (code_chars_elements); + code_chars_put (name, strlen(name)); + code_chars_add ('\0'); /* * Sanatize the numerical constant used to select the @@ -225,7 +227,7 @@ static inline bool asm_parse_func(const char *skip, size_t line, asm_state *stat printf("invalid internal function identifier, must be all numeric\n"); } else { - /* TODO: function bodies */ + printf("Found function %s\n", name); } mem_d(copy); diff --git a/ast.c b/ast.c index 81eef29..aede5aa 100644 --- a/ast.c +++ b/ast.c @@ -27,10 +27,10 @@ #include "gmqcc.h" #include "ast.h" -#define ast_instantiate(T, ctx, destroyfn) \ - T *self = (T*)mem_a(sizeof(T)); \ - ast_node_init((ast_node*)self, ctx); \ - ( (ast_node*)self )->node.destroy = (ast_node_delete*)destroyfn; +#define ast_instantiate(T, ctx, destroyfn) \ + T* self = (T*)mem_a(sizeof(T)); \ + ast_node_init((ast_node*)self, ctx); \ + ( (ast_node*)self )->node.destroy = (ast_node_delete*)destroyfn /* It must not be possible to get here. */ static void _ast_node_destroy(ast_node *self) @@ -180,6 +180,8 @@ void ast_block_delete(ast_block *self) ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype) { + ast_instantiate(ast_function, ctx, ast_function_delete); + if (!vtype) return NULL; if (vtype->isconst) @@ -187,8 +189,6 @@ ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype) if (vtype->vtype != TYPE_FUNCTION) return NULL; - ast_instantiate(ast_function, ctx, ast_function_delete); - self->vtype = vtype; self->name = name ? util_strdup(name) : NULL; MEM_VECTOR_INIT(self, blocks); @@ -241,6 +241,7 @@ bool ast_value_codegen(ast_value *self, ast_function *func, ir_value **out) bool ast_global_codegen(ast_value *self, ir_builder *ir) { + ir_value *v = NULL; if (self->isconst && self->vtype == TYPE_FUNCTION) { ir_function *func = ir_builder_create_function(ir, self->name); @@ -252,7 +253,7 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir) return true; } - ir_value *v = ir_builder_create_global(ir, self->name, self->vtype); + v = ir_builder_create_global(ir, self->name, self->vtype); if (!v) return false; diff --git a/code.c b/code.c index ff3fc99..a744f1c 100644 --- a/code.c +++ b/code.c @@ -84,6 +84,10 @@ VECTOR_MAKE(int, code_globals ); VECTOR_MAKE(char, code_chars ); void code_init() { + prog_section_function empty_function = {0,0,0,0,0,0,0,{0}}; + prog_section_statement empty_statement = {0,{0},{0},{0}}; + int i = 0; + /* omit creation of null code */ if (opts_omit_nullcode) return; @@ -92,10 +96,7 @@ void code_init() { * The way progs.dat is suppose to work is odd, there needs to be * some null (empty) statements, functions, and 28 globals */ - prog_section_function empty_function = {0,0,0,0,0,0,0,{0}}; - prog_section_statement empty_statement = {0,{0},{0},{0}}; - int i; - for(i = 0; i < 28; i++) + for(; i < 28; i++) code_globals_add(0); code_chars_add ('\0'); @@ -104,6 +105,19 @@ void code_init() { } void code_test() { + prog_section_def d1 = { TYPE_VOID, 28, 1 }; + prog_section_def d2 = { TYPE_FUNCTION, 29, 8 }; + prog_section_def d3 = { TYPE_STRING, 30, 14}; + prog_section_function f1 = { 1, 0, 0, 0, 1, 0,0, {0}}; + prog_section_function f2 = {-4, 0, 0, 0, 8, 0,0, {0}}; + prog_section_function f3 = { 0, 0, 0, 0, 14+13, 0,0, {0}}; + prog_section_function f4 = { 0, 0, 0, 0, 14+13+10, 0,0, {0}}; + prog_section_function f5 = { 0, 0, 0, 0, 14+13+10+7, 0,0, {0}}; + prog_section_function f6 = { 0, 0, 0, 0, 14+13+10+7+9, 0,0, {0}}; + prog_section_statement s1 = { INSTR_STORE_F, {30}, {OFS_PARM0}, {0}}; + prog_section_statement s2 = { INSTR_CALL1, {29}, {0}, {0}}; + prog_section_statement s3 = { INSTR_RETURN, {0}, {0}, {0}}; + code_chars_put("m_init", 0x6); code_chars_put("print", 0x5); code_chars_put("hello world\n", 0xC); @@ -117,24 +131,30 @@ void code_test() { code_globals_add(14); /* hello world in string table */ /* now the defs */ - code_defs_add((prog_section_def){.type=TYPE_VOID, .offset=28/*globals[28]*/, .name=1 }); /* m_init */ - code_defs_add((prog_section_def){.type=TYPE_FUNCTION,.offset=29/*globals[29]*/, .name=8 }); /* print */ - code_defs_add((prog_section_def){.type=TYPE_STRING, .offset=30/*globals[30]*/, .name=14}); /*hello_world*/ - - code_functions_add((prog_section_function){1, 0, 0, 0, .name=1, 0, 0, {0}}); /* m_init */ - code_functions_add((prog_section_function){-4, 0, 0, 0, .name=8, 0, 0, {0}}); /* print */ - code_functions_add((prog_section_function){0, 0, 0, 0, .name=14+13, 0,0, {0}}); /* m_keydown */ - code_functions_add((prog_section_function){0, 0, 0, 0, .name=14+13+10, 0,0, {0}}); - code_functions_add((prog_section_function){0, 0, 0, 0, .name=14+13+10+7, 0,0, {0}}); - code_functions_add((prog_section_function){0, 0, 0, 0, .name=14+13+10+7+9, 0,0, {0}}); - - code_statements_add((prog_section_statement){INSTR_STORE_F, {30}/*30 is hello_world */, {OFS_PARM0}, {0}}); - code_statements_add((prog_section_statement){INSTR_CALL1, {29}/*29 is print */, {0}, {0}}); - code_statements_add((prog_section_statement){INSTR_RETURN, {0}, {0}, {0}}); + code_defs_add (d1); /* m_init */ + code_defs_add (d2); /* print */ + code_defs_add (d3); /*hello_world*/ + code_functions_add (f1); /* m_init */ + code_functions_add (f2); /* print */ + code_functions_add (f3); /* m_keydown */ + code_functions_add (f4); + code_functions_add (f5); + code_functions_add (f6); + code_statements_add(s1); + code_statements_add(s2); + code_statements_add(s3); } void code_write() { - prog_header code_header={0}; + prog_header code_header = {0}; + prog_section statements; + prog_section defs; + prog_section fields; + prog_section functions; + prog_section globals; + prog_section strings; + FILE *fp = NULL; + size_t it = 1; /* see proposal.txt */ if (opts_omit_nullcode) { @@ -142,14 +162,27 @@ void code_write() { code_header.flags = 1; } + statements.offset = sizeof(prog_header); + statements.length = code_statements_elements; + defs.offset = code_header.statements.offset + sizeof(prog_section_statement) * code_statements_elements; + defs.length = code_defs_elements; + fields.offset = code_header.defs.offset + sizeof(prog_section_def) * code_defs_elements; + fields.length = code_fields_elements; + functions.offset = code_header.fields.offset + sizeof(prog_section_field) * code_fields_elements; + functions.length = code_functions_elements; + globals.offset = code_header.functions.offset + sizeof(prog_section_function) * code_functions_elements; + globals.length = code_globals_elements; + strings.offset = code_header.globals.offset + sizeof(int) * code_globals_elements; + strings.length = code_chars_elements; + code_header.version = 6; code_header.crc16 = 0; /* TODO: */ - code_header.statements = (prog_section){sizeof(prog_header), code_statements_elements }; - code_header.defs = (prog_section){code_header.statements.offset + sizeof(prog_section_statement)*code_statements_elements, code_defs_elements }; - code_header.fields = (prog_section){code_header.defs.offset + sizeof(prog_section_def) *code_defs_elements, code_fields_elements }; - code_header.functions = (prog_section){code_header.fields.offset + sizeof(prog_section_field) *code_fields_elements, code_functions_elements }; - code_header.globals = (prog_section){code_header.functions.offset + sizeof(prog_section_function) *code_functions_elements, code_globals_elements }; - code_header.strings = (prog_section){code_header.globals.offset + sizeof(int) *code_globals_elements, code_chars_elements }; + code_header.statements = statements; + code_header.defs = defs; + code_header.fields = fields; + code_header.functions = functions; + code_header.globals = globals; + code_header.strings = strings; code_header.entfield = 0; /* TODO: */ if (opts_darkplaces_stringtablebug) { @@ -162,21 +195,21 @@ void code_write() { } /* ensure all data is in LE format */ - util_endianswap(&code_header, 1, sizeof(prog_header)); - util_endianswap(code_statements_data, code_statements_elements, sizeof(prog_section_statement)); - util_endianswap(code_defs_data, code_defs_elements, sizeof(prog_section_def)); - util_endianswap(code_fields_data, code_fields_elements, sizeof(prog_section_field)); - util_endianswap(code_functions_data, code_functions_elements, sizeof(prog_section_function)); - util_endianswap(code_globals_data, code_globals_elements, sizeof(int)); - - FILE *fp = fopen("program.dat", "wb"); - fwrite(&code_header, 1, sizeof(prog_header), fp); - fwrite(code_statements_data, 1, sizeof(prog_section_statement)*code_statements_elements, fp); - fwrite(code_defs_data, 1, sizeof(prog_section_def) *code_defs_elements, fp); - fwrite(code_fields_data, 1, sizeof(prog_section_field) *code_fields_elements, fp); - fwrite(code_functions_data, 1, sizeof(prog_section_function) *code_functions_elements, fp); - fwrite(code_globals_data, 1, sizeof(int) *code_globals_elements, fp); - fwrite(code_chars_data, 1, 1 *code_chars_elements, fp); + util_endianswap(&code_header, 1, sizeof(prog_header)); + util_endianswap (code_statements_data, code_statements_elements, sizeof(prog_section_statement)); + util_endianswap (code_defs_data, code_defs_elements, sizeof(prog_section_def)); + util_endianswap (code_fields_data, code_fields_elements, sizeof(prog_section_field)); + util_endianswap (code_functions_data, code_functions_elements, sizeof(prog_section_function)); + util_endianswap (code_globals_data, code_globals_elements, sizeof(int)); + + fp = fopen("program.dat", "wb"); + fwrite(&code_header, 1, sizeof(prog_header), fp); + fwrite (code_statements_data, 1, sizeof(prog_section_statement)*code_statements_elements, fp); + fwrite (code_defs_data, 1, sizeof(prog_section_def) *code_defs_elements, fp); + fwrite (code_fields_data, 1, sizeof(prog_section_field) *code_fields_elements, fp); + fwrite (code_functions_data, 1, sizeof(prog_section_function) *code_functions_elements, fp); + fwrite (code_globals_data, 1, sizeof(int) *code_globals_elements, fp); + fwrite (code_chars_data, 1, 1 *code_chars_elements, fp); util_debug("GEN","HEADER:\n"); util_debug("GEN"," version: = %d\n", code_header.version ); @@ -191,22 +224,21 @@ void code_write() { /* FUNCTIONS */ util_debug("GEN", "FUNCTIONS:\n"); - size_t i = 1; - for (; i < code_functions_elements; i++) { - size_t j = code_functions_data[i].entry; + for (; it < code_functions_elements; it++) { + size_t j = code_functions_data[it].entry; util_debug("GEN", " {.entry =% 5d, .firstlocal =% 5d, .locals =% 5d, .profile =% 5d, .name =% 5d, .file =% 5d, .nargs =% 5d, .argsize =%0X }\n", - code_functions_data[i].entry, - code_functions_data[i].firstlocal, - code_functions_data[i].locals, - code_functions_data[i].profile, - code_functions_data[i].name, - code_functions_data[i].file, - code_functions_data[i].nargs, - *((int32_t*)&code_functions_data[i].argsize) + code_functions_data[it].entry, + code_functions_data[it].firstlocal, + code_functions_data[it].locals, + code_functions_data[it].profile, + code_functions_data[it].name, + code_functions_data[it].file, + code_functions_data[it].nargs, + *((int32_t*)&code_functions_data[it].argsize) ); - util_debug("GEN", " NAME: %s\n", &code_chars_data[code_functions_data[i].name]); + util_debug("GEN", " NAME: %s\n", &code_chars_data[code_functions_data[it].name]); /* Internal functions have no code */ - if (code_functions_data[i].entry >= 0) { + if (code_functions_data[it].entry >= 0) { util_debug("GEN", " CODE:\n"); for (;;) { if (code_statements_data[j].opcode != INSTR_DONE && diff --git a/gmqcc.h b/gmqcc.h index 583726e..fc92d13 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -74,6 +74,25 @@ */ #define GMQCC_SUPRESS_EMPTY_BODY do { } while (0) +/* + * Inline is not supported in < C90, however some compilers + * like gcc and clang might have an inline attribute we can + * use if present. + */ +#if __STDC_VERSION__ < 199901L +# if defined(__GNUC__) || defined (__CLANG__) +# if __GNUC__ < 2 +# define GMQCC_INLINE +# else +# define GMQCC_INLINE __attribute__ ((always_inline)) +# endif +# else +# define GMQCC_INLINE +# endif +#else +# define GMQCC_INLINE inline +#endif + /* * stdint.h and inttypes.h -less subset * for systems that don't have it, which we must @@ -94,9 +113,15 @@ #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; + + /* bail on 64 bit type! */ + typedef char int64_t; + typedef char uint64_t; #endif #ifdef _LP64 /* long pointer == 64 */ typedef unsigned long uintptr_t; @@ -109,15 +134,17 @@ 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 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]; /* 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 ================================ -//=================================================================== +/*===================================================================*/ +/*============================ lex.c ================================*/ +/*===================================================================*/ typedef struct lex_file_t { FILE *file; /* file handler */ char *name; /* name of file */ @@ -144,11 +171,11 @@ enum { TOKEN_CONTINUE , TOKEN_RETURN , TOKEN_GOTO , - TOKEN_FOR , // extension - TOKEN_TYPEDEF , // extension + TOKEN_FOR , /* extension */ + TOKEN_TYPEDEF , /* extension */ - // ensure the token types are out of the - // bounds of anyothers that may conflict. + /* ensure the token types are out of the */ + /* bounds of anyothers that may conflict. */ TOKEN_FLOAT = 110, TOKEN_VECTOR , TOKEN_STRING , @@ -176,9 +203,9 @@ void lex_parse (lex_file *); lex_file *lex_include(lex_file *, const char *); void lex_init (const char *, lex_file **); -//=================================================================== -//========================== error.c ================================ -//=================================================================== +/*===================================================================*/ +/*========================== error.c ================================*/ +/*===================================================================*/ #define ERROR_LEX (SHRT_MAX+0) #define ERROR_PARSE (SHRT_MAX+1) #define ERROR_INTERNAL (SHRT_MAX+2) @@ -186,14 +213,14 @@ void lex_init (const char *, lex_file **); #define ERROR_PREPRO (SHRT_MAX+4) int error(lex_file *, int, const char *, ...); -//=================================================================== -//========================== parse.c ================================ -//=================================================================== +/*===================================================================*/ +/*========================== parse.c ================================*/ +/*===================================================================*/ int parse_gen(lex_file *); -//=================================================================== -//========================== typedef.c ============================== -//=================================================================== +/*===================================================================*/ +/*========================== typedef.c ==============================*/ +/*===================================================================*/ typedef struct typedef_node_t { char *name; } typedef_node; @@ -204,9 +231,9 @@ typedef_node *typedef_find(const char *); int typedef_add (lex_file *file, const char *, const char *); -//=================================================================== -//=========================== util.c ================================ -//=================================================================== +/*===================================================================*/ +/*=========================== util.c ================================*/ +/*===================================================================*/ void *util_memory_a (unsigned int, unsigned int, const char *); void util_memory_d (void *, unsigned int, const char *); void util_meminfo (); @@ -242,14 +269,14 @@ uint32_t util_crc32(const char *, int, register const short); /* Builds vector add */ #define VECTOR_CORE(T,N) \ int N##_add(T element) { \ + void *temp = NULL; \ if (N##_elements == N##_allocated) { \ if (N##_allocated == 0) { \ N##_allocated = 12; \ } else { \ N##_allocated *= 2; \ } \ - void *temp = mem_a(N##_allocated * sizeof(T)); \ - if (!temp) { \ + if (!(temp = mem_a(N##_allocated * sizeof(T)))) { \ mem_d(temp); \ return -1; \ } \ @@ -272,9 +299,9 @@ uint32_t util_crc32(const char *, int, register const short); VECTOR_TYPE(T,N); \ VECTOR_CORE(T,N) -//=================================================================== -//=========================== code.c ================================ -//=================================================================== +/*===================================================================*/ +/*=========================== code.c ================================*/ +/*===================================================================*/ enum { TYPE_VOID , TYPE_STRING , @@ -285,7 +312,7 @@ enum { TYPE_FUNCTION , TYPE_POINTER , /* TYPE_INTEGER , */ - TYPE_VARIANT , + TYPE_VARIANT }; /* @@ -441,7 +468,7 @@ enum { */ VINSTR_PHI, VINSTR_JUMP, - VINSTR_COND, + VINSTR_COND }; /* @@ -481,88 +508,88 @@ extern long code_defs_elements; void code_write (); void code_init (); -//=================================================================== -//========================= assembler.c ============================= -//=================================================================== +/*===================================================================*/ +/*========================= assembler.c =============================*/ +/*===================================================================*/ static const struct { const char *m; /* menomic */ const size_t o; /* operands */ const size_t l; /* menomic len */ -} const asm_instr[] = { - [INSTR_DONE] = { "DONE" , 1, 4 }, - [INSTR_MUL_F] = { "MUL_F" , 3, 5 }, - [INSTR_MUL_V] = { "MUL_V" , 3, 5 }, - [INSTR_MUL_FV] = { "MUL_FV" , 3, 6 }, - [INSTR_MUL_VF] = { "MUL_VF" , 3, 6 }, - [INSTR_DIV_F] = { "DIV" , 0, 3 }, - [INSTR_ADD_F] = { "ADD_F" , 3, 5 }, - [INSTR_ADD_V] = { "ADD_V" , 3, 5 }, - [INSTR_SUB_F] = { "SUB_F" , 3, 5 }, - [INSTR_SUB_V] = { "DUB_V" , 3, 5 }, - [INSTR_EQ_F] = { "EQ_F" , 0, 4 }, - [INSTR_EQ_V] = { "EQ_V" , 0, 4 }, - [INSTR_EQ_S] = { "EQ_S" , 0, 4 }, - [INSTR_EQ_E] = { "EQ_E" , 0, 4 }, - [INSTR_EQ_FNC] = { "ES_FNC" , 0, 6 }, - [INSTR_NE_F] = { "NE_F" , 0, 4 }, - [INSTR_NE_V] = { "NE_V" , 0, 4 }, - [INSTR_NE_S] = { "NE_S" , 0, 4 }, - [INSTR_NE_E] = { "NE_E" , 0, 4 }, - [INSTR_NE_FNC] = { "NE_FNC" , 0, 6 }, - [INSTR_LE] = { "LE" , 0, 2 }, - [INSTR_GE] = { "GE" , 0, 2 }, - [INSTR_LT] = { "LT" , 0, 2 }, - [INSTR_GT] = { "GT" , 0, 2 }, - [INSTR_LOAD_F] = { "FIELD_F" , 0, 7 }, - [INSTR_LOAD_V] = { "FIELD_V" , 0, 7 }, - [INSTR_LOAD_S] = { "FIELD_S" , 0, 7 }, - [INSTR_LOAD_ENT] = { "FIELD_ENT" , 0, 9 }, - [INSTR_LOAD_FLD] = { "FIELD_FLD" , 0, 9 }, - [INSTR_LOAD_FNC] = { "FIELD_FNC" , 0, 9 }, - [INSTR_ADDRESS] = { "ADDRESS" , 0, 7 }, - [INSTR_STORE_F] = { "STORE_F" , 0, 7 }, - [INSTR_STORE_V] = { "STORE_V" , 0, 7 }, - [INSTR_STORE_S] = { "STORE_S" , 0, 7 }, - [INSTR_STORE_ENT] = { "STORE_ENT" , 0, 9 }, - [INSTR_STORE_FLD] = { "STORE_FLD" , 0, 9 }, - [INSTR_STORE_FNC] = { "STORE_FNC" , 0, 9 }, - [INSTR_STOREP_F] = { "STOREP_F" , 0, 8 }, - [INSTR_STOREP_V] = { "STOREP_V" , 0, 8 }, - [INSTR_STOREP_S] = { "STOREP_S" , 0, 8 }, - [INSTR_STOREP_ENT] = { "STOREP_ENT", 0, 10}, - [INSTR_STOREP_FLD] = { "STOREP_FLD", 0, 10}, - [INSTR_STOREP_FNC] = { "STOREP_FNC", 0, 10}, - [INSTR_RETURN] = { "RETURN" , 0, 6 }, - [INSTR_NOT_F] = { "NOT_F" , 0, 5 }, - [INSTR_NOT_V] = { "NOT_V" , 0, 5 }, - [INSTR_NOT_S] = { "NOT_S" , 0, 5 }, - [INSTR_NOT_ENT] = { "NOT_ENT" , 0, 7 }, - [INSTR_NOT_FNC] = { "NOT_FNC" , 0, 7 }, - [INSTR_IF] = { "IF" , 0, 2 }, - [INSTR_IFNOT] = { "IFNOT" , 0, 5 }, - [INSTR_CALL0] = { "CALL0" , 0, 5 }, - [INSTR_CALL1] = { "CALL1" , 0, 5 }, - [INSTR_CALL2] = { "CALL2" , 0, 5 }, - [INSTR_CALL3] = { "CALL3" , 0, 5 }, - [INSTR_CALL4] = { "CALL4" , 0, 5 }, - [INSTR_CALL5] = { "CALL5" , 0, 5 }, - [INSTR_CALL6] = { "CALL6" , 0, 5 }, - [INSTR_CALL7] = { "CALL7" , 0, 5 }, - [INSTR_CALL8] = { "CALL8" , 0, 5 }, - [INSTR_STATE] = { "STATE" , 0, 5 }, - [INSTR_GOTO] = { "GOTO" , 0, 4 }, - [INSTR_AND] = { "AND" , 0, 3 }, - [INSTR_OR] = { "OR" , 0, 2 }, - [INSTR_BITAND] = { "BITAND" , 0, 6 }, - [INSTR_BITOR] = { "BITOR" , 0, 5 } +} asm_instr[] = { + { "DONE" , 1, 4 }, + { "MUL_F" , 3, 5 }, + { "MUL_V" , 3, 5 }, + { "MUL_FV" , 3, 6 }, + { "MUL_VF" , 3, 6 }, + { "DIV" , 0, 3 }, + { "ADD_F" , 3, 5 }, + { "ADD_V" , 3, 5 }, + { "SUB_F" , 3, 5 }, + { "DUB_V" , 3, 5 }, + { "EQ_F" , 0, 4 }, + { "EQ_V" , 0, 4 }, + { "EQ_S" , 0, 4 }, + { "EQ_E" , 0, 4 }, + { "ES_FNC" , 0, 6 }, + { "NE_F" , 0, 4 }, + { "NE_V" , 0, 4 }, + { "NE_S" , 0, 4 }, + { "NE_E" , 0, 4 }, + { "NE_FNC" , 0, 6 }, + { "LE" , 0, 2 }, + { "GE" , 0, 2 }, + { "LT" , 0, 2 }, + { "GT" , 0, 2 }, + { "FIELD_F" , 0, 7 }, + { "FIELD_V" , 0, 7 }, + { "FIELD_S" , 0, 7 }, + { "FIELD_ENT" , 0, 9 }, + { "FIELD_FLD" , 0, 9 }, + { "FIELD_FNC" , 0, 9 }, + { "ADDRESS" , 0, 7 }, + { "STORE_F" , 0, 7 }, + { "STORE_V" , 0, 7 }, + { "STORE_S" , 0, 7 }, + { "STORE_ENT" , 0, 9 }, + { "STORE_FLD" , 0, 9 }, + { "STORE_FNC" , 0, 9 }, + { "STOREP_F" , 0, 8 }, + { "STOREP_V" , 0, 8 }, + { "STOREP_S" , 0, 8 }, + { "STOREP_ENT", 0, 10}, + { "STOREP_FLD", 0, 10}, + { "STOREP_FNC", 0, 10}, + { "RETURN" , 0, 6 }, + { "NOT_F" , 0, 5 }, + { "NOT_V" , 0, 5 }, + { "NOT_S" , 0, 5 }, + { "NOT_ENT" , 0, 7 }, + { "NOT_FNC" , 0, 7 }, + { "IF" , 0, 2 }, + { "IFNOT" , 0, 5 }, + { "CALL0" , 0, 5 }, + { "CALL1" , 0, 5 }, + { "CALL2" , 0, 5 }, + { "CALL3" , 0, 5 }, + { "CALL4" , 0, 5 }, + { "CALL5" , 0, 5 }, + { "CALL6" , 0, 5 }, + { "CALL7" , 0, 5 }, + { "CALL8" , 0, 5 }, + { "STATE" , 0, 5 }, + { "GOTO" , 0, 4 }, + { "AND" , 0, 3 }, + { "OR" , 0, 2 }, + { "BITAND" , 0, 6 }, + { "BITOR" , 0, 5 } }; void asm_init (const char *, FILE **); void asm_close(FILE *); void asm_parse(FILE *); -//====================================================================== -//============================= main.c ================================= -//====================================================================== +/*===================================================================*/ +/*============================= main.c ==============================*/ +/*===================================================================*/ enum { COMPILER_QCC, /* circa QuakeC */ COMPILER_FTEQCC, /* fteqcc QuakeC */ @@ -574,9 +601,9 @@ extern bool opts_memchk; extern bool opts_darkplaces_stringtablebug; extern bool opts_omit_nullcode; extern int opts_compiler; -//====================================================================== -//============================= ast.c ================================== -//====================================================================== +/*===================================================================*/ +/*============================= 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) @@ -690,7 +717,7 @@ _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 */ + store_value /* unassignable */ }; typedef struct { diff --git a/ir.c b/ir.c index 5401e5f..72250f7 100644 --- a/ir.c +++ b/ir.c @@ -511,6 +511,7 @@ bool ir_value_life_merge(ir_value *self, size_t s) } /* nothing found? append */ if (i == self->life_count) { + ir_life_entry_t e; if (life && life->end+1 == s) { /* previous life range can be merged in */ @@ -519,7 +520,6 @@ bool ir_value_life_merge(ir_value *self, size_t s) } if (life && life->end >= s) return false; - ir_life_entry_t e; e.start = e.end = s; if (!ir_value_life_add(self, e)) return false; /* failing */ @@ -657,7 +657,7 @@ bool ir_block_create_if(ir_block *self, ir_value *v, return false; } self->final = true; - //in = ir_instr_new(self, (v->vtype == TYPE_STRING ? INSTR_IF_S : INSTR_IF_F)); + /*in = ir_instr_new(self, (v->vtype == TYPE_STRING ? INSTR_IF_S : INSTR_IF_F));*/ in = ir_instr_new(self, VINSTR_COND); if (!in) return false; @@ -786,6 +786,9 @@ ir_value* ir_block_create_binop(ir_block *self, const char *label, int opcode, ir_value *left, ir_value *right) { + ir_value *out = NULL; + ir_instr *in = NULL; + int ot = TYPE_VOID; switch (opcode) { case INSTR_ADD_F: @@ -854,7 +857,7 @@ ir_value* ir_block_create_binop(ir_block *self, break; #endif default: - // ranges: + /* ranges: */ /* boolean operations result in floats */ if (opcode >= INSTR_EQ_F && opcode <= INSTR_GT) ot = TYPE_FLOAT; @@ -871,11 +874,11 @@ ir_value* ir_block_create_binop(ir_block *self, return NULL; } - ir_value *out = ir_value_out(self->owner, label, store_local, ot); + out = ir_value_out(self->owner, label, store_local, ot); if (!out) return NULL; - ir_instr *in = ir_instr_new(self, opcode); + in = ir_instr_new(self, opcode); if (!in) { ir_value_delete(out); return NULL; @@ -1433,7 +1436,7 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change } /* (A) */ tempbool = ir_block_living_add_instr(self, instr->eid); - //fprintf(stderr, "living added values\n"); + /*fprintf(stderr, "living added values\n");*/ *changed = *changed || tempbool; /* new reads: */ diff --git a/lex.c b/lex.c index fa09f27..4063139 100644 --- a/lex.c +++ b/lex.c @@ -67,7 +67,7 @@ static void lex_addch(int ch, lex_file *file) { if (file->current == sizeof(file->lastok)-1) file->lastok[file->current] = (char)'\0'; } -static inline void lex_clear(lex_file *file) { +static GMQCC_INLINE void lex_clear(lex_file *file) { file->current = 0; } @@ -342,13 +342,13 @@ void lex_parse(lex_file *file) { * recrusion. */ lex_file *lex_include(lex_file *lex, const char *file) { + lex_file *set = NULL; + util_strrq(file); if (strncmp(lex->name, file, strlen(lex->name)) == 0) { error(lex, ERROR_LEX, "Source file cannot include itself\n"); exit (-1); } - - lex_file *set = NULL; lex_init(file, &set); return set; diff --git a/main.c b/main.c index 4bdde47..9cd5903 100644 --- a/main.c +++ b/main.c @@ -21,7 +21,6 @@ * SOFTWARE. */ #include "gmqcc.h" -// todo CLEANUP this argitem thing typedef struct { char *name, type; } argitem; VECTOR_MAKE(argitem, items); @@ -39,21 +38,22 @@ static const int usage(const char *const app) { " %s -c -i -oprog.dat -- compile together (allowed multiple -i)\n" " %s -a -i -oprog.dat -- assemble together(allowed multiple -i)\n" " example:\n" - " %s -cfoo.qc -ibar.qc -oqc.dat -afoo.qs -ibar.qs -oqs.dat\n" - " additional flags:\n" + " %s -cfoo.qc -ibar.qc -oqc.dat -afoo.qs -ibar.qs -oqs.dat\n", app, app, app, app, app); + + printf(" additional flags:\n" " -debug -- turns on compiler debug messages\n" " -memchk -- turns on compiler memory leak check\n" " -help -- prints this help/usage text\n" - " -std -- select the QuakeC compile type (types below):\n" - " -std=qcc -- original QuakeC\n" + " -std -- select the QuakeC compile type (types below):\n"); + + printf(" -std=qcc -- original QuakeC\n" " -std=ftqecc -- fteqcc QuakeC\n" " -std=qccx -- qccx QuakeC\n" - " -std=gmqcc -- this compiler QuakeC (default selection)\n" - " codegen flags:\n" + " -std=gmqcc -- this compiler QuakeC (default selection)\n"); + + printf(" codegen flags:\n" " -fdarkplaces-string-table-bug -- patches the string table to work with bugged versions of darkplaces\n" - " -fomit-nullcode -- omits the generation of null code (will break everywhere see propsal.txt)\n", - app,app,app,app,app - ); + " -fomit-nullcode -- omits the generation of null code (will break everywhere see propsal.txt)\n"); return -1; } @@ -87,20 +87,25 @@ int main(int argc, char **argv) { return 0; } #define param_argument(argtype) do { \ + argitem item; \ if (argv[1][2]) { \ - items_add((argitem){util_strdup(&argv[1][2]), argtype}); \ + item.name = util_strdup(&argv[1][2]); \ + item.type = argtype; \ + items_add(item); \ } else { \ ++argv; \ --argc; \ if (argc <= 1) \ goto clean_params_usage; \ - items_add((argitem){util_strdup(&argv[1][0]), argtype}); \ - } \ + item.name = util_strdup(argv[1]); \ + item.type = argtype; \ + items_add(item); \ + } \ } while (0) - case 'c': param_argument(0); break; /* compile */ - case 'a': param_argument(1); break; /* assemble */ - case 'i': param_argument(2); break; /* includes */ + case 'c': { param_argument(0); break; } /* compile */ + case 'a': { param_argument(1); break; } /* assemble */ + case 'i': { param_argument(2); break; } /* includes */ #undef parm_argument default: if (!strncmp(&argv[1][1], "debug" , 5)) { opts_debug = true; break; } @@ -152,13 +157,17 @@ int main(int argc, char **argv) { switch (items_data[itr].type) { case 0: lex_init (items_data[itr].name, &lex); - lex_parse(lex); - lex_close(lex); + if (lex) { + lex_parse(lex); + lex_close(lex); + } break; case 1: asm_init (items_data[itr].name, &fpp); - asm_parse(fpp); - asm_close(fpp); + if (fpp) { + asm_parse(fpp); + asm_close(fpp); + } break; } } @@ -171,6 +180,7 @@ int main(int argc, char **argv) { util_meminfo(); return 0; + clean_params_usage: for (itr = 0; itr < items_elements; itr++) mem_d(items_data[itr].name); diff --git a/parse.c b/parse.c index c4fb8e0..40224ca 100644 --- a/parse.c +++ b/parse.c @@ -82,7 +82,7 @@ int parse_gen(lex_file *file) { case TOKEN_ENTITY: goto fall; case TOKEN_FLOAT: goto fall; { - fall:; + fall:; { char *name = NULL; int type = token; /* story copy */ @@ -119,12 +119,16 @@ int parse_gen(lex_file *file) { if (*file->lastok != '"') error(file, ERROR_PARSE, "Expected a '\"' (quote) for string constant\n"); /* add the compile-time constant */ - compile_constants_add((constant){ - .name = util_strdup(name), - .type = TYPE_STRING, - .value = {0,0,0}, - .string = util_strdup(file->lastok) - }); + { + constant c; + c.name = util_strdup(name), + c.type = TYPE_STRING, + c.value[0] = 0; + c.value[1] = 0; + c.value[2] = 0; + c.string = util_strdup(file->lastok); + compile_constants_add(c); + } break; /* TODO: name constant, old qc vec literals, whitespace fixes, name constant */ case TOKEN_VECTOR: { @@ -206,16 +210,17 @@ int parse_gen(lex_file *file) { error(file, ERROR_PARSE, "Expected `;` on end of constant initialization for vector\n"); /* add the compile-time constant */ - compile_constants_add((constant){ - .name = util_strdup(name), - .type = TYPE_VECTOR, - .value = { - [0] = compile_calc_x, - [1] = compile_calc_y, - [2] = compile_calc_z - }, - .string = NULL - }); + { + constant c; + + c.name = util_strdup(name), + c.type = TYPE_VECTOR, + c.value[0] = compile_calc_x; + c.value[1] = compile_calc_y; + c.value[2] = compile_calc_z; + c.string = NULL; + compile_constants_add(c); + } break; } @@ -223,19 +228,24 @@ int parse_gen(lex_file *file) { case TOKEN_FLOAT: /*TODO: validate, constant generation, name constant */ if (!isdigit(token)) error(file, ERROR_PARSE, "Expected numeric constant for float constant\n"); - compile_constants_add((constant){ - .name = util_strdup(name), - .type = TOKEN_FLOAT, - .value = {0,0,0}, - .string = NULL - }); + /* constant */ + { + constant c; + c.name = util_strdup(name), + c.type = TOKEN_FLOAT, + c.value[0] = 0; + c.value[1] = 0; + c.value[2] = 0; + c.string = NULL; + compile_constants_add(c); + } break; } } else if (token == '(') { printf("FUNCTION ??\n"); } mem_d(name); - } + }} /* * From here down is all language punctuation: There is no @@ -253,6 +263,8 @@ int parse_gen(lex_file *file) { * directives so far are #include. */ if (strncmp(file->lastok, "include", sizeof("include")) == 0) { + char *copy = NULL; + lex_file *next = NULL; /* * We only suport include " ", not <> like in C (why?) * because the latter is silly. @@ -262,19 +274,24 @@ int parse_gen(lex_file *file) { if (token == '\n') return error(file, ERROR_PARSE, "Invalid use of include preprocessor directive: wanted #include \"file.h\"\n"); - char *copy = util_strdup(file->lastok); - lex_file *next = lex_include(file, copy); + copy = util_strdup(file->lastok); + next = lex_include(file, copy); if (!next) { error(file, ERROR_INTERNAL, "Include subsystem failure\n"); exit (-1); } - compile_constants_add((constant) { - .name = "#include", - .type = TYPE_VOID, - .value = {0,0,0}, - .string = copy - }); + /* constant */ + { + constant c; + c.name = "#include", + c.type = TYPE_VOID, + c.value[0] = 0; + c.value[1] = 0; + c.value[2] = 0; + c.string = copy; + compile_constants_add(c); + } parse_gen(next); mem_d (copy); lex_close(next); @@ -293,12 +310,12 @@ int parse_gen(lex_file *file) { lex_reset(file); /* free constants */ { - size_t i = 0; - for (; i < compile_constants_elements; i++) { - mem_d(compile_constants_data[i].name); - mem_d(compile_constants_data[i].string); - } - mem_d(compile_constants_data); - } + size_t i = 0; + for (; i < compile_constants_elements; i++) { + mem_d(compile_constants_data[i].name); + mem_d(compile_constants_data[i].string); + } + mem_d(compile_constants_data); + } return 1; } diff --git a/util.c b/util.c index 4317e93..f97eab4 100644 --- a/util.c +++ b/util.c @@ -24,10 +24,10 @@ #include #include "gmqcc.h" -unsigned long long mem_ab = 0; -unsigned long long mem_db = 0; -unsigned long long mem_at = 0; -unsigned long long mem_dt = 0; +uint64_t mem_ab = 0; +uint64_t mem_db = 0; +uint64_t mem_at = 0; +uint64_t mem_dt = 0; struct memblock_t { const char *file; @@ -51,10 +51,12 @@ void *util_memory_a(unsigned int byte, unsigned int line, const char *file) { } void util_memory_d(void *ptrn, unsigned int line, const char *file) { + void *data = NULL; + struct memblock_t *info = NULL; if (!ptrn) return; - void *data = (void*)((uintptr_t)ptrn-sizeof(struct memblock_t)); - struct memblock_t *info = (struct memblock_t*)data; - + data = (void*)((uintptr_t)ptrn-sizeof(struct memblock_t)); + info = (struct memblock_t*)data; + util_debug("MEM", "released: % 8u (bytes) address 0x%08X @ %s:%u\n", info->byte, data, file, line); mem_db += info->byte; mem_dt++; @@ -124,10 +126,11 @@ char *util_strrq(const char *s) { * copy of it and null terminating it at the required position. */ char *util_strchp(const char *s, const char *e) { + const char *c = NULL; if (!s || !e) return NULL; - const char *c = s; + c = s; while (c != e) c++; @@ -140,12 +143,15 @@ char *util_strchp(const char *s, const char *e) { * access. */ char *util_strrnl(const char *src) { - if (!src) return NULL; - char *cpy = (char*)src; - while (*cpy && *cpy != '\n') - cpy++; + char *cpy = NULL; + + if (src) { + cpy = (char*)src; + while (*cpy && *cpy != '\n') + cpy++; - *cpy = '\0'; + *cpy = '\0'; + } return (char*)src; } @@ -191,10 +197,10 @@ bool util_strdigit(const char *str) { } void util_debug(const char *area, const char *ms, ...) { + va_list va; if (!opts_debug) return; - va_list va; va_start(va, ms); fprintf (stdout, "DEBUG: "); fputc ('[', stdout); -- 2.39.2