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 }