root/branches/dmdfe/expression.c

Revision 740, 182.5 kB (checked in by Gregor, 1 year ago)

MERGE: DMD 1.019

Line 
1 // Compiler implementation of the D programming language
2 // Copyright (c) 1999-2007 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <ctype.h>
13 #include <assert.h>
14 #include <complex>
15 #include <math.h>
16
17 #if _WIN32 && __DMC__
18 extern "C" char * __cdecl __locale_decpoint;
19 #endif
20
21 #if __WIN32 && __GNUC__
22 #define isnan _isnan
23 #elif __APPLE__
24 using std::isnan;
25 #endif
26
27 #if IN_GCC
28 // Issues with using -include total.h (defines integer_t) and then complex.h fails...
29 #undef integer_t
30 #endif
31
32 #ifdef __APPLE__
33 #define integer_t dmd_integer_t
34 #endif
35
36 #if IN_GCC || IN_DMDFE
37 #include "mem.h"
38 #elif _WIN32
39 #include "..\root\mem.h"
40 #elif linux
41 #include "../root/mem.h"
42 #endif
43
44 //#include "port.h"
45 #include "mtype.h"
46 #include "init.h"
47 #include "expression.h"
48 #include "template.h"
49 #include "utf.h"
50 #include "enum.h"
51 #include "scope.h"
52 #include "statement.h"
53 #include "declaration.h"
54 #include "aggregate.h"
55 #include "import.h"
56 #include "id.h"
57 #include "dsymbol.h"
58 #include "module.h"
59 #include "attrib.h"
60 #include "hdrgen.h"
61 #include "parse.h"
62
63 //Expression *createTypeInfoArray(Scope *sc, Expression *args[], int dim);
64
65 #define LOGSEMANTIC 0
66
67 /**********************************
68  * Set operator precedence for each operator.
69  */
70
71 // Operator precedence - greater values are higher precedence
72
73 enum PREC
74 {
75     PREC_zero,
76     PREC_expr,
77     PREC_assign,
78     PREC_cond,
79     PREC_oror,
80     PREC_andand,
81     PREC_or,
82     PREC_xor,
83     PREC_and,
84     PREC_equal,
85     PREC_rel,
86     PREC_shift,
87     PREC_add,
88     PREC_mul,
89     PREC_unary,
90     PREC_primary,
91 };
92
93 enum PREC precedence[TOKMAX];
94
95 void initPrecedence()
96 {
97     precedence[TOKimport] = PREC_primary;
98     precedence[TOKidentifier] = PREC_primary;
99     precedence[TOKthis] = PREC_primary;
100     precedence[TOKsuper] = PREC_primary;
101     precedence[TOKint64] = PREC_primary;
102     precedence[TOKfloat64] = PREC_primary;
103     precedence[TOKnull] = PREC_primary;
104     precedence[TOKstring] = PREC_primary;
105     precedence[TOKarrayliteral] = PREC_primary;
106     precedence[TOKtypedot] = PREC_primary;
107     precedence[TOKtypeid] = PREC_primary;
108     precedence[TOKis] = PREC_primary;
109     precedence[TOKassert] = PREC_primary;
110     precedence[TOKfunction] = PREC_primary;
111     precedence[TOKvar] = PREC_primary;
112
113     // post
114     precedence[TOKdotti] = PREC_primary;
115     precedence[TOKdot] = PREC_primary;
116 //  precedence[TOKarrow] = PREC_primary;
117     precedence[TOKplusplus] = PREC_primary;
118     precedence[TOKminusminus] = PREC_primary;
119     precedence[TOKcall] = PREC_primary;
120     precedence[TOKslice] = PREC_primary;
121     precedence[TOKarray] = PREC_primary;
122
123     precedence[TOKaddress] = PREC_unary;
124     precedence[TOKstar] = PREC_unary;
125     precedence[TOKneg] = PREC_unary;
126     precedence[TOKuadd] = PREC_unary;
127     precedence[TOKnot] = PREC_unary;
128     precedence[TOKtobool] = PREC_add;
129     precedence[TOKtilde] = PREC_unary;
130     precedence[TOKdelete] = PREC_unary;
131     precedence[TOKnew] = PREC_unary;
132     precedence[TOKcast] = PREC_unary;
133
134     precedence[TOKmul] = PREC_mul;
135     precedence[TOKdiv] = PREC_mul;
136     precedence[TOKmod] = PREC_mul;
137
138     precedence[TOKadd] = PREC_add;
139     precedence[TOKmin] = PREC_add;
140     precedence[TOKcat] = PREC_add;
141
142     precedence[TOKshl] = PREC_shift;
143     precedence[TOKshr] = PREC_shift;
144     precedence[TOKushr] = PREC_shift;
145
146     precedence[TOKlt] = PREC_rel;
147     precedence[TOKle] = PREC_rel;
148     precedence[TOKgt] = PREC_rel;
149     precedence[TOKge] = PREC_rel;
150     precedence[TOKunord] = PREC_rel;
151     precedence[TOKlg] = PREC_rel;
152     precedence[TOKleg] = PREC_rel;
153     precedence[TOKule] = PREC_rel;
154     precedence[TOKul] = PREC_rel;
155     precedence[TOKuge] = PREC_rel;
156     precedence[TOKug] = PREC_rel;
157     precedence[TOKue] = PREC_rel;
158     precedence[TOKin] = PREC_rel;
159
160     precedence[TOKequal] = PREC_equal;
161     precedence[TOKnotequal] = PREC_equal;
162     precedence[TOKidentity] = PREC_equal;
163     precedence[TOKnotidentity] = PREC_equal;
164
165     precedence[TOKand] = PREC_and;
166
167     precedence[TOKxor] = PREC_xor;
168
169     precedence[TOKor] = PREC_or;
170
171     precedence[TOKandand] = PREC_andand;
172
173     precedence[TOKoror] = PREC_oror;
174
175     precedence[TOKquestion] = PREC_cond;
176
177     precedence[TOKassign] = PREC_assign;
178     precedence[TOKaddass] = PREC_assign;
179     precedence[TOKminass] = PREC_assign;
180     precedence[TOKcatass] = PREC_assign;
181     precedence[TOKmulass] = PREC_assign;
182     precedence[TOKdivass] = PREC_assign;
183     precedence[TOKmodass] = PREC_assign;
184     precedence[TOKshlass] = PREC_assign;
185     precedence[TOKshrass] = PREC_assign;
186     precedence[TOKushrass] = PREC_assign;
187     precedence[TOKandass] = PREC_assign;
188     precedence[TOKorass] = PREC_assign;
189     precedence[TOKxorass] = PREC_assign;
190
191     precedence[TOKcomma] = PREC_expr;
192 }
193
194 /*****************************************
195  * Determine if 'this' is available.
196  * If it is, return the FuncDeclaration that has it.
197  */
198
199 FuncDeclaration *hasThis(Scope *sc)
200 {   FuncDeclaration *fd;
201     FuncDeclaration *fdthis;
202
203     //printf("hasThis()\n");
204     fdthis = sc->parent->isFuncDeclaration();
205     //printf("fdthis = %p, '%s'\n", fdthis, fdthis ? fdthis->toChars() : "");
206
207     // Go upwards until we find the enclosing member function
208     fd = fdthis;
209     while (1)
210     {
211     if (!fd)
212     {
213         goto Lno;
214     }
215     if (!fd->isNested())
216         break;
217
218     Dsymbol *parent = fd->parent;
219     while (parent)
220     {
221         TemplateInstance *ti = parent->isTemplateInstance();
222         if (ti)
223         parent = ti->parent;
224         else
225         break;
226     }
227
228     fd = fd->parent->isFuncDeclaration();
229     }
230
231     if (!fd->isThis())
232     {   //printf("test '%s'\n", fd->toChars());
233     goto Lno;
234     }
235
236     assert(fd->vthis);
237     return fd;
238
239 Lno:
240     return NULL;        // don't have 'this' available
241 }
242
243
244 /***************************************
245  * Pull out any properties.
246  */
247
248 Expression *resolveProperties(Scope *sc, Expression *e)
249 {
250     //printf("resolveProperties(%s)\n", e->toChars());
251     if (e->type)
252     {
253     Type *t = e->type->toBasetype();
254
255     if (t->ty == Tfunction)
256     {
257         e = new CallExp(e->loc, e);
258         e = e->semantic(sc);
259     }
260
261     /* Look for e being a lazy parameter; rewrite as delegate call
262      */
263     else if (e->op == TOKvar)
264     {   VarExp *ve = (VarExp *)e;
265
266         if (ve->var->storage_class & STClazy)
267         {
268         e = new CallExp(e->loc, e);
269         e = e->semantic(sc);
270         }
271     }
272
273     else if (e->op == TOKdotexp)
274     {
275         e->error("expression has no value");
276     }
277     }
278     return e;
279 }
280
281 /******************************
282  * Perform semantic() on an array of Expressions.
283  */
284
285 void arrayExpressionSemantic(Expressions *exps, Scope *sc)
286 {
287     if (exps)
288     {
289     for (size_t i = 0; i < exps->dim; i++)
290     {   Expression *e = (Expression *)exps->data[i];
291
292         e = e->semantic(sc);
293         exps->data[i] = (void *)e;
294     }
295     }
296 }
297
298 /****************************************
299  * Expand tuples.
300  */
301
302 void expandTuples(Expressions *exps)
303 {
304     //printf("expandTuples()\n");
305     if (exps)
306     {
307     for (size_t i = 0; i < exps->dim; i++)
308     {   Expression *arg = (Expression *)exps->data[i];
309         if (!arg)
310         continue;
311
312         // Look for tuple with 0 members
313         if (arg->op == TOKtype)
314         {   TypeExp *e = (TypeExp *)arg;
315         if (e->type->toBasetype()->ty == Ttuple)
316         {   TypeTuple *tt = (TypeTuple *)e->type->toBasetype();
317
318             if (!tt->arguments || tt->arguments->dim == 0)
319             {
320             exps->remove(i);
321             if (i == exps->dim)
322                 return;
323             i--;
324             continue;
325             }
326         }
327         }
328
329         // Inline expand all the tuples
330         while (arg->op == TOKtuple)
331         {   TupleExp *te = (TupleExp *)arg;
332
333         exps->remove(i);        // remove arg
334         exps->insert(i, te->exps);  // replace with tuple contents
335         if (i == exps->dim)
336             return;     // empty tuple, no more arguments
337         arg = (Expression *)exps->data[i];
338         }
339     }
340     }
341 }
342
343 /****************************************
344  * Preprocess arguments to function.
345  */
346
347 void preFunctionArguments(Loc loc, Scope *sc, Expressions *exps)
348 {
349     if (exps)
350     {
351     expandTuples(exps);
352
353     for (size_t i = 0; i < exps->dim; i++)
354     {   Expression *arg = (Expression *)exps->data[i];
355
356         if (!arg->type)
357         {
358 #ifdef DEBUG
359         if (!global.gag)
360             printf("1: \n");
361 #endif
362         arg->error("%s is not an expression", arg->toChars());
363         arg = new IntegerExp(arg->loc, 0, Type::tint32);
364         }
365
366         arg = resolveProperties(sc, arg);
367         exps->data[i] = (void *) arg;
368
369         //arg->rvalue();
370 #if 0
371         if (arg->type->ty == Tfunction)
372         {
373         arg = new AddrExp(arg->loc, arg);
374         arg = arg->semantic(sc);
375         exps->data[i] = (void *) arg;
376         }
377 #endif
378     }
379     }
380 }
381
382
383 /****************************************
384  * Now that we know the exact type of the function we're calling,
385  * the arguments[] need to be adjusted:
386  *  1) implicitly convert argument to the corresponding parameter type
387  *  2) add default arguments for any missing arguments
388  *  3) do default promotions on arguments corresponding to ...
389  *  4) add hidden _arguments[] argument
390  */
391
392 void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *arguments)
393 {
394     unsigned n;
395     int done;
396     Type *tb;
397
398     //printf("functionArguments()\n");
399     assert(arguments);
400     size_t nargs = arguments ? arguments->dim : 0;
401     size_t nparams = Argument::dim(tf->parameters);
402
403     if (nargs > nparams && tf->varargs == 0)
404     error(loc, "expected " ZU " arguments, not " ZU, nparams, nargs);
405
406     n = (nargs > nparams) ? nargs : nparams;    // n = max(nargs, nparams)
407
408     done = 0;
409     for (size_t i = 0; i < n; i++)
410     {
411     Expression *arg;
412
413     if (i < nargs)
414         arg = (Expression *)arguments->data[i];
415     else
416         arg = NULL;
417
418     if (i < nparams)
419     {
420         Argument *p = Argument::getNth(tf->parameters, i);
421
422         if (!arg)
423         {
424         if (!p->defaultArg)
425         {
426             if (tf->varargs == 2 && i + 1 == nparams)
427             goto L2;
428             error(loc, "expected " ZU " arguments, not " ZU, nparams, nargs);
429             break;
430         }
431         arg = p->defaultArg->copy();
432         arguments->push(arg);
433         nargs++;
434         }
435
436         if (tf->varargs == 2 && i + 1 == nparams)
437         {
438         //printf("\t\tvarargs == 2, p->type = '%s'\n", p->type->toChars());
439         if (arg->implicitConvTo(p->type))
440         {
441             if (nargs != nparams)
442                 error(loc, "expected " ZU " arguments, not " ZU, nparams, nargs);
443             goto L1;
444         }
445          L2:
446         Type *tb = p->type->toBasetype();
447         Type *tret = p->isLazyArray();
448         switch (tb->ty)
449         {
450             case Tsarray:
451             case Tarray:
452             {   // Create a static array variable v of type arg->type
453 #ifdef IN_GCC
454             /* GCC 4.0 does not like zero length arrays used like
455                this; pass a null array value instead. Could also
456                just make a one-element array. */
457             if (nargs - i == 0)
458             {
459                 arg = new NullExp(loc);
460                 break;
461             }
462 #endif
463             static int idn;
464             char name[10 + sizeof(idn)*3 + 1];
465             sprintf(name, "__arrayArg%d", ++idn);
466             Identifier *id = Lexer::idPool(name);
467             Type *t = new TypeSArray(tb->next, new IntegerExp(nargs - i));
468             t = t->semantic(loc, sc);
469             VarDeclaration *v = new VarDeclaration(loc, t, id, new VoidInitializer(loc));
470             v->semantic(sc);
471             v->parent = sc->parent;
472             //sc->insert(v);
473
474             Expression *c = new DeclarationExp(0, v);
475             c->type = v->type;
476
477             for (size_t u = i; u < nargs; u++)
478             {   Expression *a = (Expression *)arguments->data[u];
479                 if (tret && !tb->next->equals(a->type))
480                 a = a->toDelegate(sc, tret);
481
482                 Expression *e = new VarExp(loc, v);
483                 e = new IndexExp(loc, e, new IntegerExp(u + 1 - nparams));
484                 e = new AssignExp(loc, e, a);
485                 if (c)
486                 c = new CommaExp(loc, c, e);
487                 else
488                 c = e;
489             }
490             arg = new VarExp(loc, v);
491             if (c)
492                 arg = new CommaExp(loc, c, arg);
493             break;
494             }
495             case Tclass:
496             {   /* Set arg to be:
497              *  new Tclass(arg0, arg1, ..., argn)
498              */
499             Expressions *args = new Expressions();
500             args->setDim(nargs - i);
501             for (size_t u = i; u < nargs; u++)
502                 args->data[u - i] = arguments->data[u];
503             arg = new NewExp(loc, NULL, NULL, p->type, args);
504             break;
505             }
506             default:
507             if (!arg)
508             {   error(loc, "not enough arguments");
509                 return;
510                 }
511             break;
512         }
513         arg = arg->semantic(sc);
514         //printf("\targ = '%s'\n", arg->toChars());
515         arguments->setDim(i + 1);
516         done = 1;
517         }
518
519     L1:
520         if (!(p->storageClass & STClazy && p->type->ty == Tvoid))
521         arg = arg->implicitCastTo(sc, p->type);
522         if (p->storageClass & (STCout | STCref))
523         {
524         // BUG: should check that argument to ref is type 'invariant'
525         // BUG: assignments to ref should also be type 'invariant'
526         arg = arg->modifiableLvalue(sc, NULL);
527
528         //if (arg->op == TOKslice)
529             //arg->error("cannot modify slice %s", arg->toChars());
530         }
531
532         // Convert static arrays to pointers
533         tb = arg->type->toBasetype();
534         if (tb->ty == Tsarray)
535         {
536         arg = arg->checkToPointer();
537         }
538
539         // Convert lazy argument to a delegate
540         if (p->storageClass & STClazy)
541         {
542         arg = arg->toDelegate(sc, p->type);
543         }
544     }
545     else
546     {
547
548         // If not D linkage, do promotions
549         if (tf->linkage != LINKd)
550         {
551         // Promote bytes, words, etc., to ints
552         arg = arg->integralPromotions(sc);
553
554         // Promote floats to doubles
555         switch (arg->type->ty)
556         {
557             case Tfloat32:
558             arg = arg->castTo(sc, Type::tfloat64);
559             break;
560
561             case Timaginary32:
562             arg = arg->castTo(sc, Type::timaginary64);
563             break;
564         }
565         }
566
567         // Convert static arrays to dynamic arrays
568         tb = arg->type->toBasetype();
569         if (tb->ty == Tsarray)
570         {   TypeSArray *ts = (TypeSArray *)tb;
571         Type *ta = tb->next->arrayOf();
572         if (ts->size(arg->loc) == 0)
573         {   arg = new NullExp(arg->loc);
574             arg->type = ta;
575         }
576         else
577             arg = arg->castTo(sc, ta);
578         }
579
580         arg->rvalue();
581     }
582     arg = arg->optimize(WANTvalue);
583     arguments->data[i] = (void *) arg;
584     if (done)
585         break;
586     }
587
588     // If D linkage and variadic, add _arguments[] as first argument
589     if (tf->linkage == LINKd && tf->varargs == 1)
590     {
591     Expression *e;
592
593     /*e = createTypeInfoArray(sc, (Expression **)&arguments->data[nparams],
594         arguments->dim - nparams);
595     arguments->insert(0, e);*/
596        
597         e = new NullExp(loc);
598         e->type = Type::tint32;
599     }
600 }
601
602 /**************************************************
603  * Write expression out to buf, but wrap it
604  * in ( ) if its precedence is less than pr.
605  */
606
607 void expToCBuffer(OutBuffer *buf, HdrGenState *hgs, Expression *e, enum PREC pr)
608 {
609     if (precedence[e->op] < pr)
610     {
611     buf->writeByte('(');
612     e->toCBuffer(buf, hgs);
613     buf->writeByte(')');
614     }
615     else
616     e->toCBuffer(buf, hgs);
617 }
618
619 /**************************************************
620  * Write out argument list to buf.
621  */
622
623 void argsToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *hgs)
624 {
625     if (arguments)
626     {
627     for (size_t i = 0; i < arguments->dim; i++)
628     {   Expression *arg = (Expression *)arguments->data[i];
629
630         if (i)
631         buf->writeByte(',');
632         expToCBuffer(buf, hgs, arg, PREC_assign);
633     }
634     }
635 }
636
637 /**************************************************
638  * Write out argument types to buf.
639  */
640
641 void argExpTypesToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *hgs)
642 {
643     if (arguments)
644     {   OutBuffer argbuf;
645
646     for (size_t i = 0; i < arguments->dim; i++)
647     {   Expression *arg = (Expression *)arguments->data[i];
648
649         if (i)
650         buf->writeByte(',');
651