Ejemplo n.º 1
0
Expression *ArrayExp::op_overload(Scope *sc)
{
    //printf("ArrayExp::op_overload() (%s)\n", toChars());
    AggregateDeclaration *ad = isAggregate(e1->type);
    if (ad)
    {
        Dsymbol *fd = search_function(ad, opId());
        if (fd)
        {
            for (size_t i = 0; i < arguments->dim; i++)
            {   Expression *x = arguments->tdata()[i];
                // Create scope for '$' variable for this dimension
                ArrayScopeSymbol *sym = new ArrayScopeSymbol(sc, this);
                sym->loc = loc;
                sym->parent = sc->scopesym;
                sc = sc->push(sym);
                lengthVar = NULL;       // Create it only if required
                currentDimension = i;   // Dimension for $, if required

                x = x->semantic(sc);
                x = resolveProperties(sc, x);
                if (!x->type)
                    error("%s has no value", x->toChars());
                if (lengthVar)
                {   // If $ was used, declare it now
                    Expression *av = new DeclarationExp(loc, lengthVar);
                    x = new CommaExp(0, av, x);
                    x->semantic(sc);
                }
                arguments->tdata()[i] = x;
                sc = sc->pop();
            }

            /* Rewrite op e1[arguments] as:
             *    e1.opIndex(arguments)
             */
            Expression *e = new DotIdExp(loc, e1, fd->ident);
            e = new CallExp(loc, e, arguments);
            e = e->semantic(sc);
            return e;
        }

        // Didn't find it. Forward to aliasthis
        if (ad->aliasthis)
        {
            /* Rewrite op(e1) as:
             *  op(e1.aliasthis)
             */
            UnaExp *e = (UnaExp *)syntaxCopy();
            e->e1 = new DotIdExp(loc, e->e1, ad->aliasthis->ident);
            return e->trySemantic(sc);
        }
    }
    return NULL;
}
Ejemplo n.º 2
0
/***********************************************
 * This is mostly the same as UnaryExp::op_overload(), but has
 * a different rewrite.
 */
