]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - fold.c
folding for lteqgt (less than equal to or greater than) operator a.k.a <=> which...
[xonotic/gmqcc.git] / fold.c
diff --git a/fold.c b/fold.c
index 403b6f51b6d2a180438f08d4e7138d55387c9379..d7de3ae85458a19eeb223d0740fac85bad791f99 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
@@ -139,17 +137,9 @@ static GMQCC_INLINE bool vec3_pbool(vec3_t a) {
     return (a.x && a.y && a.z);
 }
 
-
-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;
-}
-
+#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));
@@ -409,6 +399,17 @@ static GMQCC_INLINE ast_expression *fold_op_andor(fold_t *fold, ast_value *a, as
     return NULL;
 }
 
+static GMQCC_INLINE ast_expression *fold_op_lteqgt(fold_t *fold, ast_value *a, ast_value *b) {
+    if (!isfloats(a, b))
+        return NULL;
+
+    if (fold_immvalue_float(a)  < fold_immvalue_float(b)) return (ast_expression*)fold->imm_float[2];/* -1 */
+    if (fold_immvalue_float(a) == fold_immvalue_float(b)) return (ast_expression*)fold->imm_float[0];/* 0  */
+    if (fold_immvalue_float(a)  > fold_immvalue_float(b)) return (ast_expression*)fold->imm_float[1];/* 1  */
+
+    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];
@@ -474,16 +475,14 @@ 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);
-        case opid2('|','|'): return fold_op_andor(fold, a, b, true);
-        case opid2('&','&'): return fold_op_andor(fold, a, b, false);
+        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 opid3('<','=','>'): return fold_op_lteqgt(fold, a, b);
         case opid2('?',':'):
             /* TODO: seperate function for this case */
             return NULL;
-        case opid3('<','=','>'):
-            /* TODO: seperate function for this case */
-            return NULL;
     }
     return NULL;
 }