comparison dmd/interpret.c @ 1630:44b145be2ef5

Merge dmd 1.056.
author Robert Clipsham <robert@octarineparrot.com>
date Sat, 06 Feb 2010 15:53:52 +0000
parents e83f0778c260
children 9bf06e02070b
comparison
equal deleted inserted replaced
1629:b07d683ba4d0 1630:44b145be2ef5
1 1
2 // Compiler implementation of the D programming language 2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2009 by Digital Mars 3 // Copyright (c) 1999-2010 by Digital Mars
4 // All Rights Reserved 4 // All Rights Reserved
5 // written by Walter Bright 5 // written by Walter Bright
6 // http://www.digitalmars.com 6 // http://www.digitalmars.com
7 // License for redistribution is by either the Artistic License 7 // License for redistribution is by either the Artistic License
8 // in artistic.txt, or the GNU General Public License in gnu.txt. 8 // in artistic.txt, or the GNU General Public License in gnu.txt.
50 50
51 Expression *interpret_length(InterState *istate, Expression *earg); 51 Expression *interpret_length(InterState *istate, Expression *earg);
52 Expression *interpret_keys(InterState *istate, Expression *earg, FuncDeclaration *fd); 52 Expression *interpret_keys(InterState *istate, Expression *earg, FuncDeclaration *fd);
53 Expression *interpret_values(InterState *istate, Expression *earg, FuncDeclaration *fd); 53 Expression *interpret_values(InterState *istate, Expression *earg, FuncDeclaration *fd);
54 54
55 ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Type *type, Expression *elem, size_t dim);
56
55 /************************************* 57 /*************************************
56 * Attempt to interpret a function given the arguments. 58 * Attempt to interpret a function given the arguments.
57 * Input: 59 * Input:
58 * istate state for calling function (NULL if none) 60 * istate state for calling function (NULL if none)
59 * arguments function arguments 61 * arguments function arguments
90 else if (ident == Id::values) 92 else if (ident == Id::values)
91 return interpret_values(istate, thisarg, this); 93 return interpret_values(istate, thisarg, this);
92 } 94 }
93 #endif 95 #endif
94 96
95 if (cantInterpret || semanticRun == 3) 97 if (cantInterpret || semanticRun == PASSsemantic3)
96 return NULL; 98 return NULL;
97 99
98 if (!fbody) 100 if (!fbody)
99 { cantInterpret = 1; 101 { cantInterpret = 1;
100 return NULL; 102 return NULL;
101 } 103 }
102 104
103 if (semanticRun < 3 && scope) 105 if (semanticRun < PASSsemantic3 && scope)
104 { 106 {
105 semantic3(scope); 107 semantic3(scope);
106 if (global.errors) // if errors compiling this function 108 if (global.errors) // if errors compiling this function
107 return NULL; 109 return NULL;
108 } 110 }
109 if (semanticRun < 4) 111 if (semanticRun < PASSsemantic3done)
110 return NULL; 112 return NULL;
111 113
112 Type *tb = type->toBasetype(); 114 Type *tb = type->toBasetype();
113 assert(tb->ty == Tfunction); 115 assert(tb->ty == Tfunction);
114 TypeFunction *tf = (TypeFunction *)tb; 116 TypeFunction *tf = (TypeFunction *)tb;
158 160
159 for (size_t i = 0; i < dim; i++) 161 for (size_t i = 0; i < dim; i++)
160 { Expression *earg = (Expression *)arguments->data[i]; 162 { Expression *earg = (Expression *)arguments->data[i];
161 Parameter *arg = Parameter::getNth(tf->parameters, i); 163 Parameter *arg = Parameter::getNth(tf->parameters, i);
162 164
163 if (arg->storageClass & (STCout | STCref)) 165 if (arg->storageClass & (STCout | STCref | STClazy))
164 { 166 {
165 } 167 }
166 else 168 else
167 { /* Value parameters 169 { /* Value parameters
168 */ 170 */
1003 printf("StringExp::interpret() %s\n", toChars()); 1005 printf("StringExp::interpret() %s\n", toChars());
1004 #endif 1006 #endif
1005 return this; 1007 return this;
1006 } 1008 }
1007 1009
1010 Expression *FuncExp::interpret(InterState *istate)
1011 {
1012 #if LOG
1013 printf("FuncExp::interpret() %s\n", toChars());
1014 #endif
1015 return this;
1016 }
1017
1018 Expression *SymOffExp::interpret(InterState *istate)
1019 {
1020 #if LOG
1021 printf("SymOffExp::interpret() %s\n", toChars());
1022 #endif
1023 if (var->isFuncDeclaration() && offset == 0)
1024 {
1025 return this;
1026 }
1027 error("Cannot interpret %s at compile time", toChars());
1028 return EXP_CANT_INTERPRET;
1029 }
1030
1031 Expression *DelegateExp::interpret(InterState *istate)
1032 {
1033 #if LOG
1034 printf("DelegateExp::interpret() %s\n", toChars());
1035 #endif
1036 return this;
1037 }
1038
1008 Expression *getVarExp(Loc loc, InterState *istate, Declaration *d) 1039 Expression *getVarExp(Loc loc, InterState *istate, Declaration *d)
1009 { 1040 {
1010 Expression *e = EXP_CANT_INTERPRET; 1041 Expression *e = EXP_CANT_INTERPRET;
1011 VarDeclaration *v = d->isVarDeclaration(); 1042 VarDeclaration *v = d->isVarDeclaration();
1012 StaticStructInitDeclaration *s = d->isStaticStructInitDeclaration(); 1043 StaticStructInitDeclaration *s = d->isStaticStructInitDeclaration();
1013 if (v) 1044 if (v)
1014 { 1045 {
1015 #if DMDV2 1046 #if DMDV2
1047 /* Magic variable __ctfe always returns true when interpreting
1048 */
1049 if (v->ident == Id::ctfe)
1050 return new IntegerExp(loc, 1, Type::tbool);
1051
1016 if ((v->isConst() || v->isImmutable() || v->storage_class & STCmanifest) && v->init && !v->value) 1052 if ((v->isConst() || v->isImmutable() || v->storage_class & STCmanifest) && v->init && !v->value)
1017 #else 1053 #else
1018 if (v->isConst() && v->init) 1054 if (v->isConst() && v->init)
1019 #endif 1055 #endif
1020 { e = v->init->toExpression(); 1056 { e = v->init->toExpression();
1021 if (e && !e->type) 1057 if (e && !e->type)
1022 e->type = v->type; 1058 e->type = v->type;
1059 }
1060 else if (v->isCTFE() && !v->value)
1061 {
1062 if (v->init)
1063 {
1064 e = v->init->toExpression();
1065 e = e->interpret(istate);
1066 }
1067 else // This should never happen
1068 e = v->type->defaultInitLiteral();
1023 } 1069 }
1024 else 1070 else
1025 { e = v->value; 1071 { e = v->value;
1026 if (!v->isCTFE()) 1072 if (!v->isCTFE())
1027 { error(loc, "static variable %s cannot be read at compile time", v->toChars()); 1073 { error(loc, "static variable %s cannot be read at compile time", v->toChars());
1480 } 1526 }
1481 return expsx; 1527 return expsx;
1482 } 1528 }
1483 1529
1484 /*************************************** 1530 /***************************************
1485 * Returns oldelems[0..insertpoint] ~ newelems ~ oldelems[insertpoint..$] 1531 * Returns oldelems[0..insertpoint] ~ newelems ~ oldelems[insertpoint+newelems.length..$]
1486 */ 1532 */
1487 Expressions *spliceElements(Expressions *oldelems, 1533 Expressions *spliceElements(Expressions *oldelems,
1488 Expressions *newelems, size_t insertpoint) 1534 Expressions *newelems, size_t insertpoint)
1489 { 1535 {
1490 Expressions *expsx = new Expressions(); 1536 Expressions *expsx = new Expressions();
1495 expsx->data[j] = newelems->data[j - insertpoint]; 1541 expsx->data[j] = newelems->data[j - insertpoint];
1496 else 1542 else
1497 expsx->data[j] = oldelems->data[j]; 1543 expsx->data[j] = oldelems->data[j];
1498 } 1544 }
1499 return expsx; 1545 return expsx;
1546 }
1547
1548 /***************************************
1549 * Returns oldstr[0..insertpoint] ~ newstr ~ oldstr[insertpoint+newlen..$]
1550 */
1551 StringExp *spliceStringExp(StringExp *oldstr, StringExp *newstr, size_t insertpoint)
1552 {
1553 assert(oldstr->sz==newstr->sz);
1554 unsigned char *s;
1555 size_t oldlen = oldstr->len;
1556 size_t newlen = newstr->len;
1557 size_t sz = oldstr->sz;
1558 s = (unsigned char *)mem.calloc(oldlen + 1, sz);
1559 memcpy(s, oldstr->string, oldlen * sz);
1560 memcpy(s + insertpoint * sz, newstr->string, newlen * sz);
1561 StringExp *se2 = new StringExp(oldstr->loc, s, oldlen);
1562 se2->committed = oldstr->committed;
1563 se2->postfix = oldstr->postfix;
1564 se2->type = oldstr->type;
1565 return se2;
1500 } 1566 }
1501 1567
1502 /****************************** 1568 /******************************
1503 * Create an array literal consisting of 'elem' duplicated 'dim' times. 1569 * Create an array literal consisting of 'elem' duplicated 'dim' times.
1504 */ 1570 */
1512 ArrayLiteralExp *ae = new ArrayLiteralExp(0, elements); 1578 ArrayLiteralExp *ae = new ArrayLiteralExp(0, elements);
1513 ae->type = type; 1579 ae->type = type;
1514 return ae; 1580 return ae;
1515 } 1581 }
1516 1582
1583 /******************************
1584 * Create a string literal consisting of 'value' duplicated 'dim' times.
1585 */
1586 StringExp *createBlockDuplicatedStringLiteral(Type *type,
1587 unsigned value, size_t dim, int sz)
1588 {
1589 unsigned char *s;
1590 s = (unsigned char *)mem.calloc(dim + 1, sz);
1591 for (int elemi=0; elemi<dim; ++elemi)
1592 {
1593 switch (sz)
1594 {
1595 case 1: s[elemi] = value; break;
1596 case 2: ((unsigned short *)s)[elemi] = value; break;
1597 case 4: ((unsigned *)s)[elemi] = value; break;
1598 default: assert(0);
1599 }
1600 }
1601 StringExp *se = new StringExp(0, s, dim);
1602 se->type = type;
1603 return se;
1604 }
1517 1605
1518 /******************************** 1606 /********************************
1519 * Add v to the istate list, unless it already exists there. 1607 * Add v to the istate list, unless it already exists there.
1520 */ 1608 */
1521 void addVarToInterstate(InterState *istate, VarDeclaration *v) 1609 void addVarToInterstate(InterState *istate, VarDeclaration *v)
1580 } 1668 }
1581 1669
1582 // To reduce code complexity of handling dotvar expressions, 1670 // To reduce code complexity of handling dotvar expressions,
1583 // extract the aggregate now. 1671 // extract the aggregate now.
1584 Expression *aggregate; 1672 Expression *aggregate;
1585 if (e1->op == TOKdotvar) { 1673 if (e1->op == TOKdotvar)
1674 {
1586 aggregate = ((DotVarExp *)e1)->e1; 1675 aggregate = ((DotVarExp *)e1)->e1;
1587 // Get rid of 'this'. 1676 // Get rid of 'this'.
1588 if (aggregate->op == TOKthis && istate->localThis) 1677 if (aggregate->op == TOKthis && istate->localThis)
1589 aggregate = istate->localThis; 1678 aggregate = istate->localThis;
1590 } 1679 }
1591 1680 if (e1->op == TOKthis && istate->localThis)
1681 e1 = istate->localThis;
1682
1592 /* Assignment to variable of the form: 1683 /* Assignment to variable of the form:
1593 * v = e2 1684 * v = e2
1594 */ 1685 */
1595 if (e1->op == TOKvar) 1686 if (e1->op == TOKvar)
1596 { 1687 {
1621 e2 = Cast(v->type, v->type, e2); 1712 e2 = Cast(v->type, v->type, e2);
1622 } 1713 }
1623 if (e2 == EXP_CANT_INTERPRET) 1714 if (e2 == EXP_CANT_INTERPRET)
1624 return e2; 1715 return e2;
1625 1716
1626 addVarToInterstate(istate, v); 1717 if (istate)
1718 addVarToInterstate(istate, v);
1627 v->value = e2; 1719 v->value = e2;
1628 e = Cast(type, type, post ? ev : e2); 1720 e = Cast(type, type, post ? ev : e2);
1629 } 1721 }
1630 } 1722 }
1631 else if (e1->op == TOKdotvar && aggregate->op == TOKdotvar) 1723 else if (e1->op == TOKdotvar && aggregate->op == TOKdotvar)
1666 * values, it is valid here to use the default initializer. 1758 * values, it is valid here to use the default initializer.
1667 * No attempt is made to determine if someone actually relies 1759 * No attempt is made to determine if someone actually relies
1668 * on the void value - to do that we'd need a VoidExp. 1760 * on the void value - to do that we'd need a VoidExp.
1669 * That's probably a good enhancement idea. 1761 * That's probably a good enhancement idea.
1670 */ 1762 */
1671 v->value = v->type->defaultInit(); 1763 v->value = v->type->defaultInitLiteral();
1672 } 1764 }
1673 Expression *vie = v->value; 1765 Expression *vie = v->value;
1766 assert(vie != EXP_CANT_INTERPRET);
1767
1674 if (vie->op == TOKvar) 1768 if (vie->op == TOKvar)
1675 { 1769 {
1676 Declaration *d = ((VarExp *)vie)->var; 1770 Declaration *d = ((VarExp *)vie)->var;
1677 vie = getVarExp(e1->loc, istate, d); 1771 vie = getVarExp(e1->loc, istate, d);
1678 } 1772 }
1679 if (vie->op != TOKstructliteral) 1773 if (vie->op != TOKstructliteral)
1774 {
1775 error("Cannot assign %s=%s in CTFE", v->toChars(), vie->toChars());
1680 return EXP_CANT_INTERPRET; 1776 return EXP_CANT_INTERPRET;
1777 }
1681 StructLiteralExp *se = (StructLiteralExp *)vie; 1778 StructLiteralExp *se = (StructLiteralExp *)vie;
1682 VarDeclaration *vf = ((DotVarExp *)e1)->var->isVarDeclaration(); 1779 VarDeclaration *vf = ((DotVarExp *)e1)->var->isVarDeclaration();
1683 if (!vf) 1780 if (!vf)
1684 return EXP_CANT_INTERPRET; 1781 return EXP_CANT_INTERPRET;
1685 int fieldi = se->getFieldIndex(type, vf->offset); 1782 int fieldi = se->getFieldIndex(type, vf->offset);
2013 if (!v || !v->isCTFE()) 2110 if (!v || !v->isCTFE())
2014 { 2111 {
2015 error("%s cannot be modified at compile time", v->toChars()); 2112 error("%s cannot be modified at compile time", v->toChars());
2016 return EXP_CANT_INTERPRET; 2113 return EXP_CANT_INTERPRET;
2017 } 2114 }
2018 // Chase down rebinding of out and ref 2115 // Chase down rebinding of out and ref
2019 if (v->value && v->value->op == TOKvar) 2116 if (v->value && v->value->op == TOKvar)
2020 { 2117 {
2021 VarExp *ve2 = (VarExp *)v->value; 2118 VarExp *ve2 = (VarExp *)v->value;
2022 if (ve2->var->isStaticStructInitDeclaration()) 2119 if (ve2->var->isStaticStructInitDeclaration())
2023 { // This can happen if v is a struct initialized to 2120 { // This can happen if v is a struct initialized to
2024 // 0 using an __initZ SymbolDeclaration from 2121 // 0 using an __initZ SymbolDeclaration from
2025 // TypeStruct::defaultInit() 2122 // TypeStruct::defaultInit()
2026 } 2123 }
2027 else 2124 else
2028 v = ve2->var->isVarDeclaration(); 2125 v = ve2->var->isVarDeclaration();
2029 assert(v); 2126 assert(v);
2030 } 2127 }
2031 /* Set the $ variable 2128 /* Set the $ variable
2032 */ 2129 */
2033 Expression *ee = v->value ? ArrayLength(Type::tsize_t, v->value) 2130 Expression *ee = v->value ? ArrayLength(Type::tsize_t, v->value)
2034 : EXP_CANT_INTERPRET; 2131 : EXP_CANT_INTERPRET;
2035 if (ee != EXP_CANT_INTERPRET && sexp->lengthVar) 2132 if (ee != EXP_CANT_INTERPRET && sexp->lengthVar)
2060 return EXP_CANT_INTERPRET; 2157 return EXP_CANT_INTERPRET;
2061 } 2158 }
2062 if (v->value->op == TOKarrayliteral) 2159 if (v->value->op == TOKarrayliteral)
2063 dim = ((ArrayLiteralExp *)v->value)->elements->dim; 2160 dim = ((ArrayLiteralExp *)v->value)->elements->dim;
2064 else if (v->value->op ==TOKstring) 2161 else if (v->value->op ==TOKstring)
2065 { 2162 dim = ((StringExp *)v->value)->len;
2066 error("String slice assignment is not yet supported in CTFE");
2067 return EXP_CANT_INTERPRET;
2068 }
2069 } 2163 }
2070 else 2164 else
2071 { 2165 {
2072 error("%s cannot be evaluated at compile time", toChars()); 2166 error("%s cannot be evaluated at compile time", toChars());
2073 return EXP_CANT_INTERPRET; 2167 return EXP_CANT_INTERPRET;
2074 } 2168 }
2075 int upperbound = upper ? upper->toInteger() : dim; 2169 int upperbound = upper ? upper->toInteger() : dim;
2076 int lowerbound = lower ? lower->toInteger() : 0; 2170 int lowerbound = lower ? lower->toInteger() : 0;
2077 2171
2078 ArrayLiteralExp *existing;
2079 if (((int)lowerbound < 0) || (upperbound > dim)) 2172 if (((int)lowerbound < 0) || (upperbound > dim))
2080 { 2173 {
2081 error("Array bounds [0..%d] exceeded in slice [%d..%d]", dim, lowerbound, upperbound); 2174 error("Array bounds [0..%d] exceeded in slice [%d..%d]",
2175 dim, lowerbound, upperbound);
2082 return EXP_CANT_INTERPRET; 2176 return EXP_CANT_INTERPRET;
2083 } 2177 }
2084 if (upperbound-lowerbound != dim) 2178 // Could either be slice assignment (v[] = e[]),
2085 { 2179 // or block assignment (v[] = val).
2086 // Only modifying part of the array. Must create a new array literal. 2180 // For the former, we check that the lengths match.
2087 // If the existing array is uninitialized (this can only happen 2181 bool isSliceAssignment = (e2->op == TOKarrayliteral)
2088 // with static arrays), create it. 2182 || (e2->op == TOKstring);
2089 if (v->value && v->value->op == TOKarrayliteral) 2183 size_t srclen = 0;
2090 existing = (ArrayLiteralExp *)v->value; 2184 if (e2->op == TOKarrayliteral)
2091 else 2185 srclen = ((ArrayLiteralExp *)e2)->elements->dim;
2092 { 2186 else if (e2->op == TOKstring)
2093 // this can only happen with static arrays 2187 srclen = ((StringExp *)e2)->len;
2094 existing = createBlockDuplicatedArrayLiteral(v->type, v->type->defaultInit(), dim); 2188 if (isSliceAssignment && srclen != (upperbound - lowerbound))
2095 } 2189 {
2096 } 2190 error("Array length mismatch assigning [0..%d] to [%d..%d]", srclen, lowerbound, upperbound);
2097 2191 return e;
2192 }
2098 if (e2->op == TOKarrayliteral) 2193 if (e2->op == TOKarrayliteral)
2099 { 2194 {
2100 // Static array assignment from literal 2195 // Static array assignment from literal
2101 ArrayLiteralExp *ae = (ArrayLiteralExp *)e2; 2196 ArrayLiteralExp *ae = (ArrayLiteralExp *)e2;
2102 if (ae->elements->dim != (upperbound - lowerbound))
2103 {
2104 error("Array length mismatch assigning [0..%d] to [%d..%d]", ae->elements->dim, lowerbound, upperbound);
2105 return e;
2106 }
2107 if (upperbound - lowerbound == dim) 2197 if (upperbound - lowerbound == dim)
2108 v->value = ae; 2198 v->value = ae;
2109 else 2199 else
2110 { 2200 {
2201 ArrayLiteralExp *existing;
2202 // Only modifying part of the array. Must create a new array literal.
2203 // If the existing array is uninitialized (this can only happen
2204 // with static arrays), create it.
2205 if (v->value && v->value->op == TOKarrayliteral)
2206 existing = (ArrayLiteralExp *)v->value;
2207 else // this can only happen with static arrays
2208 existing = createBlockDuplicatedArrayLiteral(v->type, v->type->defaultInit(), dim);
2111 // value[] = value[0..lower] ~ ae ~ value[upper..$] 2209 // value[] = value[0..lower] ~ ae ~ value[upper..$]
2112 existing->elements = spliceElements(existing->elements, ae->elements, lowerbound); 2210 existing->elements = spliceElements(existing->elements, ae->elements, lowerbound);
2113 v->value = existing; 2211 v->value = existing;
2114 } 2212 }
2115 return e2; 2213 return e2;
2116 } 2214 }
2215 else if (e2->op == TOKstring)
2216 {
2217 StringExp *se = (StringExp *)e2;
2218 if (upperbound-lowerbound == dim)
2219 v->value = e2;
2220 else
2221 {
2222 if (!v->value)
2223 v->value = createBlockDuplicatedStringLiteral(se->type,
2224 se->type->defaultInit()->toInteger(), dim, se->sz);
2225 if (v->value->op==TOKstring)
2226 v->value = spliceStringExp((StringExp *)v->value, se, lowerbound);
2227 else
2228 error("String slice assignment is not yet supported in CTFE");
2229 }
2230 return e2;
2231 }
2117 else if (t->nextOf()->ty == e2->type->ty) 2232 else if (t->nextOf()->ty == e2->type->ty)
2118 { 2233 {
2119 // Static array block assignment 2234 // Static array block assignment
2120 if (upperbound-lowerbound ==dim) 2235 if (upperbound - lowerbound == dim)
2121 v->value = createBlockDuplicatedArrayLiteral(v->type, e2, dim); 2236 v->value = createBlockDuplicatedArrayLiteral(v->type, e2, dim);
2122 else 2237 else
2123 { 2238 {
2239 ArrayLiteralExp *existing;
2240 // Only modifying part of the array. Must create a new array literal.
2241 // If the existing array is uninitialized (this can only happen
2242 // with static arrays), create it.
2243 if (v->value && v->value->op == TOKarrayliteral)
2244 existing = (ArrayLiteralExp *)v->value;
2245 else // this can only happen with static arrays
2246 existing = createBlockDuplicatedArrayLiteral(v->type, v->type->defaultInit(), dim);
2124 // value[] = value[0..lower] ~ ae ~ value[upper..$] 2247 // value[] = value[0..lower] ~ ae ~ value[upper..$]
2125 existing->elements = spliceElements(existing->elements, createBlockDuplicatedArrayLiteral(v->type, e2, upperbound-lowerbound)->elements, lowerbound); 2248 existing->elements = spliceElements(existing->elements,
2249 createBlockDuplicatedArrayLiteral(v->type, e2, upperbound-lowerbound)->elements,
2250 lowerbound);
2126 v->value = existing; 2251 v->value = existing;
2127 } 2252 }
2128 return e2;
2129 }
2130 else if (e2->op == TOKstring)
2131 {
2132 StringExp *se = (StringExp *)e2;
2133 // This is problematic. char[8] should be storing
2134 // values as a string literal, not
2135 // as an array literal. Then, for static arrays, we
2136 // could do modifications
2137 // in-place, with a dramatic memory and speed improvement.
2138 error("String slice assignment is not yet supported in CTFE");
2139 return e2; 2253 return e2;
2140 } 2254 }
2141 else 2255 else
2142 { 2256 {
2143 error("Slice operation %s cannot be evaluated at compile time", toChars()); 2257 error("Slice operation %s cannot be evaluated at compile time", toChars());
2258 { Expression *e = EXP_CANT_INTERPRET; 2372 { Expression *e = EXP_CANT_INTERPRET;
2259 2373
2260 #if LOG 2374 #if LOG
2261 printf("CallExp::interpret() %s\n", toChars()); 2375 printf("CallExp::interpret() %s\n", toChars());
2262 #endif 2376 #endif
2263 if (e1->op == TOKdotvar) 2377
2264 { 2378 Expression * pthis = NULL;
2265 Expression * pthis = ((DotVarExp*)e1)->e1; 2379 FuncDeclaration *fd = NULL;
2266 FuncDeclaration *fd = ((DotVarExp*)e1)->var->isFuncDeclaration(); 2380 Expression *ecall = e1;
2267 TypeFunction *tf = fd ? (TypeFunction *)(fd->type) : NULL; 2381 if (ecall->op == TOKindex)
2268 if (tf) 2382 ecall = e1->interpret(istate);
2269 { // Member function call 2383 if (ecall->op == TOKdotvar && !((DotVarExp*)ecall)->var->isFuncDeclaration())
2270 if(pthis->op == TOKthis) 2384 ecall = e1->interpret(istate);
2271 pthis = istate->localThis; 2385
2272 Expression *eresult = fd->interpret(istate, arguments, pthis); 2386 if (ecall->op == TOKdotvar)
2387 { // Calling a member function
2388 pthis = ((DotVarExp*)e1)->e1;
2389 fd = ((DotVarExp*)e1)->var->isFuncDeclaration();
2390 }
2391 else if (ecall->op == TOKvar)
2392 {
2393 VarDeclaration *vd = ((VarExp *)ecall)->var->isVarDeclaration();
2394 if (vd && vd->value)
2395 ecall = vd->value;
2396 else // Calling a function
2397 fd = ((VarExp *)e1)->var->isFuncDeclaration();
2398 }
2399 if (ecall->op == TOKdelegate)
2400 { // Calling a delegate
2401 fd = ((DelegateExp *)ecall)->func;
2402 pthis = ((DelegateExp *)ecall)->e1;
2403 }
2404 else if (ecall->op == TOKfunction)
2405 { // Calling a delegate literal
2406 fd = ((FuncExp*)ecall)->fd;
2407 }
2408 else if (ecall->op == TOKstar && ((PtrExp*)ecall)->e1->op==TOKfunction)
2409 { // Calling a function literal
2410 fd = ((FuncExp*)((PtrExp*)ecall)->e1)->fd;
2411 }
2412 else if (ecall->op == TOKstar && ((PtrExp*)ecall)->e1->op==TOKvar)
2413 { // Calling a function pointer
2414 VarDeclaration *vd = ((VarExp *)((PtrExp*)ecall)->e1)->var->isVarDeclaration();
2415 if (vd && vd->value && vd->value->op==TOKsymoff)
2416 fd = ((SymOffExp *)vd->value)->var->isFuncDeclaration();
2417 }
2418
2419 TypeFunction *tf = fd ? (TypeFunction *)(fd->type) : NULL;
2420 if (!tf)
2421 { // DAC: I'm not sure if this ever happens
2422 //printf("ecall=%s %d %d\n", ecall->toChars(), ecall->op, TOKcall);
2423 error("cannot evaluate %s at compile time", toChars());
2424 return EXP_CANT_INTERPRET;
2425 }
2426 if (pthis && fd)
2427 { // Member function call
2428 if (pthis->op == TOKthis)
2429 pthis = istate->localThis;
2430 else if (pthis->op == TOKcomma)
2431 pthis = pthis->interpret(istate);
2432 Expression *eresult = fd->interpret(istate, arguments, pthis);
2433 if (eresult)
2434 e = eresult;
2435 else if (fd->type->toBasetype()->nextOf()->ty == Tvoid && !global.errors)
2436 e = EXP_VOID_INTERPRET;
2437 else
2438 error("cannot evaluate %s at compile time", toChars());
2439 return e;
2440 }
2441 else if (fd)
2442 { // function call
2443 #if DMDV2
2444 enum BUILTIN b = fd->isBuiltin();
2445 if (b)
2446 { Expressions args;
2447 args.setDim(arguments->dim);
2448 for (size_t i = 0; i < args.dim; i++)
2449 {
2450 Expression *earg = (Expression *)arguments->data[i];
2451 earg = earg->interpret(istate);
2452 if (earg == EXP_CANT_INTERPRET)
2453 return earg;
2454 args.data[i] = (void *)earg;
2455 }
2456 e = eval_builtin(b, &args);
2457 if (!e)
2458 e = EXP_CANT_INTERPRET;
2459 }
2460 else
2461 #endif
2462 // Inline .dup
2463 if (fd->ident == Id::adDup && arguments && arguments->dim == 2)
2464 {
2465 e = (Expression *)arguments->data[1];
2466 e = e->interpret(istate);
2467 if (e != EXP_CANT_INTERPRET)
2468 {
2469 e = expType(type, e);
2470 }
2471 }
2472 else
2473 {
2474 Expression *eresult = fd->interpret(istate, arguments);
2273 if (eresult) 2475 if (eresult)
2274 e = eresult; 2476 e = eresult;
2275 else if (fd->type->toBasetype()->nextOf()->ty == Tvoid && !global.errors) 2477 else if (fd->type->toBasetype()->nextOf()->ty == Tvoid && !global.errors)
2276 e = EXP_VOID_INTERPRET; 2478 e = EXP_VOID_INTERPRET;
2277 else 2479 else
2278 error("cannot evaluate %s at compile time", toChars()); 2480 error("cannot evaluate %s at compile time", toChars());
2279 return e; 2481 }
2280 } 2482 }
2483 else
2484 {
2281 error("cannot evaluate %s at compile time", toChars()); 2485 error("cannot evaluate %s at compile time", toChars());
2282 return EXP_CANT_INTERPRET; 2486 return EXP_CANT_INTERPRET;
2283 } 2487 }
2284 if (e1->op == TOKvar) 2488 return e;
2285 {
2286 FuncDeclaration *fd = ((VarExp *)e1)->var->isFuncDeclaration();
2287 if (fd)
2288 {
2289 #if DMDV2
2290 enum BUILTIN b = fd->isBuiltin();
2291 if (b)
2292 { Expressions args;
2293 args.setDim(arguments->dim);
2294 for (size_t i = 0; i < args.dim; i++)
2295 {
2296 Expression *earg = (Expression *)arguments->data[i];
2297 earg = earg->interpret(istate);
2298 if (earg == EXP_CANT_INTERPRET)
2299 return earg;
2300 args.data[i] = (void *)earg;
2301 }
2302 e = eval_builtin(b, &args);
2303 if (!e)
2304 e = EXP_CANT_INTERPRET;
2305 }
2306 else
2307 #endif
2308 // Inline .dup
2309 if (fd->ident == Id::adDup && arguments && arguments->dim == 2)
2310 {
2311 e = (Expression *)arguments->data[1];
2312 e = e->interpret(istate);
2313 if (e != EXP_CANT_INTERPRET)
2314 {
2315 e = expType(type, e);
2316 }
2317 }
2318 else
2319 {
2320 Expression *eresult = fd->interpret(istate, arguments);
2321 if (eresult)
2322 e = eresult;
2323 else if (fd->type->toBasetype()->nextOf()->ty == Tvoid && !global.errors)
2324 e = EXP_VOID_INTERPRET;
2325 else
2326 error("cannot evaluate %s at compile time", toChars());
2327 }
2328 }
2329 }
2330 return e;
2331 } 2489 }
2332 2490
2333 Expression *CommaExp::interpret(InterState *istate) 2491 Expression *CommaExp::interpret(InterState *istate)
2334 { 2492 {
2335 #if LOG 2493 #if LOG
2336 printf("CommaExp::interpret() %s\n", toChars()); 2494 printf("CommaExp::interpret() %s\n", toChars());
2337 #endif 2495 #endif
2496 // If the comma returns a temporary variable, it needs to be an lvalue
2497 // (this is particularly important for struct constructors)
2498 if (e1->op == TOKdeclaration && e2->op == TOKvar
2499 && ((DeclarationExp *)e1)->declaration == ((VarExp*)e2)->var)
2500 {
2501 VarExp* ve = (VarExp *)e2;
2502 VarDeclaration *v = ve->var->isVarDeclaration();
2503 if (!v->init && !v->value)
2504 v->value = v->type->defaultInitLiteral();
2505 if (!v->value)
2506 v->value = v->init->toExpression();
2507 v->value = v->value->interpret(istate);
2508 return e2;
2509 }
2510
2338 Expression *e = e1->interpret(istate); 2511 Expression *e = e1->interpret(istate);
2339 if (e != EXP_CANT_INTERPRET) 2512 if (e != EXP_CANT_INTERPRET)
2340 e = e2->interpret(istate); 2513 e = e2->interpret(istate);
2341 return e; 2514 return e;
2342 } 2515 }
2514 printf("AssertExp::interpret() %s\n", toChars()); 2687 printf("AssertExp::interpret() %s\n", toChars());
2515 #endif 2688 #endif
2516 if( this->e1->op == TOKaddress) 2689 if( this->e1->op == TOKaddress)
2517 { // Special case: deal with compiler-inserted assert(&this, "null this") 2690 { // Special case: deal with compiler-inserted assert(&this, "null this")
2518 AddrExp *ade = (AddrExp *)this->e1; 2691 AddrExp *ade = (AddrExp *)this->e1;
2519 if(ade->e1->op == TOKthis && istate->localThis) 2692 if (ade->e1->op == TOKthis && istate->localThis)
2520 return istate->localThis->interpret(istate); 2693 if (ade->e1->op == TOKdotvar
2521 } 2694 && ((DotVarExp *)(istate->localThis))->e1->op == TOKthis)
2522 if (this->e1->op == TOKthis) 2695 return getVarExp(loc, istate, ((DotVarExp*)(istate->localThis))->var);
2523 { 2696 else
2524 if(istate->localThis) 2697 return istate->localThis->interpret(istate);
2525 return istate->localThis->interpret(istate); 2698 }
2526 } 2699 if (this->e1->op == TOKthis)
2700 {
2701 if (istate->localThis)
2702 return istate->localThis->interpret(istate);
2703 }
2527 e1 = this->e1->interpret(istate); 2704 e1 = this->e1->interpret(istate);
2528 if (e1 == EXP_CANT_INTERPRET) 2705 if (e1 == EXP_CANT_INTERPRET)
2529 goto Lcant; 2706 goto Lcant;
2530 if (e1->isBool(TRUE)) 2707 if (e1->isBool(TRUE))
2531 { 2708 {