diff options
38 files changed, 1197 insertions, 581 deletions
diff --git a/Build/source/utils/README b/Build/source/utils/README index 53fd598c2c6..d95302f6b39 100644 --- a/Build/source/utils/README +++ b/Build/source/utils/README @@ -4,7 +4,7 @@ Public domain. Originally written 2005 by Karl Berry. Extra utilities we (optionally) compile for TeX Live. See comments in ../texk/README. -asymptote 1.98 - checked 15jun10 +asymptote 1.99 - checked 19jun10 update to TL from CTAN, to include prebuilt doc. see http://tug.org/texlive/build.html#asymptote and tlpkg/bin/tl-update-asy diff --git a/Build/source/utils/asymptote/ChangeLog b/Build/source/utils/asymptote/ChangeLog index 4c391a848b8..d7f1d1796ff 100644 --- a/Build/source/utils/asymptote/ChangeLog +++ b/Build/source/utils/asymptote/ChangeLog @@ -1,4 +1,158 @@ ------------------------------------------------------------------------ +r5029 | jcbowman | 2010-06-18 01:01:53 -0600 (Fri, 18 Jun 2010) | 1 line +Changed paths: + M /trunk/asymptote/tests/gc/pen.asy + +Update test. +------------------------------------------------------------------------ +r5028 | jcbowman | 2010-06-18 00:56:06 -0600 (Fri, 18 Jun 2010) | 1 line +Changed paths: + M /trunk/asymptote/examples/xstitch.asy + +Reduce example output. +------------------------------------------------------------------------ +r5027 | jcbowman | 2010-06-18 00:43:38 -0600 (Fri, 18 Jun 2010) | 1 line +Changed paths: + M /trunk/asymptote/base/bezulate.asy + +Fix bug in bezulate containmentTree. +------------------------------------------------------------------------ +r5026 | jcbowman | 2010-06-17 14:04:11 -0600 (Thu, 17 Jun 2010) | 2 lines +Changed paths: + M /trunk/asymptote/base/graph3.asy + M /trunk/asymptote/base/three_surface.asy + M /trunk/asymptote/base/three_tube.asy + +Optimize parametric surface generation. + +------------------------------------------------------------------------ +r5025 | jcbowman | 2010-06-17 13:39:00 -0600 (Thu, 17 Jun 2010) | 1 line +Changed paths: + M /trunk/asymptote/configure.ac + +Remove --no-var-tracking for major g++ versions < 4. +------------------------------------------------------------------------ +r5024 | jcbowman | 2010-06-16 18:11:49 -0600 (Wed, 16 Jun 2010) | 2 lines +Changed paths: + M /trunk/asymptote/base/three.asy + M /trunk/asymptote/examples/animations/torusanimation.asy + +Fix perspective animations; update example. + +------------------------------------------------------------------------ +r5023 | hammera | 2010-06-16 17:08:10 -0600 (Wed, 16 Jun 2010) | 2 lines +Changed paths: + M /trunk/asymptote/entry.cc + +Removed TODOs in venv that don't need doing. + +------------------------------------------------------------------------ +r5022 | hammera | 2010-06-16 17:03:56 -0600 (Wed, 16 Jun 2010) | 2 lines +Changed paths: + M /trunk/asymptote/entry.cc + M /trunk/asymptote/entry.h + +Removed value allocation in venv. + +------------------------------------------------------------------------ +r5021 | hammera | 2010-06-16 16:39:03 -0600 (Wed, 16 Jun 2010) | 2 lines +Changed paths: + M /trunk/asymptote/TODO + M /trunk/asymptote/entry.cc + M /trunk/asymptote/entry.h + M /trunk/asymptote/env.cc + M /trunk/asymptote/exp.h + M /trunk/asymptote/types.h + +Removed stack of hash tables from venv. + +------------------------------------------------------------------------ +r5020 | hammera | 2010-06-16 16:25:59 -0600 (Wed, 16 Jun 2010) | 2 lines +Changed paths: + M /trunk/asymptote/tests/types/resolve.asy + +Added test based on previous bug. + +------------------------------------------------------------------------ +r5019 | hammera | 2010-06-16 16:23:05 -0600 (Wed, 16 Jun 2010) | 2 lines +Changed paths: + M /trunk/asymptote/knot.cc + +Eliminated string copying in knot.cc. + +------------------------------------------------------------------------ +r5018 | hammera | 2010-06-16 16:21:11 -0600 (Wed, 16 Jun 2010) | 2 lines +Changed paths: + M /trunk/asymptote/exp.cc + M /trunk/asymptote/exp.h + +Fixed bug in equalityExp. + +------------------------------------------------------------------------ +r5017 | jcbowman | 2010-06-16 01:48:07 -0600 (Wed, 16 Jun 2010) | 2 lines +Changed paths: + M /trunk/asymptote/glrender.cc + M /trunk/asymptote/settings.cc + +Add settings.framedelay for working around OpenGL rendering buffer overflows. + +------------------------------------------------------------------------ +r5016 | hammera | 2010-06-15 11:37:52 -0600 (Tue, 15 Jun 2010) | 2 lines +Changed paths: + M /trunk/asymptote/entry.cc + +Added a (crucial) semi-colon. + +------------------------------------------------------------------------ +r5015 | jcbowman | 2010-06-15 08:59:21 -0600 (Tue, 15 Jun 2010) | 2 lines +Changed paths: + M /trunk/asymptote/item.h + +Simplify code. + +------------------------------------------------------------------------ +r5014 | jcbowman | 2010-06-15 08:56:55 -0600 (Tue, 15 Jun 2010) | 2 lines +Changed paths: + A /trunk/asymptote/examples/xstitch.asy + +Add example. + +------------------------------------------------------------------------ +r5013 | jcbowman | 2010-06-14 18:16:05 -0600 (Mon, 14 Jun 2010) | 2 lines +Changed paths: + M /trunk/asymptote/item.h + +Fix segmentation fault. + +------------------------------------------------------------------------ +r5012 | hammera | 2010-06-14 17:10:17 -0600 (Mon, 14 Jun 2010) | 2 lines +Changed paths: + M /trunk/asymptote/entry.cc + M /trunk/asymptote/entry.h + +Avoid allocating in venv::key. + +------------------------------------------------------------------------ +r5011 | hammera | 2010-06-14 17:00:42 -0600 (Mon, 14 Jun 2010) | 2 lines +Changed paths: + M /trunk/asymptote/TODO + M /trunk/asymptote/application.cc + M /trunk/asymptote/camp.l + M /trunk/asymptote/env.cc + M /trunk/asymptote/env.h + M /trunk/asymptote/exp.cc + M /trunk/asymptote/types.cc + +More optimizations. + +------------------------------------------------------------------------ +r5010 | jcbowman | 2010-06-14 03:43:38 -0600 (Mon, 14 Jun 2010) | 1 line +Changed paths: + M /trunk/asymptote/asymptote.spec + M /trunk/asymptote/configure.ac + +Increment version to 1.99svn. +------------------------------------------------------------------------ r5009 | jcbowman | 2010-06-14 02:39:57 -0600 (Mon, 14 Jun 2010) | 6 lines Changed paths: M /trunk/asymptote/array.cc diff --git a/Build/source/utils/asymptote/ReleaseNotes b/Build/source/utils/asymptote/ReleaseNotes index 10581da2852..eeb16955d6e 100644 --- a/Build/source/utils/asymptote/ReleaseNotes +++ b/Build/source/utils/asymptote/ReleaseNotes @@ -1,6 +1,16 @@ +Release Notes for Version 1.99 + +A segmentation fault was fixed. Perspective animations were fixed. A bug in +the bezulate topological sorting algorithm was fixed. A settings.framedelay +parameter was added for working around OpenGL animation rendering buffer +overruns. Further optimizations were made. A portability issue was addressed. + Release Notes for Version 1.98 -Memory usage and garbage collection were greatly improved, and many optimizations were made. Labels are now aligned using the rotational instead of shiftless part of the transform. A portable CYGWIN memory limit fix was implemented. Noncyclic stokepaths are now discarded to work around a bug in gs 8.71.k. +Memory usage and garbage collection were greatly improved, and many +optimizations were made. Labels are now aligned using the rotational instead of +the shiftless part of the transform. A portable CYGWIN memory limit fix was +implemented. Noncyclic stokepaths are discarded to work around a bug in gs 8.71. Release Notes for Version 1.97 diff --git a/Build/source/utils/asymptote/TODO b/Build/source/utils/asymptote/TODO index 11eface34c8..6265d3c0dd5 100644 --- a/Build/source/utils/asymptote/TODO +++ b/Build/source/utils/asymptote/TODO @@ -1,6 +1,11 @@ +Andy: Investigate bbox error in uofa-talk Shadowing slide + +Andy: make var work in extended for + Andy: possible optimizations: - fix func op and three.asy - rewrite exp::transToType and protoenv::castSource + overloaded::simplify copies + straight guide which references a subset of a pair vector. + Is it cheaper to import a bltin module than to call base_venv again? varpush+pop --> no op varsave+pop --> one op closure+pushfunc+varsave+pop --> savefunc @@ -9,9 +14,7 @@ Andy: possible optimizations: formal::addOps calls trans only hash first 3 or 4 args of signature rm transToType from varinitArg::trans - run a perfect match through multimatch first (no casting allowed) change camp.y to flag arglists with named args - remove addFunctionOps in favor of == and != defined in types.h Andy: testing in errortest.asy for packing versus casting, default argument ambiguities, and whatever else you can think of diff --git a/Build/source/utils/asymptote/application.cc b/Build/source/utils/asymptote/application.cc index 533b624fe55..cbcb19620b0 100644 --- a/Build/source/utils/asymptote/application.cc +++ b/Build/source/utils/asymptote/application.cc @@ -346,7 +346,7 @@ bool application::halfExact() { // True if any of the formals have names. bool namedFormals(signature *sig) { - formal_vector formals = sig->formals; + formal_vector& formals = sig->formals; size_t n = formals.size(); for (size_t i = 0; i < n; ++i) { if (formals[i].name) @@ -470,7 +470,8 @@ app_list exactMultimatch(env &e, return l; } -bool halfExactMightMatch(signature *target, types::ty *t1, types::ty *t2) +bool halfExactMightMatch(env &e, + signature *target, types::ty *t1, types::ty *t2) { formal_vector& formals = target->formals; if (formals.size() < 2) @@ -484,14 +485,27 @@ bool halfExactMightMatch(signature *target, types::ty *t1, types::ty *t2) assert(formals[0].t); assert(formals[1].t); - // Test if one of the arguments matches exactly. - return equivalent(formals[0].t, t1) || equivalent(formals[1].t, t2); +#ifdef FASTCAST +# define CASTABLE fastCastable +#else +# define CASTABLE castable +#endif + + // These casting tests if successful will be repeating again by + // application::match. It would be nice to avoid this somehow, but the + // additional complexity is probably not worth the minor speed improvement. + if (equivalent(formals[0].t, t1)) + return e.CASTABLE(formals[1].t, t2); + else + return equivalent(formals[1].t, t2) && e.CASTABLE(formals[0].t, t1); +#undef CASTABLE } -// Most commonly after exact matches are cases such as 2+3.4, that is, binary -// operations were one of the operands matches exactly and the other does not. -// This searches for this so-called "half-exact" matches. -// This should only be called after exactMultimatch has failed. +// Most common after exact matches are cases such as +// 2 + 3.4 +// that is, binary operations were one of the operands matches exactly and the +// other does not. This function searches for these so-called "half-exact" +// matches. This should only be called after exactMultimatch has failed. app_list halfExactMultimatch(env &e, types::overloaded *o, types::signature *source, @@ -525,7 +539,7 @@ app_list halfExactMultimatch(env &e, function *ft = (function *)*t; #if 1 - if (!halfExactMightMatch(ft->getSignature(), t1, t2)) + if (!halfExactMightMatch(e, ft->getSignature(), t1, t2)) continue; #endif @@ -540,6 +554,13 @@ app_list halfExactMultimatch(env &e, return l; } +// Simple check if there are two many arguments to match the candidate +// function. +bool tooManyArgs(types::signature *target, types::signature *source) { + return source->getNumFormals() > target->getNumFormals() && + !target->hasRest(); +} + // The full overloading resolution system, which handles casting of arguments, // packing into rest arguments, named arguments, etc. app_list inexactMultimatch(env &e, @@ -566,53 +587,31 @@ app_list inexactMultimatch(env &e, #if DEBUG_GETAPP function *ft = dynamic_cast<function *>(*t); signature *target = ft->getSignature(); - cout << "TOTAL" << endl; - cout << "ARGS: source: " << source->getNumFormals() - << " target: " << target->getNumFormals() << endl; - //cout << "target: " << *target << endl; if (equivalent(target, source)) perfect = true; -#if 0 - cout << "TOTAL" << endl; - if (target->getNumFormals() < source->getNumFormals() && - !target->hasRest()) { - cout << "TOO MANY ARGS" << endl; - } else if (target->getNumFormals() == source->getNumFormals() && - !target->hasRest()) { - cout << "EXACT ARGS" << endl; - } else { - cout << "NOT TOO MANY ARGS" << endl; - } -#endif #endif + + // Check if there are two many arguments to match. + if (tooManyArgs((*t)->getSignature(), source)) + continue; + application *a=application::match(e, (function *)(*t), source, al); if (a) l.push_back(a); + #if DEBUG_GETAPP if (a && !namedFormals(source)) { - if (a->exact() != exactlyMatchable(ft->getSignature(), source)) { - cout << a->exact() << " != " - << exactlyMatchable(ft->getSignature(), source) << endl; - cout << "ft = " << *ft << endl; - cout << "args = " << *source << endl; - } assert(a->exact() == exactlyMatchable(ft->getSignature(), source)); if (a->halfExact() && !namedFormals(source)) { - if (!halfExactMightMatch(target, source->getFormal(0).t, - source->getFormal(1).t)) - { - cerr << "target: " << *target << " source: " << *source << endl; - cerr.flush(); - } - cerr << "test" << endl;; - cerr.flush(); - assert(halfExactMightMatch(target, source->getFormal(0).t, - source->getFormal(1).t)); + assert(halfExactMightMatch(e, target, source->getFormal(0).t, + source->getFormal(1).t)); } } - if (a && a->exact()) exact = true; - if (a && a->halfExact()) halfExact = true; + if (a && a->exact()) + exact = true; + if (a && a->halfExact()) + halfExact = true; #endif } } diff --git a/Build/source/utils/asymptote/asy-keywords.el b/Build/source/utils/asymptote/asy-keywords.el index 6ab99004d56..d5d4a97fb87 100644 --- a/Build/source/utils/asymptote/asy-keywords.el +++ b/Build/source/utils/asymptote/asy-keywords.el @@ -2,7 +2,7 @@ ;; This file is automatically generated by asy-list.pl. ;; Changes will be overwritten. ;; -(defvar asy-keywords-version "1.98") +(defvar asy-keywords-version "1.99") (defvar asy-keyword-name '( and controls tension atleast curl if else while for do return break continue struct typedef new access import unravel from include quote static public private restricted this explicit true false null cycle newframe operator )) diff --git a/Build/source/utils/asymptote/asymptote.spec b/Build/source/utils/asymptote/asymptote.spec index 9dcfa6b3ecd..78f7288d067 100644 --- a/Build/source/utils/asymptote/asymptote.spec +++ b/Build/source/utils/asymptote/asymptote.spec @@ -1,7 +1,7 @@ %{!?_texmf: %define _texmf %(eval "echo `kpsewhich -expand-var '$TEXMFLOCAL'`")} Name: asymptote -Version: 1.98 +Version: 1.99 Release: 1%{?dist} Summary: Descriptive vector graphics language diff --git a/Build/source/utils/asymptote/base/bezulate.asy b/Build/source/utils/asymptote/base/bezulate.asy index f3817a47bcf..5b21d8c1605 100644 --- a/Build/source/utils/asymptote/base/bezulate.asy +++ b/Build/source/utils/asymptote/base/bezulate.asy @@ -20,34 +20,34 @@ int countIntersections(path[] p, pair start, pair end) path[][] containmentTree(path[] paths) { path[][] result; - for(int i=0; i < paths.length; ++i) { - bool classified=false; + for(path g : paths) { // check if current curve contains or is contained in a group of curves - for(int j=0; !classified && j < result.length; ++j) - { - int test = inside(paths[i],result[j][0],zerowinding); - if(test == 1) // current curve contains group's toplevel curve - { - // replace toplevel curve with current curve - result[j].insert(0,paths[i]); - classified = true; - } - else if(test == -1) // current curve contained in group's toplevel curve - { - result[j].push(paths[i]); - classified = true; - } + int j; + for(j=0; j < result.length; ++j) { + path[] resultj=result[j]; + int test=inside(g,resultj[0],zerowinding); + if(test == 1) { + // current curve contains group's toplevel curve; + // replace toplevel curve with current curve + resultj.insert(0,g); + // check to see if any other groups are contained within this curve + for(int k=j+1; k < result.length;) { + if(inside(g,result[k][0]) == 1) { + resultj.append(result[k]); + result.delete(k); + } else ++k; + } + break; + } else if(test == -1) { + // current curve contained within group's toplevel curve + resultj.push(g); + break; } + } // create a new group if this curve does not belong to another group - if(!classified) - result.push(new path[] {paths[i]}); + if(j == result.length) + result.push(new path[] {g}); } - - // sort group so that later paths in the array are contained in previous paths - bool comparepaths(path i, path j) {return inside(i,j,zerowinding)==1;} - for(int i=0; i < result.length; ++i) - result[i] = sort(result[i],comparepaths); - return result; } diff --git a/Build/source/utils/asymptote/base/graph3.asy b/Build/source/utils/asymptote/base/graph3.asy index ee83e8cb99b..9eee4209134 100644 --- a/Build/source/utils/asymptote/base/graph3.asy +++ b/Build/source/utils/asymptote/base/graph3.asy @@ -1610,60 +1610,55 @@ surface bispline(real[][] z, real[][] p, real[][] q, real[][] r, surface s=surface(count); s.index=new int[n][m]; - int k=-1; + int k=0; for(int i=0; i < n; ++i) { - bool[] condi=all ? null : cond[i]; + int ip=i+1; real xi=x[i]; + real xp=x[ip]; + real x1=interp(xi,xp,1/3); + real x2=interp(xi,xp,2/3); + real hx=x1-xi; real[] zi=z[i]; - real[] zp=z[i+1]; + real[] zp=z[ip]; real[] ri=r[i]; - real[] rp=r[i+1]; + real[] rp=r[ip]; real[] pi=p[i]; - real[] pp=p[i+1]; + real[] pp=p[ip]; real[] qi=q[i]; - real[] qp=q[i+1]; - real xp=x[i+1]; - real hx=(xp-xi)/3; + real[] qp=q[ip]; int[] indexi=s.index[i]; + bool[] condi=all ? null : cond[i]; for(int j=0; j < m; ++j) { - real yj=y[j]; - real yp=y[j+1]; if(all || condi[j]) { - triple[][] P=array(4,array(4,O)); - real hy=(yp-yj)/3; + real yj=y[j]; + int jp=j+1; + real yp=y[jp]; + real y1=interp(yj,yp,1/3); + real y2=interp(yj,yp,2/3); + real hy=y1-yj; real hxy=hx*hy; - // x and y directions - for(int k=0; k < 4; ++k) { - P[0][k] += xi*X; - P[k][0] += yj*Y; - P[1][k] += (xp+2*xi)/3*X; - P[k][1] += (yp+2*yj)/3*Y; - P[2][k] += (2*xp+xi)/3*X; - P[k][2] += (2*yp+yj)/3*Y; - P[3][k] += xp*X; - P[k][3] += yp*Y; - } - // z: value - P[0][0] += zi[j]*Z; - P[3][0] += zp[j]*Z; - P[0][3] += zi[j+1]*Z; - P[3][3] += zp[j+1]*Z; - // z: first derivative - P[1][0] += (P[0][0].z+hx*pi[j])*Z; - P[1][3] += (P[0][3].z+hx*pi[j+1])*Z; - P[2][0] += (P[3][0].z-hx*pp[j])*Z; - P[2][3] += (P[3][3].z-hx*pp[j+1])*Z; - P[0][1] += (P[0][0].z+hy*qi[j])*Z; - P[3][1] += (P[3][0].z+hy*qp[j])*Z; - P[0][2] += (P[0][3].z-hy*qi[j+1])*Z; - P[3][2] += (P[3][3].z-hy*qp[j+1])*Z; - // z: second derivative - P[1][1] += (P[0][1].z+P[1][0].z-P[0][0].z+hxy*ri[j])*Z; - P[1][2] += (P[0][2].z+P[1][3].z-P[0][3].z-hxy*ri[j+1])*Z; - P[2][1] += (P[2][0].z+P[3][1].z-P[3][0].z-hxy*rp[j])*Z; - P[2][2] += (P[2][3].z+P[3][2].z-P[3][3].z+hxy*rp[j+1])*Z; - s.s[++k]=patch(P); + real zij=zi[j]; + real zip=zi[jp]; + real zpj=zp[j]; + real zpp=zp[jp]; + real pij=hx*pi[j]; + real ppj=hx*pp[j]; + real qip=hy*qi[jp]; + real qpp=hy*qp[jp]; + real zippip=zip+hx*pi[jp]; + real zppmppp=zpp-hx*pp[jp]; + real zijqij=zij+hy*qi[j]; + real zpjqpj=zpj+hy*qp[j]; + + s.s[k]=patch(new triple[][] { + {(xi,yj,zij),(xi,y1,zijqij),(xi,y2,zip-qip),(xi,yp,zip)}, + {(x1,yj,zij+pij),(x1,y1,zijqij+pij+hxy*ri[j]), + (x1,y2,zippip-qip-hxy*ri[jp]),(x1,yp,zippip)}, + {(x2,yj,zpj-ppj),(x2,y1,zpjqpj-ppj-hxy*rp[j]), + (x2,y2,zppmppp-qpp+hxy*rp[jp]),(x2,yp,zppmppp)}, + {(xp,yj,zpj),(xp,y1,zpjqpj),(xp,y2,zpp-qpp),(xp,yp,zpp)}},copy=false); indexi[j]=k; + ++k; } } } diff --git a/Build/source/utils/asymptote/base/three.asy b/Build/source/utils/asymptote/base/three.asy index 2de8b4a5cca..f528e2a9e52 100644 --- a/Build/source/utils/asymptote/base/three.asy +++ b/Build/source/utils/asymptote/base/three.asy @@ -2746,10 +2746,13 @@ struct scene transform3 T=identity4; picture pic2; - void operator init(frame f, projection P=currentprojection) { + void operator init(frame f, real width, real height, + projection P=currentprojection) { this.f=f; this.t=identity4; this.P=P; + this.width=width; + this.height=height; } void operator init(picture pic, real xsize=pic.xsize, real ysize=pic.ysize, @@ -2897,8 +2900,8 @@ object embed(string label="", string text=label, string prefix=defaultfilename, triple lambda=M-m; S.viewportmargin=viewportmargin((lambda.x,lambda.y)); - S.width=lambda.x+2*S.viewportmargin.x; - S.height=lambda.y+2*S.viewportmargin.y; + S.width=ceil(max(S.width,lambda.x)+2*S.viewportmargin.x); + S.height=ceil(max(S.height,lambda.y)+2*S.viewportmargin.y); S.f=shift((-0.5(m.x+M.x),-0.5*(m.y+M.y),0))*S.f; // Eye will be at (0,0,0) } else { if(P.angle == 0) { @@ -3018,7 +3021,8 @@ object embed(string label="", string text=label, light light=currentlight, projection P=currentprojection) { if(is3D(format)) - return embed(label,text,prefix,scene(f,P),format,view,options,script,light); + return embed(label,text,prefix,scene(f,width,height,P),format,view,options, + script,light); else { object F; F.f=f; @@ -3072,11 +3076,13 @@ currentpicture.fitter=new frame(string prefix, picture pic, string format, return f; }; -frame embedder(string prefix, frame f, string format, bool view, - string options, string script, light light, projection P) +frame embedder(string prefix, frame f, string format, real width, real height, + bool view, string options, string script, light light, + projection P) { return embedder(new object(string prefix, string format) { - return embed(prefix=prefix,f,format,view,options,script,light,P); + return embed(prefix=prefix,f,format,width,height,view,options,script, + light,P); },prefix,format,view,light); } @@ -3225,7 +3231,8 @@ frame[] fit3(string prefix="", picture[] pictures, picture all, for(int i=settings.reverse ? pictures.length-1 : 0; i >= 0 && i < pictures.length && !settings.interrupt; settings.reverse ? --i : ++i) { - frame f=embedder(prefix,out[i],format,view,options,script,light,S.P); + frame f=embedder(prefix,out[i],format,S.width,S.height,view,options, + script,light,S.P); if(!settings.loop) out[i]=f; } if(!settings.loop) break; diff --git a/Build/source/utils/asymptote/base/three_surface.asy b/Build/source/utils/asymptote/base/three_surface.asy index c4f05c7882f..6d0c54d2479 100644 --- a/Build/source/utils/asymptote/base/three_surface.asy +++ b/Build/source/utils/asymptote/base/three_surface.asy @@ -10,7 +10,7 @@ private real Fuzz=10.0*realEpsilon; private real nineth=1/9; struct patch { - triple[][] P=new triple[4][4]; + triple[][] P; triple[] normals; // Optionally specify 4 normal vectors at the corners. pen[] colors; // Optionally specify 4 corner colors. bool straight; // Patch is based on a piecewise straight external path. @@ -186,9 +186,9 @@ struct patch { void operator init(triple[][] P, triple[] normals=new triple[], pen[] colors=new pen[], bool straight=false, - bool3 planar=default) { + bool3 planar=default, bool copy=true) { init(); - this.P=copy(P); + this.P=copy ? copy(P) : P; if(normals.length != 0) this.normals=copy(normals); if(colors.length != 0) @@ -306,6 +306,7 @@ struct patch { patch operator * (transform3 t, patch s) { patch S; + S.P=new triple[4][4]; for(int i=0; i < 4; ++i) { triple[] si=s.P[i]; triple[] Si=S.P[i]; diff --git a/Build/source/utils/asymptote/base/three_tube.asy b/Build/source/utils/asymptote/base/three_tube.asy index 281eb0716da..aa5688f081e 100644 --- a/Build/source/utils/asymptote/base/three_tube.asy +++ b/Build/source/utils/asymptote/base/three_tube.asy @@ -92,8 +92,9 @@ private real[][][] bispline0(real[][] z, real[][] p, real[][] q, real[][] r, int k=0; for(int i=0; i < n; ++i) { int ip=i+1; - bool[] condi=all ? null : cond[i]; real xi=x[i]; + real xp=x[ip]; + real hx=(xp-xi)/3; real[] zi=z[i]; real[] zp=z[ip]; real[] ri=r[i]; @@ -102,13 +103,12 @@ private real[][][] bispline0(real[][] z, real[][] p, real[][] q, real[][] r, real[] pp=p[ip]; real[] qi=q[i]; real[] qp=q[ip]; - real xp=x[ip]; - real hx=(xp-xi)/3; + bool[] condi=all ? null : cond[i]; for(int j=0; j < m; ++j) { - real yj=y[j]; - int jp=j+1; - real yp=y[jp]; if(all || condi[j]) { + real yj=y[j]; + int jp=j+1; + real yp=y[jp]; real hy=(yp-yj)/3; real hxy=hx*hy; real zij=zi[j]; @@ -164,8 +164,7 @@ real[][][] bispline(real[][] f, real[] x, real[] y, real[][] p=transpose(tp); for(int i=0; i < n; ++i) r[i]=clamped(d1[i],d2[i])(y,p[i]); - real[][][] s=bispline0(f,p,q,r,x,y,cond); - return s; + return bispline0(f,p,q,r,x,y,cond); } bool uperiodic(real[][] a) { diff --git a/Build/source/utils/asymptote/camp.l b/Build/source/utils/asymptote/camp.l index 4e6f3b23bf2..cb4d31bdc95 100644 --- a/Build/source/utils/asymptote/camp.l +++ b/Build/source/utils/asymptote/camp.l @@ -87,7 +87,7 @@ void adjust() void savesymbol(symbol name) { adjust(); - yylval.ps.pos=here(); + yylval.ps.pos=yylval.pos; // avoid invoking here() twice yylval.ps.sym=name; } diff --git a/Build/source/utils/asymptote/configure b/Build/source/utils/asymptote/configure index a9c215d25d4..8c7a8072cb7 100755 --- a/Build/source/utils/asymptote/configure +++ b/Build/source/utils/asymptote/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.63 for Asymptote 1.98. +# Generated by GNU Autoconf 2.63 for Asymptote 1.99. # # Report bugs to <http://sourceforge.net/projects/asymptote>. # @@ -596,8 +596,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='Asymptote' PACKAGE_TARNAME='asymptote' -PACKAGE_VERSION='1.98' -PACKAGE_STRING='Asymptote 1.98' +PACKAGE_VERSION='1.99' +PACKAGE_STRING='Asymptote 1.99' PACKAGE_BUGREPORT='http://sourceforge.net/projects/asymptote' # Factoring default headers for most tests. @@ -1294,7 +1294,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Asymptote 1.98 to adapt to many kinds of systems. +\`configure' configures Asymptote 1.99 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1355,7 +1355,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Asymptote 1.98:";; + short | recursive ) echo "Configuration of Asymptote 1.99:";; esac cat <<\_ACEOF @@ -1465,7 +1465,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Asymptote configure 1.98 +Asymptote configure 1.99 generated by GNU Autoconf 2.63 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1479,7 +1479,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Asymptote $as_me 1.98, which was +It was created by Asymptote $as_me 1.99, which was generated by GNU Autoconf 2.63. Invocation command line was $ $0 $@ @@ -5928,8 +5928,9 @@ if test "$GXX" = yes ; then ac_gcc_version=`echo __GNUC__ | $CC -E - | grep -v ^\#` if test "$ac_gcc_version" -lt 4; then CFLAGS=$CFLAGS" -finline-limit=400" + else + CFLAGS=$CFLAGS" --no-var-tracking" fi - CFLAGS=$CFLAGS" --no-var-tracking" fi ac_ext=cpp @@ -12021,7 +12022,7 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Asymptote $as_me 1.98, which was +This file was extended by Asymptote $as_me 1.99, which was generated by GNU Autoconf 2.63. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12080,7 +12081,7 @@ Report bugs to <bug-autoconf@gnu.org>." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ -Asymptote config.status 1.98 +Asymptote config.status 1.99 configured by $0, generated by GNU Autoconf 2.63, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" diff --git a/Build/source/utils/asymptote/configure.ac b/Build/source/utils/asymptote/configure.ac index eba5113d9ab..45a3b47644b 100644 --- a/Build/source/utils/asymptote/configure.ac +++ b/Build/source/utils/asymptote/configure.ac @@ -3,7 +3,7 @@ # this file. AC_PREREQ(2) -AC_INIT([Asymptote],[1.98],[http://sourceforge.net/projects/asymptote]) +AC_INIT([Asymptote],[1.99],[http://sourceforge.net/projects/asymptote]) VERSION=$PACKAGE_VERSION AC_SUBST(VERSION) @@ -106,8 +106,9 @@ if test "$GXX" = yes ; then ac_gcc_version=`echo __GNUC__ | $CC -E - | grep -v ^\#` if test "$ac_gcc_version" -lt 4; then CFLAGS=$CFLAGS" -finline-limit=400" + else + CFLAGS=$CFLAGS" --no-var-tracking" fi - CFLAGS=$CFLAGS" --no-var-tracking" fi AC_CHECK_HEADER(tr1/unordered_map,, diff --git a/Build/source/utils/asymptote/doc/CAD.pdf b/Build/source/utils/asymptote/doc/CAD.pdf Binary files differindex e5cfb778ea7..1d787c85f52 100644 --- a/Build/source/utils/asymptote/doc/CAD.pdf +++ b/Build/source/utils/asymptote/doc/CAD.pdf diff --git a/Build/source/utils/asymptote/doc/FAQ/asy-faq.info b/Build/source/utils/asymptote/doc/FAQ/asy-faq.info index 1664d59845e..61c827ac745 100644 --- a/Build/source/utils/asymptote/doc/FAQ/asy-faq.info +++ b/Build/source/utils/asymptote/doc/FAQ/asy-faq.info @@ -9,7 +9,7 @@ END-INFO-DIR-ENTRY File: $prefix.info, Node: Top, Next: Question 1.1, Up: (dir) ASYMPTOTE FREQUENTLY ASKED QUESTIONS - 14 Jun 2010 + 18 Jun 2010 This is the list of Frequently Asked Questions about Asymptote (asy). diff --git a/Build/source/utils/asymptote/doc/asy.1 b/Build/source/utils/asymptote/doc/asy.1 index e5ff5977db3..d9e680befc7 100644 --- a/Build/source/utils/asymptote/doc/asy.1 +++ b/Build/source/utils/asymptote/doc/asy.1 @@ -95,7 +95,12 @@ Exit interactive mode on EOF [true]. .TP .B \-fitscreen Fit rendered image to screen [true]. --framerate frames/sec Animation speed [30] +.TP +.B \-framedelay ms +Additional frame delay [0]. +.TP +.B \-framerate frames/s +Animation speed [30]. .TP .B \-globalwrite Allow write to other directory [false]. @@ -214,7 +219,7 @@ Disable system call [true]. .B \-scroll n Scroll standard output n lines at a time [0]. .TP -.B \-spinstep deg/sec +.B \-spinstep deg/s Spin speed [60]. .TP .B \-svgemulation diff --git a/Build/source/utils/asymptote/doc/asymptote.pdf b/Build/source/utils/asymptote/doc/asymptote.pdf Binary files differindex e0b2b521e80..3056f8acbf0 100644 --- a/Build/source/utils/asymptote/doc/asymptote.pdf +++ b/Build/source/utils/asymptote/doc/asymptote.pdf diff --git a/Build/source/utils/asymptote/doc/options b/Build/source/utils/asymptote/doc/options index 468d23d8087..742bbd8702b 100644 --- a/Build/source/utils/asymptote/doc/options +++ b/Build/source/utils/asymptote/doc/options @@ -25,7 +25,8 @@ Options (negate by replacing - with -no): -embed Embed rendered preview image [true] -exitonEOF Exit interactive mode on EOF [true] -fitscreen Fit rendered image to screen [true] --framerate frames/sec Animation speed [30] +-framedelay ms Additional frame delay [0] +-framerate frames/s Animation speed [30] -globalwrite Allow write to other directory [false] -gray Convert all colors to grayscale [false] -h,-help Show summary of options; command-line only @@ -65,7 +66,7 @@ Options (negate by replacing - with -no): -rgb Convert cmyk colors to rgb [false] -safe Disable system call [true] -scroll n Scroll standard output n lines at a time [0] --spinstep deg/sec Spin speed [60] +-spinstep deg/s Spin speed [60] -svgemulation Emulate unimplemented SVG shading [false] -tabcompletion Interactive prompt auto-completion [true] -tex engine latex|pdflatex|xelatex|tex|pdftex|context|none [latex] diff --git a/Build/source/utils/asymptote/doc/png/asymptote.info b/Build/source/utils/asymptote/doc/png/asymptote.info index 481694a9d08..d672a648432 100644 --- a/Build/source/utils/asymptote/doc/png/asymptote.info +++ b/Build/source/utils/asymptote/doc/png/asymptote.info @@ -1,7 +1,7 @@ This is asymptote.info, produced by makeinfo version 4.13 from ../asymptote.texi. -This file documents `Asymptote', version 1.98. +This file documents `Asymptote', version 1.99. `http://asymptote.sourceforge.net' @@ -23,7 +23,7 @@ File: asymptote.info, Node: Top, Next: Description, Up: (dir) Asymptote ********* -This file documents `Asymptote', version 1.98. +This file documents `Asymptote', version 1.99. `http://asymptote.sourceforge.net' @@ -7846,7 +7846,8 @@ Options (negate by replacing - with -no): -embed Embed rendered preview image [true] -exitonEOF Exit interactive mode on EOF [true] -fitscreen Fit rendered image to screen [true] --framerate frames/sec Animation speed [30] +-framedelay ms Additional frame delay [0] +-framerate frames/s Animation speed [30] -globalwrite Allow write to other directory [false] -gray Convert all colors to grayscale [false] -h,-help Show summary of options; command-line only @@ -7886,7 +7887,7 @@ Options (negate by replacing - with -no): -rgb Convert cmyk colors to rgb [false] -safe Disable system call [true] -scroll n Scroll standard output n lines at a time [0] --spinstep deg/sec Spin speed [60] +-spinstep deg/s Spin speed [60] -svgemulation Emulate unimplemented SVG shading [false] -tabcompletion Interactive prompt auto-completion [true] -tex engine latex|pdflatex|xelatex|tex|pdftex|context|none [latex] @@ -8379,9 +8380,9 @@ Index * ---: Bezier curves. (line 83) * -=: Self & prefix operators. (line 6) -* -c: Options. (line 172) -* -l: Options. (line 191) -* -u: Options. (line 182) +* -c: Options. (line 173) +* -l: Options. (line 192) +* -u: Options. (line 183) * -V <1>: Tutorial. (line 19) * -V: Configuring. (line 6) * ..: Tutorial. (line 125) @@ -8444,7 +8445,7 @@ Index (line 48) * alias <1>: Arrays. (line 182) * alias: Structures. (line 52) -* align: Options. (line 166) +* align: Options. (line 167) * Align: label. (line 12) * all: Arrays. (line 330) * Allow: Pens. (line 327) @@ -8457,7 +8458,7 @@ Index * animate: Configuring. (line 67) * animation: animation. (line 6) * annotate: annotate. (line 6) -* antialias <1>: Options. (line 141) +* antialias <1>: Options. (line 142) * antialias: three. (line 210) * antialiasing: Compiling from UNIX source. (line 16) @@ -8503,7 +8504,7 @@ Index * asy.vim: Editing modes. (line 33) * asymptote.sty: LaTeX usage. (line 6) * asymptote.xml: Editing modes. (line 49) -* ASYMPTOTE_CONFIG: Options. (line 113) +* ASYMPTOTE_CONFIG: Options. (line 114) * aTan: Mathematical functions. (line 20) * atan: Mathematical functions. @@ -8516,7 +8517,7 @@ Index * attach <1>: graph. (line 415) * attach: LaTeX usage. (line 31) * autoadjust: three. (line 354) -* autoimport: Options. (line 109) +* autoimport: Options. (line 110) * automatic scaling: graph. (line 682) * axialshade: fill. (line 43) * axis <1>: graph3. (line 66) @@ -8652,13 +8653,13 @@ Index * conditional <1>: Arithmetic & logical. (line 73) * conditional: Programming. (line 8) -* config: Options. (line 113) -* configuration file <1>: Options. (line 113) +* config: Options. (line 114) +* configuration file <1>: Options. (line 114) * configuration file: Configuring. (line 23) * configuring: Configuring. (line 6) * conj: Data types. (line 57) * constructors: Structures. (line 91) -* context: Options. (line 141) +* context: Options. (line 142) * continue <1>: Debugger. (line 31) * continue: Programming. (line 29) * contour: contour. (line 9) @@ -8666,11 +8667,11 @@ Index * controls <1>: three. (line 6) * controls: Bezier curves. (line 45) * controlSpecifier: Paths and guides. (line 379) -* convert <1>: Options. (line 141) +* convert <1>: Options. (line 142) * convert <2>: animation. (line 6) * convert <3>: Files. (line 150) * convert: Configuring. (line 67) -* convertOptions: Options. (line 128) +* convertOptions: Options. (line 129) * Coons shading: fill. (line 74) * copy: Arrays. (line 169) * Cos: Mathematical functions. @@ -8761,7 +8762,7 @@ Index * drawline: math. (line 9) * drawtree: drawtree. (line 9) * dvips: Configuring. (line 67) -* dvipsOptions: Options. (line 128) +* dvipsOptions: Options. (line 129) * dvisvgm: Configuring. (line 67) * E <1>: Mathematical functions. (line 48) @@ -8799,7 +8800,7 @@ Index * eof: Files. (line 88) * eol <1>: Arrays. (line 345) * eol: Files. (line 88) -* EPS <1>: Options. (line 141) +* EPS <1>: Options. (line 142) * EPS: label. (line 80) * erase <1>: Frames and pictures. (line 7) * erase <2>: Data types. (line 239) @@ -8874,7 +8875,7 @@ Index * fontcommand: Pens. (line 207) * fontsize: Pens. (line 178) * for: Programming. (line 8) -* format <1>: Options. (line 141) +* format <1>: Options. (line 142) * format: Data types. (line 267) * forum: Help. (line 6) * frame: Frames and pictures. (line 7) @@ -8899,7 +8900,7 @@ Index * getreal: Files. (line 113) * getstring: Files. (line 113) * gettriple: Files. (line 113) -* glOptions <1>: Options. (line 128) +* glOptions <1>: Options. (line 129) * glOptions: three. (line 210) * GNU Scientific Library: Mathematical functions. (line 48) @@ -8921,7 +8922,7 @@ Index (line 48) * GSL: Compiling from UNIX source. (line 58) -* gsOptions: Options. (line 128) +* gsOptions: Options. (line 129) * GUI: GUI. (line 6) * GUI installation: GUI installation. (line 6) * GUI usage: GUI usage. (line 6) @@ -8947,7 +8948,7 @@ Index * HookHead: draw. (line 26) * HookHead3: three. (line 543) * Horizontal: flowchart. (line 81) -* hyperrefOptions: Options. (line 128) +* hyperrefOptions: Options. (line 129) * hypot: Mathematical functions. (line 6) * I: Mathematical functions. @@ -8963,7 +8964,7 @@ Index * if: Programming. (line 8) * IgnoreAspect: Frames and pictures. (line 58) * image: palette. (line 34) -* ImageMagick <1>: Options. (line 141) +* ImageMagick <1>: Options. (line 142) * ImageMagick <2>: animation. (line 6) * ImageMagick: Configuring. (line 67) * images: palette. (line 6) @@ -9037,7 +9038,7 @@ Index * Landscape: Frames and pictures. (line 95) * lastcut: Paths and guides. (line 251) * lasy-mode: Editing modes. (line 6) -* latex: Options. (line 141) +* latex: Options. (line 142) * LaTeX fonts: Pens. (line 192) * LaTeX usage: LaTeX usage. (line 6) * latin1: latin1. (line 6) @@ -9168,7 +9169,7 @@ Index * none: Files. (line 58) * None: draw. (line 19) * normal: three. (line 488) -* nosafe: Options. (line 161) +* nosafe: Options. (line 162) * NOT: Arithmetic & logical. (line 80) * NoTicks: graph. (line 161) @@ -9184,7 +9185,7 @@ Index * obliqueY: three. (line 334) * obliqueZ: three. (line 319) * ode: ode. (line 9) -* offset <1>: Options. (line 166) +* offset <1>: Options. (line 167) * offset: Pens. (line 115) * OmitTick: graph. (line 239) * OmitTickInterval: graph. (line 239) @@ -9210,7 +9211,7 @@ Index * orthographic: three. (line 338) * outformat: three. (line 127) * outprefix: Frames and pictures. (line 83) -* output <1>: Options. (line 141) +* output <1>: Options. (line 142) * output: Files. (line 35) * OutTicks: graph3. (line 34) * overloading functions: Functions. (line 44) @@ -9238,10 +9239,10 @@ Index * path[]: Tutorial. (line 132) * patterns <1>: patterns. (line 6) * patterns: Pens. (line 238) -* PDF: Options. (line 141) -* pdflatex: Options. (line 141) +* PDF: Options. (line 142) +* pdflatex: Options. (line 142) * pdfviewer: Configuring. (line 6) -* pdfviewerOptions: Options. (line 128) +* pdfviewerOptions: Options. (line 129) * pen: Pens. (line 6) * PenMargin: draw. (line 42) * PenMargin2: three. (line 559) @@ -9288,7 +9289,7 @@ Index (line 6) * psview: Microsoft Windows. (line 16) * psviewer: Configuring. (line 6) -* psviewerOptions: Options. (line 128) +* psviewerOptions: Options. (line 129) * pt: Tutorial. (line 61) * public: Structures. (line 6) * push: Arrays. (line 39) @@ -9332,7 +9333,7 @@ Index * remainder: Mathematical functions. (line 6) * rename: Files. (line 147) -* render <1>: Options. (line 141) +* render <1>: Options. (line 142) * render: three. (line 47) * replace: Data types. (line 252) * resetdefaultpen: Pens. (line 353) @@ -9367,7 +9368,7 @@ Index * runtime imports: Import. (line 98) * Russian: unicode. (line 7) * S: Tutorial. (line 104) -* safe: Options. (line 161) +* safe: Options. (line 162) * save: Frames and pictures. (line 262) * saveline: Files. (line 130) * scale: three. (line 452) @@ -9394,7 +9395,7 @@ Index * self operators: Self & prefix operators. (line 6) * sequence: Arrays. (line 127) -* settings <1>: Options. (line 113) +* settings <1>: Options. (line 114) * settings: Configuring. (line 23) * sgn: Mathematical functions. (line 26) @@ -9424,7 +9425,7 @@ Index * SixViews: three. (line 396) * SixViewsFR: three. (line 396) * SixViewsUS: three. (line 396) -* size <1>: Options. (line 141) +* size <1>: Options. (line 142) * size <2>: three. (line 502) * size <3>: Frames and pictures. (line 43) * size: Paths and guides. (line 70) @@ -9479,9 +9480,9 @@ Index * SuppressQuiet: Pens. (line 335) * surface <1>: graph3. (line 100) * surface: three. (line 47) -* SVG: Options. (line 141) +* SVG: Options. (line 142) * SVN: Subversion. (line 6) -* system <1>: Options. (line 161) +* system <1>: Options. (line 162) * system: Files. (line 155) * syzygy: syzygy. (line 6) * tab: Files. (line 58) @@ -9499,7 +9500,7 @@ Index * tensionSpecifier: Paths and guides. (line 385) * tensor product shading: fill. (line 74) * tensorshade: fill. (line 74) -* tex <1>: Options. (line 141) +* tex <1>: Options. (line 142) * tex: Frames and pictures. (line 278) * TeX fonts: Pens. (line 201) * TeX string: Data types. (line 179) @@ -9615,7 +9616,7 @@ Index * X: three. (line 274) * xasy: GUI. (line 6) * xaxis3: graph3. (line 7) -* xelatex <1>: Options. (line 141) +* xelatex <1>: Options. (line 142) * xelatex: embed. (line 10) * xequals: graph. (line 294) * XEquals: graph. (line 280) @@ -9805,18 +9806,18 @@ Node: contour3300228 Node: slopefield300535 Node: ode301972 Node: Options302232 -Ref: configuration file308028 -Ref: settings308028 -Ref: convert309229 -Node: Interactive mode312196 -Ref: history314349 -Node: GUI315654 -Node: GUI installation316157 -Node: GUI usage317287 -Node: PostScript to Asymptote318190 -Node: Help318946 -Node: Debugger320682 -Node: Credits322467 -Node: Index323399 +Ref: configuration file308077 +Ref: settings308077 +Ref: convert309278 +Node: Interactive mode312245 +Ref: history314398 +Node: GUI315703 +Node: GUI installation316206 +Node: GUI usage317336 +Node: PostScript to Asymptote318239 +Node: Help318995 +Node: Debugger320731 +Node: Credits322516 +Node: Index323448 End Tag Table diff --git a/Build/source/utils/asymptote/entry.cc b/Build/source/utils/asymptote/entry.cc index 93fb9997054..4cf0059b340 100644 --- a/Build/source/utils/asymptote/entry.cc +++ b/Build/source/utils/asymptote/entry.cc @@ -14,7 +14,11 @@ #include "entry.h" #include "coder.h" +using types::ty; using types::signature; +using types::overloaded; +using types::ty_vector; +using types::ty_iterator; namespace trans { @@ -118,89 +122,97 @@ bool tenv::add(symbol src, symbol dest, } #ifdef NOHASH //{{{ -void venv::add(venv& source, varEntry *qualifier, coder &c) -{ - // Enter each distinct (unshadowed) name,type pair. - for(names_t::iterator p = source.names.begin(); - p != source.names.end(); - ++p) - add(p->first, p->first, source, qualifier, c); -} - -bool venv::add(symbol src, symbol dest, - venv& source, varEntry *qualifier, coder &c) -{ - bool added=false; - name_t &list=source.names[src]; - types::overloaded set; // To keep track of what is shadowed. - - for(name_iterator p = list.begin(); - p != list.end(); - ++p) { - varEntry *v=*p; - if (!equivalent(v->getType(), &set)) { - set.addDistinct(v->getType(), src->special()); - if (v->checkPerm(READ, c)) { - enter(dest, qualifyVarEntry(qualifier, v)); - added=true; - } - } - } - - return added; -} - -varEntry *venv::lookByType(symbol name, ty *t) -{ - // Find first applicable function. - name_t &list = names[name]; - for(name_iterator p = list.begin(); - p != list.end(); - ++p) { - if (equivalent((*p)->getType(), t)) - return *p; - } - return 0; -} - -void venv::list(record *module) -{ - bool where=settings::getSetting<bool>("where"); - // List all functions and variables. - for(names_t::iterator N = names.begin(); N != names.end(); ++N) { - symbol s=N->first; - name_t &list=names[s]; - for(name_iterator p = list.begin(); p != list.end(); ++p) { - if(!module || (*p)->whereDefined() == module) { - if(where) cout << (*p)->getPos(); - (*p)->getType()->printVar(cout, s); - cout << ";\n"; - } - } - } - flush(cout); -} - -ty *venv::getType(symbol name) -{ - types::overloaded set; - - // Find all applicable functions in scope. - name_t &list = names[name]; - - for(name_iterator p = list.begin(); - p != list.end(); - ++p) { - set.addDistinct((*p)->getType(), name->special()); - } - - return set.simplify(); -} +/*NOHASH*/ void venv::add(venv& source, varEntry *qualifier, coder &c) +/*NOHASH*/ { +/*NOHASH*/ // Enter each distinct (unshadowed) name,type pair. +/*NOHASH*/ for(names_t::iterator p = source.names.begin(); +/*NOHASH*/ p != source.names.end(); +/*NOHASH*/ ++p) +/*NOHASH*/ add(p->first, p->first, source, qualifier, c); +/*NOHASH*/ } +/*NOHASH*/ +/*NOHASH*/ bool venv::add(symbol src, symbol dest, +/*NOHASH*/ venv& source, varEntry *qualifier, coder &c) +/*NOHASH*/ { +/*NOHASH*/ bool added=false; +/*NOHASH*/ name_t &list=source.names[src]; +/*NOHASH*/ types::overloaded set; // To keep track of what is shadowed. +/*NOHASH*/ bool special = src.special(); +/*NOHASH*/ +/*NOHASH*/ for(name_iterator p = list.begin(); +/*NOHASH*/ p != list.end(); +/*NOHASH*/ ++p) { +/*NOHASH*/ varEntry *v=*p; +/*NOHASH*/ if (!equivalent(v->getType(), &set)) { +/*NOHASH*/ set.addDistinct(v->getType(), special); +/*NOHASH*/ if (v->checkPerm(READ, c)) { +/*NOHASH*/ enter(dest, qualifyVarEntry(qualifier, v)); +/*NOHASH*/ added=true; +/*NOHASH*/ } +/*NOHASH*/ } +/*NOHASH*/ } +/*NOHASH*/ +/*NOHASH*/ return added; +/*NOHASH*/ } +/*NOHASH*/ +/*NOHASH*/ varEntry *venv::lookByType(symbol name, ty *t) +/*NOHASH*/ { +/*NOHASH*/ // Find first applicable function. +/*NOHASH*/ name_t &list = names[name]; +/*NOHASH*/ for(name_iterator p = list.begin(); +/*NOHASH*/ p != list.end(); +/*NOHASH*/ ++p) { +/*NOHASH*/ if (equivalent((*p)->getType(), t)) +/*NOHASH*/ return *p; +/*NOHASH*/ } +/*NOHASH*/ return 0; +/*NOHASH*/ } +/*NOHASH*/ +/*NOHASH*/ void venv::list(record *module) +/*NOHASH*/ { +/*NOHASH*/ bool where=settings::getSetting<bool>("where"); +/*NOHASH*/ // List all functions and variables. +/*NOHASH*/ for(names_t::iterator N = names.begin(); N != names.end(); ++N) { +/*NOHASH*/ symbol s=N->first; +/*NOHASH*/ name_t &list=names[s]; +/*NOHASH*/ for(name_iterator p = list.begin(); p != list.end(); ++p) { +/*NOHASH*/ if(!module || (*p)->whereDefined() == module) { +/*NOHASH*/ if(where) cout << (*p)->getPos(); +/*NOHASH*/ (*p)->getType()->printVar(cout, s); +/*NOHASH*/ cout << ";\n"; +/*NOHASH*/ } +/*NOHASH*/ } +/*NOHASH*/ } +/*NOHASH*/ flush(cout); +/*NOHASH*/ } +/*NOHASH*/ +/*NOHASH*/ ty *venv::getType(symbol name) +/*NOHASH*/ { +/*NOHASH*/ types::overloaded set; +/*NOHASH*/ +/*NOHASH*/ // Find all applicable functions in scope. +/*NOHASH*/ name_t &list = names[name]; +/*NOHASH*/ bool special = name.special(); +/*NOHASH*/ +/*NOHASH*/ for(name_iterator p = list.begin(); +/*NOHASH*/ p != list.end(); +/*NOHASH*/ ++p) { +/*NOHASH*/ set.addDistinct((*p)->getType(), special); +/*NOHASH*/ } +/*NOHASH*/ +/*NOHASH*/ return set.simplify(); +/*NOHASH*/ } // }}} -#else // {{{ +#else ostream& operator<< (ostream& out, const venv::key &k) { - k.t->printVar(out, k.name); + if(k.special) + k.u.t->printVar(out, k.name); + else { + out << k.name; + if (k.u.sig) + out << *k.u.sig; + } return out; } @@ -220,117 +232,270 @@ bool venv::keyeq::operator()(const key k, const key l) const { } #else bool venv::keyeq::operator()(const key k, const key l) const { -#if 0 - cerr << "k.t = " << k.t << " " << k << endl; - cerr << "l.t = " << l.t << " " << l << endl; -#endif return k.name==l.name && - (k.name.special() ? equivalent(k.t, l.t) : - equivalent(k.t->getSignature(), - l.t->getSignature())); + (k.special ? equivalent(k.u.t, l.u.t) : + equivalent(k.u.sig, l.u.sig)); } #endif -void venv::remove(key k) { - //cerr << "removing: " << k << endl; - value *&val=all[k]; - assert(val); - if (val->next) { - val->next->shadowed=false; - value *temp=val->next; - val->next=0; - val=temp; - } - else - all.erase(k); - - // Don't erase it from scopes.top() as that will be popped of the stack at - // the end of endScope anyway. - - names[k.name].pop_front(); -} - #ifdef CALLEE_SEARCH -size_t numArgs(ty *t) { +size_t numFormals(ty *t) { signature *sig = t->getSignature(); return sig ? sig->getNumFormals() : 0; } +#endif -void checkMaxArgs(venv *ve, symbol name, size_t expected) { - size_t maxFormals = 0; - ty *t = ve->getType(name); - if (types::overloaded *o=dynamic_cast<types::overloaded *>(t)) { - for (types::ty_vector::iterator i=o->sub.begin(); i != o->sub.end(); ++i) - { - size_t n = numArgs(*i); - if (n > maxFormals) - maxFormals = n; - } - } else { - maxFormals = numArgs(t); +void venv::checkName(symbol name) +{ + // TODO: test maxFormals + + // Get the type, and make it overloaded if it is not (for uniformity). + overloaded o; + ty *t = getType(name); + if (!t) + t = &o; + if (!t->isOverloaded()) { + o.add(t); + t = &o; } - if (expected != maxFormals) { - cout << "expected: " << expected << " computed: " << maxFormals << endl; - cout << "types: " << endl; - if (types::overloaded *o=dynamic_cast<types::overloaded *>(t)) { - cout << " overloaded" << endl; - for (types::ty_vector::iterator i=o->sub.begin(); i != o->sub.end(); - ++i) - { - cout << " " << **i << endl; - } - } else { - cout << " non-overloaded" << endl; - cout << " " << *t << endl; + assert(t->isOverloaded()); + + size_t size = 0; + for (ty_iterator i = t->begin(); i != t->end(); ++i) { + varEntry *v = lookByType(name, *i); + assert(v); + assert(equivalent(v->getType(), *i)); + ++size; + } + + size_t matches = 0; + for (keymap::iterator p = all.begin(); p != all.end(); ++p) { + if (p->first.name == name) { + ++matches; + + varEntry *v=p->second.v; + assert(v); + assert(equivalent(t, v->getType())); } - cout.flush(); } - assert(expected == maxFormals); + assert(matches == size); +} + +void rightKind(ty *t) { + if (t && t->isOverloaded()) { + ty_vector& set=((overloaded *)t)->sub; + assert(set.size() > 1); + } } + +#ifdef DEBUG_CACHE +#define RIGHTKIND(t) (rightKind(t)) +#define CHECKNAME(name) (checkName(name)) +#else +#define RIGHTKIND(t) (void)(t) +#define CHECKNAME(name) (void)(name) #endif -void venv::enter(symbol name, varEntry *v) { - assert(!scopes.empty()); - key k(name, v); -#ifdef DEBUG_ENTRY - cout << "entering: " << k << " (t=" << k.t << ")" << endl; +void venv::namevalue::addType(ty *s) { + RIGHTKIND(t); + +#ifdef DEBUG_CACHE + assert(!s->isOverloaded()); +#endif + + if (t == 0) { +#if CALLEE_SEARCH + maxFormals = numFormals(s); #endif - value *val=new value(v); + t = s; + } else { + if (!t->isOverloaded()) + t = new overloaded(t); -#ifdef DEBUG_ENTRY - keymap::iterator p=all.find(k); - if (p!=all.end()) { - cout << " over: " << p->first << endl; +#ifdef DEBUG_CACHE + assert(t->isOverloaded()); + assert(!equivalent(t, s)); +#endif + + ((overloaded *)t)->add(s); + +#if CALLEE_SEARCH + size_t n = numFormals(s); + if (n > maxFormals) + maxFormals = n; +#endif } + + RIGHTKIND(t); +} + +void venv::namevalue::replaceType(ty *new_t, ty *old_t) { +#ifdef DEBUG_CACHE + assert(t != 0); + RIGHTKIND(t); #endif - val->next=all[k]; - if (val->next) - val->next->shadowed=true; + if (t->isOverloaded()) { + for (ty_iterator i = t->begin(); i != t->end(); ++i) { + if (equivalent(old_t, *i)) { + *i = new_t; + return; + } + } - all[k]=val; - scopes.top().insert(keymultimap::value_type(k,val)); + // An error, the type was not found. + assert("unreachable code" == 0); -#ifdef CALLEE_SEARCH - // I'm not sure if this works properly with rest arguments. - signature *sig = v->getSignature(); - size_t newmax = sig ? sig->getNumFormals() : 0; - mem::list<value *>& namelist = names[k.name]; - if (!namelist.empty()) { - size_t oldmax = namelist.front()->maxFormals; - if (oldmax > newmax) - newmax = oldmax; + } else { +#ifdef DEBUG_CACHE + assert(equivalent(old_t, t)); +#endif + t = new_t; } - val->maxFormals = newmax; - namelist.push_front(val); - // A sanity check, disabled for speed reasons. #ifdef DEBUG_CACHE - checkMaxArgs(this, k.name, val->maxFormals); + assert(t != 0); + RIGHTKIND(t); #endif +} + +#ifdef DEBUG_CACHE +void venv::namevalue::popType(ty *s) +#else +void venv::namevalue::popType() +#endif +{ +#ifdef DEBUG_CACHE + assert(t); + RIGHTKIND(t); + assert(!s->isOverloaded()); +#endif + + if (t->isOverloaded()) { + ty_vector& set=((overloaded *)t)->sub; + +#ifdef DEBUG_CACHE + assert(set.size() > 0); + assert(equivalent(set.back(), s)); +#endif + + // We are relying on the fact that this was the last type added to t, and + // that type are added by pushing them on the end of the vector. + set.pop_back(); + + if (set.size() == 1) + t = set.front(); + } else { +#ifdef DEBUG_CACHE + assert(equivalent(t, s)); +#endif + t = 0; + } + + RIGHTKIND(t); + + // Don't try to reduce numFormals as I doubt it is worth the cost of + // recalculating. +} + +void venv::remove(const addition& a) { + CHECKNAME(a.k.name); + + value &val=all[a.k]; + +#ifdef DEBUG_CACHE + assert(val); +#endif + + if (a.shadowed) { + // Unshadow the previously shadowed varEntry. + names[a.k.name].replaceType(a.shadowed->getType(), val.v->getType()); + val.v = a.shadowed; + } else { + // Remove the (name,sig) key completely. +#if DEBUG_CACHE + names[a.k.name].popType(val.v->getType()); #else - names[k.name].push_front(val); + names[a.k.name].popType(); #endif + all.erase(a.k); + } + + CHECKNAME(a.k.name); +} + +void venv::beginScope() { + if (all.empty()) { + assert(scopesizes.empty()); + ++empty_scopes; + } else { + scopesizes.push(additions.size()); + } +} + +void venv::endScope() { + if (scopesizes.empty()) { + // The corresponding beginScope happened when the venv was empty, so + // clear the hash tables to return to that state. + all.clear(); + names.clear(); + + assert(empty_scopes > 0); + --empty_scopes; + } else { + size_t scopesize = scopesizes.top(); + assert(additions.size() >= scopesize); + while (additions.size() > scopesize) { + remove(additions.top()); + additions.pop(); + } + scopesizes.pop(); + } +} + +// Adds the definitions of the top-level scope to the level underneath, +// and then removes the top scope. +void venv::collapseScope() { + if (scopesizes.empty()) { + // Collapsing an empty scope. + assert(empty_scopes > 0); + --empty_scopes; + } else { + scopesizes.pop(); + } +} + + +void venv::enter(symbol name, varEntry *v) +{ + CHECKNAME(name); + + key k(name, v); + + value &slot=all[k]; + if (slot.v) { + // The new value shadows an old value. They have the same signature, but + // possibly different return types. If necessary, update the type stored + // by name. + names[name].replaceType(v->getType(), slot.v->getType()); + + // Replace the old value, but store its now-shadowed varEntry. + if (!scopesizes.empty()) + additions.push(addition(k, slot.v)); + + slot.v = v; + + } else { + // Add to the names hash table. + names[name].addType(v->getType()); + + if (!scopesizes.empty()) + additions.push(addition(k, 0)); + + slot.v=v; + } + + CHECKNAME(name); } @@ -353,15 +518,10 @@ varEntry *venv::lookBySignature(symbol name, signature *sig) { return 0; } - mem::list<value *>& namelist = names[name]; - if (namelist.empty()) { - // No variables of this name. - //cout << "FAIL BY EMPTY" << endl; - return 0; - } + namevalue& nv = names[name]; // Avoid ambiguities with default parameters. - if (namelist.front()->maxFormals != sig->getNumFormals()) { + if (nv.maxFormals != sig->getNumFormals()) { #if 0 if (lookByType(key(name, sig))) cout << "FAIL BY NUMARGS" << endl; @@ -390,7 +550,7 @@ void venv::add(venv& source, varEntry *qualifier, coder &c) { // Enter each distinct (unshadowed) name,type pair. for(keymap::iterator p = source.all.begin(); p != source.all.end(); ++p) { - varEntry *v=p->second->v; + varEntry *v=p->second.v; if (v->checkPerm(READ, c)) enter(p->first.name, qualifyVarEntry(qualifier, v)); } @@ -399,68 +559,75 @@ void venv::add(venv& source, varEntry *qualifier, coder &c) bool venv::add(symbol src, symbol dest, venv& source, varEntry *qualifier, coder &c) { - bool added=false; - values &list=source.names[src]; - - for (values::iterator p=list.begin(); p!=list.end(); ++p) - if (!(*p)->shadowed) { - varEntry *v=(*p)->v; + ty *t=source.getType(src); + if (!t) + return false; + else if (t->isOverloaded()) { + bool added=false; + for (ty_iterator i = t->begin(); i != t->end(); ++i) { + varEntry *v=source.lookByType(src, *i); if (v->checkPerm(READ, c)) { enter(dest, qualifyVarEntry(qualifier, v)); added=true; } } - - return added; + return added; + } else { + varEntry *v=source.lookByType(src, t); + if (v->checkPerm(READ, c)) { + enter(dest, qualifyVarEntry(qualifier, v)); + return true; + } + return false; + } } ty *venv::getType(symbol name) { -#if 0 - cout << "getType: " << name << endl; -#endif - types::overloaded set; - values &list=names[name]; + return names[name].t; +} + +void listValue(symbol name, varEntry *v, record *module) +{ + if (!module || v->whereDefined() == module) + { + if (settings::getSetting<bool>("where")) + cout << v->getPos(); - for (values::iterator p=list.begin(); p!=list.end(); ++p) - if (!(*p)->shadowed) - set.add((*p)->v->getType()); + v->getType()->printVar(cout, name); - return set.simplify(); + cout << ";\n"; + } } -void venv::listValues(symbol name, values &vals, record *module) +void venv::listValues(symbol name, record *module) { - ostream& out=cout; - - bool where=settings::getSetting<bool>("where"); - for(values::iterator p = vals.begin(); p != vals.end(); ++p) { - if(!module || (*p)->v->whereDefined() == module) { - if(where) out << (*p)->v->getPos(); - if ((*p)->shadowed) - out << " <shadowed> "; - (*p)->v->getType()->printVar(out, name); - out << ";\n"; - } - } - flush(out); + ty *t=getType(name); + + if (t->isOverloaded()) + for (ty_iterator i = t->begin(); i != t->end(); ++i) + listValue(name, lookByType(name, *i), module); + else + listValue(name, lookByType(name, t), module); + + flush(cout); } void venv::list(record *module) { // List all functions and variables. - for(namemap::iterator N = names.begin(); N != names.end(); ++N) - listValues(N->first, N->second,module); + for (namemap::iterator N = names.begin(); N != names.end(); ++N) + listValues(N->first, module); } void venv::completions(mem::list<symbol >& l, string start) { for(namemap::iterator N = names.begin(); N != names.end(); ++N) - if (prefix(start, N->first) && !N->second.empty()) + if (prefix(start, N->first) && N->second.t) l.push_back(N->first); } -#endif // }}} +#endif } // namespace trans diff --git a/Build/source/utils/asymptote/entry.h b/Build/source/utils/asymptote/entry.h index d465046961c..bffec3aa6aa 100644 --- a/Build/source/utils/asymptote/entry.h +++ b/Build/source/utils/asymptote/entry.h @@ -180,74 +180,88 @@ public: }; #ifdef NOHASH //{{{ -class venv : public sym::table<varEntry*> { - /* This version of venv is provided for compiling on systems which do not - * have some form of STL hash table. It will eventually be removed. - * See the hash version below for documentation on the functions. - */ -public: - venv() {} - - struct file_env_tag {}; - venv(file_env_tag) {} - - void add(venv& source, varEntry *qualifier, coder &c); - - bool add(symbol src, symbol dest, - venv& source, varEntry *qualifier, coder &c); - - varEntry *lookByType(symbol name, ty *t); - - varEntry *lookBySignature(symbol name, signature *sig) { - // This optimization is not implemented for the NOHASH version. - return 0; - } - - ty *getType(symbol name); - - friend std::ostream& operator<< (std::ostream& out, const venv& ve); - - void list(record *module=0); -}; + /* This version of venv is provided for compiling on systems which do not + * have some form of STL hash table. It will eventually be removed. + * See the hash version below for documentation on the functions. + */ +/*NOHASH*/ class venv : public sym::table<varEntry*> { +/*NOHASH*/ public: +/*NOHASH*/ venv() {} +/*NOHASH*/ +/*NOHASH*/ struct file_env_tag {}; +/*NOHASH*/ venv(file_env_tag) {} +/*NOHASH*/ +/*NOHASH*/ void add(venv& source, varEntry *qualifier, coder &c); +/*NOHASH*/ +/*NOHASH*/ bool add(symbol src, symbol dest, +/*NOHASH*/ venv& source, varEntry *qualifier, coder &c); +/*NOHASH*/ +/*NOHASH*/ varEntry *lookByType(symbol name, ty *t); +/*NOHASH*/ +/*NOHASH*/ varEntry *lookBySignature(symbol name, signature *sig) { +/*NOHASH*/ // This optimization is not implemented for the NOHASH version. +/*NOHASH*/ return 0; +/*NOHASH*/ } +/*NOHASH*/ +/*NOHASH*/ ty *getType(symbol name); +/*NOHASH*/ +/*NOHASH*/ friend std::ostream& operator<< (std::ostream& out, +/*NOHASH*/ const venv& ve); +/*NOHASH*/ +/*NOHASH*/ void list(record *module=0); +/*NOHASH*/ }; //}}} -#else //{{{ +#else // venv implemented with a hash table. class venv { struct key : public gc { symbol name; - ty *t; + bool special; + union { + ty *t; + signature *sig; + } u; + + //key(key& k) : name(k.name), special(k.special), u(k.u) {} key(symbol name, ty *t) - : name(name), t(t) {} + : name(name), special(name.special()) + { + if (special) + u.t = t; + else + u.sig = t->getSignature(); + } /* A fake key used for searching just based on a signature. */ key(symbol name, signature *sig) - : name(name), t(new types::function(types::primError(), sig)) + : name(name), special(false) { assert(!name.special()); + u.sig = sig; } key(symbol name, varEntry *v) - : name(name), t(v->getType()) {} + : name(name), special(name.special()) + { + ty *t = v->getType(); + if (special) + u.t = t; + else + u.sig = t->getSignature(); + } }; friend ostream& operator<< (ostream& out, const venv::key &k); struct value : public gc { varEntry *v; - bool shadowed; - value *next; // The entry (of the same key) that this one shadows. - -#ifdef CALLEE_SEARCH - // The maximum number of formals in any of the overloaded functions of - // this name (at the time this value was entered). - size_t maxFormals; -#endif - value(varEntry *v) - : v(v), shadowed(false), next(0) {} + : v(v) {} + value() : v(0) {} }; + struct namehash { size_t operator()(const symbol name) const { return name.hash(); @@ -259,13 +273,12 @@ class venv { } }; struct keyhash { - size_t hashSig(ty *t) const { - signature *sig=t->getSignature(); + size_t hashSig(signature *sig) const { return sig ? sig->hash() : 0; } size_t operator()(const key k) const { return k.name.hash() * 107 + - (k.name.special() ? k.t->hash() : hashSig(k.t)); + (k.special ? k.u.t->hash() : hashSig(k.u.sig)); } }; struct keyeq { @@ -273,9 +286,8 @@ class venv { #if TEST_COLLISION bool base(const key k, const key l) const { return k.name==l.name && - (k.name->special() ? equivalent(k.t, l.t) : - equivalent(k.t->getSignature(), - l.t->getSignature())); + (k.special ? equivalent(k.u.t, l.u.t) : + equivalent(k.u.sig, l.u.sig)); } bool operator()(const key k, const key l) const; #else @@ -286,32 +298,67 @@ class venv { // A hash table used to quickly look up a variable once its name and type are // known. Includes all scopes. - typedef mem::unordered_map<key, value *, keyhash, keyeq> keymap; + typedef mem::unordered_map<key, value, keyhash, keyeq> keymap; keymap all; - // Similar hashes, one for each scope level. - typedef mem::unordered_multimap<key, value *, keyhash, keyeq> keymultimap; - typedef mem::stack<keymultimap> mapstack; - mapstack scopes; + // Record of added variables in the order they were added. + struct addition { + key k; + varEntry *shadowed; + + addition(key k, varEntry *shadowed) : k(k), shadowed(shadowed) {} + }; + typedef mem::stack<addition> addstack; + addstack additions; + + // A scope can be recorded by the size of the addition stack at the time the + // scope began. + typedef mem::stack<size_t> scopestack; + scopestack scopesizes; + + struct namevalue { +#ifdef CALLEE_SEARCH + size_t maxFormals; +#endif + ty *t; + + namevalue() : maxFormals(0), t(0) {} - // A hash table indexed solely on the name, storing for each name the list of - // all values of that name. Used to get the (possibly overloaded) type - // of the name. - typedef mem::list<value *> values; - typedef mem::unordered_map<symbol, values, namehash, nameeq> namemap; + void addType(ty *s); + + void replaceType(ty *new_t, ty *old_t); + +#if DEBUG_CACHE + void popType(ty *tnew); +#else + void popType(); +#endif + }; + + // A hash table indexed solely on the name, storing for each name the + // current (possibly overloaded) type of the name. + typedef mem::unordered_map<symbol, namevalue, namehash, nameeq> namemap; namemap names; - void listValues(symbol name, values &vals, record *module); + // A sanity check. For a given name, it checks that the type stored in the + // names hash table exactly matches with all of the entries of that name + // stored in the full hash table. + void checkName(symbol name); + + void listValues(symbol name, /*values &vals,*/ record *module); // Helper function for endScope. - void remove(key k); + void remove(const addition& a); // These are roughly the size the hashtables will be after loading the // builtin functions and plain module. static const size_t fileAllSize=2000; static const size_t namesAllSize=1000; + + // The number of scopes begun (but not yet ended) when the venv was empty. + size_t empty_scopes; public: - venv() { + venv() : empty_scopes(0) { beginScope(); } @@ -319,7 +366,7 @@ public: // big enough to hold it in advance. struct file_env_tag {}; venv(file_env_tag) - : all(fileAllSize), names(namesAllSize) + : all(fileAllSize), names(namesAllSize), empty_scopes(0) { beginScope(); } @@ -339,7 +386,7 @@ public: varEntry *lookByType(key k) { keymap::const_iterator p=all.find(k); - return p!=all.end() ? p->second->v : 0; + return p!=all.end() ? p->second.v : 0; } // Look for a function that exactly matches the type given. @@ -363,27 +410,12 @@ public: ty *getType(symbol name); - void beginScope() { - scopes.push(keymultimap()); - } - void endScope() { - keymultimap &scope=scopes.top(); - for (keymultimap::iterator p=scope.begin(); p!=scope.end(); ++p) { - remove(p->first); - } - scopes.pop(); - } + void beginScope(); + void endScope(); // Adds the definitions of the top-level scope to the level underneath, // and then removes the top scope. - void collapseScope() { - // NOTE: May be expensively copying a large hash table. - keymultimap top=scopes.top(); - scopes.pop(); - - keymultimap& underneath=scopes.top(); - underneath.insert(top.begin(), top.end()); - } + void collapseScope(); // Prints a list of the variables to the standard output. void list(record *module=0); diff --git a/Build/source/utils/asymptote/env.cc b/Build/source/utils/asymptote/env.cc index 6eedb8bec66..91edfd41754 100644 --- a/Build/source/utils/asymptote/env.cc +++ b/Build/source/utils/asymptote/env.cc @@ -96,6 +96,7 @@ bool protoenv::fastCastable(ty *target, ty *source) { // To avoid memory allocation, fill one static variable with new parameters // in each call. + // Warning: This is not re-entrant if asy ever goes multi-threaded. static types::function castFunc(primVoid(), primVoid()); castFunc.result = target; @@ -130,6 +131,25 @@ bool protoenv::fastCastable(ty *target, ty *source) { // routine. return source->kind == ty_null && target->isReference(); } + +access *protoenv::fastLookupCast(ty *target, ty *source) { + assert(target->kind != types::ty_overloaded); + assert(target->kind != types::ty_error); + assert(source->kind != types::ty_overloaded); + assert(source->kind != types::ty_error); + + // Warning: This is not re-entrant. + static types::function castFunc(primVoid(), primVoid()); + castFunc.result = target; + castFunc.sig.formals[0].t = source; + + varEntry *ve = lookupVarByType(symbol::castsym, &castFunc); + if (ve) + return ve->getLocation(); + + // Fall back on slow routine. + return lookupCast(target, source, symbol::castsym); +} #endif diff --git a/Build/source/utils/asymptote/env.h b/Build/source/utils/asymptote/env.h index 40569dd5390..8146fa813e8 100644 --- a/Build/source/utils/asymptote/env.h +++ b/Build/source/utils/asymptote/env.h @@ -99,11 +99,13 @@ public: access *lookupCast(ty *target, ty *source, symbol name); bool castable(ty *target, ty *source, symbol name); - #ifdef FASTCAST // A cast lookup designed to work quickly with the application matching // code. The target type must not be overloaded. bool fastCastable(ty *target, ty *source); + + // For the lookup, neither target nor source may be overloaded. + access *fastLookupCast(ty *target, ty *source); #endif // Given overloaded types, this resolves which types should be the target and diff --git a/Build/source/utils/asymptote/examples/animations/torusanimation.asy b/Build/source/utils/asymptote/examples/animations/torusanimation.asy index 8370a0c25af..74a5df43278 100644 --- a/Build/source/utils/asymptote/examples/animations/torusanimation.asy +++ b/Build/source/utils/asymptote/examples/animations/torusanimation.asy @@ -1,44 +1,43 @@ -import graph3; -import animation; +import graph3; +import animation; import solids; -settings.tex="pdflatex"; -settings.prc=false; -settings.render=4; - -currentprojection=orthographic((0,5,2)); -currentlight=(0,5,5); -unitsize(1cm); - -real R=3; -real a=1; -int n=8; +currentprojection=perspective(50,40,20); + +currentlight=(0,5,5); + +real R=3; +real a=1; +int n=8; -path3[] p=new path3[n]; -animation A; +path3[] p=new path3[n]; +animation A; -for(int i=0; i < n; ++i) { - triple g(real s) { - return ((R-a*cos(2*pi*s))*cos(2*pi/(1+i+s)), - (R-a*cos(2*pi*s))*sin(2*pi/(1+i+s)), - -a*sin(2*pi*s)); +for(int i=0; i < n; ++i) { + triple g(real s) { + real twopi=2*pi; + real u=twopi*s; + real v=twopi/(1+i+s); + real cosu=cos(u); + return((R-a*cosu)*cos(v),(R-a*cosu)*sin(v),-a*sin(u)); } - p[i]=graph(g,0,1,operator ..); + p[i]=graph(g,0,1,operator ..); } triple f(pair t) { - return ((R+a*cos(t.y))*cos(t.x),(R+a*cos(t.y))*sin(t.x),a*sin(t.y)); + real costy=cos(t.y); + return((R+a*costy)*cos(t.x),(R+a*costy)*sin(t.x),a*sin(t.y)); } surface s=surface(f,(0,0),(2pi,2pi),8,8,Spline); -for(int i=0; i < n; ++i){ - picture fig; - size3(fig,400); - draw(fig,s,yellow); - for(int j=0;j <= i; ++j) - draw(fig,p[j],blue+linewidth(4)); - A.add(fig); +for(int i=0; i < n; ++i){ + picture fig; + size(fig,20cm); + draw(fig,s,yellow); + for(int j=0; j <= i; ++j) + draw(fig,p[j],blue+linewidth(4)); + A.add(fig); } A.movie(BBox(10,Fill(rgb(0.98,0.98,0.9))),delay=100); diff --git a/Build/source/utils/asymptote/examples/xstitch.asy b/Build/source/utils/asymptote/examples/xstitch.asy new file mode 100644 index 00000000000..6e692643ae1 --- /dev/null +++ b/Build/source/utils/asymptote/examples/xstitch.asy @@ -0,0 +1,169 @@ +pair c=(0,0.8); + +int iters(pair z, int max=160) { + int n=0; + while(abs(z) < 2 && n < max) { + z=z*z+c; + ++n; + } + return n; +} + +int[] cutoffs={12,15,20,30,40,60,200}; +int key(pair z) { + int i=iters(z); + int j=0; + while(cutoffs[j] < i) + ++j; + return j; +} + + +int width=210; +int height=190; + +real zoom=2.5/200; + +int[][] values=new int[width][height]; +int[] histogram; for(int v=0; v < 10; ++v) histogram.push(0); +for(int i=0; i < width; ++i) { + real x=zoom*(i-width/2); + for(int j=0; j < height; ++j) { + real y=zoom*(j-height/2); + int v=key((x,y)); + values[i][j]=v; + ++histogram[v]; + } +} + +// Print out a histogram. +write("histogram: "); +write(histogram); + + +pen linepen(int i, int max) { + real w=i == -1 || i == max+1 ? 2.0 : + i % 10 == 0 || i == max ? 1.0 : + i % 5 == 0 ? 0.8 : + 0.25; + return linewidth(w); +} + +pen xpen(int i) { + return linepen(i,width)+(i == width/2 ? red : + i == 75 || i == width-75 ? dashed : + black); +} + +pen ypen(int i) { + return linepen(i,height)+(i == height/2 ? red : + i == 75 || i == height-75 ? dashed : + black); +} + +// The length of the side of a cross stitch cell. +real cell=2.3mm; +transform t=scale(cell); + + +picture tick; +draw(tick,(0,0)--(1,1)); + +picture ell; +draw(ell,(0,1)--(0,0)--(0.7,0)); + +picture cross; +draw(cross,(0,0)--(1,1)); +draw(cross,(1,0)--(0,1)); + +picture star; +draw(star,(0.15,0.15)--(0.85,0.85)); +draw(star,(0.85,0.15)--(0.15,0.85)); +draw(star,(.5,0)--(.5,1)); +draw(star,(0,.5)--(1,.5)); + +picture triangle; +draw(triangle,(0,0)--(2,0)--(1,1.5)--cycle); + +picture circle; +fill(circle,shift(1,1)*unitcircle); + +picture ocircle; +draw(ocircle,shift(1,1)*unitcircle); + +picture spare; +fill(spare,(0,0)--(1,1)--(0,1)--cycle); + +picture[] pics={tick,ell,cross,star,triangle,circle}; +pen[] colors={black,0.2purple,0.4purple,0.6purple,0.8purple,purple, + 0.8purple+0.2white}; + +frame[] icons; +icons.push(newframe); +for(picture pic : pics) { + // Scaling factor, so that we don't need weird line widths. + real X=1.0; + frame f=pic.fit(.8X*cell,.8X*cell,Aspect); + f=scale(1/X)*f; + + // Center the icon in the cell. + f=shift((cell/2,cell/2)-0.5(max(f)-min(f)))*f; + + icons.push(f); +} + +void drawSection(int xmin, int xmax, int ymin, int ymax) { + static int shipoutNumber=0; + + // Draw directly to a frame for speed reasons. + frame pic; + + for(int i=xmin; i <= xmax; ++i) { + draw(pic,t*((i,ymin)--(i,ymax)),xpen(i)); + if(i%10 == 0) { + label(pic,string(i),t*(i,ymin),align=S); + label(pic,string(i),t*(i,ymax),align=N); + } + } + for(int j=ymin; j <= ymax; ++j) { + draw(pic,t*((xmin,j)--(xmax,j)),ypen(j)); + if(j%10 == 0) { + label(pic,string(j),t*(xmin,j),align=W); + label(pic,string(j),t*(xmax,j),align=E); + } + } + + if(xmin < 0) + xmin=0; + if(xmax >= width) + xmax=width-1; + if(ymin < 0) + ymin=0; + if(ymax >= height) + ymax=height-1; + + int stitchCount=0; + path box=scale(cell) *((0,0)--(1,0)--(1,1)--(0,1)--cycle); + for(int i=xmin; i < xmax; ++i) + for(int j=ymin; j < ymax; ++j) { + int v=values[i][j]; + add(pic,icons[v],(i*cell,j*cell)); + //fill(pic,shift(i*cell,j*cell)*box,colors[v]); + if(v != 0) + ++stitchCount; + } + + write("stitch count: ",stitchCount); + + shipout("xstitch"+string(shipoutNumber),pic); + ++shipoutNumber; +} + +drawSection(-1,width+1,-1,height+1); + + +//drawSection(-1,80,height-80,height+1); +//drawSection(70,150,height-80,height+1); +drawSection(quotient(width,2)-40,quotient(width,2)+40,quotient(height,2)-40,quotient(height,2)+40); +//drawSection(width-150,width-70,-1,80); +//drawSection(width-80,width+1,-1,80); 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) { diff --git a/Build/source/utils/asymptote/exp.h b/Build/source/utils/asymptote/exp.h index f3d086dcba3..fa4e464a5b4 100644 --- a/Build/source/utils/asymptote/exp.h +++ b/Build/source/utils/asymptote/exp.h @@ -675,11 +675,11 @@ public: return args.size(); } - virtual argument operator[] (size_t index) { + virtual argument& operator[] (size_t index) { return args[index]; } - virtual argument getRest() { + virtual argument& getRest() { return rest; } }; @@ -718,8 +718,9 @@ private: // Caches either the application object used to apply the function to the // arguments, or in cases where the arguments match the function perfectly, - // the varEntry of the callee. - void cacheAppOrVarEntry(coenv &e, bool tacit); + // the varEntry of the callee (or neither in case of an error). Returns + // what getType should return. + types::ty *cacheAppOrVarEntry(coenv &e, bool tacit); types::ty *transPerfectMatch(coenv &e); public: diff --git a/Build/source/utils/asymptote/glrender.cc b/Build/source/utils/asymptote/glrender.cc index c56a8b82219..5effe0f5f57 100644 --- a/Build/source/utils/asymptote/glrender.cc +++ b/Build/source/utils/asymptote/glrender.cc @@ -608,7 +608,11 @@ void screen() void nextframe(int) { + glFinish(); endwait(readySignal,readyLock); + double framedelay=getSetting<double>("framedelay"); + if(framedelay > 0) + usleep(1000.0*framedelay); if(Step) Animate=false; } @@ -630,6 +634,8 @@ void display() ((double) tv.tv_usec-lastframetime.tv_usec)/1000000.0; lastframetime=tv; double milliseconds=1000.0*(delay-seconds); + double framedelay=getSetting<double>("framedelay"); + if(framedelay > 0) milliseconds -= framedelay; if(milliseconds > 0) glutTimerFunc((int) (milliseconds+0.5),nextframe,0); else nextframe(0); diff --git a/Build/source/utils/asymptote/item.h b/Build/source/utils/asymptote/item.h index 2e3fb090eb7..27b8787df9d 100644 --- a/Build/source/utils/asymptote/item.h +++ b/Build/source/utils/asymptote/item.h @@ -74,13 +74,13 @@ public: template<class T> item(T *p) : p((void *) p) { - assert(p < (void *) Undefined); + assert(!empty()); } template<class T> item(const T &P) : p(new(UseGC) T(P)) { - assert(p < (void *) Undefined); + assert(!empty()); } template<class T> diff --git a/Build/source/utils/asymptote/knot.cc b/Build/source/utils/asymptote/knot.cc index 0180c4c6b2d..199be8249bf 100644 --- a/Build/source/utils/asymptote/knot.cc +++ b/Build/source/utils/asymptote/knot.cc @@ -18,7 +18,7 @@ namespace camp { //bool tracing_solving=false; template <typename T> -ostream& info(ostream& o, string name, cvector<T>& v) +ostream& info(ostream& o, const char *name, cvector<T>& v) { if (settings::verbose > 3) { o << name << ":\n\n"; diff --git a/Build/source/utils/asymptote/lex.yy.cc b/Build/source/utils/asymptote/lex.yy.cc index 935c7b382dd..5422374042f 100644 --- a/Build/source/utils/asymptote/lex.yy.cc +++ b/Build/source/utils/asymptote/lex.yy.cc @@ -881,7 +881,7 @@ void adjust() void savesymbol(symbol name) { adjust(); - yylval.ps.pos=here(); + yylval.ps.pos=yylval.pos; // avoid invoking here() twice yylval.ps.sym=name; } diff --git a/Build/source/utils/asymptote/settings.cc b/Build/source/utils/asymptote/settings.cc index 4ea29ebabe5..2a8e723e308 100644 --- a/Build/source/utils/asymptote/settings.cc +++ b/Build/source/utils/asymptote/settings.cc @@ -1237,10 +1237,12 @@ void initSettings() { 1.05)); addOption(new realSetting("zoomstep", 0, "step", "Mouse motion zoom step", 0.1)); - addOption(new realSetting("spinstep", 0, "deg/sec", "Spin speed", + addOption(new realSetting("spinstep", 0, "deg/s", "Spin speed", 60.0)); - addOption(new realSetting("framerate", 0, "frames/sec", "Animation speed", + addOption(new realSetting("framerate", 0, "frames/s", "Animation speed", 30.0)); + addOption(new realSetting("framedelay", 0, "ms", + "Additional frame delay", 0.0)); addOption(new realSetting("arcballradius", 0, "pixels", "Arcball radius", 750.0)); addOption(new realSetting("resizestep", 0, "step", "Resize step", 1.2)); diff --git a/Build/source/utils/asymptote/tests/gc/pen.asy b/Build/source/utils/asymptote/tests/gc/pen.asy index 7b8d48dfcec..691cf6dea8a 100644 --- a/Build/source/utils/asymptote/tests/gc/pen.asy +++ b/Build/source/utils/asymptote/tests/gc/pen.asy @@ -1,4 +1,4 @@ for (int i = 0; i < 1e7; ++i) { - pen p = linetype("test"); + pen p = linetype(new real[] {1,2}); } diff --git a/Build/source/utils/asymptote/tests/types/resolve.asy b/Build/source/utils/asymptote/tests/types/resolve.asy index 83dd797e7cc..b668b15490f 100644 --- a/Build/source/utils/asymptote/tests/types/resolve.asy +++ b/Build/source/utils/asymptote/tests/types/resolve.asy @@ -147,6 +147,10 @@ assert(g(y=4.4, 4.4) == 7); assert(!(f != g)); assert(!(g != f)); } +{ +void foo() {} +assert((foo == null ? 5 : 8) == 8); +} // TODO: Add packing vs. casting tests. diff --git a/Build/source/utils/asymptote/types.cc b/Build/source/utils/asymptote/types.cc index f03cca2edb2..83ac6f5a597 100644 --- a/Build/source/utils/asymptote/types.cc +++ b/Build/source/utils/asymptote/types.cc @@ -335,8 +335,7 @@ ostream& operator<< (ostream& out, const formal& f) bool equivalent(formal& f1, formal& f2) { // Just test the types. - // This will also return true for the rest parameter if both types are null. - // NOTE: Is this the right behavior? + // This cannot be used on rest formal with types equal to NULL. return equivalent(f1.t,f2.t); } @@ -402,9 +401,14 @@ bool equivalent(signature *s1, signature *s2) if (s1->formals.size() != s2->formals.size()) return false; - return std::equal(s1->formals.begin(),s1->formals.end(),s2->formals.begin(), - (bool (*)(formal&,formal&)) equivalent) && - equivalent(s1->rest, s2->rest); + if (!std::equal(s1->formals.begin(),s1->formals.end(),s2->formals.begin(), + (bool (*)(formal&,formal&)) equivalent)) + return false; + + if (s1->rest.t) + return s2->rest.t && equivalent(s1->rest, s2->rest); + else + return s1->rest.t == 0; } bool argumentEquivalent(signature *s1, signature *s2) @@ -502,20 +506,24 @@ bool equivalent(ty *t1, ty *t2) if (t1 == t2) return true; - // Handle empty types (used in equating empty rest parameters). - if (t1 == 0 || t2 == 0) - return false; - // Ensure if an overloaded type is compared to a non-overloaded one, that the // overloaded type's method is called. - if (t1->kind == ty_overloaded || t2->kind != ty_overloaded) + if (t2->kind == ty_overloaded) + return t2->equiv(t1); + if (t1->kind == ty_overloaded) return t1->equiv(t2); - return t2->equiv(t1); + + // Outside of overloaded types, different kinds mean different types. + if (t1->kind != t2->kind) + return false; + + return t1->equiv(t2); } + bool equivalent(ty *t1, ty *t2, bool special) { return special ? equivalent(t1, t2) : - equivalent(t1->getSignature(), t2->getSignature()); + equivalent(t1->getSignature(), t2->getSignature()); } #undef FIELD diff --git a/Build/source/utils/asymptote/types.h b/Build/source/utils/asymptote/types.h index 4d3c0bd5d81..0bc40863727 100644 --- a/Build/source/utils/asymptote/types.h +++ b/Build/source/utils/asymptote/types.h @@ -471,9 +471,14 @@ struct function : public ty { class overloaded : public ty { public: ty_vector sub; + + // Warning: The venv endScope routine relies heavily on the current + // implementation of overloaded. public: overloaded() : ty(ty_overloaded) {} + overloaded(ty *t) + : ty(ty_overloaded) { add(t); } virtual ~overloaded() {} bool equiv(ty *other) |