summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/exp.h
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/asymptote/exp.h')
-rw-r--r--Build/source/utils/asymptote/exp.h76
1 files changed, 65 insertions, 11 deletions
diff --git a/Build/source/utils/asymptote/exp.h b/Build/source/utils/asymptote/exp.h
index 3e9eca84ba8..425bcc91788 100644
--- a/Build/source/utils/asymptote/exp.h
+++ b/Build/source/utils/asymptote/exp.h
@@ -39,7 +39,7 @@ public:
exp(position pos)
: varinit(pos), ct(0) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) = 0;
// When reporting errors with function calls, it is nice to say "no
// function f(int)" instead of "no function matching signature
@@ -101,6 +101,17 @@ public:
// error.
virtual types::ty *getType(coenv &) = 0;
+ // TODO: Explain what this is!
+ virtual trans::varEntry *getCallee(coenv &e, types::signature *sig) {
+//#define DEBUG_GETAPP
+#if DEBUG_GETAPP
+ cout << "exp fail" << endl;
+ cout << "at " << getPos() << endl;
+ prettyprint(cout, 2);
+#endif
+ return 0;
+ }
+
// Same result as getType, but caches the result so that subsequent
// calls are faster. For this to work correctly, the expression should
// only be used in one place, so the environment doesn't change between
@@ -156,6 +167,8 @@ class tempExp : public exp {
public:
tempExp(coenv &e, varinit *v, types::ty *t);
+ void prettyprint(ostream &out, Int indent);
+
types::ty *trans(coenv &e);
types::ty *getType(coenv &) {
@@ -172,6 +185,8 @@ public:
varEntryExp(position pos, types::ty *t, access *a);
varEntryExp(position pos, types::ty *t, vm::bltin f);
+ void prettyprint(ostream &out, Int indent);
+
types::ty *getType(coenv &);
types::ty *trans(coenv &e);
@@ -234,6 +249,13 @@ public:
return t ? t : types::primError();
}
+ trans::varEntry *getCallee(coenv &e, types::signature *sig) {
+#ifdef DEBUG_GETAPP
+ cout << "nameExp" << endl;
+#endif
+ return value->getCallee(e, sig);
+ }
+
void transWrite(coenv &e, types::ty *target) {
value->varTrans(trans::WRITE, e, target);
@@ -276,6 +298,12 @@ class fieldExp : public nameExp {
types::ty *varGetType(coenv &e) {
return object->getType(e);
}
+ trans::varEntry *getCallee(coenv &, types::signature *) {
+#ifdef DEBUG_GETAPP
+ cout << "pseudoName" << endl;
+#endif
+ return 0;
+ }
// As a type:
types::ty *typeTrans(coenv &, bool tacit = false) {
@@ -425,6 +453,11 @@ public:
types::ty *trans(coenv &e);
types::ty *getType(coenv &e);
+
+ exp *evaluate(coenv &, types::ty *) {
+ // this has no side-effects
+ return this;
+ }
};
class literalExp : public exp {
@@ -433,6 +466,11 @@ public:
: exp(pos) {}
bool scalable() { return false; }
+
+ exp *evaluate(coenv &, types::ty *) {
+ // Literals are constant, they have no side-effects.
+ return this;
+ }
};
class intExp : public literalExp {
@@ -643,9 +681,13 @@ protected:
private:
// Per object caching - Cache the application when it's determined.
- application *ca;
+ application *cachedApp;
+
+ // In special cases, no application object is needed and we can store the
+ // varEntry used in advance.
+ trans::varEntry *cachedVarEntry;
- types::signature *argTypes(coenv& e);
+ types::signature *argTypes(coenv& e, bool *searchable);
void reportArgErrors(coenv &e);
application *resolve(coenv &e,
types::overloaded *o,
@@ -655,31 +697,42 @@ private:
types::overloaded *o,
types::signature *source,
bool tacit);
- void reportMismatch(symbol *s,
- types::function *ft,
+ void reportMismatch(types::function *ft,
types::signature *source);
- application *getApplication(coenv &e);
+ void reportNonFunction();
+
+ // Caches either the application object used to apply the function to the
+ // arguments, or in special cases where the arguments match the function
+ // perfectly, the varEntry of the callee.
+ void cacheAppOrVarEntry(coenv &e, bool tacit);
+
+ types::ty *transPerfectMatch(coenv &e);
public:
callExp(position pos, exp *callee, arglist *args)
- : exp(pos), callee(callee), args(args), ca(0) { assert(args); }
+ : exp(pos), callee(callee), args(args),
+ cachedApp(0), cachedVarEntry(0) { assert(args); }
callExp(position pos, exp *callee)
- : exp(pos), callee(callee), args(new arglist()), ca(0) {}
+ : exp(pos), callee(callee), args(new arglist()),
+ cachedApp(0), cachedVarEntry(0) {}
callExp(position pos, exp *callee, exp *arg1)
- : exp(pos), callee(callee), args(new arglist()), ca(0) {
+ : exp(pos), callee(callee), args(new arglist()),
+ cachedApp(0), cachedVarEntry(0) {
args->add(arg1);
}
callExp(position pos, exp *callee, exp *arg1, exp *arg2)
- : exp(pos), callee(callee), args(new arglist()), ca(0) {
+ : exp(pos), callee(callee), args(new arglist()),
+ cachedApp(0), cachedVarEntry(0) {
args->add(arg1);
args->add(arg2);
}
callExp(position pos, exp *callee, exp *arg1, exp *arg2, exp *arg3)
- : exp(pos), callee(callee), args(new arglist()), ca(0) {
+ : exp(pos), callee(callee), args(new arglist()),
+ cachedApp(0), cachedVarEntry(0) {
args->add(arg1);
args->add(arg2);
args->add(arg3);
@@ -691,6 +744,7 @@ public:
types::ty *getType(coenv &e);
};
+
class pairExp : public exp {
exp *x;
exp *y;