static double eval_expr(Parser *p, AVExpr *e)

{

    switch (e->type) {

        case e_value:  return e->value;

        case e_const:  return e->value * p->const_values[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[av_clip(eval_expr(p, e->param[0]), 0, VARS-1)];

        case e_isnan:  return e->value * !!isnan(eval_expr(p, e->param[0]));

        case e_floor:  return e->value * floor(eval_expr(p, e->param[0]));

        case e_ceil :  return e->value * ceil (eval_expr(p, e->param[0]));

        case e_trunc:  return e->value * trunc(eval_expr(p, e->param[0]));

        case e_sqrt:   return e->value * sqrt (eval_expr(p, e->param[0]));

        case e_not:    return e->value * (eval_expr(p, e->param[0]) == 0);

        case e_if:     return e->value * ( eval_expr(p, e->param[0]) ? eval_expr(p, e->param[1]) : 0);

        case e_ifnot:  return e->value * (!eval_expr(p, e->param[0]) ? eval_expr(p, e->param[1]) : 0);

        case e_random:{

            int idx= av_clip(eval_expr(p, e->param[0]), 0, VARS-1);

            uint64_t r= isnan(p->var[idx]) ? 0 : p->var[idx];

            r= r*1664525+1013904223;

            p->var[idx]= r;

            return e->value * (r * (1.0/UINT64_MAX));

        }

        case e_while: {

            double d = NAN;

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

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

            return d;

        }

        case e_taylor: {

            double t = 1, d = 0, v;

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

            int id = e->param[2] ? av_clip(eval_expr(p, e->param[2]), 0, VARS-1) : 0;

            int i;

            double var0 = p->var[id];

            for(i=0; i<1000; i++) {

                double ld = d;

                p->var[id] = i;

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

                d += t*v;

                if(ld==d && v)

                    break;

                t *= x / (i+1);

            }

            p->var[id] = var0;

            return d;

        }

        case e_root: {

            int i;

            double low = -1, high = -1, v, low_v = -DBL_MAX, high_v = DBL_MAX;

            double var0 = p->var[0];

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

            for(i=-1; i<1024; i++) {

                if(i<255) {

                    p->var[0] = av_reverse[i&255]*x_max/255;

                } else {

                    p->var[0] = x_max*pow(0.9, i-255);

                    if (i&1) p->var[0] *= -1;

                    if (i&2) p->var[0] += low;

                    else     p->var[0] += high;

                }

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

                if (v<=0 && v>low_v) {

                    low    = p->var[0];

                    low_v  = v;

                }

                if (v>=0 && v<high_v) {

                    high   = p->var[0];

                    high_v = v;

                }

                if (low>=0 && high>=0){

                    while (1) {

                        p->var[0] = (low+high)*0.5;

                        if (low == p->var[0] || high == p->var[0])

                            break;

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

                        if (v<=0) low = p->var[0];

                        if (v>=0) high= p->var[0];

                        if (isnan(v)) {

                            low = high = v;

                            break;

                        }

                    }

                    break;

                }

            }

            p->var[0] = var0;

            return -low_v<high_v ? low : high;

        }

        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_gcd: return e->value * av_gcd(d,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 e->value * d2;

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

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

            }

        }

    }

    return NAN;

}

static double eval_expr(Parser *p, AVExpr *e)

