]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
Parse vector constants and add them to the constants table now for the assembler.
authorDale Weiler <killfieldengine@gmail.com>
Sun, 29 Apr 2012 23:03:06 +0000 (19:03 -0400)
committerDale Weiler <killfieldengine@gmail.com>
Sun, 29 Apr 2012 23:03:06 +0000 (19:03 -0400)
asm.c
data/test.qs
gmqcc.h

diff --git a/asm.c b/asm.c
index ee83eaf28a124374c3b80fb504bfd27bb895f8a6..ad47b5785f89877c25705f78f9784f4aebb01808 100644 (file)
--- 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();
 }
index b087e4f8449734e7bd637ac690de6206e4138333..50a541dccde2676950875875d54a4587d88f21b9 100644 (file)
@@ -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 e0ae695194d43de21f8b4fa662c45fe26cd5c597..83c605afdd243deefafe774781b08d4fc5c5fa3f 100644 (file)
--- 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;