Expression *CastExp::op_overload(Scope *sc)
{
    //printf("CastExp::op_overload() (%s)\n", toChars());
    AggregateDeclaration *ad = isAggregate(e1->type);
    if (ad)
    {
        Dsymbol *fd = NULL;
        /* Rewrite as:
         *      e1.opCast!(T)();
         */
        fd = search_function(ad, Id::cast);
        if (fd)
        {
#if 1 // Backwards compatibility with D1 if opCast is a function, not a template
            if (fd->isFuncDeclaration())
            {   // Rewrite as:  e1.opCast()
                return build_overload(loc, sc, e1, NULL, fd);
            }
#endif
            Objects *targsi = new Objects();
            targsi->push(to);
            Expression *e = new DotTemplateInstanceExp(loc, e1, fd->ident, targsi);
            e = new CallExp(loc, e);
            e = e->semantic(sc);
            return e;
        }

        // Didn't find it. Forward to aliasthis
        if (ad->aliasthis)
        {
            /* Rewrite op(e1) as:
             *  op(e1.aliasthis)
             */
            UnaExp *e = (UnaExp *)syntaxCopy();
            e->e1 = new DotIdExp(loc, e->e1, ad->aliasthis->ident);
            return e->trySemantic(sc);
        }
    }
    return NULL;
}
Ejemplo n.º 3
0
Archivo: opover.c Proyecto: Nishi/dmd
Expression *ArrayExp::op_overload(Scope *sc)
{
    //printf("ArrayExp::op_overload() (%s)\n", toChars());
    AggregateDeclaration *ad = isAggregate(e1->type);
    if (ad)
    {
        Dsymbol *fd = search_function(ad, opId());
        if (fd)
        {
            /* Rewrite op e1[arguments] as:
             *    e1.opIndex(arguments)
             */
            Expression *e0 = resolveOpDollar(sc, this);
            Expression *e = new DotIdExp(loc, e1, fd->ident);
            e = new CallExp(loc, e, arguments);
            e = combine(e0, e);
            e = e->semantic(sc);
            return e;
        }

        // Didn't find it. Forward to aliasthis
        if (ad->aliasthis && this->e1->type != att1)
        {
            /* Rewrite op(e1) as:
             *  op(e1.aliasthis)
             */
            //printf("att arr e1 = %s\n", this->e1->type->toChars());
            Expression *e1 = new DotIdExp(loc, this->e1, ad->aliasthis->ident);
            UnaExp *ue = (UnaExp *)copy();
            if (!ue->att1 && this->e1->type->checkAliasThisRec())
                ue->att1 = this->e1->type;
            ue->e1 = e1;
            return ue->trySemantic(sc);
        }
    }
    return NULL;
}
Ejemplo n.º 4
0
Archivo: opover.c Proyecto: alexrp/dmd
Expression *UnaExp::op_overload(Scope *sc)
{
    //printf("UnaExp::op_overload() (%s)\n", toChars());

#if DMDV2
    if (e1->op == TOKarray)
    {
        ArrayExp *ae = (ArrayExp *)e1;
        ae->e1 = ae->e1->semantic(sc);
        ae->e1 = resolveProperties(sc, ae->e1);

        AggregateDeclaration *ad = isAggregate(ae->e1->type);
        if (ad)
        {
            /* Rewrite as:
             *  a.opIndexUnary!("+")(args);
             */
            Dsymbol *fd = search_function(ad, Id::opIndexUnary);
            if (fd)
            {
                ae = resolveOpDollar(sc, ae);
                Objects *tiargs = opToArg(sc, op);
                Expression *e = new DotTemplateInstanceExp(loc, ae->e1, fd->ident, tiargs);
                e = new CallExp(loc, e, ae->arguments);
                e = e->semantic(sc);
                return e;
            }

            // Didn't find it. Forward to aliasthis
            if (ad->aliasthis && ae->e1->type != att1)
            {
                /* Rewrite op(a[arguments]) as:
                 *      op(a.aliasthis[arguments])
                 */
                Expression *e1 = ae->copy();
                ((ArrayExp *)e1)->e1 = new DotIdExp(loc, ae->e1, ad->aliasthis->ident);
                UnaExp *ue = (UnaExp *)copy();
                if (!ue->att1 && ae->e1->type->checkAliasThisRec())
                    ue->att1 = ae->e1->type;
                ue->e1 = e1;
                if (Expression *e = ue->trySemantic(sc))
                    return e;
            }
            att1 = NULL;
        }
    }
    else if (e1->op == TOKslice)
    {
        SliceExp *se = (SliceExp *)e1;
        se->e1 = se->e1->semantic(sc);
        se->e1 = resolveProperties(sc, se->e1);

        AggregateDeclaration *ad = isAggregate(se->e1->type);
        if (ad)
        {
            /* Rewrite as:
             *  a.opSliceUnary!("+")(lwr, upr);
             */
            Dsymbol *fd = search_function(ad, Id::opSliceUnary);
            if (fd)
            {
                se = resolveOpDollar(sc, se);
                Expressions *a = new Expressions();
                assert(!se->lwr || se->upr);
                if (se->lwr)
                {   a->push(se->lwr);
                    a->push(se->upr);
                }
                Objects *tiargs = opToArg(sc, op);
                Expression *e = new DotTemplateInstanceExp(loc, se->e1, fd->ident, tiargs);
                e = new CallExp(loc, e, a);
                e = e->semantic(sc);
                return e;
            }

            // Didn't find it. Forward to aliasthis
            if (ad->aliasthis && se->e1->type != att1)
            {
                /* Rewrite op(a[lwr..upr]) as:
                 *      op(a.aliasthis[lwr..upr])
                 */
                Expression *e1 = se->copy();
                ((SliceExp *)e1)->e1 = new DotIdExp(loc, se->e1, ad->aliasthis->ident);
                UnaExp *ue = (UnaExp *)copy();
                if (!ue->att1 && se->e1->type->checkAliasThisRec())
                    ue->att1 = se->e1->type;
                ue->e1 = e1;
                if (Expression *e = ue->trySemantic(sc))
                    return e;
            }
            att1 = NULL;
        }
    }
#endif

    e1 = e1->semantic(sc);
    e1 = resolveProperties(sc, e1);

    AggregateDeclaration *ad = isAggregate(e1->type);
    if (ad)
    {
        Dsymbol *fd = NULL;
#if 1 // Old way, kept for compatibility with D1
        if (op != TOKpreplusplus && op != TOKpreminusminus)
        {   fd = search_function(ad, opId());
            if (fd)
            {
                if (op == TOKarray)
                {
                    /* Rewrite op e1[arguments] as:
                     *    e1.fd(arguments)
                     */
                    Expression *e = new DotIdExp(loc, e1, fd->ident);
                    ArrayExp *ae = (ArrayExp *)this;
                    e = new CallExp(loc, e, ae->arguments);
                    e = e->semantic(sc);
                    return e;
                }
                else
                {
                    // Rewrite +e1 as e1.add()
                    return build_overload(loc, sc, e1, NULL, fd);
                }
            }
        }
#endif

#if DMDV2
        /* Rewrite as:
         *      e1.opUnary!("+")();
         */
        fd = search_function(ad, Id::opUnary);
        if (fd)
        {
            Objects *tiargs = opToArg(sc, op);
            Expression *e = new DotTemplateInstanceExp(loc, e1, fd->ident, tiargs);
            e = new CallExp(loc, e);
            e = e->semantic(sc);
            return e;
        }

        // Didn't find it. Forward to aliasthis
        if (ad->aliasthis && this->e1->type != att1)
        {
            /* Rewrite op(e1) as:
             *  op(e1.aliasthis)
             */
            //printf("att una %s e1 = %s\n", Token::toChars(op), this->e1->type->toChars());
            Expression *e1 = new DotIdExp(loc, this->e1, ad->aliasthis->ident);
            UnaExp *ue = (UnaExp *)copy();
            if (!ue->att1 && this->e1->type->checkAliasThisRec())
                ue->att1 = this->e1->type;
            ue->e1 = e1;
            return ue->trySemantic(sc);
        }
#endif
    }
    return NULL;
}