]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ast.c
Make ** RIGHT associative
[xonotic/gmqcc.git] / ast.c
diff --git a/ast.c b/ast.c
index 7f6841fb96aea414e5d7f6afa78922b4f7d995f3..c0c92fbe3ab122f7c15fa0b0a588b54f7f549c0a 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -103,10 +103,6 @@ ast_value* ast_value_copy(const ast_value *self)
     ast_value *cp = ast_value_new(self->expression.node.context, self->name, self->expression.vtype);
     if (self->expression.next) {
         cp->expression.next = ast_type_copy(self->expression.node.context, self->expression.next);
-        if (!cp->expression.next) {
-            ast_value_delete(cp);
-            return NULL;
-        }
     }
     fromex   = &self->expression;
     selfex = &cp->expression;
@@ -114,16 +110,12 @@ ast_value* ast_value_copy(const ast_value *self)
     selfex->flags    = fromex->flags;
     for (i = 0; i < vec_size(fromex->params); ++i) {
         ast_value *v = ast_value_copy(fromex->params[i]);
-        if (!v) {
-            ast_value_delete(cp);
-            return NULL;
-        }
         vec_push(selfex->params, v);
     }
     return cp;
 }
 
-bool ast_type_adopt_impl(ast_expression *self, const ast_expression *other)
+void ast_type_adopt_impl(ast_expression *self, const ast_expression *other)
 {
     size_t i;
     const ast_expression_common *fromex;
@@ -131,8 +123,6 @@ bool ast_type_adopt_impl(ast_expression *self, const ast_expression *other)
     self->expression.vtype = other->expression.vtype;
     if (other->expression.next) {
         self->expression.next = (ast_expression*)ast_type_copy(ast_ctx(self), other->expression.next);
-        if (!self->expression.next)
-            return false;
     }
     fromex   = &other->expression;
     selfex = &self->expression;
@@ -140,11 +130,8 @@ bool ast_type_adopt_impl(ast_expression *self, const ast_expression *other)
     selfex->flags    = fromex->flags;
     for (i = 0; i < vec_size(fromex->params); ++i) {
         ast_value *v = ast_value_copy(fromex->params[i]);
-        if (!v)
-            return false;
         vec_push(selfex->params, v);
     }
-    return true;
 }
 
 static ast_expression* ast_shallow_type(lex_ctx ctx, int vtype)
@@ -178,13 +165,7 @@ ast_expression* ast_type_copy(lex_ctx ctx, const ast_expression *ex)
 
         selfex->vtype = fromex->vtype;
         if (fromex->next)
-        {
             selfex->next = ast_type_copy(ctx, fromex->next);
-            if (!selfex->next) {
-                ast_expression_delete_full(self);
-                return NULL;
-            }
-        }
         else
             selfex->next = NULL;
 
@@ -192,10 +173,6 @@ ast_expression* ast_type_copy(lex_ctx ctx, const ast_expression *ex)
         selfex->flags    = fromex->flags;
         for (i = 0; i < vec_size(fromex->params); ++i) {
             ast_value *v = ast_value_copy(fromex->params[i]);
-            if (!v) {
-                ast_expression_delete_full(self);
-                return NULL;
-            }
             vec_push(selfex->params, v);
         }
 
@@ -429,13 +406,17 @@ ast_binary* ast_binary_new(lex_ctx ctx, int op,
     else
         self->expression.vtype = left->expression.vtype;
 
+    /* references all */
+    self->refs = AST_REF_ALL;
+
     return self;
 }
 
 void ast_binary_delete(ast_binary *self)
 {
-    ast_unref(self->left);
-    ast_unref(self->right);
+    if (self->refs & AST_REF_LEFT)  ast_unref(self->left);
+    if (self->refs & AST_REF_RIGHT) ast_unref(self->right);
+
     ast_expression_delete((ast_expression*)self);
     mem_d(self);
 }
