/***** Autogenerated from runtriple.in; changes will be overwritten *****/

#line 1 "./runtimebase.in"
/*****
 * runtimebase.in
 * Andy Hammerlindl  2009/07/28
 *
 * Common declarations needed for all code-generating .in files.
 *
 *****/


#line 1 "./runtriple.in"
/*****
 * runtriple.in
 *
 * Runtime functions for triple operations.
 *
 *****/

#line 23 "./runtimebase.in"
#include "stack.h"
#include "types.h"
#include "builtin.h"
#include "entry.h"
#include "errormsg.h"
#include "array.h"
#include "triple.h"
#include "callable.h"
#include "opsymbols.h"

using vm::stack;
using vm::error;
using vm::array;
using vm::read;
using vm::callable;
using types::formal;
using types::function;
using camp::triple;

#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
#include <primitives.h>
#undef PRIMITIVE

void unused(void *);

namespace run {
typedef double real;

array *copyArray(array *a);
array *copyArray2(array *a);
array *copyArray3(array *a);

double *copyTripleArray2Components(array *a, size_t &N,
                                   GCPlacement placement=NoGC);
triple *copyTripleArray2C(array *a, size_t &N,
                          GCPlacement placement=NoGC);
}

function *realRealFunction();

#define CURRENTPEN processData().currentpen

#line 10 "runtriple.in"
#include "triple.h"
#include "path3.h"
#include "drawelement.h"

using namespace camp;

// Autogenerated routines:



#ifndef NOSYM
#include "runtriple.symbols.h"

