koscript_value.cc
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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
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
00243 val.ptr = _value;
00244 }
00245
00246 void KSValue::setValue( KSMethod* _value )
00247 {
00248 clear();
00249 typ = MethodType;
00250
00251 val.ptr = _value;
00252 }
00253
00254 void KSValue::setValue( KSProperty* _value )
00255 {
00256 clear();
00257 typ = PropertyType;
00258
00259 val.ptr = _value;
00260 }
00261
00262 void KSValue::setValue( KSModule* _value )
00263 {
00264 clear();
00265 typ = ModuleType;
00266
00267 val.ptr = _value;
00268 }
00269
00270 void KSValue::setValue( KSStruct* _value )
00271 {
00272 clear();
00273 typ = StructType;
00274
00275 val.ptr = _value;
00276 }
00277
00278 void KSValue::setValue( KSStructClass* _value )
00279 {
00280 clear();
00281 typ = StructClassType;
00282
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
00465
00466
00467
00468
00469
00470
00471
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
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
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
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
00743 return false;
00744 case NTypes:
00745 Q_ASSERT(0);
00746 break;
00747 }
00748
00749 return FALSE;
00750 }
This file is part of the documentation for lib Library Version 1.3.5.