Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
purr-data
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
268
Issues
268
List
Boards
Labels
Service Desk
Milestones
Merge Requests
16
Merge Requests
16
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jonathan Wilkes
purr-data
Commits
c0d6ff36
Commit
c0d6ff36
authored
Oct 22, 2017
by
Jonathan Wilkes
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'update-expr'
parents
77536614
232d14c9
Pipeline
#1022
canceled with stage
in 5 minutes and 48 seconds
Changes
5
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
199 additions
and
194 deletions
+199
-194
pd/doc/5.reference/all_about_expr_and_value.pd
pd/doc/5.reference/all_about_expr_and_value.pd
+15
-5
pd/src/x_vexp.c
pd/src/x_vexp.c
+71
-119
pd/src/x_vexp.h
pd/src/x_vexp.h
+13
-14
pd/src/x_vexp_fun.c
pd/src/x_vexp_fun.c
+89
-51
pd/src/x_vexp_if.c
pd/src/x_vexp_if.c
+11
-5
No files found.
pd/doc/5.reference/all_about_expr_and_value.pd
View file @
c0d6ff36
#N canvas 4
30 58 448 350
10;
#N canvas 4
16 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
32
8 cnv 15 445 20 empty \$0-pddp.cnv.footer empty 20 12 0
#X obj 1
47
8 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
33
0 pd META;
#X restore 392
48
0 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;
pd/src/x_vexp.c
View file @
c0d6ff36
...
...
@@ -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 i
f
called when we have already done some
* ex_parse -- This function i
s
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,8 +698,9 @@ 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 */
...
...
@@ -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
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
);
}
/*
* 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
);
}
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
);
...
...
pd/src/x_vexp.h
View file @
c0d6ff36
...
...
@@ -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)
...
...
pd/src/x_vexp_fun.c
View file @
c0d6ff36
...
...
@@ -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
);
#if
ndef _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)
}
#if
ndef _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
*/
st
atic
void
ex_if
(
t_expr
*
e
,
long
int
argc
,
struct
ex_ex
*
argv
,
struct
ex_ex
*
optr
)
st
ruct
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
*
)
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
)
;
}