// Generate code that initializes the elements of an array. // Expects an array ref on the top of the stack. dt_t* BackEnd::toDt(ArrayInitializer& init) { ModuleEmitter& modScope = getModuleScope(init.loc); IRState* irstate = modScope.getCurrentIRState(); if (!irstate) { fatalError(init.loc, "null IR state"); } irstate->getBlock(); VarDeclaration* varDecl = irstate->hasVarDecl(); if (!varDecl) { BackEnd::fatalError(init.loc, "initializer expects var decl"); } TYPE& type = toILType(init.loc, varDecl->type); ArrayType* aType = type.isArrayType(); if (!aType) { BackEnd::fatalError(init.loc, "initializer expects array type"); } aType->init(*irstate, *varDecl, init.dim); block& blk = irstate->getBlock(); IRState temp(blk); ArrayAdapter<Initializer*> value(init.value); ArrayAdapter<Expression*> index(init.index); // // and here's where the elements are initialized: // for (size_t i = 0; i != init.dim; ++i) { if (i >= value.size() || i >= index.size()) { assert(false); break; } if (i + 1 != init.dim) { // For each element duplicate the reference to the array // on the top of the stack, so that one is left on the stack for // the next element to use -- except when reaching the last element Instruction::create(blk, IL_dup); } #if 0 //todo:revisit, indices may be null, what are they useful for anyway? DEREF(index[i]).toElem(irstate); #else Const<int>::create(*TYPE::Int32, i, blk, init.loc); #endif auto_ptr<dt_t>(DEREF(value[i]).toDt()); ArrayElemAccess::store(blk, aType->elemTYPE()); } return NULL; }
NewArray::NewArray(const ArrayType& at) : elemTYPE_(at.elemTYPE()) { }