From f19cbe1400e47d9a065adcafb45f131f89731e04 Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Sun, 29 Apr 2012 19:03:06 -0400 Subject: [PATCH] Parse vector constants and add them to the constants table now for the assembler. --- asm.c | 100 +++++++++++++++++++++++++++++++++++++-------------- data/test.qs | 4 +-- gmqcc.h | 9 +++++ 3 files changed, 85 insertions(+), 28 deletions(-) diff --git a/asm.c b/asm.c index ee83eaf..ad47b57 100644 --- a/asm.c +++ b/asm.c @@ -33,6 +33,8 @@ typedef enum { typedef struct { char *name; /* name of constant */ + char type; /* type, float, vector, string */ + char elem; /* 0=x, 1=y, or 2=Z? */ int offset; /* location in globals */ } globals; VECTOR_MAKE(globals, assembly_constants); @@ -71,6 +73,28 @@ void asm_clear() { mem_d(assembly_constants_data); } +/* + * Dumps all values of all constants and assembly related + * information obtained during the assembly procedure. + */ +void asm_dumps() { + size_t i = 0; + for (; i < assembly_constants_elements; i++) { + globals *g = &assembly_constants_data[i]; + switch (g->type) { + case TYPE_VECTOR: { + util_debug("ASM", "vector %s %c[%f]\n", g->name, + (g->elem == 0) ? 'X' :( + (g->elem == 1) ? 'Y' : + (g->elem == 2) ? 'Z' :' '), + INT2FLT(code_globals_data[g->offset]) + ); + break; + } + } + } +} + /* * Parses a type, could be global or not depending on the * assembly state: global scope with assignments are constants. @@ -87,36 +111,59 @@ static GMQCC_INLINE bool asm_parse_type(const char *skip, size_t line, asm_state /* TODO: determine if constant, global, or local */ switch (*skip) { /* VECTOR */ case 'V': { - float val1; - float val2; - float val3; + float val1; + float val2; + float val3; + globals global; - const char *find = skip + 7; + char *find = (char*)skip + 7; + char *name = (char*)skip + 7; while (*find == ' ' || *find == '\t') find++; - /* - * Parse all three elements of the vector. This will only - * pass the first try if we hit a constant, otherwise it's - * a global. - */ - #define PARSE_ELEMENT(X,Y,Z) \ - if (isdigit(*X) || *X == '-'||*X == '+') { \ - bool negated = (*X == '-'); \ - if (negated || *X == '+') { X++; } \ - Y = (negated)?-atof(X):atof(X); \ - X = strchr(X, ','); \ - Z \ + /* constant? */ + if (strchr(find, ',')) { + /* strip name */ + *strchr((name = util_strdup(find)), ',')='\0'; + /* find data */ + find += strlen(name) + 1; + while (*find == ' ' || *find == '\t') find++; + /* valid name */ + if (util_strupper(name) || isdigit(*name)) { + printf("invalid name for vector variable\n"); + mem_d(name); } + /* + * Parse all three elements of the vector. This will only + * pass the first try if we hit a constant, otherwise it's + * a global. + */ + #define PARSE_ELEMENT(X,Y,Z) \ + if (isdigit(*X) || *X == '-'||*X == '+') { \ + bool negated = (*X == '-'); \ + if (negated || *X == '+') { X++; } \ + Y = (negated)?-atof(X):atof(X); \ + X = strchr(X, ','); \ + Z \ + } - PARSE_ELEMENT(find, val1, { if(find) { find +=3; }}); - PARSE_ELEMENT(find, val2, { if(find) { find +=2; }}); - PARSE_ELEMENT(find, val3, { if(find) { find +=1; }}); - #undef PARSE_ELEMENT - - printf("X:[0] = %f\n", val1); - printf("Y:[1] = %f\n", val2); - printf("Z:[2] = %f\n", val3); - + PARSE_ELEMENT(find, val1, { find ++; while (*find == ' ') { find ++; } }); + PARSE_ELEMENT(find, val2, { find ++; while (*find == ' ') { find ++; } }); + PARSE_ELEMENT(find, val3, { find ++; /* no need to do anything here */ }); + #undef PARSE_ELEMENT + #define BUILD_ELEMENT(X,Y) \ + global.type = TYPE_VECTOR; \ + global.name = util_strdup(name); \ + global.elem = (X); \ + global.offset = code_globals_elements; \ + assembly_constants_add(global); \ + code_globals_add(FLT2INT(Y)) + BUILD_ELEMENT(0, val1); + BUILD_ELEMENT(1, val2); + BUILD_ELEMENT(2, val3); + #undef BUILD_ELEMENT + } else { + /* TODO global not constant */ + } break; } /* ENTITY */ case 'E': { @@ -271,5 +318,6 @@ void asm_parse(FILE *fp) { asm_end("asm_parse_end\n"); } #undef asm_end - asm_clear(); + asm_dumps(); + asm_clear(); } diff --git a/data/test.qs b/data/test.qs index b087e4f..50a541d 100644 --- a/data/test.qs +++ b/data/test.qs @@ -83,6 +83,6 @@ FUNCTION: findfloat, $98 FUNCTION: checkextension, $99 ; constants test -VECTOR: -1, +2, 38865.444 -FLOAT: 1 +VECTOR: dude1, -1, +2, 38865.444 +FLOAT: dude2, 1 STRING: "hello world" diff --git a/gmqcc.h b/gmqcc.h index e0ae695..83c605a 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -275,6 +275,14 @@ uint32_t util_crc32(const char *, int, register const short); # define mem_d(x) util_memory_d((x), __LINE__, __FILE__) #endif +/* + * TODO: make these safer to use. Currently this only works on + * x86 and x86_64, some systems will likely not like this. Such + * as BE systems. + */ +#define FLT2INT(Y) *((int32_t*)&(Y)) +#define INT2FLT(Y) *((float *)&(Y)) + /* Builds vector type (usefull for inside structures) */ #define VECTOR_SNAP(X,Y) X ## Y #define VECTOR_FILL(X,Y) VECTOR_SNAP(X,Y) @@ -513,6 +521,7 @@ int code_chars_put (char*, size_t); extern long code_statements_elements; extern long code_chars_elements; extern long code_globals_elements; +extern int *code_globals_data; extern long code_functions_elements; extern long code_fields_elements; extern long code_defs_elements; -- 2.39.2