lib Library API Documentation

koscript_value.cc

00001 /* This file is part of the KDE project 00002 Copyright (C) 1998, 1999, 2000 Torben Weis <weis@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00017 Boston, MA 02111-1307, USA. 00018 */ 00019 00020 #include "koscript_value.h" 00021 #include "koscript_func.h" 00022 #include "koscript_context.h" 00023 #include "koscript_struct.h" 00024 #include "koscript_property.h" 00025 #include "koscript_method.h" 00026 00027 #include <klocale.h> 00028 00029 // Imported from scanner.ll 00030 extern KLocale* s_koscript_locale; 00031 00032 KSValue* KSValue::s_null = 0; 00033 00034 KSValue::KSValue() 00035 { 00036 typ = Empty; 00037 m_mode = Temp; 00038 } 00039 00040 KSValue::KSValue( Type _type ) 00041 { 00042 typ = _type; 00043 m_mode = Temp; 00044 00045 switch( typ ) 00046 { 00047 case DateType: 00048 val.ptr = new QDate; 00049 break; 00050 case TimeType: 00051 val.ptr = new QTime; 00052 break; 00053 case StringType: 00054 val.ptr = new QString; 00055 break; 00056 case ListType: 00057 val.ptr = new QValueList<Ptr>; 00058 break; 00059 case MapType: 00060 val.ptr = new QMap<QString,Ptr>; 00061 break; 00062 case CharRefType: 00063 val.ptr = new KScript::CharRef( 0, 0 ); 00064 break; 00065 case CharType: 00066 val.c = 0; 00067 break; 00068 case FunctionType: 00069 case MethodType: 00070 case PropertyType: 00071 case ModuleType: 00072 case StructType: 00073 case StructClassType: 00074 val.ptr = 0; 00075 break; 00076 case StructBuiltinMethodType: 00077 val.sm = 0; 00078 break; 00079 case IntType: 00080 case BoolType: 00081 case DoubleType: 00082 case Empty: 00083 // Do nothing 00084 break; 00085 case NTypes: 00086 Q_ASSERT( 0 ); 00087 } 00088 } 00089 00090 KSValue::KSValue( const KSValue& p ) : QShared() 00091 { 00092 typ = Empty; 00093 *this = p; 00094 } 00095 00096 KSValue::~KSValue() 00097 { 00098 clear(); 00099 } 00100 00101 KSValue& KSValue::operator= ( const KSValue& p ) 00102 { 00103 clear(); 00104 00105 switch( p.type() ) 00106 { 00107 case Empty: 00108 break; 00109 case DateType: 00110 val.ptr = new QDate( p.dateValue() ); 00111 break; 00112 case TimeType: 00113 val.ptr = new QTime( p.timeValue() ); 00114 break; 00115 case StringType: 00116 val.ptr = new QString( p.stringValue() ); 00117 break; 00118 case ListType: 00119 val.ptr = new QValueList<Ptr>( p.listValue() ); 00120 break; 00121 case MapType: 00122 val.ptr = new QMap<QString,Ptr>( p.mapValue() ); 00123 break; 00124 case IntType: 00125 val.i = p.intValue(); 00126 break; 00127 case BoolType: 00128 val.b = p.boolValue(); 00129 break; 00130 case DoubleType: 00131 val.d = p.doubleValue(); 00132 break; 00133 case CharType: 00134 val.c = p.charValue().unicode(); 00135 break; 00136 case CharRefType: 00137 val.ptr = new KScript::CharRef( p.charRefValue() ); 00138 break; 00139 case StructBuiltinMethodType: 00140 val.sm = p.val.sm; 00141 break; 00142 case FunctionType: 00143 case MethodType: 00144 case PropertyType: 00145 case ModuleType: 00146 case StructClassType: 00147 val.ptr = p.val.ptr; 00148 ((QShared*)val.ptr)->ref(); 00149 break; 00150 case StructType: 00151 val.ptr = ((KSStruct*)p.val.ptr)->clone(); 00152 break; 00153 case NTypes: 00154 Q_ASSERT( 0 ); 00155 } 00156 00157 typ = p.type(); 00158 m_mode = p.mode(); 00159 00160 return *this; 00161 } 00162 00163 QString KSValue::typeName() const 00164 { 00165 return typeToName( typ ); 00166 } 00167 00168 void KSValue::setValue( const QDate& _value ) 00169 { 00170 clear(); 00171 typ = DateType; 00172 val.ptr = new QDate( _value ); 00173 } 00174 00175 void KSValue::setValue( const QTime& _value ) 00176 { 00177 clear(); 00178 typ = TimeType; 00179 val.ptr = new QTime( _value ); 00180 } 00181 00182 void KSValue::setValue( const QString& _value ) 00183 { 00184 clear(); 00185 typ = StringType; 00186 val.ptr = new QString( _value ); 00187 } 00188 00189 void KSValue::setValue( const QValueList<Ptr>& _value ) 00190 { 00191 clear(); 00192 typ = ListType; 00193 val.ptr = new QValueList<Ptr>( _value ); 00194 } 00195 00196 void KSValue::setValue( const QMap<QString,Ptr>& _value ) 00197 { 00198 clear(); 00199 typ = MapType; 00200 val.ptr = new QMap<QString,Ptr>( _value ); 00201 } 00202 00203 void KSValue::setValue( KScript::Long _value ) 00204 { 00205 clear(); 00206 typ = IntType; 00207 val.i = _value; 00208 } 00209 00210 void KSValue::setValue( KScript::Boolean _value ) 00211 { 00212 clear(); 00213 typ = BoolType; 00214 val.b = _value; 00215 } 00216 00217 void KSValue::setValue( KScript::Double _value ) 00218 { 00219 clear(); 00220 typ = DoubleType; 00221 val.d = _value; 00222 } 00223 00224 void KSValue::setValue( const KScript::Char& _value ) 00225 { 00226 clear(); 00227 typ = CharType; 00228 val.c = _value.unicode(); 00229 } 00230 00231 void KSValue::setValue( const KScript::CharRef& _value ) 00232 { 00233 clear(); 00234 typ = CharRefType; 00235 val.ptr = new KScript::CharRef( _value ); 00236 } 00237 00238 void KSValue::setValue( KSFunction* _value ) 00239 { 00240 clear(); 00241 typ = FunctionType; 00242 // Do not call ref() since we take over ownership 00243 val.ptr = _value; 00244 } 00245 00246 void KSValue::setValue( KSMethod* _value ) 00247 { 00248 clear(); 00249 typ = MethodType; 00250 // Do not call ref() since we take over ownership 00251 val.ptr = _value; 00252 } 00253 00254 void KSValue::setValue( KSProperty* _value ) 00255 { 00256 clear(); 00257 typ = PropertyType; 00258 // Do not call ref() since we take over ownership 00259 val.ptr = _value; 00260 } 00261 00262 void KSValue::setValue( KSModule* _value ) 00263 { 00264 clear(); 00265 typ = ModuleType; 00266 // Do not call ref() since we take over ownership 00267 val.ptr = _value; 00268 } 00269 00270 void KSValue::setValue( KSStruct* _value ) 00271 { 00272 clear(); 00273 typ = StructType; 00274 // Do not call ref() since we take over ownership 00275 val.ptr = _value; 00276 } 00277 00278 void KSValue::setValue( KSStructClass* _value ) 00279 { 00280 clear(); 00281 typ = StructClassType; 00282 // Do not call ref() since we take over ownership 00283 val.ptr = _value; 00284 } 00285 00286 void KSValue::setValue( KSStructBuiltinMethod _value ) 00287 { 00288 clear(); 00289 typ = StructBuiltinMethodType; 00290 val.sm = _value; 00291 } 00292 00293 void KSValue::clear() 00294 { 00295 switch( typ ) 00296 { 00297 case Empty: 00298 case IntType: 00299 case BoolType: 00300 case DoubleType: 00301 case CharType: 00302 case StructBuiltinMethodType: 00303 break; 00304 case FunctionType: 00305 if ( val.ptr ) 00306 if ( functionValue()->deref() ) 00307 delete ((KSFunction*)val.ptr); 00308 break; 00309 case PropertyType: 00310 if ( val.ptr ) 00311 if ( propertyValue()->deref() ) 00312 delete ((KSProperty*)val.ptr); 00313 break; 00314 case MethodType: 00315 if ( val.ptr ) 00316 if ( methodValue()->deref() ) 00317 delete ((KSMethod*)val.ptr); 00318 break; 00319 case ModuleType: 00320 if ( val.ptr ) 00321 if ( moduleValue()->deref() ) 00322 delete ((KSModule*)val.ptr); 00323 break; 00324 case StructType: 00325 if ( val.ptr ) 00326 if ( structValue()->deref() ) 00327 delete ((KSStruct*)val.ptr); 00328 break; 00329 case StructClassType: 00330 if ( val.ptr ) 00331 if ( structClassValue()->deref() ) 00332 delete ((KSStructClass*)val.ptr); 00333 break; 00334 case StringType: 00335 delete (QString*)val.ptr; 00336 break; 00337 case DateType: 00338 delete (QDate*)val.ptr; 00339 break; 00340 case TimeType: 00341 delete (QTime*)val.ptr; 00342 break; 00343 case ListType: 00344 delete (QValueList<Ptr>*)val.ptr; 00345 break; 00346 case MapType: 00347 delete (QMap<QString,Ptr>*)val.ptr; 00348 break; 00349 case CharRefType: 00350 delete (KScript::CharRef*)val.ptr; 00351 break; 00352 case NTypes: 00353 Q_ASSERT(0); 00354 break; 00355 } 00356 00357 typ = Empty; 00358 } 00359 00360 static QString *typ_to_name = 0; 00361 00362 void KSValue::initTypeNameMap() 00363 { 00364 if ( typ_to_name ) return; 00365 00366 typ_to_name = new QString[(int)NTypes]; 00367 00368 typ_to_name[(int)Empty] = QString::fromLatin1("<none>"); 00369 typ_to_name[(int)StringType] = QString::fromLatin1("String"); 00370 typ_to_name[(int)IntType] = QString::fromLatin1("Integer"); 00371 typ_to_name[(int)BoolType] = QString::fromLatin1("Boolean"); 00372 typ_to_name[(int)DoubleType] = QString::fromLatin1("Double"); 00373 typ_to_name[(int)ListType] = QString::fromLatin1("List"); 00374 typ_to_name[(int)MapType] = QString::fromLatin1("Map"); 00375 typ_to_name[(int)CharType] = QString::fromLatin1("Char"); 00376 typ_to_name[(int)CharRefType] = QString::fromLatin1("Char"); 00377 typ_to_name[(int)FunctionType] = QString::fromLatin1("Function"); 00378 typ_to_name[(int)MethodType] = QString::fromLatin1("Method"); 00379 typ_to_name[(int)PropertyType] = QString::fromLatin1("Property"); 00380 typ_to_name[(int)ModuleType] = QString::fromLatin1("Module"); 00381 typ_to_name[(int)StructType] = QString::fromLatin1("Struct"); 00382 typ_to_name[(int)StructClassType] = QString::fromLatin1("StructClass"); 00383 typ_to_name[(int)StructBuiltinMethodType] = QString::fromLatin1("StructBuiltinMethod"); 00384 typ_to_name[(int)DateType] = QString::fromLatin1("Date"); 00385 typ_to_name[(int)TimeType] = QString::fromLatin1("Time"); 00386 } 00387 00388 QString KSValue::typeToName( KSValue::Type _typ ) 00389 { 00390 initTypeNameMap(); 00391 return typ_to_name[_typ]; 00392 } 00393 00394 KSValue::Type KSValue::nameToType( const QString& _name ) 00395 { 00396 initTypeNameMap(); 00397 00398 int t = (int)NTypes; 00399 while ( t > (int)Empty && typ_to_name[(int)--t] != _name ) 00400 ; 00401 return Type(t); 00402 } 00403 00404 bool KSValue::cast( Type _typ ) 00405 { 00406 if ( typ == _typ ) 00407 return true; 00408 00409 switch( typ ) 00410 { 00411 case Empty: 00412 return false; 00413 case IntType: 00414 if ( _typ == DoubleType ) 00415 { 00416 KScript::Double d = (KScript::Double)val.i; 00417 val.d = d; 00418 typ = _typ; 00419 return true; 00420 } 00421 return false; 00422 case BoolType: 00423 if ( _typ == StringType ) 00424 { 00425 KScript::Boolean b = val.b; 00426 if ( b ) 00427 setValue( "TRUE" ); 00428 else 00429 setValue( "FALSE" ); 00430 typ = _typ; 00431 return true; 00432 } 00433 else if ( _typ == IntType ) 00434 { 00435 KScript::Boolean b = val.b; 00436 setValue( b ? 1 : 0 ); 00437 typ = _typ; 00438 } 00439 return false; 00440 break; 00441 case DoubleType: 00442 if ( _typ == IntType ) 00443 { 00444 KScript::Long i = (KScript::Long)val.d; 00445 val.i = i; 00446 typ = _typ; 00447 return true; 00448 } 00449 return false; 00450 case StringType: 00451 if ( _typ == BoolType ) 00452 { 00453 setValue( !stringValue().isEmpty() ); 00454 return TRUE; 00455 } 00456 return false; 00457 case CharRefType: 00458 if ( _typ != CharType ) 00459 return false; 00460 typ = _typ; 00461 return true; 00462 case PropertyType: 00463 /* { 00464 KSValue* v = propertyValue()->object()->member( propertyValue()->name(), FALSE ); 00465 if ( !v ) 00466 return false; 00467 if ( !v->cast( _typ ) ) 00468 return false; 00469 *this = *v; 00470 } 00471 break; */ 00472 case DateType: 00473 case TimeType: 00474 case ListType: 00475 case MapType: 00476 case CharType: 00477 case FunctionType: 00478 case MethodType: 00479 case StructBuiltinMethodType: 00480 case StructType: 00481 case StructClassType: 00482 case ModuleType: 00483 // They can be casted to nothing 00484 return false; 00485 case NTypes: 00486 Q_ASSERT(0); 00487 break; 00488 } 00489 00490 typ = _typ; 00491 00492 return true; 00493 } 00494 00495 QString KSValue::toString( KSContext& context ) 00496 { 00497 switch( typ ) 00498 { 00499 case Empty: 00500 return QString( "<none>" ); 00501 break; 00502 case FunctionType: 00503 return QString( "<function>" ); 00504 break; 00505 case PropertyType: 00506 return QString( "<property>" ); 00507 break; 00508 case TimeType: 00509 return s_koscript_locale->formatTime( timeValue(), true ); 00510 case DateType: 00511 return s_koscript_locale->formatDate( dateValue(), true ); 00512 case StructClassType: 00513 return ( QString( "<struct class " ) + structClassValue()->name() + ">" ); 00514 break; 00515 case ModuleType: 00516 return ( QString( "<module " ) + moduleValue()->name() + ">" ); 00517 break; 00518 case StructType: 00519 { 00520 QString tmp( "{ Struct %1 { " ); 00521 tmp = tmp.arg( structValue()->getClass()->name() ); 00522 const QStringList& lst = structValue()->getClass()->vars(); 00523 QStringList::ConstIterator it2 = lst.begin(); 00524 for( ; it2 != lst.end(); ++it2 ) 00525 { 00526 QString s("( %1, %2 ), "); 00527 KSValue::Ptr ptr = ((KSStruct*)val.ptr)->member( context, *it2 ); 00528 s = s.arg( *it2 ).arg( ptr->toString( context ) ); 00529 tmp += s; 00530 } 00531 tmp += "} }"; 00532 return tmp; 00533 } 00534 break; 00535 case MethodType: 00536 return QString( "<method>" ); 00537 break; 00538 case StructBuiltinMethodType: 00539 return QString( "<struct builtin method>" ); 00540 break; 00541 case IntType: 00542 { 00543 QString tmp; 00544 tmp.setNum( val.i ); 00545 return tmp; 00546 } 00547 break; 00548 case BoolType: 00549 { 00550 if ( val.b ) 00551 return QString( "TRUE" ); 00552 else 00553 return QString( "FALSE" ); 00554 } 00555 break; 00556 case DoubleType: 00557 { 00558 QString tmp; 00559 tmp.setNum( val.d ); 00560 return tmp; 00561 } 00562 break; 00563 case StringType: 00564 return *((QString*)val.ptr); 00565 break; 00566 case ListType: 00567 { 00568 QString tmp( "[ " ); 00569 QValueList<Ptr>* lst = (QValueList<Ptr>*)val.ptr; 00570 QValueList<Ptr>::Iterator it = lst->begin(); 00571 QValueList<Ptr>::Iterator end = lst->end(); 00572 for( ; it != end; ++it ) 00573 { 00574 tmp += (*it)->toString( context ); 00575 tmp += ", "; 00576 } 00577 tmp.truncate( tmp.length() - 1 ); 00578 tmp[ tmp.length() - 1 ] = ' '; 00579 tmp += "]"; 00580 return tmp; 00581 } 00582 break; 00583 case MapType: 00584 { 00585 QString tmp( "{ " ); 00586 QMap<QString,Ptr>* lst = (QMap<QString,Ptr>*)val.ptr; 00587 QMap<QString,Ptr>::Iterator it = lst->begin(); 00588 QMap<QString,Ptr>::Iterator end = lst->end(); 00589 for( ; it != end; ++it ) 00590 { 00591 tmp += "( "; 00592 tmp += it.key(); 00593 tmp += ", "; 00594 tmp += it.data()->toString( context ); 00595 tmp += " ), "; 00596 } 00597 tmp.truncate( tmp.length() - 1 ); 00598 tmp[ tmp.length() - 1 ] = ' '; 00599 tmp += "}"; 00600 return tmp; 00601 } 00602 break; 00603 case CharRefType: 00604 case CharType: 00605 { 00606 QString tmp( "'%1'" ); 00607 return tmp.arg( charValue() ); 00608 } 00609 break; 00610 case NTypes: 00611 Q_ASSERT(0); 00612 break; 00613 } 00614 00615 // Never reached 00616 return QString::null; 00617 } 00618 00619 void KSValue::suck( KSValue* v ) 00620 { 00621 if ( v->mode() != Temp ) 00622 { 00623 *this = *v; 00624 return; 00625 } 00626 00627 clear(); 00628 00629 typ = v->type(); 00630 val = v->val; 00631 00632 v->typ = Empty; 00633 } 00634 00635 bool KSValue::operator==( const KSValue& v ) const 00636 { 00637 return ( val.ptr == v.val.ptr && typ == v.typ ); 00638 } 00639 00640 bool KSValue::cmp( const KSValue& v ) const 00641 { 00642 if ( typ != v.typ ) 00643 return false; 00644 00645 switch( typ ) 00646 { 00647 case Empty: 00648 return true; 00649 case StringType: 00650 return ( stringValue() == v.stringValue() ); 00651 case DateType: 00652 return ( dateValue() == v.dateValue() ); 00653 case TimeType: 00654 return ( timeValue() == v.timeValue() ); 00655 case KSValue::IntType: 00656 return ( val.i == v.val.i ); 00657 case BoolType: 00658 return ( val.b == v.val.b ); 00659 case DoubleType: 00660 return ( val.d == v.val.d ); 00661 case ListType: 00662 return ( listValue() == v.listValue() ); 00663 case MapType: 00664 { 00665 QMap<QString,KSValue::Ptr>::ConstIterator it, it2, end, end2; 00666 it = mapValue().begin(); 00667 it2 = v.mapValue().begin(); 00668 end = mapValue().end(); 00669 end2 = v.mapValue().end(); 00670 while( it != end && it2 != end2 ) 00671 { 00672 if ( it.key() != it2.key() || !it2.data()->cmp( *it.data() ) ) 00673 return false; 00674 ++it; 00675 ++it2; 00676 } 00677 return ( it == end && it2 == end2 ); 00678 } 00679 case CharType: 00680 return ( val.c == v.val.c ); 00681 case CharRefType: 00682 return ( ((KScript::Char)charRefValue()) == ((KScript::Char)v.charRefValue()) ); 00683 case FunctionType: 00684 case MethodType: 00685 case PropertyType: 00686 case ModuleType: 00687 case StructType: 00688 case StructClassType: 00689 return ( val.ptr == v.val.ptr ); 00690 case StructBuiltinMethodType: 00691 return ( val.sm == v.val.sm ); 00692 case NTypes: 00693 Q_ASSERT( 0 ); 00694 } 00695 00696 // Never reached 00697 return false; 00698 } 00699 00700 bool KSValue::implicitCast( Type _typ ) const 00701 { 00702 if ( typ == _typ ) 00703 return true; 00704 00705 switch( typ ) 00706 { 00707 case Empty: 00708 return false; 00709 case IntType: 00710 if ( _typ == BoolType ) 00711 return TRUE; 00712 if ( _typ == DoubleType ) 00713 return TRUE; 00714 return false; 00715 case BoolType: 00716 return FALSE; 00717 case DoubleType: 00718 if ( _typ == IntType ) 00719 return TRUE; 00720 if ( _typ == BoolType ) 00721 return TRUE; 00722 return false; 00723 case StringType: 00724 if ( _typ == BoolType ) 00725 return TRUE; 00726 return false; 00727 case CharRefType: 00728 if ( _typ == CharType ) 00729 return TRUE; 00730 case DateType: 00731 case TimeType: 00732 case PropertyType: 00733 case ListType: 00734 case MapType: 00735 case CharType: 00736 case FunctionType: 00737 case MethodType: 00738 case StructBuiltinMethodType: 00739 case StructType: 00740 case StructClassType: 00741 case ModuleType: 00742 // They can be casted to nothing 00743 return false; 00744 case NTypes: 00745 Q_ASSERT(0); 00746 break; 00747 } 00748 00749 return FALSE; 00750 }
KDE Logo
This file is part of the documentation for lib Library Version 1.3.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Sep 24 18:22:26 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003