summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/exp.cc
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2010-06-18 23:24:00 +0000
committerKarl Berry <karl@freefriends.org>2010-06-18 23:24:00 +0000
commit47fea6d4aa5c9cfb2e71c51f769dac3023630035 (patch)
tree6a4b15f0b85d8bb5602146e20241b49e938f409b /Build/source/utils/asymptote/exp.cc
parent0dfdf5c49b160d464b74a9cae8882ea81cc47878 (diff)
asy 1.99
git-svn-id: svn://tug.org/texlive/trunk@19047 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/exp.cc')
-rw-r--r--Build/source/utils/asymptote/exp.cc88
1 files changed, 56 insertions, 32 deletions
diff --git a/Build/source/utils/asymptote/exp.cc b/Build/source/utils/asymptote/exp.cc
index 72d947198ee..44957414f38 100644
--- a/Build/source/utils/asymptote/exp.cc
+++ b/Build/source/utils/asymptote/exp.cc
@@ -45,7 +45,27 @@ void exp::transAsType(coenv &e, types::ty *target) {
void exp::transToType(coenv &e, types::ty *target)
{
- types::ty *source=e.e.castSource(target, cgetType(e), symbol::castsym);
+ types::ty *ct=cgetType(e);
+
+ if (equivalent(target, ct)) {
+ transAsType(e, target);
+ return;
+ }
+
+#if FASTCAST
+ if (ct->kind != ty_overloaded &&
+ ct->kind != ty_error &&
+ target->kind != ty_error) {
+ access *a = e.e.fastLookupCast(target, ct);
+ if (a) {
+ transAsType(e, ct);
+ a->encode(CALL, getPos(), e.c);
+ return;
+ }
+ }
+#endif
+
+ types::ty *source = e.e.castSource(target, ct, symbol::castsym);
if (source==0) {
if (target->kind != ty_error) {
types::ty *sources=cgetType(e);
@@ -77,6 +97,7 @@ void exp::testCachedType(coenv &e) {
em.compiler(getPos());
em << "cached type '" << *ct
<< "' doesn't match actual type '" << *t << "'";
+ em.sync();
}
}
}
@@ -379,12 +400,16 @@ void equalityExp::prettyprint(ostream &out, Int indent)
#ifdef NO_FUNC_OPS
types::ty *equalityExp::getType(coenv &e) {
- if (resolved(e)) {
- assert(ct);
- return ct;
- } else {
+ // Try to the resolve the expression as a function call first.
+ types::ty *t = callExp::getType(e);
+ assert(t);
+ if (t->kind != ty_error)
+ return t;
+ else
+ // Either an error or handled by the function equality methods. In the
+ // first case, we may return whatever we like, and the second case always
+ // returns bool. In either case, it is safe to return bool.
return primBoolean();
- }
}
#endif
@@ -456,9 +481,13 @@ bltin bltinFromName(symbol name) {
#ifdef NO_FUNC_OPS
types::ty *equalityExp::trans(coenv &e) {
- if (resolved(e))
+ // First, try to handle by normal function resolution.
+ types::ty *t = callExp::getType(e);
+ assert(t);
+ if (t->kind != ty_error)
return callExp::trans(e);
+ // Then, check for the function equality case.
exp *left = (*this->args)[0].val;
exp *right = (*this->args)[1].val;
@@ -483,10 +512,13 @@ types::ty *equalityExp::trans(coenv &e) {
left->transToType(e, ft);
right->transToType(e, ft);
e.c.encode(inst::builtin, bltinFromName(callee->getName()));
+
return primBoolean();
} else {
// Let callExp report a "no such function" error.
- return callExp::trans(e);
+ types::ty *t = callExp::trans(e);
+ assert(t->kind == ty_error);
+ return t;
}
}
#endif
@@ -801,7 +833,7 @@ void callExp::reportNonFunction() {
em << "called expression is not a function";
}
-void callExp::cacheAppOrVarEntry(coenv &e, bool tacit)
+types::ty *callExp::cacheAppOrVarEntry(coenv &e, bool tacit)
{
assert(cachedVarEntry == 0 && cachedApp == 0);
@@ -820,8 +852,7 @@ void callExp::cacheAppOrVarEntry(coenv &e, bool tacit)
#endif /* }}} */
if (!source) {
- ct = primError();
- return;
+ return primError();
}
// An attempt at speeding up compilation: See if the source arguments match
@@ -840,8 +871,7 @@ void callExp::cacheAppOrVarEntry(coenv &e, bool tacit)
// Normally DEBUG_CACHE is not defined and we return here for efficiency
// reasons. If DEBUG_CACHE is defined, also resolve the function by the
// normal techniques and make sure we get the same result.
- ct = ((function *)ve->getType())->getResult();
- return;
+ return ((function *)ve->getType())->getResult();
#endif
}
}
@@ -897,8 +927,8 @@ void callExp::cacheAppOrVarEntry(coenv &e, bool tacit)
assert(equivalent(cachedVarEntry->getType(), cachedApp->getType()));
#endif
- // Get type relies on this method setting the cached type.
- ct = cachedApp ? cachedApp->getType()->getResult() : primError();
+ // getType relies on this method for the type.
+ return cachedApp ? cachedApp->getType()->getResult() : primError();
}
types::ty *callExp::transPerfectMatch(coenv &e) {
@@ -916,19 +946,12 @@ types::ty *callExp::transPerfectMatch(coenv &e) {
// Call the function.
ve->encode(CALL, getPos(), e.c);
- // That's it. Return the cached type.
- return ct;
+ // That's it. Return the return type of the function.
+ return ct ? ct : dynamic_cast<function *>(ve->getType())->getResult();
}
types::ty *callExp::trans(coenv &e)
{
-#if 0
- cerr << "callExp::trans() called for ";
- if (callee->getName())
- cerr << *callee->getName();
- cerr << endl;
-#endif
-
if (cachedVarEntry == 0 && cachedApp == 0)
cacheAppOrVarEntry(e, false);
@@ -958,18 +981,19 @@ types::ty *callExp::trans(coenv &e)
// Translate the call.
temp->transCall(e, t);
- assert(equivalent(ct, t->result));
- return ct;
+ return t->result;
}
types::ty *callExp::getType(coenv &e)
{
- if (cachedApp == 0 && cachedVarEntry == 0)
- /* This sets ct, the cached return type of the call. */
- cacheAppOrVarEntry(e, true);
-
- assert(ct);
- return ct;
+ if (cachedApp)
+ return cachedApp->getType()->getResult();
+ if (cachedVarEntry) {
+ function *ft = dynamic_cast<function *>(cachedVarEntry->getType());
+ assert(ft);
+ return ft->getResult();
+ }
+ return cacheAppOrVarEntry(e, true);
}
bool callExp::resolved(coenv &e) {