/*****
* newexp.cc
* Andy Hammerlindl 2003/07/28
*
* Handles the abstract syntax for expressions the create new objects,
* such as record, array, and function constructors.
*****/
types::ty *newRecordExp::transFromTyEntry(position pos, coenv &e,
trans::tyEntry *ent)
{
types::ty *t = ent->t;
if (t->kind == ty_error)
return t;
else if (t->kind != ty_record) {
em.error(pos);
em << "type '" << *t << "' is not a structure";
return primError();
}
// Put the enclosing frame on the stack.
if (!e.c.encodeParent(pos, ent)) {
em.error(pos);
em << "allocation of struct '" << *t << "' is not in a valid scope";
return primError();
}
record *r = dynamic_cast<record *>(t);
assert(r);
// Encode the allocation.
e.c.encode(inst::makefunc,r->getInit());
e.c.encode(inst::popcall);
return t;
}
types::ty *newRecordExp::trans(coenv &e)
{
return transFromTyEntry(getPos(), e, result->transAsTyEntry(e, 0));
}
void newArrayExp::prettyprint(ostream &out, Int indent)
{
prettyname(out,"newArrayExp",indent, getPos());
celltype->prettyprint(out, indent+1);
if (dimexps) dimexps->prettyprint(out, indent+1);
if (dims) dims->prettyprint(out, indent+1);
if (ai) ai->prettyprint(out, indent+1);
}
types::ty *newArrayExp::trans(coenv &e)
{
types::ty *c = celltype->trans(e);
if (c->kind == ty_void) {
em.error(getPos());
em << "cannot declare array of type void";
return primError();
}
if (dims)
c = dims->truetype(c);
if (ai) {
ai->transToType(e, c);
return c;
} else if (dimexps || dims) {
if (dimexps) {
for (size_t i = 0; i < dimexps->size(); ++i) {
(*dimexps)[i]->transToType(e, types::primInt());
c = new types::array(c);
}
}
if (dims) {
for (size_t i = 0; i < dims->size(); ++i) {
e.c.encode(inst::intpush,0);
}
}
e.c.encode(inst::intpush,
(Int) ((dimexps ? dimexps->size():0)
+ (dims ? dims->size():0)));
e.c.encode(inst::builtin, run::newDeepArray);
return c;
} else {
em.compiler(getPos());
em << "new array expression must have either dims or dimexps";
return primError();
}
}
types::ty *newArrayExp::getType(coenv &e)
{
types::ty *c = celltype->trans(e);
if (c->kind == ty_void) {
return primError();
}
if (dims)
c = dims->truetype(c);
if (dimexps) {
Int depth = (Int)dimexps->size();
while (depth > 0) {
c = new types::array(c);
depth--;
}
}