1 /// Author: Aziz Köksal 2 /// License: GPL3 3 /// $(Maturity high) 4 module dil.ast.Expressions; 5 6 public import dil.ast.Expression; 7 import dil.ast.Node, 8 dil.ast.Types, 9 dil.ast.Declarations, 10 dil.ast.Statements, 11 dil.ast.Parameters, 12 dil.ast.NodeCopier, 13 dil.ast.Meta; 14 import dil.lexer.Identifier; 15 import dil.semantic.Types; 16 import dil.Float, 17 dil.Complex, 18 dil.String; 19 import common; 20 21 class IllegalExpr : Expression 22 { 23 mixin(memberInfo()); 24 this() 25 { 26 mixin(set_kind); 27 } 28 mixin methods; 29 } 30 31 /// The base class for every binary operator. 32 /// 33 /// The copy method is mixed in here, not in any derived class. 34 /// If a derived class has other nodes than lhs and rhs, then it has 35 /// to have its own copy method which handles additional nodes. 36 abstract class BinaryExpr : Expression 37 { 38 Expression lhs; /// Left-hand side expression. 39 Expression rhs; /// Right-hand side expression. 40 Token* optok; /// The operator token. 41 42 mixin(memberInfo("lhs", "rhs", "optok")); 43 44 /// Constructs a BinaryExpr object. 45 this(Expression lhs, Expression rhs, Token* optok) 46 { 47 addChildren([lhs, rhs]); 48 this.lhs = lhs; 49 this.rhs = rhs; 50 this.optok = optok; 51 } 52 mixin copyMethod; 53 } 54 55 class CondExpr : BinaryExpr 56 { 57 Expression condition; 58 Token* ctok; // Colon token. 59 60 mixin(memberInfo("condition", "lhs", "rhs", "optok", "ctok")); 61 62 this(Expression condition, Expression left, Expression right, 63 Token* qtok, Token* ctok) 64 { 65 addChild(condition); 66 super(left, right, qtok); 67 mixin(set_kind); 68 this.condition = condition; 69 this.ctok = ctok; 70 } 71 mixin methods; 72 } 73 74 class CommaExpr : BinaryExpr 75 { 76 this(Expression left, Expression right, Token* optok) 77 { 78 super(left, right, optok); 79 mixin(set_kind); 80 } 81 mixin methods; 82 } 83 84 class OrOrExpr : BinaryExpr 85 { 86 this(Expression left, Expression right, Token* optok) 87 { 88 super(left, right, optok); 89 mixin(set_kind); 90 } 91 mixin methods; 92 } 93 94 class AndAndExpr : BinaryExpr 95 { 96 this(Expression left, Expression right, Token* optok) 97 { 98 super(left, right, optok); 99 mixin(set_kind); 100 } 101 mixin methods; 102 } 103 104 class OrExpr : BinaryExpr 105 { 106 this(Expression left, Expression right, Token* optok) 107 { 108 super(left, right, optok); 109 mixin(set_kind); 110 } 111 mixin methods; 112 } 113 114 class XorExpr : BinaryExpr 115 { 116 this(Expression left, Expression right, Token* optok) 117 { 118 super(left, right, optok); 119 mixin(set_kind); 120 } 121 mixin methods; 122 } 123 124 class AndExpr : BinaryExpr 125 { 126 this(Expression left, Expression right, Token* optok) 127 { 128 super(left, right, optok); 129 mixin(set_kind); 130 } 131 mixin methods; 132 } 133 134 /// This class isn't strictly needed, just here for clarity. 135 abstract class CmpExpr : BinaryExpr 136 { 137 this(Expression left, Expression right, Token* optok) 138 { 139 super(left, right, optok); 140 } 141 } 142 143 class EqualExpr : CmpExpr 144 { 145 this(Expression left, Expression right, Token* optok) 146 { 147 super(left, right, optok); 148 mixin(set_kind); 149 } 150 mixin methods; 151 } 152 153 /// Expression "!"? "is" Expression 154 class IdentityExpr : CmpExpr 155 { 156 this(Expression left, Expression right, Token* optok) 157 { 158 super(left, right, optok); 159 mixin(set_kind); 160 } 161 mixin methods; 162 } 163 164 class RelExpr : CmpExpr 165 { 166 this(Expression left, Expression right, Token* optok) 167 { 168 super(left, right, optok); 169 mixin(set_kind); 170 } 171 mixin methods; 172 } 173 174 class InExpr : BinaryExpr 175 { 176 this(Expression left, Expression right, Token* optok) 177 { 178 super(left, right, optok); 179 mixin(set_kind); 180 } 181 mixin methods; 182 } 183 184 class LShiftExpr : BinaryExpr 185 { 186 this(Expression left, Expression right, Token* optok) 187 { 188 super(left, right, optok); 189 mixin(set_kind); 190 } 191 mixin methods; 192 } 193 194 class RShiftExpr : BinaryExpr 195 { 196 this(Expression left, Expression right, Token* optok) 197 { 198 super(left, right, optok); 199 mixin(set_kind); 200 } 201 mixin methods; 202 } 203 204 class URShiftExpr : BinaryExpr 205 { 206 this(Expression left, Expression right, Token* optok) 207 { 208 super(left, right, optok); 209 mixin(set_kind); 210 } 211 mixin methods; 212 } 213 214 class PlusExpr : BinaryExpr 215 { 216 this(Expression left, Expression right, Token* optok) 217 { 218 super(left, right, optok); 219 mixin(set_kind); 220 } 221 mixin methods; 222 } 223 224 class MinusExpr : BinaryExpr 225 { 226 this(Expression left, Expression right, Token* optok) 227 { 228 super(left, right, optok); 229 mixin(set_kind); 230 } 231 mixin methods; 232 } 233 234 class CatExpr : BinaryExpr 235 { 236 this(Expression left, Expression right, Token* optok) 237 { 238 super(left, right, optok); 239 mixin(set_kind); 240 } 241 mixin methods; 242 } 243 244 class MulExpr : BinaryExpr 245 { 246 this(Expression left, Expression right, Token* optok) 247 { 248 super(left, right, optok); 249 mixin(set_kind); 250 } 251 mixin methods; 252 } 253 254 class DivExpr : BinaryExpr 255 { 256 this(Expression left, Expression right, Token* optok) 257 { 258 super(left, right, optok); 259 mixin(set_kind); 260 } 261 mixin methods; 262 } 263 264 class ModExpr : BinaryExpr 265 { 266 this(Expression left, Expression right, Token* optok) 267 { 268 super(left, right, optok); 269 mixin(set_kind); 270 } 271 mixin methods; 272 } 273 274 // D2 275 class PowExpr : BinaryExpr 276 { 277 this(Expression left, Expression right, Token* optok) 278 { 279 super(left, right, optok); 280 mixin(set_kind); 281 } 282 mixin methods; 283 } 284 285 class RangeExpr : BinaryExpr 286 { 287 this(Expression left, Expression right, Token* optok) 288 { 289 super(left, right, optok); 290 mixin(set_kind); 291 } 292 mixin methods; 293 } 294 295 class AssignExpr : BinaryExpr 296 { 297 this(Expression left, Expression right, Token* optok) 298 { 299 super(left, right, optok); 300 mixin(set_kind); 301 } 302 mixin methods; 303 } 304 class LShiftAssignExpr : BinaryExpr 305 { 306 this(Expression left, Expression right, Token* optok) 307 { 308 super(left, right, optok); 309 mixin(set_kind); 310 } 311 mixin methods; 312 } 313 class RShiftAssignExpr : BinaryExpr 314 { 315 this(Expression left, Expression right, Token* optok) 316 { 317 super(left, right, optok); 318 mixin(set_kind); 319 } 320 mixin methods; 321 } 322 class URShiftAssignExpr : BinaryExpr 323 { 324 this(Expression left, Expression right, Token* optok) 325 { 326 super(left, right, optok); 327 mixin(set_kind); 328 } 329 mixin methods; 330 } 331 class OrAssignExpr : BinaryExpr 332 { 333 this(Expression left, Expression right, Token* optok) 334 { 335 super(left, right, optok); 336 mixin(set_kind); 337 } 338 mixin methods; 339 } 340 class AndAssignExpr : BinaryExpr 341 { 342 this(Expression left, Expression right, Token* optok) 343 { 344 super(left, right, optok); 345 mixin(set_kind); 346 } 347 mixin methods; 348 } 349 class PlusAssignExpr : BinaryExpr 350 { 351 this(Expression left, Expression right, Token* optok) 352 { 353 super(left, right, optok); 354 mixin(set_kind); 355 } 356 mixin methods; 357 } 358 class MinusAssignExpr : BinaryExpr 359 { 360 this(Expression left, Expression right, Token* optok) 361 { 362 super(left, right, optok); 363 mixin(set_kind); 364 } 365 mixin methods; 366 } 367 class DivAssignExpr : BinaryExpr 368 { 369 this(Expression left, Expression right, Token* optok) 370 { 371 super(left, right, optok); 372 mixin(set_kind); 373 } 374 mixin methods; 375 } 376 class MulAssignExpr : BinaryExpr 377 { 378 this(Expression left, Expression right, Token* optok) 379 { 380 super(left, right, optok); 381 mixin(set_kind); 382 } 383 mixin methods; 384 } 385 class ModAssignExpr : BinaryExpr 386 { 387 this(Expression left, Expression right, Token* optok) 388 { 389 super(left, right, optok); 390 mixin(set_kind); 391 } 392 mixin methods; 393 } 394 class XorAssignExpr : BinaryExpr 395 { 396 this(Expression left, Expression right, Token* optok) 397 { 398 super(left, right, optok); 399 mixin(set_kind); 400 } 401 mixin methods; 402 } 403 class CatAssignExpr : BinaryExpr 404 { 405 this(Expression left, Expression right, Token* optok) 406 { 407 super(left, right, optok); 408 mixin(set_kind); 409 } 410 mixin methods; 411 } 412 // D2 413 class PowAssignExpr : BinaryExpr 414 { 415 this(Expression left, Expression right, Token* optok) 416 { 417 super(left, right, optok); 418 mixin(set_kind); 419 } 420 mixin methods; 421 } 422 423 424 425 /*++++++++++++++++++++ 426 + Unary Expressions: + 427 ++++++++++++++++++++*/ 428 429 abstract class UnaryExpr : Expression 430 { 431 Expression una; 432 433 mixin(memberInfo("una")); 434 435 this(Expression e) 436 { 437 addChild(e); 438 this.una = e; 439 } 440 mixin copyMethod; 441 } 442 443 class AddressExpr : UnaryExpr 444 { 445 this(Expression e) 446 { 447 super(e); 448 mixin(set_kind); 449 } 450 mixin methods; 451 } 452 453 class PreIncrExpr : UnaryExpr 454 { 455 this(Expression e) 456 { 457 super(e); 458 mixin(set_kind); 459 } 460 mixin methods; 461 } 462 463 class PreDecrExpr : UnaryExpr 464 { 465 this(Expression e) 466 { 467 super(e); 468 mixin(set_kind); 469 } 470 mixin methods; 471 } 472 473 class PostIncrExpr : UnaryExpr 474 { 475 this(Expression e) 476 { 477 super(e); 478 mixin(set_kind); 479 } 480 mixin methods; 481 } 482 483 class PostDecrExpr : UnaryExpr 484 { 485 this(Expression e) 486 { 487 super(e); 488 mixin(set_kind); 489 } 490 mixin methods; 491 } 492 493 class DerefExpr : UnaryExpr 494 { 495 this(Expression e) 496 { 497 super(e); 498 mixin(set_kind); 499 } 500 mixin methods; 501 } 502 503 class SignExpr : UnaryExpr 504 { 505 this(Expression e) 506 { 507 super(e); 508 mixin(set_kind); 509 } 510 511 bool isPos() 512 { 513 assert(begin !is null); 514 return begin.kind == TOK.Plus; 515 } 516 517 bool isNeg() 518 { 519 assert(begin !is null); 520 return begin.kind == TOK.Minus; 521 } 522 mixin methods; 523 } 524 525 class NotExpr : UnaryExpr 526 { 527 this(Expression e) 528 { 529 super(e); 530 mixin(set_kind); 531 } 532 mixin methods; 533 } 534 535 class CompExpr : UnaryExpr 536 { 537 this(Expression e) 538 { 539 super(e); 540 mixin(set_kind); 541 } 542 mixin methods; 543 } 544 545 class CallExpr : UnaryExpr 546 { 547 Expression[] args; 548 mixin(memberInfo("una", "args")); 549 this(Expression e, Expression[] args) 550 { 551 super(e); 552 mixin(set_kind); 553 addOptChildren(args); 554 this.args = args; 555 } 556 mixin methods; 557 } 558 559 class NewExpr : Expression 560 { 561 Expression frame; /// The frame or 'this' pointer. 562 Expression[] newArgs; 563 TypeNode type; 564 Expression[] ctorArgs; 565 566 mixin(memberInfo("frame?", "newArgs", "type", "ctorArgs")); 567 568 this(Expression frame, Expression[] newArgs, TypeNode type, 569 Expression[] ctorArgs) 570 { 571 mixin(set_kind); 572 addOptChild(frame); 573 addOptChildren(newArgs); 574 addChild(type); 575 addOptChildren(ctorArgs); 576 this.newArgs = newArgs; 577 this.type = type; 578 this.ctorArgs = ctorArgs; 579 } 580 mixin methods; 581 } 582 583 class NewClassExpr : Expression 584 { 585 Expression frame; /// The frame or 'this' pointer. 586 Expression[] newArgs; 587 Expression[] ctorArgs; 588 BaseClassType[] bases; 589 CompoundDecl decls; 590 591 mixin(memberInfo("frame?", "newArgs", "ctorArgs", "bases", "decls")); 592 593 this(Expression frame, Expression[] newArgs, Expression[] ctorArgs, 594 BaseClassType[] bases, CompoundDecl decls) 595 { 596 mixin(set_kind); 597 addOptChild(frame); 598 addOptChildren(newArgs); 599 addOptChildren(ctorArgs); 600 addOptChildren(bases); 601 addChild(decls); 602 603 this.newArgs = newArgs; 604 this.ctorArgs = ctorArgs; 605 this.bases = bases; 606 this.decls = decls; 607 } 608 mixin methods; 609 } 610 611 class DeleteExpr : UnaryExpr 612 { 613 this(Expression e) 614 { 615 super(e); 616 mixin(set_kind); 617 } 618 mixin methods; 619 } 620 621 class CastExpr : UnaryExpr 622 { 623 TypeNode type; 624 mixin(memberInfo("una", "type?")); 625 this(Expression e, TypeNode type) 626 { 627 version(D2) 628 addOptChild(type); 629 else 630 addChild(type); // Add type before super(). 631 super(e); 632 mixin(set_kind); 633 this.type = type; 634 } 635 mixin methods; 636 } 637 638 class IndexExpr : UnaryExpr 639 { 640 Expression[] args; 641 mixin(memberInfo("una", "args")); 642 this(Expression e, Expression[] args) 643 { 644 super(e); 645 mixin(set_kind); 646 addChildren(args); 647 this.args = args; 648 } 649 mixin methods; 650 } 651 652 class SliceExpr : UnaryExpr 653 { 654 Expression range; 655 mixin(memberInfo("una", "range?")); 656 this(Expression e, Expression range) 657 { 658 super(e); 659 mixin(set_kind); 660 addOptChild(range); 661 this.range = range; 662 } 663 mixin methods; 664 } 665 666 /*++++++++++++++++++++++ 667 + Primary Expressions: + 668 ++++++++++++++++++++++*/ 669 670 class IdentifierExpr : Expression 671 { 672 Expression next; 673 Token* name; 674 mixin(memberInfo("name", "next?")); 675 this(Token* name, Expression next = null) 676 { 677 mixin(set_kind); 678 addOptChild(next); 679 this.next = next; 680 this.name = name; 681 } 682 683 @property Identifier* id() 684 { 685 return name.ident; 686 } 687 688 mixin methods; 689 } 690 691 /// Module scope operator: 692 /// $(BNF ModuleScopeExpr := ".") 693 class ModuleScopeExpr : Expression 694 { 695 mixin(memberInfo()); 696 this() 697 { 698 mixin(set_kind); 699 } 700 mixin methods; 701 } 702 703 class TmplInstanceExpr : Expression 704 { 705 Expression next; 706 Token* name; 707 TemplateArguments targs; 708 mixin(memberInfo("name", "targs", "next?")); 709 this(Token* name, TemplateArguments targs, Expression next = null) 710 { 711 mixin(set_kind); 712 addChild(targs); 713 addOptChild(next); 714 this.next = next; 715 this.name = name; 716 this.targs = targs; 717 } 718 719 @property Identifier* id() 720 { 721 return name.ident; 722 } 723 724 mixin methods; 725 } 726 727 class SpecialTokenExpr : Expression 728 { 729 Token* specialToken; 730 mixin(memberInfo("specialToken")); 731 this(Token* specialToken) 732 { 733 mixin(set_kind); 734 this.specialToken = specialToken; 735 } 736 737 Expression value; /// The expression created in the semantic phase. 738 739 mixin methods; 740 } 741 742 class ThisExpr : Expression 743 { 744 mixin(memberInfo()); 745 this() 746 { 747 mixin(set_kind); 748 } 749 mixin methods; 750 } 751 752 class SuperExpr : Expression 753 { 754 mixin(memberInfo()); 755 this() 756 { 757 mixin(set_kind); 758 } 759 mixin methods; 760 } 761 762 class NullExpr : Expression 763 { 764 mixin(memberInfo()); 765 this() 766 { 767 mixin(set_kind); 768 } 769 770 // For semantic analysis. 771 this(Type type) 772 { 773 this(); 774 this.type = type; 775 } 776 777 mixin methods; 778 } 779 780 class DollarExpr : Expression 781 { 782 mixin(memberInfo()); 783 this() 784 { 785 mixin(set_kind); 786 } 787 mixin methods; 788 } 789 790 class BoolExpr : Expression 791 { 792 IntExpr value; /// IntExpr of type bool. 793 794 mixin(memberInfo("begin")); 795 this(bool value) 796 { 797 mixin(set_kind); 798 // Some semantic computation here. 799 this.value = new IntExpr(value, Types.Bool); 800 this.type = Types.Bool; 801 } 802 803 /// For ASTSerializer. 804 this(Token* t) 805 { 806 this(t.kind == TOK.True ? true : false); 807 } 808 809 bool toBool() @property 810 { 811 assert(value !is null); 812 return !!value.number; 813 } 814 815 mixin methods; 816 } 817 818 class IntExpr : Expression 819 { 820 ulong number; 821 822 mixin(memberInfo("begin")); 823 824 this(ulong number, Type type) 825 { 826 mixin(set_kind); 827 this.number = number; 828 this.type = type; 829 } 830 831 this(Token* token) 832 { 833 // Some semantic computation here. 834 auto type = Types.Int32; // Should be most common case. 835 ulong number = token.uint_; 836 switch (token.kind) 837 { 838 // case TOK.Int32: 839 // type = Types.Int32; break; 840 case TOK.UInt32: 841 type = Types.UInt32; break; 842 case TOK.Int64: 843 type = Types.Int64; number = token.intval.ulong_; break; 844 case TOK.UInt64: 845 type = Types.UInt64; number = token.intval.ulong_; break; 846 default: 847 assert(token.kind == TOK.Int32); 848 } 849 this(number, type); 850 } 851 852 mixin methods; 853 } 854 855 /// Holds a Float number and may be a real or imaginary number. 856 class FloatExpr : Expression 857 { 858 Float number; 859 860 mixin(memberInfo("begin")); 861 862 this(Float number, Type type) 863 { 864 mixin(set_kind); 865 this.number = number; 866 this.type = type; 867 } 868 869 this(Token* token) 870 { 871 // Some semantic computation here. 872 auto type = Types.fromTOK(token.kind); 873 this(token.mpfloat, type); 874 } 875 876 mixin methods; 877 } 878 879 880 /// This expression holds a complex number. 881 /// It is only created in the semantic phase. 882 class ComplexExpr : Expression 883 { 884 import dil.semantic.TypesEnum; 885 Complex number; 886 887 mixin(memberInfo("begin")); 888 this(Complex number, Type type) 889 { 890 mixin(set_kind); 891 this.number = number; 892 this.type = type; 893 } 894 895 /// For ASTSerializer. 896 this(Token*) 897 { 898 assert(0, "can't serialize ComplexExpr atm"); 899 } 900 901 Float re() 902 { 903 return number.re; 904 } 905 906 Float im() 907 { 908 return number.im; 909 } 910 911 Type reType() 912 { 913 switch (type.tid) 914 { 915 case TYP.CFloat32: return Types.Float32; 916 case TYP.CFloat64: return Types.Float64; 917 case TYP.CFloat80: return Types.Float80; 918 default: 919 assert(0); 920 } 921 } 922 923 Type imType() 924 { 925 switch (type.tid) 926 { 927 case TYP.CFloat32: return Types.IFloat32; 928 case TYP.CFloat64: return Types.IFloat64; 929 case TYP.CFloat80: return Types.IFloat80; 930 default: 931 assert(0); 932 } 933 } 934 935 mixin methods; 936 } 937 938 class CharExpr : Expression 939 { 940 IntExpr value; // IntExpr of type Char/Wchar/Dchar. 941 942 mixin(memberInfo("begin")); 943 944 this(Token* chartok) 945 { 946 mixin(set_kind); 947 const character = chartok.dchar_; 948 // Some semantic computation here. 949 if (character <= 0xFF) 950 this.type = Types.Char; 951 else if (character <= 0xFFFF) 952 this.type = Types.WChar; 953 else 954 this.type = Types.DChar; 955 956 this.value = new IntExpr(character, this.type); 957 } 958 959 dchar charValue() @property 960 { 961 return cast(dchar)value.number; 962 } 963 964 mixin methods; 965 } 966 967 class StringExpr : Expression 968 { 969 const(void)[] data; /// Contains char, wchar or dchar characters. 970 971 /// Primary constructor. 972 /// Params: 973 /// data = Never pass a string to this parameter. 974 /// Implicit array type conversion can change the length property! 975 /// charType = The semantic type of the characters. 976 this(const(void)[] data, Type charType) 977 { 978 mixin(set_kind); 979 this.data = data; 980 version(D1) 981 this.type = charType.arrayOf(data.length); 982 version(D2) 983 this.type = charType/+.immutableOf()+/.arrayOf(); 984 } 985 986 this(const void* ptr, const size_t len, Type charType) 987 { 988 this(ptr[0..len], charType); 989 } 990 991 this(cbinstr str, char kind = 0) 992 { 993 auto t = (kind == 'c') ? Types.Char : 994 (kind == 'w') ? Types.WChar : 995 (kind == 'd') ? Types.DChar : 996 Types.XChar; 997 // Adjust the length. Length / CharSize == Length >> (CharSize >> 1). 998 auto x = (kind == 'd') ? 2 : (kind == 'w') ? 1 : 0; 999 this(str.ptr, str.length >> x, t); 1000 } 1001 1002 this(cstring str) 1003 { 1004 this(str.ptr, str.length, Types.Char); 1005 } 1006 1007 this(cwstring str) 1008 { 1009 this(str.ptr, str.length, Types.WChar); 1010 } 1011 1012 this(cdstring str) 1013 { 1014 this(str.ptr, str.length, Types.DChar); 1015 } 1016 1017 /// For ASTSerializer. 1018 this(Token*[] tokens) 1019 { 1020 import dil.lexer.Lexer, dil.Unicode; 1021 assert(tokens.length >= 1); 1022 cbinstr str = tokens[0].strval.str; 1023 char postfix = tokens[0].strval.pf; 1024 // Concatenate adjacent string literals. 1025 foreach (token; tokens[1..$]) 1026 { 1027 if (auto pf = token.strval.pf) { 1028 assert(pf == postfix, "string literals' postfix mismatch"); 1029 postfix = pf; 1030 } 1031 str ~= token.strval.str; 1032 } 1033 1034 if (postfix != 0) 1035 assert(!Lexer.findInvalidUTF8Sequence(str)); 1036 1037 if (postfix == 'w') // Convert to UTF16. 1038 str = cast(cbinstr)toUTF16(cast(cstring)str); 1039 else if (postfix == 'd') // Convert to UTF32. 1040 str = cast(cbinstr)toUTF32(cast(cstring)str); 1041 1042 this(str, postfix); 1043 } 1044 1045 /// Returns true if coerced, false if polysemous. 1046 bool coerced() @property 1047 { 1048 return charType is Types.XChar; 1049 } 1050 1051 /// Returns the underlying character type. 1052 TypeBasic charType() @property 1053 { 1054 return type.next.to!(TypeBasic); 1055 } 1056 1057 /// Returns 0, 'c', 'w', or 'd'. 1058 char postfix() @property 1059 { 1060 auto t = charType; 1061 return t is Types.XChar ? '\0' : 1062 t is Types.Char ? 'c' : 1063 t is Types.WChar ? 'w' : 1064 'd'; 1065 } 1066 1067 /// Returns the tokens this literal comprises. 1068 Token*[] tokens() @property 1069 { 1070 assert(begin && end); 1071 Token*[] ts; 1072 for (auto t = begin; t <= end; t++) 1073 if (t.kind == TOK.String) 1074 ts ~= t; 1075 return ts ? ts : [begin]; 1076 } 1077 1078 mixin(memberInfo("tokens")); 1079 1080 /// Returns the number of characters in this string. 1081 size_t length() @property 1082 { 1083 return data.length; 1084 } 1085 1086 /// Returns the UTF-8 string. 1087 cstring getString() 1088 { 1089 // TODO: convert to char[] if charType !is Types.Char. 1090 return *cast(cstring*)&data; 1091 } 1092 1093 /// Returns the UTF-16 string. 1094 cwstring getWString() 1095 { 1096 assert(charType is Types.WChar); 1097 return *cast(cwstring*)&data; 1098 } 1099 1100 /// Returns the UTF-32 string. 1101 cdstring getDString() 1102 { 1103 assert(charType is Types.DChar); 1104 return *cast(cdstring*)&data; 1105 } 1106 1107 mixin methods; 1108 } 1109 1110 class ArrayLiteralExpr : Expression 1111 { 1112 Expression[] values; 1113 mixin(memberInfo("values")); 1114 this(Expression[] values) 1115 { 1116 mixin(set_kind); 1117 addOptChildren(values); 1118 this.values = values; 1119 } 1120 mixin methods; 1121 } 1122 1123 class AArrayLiteralExpr : Expression 1124 { 1125 Expression[] keys, values; 1126 mixin(memberInfo("keys", "values")); 1127 this(Expression[] keys, Expression[] values) 1128 { 1129 assert(keys.length == values.length); 1130 mixin(set_kind); 1131 foreach (i, key; keys) 1132 addChildren([key, values[i]]); 1133 this.keys = keys; 1134 this.values = values; 1135 } 1136 mixin methods; 1137 } 1138 1139 class AssertExpr : Expression 1140 { 1141 Expression expr, msg; 1142 mixin(memberInfo("expr", "msg?")); 1143 this(Expression expr, Expression msg) 1144 { 1145 mixin(set_kind); 1146 addChild(expr); 1147 addOptChild(msg); 1148 this.expr = expr; 1149 this.msg = msg; 1150 } 1151 mixin methods; 1152 } 1153 1154 class MixinExpr : Expression 1155 { 1156 Expression expr; 1157 mixin(memberInfo("expr")); 1158 this(Expression expr) 1159 { 1160 mixin(set_kind); 1161 addChild(expr); 1162 this.expr = expr; 1163 } 1164 mixin methods; 1165 } 1166 1167 class ImportExpr : Expression 1168 { 1169 Expression expr; 1170 mixin(memberInfo("expr")); 1171 this(Expression expr) 1172 { 1173 mixin(set_kind); 1174 addChild(expr); 1175 this.expr = expr; 1176 } 1177 mixin methods; 1178 } 1179 1180 class TypeExpr : Expression 1181 { 1182 TypeNode typeNode; 1183 mixin(memberInfo("typeNode")); 1184 this(TypeNode t) 1185 { 1186 mixin(set_kind); 1187 this.typeNode = t; 1188 } 1189 mixin methods; 1190 } 1191 1192 class TypeofExpr : Expression 1193 { 1194 TypeNode type; 1195 mixin(memberInfo("type")); 1196 this(TypeNode type) 1197 { 1198 mixin(set_kind); 1199 addChild(type); 1200 this.type = type; 1201 } 1202 mixin methods; 1203 } 1204 1205 class TypeDotIdExpr : Expression 1206 { 1207 TypeNode type; 1208 Token* ident; 1209 mixin(memberInfo("type", "ident")); 1210 this(TypeNode type, Token* ident) 1211 { 1212 mixin(set_kind); 1213 addChild(type); 1214 this.type = type; 1215 this.ident = ident; 1216 } 1217 mixin methods; 1218 } 1219 1220 class TypeidExpr : Expression 1221 { 1222 TypeNode type; 1223 mixin(memberInfo("type")); 1224 this(TypeNode type) 1225 { 1226 mixin(set_kind); 1227 addChild(type); 1228 this.type = type; 1229 } 1230 mixin methods; 1231 } 1232 1233 class IsExpr : Expression 1234 { 1235 TypeNode type; 1236 Token* name; /// Optional variable name. 1237 Token* opTok, specTok; 1238 TypeNode specType; 1239 TemplateParameters tparams; // D 2.0 1240 mixin(memberInfo("type", "name?", "opTok", "specTok?", "specType?", 1241 "tparams?")); 1242 1243 this(TypeNode type, Token* name, Token* opTok, Token* specTok, 1244 TypeNode specType, typeof(tparams) tparams) 1245 { 1246 mixin(set_kind); 1247 addChild(type); 1248 addOptChild(specType); 1249 version(D2) 1250 addOptChild(tparams); 1251 this.type = type; 1252 this.name = name; 1253 this.opTok = opTok; 1254 this.specTok = specTok; 1255 this.specType = specType; 1256 this.tparams = tparams; 1257 } 1258 mixin methods; 1259 } 1260 1261 class FuncLiteralExpr : Expression 1262 { 1263 Token* tok; 1264 TypeNode returnType; 1265 Parameters params; 1266 FuncBodyStmt funcBody; 1267 mixin(memberInfo("tok", "returnType?", "params?", "funcBody")); 1268 1269 this() 1270 { 1271 mixin(set_kind); 1272 addOptChild(returnType); 1273 addOptChild(params); 1274 addChild(funcBody); 1275 } 1276 1277 this(Token* tok, TypeNode returnType, Parameters params, 1278 FuncBodyStmt funcBody) 1279 { 1280 this.tok = tok; 1281 this.returnType = returnType; 1282 this.params = params; 1283 this.funcBody = funcBody; 1284 this(); 1285 } 1286 1287 this(Parameters params, FuncBodyStmt funcBody) 1288 { 1289 this.params = params; 1290 this.funcBody = funcBody; 1291 this(); 1292 } 1293 1294 this(FuncBodyStmt funcBody) 1295 { 1296 this.funcBody = funcBody; 1297 this(); 1298 } 1299 1300 mixin methods; 1301 } 1302 1303 class LambdaExpr : Expression 1304 { 1305 Parameters params; 1306 Expression expr; 1307 mixin(memberInfo("params", "expr")); 1308 1309 this(Parameters params, Expression expr) 1310 { 1311 mixin(set_kind); 1312 addChild(params); 1313 addChild(expr); 1314 this.params = params; 1315 this.expr = expr; 1316 } 1317 1318 mixin methods; 1319 } 1320 1321 /// ParenthesisExpr := "(" Expression ")" 1322 class ParenExpr : Expression 1323 { 1324 Expression next; 1325 mixin(memberInfo("next")); 1326 this(Expression next) 1327 { 1328 mixin(set_kind); 1329 addChild(next); 1330 this.next = next; 1331 } 1332 mixin methods; 1333 } 1334 1335 // version(D2) 1336 // { 1337 class TraitsExpr : Expression 1338 { 1339 Token* name; 1340 TemplateArguments targs; 1341 mixin(memberInfo("name", "targs")); 1342 this(typeof(name) name, typeof(targs) targs) 1343 { 1344 mixin(set_kind); 1345 addOptChild(targs); 1346 this.name = name; 1347 this.targs = targs; 1348 } 1349 mixin methods; 1350 } 1351 // } 1352 1353 class VoidInitExpr : Expression 1354 { 1355 mixin(memberInfo()); 1356 this() 1357 { 1358 mixin(set_kind); 1359 } 1360 mixin methods; 1361 } 1362 1363 class ArrayInitExpr : Expression 1364 { 1365 Expression[] keys; 1366 Expression[] values; 1367 mixin(memberInfo("keys?", "values")); 1368 this(Expression[] keys, Expression[] values) 1369 { 1370 assert(keys.length == values.length); 1371 mixin(set_kind); 1372 foreach (i, key; keys) 1373 { 1374 addOptChild(key); // The key is optional in ArrayInitializers. 1375 addChild(values[i]); 1376 } 1377 this.keys = keys; 1378 this.values = values; 1379 } 1380 mixin methods; 1381 } 1382 1383 class StructInitExpr : Expression 1384 { 1385 Token*[] idents; 1386 Expression[] values; 1387 mixin(memberInfo("idents", "values")); 1388 this(Token*[] idents, Expression[] values) 1389 { 1390 assert(idents.length == values.length); 1391 mixin(set_kind); 1392 addOptChildren(values); 1393 this.idents = idents; 1394 this.values = values; 1395 } 1396 mixin methods; 1397 } 1398 1399 class AsmTypeExpr : UnaryExpr 1400 { 1401 Token* prefix; 1402 mixin(memberInfo("prefix", "una")); 1403 this(Token* prefix, Expression e) 1404 { 1405 super(e); 1406 mixin(set_kind); 1407 } 1408 mixin methods; 1409 } 1410 1411 class AsmOffsetExpr : UnaryExpr 1412 { 1413 mixin(memberInfo("una")); 1414 this(Expression e) 1415 { 1416 super(e); 1417 mixin(set_kind); 1418 } 1419 mixin methods; 1420 } 1421 1422 class AsmSegExpr : UnaryExpr 1423 { 1424 mixin(memberInfo("una")); 1425 this(Expression e) 1426 { 1427 super(e); 1428 mixin(set_kind); 1429 } 1430 mixin methods; 1431 } 1432 1433 class AsmPostBracketExpr : UnaryExpr 1434 { 1435 Expression index; /// Expression in brackets: una [ index ] 1436 mixin(memberInfo("una", "index")); 1437 this(Expression e, Expression index) 1438 { 1439 super(e); 1440 mixin(set_kind); 1441 addChild(index); 1442 this.index = index; 1443 } 1444 mixin methods; 1445 } 1446 1447 class AsmBracketExpr : Expression 1448 { 1449 Expression expr; 1450 mixin(memberInfo("expr")); 1451 this(Expression e) 1452 { 1453 mixin(set_kind); 1454 addChild(e); 1455 this.expr = e; 1456 } 1457 mixin methods; 1458 } 1459 1460 class AsmLocalSizeExpr : Expression 1461 { 1462 mixin(memberInfo()); 1463 this() 1464 { 1465 mixin(set_kind); 1466 } 1467 mixin methods; 1468 } 1469 1470 class AsmRegisterExpr : Expression 1471 { 1472 Token* register; /// Name of the register. 1473 Expression number; /// ST(0) - ST(7) or FS:0, FS:4, FS:8 1474 mixin(memberInfo("register", "number?")); 1475 this(Token* register, Expression number = null) 1476 { 1477 mixin(set_kind); 1478 addOptChild(number); 1479 this.register = register; 1480 this.number = number; 1481 } 1482 mixin methods; 1483 }