]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - fold.c
Feed clang demon
[xonotic/gmqcc.git] / fold.c
diff --git a/fold.c b/fold.c
index 98e854ee3ceedd91c082a5d7e4dd496f97c378d4..f2ec7457ad3d48c3045ddc645ff862b2b5c66fe4 100644 (file)
--- a/fold.c
+++ b/fold.c
@@ -37,8 +37,6 @@
  * 
  * This file is thus, split into two parts.
  */
-ast_expression **fold_const_values = NULL;
-
 static GMQCC_INLINE bool fold_possible(const ast_value *val) {
     return  ast_istype((ast_expression*)val, ast_value) &&
             val->hasvalue && (val->cvq == CV_CONST)     &&
@@ -53,7 +51,7 @@ static GMQCC_INLINE bool fold_possible(const ast_value *val) {
 #define isstring(X)     (isstringonly(X) && fold_possible(X))
 #define isfloats(X,Y)   (isfloat     (X) && isfloat (Y))
 #define isvectors(X,Y)  (isvector    (X) && isvector(Y))
-#define isstrings(X,Y)  (isstring    (X) && isstring(Y))
+/*#define isstrings(X,Y)  (isstring    (X) && isstring(Y))*/
 
 /*
  * Implementation of basic vector math for vec3_t, for trivial constant
@@ -113,7 +111,6 @@ static GMQCC_INLINE qcfloat_t vec3_mulvv(vec3_t a, vec3_t b) {
     return (a.x * b.x + a.y * b.y + a.z * b.z);
 }
 
-
 static GMQCC_INLINE vec3_t vec3_mulvf(vec3_t a, qcfloat_t b) {
     vec3_t out;
     out.x = a.x * b;
@@ -136,17 +133,13 @@ static GMQCC_INLINE vec3_t vec3_create(float x, float y, float z) {
     return out;
 }
 
-
-static GMQCC_INLINE float fold_immvalue_float(ast_value *expr) {
-    return expr->constval.vfloat;
-}
-static GMQCC_INLINE vec3_t fold_immvalue_vector(ast_value *expr) {
-    return expr->constval.vvec;
-}
-static GMQCC_INLINE const char *fold_immvalue_string(ast_value *expr) {
-    return expr->constval.vstring;
+static GMQCC_INLINE bool vec3_pbool(vec3_t a) {
+    return (a.x && a.y && a.z);
 }
 
+#define fold_immvalue_float(E)  ((E)->constval.vfloat)
+#define fold_immvalue_vector(E) ((E)->constval.vvec)
+#define fold_immvalue_string(E) ((E)->constval.vstring)
 
 fold_t *fold_init(parser_t *parser) {
     fold_t *fold                 = (fold_t*)mem_a(sizeof(fold_t));
@@ -357,6 +350,24 @@ static GMQCC_INLINE ast_expression *fold_op_mul(fold_t *fold, ast_value *a, ast_
     return NULL;
 }
 
+static GMQCC_INLINE bool fold_immediate_true(fold_t *fold, ast_value *v) {
+    switch (v->expression.vtype) {
+        case TYPE_FLOAT:   return !!v->constval.vfloat;
+        case TYPE_INTEGER: return !!v->constval.vint;
+        case TYPE_VECTOR:  return OPTS_FLAG(CORRECT_LOGIC) ? vec3_pbool(v->constval.vvec) : !!v->constval.vvec.x;
+        case TYPE_STRING:
+            if (!v->constval.vstring)
+                return false;
+            if (OPTS_FLAG(TRUE_EMPTY_STRINGS))
+                return true;
+            return !!v->constval.vstring[0];
+        default:
+            compile_error(fold_ctx(fold), "internal error: fold_immediate_true on invalid type");
+            break;
+    }
+    return !!v->constval.vfunc;
+}
+
 static GMQCC_INLINE ast_expression *fold_op_div(fold_t *fold, ast_value *a, ast_value *b) {
     if (isfloatonly(a)) {
         return (fold_possible(a) && fold_possible(b))
@@ -373,6 +384,21 @@ static GMQCC_INLINE ast_expression *fold_op_div(fold_t *fold, ast_value *a, ast_
     return NULL;
 }
 
+static GMQCC_INLINE ast_expression *fold_op_andor(fold_t *fold, ast_value *a, ast_value *b, bool isor) {
+    if (fold_possible(a) && fold_possible(b)) {
+        if (OPTS_FLAG(PERL_LOGIC)) {
+            if (fold_immediate_true(fold, b))
+                return (ast_expression*)b;
+        } else {
+            return ((isor) ? (fold_immediate_true(fold, a) || fold_immediate_true(fold, b))
+                           : (fold_immediate_true(fold, a) && fold_immediate_true(fold, b)))
+                                 ? (ast_expression*)fold->imm_float[1]  /* 1.0f */
+                                 : (ast_expression*)fold->imm_float[0]; /* 0.0f */
+        }
+    }
+    return NULL;
+}
+
 ast_expression *fold_op(fold_t *fold, const oper_info *info, ast_expression **opexprs) {
     ast_value *a = (ast_value*)opexprs[0];
     ast_value *b = (ast_value*)opexprs[1];
@@ -438,16 +464,10 @@ ast_expression *fold_op(fold_t *fold, const oper_info *info, ast_expression **op
             return isfloat(a)              ? fold_constgen_float (fold, ~(qcint_t)fold_immvalue_float(a))
                  : NULL;
 
-        case opid1('*'): return fold_op_mul(fold, a, b);
-        case opid1('/'): return fold_op_div(fold, a, b);
-            /* TODO: seperate function for this case */
-            return NULL;
-        case opid2('|','|'):
-            /* TODO: seperate function for this case */
-            return NULL;
-        case opid2('&','&'):
-            /* TODO: seperate function for this case */
-            return NULL;
+        case opid1('*'):     return fold_op_mul  (fold, a, b);
+        case opid1('/'):     return fold_op_div  (fold, a, b);
+        case opid2('|','|'): return fold_op_andor(fold, a, b, true);
+        case opid2('&','&'): return fold_op_andor(fold, a, b, false);
         case opid2('?',':'):
             /* TODO: seperate function for this case */
             return NULL;