{

    switch (e->type) {

        case e_value:  return e->value;

        case e_const:  return e->value * p->const_values[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[av_clip(eval_expr(p, e->param[0]), 0, VARS-1)];

        case e_isnan:  return e->value * !!isnan(eval_expr(p, e->param[0]));

        case e_floor:  return e->value * floor(eval_expr(p, e->param[0]));

        case e_ceil :  return e->value * ceil (eval_expr(p, e->param[0]));

        case e_trunc:  return e->value * trunc(eval_expr(p, e->param[0]));

        case e_sqrt:   return e->value * sqrt (eval_expr(p, e->param[0]));

        case e_not:    return e->value * (eval_expr(p, e->param[0]) == 0);

        case e_if:     return e->value * ( eval_expr(p, e->param[0]) ? eval_expr(p, e->param[1]) : 0);

        case e_ifnot:  return e->value * (!eval_expr(p, e->param[0]) ? eval_expr(p, e->param[1]) : 0);

        case e_random:{

            int idx= av_clip(eval_expr(p, e->param[0]), 0, VARS-1);

            uint64_t r= isnan(p->var[idx]) ? 0 : p->var[idx];

            r= r*1664525+1013904223;

            p->var[idx]= r;

            return e->value * (r * (1.0/UINT64_MAX));

        }

        case e_while: {

            double d = NAN;

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

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

            return d;

        }

        case e_taylor: {

            double t = 1, d = 0, v;

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

            int id = e->param[2] ? av_clip(eval_expr(p, e->param[2]), 0, VARS-1) : 0;

            int i;

            double var0 = p->var[id];

            for(i=0; i<1000; i++) {

                double ld = d;

                p->var[id] = i;

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

                d += t*v;

                if(ld==d && v)

                    break;

                t *= x / (i+1);

            }

            p->var[id] = var0;

            return d;

        }

        case e_root: {

            int i;

            double low = -1, high = -1, v, low_v = -DBL_MAX, high_v = DBL_MAX;

            double var0 = p->var[0];

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

            for(i=-1; i<1024; i++) {

                if(i<255) {

                    p->var[0] = av_reverse[i&255]*x_max/255;

                } else {

                    p->var[0] = x_max*pow(0.9, i-255);

                    if (i&1) p->var[0] *= -1;

                    if (i&2) p->var[0] += low;

                    else     p->var[0] += high;

                }

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

                if (v<=0 && v>low_v) {

                    low    = p->var[0];

                    low_v  = v;

                }

                if (v>=0 && v<high_v) {

                    high   = p->var[0];

                    high_v = v;

                }

                if (low>=0 && high>=0){

                    while (1) {

                        p->var[0] = (low+high)*0.5;

                        if (low == p->var[0] || high == p->var[0])

                            break;

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

                        if (v<=0) low = p->var[0];

                        if (v>=0) high= p->var[0];

                        if (isnan(v)) {

                            low = high = v;

                            break;

                        }

                    }

                    break;

                }

            }

            p->var[0] = var0;

            return -low_v<high_v ? low : high;

        }

        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_gcd: return e->value * av_gcd(d,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 e->value * d2;

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

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

            }

        }

    }

    return NAN;

}

static double FUNC_0(Parser *VAR_0, AVExpr *VAR_1)

