]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ast.c
Fixed whitespace
[xonotic/gmqcc.git] / ast.c
diff --git a/ast.c b/ast.c
index d845eb24a5db26dfd94e962bf198f2657efada26..94b254cc91f5a3ad3931fe81d9654e1d738f4047 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -1207,6 +1207,63 @@ bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_valu
     return true;
 }
 
+static bool ast_global_array_set(ast_value *self)
+{
+    size_t count = vec_size(self->initlist);
+    size_t i;
+
+    if (count > self->expression.count) {
+        compile_error(ast_ctx(self), "too many elements in initializer");
+        count = self->expression.count;
+    }
+    else if (count < self->expression.count) {
+        /* add this?
+        compile_warning(ast_ctx(self), "not all elements are initialized");
+        */
+    }
+
+    for (i = 0; i != count; ++i) {
+        switch (self->expression.next->vtype) {
+            case TYPE_FLOAT:
+                if (!ir_value_set_float(self->ir_values[i], self->initlist[i].vfloat))
+                    return false;
+                break;
+            case TYPE_VECTOR:
+                if (!ir_value_set_vector(self->ir_values[i], self->initlist[i].vvec))
+                    return false;
+                break;
+            case TYPE_STRING:
+                if (!ir_value_set_string(self->ir_values[i], self->initlist[i].vstring))
+                    return false;
+                break;
+            case TYPE_ARRAY:
+                /* we don't support them in any other place yet either */
+                compile_error(ast_ctx(self), "TODO: nested arrays");
+                return false;
+            case TYPE_FUNCTION:
+                /* this requiers a bit more work - similar to the fields I suppose */
+                compile_error(ast_ctx(self), "global of type function not properly generated");
+                return false;
+            case TYPE_FIELD:
+                if (!self->initlist[i].vfield) {
+                    compile_error(ast_ctx(self), "field constant without vfield set");
+                    return false;
+                }
+                if (!self->initlist[i].vfield->ir_v) {
+                    compile_error(ast_ctx(self), "field constant generated before its field");
+                    return false;
+                }
+                if (!ir_value_set_field(self->ir_values[i], self->initlist[i].vfield->ir_v))
+                    return false;
+                break;
+            default:
+                compile_error(ast_ctx(self), "TODO: global constant type %i", self->expression.vtype);
+                break;
+        }
+    }
+    return true;
+}
+
 bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield)
 {
     ir_value *v = NULL;
@@ -1316,6 +1373,11 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield)
         ast_expression *elemtype = self->expression.next;
         int vtype = elemtype->vtype;
 
+        if (self->expression.flags & AST_FLAG_ARRAY_INIT && !self->expression.count) {
+            compile_error(ast_ctx(self), "array `%s' has no size", self->name);
+            return false;
+        }
+
         /* same as with field arrays */
         if (!self->expression.count || self->expression.count > OPTS_OPTION_U32(OPTION_MAX_ARRAY_SIZE))
             compile_error(ast_ctx(self), "Invalid array of size %lu", (unsigned long)self->expression.count);
@@ -1367,6 +1429,13 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield)
         v->context = ast_ctx(self);
     }
 
+    /* link us to the ir_value */
+    v->cvq = self->cvq;
+    self->ir_v = v;
+    if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
+        self->ir_v->flags |= IR_FLAG_INCLUDE_DEF;
+
+    /* initialize */
     if (self->hasvalue) {
         switch (self->expression.vtype)
         {
@@ -1383,7 +1452,7 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield)
                     goto error;
                 break;
             case TYPE_ARRAY:
-                compile_error(ast_ctx(self), "TODO: global constant array");
+                ast_global_array_set(self);
                 break;
             case TYPE_FUNCTION:
                 compile_error(ast_ctx(self), "global of type function not properly generated");
@@ -1408,12 +1477,6 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield)
                 break;
         }
     }
-
-    /* link us to the ir_value */
-    v->cvq = self->cvq;
-    self->ir_v = v;
-    if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
-        self->ir_v->flags |= IR_FLAG_INCLUDE_DEF;
     return true;
 
 error: /* clean up */