Skip to content

Commit

Permalink
bugzilla 111
Browse files Browse the repository at this point in the history
  • Loading branch information
Walter Bright committed Nov 18, 2009
1 parent ad62c01 commit a5fcce1
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 26 deletions.
2 changes: 2 additions & 0 deletions src/backend/rtlsym.h
Expand Up @@ -93,6 +93,8 @@ SYMBOL_MARS(ARRAYCATT, FLfunc,FREGSAVED,"_d_arraycatT", 0, t) \
SYMBOL_MARS(ARRAYCATNT, FLfunc,FREGSAVED,"_d_arraycatnT", 0, t) \
SYMBOL_MARS(ARRAYAPPENDT, FLfunc,FREGSAVED,"_d_arrayappendT", 0, t) \
SYMBOL_MARS(ARRAYAPPENDCT, FLfunc,FREGSAVED,"_d_arrayappendcT", 0, t) \
SYMBOL_MARS(ARRAYAPPENDCD, FLfunc,FREGSAVED,"_d_arrayappendcd", 0, t) \
SYMBOL_MARS(ARRAYAPPENDWD, FLfunc,FREGSAVED,"_d_arrayappendwd", 0, t) \
SYMBOL_MARS(ARRAYSETLENGTHT,FLfunc,FREGSAVED,"_d_arraysetlengthT", 0, t) \
SYMBOL_MARS(ARRAYSETLENGTHIT,FLfunc,FREGSAVED,"_d_arraysetlengthiT", 0, t) \
SYMBOL_MARS(ARRAYCOPY, FLfunc,FREGSAVED,"_d_arraycopy", 0, t) \
Expand Down
39 changes: 21 additions & 18 deletions src/e2ir.c
Expand Up @@ -2915,15 +2915,28 @@ elem *CatAssignExp::toElem(IRState *irs)
Type *tb1 = e1->type->toBasetype();
Type *tb2 = e2->type->toBasetype();

if (tb1->ty == Tarray || tb2->ty == Tsarray)
{ elem *e1;
elem *e2;
elem *ep;
if (tb1->ty == Tarray && tb2->ty == Tdchar &&
(tb1->nextOf()->ty == Tchar || tb1->nextOf()->ty == Twchar))
{ // Append dchar to char[] or wchar[]

elem *e1 = this->e1->toElem(irs);
e1 = el_una(OPaddr, TYnptr, e1);

elem *e2 = this->e2->toElem(irs);

e1 = this->e1->toElem(irs);
elem *ep = el_params(e2, e1, NULL);
int rtl = (tb1->nextOf()->ty == Tchar)
? RTLSYM_ARRAYAPPENDCD
: RTLSYM_ARRAYAPPENDWD;
e = el_bin(OPcall, TYdarray, el_var(rtlsym[rtl]), ep);
el_setLoc(e,loc);
}
else if (tb1->ty == Tarray || tb2->ty == Tsarray)
{
elem *e1 = this->e1->toElem(irs);
e1 = el_una(OPaddr, TYnptr, e1);

e2 = this->e2->toElem(irs);
elem *e2 = this->e2->toElem(irs);
if (tybasic(e2->Ety) == TYstruct || tybasic(e2->Ety) == TYarray)
{
e2 = el_una(OPstrpar, TYstruct, e2);
Expand All @@ -2935,23 +2948,13 @@ elem *CatAssignExp::toElem(IRState *irs)
if ((tb2->ty == Tarray || tb2->ty == Tsarray) &&
tb1n->equals(tb2->nextOf()->toBasetype()))
{ // Append array
#if 1
ep = el_params(e2, e1, this->e1->type->getTypeInfo(NULL)->toElem(irs), NULL);
elem *ep = el_params(e2, e1, this->e1->type->getTypeInfo(NULL)->toElem(irs), NULL);
e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPENDT]), ep);
#else
ep = el_params(el_long(TYint, tb1n->size()), e2, e1, NULL);
e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPEND]), ep);
#endif
}
else
{ // Append element
#if 1
ep = el_params(e2, e1, this->e1->type->getTypeInfo(NULL)->toElem(irs), NULL);
elem *ep = el_params(e2, e1, this->e1->type->getTypeInfo(NULL)->toElem(irs), NULL);
e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPENDCT]), ep);
#else
ep = el_params(e2, el_long(TYint, tb1n->size()), e1, NULL);
e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPENDC]), ep);
#endif
}
el_setLoc(e,loc);
}
Expand Down
69 changes: 61 additions & 8 deletions src/expression.c
Expand Up @@ -456,13 +456,44 @@ void expandTuples(Expressions *exps)

