Changeset 414
- Timestamp:
- 03/12/07 20:39:55 (1 year ago)
- Files:
-
- branches/dmdfe/attrib.c (modified) (3 diffs)
- branches/dmdfe/cond.c (modified) (1 diff)
- branches/dmdfe/constfold.c (modified) (4 diffs)
- branches/dmdfe/declaration.h (modified) (4 diffs)
- branches/dmdfe/expression.c (modified) (11 diffs)
- branches/dmdfe/expression.h (modified) (1 diff)
- branches/dmdfe/func.c (modified) (3 diffs)
- branches/dmdfe/idgen.c (modified) (1 diff)
- branches/dmdfe/interpret.c (modified) (18 diffs)
- branches/dmdfe/mars.c (modified) (1 diff)
- branches/dmdfe/mtype.c (modified) (4 diffs)
- branches/dmdfe/optimize.c (modified) (2 diffs)
- branches/dmdfe/parse.c (modified) (3 diffs)
- branches/dmdfe/parse.h (modified) (1 diff)
- branches/dmdfe/statement.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/dmdfe/attrib.c
r360 r414 720 720 721 721 e = e->semantic(sc); 722 e = e->optimize(WANTvalue | WANTinterpret); 722 723 if (e->op == TOKstring) 723 724 { … … 741 742 742 743 e = e->semantic(sc); 744 e = e->optimize(WANTvalue | WANTinterpret); 743 745 args->data[0] = (void *)e; 744 746 if (e->op != TOKstring) … … 1065 1067 exp = exp->semantic(sc); 1066 1068 exp = resolveProperties(sc, exp); 1067 exp = exp->optimize(WANTvalue );1069 exp = exp->optimize(WANTvalue | WANTinterpret); 1068 1070 if (exp->op != TOKstring) 1069 1071 { error("argument to mixin must be a string, not (%s)", exp->toChars()); branches/dmdfe/cond.c
r360 r414 241 241 Expression *e = exp->semantic(sc); 242 242 sc->pop(); 243 e = e->optimize(WANTvalue );243 e = e->optimize(WANTvalue | WANTinterpret); 244 244 if (e->isBool(TRUE)) 245 245 inc = 1; branches/dmdfe/constfold.c
r361 r414 34 34 35 35 #define LOG 0 36 37 Expression *expType(Type *type, Expression *e) 38 { 39 if (type != e->type) 40 { 41 e = e->copy(); 42 e->type = type; 43 } 44 return e; 45 } 36 46 37 47 /* ================================== isConst() ============================== */ … … 1020 1030 Loc loc = e1->loc; 1021 1031 1022 //printf("Index( )\n");1032 //printf("Index(e1->type = %p)\n", e1->type); 1023 1033 if (e1->op == TOKstring && e2->op == TOKint64) 1024 1034 { StringExp *es1 = (StringExp *)e1; … … 1076 1086 #if LOG 1077 1087 printf("Slice()\n"); 1088 if (lwr) 1089 { printf("\te1 = %s\n", e1->toChars()); 1090 printf("\tlwr = %s\n", lwr->toChars()); 1091 printf("\tupr = %s\n", upr->toChars()); 1092 } 1078 1093 #endif 1079 1094 if (e1->op == TOKstring && lwr->op == TOKint64 && upr->op == TOKint64) … … 1131 1146 Loc loc = e1->loc; 1132 1147 1133 //printf("Cat()\n"); 1148 //printf("Cat(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 1149 1150 if (e1->op == TOKnull && e2->op == TOKint64) 1151 { e = e2; 1152 goto L2; 1153 } 1154 else if (e1->op == TOKint64 && e2->op == TOKnull) 1155 { e = e1; 1156 L2: 1157 Type *tn = e->type->toBasetype(); 1158 if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar) 1159 { 1160 // Create a StringExp 1161 void *s; 1162 StringExp *es; 1163 size_t len = 1; 1164 int sz = tn->size(); 1165 integer_t v = e->toInteger(); 1166 1167 s = mem.malloc((len + 1) * sz); 1168 memcpy((unsigned char *)s, &v, sz); 1169 1170 // Add terminating 0 1171 memset((unsigned char *)s + len * sz, 0, sz); 1172 1173 es = new StringExp(loc, s, len); 1174 es->sz = sz; 1175 es->committed = 1; 1176 e = es; 1177 } 1178 else 1179 { // Create an ArrayLiteralExp 1180 Expressions *elements = new Expressions(); 1181 elements->push(e); 1182 e = new ArrayLiteralExp(e->loc, elements); 1183 } 1184 e->type = type; 1185 return e; 1186 } 1187 1134 1188 if (e1->op == TOKstring && e2->op == TOKstring) 1135 1189 { branches/dmdfe/declaration.h
r361 r414 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 6by Digital Mars3 // Copyright (c) 1999-2007 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 31 31 struct StructDeclaration; 32 32 struct TupleType; 33 struct InterState; 33 34 34 35 enum PROT; … … 437 438 virtual int addPreInvariant(); 438 439 virtual int addPostInvariant(); 439 Expression *interpret( Expressions *arguments);440 Expression *interpret(InterState *istate, Expressions *arguments); 440 441 void inlineScan(); 441 442 int canInline(int hasthis, int hdrscan = 0); … … 445 446 446 447 static FuncDeclaration *genCfunc(Type *treturn, char *name); 448 static FuncDeclaration *genCfunc(Type *treturn, Identifier *id); 447 449 448 450 Symbol *toThunkSymbol(int offset); // thunk version branches/dmdfe/expression.c
r364 r414 110 110 precedence[TOKassert] = PREC_primary; 111 111 precedence[TOKfunction] = PREC_primary; 112 precedence[TOKvar] = PREC_primary; 112 113 113 114 // post … … 2835 2836 error("e.new is only for allocating nested classes"); 2836 2837 } 2838 else if (thisexp) 2839 error("e.new is only for allocating nested classes"); 2840 2837 2841 FuncDeclaration *f = cd->ctor; 2838 2842 if (f) … … 2932 2936 Expression *arg = (Expression *)arguments->data[i]; 2933 2937 arg = resolveProperties(sc, arg); 2934 arg = arg->implicitCastTo(sc, Type::t index);2938 arg = arg->implicitCastTo(sc, Type::tsize_t); 2935 2939 if (arg->op == TOKint64 && (long long)arg->toInteger() < 0) 2936 2940 error("negative array index %s", arg->toChars()); … … 3322 3326 3323 3327 expandTuples(exps); 3328 if (0 && exps->dim == 1) 3329 { 3330 return (Expression *)exps->data[0]; 3331 } 3324 3332 type = new TypeTuple(exps); 3325 3333 //printf("-TupleExp::semantic(%s)\n", toChars()); … … 3329 3337 void TupleExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3330 3338 { 3331 buf->writestring("tuple ");3339 buf->writestring("tuple("); 3332 3340 argsToCBuffer(buf, exps, hgs); 3341 buf->writeByte(')'); 3333 3342 } 3334 3343 … … 4026 4035 UnaExp::semantic(sc); 4027 4036 e1 = resolveProperties(sc, e1); 4028 e1 = e1->optimize(WANTvalue );4037 e1 = e1->optimize(WANTvalue | WANTinterpret); 4029 4038 if (e1->op != TOKstring) 4030 4039 { error("argument to mixin must be a string, not (%s)", e1->toChars()); … … 5910 5919 { lwr = lwr->semantic(sc); 5911 5920 lwr = resolveProperties(sc, lwr); 5912 lwr = lwr->implicitCastTo(sc, Type::t index);5921 lwr = lwr->implicitCastTo(sc, Type::tsize_t); 5913 5922 } 5914 5923 if (upr) 5915 5924 { upr = upr->semantic(sc); 5916 5925 upr = resolveProperties(sc, upr); 5917 upr = upr->implicitCastTo(sc, Type::t index);5926 upr = upr->implicitCastTo(sc, Type::tsize_t); 5918 5927 } 5919 5928 … … 6042 6051 e1 = resolveProperties(sc, e1); 6043 6052 6044 type = Type::t index;6053 type = Type::tsize_t; 6045 6054 } 6046 6055 return this; … … 6258 6267 case Tpointer: 6259 6268 case Tarray: 6260 e2 = e2->implicitCastTo(sc, Type::t index);6269 e2 = e2->implicitCastTo(sc, Type::tsize_t); 6261 6270 e->type = t1->next; 6262 6271 break; … … 6264 6273 case Tsarray: 6265 6274 { 6266 e2 = e2->implicitCastTo(sc, Type::t index);6275 e2 = e2->implicitCastTo(sc, Type::tsize_t); 6267 6276 6268 6277 TypeSArray *tsa = (TypeSArray *)t1; … … 6295 6304 case Ttuple: 6296 6305 { 6297 e2 = e2->implicitCastTo(sc, Type::t index);6306 e2 = e2->implicitCastTo(sc, Type::tsize_t); 6298 6307 e2 = e2->optimize(WANTvalue); 6299 6308 uinteger_t index = e2->toUInteger(); branches/dmdfe/expression.h
r361 r414 1216 1216 #define EXP_GOTO_INTERPRET ((Expression *)4) 1217 1217 1218 Expression *expType(Type *type, Expression *e); 1219 1218 1220 Expression *Neg(Type *type, Expression *e1); 1219 1221 Expression *Com(Type *type, Expression *e1); branches/dmdfe/func.c
r361 r414 522 522 } 523 523 } 524 return; 525 526 Lassignerr: 527 error("identity assignment operator overload is illegal"); 528 } 529 530 void FuncDeclaration::semantic2(Scope *sc) 531 { 524 532 525 /* Save scope for possible later use (if we need the 533 526 * function internals) … … 535 528 scope = new Scope(*sc); 536 529 scope->setNoFree(); 530 return; 531 532 Lassignerr: 533 error("identity assignment operator overload is illegal"); 534 } 535 536 void FuncDeclaration::semantic2(Scope *sc) 537 { 537 538 } 538 539 … … 1711 1712 FuncDeclaration *FuncDeclaration::genCfunc(Type *treturn, char *name) 1712 1713 { 1714 return genCfunc(treturn, Lexer::idPool(name)); 1715 } 1716 1717 FuncDeclaration *FuncDeclaration::genCfunc(Type *treturn, Identifier *id) 1718 { 1713 1719 FuncDeclaration *fd; 1714 1720 TypeFunction *tf; 1715 1721 Dsymbol *s; 1716 Identifier *id;1717 1722 static DsymbolTable *st = NULL; 1718 1723 1719 //printf("genCfunc(name = '%s')\n", name);1724 //printf("genCfunc(name = '%s')\n", id->toChars()); 1720 1725 //printf("treturn\n\t"); treturn->print(); 1721 1722 id = Lexer::idPool(name);1723 1726 1724 1727 // See if already in table branches/dmdfe/idgen.c
r360 r414 194 194 { "applyReverse", "opApplyReverse" }, 195 195 196 { "adDup", "_adDupT" }, 197 { "adReverse", "_adReverse" }, 198 196 199 // For pragma's 197 200 { "lib" }, branches/dmdfe/interpret.c
r361 r414 30 30 struct InterState 31 31 { 32 Dsymbols vars; // variables used in this function 33 Statement *start; // if !=NULL, start execution at this statement 32 InterState *caller; // calling function's InterState 33 FuncDeclaration *fd; // function being interpreted 34 Dsymbols vars; // variables used in this function 35 Statement *start; // if !=NULL, start execution at this statement 34 36 Statement *gotoTarget; // target of EXP_GOTO_INTERPRET result 35 37 … … 44 46 /************************************* 45 47 * Attempt to interpret a function given the arguments. 48 * Input: 49 * istate state for calling function (NULL if none) 46 50 * Return result expression if successful, NULL if not. 47 51 */ 48 52 49 Expression *FuncDeclaration::interpret( Expressions *arguments)53 Expression *FuncDeclaration::interpret(InterState *istate, Expressions *arguments) 50 54 { 51 55 #if LOG … … 81 85 for (size_t i = 0; i < dim; i++) 82 86 { Argument *arg = Argument::getNth(tf->parameters, i); 83 if (arg->inout == Out || arg->inout == InOut || arg->inout ==Lazy)87 if (arg->inout == Lazy) 84 88 { cantInterpret = 1; 85 89 return NULL; … … 88 92 } 89 93 90 InterState istate; 94 /* Save the values of the local variables used 95 */ 96 Expressions valueSaves; 97 if (istate) 98 { 99 valueSaves.setDim(istate->vars.dim); 100 for (size_t i = 0; i < istate->vars.dim; i++) 101 { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i]; 102 if (v) 103 { valueSaves.data[i] = v->value; 104 v->value = NULL; 105 } 106 } 107 } 108 109 InterState istatex; 110 istatex.caller = istate; 111 istatex.fd = this; 112 91 113 Expressions vsave; 92 114 size_t dim = 0; … … 94 116 { 95 117 dim = arguments->dim; 96 assert(parameters && parameters->dim == dim); 118 assert(!dim || parameters->dim == dim); 119 vsave.setDim(dim); 120 97 121 for (size_t i = 0; i < dim; i++) 98 122 { Expression *earg = (Expression *)arguments->data[i]; 99 #if LOG 100 printf("arg[%d] = %s\n", i, earg->toChars()); 101 #endif 102 earg = earg->interpret(&istate); 103 if (earg == EXP_CANT_INTERPRET) 104 return NULL; 105 #if LOG 106 printf("interpreted arg[%d] = %s\n", i, earg->toChars()); 107 #endif 108 } 109 110 vsave.setDim(dim); 111 112 for (size_t i = 0; i < dim; i++) 113 { Expression *earg = (Expression *)arguments->data[i]; 114 earg = earg->interpret(&istate); 123 Argument *arg = Argument::getNth(tf->parameters, i); 115 124 VarDeclaration *v = (VarDeclaration *)parameters->data[i]; 116 125 vsave.data[i] = v->value; 117 v->value = earg; 126 #if LOG 127 printf("arg[%d] = %s\n", i, earg->toChars()); 128 #endif 129 if (arg->inout == Out || arg->inout == InOut) 130 { 131 /* Bind out or inout parameter to the corresponding 132 * variable v2 133 */ 134 if (!istate || earg->op != TOKvar) 135 return NULL; // can't bind to non-interpreted vars 136 137 VarDeclaration *v2; 138 while (1) 139 { 140 VarExp *ve = (VarExp *)earg; 141 v2 = ve->var->isVarDeclaration(); 142 if (!v2) 143 return NULL; 144 if (!v2->value || v2->value->op != TOKvar) 145 break; 146 earg = v2->value; 147 } 148 149 v->value = new VarExp(earg->loc, v2); 150 151 /* Don't restore the value of v2 upon function return 152 */ 153 assert(istate); 154 for (size_t i = 0; i < istate->vars.dim; i++) 155 { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i]; 156 if (v == v2) 157 { istate->vars.data[i] = NULL; 158 break; 159 } 160 } 161 } 162 else 163 { /* Value parameters 164 */ 165 earg = earg->interpret(&istatex); 166 if (earg == EXP_CANT_INTERPRET) 167 return NULL; 168 v->value = earg; 169 } 170 #if LOG 171 printf("interpreted arg[%d] = %s\n", i, earg->toChars()); 172 #endif 118 173 } 119 174 } … … 123 178 while (1) 124 179 { 125 e = fbody->interpret(&istate );180 e = fbody->interpret(&istatex); 126 181 if (e == EXP_CANT_INTERPRET) 127 182 { … … 140 195 if (e == EXP_GOTO_INTERPRET) 141 196 { 142 istate .start = istate.gotoTarget; // set starting statement143 istate .gotoTarget = NULL;197 istatex.start = istatex.gotoTarget; // set starting statement 198 istatex.gotoTarget = NULL; 144 199 } 145 200 else … … 147 202 } 148 203 204 /* Restore the parameter values 205 */ 149 206 for (size_t i = 0; i < dim; i++) 150 207 { … … 152 209 v->value = (Expression *)vsave.data[i]; 153 210 } 211 212 if (istate) 213 { 214 /* Restore the variable values 215 */ 216 for (size_t i = 0; i < istate->vars.dim; i++) 217 { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i]; 218 if (v) 219 v->value = (Expression *)valueSaves.data[i]; 220 } 221 } 222 154 223 return e; 155 224 } … … 759 828 760 829 Expression *VarExp::interpret(InterState *istate) 761 { Expression *e = EXP_CANT_INTERPRET; 830 { 831 #if LOG 832 printf("VarExp::interpret() %s\n", toChars()); 833 #endif 834 Expression *e = EXP_CANT_INTERPRET; 762 835 VarDeclaration *v = var->isVarDeclaration(); 763 836 if (v) … … 766 839 e = v->init->toExpression(); 767 840 else 768 e = v->value; 841 { e = v->value; 842 if (!e) 843 error("variable %s is used before initialization", v->toChars()); 844 else if (e != EXP_CANT_INTERPRET) 845 e = e->interpret(istate); 846 } 769 847 if (!e) 770 848 e = EXP_CANT_INTERPRET; … … 784 862 if (ie) 785 863 e = ie->exp->interpret(istate); 864 else if (v->init->isVoidInitializer()) 865 e = NULL; 786 866 } 787 867 } … … 983 1063 Expression *BinExp::interpretAssignCommon(InterState *istate, fp_t fp) 984 1064 { 1065 #if LOG 1066 printf("BinExp::interpretAssignCommon() %s\n", toChars()); 1067 #endif 985 1068 Expression *e = EXP_CANT_INTERPRET; 986 987 if (e1->op == TOKvar) 1069 Expression *e1 = this->e1; 1070 1071 if (fp) 1072 { 1073 if (e1->op == TOKcast) 1074 { CastExp *ce = (CastExp *)e1; 1075 e1 = ce->e1; 1076 } 1077 } 1078 if (e1 != EXP_CANT_INTERPRET && e1->op == TOKvar) 988 1079 { 989 1080 VarExp *ve = (VarExp *)e1; 990 1081 VarDeclaration *v = ve->var->isVarDeclaration(); 991 if (v && !v->isDataseg() && (!fp || v->value)) 992 { 1082 if (v && !v->isDataseg()) 1083 { 1084 /* Chase down rebinding of out and inout 1085 */ 1086 if (v->value && v->value->op == TOKvar) 1087 { 1088 ve = (VarExp *)v->value; 1089 v = ve->var->isVarDeclaration(); 1090 assert(v); 1091 } 1092 1093 if (fp && !v->value) 1094 { error("variable %s is used before initialization", v->toChars()); 1095 return e; 1096 } 993 1097 Expression *e2 = this->e2->interpret(istate); 994 1098 if (e2 != EXP_CANT_INTERPRET) … … 1053 1157 VarExp *ve = (VarExp *)e1; 1054 1158 VarDeclaration *v = ve->var->isVarDeclaration(); 1055 if (v && !v->isDataseg() && v->value) 1056 { 1159 if (v && !v->isDataseg()) 1160 { 1161 /* Chase down rebinding of out and inout 1162 */ 1163 if (v->value && v->value->op == TOKvar) 1164 { 1165 ve = (VarExp *)v->value; 1166 v = ve->var->isVarDeclaration(); 1167 assert(v); 1168 } 1169 1170 if (!v->value) 1171 { error("variable %s is used before initialization", v->toChars()); 1172 return e; 1173 } 1057 1174 Expression *e2 = this->e2->interpret(istate); 1058 1175 if (e2 != EXP_CANT_INTERPRET) … … 1138 1255 { Expression *e = EXP_CANT_INTERPRET; 1139 1256 1257 #if LOG 1258 printf("CallExp::interpret() %s\n", toChars()); 1259 #endif 1140 1260 if (e1->op == TOKvar) 1141 1261 { 1142 1262 FuncDeclaration *fd = ((VarExp *)e1)->var->isFuncDeclaration(); 1143 1263 if (fd) 1144 { 1145 /* Save the values of the variables used 1146 */ 1147 Expressions valueSaves; 1148 valueSaves.setDim(istate->vars.dim); 1149 for (size_t i = 0; i < istate->vars.dim; i++) 1150 { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i]; 1151 valueSaves.data[i] = v->value; 1152 v->value = NULL; 1153 } 1154 1155 Expression *eresult = fd->interpret(arguments); 1156 if (eresult) 1157 e = eresult; 1264 { // Inline .dup 1265 if (fd->ident == Id::adDup && arguments && arguments->dim == 2) 1266 { 1267 e = (Expression *)arguments->data[1]; 1268 e = e->interpret(istate); 1269 if (e != EXP_CANT_INTERPRET) 1270 { 1271 e = expType(type, e); 1272 } 1273 } 1158 1274 else 1159 error("cannot evaluate %s at compile time", toChars()); 1160 1161 /* Restore the variable values 1162 */ 1163 for (size_t i = 0; i < istate->vars.dim; i++) 1164 { VarDeclaration *v = (VarDeclaration *)istate->vars.data[i]; 1165 v->value = (Expression *)valueSaves.data[i]; 1275 { 1276 Expression *eresult = fd->interpret(istate, arguments); 1277 if (eresult) 1278 e = eresult; 1279 else 1280 error("cannot evaluate %s at compile time", toChars()); 1166 1281 } 1167 1282 } … … 1197 1312 Expression *e1; 1198 1313 1314 #if LOG 1315 printf("ArrayLengthExp::interpret() %s\n", toChars()); 1316 #endif 1199 1317 e1 = this->e1->interpret(istate); 1200 1318 if (e1 == EXP_CANT_INTERPRET) … … 1251 1369 if (e1 == EXP_CANT_INTERPRET) 1252 1370 goto Lcant; 1253 if (! lwr)1371 if (!this->lwr) 1254 1372 { 1255 1373 e = e1->castTo(NULL, type); … … 1286 1404 Expression *e2; 1287 1405 1406 #if LOG 1407 printf("CatExp::interpret() %s\n", toChars()); 1408 #endif 1288 1409 e1 = this->e1->interpret(istate); 1289 1410 if (e1 == EXP_CANT_INTERPRET) branches/dmdfe/mars.c
r364 r414 56 56 copyright = "Copyright (c) 1999-2007 by Digital Mars"; 57 57 written = "written by Walter Bright"; 58 version = "v1.00 6";58 version = "v1.007"; 59 59 global.structalign = 8; 60 60 branches/dmdfe/mtype.c
r361 r414 1394 1394 if (this == to) 1395 1395 return MATCHexact; 1396 if (to->ty == Tvoid) 1396 1397 if (ty == Tvoid || to->ty == Tvoid) 1397 1398 return MATCHnomatch; 1399 if (1 || global.params.Dversion == 1) 1400 { 1401 if (to->ty == Tbool) 1402 return MATCHnomatch; 1403 } 1404 else 1405 { 1406 if (ty == Tbool || to->ty == Tbool) 1407 return MATCHnomatch; 1408 } 1398 1409 if (!to->isTypeBasic()) 1399 1410 return MATCHnomatch; 1400 if (ty == Tvoid /*|| to->ty == Tvoid*/) 1401 return MATCHnomatch; 1402 if (to->ty == Tbit || to->ty == Tbool) 1403 return MATCHnomatch; 1411 1404 1412 TypeBasic *tob = (TypeBasic *)to; 1405 1413 if (flags & TFLAGSintegral) … … 1408 1416 if (tob->flags & (TFLAGSimaginary | TFLAGScomplex)) 1409 1417 return MATCHnomatch; 1418 1419 // If converting to integral 1420 if (0 && global.params.Dversion > 1 && tob->flags & TFLAGSintegral) 1421 { d_uns64 sz = size(0); 1422 d_uns64 tosz = tob->size(0); 1423 1424 /* Can't convert to smaller size or, if same size, change sign 1425 */ 1426 if (sz > tosz) 1427 return MATCHnomatch; 1428 1429 /*if (sz == tosz && (flags ^ tob->flags) & TFLAGSunsigned) 1430 return MATCHnomatch;*/ 1431 } 1410 1432 } 1411 1433 else if (flags & TFLAGSfloating) … … 1494 1516 int size = next->size(e->loc); 1495 1517 int dup; 1496 char *nm;1497 static char *name[2] = { "_adReverse", "_adDupT" };1498 1518 1499 1519 assert(size); 1500 1520 dup = (ident == Id::dup); 1501 nm = name[dup]; 1502 fd = FuncDeclaration::genCfunc(Type::tindex, nm); 1521 fd = FuncDeclaration::genCfunc(Type::tindex, dup ? Id::adDup : Id::adReverse); 1503 1522 ec = new VarExp(0, fd); 1504 1523 e = e->castTo(sc, n->arrayOf()); // convert to dynamic array … … 4596 4615 } 4597 4616 4598 // Allow conversion to (void *) 4599 if (to->ty == Tpointer && to->next->ty == Tvoid) 4600 return 1; 4601 4602 // if (to->ty == Tvoid) 4603 // return MATCHconvert; 4617 if (global.params.Dversion == 1) 4618 { 4619 // Allow conversion to (void *) 4620 if (to->ty == Tpointer && to->next->ty == Tvoid) 4621 return 1; 4622 } 4623 4604 4624 return 0; 4605 4625 } branches/dmdfe/optimize.c
r361 r414 49 49 { Expression *ei = v->init->toExpression(); 50 50 if (ei) 51 e1 = ei; 51 { e1 = ei; 52 if (!e1->type) 53 e1->type = v->type; 54 } 52 55 } 53 56 } … … 232 235 if (fd) 233 236 { 234 Expression *eresult = fd->interpret( arguments);237 Expression *eresult = fd->interpret(NULL, arguments); 235 238 if (eresult) 236 239 e = eresult; branches/dmdfe/parse.c
r361 r414 4423 4423 4424 4424 case TOKidentity: 4425 if (1 || !global.params.useDeprecated) 4426 error("'===' is no longer legal, use 'is' instead"); 4425 error("'===' is no longer legal, use 'is' instead"); 4427 4426 goto L1; 4428 4427 4429 4428 case TOKnotidentity: 4430 if (1 || !global.params.useDeprecated) 4431 error("'!==' is no longer legal, use '!is' instead"); 4429 error("'!==' is no longer legal, use '!is' instead"); 4432 4430 goto L1; 4433 4431 … … 4459 4457 } 4460 4458 4459 Expression *Parser::parseCmpExp() 4460 { Expression *e; 4461 Expression *e2; 4462 Token *t; 4463 Loc loc = this->loc; 4464 4465 e = parseShiftExp(); 4466 enum TOK op = token.value; 4467 4468 switch (op) 4469 { 4470 case TOKequal: 4471 case TOKnotequal: 4472 nextToken(); 4473 e2 = parseShiftExp(); 4474 e = new EqualExp(op, loc, e, e2); 4475 break; 4476 4477 case TOKis: 4478 op = TOKidentity; 4479 goto L1; 4480 4481 case TOKnot: 4482 // Attempt to identify '!is' 4483 t = peek(&token); 4484 if (t->value != TOKis) 4485 break; 4486 nextToken(); 4487 op = TOKnotidentity; 4488 goto L1; 4489 4490 L1: 4491 nextToken(); 4492 e2 = parseShiftExp(); 4493 e = new IdentityExp(op, loc, e, e2); 4494 break; 4495 4496 case TOKlt: 4497 case TOKle: 4498 case TOKgt: 4499 case TOKge: 4500 case TOKunord: 4501 case TOKlg: 4502 case TOKleg: 4503 case TOKule: 4504 case TOKul: 4505 case TOKuge: 4506 case TOKug: 4507 case TOKue: 4508 nextToken(); 4509 e2 = parseShiftExp(); 4510 e = new CmpExp(op, loc, e, e2); 4511 break; 4512 4513 case TOKin: 4514 nextToken(); 4515 e2 = parseShiftExp(); 4516 e = new InExp(loc, e, e2); 4517 break; 4518 4519 default: 4520 break; 4521 } 4522 return e; 4523 } 4524 4461 4525 Expression *Parser::parseAndExp() 4462 4526 { Expression *e; … … 4464 4528 Loc loc = this->loc; 4465 4529 4466 e = parseEqualExp(); 4467 while (token.value == TOKand) 4468 { 4469 nextToken(); 4470 e2 = parseEqualExp(); 4471 e = new AndExp(loc,e,e2); 4472 loc = this->loc; 4530 if (global.params.Dversion == 1) 4531 { 4532 e = parseEqualExp(); 4533 while (token.value == TOKand) 4534 { 4535 nextToken(); 4536 e2 = parseEqualExp(); 4537 e = new AndExp(loc,e,e2); 4538 loc = this->loc; 4539 } 4540 } 4541 else 4542 { 4543 e = parseCmpExp(); 4544 while (token.value == TOKand) 4545 { 4546 nextToken(); 4547 e2 = parseCmpExp(); 4548 e = new AndExp(loc,e,e2); 4549 loc = this->loc; 4550 } 4473 4551 } 4474 4552 return e; branches/dmdfe/parse.h
r360 r414 117 117 Expression *parseRelExp(); 118 118 Expression *parseEqualExp(); 119 Expression *parseCmpExp(); 119 120 Expression *parseAndExp(); 120 121 Expression *parseXorExp(); branches/dmdfe/statement.c
r361 r414 243 243 exp = exp->semantic(sc); 244 244 exp = resolveProperties(sc, exp); 245 exp = exp->optimize(WANTvalue );245 exp = exp->optimize(WANTvalue | WANTinterpret); 246 246 if (exp->op != TOKstring) 247 247 { error("argument to mixin must be a string, not (%s)", exp->toChars()); … … 1821 1821 1822 1822 e = e->semantic(sc); 1823 e = e->optimize(WANTvalue | WANTinterpret); 1823 1824 if (e->op == TOKstring) 1824 1825 { … … 1841 1842 1842 1843 e = e->semantic(sc); 1844 e = e->optimize(WANTvalue | WANTinterpret); 1843 1845 args->data[0] = (void *)e; 1844 1846 if (e->op != TOKstring)
