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 }