{

    switch (VAR_1->type) {

        case e_value:  return VAR_1->value;

        case e_const:  return VAR_1->value * VAR_0->const_values[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_16 = FUNC_0(VAR_0, VAR_1->param[0]); return exp(-VAR_16*VAR_16/2)/sqrt(2*M_PI); }

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

        case e_isnan:  return VAR_1->value * !!isnan(FUNC_0(VAR_0, VAR_1->param[0]));

        case e_floor:  return VAR_1->value * floor(FUNC_0(VAR_0, VAR_1->param[0]));

        case e_ceil :  return VAR_1->value * ceil (FUNC_0(VAR_0, VAR_1->param[0]));

        case e_trunc:  return VAR_1->value * trunc(FUNC_0(VAR_0, VAR_1->param[0]));

        case e_sqrt:   return VAR_1->value * sqrt (FUNC_0(VAR_0, VAR_1->param[0]));

        case e_not:    return VAR_1->value * (FUNC_0(VAR_0, VAR_1->param[0]) == 0);

        case e_if:     return VAR_1->value * ( FUNC_0(VAR_0, VAR_1->param[0]) ? FUNC_0(VAR_0, VAR_1->param[1]) : 0);

        case e_ifnot:  return VAR_1->value * (!FUNC_0(VAR_0, VAR_1->param[0]) ? FUNC_0(VAR_0, VAR_1->param[1]) : 0);

        case e_random:{

            int VAR_3= av_clip(FUNC_0(VAR_0, VAR_1->param[0]), 0, VARS-1);

            uint64_t r= isnan(VAR_0->var[VAR_3]) ? 0 : VAR_0->var[VAR_3];

            r= r*1664525+1013904223;

            VAR_0->var[VAR_3]= r;

            return VAR_1->value * (r * (1.0/UINT64_MAX));

        }

        case e_while: {

            double VAR_16 = NAN;

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

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

            return VAR_16;

        }

        case e_taylor: {

            double VAR_4 = 1, VAR_16 = 0, VAR_13;

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

            int VAR_7 = VAR_1->param[2] ? av_clip(FUNC_0(VAR_0, VAR_1->param[2]), 0, VARS-1) : 0;

            int VAR_11;

            double VAR_15 = VAR_0->var[VAR_7];

            for(VAR_11=0; VAR_11<1000; VAR_11++) {

                double VAR_10 = VAR_16;

                VAR_0->var[VAR_7] = VAR_11;

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

                VAR_16 += VAR_4*VAR_13;

                if(VAR_10==VAR_16 && VAR_13)

                    break;

                VAR_4 *= VAR_6 / (VAR_11+1);

            }

            VAR_0->var[VAR_7] = VAR_15;

            return VAR_16;

        }

        case e_root: {

            int VAR_11;

            double VAR_11 = -1, VAR_12 = -1, VAR_13, VAR_13 = -DBL_MAX, VAR_14 = DBL_MAX;

            double VAR_15 = VAR_0->var[0];

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

            for(VAR_11=-1; VAR_11<1024; VAR_11++) {

                if(VAR_11<255) {

                    VAR_0->var[0] = av_reverse[VAR_11&255]*VAR_15/255;

                } else {

                    VAR_0->var[0] = VAR_15*pow(0.9, VAR_11-255);

                    if (VAR_11&1) VAR_0->var[0] *= -1;

                    if (VAR_11&2) VAR_0->var[0] += VAR_11;

                    else     VAR_0->var[0] += VAR_12;

                }

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

                if (VAR_13<=0 && VAR_13>VAR_13) {

                    VAR_11    = VAR_0->var[0];

                    VAR_13  = VAR_13;

                }

                if (VAR_13>=0 && VAR_13<VAR_14) {

                    VAR_12   = VAR_0->var[0];

                    VAR_14 = VAR_13;

                }

                if (VAR_11>=0 && VAR_12>=0){

                    while (1) {

                        VAR_0->var[0] = (VAR_11+VAR_12)*0.5;

                        if (VAR_11 == VAR_0->var[0] || VAR_12 == VAR_0->var[0])

                            break;

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

                        if (VAR_13<=0) VAR_11 = VAR_0->var[0];

                        if (VAR_13>=0) VAR_12= VAR_0->var[0];

                        if (isnan(VAR_13)) {

                            VAR_11 = VAR_12 = VAR_13;

                            break;

                        }

                    }

                    break;

                }

            }

            VAR_0->var[0] = VAR_15;

            return -VAR_13<VAR_14 ? VAR_11 : VAR_12;

        }

        default: {

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

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

            switch (VAR_1->type) {

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

                case e_gcd: return VAR_1->value * av_gcd(VAR_16,VAR_16);

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

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

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

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

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

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

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

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

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

                case e_last:return VAR_1->value * VAR_16;

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

                case e_hypot:return VAR_1->value * (sqrt(VAR_16*VAR_16 + VAR_16*VAR_16));

            }

        }

    }

    return NAN;

}

