root/src/Parser/variable.cpp

Revision 196, 35.9 kB (checked in by hak, 1 year ago)

09/14/08 Ver.0.91.0.137 checked in.
- Added OSX/GCC support!!
- Can compile in XCode 3.1/GCC 4.0.1 & Visual Studio 2005.
- Runs in OSX 10.5.4 & Windows XP/Vista
- Number::toString support a radix.
- BRFALSE bug fix
- Minor code clean up

Line 
1 /****************************************************************************
2  *
3  * CRI Middleware SDK
4  *
5  * Copyright (c) 2008 CRI Middleware, Inc. All rights reserved.
6  *
7  * Use, modification and distribution are subject to the CRI Script Software
8  * License, Version 1.0(see accompanying file "CriScript_License_1_0.txt" or
9  * copy at www.criscript.com/trac/wiki/CRI%20Script%20Software%20License%201.0 ).
10  *
11  *
12  * Library  : CRIScript
13  * Module   : cil Virtual Machine/CodeGen
14  * File     : Variable.cpp
15  * Date     :
16  * Version  :
17  *
18  ****************************************************************************/
19
20 /***************************************************************************
21  *      Include file
22  ***************************************************************************/
23 #include "stdafx.h"
24 #include "criScript.h"
25 namespace cri {
26 /***************************************************************************
27  *      Variables
28  ***************************************************************************/
29
30 /***************************************************************************
31  *      Methods
32  ***************************************************************************/
33
34 /***************************************************************************
35  *      CVariable::ctor
36  ***************************************************************************/
37 CVariable::CVariable() : iOperandType(OPERAND_UNDEFINED), iOperandFlag( OPERAND_FLAG_NONE ), i64Value( 0 ),
38                                                                 ridConstraintType( 0 )
39
40 {
41 };
42
43 CVariable::CVariable( const int32_t i )// : i64Value(0)
44 {
45 #ifdef WIN32
46         //Assuming bitfield layout is contiguous in memory
47         iPrameters = OPERAND_INT;
48 #else
49         iOperandType = OPERAND_INT;
50         iOperandFlag = OPERAND_FLAG_NONE;
51         ridConstraintType = 0;
52 #endif
53         iValue = i;
54 };
55
56 CVariable::CVariable( const int64_t i )
57 {
58 #ifdef WIN32
59         //Assuming bitfield layout is contiguous in memory
60         iPrameters = OPERAND_INT64;
61 #else
62         iOperandType = OPERAND_INT64;
63         iOperandFlag = OPERAND_FLAG_NONE;
64         ridConstraintType = 0;
65 #endif
66         i64Value = i;
67 };
68
69 CVariable::CVariable( const float f )// : i64Value(0)
70 {
71 #ifdef WIN32
72         //Assuming bitfield layout is contiguous in memory
73         iPrameters = OPERAND_FLOAT;
74 #else
75         iOperandType = OPERAND_FLOAT;
76         iOperandFlag = OPERAND_FLAG_NONE;
77         ridConstraintType = 0;
78 #endif
79         fValue = f;
80 };
81        
82 CVariable::CVariable( const double d )
83 {
84 #ifdef WIN32
85         //Assuming bitfield layout is contiguous in memory
86         iPrameters = OPERAND_DOUBLE;
87 #else
88         iOperandType = OPERAND_DOUBLE;
89         iOperandFlag = OPERAND_FLAG_NONE;
90         ridConstraintType = 0;
91 #endif
92         dValue = d;
93 };
94
95 CVariable::CVariable( const VMOBJECTREF ref )// : i64Value(0)
96 {
97 #ifdef WIN32
98         //Assuming bitfield layout is contiguous in memory
99         iPrameters = OPERAND_OBJECTREF;
100 #else
101         iOperandType = OPERAND_OBJECTREF;
102         iOperandFlag = OPERAND_FLAG_NONE;
103         ridConstraintType = 0;
104 #endif
105         refObject = ref;
106         if( refObject )
107                 refObject->addRef();
108 };
109
110 CVariable::CVariable( wstring* const p )// : i64Value(0)
111 {
112 #ifdef WIN32
113         //Assuming bitfield layout is contiguous in memory
114         iPrameters = OPERAND_STRING;
115 #else
116         iOperandType = OPERAND_STRING;
117         iOperandFlag = OPERAND_FLAG_NONE;
118         ridConstraintType = 0;
119 #endif
120         pString = new wstring( p->data(), p->length() );
121 };
122
123 CVariable::CVariable( const bool b )// : i64Value(0)
124 {
125 #ifdef WIN32
126         //Assuming bitfield layout is contiguous in memory
127         iPrameters = OPERAND_BOOLEAN;
128 #else
129         iOperandType = OPERAND_BOOLEAN;
130         iOperandFlag = OPERAND_FLAG_NONE;
131         ridConstraintType = 0;
132 #endif
133         iValue = int32_t(b);
134 };
135
136 CVariable::CVariable( const wchar_t * const p )// : i64Value(0)
137 {
138 #ifdef WIN32
139         //Assuming bitfield layout is contiguous in memory
140         iPrameters = OPERAND_STRING;
141 #else
142         iOperandType = OPERAND_STRING;
143         iOperandFlag = OPERAND_FLAG_NONE;
144         ridConstraintType = 0;
145 #endif
146         pString = new wstring( p );
147 };
148
149 CVariable::CVariable( const int32_t i, const OPERAND_FLAG flag )// : i64Value(0)
150 {
151 #ifdef WIN32
152         //Assuming bitfield layout is contiguous in memory
153         iPrameters = OPERAND_INT;
154 #else
155         iOperandType = OPERAND_INT;
156         ridConstraintType = 0;
157 #endif
158         iOperandFlag = flag;
159         iValue = i;
160 };
161
162 CVariable::CVariable( const float f, const OPERAND_FLAG flag )// : i64Value(0)
163 {
164 #ifdef WIN32
165         //Assuming bitfield layout is contiguous in memory
166         iPrameters = OPERAND_FLOAT;
167 #else
168         iOperandType = OPERAND_FLOAT;
169         ridConstraintType = 0;
170 #endif
171         iOperandFlag = flag;
172         fValue = f;
173 };
174
175 CVariable::CVariable( const double d, const OPERAND_FLAG flag )
176 {
177 #ifdef WIN32
178         //Assuming bitfield layout is contiguous in memory
179         iPrameters = OPERAND_DOUBLE;
180 #else
181         iOperandType = OPERAND_DOUBLE ;
182         ridConstraintType = 0;
183 #endif
184         iOperandFlag = flag;
185         dValue = d;
186 };
187
188 CVariable::CVariable( const VMOBJECTREF ref, const OPERAND_FLAG flag )// : i64Value(0)
189 {
190 #ifdef WIN32
191         //Assuming bitfield layout is contiguous in memory
192         iPrameters = OPERAND_OBJECTREF;
193 #else
194         iOperandType = OPERAND_OBJECTREF;
195         ridConstraintType = 0;
196 #endif
197         iOperandFlag = flag;
198         refObject = ref;
199         if( refObject )
200                 refObject->addRef();
201 };
202
203 CVariable::CVariable( wstring* const p, const OPERAND_FLAG flag )// : i64Value(0)
204 {
205 #ifdef WIN32
206         //Assuming bitfield layout is contiguous in memory
207         iPrameters = OPERAND_STRING;
208 #else
209         iOperandType = OPERAND_STRING;
210         ridConstraintType = 0;
211 #endif
212         iOperandFlag = flag;
213         pString = new wstring( p->data(), p->length() );
214 };
215
216 CVariable::CVariable( const bool b, const OPERAND_FLAG flag )// : i64Value(0)
217 {
218 #ifdef WIN32
219         //Assuming bitfield layout is contiguous in memory
220         iPrameters = OPERAND_BOOLEAN;
221 #else
222         iOperandType = OPERAND_BOOLEAN;
223         ridConstraintType = 0;
224 #endif
225         iOperandFlag = flag;
226         bValue = b;
227 };
228
229 CVariable::CVariable( const wchar_t * const p, const OPERAND_FLAG flag )// : i64Value(0)
230 {
231 #ifdef WIN32
232         //Assuming bitfield layout is contiguous in memory
233         iPrameters = OPERAND_STRING;
234 #else
235         iOperandType = OPERAND_STRING;
236         ridConstraintType = 0;
237 #endif
238         iOperandFlag = flag;
239         pString = new wstring( p );
240 };
241
242 CVariable::CVariable( const OPERAND_FLAG flag )// : i64Value(0)
243 {
244 #ifdef WIN32
245         //Assuming bitfield layout is contiguous in memory
246         iPrameters = OPERAND_UNDEFINED;
247 #else
248         iOperandType = OPERAND_UNDEFINED;
249         ridConstraintType = 0;
250 #endif
251         iOperandFlag = flag ;
252 };
253        
254 /***************************************************************************
255  *      CVariable::setFlag
256  ***************************************************************************/
257 void CVariable::setFlag( const OPERAND_FLAG flag )
258 {
259         iOperandFlag = flag;
260 }
261
262 /***************************************************************************
263  *      CVariable::Copy ctor
264  ***************************************************************************/
265 CVariable::CVariable( const CVariable& right )
266 {
267         //iOperandType = right.iOperandType;
268         //iOperandFlag = right.iOperandFlag;
269         //ridConstraintType = right.ridConstraintType;
270         iPrameters = right.iPrameters;
271
272         //If already keeping a object ref...
273         switch( OperandType( iOperandType ) )
274         {
275         case OPERAND_OBJECTREF:
276                 //i64Value = 0;
277                 refObject = right.refObject;
278                 if( refObject )
279                 {
280                         assert( refObject->getRefCount() );
281                         refObject->addRef();
282                 }break;
283         case OPERAND_STRING:
284                 //i64Value = 0;
285                 pString = new wstring( *right.pString );
286                 break;
287         case OPERAND_INT64:
288         case OPERAND_UNSIGNEDINT64:
289         case OPERAND_DOUBLE:
290         default:
291                 i64Value = right.i64Value;
292                 break;
293         }
294 };
295
296 /***************************************************************************
297  *      CVariable::Operator=
298  ***************************************************************************/
299 CVariable& CVariable::operator=( const CVariable& right )
300 {
301         //Check if the variable is READONLY
302         if( iOperandFlag & OPERAND_FLAG_READONLY )
303                 return *this;
304
305         if( OperandType( right.iOperandType ) == OPERAND_SYSTEM_DELETION )
306         {
307                 if( iOperandFlag & OPERAND_FLAG_DONTDELETE )
308                         return *this;
309                 else
310                 {
311                         //If already keeping a object ref...
312                         switch( OperandType( iOperandType ) )
313                         {
314                         case OPERAND_OBJECTREF:
315                                 if( refObject )
316                                         refObject->release();
317                                 break;
318                         case OPERAND_STRING:
319                                 delete pString; //Delete old string
320                                 break;
321                         default:
322                                 break;
323                         }
324                         iOperandType = OPERAND_UNDEFINED;
325                         iOperandFlag = OPERAND_FLAG_DONTENUM;
326                         return *this;
327                 }
328         }
329
330         //If this already keeps an object ref...
331         switch( OperandType( iOperandType ) )
332         {
333         case OPERAND_OBJECTREF:
334                 if( refObject )
335                         refObject->release();
336                 break;
337         case OPERAND_STRING:
338                 delete pString; //Delete old string
339                 break;
340         default:
341                 break;
342         }
343
344         //iOperandType = (OPERAND_TYPE)right.iOperandType;
345         //iOperandFlag = right.iOperandFlag;
346         iPrameters = right.iPrameters;
347
348         switch( OperandType( right.iOperandType ) )
349         {
350         case OPERAND_OBJECTREF:
351                 refObject = right.refObject;
352                 //ridConstraintType = right.ridConstraintType;
353                 if( refObject )
354                 {
355                         refObject->addRef();
356                 }
357                 break;
358         case OPERAND_STRING:
359                 pString = new wstring( *right.pString );
360                 break;
361         case OPERAND_DOUBLE:
362         case OPERAND_INT64:
363         case OPERAND_UNSIGNEDINT64:
364                 i64Value = right.i64Value;
365                 break;
366         default:
367                 iValue = right.iValue;
368                 break;
369         }
370
371         return *this;
372 }
373
374 /***************************************************************************
375  *      CVariable::moveTo
376  *              Copy a pointer/ref without tweaking ref count,
377  ***************************************************************************/
378 void CVariable::moveTo( CVariable& dest )
379 {
380         //Check if the variable is READONLY
381         if( dest.iOperandFlag & OPERAND_FLAG_READONLY )
382                 return;
383
384         uint32_t iOperand = OperandType( iOperandType );
385         switch( iOperand )
386         {
387         case OPERAND_SYSTEM_DELETION:
388                 if( dest.iOperandFlag & OPERAND_FLAG_DONTDELETE )
389                         return;
390                 else
391                 {
392                         dest.iOperandType = OPERAND_UNDEFINED;
393                         dest.iOperandFlag = OPERAND_FLAG_DONTENUM;
394                 }
395                 break;
396         case OPERAND_STRING:
397                 dest.iOperandType = (OPERAND_TYPE)iOperand;
398                 dest.pString = pString;
399                 pString = NULL; //Clear original pointer not to be deleted
400                 break;
401         case OPERAND_OBJECTREF:
402                 dest.iOperandType = (OPERAND_TYPE)iOperand;
403                
404                 //Should not override restrict type
405                 //dest.ridConstraintType = ridConstraintType;
406                 
407                 //Does not want to invoke Copy ctor     
408                 dest.iValue = iValue;
409                 assert( dest.refObject->getRefCount() );
410                 refObject = NULL;       //Clear original pointer not to be deleted
411                 break;
412         default:
413                 dest.iOperandType = (OPERAND_TYPE)iOperand;
414                 dest.i64Value = i64Value;
415                 break;
416         }
417 }
418
419 /***************************************************************************
420  *      CVariable::moveToWithFlags
421  *              Copy a pointer/ref without tweaking ref count,
422  ***************************************************************************/
423 void CVariable::moveToWithFlags( CVariable& dest )
424 {
425         //Check if the variable is READONLY
426         if( dest.iOperandFlag & OPERAND_FLAG_READONLY )
427                 return;
428
429         uint32_t iOperand = OperandType( iOperandType );
430         switch( iOperand )
431         {
432         case OPERAND_SYSTEM_DELETION:
433                 if( dest.iOperandFlag & OPERAND_FLAG_DONTDELETE )
434                         return;
435                 else
436                 {
437                         dest.iOperandType = OPERAND_UNDEFINED;
438                         dest.iOperandFlag = OPERAND_FLAG_DONTENUM;
439                 }
440                 break;
441         case OPERAND_STRING:
442                 dest.iPrameters = iPrameters;
443                 dest.pString = pString;
444                 pString = NULL; //Clear original pointer not to be deleted
445                 break;
446         case OPERAND_OBJECTREF:
447                 dest.iOperandType = (OPERAND_TYPE)iOperand;
448                 dest.iOperandFlag = iOperandFlag;
449                
450                 //Should not override restrict type
451                 //dest.ridConstraintType = ridConstraintType;
452                 
453                 //Does not want to invoke Copy ctor     
454                 dest.iValue = iValue;
455                 assert( dest.refObject->getRefCount() );
456                 refObject = NULL;       //Clear original pointer not to be deleted
457                 break;
458         case OPERAND_DOUBLE:
459         case OPERAND_INT64:
460         case OPERAND_UNSIGNEDINT64:
461                 dest.iPrameters = iPrameters;
462                 dest.i64Value = i64Value;
463                 break;
464         default:
465                 dest.iPrameters = iPrameters;
466                 dest.iValue = iValue;
467                 break;
468         }
469 }
470
471 /***************************************************************************
472  *      CVariable::SetObject reference and increment ref count
473  ***************************************************************************/
474 void CVariable::setObjectRef( const VMOBJECTREF obj )
475 {
476         //Check if the variable is READONLY
477         if( iOperandFlag & OPERAND_FLAG_READONLY )
478                 return;
479
480         //If already keeping a object ref...
481         switch( OperandType( iOperandType ) )
482         {
483         case OPERAND_OBJECTREF:
484                 if( refObject )
485                         refObject->release();
486                 break;
487         case OPERAND_STRING:
488                 delete pString; //Delete old string
489                 break;
490         default:
491                 break;
492         }
493
494 #ifdef WIN32
495         //Assuming bitfield layout is contiguous in memory
496         iPrameters = OPERAND_OBJECTREF;
497 #else
498         iOperandType = OPERAND_OBJECTREF;
499         iOperandFlag = OPERAND_FLAG_NONE;
500         ridConstraintType = 0;
501 #endif
502         refObject = obj;
503         refObject->addRef();
504 }
505
506 /***************************************************************************
507  *      CVariable::setObjectRefWithFlags reference and increment ref count
508  ***************************************************************************/
509 void CVariable::setObjectRefWithFlags( const VMOBJECTREF obj, const OPERAND_FLAG flag, const RID ridConstraint )
510 {
511         //Check if the variable is READONLY
512         if( iOperandFlag & OPERAND_FLAG_READONLY )
513                 return;
514
515         //If already keeping a object ref...
516         switch( OperandType( iOperandType ) )
517         {
518         case OPERAND_OBJECTREF:
519                 if( refObject )
520                         refObject->release();
521                 break;
522         case OPERAND_STRING:
523                 delete pString; //Delete old string
524                 break;
525         default:
526                 break;
527         }
528
529         iOperandType = OPERAND_OBJECTREF;
530         iOperandFlag = flag;
531         ridConstraintType = ridConstraint;
532         refObject = obj;
533         refObject->addRef();
534 }
535
536 /***************************************************************************
537  *      CVariable::setString set string value to the variable
538  ***************************************************************************/
539 void CVariable::setString( const wstring& str )
540 {
541         //Check if the variable is READONLY
542         if( iOperandFlag & OPERAND_FLAG_READONLY )
543                 return;
544
545         switch( OperandType( iOperandType ) )
546         {
547         case OPERAND_OBJECTREF:
548                 //If already keeping a object ref...
549                 if( refObject )
550                         refObject->release();
551                 break;
552         case OPERAND_STRING:
553                 delete pString;
554                 break;
555         default:
556                 break;
557         }
558 #ifdef WIN32
559         //Assuming bitfield layout is contiguous in memory
560         iPrameters = OPERAND_STRING;
561 #else
562         iOperandType = OPERAND_STRING;
563         iOperandFlag = OPERAND_FLAG_NONE;
564 #endif
565         pString = new wstring( str );
566
567 }
568
569 /***************************************************************************
570  *      CVariable::setInt set integer value to the variable
571  ***************************************************************************/
572 void CVariable::setInt( const int32_t i )
573 {
574         //Check if the variable is READONLY
575         if( iOperandFlag & OPERAND_FLAG_READONLY )
576                 return;
577
578         switch( OperandType( iOperandType ) )
579         {
580         case OPERAND_OBJECTREF:
581                 //If already keeping a object ref...
582                 if( refObject )
583                         refObject->release();
584                 break;
585         case OPERAND_STRING:
586                 delete pString;
587                 break;
588         default:
589                 break;
590         }
591 #ifdef WIN32
592         //Assuming bitfield layout is contiguous in memory
593         iPrameters = OPERAND_INT;
594 #else
595         iOperandType = OPERAND_INT;
596         iOperandFlag = OPERAND_FLAG_NONE;
597 #endif
598         iValue = i;
599 }
600
601 /***************************************************************************
602  *      CVariable::setInt64 set Integer value to the variable
603  ***************************************************************************/
604 void CVariable::setInt64( const int64_t i64 )
605 {
606         //Check if the variable is READONLY
607         if( iOperandFlag & OPERAND_FLAG_READONLY )
608                 return;
609
610         switch( OperandType( iOperandType ) )
611         {
612         case OPERAND_OBJECTREF:
613                 //If already keeping a object ref...
614                 if( refObject )
615                         refObject->release();
616                 break;
617         case OPERAND_STRING:
618                 delete pString;
619                 break;
620         default:
621                 break;
622         }
623 #ifdef WIN32
624         //Assuming bitfield layout is contiguous in memory
625         iPrameters = OPERAND_INT64;
626 #else
627         iOperandType = OPERAND_INT64;
628         iOperandFlag = OPERAND_FLAG_NONE;
629 #endif
630         i64Value = i64;
631 }
632
633 /***************************************************************************
634  *      CVariable::setFloat set Integer value to the variable
635  ***************************************************************************/
636 void CVariable::setFloat( const float f )
637 {
638         //Check if the variable is READONLY
639         if( iOperandFlag & OPERAND_FLAG_READONLY )
640                 return;
641
642         switch( OperandType( iOperandType ) )
643         {
644         case OPERAND_OBJECTREF:
645                 //If already keeping a object ref...
646                 if( refObject )
647                         refObject->release();
648                 break;
649         case OPERAND_STRING:
650                 delete pString;
651                 break;
652         default:
653                 break;
654         }
655 #ifdef WIN32
656         //Assuming bitfield layout is contiguous in memory
657         iPrameters = OPERAND_FLOAT;
658 #else
659         iOperandType = OPERAND_FLOAT;
660         iOperandFlag = OPERAND_FLAG_NONE;
661 #endif
662         fValue = f;
663 }
664
665 /***************************************************************************
666  *      CVariable::setDouble set Double value to the variable
667  ***************************************************************************/
668 void CVariable::setDouble( const double d )
669 {
670         //Check if the variable is READONLY
671         if( iOperandFlag & OPERAND_FLAG_READONLY )
672                 return;
673
674         switch( OperandType( iOperandType ) )
675         {
676         case OPERAND_OBJECTREF:
677                 //If already keeping a object ref...
678                 if( refObject )
679                         refObject->release();
680                 break;
681         case OPERAND_STRING:
682                 delete pString;
683                 break;
684         default:
685                 break;
686         }
687 #ifdef WIN32
688         //Assuming bitfield layout is contiguous in memory
689         iPrameters = OPERAND_DOUBLE;
690 #else
691         iOperandType = OPERAND_DOUBLE;
692         iOperandFlag = OPERAND_FLAG_NONE;
693 #endif
694         dValue = d;
695 }
696
697 /***************************************************************************
698  *      CVariable::setStringPointer set string value to the variable
699  ***************************************************************************/
700 void CVariable::setStringPointer( wstring* pstr )
701 {
702         //Check if the variable is READONLY
703         if( iOperandFlag & OPERAND_FLAG_READONLY )
704                 return;
705
706         switch( OperandType( iOperandType ) )
707         {
708         case OPERAND_OBJECTREF:
709                 //If already keeping a object ref...
710                 if( refObject )
711                         refObject->release();
712                 break;
713         case OPERAND_STRING:
714                 delete pString;
715                 break;
716         default:
717                 break;
718         }
719 #ifdef WIN32
720         //Assuming bitfield layout is contiguous in memory
721         iPrameters = OPERAND_STRING;
722 #else
723         iOperandType = OPERAND_STRING;
724         iOperandFlag = OPERAND_FLAG_NONE;
725 #endif
726         pString = pstr;
727 }
728
729 /***************************************************************************
730  *      CVariable::dtor
731  ***************************************************************************/
732 CVariable::~CVariable()
733 {
734         switch( OperandType( iOperandType ) )
735         {
736         case OPERAND_OBJECTREF:
737                 //Release an object if referenced
738                 if( refObject )
739                 {
740                         refObject->release();
741                         //if( !refObject->release() )
742                         //      delete refObject;
743                         refObject = NULL;
744                 }
745                 break;
746         case OPERAND_STRING:
747                 delete pString; //Delete old string
748                 pString = NULL;
749                 break;
750         default:
751                 break;
752         }
753 };
754
755 /***************************************************************************
756  *      CVariable::toString
757  ***************************************************************************/
758 wstring* CVariable::toString( CCilVm* pVm )
759 {
760         CVariable var = *this;
761         var.convertToString( pVm, 10 );
762         wstring* pString = var.pString;
763         var.pString = NULL;
764         return pString;
765 }
766
767 /***************************************************************************
768  *      CVariable::toString
769  ***************************************************************************/
770 wstring* CVariable::toString( CCilVm* pVm, int32_t iRadix )
771 {
772         CVariable var = *this;
773         var.convertToString( pVm, iRadix );
774         wstring* pString = var.pString;
775         var.pString = NULL;
776         return pString;
777 }
778
779 /***************************************************************************
780  *      CVariable::convertToString
781  ***************************************************************************/
782 void CVariable::convertToString( CCilVm* pVm )
783 {
784         convertToString( pVm, 10 );
785 }
786
787 /***************************************************************************
788  *      CVariable::convertToString
789  ***************************************************************************/
790 void CVariable::convertToString( CCilVm* pVm, const int iRadix )
791 {
792         assert( pVm );
793         assert( iRadix );
794         assert( iRadix <=16 );
795
796         const wchar_t tableChar[] = {
797                 L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
798                 L'8', L'9', L'a', L'b', L'c', L'd', L'e', L'f',
799         };
800
801         wstring* pTmpString;
802         int64_t i64Tmp;
803         int32_t iIndex;
804         float fIndex;
805         double dIndex;
806         int32_t iPrecision = 0;
807
808         switch( OperandType( iOperandType ) )
809         {
810                 case OPERAND_INT:
811                 case OPERAND_UNSIGNEDINT:
812                         pTmpString = new wstring();
813                         if( iValue < 0 )
814                         {
815                                 pTmpString->append( L"-" );
816                                 iValue = -iValue;
817                         }
818                         iIndex = (int32_t)pTmpString->size();
819                         while( iValue )
820                         {
821                                 pTmpString->insert( iIndex, &tableChar[ iValue % iRadix ], 1 );
822                                 iValue = iValue / iRadix;
823                         }
824                        
825                         if( !pTmpString->length() ) pTmpString->append( L"0" );
826                         pString = pTmpString;
827                         break;
828                 case OPERAND_INT64:
829                 case OPERAND_UNSIGNEDINT64:
830                         pTmpString = new wstring();
831                         if( i64Value < 0 )
832                         {
833                                 pTmpString->append( L"-" );
834                                 i64Value = -i64Value;
835                         }
836                         iIndex = (int32_t)pTmpString->size();
837                         while( i64Value )
838                         {
839                                 pTmpString->insert( iIndex, &tableChar[ i64Value % iRadix ], 1 );
840                                 i64Value = i64Value / iRadix;
841                         }
842                         if( !pTmpString->length() ) pTmpString->append( L"0" );
843                         pString = pTmpString;
844                         break;
845                 case OPERAND_FLOAT:
846                         if( !_finite( fValue ) )
847                         {
848                                 if( fValue < 0 )
849                                         pString = new wstring( STRING_INTERNAL_NEGATIVE_INFINITY );
850                                 else
851                                         pString = new wstring( STRING_INTERNAL_INFINITY );
852                                 break;
853                         }
854                         else if( fValue > LONG_LONG_MAX || fValue < LONG_LONG_MIN )
855                         {
856                                 //exponent
857                                 int32_t iExponent = static_cast<int32_t>(log10( fabs( fValue ) ));
858                                 double dMantissa = fValue / pow( 10.0, iExponent );
859                                 CVariable var( dMantissa );
860                                 pString = var.toString( pVm, iRadix );
861                                 pString->append( L"e" );
862                                 CVariable varExp( iExponent );
863                                 pTmpString = varExp.toString( pVm, iRadix );
864                                 pString->append( *pTmpString );
865                                 delete( pTmpString );
866                                 break;
867                         }
868                         else   
869                                 pTmpString = new wstring();
870                        
871                         if( fValue < 0 )
872                         {
873                                 pTmpString->append( L"-" );
874                                 fValue = -fValue;
875                         }
876                         iIndex = static_cast<int32_t>(pTmpString->size());
877                         i64Tmp = static_cast<int64_t>(floor( fValue ));
878                         if( !i64Tmp ) pTmpString->append( L"0" );
879                        
880                         while( i64Tmp )
881                         {
882                                 pTmpString->insert( iIndex, &tableChar[ i64Tmp % iRadix ], 1 );
883                                 i64Tmp = i64Tmp / iRadix;
884                         }
885                         fValue = static_cast<float>(modf( fValue, &dIndex ));
886                         if( fValue ) pTmpString->append( L"." );
887                        
888                         while( fValue )
889                         {
890                                 fValue *= iRadix;
891                                 fValue = modff( fValue, &fIndex );
892                                 if( ++iPrecision >= TOSTRING_PRECISION_SINGLE )
893                                 {
894                                         pTmpString->append( &tableChar[ (int32_t)fIndex ], 1 );
895                                         if( fValue >= 5.f / iRadix )
896                                         {
897                                                 wstring::reverse_iterator itBegin = pTmpString->rbegin();
898                                                 wstring::reverse_iterator itEnd = pTmpString->rend();
899                                                 while( itBegin != itEnd )
900                                                 {
901                                                         if( *itBegin == L'.'  || *itBegin == L'-' )
902                                                         {
903                                                                 itBegin++;
904                                                                 continue;
905                                                         }
906                                                         if( *itBegin - L'0' + 1 < iRadix )
907                                                         {
908                                                                 *itBegin = (*itBegin)+1;
909                                                                 itBegin = itEnd;
910                                                         }
911                                                         else
912                                                         {
913                                                                 pTmpString = &pTmpString->erase( pTmpString->length() - 1, 1 );
914                                                                 itBegin = pTmpString->rbegin();
915                                                                 itEnd = pTmpString->rend();
916                                                         }
917                                                 }
918                                         }
919                                         fValue = 0;
920                                 }
921                                 else
922                                         pTmpString->append( &tableChar[ (int32_t)fIndex ], 1 );
923                         }
924                         cleanupFloatString( *pTmpString );
925                         pString = pTmpString;
926                         break;
927                 case OPERAND_DOUBLE:
928                         if( !_finite( dValue ) )
929                         {
930                                 if( fValue < 0 )
931                                         pString = new wstring( STRING_INTERNAL_NEGATIVE_INFINITY );
932                                 else
933                                         pString = new wstring( STRING_INTERNAL_INFINITY );
934                                 break;
935                         }
936                         else if( dValue > LONG_LONG_MAX || dValue < LONG_LONG_MIN )
937                         {
938                                 //exponent
939                                 int32_t iExponent = static_cast<int32_t>(log10( fabs( dValue ) ));
940                                 double dMantissa = dValue / pow( 10.0, iExponent );
941                                 CVariable var( dMantissa );
942                                 pString = var.toString( pVm, iRadix );
943                                 pString->append( L"e" );
944                                 CVariable varExp( iExponent );
945                                 pTmpString = varExp.toString( pVm, iRadix );
946                                 pString->append( *pTmpString );
947                                 delete( pTmpString );
948                                 break;
949                         }
950                         else
951                                 pTmpString = new wstring();
952
953                         if( dValue < 0 )
954                         {
955                                 pTmpString->append( L"-" );
956                                 dValue = -dValue;
957                         }
958                        
959                         iIndex = static_cast<int32_t>(pTmpString->size());
960
961                         i64Tmp = static_cast<int64_t>(floor( dValue ));
962                         if( !i64Tmp ) pTmpString->append( L"0" );
963
964                         while( i64Tmp )
965                         {
966                                 pTmpString->insert( iIndex, &tableChar[ i64Tmp % iRadix ], 1 );
967                                 i64Tmp = i64Tmp / iRadix;
968                         }
969                         dValue = modf( dValue, &dIndex );
970                         if( dValue ) pTmpString->append( L"." );
971                        
972                         while( dValue )
973                         {
974                                 dValue *= iRadix;
975                                 dValue = modf( dValue, &dIndex );
976                                 if( ++iPrecision >= TOSTRING_PRECISION_DOUBLE )
977                                 {
978                                         pTmpString->append( &tableChar[ (int32_t)dIndex ], 1 );
979                                         if( dValue >= 5.f / iRadix )
980                                         {
981                                                 wstring::reverse_iterator itBegin = pTmpString->rbegin();
982                                                 wstring::reverse_iterator itEnd = pTmpString->rend();
983                                                 while( itBegin != itEnd )
984                                                 {
985                                                         if( *itBegin == L'.'  || *itBegin == L'-' )
986                                                         {
987                                                                 itBegin++;
988                                                                 continue;
989                                                         }
990                                                         if( *itBegin - L'0' + 1 < iRadix )
991                                                         {
992                                                                 *itBegin = (*itBegin)+1;
993                                                                 itBegin = itEnd;
994                                                         }
995                                                         else
996                                                         {
997                                                                 pTmpString = &pTmpString->erase( pTmpString->length() - 1, 1 );
998                                                                 itBegin = pTmpString->rbegin();
999                                                                 itEnd = pTmpString->rend();
1000                                                         }
1001                                                 }
1002                                         }
1003                                         dValue = 0;
1004                                 }
1005                                 else
1006                                         pTmpString->append( &tableChar[ (int32_t)dIndex ], 1 );
1007                         }
1008                         cleanupFloatString( *pTmpString );
1009                         pString = pTmpString;
1010                         break;
1011                 case OPERAND_UNDEFINED:
1012                         pString = new wstring( STRING_INTERNAL_UNDEFINED );
1013                         break;
1014                 case OPERAND_NULL:
1015                         pString = new wstring( STRING_INTERNAL_NULL );
1016                         break;
1017                 case OPERAND_NAN:
1018                         pString = new wstring( STRING_INTERNAL_NAN );
1019                         break;
1020                 case OPERAND_STRING:
1021                         break;
1022                 case OPERAND_BOOLEAN:
1023                         switch( iValue )
1024                 {
1025                         case 0:
1026                                 pString = new wstring( STRING_INTERNAL_FALSE );
1027                                 break;
1028                         default:
1029                                 pString = new wstring( STRING_INTERNAL_TRUE );
1030                                 break;
1031                 }
1032                         break;
1033                 case OPERAND_OBJECTREF:
1034                 {
1035                         CVariable* pvar = refObject->lookupProperty( STRING_INTERNAL_TOSTRING );
1036                         if( pvar != NULL && OperandType( pvar->iOperandType ) == OPERAND_OBJECTREF )
1037                         {
1038                                 //call toString?
1039                                 //May push something to EvalStack, thus this pointer could be invalidated...
1040                                 CVariable* pResult = pVm->invokeMethod( pvar->refObject->getCall(),
1041                                                                                                            1,
1042                                                                                                            this );
1043                                 wstring* pConvertedString = new wstring();
1044                                 this->setStringPointer( pConvertedString );
1045                                
1046                                 if( pResult->iOperandType != OPERAND_STRING )
1047                                 {
1048                                        
1049                                 }
1050                                 else
1051                                         pConvertedString->append( *pResult->pString );
1052                                 delete( pResult );
1053                                 pString = pConvertedString;
1054                                 break;
1055                         }
1056                         else
1057                         {
1058                                 //No toString definition.
1059                                 //Just put the result of getValue
1060                                 pString = refObject->getValue().toString( pVm, iRadix );
1061                         }
1062                 }
1063                         break;
1064                 default:
1065                         Debug_Fatal( "Not implemented yet" );
1066                         break;
1067         }
1068         iOperandType = OPERAND_STRING;
1069         return;
1070 }
1071        
1072 /***************************************************************************
1073  *      CVariable::toInt
1074  ***************************************************************************/
1075 int32_t CVariable::toInt( void )
1076 {
1077         int32_t iRetValue;
1078         switch( OperandType( iOperandType ) )
1079         {
1080         case OPERAND_BOOLEAN:
1081                 iRetValue = (bValue != false);
1082                 break;
1083         case OPERAND_INT:
1084         case OPERAND_UNSIGNEDINT:
1085                 iRetValue = iValue;
1086                 break;
1087         case OPERAND_INT64:
1088         case OPERAND_UNSIGNEDINT64:
1089                 iRetValue = (int32_t)i64Value;
1090                 break;
1091         case OPERAND_FLOAT:
1092                 iRetValue = (int32_t)fValue;
1093                 break;
1094         case OPERAND_DOUBLE:
1095                 iRetValue = (int32_t)dValue;
1096                 break;
1097         case OPERAND_OBJECTREF:
1098                 iRetValue = (int32_t)refObject->getValue().toInt();
1099                 break;
1100         case OPERAND_UNDEFINED:
1101         case OPERAND_NULL:
1102         case OPERAND_NAN:
1103                 iRetValue = (int32_t)0;
1104                 break;
1105         case OPERAND_STRING:
1106                 if( pString )
1107                         iRetValue = _wtoi( pString->data() );
1108                 else
1109                         iRetValue = 0;
1110                 break;
1111         default:
1112                 Debug_Fatal( "Not implemented yet" );
1113                 break;
1114         }
1115         return iRetValue;
1116 }
1117
1118 /***************************************************************************
1119  *      CVariable::toBoolean
1120  *              ECMA262 9.2
1121  ***************************************************************************/
1122 bool CVariable::toBoolean( void )
1123 {
1124         bool bRetValue;
1125         switch( OperandType( iOperandType ) )
1126         {
1127         case OPERAND_BOOLEAN:
1128                 bRetValue = bValue;
1129                 break;
1130         case OPERAND_INT:
1131         case OPERAND_UNSIGNEDINT:
1132                 bRetValue = (iValue != 0 );
1133                 break;
1134         case OPERAND_INT64:
1135         case OPERAND_UNSIGNEDINT64:
1136                 bRetValue = (i64Value != 0 );
1137                 break;
1138         case OPERAND_FLOAT:
1139                 if( !_finite( fValue ) )
1140                         bRetValue = false;
1141                 else
1142                         bRetValue = (fValue != 0 );
1143                 break;
1144         case OPERAND_DOUBLE:
1145                 if( !_finite( fValue ) )
1146                         bRetValue = false;
1147                 else
1148                         bRetValue = (dValue != 0 );
1149                 break;
1150         case OPERAND_OBJECTREF:
1151                 bRetValue = false;
1152                 break;
1153         case OPERAND_UNDEFINED:
1154         case OPERAND_NULL:
1155                 bRetValue = false;
1156                 break;
1157         case OPERAND_STRING:
1158                 if( *pString == STRING_INTERNAL_TRUE )
1159                         bRetValue = true;
1160                 else if( *pString == STRING_INTERNAL_FALSE )
1161                         bRetValue = false;
1162                 else
1163                         bRetValue = ( _wtoi( pString->data() ) != 0 );
1164                 break;
1165         case OPERAND_NAN:
1166                 bRetValue = false;
1167                 break;
1168         default:
1169                 Debug_Fatal( "Not implemented yet" );
1170                 break;
1171         }
1172         return bRetValue;
1173 }
1174
1175 /***************************************************************************
1176  *      CVariable::toDouble
1177  ***************************************************************************/
1178 double CVariable::toDouble( void )
1179 {
1180         double retValue;
1181         switch( OperandType( iOperandType ) )
1182         {
1183         case OPERAND_BOOLEAN:
1184                 retValue = (double)bValue;
1185                 break;
1186         case OPERAND_INT:
1187         case OPERAND_UNSIGNEDINT:
1188                 retValue = (double)iValue;
1189                 break;
1190         case OPERAND_INT64:
1191         case OPERAND_UNSIGNEDINT64:
1192                 retValue = (double)i64Value;
1193                 break;
1194         case OPERAND_FLOAT:
1195                 retValue = (double)fValue;
1196                 break;
1197         case OPERAND_DOUBLE:
1198                 retValue = (double)dValue;
1199                 break;
1200         case OPERAND_OBJECTREF:
1201                 retValue = refObject->getValue().toDouble();
1202                 break;
1203         case OPERAND_UNDEFINED:
1204         case OPERAND_NULL:
1205         case OPERAND_NAN:
1206                 retValue = (double)0;
1207                 break;
1208         case OPERAND_STRING:
1209                 retValue = _wtof( pString->data() );
1210                 break;
1211         default:
1212                 Debug_Fatal( "Not implemented yet" );
1213                 break;
1214         }
1215         return retValue;
1216 }
1217
1218 /***************************************************************************
1219  *      CVariable::toFloat
1220  ***************************************************************************/
1221 float CVariable::toFloat( void )
1222 {
1223         float retValue;
1224         switch( OperandType( iOperandType ) )
1225         {
1226         case OPERAND_BOOLEAN:
1227                 retValue = (float)bValue;
1228                 break;
1229         case OPERAND_INT:
1230         case OPERAND_UNSIGNEDINT:
1231                 retValue = (float)iValue;
1232                 break;
1233         case OPERAND_INT64:
1234         case OPERAND_UNSIGNEDINT64:
1235                 retValue = (float)i64Value;
1236                 break;
1237         case OPERAND_FLOAT:
1238                 retValue = (float)fValue;
1239                 break;
1240         case OPERAND_DOUBLE:
1241                 retValue = (float)dValue;
1242                 break;
1243         case OPERAND_OBJECTREF:
1244                 retValue = refObject->getValue().toFloat();
1245                 break;
1246         case OPERAND_NAN:
1247                 //Extension
1248         case OPERAND_UNDEFINED:
1249         case OPERAND_NULL:
1250                 retValue = (float)0;
1251                 break;
1252         case OPERAND_STRING:
1253                 {
1254                 CVariable var;
1255                 CNumberObject::parseNumber( var, pString );
1256                 retValue = var.toFloat();
1257                 }
1258                 break;
1259         default:
1260                 Debug_Fatal( "Not implemented yet" );
1261                 break;
1262         }
1263         return retValue;
1264 }
1265
1266 /***************************************************************************
1267  *      CVariable::toInt64
1268  ***************************************************************************/
1269 int64_t CVariable::toInt64( void )
1270 {
1271         int64_t retValue;
1272         switch( OperandType( iOperandType ) )
1273         {
1274         case OPERAND_BOOLEAN:
1275                 retValue = (int64_t)bValue;
1276                 break;
1277         case OPERAND_INT:
1278         case OPERAND_UNSIGNEDINT:
1279                 retValue = (int64_t)iValue;
1280                 break;
1281         case OPERAND_INT64:
1282         case OPERAND_UNSIGNEDINT64:
1283                 retValue = (int64_t)i64Value;
1284                 break;
1285         case OPERAND_FLOAT:
1286                 retValue = (int64_t)fValue;
1287                 break;
1288         case OPERAND_DOUBLE:
1289                 retValue = (int64_t)dValue;
1290                 break;
1291         case OPERAND_OBJECTREF:
1292                 retValue = refObject->getValue().toInt64();
1293                 break;
1294         case OPERAND_UNDEFINED:
1295         case OPERAND_NULL:
1296         case OPERAND_NAN:
1297                 retValue = (int64_t)0;
1298                 break;
1299         case OPERAND_STRING:
1300                 retValue = _wtoi64( pString->data() );
1301                 break;
1302         default:
1303                 Debug_Fatal( "Not implemented yet" );
1304                 break;
1305         }
1306         return retValue;
1307 }
1308
1309 /***************************************************************************
1310  *      CVariable::getPrimitiveType
1311  ***************************************************************************/
1312 OPERAND_TYPE CVariable::getPrimitiveType( PRIMITIVETYPE_PREFERENCE prefferred )
1313 {
1314         RID rid;
1315         switch( prefferred )
1316         {
1317         default:
1318         case PRIMITIVETYPE_PREFERRED:
1319                 switch( OperandType( iOperandType ) )
1320                 {
1321                 case OPERAND_OBJECTREF:
1322                 {
1323                         //if( ridConstraintType )
1324                         //      rid = getConstraintRid();
1325                         //else
1326                         //      rid = refObject->getRID();
1327                         rid = refObject->getRID();
1328
1329                         if( rid == CCilVm::getBooleanObjectRID() )
1330                         {
1331                                 return OPERAND_BOOLEAN;
1332                         }
1333                         else if( rid == CCilVm::getNumberObjectRID() )
1334                         {
1335                                 return (OPERAND_TYPE)refObject->getValue().iOperandType;
1336                         }
1337                         else if( rid == CCilVm::getFunctionObjectRID() )
1338                         {
1339                                 return OPERAND_STRING;
1340                         }
1341                         return OPERAND_STRING;
1342                         break;
1343                 }
1344                 default:
1345                         return (OPERAND_TYPE)iOperandType;
1346                 }
1347                 break;
1348         case PRIMITIVETYPE_NUMBER:      //Can convert to number?
1349                 switch( OperandType( iOperandType ) )
1350                 {
1351                 case OPERAND_OBJECTREF:
1352                 {
1353                         //if( ridConstraintType )
1354                         //      rid = getConstraintRid();
1355                         //else
1356                         //      rid = refObject->getRID();
1357                         rid = refObject->getRID();
1358                         if(  TypeFromToken( rid ) == MDT_METHODDEF )
1359                         {
1360                                 return OPERAND_OBJECTREF;
1361                         } else if( rid == CCilVm::getBooleanObjectRID() )
1362                         {
1363                                 return OPERAND_BOOLEAN;
1364                         }
1365                         else if( rid == CCilVm::getNumberObjectRID() )
1366                         {
1367                                 return (OPERAND_TYPE)refObject->getValue().iOperandType;
1368                         }
1369                         else if( rid == CCilVm::getDateObjectRID() ||
1370                                 rid == CCilVm::getObjectRID() ||
1371                                 rid == CCilVm::getArrayObjectRID() ||
1372                                 rid == CCilVm::getFunctionObjectRID() ||
1373                                 rid == CCilVm::getErrorObjectRID() ||
1374                                 rid == CCilVm::getRegexObjectRID()
1375                                 )
1376                         {
1377                                 return OPERAND_OBJECTREF;
1378                         }
1379                         return OPERAND_STRING;
1380                         break;
1381                 }
1382                 default:
1383                         return (OPERAND_TYPE)iOperandType;
1384                 }
1385                 break;
1386         }
1387 }
1388
1389 /***************************************************************************
1390  *      CVariable::convertToPrimitiveType
1391  ***************************************************************************/
1392 void CVariable::convertToPrimitiveType( CCilVm* pVm )
1393 {
1394         switch( OperandType( iOperandType ) )
1395         {
1396         case OPERAND_OBJECTREF:
1397         {
1398                 RID rid = refObject->getRID();
1399                 if( rid == CCilVm::getBooleanObjectRID() )
1400                 {
1401                         bool b = refObject->getValue().toBoolean();
1402                         refObject->release();
1403                         bValue = b;
1404                         iOperandType = OPERAND_BOOLEAN;
1405                 }
1406                 else if( rid == CCilVm::getNumberObjectRID() )
1407                 {
1408                         //Dup it before it possiblly released..
1409                         CVariable var = refObject->getValue();
1410
1411                         refObject->release();
1412                         iOperandType = var.iOperandType;
1413                         i64Value = var.i64Value;
1414                 }
1415                 else if( rid == CCilVm::getStringObjectRID() )
1416                 {
1417                         convertToString( pVm );
1418                 }
1419                 break;
1420         }
1421         default:
1422                 break;
1423         }
1424 }
1425
1426 /***************************************************************************
1427  *      CVariable::cleanupFloatString, toString helper
1428  ***************************************************************************/
1429 void CVariable::cleanupFloatString( wstring& String )
1430 {
1431         if( String.find( L'.' ) != string::npos )
1432         {
1433                 while( *String.rbegin() == L'0' )
1434                 {
1435                         String.erase( String.end() -1, String.end() );
1436                 }
1437                 while( *String.rbegin() == L'.' )
1438                 {
1439                         String.erase( String.end() -1, String.end() );
1440                 }
1441                 //Replace infinity string
1442                 //For VisualStudio
1443                 //const wchar_t STRING_INTERNAL_INFINITY_TOBEREPLACED[] = L"1.#INF";
1444                 size_t iInfIndex = String.find( STRING_INTERNAL_INFINITY_TOBEREPLACED );
1445                 if( iInfIndex != string::npos )
1446                 {
1447                         String.replace( iInfIndex, sizeof( STRING_INTERNAL_INFINITY_TOBEREPLACED ) / sizeof( wchar_t ), STRING_INTERNAL_INFINITY );
1448                 }
1449         }
1450 }
1451
1452 /***************************************************************************
1453  *      CVariable::addObjectRef
1454  ***************************************************************************/
1455 void CVariable::addObjectRef()
1456 {
1457         assert( iOperandType == OPERAND_OBJECTREF );
1458         if( refObject )
1459         {
1460                 refObject->addRef();
1461         }
1462 }
1463
1464 /***************************************************************************
1465  *      CVariable::erase
1466  ***************************************************************************/
1467 void CVariable::erase()
1468 {
1469         switch( OperandType( iOperandType ) )
1470         {
1471         case OPERAND_OBJECTREF:
1472                 //Release an object if referenced
1473                 if( refObject )
1474                 {
1475                         refObject->release();
1476                         //if( !refObject->release() )
1477                         //      delete refObject;
1478                         //refObject = NULL;
1479                 }
1480                 break;
1481         case OPERAND_STRING:
1482                 delete pString; //Delete old string
1483                 //pString = NULL;
1484                 break;
1485         default:
1486                 break;
1487         }
1488         iValue = 0;
1489 }
1490
1491 } //namespace CRI       
Note: See TracBrowser for help on using the browser.