Fixed semi-colon parsing in C-style for loops
[delight/core.git] / dmd2 / init.c
blobd31c80a346bbd8df138d3b298fb36eb3c6d11efb
2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2007 by Digital Mars
4 // All Rights Reserved
5 // written by Walter Bright
6 // http://www.digitalmars.com
7 // License for redistribution is by either the Artistic License
8 // in artistic.txt, or the GNU General Public License in gnu.txt.
9 // See the included readme.txt for details.
11 /* NOTE: This file has been patched from the original DMD distribution to
12 work with the GDC compiler.
14 Modified by David Friedman, December 2006
17 #include <stdio.h>
18 #include <assert.h>
20 #include "mars.h"
21 #include "init.h"
22 #include "expression.h"
23 #include "statement.h"
24 #include "identifier.h"
25 #include "declaration.h"
26 #include "aggregate.h"
27 #include "scope.h"
28 #include "mtype.h"
29 #include "hdrgen.h"
31 /********************************** Initializer *******************************/
33 Initializer::Initializer(Loc loc)
35 this->loc = loc;
38 Initializer *Initializer::syntaxCopy()
40 return this;
43 Initializer *Initializer::semantic(Scope *sc, Type *t)
45 return this;
48 Type *Initializer::inferType(Scope *sc)
50 error(loc, "cannot infer type from initializer");
51 return Type::terror;
54 Initializers *Initializer::arraySyntaxCopy(Initializers *ai)
55 { Initializers *a = NULL;
57 if (ai)
59 a = new Initializers();
60 a->setDim(ai->dim);
61 for (int i = 0; i < a->dim; i++)
62 { Initializer *e = (Initializer *)ai->data[i];
64 e = e->syntaxCopy();
65 a->data[i] = e;
68 return a;
71 char *Initializer::toChars()
72 { OutBuffer *buf;
73 HdrGenState hgs;
75 memset(&hgs, 0, sizeof(hgs));
76 buf = new OutBuffer();
77 toCBuffer(buf, &hgs);
78 return buf->toChars();
81 /********************************** VoidInitializer ***************************/
83 VoidInitializer::VoidInitializer(Loc loc)
84 : Initializer(loc)
86 type = NULL;
90 Initializer *VoidInitializer::syntaxCopy()
92 return new VoidInitializer(loc);
96 Initializer *VoidInitializer::semantic(Scope *sc, Type *t)
98 //printf("VoidInitializer::semantic(t = %p)\n", t);
99 type = t;
100 return this;
104 Expression *VoidInitializer::toExpression()
106 error(loc, "void initializer has no value");
107 return new IntegerExp(0);
111 void VoidInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
113 buf->writestring("void");
117 /********************************** StructInitializer *************************/
119 StructInitializer::StructInitializer(Loc loc)
120 : Initializer(loc)
122 ad = NULL;
125 Initializer *StructInitializer::syntaxCopy()
127 StructInitializer *ai = new StructInitializer(loc);
129 assert(field.dim == value.dim);
130 ai->field.setDim(field.dim);
131 ai->value.setDim(value.dim);
132 for (int i = 0; i < field.dim; i++)
134 ai->field.data[i] = field.data[i];
136 Initializer *init = (Initializer *)value.data[i];
137 init = init->syntaxCopy();
138 ai->value.data[i] = init;
140 return ai;
143 void StructInitializer::addInit(Identifier *field, Initializer *value)
145 //printf("StructInitializer::addInit(field = %p, value = %p)\n", field, value);
146 this->field.push(field);
147 this->value.push(value);
150 Initializer *StructInitializer::semantic(Scope *sc, Type *t)
152 TypeStruct *ts;
153 int errors = 0;
155 //printf("StructInitializer::semantic(t = %s) %s\n", t->toChars(), toChars());
156 vars.setDim(field.dim);
157 t = t->toBasetype();
158 if (t->ty == Tstruct)
159 { unsigned i;
160 unsigned fieldi = 0;
162 ts = (TypeStruct *)t;
163 ad = ts->sym;
164 for (i = 0; i < field.dim; i++)
166 Identifier *id = (Identifier *)field.data[i];
167 Initializer *val = (Initializer *)value.data[i];
168 Dsymbol *s;
169 VarDeclaration *v;
171 if (id == NULL)
173 if (fieldi >= ad->fields.dim)
174 { error(loc, "too many initializers for %s", ad->toChars());
175 field.remove(i);
176 i--;
177 continue;
179 else
181 s = (Dsymbol *)ad->fields.data[fieldi];
184 else
186 //s = ad->symtab->lookup(id);
187 s = ad->search(loc, id, 0);
188 if (!s)
190 error(loc, "'%s' is not a member of '%s'", id->toChars(), t->toChars());
191 continue;
194 // Find out which field index it is
195 for (fieldi = 0; 1; fieldi++)
197 if (fieldi >= ad->fields.dim)
199 s->error("is not a per-instance initializable field");
200 break;
202 if (s == (Dsymbol *)ad->fields.data[fieldi])
203 break;
206 if (s && (v = s->isVarDeclaration()) != NULL)
208 val = val->semantic(sc, v->type);
209 value.data[i] = (void *)val;
210 vars.data[i] = (void *)v;
212 else
213 { error(loc, "%s is not a field of %s", id ? id->toChars() : s->toChars(), ad->toChars());
214 errors = 1;
216 fieldi++;
219 else if (t->ty == Tdelegate && value.dim == 0)
220 { /* Rewrite as empty delegate literal { }
222 Arguments *arguments = new Arguments;
223 Type *tf = new TypeFunction(arguments, NULL, 0, LINKd);
224 FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(loc, 0, tf, TOKdelegate, NULL);
225 fd->fbody = new CompoundStatement(loc, new Statements());
226 fd->endloc = loc;
227 Expression *e = new FuncExp(loc, fd);
228 ExpInitializer *ie = new ExpInitializer(loc, e);
229 return ie->semantic(sc, t);
231 else
233 error(loc, "a struct is not a valid initializer for a %s", t->toChars());
234 errors = 1;
236 if (errors)
238 field.setDim(0);
239 value.setDim(0);
240 vars.setDim(0);
242 return this;
246 /***************************************
247 * This works by transforming a struct initializer into
248 * a struct literal. In the future, the two should be the
249 * same thing.
251 Expression *StructInitializer::toExpression()
252 { Expression *e;
254 //printf("StructInitializer::toExpression() %s\n", toChars());
255 if (!ad) // if fwd referenced
257 return NULL;
259 StructDeclaration *sd = ad->isStructDeclaration();
260 if (!sd)
261 return NULL;
262 Expressions *elements = new Expressions();
263 for (size_t i = 0; i < value.dim; i++)
265 if (field.data[i])
266 goto Lno;
267 Initializer *iz = (Initializer *)value.data[i];
268 if (!iz)
269 goto Lno;
270 Expression *ex = iz->toExpression();
271 if (!ex)
272 goto Lno;
273 elements->push(ex);
275 e = new StructLiteralExp(loc, sd, elements);
276 e->type = sd->type;
277 return e;
279 Lno:
280 delete elements;
281 //error(loc, "struct initializers as expressions are not allowed");
282 return NULL;
286 void StructInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
288 //printf("StructInitializer::toCBuffer()\n");
289 buf->writebyte('{');
290 for (int i = 0; i < field.dim; i++)
292 if (i > 0)
293 buf->writebyte(',');
294 Identifier *id = (Identifier *)field.data[i];
295 if (id)
297 buf->writestring(id->toChars());
298 buf->writebyte(':');
300 Initializer *iz = (Initializer *)value.data[i];
301 if (iz)
302 iz->toCBuffer(buf, hgs);
304 buf->writebyte('}');
307 /********************************** ArrayInitializer ************************************/
309 ArrayInitializer::ArrayInitializer(Loc loc)
310 : Initializer(loc)
312 dim = 0;
313 type = NULL;
314 sem = 0;
317 Initializer *ArrayInitializer::syntaxCopy()
319 //printf("ArrayInitializer::syntaxCopy()\n");
321 ArrayInitializer *ai = new ArrayInitializer(loc);
323 assert(index.dim == value.dim);
324 ai->index.setDim(index.dim);
325 ai->value.setDim(value.dim);
326 for (int i = 0; i < ai->value.dim; i++)
327 { Expression *e = (Expression *)index.data[i];
328 if (e)
329 e = e->syntaxCopy();
330 ai->index.data[i] = e;
332 Initializer *init = (Initializer *)value.data[i];
333 init = init->syntaxCopy();
334 ai->value.data[i] = init;
336 return ai;
339 void ArrayInitializer::addInit(Expression *index, Initializer *value)
341 this->index.push(index);
342 this->value.push(value);
343 dim = 0;
344 type = NULL;
347 Initializer *ArrayInitializer::semantic(Scope *sc, Type *t)
348 { unsigned i;
349 unsigned length;
351 //printf("ArrayInitializer::semantic(%s)\n", t->toChars());
352 if (sem) // if semantic() already run
353 return this;
354 sem = 1;
355 type = t;
356 t = t->toBasetype();
357 switch (t->ty)
359 case Tpointer:
360 case Tsarray:
361 case Tarray:
362 break;
364 default:
365 error(loc, "cannot use array to initialize %s", type->toChars());
366 return this;
369 length = 0;
370 for (i = 0; i < index.dim; i++)
371 { Expression *idx;
372 Initializer *val;
374 idx = (Expression *)index.data[i];
375 if (idx)
376 { idx = idx->semantic(sc);
377 idx = idx->optimize(WANTvalue | WANTinterpret);
378 index.data[i] = (void *)idx;
379 length = idx->toInteger();
382 val = (Initializer *)value.data[i];
383 val = val->semantic(sc, t->nextOf());
384 value.data[i] = (void *)val;
385 length++;
386 if (length == 0)
387 error("array dimension overflow");
388 if (length > dim)
389 dim = length;
391 uintmax_t amax = 0x80000000;
392 if ((uintmax_t) dim * t->nextOf()->size() >= amax)
393 error(loc, "array dimension %"PRIuTSIZE" exceeds max of %"PRIuMAX, dim, amax / t->nextOf()->size());
394 return this;
397 /********************************
398 * If possible, convert array initializer to array literal.
401 Expression *ArrayInitializer::toExpression()
402 { Expressions *elements;
403 Expression *e;
405 //printf("ArrayInitializer::toExpression()\n");
406 //static int i; if (++i == 2) halt();
407 elements = new Expressions();
408 for (size_t i = 0; i < value.dim; i++)
410 if (index.data[i])
411 goto Lno;
412 Initializer *iz = (Initializer *)value.data[i];
413 if (!iz)
414 goto Lno;
415 Expression *ex = iz->toExpression();
416 if (!ex)
417 goto Lno;
418 elements->push(ex);
420 e = new ArrayLiteralExp(loc, elements);
421 e->type = type;
422 return e;
424 Lno:
425 delete elements;
426 error(loc, "array initializers as expressions are not allowed");
427 return NULL;
431 /********************************
432 * If possible, convert array initializer to associative array initializer.
435 Initializer *ArrayInitializer::toAssocArrayInitializer()
436 { Expressions *keys;
437 Expressions *values;
438 Expression *e;
440 //printf("ArrayInitializer::toAssocArrayInitializer()\n");
441 //static int i; if (++i == 2) halt();
442 keys = new Expressions();
443 keys->setDim(value.dim);
444 values = new Expressions();
445 values->setDim(value.dim);
447 for (size_t i = 0; i < value.dim; i++)
449 e = (Expression *)index.data[i];
450 if (!e)
451 goto Lno;
452 keys->data[i] = (void *)e;
454 Initializer *iz = (Initializer *)value.data[i];
455 if (!iz)
456 goto Lno;
457 e = iz->toExpression();
458 if (!e)
459 goto Lno;
460 values->data[i] = (void *)e;
462 e = new AssocArrayLiteralExp(loc, keys, values);
463 return new ExpInitializer(loc, e);
465 Lno:
466 delete keys;
467 delete values;
468 error(loc, "not an associative array initializer");
469 return this;
473 Type *ArrayInitializer::inferType(Scope *sc)
475 for (size_t i = 0; i < value.dim; i++)
477 if (index.data[i])
478 goto Lno;
480 if (value.dim)
482 Initializer *iz = (Initializer *)value.data[0];
483 if (iz)
484 { Type *t = iz->inferType(sc);
485 t = new TypeSArray(t, new IntegerExp(value.dim));
486 t = t->semantic(loc, sc);
487 return t;
491 Lno:
492 error(loc, "cannot infer type from this array initializer");
493 return Type::terror;
497 void ArrayInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
499 buf->writebyte('[');
500 for (int i = 0; i < index.dim; i++)
502 if (i > 0)
503 buf->writebyte(',');
504 Expression *ex = (Expression *)index.data[i];
505 if (ex)
507 ex->toCBuffer(buf, hgs);
508 buf->writebyte(':');
510 Initializer *iz = (Initializer *)value.data[i];
511 if (iz)
512 iz->toCBuffer(buf, hgs);
514 buf->writebyte(']');
518 /********************************** ExpInitializer ************************************/
520 ExpInitializer::ExpInitializer(Loc loc, Expression *exp)
521 : Initializer(loc)
523 this->exp = exp;
526 Initializer *ExpInitializer::syntaxCopy()
528 return new ExpInitializer(loc, exp->syntaxCopy());
531 Initializer *ExpInitializer::semantic(Scope *sc, Type *t)
533 //printf("ExpInitializer::semantic(%s), type = %s\n", exp->toChars(), t->toChars());
534 exp = exp->semantic(sc);
535 exp = exp->optimize(WANTvalue | WANTinterpret);
536 Type *tb = t->toBasetype();
538 /* Look for case of initializing a static array with a too-short
539 * string literal, such as:
540 * char[5] foo = "abc";
541 * Allow this by doing an explicit cast, which will lengthen the string
542 * literal.
544 if (exp->op == TOKstring && tb->ty == Tsarray && exp->type->ty == Tsarray)
545 { StringExp *se = (StringExp *)exp;
547 if (!se->committed && se->type->ty == Tsarray &&
548 ((TypeSArray *)se->type)->dim->toInteger() <
549 ((TypeSArray *)t)->dim->toInteger())
551 exp = se->castTo(sc, t);
552 goto L1;
556 // Look for the case of statically initializing an array
557 // with a single member.
558 if (tb->ty == Tsarray &&
559 !tb->nextOf()->equals(exp->type->toBasetype()->nextOf()) &&
560 exp->implicitConvTo(tb->nextOf())
563 t = tb->nextOf();
566 exp = exp->implicitCastTo(sc, t);
568 exp = exp->optimize(WANTvalue | WANTinterpret);
569 //printf("-ExpInitializer::semantic(): "); exp->print();
570 return this;
573 Type *ExpInitializer::inferType(Scope *sc)
575 //printf("ExpInitializer::inferType() %s\n", toChars());
576 exp = exp->semantic(sc);
577 exp = resolveProperties(sc, exp);
579 // Give error for overloaded function addresses
580 if (exp->op == TOKsymoff)
581 { SymOffExp *se = (SymOffExp *)exp;
582 if (se->hasOverloads && !se->var->isFuncDeclaration()->isUnique())
583 exp->error("cannot infer type from overloaded function symbol %s", exp->toChars());
586 Type *t = exp->type;
587 return t;
588 //return t->ty == Tsarray ? t : t->toHeadMutable();
591 Expression *ExpInitializer::toExpression()
593 return exp;
597 void ExpInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
599 exp->toCBuffer(buf, hgs);