diff options
author | Mike Buland <eichlan@xagasoft.com> | 2009-12-21 18:04:02 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2009-12-21 18:04:02 +0000 |
commit | fb28f6800864176be2ffca29e8e664b641f33170 (patch) | |
tree | ba9180ac442939edc4eacbe1fdae93c5a7f87cee /src/variable.cpp | |
parent | 51e21a316be6e052251b3dfc7d671061ebd67cee (diff) | |
download | build-fb28f6800864176be2ffca29e8e664b641f33170.tar.gz build-fb28f6800864176be2ffca29e8e664b641f33170.tar.bz2 build-fb28f6800864176be2ffca29e8e664b641f33170.tar.xz build-fb28f6800864176be2ffca29e8e664b641f33170.zip |
m3 is copied into trunk, we should be good to go, now.
Diffstat (limited to '')
-rw-r--r-- | src/variable.cpp | 892 |
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" | ||
4 | using Bu::sio; | ||
5 | |||
6 | #include <stdlib.h> | ||
7 | |||
8 | Variable::Variable() : | ||
9 | eType( typeNone ) | ||
10 | { | ||
11 | memset( &uVal, 0, sizeof(uVal) ); | ||
12 | } | ||
13 | |||
14 | Variable::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 | |||
28 | Variable::Variable( int iVal ) : | ||
29 | eType( typeInt ) | ||
30 | { | ||
31 | memset( &uVal, 0, sizeof(uVal) ); | ||
32 | uVal.iVal = iVal; | ||
33 | } | ||
34 | |||
35 | Variable::Variable( double fVal ) : | ||
36 | eType( typeFloat ) | ||
37 | { | ||
38 | memset( &uVal, 0, sizeof(uVal) ); | ||
39 | uVal.fVal = fVal; | ||
40 | } | ||
41 | |||
42 | Variable::Variable( bool bVal ) : | ||
43 | eType( typeBool ) | ||
44 | { | ||
45 | memset( &uVal, 0, sizeof(uVal) ); | ||
46 | uVal.bVal = bVal; | ||
47 | } | ||
48 | |||
49 | Variable::Variable( const Bu::FString &sVal ) : | ||
50 | eType( typeString ) | ||
51 | { | ||
52 | memset( &uVal, 0, sizeof(uVal) ); | ||
53 | uVal.sVal = new Bu::FString( sVal ); | ||
54 | } | ||
55 | |||
56 | Variable::Variable( const char *sVal ) : | ||
57 | eType( typeString ) | ||
58 | { | ||
59 | memset( &uVal, 0, sizeof(uVal) ); | ||
60 | uVal.sVal = new Bu::FString( sVal ); | ||
61 | } | ||
62 | |||
63 | Variable::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 | |||
81 | Variable::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 | |||
116 | Variable::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 | |||
134 | Variable::Variable( const VarList &lst ) | ||
135 | { | ||
136 | eType = typeList; | ||
137 | uVal.lVal = new VarList( lst ); | ||
138 | } | ||
139 | |||
140 | Variable::~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 | |||
152 | Variable Variable::mkRef( const Bu::FString &sVal ) | ||
153 | { | ||
154 | Variable v( typeRef ); | ||
155 | (*v.uVal.sVal) = sVal; | ||
156 | return v; | ||
157 | } | ||
158 | |||
159 | Variable::Type Variable::getType() const | ||
160 | { | ||
161 | return eType; | ||
162 | } | ||
163 | |||
164 | int Variable::getInt() const | ||
165 | { | ||
166 | if( eType != typeInt ) throw Bu::ExceptionBase("Wrong variable type."); | ||
167 | return uVal.iVal; | ||
168 | } | ||
169 | |||
170 | double Variable::getFloat() const | ||
171 | { | ||
172 | if( eType != typeFloat ) throw Bu::ExceptionBase("Wrong variable type."); | ||
173 | return uVal.fVal; | ||
174 | } | ||
175 | |||
176 | bool Variable::getBool() const | ||
177 | { | ||
178 | if( eType != typeBool ) throw Bu::ExceptionBase("Wrong variable type."); | ||
179 | return uVal.bVal; | ||
180 | } | ||
181 | |||
182 | const Bu::FString &Variable::getString() const | ||
183 | { | ||
184 | if( eType != typeString && eType != typeRef ) throw Bu::ExceptionBase("Wrong variable type."); | ||
185 | return *uVal.sVal; | ||
186 | } | ||
187 | |||
188 | const VarList &Variable::getList() const | ||
189 | { | ||
190 | if( eType != typeList ) throw Bu::ExceptionBase("Wrong variable type."); | ||
191 | return *uVal.lVal; | ||
192 | } | ||
193 | |||
194 | int 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 | |||
217 | double 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 | |||
240 | bool 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 | |||
266 | Bu::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 | |||
310 | VarList Variable::toList() const | ||
311 | { | ||
312 | if( eType == typeList ) | ||
313 | return *this; | ||
314 | return VarList( *this ); | ||
315 | } | ||
316 | |||
317 | Variable 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 | |||
348 | void 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 | |||
362 | VarList::iterator Variable::begin() | ||
363 | { | ||
364 | if( eType != typeList ) throw Bu::ExceptionBase("Wrong variable type."); | ||
365 | |||
366 | return uVal.lVal->begin(); | ||
367 | } | ||
368 | |||
369 | VarList::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 | |||
376 | void 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 | |||
408 | void Variable::doNot() | ||
409 | { | ||
410 | bool bVal = !toBool(); | ||
411 | reset( typeBool ); | ||
412 | uVal.bVal = bVal; | ||
413 | } | ||
414 | |||
415 | const 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 | |||
434 | const Variable &Variable::operator=( const int &rhs ) | ||
435 | { | ||
436 | reset( typeInt ); | ||
437 | uVal.iVal = rhs; | ||
438 | |||
439 | return *this; | ||
440 | } | ||
441 | |||
442 | const Variable &Variable::operator=( const double &rhs ) | ||
443 | { | ||
444 | reset( typeFloat ); | ||
445 | uVal.fVal = rhs; | ||
446 | |||
447 | return *this; | ||
448 | } | ||
449 | |||
450 | const Variable &Variable::operator=( const bool &rhs ) | ||
451 | { | ||
452 | reset( typeBool ); | ||
453 | uVal.bVal = rhs; | ||
454 | |||
455 | return *this; | ||
456 | } | ||
457 | |||
458 | const Variable &Variable::operator=( const Bu::FString &rhs ) | ||
459 | { | ||
460 | reset( typeString ); | ||
461 | uVal.sVal = new Bu::FString( rhs ); | ||
462 | |||
463 | return *this; | ||
464 | } | ||
465 | |||
466 | const 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 | |||
516 | const 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 | |||
551 | bool 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 | |||
583 | bool Variable::operator!=( const Variable &rhs ) const | ||
584 | { | ||
585 | return !(*this == rhs); | ||
586 | } | ||
587 | |||
588 | bool 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 | |||
620 | bool 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 | |||
652 | bool 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 | |||
684 | bool 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 | |||
716 | Variable 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 | |||
748 | Variable 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 | |||
780 | Variable 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 | |||
812 | Variable 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 | |||
844 | void 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 | |||
859 | Bu::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 | |||
875 | Bu::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 | |||