1 /// Author: Aziz Köksal
2 /// License: GPL3
3 /// $(Maturity very low)
4 module dil.code.Interpreter;
5 
6 import dil.code.NotAResult;
7 import dil.code.Methods;
8 import dil.ast.Visitor,
9        dil.ast.Node,
10        dil.ast.Declarations,
11        dil.ast.Expressions,
12        dil.ast.Statements,
13        dil.ast.Types,
14        dil.ast.Parameters;
15 import dil.semantic.Symbol,
16        dil.semantic.Symbols,
17        dil.semantic.Types,
18        dil.semantic.TypesEnum;
19 import dil.Float,
20        dil.Complex,
21        dil.Diagnostics;
22 import common;
23 
24 /// Used for compile-time evaluation of D code.
25 class Interpreter : Visitor
26 {
27   Diagnostics diag;
28   EMethods EM;
29 
30   alias NAR = dil.code.NotAResult.NAR;
31 
32   /// Evaluates the expression e.
33   /// Returns: NAR or a value.
34   static Expression interpret(Expression e, Diagnostics diag)
35   {
36     return (new Interpreter(diag)).eval(e);
37   }
38 
39   /// Executes the function at compile-time with the given arguments.
40   /// Returns: NAR or a value.
41   static Expression interpret(FunctionDecl fd, Expression[] args,
42                               Diagnostics diag)
43   {
44     return (new Interpreter(diag)).eval(fd, args);
45   }
46 
47   /// Constructs an Interpreter object.
48   this(Diagnostics diag)
49   {
50     this.diag = diag;
51     this.EM = new EMethods(diag);
52   }
53 
54   /// Start evaluation.
55   Expression eval(Expression e)
56   {
57     return e;
58   }
59   // TODO: are eval() methods needed for other Nodes?
60 
61   /// Start evaluation of a function.
62   Expression eval(FunctionDecl fd, Expression[] args)
63   {
64     // We cache this result so that we don't blindly try to reevaluate
65     // functions that can't be evaluated at compile time
66     if (fd.cantInterpret)
67       return NAR;
68 
69     // TODO: check for nested/method
70 
71     // Check for invalid parameter types
72     if (fd.params.hasVariadic() || fd.params.hasLazy())
73     {
74       fd.cantInterpret = true;
75       return NAR;
76     }
77 
78     // remove me plx
79     assert(false);
80     return NAR;
81   }
82 
83   void error(Node n, cstring msg, ...)
84   {
85     auto location = n.begin.getErrorLocation(/+filePath+/""); // FIXME
86     msg = Format(_arguments, _argptr, msg);
87     auto error = new SemanticError(location, msg);
88     if (diag !is null)
89       diag ~= error;
90   }
91 
92   /// Some handy aliases.
93   private alias D = Declaration;
94   private alias E = Expression; /// ditto
95   private alias S = Statement; /// ditto
96   private alias T = TypeNode; /// ditto
97   private alias P = Parameter; /// ditto
98   private alias N = Node; /// ditto
99   private alias NK = NodeKind; /// ditto
100 
101   /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
102   |                                Declarations                               |
103    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
104 
105 override
106 {
107   D visit(CompoundDecl d)
108   {
109     return d;
110   }
111 
112   D visit(IllegalDecl)
113   { assert(0, "interpreting invalid AST"); return null; }
114 
115   // D visit(EmptyDecl ed)
116   // { return ed; }
117 
118   // D visit(ModuleDecl)
119   // { return null; }
120 
121   D visit(ImportDecl d)
122   {
123     return d;
124   }
125 
126   D visit(AliasDecl ad)
127   {
128     return ad;
129   }
130 
131   D visit(TypedefDecl td)
132   {
133     return td;
134   }
135 
136   D visit(EnumDecl d)
137   {
138     return d;
139   }
140 
141   D visit(EnumMemberDecl d)
142   {
143     return d;
144   }
145 
146   D visit(ClassDecl d)
147   {
148     return d;
149   }
150 
151   D visit(InterfaceDecl d)
152   {
153     return d;
154   }
155 
156   D visit(StructDecl d)
157   {
158     return d;
159   }
160 
161   D visit(UnionDecl d)
162   {
163     return d;
164   }
165 
166   D visit(ConstructorDecl d)
167   {
168     return d;
169   }
170 
171   D visit(StaticCtorDecl d)
172   {
173     return d;
174   }
175 
176   D visit(DestructorDecl d)
177   {
178     return d;
179   }
180 
181   D visit(StaticDtorDecl d)
182   {
183     return d;
184   }
185 
186   D visit(FunctionDecl d)
187   {
188     return d;
189   }
190 
191   D visit(VariablesDecl vd)
192   {
193     return vd;
194   }
195 
196   D visit(InvariantDecl d)
197   {
198     return d;
199   }
200 
201   D visit(UnittestDecl d)
202   {
203     return d;
204   }
205 
206   D visit(DebugDecl d)
207   {
208     return d;
209   }
210 
211   D visit(VersionDecl d)
212   {
213     return d;
214   }
215 
216   D visit(TemplateDecl d)
217   {
218     return d;
219   }
220 
221   D visit(NewDecl d)
222   {
223     return d;
224   }
225 
226   D visit(DeleteDecl d)
227   {
228     return d;
229   }
230 
231   // Attributes:
232 
233   D visit(ProtectionDecl d)
234   {
235     return d;
236   }
237 
238   D visit(StorageClassDecl d)
239   {
240     return d;
241   }
242 
243   D visit(LinkageDecl d)
244   {
245     return d;
246   }
247 
248   D visit(AlignDecl d)
249   {
250     return d;
251   }
252 
253   D visit(StaticAssertDecl d)
254   {
255     return d;
256   }
257 
258   D visit(StaticIfDecl d)
259   {
260     return d;
261   }
262 
263   D visit(MixinDecl d)
264   {
265     return d;
266   }
267 
268   D visit(PragmaDecl d)
269   {
270     return d;
271   }
272 } // override
273 
274   /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
275   |                                 Statements                                |
276    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
277 
278 override
279 {
280   S visit(CompoundStmt s)
281   {
282     return s;
283   }
284 
285   S visit(IllegalStmt)
286   { assert(0, "interpreting invalid AST"); return null; }
287 
288   S visit(EmptyStmt s)
289   {
290     return s;
291   }
292 
293   S visit(FuncBodyStmt s)
294   {
295     return s;
296   }
297 
298   S visit(ScopeStmt s)
299   {
300     return s;
301   }
302 
303   S visit(LabeledStmt s)
304   {
305     return s;
306   }
307 
308   S visit(ExpressionStmt s)
309   {
310     return s;
311   }
312 
313   S visit(DeclarationStmt s)
314   {
315     return s;
316   }
317 
318   S visit(IfStmt s)
319   {
320     return s;
321   }
322 
323   S visit(WhileStmt s)
324   {
325     return s;
326   }
327 
328   S visit(DoWhileStmt s)
329   {
330     return s;
331   }
332 
333   S visit(ForStmt s)
334   {
335     return s;
336   }
337 
338   S visit(ForeachStmt s)
339   {
340     return s;
341   }
342 
343   S visit(SwitchStmt s)
344   {
345     return s;
346   }
347 
348   S visit(CaseStmt s)
349   {
350     return s;
351   }
352 
353   S visit(DefaultStmt s)
354   {
355     return s;
356   }
357 
358   S visit(ContinueStmt s)
359   {
360     return s;
361   }
362 
363   S visit(BreakStmt s)
364   {
365     return s;
366   }
367 
368   S visit(ReturnStmt s)
369   {
370     return s;
371   }
372 
373   S visit(GotoStmt s)
374   {
375     return s;
376   }
377 
378   S visit(WithStmt s)
379   {
380     return s;
381   }
382 
383   S visit(SynchronizedStmt s)
384   {
385     return s;
386   }
387 
388   S visit(TryStmt s)
389   {
390     return s;
391   }
392 
393   S visit(CatchStmt s)
394   {
395     return s;
396   }
397 
398   S visit(FinallyStmt s)
399   {
400     return s;
401   }
402 
403   S visit(ScopeGuardStmt s)
404   {
405     return s;
406   }
407 
408   S visit(ThrowStmt s)
409   {
410     return s;
411   }
412 
413   S visit(VolatileStmt s)
414   {
415     return s;
416   }
417 
418   S visit(AsmBlockStmt s)
419   {
420     error(s, "cannot interpret assembler statements at compile time");
421     return s;
422   }
423 
424   S visit(AsmStmt s)
425   {
426     assert(0);
427     return s;
428   }
429 
430   S visit(AsmAlignStmt s)
431   {
432     assert(0);
433     return s;
434   }
435 
436   S visit(IllegalAsmStmt)
437   { assert(0, "interpreting invalid AST"); return null; }
438 
439   S visit(PragmaStmt s)
440   {
441     return s;
442   }
443 
444   S visit(MixinStmt s)
445   {
446     return s;
447   }
448 
449   S visit(StaticIfStmt s)
450   {
451     return s;
452   }
453 
454   S visit(StaticAssertStmt s)
455   {
456     return s;
457   }
458 
459   S visit(DebugStmt s)
460   {
461     return s;
462   }
463 
464   S visit(VersionStmt s)
465   {
466     return s;
467   }
468 } // override
469 
470   /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
471   |                                Expressions                                |
472    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
473 
474   /// Calculates z1 + z2 or z1 - z2.
475   /// Returns a new ComplexExpr.
476   ComplexExpr complexPlusOrMinus(BinaryExpr e, bool minusOp)
477   {
478     int comb = void; // Indicates which case needs to be calculated.
479     Complex z = void; // Temp variable.
480     Float re, im, r2, i2;
481     Expression lhs = e.lhs, rhs = e.rhs; // Left and right operand.
482     auto lt = lhs.type.flagsOf(), rt = rhs.type.flagsOf(); // Type flags.
483     // Initialize left-hand side.
484     if (lt.isReal())
485       (re = EM.toReal(lhs)), (comb = 0);
486     else if (lt.isImaginary())
487       (im = EM.toImag(lhs)), (comb = 3);
488     else if (lt.isComplex())
489       (z = EM.toComplex(lhs)), (re = z.re), (im = z.im), (comb = 6);
490     // Initialize right-hand side.
491     if (rt.isReal())
492       (r2 = EM.toReal(rhs)), (comb += 0);
493     else if (rt.isImaginary())
494       (i2 = EM.toImag(rhs)), (comb += 1);
495     else if (rt.isComplex())
496       (z = EM.toComplex(rhs)), (r2 = z.re), (i2 = z.im), (comb += 2);
497     assert(comb != 0 && comb != 4, "must be handled elsewhere");
498     if (minusOp)
499     { // Negate the second operand if we have a minus operation.
500       if (r2) r2.neg();
501       if (i2) i2.neg();
502     }
503     // Do the calculation.
504     switch (comb)
505     {
506     //case 0: re = re + r2; break;             // re + r2
507     case 1: im = i2; break;                    // re + i2
508     case 2: im = i2; goto case 6;              // re + (r2+i2)
509     case 3: re = r2; break;                    // im + r2
510     //case 4: im = im + i2; break;             // im + i2
511     case 5: re = r2; goto case 7;              // im + (r2+i2)
512     case 6: re = re + r2; break;               // (re+im) + r2
513     case 7: im = im + i2; break;               // (re+im) + i2
514     case 8: re = re + r2; im = im + i2; break; // (re+im) + (r2+i2)
515     default: assert(0);
516     }
517     return new ComplexExpr(Complex(re, im), e.type);
518   }
519 
520 override
521 {
522   E visit(IllegalExpr)
523   { assert(0, "interpreting invalid AST"); return null; }
524 
525   E visit(CondExpr e)
526   {
527     auto r = visitE(e.condition);
528     if (r !is NAR)
529     {
530       auto bval = EM.isBool(r);
531       if (bval == 1)      r = visitE(e.lhs);
532       else if (bval == 0) r = visitE(e.rhs);
533       else                r = NAR;
534     }
535     return r;
536   }
537 
538   E visit(CommaExpr e)
539   {
540     return visitE(e.lhs) is NAR ? NAR : visitE(e.rhs);
541   }
542 
543   E visit(OrOrExpr e)
544   {
545     auto r = EM.toBool(visitE(e.lhs));
546     if (r !is NAR && r.to!(IntExpr).number == 0)
547       r = EM.toBool(visitE(e.rhs));
548     return r;
549   }
550 
551   E visit(AndAndExpr e)
552   {
553     auto r = EM.toBool(visitE(e.lhs));
554     if (r !is NAR && r.to!(IntExpr).number == 1)
555       r = EM.toBool(visitE(e.rhs));
556     return r;
557   }
558 
559   E visit(OrExpr e)
560   {
561     auto r = new IntExpr(EM.toInt(e.lhs) | EM.toInt(e.rhs), e.type);
562     r.setLoc(e);
563     return r;
564   }
565 
566   E visit(XorExpr e)
567   {
568     auto r = new IntExpr(EM.toInt(e.lhs) ^ EM.toInt(e.rhs), e.type);
569     r.setLoc(e);
570     return r;
571   }
572 
573   E visit(AndExpr e)
574   {
575     auto r = new IntExpr(EM.toInt(e.lhs) & EM.toInt(e.rhs), e.type);
576     r.setLoc(e);
577     return r;
578   }
579 
580   E visit(EqualExpr e)
581   {
582     return e;
583   }
584 
585   E visit(IdentityExpr e)
586   {
587     return e;
588   }
589 
590   E visit(RelExpr e)
591   {
592     return e;
593   }
594 
595   E visit(InExpr e)
596   {
597     return e;
598   }
599 
600   E visit(LShiftExpr e)
601   {
602     auto r = new IntExpr(EM.toInt(e.lhs) << EM.toInt(e.rhs), e.type);
603     r.setLoc(e);
604     return r;
605   }
606 
607   E visit(RShiftExpr e)
608   {
609     Expression r;
610     ulong val = EM.toInt(e.lhs), bits = EM.toInt(e.rhs);
611     switch (e.lhs.type.baseType().tid)
612     {
613     case TYP.Int8:    val =   cast(byte)val >> bits; break;
614     case TYP.UInt8:   val =  cast(ubyte)val >> bits; break;
615     case TYP.Int16:   val =  cast(short)val >> bits; break;
616     case TYP.UInt16:  val = cast(ushort)val >> bits; break;
617     case TYP.Int32:   val =    cast(int)val >> bits; break;
618     case TYP.UInt32:  val =   cast(uint)val >> bits; break;
619     case TYP.Int64:   val =   cast(long)val >> bits; break;
620     case TYP.UInt64:  val =  cast(ulong)val >> bits; break;
621     //case TYP.Int128:  val =   cast(cent)val >> bits; break;
622     //case TYP.UInt128: val =  cast(ucent)val >> bits; break;
623     case TYP.Error:  r = e; return r;
624     default: assert(0);
625     }
626     r = new IntExpr(val, e.type);
627     r.setLoc(e);
628     return r;
629   }
630 
631   E visit(URShiftExpr e)
632   {
633     Expression r;
634     ulong val = EM.toInt(e.lhs), bits = EM.toInt(e.rhs);
635     switch (e.lhs.type.baseType().tid)
636     {
637     case TYP.Int8, TYP.UInt8:     val =  cast(ubyte)val; break;
638     case TYP.Int16, TYP.UInt16:   val = cast(ushort)val; break;
639     case TYP.Int32, TYP.UInt32:   val =   cast(uint)val; break;
640     case TYP.Int64, TYP.UInt64:   val =  cast(ulong)val; break;
641     //case TYP.Int128, TYP.UInt128: val =  cast(ucent)val; break;
642     case TYP.Error:  r = e; return r;
643     default: assert(0);
644     }
645     r = new IntExpr(val >> bits, e.type);
646     r.setLoc(e);
647     return r;
648   }
649 
650   E visit(PlusExpr e)
651   {
652     Expression r, lhs = e.lhs, rhs = e.rhs;
653     auto et = e.type.flagsOf();
654     if (et.isReal() || et.isImaginary()) // Boths operands are real or imag.
655       r = new FloatExpr(EM.toRealOrImag(lhs) + EM.toRealOrImag(rhs), e.type);
656     else if (et.isComplex())
657       r = complexPlusOrMinus(e, false);
658     else
659       r = new IntExpr(EM.toInt(lhs) + EM.toInt(rhs), e.type);
660     r.setLoc(e);
661     return r;
662   }
663 
664   E visit(MinusExpr e)
665   {
666     Expression r, lhs = e.lhs, rhs = e.rhs;
667     auto et = e.type.flagsOf();
668     if (et.isReal() || et.isImaginary()) // Boths operands are real or imag.
669       r = new FloatExpr(EM.toRealOrImag(lhs) - EM.toRealOrImag(rhs), e.type);
670     else if (et.isComplex())
671       r = complexPlusOrMinus(e, true);
672     else
673       r = new IntExpr(EM.toInt(lhs) - EM.toInt(rhs), e.type);
674     r.setLoc(e);
675     return r;
676   }
677 
678   E visit(CatExpr e)
679   {
680     return e;
681   }
682 
683   E visit(MulExpr e)
684   {
685     Expression r, lhs = e.lhs, rhs = e.rhs;
686     auto et = e.type.flagsOf();
687     if (et.isFloating())
688     {
689       Complex z = EM.toComplex(lhs) * EM.toComplex(rhs);
690       if (et.isReal() || et.isImaginary())
691         r = new FloatExpr(et.isReal() ? z.re : z.im, e.type);
692       else
693         assert(et.isComplex()), r = new ComplexExpr(z, e.type);
694     }
695     else
696       r = new IntExpr(EM.toInt(lhs) * EM.toInt(rhs), e.type);
697     return r;
698   }
699 
700   E visit(DivExpr e)
701   {
702     Expression r, lhs = e.lhs, rhs = e.rhs;
703     auto et = e.type.flagsOf();
704     if (et.isFloating())
705     {
706       Complex z = EM.toComplex(lhs) / EM.toComplex(rhs);
707       if (et.isReal() || et.isImaginary())
708         r = new FloatExpr(et.isReal() ? z.re : z.im, e.type);
709       else
710         assert(et.isComplex()), r = new ComplexExpr(z, e.type);
711     }
712     else
713     {
714       ulong x, x1 = EM.toInt(lhs), x2 = EM.toInt(rhs);
715       if (x2 == 0)
716         error(rhs, "division by 0");
717       else if (lhs.type.isSigned() && rhs.type.isSigned())
718         x = cast(long)x1 / cast(long)x2;
719       else
720         x = x1 / x2;
721       r = new IntExpr(x, e.type);
722     }
723     return r;
724   }
725 
726   E visit(ModExpr e)
727   {
728     Expression r, lhs = e.lhs, rhs = e.rhs;
729     auto et = e.type.flagsOf();
730     if (et.isFloating())
731     {
732       Complex z = EM.toComplex(lhs) % EM.toComplex(rhs);
733       if (et.isReal() || et.isImaginary())
734         r = new FloatExpr(et.isReal() ? z.re : z.im, e.type);
735       else
736         assert(et.isComplex()), r = new ComplexExpr(z, e.type);
737     }
738     else
739     {
740       ulong x, x1 = EM.toInt(lhs), x2 = EM.toInt(rhs);
741       if (x2 == 0)
742         error(rhs, "modulo by 0");
743       else if (lhs.type.isSigned() && rhs.type.isSigned())
744         x = cast(long)x1 % cast(long)x2;
745       else
746         x = x1 % x2;
747       r = new IntExpr(x, e.type);
748     }
749     return r;
750   }
751 
752   E visit(AssignExpr e)
753   {
754     return e;
755   }
756 
757   E visit(LShiftAssignExpr e)
758   {
759     return e;
760   }
761 
762   E visit(RShiftAssignExpr e)
763   {
764     return e;
765   }
766 
767   E visit(URShiftAssignExpr e)
768   {
769     return e;
770   }
771 
772   E visit(OrAssignExpr e)
773   {
774     return e;
775   }
776 
777   E visit(AndAssignExpr e)
778   {
779     return e;
780   }
781 
782   E visit(PlusAssignExpr e)
783   {
784     return e;
785   }
786 
787   E visit(MinusAssignExpr e)
788   {
789     return e;
790   }
791 
792   E visit(DivAssignExpr e)
793   {
794     return e;
795   }
796 
797   E visit(MulAssignExpr e)
798   {
799     return e;
800   }
801 
802   E visit(ModAssignExpr e)
803   {
804     return e;
805   }
806 
807   E visit(XorAssignExpr e)
808   {
809     return e;
810   }
811 
812   E visit(CatAssignExpr e)
813   {
814     return e;
815   }
816 
817   E visit(AddressExpr e)
818   {
819     return e;
820   }
821 
822   E visit(PreIncrExpr e)
823   {
824     return e;
825   }
826 
827   E visit(PreDecrExpr e)
828   {
829     return e;
830   }
831 
832   E visit(PostIncrExpr e)
833   {
834     return e;
835   }
836 
837   E visit(PostDecrExpr e)
838   {
839     return e;
840   }
841 
842   E visit(DerefExpr e)
843   {
844     return e;
845   }
846 
847   E visit(SignExpr e)
848   {
849     Expression r;
850     if (e.isNeg()) // -(e.una)
851     {
852       auto et = e.type.flagsOf();
853       if (et.isReal() || et.isImaginary())
854         r = new FloatExpr(-EM.toRealOrImag(e.una), e.type);
855       else if (et.isComplex())
856         r = new ComplexExpr(-EM.toComplex(e.una), e.type);
857       else
858         r = new IntExpr(-EM.toInt(e.una), e.type);
859     }
860     else // +(e.una)
861       r = e.una;
862     r.setLoc(e);
863     return r;
864   }
865 
866   E visit(NotExpr e)
867   {
868     auto r = new IntExpr(EM.isBool(e) == 0, e.type);
869     r.setLoc(e);
870     return r;
871   }
872 
873   E visit(CompExpr e)
874   {
875     auto r = new IntExpr(~EM.toInt(e), e.type);
876     r.setLoc(e);
877     return r;
878   }
879 
880   E visit(CallExpr e)
881   {
882     return e;
883   }
884 
885   E visit(NewExpr e)
886   {
887     return e;
888   }
889 
890   E visit(NewClassExpr e)
891   {
892     return e;
893   }
894 
895   E visit(DeleteExpr e)
896   {
897     return e;
898   }
899 
900   E visit(CastExpr e)
901   {
902     return e;
903   }
904 
905   E visit(IndexExpr e)
906   {
907     return e;
908   }
909 
910   E visit(SliceExpr e)
911   {
912     return e;
913   }
914 
915   E visit(ModuleScopeExpr e)
916   {
917     return e;
918   }
919 
920   E visit(IdentifierExpr e)
921   {
922     return e;
923   }
924 
925   E visit(TmplInstanceExpr e)
926   {
927     return e;
928   }
929 
930   E visit(SpecialTokenExpr e)
931   {
932     return e;
933   }
934 
935   E visit(ThisExpr e)
936   {
937     return e;
938   }
939 
940   E visit(SuperExpr e)
941   {
942     return e;
943   }
944 
945   E visit(NullExpr e)
946   { // Just return e.
947     return e;
948   }
949 
950   E visit(DollarExpr e)
951   {
952     return e;
953   }
954 
955   E visit(BoolExpr e)
956   { // Just return the value of e.
957     return e.value;
958   }
959 
960   E visit(IntExpr e)
961   { // Just return e.
962     return e;
963   }
964 
965   E visit(FloatExpr e)
966   { // Just return e.
967     return e;
968   }
969 
970   E visit(ComplexExpr e)
971   { // Just return e.
972     return e;
973   }
974 
975   E visit(CharExpr e)
976   { // Just return e.
977     return e;
978   }
979 
980   E visit(StringExpr e)
981   { // Just return e.
982     return e;
983   }
984 
985   E visit(ArrayLiteralExpr e)
986   {
987     if (!e.values)
988       goto Lerror;
989     {
990     Expression[] elems_dup; // Duplicate if the elements changed.
991     foreach (i, elem; e.values)
992     {
993       auto newelem = visitE(elem);
994       if (newelem is NAR)
995         goto Lerror;
996       if (newelem !is elem)
997       {
998         if (!elems_dup)
999           elems_dup = e.values.dup;
1000         elems_dup[i] = newelem; // Overwrite if the element changed.
1001       }
1002     }
1003     Expression r = e;
1004     if (elems_dup)
1005     { // Make a new array literal.
1006       r = new ArrayLiteralExpr(elems_dup);
1007       r.setLoc(e);
1008       r.type = e.type;
1009     }
1010     return r;
1011     }
1012   Lerror:
1013     error(e, "cannot interpret array literal");
1014     return NAR;
1015   }
1016 
1017   E visit(AArrayLiteralExpr e)
1018   {
1019     return e;
1020   }
1021 
1022   E visit(AssertExpr e)
1023   {
1024     return e;
1025   }
1026 
1027   E visit(MixinExpr e)
1028   {
1029     return e;
1030   }
1031 
1032   E visit(ImportExpr e)
1033   {
1034     return e;
1035   }
1036 
1037   E visit(TypeofExpr e)
1038   {
1039     return e;
1040   }
1041 
1042   E visit(TypeDotIdExpr e)
1043   {
1044     return e;
1045   }
1046 
1047   E visit(TypeidExpr e)
1048   {
1049     return e;
1050   }
1051 
1052   E visit(IsExpr e)
1053   {
1054     return e;
1055   }
1056 
1057   E visit(ParenExpr e)
1058   {
1059     return e;
1060   }
1061 
1062   E visit(FuncLiteralExpr e)
1063   {
1064     return e;
1065   }
1066 
1067   E visit(LambdaExpr e)
1068   {
1069     return e;
1070   }
1071 
1072   E visit(TraitsExpr e) // D2.0
1073   {
1074     return e;
1075   }
1076 
1077   E visit(VoidInitExpr e)
1078   {
1079     return e;
1080   }
1081 
1082   E visit(ArrayInitExpr e)
1083   {
1084     return e;
1085   }
1086 
1087   E visit(StructInitExpr e)
1088   {
1089     return e;
1090   }
1091 
1092   E visit(AsmTypeExpr e)
1093   {
1094     assert(0);
1095     return e;
1096   }
1097 
1098   E visit(AsmOffsetExpr e)
1099   {
1100     assert(0);
1101     return e;
1102   }
1103 
1104   E visit(AsmSegExpr e)
1105   {
1106     assert(0);
1107     return e;
1108   }
1109 
1110   E visit(AsmPostBracketExpr e)
1111   {
1112     assert(0);
1113     return e;
1114   }
1115 
1116   E visit(AsmBracketExpr e)
1117   {
1118     assert(0);
1119     return e;
1120   }
1121 
1122   E visit(AsmLocalSizeExpr e)
1123   {
1124     assert(0);
1125     return e;
1126   }
1127 
1128   E visit(AsmRegisterExpr e)
1129   {
1130     assert(0);
1131     return e;
1132   }
1133 } // override
1134 
1135   /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1136   |                                   Types                                   |
1137    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
1138 
1139 override
1140 {
1141   T visit(IllegalType)
1142   { assert(0, "interpreting invalid AST"); return null; }
1143 
1144   T visit(IntegralType t)
1145   {
1146     return t;
1147   }
1148 
1149   T visit(ModuleScopeType t)
1150   {
1151     return t;
1152   }
1153 
1154   T visit(IdentifierType t)
1155   {
1156     return t;
1157   }
1158 
1159   T visit(TypeofType t)
1160   {
1161     return t;
1162   }
1163 
1164   T visit(TmplInstanceType t)
1165   {
1166     return t;
1167   }
1168 
1169   T visit(PointerType t)
1170   {
1171     return t;
1172   }
1173 
1174   T visit(ArrayType t)
1175   {
1176     return t;
1177   }
1178 
1179   T visit(FunctionType t)
1180   {
1181     return t;
1182   }
1183 
1184   T visit(DelegateType t)
1185   {
1186     return t;
1187   }
1188 
1189   T visit(BaseClassType t)
1190   {
1191     return t;
1192   }
1193 } // override
1194 
1195   /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1196   |                                 Parameters                                |
1197    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
1198 
1199 override
1200 {
1201   N visit(Parameter p)
1202   {
1203     return p;
1204   }
1205 
1206   N visit(Parameters p)
1207   {
1208     return p;
1209   }
1210 
1211   N visit(TemplateAliasParam p)
1212   {
1213     return p;
1214   }
1215 
1216   N visit(TemplateTypeParam p)
1217   {
1218     return p;
1219   }
1220 
1221   N visit(TemplateThisParam p) // D2.0
1222   {
1223     return p;
1224   }
1225 
1226   N visit(TemplateValueParam p)
1227   {
1228     return p;
1229   }
1230 
1231   N visit(TemplateTupleParam p)
1232   {
1233     return p;
1234   }
1235 
1236   N visit(TemplateParameters p)
1237   {
1238     return p;
1239   }
1240 
1241   N visit(TemplateArguments p)
1242   {
1243     return p;
1244   }
1245 } // override
1246 }