Hormiga 1.0

/var/www/hormigaproject.com.ar/files/src/oper/operand.cpp

Go to the documentation of this file.
00001 
00002 /*
00003 # Hormiga - Software de cálculo programable.
00004 #
00005 # Copyright (C) 2008, 2009 Leonardo Román, Hugo J. Curti, Norma  Ercoli,
00006 # Universidad Nacional del Centro de la Provincia de Buenos Aires
00007 # (UNCPBA)
00008 #
00009 # Este programa es parte de Hormiga.
00010 #
00011 # Hormiga es software libre. Puede redistribuirlo y/o modificarlo
00012 # bajo los términos de la Licencia Pública General de GNU según es
00013 # publicada por la Free Software Foundation, versión 2. Vea el archivo
00014 # COPIA (español, no oficial) o COPYING (inglés, oficial) en directorio
00015 # raíz.
00016 #
00017 # Hormiga se distribuye con la esperanza de que sea útil, pero SIN
00018 # NINGUNA GARANTÍA, incluso sin la garantía MERCANTIL implícita o sin
00019 # garantizar la CONVENIENCIA PARA UN PROPÓSITO PARTICULAR. Véase la
00020 # Licencia Pública General de GNU para más detalles.
00021 #
00022 # Debería haber recibido una copia de la Licencia Pública General junto
00023 # con Hormiga. Si no ha sido así, escriba a la Free Software
00024 # Foundation, Inc., en 675 Mass Ave, Cambridge, MA 02139, EEUU.
00025 # Añada también información sobre cómo contactar con usted mediante
00026 # correo electrónico y postal.
00027 #
00028 # This file is part of Hormiga.
00029 #
00030 # Hormiga is free software; you can redistribute it and/or modify
00031 # it under the terms of the GNU General Public License version 2
00032 # as published by the Free Software Foundation; see the file COPYING
00033 # in the top directory for details.
00034 #
00035 # Hormiga is distributed in the hope that it will be useful,
00036 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00037 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00038 # GNU General Public License for more details.
00039 #
00040 # You should have received a copy of the GNU General Public License
00041 # along with Hormiga; if not, write to the Free Software
00042 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
00043 # USA
00044 */
00045 
00046 
00047 #include "operand.h"
00048 
00049 #include <math.h>
00050 
00052 Typeable::Typeable( Type* t )
00053 {
00054     this->type = t ;
00055 }
00056 
00057 Type* Typeable::getType() const
00058 {
00059     return this->type ;
00060 }
00061 
00063 T_MAGNITUDE Boolean::getValue() const
00064 {
00065     return ( ( this->value == FALSE )? FALSE : TRUE ) ;
00066 }
00067 
00068 T_STRING Boolean::toString() const
00069 {
00070     //return ( ( this->value == FALSE )? QString("FALSE") : QString("TRUE") ) ;
00071     return ( this->getSymbol() ) ;
00072 }
00073 
00074 bool Boolean::isConstantExpresion () const
00075 {
00076     return ( true ) ;
00077 }
00078 
00079 Boolean::Boolean()
00080 {
00081     this->value = FALSE ;
00082 }
00083 
00084 Boolean::Boolean( Boolean &v )
00085 {
00086     this->value = v.getValue() ;
00087     this->symbol = v.getSymbol() ;
00088 }
00089 
00090 Boolean::Boolean( T_MAGNITUDE v , T_STRING &symbol )
00091 {
00092     this->value = ( v == FALSE )? FALSE : TRUE ;
00093     this->symbol = symbol ;
00094 }
00095 
00096 
00098 T_MAGNITUDE VarBoolean::setValue( T_MAGNITUDE v )
00099 {
00100     return ( this->value = v != FALSE ) ;
00101 }
00102 
00103 bool VarBoolean::isConstantExpresion () const
00104 {
00105     return ( false ) ;
00106 }
00107 
00108 VarBoolean::VarBoolean()
00109 {}
00110 
00111 VarBoolean::VarBoolean( T_MAGNITUDE &v , T_STRING &symbol )
00112 {
00113     this->setValue( v ) ;
00114     this->symbol = symbol ;
00115 }
00116 
00117 VarBoolean::VarBoolean( VarBoolean &v ) : Boolean::Boolean( (Boolean&) v )
00118 {}
00119 
00120 VarBoolean::VarBoolean( Boolean &v ) : Boolean::Boolean( v )
00121 {}
00122 
00123 
00125 T_MAGNITUDE Value::getValue() const
00126 {
00127     return ( this->value ) ;
00128 }
00129 
00130 T_STRING Value::toString() const
00131 {
00132     //return ( QString("%1").arg( this->getValue() ) ) ;
00133     return ( this->getSymbol() ) ;
00134 }
00135 
00136 bool Value::isConstantExpresion () const
00137 {
00138     return ( true ) ;
00139 }
00140 
00141 Value::Value()
00142 {
00143     this->value = 0 ;
00144 }
00145 
00146 Value::Value( T_MAGNITUDE v , T_STRING &symbol , Type *t ) : Typeable( t )
00147 {
00148     this->value = v ;
00149     this->symbol = symbol ;
00150 }
00151 
00152 Value::Value( Value &v ) : Typeable( v.type )
00153 {
00154     this->value = v.getValue() ;
00155     this->symbol = v.getSymbol() ;
00156 }
00157 
00158 
00160 T_MAGNITUDE VarValue::setValue( T_MAGNITUDE v )
00161 {
00162     this->value = v ;
00163     return ( v ) ;
00164 }
00165 
00166 bool VarValue::isConstantExpresion () const
00167 {
00168     return ( false ) ;
00169 }
00170 
00171 VarValue::VarValue()
00172 {
00173     owner = NULL ;
00174 }
00175 
00176 VarValue::VarValue( T_MAGNITUDE v , T_STRING &s , Type *t ) : Value ( v , s , t )
00177 {
00178     owner = NULL ;
00179 }
00180 
00181 VarValue::VarValue( Value &v ) : Value ( v )
00182 {
00183     owner = NULL ;
00184 }
00185 
00186 VarValue::VarValue( VarValue &v ) : Value::Value( v )
00187 {
00188     owner = v.getOwnerStep() ;
00189 }
00190 
00191 
00193 void VarValueProxy::setProxiedOperand ( Operand* pv )
00194 {
00195     this->realParam = pv ;
00196     /* As we only accept 'COPY passed params', here can't be a SymbolTable
00197      * object ('REFERENCE passed' param), then we need to delete it
00198      */
00199     if ( this->formalParam != NULL )
00200         delete this->formalParam ;
00201     this->formalParam = NULL ;
00202 }
00203 
00204 void VarValueProxy::resetInternalValue ()
00205 {
00206     /* First condition is needed when it's used for internals params values on
00207        'integration' */
00208     if ( ( this->realParam != NULL )
00209          && (this->formalParam != NULL )
00210          && ( ! this->isReference ) )
00211     {
00212         delete this->formalParam ;
00213         this->formalParam = NULL ;
00214     }
00215 }
00216 
00217 T_MAGNITUDE VarValueProxy::setValue ( T_MAGNITUDE v )
00218 {
00219     /* For memory management efficience, we only create an internal storage
00220      * if it's realy needed.
00221      */
00222     if ( this->formalParam == NULL )
00223     {
00224         if ( this->isReference )
00225         {
00226             this->formalParam = (VarValue*) this->realParam ;
00227             this->formalParam->setValue( v ) ;
00228         }
00229         else
00230         {
00231             T_STRING symbol = "internal" ;
00232             this->formalParam = new VarValue ( v , symbol , this->getType() ) ;
00233         }
00234     }
00235     else
00236         this->formalParam->setValue( v ) ;
00237     return v ;
00238 }
00239 
00240 T_MAGNITUDE VarValueProxy::getValue () const
00241 {
00242     if ( this->formalParam == NULL )
00243         return this->realParam->getValue() ;
00244     else
00245         return this->formalParam->getValue() ;
00246 }
00247 
00248 T_STRING VarValueProxy::toString () const
00249 {
00250     if ( this->realParam != NULL )
00251         return this->realParam->toString() ;
00252     else if ( this->formalParam != NULL )
00253         return this->formalParam->toString() ;
00254     return ( "VarValueProxy without instance" ) ;
00255 }
00256 
00257 VarValueProxy::VarValueProxy ()
00258 {
00259     this->formalParam = NULL ;
00260     this->realParam = NULL ;
00261     this->isReference = false ;
00262 }
00263 
00264 VarValueProxy::VarValueProxy ( T_STRING symbol , Type* type , bool isReference )
00265         : VarValue( 0.0 , symbol , type )
00266 {
00267     this->formalParam = NULL ;
00268     this->realParam = NULL ;
00269     this->isReference = isReference ;
00270 }
00271 
00272 VarValueProxy::~VarValueProxy ()
00273 {
00274     if ( (this->formalParam != NULL ) && ( ! this->isReference ) )
00275         delete this->formalParam ;
00276 }
00277 
00278 
00280 T_MAGNITUDE Sequence::getFirst() const
00281 {
00282     return ( this->first->getValue() ) ;
00283 }
00284 
00285 T_MAGNITUDE Sequence::getLast() const
00286 {
00287     return ( this->last->getValue() ) ;
00288 }
00289 
00290 T_MAGNITUDE Sequence::getStep() const
00291 {
00292     return ( this->step->getValue() ) ;
00293 }
00294 
00295 T_MAGNITUDE Sequence::getValue () const
00296 {
00297     T_MAGNITUDE total = 0 ;
00298     for ( T_MAGNITUDE i = first->getValue() ;
00299           i <= last->getValue() ;
00300           i += step->getValue() )
00301         total += i ;
00302     return ( total ) ;
00303 }
00304 
00305 T_STRING Sequence::toString () const
00306 {
00307     return ( QString ("[%1 .. %2 step %3]")
00308             .arg( first->toString() )
00309             .arg( last->toString() )
00310             .arg( step->toString() ) ) ;
00311 }
00312 
00313 bool Sequence::isConstantExpresion () const
00314 {
00315     return ( this->first->isConstantExpresion()
00316              && this->last->isConstantExpresion()
00317              && this->step->isConstantExpresion() ) ;
00318 }
00319 
00320 Sequence::Sequence( Operand *f , Operand *l , Operand *s )
00321 {
00322     this->first = f ;
00323     this->last = l ;
00324     this->step = s ;
00325 }
00326 
00327 Sequence::~Sequence ()
00328 {
00329     if ( (first != NULL) && !first->isShareable() ) delete first ;
00330     if ( (last != NULL) && !last->isShareable() ) delete last ;
00331     if ( (step != NULL) && !step->isShareable() ) delete step ;
00332 }
00333 
00334 
00336 T_STRING UnaryOperator::toString() const
00337 {
00338     return ( QString ("(%1 %2)")
00339             .arg( this->getSymbol() )
00340             .arg( op1->toString() ) ) ;
00341 }
00342 
00343 bool UnaryOperator::isConstantExpresion () const
00344 {
00345     return ( this->op1->isConstantExpresion () ) ;
00346 }
00347 
00348 UnaryOperator::UnaryOperator ( Operand *op )
00349 {
00350     this->op1 = op ;
00351 }
00352 
00353 UnaryOperator::~UnaryOperator ()
00354 {
00355     if ( op1 != NULL && ! op1->isShareable() ) delete op1 ;
00356 }
00357 
00358 
00360 T_STRING OperatorNot::symbol = "NOT" ;
00361 
00362 T_STRING OperatorNot::getSymbol() const
00363 {
00364     return ( OperatorNot::symbol ) ;
00365 }
00366 
00367 T_MAGNITUDE OperatorNot::getValue() const
00368 {
00369     return ( ( this->op1->getValue() == FALSE )? TRUE : FALSE ) ;
00370 }
00371 
00372 OperatorNot::OperatorNot( Operand *op ) : UnaryOperator::UnaryOperator ( op )
00373 {}
00374 
00375 
00377 T_STRING OperatorNeg::symbol = "-" ;
00378 
00379 T_STRING OperatorNeg::getSymbol() const
00380 {
00381     return ( OperatorNeg::symbol );
00382 }
00383 
00384 T_MAGNITUDE OperatorNeg::getValue() const
00385 {
00386     return ( - this->op1->getValue() ) ;
00387 }
00388 
00389 OperatorNeg::OperatorNeg( Operand *op ) : UnaryOperator::UnaryOperator ( op )
00390 {}
00391 
00392 
00394 T_STRING OperatorFactorial::symbol = "!" ;
00395 
00396 T_STRING OperatorFactorial::getSymbol() const
00397 {
00398     return ( OperatorFactorial::symbol );
00399 }
00400 
00401 T_MAGNITUDE OperatorFactorial::getValue() const
00402 {
00403     long long i = nearbyintl ( this->op1->getValue() ) ;
00404     long long t = 1 ;
00405     while ( i > 1 ) {
00406         t *= i-- ;
00407     }
00408     return ( t ) ;
00409 }
00410 
00411 OperatorFactorial::OperatorFactorial( Operand *op )
00412     : UnaryOperator::UnaryOperator ( op )
00413 {}
00414 
00415 
00417 T_STRING BinaryOperator::toString() const
00418 {
00419     return ( QString ("( %1 %2 %3 )")
00420             .arg( op1->toString() )
00421             .arg( this->getSymbol() )
00422             .arg( op2->toString() ) ) ;
00423 }
00424 
00425 bool BinaryOperator::isConstantExpresion () const
00426 {
00427     return ( this->op1->isConstantExpresion ()
00428              && this->op2->isConstantExpresion () ) ;
00429 }
00430 
00431 BinaryOperator::BinaryOperator ( Operand *op1 , Operand *op2 )
00432 {
00433     this->op1 = op1 ;
00434     this->op2 = op2 ;
00435 }
00436 
00437 BinaryOperator::~BinaryOperator ()
00438 {
00439     if ( op1 != NULL && ! op1->isShareable() ) delete op1 ;
00440     if ( op2 != NULL && ! op2->isShareable() ) delete op2 ;
00441 }
00442 
00443 
00445 T_STRING OperatorAdd::symbol = "+" ;
00446 
00447 T_STRING OperatorAdd::getSymbol() const
00448 {
00449     return ( OperatorAdd::symbol );
00450 }
00451 
00452 T_MAGNITUDE OperatorAdd::getValue() const
00453 {
00454     return ( this->op1->getValue() + this->op2->getValue() ) ;
00455 }
00456 
00457 OperatorAdd::OperatorAdd( Operand *op1 , Operand *op2 )
00458     : BinaryOperator::BinaryOperator ( op1 , op2 )
00459 {}
00460 
00462 T_STRING OperatorSub::symbol = "-" ;
00463 
00464 T_STRING OperatorSub::getSymbol() const
00465 {
00466     return ( OperatorSub::symbol );
00467 }
00468 
00469 T_MAGNITUDE OperatorSub::getValue() const
00470 {
00471     return ( this->op1->getValue() - this->op2->getValue() ) ;
00472 }
00473 
00474 OperatorSub::OperatorSub( Operand *op1 , Operand *op2 )
00475     : BinaryOperator::BinaryOperator ( op1 , op2 )
00476 {}
00477 
00478 
00480 T_STRING OperatorMul::symbol = "*" ;
00481 
00482 T_STRING OperatorMul::getSymbol() const
00483 {
00484     return ( OperatorMul::symbol );
00485 }
00486 
00487 T_MAGNITUDE OperatorMul::getValue() const
00488 {
00489     return ( this->op1->getValue() * this->op2->getValue() ) ;
00490 }
00491 
00492 OperatorMul::OperatorMul( Operand *op1 , Operand *op2 )
00493     : BinaryOperator::BinaryOperator ( op1 , op2 )
00494 {}
00495 
00496 
00498 T_STRING OperatorDiv::symbol = "/" ;
00499 
00500 T_STRING OperatorDiv::getSymbol() const
00501 {
00502     return ( OperatorDiv::symbol );
00503 }
00504 
00505 T_MAGNITUDE OperatorDiv::getValue() const
00506 {
00507     return ( this->op1->getValue() / this->op2->getValue() ) ;
00508 }
00509 
00510 OperatorDiv::OperatorDiv( Operand *op1 , Operand *op2 )
00511     : BinaryOperator::BinaryOperator ( op1 , op2 )
00512 {}
00513 
00514 
00516 T_STRING OperatorMod::symbol = "MOD" ;
00517 
00518 T_STRING OperatorMod::getSymbol() const
00519 {
00520     return ( OperatorMod::symbol );
00521 }
00522 
00523 T_MAGNITUDE OperatorMod::getValue() const
00524 {
00525     /* Here we sould use modf() ?? */
00526     long long x = nearbyintl ( this->op1->getValue() ) ;
00527     long long y = nearbyintl ( this->op1->getValue() ) ;
00528     return ( x % y ) ;
00529 }
00530 
00531 OperatorMod::OperatorMod( Operand *op1 , Operand *op2 )
00532     : BinaryOperator::BinaryOperator ( op1 , op2 )
00533 {}
00534 
00535 
00537 T_STRING OperatorAnd::symbol = "AND" ;
00538 
00539 T_STRING OperatorAnd::getSymbol() const
00540 {
00541     return ( OperatorAnd::symbol );
00542 }
00543 
00544 T_MAGNITUDE OperatorAnd::getValue() const
00545 {
00546     return ( this->op1->getValue() && this->op2->getValue() ) ;
00547 }
00548 
00549 OperatorAnd::OperatorAnd( Operand *op1 , Operand *op2 )
00550     : BinaryOperator::BinaryOperator ( op1 , op2 )
00551 {}
00552 
00553 
00555 T_STRING OperatorOr::symbol = "OR" ;
00556 
00557 T_STRING OperatorOr::getSymbol() const
00558 {
00559     return ( OperatorOr::symbol );
00560 }
00561 
00562 T_MAGNITUDE OperatorOr::getValue() const
00563 {
00564     return ( this->op1->getValue() || this->op2->getValue() ) ;
00565 }
00566 
00567 OperatorOr::OperatorOr( Operand *op1 , Operand *op2 )
00568     : BinaryOperator::BinaryOperator ( op1 , op2 )
00569 {}
00570 
00571 
00573 T_STRING OperatorEqual::symbol = "=" ;
00574 
00575 T_STRING OperatorEqual::getSymbol() const
00576 {
00577     return ( OperatorEqual::symbol );
00578 }
00579 
00580 T_MAGNITUDE OperatorEqual::getValue() const
00581 {
00582     return ( this->op1->getValue() == this->op2->getValue() ) ;
00583 }
00584 
00585 OperatorEqual::OperatorEqual( Operand *op1 , Operand *op2 )
00586     : BinaryOperator::BinaryOperator ( op1 , op2 )
00587 {}
00588 
00589 
00591 T_STRING OperatorDistinct::symbol = "!=" ;
00592 
00593 T_STRING OperatorDistinct::getSymbol() const
00594 {
00595     return ( OperatorDistinct::symbol );
00596 }
00597 
00598 T_MAGNITUDE OperatorDistinct::getValue() const
00599 {
00600     return ( this->op1->getValue() != this->op2->getValue() ) ;
00601 }
00602 
00603 OperatorDistinct::OperatorDistinct( Operand *op1 , Operand *op2 )
00604     : BinaryOperator::BinaryOperator ( op1 , op2 )
00605 {}
00606 
00607 
00609 T_STRING OperatorGT::symbol = ">" ;
00610 
00611 T_STRING OperatorGT::getSymbol() const
00612 {
00613     return ( OperatorGT::symbol );
00614 }
00615 
00616 T_MAGNITUDE OperatorGT::getValue() const
00617 {
00618     return ( this->op1->getValue() > this->op2->getValue() ) ;
00619 }
00620 
00621 OperatorGT::OperatorGT( Operand *op1 , Operand *op2 )
00622     : BinaryOperator::BinaryOperator ( op1 , op2 )
00623 {}
00624 
00625 
00627 T_STRING OperatorLT::symbol = "<" ;
00628 
00629 T_STRING OperatorLT::getSymbol() const
00630 {
00631     return ( OperatorLT::symbol );
00632 }
00633 
00634 T_MAGNITUDE OperatorLT::getValue() const
00635 {
00636     return ( this->op1->getValue() < this->op2->getValue() ) ;
00637 }
00638 
00639 OperatorLT::OperatorLT( Operand *op1 , Operand *op2 )
00640     : BinaryOperator::BinaryOperator ( op1 , op2 )
00641 {}
00642 
00643 
00645 T_STRING OperatorGE::symbol = ">=" ;
00646 
00647 T_STRING OperatorGE::getSymbol() const
00648 {
00649     return ( OperatorGE::symbol );
00650 }
00651 
00652 T_MAGNITUDE OperatorGE::getValue() const
00653 {
00654     return ( this->op1->getValue() >= this->op2->getValue() ) ;
00655 }
00656 
00657 OperatorGE::OperatorGE( Operand *op1 , Operand *op2 )
00658     : BinaryOperator::BinaryOperator ( op1 , op2 )
00659 {}
00660 
00661 
00663 T_STRING OperatorLE::symbol = "<=" ;
00664 
00665 T_STRING OperatorLE::getSymbol() const
00666 {
00667     return ( OperatorLE::symbol );
00668 }
00669 
00670 T_MAGNITUDE OperatorLE::getValue() const
00671 {
00672     return ( this->op1->getValue() <= this->op2->getValue() ) ;
00673 }
00674 
00675 OperatorLE::OperatorLE( Operand *op1 , Operand *op2 )
00676     : BinaryOperator::BinaryOperator ( op1 , op2 )
00677 {}
00678