/***** * builtin.cc * Tom Prince 2004/08/25 * * Initialize builtins. *****/ #include #include "builtin.h" #include "entry.h" #include "runtime.h" #include "runpicture.h" #include "runlabel.h" #include "runhistory.h" #include "runarray.h" #include "runfile.h" #include "runsystem.h" #include "runstring.h" #include "runpair.h" #include "runtriple.h" #include "runpath.h" #include "runpath3d.h" #include "runmath.h" #include "types.h" #include "castop.h" #include "mathop.h" #include "arrayop.h" #include "vm.h" #include "coder.h" #include "exp.h" #include "refaccess.h" #include "settings.h" #include "opsymbols.h" #include "builtin.symbols.h" #ifdef HAVE_LIBGSL #include #include #include #endif using namespace types; using namespace camp; using namespace vm; namespace trans { using camp::transform; using camp::pair; using vm::bltin; using run::divide; using run::less; using run::greater; using run::plus; using run::minus; using namespace run; void gen_runtime_venv(venv &ve); void gen_runbacktrace_venv(venv &ve); void gen_runpicture_venv(venv &ve); void gen_runlabel_venv(venv &ve); void gen_runhistory_venv(venv &ve); void gen_runarray_venv(venv &ve); void gen_runfile_venv(venv &ve); void gen_runsystem_venv(venv &ve); void gen_runstring_venv(venv &ve); void gen_runpair_venv(venv &ve); void gen_runtriple_venv(venv &ve); void gen_runpath_venv(venv &ve); void gen_runpath3d_venv(venv &ve); void gen_runmath_venv(venv &ve); void addType(tenv &te, symbol *name, ty *t) { te.enter(name, new tyEntry(t,0,0,position())); } // The base environments for built-in types and functions void base_tenv(tenv &te) { #define PRIMITIVE(name,Name,asyName) \ addType(te, symbol::trans(#asyName), prim##Name()); #include "primitives.h" #undef PRIMITIVE } const formal noformal(0); 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 = new function(result); if (f1.t) fun->add(f1); if (f2.t) fun->add(f2); if (f3.t) fun->add(f3); if (f4.t) fun->add(f4); if (f5.t) fun->add(f5); if (f6.t) fun->add(f6); if (f7.t) fun->add(f7); if (f8.t) fun->add(f8); if (f9.t) fun->add(f9); if (fA.t) fun->add(fA); if (fB.t) fun->add(fB); if (fC.t) fun->add(fC); if (fD.t) fun->add(fD); if (fE.t) fun->add(fE); if (fF.t) fun->add(fF); if (fG.t) fun->add(fG); if (fH.t) fun->add(fH); if (fI.t) fun->add(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()); ve.enter(id, ent); } // Add a function with one or more default arguments. void addFunc(venv &ve, bltin f, ty *result, symbol *name, formal f1, formal f2, formal f3, formal f4, formal f5, formal f6, 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); 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); } #if 0 // Add a function with one or more default arguments. void addFunc(venv &ve, bltin f, ty *result, const char *name, formal f1, formal f2, formal f3, formal f4, formal f5, formal f6, 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); access *a = new bltinAccess(f); addFunc(ve,a,result,symbol::trans(name),f1,f2,f3,f4,f5,f6,f7,f8,f9, fA,fB,fC,fD,fE,fF,fG,fH,fI); } void addFunc(venv &ve, access *a, ty *result, const char *name, formal f1) { addFunc(ve,a,result,symbol::trans(name),f1); } #endif void addOpenFunc(venv &ve, bltin f, ty *result, symbol *name) { function *fun = new function(result, signature::OPEN); REGISTER_BLTIN(f, name); access *a= new bltinAccess(f); varEntry *ent = new varEntry(fun, a, 0, position()); ve.enter(name, ent); } // Add a rest function with zero or more default/explicit arguments. void addRestFunc(venv &ve, bltin f, ty *result, symbol *name, formal frest, 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) { REGISTER_BLTIN(f, name); access *a = new bltinAccess(f); function *fun = new function(result); if (f1.t) fun->add(f1); if (f2.t) fun->add(f2); if (f3.t) fun->add(f3); if (f4.t) fun->add(f4); if (f5.t) fun->add(f5); if (f6.t) fun->add(f6); if (f7.t) fun->add(f7); if (f8.t) fun->add(f8); if (f9.t) fun->add(f9); if (frest.t) fun->addRest(frest); varEntry *ent = new varEntry(fun, a, 0, position()); ve.enter(name, ent); } void addRealFunc0(venv &ve, bltin fcn, symbol *name) { addFunc(ve, fcn, primReal(), name); } template void addRealFunc(venv &ve, symbol *name) { addFunc(ve, realReal, primReal(), name, formal(primReal(),SYM(x))); addFunc(ve, arrayFunc, realArray(), name, formal(realArray(),SYM(a))); } #define addRealFunc(fcn, sym) addRealFunc(ve, sym); void addRealFunc2(venv &ve, bltin fcn, symbol *name) { addFunc(ve,fcn,primReal(),name,formal(primReal(),SYM(a)), formal(primReal(),SYM(b))); } template void realRealInt(vm::stack *s) { Int n = pop(s); double x = pop(s); s->push(func(x, intcast(n))); } template void addRealIntFunc(venv& ve, symbol *name, symbol *arg1, symbol *arg2) { addFunc(ve, realRealInt, primReal(), name, formal(primReal(), arg1), formal(primInt(), arg2)); } #ifdef HAVE_LIBGSL bool GSLerror=false; types::dummyRecord *GSLModule; types::record *getGSLModule() { return GSLModule; } inline void checkGSLerror() { if(GSLerror) { GSLerror=false; throw handled_error(); } } template void realRealGSL(vm::stack *s) { double x=pop(s); s->push(func(x)); checkGSLerror(); } template void realRealDOUBLE(vm::stack *s) { double x=pop(s); s->push(func(x,GSL_PREC_DOUBLE)); checkGSLerror(); } template void realRealRealDOUBLE(vm::stack *s) { double y=pop(s); double x=pop(s); s->push(func(x,y,GSL_PREC_DOUBLE)); checkGSLerror(); } template void realIntGSL(vm::stack *s) { s->push(func(unsignedcast(pop(s)))); checkGSLerror(); } template void realIntRealGSL(vm::stack *s) { double x=pop(s); s->push(func(intcast(pop(s)),x)); checkGSLerror(); } template void realRealRealGSL(vm::stack *s) { double x=pop(s); double n=pop(s); s->push(func(n,x)); checkGSLerror(); } template void intRealRealRealGSL(vm::stack *s) { double x=pop(s); double n=pop(s); double a=pop(s); s->push(func(a,n,x)); checkGSLerror(); } template void realRealRealRealGSL(vm::stack *s) { double x=pop(s); double n=pop(s); double a=pop(s); s->push(func(a,n,x)); checkGSLerror(); } template void realRealIntGSL(vm::stack *s) { Int n=pop(s); double x=pop(s); s->push(func(x,unsignedcast(n))); checkGSLerror(); } // Add a GSL special function from the GNU GSL library template void addGSLRealFunc(symbol *name, symbol *arg1=SYM(x)) { addFunc(GSLModule->e.ve, realRealGSL, primReal(), name, formal(primReal(),arg1)); } // Add a GSL_PREC_DOUBLE GSL special function. template void addGSLDOUBLEFunc(symbol *name, symbol *arg1=SYM(x)) { addFunc(GSLModule->e.ve, realRealDOUBLE, primReal(), name, formal(primReal(),arg1)); } template void addGSLDOUBLE2Func(symbol *name, symbol *arg1=SYM(phi), symbol *arg2=SYM(k)) { addFunc(GSLModule->e.ve, realRealRealDOUBLE, primReal(), name, formal(primReal(),arg1), formal(primReal(),arg2)); } template void realRealRealRealDOUBLE(vm::stack *s) { double z=pop(s); double y=pop(s); double x=pop(s); s->push(func(x,y,z,GSL_PREC_DOUBLE)); checkGSLerror(); } template void addGSLDOUBLE3Func(symbol *name, symbol *arg1, symbol *arg2, symbol *arg3) { addFunc(GSLModule->e.ve, realRealRealRealDOUBLE, primReal(), name, formal(primReal(),arg1), formal(primReal(),arg2), formal(primReal(), arg3)); } template void realRealRealRealRealDOUBLE(vm::stack *s) { double z=pop(s); double y=pop(s); double x=pop(s); double w=pop(s); s->push(func(w,x,y,z,GSL_PREC_DOUBLE)); checkGSLerror(); } template void addGSLDOUBLE4Func(symbol *name, symbol *arg1, symbol *arg2, symbol *arg3, symbol *arg4) { addFunc(GSLModule->e.ve, realRealRealRealRealDOUBLE, primReal(), name, formal(primReal(),arg1), formal(primReal(),arg2), formal(primReal(), arg3), formal(primReal(), arg4)); } template void addGSLIntFunc(symbol *name) { addFunc(GSLModule->e.ve, realIntGSL, primReal(), name, formal(primInt(),SYM(s))); } template void realSignedGSL(vm::stack *s) { Int a = pop(s); s->push(func(intcast(a))); checkGSLerror(); } template void addGSLSignedFunc(symbol *name, symbol *arg1) { addFunc(GSLModule->e.ve, realSignedGSL, primReal(), name, formal(primInt(),arg1)); } template void addGSLIntRealFunc(symbol *name, symbol *arg1=SYM(n), symbol *arg2=SYM(x)) { addFunc(GSLModule->e.ve, realIntRealGSL, primReal(), name, formal(primInt(),arg1), formal(primReal(),arg2)); } template void addGSLRealRealFunc(symbol *name, symbol *arg1=SYM(nu), symbol *arg2=SYM(x)) { addFunc(GSLModule->e.ve, realRealRealGSL, primReal(), name, formal(primReal(),arg1), formal(primReal(),arg2)); } template void addGSLRealRealRealFunc(symbol *name, symbol *arg1, symbol *arg2, symbol *arg3) { addFunc(GSLModule->e.ve, realRealRealRealGSL, primReal(), name, formal(primReal(),arg1), formal(primReal(),arg2), formal(primReal(), arg3)); } template void addGSLRealRealRealFuncInt(symbol *name, symbol *arg1, symbol *arg2, symbol *arg3) { addFunc(GSLModule->e.ve, intRealRealRealGSL, primInt(), name, formal(primReal(),arg1), formal(primReal(),arg2), formal(primReal(), arg3)); } template void addGSLRealIntFunc(symbol *name, symbol *arg1=SYM(nu), symbol *arg2=SYM(s)) { addFunc(GSLModule->e.ve, realRealIntGSL, primReal(), name, formal(primReal(),arg1), formal(primInt(),arg2)); } template void realRealSignedGSL(vm::stack *s) { Int b = pop(s); double a = pop(s); s->push(func(a, intcast(b))); checkGSLerror(); } template void addGSLRealSignedFunc(symbol *name, symbol *arg1, symbol *arg2) { addFunc(GSLModule->e.ve, realRealSignedGSL, primReal(), name, formal(primReal(),arg1), formal(primInt(),arg2)); } template void realUnsignedUnsignedGSL(vm::stack *s) { Int b = pop(s); Int a = pop(s); s->push(func(unsignedcast(a), unsignedcast(b))); checkGSLerror(); } template void addGSLUnsignedUnsignedFunc(symbol *name, symbol *arg1, symbol *arg2) { addFunc(GSLModule->e.ve, realUnsignedUnsignedGSL, primReal(), name, formal(primInt(), arg1), formal(primInt(), arg2)); } template void realIntRealRealGSL(vm::stack *s) { double c = pop(s); double b = pop(s); Int a = pop(s); s->push(func(intcast(a), b, c)); checkGSLerror(); } template void addGSLIntRealRealFunc(symbol *name, symbol *arg1, symbol *arg2, symbol *arg3) { addFunc(GSLModule->e.ve, realIntRealRealGSL, primReal(), name, formal(primInt(), arg1), formal(primReal(), arg2), formal(primReal(), arg3)); } template void realIntIntRealGSL(vm::stack *s) { double c = pop(s); Int b = pop(s); Int a = pop(s); s->push(func(intcast(a), intcast(b), c)); checkGSLerror(); } template void addGSLIntIntRealFunc(symbol *name, symbol *arg1, symbol *arg2, symbol *arg3) { addFunc(GSLModule->e.ve, realIntIntRealGSL, primReal(), name, formal(primInt(), arg1), formal(primInt(), arg2), formal(primReal(), arg3)); } template void realIntIntRealRealGSL(vm::stack *s) { double d = pop(s); double c = pop(s); Int b = pop(s); Int a = pop(s); s->push(func(intcast(a), intcast(b), c, d)); checkGSLerror(); } template void addGSLIntIntRealRealFunc(symbol *name, symbol *arg1, symbol *arg2, symbol *arg3, symbol *arg4) { addFunc(GSLModule->e.ve, realIntIntRealRealGSL, primReal(), name, formal(primInt(), arg1), formal(primInt(), arg2), formal(primReal(), arg3), formal(primReal(), arg4)); } template void realRealRealRealRealGSL(vm::stack *s) { double d = pop(s); double c = pop(s); double b = pop(s); double a = pop(s); s->push(func(a, b, c, d)); checkGSLerror(); } template void addGSLRealRealRealRealFunc(symbol *name, symbol *arg1, symbol *arg2, symbol *arg3, symbol *arg4) { addFunc(GSLModule->e.ve, realRealRealRealRealGSL, primReal(), name, formal(primReal(), arg1), formal(primReal(), arg2), formal(primReal(), arg3), formal(primReal(), arg4)); } template void realIntIntIntIntIntIntGSL(vm::stack *s) { Int f = pop(s); Int e = pop(s); Int d = pop(s); Int c = pop(s); Int b = pop(s); Int a = pop(s); s->push(func(intcast(a), intcast(b), intcast(c), intcast(d), intcast(e), intcast(f))); checkGSLerror(); } template void addGSLIntIntIntIntIntIntFunc(symbol *name, symbol *arg1, symbol *arg2, symbol *arg3, symbol *arg4, symbol *arg5, symbol *arg6) { addFunc(GSLModule->e.ve, realIntIntIntIntIntIntGSL, primReal(), name, formal(primInt(), arg1), formal(primInt(), arg2), formal(primInt(), arg3), formal(primInt(), arg4), formal(primInt(), arg5), formal(primInt(), arg6)); } template void realIntIntIntIntIntIntIntIntIntGSL(vm::stack *s) { Int i = pop(s); Int h = pop(s); Int g = pop(s); Int f = pop(s); Int e = pop(s); Int d = pop(s); Int c = pop(s); Int b = pop(s); Int a = pop(s); s->push(func(intcast(a), intcast(b), intcast(c), intcast(d), intcast(e), intcast(f), intcast(g), intcast(h), intcast(i))); checkGSLerror(); } template void addGSLIntIntIntIntIntIntIntIntIntFunc(symbol *name, symbol *arg1, symbol *arg2, symbol *arg3, symbol *arg4, symbol *arg5, symbol *arg6, symbol *arg7, symbol *arg8, symbol *arg9) { addFunc(GSLModule->e.ve, realIntIntIntIntIntIntIntIntIntGSL, primReal(), name, formal(primInt(), arg1), formal(primInt(), arg2), formal(primInt(), arg3), formal(primInt(), arg4), formal(primInt(), arg5), formal(primInt(), arg6), formal(primInt(), arg7), formal(primInt(), arg8), formal(primInt(), arg9)); } // Handle GSL errors gracefully. void GSLerrorhandler(const char *reason, const char *, int, int) { if(!GSLerror) { vm::errornothrow(reason); GSLerror=true; } } #endif void addInitializer(venv &ve, ty *t, access *a) { addFunc(ve, a, t, symbol::initsym); } void addInitializer(venv &ve, ty *t, bltin f) { #ifdef DEBUG_BLTIN ostringstream s; s << "initializer for " << *t; REGISTER_BLTIN(f, s.str()); #endif access *a = new bltinAccess(f); addInitializer(ve, t, a); } // Specifies that source may be cast to target, but only if an explicit // cast expression is used. void addExplicitCast(venv &ve, ty *target, ty *source, access *a) { addFunc(ve, a, target, symbol::ecastsym, source); } // Specifies that source may be implicitly cast to target by the // function or instruction stores at a. void addCast(venv &ve, ty *target, ty *source, access *a) { //addExplicitCast(target,source,a); addFunc(ve, a, target, symbol::castsym, source); } void addExplicitCast(venv &ve, ty *target, ty *source, bltin f) { #ifdef DEBUG_BLTIN ostringstream s; s << "explicit cast from " << *source << " to " << *target; REGISTER_BLTIN(f, s.str()); #endif addExplicitCast(ve, target, source, new bltinAccess(f)); } void addCast(venv &ve, ty *target, ty *source, bltin f) { #ifdef DEBUG_BLTIN ostringstream s; s << "cast from " << *source << " to " << *target; REGISTER_BLTIN(f, s.str()); #endif addCast(ve, target, source, new bltinAccess(f)); } template void addVariable(venv &ve, T *ref, ty *t, symbol *name, record *module=settings::getSettingsModule()) { access *a = new refAccess(ref); varEntry *ent = new varEntry(t, a, PUBLIC, module, 0, position()); ve.enter(name, ent); } template void addVariable(venv &ve, T value, ty *t, symbol *name, record *module=settings::getSettingsModule(), permission perm=PUBLIC) { item* ref=new item; *ref=value; access *a = new itemRefAccess(ref); varEntry *ent = new varEntry(t, a, perm, module, 0, position()); ve.enter(name, ent); } template void addConstant(venv &ve, T value, ty *t, symbol *name, record *module=settings::getSettingsModule()) { addVariable(ve,value,t,name,module,RESTRICTED); } // The identity access, i.e. no instructions are encoded for a cast or // operation, and no functions are called. identAccess id; function *IntRealFunction() { return new function(primInt(),primReal()); } function *realPairFunction() { return new function(primReal(),primPair()); } function *voidFileFunction() { return new function(primVoid(),primFile()); } void addInitializers(venv &ve) { addInitializer(ve, primBoolean(), boolFalse); addInitializer(ve, primInt(), IntZero); addInitializer(ve, primReal(), realZero); addInitializer(ve, primString(), emptyString); addInitializer(ve, primPair(), pairZero); addInitializer(ve, primTriple(), tripleZero); addInitializer(ve, primTransform(), transformIdentity); addInitializer(ve, primGuide(), nullGuide); addInitializer(ve, primPath(), nullPath); addInitializer(ve, primPath3(), nullPath3); addInitializer(ve, primPen(), newPen); addInitializer(ve, primPicture(), newPicture); addInitializer(ve, primFile(), nullFile); } void addCasts(venv &ve) { addExplicitCast(ve, primString(), primInt(), stringCast); addExplicitCast(ve, primString(), primReal(), stringCast); addExplicitCast(ve, primString(), primPair(), stringCast); addExplicitCast(ve, primString(), primTriple(), stringCast); addExplicitCast(ve, primInt(), primString(), castString); addExplicitCast(ve, primReal(), primString(), castString); addExplicitCast(ve, primPair(), primString(), castString); addExplicitCast(ve, primTriple(), primString(), castString); addExplicitCast(ve, primInt(), primReal(), castDoubleInt); addCast(ve, primReal(), primInt(), cast); addCast(ve, primPair(), primInt(), cast); addCast(ve, primPair(), primReal(), cast); addCast(ve, primPath(), primPair(), cast); addCast(ve, primGuide(), primPair(), pairToGuide); addCast(ve, primGuide(), primPath(), pathToGuide); addCast(ve, primPath(), primGuide(), guideToPath); addCast(ve, primFile(), primNull(), nullFile); // Vectorized casts. addExplicitCast(ve, IntArray(), realArray(), arrayToArray); addCast(ve, realArray(), IntArray(), arrayToArray); addCast(ve, pairArray(), IntArray(), arrayToArray); addCast(ve, pairArray(), realArray(), arrayToArray); addCast(ve, realArray2(), IntArray2(), array2ToArray2); addCast(ve, pairArray2(), IntArray2(), array2ToArray2); addCast(ve, pairArray2(), realArray2(), array2ToArray2); } void addGuideOperators(venv &ve) { // The guide operators .. and -- take an array of guides, and turn them // into a single guide. addRestFunc(ve, dotsGuide, primGuide(), SYM_DOTS, guideArray()); addRestFunc(ve, dashesGuide, primGuide(), SYM_DASHES, guideArray()); } /* Avoid typing the same type three times. */ void addSimpleOperator(venv &ve, bltin f, ty *t, symbol *name) { addFunc(ve,f,t,name,formal(t,SYM(a)),formal(t,SYM(b))); } void addBooleanOperator(venv &ve, bltin f, ty *t, symbol *name) { addFunc(ve,f,primBoolean(),name,formal(t,SYM(a)),formal(t,SYM(b))); } template class op> void addArray2Array2Op(venv &ve, ty *t3, symbol *name) { addFunc(ve,array2Array2Op,t3,name,formal(t3,SYM(a)),formal(t3,SYM(b))); } template class op> void addOpArray2(venv &ve, ty *t1, symbol *name, ty *t3) { addFunc(ve,opArray2,t3,name,formal(t1,SYM(a)),formal(t3,SYM(b))); } template class op> void addArray2Op(venv &ve, ty *t1, symbol *name, ty *t3) { addFunc(ve,array2Op,t3,name,formal(t3,SYM(a)),formal(t1,SYM(b))); } template class op> void addOps(venv &ve, ty *t1, symbol *name, ty *t2) { addSimpleOperator(ve,binaryOp,t1,name); addFunc(ve,opArray,t2,name,formal(t1,SYM(a)),formal(t2,SYM(b))); addFunc(ve,arrayOp,t2,name,formal(t2,SYM(a)),formal(t1,SYM(b))); addSimpleOperator(ve,arrayArrayOp,t2,name); } template class op> void addBooleanOps(venv &ve, ty *t1, symbol *name, ty *t2) { addBooleanOperator(ve,binaryOp,t1,name); addFunc(ve,opArray, booleanArray(),name,formal(t1,SYM(a)),formal(t2,SYM(b))); addFunc(ve,arrayOp, booleanArray(),name,formal(t2,SYM(a)),formal(t1,SYM(b))); addFunc(ve,arrayArrayOp,booleanArray(),name,formal(t2,SYM(a)), formal(t2,SYM(b))); } void addWrite(venv &ve, bltin f, ty *t1, ty *t2) { addRestFunc(ve,f,primVoid(),SYM(write),t2, formal(primFile(),SYM(file),true),formal(primString(),SYM(s),true), formal(t1,SYM(x)),formal(voidFileFunction(),SYM(suffix),true)); } template void addUnorderedOps(venv &ve, ty *t1, ty *t2, ty *t3, ty *t4) { addBooleanOps(ve,t1,SYM_EQ,t2); addBooleanOps(ve,t1,SYM_NEQ,t2); addFunc(ve, run::array2Equals, primBoolean(), SYM_EQ, formal(t3, SYM(a)), formal(t3, SYM(b))); addFunc(ve, run::array2NotEquals, primBoolean(), SYM_NEQ, formal(t3, SYM(a)), formal(t3, SYM(b))); addCast(ve,t1,primFile(),read); addCast(ve,t2,primFile(),readArray); addCast(ve,t3,primFile(),readArray); addCast(ve,t4,primFile(),readArray); addWrite(ve,write,t1,t2); addRestFunc(ve,writeArray,primVoid(),SYM(write),t3, formal(primFile(),SYM(file),true),formal(primString(),SYM(s),true), formal(t2,SYM(a),false,true)); addFunc(ve,writeArray2,primVoid(),SYM(write), formal(primFile(),SYM(file),true),t3); addFunc(ve,writeArray3,primVoid(),SYM(write), formal(primFile(),SYM(file),true),t4); } inline double abs(pair z) { return z.length(); } inline double abs(triple v) { return v.length(); } inline pair conjugate(pair z) { return conj(z); } template inline T negate(T x) { return -x; } template class op> void addBinOps(venv &ve, ty *t1, ty *t2, ty *t3, ty *t4, symbol *name) { addFunc(ve,binopArray,t1,name,formal(t2,SYM(a))); addFunc(ve,binopArray2,t1,name,formal(t3,SYM(a))); addFunc(ve,binopArray3,t1,name,formal(t4,SYM(a))); } template void addOrderedOps(venv &ve, ty *t1, ty *t2, ty *t3, ty *t4) { addBooleanOps(ve,t1,SYM_LT,t2); addBooleanOps(ve,t1,SYM_LE,t2); addBooleanOps(ve,t1,SYM_GE,t2); addBooleanOps(ve,t1,SYM_GT,t2); addOps(ve,t1,SYM(min),t2); addOps(ve,t1,SYM(max),t2); addBinOps(ve,t1,t2,t3,t4,SYM(min)); addBinOps(ve,t1,t2,t3,t4,SYM(max)); addFunc(ve,sortArray,t2,SYM(sort),formal(t2,SYM(a))); addFunc(ve,sortArray2,t3,SYM(sort),formal(t3,SYM(a))); addFunc(ve,searchArray,primInt(),SYM(search),formal(t2,SYM(a)), formal(t1,SYM(key))); } template void addBasicOps(venv &ve, ty *t1, ty *t2, ty *t3, ty *t4, bool integer=false, bool Explicit=false) { addOps(ve,t1,SYM_PLUS,t2); addOps(ve,t1,SYM_MINUS,t2); addArray2Array2Op(ve,t3,SYM_PLUS); addArray2Array2Op(ve,t3,SYM_MINUS); addFunc(ve,&id,t1,SYM_PLUS,formal(t1,SYM(a))); addFunc(ve,&id,t2,SYM_PLUS,formal(t2,SYM(a))); addFunc(ve,Negate,t1,SYM_MINUS,formal(t1,SYM(a))); addFunc(ve,arrayFunc,t2,SYM_MINUS,formal(t2,SYM(a))); addFunc(ve,arrayFunc2,t3,SYM_MINUS,formal(t3,SYM(a))); if(!integer) addFunc(ve,interp,t1,SYM(interp),formal(t1,SYM(a),false,Explicit), formal(t1,SYM(b),false,Explicit), formal(primReal(),SYM(t))); addFunc(ve,sumArray,t1,SYM(sum),formal(t2,SYM(a))); addUnorderedOps(ve,t1,t2,t3,t4); } template void addOps(venv &ve, ty *t1, ty *t2, ty *t3, ty *t4, bool integer=false, bool Explicit=false) { addBasicOps(ve,t1,t2,t3,t4,integer,Explicit); addOps(ve,t1,SYM_TIMES,t2); addOpArray2(ve,t1,SYM_TIMES,t3); addArray2Op(ve,t1,SYM_TIMES,t3); if(!integer) { addOps(ve,t1,SYM_DIVIDE,t2); addArray2Op(ve,t1,SYM_DIVIDE,t3); } addOps(ve,t1,SYM_CARET,t2); } // Adds standard functions for a newly added array type. void addArrayOps(venv &ve, types::array *t) { ty *ct = t->celltype; addFunc(ve, run::arrayAlias, primBoolean(), SYM(alias), formal(t, SYM(a)), formal(t, SYM(b))); addFunc(ve, run::newDuplicateArray, t, SYM(array), formal(primInt(), SYM(n)), formal(ct, SYM(value)), formal(primInt(), SYM(depth), /*optional=*/ true)); switch (t->depth()) { case 1: addFunc(ve, run::arrayCopy, t, SYM(copy), formal(t, SYM(a))); addRestFunc(ve, run::arrayConcat, t, SYM(concat), new types::array(t)); addFunc(ve, run::arraySequence, t, SYM(sequence), formal(new function(ct, primInt()), SYM(f)), formal(primInt(), SYM(n))); addFunc(ve, run::arrayFunction, t, SYM(map), formal(new function(ct, ct), SYM(f)), formal(t, SYM(a))); addFunc(ve, run::arraySort, t, SYM(sort), formal(t, SYM(a)), formal(new function(primBoolean(), ct, ct), SYM(f))); break; case 2: addFunc(ve, run::array2Copy, t, SYM(copy), formal(t, SYM(a))); addFunc(ve, run::array2Transpose, t, SYM(transpose), formal(t, SYM(a))); break; case 3: addFunc(ve, run::array3Copy, t, SYM(copy), formal(t, SYM(a))); addFunc(ve, run::array3Transpose, t, SYM(transpose), formal(t, SYM(a)), formal(IntArray(),SYM(perm))); break; default: break; } } void addRecordOps(venv &ve, record *r) { addFunc(ve, run::boolMemEq, primBoolean(), SYM(alias), formal(r, SYM(a)), formal(r, SYM(b))); addFunc(ve, run::boolMemEq, primBoolean(), SYM_EQ, formal(r, SYM(a)), formal(r, SYM(b))); addFunc(ve, run::boolMemNeq, primBoolean(), SYM_NEQ, formal(r, SYM(a)), formal(r, SYM(b))); } void addFunctionOps(venv &ve, function *f) { 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))); } void addOperators(venv &ve) { addSimpleOperator(ve,binaryOp,primString(),SYM_PLUS); addBooleanOps(ve,primBoolean(),SYM_AMPERSAND,booleanArray()); addBooleanOps(ve,primBoolean(),SYM_BAR,booleanArray()); addBooleanOps(ve,primBoolean(),SYM_CARET,booleanArray()); addUnorderedOps(ve,primBoolean(),booleanArray(),booleanArray2(), booleanArray3()); addOps(ve,primInt(),IntArray(),IntArray2(),IntArray3(),true); addOps(ve,primReal(),realArray(),realArray2(),realArray3()); addOps(ve,primPair(),pairArray(),pairArray2(),pairArray3(),false,true); addBasicOps(ve,primTriple(),tripleArray(),tripleArray2(), tripleArray3()); addFunc(ve,opArray,tripleArray(),SYM_TIMES, formal(primReal(),SYM(a)),formal(tripleArray(),SYM(b))); addFunc(ve,opArray2,tripleArray2(),SYM_TIMES, formal(primReal(),SYM(a)),formal(tripleArray2(),SYM(b))); addFunc(ve,arrayOp,tripleArray(),SYM_TIMES, formal(tripleArray(),SYM(a)),formal(primReal(),SYM(b))); addFunc(ve,array2Op,tripleArray2(),SYM_TIMES, formal(tripleArray2(),SYM(a)),formal(primReal(),SYM(b))); addFunc(ve,arrayOp,tripleArray(),SYM_DIVIDE, formal(tripleArray(),SYM(a)),formal(primReal(),SYM(b))); addUnorderedOps(ve,primString(),stringArray(),stringArray2(), stringArray3()); addSimpleOperator(ve,binaryOp,primPair(),SYM(minbound)); addSimpleOperator(ve,binaryOp,primPair(),SYM(maxbound)); addSimpleOperator(ve,binaryOp,primTriple(),SYM(minbound)); addSimpleOperator(ve,binaryOp,primTriple(),SYM(maxbound)); addBinOps(ve,primPair(),pairArray(),pairArray2(),pairArray3(), SYM(minbound)); addBinOps(ve,primPair(),pairArray(),pairArray2(),pairArray3(), SYM(maxbound)); addBinOps(ve,primTriple(),tripleArray(),tripleArray2(), tripleArray3(),SYM(minbound)); addBinOps(ve,primTriple(),tripleArray(),tripleArray2(), tripleArray3(),SYM(maxbound)); addFunc(ve,arrayFunc,realArray(),SYM(abs), formal(pairArray(),SYM(a))); addFunc(ve,arrayFunc,realArray(),SYM(abs), formal(tripleArray(),SYM(a))); addFunc(ve,arrayFunc,pairArray(),SYM(conj), formal(pairArray(),SYM(a))); addFunc(ve,arrayFunc2,pairArray2(),SYM(conj), formal(pairArray2(),SYM(a))); addFunc(ve,binaryOp,primReal(),SYM_DIVIDE, formal(primInt(),SYM(a)),formal(primInt(),SYM(b))); addFunc(ve,arrayOp,realArray(),SYM_DIVIDE, formal(IntArray(),SYM(a)),formal(primInt(),SYM(b))); addFunc(ve,opArray,realArray(),SYM_DIVIDE, formal(primInt(),SYM(a)),formal(IntArray(),SYM(b))); addFunc(ve,arrayArrayOp,realArray(),SYM_DIVIDE, formal(IntArray(),SYM(a)),formal(IntArray(),SYM(b))); addOrderedOps(ve,primInt(),IntArray(),IntArray2(),IntArray3()); addOrderedOps(ve,primReal(),realArray(),realArray2(),realArray3()); addOrderedOps(ve,primString(),stringArray(),stringArray2(), stringArray3()); addOps(ve,primInt(),SYM_MOD,IntArray()); addOps(ve,primReal(),SYM_MOD,realArray()); addRestFunc(ve,diagonal,IntArray2(),SYM(diagonal),IntArray()); addRestFunc(ve,diagonal,realArray2(),SYM(diagonal),realArray()); addRestFunc(ve,diagonal,pairArray2(),SYM(diagonal),pairArray()); } 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 addConstant(ve, f, r, name); addRecordOps(ve, r); return r; } double identity(double x) {return x;} double pow10(double x) {return run::pow(10.0,x);} // An example of an open function. #ifdef OPENFUNCEXAMPLE void openFunc(stack *Stack) { vm::array *a=vm::pop(Stack); size_t numArgs=checkArray(a); for (size_t k=0; kpush((Int)numArgs); } #endif // NOTE: We should move all of these into a "builtin" module. void base_venv(venv &ve) { addInitializers(ve); addCasts(ve); addOperators(ve); addGuideOperators(ve); addRealFunc(sin,SYM(sin)); addRealFunc(cos,SYM(cos)); addRealFunc(tan,SYM(tan)); addRealFunc(asin,SYM(asin)); addRealFunc(acos,SYM(acos)); addRealFunc(atan,SYM(atan)); addRealFunc(exp,SYM(exp)); addRealFunc(log,SYM(log)); addRealFunc(log10,SYM(log10)); addRealFunc(sinh,SYM(sinh)); addRealFunc(cosh,SYM(cosh)); addRealFunc(tanh,SYM(tanh)); addRealFunc(asinh,SYM(asinh)); addRealFunc(acosh,SYM(acosh)); addRealFunc(atanh,SYM(atanh)); addRealFunc(sqrt,SYM(sqrt)); addRealFunc(cbrt,SYM(cbrt)); addRealFunc(fabs,SYM(fabs)); addRealFunc(ve,SYM(abs)); addRealFunc(expm1,SYM(expm1)); addRealFunc(log1p,SYM(log1p)); addRealIntFunc(ve, SYM(ldexp), SYM(x), SYM(e)); addRealFunc(pow10,SYM(pow10)); addRealFunc(identity,SYM(identity)); #ifdef HAVE_LIBGSL GSLModule=new dummyRecord(SYM(gsl)); gsl_set_error_handler(GSLerrorhandler); // Common functions addGSLRealRealFunc(SYM(hypot),SYM(x),SYM(y)); // addGSLRealRealRealFunc(SYM(hypot),SYM(x),SYM(y),SYM(z)); addGSLRealRealRealFuncInt(SYM(fcmp),SYM(x),SYM(y),SYM(epsilon)); // Airy functions addGSLDOUBLEFunc(SYM(Ai)); addGSLDOUBLEFunc(SYM(Bi)); addGSLDOUBLEFunc(SYM(Ai_scaled)); addGSLDOUBLEFunc(SYM(Bi_scaled)); addGSLDOUBLEFunc(SYM(Ai_deriv)); addGSLDOUBLEFunc(SYM(Bi_deriv)); addGSLDOUBLEFunc(SYM(Ai_deriv_scaled)); addGSLDOUBLEFunc(SYM(Bi_deriv_scaled)); addGSLIntFunc(SYM(zero_Ai)); addGSLIntFunc(SYM(zero_Bi)); addGSLIntFunc(SYM(zero_Ai_deriv)); addGSLIntFunc(SYM(zero_Bi_deriv)); // Bessel functions addGSLRealFunc(SYM(J0)); addGSLRealFunc(SYM(J1)); addGSLIntRealFunc(SYM(Jn)); addGSLRealFunc(SYM(Y0)); addGSLRealFunc(SYM(Y1)); addGSLIntRealFunc(SYM(Yn)); addGSLRealFunc(SYM(I0)); addGSLRealFunc(SYM(I1)); addGSLIntRealFunc(SYM(I)); addGSLRealFunc(SYM(I0_scaled)); addGSLRealFunc(SYM(I1_scaled)); addGSLIntRealFunc(SYM(I_scaled)); addGSLRealFunc(SYM(K0)); addGSLRealFunc(SYM(K1)); addGSLIntRealFunc(SYM(K)); addGSLRealFunc(SYM(K0_scaled)); addGSLRealFunc(SYM(K1_scaled)); addGSLIntRealFunc(SYM(K_scaled)); addGSLRealFunc(SYM(j0)); addGSLRealFunc(SYM(j1)); addGSLRealFunc(SYM(j2)); addGSLIntRealFunc(SYM(j),SYM(l)); addGSLRealFunc(SYM(y0)); addGSLRealFunc(SYM(y1)); addGSLRealFunc(SYM(y2)); addGSLIntRealFunc(SYM(y),SYM(l)); addGSLRealFunc(SYM(i0_scaled)); addGSLRealFunc(SYM(i1_scaled)); addGSLRealFunc(SYM(i2_scaled)); addGSLIntRealFunc(SYM(i_scaled),SYM(l)); addGSLRealFunc(SYM(k0_scaled)); addGSLRealFunc(SYM(k1_scaled)); addGSLRealFunc(SYM(k2_scaled)); addGSLIntRealFunc(SYM(k_scaled),SYM(l)); addGSLRealRealFunc(SYM(J)); addGSLRealRealFunc(SYM(Y)); addGSLRealRealFunc(SYM(I)); addGSLRealRealFunc(SYM(I_scaled)); addGSLRealRealFunc(SYM(K)); addGSLRealRealFunc(SYM(lnK)); addGSLRealRealFunc(SYM(K_scaled)); addGSLIntFunc(SYM(zero_J0)); addGSLIntFunc(SYM(zero_J1)); addGSLRealIntFunc(SYM(zero_J)); // Clausen functions addGSLRealFunc(SYM(clausen)); // Coulomb functions addGSLRealRealFunc(SYM(hydrogenicR_1),SYM(Z),SYM(r)); addGSLIntIntRealRealFunc(SYM(hydrogenicR),SYM(n),SYM(l),SYM(Z), SYM(r)); // Missing: F_L(eta,x), G_L(eta,x), C_L(eta) // Coupling coefficients addGSLIntIntIntIntIntIntFunc(SYM(coupling_3j),SYM(two_ja), SYM(two_jb),SYM(two_jc),SYM(two_ma), SYM(two_mb),SYM(two_mc)); addGSLIntIntIntIntIntIntFunc(SYM(coupling_6j),SYM(two_ja), SYM(two_jb),SYM(two_jc),SYM(two_jd), SYM(two_je),SYM(two_jf)); addGSLIntIntIntIntIntIntIntIntIntFunc(SYM(coupling_9j), SYM(two_ja),SYM(two_jb), SYM(two_jc),SYM(two_jd), SYM(two_je),SYM(two_jf), SYM(two_jg),SYM(two_jh), SYM(two_ji)); // Dawson function addGSLRealFunc(SYM(dawson)); // Debye functions addGSLRealFunc(SYM(debye_1)); addGSLRealFunc(SYM(debye_2)); addGSLRealFunc(SYM(debye_3)); addGSLRealFunc(SYM(debye_4)); addGSLRealFunc(SYM(debye_5)); addGSLRealFunc(SYM(debye_6)); // Dilogarithm addGSLRealFunc(SYM(dilog)); // Missing: complex dilogarithm // Elementary operations // we don't support errors at the moment // Elliptic integrals addGSLDOUBLEFunc(SYM(K),SYM(k)); addGSLDOUBLEFunc(SYM(E),SYM(k)); addGSLDOUBLE2Func(SYM(P),SYM(k),SYM(n)); addGSLDOUBLE2Func(SYM(F)); addGSLDOUBLE2Func(SYM(E)); addGSLDOUBLE3Func(SYM(P),SYM(phi),SYM(k),SYM(n)); addGSLDOUBLE3Func(SYM(D),SYM(phi),SYM(k),SYM(n)); addGSLDOUBLE2Func(SYM(RC),SYM(x),SYM(y)); addGSLDOUBLE3Func(SYM(RD),SYM(x),SYM(y),SYM(z)); addGSLDOUBLE3Func(SYM(RF),SYM(x),SYM(y),SYM(z)); addGSLDOUBLE4Func(SYM(RJ),SYM(x),SYM(y),SYM(z),SYM(p)); // Elliptic functions (Jacobi) // to be implemented // Error functions addGSLRealFunc(SYM(erf)); addGSLRealFunc(SYM(erfc)); addGSLRealFunc(SYM(log_erfc)); addGSLRealFunc(SYM(erf_Z)); addGSLRealFunc(SYM(erf_Q)); addGSLRealFunc(SYM(hazard)); // Exponential functions addGSLRealRealFunc(SYM(exp_mult),SYM(x),SYM(y)); // addGSLRealFunc(SYM(expm1)); addGSLRealFunc(SYM(exprel)); addGSLRealFunc(SYM(exprel_2)); addGSLIntRealFunc(SYM(exprel),SYM(n),SYM(x)); // Exponential integrals addGSLRealFunc(SYM(E1)); addGSLRealFunc(SYM(E2)); // addGSLIntRealFunc(SYM(En),SYM(n),SYM(x)); addGSLRealFunc(SYM(Ei)); addGSLRealFunc(SYM(Shi)); addGSLRealFunc(SYM(Chi)); addGSLRealFunc(SYM(Ei3)); addGSLRealFunc(SYM(Si)); addGSLRealFunc(SYM(Ci)); addGSLRealFunc(SYM(atanint)); // Fermi--Dirac function addGSLRealFunc(SYM(FermiDiracM1)); addGSLRealFunc(SYM(FermiDirac0)); addGSLRealFunc(SYM(FermiDirac1)); addGSLRealFunc(SYM(FermiDirac2)); addGSLIntRealFunc(SYM(FermiDirac),SYM(j),SYM(x)); addGSLRealFunc(SYM(FermiDiracMHalf)); addGSLRealFunc(SYM(FermiDiracHalf)); addGSLRealFunc(SYM(FermiDirac3Half)); addGSLRealRealFunc(SYM(FermiDiracInc0),SYM(x),SYM(b)); // Gamma and beta functions addGSLRealFunc(SYM(gamma)); addGSLRealFunc(SYM(lngamma)); addGSLRealFunc(SYM(gammastar)); addGSLRealFunc(SYM(gammainv)); addGSLIntFunc(SYM(fact)); addGSLIntFunc(SYM(doublefact)); addGSLIntFunc(SYM(lnfact)); addGSLIntFunc(SYM(lndoublefact)); addGSLUnsignedUnsignedFunc(SYM(choose),SYM(n),SYM(m)); addGSLUnsignedUnsignedFunc(SYM(lnchoose),SYM(n),SYM(m)); addGSLIntRealFunc(SYM(taylorcoeff),SYM(n),SYM(x)); addGSLRealRealFunc(SYM(poch),SYM(a),SYM(x)); addGSLRealRealFunc(SYM(lnpoch),SYM(a),SYM(x)); addGSLRealRealFunc(SYM(pochrel),SYM(a),SYM(x)); addGSLRealRealFunc(SYM(gamma),SYM(a),SYM(x)); addGSLRealRealFunc(SYM(gamma_Q),SYM(a),SYM(x)); addGSLRealRealFunc(SYM(gamma_P),SYM(a),SYM(x)); addGSLRealRealFunc(SYM(beta),SYM(a),SYM(b)); addGSLRealRealFunc(SYM(lnbeta),SYM(a),SYM(b)); addGSLRealRealRealFunc(SYM(beta),SYM(a),SYM(b),SYM(x)); // Gegenbauer functions addGSLRealRealFunc(SYM(gegenpoly_1),SYM(lambda),SYM(x)); addGSLRealRealFunc(SYM(gegenpoly_2),SYM(lambda),SYM(x)); addGSLRealRealFunc(SYM(gegenpoly_3),SYM(lambda),SYM(x)); addGSLIntRealRealFunc(SYM(gegenpoly),SYM(n),SYM(lambda),SYM(x)); // Hypergeometric functions addGSLRealRealFunc(SYM(hy0F1),SYM(c),SYM(x)); addGSLIntIntRealFunc(SYM(hy1F1),SYM(m),SYM(n),SYM(x)); addGSLRealRealRealFunc(SYM(hy1F1),SYM(a),SYM(b),SYM(x)); addGSLIntIntRealFunc(SYM(U),SYM(m),SYM(n),SYM(x)); addGSLRealRealRealFunc(SYM(U),SYM(a),SYM(b),SYM(x)); addGSLRealRealRealRealFunc(SYM(hy2F1),SYM(a),SYM(b),SYM(c),SYM(x)); addGSLRealRealRealRealFunc(SYM(hy2F1_conj),SYM(aR),SYM(aI),SYM(c), SYM(x)); addGSLRealRealRealRealFunc(SYM(hy2F1_renorm),SYM(a),SYM(b), SYM(c),SYM(x)); addGSLRealRealRealRealFunc(SYM(hy2F1_conj_renorm), SYM(aR),SYM(aI),SYM(c),SYM(x)); addGSLRealRealRealFunc(SYM(hy2F0),SYM(a),SYM(b),SYM(x)); // Laguerre functions addGSLRealRealFunc(SYM(L1),SYM(a),SYM(x)); addGSLRealRealFunc(SYM(L2),SYM(a),SYM(x)); addGSLRealRealFunc(SYM(L3),SYM(a),SYM(x)); addGSLIntRealRealFunc(SYM(L),SYM(n),SYM(a),SYM(x)); // Lambert W functions addGSLRealFunc(SYM(W0)); addGSLRealFunc(SYM(Wm1)); // Legendre functions and spherical harmonics addGSLRealFunc(SYM(P1)); addGSLRealFunc(SYM(P2)); addGSLRealFunc(SYM(P3)); addGSLIntRealFunc(SYM(Pl),SYM(l)); addGSLRealFunc(SYM(Q0)); addGSLRealFunc(SYM(Q1)); addGSLIntRealFunc(SYM(Ql),SYM(l)); addGSLIntIntRealFunc(SYM(Plm),SYM(l),SYM(m),SYM(x)); addGSLIntIntRealFunc(SYM(sphPlm),SYM(l),SYM(m),SYM(x)); addGSLRealRealFunc(SYM(conicalP_half),SYM(lambda),SYM(x)); addGSLRealRealFunc(SYM(conicalP_mhalf),SYM(lambda),SYM(x)); addGSLRealRealFunc(SYM(conicalP_0),SYM(lambda),SYM(x)); addGSLRealRealFunc(SYM(conicalP_1),SYM(lambda),SYM(x)); addGSLIntRealRealFunc(SYM(conicalP_sph_reg),SYM(l), SYM(lambda),SYM(x)); addGSLIntRealRealFunc(SYM(conicalP_cyl_reg),SYM(m), SYM(lambda),SYM(x)); addGSLRealRealFunc(SYM(H3d0),SYM(lambda),SYM(eta)); addGSLRealRealFunc(SYM(H3d1),SYM(lambda),SYM(eta)); addGSLIntRealRealFunc(SYM(H3d),SYM(l),SYM(lambda),SYM(eta)); // Logarithm and related functions addGSLRealFunc(SYM(logabs)); // addGSLRealFunc(SYM(log1p)); addGSLRealFunc(SYM(log1pm)); // Matthieu functions // to be implemented // Power function addGSLRealSignedFunc(SYM(pow),SYM(x),SYM(n)); // Psi (digamma) function addGSLSignedFunc(SYM(psi),SYM(n)); addGSLRealFunc(SYM(psi)); addGSLRealFunc(SYM(psi_1piy),SYM(y)); addGSLSignedFunc(SYM(psi1),SYM(n)); addGSLRealFunc(SYM(psi1),SYM(x)); addGSLIntRealFunc(SYM(psi),SYM(n),SYM(x)); // Synchrotron functions addGSLRealFunc(SYM(synchrotron_1)); addGSLRealFunc(SYM(synchrotron_2)); // Transport functions addGSLRealFunc(SYM(transport_2)); addGSLRealFunc(SYM(transport_3)); addGSLRealFunc(SYM(transport_4)); addGSLRealFunc(SYM(transport_5)); // Trigonometric functions addGSLRealFunc(SYM(sinc)); addGSLRealFunc(SYM(lnsinh)); addGSLRealFunc(SYM(lncosh)); // Zeta functions addGSLSignedFunc(SYM(zeta),SYM(n)); addGSLRealFunc(SYM(zeta),SYM(s)); addGSLSignedFunc(SYM(zetam1),SYM(n)); addGSLRealFunc(SYM(zetam1),SYM(s)); addGSLRealRealFunc(SYM(hzeta),SYM(s),SYM(q)); addGSLSignedFunc(SYM(eta),SYM(n)); addGSLRealFunc(SYM(eta),SYM(s)); #endif #ifdef STRUCTEXAMPLE dummyRecord *fun=createDummyRecord(ve, SYM(test)); addFunc(fun->e.ve,realReal,primReal(),SYM(f),formal(primReal(),SYM(x))); addVariable(fun->e.ve,1,primInt(),SYM(x)); #endif addFunc(ve,writestring,primVoid(),SYM(write), formal(primFile(),SYM(file),true), formal(primString(),SYM(s)), formal(voidFileFunction(),SYM(suffix),true)); addWrite(ve,write,primTransform(),transformArray()); addWrite(ve,write,primGuide(),guideArray()); addWrite(ve,write,primPen(),penArray()); addFunc(ve,arrayArrayOp,booleanArray(),SYM_EQ, formal(penArray(),SYM(a)),formal(penArray(),SYM(b))); addFunc(ve,arrayArrayOp,booleanArray(),SYM_NEQ, formal(penArray(),SYM(a)),formal(penArray(),SYM(b))); addFunc(ve,arrayFunction,realArray(),SYM(map), formal(realPairFunction(),SYM(f)), formal(pairArray(),SYM(a))); addFunc(ve,arrayFunction,IntArray(),SYM(map), formal(IntRealFunction(),SYM(f)), formal(realArray(),SYM(a))); addConstant(ve, Int_MAX, primInt(), SYM(intMax)); addConstant(ve, Int_MIN, primInt(), SYM(intMin)); addConstant(ve, HUGE_VAL, primReal(), SYM(inf)); addConstant(ve, run::infinity, primReal(), SYM(infinity)); addConstant(ve, DBL_MAX, primReal(), SYM(realMax)); addConstant(ve, DBL_MIN, primReal(), SYM(realMin)); addConstant(ve, DBL_EPSILON, primReal(), SYM(realEpsilon)); addConstant(ve, DBL_DIG, primInt(), SYM(realDigits)); addConstant(ve, RAND_MAX, primInt(), SYM(randMax)); addConstant(ve, PI, primReal(), SYM(pi)); addConstant(ve, string(settings::VERSION)+string(SVN_REVISION), primString(),SYM(VERSION)); addVariable(ve, &processData().currentpen, primPen(), SYM(currentpen)); #ifdef OPENFUNCEXAMPLE addOpenFunc(ve, openFunc, primInt(), SYM(openFunc)); #endif gen_runtime_venv(ve); gen_runbacktrace_venv(ve); gen_runpicture_venv(ve); gen_runlabel_venv(ve); gen_runhistory_venv(ve); gen_runarray_venv(ve); gen_runfile_venv(ve); gen_runsystem_venv(ve); gen_runstring_venv(ve); gen_runpair_venv(ve); gen_runtriple_venv(ve); gen_runpath_venv(ve); gen_runpath3d_venv(ve); gen_runmath_venv(ve); } } //namespace trans namespace run { double infinity=cbrt(DBL_MAX); // Reduced for tension atleast infinity void arrayDeleteHelper(stack *Stack) { array *a=pop(Stack); item itj=pop(Stack); bool jdefault=isdefault(itj); item iti=pop(Stack); Int i,j; if(isdefault(iti)) { if(jdefault) { (*a).clear(); return; } else i=j=get(itj); } else { i=get(iti); j=jdefault ? i : get(itj); } size_t asize=checkArray(a); if(a->cyclic() && asize > 0) { if(j-i+1 >= (Int) asize) { (*a).clear(); return; } i=imod(i,asize); j=imod(j,asize); if(j >= i) (*a).erase((*a).begin()+i,(*a).begin()+j+1); else { (*a).erase((*a).begin()+i,(*a).end()); (*a).erase((*a).begin(),(*a).begin()+j+1); } return; } if(i < 0 || i >= (Int) asize || i > j || j >= (Int) asize) { ostringstream buf; buf << "delete called on array of length " << (Int) asize << " with out-of-bounds index range [" << i << "," << j << "]"; error(buf); } (*a).erase((*a).begin()+i,(*a).begin()+j+1); } }