|
Hormiga 1.0
|
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 }