Changeset 656
- Timestamp:
- 07/02/07 18:05:45 (1 year ago)
- Files:
-
- branches/dmdfe/aggregate.h (modified) (1 diff)
- branches/dmdfe/constfold.c (modified) (4 diffs)
- branches/dmdfe/delegatize.c (modified) (1 diff)
- branches/dmdfe/enum.c (modified) (1 diff)
- branches/dmdfe/enum.h (modified) (2 diffs)
- branches/dmdfe/expression.c (modified) (6 diffs)
- branches/dmdfe/expression.h (modified) (5 diffs)
- branches/dmdfe/idgen.c (modified) (1 diff)
- branches/dmdfe/inline.c (modified) (3 diffs)
- branches/dmdfe/interpret.c (modified) (11 diffs)
- branches/dmdfe/lexer.c (modified) (1 diff)
- branches/dmdfe/lexer.h (modified) (1 diff)
- branches/dmdfe/mars.c (modified) (1 diff)
- branches/dmdfe/mtype.c (modified) (5 diffs)
- branches/dmdfe/optimize.c (modified) (3 diffs)
- branches/dmdfe/struct.c (modified) (1 diff)
- branches/dmdfe/template.c (modified) (4 diffs)
- branches/dmdfe/tocsym.c (modified) (2 diffs)
- branches/dmdfe/todt.c (modified) (2 diffs)
- branches/dmdfe/toobj.c (modified) (1 diff)
- branches/dmdfe/typinf.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/dmdfe/aggregate.h
r458 r656 44 44 unsigned alignsize; // size of struct for alignment purposes 45 45 unsigned structalign; // struct member alignment in effect 46 int hasUnions; // set if aggregate has overlapping fields 46 47 Array fields; // VarDeclaration fields 47 48 unsigned sizeok; // set when structsize contains valid data branches/dmdfe/constfold.c
r523 r656 663 663 real_t r2; 664 664 665 //printf("Equal(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 666 665 667 assert(op == TOKequal || op == TOKnotequal); 666 668 … … 693 695 Expression *ee2 = (Expression *)es2->elements->data[i]; 694 696 697 Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2); 698 if (v == EXP_CANT_INTERPRET) 699 return EXP_CANT_INTERPRET; 700 cmp = v->toInteger(); 701 if (cmp == 0) 702 break; 703 } 704 } 705 } 706 else if (e1->op == TOKstructliteral && e2->op == TOKstructliteral) 707 { StructLiteralExp *es1 = (StructLiteralExp *)e1; 708 StructLiteralExp *es2 = (StructLiteralExp *)e2; 709 710 if (es1->sd != es2->sd) 711 cmp = 0; 712 else if ((!es1->elements || !es1->elements->dim) && 713 (!es2->elements || !es2->elements->dim)) 714 cmp = 1; // both arrays are empty 715 else if (!es1->elements || !es2->elements) 716 cmp = 0; 717 else if (es1->elements->dim != es2->elements->dim) 718 cmp = 0; 719 else 720 { 721 cmp = 1; 722 for (size_t i = 0; i < es1->elements->dim; i++) 723 { Expression *ee1 = (Expression *)es1->elements->data[i]; 724 Expression *ee2 = (Expression *)es2->elements->data[i]; 725 726 if (ee1 == ee2) 727 continue; 728 if (!ee1 || !ee2) 729 { cmp = 0; 730 break; 731 } 695 732 Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2); 696 733 if (v == EXP_CANT_INTERPRET) … … 1036 1073 Loc loc = e1->loc; 1037 1074 1038 //printf("Index(e1 = %s )\n", e1->toChars());1075 //printf("Index(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 1039 1076 assert(e1->type); 1040 1077 if (e1->op == TOKstring && e2->op == TOKint64) … … 1384 1421 } 1385 1422 1386 1423 Expression *Ptr(Type *type, Expression *e1) 1424 { 1425 //printf("Ptr(e1 = %s)\n", e1->toChars()); 1426 if (e1->op == TOKadd) 1427 { AddExp *ae = (AddExp *)e1; 1428 if (ae->e1->op == TOKaddress && ae->e2->op == TOKint64) 1429 { AddrExp *ade = (AddrExp *)ae->e1; 1430 if (ade->e1->op == TOKstructliteral) 1431 { StructLiteralExp *se = (StructLiteralExp *)ade->e1; 1432 unsigned offset = ae->e2->toInteger(); 1433 Expression *e = se->getField(type, offset); 1434 if (!e) 1435 e = EXP_CANT_INTERPRET; 1436 return e; 1437 } 1438 } 1439 } 1440 return EXP_CANT_INTERPRET; 1441 } 1442 branches/dmdfe/delegatize.c
r460 r656 185 185 186 186 187 void StructLiteralExp::scanForNestedRef(Scope *sc) 188 { 189 arrayExpressionScanForNestedRef(sc, elements); 190 } 191 192 187 193 void TupleExp::scanForNestedRef(Scope *sc) 188 194 { branches/dmdfe/enum.c
r458 r656 27 27 minval = 0; 28 28 defaultval = 0; 29 sinit = NULL; 29 30 } 30 31 branches/dmdfe/enum.h
r458 r656 26 26 #endif 27 27 28 28 29 struct EnumDeclaration : ScopeDsymbol 29 30 { … … 48 49 49 50 void toDebug(); 51 52 Symbol *sinit; 53 Symbol *toInitializer(); 50 54 }; 51 55 branches/dmdfe/expression.c
r523 r656 307 307 for (size_t i = 0; i < exps->dim; i++) 308 308 { Expression *arg = (Expression *)exps->data[i]; 309 if (!arg) 310 continue; 309 311 310 312 // Inline expand all the tuples … … 2642 2644 key->toMangleBuffer(buf); 2643 2645 value->toMangleBuffer(buf); 2646 } 2647 } 2648 2649 /************************ StructLiteralExp ************************************/ 2650 2651 // sd( e1, e2, e3, ... ) 2652 2653 StructLiteralExp::StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *elements) 2654 : Expression(loc, TOKstructliteral, sizeof(StructLiteralExp)) 2655 { 2656 this->sd = sd; 2657 this->elements = elements; 2658 this->s = NULL; 2659 this->soffset = 0; 2660 this->fillHoles = 1; 2661 } 2662 2663 Expression *StructLiteralExp::syntaxCopy() 2664 { 2665 return new StructLiteralExp(loc, sd, arraySyntaxCopy(elements)); 2666 } 2667 2668 Expression *StructLiteralExp::semantic(Scope *sc) 2669 { Expression *e; 2670 2671 #if LOGSEMANTIC 2672 printf("StructLiteralExp::semantic('%s')\n", toChars()); 2673 #endif 2674 2675 // Run semantic() on each element 2676 for (size_t i = 0; i < elements->dim; i++) 2677 { e = (Expression *)elements->data[i]; 2678 if (!e) 2679 continue; 2680 e = e->semantic(sc); 2681 elements->data[i] = (void *)e; 2682 } 2683 expandTuples(elements); 2684 size_t offset = 0; 2685 for (size_t i = 0; i < elements->dim; i++) 2686 { e = (Expression *)elements->data[i]; 2687 if (!e) 2688 continue; 2689 2690 if (!e->type) 2691 error("%s has no value", e->toChars()); 2692 e = resolveProperties(sc, e); 2693 if (i >= sd->fields.dim) 2694 { error("more initializers than fields of %s", sd->toChars()); 2695 break; 2696 } 2697 Dsymbol *s = (Dsymbol *)sd->fields.data[i]; 2698 VarDeclaration *v = s->isVarDeclaration(); 2699 assert(v); 2700 if (v->offset < offset) 2701 error("overlapping initialization for %s", v->toChars()); 2702 offset = v->offset + v->type->size(); 2703 e = e->implicitCastTo(sc, v->type); 2704 elements->data[i] = (void *)e; 2705 } 2706 2707 /* Fill out remainder of elements[] with default initializers for fields[] 2708 */ 2709 for (size_t i = elements->dim; i < sd->fields.dim; i++) 2710 { Dsymbol *s = (Dsymbol *)sd->fields.data[i]; 2711 VarDeclaration *v = s->isVarDeclaration(); 2712 assert(v); 2713 2714 if (v->offset < offset) 2715 { e = NULL; 2716 sd->hasUnions = 1; 2717 } 2718 else 2719 { 2720 if (v->init) 2721 { e = v->init->toExpression(); 2722 if (!e) 2723 error("cannot make expression out of initializer for %s", v->toChars()); 2724 } 2725 else 2726 e = v->type->defaultInit(); 2727 offset = v->offset + v->type->size(); 2728 } 2729 elements->push(e); 2730 } 2731 2732 type = sd->type; 2733 return this; 2734 } 2735 2736 /************************************** 2737 * Gets expression at offset of type. 2738 * Returns NULL if not found. 2739 */ 2740 2741 Expression *StructLiteralExp::getField(Type *type, unsigned offset) 2742 { Expression *e = NULL; 2743 int i = getFieldIndex(type, offset); 2744 2745 if (i != -1) 2746 { e = (Expression *)elements->data[i]; 2747 if (e) 2748 { 2749 e = e->copy(); 2750 e->type = type; 2751 } 2752 } 2753 return e; 2754 } 2755 2756 /************************************ 2757 * Get index of field. 2758 * Returns -1 if not found. 2759 */ 2760 2761 int StructLiteralExp::getFieldIndex(Type *type, unsigned offset) 2762 { 2763 /* Find which field offset is by looking at the field offsets 2764 */ 2765 for (size_t i = 0; i < sd->fields.dim; i++) 2766 { 2767 Dsymbol *s = (Dsymbol *)sd->fields.data[i]; 2768 VarDeclaration *v = s->isVarDeclaration(); 2769 assert(v); 2770 2771 if (offset == v->offset && 2772 type->size() == v->type->size()) 2773 { Expression *e = (Expression *)elements->data[i]; 2774 if (e) 2775 { 2776 return i; 2777 } 2778 break; 2779 } 2780 } 2781 return -1; 2782 } 2783 2784 2785 2786 int StructLiteralExp::checkSideEffect(int flag) 2787 { int f = 0; 2788 2789 for (size_t i = 0; i < elements->dim; i++) 2790 { Expression *e = (Expression *)elements->data[i]; 2791 if (!e) 2792 continue; 2793 2794 f |= e->checkSideEffect(2); 2795 } 2796 if (flag == 0 && f == 0) 2797 Expression::checkSideEffect(0); 2798 return f; 2799 } 2800 2801 void StructLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2802 { 2803 buf->writestring(sd->toChars()); 2804 buf->writeByte('('); 2805 argsToCBuffer(buf, elements, hgs); 2806 buf->writeByte(')'); 2807 } 2808 2809 void StructLiteralExp::toMangleBuffer(OutBuffer *buf) 2810 { 2811 size_t dim = elements ? elements->dim : 0; 2812 buf->printf("S%u", dim); 2813 for (size_t i = 0; i < dim; i++) 2814 { Expression *e = (Expression *)elements->data[i]; 2815 if (e) 2816 e->toMangleBuffer(buf); 2817 else 2818 buf->writeByte('v'); // 'v' for void 2644 2819 } 2645 2820 } … … 4188 4363 if (e1->op != TOKstring) 4189 4364 { error("argument to mixin must be a string, not (%s)", e1->toChars()); 4365 type = Type::terror; 4190 4366 return this; 4191 4367 } … … 5178 5354 { AggregateDeclaration *ad; 5179 5355 5180 if (t1->ty == Tclass) 5356 if (t1->ty == Tstruct) 5357 { 5358 ad = ((TypeStruct *)t1)->sym; 5359 if (search_function(ad, Id::call)) 5360 goto L1; // overload of opCall, therefore it's a call 5361 /* It's a struct literal 5362 */ 5363 Expression *e = new StructLiteralExp(loc, (StructDeclaration *)ad, arguments); 5364 e = e->semantic(sc); 5365 return e; 5366 } 5367 else if (t1->ty == Tclass) 5181 5368 { 5182 5369 ad = ((TypeClass *)t1)->sym; 5183 5370 goto L1; 5184 }5185 else if (t1->ty == Tstruct)5186 {5187 ad = ((TypeStruct *)t1)->sym;5188 5371 L1: 5189 5372 // Rewrite as e1.call(arguments) … … 6374 6557 : BinExp(loc, TOKindex, sizeof(IndexExp), e1, e2) 6375 6558 { 6559 //printf("IndexExp::IndexExp('%s')\n", toChars()); 6376 6560 lengthVar = NULL; 6377 6561 modifiable = 0; // assume it is an rvalue … … 6390 6574 if (type) 6391 6575 return this; 6576 if (!e1->type) 6577 e1 = e1->semantic(sc); 6392 6578 assert(e1->type); // semantic() should already be run on it 6393 6579 e = this; branches/dmdfe/expression.h
r523 r656 36 36 struct Declaration; 37 37 struct AggregateDeclaration; 38 struct StructDeclaration; 38 39 struct TemplateInstance; 39 40 struct TemplateDeclaration; … … 42 43 struct BinExp; 43 44 struct InterState; 45 struct Symbol; // back end symbol 44 46 45 47 enum TOK; … … 376 378 }; 377 379 380 struct StructLiteralExp : Expression 381 { 382 StructDeclaration *sd; // which aggregate this is for 383 Expressions *elements; // parallels sd->fields[] with 384 // NULL entries for fields to skip 385 386 Symbol *s; // back end symbol to initialize with literal 387 size_t soffset; // offset from start of s 388 int fillHoles; // fill alignment 'holes' with zero 389 390 StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *elements); 391 392 Expression *syntaxCopy(); 393 Expression *semantic(Scope *sc); 394 Expression *getField(Type *type, unsigned offset); 395 int getFieldIndex(Type *type, unsigned offset); 396 elem *toElem(IRState *irs); 397 int checkSideEffect(int flag); 398 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 399 void toMangleBuffer(OutBuffer *buf); 400 void scanForNestedRef(Scope *sc); 401 Expression *optimize(int result); 402 Expression *interpret(InterState *istate); 403 dt_t **toDt(dt_t **pdt); 404 405 int inlineCost(InlineCostState *ics); 406 Expression *doInline(InlineDoState *ids); 407 Expression *inlineScan(InlineScanState *iss); 408 }; 409 378 410 struct TypeDotIdExp : Expression 379 411 { … … 768 800 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 769 801 Expression *optimize(int result); 802 Expression *interpret(InterState *istate); 770 803 }; 771 804 … … 1253 1286 Expression *Cast(Type *type, Type *to, Expression *e1); 1254 1287 Expression *ArrayLength(Type *type, Expression *e1); 1288 Expression *Ptr(Type *type, Expression *e1); 1255 1289 1256 1290 Expression *Add(Type *type, Expression *e1, Expression *e2); branches/dmdfe/idgen.c
r458 r656 197 197 { "adReverse", "_adReverse" }, 198 198 199 // For internal functions 200 { "aaLen", "_aaLen" }, 201 { "aaKeys", "_aaKeys" }, 202 { "aaValues", "_aaValues" }, 203 { "aaRehash", "_aaRehash" }, 204 199 205 // For pragma's 200 206 { "lib" }, branches/dmdfe/inline.c
r460 r656 187 187 { 188 188 return 1 + arrayInlineCost(ics, keys) + arrayInlineCost(ics, values); 189 } 190 191 int StructLiteralExp::inlineCost(InlineCostState *ics) 192 { 193 return 1 + arrayInlineCost(ics, elements); 189 194 } 190 195 … … 716 721 717 722 723 Expression *StructLiteralExp::doInline(InlineDoState *ids) 724 { 725 StructLiteralExp *ce; 726 727 ce = (StructLiteralExp *)copy(); 728 ce->elements = arrayExpressiondoInline(elements, ids); 729 return ce; 730 } 731 732 718 733 Expression *ArrayExp::doInline(InlineDoState *ids) 719 734 { … … 1116 1131 arrayInlineScan(iss, keys); 1117 1132 arrayInlineScan(iss, values); 1133 1134 return e; 1135 } 1136 1137 1138 Expression *StructLiteralExp::inlineScan(InlineScanState *iss) 1139 { Expression *e = this; 1140 1141 //printf("StructLiteralExp::inlineScan()\n"); 1142 arrayInlineScan(iss, elements); 1118 1143 1119 1144 return e; branches/dmdfe/interpret.c
r523 r656 44 44 } 45 45 46 Expression *interpret_aaLen(InterState *istate, Expressions *arguments); 47 Expression *interpret_aaKeys(InterState *istate, Expressions *arguments); 48 Expression *interpret_aaValues(InterState *istate, Expressions *arguments); 49 46 50 /************************************* 47 51 * Attempt to interpret a function given the arguments. … … 57 61 printf("cantInterpret = %d, semanticRun = %d\n", cantInterpret, semanticRun); 58 62 #endif 63 if (global.errors) 64 return NULL; 65 if (ident == Id::aaLen) 66 return interpret_aaLen(istate, arguments); 67 else if (ident == Id::aaKeys) 68 return interpret_aaKeys(istate, arguments); 69 else if (ident == Id::aaValues) 70 return interpret_aaValues(istate, arguments); 71 59 72 if (cantInterpret || semanticRun == 1) 60 73 return NULL; … … 846 859 } 847 860 848 Expression *VarExp::interpret(InterState *istate) 849 { 850 #if LOG 851 printf("VarExp::interpret() %s\n", toChars()); 852 #endif 861 Expression *getVarExp(InterState *istate, VarDeclaration *v) 862 { 853 863 Expression *e = EXP_CANT_INTERPRET; 854 VarDeclaration *v = var->isVarDeclaration();855 864 if (v) 856 865 { … … 871 880 } 872 881 return e; 882 } 883 884 Expression *VarExp::interpret(InterState *istate) 885 { 886 #if LOG 887 printf("VarExp::interpret() %s\n", toChars()); 888 #endif 889 return getVarExp(istate, var->isVarDeclaration()); 873 890 } 874 891 … … 1078 1095 } 1079 1096 1097 Expression *StructLiteralExp::interpret(InterState *istate) 1098 { Expressions *expsx = NULL; 1099 1100 #if LOG 1101 printf("StructLiteralExp::interpret() %s\n", toChars()); 1102 #endif 1103 /* We don't know how to deal with overlapping fields 1104 */ 1105 if (sd->hasUnions) 1106 return EXP_CANT_INTERPRET; 1107 1108 if (elements) 1109 { 1110 for (size_t i = 0; i < elements->dim; i++) 1111 { Expression *e = (Expression *)elements->data[i]; 1112 if (!e) 1113 continue; 1114 1115 Expression *ex = e->interpret(istate); 1116 if (ex == EXP_CANT_INTERPRET) 1117 { delete expsx; 1118 return EXP_CANT_INTERPRET; 1119 } 1120 1121 /* If any changes, do Copy On Write 1122 */ 1123 if (ex != e) 1124 { 1125 if (!expsx) 1126 { expsx = new Expressions(); 1127 expsx->setDim(elements->dim); 1128 for (size_t j = 0; j < i; j++) 1129 { 1130 expsx->data[j] = elements->data[j]; 1131 } 1132 } 1133 expsx->data[i] = (void *)ex; 1134 } 1135 } 1136 } 1137 if (elements && expsx) 1138 { 1139 expandTuples(expsx); 1140 if (expsx->dim != elements->dim) 1141 { delete expsx; 1142 return EXP_CANT_INTERPRET; 1143 } 1144 StructLiteralExp *se = new StructLiteralExp(loc, sd, expsx); 1145 se->type = type; 1146 return se; 1147 } 1148 return this; 1149 } 1150 1080 1151 Expression *UnaExp::interpretCommon(InterState *istate, Expression *(*fp)(Type *, Expression *)) 1081 1152 { Expression *e; … … 1171 1242 if (e1 == EXP_CANT_INTERPRET) 1172 1243 goto Lcant; 1173 if (e1->isConst() != 1 && e1->op != TOKstring && e1->op != TOKarrayliteral) 1244 if (e1->isConst() != 1 && 1245 e1->op != TOKstring && 1246 e1->op != TOKarrayliteral && 1247 e1->op != TOKstructliteral) 1174 1248 goto Lcant; 1175 1249 … … 1177 1251 if (e2 == EXP_CANT_INTERPRET) 1178 1252 goto Lcant; 1179 if (e2->isConst() != 1 && e2->op != TOKstring && e2->op != TOKarrayliteral) 1253 if (e2->isConst() != 1 && 1254 e2->op != TOKstring && 1255 e2->op != TOKarrayliteral && 1256 e2->op != TOKstructliteral) 1180 1257 goto Lcant; 1181 1258 … … 1214 1291 if (e1 == EXP_CANT_INTERPRET) 1215 1292 return e1; 1293 Expression *e2 = this->e2->interpret(istate); 1294 if (e2 == EXP_CANT_INTERPRET) 1295 return e2; 1296 1297 /* Assignment to variable of the form: 1298 * v = e2 1299 */ 1216 1300 if (e1->op == TOKvar) 1217 1301 { … … 1233 1317 return e; 1234 1318 } 1235 Expression *e2 = this->e2->interpret(istate); 1319 if (fp) 1320 e2 = (*fp)(v->type, v->value, e2); 1321 else 1322 e2 = Cast(v->type, v->type, e2); 1236 1323 if (e2 != EXP_CANT_INTERPRET) 1237 1324 { 1238 if (fp) 1239 e2 = (*fp)(v->type, v->value, e2); 1325 if (!v->isParameter()) 1326 { 1327 for (size_t i = 0; 1; i++) 1328 { 1329 if (i == istate->vars.dim) 1330 { istate->vars.push(v); 1331 break; 1332 } 1333 if (v == (VarDeclaration *)istate->vars.data[i]) 1334 break; 1335 } 1336 } 1337 v->value = e2; 1338 e = Cast(type, type, e2); 1339 } 1340 } 1341 } 1342 /* Assignment to struct member of the form: 1343 * *(symoffexp) = e2 1344 */ 1345 else if (e1->op == TOKstar && ((PtrExp *)e1)->e1->op == TOKsymoff) 1346 { SymOffExp *soe = (SymOffExp *)((PtrExp *)e1)->e1; 1347 VarDeclaration *v = soe->var->isVarDeclaration(); 1348 1349 if (v->isDataseg()) 1350 return EXP_CANT_INTERPRET; 1351 if (fp && !v->value) 1352 { error("variable %s is used before initialization", v->toChars()); 1353 return e; 1354 } 1355 if (v->value->op != TOKstructliteral) 1356 return EXP_CANT_INTERPRET; 1357 StructLiteralExp *se = (StructLiteralExp *)v->value; 1358 int fieldi = se->getFieldIndex(type, soe->offset); 1359 if (fieldi == -1) 1360 return EXP_CANT_INTERPRET; 1361 Expression *ev = se->getField(type, soe->offset); 1362 if (fp) 1363 e2 = (*fp)(type, ev, e2); 1364 else 1365 e2 = Cast(type, type, e2); 1366 if (e2 == EXP_CANT_INTERPRET) 1367 return e2; 1368 1369 if (!v->isParameter()) 1370 { 1371 for (size_t i = 0; 1; i++) 1372 { 1373 if (i == istate->vars.dim) 1374 { istate->vars.push(v); 1375 break; 1376 } 1377 if (v == (VarDeclaration *)istate->vars.data[i]) 1378 break; 1379 } 1380 } 1381 1382 /* Create new struct literal reflecting updated fieldi 1383 */ 1384 Expressions *expsx = new Expressions(); 1385 expsx->setDim(se->elements->dim); 1386 for (size_t j = 0; j < expsx->dim; j++) 1387 { 1388 if (j == fieldi) 1389 expsx->data[j] = (void *)e2; 1390 else 1391 expsx->data[j] = se->elements->data[j]; 1392 } 1393 v->value = new StructLiteralExp(se->loc, se->sd, expsx); 1394 1395 e = Cast(type, type, e2); 1396 } 1397 /* Assignment to array element of the form: 1398 * a[i] = e2 1399 */ 1400 else if (e1->op == TOKindex && ((IndexExp *)e1)->e1->op == TOKvar) 1401 { IndexExp *ie = (IndexExp *)e1; 1402 VarExp *ve = (VarExp *)ie->e1; 1403 VarDeclaration *v = ve->var->isVarDeclaration(); 1404 1405 if (!v || v->isDataseg()) 1406 return EXP_CANT_INTERPRET; 1407 if (fp && !v->value) 1408 { error("variable %s is used before initialization", v->toChars()); 1409 return e; 1410 } 1411 1412 ArrayLiteralExp *ae = NULL; 1413 AssocArrayLiteralExp *aae = NULL; 1414 StringExp *se = NULL; 1415 if (v->value->op == TOKarrayliteral) 1416 ae = (ArrayLiteralExp *)v->value; 1417 else if (v->value->op == TOKassocarrayliteral) 1418 aae = (AssocArrayLiteralExp *)v->value; 1419 else if (v->value->op == TOKstring) 1420 se = (StringExp *)v->value; 1421 else 1422 return EXP_CANT_INTERPRET; 1423 1424 Expression *index = ie->e2->interpret(istate); 1425 if (index == EXP_CANT_INTERPRET) 1426 return EXP_CANT_INTERPRET; 1427 Expression *ev; 1428 if (fp || ae || se) // not for aae, because key might not be there 1429 { 1430 ev = Index(type, v->value, index); 1431 if (ev == EXP_CANT_INTERPRET) 1432 return EXP_CANT_INTERPRET; 1433 } 1434 1435 if (fp) 1436 e2 = (*fp)(type, ev, e2); 1437 else 1438 e2 = Cast(type, type, e2); 1439 if (e2 == EXP_CANT_INTERPRET) 1440 return e2; 1441 1442 if (!v->isParameter()) 1443 { 1444 for (size_t i = 0; 1; i++) 1445 { 1446 if (i == istate->vars.dim) 1447 { istate->vars.push(v); 1448 break; 1449 } 1450 if (v == (VarDeclaration *)istate->vars.data[i]) 1451 break; 1452 } 1453 } 1454 1455 if (ae) 1456 { 1457 /* Create new array literal reflecting updated elem 1458 */ 1459 int elemi = index->toInteger(); 1460 Expressions *expsx = new Expressions(); 1461 expsx->setDim(ae->elements->dim); 1462 for (size_t j = 0; j < expsx->dim; j++) 1463 { 1464 if (j == elemi) 1465 expsx->data[j] = (void *)e2; 1240 1466 else 1241 e2 = Cast(v->type, v->type, e2); 1242 if (e2 != EXP_CANT_INTERPRET) 1243 { 1244 if (!(v->isDataseg() || v->isParameter())) 1245 { 1246 for (size_t i = 0; 1; i++) 1247 { 1248 if (i == istate->vars.dim) 1249 { istate->vars.push(v); 1250 break; 1251 } 1252 if (v == (VarDeclaration *)istate->vars.data[i]) 1253 break; 1254 } 1255 } 1256 v->value = e2; 1257 e = Cast(type, type, e2); 1467 expsx->data[j] = ae->elements->data[j]; 1468 } 1469 v->value = new ArrayLiteralExp(ae->loc, expsx); 1470 v->value->type = ae->type; 1471 } 1472 else if (aae) 1473 { 1474 /* Create new associative array literal reflecting updated key/value 1475 */ 1476 Expressions *keysx = aae->keys; 1477 Expressions *valuesx = new Expressions(); 1478 valuesx->setDim(aae->values->dim); 1479 int updated = 0; 1480 for (size_t j = valuesx->dim; j; ) 1481 { j--; 1482 Expression *ekey = (Expression *)aae->keys->data[j]; 1483 Expression *ex = Equal(TOKequal, Type::tbool, ekey, index); 1484 if (ex == EXP_CANT_INTERPRET) 1485 return EXP_CANT_INTERPRET; 1486 if (ex->isBool(TRUE)) 1487 { valuesx->data[j] = (void *)e2; 1488 updated = 1; 1258 1489 } 1259 } 1260 } 1490 else 1491 valuesx->data[j] = aae->values->data[j]; 1492 } 1493 if (!updated) 1494 { // Append index/e2 to keysx[]/valuesx[] 1495 valuesx->push(e2); 1496 keysx = (Expressions *)keysx->copy(); 1497 keysx->push(index); 1498 } 1499 v->value = new AssocArrayLiteralExp(aae->loc, keysx, valuesx); 1500 v->value->type = aae->type; 1501 } 1502 else if (se) 1503 { 1504 /* Create new string literal reflecting updated elem 1505 */ 1506 int elemi = index->toInteger(); 1507 unsigned char *s; 1508 s = (unsigned char *)mem.calloc(se->len + 1, se->sz); 1509 memcpy(s, se->string, se->len * se->sz); 1510 unsigned value = e2->toInteger(); 1511 switch (se->sz) 1512 { 1513 case 1: s[elemi] = value; break; 1514 case 2: ((unsigned short *)s)[elemi] = value; break; 1515 case 4: ((unsigned *)s)[elemi] = value; break; 1516 default: 1517 assert(0); 1518 break; 1519 } 1520 StringExp *se2 = new StringExp(se->loc, s, se->len); 1521 se2->committed = se->committed; 1522 se2->postfix = se->postfix; 1523 se2->type = se->type; 1524 v->value = se2; 1525 } 1526 else 1527 assert(0); 1528 1529 e = Cast(type, type, e2); 1530 } 1531 else 1532 { 1533 #ifdef DEBUG 1534 dump(0); 1535 #endif 1261 1536 } 1262 1537 return e; … … 1497 1772 goto Lcant; 1498 1773 1499 if ( op == TOKstring ||op == TOKarrayliteral)1774 if (e1->op == TOKstring || e1->op == TOKarrayliteral) 1500 1775 { 1501 1776 /* Set the $ variable … … 1631 1906 } 1632 1907 1633 1908 Expression *PtrExp::interpret(InterState *istate) 1909 { Expression *e = EXP_CANT_INTERPRET; 1910 1911 #if LOG 1912 printf("PtrExp::interpret() %s\n", toChars()); 1913 #endif 1914 1915 // Constant fold *(&structliteral + offset) 1916 if (e1->op == TOKadd) 1917 { 1918 e = Ptr(type, e1); 1919 } 1920 else if (e1->op == TOKsymoff) 1921 { SymOffExp *soe = (SymOffExp *)e1; 1922 VarDeclaration *v = soe->var->isVarDeclaration(); 1923 if (v) 1924 { Expression *ev = getVarExp(istate, v); 1925 if (ev != EXP_CANT_INTERPRET && ev->op == TOKstructliteral) 1926 { StructLiteralExp *se = (StructLiteralExp *)ev; 1927 e = se->getField(type, soe->offset); 1928 if (!e) 1929 e = EXP_CANT_INTERPRET; 1930 } 1931 } 1932 } 1933 return e; 1934 } 1935 1936 /******************************* Special Functions ***************************/ 1937 1938 Expression *interpret_aaLen(InterState *istate, Expressions *arguments) 1939 { 1940 if (!arguments || arguments->dim != 1) 1941 return NULL; 1942 Expression *earg = (Expression *)arguments->data[0]; 1943 earg = earg->interpret(istate); 1944 if (earg == EXP_CANT_INTERPRET) 1945 return NULL; 1946 if (earg->op != TOKassocarrayliteral) 1947 return NULL; 1948 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg; 1949 Expression *e = new IntegerExp(aae->loc, aae->keys->dim, Type::tsize_t); 1950 return e; 1951 } 1952 1953 Expression *interpret_aaKeys(InterState *istate, Expressions *arguments) 1954 { 1955 printf("interpret_aaKeys()\n"); 1956 if (!arguments || arguments->dim != 2) 1957 return NULL; 1958 Expression *earg = (Expression *)arguments->data[0]; 1959 earg = earg->interpret(istate); 1960 if (earg == EXP_CANT_INTERPRET) 1961 return NULL; 1962 if (earg->op != TOKassocarrayliteral) 1963 return NULL; 1964 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg; 1965 Expression *e = new ArrayLiteralExp(aae->loc, aae->keys); 1966 return e; 1967 } 1968 1969 Expression *interpret_aaValues(InterState *istate, Expressions *arguments) 1970 { 1971 //printf("interpret_aaValues()\n"); 1972 if (!arguments || arguments->dim != 3) 1973 return NULL; 1974 Expression *earg = (Expression *)arguments->data[0]; 1975 earg = earg->interpret(istate); 1976 if (earg == EXP_CANT_INTERPRET) 1977 return NULL; 1978 if (earg->op != TOKassocarrayliteral) 1979 return NULL; 1980 AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg; 1981 Expression *e = new ArrayLiteralExp(aae->loc, aae->values); 1982 //printf("result is %s\n", e->toChars()); 1983 return e; 1984 } 1985 branches/dmdfe/lexer.c
r460 r656 2731 2731 Token::tochars[TOKarrayliteral] = "arrayliteral"; 2732 2732 Token::tochars[TOKassocarrayliteral] = "assocarrayliteral"; 2733 Token::tochars[TOKstructliteral] = "structliteral"; 2733 2734 Token::tochars[TOKstring] = "string"; 2734 2735 Token::tochars[TOKdsymbol] = "symbol"; branches/dmdfe/lexer.h
r460 r656 68 68 TOKnewanonclass, TOKcomment, 69 69 TOKarrayliteral, TOKassocarrayliteral, 70 TOKstructliteral, 70 71 71 72 // Operators branches/dmdfe/mars.c
r523 r656 56 56 copyright = "Copyright (c) 1999-2007 by Digital Mars"; 57 57 written = "written by Walter Bright"; 58 version = "v1.01 3";58 version = "v1.014"; 59 59 global.structalign = 8; 60 60 branches/dmdfe/mtype.c
r523 r656 2195 2195 // Convert to Tarray 2196 2196 key = key->next->arrayOf(); 2197 #endif 2197 2198 break; 2198 #endif2199 2199 case Tbit: 2200 2200 case Tbool: … … 2230 2230 Expressions *arguments; 2231 2231 2232 fd = FuncDeclaration::genCfunc(Type::tsize_t, "_aaLen");2232 fd = FuncDeclaration::genCfunc(Type::tsize_t, Id::aaLen); 2233 2233 ec = new VarExp(0, fd); 2234 2234 arguments = new Expressions(); … … 2245 2245 2246 2246 assert(size); 2247 fd = FuncDeclaration::genCfunc(Type::tindex, "_aaKeys");2247 fd = FuncDeclaration::genCfunc(Type::tindex, Id::aaKeys); 2248 2248 ec = new VarExp(0, fd); 2249 2249 arguments = new Expressions(); … … 2259 2259 Expressions *arguments; 2260 2260 2261 fd = FuncDeclaration::genCfunc(Type::tindex, "_aaValues");2261 fd = FuncDeclaration::genCfunc(Type::tindex, Id::aaValues); 2262 2262 ec = new VarExp(0, fd); 2263 2263 arguments = new Expressions(); … … 2276 2276 Expressions *arguments; 2277 2277 2278 fd = FuncDeclaration::genCfunc(Type::tint64, "_aaRehash");2278 fd = FuncDeclaration::genCfunc(Type::tint64, Id::aaRehash); 2279 2279 ec = new VarExp(0, fd); 2280 2280 arguments = new Expressions();
