]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ast.c
some debug outputs which can be activated via a define, fixing a bug where the shunti...
[xonotic/gmqcc.git] / ast.c
diff --git a/ast.c b/ast.c
index 944fee9b613dec7ba830c4a5e3d5d05397e5a540..5dfad22a408a57c84f939ab6c3d6e0022b3e318b 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -32,7 +32,7 @@
     if (!self) {                                                    \
         return NULL;                                                \
     }                                                               \
-    ast_node_init((ast_node*)self, ctx);                            \
+    ast_node_init((ast_node*)self, ctx, TYPE_##T);                  \
     ( (ast_node*)self )->node.destroy = (ast_node_delete*)destroyfn
 
 /* It must not be possible to get here. */
@@ -43,11 +43,12 @@ static GMQCC_NORETURN void _ast_node_destroy(ast_node *self)
 }
 
 /* Initialize main ast node aprts */
-static void ast_node_init(ast_node *self, lex_ctx ctx)
+static void ast_node_init(ast_node *self, lex_ctx ctx, int nodetype)
 {
     self->node.context = ctx;
     self->node.destroy = &_ast_node_destroy;
     self->node.keep    = false;
+    self->node.nodetype = nodetype;
 }
 
 /* General expression initialization */
@@ -93,6 +94,15 @@ static ast_value* ast_value_copy(const ast_value *self)
     return cp;
 }
 
+static ast_expression* ast_shallow_type(lex_ctx ctx, int vtype)
+{
+    ast_instantiate(ast_expression, ctx, ast_expression_delete_full);
+    self->expression.codegen = NULL;
+    self->expression.next    = NULL;
+    self->expression.vtype   = vtype;
+    return self;
+}
+
 static ast_expression* ast_type_copy(lex_ctx ctx, const ast_expression *ex)
 {
     size_t i;
@@ -297,6 +307,44 @@ void ast_entfield_delete(ast_entfield *self)
     mem_d(self);
 }
 
+ast_member* ast_member_new(lex_ctx ctx, ast_expression *owner, unsigned int field)
+{
+    ast_instantiate(ast_member, ctx, ast_member_delete);
+    if (field >= 3) {
+        mem_d(self);
+        return NULL;
+    }
+
+    if (owner->expression.vtype != TYPE_VECTOR &&
+        owner->expression.vtype != TYPE_FIELD) {
+        printf("ast_member on an invalid owner of type %i\n", (int)owner->expression.vtype);
+        mem_d(self);
+        return NULL;
+    }
+
+    ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_member_codegen);
+
+    if (owner->expression.vtype == TYPE_VECTOR) {
+        self->expression.vtype = TYPE_FLOAT;
+        self->expression.next  = NULL;
+    } else {
+        self->expression.vtype = TYPE_FIELD;
+        self->expression.next = ast_shallow_type(ctx, TYPE_FLOAT);
+    }
+
+    self->owner = owner;
+    self->field = field;
+
+    return self;
+}
+
+void ast_member_delete(ast_member *self)
+{
+    ast_unref(self->owner);
+    ast_expression_delete((ast_expression*)self);
+    mem_d(self);
+}
+
 ast_ifthen* ast_ifthen_new(lex_ctx ctx, ast_expression *cond, ast_expression *ontrue, ast_expression *onfalse)
 {
     ast_instantiate(ast_ifthen, ctx, ast_ifthen_delete);
@@ -416,7 +464,7 @@ void ast_call_delete(ast_call *self)
 }
 
 ast_store* ast_store_new(lex_ctx ctx, int op,
-                         ast_value *dest, ast_expression *source)
+                         ast_expression *dest, ast_expression *source)
 {
     ast_instantiate(ast_store, ctx, ast_store_delete);
     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_store_codegen);
@@ -601,6 +649,18 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir)
         return true;
     }
 
+    if (self->expression.vtype == TYPE_FIELD) {
+        v = ir_builder_create_field(ir, self->name, self->expression.next->expression.vtype);
+        if (!v)
+            return false;
+        if (self->isconst) {
+            printf("TODO: constant field pointers with value\n");
+            goto error;
+        }
+        self->ir_v = v;
+        return true;
+    }
+
     v = ir_builder_create_global(ir, self->name, self->expression.vtype);
     if (!v) {
         printf("ir_builder_create_global failed\n");
@@ -924,6 +984,26 @@ bool ast_entfield_codegen(ast_entfield *self, ast_function *func, bool lvalue, i
     return true;
 }
 
+bool ast_member_codegen(ast_member *self, ast_function *func, bool lvalue, ir_value **out)
+{
+    ast_expression_codegen *cgen;
+    ir_value *vec;
+
+    cgen = self->owner->expression.codegen;
+    if (!(*cgen)((ast_expression*)(self->owner), func, true, &vec))
+        return false;
+
+    if (vec->vtype != TYPE_VECTOR &&
+        !(vec->vtype == TYPE_FIELD && self->owner->expression.next->expression.vtype == TYPE_VECTOR))
+    {
+        return false;
+    }
+
+    *out = ir_value_vector_member(vec, self->field);
+
+    return (*out != NULL);
+}
+
 bool ast_ifthen_codegen(ast_ifthen *self, ast_function *func, bool lvalue, ir_value **out)
 {
     ast_expression_codegen *cgen;