#endif
namespace run {
#line 19 "./runtriple.in"
void tripleZero(stack *Stack)
{
#line 20 "./runtriple.in"
  static triple zero;
  {Stack->push<triple>(zero); return;}
}

#line 25 "./runtriple.in"
void realRealRealToTriple(stack *Stack)
{
  real z=vm::pop<real>(Stack);
  real y=vm::pop<real>(Stack);
  real x=vm::pop<real>(Stack);
#line 26 "./runtriple.in"
  {Stack->push<triple>(triple(x,y,z)); return;}
}

#line 30 "./runtriple.in"
// real xpart(triple v);
void tripleXPart(stack *Stack)
{
  triple v=vm::pop<triple>(Stack);
#line 31 "./runtriple.in"
  {Stack->push<real>(v.getx()); return;}
}

#line 35 "./runtriple.in"
// real ypart(triple v);
void tripleYPart(stack *Stack)
{
  triple v=vm::pop<triple>(Stack);
#line 36 "./runtriple.in"
  {Stack->push<real>(v.gety()); return;}
}

#line 40 "./runtriple.in"
// real zpart(triple v);
void tripleZPart(stack *Stack)
{
  triple v=vm::pop<triple>(Stack);
#line 41 "./runtriple.in"
  {Stack->push<real>(v.getz()); return;}
}

#line 45 "./runtriple.in"
// triple *(real x, triple v);
void gen_runtriple5(stack *Stack)
{
  triple v=vm::pop<triple>(Stack);
  real x=vm::pop<real>(Stack);
#line 46 "./runtriple.in"
  {Stack->push<triple>(x*v); return;}
}

#line 50 "./runtriple.in"
// triple *(triple v, real x);
void gen_runtriple6(stack *Stack)
{
  real x=vm::pop<real>(Stack);
  triple v=vm::pop<triple>(Stack);
#line 51 "./runtriple.in"
  {Stack->push<triple>(v*x); return;}
}

#line 55 "./runtriple.in"
// triple /(triple v, real x);
void gen_runtriple7(stack *Stack)
{
  real x=vm::pop<real>(Stack);
  triple v=vm::pop<triple>(Stack);
#line 56 "./runtriple.in"
  {Stack->push<triple>(v/x); return;}
}

#line 60 "./runtriple.in"
// real length(triple v);
void gen_runtriple8(stack *Stack)
{
  triple v=vm::pop<triple>(Stack);
#line 61 "./runtriple.in"
  {Stack->push<real>(v.length()); return;}
}

#line 65 "./runtriple.in"
// real abs(triple v);
void gen_runtriple9(stack *Stack)
{
  triple v=vm::pop<triple>(Stack);
#line 66 "./runtriple.in"
  {Stack->push<real>(v.length()); return;}
}

#line 70 "./runtriple.in"
// real abs2(triple v);
void gen_runtriple10(stack *Stack)
{
  triple v=vm::pop<triple>(Stack);
#line 71 "./runtriple.in"
  {Stack->push<real>(abs2(v)); return;}
}

#line 75 "./runtriple.in"
// real polar(triple v, bool warn=true);
void gen_runtriple11(stack *Stack)
{
  bool warn=vm::pop<bool>(Stack,true);
  triple v=vm::pop<triple>(Stack);
#line 76 "./runtriple.in"
  {Stack->push<real>(v.polar(warn)); return;}
}

#line 80 "./runtriple.in"
// real azimuth(triple v, bool warn=true);
void gen_runtriple12(stack *Stack)
{
  bool warn=vm::pop<bool>(Stack,true);
  triple v=vm::pop<triple>(Stack);
#line 81 "./runtriple.in"
  if(!warn && v.getx() == 0.0 && v.gety() == 0.0) {Stack->push<real>(0.0); return;}
  {Stack->push<real>(v.azimuth()); return;}
}

#line 86 "./runtriple.in"
// real colatitude(triple v, bool warn=true);
void gen_runtriple13(stack *Stack)
{
  bool warn=vm::pop<bool>(Stack,true);
  triple v=vm::pop<triple>(Stack);
#line 87 "./runtriple.in"
  if(!warn && v.getx() == 0.0 && v.gety() == 0.0 && v.getz() == 0.0) {Stack->push<real>(0.0); return;}
  {Stack->push<real>(degrees(v.polar())); return;}
}

#line 92 "./runtriple.in"
// real latitude(triple v, bool warn=true);
void gen_runtriple14(stack *Stack)
{
  bool warn=vm::pop<bool>(Stack,true);
  triple v=vm::pop<triple>(Stack);
#line 93 "./runtriple.in"
  if(!warn && v.getx() == 0.0 && v.gety() == 0.0 && v.getz() == 0.0) {Stack->push<real>(0.0); return;}
  {Stack->push<real>(90.0-degrees(v.polar())); return;}
}

// Return the longitude of v in [0,360).
#line 99 "./runtriple.in"
// real longitude(triple v, bool warn=true);
void gen_runtriple15(stack *Stack)
{
  bool warn=vm::pop<bool>(Stack,true);
  triple v=vm::pop<triple>(Stack);
#line 100 "./runtriple.in"
  if(!warn && v.getx() == 0.0 && v.gety() == 0.0) {Stack->push<real>(0.0); return;}
  {Stack->push<real>(principalBranch(degrees(v.azimuth()))); return;}
}

#line 105 "./runtriple.in"
// triple unit(triple v);
void gen_runtriple16(stack *Stack)
{
  triple v=vm::pop<triple>(Stack);
#line 106 "./runtriple.in"
  {Stack->push<triple>(unit(v)); return;}
}

#line 110 "./runtriple.in"
// real dot(triple u, triple v);
void gen_runtriple17(stack *Stack)
{
  triple v=vm::pop<triple>(Stack);
  triple u=vm::pop<triple>(Stack);
#line 111 "./runtriple.in"
  {Stack->push<real>(dot(u,v)); return;}
}

#line 115 "./runtriple.in"
// triple cross(triple u, triple v);
void gen_runtriple18(stack *Stack)
{
  triple v=vm::pop<triple>(Stack);
  triple u=vm::pop<triple>(Stack);
#line 116 "./runtriple.in"
  {Stack->push<triple>(cross(u,v)); return;}
}

#line 120 "./runtriple.in"
// triple dir(explicit triple z);
void gen_runtriple19(stack *Stack)
{
  triple z=vm::pop<triple>(Stack);
#line 121 "./runtriple.in"
  {Stack->push<triple>(unit(z)); return;}
}

#line 125 "./runtriple.in"
// triple expi(real polar, real azimuth);
void gen_runtriple20(stack *Stack)
{
  real azimuth=vm::pop<real>(Stack);
  real polar=vm::pop<real>(Stack);
#line 126 "./runtriple.in"
  {Stack->push<triple>(expi(polar,azimuth)); return;}
}

#line 130 "./runtriple.in"
// triple dir(real colatitude, real longitude);
void gen_runtriple21(stack *Stack)
{
  real longitude=vm::pop<real>(Stack);
  real colatitude=vm::pop<real>(Stack);
#line 131 "./runtriple.in"
  {Stack->push<triple>(expi(radians(colatitude),radians(longitude))); return;}
}

#line 135 "./runtriple.in"
// triple realmult(triple u, triple v);
void gen_runtriple22(stack *Stack)
{
  triple v=vm::pop<triple>(Stack);
  triple u=vm::pop<triple>(Stack);
#line 136 "./runtriple.in"
  {Stack->push<triple>(triple (u.getx()*v.getx(),u.gety()*v.gety(),u.getz()*v.getz())); return;}
}

// Return the component of vector v perpendicular to a unit vector u.
#line 141 "./runtriple.in"
// triple perp(triple v, triple u);
void gen_runtriple23(stack *Stack)
{
  triple u=vm::pop<triple>(Stack);
  triple v=vm::pop<triple>(Stack);
#line 142 "./runtriple.in"
  {Stack->push<triple>(perp(v,u)); return;}
}

#line 146 "./runtriple.in"
// triple bezier(triple a, triple b, triple c, triple d, real t);
void gen_runtriple24(stack *Stack)
{
  real t=vm::pop<real>(Stack);
  triple d=vm::pop<triple>(Stack);
  triple c=vm::pop<triple>(Stack);
  triple b=vm::pop<triple>(Stack);
  triple a=vm::pop<triple>(Stack);
#line 147 "./runtriple.in"
  real onemt=1-t;
  real onemt2=onemt*onemt;
  {Stack->push<triple>(onemt2*onemt*a+t*(3.0*(onemt2*b+t*onemt*c)+t*t*d)); return;}
}

#line 153 "./runtriple.in"
// triple bezierP(triple a, triple b, triple c, triple d, real t);
void gen_runtriple25(stack *Stack)
{
  real t=vm::pop<real>(Stack);
  triple d=vm::pop<triple>(Stack);
  triple c=vm::pop<triple>(Stack);
  triple b=vm::pop<triple>(Stack);
  triple a=vm::pop<triple>(Stack);
#line 154 "./runtriple.in"
  {Stack->push<triple>(3.0*(t*t*(d-a+3.0*(b-c))+t*(2.0*(a+c)-4.0*b)+b-a)); return;}
}

#line 158 "./runtriple.in"
// triple bezierPP(triple a, triple b, triple c, triple d, real t);
void gen_runtriple26(stack *Stack)
{
  real t=vm::pop<real>(Stack);
  triple d=vm::pop<triple>(Stack);
  triple c=vm::pop<triple>(Stack);
  triple b=vm::pop<triple>(Stack);
  triple a=vm::pop<triple>(Stack);
#line 159 "./runtriple.in"
  {Stack->push<triple>(6.0*(t*(d-a+3.0*(b-c))+a+c)-12.0*b); return;}
}

#line 163 "./runtriple.in"
// triple bezierPPP(triple a, triple b, triple c, triple d);
void gen_runtriple27(stack *Stack)
{
  triple d=vm::pop<triple>(Stack);
  triple c=vm::pop<triple>(Stack);
  triple b=vm::pop<triple>(Stack);
  triple a=vm::pop<triple>(Stack);
#line 164 "./runtriple.in"
  {Stack->push<triple>(6.0*(d-a)+18.0*(b-c)); return;}
}

} // namespace run

