Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026
00027 #include "error.h"
00028 #include "oct-obj.h"
00029 #include "ov.h"
00030 #include "pt-cbinop.h"
00031 #include "pt-bp.h"
00032 #include "pt-unop.h"
00033 #include "pt-walk.h"
00034
00035
00036
00037
00038 static octave_value::unary_op
00039 strip_trans_herm (tree_expression *&exp)
00040 {
00041 if (exp->is_unary_expression ())
00042 {
00043 tree_unary_expression *uexp =
00044 dynamic_cast<tree_unary_expression *> (exp);
00045
00046 octave_value::unary_op op = uexp->op_type ();
00047
00048 if (op == octave_value::op_transpose
00049 || op == octave_value::op_hermitian)
00050 exp = uexp->operand ();
00051 else
00052 op = octave_value::unknown_unary_op;
00053
00054 return op;
00055 }
00056 else
00057 return octave_value::unknown_unary_op;
00058 }
00059
00060 static octave_value::unary_op
00061 strip_not (tree_expression *&exp)
00062 {
00063 if (exp->is_unary_expression ())
00064 {
00065 tree_unary_expression *uexp =
00066 dynamic_cast<tree_unary_expression *> (exp);
00067
00068 octave_value::unary_op op = uexp->op_type ();
00069
00070 if (op == octave_value::op_not)
00071 exp = uexp->operand ();
00072 else
00073 op = octave_value::unknown_unary_op;
00074
00075 return op;
00076 }
00077 else
00078 return octave_value::unknown_unary_op;
00079 }
00080
00081
00082
00083
00084 static octave_value::compound_binary_op
00085 simplify_mul_op (tree_expression *&a, tree_expression *&b)
00086 {
00087 octave_value::compound_binary_op retop
00088 = octave_value::unknown_compound_binary_op;
00089
00090 octave_value::unary_op opa = strip_trans_herm (a);
00091
00092 if (opa == octave_value::op_hermitian)
00093 retop = octave_value::op_herm_mul;
00094 else if (opa == octave_value::op_transpose)
00095 retop = octave_value::op_trans_mul;
00096 else
00097 {
00098 octave_value::unary_op opb = strip_trans_herm (b);
00099
00100 if (opb == octave_value::op_hermitian)
00101 retop = octave_value::op_mul_herm;
00102 else if (opb == octave_value::op_transpose)
00103 retop = octave_value::op_mul_trans;
00104 }
00105
00106 return retop;
00107 }
00108
00109
00110
00111 static octave_value::compound_binary_op
00112 simplify_ldiv_op (tree_expression *&a, tree_expression *&)
00113 {
00114 octave_value::compound_binary_op retop
00115 = octave_value::unknown_compound_binary_op;
00116
00117 octave_value::unary_op opa = strip_trans_herm (a);
00118
00119 if (opa == octave_value::op_hermitian)
00120 retop = octave_value::op_herm_ldiv;
00121 else if (opa == octave_value::op_transpose)
00122 retop = octave_value::op_trans_ldiv;
00123
00124 return retop;
00125 }
00126
00127
00128
00129 static octave_value::compound_binary_op
00130 simplify_and_or_op (tree_expression *&a, tree_expression *&b, octave_value::binary_op op)
00131 {
00132 octave_value::compound_binary_op retop
00133 = octave_value::unknown_compound_binary_op;
00134
00135 octave_value::unary_op opa = strip_not (a);
00136
00137 if (opa == octave_value::op_not)
00138 {
00139 if (op == octave_value::op_el_and)
00140 retop = octave_value::op_el_not_and;
00141 else if (op == octave_value::op_el_or)
00142 retop = octave_value::op_el_not_or;
00143 }
00144 else
00145 {
00146 octave_value::unary_op opb = strip_not (b);
00147
00148 if (opb == octave_value::op_not)
00149 {
00150 if (op == octave_value::op_el_and)
00151 retop = octave_value::op_el_and_not;
00152 else if (op == octave_value::op_el_or)
00153 retop = octave_value::op_el_or_not;
00154 }
00155 }
00156
00157 return retop;
00158 }
00159
00160 tree_binary_expression *
00161 maybe_compound_binary_expression (tree_expression *a, tree_expression *b,
00162 int l, int c, octave_value::binary_op t)
00163 {
00164 tree_expression *ca = a, *cb = b;
00165 octave_value::compound_binary_op ct;
00166
00167 switch (t)
00168 {
00169 case octave_value::op_mul:
00170 ct = simplify_mul_op (ca, cb);
00171 break;
00172
00173 case octave_value::op_ldiv:
00174 ct = simplify_ldiv_op (ca, cb);
00175 break;
00176
00177 case octave_value::op_el_and:
00178 case octave_value::op_el_or:
00179 ct = simplify_and_or_op (ca, cb, t);
00180 break;
00181
00182 default:
00183 ct = octave_value::unknown_compound_binary_op;
00184 break;
00185 }
00186
00187 tree_binary_expression *ret = (ct == octave_value::unknown_compound_binary_op)
00188 ? new tree_binary_expression (a, b, l, c, t)
00189 : new tree_compound_binary_expression (a, b, l, c, t, ca, cb, ct);
00190
00191 return ret;
00192 }
00193
00194 octave_value
00195 tree_compound_binary_expression::rvalue1 (int)
00196 {
00197 octave_value retval;
00198
00199 if (error_state)
00200 return retval;
00201
00202 if (op_lhs)
00203 {
00204 octave_value a = op_lhs->rvalue1 ();
00205
00206 if (! error_state && a.is_defined () && op_rhs)
00207 {
00208 octave_value b = op_rhs->rvalue1 ();
00209
00210 if (! error_state && b.is_defined ())
00211 {
00212 retval = ::do_binary_op (etype, a, b);
00213
00214 if (error_state)
00215 retval = octave_value ();
00216 }
00217 }
00218 }
00219
00220 return retval;
00221 }
00222
00223