Esempio n. 1
0
File: init.c Progetto: kryptonX/dmd
Expression *ArrayInitializer::toAssocArrayLiteral()
{
    Expression *e;

    //printf("ArrayInitializer::toAssocArrayInitializer()\n");
    //static int i; if (++i == 2) halt();
    Expressions *keys = new Expressions();
    keys->setDim(value.dim);
    Expressions *values = new Expressions();
    values->setDim(value.dim);

    for (size_t i = 0; i < value.dim; i++)
    {
        e = index.tdata()[i];
        if (!e)
            goto Lno;
        keys->tdata()[i] = e;

        Initializer *iz = value.tdata()[i];
        if (!iz)
            goto Lno;
        e = iz->toExpression();
        if (!e)
            goto Lno;
        values->tdata()[i] = e;
    }
    e = new AssocArrayLiteralExp(loc, keys, values);
    return e;

Lno:
    delete keys;
    delete values;
    error(loc, "not an associative array initializer");
    return new ErrorExp();
}
Esempio n. 2
0
Expressions *arrayExpressiondoInline(Expressions *a, InlineDoState *ids)
{   Expressions *newa = NULL;

    if (a)
    {
        newa = new Expressions();
        newa->setDim(a->dim);

        for (size_t i = 0; i < a->dim; i++)
        {   Expression *e = a->tdata()[i];

            if (e)
                e = e->doInline(ids);
            newa->tdata()[i] = e;
        }
    }
    return newa;
}
Esempio n. 3
0
File: init.c Progetto: smunix/ldc
Expression *ArrayInitializer::toExpression()
{   Expressions *elements;

    //printf("ArrayInitializer::toExpression(), dim = %d\n", dim);
    //static int i; if (++i == 2) halt();

    size_t edim;
    Type *t = NULL;
    if (type)
    {
        if (type == Type::terror)
            return new ErrorExp();

        t = type->toBasetype();
        switch (t->ty)
        {
           case Tsarray:
               edim = ((TypeSArray *)t)->dim->toInteger();
               break;

           case Tpointer:
           case Tarray:
               edim = dim;
               break;

           default:
               assert(0);
        }
    }
    else
    {
        edim = value.dim;
        for (size_t i = 0, j = 0; i < value.dim; i++, j++)
        {
            if (index.tdata()[i])
                j = index.tdata()[i]->toInteger();
            if (j >= edim)
                edim = j + 1;
        }
    }

    elements = new Expressions();
    elements->setDim(edim);
    elements->zero();
    for (size_t i = 0, j = 0; i < value.dim; i++, j++)
    {
        if (index.tdata()[i])
            j = (index.tdata()[i])->toInteger();
        assert(j < edim);
        Initializer *iz = value.tdata()[i];
        if (!iz)
            goto Lno;
        Expression *ex = iz->toExpression();
        if (!ex)
        {
            goto Lno;
        }
        elements->tdata()[j] = ex;
    }

    /* Fill in any missing elements with the default initializer
     */
    {
    Expression *init = NULL;
    for (size_t i = 0; i < edim; i++)
    {
        if (!elements->tdata()[i])
        {
            if (!type)
                goto Lno;
            if (!init)
                init = ((TypeNext *)t)->next->defaultInit();
            elements->tdata()[i] = init;
        }
    }

    Expression *e = new ArrayLiteralExp(loc, elements);
    e->type = type;
    return e;
    }

Lno:
    return NULL;
}
Esempio n. 4
0
File: init.c Progetto: smunix/ldc
/***************************************
 * This works by transforming a struct initializer into
 * a struct literal. In the future, the two should be the
 * same thing.
 */
