mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-03-21 10:21:03 +00:00
Parse vector constants and add them to the constants table now for the assembler.
This commit is contained in:
parent
8156374a71
commit
f19cbe1400
3 changed files with 85 additions and 28 deletions
100
asm.c
100
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();
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
9
gmqcc.h
9
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;
|
||||
|
|
Loading…
Reference in a new issue