diff options
author | Karl Berry <karl@freefriends.org> | 2011-05-28 02:18:52 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2011-05-28 02:18:52 +0000 |
commit | c59fe5fe4739f0c61560f05d4e42b4e552219b27 (patch) | |
tree | 8cf79e85e394b3177a28d374415840a4e0a025ad /Build/source/utils/asymptote/builtin.cc | |
parent | 771db15706dbf3f4af8b630dcb15646a3e5fda00 (diff) |
asy 2.10
git-svn-id: svn://tug.org/texlive/trunk@22633 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/builtin.cc')
-rw-r--r-- | Build/source/utils/asymptote/builtin.cc | 111 |
1 files changed, 84 insertions, 27 deletions
diff --git a/Build/source/utils/asymptote/builtin.cc b/Build/source/utils/asymptote/builtin.cc index 4a8ed9c2216..b5066061384 100644 --- a/Build/source/utils/asymptote/builtin.cc +++ b/Build/source/utils/asymptote/builtin.cc @@ -42,6 +42,11 @@ #include "builtin.symbols.h" #endif +namespace vm { + // Defined in stack.cc + extern vm::frame *make_dummyframe(string name); +} + using namespace types; using namespace camp; using namespace vm; @@ -90,7 +95,7 @@ void base_tenv(tenv &te) const formal noformal(0); -void addFunc(venv &ve, access *a, ty *result, symbol id, +function *functionFromFormals(ty *result, formal f1=noformal, formal f2=noformal, formal f3=noformal, formal f4=noformal, formal f5=noformal, formal f6=noformal, formal f7=noformal, formal f8=noformal, formal f9=noformal, @@ -119,6 +124,20 @@ void addFunc(venv &ve, access *a, ty *result, symbol id, if (fH.t) fun->add(fH); if (fI.t) fun->add(fI); + return fun; +} + +void addFunc(venv &ve, access *a, ty *result, symbol id, + formal f1=noformal, formal f2=noformal, formal f3=noformal, + formal f4=noformal, formal f5=noformal, formal f6=noformal, + formal f7=noformal, formal f8=noformal, formal f9=noformal, + formal fA=noformal, formal fB=noformal, formal fC=noformal, + formal fD=noformal, formal fE=noformal, formal fF=noformal, + formal fG=noformal, formal fH=noformal, formal fI=noformal) +{ + function *fun = functionFromFormals(result,f1,f2,f3,f4,f5,f6,f7,f8,f9, + fA,fB,fC,fD,fE,fF,fG,fH,fI); + // NOTE: If the function is a field, we should encode the defining record in // the entry varEntry *ent = new varEntry(fun, a, 0, position()); @@ -132,7 +151,25 @@ void addFunc(venv &ve, bltin f, ty *result, symbol name, formal f7, formal f8, formal f9, formal fA, formal fB, formal fC, formal fD, formal fE, formal fF, formal fG, formal fH, formal fI) { - REGISTER_BLTIN(f, name); +#ifdef DEBUG_BLTIN + // If the function is an operator, print out the whole signature with the + // types, as operators are heavily overloaded. min and max are also heavily + // overloaded, so we check for them too. Many builtin functions have so + // many arguments that it is noise to print out their full signatures. + string s = name; + if (s.find("operator ", 0) == 0 || s == "min" || s == "max") + { + function *fun = functionFromFormals(result,f1,f2,f3,f4,f5,f6,f7,f8,f9, + fA,fB,fC,fD,fE,fF,fG,fH,fI); + ostringstream out; + fun->printVar(out, name); + REGISTER_BLTIN(f, out.str()); + } + else { + REGISTER_BLTIN(f, name); + } +#endif + access *a = new bltinAccess(f); addFunc(ve,a,result,name,f1,f2,f3,f4,f5,f6,f7,f8,f9, fA,fB,fC,fD,fE,fF,fG,fH,fI); @@ -544,13 +581,11 @@ void addArrayOps(venv &ve, types::array *t) { ty *ct = t->celltype; -#ifdef TEST_ADDED_OPS // Check for the alias function to see if these operation have already been // added, if they have, don't add them again. static types::function aliasType(primBoolean(), primVoid(), primVoid()); aliasType.sig.formals[0].t = t; aliasType.sig.formals[1].t = t; -#endif if (ve.lookByType(SYM(alias), &aliasType)) return; @@ -559,17 +594,16 @@ void addArrayOps(venv &ve, types::array *t) primBoolean(), SYM(alias), formal(t, SYM(a)), formal(t, SYM(b))); size_t depth=(size_t) t->depth(); - typedef void (*stackFcn)(stack *Stack); - static stackFcn routine[]={run::copyArray0,run::copyArray1,run::copyArray2}; - - size_t ndepth=sizeof(routine)/sizeof(stackFcn); - - if(depth <= ndepth) { - addFunc(ve, routine[depth-1], - t, SYM(array), formal(primInt(), SYM(n)), - formal(ct, SYM(value)), - formal(primInt(), SYM(depth), true)); - } + + // Define an array constructor. This needs to know the depth of the array, + // which may not be known at runtime. Therefore, the depth, which is known + // here at compile-time, is pushed on the stack beforehand by use of a + // thunk. + callable *copyFunc = new thunk(new vm::bfunc(run::copyArray),(Int) depth-1); + addFunc(ve, new callableAccess(copyFunc), + t, SYM(array), formal(primInt(), SYM(n)), + formal(ct, SYM(value)), + formal(primInt(), SYM(depth), true)); switch (depth) { case 1: @@ -614,14 +648,7 @@ void addRecordOps(venv &ve, record *r) void addFunctionOps(venv &ve, function *f) { -#ifdef NO_FUNC_OPS // No function ops. -#else - addFunc(ve, run::boolFuncEq, primBoolean(), SYM_EQ, formal(f, SYM(a)), - formal(f, SYM(b))); - addFunc(ve, run::boolFuncNeq, primBoolean(), SYM_NEQ, formal(f, SYM(a)), - formal(f, SYM(b))); -#endif } @@ -702,11 +729,7 @@ void addOperators(venv &ve) dummyRecord *createDummyRecord(venv &ve, symbol name) { dummyRecord *r=new dummyRecord(name); -#ifdef DEBUG_FRAME - vm::frame *f = new vm::frame("dummy record " + string(name), 0); -#else - vm::frame *f = new vm::frame(0); -#endif + vm::frame *f = make_dummyframe(name); addConstant(ve, f, r, name); addRecordOps(ve, r); return r; @@ -728,9 +751,41 @@ void openFunc(stack *Stack) } #endif +// A function accessible in asy code print the bytecode of a function. +void printBytecode(stack *Stack) +{ + // As arbitrary addresses can be sent to printBytecode, it should not be run + // in safe mode. + if (settings::safe) { + cerr << "use -nosafe flag to enable printBytecode" << endl; + return; + } + + vm::array *a=vm::pop<vm::array *>(Stack); + size_t numArgs=checkArray(a); + if (numArgs != 1) + cerr << "printBytecode takes one argument" << endl; + + // TODO: Add a reliable test for the object being a func. + callable *c = a->read<callable *>(0); + if (func *f = dynamic_cast<func *>(c)) + print(cout, f->body->code); + else + cout << "callable is not a standard function"; +} + + + + // NOTE: We should move all of these into a "builtin" module. void base_venv(venv &ve) { + // Register the name of arrayDeleteHelper for debugging in "asy -s" mode. + // This is done automatically for other function, but because + // arrayDeleteHelper is not defined in the usual way, it must be done + // explicitly, and here is as good a place as any. + REGISTER_BLTIN(arrayDeleteHelper, "arrayDeleteHelper"); + addInitializers(ve); addCasts(ve); addOperators(ve); @@ -807,6 +862,8 @@ void base_venv(venv &ve) addOpenFunc(ve, openFunc, primInt(), SYM(openFunc)); #endif + addOpenFunc(ve, printBytecode, primVoid(), SYM(printBytecode)); + gen_runtime_venv(ve); gen_runbacktrace_venv(ve); gen_runpicture_venv(ve); |