C-Breeze
C Compiler Infrastructure

[ Project home page]
Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

ternarynode.cc

Go to the documentation of this file.
00001 // $Id: ternarynode.cc,v 1.3 2003/08/07 23:13:14 pnav Exp $
00002 // ----------------------------------------------------------------------
00003 //
00004 //  C-Breeze
00005 //  C Compiler Framework
00006 // 
00007 //  Copyright (c) 2000 University of Texas at Austin
00008 // 
00009 //  Samuel Z. Guyer
00010 //  Daniel A. Jimenez
00011 //  Calvin Lin
00012 // 
00013 //  Permission is hereby granted, free of charge, to any person
00014 //  obtaining a copy of this software and associated documentation
00015 //  files (the "Software"), to deal in the Software without
00016 //  restriction, including without limitation the rights to use, copy,
00017 //  modify, merge, publish, distribute, sublicense, and/or sell copies
00018 //  of the Software, and to permit persons to whom the Software is
00019 //  furnished to do so, subject to the following conditions:
00020 //  
00021 //  The above copyright notice and this permission notice shall be
00022 //  included in all copies or substantial portions of the Software.
00023 //  
00024 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00025 //  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00026 //  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00027 //  NONINFRINGEMENT.  IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT
00028 //  AUSTIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00029 //  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
00030 //  OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00031 //  THE SOFTWARE.
00032 //
00033 //  We acknowledge the C-to-C Translator from MIT Laboratory for
00034 //  Computer Science for inspiring parts of the C-Breeze design.
00035 //
00036 // ----------------------------------------------------------------------
00037 
00038 #include "c_breeze.h"
00039 
00040 // --------------------------------------------------------------------
00041 // Constructors
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 // Operator precedence
00056 // ------------------------------------------------------------
00057 
00058 int ternaryNode::precedence(Assoc & assoc)
00059 {
00060   assoc = Right;
00061   return 3;
00062 }
00063 
00064 // ------------------------------------------------------------
00065 // Expression evaluator
00066 // ------------------------------------------------------------
00067 
00068 void ternaryNode::eval()
00069 {
00070   // -- Eval the subexpressions
00071 
00072   cond()->eval();
00073   true_br()->eval();
00074   false_br()->eval();
00075 
00076   // -- Test if the condition can be evaluated
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 //  Walker
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     // -- Visit the children 
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 //  Dataflow
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 // Output
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 //  Changer
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         //if (the_changer.delete_old())
00220           //delete old_cond;
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         //if (the_changer.delete_old())
00230           //delete old_true_br;
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         //if (the_changer.delete_old())
00240           //delete old_false_br;
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         //if (the_changer.delete_old())
00250           //delete old_type;
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 // Destructor
00266 // ------------------------------------------------------------
00267 
00268 ternaryNode::~ternaryNode()
00269 {
00270   //delete _cond;
00271   //delete _true_br;
00272   //delete _false_br;
00273 }

Generated on August 27, 2003
Back to the C-Breeze home page