]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
relation operation in #if just as wrong as in fteqcc
authorWolfgang (Blub) Bumiller <blub@speed.at>
Fri, 23 Nov 2012 20:04:57 +0000 (21:04 +0100)
committerWolfgang (Blub) Bumiller <blub@speed.at>
Fri, 23 Nov 2012 20:05:07 +0000 (21:05 +0100)
ftepp.c

diff --git a/ftepp.c b/ftepp.c
index 68d46b24b7699b13acf19b99bd60a5d43dd4ebe8..4cdfb68fbf6f04042722ee102be0097b4c90628a 100644 (file)
--- a/ftepp.c
+++ b/ftepp.c
@@ -655,7 +655,17 @@ cleanup:
  * parameter lists on macros are errors
  * No mathematical calculations are executed
  */
  * parameter lists on macros are errors
  * No mathematical calculations are executed
  */
-static bool ftepp_if_expr(ftepp_t *ftepp, bool *out)
+static bool ftepp_if_expr(ftepp_t *ftepp, bool *out, double *value_out);
+static bool ftepp_if_op(ftepp_t *ftepp)
+{
+    ftepp->lex->flags.noops = false;
+    ftepp_next(ftepp);
+    if (!ftepp_skipspace(ftepp))
+        return false;
+    ftepp->lex->flags.noops = true;
+    return true;
+}
+static bool ftepp_if_value(ftepp_t *ftepp, bool *out, double *value_out)
 {
     ppmacro *macro;
     bool     wasnot = false;
 {
     ppmacro *macro;
     bool     wasnot = false;
@@ -707,13 +717,16 @@ static bool ftepp_if_expr(ftepp_t *ftepp, bool *out)
             macro = ftepp_macro_find(ftepp, ftepp_tokval(ftepp));
             if (!macro || !vec_size(macro->output)) {
                 *out = false;
             macro = ftepp_macro_find(ftepp, ftepp_tokval(ftepp));
             if (!macro || !vec_size(macro->output)) {
                 *out = false;
+                *value_out = 0;
             } else {
                 /* This does not expand recursively! */
                 switch (macro->output[0]->token) {
                     case TOKEN_INTCONST:
             } else {
                 /* This does not expand recursively! */
                 switch (macro->output[0]->token) {
                     case TOKEN_INTCONST:
-                        *out = !!(macro->output[0]->constval.f);
+                        *value_out = macro->output[0]->constval.i;
+                        *out = !!(macro->output[0]->constval.i);
                         break;
                     case TOKEN_FLOATCONST:
                         break;
                     case TOKEN_FLOATCONST:
+                        *value_out = macro->output[0]->constval.f;
                         *out = !!(macro->output[0]->constval.f);
                         break;
                     default:
                         *out = !!(macro->output[0]->constval.f);
                         break;
                     default:
@@ -726,15 +739,17 @@ static bool ftepp_if_expr(ftepp_t *ftepp, bool *out)
             *out = false;
             break;
         case TOKEN_INTCONST:
             *out = false;
             break;
         case TOKEN_INTCONST:
+            *value_out = ftepp->lex->tok.constval.i;
             *out = !!(ftepp->lex->tok.constval.i);
             break;
         case TOKEN_FLOATCONST:
             *out = !!(ftepp->lex->tok.constval.i);
             break;
         case TOKEN_FLOATCONST:
+            *value_out = ftepp->lex->tok.constval.f;
             *out = !!(ftepp->lex->tok.constval.f);
             break;
 
         case '(':
             ftepp_next(ftepp);
             *out = !!(ftepp->lex->tok.constval.f);
             break;
 
         case '(':
             ftepp_next(ftepp);
-            if (!ftepp_if_expr(ftepp, out))
+            if (!ftepp_if_expr(ftepp, out, value_out))
                 return false;
             if (ftepp->token != ')') {
                 ftepp_error(ftepp, "expected closing paren in #if expression");
                 return false;
             if (ftepp->token != ')') {
                 ftepp_error(ftepp, "expected closing paren in #if expression");
@@ -743,38 +758,89 @@ static bool ftepp_if_expr(ftepp_t *ftepp, bool *out)
             break;
 
         default:
             break;
 
         default:
-            ftepp_error(ftepp, "junk in #if");
+            ftepp_error(ftepp, "junk in #if: `%s` ...", ftepp_tokval(ftepp));
             return false;
     }
             return false;
     }
-    if (wasnot)
+    if (wasnot) {
         *out = !*out;
         *out = !*out;
+        *value_out = (*out ? 1 : 0);
+    }
+    return true;
+}
 
 
-    ftepp->lex->flags.noops = false;
-    ftepp_next(ftepp);
-    if (!ftepp_skipspace(ftepp))
+/*
+static bool ftepp_if_nextvalue(ftepp_t *ftepp, bool *out, double *value_out)
+{
+    if (!ftepp_next(ftepp))
         return false;
         return false;
-    ftepp->lex->flags.noops = true;
+    return ftepp_if_value(ftepp, out, value_out);
+}
+*/
 
 
-    if (ftepp->token == ')')
-        return true;
+static bool ftepp_if_expr(ftepp_t *ftepp, bool *out, double *value_out)
+{
+    if (!ftepp_if_value(ftepp, out, value_out))
+        return false;
+
+    if (!ftepp_if_op(ftepp))
+        return false;
 
 
-    if (ftepp->token != TOKEN_OPERATOR)
+    if (ftepp->token == ')' || ftepp->token != TOKEN_OPERATOR)
         return true;
 
         return true;
 
+    /* FTEQCC is all right-associative and no precedence here */
     if (!strcmp(ftepp_tokval(ftepp), "&&") ||
         !strcmp(ftepp_tokval(ftepp), "||"))
     {
         bool next = false;
         char opc  = ftepp_tokval(ftepp)[0];
     if (!strcmp(ftepp_tokval(ftepp), "&&") ||
         !strcmp(ftepp_tokval(ftepp), "||"))
     {
         bool next = false;
         char opc  = ftepp_tokval(ftepp)[0];
+        double nextvalue;
 
 
-        ftepp_next(ftepp);
-        if (!ftepp_if_expr(ftepp, &next))
+        (void)nextvalue;
+        if (!ftepp_next(ftepp))
+            return false;
+        if (!ftepp_if_expr(ftepp, &next, &nextvalue))
             return false;
 
         if (opc == '&')
             *out = *out && next;
         else
             *out = *out || next;
             return false;
 
         if (opc == '&')
             *out = *out && next;
         else
             *out = *out || next;
+
+        *value_out = (*out ? 1 : 0);
+        return true;
+    }
+    else if (!strcmp(ftepp_tokval(ftepp), "==") ||
+             !strcmp(ftepp_tokval(ftepp), "!=") ||
+             !strcmp(ftepp_tokval(ftepp), ">=") ||
+             !strcmp(ftepp_tokval(ftepp), "<=") ||
+             !strcmp(ftepp_tokval(ftepp), ">") ||
+             !strcmp(ftepp_tokval(ftepp), "<"))
+    {
+        bool next = false;
+        const char opc0 = ftepp_tokval(ftepp)[0];
+        const char opc1 = ftepp_tokval(ftepp)[1];
+        double other;
+
+        if (!ftepp_next(ftepp))
+            return false;
+        if (!ftepp_if_expr(ftepp, &next, &other))
+            return false;
+
+        if (opc0 == '=')
+            *out = (*value_out == other);
+        else if (opc0 == '!')
+            *out = (*value_out != other);
+        else if (opc0 == '>') {
+            if (opc1 == '=') *out = (*value_out >= other);
+            else             *out = (*value_out > other);
+        }
+        else if (opc0 == '<') {
+            if (opc1 == '=') *out = (*value_out <= other);
+            else             *out = (*value_out < other);
+        }
+        *value_out = (*out ? 1 : 0);
+
         return true;
     }
     else {
         return true;
     }
     else {
@@ -786,6 +852,7 @@ static bool ftepp_if_expr(ftepp_t *ftepp, bool *out)
 static bool ftepp_if(ftepp_t *ftepp, ppcondition *cond)
 {
     bool result = false;
 static bool ftepp_if(ftepp_t *ftepp, ppcondition *cond)
 {
     bool result = false;
+    double dummy = 0;
 
     memset(cond, 0, sizeof(*cond));
     (void)ftepp_next(ftepp);
 
     memset(cond, 0, sizeof(*cond));
     (void)ftepp_next(ftepp);
@@ -797,7 +864,7 @@ static bool ftepp_if(ftepp_t *ftepp, ppcondition *cond)
         return false;
     }
 
         return false;
     }
 
-    if (!ftepp_if_expr(ftepp, &result))
+    if (!ftepp_if_expr(ftepp, &result, &dummy))
         return false;
 
     cond->on = result;
         return false;
 
     cond->on = result;