diff options
Diffstat (limited to 'Build/source/utils/asymptote/impdatum.cc')
-rw-r--r-- | Build/source/utils/asymptote/impdatum.cc | 615 |
1 files changed, 0 insertions, 615 deletions
diff --git a/Build/source/utils/asymptote/impdatum.cc b/Build/source/utils/asymptote/impdatum.cc deleted file mode 100644 index af074c85403..00000000000 --- a/Build/source/utils/asymptote/impdatum.cc +++ /dev/null @@ -1,615 +0,0 @@ -#include <cstring> - -#include "stack.h" -#include "env.h" -#include "exp.h" -#include "stm.h" -#include "refaccess.h" - -using std::strlen; - -using namespace absyntax; -using namespace trans; - -using vm::item; -using vm::get; - - -#include "policy.h" - -coenv &coenvInOngoingProcess(); -void runInOngoingProcess(absyntax::runnable *r); - -void runExp(absyntax::exp *e) -{ - absyntax::expStm s(nullPos, e); - runInOngoingProcess(&s); -} - -class ImpDatum; -class ImpArguments; - -ImpDatum *datumError(const char *msg); - -// Expression used for non-item datums. -class errorExp : public absyntax::exp { -public: - errorExp() : exp(nullPos) {} - - void prettyprint(ostream &out, Int indent) - { - absyntax::prettyname(out, "errorExp", indent); - } - - void complain() { - em.error(nullPos); em << "cannot use datum as expression"; - } - - types::ty *getType(coenv &) { return types::primError(); } - types::ty *trans(coenv &e) { complain(); return getType(e); } - - void transAsType(coenv &e, types::ty *target) { complain(); } -}; - -// Abstract base class for Datum types. -class ImpDatum { -public: - virtual operator handle_typ() { return (handle_typ)(this); } - - virtual int_typ toInt() { - datumError("cannot convert to integer"); - - // Return a weird value that will hopefully be noticed. - return -777777; - } - - virtual bool toBool() { - datumError("cannot convert to bool"); - return false; - } - - virtual double toDouble() { - datumError("cannot convert to double"); - return -777e77; - } - - 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; - -handle_typ wrap(ImpDatum *d) -{ - handle_typ h = (handle_typ)(d); - handles.push_back(h); - return h; -} - -ImpDatum *unwrap(handle_typ handle) -{ - assert(handle != 0); - return (ImpDatum *)(handle); -} - -class ErrorDatum : public ImpDatum { -}; - -error_callback_typ errorCallback = 0; - -ImpDatum *datumError(const char *msg) -{ - static ErrorDatum ed; - - 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(); - } - - bool toBool() { - if (t->kind == types::ty_boolean) - return get<bool>(i); - else - return ImpDatum::toBool(); - } - - double toDouble() { - if (t->kind == types::ty_real) - return get<double>(i); - else - return ImpDatum::toDouble(); - } - - string_typ toString() { - if (t->kind == types::ty_string) { - // TODO: Fix for strings containing NUL. - string *s = get<string *>(i); - string_typ st = { s->c_str(), s->length() }; - return st; - } - else - return ImpDatum::toString(); - } -}; - -ItemDatum *ItemDatumFromExp(types::ty *t, absyntax::exp *e) -{ - ItemDatum *d = new ItemDatum(t); - assignExp ae(nullPos, d->getExp(), e); - runExp(&ae); - - return d; -} - -ItemDatum *ItemDatumFromInt(int_typ x) -{ - intExp ie(nullPos, static_cast<Int>(x)); - return ItemDatumFromExp(types::primInt(), &ie); -} - -ItemDatum *ItemDatumFromBool(bool x) -{ - booleanExp be(nullPos, x); - return ItemDatumFromExp(types::primBoolean(), &be); -} - -ItemDatum *ItemDatumFromDouble(double x) -{ - realExp re(nullPos, x); - return ItemDatumFromExp(types::primReal(), &re); -} - -ItemDatum *ItemDatumFromString(string_typ x) -{ - mem::string s(x.buf, (size_t)x.length); - stringExp se(nullPos, s); - return ItemDatumFromExp(types::primString(), &se); -} - - -// 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; - -public: - OverloadedDatum(ImpDatum *parent, symbol id) : parent(parent), id(id) - { - assert(parent); - assert(id); - } - - absyntax::exp *getExp() { - return parent->getFieldExp(id); - return new fieldExp(nullPos, parent->getExp(), id); - } -}; - -ImpDatum *ImpDatum::getField(const char *name) -{ - coenv &e = coenvInOngoingProcess(); - symbol id = symbol::trans(name); - - absyntax::exp *ex = getFieldExp(id); - - types::ty *t = ex->getType(e); - if (t->isError()) - return datumError("no field of that name"); - - if (t->isOverloaded()) - return new OverloadedDatum(this, id); - - // Create a new datum and assign the variable to it. - ItemDatum *d = new ItemDatum(t); - assignExp ae(nullPos, d->getExp(), ex); - runExp(&ae); - - return d; -} - -handle_typ imp_handleFromInt(int_typ x) -{ - return wrap(ItemDatumFromInt(x)); -} - -handle_typ imp_handleFromBool(int_typ x) -{ - if (x != 0 && x != 1) - return wrap(datumError("invalid boolean value")); - - return wrap(ItemDatumFromBool(x == 1)); -} - -handle_typ imp_handleFromDouble(double x) -{ - return wrap(ItemDatumFromDouble(x)); -} - -int_typ imp_IntFromHandle(handle_typ handle) -{ - return unwrap(handle)->toInt(); -} - -int_typ imp_boolFromHandle(handle_typ handle) -{ - return unwrap(handle)->toBool() ? 1 : 0; -} - -double imp_doubleFromHandle(handle_typ handle) -{ - return unwrap(handle)->toDouble(); -} - - -handle_typ imp_handleFromString(string_typ x) -{ - return wrap(ItemDatumFromString(x)); -} - -string_typ imp_stringFromHandle(handle_typ handle) -{ - return unwrap(handle)->toString(); -} - -handle_typ imp_getField(handle_typ handle, const char *name) -{ - return wrap(unwrap(handle)->getField(name)); -} - -handle_typ imp_getCell(handle_typ handle, handle_typ index) -{ - return wrap(unwrap(handle)->getCell(unwrap(index))); -} - -void imp_addField(handle_typ handle, const char *name, handle_typ init) -{ - unwrap(handle)->addField(name, unwrap(init)); -} - -class ImpArguments /* TODO: gc visible but not collected */ { - arglist args; -public: - - ImpArguments() {} - - void add(const char *name, ImpDatum *arg, arg_rest_option isRest) - { - assert(isRest == NORMAL_ARG); // TODO: Implement rest. - symbol id = (name && name[0]) ? symbol::trans(name) : symbol::nullsym; - - args.add(arg->getExp(), id); - } - - arglist *getArgs() { return &args; } -}; - -arguments_typ wrapArgs(ImpArguments *args) -{ - return (arguments_typ)(args); -} -ImpArguments *unwrapArgs(arguments_typ args) -{ - return (ImpArguments *)(args); -} - -arguments_typ imp_newArguments() -{ - return wrapArgs(new ImpArguments); -} - -void imp_releaseArguments(arguments_typ args) -{ - // For now, do nothing. -} - -void imp_addArgument(arguments_typ args, const char *name, handle_typ handle, - arg_rest_option isRest) -{ - unwrapArgs(args)->add(name, unwrap(handle), isRest); -} - -ImpDatum *callDatum(ImpDatum *callee, ImpArguments *args) -{ - coenv &e = coenvInOngoingProcess(); - - callExp callex(nullPos, callee->getExp(), args->getArgs()); - - types::ty *t = callex.getType(e); - if (t->isError()) { - // Run for errors. - runExp(&callex); em.sync(); - return datumError("invalid call"); - } - - assert(t->isNotOverloaded()); // Calls are never overloaded. - - if (t->kind == types::ty_void) { - // Execute the call and return 0 to indicate void. - runExp(&callex); - return 0; - } - else - return ItemDatumFromExp(t, &callex); -} - -handle_typ imp_call(handle_typ callee, arguments_typ args) -{ - return wrap(callDatum(unwrap(callee), unwrapArgs(args))); -} - -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); - } - - virtual void addField(const char *name, ImpDatum *init) { - datumError("addField not yet re-implemented"); - } -}; - -class ImpState { - //ImpArguments *params; - - ImpDatum *retval; -public: - ImpState() : retval(0) {} - - ImpDatum *globals() { - return new GlobalsDatum(); - } - - int_typ numParams() { - /*if (params) - return params->val.size(); - else */ { - datumError("parameters accessed outside of function"); - return 0; - } - } - - 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"); - } - } - - ImpDatum *getReturnValue() - { - return retval; - } -}; - -state_typ wrapState(ImpState *s) -{ - return (state_typ)(s); -} -ImpState *unwrapState(state_typ s) -{ - return (ImpState *)(s); -} - - -handle_typ imp_globals(state_typ state) -{ - return wrap(unwrapState(state)->globals()); -} - -int_typ imp_numParams(state_typ state) -{ - return unwrapState(state)->numParams(); -} - -handle_typ imp_getParam(state_typ state, int_typ index) -{ - return wrap(unwrapState(state)->getParam(index)); -} - -void imp_setReturnValue(state_typ state, handle_typ handle) -{ - unwrapState(state)->setReturnValue(unwrap(handle)); -} - -state_typ cheatState() -{ - return wrapState(new ImpState()); -} - -#if 0 -class FunctionDatum : public ImpDatum { - function_typ f; - void *data; - -public: - FunctionDatum(function_typ f, void *data) : f(f), data(data) {} - - ImpDatum *call(ImpArguments *args) { - ImpState state(args); - - // Call the function. - f(wrapState(&state),data); - - if (state.getReturnValue()) - return state.getReturnValue(); - else - // TODO: Decide on datum for void return. - return 0; - } -}; -#endif - -handle_typ imp_handleFromFunction(const char *signature, - function_typ f, void *data) -{ - // TODO: Re-implement. - return 0; //wrap(new FunctionDatum(f, data)); -} - -void imp_setErrorCallback(error_callback_typ callback) -{ - errorCallback = callback; -} - -extern policy_typ imp_policy; -policy_typ imp_policy = -{ - /* version = */ 101, - imp_copyHandle, - imp_releaseHandle, - imp_handleFromInt, - imp_handleFromBool, - imp_handleFromDouble, - imp_handleFromString, - imp_handleFromFunction, - imp_IntFromHandle, - imp_boolFromHandle, - imp_doubleFromHandle, - imp_stringFromHandle, - imp_getField, - imp_getCell, - imp_addField, - imp_newArguments, - imp_releaseArguments, - imp_addArgument, - imp_call, - imp_globals, - imp_numParams, - imp_getParam, - imp_setReturnValue, - imp_setErrorCallback, -}; - -// Defined in process.cc -void init(bool resetpath=true); - -extern "C" { - - policy_typ *_asy_getPolicy() - { - return &imp_policy; - } - - state_typ _asy_getState() - { - static state_typ state = cheatState(); - - // TODO: Make sure this runs once. - char buf[] = "asymptote.so"; - char *argv [] = { buf }; - settings::setOptions(1,argv); - - // Ensures uptodate is not used. - init(); - - return state; - } - -} |