00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "c_breeze.h"
00039
00040
00041
00042
00043
00044 ternaryNode::ternaryNode(exprNode * cond,
00045 exprNode * true_br, exprNode * false_br,
00046 const Coord qmark_coord, const Coord colon_coord)
00047 : exprNode(Ternary, 0, qmark_coord),
00048 _cond(cond),
00049 _true_br(true_br),
00050 _false_br(false_br),
00051 _colon_coord(colon_coord)
00052 {}
00053
00054
00055
00056
00057
00058 int ternaryNode::precedence(Assoc & assoc)
00059 {
00060 assoc = Right;
00061 return 3;
00062 }
00063
00064
00065
00066
00067
00068 void ternaryNode::eval()
00069 {
00070
00071
00072 cond()->eval();
00073 true_br()->eval();
00074 false_br()->eval();
00075
00076
00077
00078 if ( ! cond()->value().no_val() )
00079 if (cond()->value().Boolean())
00080 value(true_br()->value());
00081 else
00082 value(false_br()->value());
00083 else
00084 value(constant());
00085 }
00086
00087
00088
00089
00090
00091 void ternaryNode::visit(Visitor * the_visitor)
00092 {
00093 the_visitor->at_ternary(this);
00094 }
00095
00096 void ternaryNode::walk(Walker & the_walker)
00097 {
00098 Walker::Order ord = the_walker.order();
00099
00100 if (ord == Walker::Preorder || ord == Walker::Both)
00101 the_walker.at_ternary(this, Walker::Preorder);
00102
00103 if (the_walker.depth() == Walker::Subtree) {
00104
00105
00106 if (cond())
00107 cond()->walk(the_walker);
00108
00109 if (true_br())
00110 true_br()->walk(the_walker);
00111
00112 if (false_br())
00113 false_br()->walk(the_walker);
00114
00115 if (type())
00116 type()->walk(the_walker);
00117 }
00118
00119 if (ord == Walker::Postorder || ord == Walker::Both)
00120 the_walker.at_ternary(this, Walker::Postorder);
00121 }
00122
00123
00124
00125
00126
00127 void ternaryNode::dataflow(FlowVal * v, FlowProblem & fp)
00128 {
00129 if (fp.forward()) {
00130 fp.flow_ternary(v, this, FlowProblem::Entry);
00131
00132 if (cond())
00133 cond()->dataflow(v, fp);
00134
00135 FlowVal * fv = v->clone();
00136
00137 if (true_br())
00138 true_br()->dataflow(v, fp);
00139
00140 if (false_br())
00141 false_br()->dataflow(fv, fp);
00142
00143 v->meet(fv);
00144 delete fv;
00145
00146 fp.flow_ternary(v, this, FlowProblem::Exit);
00147 }
00148 else {
00149 fp.flow_ternary(v, this, FlowProblem::Exit);
00150
00151 FlowVal * fv = v->clone();
00152
00153 if (true_br())
00154 true_br()->dataflow(v, fp);
00155
00156 if (false_br())
00157 false_br()->dataflow(fv, fp);
00158
00159 v->meet(fv);
00160 delete fv;
00161
00162 if (cond())
00163 cond()->dataflow(v, fp);
00164
00165 fp.flow_ternary(v, this, FlowProblem::Entry);
00166 }
00167 }
00168
00169
00170
00171
00172
00173 void ternaryNode::output_expr(output_context & ct, Node * parent, int prec, Assoc assoc)
00174 {
00175 bool par = parens(prec, assoc);
00176 int myprec;
00177 Assoc myassoc;
00178
00179 myprec = precedence(myassoc);
00180
00181 if (par)
00182 ct << '(';
00183
00184 cond()->output_expr(ct, this, myprec, Left);
00185
00186 ct << " ? ";
00187
00188 true_br()->output_expr(ct, this, myprec, Right);
00189
00190 ct << " : ";
00191
00192 false_br()->output_expr(ct, this, myprec, Right);
00193
00194 if (par)
00195 ct << ')';
00196 }
00197
00198
00199
00200
00201
00202 Node * ternaryNode::change(Changer & the_changer, bool redispatch)
00203 {
00204 Changer::Order ord = the_changer.order();
00205 ternaryNode * the_ternary = this;
00206
00207 if ((ord == Changer::Preorder || ord == Changer::Both) && ! redispatch)
00208 the_ternary = (ternaryNode *) the_changer.at_ternary(the_ternary, Changer::Preorder);
00209
00210 if (the_ternary) {
00211
00212 if (the_ternary != this)
00213 return the_ternary->change(the_changer, true);
00214
00215 exprNode * old_cond = the_ternary->cond();
00216 if (old_cond) {
00217 exprNode * new_cond = (exprNode *) old_cond->change(the_changer);
00218 if (old_cond != new_cond) {
00219
00220
00221 the_ternary->cond(new_cond);
00222 }
00223 }
00224
00225 exprNode * old_true_br = the_ternary->true_br();
00226 if (old_true_br) {
00227 exprNode * new_true_br = (exprNode *) old_true_br->change(the_changer);
00228 if (old_true_br != new_true_br) {
00229
00230
00231 the_ternary->true_br(new_true_br);
00232 }
00233 }
00234
00235 exprNode * old_false_br = the_ternary->false_br();
00236 if (old_false_br) {
00237 exprNode * new_false_br = (exprNode *) old_false_br->change(the_changer);
00238 if (old_false_br != new_false_br) {
00239
00240
00241 the_ternary->false_br(new_false_br);
00242 }
00243 }
00244
00245 typeNode * old_type = the_ternary->type();
00246 if (old_type) {
00247 typeNode * new_type = (typeNode *) old_type->change(the_changer);
00248 if (old_type != new_type) {
00249
00250
00251 the_ternary->type(new_type);
00252 }
00253 }
00254
00255 }
00256
00257 if ((ord == Changer::Postorder || ord == Changer::Both) && ! redispatch)
00258 the_ternary = (ternaryNode *) the_changer.at_ternary(the_ternary, Changer::Postorder);
00259
00260 return the_ternary;
00261 }
00262
00263
00264
00265
00266
00267
00268 ternaryNode::~ternaryNode()
00269 {
00270
00271
00272
00273 }