diff src/pt-cbinop.cc @ 8982:dc6bda6f9994

implement compound logical ops
author Jaroslav Hajek <highegg@gmail.com>
date Sat, 14 Mar 2009 23:08:08 +0100
parents eb63fbe60fab
children afcf852256d2
line wrap: on
line diff
--- a/src/pt-cbinop.cc
+++ b/src/pt-cbinop.cc
@@ -57,6 +57,27 @@
     return octave_value::unknown_unary_op;
 }
 
+static octave_value::unary_op 
+strip_not (tree_expression *&exp)
+{
+  if (exp->is_unary_expression ())
+    {
+      tree_unary_expression *uexp = 
+        dynamic_cast<tree_unary_expression *> (exp);
+
+      octave_value::unary_op op = uexp->op_type ();
+
+      if (op == octave_value::op_not)
+	exp = uexp->operand ();
+      else
+	op = octave_value::unknown_unary_op;
+
+      return op;
+    }
+  else
+    return octave_value::unknown_unary_op;
+}
+
 // Possibly convert multiplication to trans_mul, mul_trans, herm_mul,
 // or mul_herm.
 
@@ -85,6 +106,39 @@
   return retop;
 }
 
+// Possibly contract and/or with negation.
+
+static octave_value::compound_binary_op
+simplify_and_or_op (tree_expression *&a, tree_expression *&b, octave_value::binary_op op)
+{
+  octave_value::compound_binary_op retop;
+  octave_value::unary_op opa = strip_not (a);
+
+  if (opa == octave_value::op_not)
+    {
+      if (op == octave_value::op_el_and)
+        retop = octave_value::op_el_not_and;
+      else if (op == octave_value::op_el_or)
+        retop = octave_value::op_el_not_or;
+    }
+  else
+    {
+      octave_value::unary_op opb = strip_not (b);
+
+      if (opb == octave_value::op_not)
+        {
+          if (op == octave_value::op_el_and)
+            retop = octave_value::op_el_and_not;
+          else if (op == octave_value::op_el_or)
+            retop = octave_value::op_el_or_not;
+        }
+      else
+        retop = octave_value::unknown_compound_binary_op;
+    }
+
+  return retop;
+}
+
 tree_binary_expression *
 maybe_compound_binary_expression (tree_expression *a, tree_expression *b,
                                   int l, int c, octave_value::binary_op t)
@@ -98,6 +152,11 @@
       ct = simplify_mul_op (ca, cb);
       break;
 
+    case octave_value::op_el_and:
+    case octave_value::op_el_or:
+      ct = simplify_and_or_op (ca, cb, t);
+      break;
+
     default:
       ct = octave_value::unknown_compound_binary_op;
       break;