static double FUNC_0(Parser *VAR_0, AVExpr *VAR_1)
{ switch (VAR_1->type) { case e_value:  return VAR_1->value; case e_const:  return VAR_1->value * VAR_0->const_values[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_16 = FUNC_0(VAR_0, VAR_1->param[0]); return exp(-VAR_16*VAR_16/2)/sqrt(2*M_PI); } case e_ld:     return VAR_1->value * VAR_0->var[av_clip(FUNC_0(VAR_0, VAR_1->param[0]), 0, VARS-1)]; case e_isnan:  return VAR_1->value * !!isnan(FUNC_0(VAR_0, VAR_1->param[0])); case e_floor:  return VAR_1->value * floor(FUNC_0(VAR_0, VAR_1->param[0])); case e_ceil :  return VAR_1->value * ceil (FUNC_0(VAR_0, VAR_1->param[0])); case e_trunc:  return VAR_1->value * trunc(FUNC_0(VAR_0, VAR_1->param[0])); case e_sqrt:   return VAR_1->value * sqrt (FUNC_0(VAR_0, VAR_1->param[0])); case e_not:    return VAR_1->value * (FUNC_0(VAR_0, VAR_1->param[0]) == 0); case e_if:     return VAR_1->value * ( FUNC_0(VAR_0, VAR_1->param[0]) ? FUNC_0(VAR_0, VAR_1->param[1]) : 0); case e_ifnot:  return VAR_1->value * (!FUNC_0(VAR_0, VAR_1->param[0]) ? FUNC_0(VAR_0, VAR_1->param[1]) : 0); case e_random:{ int VAR_3= av_clip(FUNC_0(VAR_0, VAR_1->param[0]), 0, VARS-1); uint64_t r= isnan(VAR_0->var[VAR_3]) ? 0 : VAR_0->var[VAR_3]; r= r*1664525+1013904223; VAR_0->var[VAR_3]= r; return VAR_1->value * (r * (1.0/UINT64_MAX)); } case e_while: { double VAR_16 = NAN; while (FUNC_0(VAR_0, VAR_1->param[0]))
VAR_16=FUNC_0(VAR_0, VAR_1->param[1]); return VAR_16; } case e_taylor: { double VAR_4 = 1, VAR_16 = 0, VAR_13; double VAR_6 = FUNC_0(VAR_0, VAR_1->param[1]); int VAR_7 = VAR_1->param[2] ? av_clip(FUNC_0(VAR_0, VAR_1->param[2]), 0, VARS-1) : 0; int VAR_11; double VAR_15 = VAR_0->var[VAR_7]; for(VAR_11=0; VAR_11<1000; VAR_11++) { double VAR_10 = VAR_16; VAR_0->var[VAR_7] = VAR_11; VAR_13 = FUNC_0(VAR_0, VAR_1->param[0]); VAR_16 += VAR_4*VAR_13; if(VAR_10==VAR_16 && VAR_13)
break; VAR_4 *= VAR_6 / (VAR_11+1); } VAR_0->var[VAR_7] = VAR_15; return VAR_16; } case e_root: { int VAR_11; double VAR_11 = -1, VAR_12 = -1, VAR_13, VAR_13 = -DBL_MAX, VAR_14 = DBL_MAX; double VAR_15 = VAR_0->var[0]; double VAR_15 = FUNC_0(VAR_0, VAR_1->param[1]); for(VAR_11=-1; VAR_11<1024; VAR_11++) { if(VAR_11<255) { VAR_0->var[0] = av_reverse[VAR_11&255]*VAR_15/255; } else { VAR_0->var[0] = VAR_15*pow(0.9, VAR_11-255); if (VAR_11&1) VAR_0->var[0] *= -1; if (VAR_11&2) VAR_0->var[0] += VAR_11; else     VAR_0->var[0] += VAR_12; } VAR_13 = FUNC_0(VAR_0, VAR_1->param[0]); if (VAR_13<=0 && VAR_13>VAR_13) { VAR_11    = VAR_0->var[0]; VAR_13  = VAR_13; } if (VAR_13>=0 && VAR_13<VAR_14) { VAR_12   = VAR_0->var[0]; VAR_14 = VAR_13; } if (VAR_11>=0 && VAR_12>=0){ while (1) { VAR_0->var[0] = (VAR_11+VAR_12)*0.5; if (VAR_11 == VAR_0->var[0] || VAR_12 == VAR_0->var[0])
break; VAR_13 = FUNC_0(VAR_0, VAR_1->param[0]); if (VAR_13<=0) VAR_11 = VAR_0->var[0]; if (VAR_13>=0) VAR_12= VAR_0->var[0]; if (isnan(VAR_13)) { VAR_11 = VAR_12 = VAR_13; break; } } break; } } VAR_0->var[0] = VAR_15; return -VAR_13<VAR_14 ? VAR_11 : VAR_12; } default: { double VAR_16 = FUNC_0(VAR_0, VAR_1->param[0]); double VAR_16 = FUNC_0(VAR_0, VAR_1->param[1]); switch (VAR_1->type) { case e_mod: return VAR_1->value * (VAR_16 - floor(VAR_16/VAR_16)*VAR_16); case e_gcd: return VAR_1->value * av_gcd(VAR_16,VAR_16); case e_max: return VAR_1->value * (VAR_16 >  VAR_16 ?   VAR_16 : VAR_16); case e_min: return VAR_1->value * (VAR_16 <  VAR_16 ?   VAR_16 : VAR_16); case e_eq:  return VAR_1->value * (VAR_16 == VAR_16 ? 1.0 : 0.0); case e_gt:  return VAR_1->value * (VAR_16 >  VAR_16 ? 1.0 : 0.0); case e_gte: return VAR_1->value * (VAR_16 >= VAR_16 ? 1.0 : 0.0); case e_pow: return VAR_1->value * pow(VAR_16, VAR_16); case e_mul: return VAR_1->value * (VAR_16 * VAR_16); case e_div: return VAR_1->value * (VAR_16 / VAR_16); case e_add: return VAR_1->value * (VAR_16 + VAR_16); case e_last:return VAR_1->value * VAR_16; case e_st : return VAR_1->value * (VAR_0->var[av_clip(VAR_16, 0, VARS-1)]= VAR_16); case e_hypot:return VAR_1->value * (sqrt(VAR_16*VAR_16 + VAR_16*VAR_16)); } } } return NAN; }