static double eval_expr(Parser * p, AVEvalExpr * e) {

    switch (e->type) {

        case e_value:  return e->value;

        case e_const:  return e->value * p->const_value[e->a.const_index];

        case e_func0:  return e->value * e->a.func0(eval_expr(p, e->param[0]));

        case e_func1:  return e->value * e->a.func1(p->opaque, eval_expr(p, e->param[0]));

        case e_func2:  return e->value * e->a.func2(p->opaque, eval_expr(p, e->param[0]), eval_expr(p, e->param[1]));

        case e_squish: return 1/(1+exp(4*eval_expr(p, e->param[0])));

        case e_gauss: { double d = eval_expr(p, e->param[0]); return exp(-d*d/2)/sqrt(2*M_PI); }

        case e_ld:     return e->value * p->var[clip(eval_expr(p, e->param[0]), 0, VARS-1)];

        case e_while: {

            double d;

            while(eval_expr(p, e->param[0]))

                d=eval_expr(p, e->param[1]);

            return d;

        }

        default: {

            double d = eval_expr(p, e->param[0]);

            double d2 = eval_expr(p, e->param[1]);

            switch (e->type) {

                case e_mod: return e->value * (d - floor(d/d2)*d2);

                case e_max: return e->value * (d >  d2 ?   d : d2);

                case e_min: return e->value * (d <  d2 ?   d : d2);

                case e_eq:  return e->value * (d == d2 ? 1.0 : 0.0);

                case e_gt:  return e->value * (d >  d2 ? 1.0 : 0.0);

                case e_gte: return e->value * (d >= d2 ? 1.0 : 0.0);

                case e_pow: return e->value * pow(d, d2);

                case e_mul: return e->value * (d * d2);

                case e_div: return e->value * (d / d2);

                case e_add: return e->value * (d + d2);

                case e_last:return d2;

                case e_st : return e->value * (p->var[clip(d, 0, VARS-1)]= d2);

            }

        }

    }

    return NAN;

}

static double eval_expr(Parser * p, AVEvalExpr * e) {

    switch (e->type) {

        case e_value:  return e->value;

        case e_const:  return e->value * p->const_value[e->a.const_index];

        case e_func0:  return e->value * e->a.func0(eval_expr(p, e->param[0]));

        case e_func1:  return e->value * e->a.func1(p->opaque, eval_expr(p, e->param[0]));

        case e_func2:  return e->value * e->a.func2(p->opaque, eval_expr(p, e->param[0]), eval_expr(p, e->param[1]));

        case e_squish: return 1/(1+exp(4*eval_expr(p, e->param[0])));

        case e_gauss: { double d = eval_expr(p, e->param[0]); return exp(-d*d/2)/sqrt(2*M_PI); }

        case e_ld:     return e->value * p->var[clip(eval_expr(p, e->param[0]), 0, VARS-1)];

        case e_while: {

            double d;

            while(eval_expr(p, e->param[0]))

                d=eval_expr(p, e->param[1]);

            return d;

        }

        default: {

            double d = eval_expr(p, e->param[0]);

            double d2 = eval_expr(p, e->param[1]);

            switch (e->type) {

                case e_mod: return e->value * (d - floor(d/d2)*d2);

                case e_max: return e->value * (d >  d2 ?   d : d2);

                case e_min: return e->value * (d <  d2 ?   d : d2);

                case e_eq:  return e->value * (d == d2 ? 1.0 : 0.0);

                case e_gt:  return e->value * (d >  d2 ? 1.0 : 0.0);

                case e_gte: return e->value * (d >= d2 ? 1.0 : 0.0);

                case e_pow: return e->value * pow(d, d2);

                case e_mul: return e->value * (d * d2);

                case e_div: return e->value * (d / d2);

                case e_add: return e->value * (d + d2);

                case e_last:return d2;

                case e_st : return e->value * (p->var[clip(d, 0, VARS-1)]= d2);

            }

        }

    }

    return NAN;

}

