diff options
author | Karl Berry <karl@freefriends.org> | 2010-06-18 23:24:00 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2010-06-18 23:24:00 +0000 |
commit | 47fea6d4aa5c9cfb2e71c51f769dac3023630035 (patch) | |
tree | 6a4b15f0b85d8bb5602146e20241b49e938f409b /Build/source/utils/asymptote/exp.cc | |
parent | 0dfdf5c49b160d464b74a9cae8882ea81cc47878 (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.cc | 88 |
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) { |