From d8890fda9e8234870cd330d968e90ad7d3ee4bcb Mon Sep 17 00:00:00 2001
From: "Wolfgang (Blub) Bumiller" <blub@speed.at>
Date: Mon, 13 Aug 2012 15:24:55 +0200
Subject: [PATCH] More operations

---
 parser.c | 52 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 44 insertions(+), 8 deletions(-)

diff --git a/parser.c b/parser.c
index 7708144..46c7ff4 100644
--- a/parser.c
+++ b/parser.c
@@ -327,6 +327,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
     ast_expression *exprs[3];
     ast_block      *blocks[3];
     size_t i, assignop;
+    qcint  generated_op = 0;
 
     if (!sy->ops_count) {
         parseerror(parser, "internal error: missing operator");
@@ -361,6 +362,9 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
         return false;
     }
 
+#define NotSameType(T) \
+             (exprs[0]->expression.vtype != exprs[1]->expression.vtype || \
+              exprs[0]->expression.vtype != T)
     switch (op->id)
     {
         default:
@@ -410,7 +414,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
                            type_name[exprs[1]->expression.vtype]);
                 return false;
             }
-            if (exprs[0]->expression.vteyp != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) {
+            if (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) {
                 parseerror(parser, "type error: %s - %s not defined",
                            type_name[exprs[0]->expression.vtype],
                            type_name[exprs[1]->expression.vtype]);
@@ -437,7 +441,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
                            type_name[exprs[0]->expression.vtype]);
                 return false;
             }
-            if (exprs[0]->expression.vteyp != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) {
+            if (exprs[0]->expression.vtype != TYPE_VECTOR && exprs[0]->expression.vtype != TYPE_FLOAT) {
                 parseerror(parser, "type error: %s - %s not defined",
                            type_name[exprs[0]->expression.vtype],
                            type_name[exprs[1]->expression.vtype]);
@@ -490,9 +494,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
             };
             break;
         case opid1('/'):
-            if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
-                exprs[0]->expression.vtype != TYPE_FLOAT)
-            {
+            if (NotSameType(TYPE_FLOAT)) {
                 parseerror(parser, "type error: cannot divide types %s and %s",
                            type_name[exprs[0]->expression.vtype],
                            type_name[exprs[1]->expression.vtype]);
@@ -502,9 +504,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
             break;
         case opid1('|'):
         case opid1('&'):
-            if (exprs[0]->expression.vtype != exprs[1]->expression.vtype ||
-                exprs[0]->expression.vtype != TYPE_FLOAT)
-            {
+            if (NotSameType(TYPE_FLOAT)) {
                 parseerror(parser, "type error: cannot perform bit operations on types %s and %s",
                            type_name[exprs[0]->expression.vtype],
                            type_name[exprs[1]->expression.vtype]);
@@ -515,6 +515,41 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
                                                   exprs[0], exprs[1]);
             break;
 
+        case opid1('>'):
+            generated_op += 1; /* INSTR_GT */
+        case opid1('<'):
+            generated_op += 1; /* INSTR_LT */
+        case opid2('>', '='):
+            generated_op += 1; /* INSTR_GE */
+        case opid2('<', '='):
+            generated_op += INSTR_LE;
+            if (NotSameType(TYPE_FLOAT)) {
+                parseerror(parser, "type error: cannot compare types %s and %s",
+                           type_name[exprs[0]->expression.vtype],
+                           type_name[exprs[1]->expression.vtype]);
+                return false;
+            }
+            out = (ast_expression*)ast_binary_new(ctx, generated_op, exprs[0], exprs[1]);
+            break;
+        case opid2('!', '='):
+            if (exprs[0]->expression.vtype != exprs[1]->expression.vtype) {
+                parseerror(parser, "type error: cannot compare types %s and %s",
+                           type_name[exprs[0]->expression.vtype],
+                           type_name[exprs[1]->expression.vtype]);
+                return false;
+            }
+            out = (ast_expression*)ast_binary_new(ctx, type_ne_op[exprs[0]->expression.vtype], exprs[0], exprs[1]);
+            break;
+        case opid2('=', '='):
+            if (exprs[0]->expression.vtype != exprs[1]->expression.vtype) {
+                parseerror(parser, "type error: cannot compare types %s and %s",
+                           type_name[exprs[0]->expression.vtype],
+                           type_name[exprs[1]->expression.vtype]);
+                return false;
+            }
+            out = (ast_expression*)ast_binary_new(ctx, type_eq_op[exprs[0]->expression.vtype], exprs[0], exprs[1]);
+            break;
+
 
         case opid1('='):
             if (ast_istype(exprs[0], ast_entfield))
@@ -524,6 +559,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
             out = (ast_expression*)ast_store_new(ctx, assignop, exprs[0], exprs[1]);
             break;
     }
+#undef NotSameType
 
     if (!out) {
         parseerror(parser, "failed to apply operand %s", op->op);
-- 
2.39.5