namespace trans {

void gen_runtriple_venv(venv &ve)
{
#line 19 "./runtriple.in"
  REGISTER_BLTIN(run::tripleZero,"tripleZero");
#line 25 "./runtriple.in"
  REGISTER_BLTIN(run::realRealRealToTriple,"realRealRealToTriple");
#line 30 "./runtriple.in"
  addFunc(ve, run::tripleXPart, primReal(), SYM(xpart), formal(primTriple(), SYM(v), false, false));
#line 35 "./runtriple.in"
  addFunc(ve, run::tripleYPart, primReal(), SYM(ypart), formal(primTriple(), SYM(v), false, false));
#line 40 "./runtriple.in"
  addFunc(ve, run::tripleZPart, primReal(), SYM(zpart), formal(primTriple(), SYM(v), false, false));
#line 45 "./runtriple.in"
  addFunc(ve, run::gen_runtriple5, primTriple(), SYM_TIMES, formal(primReal(), SYM(x), false, false), formal(primTriple(), SYM(v), false, false));
#line 50 "./runtriple.in"
  addFunc(ve, run::gen_runtriple6, primTriple(), SYM_TIMES, formal(primTriple(), SYM(v), false, false), formal(primReal(), SYM(x), false, false));
#line 55 "./runtriple.in"
  addFunc(ve, run::gen_runtriple7, primTriple(), SYM_DIVIDE, formal(primTriple(), SYM(v), false, false), formal(primReal(), SYM(x), false, false));
#line 60 "./runtriple.in"
  addFunc(ve, run::gen_runtriple8, primReal(), SYM(length), formal(primTriple(), SYM(v), false, false));
#line 65 "./runtriple.in"
  addFunc(ve, run::gen_runtriple9, primReal(), SYM(abs), formal(primTriple(), SYM(v), false, false));
#line 70 "./runtriple.in"
  addFunc(ve, run::gen_runtriple10, primReal(), SYM(abs2), formal(primTriple(), SYM(v), false, false));
#line 75 "./runtriple.in"
  addFunc(ve, run::gen_runtriple11, primReal(), SYM(polar), formal(primTriple(), SYM(v), false, false), formal(primBoolean(), SYM(warn), true, false));
#line 80 "./runtriple.in"
  addFunc(ve, run::gen_runtriple12, primReal(), SYM(azimuth), formal(primTriple(), SYM(v), false, false), formal(primBoolean(), SYM(warn), true, false));
#line 86 "./runtriple.in"
  addFunc(ve, run::gen_runtriple13, primReal(), SYM(colatitude), formal(primTriple(), SYM(v), false, false), formal(primBoolean(), SYM(warn), true, false));
#line 92 "./runtriple.in"
  addFunc(ve, run::gen_runtriple14, primReal(), SYM(latitude), formal(primTriple(), SYM(v), false, false), formal(primBoolean(), SYM(warn), true, false));
#line 98 "./runtriple.in"
  addFunc(ve, run::gen_runtriple15, primReal(), SYM(longitude), formal(primTriple(), SYM(v), false, false), formal(primBoolean(), SYM(warn), true, false));
#line 105 "./runtriple.in"
  addFunc(ve, run::gen_runtriple16, primTriple(), SYM(unit), formal(primTriple(), SYM(v), false, false));
#line 110 "./runtriple.in"
  addFunc(ve, run::gen_runtriple17, primReal(), SYM(dot), formal(primTriple(), SYM(u), false, false), formal(primTriple(), SYM(v), false, false));
#line 115 "./runtriple.in"
  addFunc(ve, run::gen_runtriple18, primTriple(), SYM(cross), formal(primTriple(), SYM(u), false, false), formal(primTriple(), SYM(v), false, false));
#line 120 "./runtriple.in"
  addFunc(ve, run::gen_runtriple19, primTriple(), SYM(dir), formal(primTriple(), SYM(z), false, true));
#line 125 "./runtriple.in"
  addFunc(ve, run::gen_runtriple20, primTriple(), SYM(expi), formal(primReal(), SYM(polar), false, false), formal(primReal(), SYM(azimuth), false, false));
#line 130 "./runtriple.in"
  addFunc(ve, run::gen_runtriple21, primTriple(), SYM(dir), formal(primReal(), SYM(colatitude), false, false), formal(primReal(), SYM(longitude), false, false));
#line 135 "./runtriple.in"
  addFunc(ve, run::gen_runtriple22, primTriple(), SYM(realmult), formal(primTriple(), SYM(u), false, false), formal(primTriple(), SYM(v), false, false));
#line 140 "./runtriple.in"
  addFunc(ve, run::gen_runtriple23, primTriple(), SYM(perp), formal(primTriple(), SYM(v), false, false), formal(primTriple(), SYM(u), false, false));
#line 146 "./runtriple.in"
  addFunc(ve, run::gen_runtriple24, primTriple(), SYM(bezier), formal(primTriple(), SYM(a), false, false), formal(primTriple(), SYM(b), false, false), formal(primTriple(), SYM(c), false, false), formal(primTriple(), SYM(d), false, false), formal(primReal(), SYM(t), false, false));
#line 153 "./runtriple.in"
  addFunc(ve, run::gen_runtriple25, primTriple(), SYM(bezierP), formal(primTriple(), SYM(a), false, false), formal(primTriple(), SYM(b), false, false), formal(primTriple(), SYM(c), false, false), formal(primTriple(), SYM(d), false, false), formal(primReal(), SYM(t), false, false));
#line 158 "./runtriple.in"
  addFunc(ve, run::gen_runtriple26, primTriple(), SYM(bezierPP), formal(primTriple(), SYM(a), false, false), formal(primTriple(), SYM(b), false, false), formal(primTriple(), SYM(c), false, false), formal(primTriple(), SYM(d), false, false), formal(primReal(), SYM(t), false, false));
#line 163 "./runtriple.in"
  addFunc(ve, run::gen_runtriple27, primTriple(), SYM(bezierPPP), formal(primTriple(), SYM(a), false, false), formal(primTriple(), SYM(b), false, false), formal(primTriple(), SYM(c), false, false), formal(primTriple(), SYM(d), false, false));
}

} // namespace trans