Expression *StructInitializer::toExpression()
{   Expression *e;
    size_t offset;

    //printf("StructInitializer::toExpression() %s\n", toChars());
    if (!ad)                            // if fwd referenced
    {
        return NULL;
    }
    StructDeclaration *sd = ad->isStructDeclaration();
    if (!sd)
        return NULL;
    Expressions *elements = new Expressions();
    size_t nfields = ad->fields.dim;
#if DMDV2
    if (sd->isnested)
       nfields--;
#endif
    elements->setDim(nfields);
    for (size_t i = 0; i < elements->dim; i++)
    {
        elements->tdata()[i] = NULL;
    }
    unsigned fieldi = 0;
    for (size_t i = 0; i < value.dim; i++)
    {
        Identifier *id = field.tdata()[i];
        if (id)
        {
            Dsymbol * s = ad->search(loc, id, 0);
            if (!s)
            {
                error(loc, "'%s' is not a member of '%s'", id->toChars(), sd->toChars());
                goto Lno;
            }

            // Find out which field index it is
            for (fieldi = 0; 1; fieldi++)
            {
                if (fieldi >= nfields)
                {
                    s->error("is not a per-instance initializable field");
                    goto Lno;
                }
                if (s == ad->fields.tdata()[fieldi])
                    break;
            }
        }
        else if (fieldi >= nfields)
        {   error(loc, "too many initializers for '%s'", ad->toChars());
            goto Lno;
        }
        Initializer *iz = value.tdata()[i];
        if (!iz)
            goto Lno;
        Expression *ex = iz->toExpression();
        if (!ex)
            goto Lno;
        if (elements->tdata()[fieldi])
        {   error(loc, "duplicate initializer for field '%s'",
                ad->fields.tdata()[fieldi]->toChars());
            goto Lno;
        }
        elements->tdata()[fieldi] = ex;
        ++fieldi;
    }
    // Now, fill in any missing elements with default initializers.
    // We also need to validate any anonymous unions
    offset = 0;
    for (size_t i = 0; i < elements->dim; )
    {
        VarDeclaration * vd = ad->fields.tdata()[i]->isVarDeclaration();

        //printf("test2 [%d] : %s %d %d\n", i, vd->toChars(), (int)offset, (int)vd->offset);
        if (vd->offset < offset)
        {
            // Only the first field of a union can have an initializer
            if (elements->tdata()[i])
                goto Lno;
        }
        else
        {
            if (!elements->tdata()[i])
                // Default initialize
                elements->tdata()[i] = vd->type->defaultInit();
        }
        offset = vd->offset + vd->type->size();
        i++;
#if 0
        int unionSize = ad->numFieldsInUnion(i);
        if (unionSize == 1)
        {   // Not a union -- default initialize if missing
            if (!elements->tdata()[i])
                elements->tdata()[i] = vd->type->defaultInit();
        }
        else
        {   // anonymous union -- check for errors
            int found = -1; // index of the first field with an initializer
            for (int j = i; j < i + unionSize; ++j)
            {
                if (!elements->tdata()[j])
                    continue;
                if (found >= 0)
                {
                    VarDeclaration * v1 = ((Dsymbol *)ad->fields.data[found])->isVarDeclaration();
                    VarDeclaration * v = ((Dsymbol *)ad->fields.data[j])->isVarDeclaration();
                    error(loc, "%s cannot have initializers for fields %s and %s in same union",
                        ad->toChars(),
                        v1->toChars(), v->toChars());
                    goto Lno;
                }
                found = j;
            }
            if (found == -1)
            {
                error(loc, "no initializer for union that contains field %s",
                    vd->toChars());
                goto Lno;
            }
        }
        i += unionSize;
#endif
    }
    e = new StructLiteralExp(loc, sd, elements);
    e->type = sd->type;
    return e;

Lno:
    delete elements;
    return NULL;
}
Esempio n. 5
0
Expression *BinExp::arrayOp(Scope *sc)
{
    //printf("BinExp::arrayOp() %s\n", toChars());

    Type *tb = type->toBasetype();
    assert(tb->ty == Tarray || tb->ty == Tsarray);
    if (tb->nextOf()->toBasetype()->ty == Tvoid)
    {
        error("Cannot perform array operations on void[] arrays");
        return new ErrorExp();
    }

    if (!isArrayOpValid(e2))
    {
        e2->error("invalid array operation %s (did you forget a [] ?)", toChars());
        return new ErrorExp();
    }

    Expressions *arguments = new Expressions();

    /* The expression to generate an array operation for is mangled
     * into a name to use as the array operation function name.
     * Mangle in the operands and operators in RPN order, and type.
     */
    OutBuffer buf;
    buf.writestring("_array");
    buildArrayIdent(&buf, arguments);
    buf.writeByte('_');

    /* Append deco of array element type
     */
#if DMDV2
    buf.writestring(type->toBasetype()->nextOf()->toBasetype()->mutableOf()->deco);
#else
    buf.writestring(type->toBasetype()->nextOf()->toBasetype()->deco);
#endif

    size_t namelen = buf.offset;
    buf.writeByte(0);
    char *name = buf.toChars();
    Identifier *ident = Lexer::idPool(name);

    /* Look up name in hash table
     */
    FuncDeclaration **pfd = (FuncDeclaration **)_aaGet(&arrayfuncs, ident);
    FuncDeclaration *fd = (FuncDeclaration *)*pfd;
    if (!fd)
    {
        /* Some of the array op functions are written as library functions,
         * presumably to optimize them with special CPU vector instructions.
         * List those library functions here, in alpha order.
         */
        static const char *libArrayopFuncs[] =
        {
            "_arrayExpSliceAddass_a",
            "_arrayExpSliceAddass_d",           // T[]+=T
            "_arrayExpSliceAddass_f",           // T[]+=T
            "_arrayExpSliceAddass_g",
            "_arrayExpSliceAddass_h",
            "_arrayExpSliceAddass_i",
            "_arrayExpSliceAddass_k",
            "_arrayExpSliceAddass_s",
            "_arrayExpSliceAddass_t",
            "_arrayExpSliceAddass_u",
            "_arrayExpSliceAddass_w",

            "_arrayExpSliceDivass_d",           // T[]/=T
            "_arrayExpSliceDivass_f",           // T[]/=T

            "_arrayExpSliceMinSliceAssign_a",
            "_arrayExpSliceMinSliceAssign_d",   // T[]=T-T[]
            "_arrayExpSliceMinSliceAssign_f",   // T[]=T-T[]
            "_arrayExpSliceMinSliceAssign_g",
            "_arrayExpSliceMinSliceAssign_h",
            "_arrayExpSliceMinSliceAssign_i",
            "_arrayExpSliceMinSliceAssign_k",
            "_arrayExpSliceMinSliceAssign_s",
            "_arrayExpSliceMinSliceAssign_t",
            "_arrayExpSliceMinSliceAssign_u",
            "_arrayExpSliceMinSliceAssign_w",

            "_arrayExpSliceMinass_a",
            "_arrayExpSliceMinass_d",           // T[]-=T
            "_arrayExpSliceMinass_f",           // T[]-=T
            "_arrayExpSliceMinass_g",
            "_arrayExpSliceMinass_h",
            "_arrayExpSliceMinass_i",
            "_arrayExpSliceMinass_k",
            "_arrayExpSliceMinass_s",
            "_arrayExpSliceMinass_t",
            "_arrayExpSliceMinass_u",
            "_arrayExpSliceMinass_w",

            "_arrayExpSliceMulass_d",           // T[]*=T
            "_arrayExpSliceMulass_f",           // T[]*=T
            "_arrayExpSliceMulass_i",
            "_arrayExpSliceMulass_k",
            "_arrayExpSliceMulass_s",
            "_arrayExpSliceMulass_t",
            "_arrayExpSliceMulass_u",
            "_arrayExpSliceMulass_w",

            "_arraySliceExpAddSliceAssign_a",
            "_arraySliceExpAddSliceAssign_d",   // T[]=T[]+T
            "_arraySliceExpAddSliceAssign_f",   // T[]=T[]+T
            "_arraySliceExpAddSliceAssign_g",
            "_arraySliceExpAddSliceAssign_h",
            "_arraySliceExpAddSliceAssign_i",
            "_arraySliceExpAddSliceAssign_k",
            "_arraySliceExpAddSliceAssign_s",
            "_arraySliceExpAddSliceAssign_t",
            "_arraySliceExpAddSliceAssign_u",
            "_arraySliceExpAddSliceAssign_w",

            "_arraySliceExpDivSliceAssign_d",   // T[]=T[]/T
            "_arraySliceExpDivSliceAssign_f",   // T[]=T[]/T

            "_arraySliceExpMinSliceAssign_a",
            "_arraySliceExpMinSliceAssign_d",   // T[]=T[]-T
            "_arraySliceExpMinSliceAssign_f",   // T[]=T[]-T
            "_arraySliceExpMinSliceAssign_g",
            "_arraySliceExpMinSliceAssign_h",
            "_arraySliceExpMinSliceAssign_i",
            "_arraySliceExpMinSliceAssign_k",
            "_arraySliceExpMinSliceAssign_s",
            "_arraySliceExpMinSliceAssign_t",
            "_arraySliceExpMinSliceAssign_u",
            "_arraySliceExpMinSliceAssign_w",

            "_arraySliceExpMulSliceAddass_d",   // T[] += T[]*T
            "_arraySliceExpMulSliceAddass_f",
            "_arraySliceExpMulSliceAddass_r",

            "_arraySliceExpMulSliceAssign_d",   // T[]=T[]*T
            "_arraySliceExpMulSliceAssign_f",   // T[]=T[]*T
            "_arraySliceExpMulSliceAssign_i",
            "_arraySliceExpMulSliceAssign_k",
            "_arraySliceExpMulSliceAssign_s",
            "_arraySliceExpMulSliceAssign_t",
            "_arraySliceExpMulSliceAssign_u",
            "_arraySliceExpMulSliceAssign_w",

            "_arraySliceExpMulSliceMinass_d",   // T[] -= T[]*T
            "_arraySliceExpMulSliceMinass_f",
            "_arraySliceExpMulSliceMinass_r",

            "_arraySliceSliceAddSliceAssign_a",
            "_arraySliceSliceAddSliceAssign_d", // T[]=T[]+T[]
            "_arraySliceSliceAddSliceAssign_f", // T[]=T[]+T[]
            "_arraySliceSliceAddSliceAssign_g",
            "_arraySliceSliceAddSliceAssign_h",
            "_arraySliceSliceAddSliceAssign_i",
            "_arraySliceSliceAddSliceAssign_k",
            "_arraySliceSliceAddSliceAssign_r", // T[]=T[]+T[]
            "_arraySliceSliceAddSliceAssign_s",
            "_arraySliceSliceAddSliceAssign_t",
            "_arraySliceSliceAddSliceAssign_u",
            "_arraySliceSliceAddSliceAssign_w",

            "_arraySliceSliceAddass_a",
            "_arraySliceSliceAddass_d",         // T[]+=T[]
            "_arraySliceSliceAddass_f",         // T[]+=T[]
            "_arraySliceSliceAddass_g",
            "_arraySliceSliceAddass_h",
            "_arraySliceSliceAddass_i",
            "_arraySliceSliceAddass_k",
            "_arraySliceSliceAddass_s",
            "_arraySliceSliceAddass_t",
            "_arraySliceSliceAddass_u",
            "_arraySliceSliceAddass_w",

            "_arraySliceSliceMinSliceAssign_a",
            "_arraySliceSliceMinSliceAssign_d", // T[]=T[]-T[]
            "_arraySliceSliceMinSliceAssign_f", // T[]=T[]-T[]
            "_arraySliceSliceMinSliceAssign_g",
            "_arraySliceSliceMinSliceAssign_h",
            "_arraySliceSliceMinSliceAssign_i",
            "_arraySliceSliceMinSliceAssign_k",
            "_arraySliceSliceMinSliceAssign_r", // T[]=T[]-T[]
            "_arraySliceSliceMinSliceAssign_s",
            "_arraySliceSliceMinSliceAssign_t",
            "_arraySliceSliceMinSliceAssign_u",
            "_arraySliceSliceMinSliceAssign_w",

            "_arraySliceSliceMinass_a",
            "_arraySliceSliceMinass_d",         // T[]-=T[]
            "_arraySliceSliceMinass_f",         // T[]-=T[]
            "_arraySliceSliceMinass_g",
            "_arraySliceSliceMinass_h",
            "_arraySliceSliceMinass_i",
            "_arraySliceSliceMinass_k",
            "_arraySliceSliceMinass_s",
            "_arraySliceSliceMinass_t",
            "_arraySliceSliceMinass_u",
            "_arraySliceSliceMinass_w",

            "_arraySliceSliceMulSliceAssign_d", // T[]=T[]*T[]
            "_arraySliceSliceMulSliceAssign_f", // T[]=T[]*T[]
            "_arraySliceSliceMulSliceAssign_i",
            "_arraySliceSliceMulSliceAssign_k",
            "_arraySliceSliceMulSliceAssign_s",
            "_arraySliceSliceMulSliceAssign_t",
            "_arraySliceSliceMulSliceAssign_u",
            "_arraySliceSliceMulSliceAssign_w",

            "_arraySliceSliceMulass_d",         // T[]*=T[]
            "_arraySliceSliceMulass_f",         // T[]*=T[]
            "_arraySliceSliceMulass_i",
            "_arraySliceSliceMulass_k",
            "_arraySliceSliceMulass_s",
            "_arraySliceSliceMulass_t",
            "_arraySliceSliceMulass_u",
            "_arraySliceSliceMulass_w",
        };

        int i = binary(name, libArrayopFuncs, sizeof(libArrayopFuncs) / sizeof(char *));
        if (i == -1)
        {
#ifdef DEBUG    // Make sure our array is alphabetized
            for (i = 0; i < sizeof(libArrayopFuncs) / sizeof(char *); i++)
            {
                if (strcmp(name, libArrayopFuncs[i]) == 0)
                    assert(0);
            }
#endif
            /* Not in library, so generate it.
             * Construct the function body:
             *  foreach (i; 0 .. p.length)    for (size_t i = 0; i < p.length; i++)
             *      loopbody;
             *  return p;
             */

            Parameters *fparams = new Parameters();
            Expression *loopbody = buildArrayLoop(fparams);
            Parameter *p = (*fparams)[0 /*fparams->dim - 1*/];
#if DMDV1
            // for (size_t i = 0; i < p.length; i++)
            Initializer *init = new ExpInitializer(0, new IntegerExp(0, 0, Type::tsize_t));
            Dsymbol *d = new VarDeclaration(0, Type::tsize_t, Id::p, init);
            Statement *s1 = new ForStatement(0,
                new DeclarationStatement(0, d),
                new CmpExp(TOKlt, 0, new IdentifierExp(0, Id::p), new ArrayLengthExp(0, new IdentifierExp(0, p->ident))),
                new PostExp(TOKplusplus, 0, new IdentifierExp(0, Id::p)),
                new ExpStatement(0, loopbody));
#else
            // foreach (i; 0 .. p.length)
            Statement *s1 = new ForeachRangeStatement(0, TOKforeach,
                new Parameter(0, NULL, Id::p, NULL),
                new IntegerExp(0, 0, Type::tint32),
                new ArrayLengthExp(0, new IdentifierExp(0, p->ident)),
                new ExpStatement(0, loopbody));
#endif
            Statement *s2 = new ReturnStatement(0, new IdentifierExp(0, p->ident));
            //printf("s2: %s\n", s2->toChars());
            Statement *fbody = new CompoundStatement(0, s1, s2);

            /* Construct the function
             */
            TypeFunction *ftype = new TypeFunction(fparams, type, 0, LINKc);
            //printf("ftype: %s\n", ftype->toChars());
            fd = new FuncDeclaration(loc, 0, ident, STCundefined, ftype);
            fd->fbody = fbody;
            fd->protection = PROTpublic;
            fd->linkage = LINKc;
            fd->isArrayOp = 1;

            sc->module->importedFrom->members->push(fd);

            sc = sc->push();
            sc->parent = sc->module->importedFrom;
            sc->stc = 0;
            sc->linkage = LINKc;
            fd->semantic(sc);
            fd->semantic2(sc);
            fd->semantic3(sc);
            sc->pop();
        }
        else
        {   /* In library, refer to it.
             */
            fd = FuncDeclaration::genCfunc(type, ident);
#ifdef IN_GCC
            /* Setup function parameters for GCC backend
             */
            TypeFunction * tf = (TypeFunction *) fd->type;
            Parameters * targs = new Parameters;
            targs->setDim(arguments->dim);
            for (unsigned i = 0; i < arguments->dim; i++)
            {
                targs->tdata()[i] = new Parameter(STCin,
                        (arguments->tdata()[i])->type, NULL, NULL);
            }
            tf->parameters = targs;
#endif
        }
        *pfd = fd;      // cache symbol in hash table
    }

    /* Call the function fd(arguments)
     */
    Expression *ec = new VarExp(0, fd);
    Expression *e = new CallExp(loc, ec, arguments);
    e->type = type;
    return e;
}