Expressions *arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt)
{
#if DMDV1
/* The first element sets the type
*/
Type *t0 = NULL;
for (size_t i = 0; i < exps->dim; i++)
{ Expression *e = (Expression *)exps->data[i];

if (!e->type)
{ error("%s has no value", e->toChars());
e = new ErrorExp();
}
e = resolveProperties(sc, e);

if (!t0)
t0 = e->type;
else
e = e->implicitCastTo(sc, t0);
exps->data[i] = (void *)e;
}

if (!t0)
t0 = Type::tvoid;
if (pt)
*pt = t0;

// Eventually, we want to make this copy-on-write
return exps;
#endif
#if DMDV2
/* The type is determined by applying ?: to each pair.
*/
IntegerExp integerexp(0);
CondExp condexp(0, &integerexp, NULL, NULL);

Type *t0 = NULL;
Expression *e0;
int j0;
for (int i = 0; i < exps->dim; i++)
for (size_t i = 0; i < exps->dim; i++)
{ Expression *e = (Expression *)exps->data[i];

e = resolveProperties(sc, e);
Expand Down Expand Up @@ -496,7 +527,7 @@ Expressions *arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt

if (t0)
{
for (int i = 0; i < exps->dim; i++)
for (size_t i = 0; i < exps->dim; i++)
{ Expression *e = (Expression *)exps->data[i];
e = e->implicitCastTo(sc, t0);
exps->data[i] = (void *)e;
Expand All @@ -509,6 +540,7 @@ Expressions *arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt

// Eventually, we want to make this copy-on-write
return exps;
#endif
}

/****************************************
Expand Down Expand Up @@ -8890,29 +8922,46 @@ Expression *CatAssignExp::semantic(Scope *sc)

e2->rvalue();

Type *tb1next = tb1->nextOf();

if ((tb1->ty == Tarray) &&
(tb2->ty == Tarray || tb2->ty == Tsarray) &&
(e2->implicitConvTo(e1->type) ||
tb2->nextOf()->implicitConvTo(tb1->nextOf()))
(e2->implicitConvTo(e1->type)
#if DMDV2
|| tb2->nextOf()->implicitConvTo(tb1next)
#endif
)
)
{ // Append array
e2 = e2->castTo(sc, e1->type);
type = e1->type;
e = this;
}
else if ((tb1->ty == Tarray) &&
e2->implicitConvTo(tb1->nextOf())
e2->implicitConvTo(tb1next)
)
{ // Append element
e2 = e2->castTo(sc, tb1->nextOf());
e2 = e2->castTo(sc, tb1next);
type = e1->type;
e = this;
}
else if (tb1->ty == Tarray &&
(tb1next->ty == Tchar || tb1next->ty == Twchar) &&
e2->implicitConvTo(Type::tdchar)
)
{ // Append dchar to char[] or wchar[]
e2 = e2->castTo(sc, Type::tdchar);
type = e1->type;
e = this;

/* Do not allow appending wchar to char[] because if wchar happens
* to be a surrogate pair, nothing good can result.
*/
}
else
{
error("cannot append type %s to type %s", tb2->toChars(), tb1->toChars());
type = Type::tint32;
e = this;
e = new ErrorExp();
}
return e;
}
Expand All @@ -8934,12 +8983,14 @@ Expression *MulAssignExp::semantic(Scope *sc)
if (e)
return e;

#if DMDV2
if (e1->op == TOKarraylength)
{
e = ArrayLengthExp::rewriteOpAssign(this);
e = e->semantic(sc);
return e;
}
#endif

if (e1->op == TOKslice)
{ // T[] -= ...
Expand Down Expand Up @@ -9005,12 +9056,14 @@ Expression *DivAssignExp::semantic(Scope *sc)
if (e)
return e;

#if DMDV2
if (e1->op == TOKarraylength)
{
e = ArrayLengthExp::rewriteOpAssign(this);
e = e->semantic(sc);
return e;
}
#endif

if (e1->op == TOKslice)
{ // T[] -= ...
Expand Down

0 comments on commit a5fcce1

Please sign in to comment.