xref: /haiku/src/kits/debugger/source_language/c_family/CLanguageExpressionEvaluator.cpp (revision 770075026caa7953c27fb2d7489c5b3ea25a5853)
1 /*
2  * Copyright 2006-2014 Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Stephan Aßmus <superstippi@gmx.de>
7  *		Rene Gollent <rene@gollent.com>
8  *		John Scipione <jscipione@gmail.com>
9  *		Ingo Weinhold <bonefish@cs.tu-berlin.de>
10  */
11 
12 #include "CLanguageExpressionEvaluator.h"
13 
14 #include <algorithm>
15 
16 #include "AutoLocker.h"
17 
18 #include "CLanguageTokenizer.h"
19 #include "ExpressionInfo.h"
20 #include "FloatValue.h"
21 #include "IntegerFormatter.h"
22 #include "IntegerValue.h"
23 #include "ObjectID.h"
24 #include "StackFrame.h"
25 #include "SyntheticPrimitiveType.h"
26 #include "TeamTypeInformation.h"
27 #include "Thread.h"
28 #include "Type.h"
29 #include "TypeHandlerRoster.h"
30 #include "TypeLookupConstraints.h"
31 #include "Value.h"
32 #include "ValueLocation.h"
33 #include "ValueNode.h"
34 #include "ValueNodeManager.h"
35 #include "Variable.h"
36 #include "VariableValueNodeChild.h"
37 
38 
39 using namespace CLanguage;
40 
41 
42 enum operand_kind {
43 	OPERAND_KIND_UNKNOWN = 0,
44 	OPERAND_KIND_PRIMITIVE,
45 	OPERAND_KIND_TYPE,
46 	OPERAND_KIND_VALUE_NODE
47 };
48 
49 
TokenTypeToString(int32 type)50 static BString TokenTypeToString(int32 type)
51 {
52 	BString token;
53 
54 	switch (type) {
55 		case TOKEN_PLUS:
56 			token = "+";
57 			break;
58 
59 		case TOKEN_MINUS:
60 			token = "-";
61 			break;
62 
63 		case TOKEN_STAR:
64 			token = "*";
65 			break;
66 
67 		case TOKEN_SLASH:
68 			token = "/";
69 			break;
70 
71 		case TOKEN_MODULO:
72 			token = "%";
73 			break;
74 
75 		case TOKEN_OPENING_PAREN:
76 			token = "(";
77 			break;
78 
79 		case TOKEN_CLOSING_PAREN:
80 			token = ")";
81 			break;
82 
83 		case TOKEN_LOGICAL_AND:
84 			token = "&&";
85 			break;
86 
87 		case TOKEN_LOGICAL_OR:
88 			token = "||";
89 			break;
90 
91 		case TOKEN_LOGICAL_NOT:
92 			token = "!";
93 			break;
94 
95 		case TOKEN_BITWISE_AND:
96 			token = "&";
97 			break;
98 
99 		case TOKEN_BITWISE_OR:
100 			token = "|";
101 			break;
102 
103 		case TOKEN_BITWISE_NOT:
104 			token = "~";
105 			break;
106 
107 		case TOKEN_BITWISE_XOR:
108 			token = "^";
109 			break;
110 
111 		case TOKEN_EQ:
112 			token = "==";
113 			break;
114 
115 		case TOKEN_NE:
116 			token = "!=";
117 			break;
118 
119 		case TOKEN_GT:
120 			token = ">";
121 			break;
122 
123 		case TOKEN_GE:
124 			token = ">=";
125 			break;
126 
127 		case TOKEN_LT:
128 			token = "<";
129 			break;
130 
131 		case TOKEN_LE:
132 			token = "<=";
133 			break;
134 
135 		case TOKEN_MEMBER_PTR:
136 			token = "->";
137 			break;
138 
139 		default:
140 			token.SetToFormat("Unknown token type %" B_PRId32, type);
141 			break;
142 	}
143 
144 	return token;
145 }
146 
147 
148 // #pragma mark - CLanguageExpressionEvaluator::InternalVariableID
149 
150 
151 class CLanguageExpressionEvaluator::InternalVariableID : public ObjectID {
152 public:
InternalVariableID(const BVariant & value)153 	InternalVariableID(const BVariant& value)
154 		:
155 		fValue(value)
156 	{
157 	}
158 
~InternalVariableID()159 	virtual ~InternalVariableID()
160 	{
161 	}
162 
operator ==(const ObjectID & other) const163 	virtual	bool operator==(const ObjectID& other) const
164 	{
165 		const InternalVariableID* otherID
166 			= dynamic_cast<const InternalVariableID*>(&other);
167 		if (otherID == NULL)
168 			return false;
169 
170 		return fValue == otherID->fValue;
171 	}
172 
173 protected:
ComputeHashValue() const174 	virtual	uint32 ComputeHashValue() const
175 	{
176 		return *(uint32*)(&fValue);
177 	}
178 
179 private:
180 	BVariant fValue;
181 };
182 
183 
184 // #pragma mark - CLanguageExpressionEvaluator::Operand
185 
186 
187 class CLanguageExpressionEvaluator::Operand {
188 public:
Operand()189 	Operand()
190 		:
191 		fPrimitive(),
192 		fValueNode(NULL),
193 		fType(NULL),
194 		fKind(OPERAND_KIND_UNKNOWN)
195 	{
196 	}
197 
Operand(int64 value)198 	Operand(int64 value)
199 		:
200 		fPrimitive(value),
201 		fValueNode(NULL),
202 		fType(NULL),
203 		fKind(OPERAND_KIND_PRIMITIVE)
204 	{
205 	}
206 
Operand(double value)207 	Operand(double value)
208 		:
209 		fPrimitive(value),
210 		fValueNode(NULL),
211 		fType(NULL),
212 		fKind(OPERAND_KIND_PRIMITIVE)
213 	{
214 	}
215 
Operand(ValueNode * node)216 	Operand(ValueNode* node)
217 		:
218 		fPrimitive(),
219 		fValueNode(NULL),
220 		fType(NULL),
221 		fKind(OPERAND_KIND_UNKNOWN)
222 	{
223 		SetTo(node);
224 	}
225 
Operand(Type * type)226 	Operand(Type* type)
227 		:
228 		fPrimitive(),
229 		fValueNode(NULL),
230 		fType(NULL),
231 		fKind(OPERAND_KIND_UNKNOWN)
232 	{
233 		SetTo(type);
234 	}
235 
Operand(const Operand & X)236 	Operand(const Operand& X)
237 		:
238 		fPrimitive(),
239 		fValueNode(NULL),
240 		fType(NULL),
241 		fKind(OPERAND_KIND_UNKNOWN)
242 	{
243 		*this = X;
244 	}
245 
246 
~Operand()247 	virtual ~Operand()
248 	{
249 		Unset();
250 	}
251 
operator =(const Operand & X)252 	Operand& operator=(const Operand& X)
253 	{
254 		switch (X.fKind) {
255 			case OPERAND_KIND_UNKNOWN:
256 				Unset();
257 				break;
258 
259 			case OPERAND_KIND_PRIMITIVE:
260 				SetTo(X.fPrimitive);
261 				break;
262 
263 			case OPERAND_KIND_VALUE_NODE:
264 				SetTo(X.fValueNode);
265 				break;
266 
267 			case OPERAND_KIND_TYPE:
268 				SetTo(X.fType);
269 				break;
270 		}
271 
272 		return *this;
273 	}
274 
SetTo(const BVariant & value)275 	void SetTo(const BVariant& value)
276 	{
277 		Unset();
278 		fPrimitive = value;
279 		fKind = OPERAND_KIND_PRIMITIVE;
280 	}
281 
SetTo(ValueNode * node)282 	void SetTo(ValueNode* node)
283 	{
284 		Unset();
285 		fValueNode = node;
286 		fValueNode->AcquireReference();
287 
288 		Value* value = node->GetValue();
289 		if (value != NULL)
290 			value->ToVariant(fPrimitive);
291 
292 		fKind = OPERAND_KIND_VALUE_NODE;
293 	}
294 
SetTo(Type * type)295 	void SetTo(Type* type)
296 	{
297 		Unset();
298 		fType = type;
299 		fType->AcquireReference();
300 
301 		fKind = OPERAND_KIND_TYPE;
302 	}
303 
Unset()304 	void Unset()
305 	{
306 		if (fValueNode != NULL)
307 			fValueNode->ReleaseReference();
308 
309 		if (fType != NULL)
310 			fType->ReleaseReference();
311 
312 		fValueNode = NULL;
313 		fType = NULL;
314 		fKind = OPERAND_KIND_UNKNOWN;
315 	}
316 
Kind() const317 	inline operand_kind Kind() const
318 	{
319 		return fKind;
320 	}
321 
PrimitiveValue() const322 	inline const BVariant& PrimitiveValue() const
323 	{
324 		return fPrimitive;
325 	}
326 
GetValueNode() const327 	inline ValueNode* GetValueNode() const
328 	{
329 		return fValueNode;
330 
331 	}
332 
GetType() const333 	inline Type* GetType() const
334 	{
335 		return fType;
336 	}
337 
operator +=(const Operand & rhs)338 	Operand& operator+=(const Operand& rhs)
339 	{
340 		Operand temp = rhs;
341 		_ResolveTypesIfNeeded(temp);
342 
343 		switch (fPrimitive.Type()) {
344 			case B_INT8_TYPE:
345 			{
346 				fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
347 					+ temp.fPrimitive.ToInt8()));
348 				break;
349 			}
350 
351 			case B_UINT8_TYPE:
352 			{
353 				fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
354 					+ temp.fPrimitive.ToUInt8()));
355 				break;
356 			}
357 
358 			case B_INT16_TYPE:
359 			{
360 				fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
361 					+ temp.fPrimitive.ToInt16()));
362 				break;
363 			}
364 
365 			case B_UINT16_TYPE:
366 			{
367 				fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
368 					+ temp.fPrimitive.ToUInt16()));
369 				break;
370 			}
371 
372 			case B_INT32_TYPE:
373 			{
374 				fPrimitive.SetTo(fPrimitive.ToInt32()
375 					+ temp.fPrimitive.ToInt32());
376 				break;
377 			}
378 
379 			case B_UINT32_TYPE:
380 			{
381 				fPrimitive.SetTo(fPrimitive.ToUInt32()
382 					+ temp.fPrimitive.ToUInt32());
383 				break;
384 			}
385 
386 			case B_INT64_TYPE:
387 			{
388 				fPrimitive.SetTo(fPrimitive.ToInt64()
389 					+ temp.fPrimitive.ToInt64());
390 				break;
391 			}
392 
393 			case B_UINT64_TYPE:
394 			{
395 				fPrimitive.SetTo(fPrimitive.ToUInt64()
396 					+ temp.fPrimitive.ToUInt64());
397 				break;
398 			}
399 
400 			case B_FLOAT_TYPE:
401 			{
402 				fPrimitive.SetTo(fPrimitive.ToFloat()
403 					+ temp.fPrimitive.ToFloat());
404 				break;
405 			}
406 
407 			case B_DOUBLE_TYPE:
408 			{
409 				fPrimitive.SetTo(fPrimitive.ToDouble()
410 					+ temp.fPrimitive.ToDouble());
411 				break;
412 			}
413 		}
414 
415 		return *this;
416 	}
417 
operator -=(const Operand & rhs)418 	Operand& operator-=(const Operand& rhs)
419 	{
420 		Operand temp = rhs;
421 		_ResolveTypesIfNeeded(temp);
422 
423 		switch (fPrimitive.Type()) {
424 			case B_INT8_TYPE:
425 			{
426 				fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
427 					- temp.fPrimitive.ToInt8()));
428 				break;
429 			}
430 
431 			case B_UINT8_TYPE:
432 			{
433 				fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
434 					- temp.fPrimitive.ToUInt8()));
435 				break;
436 			}
437 
438 			case B_INT16_TYPE:
439 			{
440 				fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
441 					- temp.fPrimitive.ToInt16()));
442 				break;
443 			}
444 
445 			case B_UINT16_TYPE:
446 			{
447 				fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
448 					- temp.fPrimitive.ToUInt16()));
449 				break;
450 			}
451 
452 			case B_INT32_TYPE:
453 			{
454 				fPrimitive.SetTo(fPrimitive.ToInt32()
455 					- temp.fPrimitive.ToInt32());
456 				break;
457 			}
458 
459 			case B_UINT32_TYPE:
460 			{
461 				fPrimitive.SetTo(fPrimitive.ToUInt32()
462 					- temp.fPrimitive.ToUInt32());
463 				break;
464 			}
465 
466 			case B_INT64_TYPE:
467 			{
468 				fPrimitive.SetTo(fPrimitive.ToInt64()
469 					- temp.fPrimitive.ToInt64());
470 				break;
471 			}
472 
473 			case B_UINT64_TYPE:
474 			{
475 				fPrimitive.SetTo(fPrimitive.ToUInt64()
476 					- temp.fPrimitive.ToUInt64());
477 				break;
478 			}
479 
480 			case B_FLOAT_TYPE:
481 			{
482 				fPrimitive.SetTo(fPrimitive.ToFloat()
483 					- temp.fPrimitive.ToFloat());
484 				break;
485 			}
486 
487 			case B_DOUBLE_TYPE:
488 			{
489 				fPrimitive.SetTo(fPrimitive.ToDouble()
490 					- temp.fPrimitive.ToDouble());
491 				break;
492 			}
493 		}
494 
495 		return *this;
496 	}
497 
operator /=(const Operand & rhs)498 	Operand& operator/=(const Operand& rhs)
499 	{
500 		Operand temp = rhs;
501 		_ResolveTypesIfNeeded(temp);
502 
503 		switch (fPrimitive.Type()) {
504 			case B_INT8_TYPE:
505 			{
506 				fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
507 					/ temp.fPrimitive.ToInt8()));
508 				break;
509 			}
510 
511 			case B_UINT8_TYPE:
512 			{
513 				fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
514 					/ temp.fPrimitive.ToUInt8()));
515 				break;
516 			}
517 
518 			case B_INT16_TYPE:
519 			{
520 				fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
521 					/ temp.fPrimitive.ToInt16()));
522 				break;
523 			}
524 
525 			case B_UINT16_TYPE:
526 			{
527 				fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
528 					/ temp.fPrimitive.ToUInt16()));
529 				break;
530 			}
531 
532 			case B_INT32_TYPE:
533 			{
534 				fPrimitive.SetTo(fPrimitive.ToInt32()
535 					/ temp.fPrimitive.ToInt32());
536 				break;
537 			}
538 
539 			case B_UINT32_TYPE:
540 			{
541 				fPrimitive.SetTo(fPrimitive.ToUInt32()
542 					/ temp.fPrimitive.ToUInt32());
543 				break;
544 			}
545 
546 			case B_INT64_TYPE:
547 			{
548 				fPrimitive.SetTo(fPrimitive.ToInt64()
549 					/ temp.fPrimitive.ToInt64());
550 				break;
551 			}
552 
553 			case B_UINT64_TYPE:
554 			{
555 				fPrimitive.SetTo(fPrimitive.ToUInt64()
556 					/ temp.fPrimitive.ToUInt64());
557 				break;
558 			}
559 
560 			case B_FLOAT_TYPE:
561 			{
562 				fPrimitive.SetTo(fPrimitive.ToFloat()
563 					/ temp.fPrimitive.ToFloat());
564 				break;
565 			}
566 
567 			case B_DOUBLE_TYPE:
568 			{
569 				fPrimitive.SetTo(fPrimitive.ToDouble()
570 					/ temp.fPrimitive.ToDouble());
571 				break;
572 			}
573 		}
574 
575 		return *this;
576 	}
577 
operator *=(const Operand & rhs)578 	Operand& operator*=(const Operand& rhs)
579 	{
580 		Operand temp = rhs;
581 		_ResolveTypesIfNeeded(temp);
582 
583 		switch (fPrimitive.Type()) {
584 			case B_INT8_TYPE:
585 			{
586 				fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
587 					* temp.fPrimitive.ToInt8()));
588 				break;
589 			}
590 
591 			case B_UINT8_TYPE:
592 			{
593 				fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
594 					* temp.fPrimitive.ToUInt8()));
595 				break;
596 			}
597 
598 			case B_INT16_TYPE:
599 			{
600 				fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
601 					* temp.fPrimitive.ToInt16()));
602 				break;
603 			}
604 
605 			case B_UINT16_TYPE:
606 			{
607 				fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
608 					* temp.fPrimitive.ToUInt16()));
609 				break;
610 			}
611 
612 			case B_INT32_TYPE:
613 			{
614 				fPrimitive.SetTo(fPrimitive.ToInt32()
615 					* temp.fPrimitive.ToInt32());
616 				break;
617 			}
618 
619 			case B_UINT32_TYPE:
620 			{
621 				fPrimitive.SetTo(fPrimitive.ToUInt32()
622 					* temp.fPrimitive.ToUInt32());
623 				break;
624 			}
625 
626 			case B_INT64_TYPE:
627 			{
628 				fPrimitive.SetTo(fPrimitive.ToInt64()
629 					* temp.fPrimitive.ToInt64());
630 				break;
631 			}
632 
633 			case B_UINT64_TYPE:
634 			{
635 				fPrimitive.SetTo(fPrimitive.ToUInt64()
636 					* temp.fPrimitive.ToUInt64());
637 				break;
638 			}
639 
640 			case B_FLOAT_TYPE:
641 			{
642 				fPrimitive.SetTo(fPrimitive.ToFloat()
643 					* temp.fPrimitive.ToFloat());
644 				break;
645 			}
646 
647 			case B_DOUBLE_TYPE:
648 			{
649 				fPrimitive.SetTo(fPrimitive.ToDouble()
650 					* temp.fPrimitive.ToDouble());
651 				break;
652 			}
653 		}
654 
655 		return *this;
656 	}
657 
operator %=(const Operand & rhs)658 	Operand& operator%=(const Operand& rhs)
659 	{
660 		Operand temp = rhs;
661 		_ResolveTypesIfNeeded(temp);
662 
663 		switch (fPrimitive.Type()) {
664 			case B_INT8_TYPE:
665 			{
666 				fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
667 					% temp.fPrimitive.ToInt8()));
668 				break;
669 			}
670 
671 			case B_UINT8_TYPE:
672 			{
673 				fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
674 					% temp.fPrimitive.ToUInt8()));
675 				break;
676 			}
677 
678 			case B_INT16_TYPE:
679 			{
680 				fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
681 					% temp.fPrimitive.ToInt16()));
682 				break;
683 			}
684 
685 			case B_UINT16_TYPE:
686 			{
687 				fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
688 					% temp.fPrimitive.ToUInt16()));
689 				break;
690 			}
691 
692 			case B_INT32_TYPE:
693 			{
694 				fPrimitive.SetTo(fPrimitive.ToInt32()
695 					% temp.fPrimitive.ToInt32());
696 				break;
697 			}
698 
699 			case B_UINT32_TYPE:
700 			{
701 				fPrimitive.SetTo(fPrimitive.ToUInt32()
702 					% temp.fPrimitive.ToUInt32());
703 				break;
704 			}
705 
706 			case B_INT64_TYPE:
707 			{
708 				fPrimitive.SetTo(fPrimitive.ToInt64()
709 					% temp.fPrimitive.ToInt64());
710 				break;
711 			}
712 
713 			case B_UINT64_TYPE:
714 			{
715 				fPrimitive.SetTo(fPrimitive.ToUInt64()
716 					% temp.fPrimitive.ToUInt64());
717 				break;
718 			}
719 		}
720 
721 		return *this;
722 	}
723 
operator &=(const Operand & rhs)724 	Operand& operator&=(const Operand& rhs)
725 	{
726 		Operand temp = rhs;
727 		_ResolveTypesIfNeeded(temp);
728 
729 		switch (fPrimitive.Type()) {
730 			case B_INT8_TYPE:
731 			{
732 				fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
733 					& temp.fPrimitive.ToInt8()));
734 				break;
735 			}
736 
737 			case B_UINT8_TYPE:
738 			{
739 				fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
740 					& temp.fPrimitive.ToUInt8()));
741 				break;
742 			}
743 
744 			case B_INT16_TYPE:
745 			{
746 				fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
747 					& temp.fPrimitive.ToInt16()));
748 				break;
749 			}
750 
751 			case B_UINT16_TYPE:
752 			{
753 				fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
754 					& temp.fPrimitive.ToUInt16()));
755 				break;
756 			}
757 
758 			case B_INT32_TYPE:
759 			{
760 				fPrimitive.SetTo(fPrimitive.ToInt32()
761 					& temp.fPrimitive.ToInt32());
762 				break;
763 			}
764 
765 			case B_UINT32_TYPE:
766 			{
767 				fPrimitive.SetTo(fPrimitive.ToUInt32()
768 					& temp.fPrimitive.ToUInt32());
769 				break;
770 			}
771 
772 			case B_INT64_TYPE:
773 			{
774 				fPrimitive.SetTo(fPrimitive.ToInt64()
775 					& temp.fPrimitive.ToInt64());
776 				break;
777 			}
778 
779 			case B_UINT64_TYPE:
780 			{
781 				fPrimitive.SetTo(fPrimitive.ToUInt64()
782 					& temp.fPrimitive.ToUInt64());
783 				break;
784 			}
785 		}
786 
787 		return *this;
788 	}
789 
operator |=(const Operand & rhs)790 	Operand& operator|=(const Operand& rhs)
791 	{
792 		Operand temp = rhs;
793 		_ResolveTypesIfNeeded(temp);
794 
795 		switch (fPrimitive.Type()) {
796 			case B_INT8_TYPE:
797 			{
798 				fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
799 					| temp.fPrimitive.ToInt8()));
800 				break;
801 			}
802 
803 			case B_UINT8_TYPE:
804 			{
805 				fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
806 					| temp.fPrimitive.ToUInt8()));
807 				break;
808 			}
809 
810 			case B_INT16_TYPE:
811 			{
812 				fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
813 					| temp.fPrimitive.ToInt16()));
814 				break;
815 			}
816 
817 			case B_UINT16_TYPE:
818 			{
819 				fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
820 					| temp.fPrimitive.ToUInt16()));
821 				break;
822 			}
823 
824 			case B_INT32_TYPE:
825 			{
826 				fPrimitive.SetTo(fPrimitive.ToInt32()
827 					| temp.fPrimitive.ToInt32());
828 				break;
829 			}
830 
831 			case B_UINT32_TYPE:
832 			{
833 				fPrimitive.SetTo(fPrimitive.ToUInt32()
834 					| temp.fPrimitive.ToUInt32());
835 				break;
836 			}
837 
838 			case B_INT64_TYPE:
839 			{
840 				fPrimitive.SetTo(fPrimitive.ToInt64()
841 					| temp.fPrimitive.ToInt64());
842 				break;
843 			}
844 
845 			case B_UINT64_TYPE:
846 			{
847 				fPrimitive.SetTo(fPrimitive.ToUInt64()
848 					| temp.fPrimitive.ToUInt64());
849 				break;
850 			}
851 		}
852 
853 		return *this;
854 	}
855 
operator ^=(const Operand & rhs)856 	Operand& operator^=(const Operand& rhs)
857 	{
858 		Operand temp = rhs;
859 		_ResolveTypesIfNeeded(temp);
860 
861 		switch (fPrimitive.Type()) {
862 			case B_INT8_TYPE:
863 			{
864 				fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
865 					^ temp.fPrimitive.ToInt8()));
866 				break;
867 			}
868 
869 			case B_UINT8_TYPE:
870 			{
871 				fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
872 					^ temp.fPrimitive.ToUInt8()));
873 				break;
874 			}
875 
876 			case B_INT16_TYPE:
877 			{
878 				fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
879 					^ temp.fPrimitive.ToInt16()));
880 				break;
881 			}
882 
883 			case B_UINT16_TYPE:
884 			{
885 				fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
886 					^ temp.fPrimitive.ToUInt16()));
887 				break;
888 			}
889 
890 			case B_INT32_TYPE:
891 			{
892 				fPrimitive.SetTo(fPrimitive.ToInt32()
893 					^ temp.fPrimitive.ToInt32());
894 				break;
895 			}
896 
897 			case B_UINT32_TYPE:
898 			{
899 				fPrimitive.SetTo(fPrimitive.ToUInt32()
900 					^ temp.fPrimitive.ToUInt32());
901 				break;
902 			}
903 
904 			case B_INT64_TYPE:
905 			{
906 				fPrimitive.SetTo(fPrimitive.ToInt64()
907 					^ temp.fPrimitive.ToInt64());
908 				break;
909 			}
910 
911 			case B_UINT64_TYPE:
912 			{
913 				fPrimitive.SetTo(fPrimitive.ToUInt64()
914 					^ temp.fPrimitive.ToUInt64());
915 				break;
916 			}
917 		}
918 
919 		return *this;
920 	}
921 
operator -() const922 	Operand operator-() const
923 	{
924 		Operand value(*this);
925 		value._ResolveToPrimitive();
926 
927 		switch (fPrimitive.Type()) {
928 			case B_INT8_TYPE:
929 			{
930 				value.fPrimitive.SetTo((int8)-fPrimitive.ToInt8());
931 				break;
932 			}
933 
934 			case B_UINT8_TYPE:
935 			{
936 				value.fPrimitive.SetTo((uint8)-fPrimitive.ToUInt8());
937 				break;
938 			}
939 
940 			case B_INT16_TYPE:
941 			{
942 				value.fPrimitive.SetTo((int16)-fPrimitive.ToInt16());
943 				break;
944 			}
945 
946 			case B_UINT16_TYPE:
947 			{
948 				value.fPrimitive.SetTo((uint16)-fPrimitive.ToUInt16());
949 				break;
950 			}
951 
952 			case B_INT32_TYPE:
953 			{
954 				value.fPrimitive.SetTo(-fPrimitive.ToInt32());
955 				break;
956 			}
957 
958 			case B_UINT32_TYPE:
959 			{
960 				value.fPrimitive.SetTo(-fPrimitive.ToUInt32());
961 				break;
962 			}
963 
964 			case B_INT64_TYPE:
965 			{
966 				value.fPrimitive.SetTo(-fPrimitive.ToInt64());
967 				break;
968 			}
969 
970 			case B_UINT64_TYPE:
971 			{
972 				value.fPrimitive.SetTo(-fPrimitive.ToUInt64());
973 				break;
974 			}
975 
976 			case B_FLOAT_TYPE:
977 			{
978 				value.fPrimitive.SetTo(-fPrimitive.ToFloat());
979 				break;
980 			}
981 
982 			case B_DOUBLE_TYPE:
983 			{
984 				value.fPrimitive.SetTo(-fPrimitive.ToDouble());
985 				break;
986 			}
987 		}
988 
989 		return value;
990 	}
991 
operator ~() const992 	Operand operator~() const
993 	{
994 		Operand value(*this);
995 		value._ResolveToPrimitive();
996 
997 		switch (fPrimitive.Type()) {
998 			case B_INT8_TYPE:
999 			{
1000 				value.fPrimitive.SetTo((int8)~fPrimitive.ToInt8());
1001 				break;
1002 			}
1003 
1004 			case B_UINT8_TYPE:
1005 			{
1006 				value.fPrimitive.SetTo((uint8)~fPrimitive.ToUInt8());
1007 				break;
1008 			}
1009 
1010 			case B_INT16_TYPE:
1011 			{
1012 				value.fPrimitive.SetTo((int16)~fPrimitive.ToInt16());
1013 				break;
1014 			}
1015 
1016 			case B_UINT16_TYPE:
1017 			{
1018 				value.fPrimitive.SetTo((uint16)~fPrimitive.ToUInt16());
1019 				break;
1020 			}
1021 
1022 			case B_INT32_TYPE:
1023 			{
1024 				value.fPrimitive.SetTo(~fPrimitive.ToInt32());
1025 				break;
1026 			}
1027 
1028 			case B_UINT32_TYPE:
1029 			{
1030 				value.fPrimitive.SetTo(~fPrimitive.ToUInt32());
1031 				break;
1032 			}
1033 
1034 			case B_INT64_TYPE:
1035 			{
1036 				value.fPrimitive.SetTo(~fPrimitive.ToInt64());
1037 				break;
1038 			}
1039 
1040 			case B_UINT64_TYPE:
1041 			{
1042 				value.fPrimitive.SetTo(~fPrimitive.ToUInt64());
1043 				break;
1044 			}
1045 		}
1046 
1047 		return value;
1048 	}
1049 
operator <(const Operand & rhs) const1050 	int operator<(const Operand& rhs) const
1051 	{
1052 		Operand lhs = *this;
1053 		Operand temp = rhs;
1054 
1055 		lhs._ResolveTypesIfNeeded(temp);
1056 
1057 		int result = 0;
1058 		switch (fPrimitive.Type()) {
1059 			case B_INT8_TYPE:
1060 			{
1061 				result = lhs.fPrimitive.ToInt8() < temp.fPrimitive.ToInt8();
1062 				break;
1063 			}
1064 
1065 			case B_UINT8_TYPE:
1066 			{
1067 				result = lhs.fPrimitive.ToUInt8() < temp.fPrimitive.ToUInt8();
1068 				break;
1069 			}
1070 
1071 			case B_INT16_TYPE:
1072 			{
1073 				result = lhs.fPrimitive.ToInt16() < temp.fPrimitive.ToInt16();
1074 				break;
1075 			}
1076 
1077 			case B_UINT16_TYPE:
1078 			{
1079 				result = lhs.fPrimitive.ToUInt16()
1080 					< temp.fPrimitive.ToUInt16();
1081 				break;
1082 			}
1083 
1084 			case B_INT32_TYPE:
1085 			{
1086 				result = lhs.fPrimitive.ToInt32() < temp.fPrimitive.ToInt32();
1087 				break;
1088 			}
1089 
1090 			case B_UINT32_TYPE:
1091 			{
1092 				result = lhs.fPrimitive.ToUInt32()
1093 					< temp.fPrimitive.ToUInt32();
1094 				break;
1095 			}
1096 
1097 			case B_INT64_TYPE:
1098 			{
1099 				result = lhs.fPrimitive.ToInt64() < temp.fPrimitive.ToInt64();
1100 				break;
1101 			}
1102 
1103 			case B_UINT64_TYPE:
1104 			{
1105 				result = lhs.fPrimitive.ToUInt64()
1106 					< temp.fPrimitive.ToUInt64();
1107 				break;
1108 			}
1109 
1110 			case B_FLOAT_TYPE:
1111 			{
1112 				result = lhs.fPrimitive.ToFloat() < temp.fPrimitive.ToFloat();
1113 				break;
1114 			}
1115 
1116 			case B_DOUBLE_TYPE:
1117 			{
1118 				result = lhs.fPrimitive.ToDouble()
1119 					< temp.fPrimitive.ToDouble();
1120 				break;
1121 			}
1122 		}
1123 
1124 		return result;
1125 	}
1126 
operator <=(const Operand & rhs) const1127 	int operator<=(const Operand& rhs) const
1128 	{
1129 		return (*this < rhs) || (*this == rhs);
1130 	}
1131 
operator >(const Operand & rhs) const1132 	int operator>(const Operand& rhs) const
1133 	{
1134 		Operand lhs = *this;
1135 		Operand temp = rhs;
1136 		lhs._ResolveTypesIfNeeded(temp);
1137 
1138 		int result = 0;
1139 		switch (fPrimitive.Type()) {
1140 			case B_INT8_TYPE:
1141 			{
1142 				result = lhs.fPrimitive.ToInt8() > temp.fPrimitive.ToInt8();
1143 				break;
1144 			}
1145 
1146 			case B_UINT8_TYPE:
1147 			{
1148 				result = lhs.fPrimitive.ToUInt8() > temp.fPrimitive.ToUInt8();
1149 				break;
1150 			}
1151 
1152 			case B_INT16_TYPE:
1153 			{
1154 				result = lhs.fPrimitive.ToInt16() > temp.fPrimitive.ToInt16();
1155 				break;
1156 			}
1157 
1158 			case B_UINT16_TYPE:
1159 			{
1160 				result = lhs.fPrimitive.ToUInt16()
1161 					> temp.fPrimitive.ToUInt16();
1162 				break;
1163 			}
1164 
1165 			case B_INT32_TYPE:
1166 			{
1167 				result = lhs.fPrimitive.ToInt32() > temp.fPrimitive.ToInt32();
1168 				break;
1169 			}
1170 
1171 			case B_UINT32_TYPE:
1172 			{
1173 				result = lhs.fPrimitive.ToUInt32()
1174 					> temp.fPrimitive.ToUInt32();
1175 				break;
1176 			}
1177 
1178 			case B_INT64_TYPE:
1179 			{
1180 				result = lhs.fPrimitive.ToInt64() > temp.fPrimitive.ToInt64();
1181 				break;
1182 			}
1183 
1184 			case B_UINT64_TYPE:
1185 			{
1186 				result = lhs.fPrimitive.ToUInt64()
1187 					> temp.fPrimitive.ToUInt64();
1188 				break;
1189 			}
1190 
1191 			case B_FLOAT_TYPE:
1192 			{
1193 				result = lhs.fPrimitive.ToFloat() > temp.fPrimitive.ToFloat();
1194 				break;
1195 			}
1196 
1197 			case B_DOUBLE_TYPE:
1198 			{
1199 				result = lhs.fPrimitive.ToDouble()
1200 					> temp.fPrimitive.ToDouble();
1201 				break;
1202 			}
1203 		}
1204 
1205 		return result;
1206 	}
1207 
operator >=(const Operand & rhs) const1208 	int operator>=(const Operand& rhs) const
1209 	{
1210 		return (*this > rhs) || (*this == rhs);
1211 	}
1212 
operator ==(const Operand & rhs) const1213 	int	operator==(const Operand& rhs) const
1214 	{
1215 		Operand lhs = *this;
1216 		Operand temp = rhs;
1217 		lhs._ResolveTypesIfNeeded(temp);
1218 
1219 		int result = 0;
1220 		switch (fPrimitive.Type()) {
1221 			case B_INT8_TYPE:
1222 			{
1223 				result = lhs.fPrimitive.ToInt8() == temp.fPrimitive.ToInt8();
1224 				break;
1225 			}
1226 
1227 			case B_UINT8_TYPE:
1228 			{
1229 				result = lhs.fPrimitive.ToUInt8() == temp.fPrimitive.ToUInt8();
1230 				break;
1231 			}
1232 
1233 			case B_INT16_TYPE:
1234 			{
1235 				result = lhs.fPrimitive.ToInt16() == temp.fPrimitive.ToInt16();
1236 				break;
1237 			}
1238 
1239 			case B_UINT16_TYPE:
1240 			{
1241 				result = lhs.fPrimitive.ToUInt16()
1242 					== temp.fPrimitive.ToUInt16();
1243 				break;
1244 			}
1245 
1246 			case B_INT32_TYPE:
1247 			{
1248 				result = lhs.fPrimitive.ToInt32() == temp.fPrimitive.ToInt32();
1249 				break;
1250 			}
1251 
1252 			case B_UINT32_TYPE:
1253 			{
1254 				result = lhs.fPrimitive.ToUInt32()
1255 					== temp.fPrimitive.ToUInt32();
1256 				break;
1257 			}
1258 
1259 			case B_INT64_TYPE:
1260 			{
1261 				result = lhs.fPrimitive.ToInt64() == temp.fPrimitive.ToInt64();
1262 				break;
1263 			}
1264 
1265 			case B_UINT64_TYPE:
1266 			{
1267 				result = lhs.fPrimitive.ToUInt64()
1268 					== temp.fPrimitive.ToUInt64();
1269 				break;
1270 			}
1271 
1272 			case B_FLOAT_TYPE:
1273 			{
1274 				result = lhs.fPrimitive.ToFloat() == temp.fPrimitive.ToFloat();
1275 				break;
1276 			}
1277 
1278 			case B_DOUBLE_TYPE:
1279 			{
1280 				result = lhs.fPrimitive.ToDouble()
1281 					== temp.fPrimitive.ToDouble();
1282 				break;
1283 			}
1284 		}
1285 
1286 		return result;
1287 	}
1288 
operator !=(const Operand & rhs) const1289 	int operator!=(const Operand& rhs) const
1290 	{
1291 		return !(*this == rhs);
1292 	}
1293 
1294 private:
_GetAsType(type_code type)1295 	void _GetAsType(type_code type)
1296 	{
1297 		switch (type) {
1298 			case B_INT8_TYPE:
1299 				fPrimitive.SetTo(fPrimitive.ToInt8());
1300 				break;
1301 			case B_UINT8_TYPE:
1302 				fPrimitive.SetTo(fPrimitive.ToUInt8());
1303 				break;
1304 			case B_INT16_TYPE:
1305 				fPrimitive.SetTo(fPrimitive.ToInt16());
1306 				break;
1307 			case B_UINT16_TYPE:
1308 				fPrimitive.SetTo(fPrimitive.ToUInt16());
1309 				break;
1310 			case B_INT32_TYPE:
1311 				fPrimitive.SetTo(fPrimitive.ToInt32());
1312 				break;
1313 			case B_UINT32_TYPE:
1314 				fPrimitive.SetTo(fPrimitive.ToUInt32());
1315 				break;
1316 			case B_INT64_TYPE:
1317 				fPrimitive.SetTo(fPrimitive.ToInt64());
1318 				break;
1319 			case B_UINT64_TYPE:
1320 				fPrimitive.SetTo(fPrimitive.ToUInt64());
1321 				break;
1322 			case B_FLOAT_TYPE:
1323 				fPrimitive.SetTo(fPrimitive.ToFloat());
1324 				break;
1325 			case B_DOUBLE_TYPE:
1326 				fPrimitive.SetTo(fPrimitive.ToDouble());
1327 				break;
1328 		}
1329 	}
1330 
_ResolveTypesIfNeeded(Operand & other)1331 	void _ResolveTypesIfNeeded(Operand& other)
1332 	{
1333 		_ResolveToPrimitive();
1334 		other._ResolveToPrimitive();
1335 
1336 		if (!fPrimitive.IsNumber() || !other.fPrimitive.IsNumber()) {
1337 				throw ParseException("Cannot perform mathematical operations "
1338 					"between non-numerical objects.", 0);
1339 		}
1340 
1341 		type_code thisType = fPrimitive.Type();
1342 		type_code otherType = other.fPrimitive.Type();
1343 
1344 		if (thisType == otherType)
1345 			return;
1346 
1347 		type_code resolvedType = _ResolvePriorityType(thisType, otherType);
1348 		if (thisType != resolvedType)
1349 			_GetAsType(resolvedType);
1350 
1351 		if (otherType != resolvedType)
1352 			other._GetAsType(resolvedType);
1353 	}
1354 
_ResolveToPrimitive()1355 	void _ResolveToPrimitive()
1356 	{
1357 		if (Kind() == OPERAND_KIND_PRIMITIVE)
1358 			return;
1359 		else if (Kind() == OPERAND_KIND_TYPE) {
1360 			throw ParseException("Cannot perform mathematical operations "
1361 				"between type objects.", 0);
1362 		}
1363 
1364 		status_t error = fValueNode->LocationAndValueResolutionState();
1365 		if (error != B_OK) {
1366 			BString errorMessage;
1367 			errorMessage.SetToFormat("Failed to resolve value of %s: %"
1368 				B_PRId32 ".", fValueNode->Name().String(), error);
1369 			throw ParseException(errorMessage.String(), 0);
1370 		}
1371 
1372 		Value* value = fValueNode->GetValue();
1373 		BVariant tempValue;
1374 		if (value->ToVariant(tempValue))
1375 			SetTo(tempValue);
1376 		else {
1377 			BString error;
1378 			error.SetToFormat("Failed to retrieve value of %s.",
1379 				fValueNode->Name().String());
1380 			throw ParseException(error.String(), 0);
1381 		}
1382 	}
1383 
_ResolvePriorityType(type_code lhs,type_code rhs) const1384 	type_code _ResolvePriorityType(type_code lhs, type_code rhs) const
1385 	{
1386 		size_t byteSize = std::max(BVariant::SizeOfType(lhs),
1387 			BVariant::SizeOfType(rhs));
1388 		bool isFloat = BVariant::TypeIsFloat(lhs)
1389 			|| BVariant::TypeIsFloat(rhs);
1390 		bool isSigned = isFloat;
1391 		if (!isFloat) {
1392 			BVariant::TypeIsInteger(lhs, &isSigned);
1393 			if (!isSigned)
1394 				BVariant::TypeIsInteger(rhs, &isSigned);
1395 		}
1396 
1397 		if (isFloat) {
1398 			if (byteSize == sizeof(float))
1399 				return B_FLOAT_TYPE;
1400 			return B_DOUBLE_TYPE;
1401 		}
1402 
1403 		switch (byteSize) {
1404 			case 1:
1405 				return isSigned ? B_INT8_TYPE : B_UINT8_TYPE;
1406 			case 2:
1407 				return isSigned ? B_INT16_TYPE : B_UINT16_TYPE;
1408 			case 4:
1409 				return isSigned ? B_INT32_TYPE : B_UINT32_TYPE;
1410 			case 8:
1411 				return isSigned ? B_INT64_TYPE : B_UINT64_TYPE;
1412 			default:
1413 				break;
1414 		}
1415 
1416 		BString error;
1417 		error.SetToFormat("Unable to reconcile types %#" B_PRIx32
1418 			" and %#" B_PRIx32, lhs, rhs);
1419 		throw ParseException(error.String(), 0);
1420 	}
1421 
1422 private:
1423 	BVariant 		fPrimitive;
1424 	ValueNode*		fValueNode;
1425 	Type*			fType;
1426 	operand_kind	fKind;
1427 };
1428 
1429 
1430 // #pragma mark - CLanguageExpressionEvaluator
1431 
1432 
CLanguageExpressionEvaluator()1433 CLanguageExpressionEvaluator::CLanguageExpressionEvaluator()
1434 	:
1435 	fTokenizer(new Tokenizer()),
1436 	fTypeInfo(NULL),
1437 	fNodeManager(NULL)
1438 {
1439 }
1440 
1441 
~CLanguageExpressionEvaluator()1442 CLanguageExpressionEvaluator::~CLanguageExpressionEvaluator()
1443 {
1444 	delete fTokenizer;
1445 }
1446 
1447 
1448 ExpressionResult*
Evaluate(const char * expressionString,ValueNodeManager * manager,TeamTypeInformation * info)1449 CLanguageExpressionEvaluator::Evaluate(const char* expressionString,
1450 	ValueNodeManager* manager, TeamTypeInformation* info)
1451 {
1452 	fNodeManager = manager;
1453 	fTypeInfo = info;
1454 	fTokenizer->SetTo(expressionString);
1455 
1456 	Operand value = _ParseSum();
1457 	Token token = fTokenizer->NextToken();
1458 	if (token.type != TOKEN_END_OF_LINE)
1459 		throw ParseException("parse error", token.position);
1460 
1461 	ExpressionResult* result = new(std::nothrow)ExpressionResult;
1462 	if (result != NULL) {
1463 		BReference<ExpressionResult> resultReference(result, true);
1464 		if (value.Kind() == OPERAND_KIND_PRIMITIVE) {
1465 			Value* outputValue = NULL;
1466 			BVariant primitive = value.PrimitiveValue();
1467 			if (primitive.IsInteger())
1468 				outputValue = new(std::nothrow) IntegerValue(primitive);
1469 			else if (primitive.IsFloat()) {
1470 				outputValue = new(std::nothrow) FloatValue(
1471 					primitive.ToDouble());
1472 			}
1473 
1474 			BReference<Value> valueReference;
1475 			if (outputValue != NULL) {
1476 				valueReference.SetTo(outputValue, true);
1477 				result->SetToPrimitive(outputValue);
1478 			} else
1479 				return NULL;
1480 		} else if (value.Kind() == OPERAND_KIND_VALUE_NODE)
1481 			result->SetToValueNode(value.GetValueNode()->NodeChild());
1482 		else if (value.Kind() == OPERAND_KIND_TYPE)
1483 			result->SetToType(value.GetType());
1484 
1485 		resultReference.Detach();
1486 	}
1487 
1488 	return result;
1489 }
1490 
1491 
1492 CLanguageExpressionEvaluator::Operand
_ParseSum()1493 CLanguageExpressionEvaluator::_ParseSum()
1494 {
1495 	Operand value = _ParseProduct();
1496 
1497 	while (true) {
1498 		Token token = fTokenizer->NextToken();
1499 		switch (token.type) {
1500 			case TOKEN_PLUS:
1501 				value += _ParseProduct();
1502 				break;
1503 			case TOKEN_MINUS:
1504 				value -= _ParseProduct();
1505 				break;
1506 
1507 			default:
1508 				fTokenizer->RewindToken();
1509 				return value;
1510 		}
1511 	}
1512 }
1513 
1514 
1515 CLanguageExpressionEvaluator::Operand
_ParseProduct()1516 CLanguageExpressionEvaluator::_ParseProduct()
1517 {
1518 	static Operand zero(int64(0LL));
1519 
1520 	Operand value = _ParseUnary();
1521 
1522 	while (true) {
1523 		Token token = fTokenizer->NextToken();
1524 		switch (token.type) {
1525 			case TOKEN_STAR:
1526 				value *= _ParseUnary();
1527 				break;
1528 			case TOKEN_SLASH:
1529 			{
1530 				Operand rhs = _ParseUnary();
1531 				if (rhs == zero)
1532 					throw ParseException("division by zero", token.position);
1533 				value /= rhs;
1534 				break;
1535 			}
1536 
1537 			case TOKEN_MODULO:
1538 			{
1539 				Operand rhs = _ParseUnary();
1540 				if (rhs == zero)
1541 					throw ParseException("modulo by zero", token.position);
1542 				value %= rhs;
1543 				break;
1544 			}
1545 
1546 			case TOKEN_LOGICAL_AND:
1547 			{
1548 				value.SetTo((value != zero)
1549 					&& (_ParseUnary() != zero));
1550 
1551 				break;
1552 			}
1553 
1554 			case TOKEN_LOGICAL_OR:
1555 			{
1556 				value.SetTo((value != zero)
1557 					|| (_ParseUnary() != zero));
1558 				break;
1559 			}
1560 
1561 			case TOKEN_BITWISE_AND:
1562 				value &= _ParseUnary();
1563 				break;
1564 
1565 			case TOKEN_BITWISE_OR:
1566 				value |= _ParseUnary();
1567 				break;
1568 
1569 			case TOKEN_BITWISE_XOR:
1570 				value ^= _ParseUnary();
1571 				break;
1572 
1573 			case TOKEN_EQ:
1574 				value.SetTo((int64)(value == _ParseUnary()));
1575 				break;
1576 
1577 			case TOKEN_NE:
1578 				value.SetTo((int64)(value != _ParseUnary()));
1579 				break;
1580 
1581 			case TOKEN_GT:
1582 				value.SetTo((int64)(value > _ParseUnary()));
1583 				break;
1584 
1585 			case TOKEN_GE:
1586 				value.SetTo((int64)(value >= _ParseUnary()));
1587 				break;
1588 
1589 			case TOKEN_LT:
1590 				value.SetTo((int64)(value < _ParseUnary()));
1591 				break;
1592 
1593 			case TOKEN_LE:
1594 				value.SetTo((int64)(value <= _ParseUnary()));
1595 				break;
1596 
1597 			default:
1598 				fTokenizer->RewindToken();
1599 				return value;
1600 		}
1601 	}
1602 }
1603 
1604 
1605 CLanguageExpressionEvaluator::Operand
_ParseUnary()1606 CLanguageExpressionEvaluator::_ParseUnary()
1607 {
1608 	Token token = fTokenizer->NextToken();
1609 	if (token.type == TOKEN_END_OF_LINE)
1610 		throw ParseException("unexpected end of expression", token.position);
1611 
1612 	switch (token.type) {
1613 		case TOKEN_PLUS:
1614 			return _ParseUnary();
1615 
1616 		case TOKEN_MINUS:
1617 			return -_ParseUnary();
1618 
1619 		case TOKEN_BITWISE_NOT:
1620 			return ~_ParseUnary();
1621 
1622 		case TOKEN_LOGICAL_NOT:
1623 		{
1624 			Operand zero((int64)0);
1625 			return Operand((int64)(_ParseUnary() == zero));
1626 		}
1627 
1628 		case TOKEN_IDENTIFIER:
1629 			fTokenizer->RewindToken();
1630 			return _ParseIdentifier();
1631 
1632 		default:
1633 			fTokenizer->RewindToken();
1634 			return _ParseAtom();
1635 	}
1636 
1637 	return Operand();
1638 }
1639 
1640 
1641 CLanguageExpressionEvaluator::Operand
_ParseIdentifier(ValueNode * parentNode)1642 CLanguageExpressionEvaluator::_ParseIdentifier(ValueNode* parentNode)
1643 {
1644 	Token token = fTokenizer->NextToken();
1645 	const BString& identifierName = token.string;
1646 
1647 	ValueNodeChild* child = NULL;
1648 	if (fNodeManager != NULL) {
1649 		ValueNodeContainer* container = fNodeManager->GetContainer();
1650 		AutoLocker<ValueNodeContainer> containerLocker(container);
1651 
1652 		if (parentNode == NULL) {
1653 			ValueNodeChild* thisChild = NULL;
1654 			for (int32 i = 0; i < container->CountChildren(); i++) {
1655 				ValueNodeChild* current = container->ChildAt(i);
1656 				const BString& nodeName = current->Name();
1657 				if (nodeName == identifierName) {
1658 					child = current;
1659 					break;
1660 				} else if (nodeName == "this")
1661 					thisChild = current;
1662 			}
1663 
1664 			if (child == NULL && thisChild != NULL) {
1665 				// the name was not found in the variables or parameters,
1666 				// but we have a class pointer. Try to find the name in the
1667 				// list of members.
1668 				_RequestValueIfNeeded(token, thisChild);
1669 				ValueNode* thisNode = thisChild->Node();
1670 				fTokenizer->RewindToken();
1671 				return _ParseIdentifier(thisNode);
1672 			}
1673 		} else {
1674 			// skip intermediate address nodes
1675 			if (parentNode->GetType()->Kind() == TYPE_ADDRESS
1676 				&& parentNode->CountChildren() == 1) {
1677 				child = parentNode->ChildAt(0);
1678 
1679 				_RequestValueIfNeeded(token, child);
1680 				parentNode = child->Node();
1681 				fTokenizer->RewindToken();
1682 				return _ParseIdentifier(parentNode);
1683 			}
1684 
1685 			for (int32 i = 0; i < parentNode->CountChildren(); i++) {
1686 				ValueNodeChild* current = parentNode->ChildAt(i);
1687 				const BString& nodeName = current->Name();
1688 				if (nodeName == identifierName) {
1689 					child = current;
1690 					break;
1691 				}
1692 			}
1693 		}
1694 	}
1695 
1696 	if (child == NULL && fTypeInfo != NULL) {
1697 		Type* resultType = NULL;
1698 		status_t error = fTypeInfo->LookupTypeByName(identifierName,
1699 			TypeLookupConstraints(), resultType);
1700 		if (error == B_OK) {
1701 			BReference<Type> typeReference(resultType, true);
1702 			return _ParseType(resultType);
1703 		} else if (error != B_ENTRY_NOT_FOUND) {
1704 			BString errorMessage;
1705 			errorMessage.SetToFormat("Failed to look up type name '%s': %"
1706 				B_PRId32 ".", identifierName.String(), error);
1707 			throw ParseException(errorMessage.String(), token.position);
1708 		}
1709 	}
1710 
1711 	BString errorMessage;
1712 	if (child == NULL) {
1713 		errorMessage.SetToFormat("Unable to resolve variable name: '%s'",
1714 			identifierName.String());
1715 		throw ParseException(errorMessage, token.position);
1716 	}
1717 
1718 	_RequestValueIfNeeded(token, child);
1719 	ValueNode* node = child->Node();
1720 
1721 	token = fTokenizer->NextToken();
1722 	if (token.type == TOKEN_MEMBER_PTR) {
1723 		token = fTokenizer->NextToken();
1724 		if (token.type == TOKEN_IDENTIFIER) {
1725 			fTokenizer->RewindToken();
1726 			return _ParseIdentifier(node);
1727 		} else {
1728 			throw ParseException("Expected identifier after member "
1729 				"dereference.", token.position);
1730 		}
1731 	} else
1732 		fTokenizer->RewindToken();
1733 
1734 	return Operand(node);
1735 }
1736 
1737 
1738 CLanguageExpressionEvaluator::Operand
_ParseAtom()1739 CLanguageExpressionEvaluator::_ParseAtom()
1740 {
1741 	Token token = fTokenizer->NextToken();
1742 	if (token.type == TOKEN_END_OF_LINE)
1743 		throw ParseException("Unexpected end of expression", token.position);
1744 
1745 	Operand value;
1746 
1747 	if (token.type == TOKEN_CONSTANT)
1748 		value.SetTo(token.value);
1749 	else {
1750 		fTokenizer->RewindToken();
1751 
1752 		_EatToken(TOKEN_OPENING_PAREN);
1753 
1754 		value = _ParseSum();
1755 
1756 		_EatToken(TOKEN_CLOSING_PAREN);
1757 	}
1758 
1759 	if (value.Kind() == OPERAND_KIND_TYPE) {
1760 		token = fTokenizer->NextToken();
1761 		if (token.type == TOKEN_END_OF_LINE)
1762 			return value;
1763 
1764 		Type* castType = value.GetType();
1765 		// if our evaluated result was a type, and there still remain
1766 		// further tokens to evaluate, then this is a typecast for
1767 		// a subsequent expression. Attempt to evaluate it, and then
1768 		// apply the cast to the result.
1769 		fTokenizer->RewindToken();
1770 		value = _ParseSum();
1771 		ValueNodeChild* child = NULL;
1772 		if (value.Kind() != OPERAND_KIND_PRIMITIVE
1773 			&& value.Kind() != OPERAND_KIND_VALUE_NODE) {
1774 			throw ParseException("Expected value or variable expression after"
1775 				" typecast.", token.position);
1776 		}
1777 
1778 		if (value.Kind() == OPERAND_KIND_VALUE_NODE)
1779 			child = value.GetValueNode()->NodeChild();
1780 		else if (value.Kind() == OPERAND_KIND_PRIMITIVE)
1781 			_GetNodeChildForPrimitive(token, value.PrimitiveValue(), child);
1782 
1783 		ValueNode* newNode = NULL;
1784 		status_t error = TypeHandlerRoster::Default()->CreateValueNode(child,
1785 			castType, NULL, newNode);
1786 		if (error != B_OK) {
1787 			throw ParseException("Unable to create value node for typecast"
1788 				" operation.", token.position);
1789 		}
1790 		child->SetNode(newNode);
1791 		value.SetTo(newNode);
1792 	}
1793 
1794 	return value;
1795 }
1796 
1797 
1798 void
_EatToken(int32 type)1799 CLanguageExpressionEvaluator::_EatToken(int32 type)
1800 {
1801 	Token token = fTokenizer->NextToken();
1802 	if (token.type != type) {
1803 		BString expected;
1804 		switch (type) {
1805 			case TOKEN_IDENTIFIER:
1806 				expected = "an identifier";
1807 				break;
1808 
1809 			case TOKEN_CONSTANT:
1810 				expected = "a constant";
1811 				break;
1812 
1813 			case TOKEN_SLASH:
1814 				expected = "'/', '\\', or ':'";
1815 				break;
1816 
1817 			case TOKEN_END_OF_LINE:
1818 				expected = "'\\n'";
1819 				break;
1820 
1821 			default:
1822 				expected << "'" << TokenTypeToString(type) << "'";
1823 				break;
1824 		}
1825 
1826 		BString temp;
1827 		temp << "Expected " << expected.String() << " got '" << token.string
1828 			<< "'";
1829 		throw ParseException(temp.String(), token.position);
1830 	}
1831 }
1832 
1833 
1834 CLanguageExpressionEvaluator::Operand
_ParseType(Type * baseType)1835 CLanguageExpressionEvaluator::_ParseType(Type* baseType)
1836 {
1837 	BReference<Type> typeReference;
1838 	Type* finalType = baseType;
1839 
1840 	bool arraySpecifierEncountered = false;
1841 	status_t error;
1842 	for (;;) {
1843 		Token token = fTokenizer->NextToken();
1844 		if (token.type == TOKEN_STAR || token.type == TOKEN_BITWISE_AND) {
1845 			if (arraySpecifierEncountered)
1846 				break;
1847 
1848 			address_type_kind addressKind = (token.type == TOKEN_STAR)
1849 					? DERIVED_TYPE_POINTER : DERIVED_TYPE_REFERENCE;
1850 			AddressType* derivedType = NULL;
1851 			error = finalType->CreateDerivedAddressType(addressKind,
1852 				derivedType);
1853 			if (error != B_OK) {
1854 				BString errorMessage;
1855 				errorMessage.SetToFormat("Failed to create derived address"
1856 					" type %d for base type %s: %s (%" B_PRId32 ")",
1857 					addressKind, finalType->Name().String(), strerror(error),
1858 					error);
1859 				throw ParseException(errorMessage, token.position);
1860 			}
1861 
1862 			finalType = derivedType;
1863 			typeReference.SetTo(finalType, true);
1864 		} else if (token.type == TOKEN_OPENING_SQUARE_BRACKET) {
1865 			Operand indexSize = _ParseSum();
1866 			if (indexSize.Kind() == OPERAND_KIND_TYPE) {
1867 				throw ParseException("Cannot specify type name as array"
1868 					" subscript.", token.position);
1869 			}
1870 
1871 			_EatToken(TOKEN_CLOSING_SQUARE_BRACKET);
1872 
1873 			uint32 resolvedSize = indexSize.PrimitiveValue().ToUInt32();
1874 			if (resolvedSize == 0) {
1875 				throw ParseException("Non-zero array size required in type"
1876 					" specifier.", token.position);
1877 			}
1878 
1879 			ArrayType* derivedType = NULL;
1880 			error = finalType->CreateDerivedArrayType(0, resolvedSize, true,
1881 				derivedType);
1882 			if (error != B_OK) {
1883 				BString errorMessage;
1884 				errorMessage.SetToFormat("Failed to create derived array type"
1885 					" of size %" B_PRIu32 " for base type %s: %s (%"
1886 					B_PRId32 ")", resolvedSize, finalType->Name().String(),
1887 					strerror(error), error);
1888 				throw ParseException(errorMessage, token.position);
1889 			}
1890 
1891 			arraySpecifierEncountered = true;
1892 			finalType = derivedType;
1893 			typeReference.SetTo(finalType, true);
1894 		} else
1895 			break;
1896 	}
1897 
1898 	typeReference.Detach();
1899 	fTokenizer->RewindToken();
1900 	return Operand(finalType);
1901 }
1902 
1903 
1904 void
_RequestValueIfNeeded(const Token & token,ValueNodeChild * child)1905 CLanguageExpressionEvaluator::_RequestValueIfNeeded(
1906 	const Token& token, ValueNodeChild* child)
1907 {
1908 	status_t state;
1909 	BString errorMessage;
1910 	if (child->Node() == NULL) {
1911 		state = fNodeManager->AddChildNodes(child);
1912 		if (state != B_OK) {
1913 			errorMessage.SetToFormat("Unable to add children for node '%s': "
1914 				"%s", child->Name().String(), strerror(state));
1915 			throw ParseException(errorMessage, token.position);
1916 		}
1917 	}
1918 
1919 	state = child->LocationResolutionState();
1920 	if (state == VALUE_NODE_UNRESOLVED)
1921 		throw ValueNeededException(child->Node());
1922 	else if (state != B_OK) {
1923 		errorMessage.SetToFormat("Unable to resolve variable value for '%s': "
1924 			"%s", child->Name().String(), strerror(state));
1925 		throw ParseException(errorMessage, token.position);
1926 	}
1927 
1928 	ValueNode* node = child->Node();
1929 	state = node->LocationAndValueResolutionState();
1930 	if (state == VALUE_NODE_UNRESOLVED)
1931 		throw ValueNeededException(child->Node());
1932 	else if (state != B_OK) {
1933 		errorMessage.SetToFormat("Unable to resolve variable value for '%s': "
1934 			"%s", child->Name().String(), strerror(state));
1935 		throw ParseException(errorMessage, token.position);
1936 	}
1937 }
1938 
1939 
1940 void
_GetNodeChildForPrimitive(const Token & token,const BVariant & value,ValueNodeChild * & _output) const1941 CLanguageExpressionEvaluator::_GetNodeChildForPrimitive(const Token& token,
1942 	const BVariant& value, ValueNodeChild*& _output) const
1943 {
1944 	Type* type = new(std::nothrow) SyntheticPrimitiveType(value.Type());
1945 	if (type == NULL) {
1946 		throw ParseException("Out of memory while creating type object.",
1947 			token.position);
1948 	}
1949 
1950 	BReference<Type> typeReference(type, true);
1951 	ValueLocation* location = new(std::nothrow) ValueLocation();
1952 	if (location == NULL) {
1953 		throw ParseException("Out of memory while creating location object.",
1954 			token.position);
1955 	}
1956 
1957 	BReference<ValueLocation> locationReference(location, true);
1958 	ValuePieceLocation piece;
1959 	if (!piece.SetToValue(value.Bytes(), value.Size())
1960 		|| !location->AddPiece(piece)) {
1961 		throw ParseException("Out of memory populating location"
1962 			" object.", token.position);
1963 	}
1964 
1965 	char variableName[32];
1966 	if (!IntegerFormatter::FormatValue(value, INTEGER_FORMAT_HEX_DEFAULT,
1967 		variableName, sizeof(variableName))) {
1968 		throw ParseException("Failed to generate internal variable name.",
1969 			token.position);
1970 	}
1971 
1972 	InternalVariableID* id = new(std::nothrow) InternalVariableID(value);
1973 	if (id == NULL) {
1974 		throw ParseException("Out of memory while creating ID object.",
1975 			token.position);
1976 	}
1977 
1978 	BReference<ObjectID> idReference(id, true);
1979 	Variable* variable = new(std::nothrow) Variable(id, variableName, type,
1980 		location);
1981 	if (variable == NULL) {
1982 		throw ParseException("Out of memory while creating variable object.",
1983 			token.position);
1984 	}
1985 
1986 	BReference<Variable> variableReference(variable, true);
1987 	_output = new(std::nothrow) VariableValueNodeChild(
1988 		variable);
1989 	if (_output == NULL) {
1990 		throw ParseException("Out of memory while creating node child object.",
1991 			token.position);
1992 	}
1993 }
1994