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);
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.
/* 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': {
asm_end("asm_parse_end\n");
}
#undef asm_end
- asm_clear();
+ asm_dumps();
+ asm_clear();
}
# 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)
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;