@@ -455,11 +436,7 @@ ast_binstore* ast_binstore_new(lex_ctx ctx, int storop, int op,
 
     self->keep_dest = false;
 
-    if (!ast_type_adopt(self, left)) {
-        ast_delete(self);
-        return NULL;
-    }
-
+    ast_type_adopt(self, left);
     return self;
 }
 
@@ -545,11 +522,7 @@ ast_entfield* ast_entfield_new_force(lex_ctx ctx, ast_expression *entity, ast_ex
     ast_propagate_effects(self, entity);
     ast_propagate_effects(self, field);
 
-    if (!ast_type_adopt(self, outtype)) {
-        ast_entfield_delete(self);
-        return NULL;
-    }
-
+    ast_type_adopt(self, outtype);
     return self;
 }
 
@@ -641,10 +614,7 @@ ast_array_index* ast_array_index_new(lex_ctx ctx, ast_expression *array, ast_exp
     ast_propagate_effects(self, array);
     ast_propagate_effects(self, index);
 
-    if (!ast_type_adopt(self, outtype)) {
-        ast_array_index_delete(self);
-        return NULL;
-    }
+    ast_type_adopt(self, outtype);
     if (array->expression.vtype == TYPE_FIELD && outtype->expression.vtype == TYPE_ARRAY) {
         if (self->expression.vtype != TYPE_ARRAY) {
             compile_error(ast_ctx(self), "array_index node on type");
@@ -660,8 +630,10 @@ ast_array_index* ast_array_index_new(lex_ctx ctx, ast_expression *array, ast_exp
 
 void ast_array_index_delete(ast_array_index *self)
 {
-    ast_unref(self->array);
-    ast_unref(self->index);
+    if (self->array)
+        ast_unref(self->array);
+    if (self->index)
+        ast_unref(self->index);
     ast_expression_delete((ast_expression*)self);
     mem_d(self);
 }
@@ -719,10 +691,7 @@ ast_ternary* ast_ternary_new(lex_ctx ctx, ast_expression *cond, ast_expression *
 
     if (ontrue->expression.vtype == TYPE_NIL)
         exprtype = onfalse;
-    if (!ast_type_adopt(self, exprtype)) {
-        ast_ternary_delete(self);
-        return NULL;
-    }
+    ast_type_adopt(self, exprtype);
 
     return self;
 }
@@ -976,10 +945,7 @@ ast_store* ast_store_new(lex_ctx ctx, int op,
     self->dest = dest;
     self->source = source;
 
-    if (!ast_type_adopt(self, dest)) {
-        ast_delete(self);
-        return NULL;
-    }
+    ast_type_adopt(self, dest);
 
     return self;
 }
@@ -1013,10 +979,7 @@ bool ast_block_add_expr(ast_block *self, ast_expression *e)
         ast_delete(self->expression.next);
         self->expression.next = NULL;
     }
-    if (!ast_type_adopt(self, e)) {
-        compile_error(ast_ctx(self), "internal error: failed to adopt type");
-        return false;
-    }
+    ast_type_adopt(self, e);
     return true;
 }
 
@@ -1042,13 +1005,11 @@ void ast_block_delete(ast_block *self)
     mem_d(self);
 }
 
-bool ast_block_set_type(ast_block *self, ast_expression *from)
+void ast_block_set_type(ast_block *self, ast_expression *from)
 {
     if (self->expression.next)
         ast_delete(self->expression.next);
-    if (!ast_type_adopt(self, from))
-        return false;
-    return true;
+    ast_type_adopt(self, from);
 }
 
 ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype)
@@ -2226,9 +2187,11 @@ bool ast_array_index_codegen(ast_array_index *self, ast_function *func, bool lva
 
     if (!lvalue && self->expression.outr) {
         *out = self->expression.outr;
+        return true;
     }
     if (lvalue && self->expression.outl) {
         *out = self->expression.outl;
+        return true;
     }
 
     if (!ast_istype(self->array, ast_value)) {