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  

binarynode.cc

Go to the documentation of this file.
00001 // $Id: binarynode.cc,v 1.5 2003/08/07 23:12:59 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 binaryNode::binaryNode(unsigned int op_id, exprNode * left, exprNode * right,
00045                        const Coord coord)
00046   : exprNode(Binary, 0, coord),
00047     _op(Operators::table[op_id]),
00048     _left(left),
00049     _right(right)
00050 {
00051 }
00052 
00053 // ------------------------------------------------------------
00054 // Symbol lookup
00055 // ------------------------------------------------------------
00056 
00057 /*
00058 void binaryNode::lookup()
00059 {
00060   if (op()->id() == '.' || op()->id() == Operator::ARROW)
00061     left()->lookup();
00062 }
00063 */
00064 
00065 // ------------------------------------------------------------
00066 // Operator precedence
00067 // ------------------------------------------------------------
00068 
00069 int binaryNode::precedence(Assoc & my_assoc)
00070 {
00071   if (op()->is_left_assoc())
00072     my_assoc = Left;
00073   else
00074     my_assoc = Right;
00075 
00076   return op()->binary_prec();
00077 }
00078 
00079 // ------------------------------------------------------------
00080 // Expression evaluator
00081 // ------------------------------------------------------------
00082 
00083 void binaryNode::eval()
00084 {
00085   // -- Evaluate the two arguments...
00086 
00087   left()->eval();
00088   right()->eval();
00089 
00090   // -- Evaluate the operator
00091 
00092   value(constant::eval(op(),
00093                        left()->value(),
00094                        right()->value()));
00095 }
00096 
00097 // ------------------------------------------------------------
00098 //  Walker
00099 // ------------------------------------------------------------
00100 
00101 void binaryNode::visit(Visitor * the_visitor) 
00102 {
00103   the_visitor->at_binary(this);
00104 }
00105 
00106 void binaryNode::walk(Walker & the_walker)
00107 {
00108   Walker::Order ord = the_walker.order(); 
00109 
00110   if (ord == Walker::Preorder || ord == Walker::Both)
00111     the_walker.at_binary(this, Walker::Preorder);
00112 
00113   if (the_walker.depth() == Walker::Subtree) {
00114     // -- Visit the children 
00115 
00116     if (op()->id()=='.' || op()->id()==Operator::ARROW) {
00117         // djimenez
00118         // BUG: we aren't handling the rhs of . or -> properly;
00119         // it should be looked up and something done with it.
00120         // the above if/else is a hack so that C-Breeze will at least
00121         // not bail with an error.
00122         if (right()->typ() == Id) {
00123                 idNode *n = (idNode *) right();
00124                 // do something here...
00125         }
00126     } else {
00127             if (right())
00128               right()->walk(the_walker);
00129     }
00130 
00131     if (left())
00132       left()->walk(the_walker);
00133 
00134     if (type())
00135       type()->walk(the_walker);
00136   }
00137 
00138   if (ord == Walker::Postorder || ord == Walker::Both)
00139     the_walker.at_binary(this, Walker::Postorder);
00140 }
00141 
00142 // ------------------------------------------------------------
00143 //  Dataflow
00144 // ------------------------------------------------------------
00145 
00146 void binaryNode::dataflow(FlowVal * v, FlowProblem & fp)
00147 {
00148   Operator * o = op();
00149 
00150   // -- The "&&" and "||" operators require us to consider the binary
00151   // operation as a branch that always executes it's left part, but
00152   // may not execute the right part.
00153 
00154   bool short_circuit = ((o->id() == Operator::ANDAND) ||
00155                         (o->id() == Operator::OROR));
00156 
00157   if (fp.forward()) {
00158     fp.flow_binary(v, this, FlowProblem::Entry);
00159 
00160     if (short_circuit) {
00161       FlowVal * fv = v->clone();
00162 
00163       if (left())
00164         left()->dataflow(v, fp);
00165 
00166       if (right())
00167         right()->dataflow(fv, fp);
00168 
00169       v->meet(fv);
00170       delete fv;
00171     }
00172     else {
00173       if (left())
00174         left()->dataflow(v, fp);
00175 
00176       if (right())
00177         right()->dataflow(v, fp);
00178     }
00179 
00180     fp.flow_binary(v, this, FlowProblem::Exit);
00181   }
00182   else {
00183     fp.flow_binary(v, this, FlowProblem::Exit);
00184 
00185     if (short_circuit) {
00186       FlowVal * fv = v->clone();
00187 
00188       if (right())
00189         right()->dataflow(fv, fp);
00190 
00191       if (left())
00192         left()->dataflow(v, fp);
00193 
00194       v->meet(fv);
00195       delete fv;
00196     }
00197     else {
00198       if (right())
00199         right()->dataflow(v, fp);
00200 
00201       if (left())
00202         left()->dataflow(v, fp);
00203     }
00204 
00205     fp.flow_binary(v, this, FlowProblem::Entry);
00206   }
00207 }
00208 
00209 // ------------------------------------------------------------
00210 // Output
00211 // ------------------------------------------------------------
00212 
00213 void binaryNode::output_expr(output_context & ct, Node * parent, int prec, Assoc assoc)
00214 {
00215   bool par = parens(prec, assoc);
00216 
00217   if (par)
00218     ct << '(';
00219 
00220   left()->output_expr(ct, this, op()->binary_prec(), Left);
00221 
00222   if (op()->id() == Operator::Index) {
00223 
00224     exprNode * d = right();
00225     if (d) {
00226       ct << '[';
00227       d->output(ct, this);
00228       ct << ']';
00229     }
00230   }
00231   else {
00232 
00233     ct.space();
00234     ct << op()->print();
00235     ct.space();
00236 
00237     ct.continue_line();
00238 
00239     right()->output_expr(ct, this, op()->binary_prec(), Right);
00240   }
00241 
00242   if (par)
00243     ct << ')';
00244 }
00245 
00246 // ------------------------------------------------------------
00247 //  Changer
00248 // ------------------------------------------------------------
00249 
00250 Node * binaryNode::change(Changer & the_changer, bool redispatch)
00251 {
00252   Changer::Order ord = the_changer.order(); 
00253   binaryNode * the_binary = this;
00254 
00255   if ((ord == Changer::Preorder || ord == Changer::Both) && ! redispatch)
00256     the_binary = (binaryNode *) the_changer.at_binary(the_binary, Changer::Preorder);
00257 
00258   if (the_binary) {
00259 
00260     if (the_binary != this)
00261       return the_binary->change(the_changer, true);
00262 
00263     exprNode * old_left = the_binary->left();
00264     if (old_left) {
00265       exprNode * new_left = (exprNode *) old_left->change(the_changer);
00266       if (old_left != new_left) {
00267         //if (the_changer.delete_old())
00268          // delete old_left;
00269         the_binary->left(new_left);
00270       }
00271     }
00272 
00273     exprNode * old_right = the_binary->right();
00274     if (old_right) {
00275       exprNode * new_right = (exprNode *) old_right->change(the_changer);
00276       if (old_right != new_right) {
00277         //if (the_changer.delete_old())
00278          // delete old_right;
00279         the_binary->right(new_right);
00280       }
00281     }
00282 
00283     typeNode * old_type = the_binary->type();
00284     if (old_type) {
00285       typeNode * new_type = (typeNode *) old_type->change(the_changer);
00286       if (old_type != new_type) {
00287         //if (the_changer.delete_old())
00288           //delete old_type;
00289         the_binary->type(new_type);
00290       }
00291     }
00292 
00293   }
00294 
00295   if ((ord == Changer::Postorder || ord == Changer::Both) && ! redispatch)
00296     the_binary = (binaryNode *) the_changer.at_binary(the_binary, Changer::Postorder);
00297 
00298   return the_binary;
00299 }
00300 
00301 
00302 // ------------------------------------------------------------
00303 // Destructor
00304 // ------------------------------------------------------------
00305 
00306 binaryNode::~binaryNode()
00307 {
00308   //delete _left;
00309   //delete _right;
00310 }

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