]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - parser.c
Merge branch 'cooking' of github.com:graphitemaster/gmqcc into cooking
[xonotic/gmqcc.git] / parser.c
index 25c9c8c6fd279a6a40d8df6397c076cafd36f6d2..1adab691326b9ea844e2d0cf82b65a8355ea0a08 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -1068,6 +1068,51 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
                 out = (ast_expression*)ast_ternary_new(ctx, exprs[0], exprs[1], exprs[2]);
             break;
 
+        case opid3('<', '=', '>'): /* -1, 0, or 1 */
+            if (NotSameType(TYPE_FLOAT)) {
+                ast_type_to_string(exprs[0], ty1, sizeof(ty1));
+                ast_type_to_string(exprs[1], ty2, sizeof(ty2));
+                compile_error(ctx, "invalid types used in comparision: %s and %s",
+                    ty1, ty2);
+
+                return false;
+            }
+
+            if (CanConstFold(exprs[0], exprs[1])) {
+                if (ConstF(0) < ConstF(1))
+                    out = (ast_expression*)parser_const_float_neg1(parser);
+                else if (ConstF(0) == ConstF(1))
+                    out = (ast_expression*)parser_const_float_0(parser);
+                else if (ConstF(0) > ConstF(1))
+                    out = (ast_expression*)parser_const_float_1(parser);
+            } else {
+                    /* if (lt) { */
+                out = (ast_expression*)ast_ternary_new(ctx,
+                        (ast_expression*)ast_binary_new(ctx, INSTR_LT, exprs[0], exprs[1]),
+
+                        /* out = -1 */
+                        (ast_expression*)parser_const_float_neg1(parser),
+
+                    /* } else { */
+                        /* if (eq) { */
+                        (ast_expression*)ast_ternary_new(ctx,
+                            (ast_expression*)ast_binary_new(ctx, INSTR_EQ_F, exprs[0], exprs[1]),
+
+                            /* out = 0 */
+                            (ast_expression*)parser_const_float_0(parser),
+
+                        /* } else { */
+
+                            /* out = 1 */
+                            (ast_expression*)parser_const_float_1(parser)
+                        /* } */
+                        )
+                    /* } */
+                    );
+
+            }
+            break;
+
         case opid1('>'):
             generated_op += 1; /* INSTR_GT */
         case opid1('<'):
@@ -1372,7 +1417,6 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
             else
                 out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F, (ast_expression*)parser_const_float_neg1(parser), exprs[0]);
             break;
-            
     }
 #undef NotSameType
 
@@ -1900,11 +1944,6 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
             if (o == operator_count) {
                 compile_error(parser_ctx(parser), "unknown operator: %s", parser_tokval(parser));
                 goto onerr;
-#if 0
-/* Are there any expressions which actually end with an operator? */
-                /* no operator found... must be the end of the statement */
-                break;
-#endif
             }
             /* found an operator */
             op = &operators[o];