Changeset 656

Show
Ignore:
Timestamp:
07/02/07 18:05:45 (1 year ago)
Author:
Gregor
Message:

MERGE: DMD 1.014

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dmdfe/aggregate.h

    r458 r656  
    4444    unsigned alignsize;     // size of struct for alignment purposes 
    4545    unsigned structalign;   // struct member alignment in effect 
     46    int hasUnions;      // set if aggregate has overlapping fields 
    4647    Array fields;       // VarDeclaration fields 
    4748    unsigned sizeok;        // set when structsize contains valid data 
  • branches/dmdfe/constfold.c

    r523 r656  
    663663    real_t r2; 
    664664 
     665    //printf("Equal(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 
     666 
    665667    assert(op == TOKequal || op == TOKnotequal); 
    666668 
     
    693695        Expression *ee2 = (Expression *)es2->elements->data[i]; 
    694696 
     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        } 
    695732        Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2); 
    696733        if (v == EXP_CANT_INTERPRET) 
     
    10361073    Loc loc = e1->loc; 
    10371074 
    1038     //printf("Index(e1 = %s)\n", e1->toChars()); 
     1075    //printf("Index(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 
    10391076    assert(e1->type); 
    10401077    if (e1->op == TOKstring && e2->op == TOKint64) 
     
    13841421} 
    13851422 
    1386  
     1423Expression *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  
    185185 
    186186 
     187void StructLiteralExp::scanForNestedRef(Scope *sc) 
     188{ 
     189    arrayExpressionScanForNestedRef(sc, elements); 
     190} 
     191 
     192 
    187193void TupleExp::scanForNestedRef(Scope *sc) 
    188194{ 
  • branches/dmdfe/enum.c

    r458 r656  
    2727    minval = 0; 
    2828    defaultval = 0; 
     29    sinit = NULL; 
    2930} 
    3031 
  • branches/dmdfe/enum.h

    r458 r656  
    2626#endif 
    2727 
     28 
    2829struct EnumDeclaration : ScopeDsymbol 
    2930{ 
     
    4849 
    4950    void toDebug(); 
     51 
     52    Symbol *sinit; 
     53    Symbol *toInitializer(); 
    5054}; 
    5155 
  • branches/dmdfe/expression.c

    r523 r656  
    307307    for (size_t i = 0; i < exps->dim; i++) 
    308308    {   Expression *arg = (Expression *)exps->data[i]; 
     309        if (!arg) 
     310        continue; 
    309311 
    310312        // Inline expand all the tuples 
     
    26422644    key->toMangleBuffer(buf); 
    26432645    value->toMangleBuffer(buf); 
     2646    } 
     2647} 
     2648 
     2649/************************ StructLiteralExp ************************************/ 
     2650 
     2651// sd( e1, e2, e3, ... ) 
     2652 
     2653StructLiteralExp::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 
     2663Expression *StructLiteralExp::syntaxCopy() 
     2664{ 
     2665    return new StructLiteralExp(loc, sd, arraySyntaxCopy(elements)); 
     2666} 
     2667 
     2668Expression *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 
     2741Expression *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 
     2761int 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 
     2786int 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 
     2801void 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 
     2809void 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 
    26442819    } 
    26452820} 
     
    41884363    if (e1->op != TOKstring) 
    41894364    {   error("argument to mixin must be a string, not (%s)", e1->toChars()); 
     4365    type = Type::terror; 
    41904366    return this; 
    41914367    } 
     
    51785354    {   AggregateDeclaration *ad; 
    51795355 
    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) 
    51815368    { 
    51825369        ad = ((TypeClass *)t1)->sym; 
    51835370        goto L1; 
    5184     } 
    5185     else if (t1->ty == Tstruct) 
    5186     { 
    5187         ad = ((TypeStruct *)t1)->sym; 
    51885371    L1: 
    51895372        // Rewrite as e1.call(arguments) 
     
    63746557    : BinExp(loc, TOKindex, sizeof(IndexExp), e1, e2) 
    63756558{ 
     6559    //printf("IndexExp::IndexExp('%s')\n", toChars()); 
    63766560    lengthVar = NULL; 
    63776561    modifiable = 0; // assume it is an rvalue 
     
    63906574    if (type) 
    63916575    return this; 
     6576    if (!e1->type) 
     6577    e1 = e1->semantic(sc); 
    63926578    assert(e1->type);       // semantic() should already be run on it 
    63936579    e = this; 
  • branches/dmdfe/expression.h

    r523 r656  
    3636struct Declaration; 
    3737struct AggregateDeclaration; 
     38struct StructDeclaration; 
    3839struct TemplateInstance; 
    3940struct TemplateDeclaration; 
     
    4243struct BinExp; 
    4344struct InterState; 
     45struct Symbol;      // back end symbol 
    4446 
    4547enum TOK; 
     
    376378}; 
    377379 
     380struct 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 
    378410struct TypeDotIdExp : Expression 
    379411{ 
     
    768800    void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 
    769801    Expression *optimize(int result); 
     802    Expression *interpret(InterState *istate); 
    770803}; 
    771804 
     
    12531286Expression *Cast(Type *type, Type *to, Expression *e1); 
    12541287Expression *ArrayLength(Type *type, Expression *e1); 
     1288Expression *Ptr(Type *type, Expression *e1); 
    12551289 
    12561290Expression *Add(Type *type, Expression *e1, Expression *e2); 
  • branches/dmdfe/idgen.c

    r458 r656  
    197197    { "adReverse", "_adReverse" }, 
    198198 
     199    // For internal functions 
     200    { "aaLen", "_aaLen" }, 
     201    { "aaKeys", "_aaKeys" }, 
     202    { "aaValues", "_aaValues" }, 
     203    { "aaRehash", "_aaRehash" }, 
     204 
    199205    // For pragma's 
    200206    { "lib" }, 
  • branches/dmdfe/inline.c

    r460 r656  
    187187{ 
    188188    return 1 + arrayInlineCost(ics, keys) + arrayInlineCost(ics, values); 
     189} 
     190 
     191int StructLiteralExp::inlineCost(InlineCostState *ics) 
     192{ 
     193    return 1 + arrayInlineCost(ics, elements); 
    189194} 
    190195 
     
    716721 
    717722 
     723Expression *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 
    718733Expression *ArrayExp::doInline(InlineDoState *ids) 
    719734{ 
     
    11161131    arrayInlineScan(iss, keys); 
    11171132    arrayInlineScan(iss, values); 
     1133 
     1134    return e; 
     1135} 
     1136 
     1137 
     1138Expression *StructLiteralExp::inlineScan(InlineScanState *iss) 
     1139{   Expression *e = this; 
     1140 
     1141    //printf("StructLiteralExp::inlineScan()\n"); 
     1142    arrayInlineScan(iss, elements); 
    11181143 
    11191144    return e; 
  • branches/dmdfe/interpret.c

    r523 r656  
    4444} 
    4545 
     46Expression *interpret_aaLen(InterState *istate, Expressions *arguments); 
     47Expression *interpret_aaKeys(InterState *istate, Expressions *arguments); 
     48Expression *interpret_aaValues(InterState *istate, Expressions *arguments); 
     49 
    4650/************************************* 
    4751 * Attempt to interpret a function given the arguments. 
     
    5761    printf("cantInterpret = %d, semanticRun = %d\n", cantInterpret, semanticRun); 
    5862#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 
    5972    if (cantInterpret || semanticRun == 1) 
    6073    return NULL; 
     
    846859} 
    847860 
    848 Expression *VarExp::interpret(InterState *istate) 
    849 
    850 #if LOG 
    851     printf("VarExp::interpret() %s\n", toChars()); 
    852 #endif 
     861Expression *getVarExp(InterState *istate, VarDeclaration *v) 
     862
    853863    Expression *e = EXP_CANT_INTERPRET; 
    854     VarDeclaration *v = var->isVarDeclaration(); 
    855864    if (v) 
    856865    { 
     
    871880    } 
    872881    return e; 
     882} 
     883 
     884Expression *VarExp::interpret(InterState *istate) 
     885{ 
     886#if LOG 
     887    printf("VarExp::interpret() %s\n", toChars()); 
     888#endif 
     889    return getVarExp(istate, var->isVarDeclaration()); 
    873890} 
    874891 
     
    10781095} 
    10791096 
     1097Expression *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 
    10801151Expression *UnaExp::interpretCommon(InterState *istate, Expression *(*fp)(Type *, Expression *)) 
    10811152{   Expression *e; 
     
    11711242    if (e1 == EXP_CANT_INTERPRET) 
    11721243    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) 
    11741248    goto Lcant; 
    11751249 
     
    11771251    if (e2 == EXP_CANT_INTERPRET) 
    11781252    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) 
    11801257    goto Lcant; 
    11811258 
     
    12141291    if (e1 == EXP_CANT_INTERPRET) 
    12151292    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     */ 
    12161300    if (e1->op == TOKvar) 
    12171301    { 
     
    12331317        return e; 
    12341318        } 
    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); 
    12361323        if (e2 != EXP_CANT_INTERPRET) 
    12371324        { 
    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; 
    12401466        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; 
    12581489        } 
    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 
    12611536    } 
    12621537    return e; 
     
    14971772    goto Lcant; 
    14981773 
    1499     if (op == TOKstring || op == TOKarrayliteral) 
     1774    if (e1->op == TOKstring || e1->op == TOKarrayliteral) 
    15001775    { 
    15011776    /* Set the $ variable 
     
    16311906} 
    16321907 
    1633  
     1908Expression *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 
     1938Expression *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 
     1953Expression *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 
     1969Expression *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  
    27312731    Token::tochars[TOKarrayliteral] = "arrayliteral"; 
    27322732    Token::tochars[TOKassocarrayliteral] = "assocarrayliteral"; 
     2733    Token::tochars[TOKstructliteral]    = "structliteral"; 
    27332734    Token::tochars[TOKstring]       = "string"; 
    27342735    Token::tochars[TOKdsymbol]      = "symbol"; 
  • branches/dmdfe/lexer.h

    r460 r656  
    6868    TOKnewanonclass, TOKcomment, 
    6969    TOKarrayliteral, TOKassocarrayliteral, 
     70    TOKstructliteral, 
    7071 
    7172    // Operators 
  • branches/dmdfe/mars.c

    r523 r656  
    5656    copyright = "Copyright (c) 1999-2007 by Digital Mars"; 
    5757    written = "written by Walter Bright"; 
    58     version = "v1.013"; 
     58    version = "v1.014"; 
    5959    global.structalign = 8; 
    6060 
  • branches/dmdfe/mtype.c

    r523 r656  
    21952195        // Convert to Tarray 
    21962196        key = key->next->arrayOf(); 
     2197#endif 
    21972198        break; 
    2198 #endif 
    21992199    case Tbit: 
    22002200    case Tbool: 
     
    22302230    Expressions *arguments; 
    22312231 
    2232     fd = FuncDeclaration::genCfunc(Type::tsize_t, "_aaLen"); 
     2232    fd = FuncDeclaration::genCfunc(Type::tsize_t, Id::aaLen); 
    22332233    ec = new VarExp(0, fd); 
    22342234    arguments = new Expressions(); 
     
    22452245 
    22462246    assert(size); 
    2247     fd = FuncDeclaration::genCfunc(Type::tindex, "_aaKeys"); 
     2247    fd = FuncDeclaration::genCfunc(Type::tindex, Id::aaKeys); 
    22482248    ec = new VarExp(0, fd); 
    22492249    arguments = new Expressions(); 
     
    22592259    Expressions *arguments; 
    22602260 
    2261     fd = FuncDeclaration::genCfunc(Type::tindex, "_aaValues"); 
     2261    fd = FuncDeclaration::genCfunc(Type::tindex, Id::aaValues); 
    22622262    ec = new VarExp(0, fd); 
    22632263    arguments = new Expressions(); 
     
    22762276    Expressions *arguments; 
    22772277 
    2278     fd = FuncDeclaration::genCfunc(Type::tint64, "_aaRehash"); 
     2278    fd = FuncDeclaration::genCfunc(Type::tint64, Id::aaRehash); 
    22792279    ec = new VarExp(0, fd); 
    22802280    arguments = new Expressions();