aboutsummaryrefslogtreecommitdiff
path: root/src/variable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/variable.cpp')
-rw-r--r--src/variable.cpp892
1 files changed, 892 insertions, 0 deletions
diff --git a/src/variable.cpp b/src/variable.cpp
new file mode 100644
index 0000000..99bac59
--- /dev/null
+++ b/src/variable.cpp
@@ -0,0 +1,892 @@
1#include "variable.h"
2#include "astleaf.h"
3#include "bu/sio.h"
4using Bu::sio;
5
6#include <stdlib.h>
7
8Variable::Variable() :
9 eType( typeNone )
10{
11 memset( &uVal, 0, sizeof(uVal) );
12}
13
14Variable::Variable( Type t ) :
15 eType( t )
16{
17 memset( &uVal, 0, sizeof(uVal) );
18 if( eType == typeString || eType == typeRef )
19 {
20 uVal.sVal = new Bu::FString;
21 }
22 else if( eType == typeList )
23 {
24 uVal.lVal = new VarList;
25 }
26}
27
28Variable::Variable( int iVal ) :
29 eType( typeInt )
30{
31 memset( &uVal, 0, sizeof(uVal) );
32 uVal.iVal = iVal;
33}
34
35Variable::Variable( double fVal ) :
36 eType( typeFloat )
37{
38 memset( &uVal, 0, sizeof(uVal) );
39 uVal.fVal = fVal;
40}
41
42Variable::Variable( bool bVal ) :
43 eType( typeBool )
44{
45 memset( &uVal, 0, sizeof(uVal) );
46 uVal.bVal = bVal;
47}
48
49Variable::Variable( const Bu::FString &sVal ) :
50 eType( typeString )
51{
52 memset( &uVal, 0, sizeof(uVal) );
53 uVal.sVal = new Bu::FString( sVal );
54}
55
56Variable::Variable( const char *sVal ) :
57 eType( typeString )
58{
59 memset( &uVal, 0, sizeof(uVal) );
60 uVal.sVal = new Bu::FString( sVal );
61}
62
63Variable::Variable( const Variable &v ) :
64 eType( v.eType )
65{
66 memset( &uVal, 0, sizeof(uVal) );
67 if( eType == typeString || eType == typeRef )
68 {
69 uVal.sVal = new Bu::FString( *v.uVal.sVal );
70 }
71 else if( eType == typeList )
72 {
73 uVal.lVal = new VarList( *v.uVal.lVal );
74 }
75 else
76 {
77 uVal = v.uVal;
78 }
79}
80
81Variable::Variable( const class AstLeaf &l )
82{
83 switch( l.getDataType() )
84 {
85 case AstNode::typeDataInt:
86 eType = typeInt;
87 uVal.iVal = l.getIntValue();
88 break;
89
90 case AstNode::typeDataFloat:
91 eType = typeFloat;
92 uVal.fVal = l.getFloatValue();
93 break;
94
95 case AstNode::typeDataBool:
96 eType = typeBool;
97 uVal.bVal = l.getBoolValue();
98 break;
99
100 case AstNode::typeDataString:
101 eType = typeString;
102 uVal.sVal = new Bu::FString( l.getStrValue() );
103 break;
104
105 case AstNode::typeDataNone:
106 eType = typeNone;
107 memset( &uVal, 0, sizeof(uVal) );
108 break;
109
110 default:
111 sio << "Unhandled type <<!>>" << sio.nl << sio.nl;
112 break;
113 }
114}
115
116Variable::Variable( const StrList &lst )
117{
118 if( lst.getSize() == 1 )
119 {
120 eType = typeString;
121 uVal.sVal = new Bu::FString( lst.first() );
122 }
123 else
124 {
125 eType = typeList;
126 uVal.lVal = new VarList();
127 for( StrList::const_iterator i = lst.begin(); i; i++ )
128 {
129 uVal.lVal->append( Variable( *i ) );
130 }
131 }
132}
133
134Variable::Variable( const VarList &lst )
135{
136 eType = typeList;
137 uVal.lVal = new VarList( lst );
138}
139
140Variable::~Variable()
141{
142 if( eType == typeString || eType == typeRef )
143 {
144 delete uVal.sVal;
145 }
146 else if( eType == typeList )
147 {
148 delete uVal.lVal;
149 }
150}
151
152Variable Variable::mkRef( const Bu::FString &sVal )
153{
154 Variable v( typeRef );
155 (*v.uVal.sVal) = sVal;
156 return v;
157}
158
159Variable::Type Variable::getType() const
160{
161 return eType;
162}
163
164int Variable::getInt() const
165{
166 if( eType != typeInt ) throw Bu::ExceptionBase("Wrong variable type.");
167 return uVal.iVal;
168}
169
170double Variable::getFloat() const
171{
172 if( eType != typeFloat ) throw Bu::ExceptionBase("Wrong variable type.");
173 return uVal.fVal;
174}
175
176bool Variable::getBool() const
177{
178 if( eType != typeBool ) throw Bu::ExceptionBase("Wrong variable type.");
179 return uVal.bVal;
180}
181
182const Bu::FString &Variable::getString() const
183{
184 if( eType != typeString && eType != typeRef ) throw Bu::ExceptionBase("Wrong variable type.");
185 return *uVal.sVal;
186}
187
188const VarList &Variable::getList() const
189{
190 if( eType != typeList ) throw Bu::ExceptionBase("Wrong variable type.");
191 return *uVal.lVal;
192}
193
194int Variable::toInt() const
195{
196 switch( eType )
197 {
198 case typeInt:
199 return uVal.iVal;
200
201 case typeFloat:
202 return (int)uVal.fVal;
203
204 case typeBool:
205 return (uVal.bVal)?(1):(0);
206
207 case typeString:
208 case typeRef:
209 return strtol( uVal.sVal->getStr(), NULL, 0 );
210
211 default:
212 return 0;
213 }
214 return 0;
215}
216
217double Variable::toFloat() const
218{
219 switch( eType )
220 {
221 case typeInt:
222 return (double)uVal.iVal;
223
224 case typeFloat:
225 return uVal.fVal;
226
227 case typeBool:
228 return (uVal.bVal)?(1.0):(0.0);
229
230 case typeString:
231 case typeRef:
232 return strtod( uVal.sVal->getStr(), NULL );
233
234 default:
235 return 0.0;
236 }
237 return 0.0;
238}
239
240bool Variable::toBool() const
241{
242 switch( eType )
243 {
244 case typeInt:
245 return uVal.iVal != 0;
246
247 case typeFloat:
248 return uVal.fVal != 0.0;
249
250 case typeBool:
251 return uVal.bVal;
252
253 case typeString:
254 case typeRef:
255 return (*uVal.sVal) == "true";
256
257 case typeList:
258 return !(*uVal.lVal).isEmpty();
259
260 default:
261 return false;
262 }
263 return false;
264}
265
266Bu::FString Variable::toString() const
267{
268 Bu::FString sRet;
269 switch( eType )
270 {
271 case typeNone:
272 // No type, no data, we return empty string
273 break;
274
275 case typeInt:
276 sRet.format("%d", uVal.iVal );
277 break;
278
279 case typeFloat:
280 sRet.format("%f", uVal.fVal );
281 break;
282
283 case typeBool:
284 sRet = (uVal.bVal)?("true"):("false");
285 break;
286
287 case typeString:
288 case typeRef:
289 sRet = *uVal.sVal;
290 break;
291
292 case typeList:
293 {
294 for( VarList::const_iterator i = uVal.lVal->begin(); i; i++ )
295 {
296 if( i != uVal.lVal->begin() )
297 sRet += " ";
298 sRet += (*i).toString();
299 }
300 }
301 break;
302
303 case typeVersion:
304 break;
305 }
306
307 return sRet;
308}
309
310VarList Variable::toList() const
311{
312 if( eType == typeList )
313 return *this;
314 return VarList( *this );
315}
316
317Variable Variable::toType( Type eNewType ) const
318{
319 switch( eNewType )
320 {
321 case typeNone:
322 return Variable();
323
324 case typeBool:
325 return Variable( toBool() );
326
327 case typeInt:
328 return Variable( toInt() );
329
330 case typeFloat:
331 return Variable( toFloat() );
332
333 case typeVersion:
334 return Variable();
335
336 case typeString:
337 return Variable( toString() );
338
339 case typeList:
340 return Variable( toList() );
341
342 case typeRef:
343 return Variable::mkRef( toString() );
344 }
345 throw Bu::ExceptionBase("Unhandled case in Variable toType");
346}
347
348void Variable::append( const Variable &v )
349{
350 if( eType != typeList ) throw Bu::ExceptionBase("Wrong variable type.");
351
352 if( v.eType == typeList )
353 {
354 uVal.lVal->append( *v.uVal.lVal );
355 }
356 else
357 {
358 uVal.lVal->append( v );
359 }
360}
361
362VarList::iterator Variable::begin()
363{
364 if( eType != typeList ) throw Bu::ExceptionBase("Wrong variable type.");
365
366 return uVal.lVal->begin();
367}
368
369VarList::const_iterator Variable::begin() const
370{
371 if( eType != typeList ) throw Bu::ExceptionBase("Wrong variable type.");
372
373 return const_cast<const VarList *>(uVal.lVal)->begin();
374}
375
376void Variable::doNegate()
377{
378 switch( eType )
379 {
380 case typeNone:
381 break;
382
383 case typeBool:
384 throw Bu::ExceptionBase("You cannot negate boolean values.");
385
386 case typeInt:
387 uVal.iVal = -uVal.iVal;
388 break;
389
390 case typeFloat:
391 uVal.fVal = -uVal.fVal;
392 break;
393
394 case typeVersion:
395 throw Bu::ExceptionBase("You cannot negate version values.");
396
397 case typeString:
398 throw Bu::ExceptionBase("You cannot negate string values.");
399
400 case typeList:
401 throw Bu::ExceptionBase("You cannot negate list values.");
402
403 case typeRef:
404 throw Bu::ExceptionBase("You cannot negate reference values.");
405 }
406}
407
408void Variable::doNot()
409{
410 bool bVal = !toBool();
411 reset( typeBool );
412 uVal.bVal = bVal;
413}
414
415const Variable &Variable::operator=( const Variable &rhs )
416{
417 reset( rhs.eType );
418 if( rhs.eType == typeString || rhs.eType == typeRef )
419 {
420 uVal.sVal = new Bu::FString( *rhs.uVal.sVal );
421 }
422 else if( rhs.eType == typeList )
423 {
424 uVal.lVal = new VarList( *rhs.uVal.lVal );
425 }
426 else
427 {
428 uVal = rhs.uVal;
429 }
430
431 return *this;
432}
433
434const Variable &Variable::operator=( const int &rhs )
435{
436 reset( typeInt );
437 uVal.iVal = rhs;
438
439 return *this;
440}
441
442const Variable &Variable::operator=( const double &rhs )
443{
444 reset( typeFloat );
445 uVal.fVal = rhs;
446
447 return *this;
448}
449
450const Variable &Variable::operator=( const bool &rhs )
451{
452 reset( typeBool );
453 uVal.bVal = rhs;
454
455 return *this;
456}
457
458const Variable &Variable::operator=( const Bu::FString &rhs )
459{
460 reset( typeString );
461 uVal.sVal = new Bu::FString( rhs );
462
463 return *this;
464}
465
466const Variable &Variable::operator+=( const Variable &rhs )
467{
468 switch( eType )
469 {
470 case typeNone:
471 reset( rhs.eType );
472 if( eType == typeString || eType == typeRef )
473 {
474 uVal.sVal = new Bu::FString( *rhs.uVal.sVal );
475 }
476 else if( eType == typeList )
477 {
478 uVal.lVal = new VarList( *rhs.uVal.lVal );
479 }
480 else
481 {
482 uVal = rhs.uVal;
483 }
484 break;
485
486 case typeInt:
487 uVal.iVal += rhs.getInt();
488 break;
489
490 case typeFloat:
491 uVal.fVal += rhs.getFloat();
492 break;
493
494 case typeBool:
495 throw Bu::ExceptionBase("Can't += with a boolean...");
496 break;
497
498 case typeString:
499 uVal.sVal->append(" ");
500 uVal.sVal->append( rhs.getString() );
501 break;
502
503 case typeList:
504 uVal.lVal->append( rhs.getList() );
505 break;
506
507 case typeVersion:
508 break;
509
510 default:
511 break;
512 }
513 return *this;
514}
515
516const Variable &Variable::operator<<( const Variable &rhs )
517{
518 switch( eType )
519 {
520 case typeNone:
521 reset( rhs.eType );
522 if( eType == typeString )
523 {
524 uVal.sVal = new Bu::FString( *rhs.uVal.sVal );
525 }
526 else if( eType == typeList )
527 {
528 uVal.lVal = new VarList( *rhs.uVal.lVal );
529 }
530 else
531 {
532 uVal = rhs.uVal;
533 }
534 break;
535
536 case typeString:
537 uVal.sVal->append( rhs.getString() );
538 break;
539
540 case typeList:
541 uVal.lVal->append( rhs.getList() );
542 break;
543
544 default:
545 throw Bu::ExceptionBase("Can't << with non-string or non-list.");
546 break;
547 }
548 return *this;
549}
550
551bool Variable::operator==( const Variable &rhs ) const
552{
553 if( eType != rhs.eType )
554 return false;
555 switch( eType )
556 {
557 case typeNone:
558 return true;
559
560 case typeInt:
561 return uVal.iVal == rhs.uVal.iVal;
562
563 case typeFloat:
564 return uVal.fVal == rhs.uVal.fVal;
565
566 case typeBool:
567 return uVal.bVal == rhs.uVal.bVal;
568
569 case typeString:
570 case typeRef:
571 return *uVal.sVal == *rhs.uVal.sVal;
572
573 case typeList:
574 return *uVal.lVal == *rhs.uVal.lVal;
575
576 case typeVersion:
577 return false;
578 }
579
580 return false;
581}
582
583bool Variable::operator!=( const Variable &rhs ) const
584{
585 return !(*this == rhs);
586}
587
588bool Variable::operator<( const Variable &rhs ) const
589{
590 Type eTop = Bu::max( eType, rhs.eType );
591 switch( eTop )
592 {
593 case typeNone:
594 return false;
595
596 case typeBool:
597 throw Bu::ExceptionBase("You cannot < compare boolean values.");
598
599 case typeInt:
600 return toInt() < rhs.toInt();
601
602 case typeFloat:
603 return toFloat() < rhs.toFloat();
604
605 case typeVersion:
606 return true;
607
608 case typeString:
609 return toString() < rhs.toString();
610
611 case typeList:
612 throw Bu::ExceptionBase("You cannot < compare list values.");
613
614 case typeRef:
615 throw Bu::ExceptionBase("You cannot < compare reference values.");
616 }
617 throw Bu::ExceptionBase("Unhandled case in Variable < compare");
618}
619
620bool Variable::operator>( const Variable &rhs ) const
621{
622 Type eTop = Bu::max( eType, rhs.eType );
623 switch( eTop )
624 {
625 case typeNone:
626 return false;
627
628 case typeBool:
629 throw Bu::ExceptionBase("You cannot > compare boolean values.");
630
631 case typeInt:
632 return toInt() > rhs.toInt();
633
634 case typeFloat:
635 return toFloat() > rhs.toFloat();
636
637 case typeVersion:
638 return true;
639
640 case typeString:
641 return toString() > rhs.toString();
642
643 case typeList:
644 throw Bu::ExceptionBase("You cannot > compare list values.");
645
646 case typeRef:
647 throw Bu::ExceptionBase("You cannot > compare reference values.");
648 }
649 throw Bu::ExceptionBase("Unhandled case in Variable > compare");
650}
651
652bool Variable::operator<=( const Variable &rhs ) const
653{
654 Type eTop = Bu::max( eType, rhs.eType );
655 switch( eTop )
656 {
657 case typeNone:
658 return false;
659
660 case typeBool:
661 throw Bu::ExceptionBase("You cannot <= compare boolean values.");
662
663 case typeInt:
664 return toInt() <= rhs.toInt();
665
666 case typeFloat:
667 return toFloat() <= rhs.toFloat();
668
669 case typeVersion:
670 return true;
671
672 case typeString:
673 return toString() <= rhs.toString();
674
675 case typeList:
676 throw Bu::ExceptionBase("You cannot <= compare list values.");
677
678 case typeRef:
679 throw Bu::ExceptionBase("You cannot <= compare reference values.");
680 }
681 throw Bu::ExceptionBase("Unhandled case in Variable <= compare");
682}
683
684bool Variable::operator>=( const Variable &rhs ) const
685{
686 Type eTop = Bu::max( eType, rhs.eType );
687 switch( eTop )
688 {
689 case typeNone:
690 return false;
691
692 case typeBool:
693 throw Bu::ExceptionBase("You cannot >= compare boolean values.");
694
695 case typeInt:
696 return toInt() >= rhs.toInt();
697
698 case typeFloat:
699 return toFloat() >= rhs.toFloat();
700
701 case typeVersion:
702 return true;
703
704 case typeString:
705 return toString() >= rhs.toString();
706
707 case typeList:
708 throw Bu::ExceptionBase("You cannot >= compare list values.");
709
710 case typeRef:
711 throw Bu::ExceptionBase("You cannot >= compare reference values.");
712 }
713 throw Bu::ExceptionBase("Unhandled case in Variable >= compare");
714}
715
716Variable Variable::operator+( const Variable &rhs ) const
717{
718 Type eTop = Bu::max( eType, rhs.eType );
719 switch( eTop )
720 {
721 case typeNone:
722 return Variable();
723
724 case typeBool:
725 throw Bu::ExceptionBase("You cannot add boolean values.");
726
727 case typeInt:
728 return Variable( toInt() + rhs.toInt() );
729
730 case typeFloat:
731 return Variable( toFloat() + rhs.toFloat() );
732
733 case typeVersion:
734 throw Bu::ExceptionBase("You cannot add version values.");
735
736 case typeString:
737 return Variable( toString() + rhs.toString() );
738
739 case typeList:
740 return Variable( toList() + rhs.toList() );
741
742 case typeRef:
743 throw Bu::ExceptionBase("You cannot add reference values.");
744 }
745 throw Bu::ExceptionBase("Unhandled case in Variable add");
746}
747
748Variable Variable::operator-( const Variable &rhs ) const
749{
750 Type eTop = Bu::max( eType, rhs.eType );
751 switch( eTop )
752 {
753 case typeNone:
754 return Variable();
755
756 case typeBool:
757 throw Bu::ExceptionBase("You cannot subtract boolean values.");
758
759 case typeInt:
760 return Variable( toInt() - rhs.toInt() );
761
762 case typeFloat:
763 return Variable( toFloat() - rhs.toFloat() );
764
765 case typeVersion:
766 throw Bu::ExceptionBase("You cannot subtract version values.");
767
768 case typeString:
769 throw Bu::ExceptionBase("You cannot subtract string values.");
770
771 case typeList:
772 throw Bu::ExceptionBase("You cannot subtract list values.");
773
774 case typeRef:
775 throw Bu::ExceptionBase("You cannot subtract reference values.");
776 }
777 throw Bu::ExceptionBase("Unhandled case in Variable subtract");
778}
779
780Variable Variable::operator*( const Variable &rhs ) const
781{
782 Type eTop = Bu::max( eType, rhs.eType );
783 switch( eTop )
784 {
785 case typeNone:
786 return Variable();
787
788 case typeBool:
789 throw Bu::ExceptionBase("You cannot multiply boolean values.");
790
791 case typeInt:
792 return Variable( toInt() * rhs.toInt() );
793
794 case typeFloat:
795 return Variable( toFloat() * rhs.toFloat() );
796
797 case typeVersion:
798 throw Bu::ExceptionBase("You cannot multiply version values.");
799
800 case typeString:
801 throw Bu::ExceptionBase("You cannot multiply string values.");
802
803 case typeList:
804 throw Bu::ExceptionBase("You cannot multiply list values.");
805
806 case typeRef:
807 throw Bu::ExceptionBase("You cannot multiply reference values.");
808 }
809 throw Bu::ExceptionBase("Unhandled case in Variable multiply");
810}
811
812Variable Variable::operator/( const Variable &rhs ) const
813{
814 Type eTop = Bu::max( eType, rhs.eType );
815 switch( eTop )
816 {
817 case typeNone:
818 return Variable();
819
820 case typeBool:
821 throw Bu::ExceptionBase("You cannot divide boolean values.");
822
823 case typeInt:
824 return Variable( toInt() / rhs.toInt() );
825
826 case typeFloat:
827 return Variable( toFloat() / rhs.toFloat() );
828
829 case typeVersion:
830 throw Bu::ExceptionBase("You cannot divide version values.");
831
832 case typeString:
833 throw Bu::ExceptionBase("You cannot divide string values.");
834
835 case typeList:
836 throw Bu::ExceptionBase("You cannot divide list values.");
837
838 case typeRef:
839 throw Bu::ExceptionBase("You cannot divide reference values.");
840 }
841 throw Bu::ExceptionBase("Unhandled case in Variable divide");
842}
843
844void Variable::reset( Type eNewType )
845{
846 if( eType == typeString || eType == typeRef )
847 {
848 delete uVal.sVal;
849 }
850 else if( eType == typeList )
851 {
852 delete uVal.lVal;
853 }
854 memset( &uVal, 0, sizeof(uVal) );
855
856 eType = eNewType;
857}
858
859Bu::Formatter &operator<<( Bu::Formatter &f, const Variable::Type &t )
860{
861 switch( t )
862 {
863 case Variable::typeNone: f << "*typeless*"; break;
864 case Variable::typeInt: f << "int"; break;
865 case Variable::typeFloat: f << "double"; break;
866 case Variable::typeBool: f << "bool"; break;
867 case Variable::typeString: f << "string"; break;
868 case Variable::typeList: f << "list"; break;
869 case Variable::typeVersion: f << "version"; break;
870 case Variable::typeRef: f << "ref"; break;
871 }
872 return f;
873}
874
875Bu::Formatter &operator<<( Bu::Formatter &f, const Variable &v )
876{
877 f << "Variable(" << v.getType() << ") = ";
878 switch( v.getType() )
879 {
880 case Variable::typeNone: break;
881 case Variable::typeInt: f << v.getInt(); break;
882 case Variable::typeFloat: f << v.getFloat(); break;
883 case Variable::typeBool: f << v.getBool(); break;
884 case Variable::typeString: f << v.getString(); break;
885 case Variable::typeList: f << v.getList(); break;
886 case Variable::typeVersion:/*f << v.getVersion();*/ break;
887 case Variable::typeRef: f << v.getString(); break;
888 }
889
890 return f;
891}
892