Commit 232d14c9 authored by Jonathan Wilkes's avatar Jonathan Wilkes

update expr to Pd Vanilla 0.48 (adds the assignment operator, some other ops)

parent ac235f2b
Pipeline #1019 passed with stage
in 299 minutes and 35 seconds
#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;
......@@ -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;
......
......@@ -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"
  • @jwilkes: There's something wrong with this commit. We don't have the "ext.h" include which is now required, so I'm suddenly getting the following compile error on Linux early on in the build:

    cc -DHAVE_LIBDL -DPA_USE_OSS -DUNIX -DUNISTD -fno-strict-aliasing -DPA_USE_OSS -DUSEAPI_OSS -DPA_USE_ALSA -DUSEAPI_ALSA -M d_ctl.c d_array.c d_delay.c d_filter.c d_math.c d_osc.c d_soundfile.c g_canvas.c g_graph.c g_text.c g_rtext.c g_array.c g_template.c g_io.c g_scalar.c g_traversal.c g_guiconnect.c g_readwrite.c g_editor.c g_clone.c g_undo.c g_all_guis.c g_bang.c g_mycanvas.c g_numbox.c g_toggle.c g_vumeter.c g_magicglass.c g_radio.c g_slider.c m_pd.c m_class.c m_obj.c m_atom.c m_memory.c m_binbuf.c m_conf.c m_glob.c m_sched.c s_main.c s_inter.c s_file.c s_print.c s_loader.c s_path.c s_entry.c s_audio.c s_midi.c s_utf8.c d_ugen.c d_arithmetic.c d_dac.c d_misc.c d_fft.c d_global.c d_resample.c x_arithmetic.c x_connective.c x_interface.c x_midi.c x_misc.c x_time.c x_acoustics.c x_net.c x_text.c x_gui.c x_list.c x_array.c x_preset.c x_scalar.c x_vexp.c x_vexp_if.c x_vexp_fun.c import.c s_midi_oss.c s_audio_oss.c s_audio_alsa.c s_audio_alsamm.c s_midi_alsa.c s_audio_jack.c d_fft_fftw.c d_fftroutine.c > makefile.dependencies
    In file included from x_vexp.c:66:0:
    x_vexp.h:16:10: fatal error: ext.h: No such file or directory
     #include "ext.h"
              ^~~~~~~
    compilation terminated.
    In file included from x_vexp_if.c:24:0:
    x_vexp.h:16:10: fatal error: ext.h: No such file or directory
     #include "ext.h"
              ^~~~~~~
    compilation terminated.
    In file included from x_vexp_fun.c:81:0:
    x_vexp.h:16:10: fatal error: ext.h: No such file or directory
     #include "ext.h"
              ^~~~~~~
    compilation terminated.
    makefile:257: makefile.dependencies: No such file or directory
    make[2]: *** [makefile:242: makefile.dependencies] Error 1
    make[2]: Leaving directory '/home/ag/Sources/aur4/pd+friends/purr-data-dev/src/purr-data/pd/src'
    make[1]: [Makefile:158: pd] Error 2 (ignored)

    I'm not sure what the consequences are (afterwards the rest of the build seems to go through fine, and all my own patches seem to run fine anyway). But I don't remember seeing that compile error before, and it certainly can't be a good thing. ;-) We might be missing some objects due to this error, it's just that nobody noticed it yet?

  • I can't find that ext.h file in vanilla's github repo either, maybe it's something that's supposed to be generated?

  • I think that we should really just skip that #ifdef PD nonsense there and just include m_pd.h, as it was before. I'm currently trying that to see how it goes.

  • Ok, that's obviously just something like make depend that's failing there, so luckily this bug is inconsequential (the resulting packages on Arch look the same, too).

    But we should really fix this. The fix is easy:

    diff --git a/pd/src/x_vexp.h b/pd/src/x_vexp.h
    index 608a64a4..544c1149 100644
    --- a/pd/src/x_vexp.h
    +++ b/pd/src/x_vexp.h
    @@ -10,12 +10,12 @@
     #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

    This simply reverts that part of x_vexp.h to what it was before this commit, which seems to work fine. @jwilkes, can you commit this please? Or should I follow up with a PR?

Please register or sign in to reply
#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)
......
......@@ -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;