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
39using namespace CLanguage;
40
41
42enum operand_kind {
43	OPERAND_KIND_UNKNOWN = 0,
44	OPERAND_KIND_PRIMITIVE,
45	OPERAND_KIND_TYPE,
46	OPERAND_KIND_VALUE_NODE
47};
48
49
50static 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
151class CLanguageExpressionEvaluator::InternalVariableID : public ObjectID {
152public:
153	InternalVariableID(const BVariant& value)
154		:
155		fValue(value)
156	{
157	}
158
159	virtual ~InternalVariableID()
160	{
161	}
162
163	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
173protected:
174	virtual	uint32 ComputeHashValue() const
175	{
176		return *(uint32*)(&fValue);
177	}
178
179private:
180	BVariant fValue;
181};
182
183
184// #pragma mark - CLanguageExpressionEvaluator::Operand
185
186
187class CLanguageExpressionEvaluator::Operand {
188public:
189	Operand()
190		:
191		fPrimitive(),
192		fValueNode(NULL),
193		fType(NULL),
194		fKind(OPERAND_KIND_UNKNOWN)
195	{
196	}
197
198	Operand(int64 value)
199		:
200		fPrimitive(value),
201		fValueNode(NULL),
202		fType(NULL),
203		fKind(OPERAND_KIND_PRIMITIVE)
204	{
205	}
206
207	Operand(double value)
208		:
209		fPrimitive(value),
210		fValueNode(NULL),
211		fType(NULL),
212		fKind(OPERAND_KIND_PRIMITIVE)
213	{
214	}
215
216	Operand(ValueNode* node)
217		:
218		fPrimitive(),
219		fValueNode(NULL),
220		fType(NULL),
221		fKind(OPERAND_KIND_UNKNOWN)
222	{
223		SetTo(node);
224	}
225
226	Operand(Type* type)
227		:
228		fPrimitive(),
229		fValueNode(NULL),
230		fType(NULL),
231		fKind(OPERAND_KIND_UNKNOWN)
232	{
233		SetTo(type);
234	}
235
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
247	virtual ~Operand()
248	{
249		Unset();
250	}
251
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
275	void SetTo(const BVariant& value)
276	{
277		Unset();
278		fPrimitive = value;
279		fKind = OPERAND_KIND_PRIMITIVE;
280	}
281
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
295	void SetTo(Type* type)
296	{
297		Unset();
298		fType = type;
299		fType->AcquireReference();
300
301		fKind = OPERAND_KIND_TYPE;
302	}
303
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
317	inline operand_kind Kind() const
318	{
319		return fKind;
320	}
321
322	inline const BVariant& PrimitiveValue() const
323	{
324		return fPrimitive;
325	}
326
327	inline ValueNode* GetValueNode() const
328	{
329		return fValueNode;
330
331	}
332
333	inline Type* GetType() const
334	{
335		return fType;
336	}
337
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
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
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
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
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
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
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
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
922	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
992	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
1050	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
1127	int operator<=(const Operand& rhs) const
1128	{
1129		return (*this < rhs) || (*this == rhs);
1130	}
1131
1132	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
1208	int operator>=(const Operand& rhs) const
1209	{
1210		return (*this > rhs) || (*this == rhs);
1211	}
1212
1213	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
1289	int operator!=(const Operand& rhs) const
1290	{
1291		return !(*this == rhs);
1292	}
1293
1294private:
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
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
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
1384	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
1422private:
1423	BVariant 		fPrimitive;
1424	ValueNode*		fValueNode;
1425	Type*			fType;
1426	operand_kind	fKind;
1427};
1428
1429
1430// #pragma mark - CLanguageExpressionEvaluator
1431
1432
1433CLanguageExpressionEvaluator::CLanguageExpressionEvaluator()
1434	:
1435	fTokenizer(new Tokenizer()),
1436	fTypeInfo(NULL),
1437	fNodeManager(NULL)
1438{
1439}
1440
1441
1442CLanguageExpressionEvaluator::~CLanguageExpressionEvaluator()
1443{
1444	delete fTokenizer;
1445}
1446
1447
1448ExpressionResult*
1449CLanguageExpressionEvaluator::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
1492CLanguageExpressionEvaluator::Operand
1493CLanguageExpressionEvaluator::_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
1515CLanguageExpressionEvaluator::Operand
1516CLanguageExpressionEvaluator::_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
1605CLanguageExpressionEvaluator::Operand
1606CLanguageExpressionEvaluator::_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
1641CLanguageExpressionEvaluator::Operand
1642CLanguageExpressionEvaluator::_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
1738CLanguageExpressionEvaluator::Operand
1739CLanguageExpressionEvaluator::_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
1798void
1799CLanguageExpressionEvaluator::_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
1834CLanguageExpressionEvaluator::Operand
1835CLanguageExpressionEvaluator::_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
1904void
1905CLanguageExpressionEvaluator::_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
1940void
1941CLanguageExpressionEvaluator::_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