Mercurial > projects > ldc
comparison dmd2/interpret.c @ 1452:638d16625da2
LDC 2 compiles again.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Sat, 30 May 2009 17:23:32 +0100 |
parents | 75c53f8f67a4 |
children | 54b3c1394d62 |
comparison
equal
deleted
inserted
replaced
1423:42bd767ec5a4 | 1452:638d16625da2 |
---|---|
10 | 10 |
11 #include <stdio.h> | 11 #include <stdio.h> |
12 #include <stdlib.h> | 12 #include <stdlib.h> |
13 #include <assert.h> | 13 #include <assert.h> |
14 | 14 |
15 #include "mem.h" | 15 #include "rmem.h" |
16 | 16 |
17 #include "statement.h" | 17 #include "statement.h" |
18 #include "expression.h" | 18 #include "expression.h" |
19 #include "cond.h" | 19 #include "cond.h" |
20 #include "init.h" | 20 #include "init.h" |
67 else if (ident == Id::aaKeys) | 67 else if (ident == Id::aaKeys) |
68 return interpret_aaKeys(istate, arguments); | 68 return interpret_aaKeys(istate, arguments); |
69 else if (ident == Id::aaValues) | 69 else if (ident == Id::aaValues) |
70 return interpret_aaValues(istate, arguments); | 70 return interpret_aaValues(istate, arguments); |
71 | 71 |
72 if (cantInterpret || semanticRun == 1) | 72 if (cantInterpret || semanticRun == 3) |
73 return NULL; | 73 return NULL; |
74 | 74 |
75 if (needThis() || isNested() || !fbody) | 75 if (needThis() || isNested() || !fbody) |
76 { cantInterpret = 1; | 76 { cantInterpret = 1; |
77 return NULL; | 77 return NULL; |
78 } | 78 } |
79 | 79 |
80 if (semanticRun == 0 && scope) | 80 if (semanticRun < 3 && scope) |
81 { | 81 { |
82 semantic3(scope); | 82 semantic3(scope); |
83 if (global.errors) // if errors compiling this function | 83 if (global.errors) // if errors compiling this function |
84 return NULL; | 84 return NULL; |
85 } | 85 } |
86 if (semanticRun < 2) | 86 if (semanticRun < 4) |
87 return NULL; | 87 return NULL; |
88 | 88 |
89 Type *tb = type->toBasetype(); | 89 Type *tb = type->toBasetype(); |
90 assert(tb->ty == Tfunction); | 90 assert(tb->ty == Tfunction); |
91 TypeFunction *tf = (TypeFunction *)tb; | 91 TypeFunction *tf = (TypeFunction *)tb; |
985 | 985 |
986 Expression *getVarExp(Loc loc, InterState *istate, Declaration *d) | 986 Expression *getVarExp(Loc loc, InterState *istate, Declaration *d) |
987 { | 987 { |
988 Expression *e = EXP_CANT_INTERPRET; | 988 Expression *e = EXP_CANT_INTERPRET; |
989 VarDeclaration *v = d->isVarDeclaration(); | 989 VarDeclaration *v = d->isVarDeclaration(); |
990 #if IN_LLVM | |
990 StaticStructInitDeclaration *s = d->isStaticStructInitDeclaration(); | 991 StaticStructInitDeclaration *s = d->isStaticStructInitDeclaration(); |
992 #else | |
993 SymbolDeclaration *s = d->isSymbolDeclaration(); | |
994 #endif | |
991 if (v) | 995 if (v) |
992 { | 996 { |
993 #if DMDV2 | 997 #if DMDV2 |
994 if ((v->isConst() || v->isInvariant()) && v->init && !v->value) | 998 if ((v->isConst() || v->isInvariant()) && v->init && !v->value) |
995 #else | 999 #else |
1509 } | 1513 } |
1510 v->value = e2; | 1514 v->value = e2; |
1511 e = Cast(type, type, post ? ev : e2); | 1515 e = Cast(type, type, post ? ev : e2); |
1512 } | 1516 } |
1513 } | 1517 } |
1518 } | |
1519 /* Assignment to struct member of the form: | |
1520 * v.var = e2 | |
1521 */ | |
1522 else if (e1->op == TOKdotvar && ((DotVarExp *)e1)->e1->op == TOKvar) | |
1523 { VarExp *ve = (VarExp *)((DotVarExp *)e1)->e1; | |
1524 VarDeclaration *v = ve->var->isVarDeclaration(); | |
1525 | |
1526 if (v->isDataseg()) | |
1527 return EXP_CANT_INTERPRET; | |
1528 if (fp && !v->value) | |
1529 { error("variable %s is used before initialization", v->toChars()); | |
1530 return e; | |
1531 } | |
1532 if (v->value == NULL && v->init->isVoidInitializer()) | |
1533 { /* Since a void initializer initializes to undefined | |
1534 * values, it is valid here to use the default initializer. | |
1535 * No attempt is made to determine if someone actually relies | |
1536 * on the void value - to do that we'd need a VoidExp. | |
1537 * That's probably a good enhancement idea. | |
1538 */ | |
1539 v->value = v->type->defaultInit(); | |
1540 } | |
1541 Expression *vie = v->value; | |
1542 if (vie->op == TOKvar) | |
1543 { | |
1544 Declaration *d = ((VarExp *)vie)->var; | |
1545 vie = getVarExp(e1->loc, istate, d); | |
1546 } | |
1547 if (vie->op != TOKstructliteral) | |
1548 return EXP_CANT_INTERPRET; | |
1549 StructLiteralExp *se = (StructLiteralExp *)vie; | |
1550 VarDeclaration *vf = ((DotVarExp *)e1)->var->isVarDeclaration(); | |
1551 if (!vf) | |
1552 return EXP_CANT_INTERPRET; | |
1553 int fieldi = se->getFieldIndex(type, vf->offset); | |
1554 if (fieldi == -1) | |
1555 return EXP_CANT_INTERPRET; | |
1556 Expression *ev = se->getField(type, vf->offset); | |
1557 if (fp) | |
1558 e2 = (*fp)(type, ev, e2); | |
1559 else | |
1560 e2 = Cast(type, type, e2); | |
1561 if (e2 == EXP_CANT_INTERPRET) | |
1562 return e2; | |
1563 | |
1564 if (!v->isParameter()) | |
1565 { | |
1566 for (size_t i = 0; 1; i++) | |
1567 { | |
1568 if (i == istate->vars.dim) | |
1569 { istate->vars.push(v); | |
1570 break; | |
1571 } | |
1572 if (v == (VarDeclaration *)istate->vars.data[i]) | |
1573 break; | |
1574 } | |
1575 } | |
1576 | |
1577 /* Create new struct literal reflecting updated fieldi | |
1578 */ | |
1579 Expressions *expsx = new Expressions(); | |
1580 expsx->setDim(se->elements->dim); | |
1581 for (size_t j = 0; j < expsx->dim; j++) | |
1582 { | |
1583 if (j == fieldi) | |
1584 expsx->data[j] = (void *)e2; | |
1585 else | |
1586 expsx->data[j] = se->elements->data[j]; | |
1587 } | |
1588 v->value = new StructLiteralExp(se->loc, se->sd, expsx); | |
1589 v->value->type = se->type; | |
1590 | |
1591 e = Cast(type, type, post ? ev : e2); | |
1514 } | 1592 } |
1515 /* Assignment to struct member of the form: | 1593 /* Assignment to struct member of the form: |
1516 * *(symoffexp) = e2 | 1594 * *(symoffexp) = e2 |
1517 */ | 1595 */ |
1518 else if (e1->op == TOKstar && ((PtrExp *)e1)->e1->op == TOKsymoff) | 1596 else if (e1->op == TOKstar && ((PtrExp *)e1)->e1->op == TOKsymoff) |
2157 } | 2235 } |
2158 | 2236 |
2159 Expression *DotVarExp::interpret(InterState *istate) | 2237 Expression *DotVarExp::interpret(InterState *istate) |
2160 { Expression *e = EXP_CANT_INTERPRET; | 2238 { Expression *e = EXP_CANT_INTERPRET; |
2161 | 2239 |
2240 #if LOG | |
2241 printf("DotVarExp::interpret() %s\n", toChars()); | |
2242 #endif | |
2243 | |
2162 Expression *ex = e1->interpret(istate); | 2244 Expression *ex = e1->interpret(istate); |
2163 | 2245 if (ex != EXP_CANT_INTERPRET) |
2164 // Constant fold structliteral.member | 2246 { |
2165 if (ex != EXP_CANT_INTERPRET && ex->op == TOKstructliteral) | 2247 if (ex->op == TOKstructliteral) |
2166 { StructLiteralExp *se = (StructLiteralExp *)ex; | 2248 { StructLiteralExp *se = (StructLiteralExp *)ex; |
2167 | 2249 VarDeclaration *v = var->isVarDeclaration(); |
2168 VarDeclaration* v; | 2250 if (v) |
2169 if (v = var->isVarDeclaration()) | 2251 { e = se->getField(type, v->offset); |
2170 { | 2252 if (!e) |
2171 e = se->getField(type, v->offset); | 2253 e = EXP_CANT_INTERPRET; |
2172 if (!e) | 2254 return e; |
2173 e = EXP_CANT_INTERPRET; | 2255 } |
2174 } | 2256 } |
2175 } | 2257 } |
2176 | 2258 |
2259 #if LOG | |
2260 if (e == EXP_CANT_INTERPRET) | |
2261 printf("DotVarExp::interpret() %s = EXP_CANT_INTERPRET\n", toChars()); | |
2262 #endif | |
2177 return e; | 2263 return e; |
2178 } | 2264 } |
2179 | 2265 |
2180 /******************************* Special Functions ***************************/ | 2266 /******************************* Special Functions ***************************/ |
2181 | 2267 |