diff --git a/pd/doc/5.reference/all_about_expr_and_value.pd b/pd/doc/5.reference/all_about_expr_and_value.pd index df7756794488cc78501b0d002aa201666e3e213c..4f9f0d53a9a878535cc60878f1f4517d720d7bf3 100644 --- a/pd/doc/5.reference/all_about_expr_and_value.pd +++ b/pd/doc/5.reference/all_about_expr_and_value.pd @@ -1,4 +1,4 @@ -#N canvas 430 58 448 350 10; +#N canvas 416 53 448 471 10; #X obj 1 1 cnv 15 445 20 empty \$0-pddp.cnv.header expr_and_value 20 10 1 18 -261106 -33289 0; #X obj 407 2 pddp/pddplink http://puredata.info/dev/pddp -text pddp @@ -23,7 +23,7 @@ aren't the names of functions or operators like some_number \, below: \, \$0-foo is interpretated as "\$0 minus foo". Additionally \, \$0 cannot be at the beginning of the variable name (e.g. \, \$0foo). Underscores provide a workable \, if clunky \, solution:; -#X obj 1 328 cnv 15 445 20 empty \$0-pddp.cnv.footer empty 20 12 0 +#X obj 1 478 cnv 15 445 20 empty \$0-pddp.cnv.footer empty 20 12 0 14 -233017 -33289 0; #N canvas 373 194 494 164 META 0; #X text 12 105 HELP_PATCH_AUTHORS Dave Sabine \, May 5 \, 2003 . Jonathan @@ -34,16 +34,26 @@ Wilkes revised the patch to conform to the PDDP template for Pd version two Pd objects; #X text 12 25 KEYWORDS expr expr~ fexpr~ value all_about_pd nonlocal ; -#X restore 392 330 pd META; +#X restore 392 480 pd META; #N canvas 218 216 428 141 Related_objects 0; #X obj 1 1 cnv 15 425 20 empty \$0-pddp.cnv.subheading empty 3 12 0 14 -261106 -33289 0; #X text 7 2 [expr] and [value]- Related Objects; -#X restore 103 330 pd Related_objects; -#X obj 6 330 pddp/pddplink all_about.pd -text All About Pd; +#X restore 103 480 pd Related_objects; +#X obj 6 480 pddp/pddplink all_about.pd -text All About Pd; +#X text 21 324 You can also use the assignment operator "=" to assign +a new value to a [value] variable:; +#X floatatom 24 368 5 0 0 0 - - -, f 5; +#X obj 24 388 expr _\$0_foo = $f1 + 42; +#X msg 215 366 bang; +#X obj 215 388 v _\$0_foo; +#X floatatom 215 410 5 0 0 0 - - -, f 5; #X connect 3 0 5 0; #X connect 4 0 3 0; #X connect 6 0 2 0; #X connect 7 0 11 0; #X connect 8 0 12 0; #X connect 12 0 9 0; +#X connect 20 0 21 0; +#X connect 22 0 23 0; +#X connect 23 0 24 0; diff --git a/pd/src/x_vexp.c b/pd/src/x_vexp.c index 548174c3bef1bb3a37470ab358f139765c55404b..b11bc5f96f8d9b486af36540174aa429df3e29ea 100644 --- a/pd/src/x_vexp.c +++ b/pd/src/x_vexp.c @@ -20,6 +20,17 @@ * Oct 2015 * $x[-1] was not equal $x1[-1], not accessing the previous block * (bug fix by Dan Ellis) + * July 2017 --sdy + * - Version 0.55 + * + * - The arrays now redraw after a store into one of their members + * - ex_if() (the "if()" function is reworked to only evaluate either + * the left or the right args depending on the truth value of the condition. + * However, if the condition is a vector, both the left and the right + * are evaluated regradless. + * - priority of ',' and '=' was switched ot fix the bug of using store "=" in + * functions with multiple arguments, which caused an error during execution. + * - The number of inlet and outlets (MAX_VARS) is now set at 100 */ /* @@ -256,6 +267,12 @@ expr_donew(struct expr *expr, int ac, t_atom *av) } expr->exp_stack[expr->exp_nexpr] = (struct ex_ex *)fts_malloc(max_node * sizeof (struct ex_ex)); + if (!expr->exp_stack[expr->exp_nexpr]) { + post_error( (fts_object_t *) expr, + "expr: malloc for expr nodes failed\n"); + goto error; + } + expr->exp_stack[expr->exp_nexpr][max_node-1].ex_type=0; expr->exp_nexpr++; ret = ex_match(list, (long)0); if (expr->exp_nexpr > MAX_VARS) @@ -272,6 +289,7 @@ expr_donew(struct expr *expr, int ac, t_atom *av) list, expr->exp_stack[expr->exp_nexpr - 1], (long *)0); if (!ret) goto error; + fts_free(list); } *ret = nullex; t_freebytes(exp_string, exp_strlen+1); @@ -496,7 +514,7 @@ ex_match(struct ex_ex *eptr, long int op) } /* - * ex_parse -- This function if called when we have already done some + * ex_parse -- This function is called when we have already done some * parsing on the expression, and we have already matched * our brackets and parenthesis. The main job of this * function is to convert the infix expression to the @@ -518,6 +536,7 @@ ex_parse(struct expr *x, struct ex_ex *iptr, struct ex_ex *optr, long int *argc) struct ex_ex *eptr; struct ex_ex *lowpre = 0; /* pointer to the lowest precedence */ struct ex_ex savex; + struct ex_ex *tmpex; long pre = HI_PRE; long count; @@ -551,7 +570,9 @@ ex_parse(struct expr *x, struct ex_ex *iptr, struct ex_ex *optr, long int *argc) case ET_VI: case ET_VAR: if (!count && !eptr[1].ex_type) { - *optr++ = *eptr; + *optr = *eptr; + tmpex = optr; + tmpex->ex_end = ++optr; return (optr); } break; @@ -569,9 +590,10 @@ ex_parse(struct expr *x, struct ex_ex *iptr, struct ex_ex *optr, long int *argc) !((struct ex_ex *) eptr[1].ex_ptr)[1].ex_type) { savex = *((struct ex_ex *) eptr[1].ex_ptr); *((struct ex_ex *) eptr[1].ex_ptr) = nullex; - *optr++ = *eptr; - lowpre = ex_parse(x, &eptr[2], optr, (long *)0); + *optr = *eptr; + lowpre = ex_parse(x, &eptr[2], optr + 1, (long *)0); *((struct ex_ex *) eptr[1].ex_ptr) = savex; + optr->ex_end = lowpre; return(lowpre); } eptr = (struct ex_ex *) eptr[1].ex_ptr; @@ -612,8 +634,8 @@ ex_parse(struct expr *x, struct ex_ex *iptr, struct ex_ex *optr, long int *argc) ac = 0; savex = *((struct ex_ex *) eptr[1].ex_ptr); *((struct ex_ex *) eptr[1].ex_ptr) = nullex; - *optr++ = *eptr; - lowpre = ex_parse(x, &eptr[2], optr, &ac); + *optr = *eptr; + lowpre = ex_parse(x, &eptr[2], optr + 1, &ac); if (!lowpre) return (exNULL); ac++; @@ -625,6 +647,7 @@ ex_parse(struct expr *x, struct ex_ex *iptr, struct ex_ex *optr, long int *argc) return (exNULL); } *((struct ex_ex *) eptr[1].ex_ptr) = savex; + optr->ex_end = lowpre; return (lowpre); } eptr = (struct ex_ex *) eptr[1].ex_ptr; @@ -643,6 +666,7 @@ ex_parse(struct expr *x, struct ex_ex *iptr, struct ex_ex *optr, long int *argc) *((struct ex_ex *) eptr->ex_ptr) = nullex; lowpre = ex_parse(x, &eptr[1], optr, (long *)0); *((struct ex_ex *) eptr->ex_ptr) = savex; + optr->ex_end = lowpre; return (lowpre); } eptr = (struct ex_ex *)eptr->ex_ptr; @@ -674,16 +698,17 @@ ex_parse(struct expr *x, struct ex_ex *iptr, struct ex_ex *optr, long int *argc) ex_print(iptr); return (exNULL); } - *optr++ = *lowpre; - eptr = ex_parse(x, &lowpre[1], optr, argc); + *optr = *lowpre; + eptr = ex_parse(x, &lowpre[1], optr + 1, argc); + optr->ex_end = eptr; return (eptr); } - /* this is the case of using unary operator as a binary opetator */ - if (count == 3 && unary_op(lowpre->ex_op)) { - post("expr: syntax error, missing operand before unary operator\n"); - ex_print(iptr); - return (exNULL); - } + /* this is the case of using unary operator as a binary opetator */ + if (count == 3 && unary_op(lowpre->ex_op)) { + post("expr: syntax error, missing operand before unary operator\n"); + ex_print(iptr); + return (exNULL); + } if (lowpre == iptr) { post("expr: syntax error: mission operand\n"); ex_print(iptr); @@ -691,15 +716,18 @@ ex_parse(struct expr *x, struct ex_ex *iptr, struct ex_ex *optr, long int *argc) } savex = *lowpre; *lowpre = nullex; - if (savex.ex_op != OP_COMMA) - *optr++ = savex; - else - (*argc)++; - eptr = ex_parse(x, iptr, optr, argc); + if (savex.ex_op != OP_COMMA) { + *optr = savex; + eptr = ex_parse(x, iptr, optr + 1, argc); + } else { + (*argc)++; + eptr = ex_parse(x, iptr, optr, argc); + } if (eptr) { eptr = ex_parse(x, &lowpre[1], eptr, argc); *lowpre = savex; } + optr->ex_end = eptr; return (eptr); } @@ -1225,6 +1253,9 @@ ex_eval(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int idx) return (eptr); } +extern struct ex_ex * ex_if(t_expr *expr, struct ex_ex *eptr, + struct ex_ex *optr,struct ex_ex *argv, int idx); + /* * eval_func -- evaluate a function, call ex_eval() on all the arguments * so that all of them are terminal nodes. The call the @@ -1249,12 +1280,24 @@ eval_func(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int idx) return (exNULL); } - for (i = 0; i < f->f_argc; i++) { + /* + * We treat the "if" function differently to be able to evaluate + * the args selectively based on the truth value of the "condition" + */ + if (f->f_func != (void (*)) ex_if) { + for (i = 0; i < f->f_argc; i++) { args[i].ex_type = 0; args[i].ex_int = 0; eptr = ex_eval(expr, eptr, &args[i], idx); - } - (*f->f_func)(expr, f->f_argc, args, optr); + } + (*f->f_func)(expr, f->f_argc, args, optr); + } else { + for (i = 0; i < f->f_argc; i++) { + args[i].ex_type = 0; + args[i].ex_int = 0; + } + eptr = ex_if(expr, eptr, optr, args, idx); + } for (i = 0; i < f->f_argc; i++) { if (args[i].ex_type == ET_VEC) fts_free(args[i].ex_vec); @@ -1956,99 +1999,6 @@ atoif(char *s, long int *value, long int *type) return (p); } - - -#ifdef notdef -/* - * atoif -- ascii to float or integer (understands hex numbers also) - */ -char * -atoif(char *s, long int *value, long int *type) -{ - char *p; - long int_val = 0; - int flt = 0; - t_float pos = 0; - t_float flt_val = 0; - int base = 10; - - p = s; - if (*p == '0' && (p[1] == 'x' || p[1] == 'X')) { - base = 16; - p += 2; - } - while (8) { - switch (*p) { - case '.': - if (flt || base != 10) { - post("expr: syntax error: %s\n", s); - return ((char *) 0); - } - flt++; - pos = 10; - flt_val = int_val; - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (flt) { - flt_val += (*p - '0') / pos; - pos *= 10; - } else { - int_val *= base; - int_val += (*p - '0'); - } - break; - case 'e': - if (base != 16) { - if ( - case 'a': - case 'b': - case 'c': - case 'd': - case 'f': - if (base != 16 || flt) { - post("expr: syntax error: %s\n", s); - return ((char *) 0); - } - int_val *= base; - int_val += (*p - 'a' + 10); - break; - case 'E': - case 'A': - case 'B': - case 'C': - case 'D': - case 'F': - if (base != 16 || flt) { - post("expr: syntax error: %s\n", s); - return ((char *) 0); - } - int_val *= base; - int_val += (*p - 'A' + 10); - break; - default: - if (flt) { - *type = ET_FLT; - *((t_float *) value) = flt_val; - } else { - *type = ET_INT; - *value = int_val; - } - return (p); - } - p++; - } -} -#endif - /* * find_func -- returns a pointer to the found function structure * otherwise it returns 0 @@ -2072,8 +2022,10 @@ find_func(char *s) void ex_print(struct ex_ex *eptr) { + struct ex_ex *extmp; - while (eptr->ex_type) { + extmp = eptr->ex_end; + while (eptr->ex_type && eptr != extmp) { switch (eptr->ex_type) { case ET_INT: post("%ld ", eptr->ex_int); @@ -2085,10 +2037,10 @@ ex_print(struct ex_ex *eptr) post("%s ", eptr->ex_ptr); break; case ET_TBL: - if (!eptr->ex_ptr) { /* special case of $# processing */ + if (!eptr->ex_ptr) { /* special case of $# processing */ post("%s ", "$$"); - break; - } + break; + } case ET_VAR: post("%s ", ex_symname((fts_symbol_t )eptr->ex_ptr)); break; diff --git a/pd/src/x_vexp.h b/pd/src/x_vexp.h index 16f74ef5dd47a0f36a8a2650a92067755766fad9..608a64a486f9c94eb934fd8ed54b256d509e540a 100644 --- a/pd/src/x_vexp.h +++ b/pd/src/x_vexp.h @@ -5,17 +5,17 @@ /* "expr" was written by Shahrokh Yadegari c. 1989. -msp */ /* "expr~" and "fexpr~" conversion by Shahrokh Yadegari c. 1999,2000 */ -//#define MSP -//#ifdef PD -//#undef MSP -//#endif +#define MSP +#ifdef PD +#undef MSP +#endif -//#ifdef PD +#ifdef PD #include "m_pd.h" -//#else /* MSP */ -//#include "ext.h" -//#include "z_dsp.h" -//#endif +#else /* MSP */ +#include "ext.h" +#include "z_dsp.h" +#endif #define fts_malloc malloc #define fts_calloc calloc @@ -57,7 +57,7 @@ void pd_error(void *object, char *fmt, ...); * is 10. */ -#define MAX_VARS 9 +#define MAX_VARS 100 #define MINODES 10 /* was 200 */ /* terminal defines */ @@ -70,8 +70,8 @@ void pd_error(void *object, char *fmt, ...); */ #define OP_SEMI ((long)(1<<16|1)) /* ; */ -#define OP_STORE ((long)(2<<16|28)) /* = */ -#define OP_COMMA ((long)(3<<16|2)) /* , */ +#define OP_COMMA ((long)(2<<16|2)) /* , */ +#define OP_STORE ((long)(3<<16|28)) /* = */ #define OP_LOR ((long)(4<<16|3)) /* || */ #define OP_LAND ((long)(5<<16|4)) /* && */ #define OP_OR ((long)(6<<16|5)) /* | */ @@ -100,8 +100,6 @@ void pd_error(void *object, char *fmt, ...); #define HI_PRE ((long)(100<<16)) /* infinite precedence */ #define PRE_MASK ((long)0xffff0000) /* precedence level mask */ -struct ex_ex; - #define name_ok(c) (((c)=='_') || ((c)>='a' && (c)<='z') || \ ((c)>='A' && (c)<='Z') || ((c) >= '0' && (c) <= '9')) #define unary_op(x) ((x) == OP_NOT || (x) == OP_NEG || (x) == OP_UMINUS) @@ -120,6 +118,7 @@ struct ex_ex { #define ex_op ex_cont.op #define ex_ptr ex_cont.ptr long ex_type; /* type of the node */ + struct ex_ex *ex_end; /* the node after the end of this expression */ }; #define exNULL ((struct ex_ex *)0) diff --git a/pd/src/x_vexp_fun.c b/pd/src/x_vexp_fun.c index 95c323c8004bec639465d38fa71bb7342da9151b..c54cced359b5cff0ef8086bcd2c2eaa4e42debba 100644 --- a/pd/src/x_vexp_fun.c +++ b/pd/src/x_vexp_fun.c @@ -46,6 +46,9 @@ * - fixed sum("table"), and Sum("table", x, y) * - deleted avg(), Avg() as they can be simple expressions * - deleted store as this can be achieved by the '=' operator + * July 2017 --sdy + * + * - ex_if() is reworked to only evaluate either the left or the right arg */ @@ -77,6 +80,9 @@ #include "x_vexp.h" +struct ex_ex *ex_eval(struct expr *expr, struct ex_ex *eptr, + struct ex_ex *optr, int i); + /* forward declarations */ static void ex_min(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); @@ -108,11 +114,12 @@ static void ex_abs(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex static void ex_fmod(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_ceil(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_floor(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); -static void ex_if(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +struct ex_ex * ex_if(t_expr *expr, struct ex_ex *argv, struct ex_ex *optr, + struct ex_ex *args, int idx); static void ex_ldexp(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_imodf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_modf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); -#ifndef _WIN32 +#if !defined(_MSC_VER) || (_MSC_VER >= 17000) static void ex_cbrt(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_erf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_erfc(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); @@ -162,27 +169,27 @@ t_ex_func ex_funcs[] = { {"fact", ex_fact, 1}, {"random", ex_random, 2}, /* random number */ {"abs", ex_abs, 1}, - {"if", ex_if, 3}, + {"if", (void (*))ex_if, 3}, {"ldexp", ex_ldexp, 2}, {"imodf", ex_imodf, 1}, {"modf", ex_modf, 1}, -#ifndef _WIN32 +#if !defined(_MSC_VER) || (_MSC_VER >= 17000) + {"asinh", ex_asinh, 1}, + {"acosh", ex_acosh, 1}, + {"atanh", ex_atanh, 1}, /* hyperbolic atan */ + {"isnan", ex_isnan, 1}, {"cbrt", ex_cbrt, 1}, + {"round", ex_round, 1}, + {"trunc", ex_trunc, 1}, {"erf", ex_erf, 1}, {"erfc", ex_erfc, 1}, {"expm1", ex_expm1, 1}, {"log1p", ex_log1p, 1}, - {"isinf", ex_isinf, 1}, {"finite", ex_finite, 1}, - {"isnan", ex_isnan, 1}, + {"nearbyint", ex_nearbyint, 1}, {"copysign", ex_copysign, 2}, + {"isinf", ex_isinf, 1}, {"remainder", ex_remainder, 2}, - {"asinh", ex_asinh, 1}, - {"acosh", ex_acosh, 1}, - {"atanh", ex_atanh, 1}, /* hyperbolic atan */ - {"round", ex_round, 1}, - {"trunc", ex_trunc, 1}, - {"nearbyint", ex_nearbyint, 1}, #endif #ifdef PD {"size", ex_size, 1}, @@ -861,7 +868,7 @@ ex_tanh(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) } -#ifndef _WIN32 +#if !defined(_MSC_VER) || (_MSC_VER >= 17000) static void ex_asinh(t_expr *e, long argc, struct ex_ex *argv, struct ex_ex *optr) { @@ -979,10 +986,10 @@ ex_abs(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) } /* - *ex_if -- floating point modulo + * ex_if -- if function */ -static void -ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) +struct ex_ex * +ex_if(t_expr *e, struct ex_ex *eptr, struct ex_ex *optr, struct ex_ex *argv, int idx) { struct ex_ex *left, *right, *cond, *res; t_float *op; /* output pointer */ @@ -990,10 +997,14 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) t_float *cp; /* condition pointer */ t_float leftvalue, rightvalue; int j; + int condtrue = 0; + // evaluate the condition + eptr = ex_eval(e, eptr, argv, idx); cond = argv++; - left = argv++; - right = argv; + // only either the left or right will be evaluated depending + // on the truth value of the condition + // However, if the condition is a vector, both args will be evaluated switch (cond->ex_type) { case ET_VEC: @@ -1002,12 +1013,25 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) if (optr->ex_type == ET_VI) { /* SDY remove this test */ post("expr~: Int. error %d", __LINE__); - return; + return (eptr); } - optr->ex_type = ET_VEC; - optr->ex_vec = (t_float *) + optr->ex_type = ET_VEC; + optr->ex_vec = (t_float *) fts_malloc(sizeof (t_float) * e->exp_vsize); + if (!optr->ex_vec) { + post("expr:if: no mem"); + /* pass over the left and right args */ + return(cond->ex_end->ex_end); + } } + /* + * if the condition is a vector + * the left and the right args both will get processed + */ + eptr = ex_eval(e, eptr, argv, idx); + left = argv++; + eptr = ex_eval(e, eptr, argv, idx); + right = argv; op = optr->ex_vec; j = e->exp_vsize; cp = cond->ex_vec; @@ -1023,7 +1047,7 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) else *op++ = rightvalue; } - return; + return (eptr); case ET_FLT: rightvalue = right->ex_flt; while (j--) { @@ -1032,7 +1056,7 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) else *op++ = rightvalue; } - return; + return (eptr); case ET_VEC: case ET_VI: rp = right->ex_vec; @@ -1043,13 +1067,13 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) *op++ = *rp; rp++; } - return; + return (eptr); case ET_SYM: default: post_error((fts_object_t *) e, "expr: FUNC_EVAL(%d): bad right type %ld\n", __LINE__, right->ex_type); - return; + return (eptr); } case ET_FLT: leftvalue = left->ex_flt; @@ -1062,7 +1086,7 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) else *op++ = rightvalue; } - return; + return (eptr); case ET_FLT: rightvalue = right->ex_flt; while (j--) { @@ -1071,7 +1095,7 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) else *op++ = rightvalue; } - return; + return (eptr); case ET_VEC: case ET_VI: rp = right->ex_vec; @@ -1082,13 +1106,13 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) *op++ = *rp; rp++; } - return; + return (eptr); case ET_SYM: default: post_error((fts_object_t *) e, "expr: FUNC_EVAL(%d): bad right type %ld\n", __LINE__, right->ex_type); - return; + return (eptr); } case ET_VEC: case ET_VI: @@ -1103,7 +1127,7 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) *op++ = rightvalue; lp++; } - return; + return (eptr); case ET_FLT: rightvalue = right->ex_flt; while (j--) { @@ -1113,7 +1137,7 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) *op++ = rightvalue; lp++; } - return; + return (eptr); case ET_VEC: case ET_VI: rp = right->ex_vec; @@ -1124,77 +1148,91 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) *op++ = *rp; lp++; rp++; } - return; + return (eptr); case ET_SYM: default: post_error((fts_object_t *) e, "expr: FUNC_EVAL(%d): bad right type %ld\n", __LINE__, right->ex_type); - return; + return (eptr); } case ET_SYM: default: post_error((fts_object_t *) e, "expr: FUNC_EVAL(%d): bad left type %ld\n", __LINE__, left->ex_type); - return; + return (eptr); } case ET_INT: if (cond->ex_int) - res = left; - else - res = right; + condtrue = 1; + else + condtrue = 0; break; case ET_FLT: if (cond->ex_flt) - res = left; - else - res = right; + condtrue = 1; + else + condtrue = 0; break; case ET_SYM: default: post_error((fts_object_t *) e, "expr: FUNC_EVAL(%d): bad condition type %ld\n", __LINE__, cond->ex_type); - return; + return (eptr); } + if (condtrue) { + eptr = ex_eval(e, eptr, argv, idx); + res = argv++; + eptr = eptr->ex_end; /* no right processing */ + + } else { + eptr = eptr->ex_end; /* no left rocessing */ + eptr = ex_eval(e, eptr, argv, idx); + res = argv++; + } switch(res->ex_type) { case ET_INT: if (optr->ex_type == ET_VEC) { ex_mkvector(optr->ex_vec, (t_float)res->ex_int, e->exp_vsize); - return; + return (eptr); } *optr = *res; - return; + return (eptr); case ET_FLT: if (optr->ex_type == ET_VEC) { ex_mkvector(optr->ex_vec, (t_float)res->ex_flt, e->exp_vsize); - return; + return (eptr); } *optr = *res; - return; + return (eptr); case ET_VEC: case ET_VI: if (optr->ex_type != ET_VEC) { if (optr->ex_type == ET_VI) { /* SDY remove this test */ post("expr~: Int. error %d", __LINE__); - return; + return (eptr); } - optr->ex_type = ET_VEC; - optr->ex_vec = (t_float *) + optr->ex_type = ET_VEC; + optr->ex_vec = (t_float *) fts_malloc(sizeof (t_float) * e->exp_vsize); + if (!optr->ex_vec) { + post("expr:if: no mem"); + return (eptr); + } } memcpy(optr->ex_vec, res->ex_vec, e->exp_vsize*sizeof(t_float)); - return; + return (eptr); case ET_SYM: default: post_error((fts_object_t *) e, "expr: FUNC_EVAL(%d): bad res type %ld\n", __LINE__, res->ex_type); - return; + return (eptr); } } @@ -1231,7 +1269,7 @@ FUNC_DEF_UNARY(ex_modf, fracmodf, (double), 1); */ FUNC_DEF(ex_ldexp, ldexp, (double), (int), 1); -#ifndef _WIN32 +#if !defined(_MSC_VER) || (_MSC_VER >= 17000) /* * ex_cbrt - cube root */ diff --git a/pd/src/x_vexp_if.c b/pd/src/x_vexp_if.c index 675bae4830e6060b982ae1acaefb97611c863fcf..260a198d7e1140fdf2afde36a9cf635900b0be89 100644 --- a/pd/src/x_vexp_if.c +++ b/pd/src/x_vexp_if.c @@ -13,7 +13,8 @@ * --sdy * * - * version 0.50 - March 2015 + * version 0.50 - March 2016 + * version 0.55 - July 2017 */ #include <stdio.h> @@ -22,7 +23,7 @@ #include "x_vexp.h" -static char *exp_version = "0.50"; +static char *exp_version = "0.55"; extern struct ex_ex *ex_eval(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int n); @@ -863,6 +864,8 @@ ex_getsym(char *p, fts_symbol_t *s) const char * ex_symname(fts_symbol_t s) { + if (!s) + return (0); return (fts_symbol_name(s)); } @@ -892,7 +895,7 @@ max_ex_tab(struct expr *expr, fts_symbol_t s, struct ex_ex *arg, { optr->ex_type = ET_FLT; optr->ex_flt = 0; - pd_error(expr, "no such table '%s'", s->s_name); + pd_error(expr, "no such table '%s'", ex_symname(s)); return (1); } optr->ex_type = ET_FLT; @@ -981,16 +984,19 @@ max_ex_tab_store(struct expr *expr, t_symbol *s, struct ex_ex *arg, switch (rval->ex_type) { case ET_INT: wvec[indx].w_float = rval->ex_int; - return(0); + break; case ET_FLT: wvec[indx].w_float = rval->ex_flt; - return(0); + break; default: pd_error(expr, "expr:bad right value type '%ld'", rval->ex_type); optr->ex_type = ET_FLT; optr->ex_flt = 0; return (1); } + garray_redraw(garray); + return(0); + #else /* MSP */ /* * table lookup not done for MSP yet