virtual string_typ toString() {
datumError("cannot convert to string");
string_typ s = { "XXXXX", 5 };
return s;
}
virtual absyntax::exp *getExp() {
datumError("invalid use of datum");
return new errorExp;
}
// How to access a field of the datum.
virtual absyntax::exp *getFieldExp(symbol id) {
assert(id);
return new fieldExp(nullPos, this->getExp(), id);
}
virtual ImpDatum *getField(const char *name);
virtual ImpDatum *getCell(ImpDatum *index) {
return datumError("cannot index datatype");
}
virtual void addField(const char *name, ImpDatum *init)
{
datumError("cannot set field of datatype");
}
};
// An ever-growing list of handles, used to avoid garbage collecting the data.
// TODO: Implement effective releaseHandle.
mem::vector<handle_typ> handles;
if (errorCallback) {
string_typ s = { msg, strlen(msg) };
errorCallback(s);
}
else {
cerr << msg << '\n';
}
return &ed;
}
handle_typ imp_copyHandle(handle_typ handle)
{
//cout << "+";
// For now, don't do anything.
return handle;
}
void imp_releaseHandle()
{
//cout << "-";
// Do nothing, for now.
}
// A datum representing a value in Asymptote. Both the runtime representation
// of the value and its type are stored.
class ItemDatum : public ImpDatum {
item i;
types::ty *t;
public:
// Every itemDatum has a fixed (non-overloaded) type, t
ItemDatum(types::ty *t) : t(t) {
assert(t);
assert(t->isNotOverloaded());
assert(t->isNotError());
}
// An expression that can be used to get and set the datum.
// The value should only be set once, when the datum is created, and not
// changed.
absyntax::exp *getExp() {
// It may be faster to create this once on start, but then the datum will
// require more space. For now, we create the access and expression on
// demand.
return new varEntryExp(nullPos, t, new itemRefAccess(&i));
}
int_typ toInt() {
// TODO: Decide if we want to use casting.
if (t->kind == types::ty_Int)
return static_cast<int_typ>(get<Int>(i));
else
return ImpDatum::toInt();
}
// If the interface is asked to return a field which is overloaded, a handle
// to and OverloadedDatum is returned. No evaluation actually occurs. The
// datum simply consists of the containing datum and the name of the field
// requested. Subsequent use of the datum will resolve the overloading (or
// report an error).
class OverloadedDatum : public ImpDatum {
ImpDatum *parent;
symbol id;
class GlobalsDatum : public ImpDatum {
typedef std::map<const char*, ImpDatum *> gmap;
gmap base;
virtual absyntax::exp *getFieldExp(symbol id)
{
// Fields of the globals datum are global variables. Use the unqualified
// name.
return new nameExp(nullPos, id);
}
ImpDatum *getParam(int_typ index) {
/*if (params) {
if (index >= 0 && index < static_cast<int_typ>(params->val.size()))
return params->val[index];
else
return datumError("invalid index for parameter");
}
else */ {
return datumError("parameters accessed outside of function");
}
}
void setReturnValue(ImpDatum *retval)
{
/*if (params) {
if (this->retval)
datumError("return value set more than once");
else
this->retval = retval;
}
else */ {
datumError("return value set outside of function");
}
}