Changeset 361

Show
Ignore:
Timestamp:
02/16/07 18:10:55 (2 years ago)
Author:
Gregor
Message:

MERGE: DMD 1.006

Added some Mac OS X fixes.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dmdfe/Makefile

    r360 r361  
    77 
    88LDFLAGS= 
    9 WA=-Wl,--whole-archive 
    10 NWA=-Wl,--no-whole-archive 
    11  
    12 AR=$(CROSS)ar 
    13 ARFLAGS=rc 
    14 RANLIB=$(CROSS)ranlib 
    159 
    1610OBJS=\ 
     
    4236  init.o \ 
    4337  inline.o \ 
     38  interpret.o \ 
    4439  lexer.o \ 
    4540  link.o \ 
     
    6762all: dmdfe$(EXEEXT) 
    6863 
    69 dmdfe$(EXEEXT): libdmd.a 
    70     $(CXX) $(CXXFLAGS) $(LDFLAGS) $(WA) libdmd.a $(NWA) -o dmdfe$(EXEEXT) 
    71  
    72 libdmd.a: id.c impcnvtab.c $(OBJS) 
    73     $(AR) $(ARFLAGS) libdmd.a $(OBJS) 
     64dmdfe$(EXEEXT): $(OBJS) 
     65    $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) -o dmdfe$(EXEEXT) 
    7466 
    7567id.c: idgen$(EXEEXT) 
     
    9789 
    9890clean: 
    99     rm -f dmdfe$(EXEEXT) libdmd.a $(OBJS) 
     91    rm -f dmdfe$(EXEEXT) $(OBJS) 
    10092    rm -f id.c id.h idgen$(EXEEXT) idgen.o 
    10193    rm -f impcnvtab.c impcnvtab.h impcnvgen$(EXEEXT) impcnvgen.o 
  • branches/dmdfe/arraytypes.h

    r360 r361  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 2006 by Digital Mars 
     3// Copyright (c) 2006-2007 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
  • branches/dmdfe/constfold.c

    r360 r361  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2006 by Digital Mars 
     3// Copyright (c) 1999-2007 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
     
    1818#endif 
    1919 
     20#include "mem.h" 
     21#include "root.h" 
     22 
    2023#include "mtype.h" 
    2124#include "expression.h" 
     
    3033static real_t zero; // work around DMC bug for now 
    3134 
     35#define LOG 0 
    3236 
    3337/* ================================== isConst() ============================== */ 
     
    5963} 
    6064 
    61 /* ================================== constFold() ============================== */ 
    62  
    63 Expression *Expression::constFold() 
    64 
    65     return this; 
    66 
    67  
    68 Expression *NegExp::constFold() 
    69 
    70     e1 = e1->constFold(); 
     65/* =============================== constFold() ============================== */ 
     66 
     67/* The constFold() functions were redundant with the optimize() ones, 
     68 * and so have been folded in with them. 
     69 */ 
     70 
     71/* ========================================================================== */ 
     72 
     73Expression *Neg(Type *type, Expression *e1) 
     74{   Expression *e; 
     75    Loc loc = e1->loc; 
     76 
    7177    if (e1->type->isreal()) 
    72     {   RealExp *e; 
    73  
     78    { 
    7479    e = new RealExp(loc, -e1->toReal(), type); 
    75     return e; 
    7680    } 
    7781    else if (e1->type->isimaginary()) 
    78     {   RealExp *e; 
    79  
     82    { 
    8083    e = new RealExp(loc, -e1->toImaginary(), type); 
    81     return e; 
    8284    } 
    8385    else if (e1->type->iscomplex()) 
    84     {   ComplexExp *e; 
    85  
     86    { 
    8687    e = new ComplexExp(loc, -e1->toComplex(), type); 
    87     return e; 
    8888    } 
    8989    else 
    90     return new IntegerExp(loc, -e1->toInteger(), type); 
    91 
    92  
    93 Expression *ComExp::constFold() 
    94 
    95     e1 = e1->constFold(); 
    96     return new IntegerExp(loc, ~e1->toInteger(), type); 
    97 
    98  
    99 Expression *NotExp::constFold() 
    100 
    101     e1 = e1->constFold(); 
    102     return new IntegerExp(loc, e1->isBool(0), type); 
    103 
    104  
    105 Expression *BoolExp::constFold() 
    106 
    107     e1 = e1->constFold(); 
    108     return new IntegerExp(loc, e1->isBool(1), type); 
    109 
    110  
    111 Expression *CastExp::constFold() 
    112 
    113     //printf("CastExp::constFold(%s)\n", toChars()); 
    114     //printf("from %s to %s\n", type->toChars(), to->toChars()); 
    115     //printf("type = %p\n", type); 
    116     assert(type); 
    117  
    118     e1 = e1->constFold(); 
    119     if (e1->op == TOKsymoff) 
    120     { 
    121     if (type->size() == e1->type->size() && 
    122         type->toBasetype()->ty != Tsarray) 
    123     { 
    124         e1->type = type; 
    125         return e1; 
    126     } 
    127     return this; 
    128     } 
     90    e = new IntegerExp(loc, -e1->toInteger(), type); 
     91    return e; 
     92
     93 
     94Expression *Com(Type *type, Expression *e1) 
     95{   Expression *e; 
     96    Loc loc = e1->loc; 
     97 
     98    e = new IntegerExp(loc, ~e1->toInteger(), type); 
     99    return e; 
     100
     101 
     102Expression *Not(Type *type, Expression *e1) 
     103{   Expression *e; 
     104    Loc loc = e1->loc; 
     105 
     106    e = new IntegerExp(loc, e1->isBool(0), type); 
     107    return e; 
     108
     109 
     110Expression *Bool(Type *type, Expression *e1) 
     111{   Expression *e; 
     112    Loc loc = e1->loc; 
     113 
     114    e = new IntegerExp(loc, e1->isBool(1), type); 
     115    return e; 
     116
     117 
     118Expression *Add(Type *type, Expression *e1, Expression *e2) 
     119{   Expression *e; 
     120    Loc loc = e1->loc; 
     121 
     122#if LOG 
     123    printf("Add(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 
     124#endif 
     125    if (type->isreal()) 
     126    { 
     127    e = new RealExp(loc, e1->toReal() + e2->toReal(), type); 
     128    } 
     129    else if (type->isimaginary()) 
     130    { 
     131    e = new RealExp(loc, e1->toImaginary() + e2->toImaginary(), type); 
     132    } 
     133    else if (type->iscomplex()) 
     134    { 
     135    // This rigamarole is necessary so that -0.0 doesn't get 
     136    // converted to +0.0 by doing an extraneous add with +0.0 
     137    complex_t c1; 
     138    real_t r1; 
     139    real_t i1; 
     140 
     141    complex_t c2; 
     142    real_t r2; 
     143    real_t i2; 
     144 
     145    complex_t v; 
     146    int x; 
     147 
     148    if (e1->type->isreal()) 
     149    {   r1 = e1->toReal(); 
     150        x = 0; 
     151    } 
     152    else if (e1->type->isimaginary()) 
     153    {   i1 = e1->toImaginary(); 
     154        x = 3; 
     155    } 
     156    else 
     157    {   c1 = e1->toComplex(); 
     158        x = 6; 
     159    } 
     160 
     161    if (e2->type->isreal()) 
     162    {   r2 = e2->toReal(); 
     163    } 
     164    else if (e2->type->isimaginary()) 
     165    {   i2 = e2->toImaginary(); 
     166        x += 1; 
     167    } 
     168    else 
     169    {   c2 = e2->toComplex(); 
     170        x += 2; 
     171    } 
     172 
     173    switch (x) 
     174    { 
     175#if __DMC__ 
     176        case 0+0:   v = (complex_t) (r1 + r2);  break; 
     177        case 0+1:   v = r1 + i2 * I;        break; 
     178        case 0+2:   v = r1 + c2;            break; 
     179        case 3+0:   v = i1 * I + r2;        break; 
     180        case 3+1:   v = (complex_t) ((i1 + i2) * I); break; 
     181        case 3+2:   v = i1 * I + c2;        break; 
     182        case 6+0:   v = c1 + r2;            break; 
     183        case 6+1:   v = c1 + i2 * I;        break; 
     184        case 6+2:   v = c1 + c2;            break; 
     185#else 
     186        case 0+0:   v = complex_t(r1 + r2, 0);  break; 
     187        case 0+1:   v = complex_t(r1, i2);      break; 
     188        case 0+2:   v = complex_t(r1 + creall(c2), cimagl(c2)); break; 
     189        case 3+0:   v = complex_t(r2, i1);      break; 
     190        case 3+1:   v = complex_t(0, i1 + i2);  break; 
     191        case 3+2:   v = complex_t(creall(c2), i1 + cimagl(c2)); break; 
     192        case 6+0:   v = complex_t(creall(c1) + r2, cimagl(c2)); break; 
     193        case 6+1:   v = complex_t(creall(c1), cimagl(c1) + i2); break; 
     194        case 6+2:   v = c1 + c2;            break; 
     195#endif 
     196        default: assert(0); 
     197    } 
     198    e = new ComplexExp(loc, v, type); 
     199    } 
     200    else if (e1->op == TOKsymoff) 
     201    { 
     202    SymOffExp *soe = (SymOffExp *)e1; 
     203    e = new SymOffExp(loc, soe->var, soe->offset + e2->toInteger()); 
     204    e->type = type; 
     205    } 
     206    else if (e2->op == TOKsymoff) 
     207    { 
     208    SymOffExp *soe = (SymOffExp *)e2; 
     209    e = new SymOffExp(loc, soe->var, soe->offset + e1->toInteger()); 
     210    e->type = type; 
     211    } 
     212    else 
     213    e = new IntegerExp(loc, e1->toInteger() + e2->toInteger(), type); 
     214    return e; 
     215
     216 
     217 
     218Expression *Min(Type *type, Expression *e1, Expression *e2) 
     219{   Expression *e; 
     220    Loc loc = e1->loc; 
     221 
     222    if (type->isreal()) 
     223    { 
     224    e = new RealExp(loc, e1->toReal() - e2->toReal(), type); 
     225    } 
     226    else if (type->isimaginary()) 
     227    { 
     228    e = new RealExp(loc, e1->toImaginary() - e2->toImaginary(), type); 
     229    } 
     230    else if (type->iscomplex()) 
     231    { 
     232    // This rigamarole is necessary so that -0.0 doesn't get 
     233    // converted to +0.0 by doing an extraneous add with +0.0 
     234    complex_t c1; 
     235    real_t r1; 
     236    real_t i1; 
     237 
     238    complex_t c2; 
     239    real_t r2; 
     240    real_t i2; 
     241 
     242    complex_t v; 
     243    int x; 
     244 
     245    if (e1->type->isreal()) 
     246    {   r1 = e1->toReal(); 
     247        x = 0; 
     248    } 
     249    else if (e1->type->isimaginary()) 
     250    {   i1 = e1->toImaginary(); 
     251        x = 3; 
     252    } 
     253    else 
     254    {   c1 = e1->toComplex(); 
     255        x = 6; 
     256    } 
     257 
     258    if (e2->type->isreal()) 
     259    {   r2 = e2->toReal(); 
     260    } 
     261    else if (e2->type->isimaginary()) 
     262    {   i2 = e2->toImaginary(); 
     263        x += 1; 
     264    } 
     265    else 
     266    {   c2 = e2->toComplex(); 
     267        x += 2; 
     268    } 
     269 
     270    switch (x) 
     271    { 
     272#if __DMC__ 
     273        case 0+0:   v = (complex_t) (r1 - r2);  break; 
     274        case 0+1:   v = r1 - i2 * I;        break; 
     275        case 0+2:   v = r1 - c2;            break; 
     276        case 3+0:   v = i1 * I - r2;        break; 
     277        case 3+1:   v = (complex_t) ((i1 - i2) * I); break; 
     278        case 3+2:   v = i1 * I - c2;        break; 
     279        case 6+0:   v = c1 - r2;            break; 
     280        case 6+1:   v = c1 - i2 * I;        break; 
     281        case 6+2:   v = c1 - c2;            break; 
     282#else 
     283        case 0+0:   v = complex_t(r1 - r2, 0);  break; 
     284        case 0+1:   v = complex_t(r1, -i2);     break; 
     285        case 0+2:   v = complex_t(r1 - creall(c2), -cimagl(c2));    break; 
     286        case 3+0:   v = complex_t(-r2, i1);     break; 
     287        case 3+1:   v = complex_t(0, i1 - i2);  break; 
     288        case 3+2:   v = complex_t(-creall(c2), i1 - cimagl(c2));    break; 
     289        case 6+0:   v = complex_t(creall(c1) - r2, cimagl(c1)); break; 
     290        case 6+1:   v = complex_t(creall(c1), cimagl(c1) - i2); break; 
     291        case 6+2:   v = c1 - c2;            break; 
     292#endif 
     293        default: assert(0); 
     294    } 
     295    e = new ComplexExp(loc, v, type); 
     296    } 
     297    else if (e1->op == TOKsymoff) 
     298    { 
     299    SymOffExp *soe = (SymOffExp *)e1; 
     300    e = new SymOffExp(loc, soe->var, soe->offset - e2->toInteger()); 
     301    e->type = type; 
     302    } 
     303    else 
     304    { 
     305    e = new IntegerExp(loc, e1->toInteger() - e2->toInteger(), type); 
     306    } 
     307    return e; 
     308
     309 
     310Expression *Mul(Type *type, Expression *e1, Expression *e2) 
     311{   Expression *e; 
     312    Loc loc = e1->loc; 
     313 
     314    if (type->isfloating()) 
     315    {   complex_t c; 
     316#ifdef IN_GCC 
     317    real_t r; 
     318#else 
     319    d_float80 r; 
     320#endif 
     321 
     322    if (e1->type->isreal()) 
     323    { 
     324#if __DMC__ 
     325        c = e1->toReal() * e2->toComplex(); 
     326#else 
     327        r = e1->toReal(); 
     328        c = e2->toComplex(); 
     329        c = complex_t(r * creall(c), r * cimagl(c)); 
     330#endif 
     331    } 
     332    else if (e1->type->isimaginary()) 
     333    { 
     334#if __DMC__ 
     335        c = e1->toImaginary() * I * e2->toComplex(); 
     336#else 
     337        r = e1->toImaginary(); 
     338        c = e2->toComplex(); 
     339        c = complex_t(-r * cimagl(c), r * creall(c)); 
     340#endif 
     341    } 
     342    else if (e2->type->isreal()) 
     343    { 
     344#if __DMC__ 
     345        c = e2->toReal() * e1->toComplex(); 
     346#else 
     347        r = e2->toReal(); 
     348        c = e1->toComplex(); 
     349        c = complex_t(r * creall(c), r * cimagl(c)); 
     350#endif 
     351    } 
     352    else if (e2->type->isimaginary()) 
     353    { 
     354#if __DMC__ 
     355        c = e1->toComplex() * e2->toImaginary() * I; 
     356#else 
     357        r = e2->toImaginary(); 
     358        c = e1->toComplex(); 
     359        c = complex_t(-r * cimagl(c), r * creall(c)); 
     360#endif 
     361    } 
     362    else 
     363        c = e1->toComplex() * e2->toComplex(); 
     364 
     365    if (type->isreal()) 
     366        e = new RealExp(loc, creall(c), type); 
     367    else if (type->isimaginary()) 
     368        e = new RealExp(loc, cimagl(c), type); 
     369    else if (type->iscomplex()) 
     370        e = new ComplexExp(loc, c, type); 
     371    else 
     372        assert(0); 
     373    } 
     374    else 
     375    { 
     376    e = new IntegerExp(loc, e1->toInteger() * e2->toInteger(), type); 
     377    } 
     378    return e; 
     379
     380 
     381Expression *Div(Type *type, Expression *e1, Expression *e2) 
     382{   Expression *e; 
     383    Loc loc = e1->loc; 
     384 
     385    if (type->isfloating()) 
     386    {   complex_t c; 
     387#ifdef IN_GCC 
     388    real_t r; 
     389#else 
     390    d_float80 r; 
     391#endif 
     392 
     393    //e1->type->print(); 
     394    //e2->type->print(); 
     395    if (e2->type->isreal()) 
     396    { 
     397        if (e1->type->isreal()) 
     398        { 
     399        e = new RealExp(loc, e1->toReal() / e2->toReal(), type); 
     400        return e; 
     401        } 
     402#if __DMC__ 
     403        //r = e2->toReal(); 
     404        //c = e1->toComplex(); 
     405        //printf("(%Lg + %Lgi) / %Lg\n", creall(c), cimagl(c), r); 
     406 
     407        c = e1->toComplex() / e2->toReal(); 
     408#else 
     409        r = e2->toReal(); 
     410        c = e1->toComplex(); 
     411        c = complex_t(creall(c) / r, cimagl(c) / r); 
     412#endif 
     413    } 
     414    else if (e2->type->isimaginary()) 
     415    { 
     416#if __DMC__ 
     417        //r = e2->toImaginary(); 
     418        //c = e1->toComplex(); 
     419        //printf("(%Lg + %Lgi) / %Lgi\n", creall(c), cimagl(c), r); 
     420 
     421        c = e1->toComplex() / (e2->toImaginary() * I); 
     422#else 
     423        r = e2->toImaginary(); 
     424        c = e1->toComplex(); 
     425        c = complex_t(cimagl(c) / r, -creall(c) / r); 
     426#endif 
     427    } 
     428    else 
     429    { 
     430        c = e1->toComplex() / e2->toComplex(); 
     431    } 
     432 
     433    if (type->isreal()) 
     434        e = new RealExp(loc, creall(c), type); 
     435    else if (type->isimaginary()) 
     436        e = new RealExp(loc, cimagl(c), type); 
     437    else if (type->iscomplex()) 
     438        e = new ComplexExp(loc, c, type); 
     439    else 
     440        assert(0); 
     441    } 
     442    else 
     443    {   sinteger_t n1; 
     444    sinteger_t n2; 
     445    sinteger_t n; 
     446 
     447    n1 = e1->toInteger(); 
     448    n2 = e2->toInteger(); 
     449    if (n2 == 0) 
     450    {   error("divide by 0"); 
     451        e2 = new IntegerExp(0, 1, e2->type); 
     452        n2 = 1; 
     453    } 
     454    if (e1->type->isunsigned() || e2->type->isunsigned()) 
     455        n = ((d_uns64) n1) / ((d_uns64) n2); 
     456    else 
     457        n = n1 / n2; 
     458    e = new IntegerExp(loc, n, type); 
     459    } 
     460    return e; 
     461
     462 
     463Expression *Mod(Type *type, Expression *e1, Expression *e2) 
     464{   Expression *e; 
     465    Loc loc = e1->loc; 
     466 
     467    if (type->isfloating()) 
     468    { 
     469    complex_t c; 
     470 
     471    if (e2->type->isreal()) 
     472    {   real_t r2 = e2->toReal(); 
     473 
     474#ifdef __DMC__ 
     475        c = fmodl(e1->toReal(), r2) + fmodl(e1->toImaginary(), r2) * I; 
     476#elif defined(IN_GCC) 
     477        c = complex_t(e1->toReal() % r2, e1->toImaginary() % r2); 
     478#else 
     479        c = complex_t(fmodl(e1->toReal(), r2), fmodl(e1->toImaginary(), r2)); 
     480#endif 
     481    } 
     482    else if (e2->type->isimaginary()) 
     483    {   real_t i2 = e2->toImaginary(); 
     484 
     485#ifdef __DMC__ 
     486        c = fmodl(e1->toReal(), i2) + fmodl(e1->toImaginary(), i2) * I; 
     487#elif defined(IN_GCC) 
     488        c = complex_t(e1->toReal() % i2, e1->toImaginary() % i2); 
     489#else 
     490        c = complex_t(fmodl(e1->toReal(), i2), fmodl(e1->toImaginary(), i2)); 
     491#endif 
     492    } 
     493    else 
     494        assert(0); 
     495 
     496    if (type->isreal()) 
     497        e = new RealExp(loc, creall(c), type); 
     498    else if (type->isimaginary()) 
     499        e = new RealExp(loc, cimagl(c), type); 
     500    else if (type->iscomplex()) 
     501        e = new ComplexExp(loc, c, type); 
     502    else 
     503        assert(0); 
     504    } 
     505    else 
     506    {   sinteger_t n1; 
     507    sinteger_t n2; 
     508    sinteger_t n; 
     509 
     510    n1 = e1->toInteger(); 
     511    n2 = e2->toInteger(); 
     512    if (n2 == 0) 
     513    {   error("divide by 0"); 
     514        e2 = new IntegerExp(0, 1, e2->type); 
     515        n2 = 1; 
     516    } 
     517    if (e1->type->isunsigned() || e2->type->isunsigned()) 
     518        n = ((d_uns64) n1) % ((d_uns64) n2); 
     519    else 
     520        n = n1 % n2; 
     521    e = new IntegerExp(loc, n, type); 
     522    } 
     523    return e; 
     524
     525 
     526Expression *Shl(Type *type, Expression *e1, Expression *e2) 
     527{   Expression *e; 
     528    Loc loc = e1->loc; 
     529 
     530    e = new IntegerExp(loc, e1->toInteger() << e2->toInteger(), type); 
     531    return e; 
     532
     533 
     534Expression *Shr(Type *type, Expression *e1, Expression *e2) 
     535{   Expression *e; 
     536    Loc loc = e1->loc; 
     537    unsigned count; 
     538    integer_t value; 
     539 
     540    value = e1->toInteger(); 
     541    count = e2->toInteger(); 
     542    switch (e1->type->toBasetype()->ty) 
     543    { 
     544    case Tint8: 
     545        value = (d_int8)(value) >> count; 
     546        break; 
     547 
     548    case Tuns8: 
     549        value = (d_uns8)(value) >> count; 
     550        break; 
     551 
     552    case Tint16: 
     553        value = (d_int16)(value) >> count; 
     554        break; 
     555 
     556    case Tuns16: 
     557        value = (d_uns16)(value) >> count; 
     558        break; 
     559 
     560    case Tint32: 
     561        value = (d_int32)(value) >> count; 
     562        break; 
     563 
     564    case Tuns32: 
     565        value = (d_uns32)(value) >> count; 
     566        break; 
     567 
     568    case Tint64: 
     569        value = (d_int64)(value) >> count; 
     570        break; 
     571 
     572    case Tuns64: 
     573        value = (d_uns64)(value) >> count; 
     574        break; 
     575 
     576    default: 
     577        assert(0); 
     578    } 
     579    e = new IntegerExp(loc, value, type); 
     580    return e; 
     581
     582 
     583Expression *Ushr(Type *type, Expression *e1, Expression *e2) 
     584{   Expression *e; 
     585    Loc loc = e1->loc; 
     586    unsigned count; 
     587    integer_t value; 
     588 
     589    value = e1->toInteger(); 
     590    count = e2->toInteger(); 
     591    switch (e1->type->toBasetype()->ty) 
     592    { 
     593    case Tint8: 
     594    case Tuns8: 
     595        assert(0);      // no way to trigger this 
     596        value = (value & 0xFF) >> count; 
     597        break; 
     598 
     599    case Tint16: 
     600    case Tuns16: 
     601        assert(0);      // no way to trigger this 
     602        value = (value & 0xFFFF) >> count; 
     603        break; 
     604 
     605    case Tint32: 
     606    case Tuns32: 
     607        value = (value & 0xFFFFFFFF) >> count; 
     608        break; 
     609 
     610    case Tint64: 
     611    case Tuns64: 
     612        value = (d_uns64)(value) >> count; 
     613        break; 
     614 
     615    default: 
     616        assert(0); 
     617    } 
     618    e = new IntegerExp(loc, value, type); 
     619    return e; 
     620
     621 
     622Expression *And(Type *type, Expression *e1, Expression *e2) 
     623{   Expression *e; 
     624    Loc loc = e1->loc; 
     625 
     626    e = new IntegerExp(loc, e1->toInteger() & e2->toInteger(), type); 
     627    return e; 
     628
     629 
     630Expression *Or(Type *type, Expression *e1, Expression *e2) 
     631{   Expression *e; 
     632    Loc loc = e1->loc; 
     633 
     634    e = new IntegerExp(loc, e1->toInteger() | e2->toInteger(), type); 
     635    return e; 
     636
     637 
     638Expression *Xor(Type *type, Expression *e1, Expression *e2) 
     639{   Expression *e; 
     640    Loc loc = e1->loc; 
     641 
     642    e = new IntegerExp(loc, e1->toInteger() ^ e2->toInteger(), type); 
     643    return e; 
     644
     645 
     646/* Also returns EXP_CANT_INTERPRET if cannot be computed. 
     647 */ 
     648Expression *Equal(enum TOK op, Type *type, Expression *e1, Expression *e2) 
     649{   Expression *e; 
     650    Loc loc = e1->loc; 
     651    int cmp; 
     652    real_t r1; 
     653    real_t r2; 
     654 
     655    assert(op == TOKequal || op == TOKnotequal); 
     656 
     657    if (e1->op == TOKstring && e2->op == TOKstring) 
     658    {   StringExp *es1 = (StringExp *)e1; 
     659    StringExp *es2 = (StringExp *)e2; 
     660 
     661    assert(es1->sz == es2->sz); 
     662    if (es1->len == es2->len && 
     663        memcmp(es1->string, es2->string, es1->sz * es1->len) == 0) 
     664        cmp = 1; 
     665    else 
     666        cmp = 0; 
     667    } 
     668    else if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral) 
     669    {   ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; 
     670    ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; 
     671 
     672    if ((!es1->elements || !es1->elements->dim) && 
     673        (!es2->elements || !es2->elements->dim)) 
     674        cmp = 1;        // both arrays are empty 
     675    else if (!es1->elements || !es2->elements) 
     676        cmp = 0; 
     677    else if (es1->elements->dim != es2->elements->dim) 
     678        cmp = 0; 
     679    else 
     680    { 
     681        for (size_t i = 0; i < es1->elements->dim; i++) 
     682        {   Expression *ee1 = (Expression *)es1->elements->data[i]; 
     683        Expression *ee2 = (Expression *)es2->elements->data[i]; 
     684 
     685        Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2); 
     686        if (v == EXP_CANT_INTERPRET) 
     687            return EXP_CANT_INTERPRET; 
     688        cmp = v->toInteger(); 
     689        if (cmp == 0) 
     690            break; 
     691        } 
     692    } 
     693    } 
     694#if 0 // Should handle this 
     695    else if (e1->op == TOKarrayliteral && e2->op == TOKstring) 
     696    { 
     697    } 
     698#endif 
     699    else if (e1->isConst() != 1 || e2->isConst() != 1) 
     700    return EXP_CANT_INTERPRET; 
     701    else if (e1->type->isreal()) 
     702    { 
     703    r1 = e1->toReal(); 
     704    r2 = e2->toReal(); 
     705    goto L1; 
     706    } 
     707    else if (e1->type->isimaginary()) 
     708    { 
     709    r1 = e1->toImaginary(); 
     710    r2 = e2->toImaginary(); 
     711     L1: 
     712#if __DMC__ 
     713    cmp = (r1 == r2); 
     714#else 
     715    if (isnan(r1) || isnan(r2)) // if unordered 
     716    { 
     717        cmp = 0; 
     718    } 
     719    else 
     720    { 
     721        cmp = (r1 == r2); 
     722    } 
     723#endif 
     724    } 
     725    else if (e1->type->iscomplex()) 
     726    { 
     727    cmp = e1->toComplex() == e2->toComplex(); 
     728    } 
     729    else if (e1->type->isintegral()) 
     730    { 
     731    cmp = (e1->toInteger() == e2->toInteger()); 
     732    } 
     733    else 
     734    return EXP_CANT_INTERPRET; 
     735    if (op == TOKnotequal) 
     736    cmp ^= 1; 
     737    e = new IntegerExp(loc, cmp, type); 
     738    return e; 
     739
     740 
     741Expression *Identity(enum TOK op, Type *type, Expression *e1, Expression *e2) 
     742{   Expression *e; 
     743    Loc loc = e1->loc; 
     744    int cmp; 
     745 
     746    if (e1->op == TOKsymoff && e2->op == TOKsymoff) 
     747    { 
     748    SymOffExp *es1 = (SymOffExp *)e1; 
     749    SymOffExp *es2 = (SymOffExp *)e2; 
     750 
     751    cmp = (es1->var == es2->var && es1->offset == es2->offset); 
     752    } 
     753    else if (e1->isConst() == 1 && e2->isConst() == 1) 
     754    return Equal((op == TOKidentity) ? TOKequal : TOKnotequal, 
     755        type, e1, e2); 
     756    else 
     757    assert(0); 
     758    if (op == TOKnotidentity) 
     759    cmp ^= 1; 
     760    return new IntegerExp(loc, cmp, type); 
     761
     762 
     763 
     764Expression *Cmp(enum TOK op, Type *type, Expression *e1, Expression *e2) 
     765{   Expression *e; 
     766    Loc loc = e1->loc; 
     767    integer_t n; 
     768    real_t r1; 
     769    real_t r2; 
     770 
     771    if (e1->type->isreal()) 
     772    { 
     773    r1 = e1->toReal(); 
     774    r2 = e2->toReal(); 
     775    goto L1; 
     776    } 
     777    else if (e1->type->isimaginary()) 
     778    { 
     779    r1 = e1->toImaginary(); 
     780    r2 = e2->toImaginary(); 
     781     L1: 
     782#if __DMC__ 
     783    // DMC is the only compiler I know of that handles NAN arguments 
     784    // correctly in comparisons. 
     785    switch (op) 
     786    { 
     787        case TOKlt:    n = r1 <  r2;    break; 
     788        case TOKle:    n = r1 <= r2;    break; 
     789        case TOKgt:    n = r1 >  r2;    break; 
     790        case TOKge:    n = r1 >= r2;    break; 
     791 
     792        case TOKleg:   n = r1 <>=  r2;  break; 
     793        case TOKlg:    n = r1 <>   r2;  break; 
     794        case TOKunord: n = r1 !<>= r2;  break; 
     795        case TOKue:    n = r1 !<>  r2;  break; 
     796        case TOKug:    n = r1 !<=  r2;  break; 
     797        case TOKuge:   n = r1 !<   r2;  break; 
     798        case TOKul:    n = r1 !>=  r2;  break; 
     799        case TOKule:   n = r1 !>   r2;  break; 
     800 
     801        default: 
     802        assert(0); 
     803    } 
     804#else 
     805    // Don't rely on compiler, handle NAN arguments separately 
     806#if IN_GCC 
     807    if (real_isnan(&r1) || real_isnan(&r2)) // if unordered 
     808#else 
     809    if (isnan(r1) || isnan(r2)) // if unordered 
     810#endif 
     811    { 
     812        switch (op) 
     813        { 
     814        case TOKlt: n = 0;  break; 
     815        case TOKle: n = 0;  break; 
     816        case TOKgt: n = 0;  break; 
     817        case TOKge: n = 0;  break; 
     818 
     819        case TOKleg:    n = 0;  break; 
     820        case TOKlg: n = 0;  break; 
     821        case TOKunord:  n = 1;  break; 
     822        case TOKue: n = 1;  break; 
     823        case TOKug: n = 1;  break; 
     824        case TOKuge:    n = 1;  break; 
     825        case TOKul: n = 1;  break; 
     826        case TOKule:    n = 1;  break; 
     827 
     828        default: 
     829            assert(0); 
     830        } 
     831    } 
     832    else 
     833    { 
     834        switch (op) 
     835        { 
     836        case TOKlt: n = r1 <  r2;   break; 
     837        case TOKle: n = r1 <= r2;   break; 
     838        case TOKgt: n = r1 >  r2;   break; 
     839        case TOKge: n = r1 >= r2;   break; 
     840 
     841        case TOKleg:    n = 1;      break; 
     842        case TOKlg: n = r1 != r2;   break; 
     843        case TOKunord:  n = 0;      break; 
     844        case TOKue: n = r1 == r2;   break; 
     845        case TOKug: n = r1 >  r2;   break; 
     846        case TOKuge:    n = r1 >= r2;   break; 
     847        case TOKul: n = r1 <  r2;   break; 
     848        case TOKule:    n = r1 <= r2;   break; 
     849 
     850        default: 
     851            assert(0); 
     852        } 
     853    } 
     854#endif 
     855    } 
     856    else if (e1->type->iscomplex()) 
     857    { 
     858    assert(0); 
     859    } 
     860    else 
     861    {   sinteger_t n1; 
     862    sinteger_t n2; 
     863 
     864    n1 = e1->toInteger(); 
     865    n2 = e2->toInteger(); 
     866    if (e1->type->isunsigned() || e2->type->isunsigned()) 
     867    { 
     868        switch (op) 
     869        { 
     870        case TOKlt: n = ((d_uns64) n1) <  ((d_uns64) n2);   break; 
     871        case TOKle: n = ((d_uns64) n1) <= ((d_uns64) n2);   break; 
     872        case TOKgt: n = ((d_uns64) n1) >  ((d_uns64) n2);   break; 
     873        case TOKge: n = ((d_uns64) n1) >= ((d_uns64) n2);   break; 
     874 
     875        case TOKleg:    n = 1;                  break; 
     876        case TOKlg: n = ((d_uns64) n1) != ((d_uns64) n2);   break; 
     877        case TOKunord:  n = 0;                  break; 
     878        case TOKue: n = ((d_uns64) n1) == ((d_uns64) n2);   break; 
     879        case TOKug: n = ((d_uns64) n1) >  ((d_uns64) n2);   break; 
     880        case TOKuge:    n = ((d_uns64) n1) >= ((d_uns64) n2);   break; 
     881        case TOKul: n = ((d_uns64) n1) <  ((d_uns64) n2);   break; 
     882        case TOKule:    n = ((d_uns64) n1) <= ((d_uns64) n2);   break; 
     883 
     884        default: 
     885            assert(0); 
     886        } 
     887    } 
     888    else 
     889    { 
     890        switch (op) 
     891        { 
     892        case TOKlt: n = n1 <  n2;   break; 
     893        case TOKle: n = n1 <= n2;   break; 
     894        case TOKgt: n = n1 >  n2;   break; 
     895        case TOKge: n = n1 >= n2;   break; 
     896 
     897        case TOKleg:    n = 1;      break; 
     898        case TOKlg: n = n1 != n2;   break; 
     899        case TOKunord:  n = 0;      break; 
     900        case TOKue: n = n1 == n2;   break; 
     901        case TOKug: n = n1 >  n2;   break; 
     902        case TOKuge:    n = n1 >= n2;   break; 
     903        case TOKul: n = n1 <  n2;   break; 
     904        case TOKule:    n = n1 <= n2;   break; 
     905 
     906        default: 
     907            assert(0); 
     908        } 
     909    } 
     910    } 
     911    e = new IntegerExp(loc, n, type); 
     912    return e; 
     913
     914 
     915/* Also returns EXP_CANT_INTERPRET if cannot be computed. 
     916 *  to: type to cast to 
     917 *  type: type to paint the result 
     918 */ 
     919 
     920Expression *Cast(Type *type, Type *to, Expression *e1) 
     921{   Expression *e = EXP_CANT_INTERPRET; 
     922    Loc loc = e1->loc; 
     923 
     924    //printf("Cast(type = %s, to = %s, e1 = %s)\n", type->toChars(), to->toChars(), e1->toChars()); 
     925    //printf("e1->type = %s\n", e1->type->toChars()); 
     926    if (type->equals(e1->type) && to->equals(type)) 
     927    return e1; 
     928 
     929    if (e1->isConst() != 1) 
     930    return EXP_CANT_INTERPRET; 
    129931 
    130932    Type *tb = to->toBasetype(); 
    131     if (tb->ty == Tbit || tb->ty == Tbool) 
    132     return new IntegerExp(loc, e1->toInteger() != 0, type); 
    133     if (type->isintegral()) 
     933    if (tb->ty == Tbool) 
     934    e = new IntegerExp(loc, e1->toInteger() != 0, type); 
     935    else if (type->isintegral()) 
    134936    { 
    135937    if (e1->type->isfloating()) 
     
    154956        } 
    155957 
    156         return new IntegerExp(loc, result, type); 
    157     } 
    158     if (type->isunsigned()) 
    159         return new IntegerExp(loc, e1->toUInteger(), type); 
    160     else 
    161         return new IntegerExp(loc, e1->toInteger(), type); 
    162     } 
    163     if (tb->isreal()) 
    164     {   real_t value = e1->toReal(); 
    165  
    166     return new RealExp(loc, value, type); 
    167     } 
    168     if (tb->isimaginary()) 
    169     {   real_t value = e1->toImaginary(); 
    170  
    171     return new RealExp(loc, value, type); 
    172     } 
    173     if (tb->iscomplex()) 
    174     {   complex_t value = e1->toComplex(); 
    175  
    176     return new ComplexExp(loc, value, type); 
    177     } 
    178     if (tb->isscalar()) 
    179     return new IntegerExp(loc, e1->toInteger(), type); 
    180     if (tb->ty != Tvoid) 
    181     error("cannot cast %s to %s", e1->type->toChars(), to->toChars()); 
    182     return this; 
    183 
    184  
    185 Expression *AddExp::constFold() 
    186 
    187     Expression *e; 
    188  
    189     //printf("AddExp::constFold(%s)\n", toChars()); 
    190     e1 = e1->constFold(); 
    191     e2 = e2->constFold(); 
    192     if (e1->op == TOKsymoff && e2->op == TOKsymoff) 
    193     return this; 
    194     if (type->isreal()) 
    195     { 
    196     e = new RealExp(loc, e1->toReal() + e2->toReal(), type); 
    197     } 
    198     else if (type->isimaginary()) 
    199     { 
    200     e = new RealExp(loc, e1->toImaginary() + e2->toImaginary(), type); 
    201     } 
    202     else if (type->iscomplex()) 
    203     { 
    204     // This rigamarole is necessary so that -0.0 doesn't get 
    205     // converted to +0.0 by doing an extraneous add with +0.0 
    206     complex_t c1; 
    207     real_t r1; 
    208     real_t i1; 
    209  
    210     complex_t c2; 
    211     real_t r2; 
    212     real_t i2; 
    213  
    214     complex_t v; 
    215     int x; 
    216  
    217     if (e1->type->isreal()) 
    218     {   r1 = e1->toReal(); 
    219         x = 0; 
    220     } 
    221     else if (e1->type->isimaginary()) 
    222     {   i1 = e1->toImaginary(); 
    223         x = 3; 
    224     } 
    225     else 
    226     {   c1 = e1->toComplex(); 
    227         x = 6; 
    228     } 
    229  
    230     if (e2->type->isreal()) 
    231     {   r2 = e2->toReal(); 
    232     } 
    233     else if (e2->type->isimaginary()) 
    234     {   i2 = e2->toImaginary(); 
    235         x += 1; 
    236     } 
    237     else 
    238     {   c2 = e2->toComplex(); 
    239         x += 2; 
    240     } 
    241  
    242     switch (x) 
    243     { 
    244 #if __DMC__ 
    245         case 0+0:   v = (complex_t) (r1 + r2);  break; 
    246         case 0+1:   v = r1 + i2 * I;        break; 
    247         case 0+2:   v = r1 + c2;            break; 
    248         case 3+0:   v = i1 * I + r2;        break; 
    249         case 3+1:   v = (complex_t) ((i1 + i2) * I); break; 
    250         case 3+2:   v = i1 * I + c2;        break; 
    251         case 6+0:   v = c1 + r2;            break; 
    252         case 6+1:   v = c1 + i2 * I;        break; 
    253         case 6+2:   v = c1 + c2;            break; 
    254 #else 
    255         case 0+0:   v = complex_t(r1 + r2, 0);  break; 
    256         case 0+1:   v = complex_t(r1, i2);      break; 
    257         case 0+2:   v = complex_t(r1 + creall(c2), cimagl(c2)); break; 
    258         case 3+0:   v = complex_t(r2, i1);      break; 
    259         case 3+1:   v = complex_t(0, i1 + i2);  break; 
    260         case 3+2:   v = complex_t(creall(c2), i1 + cimagl(c2)); break; 
    261         case 6+0:   v = complex_t(creall(c1) + r2, cimagl(c2)); break; 
    262         case 6+1:   v = complex_t(creall(c1), cimagl(c1) + i2); break; 
    263         case 6+2:   v = c1 + c2;            break; 
    264 #endif 
    265         default: assert(0); 
    266     } 
    267     e = new ComplexExp(loc, v, type); 
    268     } 
    269     else if (e1->op == TOKsymoff) 
    270     { 
    271     SymOffExp *soe = (SymOffExp *)e1; 
    272     e = new SymOffExp(loc, soe->var, soe->offset + e2->toInteger()); 
    273     e->type = type; 
    274     } 
    275     else if (e2->op == TOKsymoff) 
    276     { 
    277     SymOffExp *soe = (SymOffExp *)e2; 
    278     e = new SymOffExp(loc, soe->var, soe->offset + e1->toInteger()); 
    279     e->type = type; 
    280     } 
     958        e = new IntegerExp(loc, result, type); 
     959    } 
     960    else if (type->isunsigned()) 
     961        e = new IntegerExp(loc, e1->toUInteger(), type); 
     962    else 
     963        e = new IntegerExp(loc, e1->toInteger(), type); 
     964    } 
     965    else if (tb->isreal()) 
     966    {   real_t value = e1->toReal(); 
     967 
     968    e = new RealExp(loc, value, type); 
     969    } 
     970    else if (tb->isimaginary()) 
     971    {   real_t value = e1->toImaginary(); 
     972 
     973    e = new RealExp(loc, value, type); 
     974    } 
     975    else if (tb->iscomplex()) 
     976    {   complex_t value = e1->toComplex(); 
     977 
     978    e = new ComplexExp(loc, value, type); 
     979    } 
     980    else if (tb->isscalar()) 
     981    e = new IntegerExp(loc, e1->toInteger(), type);