Hormiga 1.0

/var/www/hormigaproject.com.ar/files/src/symboltable.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 #include "symboltable.h"
00047 
00049 SymbolTable::SymbolTable( SymbolTable *parentContext )
00050 {
00051     this->parent = parentContext ;
00052 }
00053 
00054 SymbolTable::~SymbolTable()
00055 {
00056     T_ST_HASH_IT is ( this->symbols ) ;
00057     while ( is.hasNext () )
00058     {
00059         is.next() ;
00060         Operand *o = this->symbols.take( is.key() ) ;
00061         delete ( o ) ;
00062     }
00063 
00064     T_TYPE_HASH_IT it ( this->types ) ;
00065     while ( it.hasNext () )
00066     {
00067         it.next() ;
00068         Type *o = this->types.take( it.key() ) ;
00069         delete ( o ) ;
00070     }
00071 
00072     T_UNIT_HASH_IT iu ( this->units ) ;
00073     while ( iu.hasNext () )
00074     {
00075         iu.next() ;
00076         Unit *o = this->units.take( iu.key() ) ;
00077         delete ( o ) ;
00078     }
00079 
00080     T_FUNC_HASH_IT iF ( this->funcs ) ;
00081     while ( iF.hasNext () )
00082     {
00083         iF.next() ;
00084         Function *o = this->funcs.take( iF.key() ) ;
00085         delete ( o ) ;
00086     }
00087 
00088     T_STEPS_HASH_IT ip ( this->steps ) ;
00089     while ( ip.hasNext () )
00090     {
00091         ip.next() ;
00092         Step *o = this->steps.take( ip.key() ) ;
00093         delete ( o ) ;
00094     }
00095 }
00096 
00097 SymbolTable* SymbolTable::getParentSymbolTable ()
00098 {
00099     return this->parent ;
00100 }
00101 
00102 T_STRING SymbolTable::toString()
00103 {
00104     T_ST_HASH_IT it ( this->symbols ) ;
00105     it.toFront() ;
00106     T_STRING toRet = "**Symbols:\n" ;
00107     while ( it.hasNext () )
00108     {
00109         it.next() ;
00110         Operand *o = this->symbols.value( it.key() , NULL ) ;
00111         toRet += QString( "%1 = %2\n" )
00112                  .arg( o->getSymbol() )
00113                  .arg( o->getValue() ) ;
00114     }
00115     return ( toRet ) ;
00116 }
00117 
00118 bool SymbolTable::populateSymbol ( Operand *o )
00119 {
00120     /* First, some security checks...
00121      * if a symbol with the same name is already at global scope, do nothing.
00122      */
00123     T_STRING name = o->getSymbol() ;
00124     if ( (parent != NULL) && (parent->getLocalSymbol( name ) == NULL)
00125         && ( this->symbols.remove( name ) > 0 ) )
00126     {
00127         parent->setLocalSymbol( name , o ) ;
00128         return ( true ) ;
00129     }
00130     return ( false ) ;
00131 }
00132 
00133 Operand* SymbolTable::getSymbol ( T_STRING &key ) const
00134 {
00135     Operand *o = this->getLocalSymbol( key ) ;
00136     if ( ( o == NULL ) && ( this->parent != NULL ) )
00137         o = this->parent->getSymbol( key ) ;
00138     return ( o ) ;
00139 }
00140 
00141 Operand* SymbolTable::getLocalSymbol ( T_STRING &key ) const
00142 {
00143     return ( this->symbols.value( key , NULL ) ) ;
00144 }
00145 
00146 Operand* SymbolTable::setLocalSymbol( T_STRING &key, Operand *o )
00147 {
00148     Operand *tmp = this->getLocalSymbol( key ) ;
00149     if ( tmp == NULL )
00150     {
00151         this->symbols.insert( key , o ) ;
00152         return ( o ) ;
00153     }
00154     delete ( o ) ;
00155     return ( tmp ) ;
00156 }
00157 
00158 Type* SymbolTable::getType ( T_STRING &key )  const
00159 {
00160     Type *t = this->getLocalType( key ) ;
00161     if ( ( t == NULL ) && ( this->parent != NULL ) )
00162         t = this->parent->getType( key ) ;
00163     return ( t ) ;
00164 }
00165 
00166 Type* SymbolTable::getLocalType ( T_STRING &key ) const
00167 {
00168     return ( this->types.value( key , NULL ) ) ;
00169 }
00170 
00171 Type* SymbolTable::setLocalType ( T_STRING &key , Type *t )
00172 {
00173     Type *tmp = this->getLocalType( key ) ;
00174     if ( tmp == NULL )
00175     {
00176         this->types.insert( key , t ) ;
00177         return ( t ) ;
00178     }
00179     delete ( t ) ;
00180     return ( tmp ) ;
00181 }
00182 
00183 Unit* SymbolTable::getUnit ( T_STRING &key )  const
00184 {
00185     Unit *t = this->getLocalUnit( key ) ;
00186     if ( ( t == NULL ) && ( this->parent != NULL ) )
00187         t = this->parent->getUnit( key ) ;
00188     return ( t ) ;
00189 }
00190 
00191 Unit* SymbolTable::getLocalUnit ( T_STRING &key ) const
00192 {
00193     return ( this->units.value( key , NULL ) ) ;
00194 }
00195 
00196 Unit* SymbolTable::setLocalUnit ( T_STRING &key , Unit *t )
00197 {
00198     Unit *tmp = this->getLocalUnit( key ) ;
00199     if ( tmp == NULL )
00200     {
00201         this->units.insert( key , t ) ;
00202         return ( t ) ;
00203     }
00204     delete ( t ) ;
00205     return ( tmp ) ;
00206 }
00207 
00208 Function* SymbolTable::getFunction ( T_STRING &key ) const
00209 {
00210     Function *t = this->getLocalFunction( key ) ;
00211     if ( ( t == NULL ) && ( this->parent != NULL ) )
00212         t = this->parent->getFunction( key ) ;
00213     return ( t ) ;
00214 }
00215 
00216 Function* SymbolTable::getLocalFunction ( T_STRING &key ) const
00217 {
00218     return ( this->funcs.value( key , NULL ) ) ;
00219 }
00220 
00221 
00222 Function* SymbolTable::setLocalFunction ( T_STRING &key , Function *f )
00223 {
00224     Function *tmp = this->getLocalFunction( key ) ;
00225     if ( tmp == NULL )
00226     {
00227         this->funcs.insert( key , f ) ;
00228         return ( f ) ;
00229     }
00230     delete ( f ) ;
00231     return ( tmp ) ;
00232 }
00233 
00234 Step* SymbolTable::getStep ( T_STRING &key ) const
00235 {
00236     Step *t = this->getLocalStep( key ) ;
00237     if ( ( t == NULL ) && ( this->parent != NULL ) )
00238         t = this->parent->getStep( key ) ;
00239     return ( t ) ;
00240 }
00241 
00242 Step* SymbolTable::getLocalStep ( T_STRING &key ) const
00243 {
00244     return ( this->steps.value( key , NULL ) ) ;
00245 }
00246 
00247 Step* SymbolTable::setLocalStep ( T_STRING &key , Step *f )
00248 {
00249     Step *tmp = this->getLocalStep( key ) ;
00250     if ( tmp == NULL )
00251     {
00252         this->steps.insert( key , f ) ;
00253         return ( f ) ;
00254     }
00255     delete ( f ) ;
00256     return ( tmp ) ;
00257 }
00258 
00259 
00260 
00261 #include "function/corefunctions.h"
00262 Function* CoreFunctionsBuilder::getFunction ( T_STRING &key )
00263 {
00264     /* Aca habria que implementar un buen builder capaz de soportar dinamicamente
00265      * las funciones cargadas por biblioteca de carga dinamica
00266      */
00267     Function* f = this->funcs.value( key , NULL ) ;
00268     if ( f == NULL )
00269     {
00270         if ( key == "pow" )
00271             f = this->setFunction( key, new FunctionPow ) ;
00272         else if ( key == "sqrt" )
00273             f = this->setFunction( key, new FunctionSqrt ) ;
00274         else if ( key == "abs" )
00275             f = this->setFunction( key, new FunctionAbs ) ;
00276         else if ( key == "ln" )
00277             f = this->setFunction( key, new FunctionLn ) ;
00278         else if ( key == "log" )
00279             f = this->setFunction( key, new FunctionLog ) ;
00280         else if ( key == "sin" )
00281             f = this->setFunction( key, new FunctionSin ) ;
00282         else if ( key == "cos" )
00283             f = this->setFunction( key, new FunctionCos ) ;
00284         else if ( key == "tan" )
00285             f = this->setFunction( key, new FunctionTan ) ;
00286         else if ( key == "floor" )
00287             f = this->setFunction( key, new FunctionFloor ) ;
00288         else if ( key == "ceil" )
00289             f = this->setFunction( key, new FunctionCeil ) ;
00290     }
00291     return ( f ) ;
00292 }
00293 
00294 Function* CoreFunctionsBuilder::setFunction ( T_STRING &key , Function *f )
00295 {
00296     this->funcs.insert( key , f ) ;
00297     return f ;
00298 }