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 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: 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 173 protected: 174 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: 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 1294 private: 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 1422 private: 1423 BVariant fPrimitive; 1424 ValueNode* fValueNode; 1425 Type* fType; 1426 operand_kind fKind; 1427 }; 1428 1429 1430 // #pragma mark - CLanguageExpressionEvaluator 1431 1432 1433 CLanguageExpressionEvaluator::CLanguageExpressionEvaluator() 1434 : 1435 fTokenizer(new Tokenizer()), 1436 fTypeInfo(NULL), 1437 fNodeManager(NULL) 1438 { 1439 } 1440 1441 1442 CLanguageExpressionEvaluator::~CLanguageExpressionEvaluator() 1443 { 1444 delete fTokenizer; 1445 } 1446 1447 1448 ExpressionResult* 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 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 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 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 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 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 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 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 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 1941 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