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  

constant.cc

Go to the documentation of this file.
00001 // $Id: constant.cc,v 1.17 2003/08/11 17:15:42 abrown 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 #include <stdio.h>
00038 #include "c_breeze.h"
00039 
00040 // ------------------------------------------------------------
00041 // Copy constructor
00042 // ------------------------------------------------------------
00043 
00044 constant::constant(const constant & other)
00045   : _v(other._v),
00046     _bt(other._bt),
00047     _is_str(other._is_str),
00048     _is_ptr(other._is_ptr),
00049     _no_val(other._no_val)
00050 {
00051   if (_is_str)
00052     _v.Str = strdup(other._v.Str);
00053 }
00054 
00055 // ------------------------------------------------------------
00056 // Assignment operator
00057 // ------------------------------------------------------------
00058 
00059 constant & constant::operator=(const constant & rhs)
00060 {
00061   if (this != &rhs) {
00062     if (rhs.is_str()) {
00063           if (_is_str)
00064         delete _v.Str;
00065       _v.Str = strdup(rhs._v.Str);
00066     }
00067     else
00068       _v = rhs._v;
00069 
00070     _bt     = rhs._bt;
00071     _is_str = rhs._is_str;
00072     _is_ptr = rhs._is_ptr;
00073     _no_val = rhs._no_val;
00074   }
00075 
00076   return * this;
00077 }
00078 
00079 // ------------------------------------------------------------
00080 // Destructor
00081 // ------------------------------------------------------------
00082 
00083 constant::~constant()
00084 {
00085   if (_is_str)
00086     free(_v.Str);
00087 }
00088 
00089 // ------------------------------------------------------------
00090 // Access values
00091 // ------------------------------------------------------------
00092 
00093 unsigned long constant::Integer() const
00094 {
00095   if (_bt == basic_type::SShort)
00096     return (unsigned long) _v.SShort;
00097 
00098   if (_bt == basic_type::UShort)
00099     return (unsigned long) _v.UShort;
00100 
00101   if (_bt == basic_type::SInt)
00102     return (unsigned long) _v.SInt;
00103 
00104   if (_bt == basic_type::UInt)
00105     return (unsigned long) _v.UInt;
00106 
00107   if (_bt == basic_type::SLong)
00108     return (unsigned long) _v.SLong;
00109 
00110   if (_bt == basic_type::ULong)
00111     return (unsigned long) _v.ULong;
00112 
00113   // -- Should never get here...
00114 
00115   return 0;
00116 }
00117 
00118 bool constant::Boolean() const
00119 {
00120   if (is_str())
00121     return true;
00122 
00123   if (is_ptr())
00124     return _v.Ptr != 0;
00125   
00126   if (_bt == basic_type::SShort)
00127     return _v.SShort != 0 ;
00128 
00129   if (_bt == basic_type::UShort)
00130     return _v.UShort != 0 ;
00131 
00132   if (_bt == basic_type::SInt)
00133     return _v.SInt != 0 ;
00134 
00135   if (_bt == basic_type::UInt)
00136     return _v.UInt != 0 ;
00137 
00138   if (_bt == basic_type::SLong)
00139     return _v.SLong != 0 ;
00140 
00141   if (_bt == basic_type::ULong)
00142     return _v.ULong != 0 ;
00143 
00144   if (_bt == basic_type::Float)
00145     return _v.Float != 0 ;
00146 
00147   if (_bt == basic_type::Double)
00148     return _v.Double != 0 ;
00149 
00150   // -- Should never get here...
00151   // pnav -- got here...
00152   // assert( false );
00153 
00154 
00155   // pnav -- gets here when _bt == basic_type::NO_TYPE
00156   return false;
00157 }
00158 
00159 bool constant::is_zero() const
00160 {
00161   return ! Boolean();
00162 }
00163 
00164 void constant::make_zero()
00165 {
00166   if (is_str()) {
00167     if ( _v.Str )
00168                 free( _v.Str );
00169         _v.Str = 0;
00170   }
00171 
00172   else if (is_ptr())
00173     _v.Ptr = 0;
00174   
00175   else if (_bt == basic_type::SShort)
00176     _v.SShort = 0;
00177 
00178   else if (_bt == basic_type::UShort)
00179     _v.UShort = 0;
00180 
00181   else if (_bt == basic_type::SInt)
00182     _v.SInt = 0;
00183 
00184   else if (_bt == basic_type::UInt)
00185     _v.UInt = 0;
00186 
00187   else if (_bt == basic_type::SLong)
00188     _v.SLong = 0;
00189 
00190   else if (_bt == basic_type::ULong)
00191     _v.ULong = 0;
00192 
00193   else if (_bt == basic_type::Float)
00194     _v.Float = 0;
00195 
00196   else if (_bt == basic_type::Double)
00197     _v.Double = 0;
00198 
00199   else {
00200           // make us a simple integer zero
00201           SInt( 0 );
00202   }
00203 
00204   return;
00205 }
00206 
00207 // ------------------------------------------------------------
00208 // Operators
00209 // ------------------------------------------------------------
00210 
00211 bool constant::is_equal_to(const constant & other) const
00212 {
00213   if (is_str() &&
00214       other.is_str())
00215     return (strcmp(Str(),other.Str()) == 0);
00216 
00217   if (is_ptr() &&
00218       other.is_ptr())
00219     return Ptr() == other.Ptr();
00220 
00221   if (basic().is_integer() &&
00222       other.basic().is_integer())
00223     return Integer() == other.Integer();
00224 
00225   if ((basic() == basic_type::Float) &&
00226       (other.basic() == basic_type::Float))
00227     return  Float() == other.Float();
00228 
00229   if ((basic() == basic_type::Double) &&
00230       (other.basic() == basic_type::Double))
00231     return  Double() == other.Double();
00232 
00233   return false;
00234 }
00235 
00236 bool constant::operator<(const constant & other) const
00237 {
00238   // -- CASE 1: Non value is the smallest element
00239 
00240   if (no_val() && other.no_val())
00241     return false;
00242 
00243   if (no_val())
00244     return true;
00245 
00246   if (other.no_val())
00247     return false;
00248 
00249   // -- CASE 2: Strings
00250 
00251   if (is_str() &&
00252       other.is_str())
00253     return (strcmp(Str(),other.Str()) < 0);
00254 
00255   // -- CASE 3: Pointers
00256 
00257   if (is_ptr() &&
00258       other.is_ptr())
00259     return Ptr() < other.Ptr();
00260 
00261   // -- CASE 4: Regular numeric types
00262 
00263   if (basic() == other.basic()) {
00264     constant result = constant::eval(Operators::table['<'], *this, other);
00265     return result.Boolean();
00266   }
00267   else {
00268 
00269     // -- CASE 5: Two different basic types: Always return false?
00270 
00271     return basic() < other.basic();
00272   }
00273 }
00274 
00275 // ------------------------------------------------------------
00276 // Expression evaluation
00277 // (static functions)
00278 // ------------------------------------------------------------
00279 
00280 // There are several conditions on this function working:
00281 //  (1) The semcheck_visitor has been run.
00282 //  (2) The operands are of the same basic_type
00283 //  (3) Integral promotion has removed any char/short types.
00284 //  (4) Only arithmetic operations are allowed
00285 //  (5) No pointer operations are supported
00286 
00287 constant constant::eval(const Operator * op,
00288                         const constant & oper1,
00289                         const constant & oper2)
00290 {
00291   // -- If either input is a non-value, or the basic types don't
00292   // match, then simply return another non-value.
00293 
00294   // pnav -- is a null pointer here an error, or just another case for this guard?
00295   if (!&oper1 || !&oper2 ||
00296       oper1.no_val() ||
00297       oper2.no_val() ||
00298       ( ! (oper1.basic() == oper2.basic())))
00299     return constant();
00300 
00301   // -- Big switch...
00302 
00303   const basic_type & bt = oper1.basic();
00304 
00305   switch (op->id()) {
00306   case '*':
00307     if (bt == basic_type::SInt)
00308       return constant(oper1.SInt() * oper2.SInt());
00309 
00310     if (bt == basic_type::UInt)
00311       return constant(oper1.UInt() * oper2.UInt());
00312 
00313     if (bt == basic_type::SLong)
00314       return constant(oper1.SLong() * oper2.SLong());
00315 
00316     if (bt == basic_type::ULong)
00317       return constant(oper1.ULong() * oper2.ULong());
00318 
00319     if (bt == basic_type::Float)
00320       return constant(oper1.Float() * oper2.Float());
00321 
00322     if (bt == basic_type::Double)
00323       return constant(oper1.Double() * oper2.Double());
00324 
00325     break;
00326 
00327   case '/':
00328     if (bt == basic_type::SInt) {
00329       if (oper2.SInt() == 0)
00330         return constant();
00331       else
00332         return constant(oper1.SInt() / oper2.SInt());
00333     }
00334 
00335     if (bt == basic_type::UInt) {
00336       if (oper2.UInt() == 0)
00337         return constant();
00338       else
00339         return constant(oper1.UInt() / oper2.UInt());
00340     }
00341 
00342     if (bt == basic_type::SLong) {
00343       if (oper2.SLong() == 0)
00344         return constant();
00345       else
00346         return constant(oper1.SLong() / oper2.SLong());
00347     }
00348 
00349     if (bt == basic_type::ULong) {
00350       if (oper2.ULong() == 0)
00351         return constant();
00352       else
00353         return constant(oper1.ULong() / oper2.ULong());
00354     }
00355 
00356     if (bt == basic_type::Float) {
00357       if (oper2.Float() == 0.0)
00358         return constant();
00359       else
00360         return constant(oper1.Float() / oper2.Float());
00361     }
00362 
00363     if (bt == basic_type::Double) {
00364       if (oper2.Double() == 0.0)
00365         return constant();
00366       else
00367         return constant(oper1.Double() / oper2.Double());
00368     }
00369 
00370     break;
00371 
00372   case '%':
00373     if (bt == basic_type::SInt)
00374       return constant(oper1.SInt() % oper2.SInt());
00375 
00376     if (bt == basic_type::UInt)
00377       return constant(oper1.UInt() % oper2.UInt());
00378 
00379     if (bt == basic_type::SLong)
00380       return constant(oper1.SLong() % oper2.SLong());
00381 
00382     if (bt == basic_type::ULong)
00383       return constant(oper1.ULong() % oper2.ULong());
00384 
00385     break;
00386 
00387   case '+':
00388     if (bt == basic_type::SInt)
00389       return constant(oper1.SInt() + oper2.SInt());
00390 
00391     if (bt == basic_type::UInt)
00392       return constant(oper1.UInt() + oper2.UInt());
00393 
00394     if (bt == basic_type::SLong)
00395       return constant(oper1.SLong() + oper2.SLong());
00396 
00397     if (bt == basic_type::ULong)
00398       return constant(oper1.ULong() + oper2.ULong());
00399 
00400     if (bt == basic_type::Float)
00401       return constant(oper1.Float() + oper2.Float());
00402 
00403     if (bt == basic_type::Double)
00404       return constant(oper1.Double() + oper2.Double());
00405 
00406     break;
00407 
00408   case '-':
00409     if (bt == basic_type::SInt)
00410       return constant(oper1.SInt() - oper2.SInt());
00411 
00412     if (bt == basic_type::UInt)
00413       return constant(oper1.UInt() - oper2.UInt());
00414 
00415     if (bt == basic_type::SLong)
00416       return constant(oper1.SLong() - oper2.SLong());
00417 
00418     if (bt == basic_type::ULong)
00419       return constant(oper1.ULong() - oper2.ULong());
00420 
00421     if (bt == basic_type::Float)
00422       return constant(oper1.Float() - oper2.Float());
00423 
00424     if (bt == basic_type::Double)
00425       return constant(oper1.Double() - oper2.Double());
00426 
00427     break;
00428 
00429   case Operator::LS:
00430     if (bt == basic_type::SInt)
00431       return constant(oper1.SInt() << oper2.SInt());
00432 
00433     if (bt == basic_type::UInt)
00434       return constant(oper1.UInt() << oper2.UInt());
00435 
00436     if (bt == basic_type::SLong)
00437       return constant(oper1.SLong() << oper2.SLong());
00438 
00439     if (bt == basic_type::ULong)
00440       return constant(oper1.ULong() << oper2.ULong());
00441 
00442     break;
00443 
00444   case Operator::RS:
00445     if (bt == basic_type::SInt)
00446       return constant(oper1.SInt() >> oper2.SInt());
00447 
00448     if (bt == basic_type::UInt)
00449       return constant(oper1.UInt() >> oper2.UInt());
00450 
00451     if (bt == basic_type::SLong)
00452       return constant(oper1.SLong() >> oper2.SLong());
00453 
00454     if (bt == basic_type::ULong)
00455       return constant(oper1.ULong() >> oper2.ULong());
00456 
00457     break;
00458 
00459   case '<':
00460     if (bt == basic_type::SInt)
00461       return constant( (int) (oper1.SInt() < oper2.SInt()));
00462 
00463     if (bt == basic_type::UInt)
00464       return constant( (int) (oper1.UInt() < oper2.UInt()));
00465 
00466     if (bt == basic_type::SLong)
00467       return constant( (int) (oper1.SLong() < oper2.SLong()));
00468 
00469     if (bt == basic_type::ULong)
00470       return constant( (int) (oper1.ULong() < oper2.ULong()));
00471 
00472     if (bt == basic_type::Float)
00473       return constant( (int) (oper1.Float() < oper2.Float()));
00474 
00475     if (bt == basic_type::Double)
00476       return constant( (int) (oper1.Double() < oper2.Double()));
00477 
00478     break;
00479 
00480   case '>':
00481     if (bt == basic_type::SInt)
00482       return constant( (int) (oper1.SInt() > oper2.SInt()));
00483 
00484     if (bt == basic_type::UInt)
00485       return constant( (int) (oper1.UInt() > oper2.UInt()));
00486 
00487     if (bt == basic_type::SLong)
00488       return constant( (int) (oper1.SLong() > oper2.SLong()));
00489 
00490     if (bt == basic_type::ULong)
00491       return constant( (int) (oper1.ULong() > oper2.ULong()));
00492 
00493     if (bt == basic_type::Float)
00494       return constant( (int) (oper1.Float() > oper2.Float()));
00495 
00496     if (bt == basic_type::Double)
00497       return constant( (int) (oper1.Double() > oper2.Double()));
00498 
00499     break;
00500 
00501   case Operator::GE:
00502     if (bt == basic_type::SInt)
00503       return constant( (int) (oper1.SInt() >= oper2.SInt()));
00504 
00505     if (bt == basic_type::UInt)
00506       return constant( (int) (oper1.UInt() >= oper2.UInt()));
00507 
00508     if (bt == basic_type::SLong)
00509       return constant( (int) (oper1.SLong() >= oper2.SLong()));
00510 
00511     if (bt == basic_type::ULong)
00512       return constant( (int) (oper1.ULong() >= oper2.ULong()));
00513 
00514     if (bt == basic_type::Float)
00515       return constant( (int) (oper1.Float() >= oper2.Float()));
00516 
00517     if (bt == basic_type::Double)
00518       return constant( (int) (oper1.Double() >= oper2.Double()));
00519 
00520     break;
00521 
00522   case Operator::LE:
00523     if (bt == basic_type::SInt)
00524       return constant( (int) (oper1.SInt() <= oper2.SInt()));
00525 
00526     if (bt == basic_type::UInt)
00527       return constant( (int) (oper1.UInt() <= oper2.UInt()));
00528 
00529     if (bt == basic_type::SLong)
00530       return constant( (int) (oper1.SLong() <= oper2.SLong()));
00531 
00532     if (bt == basic_type::ULong)
00533       return constant( (int) (oper1.ULong() <= oper2.ULong()));
00534 
00535     if (bt == basic_type::Float)
00536       return constant( (int) (oper1.Float() <= oper2.Float()));
00537 
00538     if (bt == basic_type::Double)
00539       return constant( (int) (oper1.Double() <= oper2.Double()));
00540 
00541     break;
00542 
00543   case Operator::EQ:
00544     if (bt == basic_type::SInt)
00545       return constant( (int) (oper1.SInt() == oper2.SInt()));
00546 
00547     if (bt == basic_type::UInt)
00548       return constant( (int) (oper1.UInt() == oper2.UInt()));
00549 
00550     if (bt == basic_type::SLong)
00551       return constant( (int) (oper1.SLong() == oper2.SLong()));
00552 
00553     if (bt == basic_type::ULong)
00554       return constant( (int) (oper1.ULong() == oper2.ULong()));
00555 
00556     if (bt == basic_type::Float)
00557       return constant( (int) (oper1.Float() == oper2.Float()));
00558 
00559     if (bt == basic_type::Double)
00560       return constant( (int) (oper1.Double() == oper2.Double()));
00561 
00562     break;
00563 
00564   case Operator::NE:
00565     if (bt == basic_type::SInt)
00566       return constant( (int) (oper1.SInt() != oper2.SInt()));
00567 
00568     if (bt == basic_type::UInt)
00569       return constant( (int) (oper1.UInt() != oper2.UInt()));
00570 
00571     if (bt == basic_type::SLong)
00572       return constant( (int) (oper1.SLong() != oper2.SLong()));
00573 
00574     if (bt == basic_type::ULong)
00575       return constant( (int) (oper1.ULong() != oper2.ULong()));
00576 
00577     if (bt == basic_type::Float)
00578       return constant( (int) (oper1.Float() != oper2.Float()));
00579 
00580     if (bt == basic_type::Double)
00581       return constant( (int) (oper1.Double() != oper2.Double()));
00582 
00583     break;
00584 
00585   case '&':
00586     if (bt == basic_type::SInt)
00587       return constant(oper1.SInt() & oper2.SInt());
00588 
00589     if (bt == basic_type::UInt)
00590       return constant(oper1.UInt() & oper2.UInt());
00591 
00592     if (bt == basic_type::SLong)
00593       return constant(oper1.SLong() & oper2.SLong());
00594 
00595     if (bt == basic_type::ULong)
00596       return constant(oper1.ULong() & oper2.ULong());
00597 
00598     break;
00599 
00600   case '^':
00601     if (bt == basic_type::SInt)
00602       return constant(oper1.SInt() ^ oper2.SInt());
00603 
00604     if (bt == basic_type::UInt)
00605       return constant(oper1.UInt() ^ oper2.UInt());
00606 
00607     if (bt == basic_type::SLong)
00608       return constant(oper1.SLong() ^ oper2.SLong());
00609 
00610     if (bt == basic_type::ULong)
00611       return constant(oper1.ULong() ^ oper2.ULong());
00612 
00613     break;
00614 
00615   case '|':
00616     if (bt == basic_type::SInt)
00617       return constant(oper1.SInt() | oper2.SInt());
00618 
00619     if (bt == basic_type::UInt)
00620       return constant(oper1.UInt() | oper2.UInt());
00621 
00622     if (bt == basic_type::SLong)
00623       return constant(oper1.SLong() | oper2.SLong());
00624 
00625     if (bt == basic_type::ULong)
00626       return constant(oper1.ULong() | oper2.ULong());
00627 
00628     break;
00629 
00630   case Operator::ANDAND:
00631     if (bt == basic_type::SInt)
00632       return constant( (int) (oper1.SInt() && oper2.SInt()));
00633 
00634     if (bt == basic_type::UInt)
00635       return constant( (int) (oper1.UInt() && oper2.UInt()));
00636 
00637     if (bt == basic_type::SLong)
00638       return constant( (int) (oper1.SLong() && oper2.SLong()));
00639 
00640     if (bt == basic_type::ULong)
00641       return constant( (int) (oper1.ULong() && oper2.ULong()));
00642 
00643     if (bt == basic_type::Float)
00644       return constant( (int) (oper1.Float() && oper2.Float()));
00645 
00646     if (bt == basic_type::Double)
00647       return constant( (int) (oper1.Double() && oper2.Double()));
00648 
00649     break;
00650 
00651   case Operator::OROR:
00652     if (bt == basic_type::SInt)
00653       return constant( (int) (oper1.SInt() || oper2.SInt()));
00654 
00655     if (bt == basic_type::UInt)
00656       return constant( (int) (oper1.UInt() || oper2.UInt()));
00657 
00658     if (bt == basic_type::SLong)
00659       return constant( (int) (oper1.SLong() || oper2.SLong()));
00660 
00661     if (bt == basic_type::ULong)
00662       return constant( (int) (oper1.ULong() || oper2.ULong()));
00663 
00664     if (bt == basic_type::Float)
00665       return constant( (int) (oper1.Float() || oper2.Float()));
00666 
00667     if (bt == basic_type::Double)
00668       return constant( (int) (oper1.Double() || oper2.Double()));
00669 
00670     break;
00671   default:
00672     break;
00673   }
00674 
00675   // -- If none of the cases match, return non-value
00676 
00677   return constant();
00678 }
00679 
00680 constant constant::eval(const Operator * op,
00681                         const constant & oper)
00682 {
00683   // -- If the input is a non-value, return a non-value
00684 
00685   if (oper.no_val())
00686     return constant();
00687 
00688   // -- Big switch...
00689 
00690   const basic_type & bt = oper.basic();
00691 
00692   switch (op->id()) {
00693   case Operator::UPLUS:
00694     if (bt == basic_type::SInt)
00695       return constant( + oper.SInt());
00696 
00697     if (bt == basic_type::UInt)
00698       return constant( + oper.UInt());
00699 
00700     if (bt == basic_type::SLong)
00701       return constant( + oper.SLong());
00702 
00703     if (bt == basic_type::ULong)
00704       return constant( + oper.ULong());
00705 
00706     if (bt == basic_type::Float)
00707       return constant( + oper.Float());
00708 
00709     if (bt == basic_type::Double)
00710       return constant( + oper.Double());
00711 
00712     break;
00713 
00714   case Operator::UMINUS:
00715     if (bt == basic_type::SInt)
00716       return constant( - oper.SInt());
00717 
00718     if (bt == basic_type::UInt)
00719       return constant( - oper.UInt());
00720 
00721     if (bt == basic_type::SLong)
00722       return constant( - oper.SLong());
00723 
00724     if (bt == basic_type::ULong)
00725       return constant( - oper.ULong());
00726 
00727     if (bt == basic_type::Float)
00728       return constant( - oper.Float());
00729 
00730     if (bt == basic_type::Double)
00731       return constant( - oper.Double());
00732 
00733     break;
00734 
00735   case '~':
00736     if (bt == basic_type::SInt)
00737       return constant( ~ oper.SInt());
00738 
00739     if (bt == basic_type::UInt)
00740       return constant( ~ oper.UInt());
00741 
00742     if (bt == basic_type::SLong)
00743       return constant( ~ oper.SLong());
00744 
00745     if (bt == basic_type::ULong)
00746       return constant( ~ oper.ULong());
00747 
00748     break;
00749 
00750   case '!':
00751     if (bt == basic_type::SInt)
00752       return constant( ! oper.SInt());
00753 
00754     if (bt == basic_type::UInt)
00755       return constant( ! oper.UInt());
00756 
00757     if (bt == basic_type::SLong)
00758       return constant( ! oper.SLong());
00759 
00760     if (bt == basic_type::ULong)
00761       return constant( ! oper.ULong());
00762 
00763     if (bt == basic_type::Float)
00764       return constant( ! oper.Float());
00765 
00766     if (bt == basic_type::Double)
00767       return constant( ! oper.Double());
00768 
00769     break;
00770 
00771   default:
00772     break;
00773   }
00774 
00775   // -- If none of the cases match, return non-value
00776 
00777   return constant();
00778 }
00779 
00780 constant constant::cast(const basic_type & new_bt, const constant & con)
00781 {
00782   // -- If the input is a non-value, return a non-value
00783 
00784   if (con.no_val())
00785     return constant();
00786 
00787   // -- Consider all possible combinations of primitive types
00788 
00789   const basic_type & bt = con.basic();
00790 
00791   if (bt == basic_type::SChar) {
00792     if (new_bt == basic_type::SChar)
00793       return constant( (signed char) con.SChar());
00794 
00795     if (new_bt == basic_type::UChar)
00796       return constant( (unsigned char) con.SChar());
00797 
00798     if (new_bt == basic_type::SShort)
00799       return constant( (signed short int) con.SChar());
00800 
00801     if (new_bt == basic_type::UShort)
00802       return constant( (unsigned short int) con.SChar());
00803 
00804     if (new_bt == basic_type::SInt)
00805       return constant( (signed int) con.SChar());
00806 
00807     if (new_bt == basic_type::UInt)
00808       return constant( (unsigned int) con.SChar());
00809 
00810     if (new_bt == basic_type::SLong)
00811       return constant( (signed long int) con.SChar());
00812 
00813     if (new_bt == basic_type::ULong)
00814       return constant( (unsigned long int) con.SChar());
00815 
00816     if (new_bt == basic_type::Float)
00817       return constant( (float) con.SChar());
00818 
00819     if (new_bt == basic_type::Double)
00820       return constant( (double) con.SChar());
00821   }
00822 
00823   if (bt == basic_type::UChar) {
00824     if (new_bt == basic_type::SChar)
00825       return constant( (signed char) con.UChar());
00826 
00827     if (new_bt == basic_type::UChar)
00828       return constant( (unsigned char) con.UChar());
00829 
00830     if (new_bt == basic_type::SShort)
00831       return constant( (signed short int) con.UChar());
00832 
00833     if (new_bt == basic_type::UShort)
00834       return constant( (unsigned short int) con.UChar());
00835 
00836     if (new_bt == basic_type::SInt)
00837       return constant( (signed int) con.UChar());
00838 
00839     if (new_bt == basic_type::UInt)
00840       return constant( (unsigned int) con.UChar());
00841 
00842     if (new_bt == basic_type::SLong)
00843       return constant( (signed long int) con.UChar());
00844 
00845     if (new_bt == basic_type::ULong)
00846       return constant( (unsigned long int) con.UChar());
00847 
00848     if (new_bt == basic_type::Float)
00849       return constant( (float) con.UChar());
00850 
00851     if (new_bt == basic_type::Double)
00852       return constant( (double) con.UChar());
00853   }
00854 
00855   if (bt == basic_type::SShort) {
00856     if (new_bt == basic_type::SChar)
00857       return constant( (signed char) con.SShort());
00858 
00859     if (new_bt == basic_type::UChar)
00860       return constant( (unsigned char) con.SShort());
00861 
00862     if (new_bt == basic_type::SShort)
00863       return constant( (signed short int) con.SShort());
00864 
00865     if (new_bt == basic_type::UShort)
00866       return constant( (unsigned short int) con.SShort());
00867 
00868     if (new_bt == basic_type::SInt)
00869       return constant( (signed int) con.SShort());
00870 
00871     if (new_bt == basic_type::UInt)
00872       return constant( (unsigned int) con.SShort());
00873 
00874     if (new_bt == basic_type::SLong)
00875       return constant( (signed long int) con.SShort());
00876 
00877     if (new_bt == basic_type::ULong)
00878       return constant( (unsigned long int) con.SShort());
00879 
00880     if (new_bt == basic_type::Float)
00881       return constant( (float) con.SShort());
00882 
00883     if (new_bt == basic_type::Double)
00884       return constant( (double) con.SShort());
00885   }
00886 
00887   if (bt == basic_type::UShort) {
00888     if (new_bt == basic_type::SChar)
00889       return constant( (signed char) con.UShort());
00890 
00891     if (new_bt == basic_type::UChar)
00892       return constant( (unsigned char) con.UShort());
00893 
00894     if (new_bt == basic_type::SShort)
00895       return constant( (signed short int) con.UShort());
00896 
00897     if (new_bt == basic_type::UShort)
00898       return constant( (unsigned short int) con.UShort());
00899 
00900     if (new_bt == basic_type::SInt)
00901       return constant( (signed int) con.UShort());
00902 
00903     if (new_bt == basic_type::UInt)
00904       return constant( (unsigned int) con.UShort());
00905 
00906     if (new_bt == basic_type::SLong)
00907       return constant( (signed long int) con.UShort());
00908 
00909     if (new_bt == basic_type::ULong)
00910       return constant( (unsigned long int) con.UShort());
00911 
00912     if (new_bt == basic_type::Float)
00913       return constant( (float) con.UShort());
00914 
00915     if (new_bt == basic_type::Double)
00916       return constant( (double) con.UShort());
00917   }
00918 
00919   if (bt == basic_type::SInt) {
00920     if (new_bt == basic_type::SChar)
00921       return constant( (signed char) con.SInt());
00922 
00923     if (new_bt == basic_type::UChar)
00924       return constant( (unsigned char) con.SInt());
00925 
00926     if (new_bt == basic_type::SShort)
00927       return constant( (signed short int) con.SInt());
00928 
00929     if (new_bt == basic_type::UShort)
00930       return constant( (unsigned short int) con.SInt());
00931 
00932     if (new_bt == basic_type::SInt)
00933       return constant( (signed int) con.SInt());
00934 
00935     if (new_bt == basic_type::UInt)
00936       return constant( (unsigned int) con.SInt());
00937 
00938     if (new_bt == basic_type::SLong)
00939       return constant( (signed long int) con.SInt());
00940 
00941     if (new_bt == basic_type::ULong)
00942       return constant( (unsigned long int) con.SInt());
00943 
00944     if (new_bt == basic_type::Float)
00945       return constant( (float) con.SInt());
00946 
00947     if (new_bt == basic_type::Double)
00948       return constant( (double) con.SInt());
00949   }
00950 
00951   if (bt == basic_type::UInt) {
00952     if (new_bt == basic_type::SChar)
00953       return constant( (signed char) con.UInt());
00954 
00955     if (new_bt == basic_type::UChar)
00956       return constant( (unsigned char) con.UInt());
00957 
00958     if (new_bt == basic_type::SShort)
00959       return constant( (signed short int) con.UInt());
00960 
00961     if (new_bt == basic_type::UShort)
00962       return constant( (unsigned short int) con.UInt());
00963 
00964     if (new_bt == basic_type::SInt)
00965       return constant( (signed int) con.UInt());
00966 
00967     if (new_bt == basic_type::UInt)
00968       return constant( (unsigned int) con.UInt());
00969 
00970     if (new_bt == basic_type::SLong)
00971       return constant( (signed long int) con.UInt());
00972 
00973     if (new_bt == basic_type::ULong)
00974       return constant( (unsigned long int) con.UInt());
00975 
00976     if (new_bt == basic_type::Float)
00977       return constant( (float) con.UInt());
00978 
00979     if (new_bt == basic_type::Double)
00980       return constant( (double) con.UInt());
00981   }
00982 
00983   if (bt == basic_type::SLong) {
00984     if (new_bt == basic_type::SChar)
00985       return constant( (signed char) con.SLong());
00986 
00987     if (new_bt == basic_type::UChar)
00988       return constant( (unsigned char) con.SLong());
00989 
00990     if (new_bt == basic_type::SShort)
00991       return constant( (signed short int) con.SLong());
00992 
00993     if (new_bt == basic_type::UShort)
00994       return constant( (unsigned short int) con.SLong());
00995 
00996     if (new_bt == basic_type::SInt)
00997       return constant( (signed int) con.SLong());
00998 
00999     if (new_bt == basic_type::UInt)
01000       return constant( (unsigned int) con.SLong());
01001 
01002     if (new_bt == basic_type::SLong)
01003       return constant( (signed long int) con.SLong());
01004 
01005     if (new_bt == basic_type::ULong)
01006       return constant( (unsigned long int) con.SLong());
01007 
01008     if (new_bt == basic_type::Float)
01009       return constant( (float) con.SLong());
01010 
01011     if (new_bt == basic_type::Double)
01012       return constant( (double) con.SLong());
01013   }
01014 
01015   if (bt == basic_type::ULong) {
01016     if (new_bt == basic_type::SChar)
01017       return constant( (signed char) con.ULong());
01018 
01019     if (new_bt == basic_type::UChar)
01020       return constant( (unsigned char) con.ULong());
01021 
01022     if (new_bt == basic_type::SShort)
01023       return constant( (signed short int) con.ULong());
01024 
01025     if (new_bt == basic_type::UShort)
01026       return constant( (unsigned short int) con.ULong());
01027 
01028     if (new_bt == basic_type::SInt)
01029       return constant( (signed int) con.ULong());
01030 
01031     if (new_bt == basic_type::UInt)
01032       return constant( (unsigned int) con.ULong());
01033 
01034     if (new_bt == basic_type::SLong)
01035       return constant( (signed long int) con.ULong());
01036 
01037     if (new_bt == basic_type::ULong)
01038       return constant( (unsigned long int) con.ULong());
01039 
01040     if (new_bt == basic_type::Float)
01041       return constant( (float) con.ULong());
01042 
01043     if (new_bt == basic_type::Double)
01044       return constant( (double) con.ULong());
01045   }
01046 
01047   if (bt == basic_type::Float) {
01048     if (new_bt == basic_type::SChar)
01049       return constant( (signed char) con.Float());
01050 
01051     if (new_bt == basic_type::UChar)
01052       return constant( (unsigned char) con.Float());
01053 
01054     if (new_bt == basic_type::SShort)
01055       return constant( (signed short int) con.Float());
01056 
01057     if (new_bt == basic_type::UShort)
01058       return constant( (unsigned short int) con.Float());
01059 
01060     if (new_bt == basic_type::SInt)
01061       return constant( (signed int) con.Float());
01062 
01063     if (new_bt == basic_type::UInt)
01064       return constant( (unsigned int) con.Float());
01065 
01066     if (new_bt == basic_type::SLong)
01067       return constant( (signed long int) con.Float());
01068 
01069     if (new_bt == basic_type::ULong)
01070       return constant( (unsigned long int) con.Float());
01071 
01072     if (new_bt == basic_type::Float)
01073       return constant( (float) con.Float());
01074 
01075     if (new_bt == basic_type::Double)
01076       return constant( (double) con.Float());
01077   }
01078 
01079   if (bt == basic_type::Double) {
01080     if (new_bt == basic_type::SChar)
01081       return constant( (signed char) con.Double());
01082 
01083     if (new_bt == basic_type::UChar)
01084       return constant( (unsigned char) con.Double());
01085 
01086     if (new_bt == basic_type::SShort)
01087       return constant( (signed short int) con.Double());
01088 
01089     if (new_bt == basic_type::UShort)
01090       return constant( (unsigned short int) con.Double());
01091 
01092     if (new_bt == basic_type::SInt)
01093       return constant( (signed int) con.Double());
01094 
01095     if (new_bt == basic_type::UInt)
01096       return constant( (unsigned int) con.Double());
01097 
01098     if (new_bt == basic_type::SLong)
01099       return constant( (signed long int) con.Double());
01100 
01101     if (new_bt == basic_type::ULong)
01102       return constant( (unsigned long int) con.Double());
01103 
01104     if (new_bt == basic_type::Float)
01105       return constant( (float) con.Double());
01106 
01107     if (new_bt == basic_type::Double)
01108       return constant( (double) con.Double());
01109   }
01110 
01111   return constant();
01112 }
01113   
01114 
01115 // ------------------------------------------------------------
01116 // Output
01117 // ------------------------------------------------------------
01118 
01119 string constant::to_string(bool wantQuoteChar) const
01120 {
01121   ostringstream ost;
01122 
01123   if (is_str()) {
01124     ost << "\"";
01125     const string & s = Str();
01126     int len = s.length();
01127 
01128     for (int i=0 ; i<len ; ++i) {
01129       int ch = s[i];
01130       print_char(s[i], ost);
01131     }
01132 
01133     ost << "\"";
01134   }
01135 
01136   else if (is_ptr())
01137     ost << Ptr();
01138 
01139   else if (_bt.is_char() && wantQuoteChar) {
01140     int value;
01141 
01142     ost << '\'';
01143 
01144     if (_bt == basic_type::SChar)
01145       value = _v.SChar;
01146 
01147     if (_bt == basic_type::UChar)
01148       value = _v.UChar;
01149 
01150     print_char(value, ost);
01151 
01152     ost << '\'';
01153   }
01154 
01155   else if (_bt == basic_type::SChar)
01156     ost << (int)_v.SChar;
01157 
01158   else if (_bt == basic_type::UChar)
01159     ost << (int)_v.UChar;
01160 
01161   else if (_bt == basic_type::SShort)
01162     ost << _v.SShort;
01163 
01164   else if (_bt == basic_type::UShort)
01165     ost << _v.UShort << "U";
01166 
01167   else if (_bt == basic_type::SInt)
01168     ost << _v.SInt;
01169 
01170   else if (_bt == basic_type::UInt)
01171     ost << _v.UInt << "U";
01172 
01173   else if (_bt == basic_type::SLong)
01174     ost << _v.SLong << "L";
01175 
01176   else if (_bt == basic_type::ULong)
01177     ost << _v.ULong << "UL";
01178 
01179   else if (_bt == basic_type::Float)
01180     ost << fixed << _v.Float << "F";
01181 
01182   else if (_bt == basic_type::Double)
01183     ost << fixed << _v.Double;
01184 
01185   return ost.str();
01186 }
01187 
01188 // -- This function returns a printable representation of a char. It
01189 // handles converting non-printable characters back into their
01190 // printable representations.
01191 
01192 void constant::print_char(int value, ostringstream & ost)
01193 {
01194   switch(value) {
01195   case '\n': ost << "\\n"; break;
01196   case '\t': ost << "\\t"; break;
01197   case '\v': ost << "\\v"; break;
01198   case '\b': ost << "\\b"; break;
01199   case '\r': ost << "\\r"; break;
01200   case '\f': ost << "\\f"; break;
01201   case '\a': ost << "\\a"; break;
01202   case '\\': ost << "\\\\"; break;
01203   case '\?': ost << "\\\?"; break;
01204   case '\"': ost << "\\\""; break;
01205   case '\'': ost << "\\\'"; break;
01206   default:
01207     if (isprint(value)) {
01208       ost << (char) value;
01209     } else {
01210       char s[100];
01211       // djimenez - this wasn't converting to octal; now it is
01212       // djimenez - now it's converting to exactly 3-digit octal.
01213       // why?  consider "\0021" in an input program.  It means
01214       // ASCII 2 followed by the digit 1 (i.e., 0x31)
01215       // if we print "\21", we're saying ASCII 17.  f2c is
01216       // full of this type of thing in FORMAT stmts...
01217       sprintf (s, "%0.3o", value & 0xff);
01218       ost << "\\" << s;
01219     }
01220   }
01221 }

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