static double FUNC_0(Parser * VAR_0, AVEvalExpr * VAR_1) {

    switch (VAR_1->type) {

        case e_value:  return VAR_1->value;

        case e_const:  return VAR_1->value * VAR_0->const_value[VAR_1->a.const_index];

        case e_func0:  return VAR_1->value * VAR_1->a.func0(FUNC_0(VAR_0, VAR_1->param[0]));

        case e_func1:  return VAR_1->value * VAR_1->a.func1(VAR_0->opaque, FUNC_0(VAR_0, VAR_1->param[0]));

        case e_func2:  return VAR_1->value * VAR_1->a.func2(VAR_0->opaque, FUNC_0(VAR_0, VAR_1->param[0]), FUNC_0(VAR_0, VAR_1->param[1]));

        case e_squish: return 1/(1+exp(4*FUNC_0(VAR_0, VAR_1->param[0])));

        case e_gauss: { double VAR_3 = FUNC_0(VAR_0, VAR_1->param[0]); return exp(-VAR_3*VAR_3/2)/sqrt(2*M_PI); }

        case e_ld:     return VAR_1->value * VAR_0->var[clip(FUNC_0(VAR_0, VAR_1->param[0]), 0, VARS-1)];

        case e_while: {

            double VAR_3;

            while(FUNC_0(VAR_0, VAR_1->param[0]))

                VAR_3=FUNC_0(VAR_0, VAR_1->param[1]);

            return VAR_3;

        }

        default: {

            double VAR_3 = FUNC_0(VAR_0, VAR_1->param[0]);

            double VAR_3 = FUNC_0(VAR_0, VAR_1->param[1]);

            switch (VAR_1->type) {

                case e_mod: return VAR_1->value * (VAR_3 - floor(VAR_3/VAR_3)*VAR_3);

                case e_max: return VAR_1->value * (VAR_3 >  VAR_3 ?   VAR_3 : VAR_3);

                case e_min: return VAR_1->value * (VAR_3 <  VAR_3 ?   VAR_3 : VAR_3);

                case e_eq:  return VAR_1->value * (VAR_3 == VAR_3 ? 1.0 : 0.0);

                case e_gt:  return VAR_1->value * (VAR_3 >  VAR_3 ? 1.0 : 0.0);

                case e_gte: return VAR_1->value * (VAR_3 >= VAR_3 ? 1.0 : 0.0);

                case e_pow: return VAR_1->value * pow(VAR_3, VAR_3);

                case e_mul: return VAR_1->value * (VAR_3 * VAR_3);

                case e_div: return VAR_1->value * (VAR_3 / VAR_3);

                case e_add: return VAR_1->value * (VAR_3 + VAR_3);

                case e_last:return VAR_3;

                case e_st : return VAR_1->value * (VAR_0->var[clip(VAR_3, 0, VARS-1)]= VAR_3);

            }

        }

    }

    return NAN;

}

static double FUNC_0(Parser * VAR_0, AVEvalExpr * VAR_1) { switch (VAR_1->type) { case e_value:  return VAR_1->value; case e_const:  return VAR_1->value * VAR_0->const_value[VAR_1->a.const_index]; case e_func0:  return VAR_1->value * VAR_1->a.func0(FUNC_0(VAR_0, VAR_1->param[0])); case e_func1:  return VAR_1->value * VAR_1->a.func1(VAR_0->opaque, FUNC_0(VAR_0, VAR_1->param[0])); case e_func2:  return VAR_1->value * VAR_1->a.func2(VAR_0->opaque, FUNC_0(VAR_0, VAR_1->param[0]), FUNC_0(VAR_0, VAR_1->param[1])); case e_squish: return 1/(1+exp(4*FUNC_0(VAR_0, VAR_1->param[0]))); case e_gauss: { double VAR_3 = FUNC_0(VAR_0, VAR_1->param[0]); return exp(-VAR_3*VAR_3/2)/sqrt(2*M_PI); } case e_ld:     return VAR_1->value * VAR_0->var[clip(FUNC_0(VAR_0, VAR_1->param[0]), 0, VARS-1)]; case e_while: { double VAR_3; while(FUNC_0(VAR_0, VAR_1->param[0]))
VAR_3=FUNC_0(VAR_0, VAR_1->param[1]); return VAR_3; } default: { double VAR_3 = FUNC_0(VAR_0, VAR_1->param[0]); double VAR_3 = FUNC_0(VAR_0, VAR_1->param[1]); switch (VAR_1->type) { case e_mod: return VAR_1->value * (VAR_3 - floor(VAR_3/VAR_3)*VAR_3); case e_max: return VAR_1->value * (VAR_3 >  VAR_3 ?   VAR_3 : VAR_3); case e_min: return VAR_1->value * (VAR_3 <  VAR_3 ?   VAR_3 : VAR_3); case e_eq:  return VAR_1->value * (VAR_3 == VAR_3 ? 1.0 : 0.0); case e_gt:  return VAR_1->value * (VAR_3 >  VAR_3 ? 1.0 : 0.0); case e_gte: return VAR_1->value * (VAR_3 >= VAR_3 ? 1.0 : 0.0); case e_pow: return VAR_1->value * pow(VAR_3, VAR_3); case e_mul: return VAR_1->value * (VAR_3 * VAR_3); case e_div: return VAR_1->value * (VAR_3 / VAR_3); case e_add: return VAR_1->value * (VAR_3 + VAR_3); case e_last:return VAR_3; case e_st : return VAR_1->value * (VAR_0->var[clip(VAR_3, 0, VARS-1)]= VAR_3); } } } return NAN; }