aboutsummaryrefslogtreecommitdiff
path: root/externals/extra/0.43.2/expr~
diff options
context:
space:
mode:
Diffstat (limited to 'externals/extra/0.43.2/expr~')
-rw-r--r--externals/extra/0.43.2/expr~/LICENSE.txt165
-rw-r--r--externals/extra/0.43.2/expr~/README.txt97
-rw-r--r--externals/extra/0.43.2/expr~/fts_to_pd.h41
-rw-r--r--externals/extra/0.43.2/expr~/vexp.c2142
-rw-r--r--externals/extra/0.43.2/expr~/vexp.h248
-rw-r--r--externals/extra/0.43.2/expr~/vexp_fun.c1315
-rw-r--r--externals/extra/0.43.2/expr~/vexp_if.c1225
7 files changed, 0 insertions, 5233 deletions
diff --git a/externals/extra/0.43.2/expr~/LICENSE.txt b/externals/extra/0.43.2/expr~/LICENSE.txt
deleted file mode 100644
index 01469ec7..00000000
--- a/externals/extra/0.43.2/expr~/LICENSE.txt
+++ /dev/null
@@ -1,165 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
- This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
-
- 0. Additional Definitions.
-
- As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
-
- "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
- An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
- A "Combined Work" is a work produced by combining or linking an
-Application with the Library. The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
- The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
- The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
- 1. Exception to Section 3 of the GNU GPL.
-
- You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
- 2. Conveying Modified Versions.
-
- If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
- a) under this License, provided that you make a good faith effort to
- ensure that, in the event an Application does not supply the
- function or data, the facility still operates, and performs
- whatever part of its purpose remains meaningful, or
-
- b) under the GNU GPL, with none of the additional permissions of
- this License applicable to that copy.
-
- 3. Object Code Incorporating Material from Library Header Files.
-
- The object code form of an Application may incorporate material from
-a header file that is part of the Library. You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
- a) Give prominent notice with each copy of the object code that the
- Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the object code with a copy of the GNU GPL and this license
- document.
-
- 4. Combined Works.
-
- You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
-
- a) Give prominent notice with each copy of the Combined Work that
- the Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the Combined Work with a copy of the GNU GPL and this license
- document.
-
- c) For a Combined Work that displays copyright notices during
- execution, include the copyright notice for the Library among
- these notices, as well as a reference directing the user to the
- copies of the GNU GPL and this license document.
-
- d) Do one of the following:
-
- 0) Convey the Minimal Corresponding Source under the terms of this
- License, and the Corresponding Application Code in a form
- suitable for, and under terms that permit, the user to
- recombine or relink the Application with a modified version of
- the Linked Version to produce a modified Combined Work, in the
- manner specified by section 6 of the GNU GPL for conveying
- Corresponding Source.
-
- 1) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (a) uses at run time
- a copy of the Library already present on the user's computer
- system, and (b) will operate properly with a modified version
- of the Library that is interface-compatible with the Linked
- Version.
-
- e) Provide Installation Information, but only if you would otherwise
- be required to provide such information under section 6 of the
- GNU GPL, and only to the extent that such information is
- necessary to install and execute a modified version of the
- Combined Work produced by recombining or relinking the
- Application with a modified version of the Linked Version. (If
- you use option 4d0, the Installation Information must accompany
- the Minimal Corresponding Source and Corresponding Application
- Code. If you use option 4d1, you must provide the Installation
- Information in the manner specified by section 6 of the GNU GPL
- for conveying Corresponding Source.)
-
- 5. Combined Libraries.
-
- You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
- a) Accompany the combined library with a copy of the same work based
- on the Library, uncombined with any other library facilities,
- conveyed under the terms of this License.
-
- b) Give prominent notice with the combined library that part of it
- is a work based on the Library, and explaining where to find the
- accompanying uncombined form of the same work.
-
- 6. Revised Versions of the GNU Lesser General Public License.
-
- The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
-
- If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
diff --git a/externals/extra/0.43.2/expr~/README.txt b/externals/extra/0.43.2/expr~/README.txt
deleted file mode 100644
index bf84f2ae..00000000
--- a/externals/extra/0.43.2/expr~/README.txt
+++ /dev/null
@@ -1,97 +0,0 @@
-
-You can get more information on the expr object at
-http://www.crca.ucsd.edu/~yadegari/expr.html
-
------------
-
-New if Version 0.4
-
--access to variables (made by value object)
--multiple expression separated by ;
--added the following shorthands:
- $y or $y1 = $y1[-1] and $y2 = $y2[-1]
--new functions:
- if - conditional evaluation
- cbrt - cube root
- erf - error function
- erfc - complementary error function
- expm1 - exponential minus 1,
- log1p - logarithm of 1 plus
- isinf - is the value infinite,
- finite - is the value finite
- isnan -- is the resut a nan (Not a number)
- copysign - copy sign of a number
- ldexp - multiply floating-point number by integral power of 2
- imodf - get signed integral value from floating-point number
- modf - get signed fractional value from floating-point number
- drem - floating-point remainder function
-
- Thanks to Orm Finnendahl for adding the following functions:
- fmod - floating-point remainder function
- ceil - ceiling function: smallest integral value not less than argument
- floor - largest integral value not greater than argument
-
-------------
-
-New in Version 0.3
--Full function functionality
-
-------------
-
-The object "expr" is used for expression evaluaion of control data.
-
-Expr~ and fexpr~ are extentions to the expr object to work with vectors.
-The expr~ object is designed to efficiently combine signal and control
-stream processing by vector operations on the basis of the block size of
-the environment.
-
-fexpr~ object provides a flexible mechanism for building FIR and
-IIR filters by evaluating expressions on a sample by sample basis
-and providing access to prior samples of the input and output audio
-streams. When fractional offset is used, fexpr~ uses linear interpolation
-to determine the value of the indexed sample. fexpr~ evaluates the
-expression for every single sample and at every evaluation previous
-samples (limited by the audio vector size) can be accessed. $x is used to
-denote a singnal input whose samples we would like to access. The syntax
-is $x followed by the inlet number and indexed by brackets, for example
-$x1[-1] specifies the previous sample of the first inlet. Therefore,
-if we are to build a simple filter which replaces every sample by
-the average of that sample and its previous one, we would use "fexpr~
-($x1[0]+$x1[-1])/2 ". For ease of when the brackets are omitted, the
-current sample is implied, so we can right the previous filter expression
-as follows: " fexpr~ ($x1+$x1[-1])/2". To build IIR filters $y is used
-to access the previous samples of the output stream.
-
-The three objects expr, expr~, and fexpr~ are implemented in the same object
-so the files expr~.pd_linux and fexpr~.pd_linux are links to expr.pd_linux
-This release has been compiled and tested on Linux 6.0.
-
---------
-
-Here are some syntax information: (refer to help-expr.pd for examples)
-
-Syntyax:
-The syntax is very close to how expression are written in
-C. Variables are specified as follows where the '#' stands
-for the inlet number:
-$i#: integer input variable
-$f#: float input variable
-$s#: symbol input variable
-
-Used for expr~ only:
-$v#: signal (vector) input (vector by vector evaluation)
-
-Used for fexpr~ only:
-$x#[n]: the sample from inlet # indexed by n, where n has to
- satisfy 0 => n >= -vector size,
- ($x# is a shorthand for $x#[0], specifying the current sample)
-
-$y#[n]: the output value indexed by n, where n has to
- satisfy 0 > n >= -vector size,
- $y[n] is a shorthand for $y1[n]
-
-
-I'll appreciate hearing about bugs, comments, suggestions, ...
-
-Shahrokh Yadegari (sdy@ucsd.edu)
-7/10/02
diff --git a/externals/extra/0.43.2/expr~/fts_to_pd.h b/externals/extra/0.43.2/expr~/fts_to_pd.h
deleted file mode 100644
index 9ca2fc42..00000000
--- a/externals/extra/0.43.2/expr~/fts_to_pd.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* fts_to_pd.h -- alias some fts names to compile in Pd.
-
-copyright 1999 Miller Puckette;
-permission is granted to use this file for any purpose.
-*/
-
-
-#define fts_malloc malloc
-#define fts_calloc calloc
-#define fts_free free
-#define fts_realloc realloc
-#define fts_atom_t t_atom
-#define fts_object_t t_object
-typedef t_symbol *fts_symbol_t;
-
-#ifdef MSP
-#define t_atom Atom
-#define t_symbol Symbol
-#define pd_new(x) newobject(x);
-#define pd_free(x) freeobject(x);
-#define t_outlet void
-#define t_binbuf void
-typedef t_class *t_pd;
-typedef float t_floatarg;
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-
-void pd_error(void *object, char *fmt, ...);
-
-#endif /* MSP */
-
-#define post_error pd_error
-#define fts_is_floatg(x) ((x)->a_type == A_FLOAT)
-
-#define fts_new_symbol_copy gensym
-
-#define fts_symbol_name(x) ((x)->s_name)
diff --git a/externals/extra/0.43.2/expr~/vexp.c b/externals/extra/0.43.2/expr~/vexp.c
deleted file mode 100644
index 8f8ff46c..00000000
--- a/externals/extra/0.43.2/expr~/vexp.c
+++ /dev/null
@@ -1,2142 +0,0 @@
-/*
- * jMax
- * Copyright (C) 1994, 1995, 1998, 1999 by IRCAM-Centre Georges Pompidou, Paris, France.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * See file LICENSE for further informations on licensing terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Based on Max/ISPW by Miller Puckette.
- *
- * Authors: Maurizio De Cecco, Francois Dechelle, Enzo Maggi, Norbert Schnell.
- *
- */
-
-/* "expr" was written by Shahrokh Yadegari c. 1989. -msp */
-/* "expr~" and "fexpr~" conversion by Shahrokh Yadegari c. 1999,2000 */
-
-/*
- * Feb 2002 - added access to variables
- * multiple expression support
- * new short hand forms for fexpr~
- * now $y or $y1 = $y1[-1] and $y2 = $y2[-1]
- * --sdy
- *
- * July 2002
- * fixed bugs introduced in last changes in store and ET_EQ
- * --sdy
- *
- */
-
-/*
- * vexp.c -- a variable expression evaluator
- *
- * This modules implements an expression evaluator using the
- * operator-precedence parsing. It transforms an infix expression
- * to a prefix stack ready to be evaluated. The expression sysntax
- * is close to that of C. There are a few operators that are not
- * supported and functions are also recognized. Strings can be
- * passed to functions when they are quoted in '"'s. "[]" are implememted
- * as an easy way of accessing the content of tables, and the syntax
- * table_name[index].
- * Variables (inlets) are specified with the following syntax: $x#,
- * where x is either i(integers), f(floats), and s(strings); and #
- * is a digit that coresponds to the inlet number. The string variables
- * can be used as strings when they are quoted and can also be used as
- * table names when they are followed by "[]".
- *
- * signal vectors have been added to this implementation:
- * $v# denotes a signal vector
- * $x#[index] is the value of a sample at the index of a the signal vector
- * $x# is the shorthand for $x#[0]
- * $y[index] is the value of the sample output at the index of a the
- * signal output
- * "index" for $x#[index] has to have this range (0 <= index < vectorsize)
- * "index" for $y[index] has to have this range (0 < index < vectorsize)
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include "vexp.h"
-#ifdef MSP
-#undef isdigit
-#define isdigit(x) (x >= '0' && x <= '9')
-#endif
-
-char *atoif(char *s, long int *value, long int *type);
-
-static struct ex_ex *ex_lex(struct expr *expr, long int *n);
-struct ex_ex *ex_match(struct ex_ex *eptr, long int op);
-struct ex_ex *ex_parse(struct expr *expr, struct ex_ex *iptr,
- struct ex_ex *optr, long int *argc);
-struct ex_ex *ex_eval(struct expr *expr, struct ex_ex *eptr,
- struct ex_ex *optr, int i);
-
-int expr_donew(struct expr *exprr, int ac, t_atom *av);
-struct ex_ex *eval_func(struct expr *expr,struct ex_ex *eptr,
- struct ex_ex *optr, int i);
-struct ex_ex *eval_tab(struct expr *expr, struct ex_ex *eptr,
- struct ex_ex *optr, int i);
-struct ex_ex *eval_var(struct expr *expr, struct ex_ex *eptr,
- struct ex_ex *optr, int i);
-struct ex_ex *eval_store(struct expr *expr, struct ex_ex *eptr,
- struct ex_ex *optr, int i);
-struct ex_ex *eval_sigidx(struct expr *expr, struct ex_ex *eptr,
- struct ex_ex *optr, int i);
-static int cal_sigidx(struct ex_ex *optr, /* The output value */
- int i, t_float rem_i, /* integer and fractinal part of index */
- int idx, /* index of current fexpr~ processing */
- int vsize, /* vector size */
- t_float *curvec, t_float *prevec); /* current and previous table */
-t_ex_func *find_func(char *s);
-void ex_dzdetect(struct expr *expr);
-
-#define MAX_ARGS 10
-extern t_ex_func ex_funcs[];
-
-struct ex_ex nullex;
-
-void set_tokens (char *s);
-int getoken (struct expr *expr, struct ex_ex *eptr);
-void ex_print (struct ex_ex *eptr);
-#ifdef MSP
-void atom_string(t_atom *a, char *buf, unsigned int bufsize);
-
-void atom_string(t_atom *a, char *buf, unsigned int bufsize)
-{
- char tbuf[30];
- switch(a->a_type)
- {
- case A_SEMI: strcpy(buf, ";"); break;
- case A_COMMA: strcpy(buf, ","); break;
-#ifdef PD
- case A_POINTER:
- strcpy(buf, "(pointer)");
- break;
-#endif
- case A_FLOAT:
- sprintf(tbuf, "%g", a->a_w.w_float);
- if (strlen(tbuf) < bufsize-1) strcpy(buf, tbuf);
- else if (a->a_w.w_float < 0) strcpy(buf, "-");
- else strcat(buf, "+");
- break;
- case A_LONG:
- sprintf(tbuf, "%d", a->a_w.w_long);
- if (strlen(tbuf) < bufsize-1) strcpy(buf, tbuf);
- else if (a->a_w.w_float < 0) strcpy(buf, "-");
- else strcat(buf, "+");
- break;
- case A_SYMBOL:
- {
- char *sp;
- unsigned int len;
- int quote;
- for (sp = a->a_w.w_symbol->s_name, len = 0, quote = 0; *sp; sp++, len++)
- if (*sp == ';' || *sp == ',' || *sp == '\\' ||
- (*sp == '$' && sp == a->a_w.w_symbol->s_name && sp[1] >= '0'
- && sp[1] <= '9'))
- quote = 1;
- if (quote)
- {
- char *bp = buf, *ep = buf + (bufsize-2);
- sp = a->a_w.w_symbol->s_name;
- while (bp < ep && *sp)
- {
- if (*sp == ';' || *sp == ',' || *sp == '\\' ||
- (*sp == '$' && bp == buf && sp[1] >= '0' && sp[1] <= '9'))
- *bp++ = '\\';
- *bp++ = *sp++;
- }
- if (*sp) *bp++ = '*';
- *bp = 0;
- /* post("quote %s -> %s", a->a_w.w_symbol->s_name, buf); */
- }
- else
- {
- if (len < bufsize-1) strcpy(buf, a->a_w.w_symbol->s_name);
- else
- {
- strncpy(buf, a->a_w.w_symbol->s_name, bufsize - 2);
- strcpy(buf + (bufsize - 2), "*");
- }
- }
- }
- break;
-#ifdef PD
- case A_DOLLAR:
- sprintf(buf, "$%d", a->a_w.w_index);
- break;
- case A_DOLLSYM:
- sprintf(buf, "$%s", a->a_w.w_symbol->s_name);
- break;
-#else /* MAX */
- case A_DOLLAR:
- sprintf(buf, "$%s", a->a_w.w_symbol->s_name);
- break;
-#endif
- default:
- post("atom_string bug");
- }
-}
-#endif /* MSP */
-/*
- * expr_donew -- create a new "expr" object.
- * returns 1 on failure, 0 on success.
- */
-int
-expr_donew(struct expr *expr, int ac, t_atom *av)
-{
- struct ex_ex *list;
- struct ex_ex *ret;
- long max_node = 0; /* maximum number of nodes needed */
- char *exp_string;
- int exp_strlen;
- t_binbuf *b;
- int i;
-
- memset(expr->exp_var, 0, MAX_VARS * sizeof (*expr->exp_var));
-#ifdef PD
- b = binbuf_new();
- binbuf_add(b, ac, av);
- binbuf_gettext(b, &exp_string, &exp_strlen);
-
-#else /* MSP */
- {
- char *buf = getbytes(0), *newbuf;
- int length = 0;
- char string[250];
- t_atom *ap;
- int indx;
-
- for (ap = av, indx = 0; indx < ac; indx++, ap = ++av) {
- int newlength;
- if ((ap->a_type == A_SEMI || ap->a_type == A_COMMA) &&
- length && buf[length-1] == ' ') length--;
- atom_string(ap, string, 250);
- newlength = length + strlen(string) + 1;
- if (!(newbuf = t_resizebytes(buf, length, newlength))) break;
- buf = newbuf;
- strcpy(buf + length, string);
- length = newlength;
- if (ap->a_type == A_SEMI) buf[length-1] = '\n';
- else buf[length-1] = ' ';
- }
-
- if (length && buf[length-1] == ' ') {
- if (newbuf = t_resizebytes(buf, length, length-1))
- {
- buf = newbuf;
- length--;
- }
- }
- exp_string = buf;
- exp_strlen = length;
- }
-#endif
- exp_string = (char *)t_resizebytes(exp_string, exp_strlen,exp_strlen+1);
- exp_string[exp_strlen] = 0;
- expr->exp_string = exp_string;
- expr->exp_str = exp_string;
- expr->exp_nexpr = 0;
- ret = (struct ex_ex *) 0;
- /*
- * if ret == 0 it means that we have no expression
- * so we let the pass go through to build a single null stack
- */
- while (*expr->exp_str || !ret) {
- list = ex_lex(expr, &max_node);
- if (!list) { /* syntax error */
- goto error;
- }
- expr->exp_stack[expr->exp_nexpr] =
- (struct ex_ex *)fts_malloc(max_node * sizeof (struct ex_ex));
- expr->exp_nexpr++;
- ret = ex_match(list, (long)0);
- if (!ret) /* syntax error */
- goto error;
- ret = ex_parse(expr,
- list, expr->exp_stack[expr->exp_nexpr - 1], (long *)0);
- if (!ret)
- goto error;
- }
- *ret = nullex;
- t_freebytes(exp_string, exp_strlen+1);
- return (0);
-error:
- for (i = 0; i < expr->exp_nexpr; i++) {
- fts_free(expr->exp_stack[i]);
- expr->exp_stack[i] = 0;
- }
- expr->exp_nexpr = 0;
- if (list)
- fts_free(list);
- t_freebytes(exp_string, exp_strlen+1);
- return (1);
-}
-
-/*
- * ex_lex -- This routine is a bit more than a lexical parser since it will
- * also do some syntax checking. It reads the string s and will
- * return a linked list of struct ex_ex.
- * It will also put the number of the nodes in *n.
- */
-struct ex_ex *
-ex_lex(struct expr *expr, long int *n)
-{
- struct ex_ex *list_arr;
- struct ex_ex *exptr;
- long non = 0; /* number of nodes */
- long maxnode = 0;
-
- list_arr = (struct ex_ex *)fts_malloc(sizeof (struct ex_ex) * MINODES);
- if (! list_arr) {
- post("ex_lex: no mem\n");
- return ((struct ex_ex *)0);
- }
- exptr = list_arr;
- maxnode = MINODES;
-
- while (8)
- {
- if (non >= maxnode) {
- maxnode += MINODES;
-
- list_arr = fts_realloc((void *)list_arr,
- sizeof (struct ex_ex) * maxnode);
- if (!list_arr) {
- post("ex_lex: no mem\n");
- return ((struct ex_ex *)0);
- }
- exptr = &(list_arr)[non];
- }
-
- if (getoken(expr, exptr)) {
- fts_free(list_arr);
- return ((struct ex_ex *)0);
- }
- non++;
-
- if (!exptr->ex_type)
- break;
-
- exptr++;
- }
- *n = non;
-
- return list_arr;
-}
-
-/*
- * ex_match -- this routine walks through the eptr and matches the
- * perentheses and brackets, it also converts the function
- * names to a pointer to the describing structure of the
- * specified function
- */
-/* operator to match */
-struct ex_ex *
-ex_match(struct ex_ex *eptr, long int op)
-{
- int firstone = 1;
- struct ex_ex *ret;
- t_ex_func *fun;
-
- for (; 8; eptr++, firstone = 0) {
- switch (eptr->ex_type) {
- case 0:
- if (!op)
- return (eptr);
- post("expr syntax error: an open %s not matched\n",
- op == OP_RP ? "parenthesis" : "bracket");
- return (exNULL);
- case ET_INT:
- case ET_FLT:
- case ET_II:
- case ET_FI:
- case ET_SI:
- case ET_VI:
- case ET_SYM:
- case ET_VSYM:
- continue;
- case ET_YO:
- if (eptr[1].ex_type != ET_OP || eptr[1].ex_op != OP_LB)
- eptr->ex_type = ET_YOM1;
- continue;
- case ET_XI:
- if (eptr[1].ex_type != ET_OP || eptr[1].ex_op != OP_LB)
- eptr->ex_type = ET_XI0;
- continue;
- case ET_TBL:
- case ET_FUNC:
- case ET_LP:
- /* CHANGE
- case ET_RP:
- */
- case ET_LB:
- /* CHANGE
- case ET_RB:
- */
- post("ex_match: unexpected type, %ld\n", eptr->ex_type);
- return (exNULL);
- case ET_OP:
- if (op == eptr->ex_op)
- return (eptr);
- /*
- * if we are looking for a right peranthesis
- * or a right bracket and find the other kind,
- * it has to be a syntax error
- */
- if ((eptr->ex_op == OP_RP && op == OP_RB) ||
- (eptr->ex_op == OP_RB && op == OP_RP)) {
- post("expr syntax error: prenthesis or brackets not matched\n");
- return (exNULL);
- }
- /*
- * Up to now we have marked the unary minuses as
- * subrtacts. Any minus that is the first one in
- * chain or is preceeded by anything except ')' and
- * ']' is a unary minus.
- */
- if (eptr->ex_op == OP_SUB) {
- ret = eptr - 1;
- if (firstone || (ret->ex_type == ET_OP &&
- ret->ex_op != OP_RB && ret->ex_op != OP_RP))
- eptr->ex_op = OP_UMINUS;
- } else if (eptr->ex_op == OP_LP) {
- ret = ex_match(eptr + 1, OP_RP);
- if (!ret)
- return (ret);
- eptr->ex_type = ET_LP;
- eptr->ex_ptr = (char *) ret;
- eptr = ret;
- } else if (eptr->ex_op == OP_LB) {
- ret = ex_match(eptr + 1, OP_RB);
- if (!ret)
- return (ret);
- eptr->ex_type = ET_LB;
- eptr->ex_ptr = (char *) ret;
- eptr = ret;
- }
- continue;
- case ET_STR:
- if (eptr[1].ex_op == OP_LB) {
- char *tmp;
-
- eptr->ex_type = ET_TBL;
- tmp = eptr->ex_ptr;
- if (ex_getsym(tmp, (t_symbol **)&(eptr->ex_ptr))) {
- post("expr: syntax error: problms with ex_getsym\n");
- return (exNULL);
- }
- fts_free((void *)tmp);
- } else if (eptr[1].ex_op == OP_LP) {
- fun = find_func(eptr->ex_ptr);
- if (!fun) {
- post(
- "expr: error: function %s not found\n",
- eptr->ex_ptr);
- return (exNULL);
- }
- eptr->ex_type = ET_FUNC;
- eptr->ex_ptr = (char *) fun;
- } else {
- char *tmp;
-
- if (eptr[1].ex_type && eptr[1].ex_type!=ET_OP){
- post("expr: syntax error: bad string '%s'\n", eptr->ex_ptr);
- return (exNULL);
- }
- /* it is a variable */
- eptr->ex_type = ET_VAR;
- tmp = eptr->ex_ptr;
- if (ex_getsym(tmp,
- (t_symbol **)&(eptr->ex_ptr))) {
- post("expr: variable '%s' not found",tmp);
- return (exNULL);
- }
- }
- continue;
- default:
- post("ex_match: bad type\n");
- return (exNULL);
- }
- }
- /* NOTREACHED */
-}
-
-/*
- * ex_parse -- This function if 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
- * prefix form.
- * First we find the operator with the lowest precedence and
- * put it on the stack ('optr', it is really just an array), then
- * we call ourself (ex_parse()), on its arguments (unary operators
- * only have one operator.)
- * When "argc" is set it means that we are parsing the arguments
- * of a function and we will increment *argc anytime we find
- * a a segment that can qualify as an argument (counting commas).
- *
- * returns 0 on syntax error
- */
-/* number of argument separated by comma */
-struct ex_ex *
-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;
- long pre = HI_PRE;
- long count;
-
- if (!iptr) {
- post("ex_parse: input is null, iptr = 0x%lx\n", iptr);
- return (exNULL);
- }
- if (!iptr->ex_type)
- return (exNULL);
-
- /*
- * the following loop finds the lowest precedence operator in the
- * the input token list, comma is explicitly checked here since
- * that is a special operator and is only legal in functions
- */
- for (eptr = iptr, count = 0; eptr->ex_type; eptr++, count++)
- switch (eptr->ex_type) {
- case ET_SYM:
- case ET_VSYM:
- if (!argc) {
- post("expr: syntax error: symbols allowed for functions only\n");
- ex_print(eptr);
- return (exNULL);
- }
- case ET_INT:
- case ET_FLT:
- case ET_II:
- case ET_FI:
- case ET_XI0:
- case ET_YOM1:
- case ET_VI:
- case ET_VAR:
- if (!count && !eptr[1].ex_type) {
- *optr++ = *eptr;
- return (optr);
- }
- break;
- case ET_XI:
- case ET_YO:
- case ET_SI:
- case ET_TBL:
- if (eptr[1].ex_type != ET_LB) {
- post("expr: syntax error: brackets missing\n");
- ex_print(eptr);
- return (exNULL);
- }
- /* if this table is the only token, parse the table */
- if (!count &&
- !((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);
- *((struct ex_ex *) eptr[1].ex_ptr) = savex;
- return(lowpre);
- }
- eptr = (struct ex_ex *) eptr[1].ex_ptr;
- break;
- case ET_OP:
- if (eptr->ex_op == OP_COMMA) {
- if (!argc || !count || !eptr[1].ex_type) {
- post("expr: syntax error: illegal comma\n");
- ex_print(eptr[1].ex_type ? eptr : iptr);
- return (exNULL);
- }
- }
- if (!eptr[1].ex_type) {
- post("expr: syntax error: missing operand\n");
- ex_print(iptr);
- return (exNULL);
- }
- if ((eptr->ex_op & PRE_MASK) <= pre) {
- pre = eptr->ex_op & PRE_MASK;
- lowpre = eptr;
- }
- break;
- case ET_FUNC:
- if (eptr[1].ex_type != ET_LP) {
- post("expr: ex_parse: no parenthesis\n");
- return (exNULL);
- }
- /* if this function is the only token, parse it */
- if (!count &&
- !((struct ex_ex *) eptr[1].ex_ptr)[1].ex_type) {
- long ac;
-
- if (eptr[1].ex_ptr == (char *) &eptr[2]) {
- post("expr: syntax error: missing argument\n");
- ex_print(eptr);
- return (exNULL);
- }
- 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);
- if (!lowpre)
- return (exNULL);
- ac++;
- if (ac !=
- ((t_ex_func *)eptr->ex_ptr)->f_argc){
- post("expr: syntax error: function '%s' needs %ld arguments\n",
- ((t_ex_func *)eptr->ex_ptr)->f_name,
- ((t_ex_func *)eptr->ex_ptr)->f_argc);
- return (exNULL);
- }
- *((struct ex_ex *) eptr[1].ex_ptr) = savex;
- return (lowpre);
- }
- eptr = (struct ex_ex *) eptr[1].ex_ptr;
- break;
- case ET_LP:
- case ET_LB:
- if (!count &&
- !((struct ex_ex *) eptr->ex_ptr)[1].ex_type) {
- if (eptr->ex_ptr == (char *)(&eptr[1])) {
- post("expr: syntax error: empty '%s'\n",
- eptr->ex_type==ET_LP?"()":"[]");
- ex_print(eptr);
- return (exNULL);
- }
- savex = *((struct ex_ex *) eptr->ex_ptr);
- *((struct ex_ex *) eptr->ex_ptr) = nullex;
- lowpre = ex_parse(x, &eptr[1], optr, (long *)0);
- *((struct ex_ex *) eptr->ex_ptr) = savex;
- return (lowpre);
- }
- eptr = (struct ex_ex *)eptr->ex_ptr;
- break;
- case ET_STR:
- default:
- ex_print(eptr);
- post("expr: ex_parse: type = 0x%lx\n", eptr->ex_type);
- return (exNULL);
- }
-
- if (pre == HI_PRE) {
- post("expr: syntax error: missing operation\n");
- ex_print(iptr);
- return (exNULL);
- }
- if (count < 2) {
- post("expr: syntax error: mission operand\n");
- ex_print(iptr);
- return (exNULL);
- }
- if (count == 2) {
- if (lowpre != iptr) {
- post("expr: ex_parse: unary operator should be first\n");
- return (exNULL);
- }
- if (!unary_op(lowpre->ex_op)) {
- post("expr: syntax error: not a uniary operator\n");
- ex_print(iptr);
- return (exNULL);
- }
- *optr++ = *lowpre;
- eptr = ex_parse(x, &lowpre[1], optr, argc);
- return (eptr);
- }
- if (lowpre == iptr) {
- post("expr: syntax error: mission operand\n");
- ex_print(iptr);
- return (exNULL);
- }
- savex = *lowpre;
- *lowpre = nullex;
- if (savex.ex_op != OP_COMMA)
- *optr++ = savex;
- else
- (*argc)++;
- eptr = ex_parse(x, iptr, optr, argc);
- if (eptr) {
- eptr = ex_parse(x, &lowpre[1], eptr, argc);
- *lowpre = savex;
- }
- return (eptr);
-}
-
-/*
- * this is the devide zero check for a a non devide operator
- */
-#define DZC(ARG1,OPR,ARG2) (ARG1 OPR ARG2)
-
-#define EVAL(OPR); \
-eptr = ex_eval(expr, ex_eval(expr, eptr, &left, idx), &right, idx); \
-switch (left.ex_type) { \
-case ET_INT: \
- switch(right.ex_type) { \
- case ET_INT: \
- if (optr->ex_type == ET_VEC) { \
- op = optr->ex_vec; \
- scalar = (t_float)DZC(left.ex_int, OPR, right.ex_int); \
- for (j = 0; j < expr->exp_vsize; j++) \
- *op++ = scalar; \
- } else { \
- optr->ex_type = ET_INT; \
- optr->ex_int = DZC(left.ex_int, OPR, right.ex_int); \
- } \
- break; \
- case ET_FLT: \
- if (optr->ex_type == ET_VEC) { \
- op = optr->ex_vec; \
- scalar = DZC(((t_float)left.ex_int), OPR, right.ex_flt);\
- for (j = 0; j < expr->exp_vsize; j++) \
- *op++ = scalar; \
- } else { \
- optr->ex_type = ET_FLT; \
- optr->ex_flt = DZC(((t_float)left.ex_int), OPR, \
- right.ex_flt); \
- } \
- break; \
- case ET_VEC: \
- case ET_VI: \
- if (optr->ex_type != ET_VEC) { \
- if (optr->ex_type == ET_VI) { \
- post("expr~: Int. error %d", __LINE__); \
- abort(); \
- } \
- optr->ex_type = ET_VEC; \
- optr->ex_vec = (t_float *) \
- fts_malloc(sizeof (t_float)*expr->exp_vsize); \
- } \
- scalar = left.ex_int; \
- rp = right.ex_vec; \
- op = optr->ex_vec; \
- for (i = 0; i < expr->exp_vsize; i++) { \
- *op++ = DZC (scalar, OPR, *rp); \
- rp++; \
- } \
- break; \
- case ET_SYM: \
- default: \
- post_error((fts_object_t *) expr, \
- "expr: ex_eval(%d): bad right type %ld\n", \
- __LINE__, right.ex_type); \
- nullret = 1; \
- } \
- break; \
-case ET_FLT: \
- switch(right.ex_type) { \
- case ET_INT: \
- if (optr->ex_type == ET_VEC) { \
- op = optr->ex_vec; \
- scalar = DZC((t_float) left.ex_flt, OPR, right.ex_int); \
- for (j = 0; j < expr->exp_vsize; j++) \
- *op++ = scalar; \
- } else { \
- optr->ex_type = ET_FLT; \
- optr->ex_flt = DZC(left.ex_flt, OPR, right.ex_int); \
- } \
- break; \
- case ET_FLT: \
- if (optr->ex_type == ET_VEC) { \
- op = optr->ex_vec; \
- scalar = DZC(left.ex_flt, OPR, right.ex_flt); \
- for (j = 0; j < expr->exp_vsize; j++) \
- *op++ = scalar; \
- } else { \
- optr->ex_type = ET_FLT; \
- optr->ex_flt= DZC(left.ex_flt, OPR, right.ex_flt); \
- } \
- break; \
- case ET_VEC: \
- case ET_VI: \
- if (optr->ex_type != ET_VEC) { \
- if (optr->ex_type == ET_VI) { \
- post("expr~: Int. error %d", __LINE__); \
- abort(); \
- } \
- optr->ex_type = ET_VEC; \
- optr->ex_vec = (t_float *) \
- fts_malloc(sizeof (t_float)*expr->exp_vsize); \
- } \
- scalar = left.ex_flt; \
- rp = right.ex_vec; \
- op = optr->ex_vec; \
- for (i = 0; i < expr->exp_vsize; i++) { \
- *op++ = DZC(scalar, OPR, *rp); \
- rp++; \
- } \
- break; \
- case ET_SYM: \
- default: \
- post_error((fts_object_t *) expr, \
- "expr: ex_eval(%d): bad right type %ld\n", \
- __LINE__, right.ex_type); \
- nullret = 1; \
- } \
- break; \
-case ET_VEC: \
-case ET_VI: \
- if (optr->ex_type != ET_VEC) { \
- if (optr->ex_type == ET_VI) { \
- post("expr~: Int. error %d", __LINE__); \
- abort(); \
- } \
- optr->ex_type = ET_VEC; \
- optr->ex_vec = (t_float *) \
- fts_malloc(sizeof (t_float)*expr->exp_vsize); \
- } \
- op = optr->ex_vec; \
- lp = left.ex_vec; \
- switch(right.ex_type) { \
- case ET_INT: \
- scalar = right.ex_int; \
- for (i = 0; i < expr->exp_vsize; i++) { \
- *op++ = DZC(*lp, OPR, scalar); \
- lp++; \
- } \
- break; \
- case ET_FLT: \
- scalar = right.ex_flt; \
- for (i = 0; i < expr->exp_vsize; i++) { \
- *op++ = DZC(*lp, OPR, scalar); \
- lp++; \
- } \
- break; \
- case ET_VEC: \
- case ET_VI: \
- rp = right.ex_vec; \
- for (i = 0; i < expr->exp_vsize; i++) { \
- /* \
- * on a RISC processor one could copy \
- * 8 times in each round to get a considerable \
- * improvement \
- */ \
- *op++ = DZC(*lp, OPR, *rp); \
- rp++; lp++; \
- } \
- break; \
- case ET_SYM: \
- default: \
- post_error((fts_object_t *) expr, \
- "expr: ex_eval(%d): bad right type %ld\n", \
- __LINE__, right.ex_type); \
- nullret = 1; \
- } \
- break; \
-case ET_SYM: \
-default: \
- post_error((fts_object_t *) expr, \
- "expr: ex_eval(%d): bad left type %ld\n", \
- __LINE__, left.ex_type); \
-} \
-break;
-
-/*
- * evaluate a unary operator, TYPE is applied to float operands
- */
-#define EVAL_UNARY(OPR, TYPE) \
- eptr = ex_eval(expr, eptr, &left, idx); \
- switch(left.ex_type) { \
- case ET_INT: \
- if (optr->ex_type == ET_VEC) { \
- ex_mkvector(optr->ex_vec,(t_float)(OPR left.ex_int),\
- expr->exp_vsize);\
- break; \
- } \
- optr->ex_type = ET_INT; \
- optr->ex_int = OPR left.ex_int; \
- break; \
- case ET_FLT: \
- if (optr->ex_type == ET_VEC) { \
- ex_mkvector(optr->ex_vec, OPR (TYPE left.ex_flt),\
- expr->exp_vsize);\
- break; \
- } \
- optr->ex_type = ET_FLT; \
- optr->ex_flt = OPR (TYPE left.ex_flt); \
- break; \
- case ET_VI: \
- case ET_VEC: \
- j = expr->exp_vsize; \
- if (optr->ex_type != ET_VEC) { \
- optr->ex_type = ET_VEC; \
- optr->ex_vec = (t_float *) \
- fts_malloc(sizeof (t_float)*expr->exp_vsize); \
- } \
- op = optr->ex_vec; \
- lp = left.ex_vec; \
- j = expr->exp_vsize; \
- for (i = 0; i < j; i++) \
- *op++ = OPR (TYPE *lp++); \
- break; \
- default: \
- post_error((fts_object_t *) expr, \
- "expr: ex_eval(%d): bad left type %ld\n", \
- __LINE__, left.ex_type); \
- nullret++; \
- } \
- break;
-
-void
-ex_mkvector(t_float *fp, t_float x, int size)
-{
- while (size--)
- *fp++ = x;
-}
-
-/*
- * ex_dzdetect -- divide by zero detected
- */
-void
-ex_dzdetect(struct expr *expr)
-{
- char *etype;
-
- if (!expr->exp_error & EE_DZ) {
- if (IS_EXPR(expr))
- etype = "expr";
- else if (IS_EXPR_TILDE(expr))
- etype = "expr~";
- else if (IS_FEXPR_TILDE(expr))
- etype = "fexpr~";
- else {
- post ("expr -- ex_dzdetect internal error");
- etype = "";
- }
- post ("%s divide by zero detected", etype);
- expr->exp_error |= EE_DZ;
- }
-}
-
-
-/*
- * ex_eval -- evaluate the array of prefix expression
- * ex_eval returns the pointer to the first unevaluated node
- * in the array. This is a recursive routine.
- */
-
-/* SDY
-all the returns in this function need to be changed so that the code
-ends up at the end to check for newly allocated right and left vectors which
-need to be freed
-
-look into the variable nullret
-*/
-struct ex_ex *
-ex_eval(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int idx)
-/* the expr object data pointer */
-/* the operation stack */
-/* the result pointer */
-/* the sample numnber processed for fexpr~ */
-{
- int i, j;
- t_float *lp, *rp, *op; /* left, right, and out pointer to vectors */
- t_float scalar;
- int nullret = 0; /* did we have an error */
- struct ex_ex left, right; /* left and right operands */
-
- left.ex_type = 0;
- left.ex_int = 0;
- right.ex_type = 0;
- right.ex_int = 0;
-
- if (!eptr)
- return (exNULL);
- switch (eptr->ex_type) {
- case ET_INT:
- if (optr->ex_type == ET_VEC)
- ex_mkvector(optr->ex_vec, (t_float) eptr->ex_int,
- expr->exp_vsize);
- else
- *optr = *eptr;
- return (++eptr);
-
- case ET_FLT:
-
- if (optr->ex_type == ET_VEC)
- ex_mkvector(optr->ex_vec, eptr->ex_flt, expr->exp_vsize);
- else
- *optr = *eptr;
- return (++eptr);
-
- case ET_SYM:
- if (optr->ex_type == ET_VEC) {
- post_error((fts_object_t *) expr,
- "expr: ex_eval: cannot turn string to vector\n");
- return (exNULL);
- }
- *optr = *eptr;
- return (++eptr);
- case ET_II:
- if (eptr->ex_int == -1) {
- post_error((fts_object_t *) expr,
- "expr: ex_eval: inlet number not set\n");
- return (exNULL);
- }
- if (optr->ex_type == ET_VEC) {
- ex_mkvector(optr->ex_vec,
- (t_float)expr->exp_var[eptr->ex_int].ex_int,
- expr->exp_vsize);
- } else {
- optr->ex_type = ET_INT;
- optr->ex_int = expr->exp_var[eptr->ex_int].ex_int;
- }
- return (++eptr);
- case ET_FI:
- if (eptr->ex_int == -1) {
- post_error((fts_object_t *) expr,
- "expr: ex_eval: inlet number not set\n");
- return (exNULL);
- }
- if (optr->ex_type == ET_VEC) {
- ex_mkvector(optr->ex_vec,
- expr->exp_var[eptr->ex_int].ex_flt, expr->exp_vsize);
- } else {
- optr->ex_type = ET_FLT;
- optr->ex_flt = expr->exp_var[eptr->ex_int].ex_flt;
- }
- return (++eptr);
-
- case ET_VSYM:
- if (optr->ex_type == ET_VEC) {
- post_error((fts_object_t *) expr,
- "expr: IntErr. vsym in for vec out\n");
- return (exNULL);
- }
- if (eptr->ex_int == -1) {
- post_error((fts_object_t *) expr,
- "expr: ex_eval: inlet number not set\n");
- return (exNULL);
- }
- optr->ex_type = ET_SYM;
- optr->ex_ptr = expr->exp_var[eptr->ex_int].ex_ptr;
- return(++eptr);
-
- case ET_VI:
- if (optr->ex_type != ET_VEC)
- *optr = expr->exp_var[eptr->ex_int];
- else if (optr->ex_vec != expr->exp_var[eptr->ex_int].ex_vec)
- memcpy(optr->ex_vec, expr->exp_var[eptr->ex_int].ex_vec,
- expr->exp_vsize * sizeof (t_float));
- return(++eptr);
- case ET_VEC:
- if (optr->ex_type != ET_VEC) {
- optr->ex_type = ET_VEC;
- optr->ex_vec = eptr->ex_vec;
- eptr->ex_type = ET_INT;
- eptr->ex_int = 0;
- } else if (optr->ex_vec != eptr->ex_vec) {
- memcpy(optr->ex_vec, eptr->ex_vec,
- expr->exp_vsize * sizeof (t_float));
-/* do we need to free here? or can we free higher up */
-/* SDY the next lines do not make sense */
-post("calling fts_free\n");
-abort();
- fts_free(optr->ex_vec);
- optr->ex_type = ET_INT;
- eptr->ex_int = 0;
- } else { /* this should not happen */
- post("expr int. error, optr->ex_vec = %d",optr->ex_vec);
- abort();
- }
- return(++eptr);
- case ET_XI0:
- /* short hand for $x?[0] */
-
- /* SDY delete the following check */
- if (!IS_FEXPR_TILDE(expr) || optr->ex_type==ET_VEC) {
- post("%d:exp->exp_flags = %d", __LINE__,expr->exp_flags);
- abort();
- }
- optr->ex_type = ET_FLT;
- optr->ex_flt = expr->exp_var[eptr->ex_int].ex_vec[idx];
- return(++eptr);
- case ET_YOM1:
- /*
- * short hand for $y?[-1]
- * if we are calculating the first sample of the vector
- * we need to look at the previous results buffer
- */
- optr->ex_type = ET_FLT;
- if (idx == 0)
- optr->ex_flt =
- expr->exp_p_res[eptr->ex_int][expr->exp_vsize - 1];
- else
- optr->ex_flt=expr->exp_tmpres[eptr->ex_int][idx-1];
- return(++eptr);
-
- case ET_YO:
- case ET_XI:
- /* SDY delete the following */
- if (!IS_FEXPR_TILDE(expr) || optr->ex_type==ET_VEC) {
- post("%d:expr->exp_flags = %d", __LINE__,expr->exp_flags);
- abort();
- }
- return (eval_sigidx(expr, eptr, optr, idx));
-
- case ET_TBL:
- case ET_SI:
- return (eval_tab(expr, eptr, optr, idx));
- case ET_FUNC:
- return (eval_func(expr, eptr, optr, idx));
- case ET_VAR:
- return (eval_var(expr, eptr, optr, idx));
- case ET_OP:
- break;
- case ET_STR:
- case ET_LP:
- case ET_LB:
- default:
- post_error((fts_object_t *) expr,
- "expr: ex_eval: unexpected type %d\n", eptr->ex_type);
- return (exNULL);
- }
- if (!eptr[1].ex_type) {
- post_error((fts_object_t *) expr,
- "expr: ex_eval: not enough nodes 1\n");
- return (exNULL);
- }
- if (!unary_op(eptr->ex_op) && !eptr[2].ex_type) {
- post_error((fts_object_t *) expr,
- "expr: ex_eval: not enough nodes 2\n");
- return (exNULL);
- }
-
- switch((eptr++)->ex_op) {
- case OP_STORE:
- return (eval_store(expr, eptr, optr, idx));
- case OP_NOT:
- EVAL_UNARY(!, +);
- case OP_NEG:
- EVAL_UNARY(~, (long));
- case OP_UMINUS:
- EVAL_UNARY(-, +);
- case OP_MUL:
- EVAL(*);
- case OP_ADD:
- EVAL(+);
- case OP_SUB:
- EVAL(-);
- case OP_LT:
- EVAL(<);
- case OP_LE:
- EVAL(<=);
- case OP_GT:
- EVAL(>);
- case OP_GE:
- EVAL(>=);
- case OP_EQ:
- EVAL(==);
- case OP_NE:
- EVAL(!=);
-/*
- * following operators convert their argument to integer
- */
-#undef DZC
-#define DZC(ARG1,OPR,ARG2) (((int)ARG1) OPR ((int)ARG2))
- case OP_SL:
- EVAL(<<);
- case OP_SR:
- EVAL(>>);
- case OP_AND:
- EVAL(&);
- case OP_XOR:
- EVAL(^);
- case OP_OR:
- EVAL(|);
- case OP_LAND:
- EVAL(&&);
- case OP_LOR:
- EVAL(||);
-/*
- * for modulo we need to convert to integer and check for divide by zero
- */
-#undef DZC
-#define DZC(ARG1,OPR,ARG2) (((ARG2)?(((int)ARG1) OPR ((int)ARG2)) \
- : (ex_dzdetect(expr),0)))
- case OP_MOD:
- EVAL(%);
-/*
- * define the divide by zero check for divide
- */
-#undef DZC
-#define DZC(ARG1,OPR,ARG2) (((ARG2)?(ARG1 OPR ARG2):(ex_dzdetect(expr),0)))
- case OP_DIV:
- EVAL(/);
- case OP_LP:
- case OP_RP:
- case OP_LB:
- case OP_RB:
- case OP_COMMA:
- case OP_SEMI:
- default:
- post_error((fts_object_t *) expr, "expr: ex_print: bad op 0x%x\n", eptr->ex_op);
- return (exNULL);
- }
-
-
- /*
- * the left and right nodes could have been transformed to vectors
- * down the chain
- */
- if (left.ex_type == ET_VEC)
- fts_free(left.ex_vec);
- if (right.ex_type == ET_VEC)
- fts_free(right.ex_vec);
- if (nullret)
- return (exNULL);
- else
- return (eptr);
-}
-
-/*
- * eval_func -- evaluate a function, call ex_eval() on all the arguments
- * so that all of them are terminal nodes. The call the
- * appropriate function
- */
-struct ex_ex *
-eval_func(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int idx)
-/* the expr object data pointer */
-/* the operation stack */
-/* the result pointer */
-{
- int i;
- struct ex_ex args[MAX_ARGS];
- t_ex_func *f;
-
- f = (t_ex_func *)(eptr++)->ex_ptr;
- if (!f || !f->f_name) {
- return (exNULL);
- }
- if (f->f_argc > MAX_ARGS) {
- post_error((fts_object_t *) expr, "expr: eval_func: asking too many arguments\n");
- return (exNULL);
- }
-
- 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);
- for (i = 0; i < f->f_argc; i++) {
- if (args[i].ex_type == ET_VEC)
- fts_free(args[i].ex_vec);
- }
- return (eptr);
-}
-
-
-/*
- * eval_store -- evaluate the '=' operator,
- * make sure the first operator is a legal left operator
- * and call ex_eval on the right operator
- */
-struct ex_ex *
-eval_store(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int idx)
-/* the expr object data pointer */
-/* the operation stack */
-/* the result pointer */
-{
- struct ex_ex arg;
- int isvalue;
- char *tbl = (char *) 0;
- char *var = (char *) 0;
- int badleft = 0;
-
-post("store called\n");
-ex_print(eptr);
-eptr = ex_eval(expr, ++eptr, optr, idx);
-return (eptr);
-
-#ifdef notdef /* SDY */
- arg.ex_type = ET_INT;
- arg.ex_int = 0;
- if (eptr->ex_type == ET_VAR) {
- var = (char *) eptr->ex_ptr;
-
- eptr = ex_eval(expr, ++eptr, &arg, idx);
- (void)max_ex_var_store(expr, (t_symbol *)var, &arg, optr);
- if (arg.ex_type == ET_VEC)
- fts_free(arg.ex_vec);
- }
-
-
- if (eptr->ex_type == ET_SI) {
- eptr++;
- if (eptr->ex_type =
- }
-
- /* the left operator should either be a value or a array member */
- switch (eptr->ex_type) {
- case ET_SI:
- if ((eptr + 1)->ex_type == OP_LB) {
- }
- if (!expr->exp_var[eptr->ex_int].ex_ptr) {
- if (!(expr->exp_error & EE_NOTABLE)) {
- post("expr: syntax error: no string for inlet %d", eptr->ex_int + 1);
- post("expr: No more table errors will be reported");
- post("expr: till the next reset");
- expr->exp_error |= EE_NOTABLE;
- }
- badleft++;
- } else
- tbl = (char *) expr->exp_var[eptr->ex_int].ex_ptr;
- break;
- case ET_TBL:
- }
-#endif /* SDY */
-}
-
-/*
- * eval_tab -- evaluate a table operation
- */
-struct ex_ex *
-eval_tab(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int idx)
-/* the expr object data pointer */
-/* the operation stack */
-/* the result pointer */
-{
- struct ex_ex arg;
- char *tbl = (char *) 0;
- int notable = 0;
-
- if (eptr->ex_type == ET_SI) {
- if (!expr->exp_var[eptr->ex_int].ex_ptr) {
-/* SDY post_error() does not work in MAX/MSP yet
- post_error((fts_object_t *) expr,
- "expr: syntax error: no string for inlet %d\n", eptr->ex_int + 1);
-*/
- if (!(expr->exp_error & EE_NOTABLE)) {
- post("expr: syntax error: no string for inlet %d", eptr->ex_int + 1);
- post("expr: No more table errors will be reported");
- post("expr: till the next reset");
- expr->exp_error |= EE_NOTABLE;
- }
- notable++;
- } else
- tbl = (char *) expr->exp_var[eptr->ex_int].ex_ptr;
- } else if (eptr->ex_type == ET_TBL)
- tbl = (char *) eptr->ex_ptr;
- else {
- post_error((fts_object_t *) expr, "expr: eval_tbl: bad type %ld\n", eptr->ex_type);
- notable++;
-
- }
- arg.ex_type = 0;
- arg.ex_int = 0;
- eptr = ex_eval(expr, ++eptr, &arg, idx);
-
- optr->ex_type = ET_INT;
- optr->ex_int = 0;
- if (!notable)
- (void)max_ex_tab(expr, (t_symbol *)tbl, &arg, optr);
- if (arg.ex_type == ET_VEC)
- fts_free(arg.ex_vec);
- return (eptr);
-}
-
-/*
- * eval_var -- evaluate a variable
- */
-struct ex_ex *
-eval_var(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int idx)
-/* the expr object data pointer */
-/* the operation stack */
-/* the result pointer */
-{
- struct ex_ex arg;
- char *var = (char *) 0;
- int novar = 0;
-
- if (eptr->ex_type == ET_SI) {
- if (!expr->exp_var[eptr->ex_int].ex_ptr) {
-/* SDY post_error() does not work in MAX/MSP yet
-post_error((fts_object_t *) expr,
-"expr: syntax error: no string for inlet %d\n", eptr->ex_int + 1);
-*/
- if (!(expr->exp_error & EE_NOVAR)) {
- post("expr: syntax error: no string for inlet %d", eptr->ex_int + 1);
- post("expr: No more table errors will be reported");
- post("expr: till the next reset");
- expr->exp_error |= EE_NOVAR;
- }
- novar++;
- } else
- var = (char *) expr->exp_var[eptr->ex_int].ex_ptr;
- } else if (eptr->ex_type == ET_VAR)
- var = (char *) eptr->ex_ptr;
- else {
- post_error((fts_object_t *) expr, "expr: eval_tbl: bad type %ld\n", eptr->ex_type);
- novar++;
-
- }
-
- optr->ex_type = ET_INT;
- optr->ex_int = 0;
- if (!novar)
- (void)max_ex_var(expr, (t_symbol *)var, optr);
- return (++eptr);
-}
-
-/*
- * eval_sigidx -- evaluate the value of an indexed signal for fexpr~
- */
-struct ex_ex *
-eval_sigidx(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int idx)
-/* the expr object data pointer */
-/* the operation stack */
-/* the result pointer */
-/* the index */
-{
- struct ex_ex arg;
- struct ex_ex *reteptr;
- int i = 0, j = 0;
- t_float fi = 0, /* index in float */
- rem_i = 0; /* remains of the float */
- char *tbl;
-
- arg.ex_type = 0;
- arg.ex_int = 0;
- reteptr = ex_eval(expr, eptr + 1, &arg, idx);
- if (arg.ex_type == ET_FLT) {
- fi = arg.ex_flt; /* float index */
- i = (int) arg.ex_flt; /* integer index */
- rem_i = arg.ex_flt - i; /* remains of integer */
- } else if (arg.ex_type == ET_INT) {
- fi = arg.ex_int; /* float index */
- i = arg.ex_int;
- rem_i = 0;
- } else {
- post("eval_sigidx: bad res type (%d)", arg.ex_type);
- }
- optr->ex_type = ET_FLT;
- /*
- * indexing an input vector
- */
- if (eptr->ex_type == ET_XI) {
- if (fi > 0) {
- if (!(expr->exp_error & EE_BI_INPUT)) {
- expr->exp_error |= EE_BI_INPUT;
- post("expr: input vector index > 0, (vector x%d[%f])",
- eptr->ex_int + 1, i + rem_i);
- post("fexpr~: index assumed to be = 0");
- post("fexpr~: no error report till next reset");
- ex_print(eptr);
- }
- /* just replace it with zero */
- i = 0;
- rem_i = 0;
- }
- if (cal_sigidx(optr, i, rem_i, idx, expr->exp_vsize,
- expr->exp_var[eptr->ex_int].ex_vec,
- expr->exp_p_var[eptr->ex_int])) {
- if (!(expr->exp_error & EE_BI_INPUT)) {
- expr->exp_error |= EE_BI_INPUT;
- post("expr: input vector index < -VectorSize, (vector x%d[%f])", eptr->ex_int + 1, fi);
- ex_print(eptr);
- post("fexpr~: index assumed to be = -%d",
- expr->exp_vsize);
- post("fexpr~: no error report till next reset");
- }
- }
-
- /*
- * indexing an output vector
- */
- } else if (eptr->ex_type == ET_YO) {
- /* for output vectors index of zero is not legal */
- if (fi >= 0) {
- if (!(expr->exp_error & EE_BI_OUTPUT)) {
- expr->exp_error |= EE_BI_OUTPUT;
- post("fexpr~: bad output index, (%f)", fi);
- ex_print(eptr);
- post("fexpr~: no error report till next reset");
- post("fexpr~: index assumed to be = -1");
- }
- i = -1;
- }
- if (eptr->ex_int >= expr->exp_nexpr) {
- post("fexpr~: $y%d illegal: not that many exprs",
- eptr->ex_int);
- optr->ex_flt = 0;
- return (reteptr);
- }
- if (cal_sigidx(optr, i, rem_i, idx, expr->exp_vsize,
- expr->exp_tmpres[eptr->ex_int],
- expr->exp_p_res[eptr->ex_int])) {
- if (!(expr->exp_error & EE_BI_OUTPUT)) {
- expr->exp_error |= EE_BI_OUTPUT;
- post("fexpr~: bad output index, (%f)", fi);
- ex_print(eptr);
- post("fexpr~: index assumed to be = -%d",
- expr->exp_vsize);
- }
- }
- } else {
- optr->ex_flt = 0;
- post("fexpr~:eval_sigidx: internal error - unknown vector (%d)",
- eptr->ex_type);
- }
- return (reteptr);
-}
-
-/*
- * cal_sigidx -- given two tables (one current one previous) calculate an
- * evaluation of a float index into the vectors by linear
- * interpolation
- * return 0 on success, 1 on failure (index out of bound)
- */
-static int
-cal_sigidx(struct ex_ex *optr, /* The output value */
- int i, t_float rem_i,/* integer and fractinal part of index */
- int idx, /* index of current fexpr~ processing */
- int vsize, /* vector size */
- t_float *curvec, t_float *prevec) /* current and previous table */
-{
- int n;
-
- n = i + idx;
- if (n > 0) {
- /* from the curvec */
- if (rem_i)
- optr->ex_flt = curvec[n] +
- rem_i * (curvec[n] - curvec[n - 1]);
- else
- optr->ex_flt = curvec[n];
- return (0);
- }
- if (n == 0) {
- /*
- * this is the case that the remaining float
- * is between two tables
- */
- if (rem_i)
- optr->ex_flt = *curvec +
- rem_i * (*curvec - prevec[vsize - 1]);
- else
- optr->ex_flt = *curvec;
- return (0);
- }
- /* find the index in the saved buffer */
- n = vsize + n;
- if (n > 0) {
- if (rem_i)
- optr->ex_flt = prevec[n] +
- rem_i * (prevec[n] - prevec[n - 1]);
- else
- optr->ex_flt = prevec[n];
- return (0);
- }
- /* out of bound */
- optr->ex_flt = *prevec;
- return (1);
-}
-
-/*
- * getoken -- return 1 on syntax error otherwise 0
- */
-int
-getoken(struct expr *expr, struct ex_ex *eptr)
-{
- char *p;
- long i;
-
-
- if (!expr->exp_str) {
- post("expr: getoken: expression string not set\n");
- return (0);
- }
-retry:
- if (!*expr->exp_str) {
- eptr->ex_type = 0;
- eptr->ex_int = 0;
- return (0);
- }
- if (*expr->exp_str == ';') {
- expr->exp_str++;
- eptr->ex_type = 0;
- eptr->ex_int = 0;
- return (0);
- }
- eptr->ex_type = ET_OP;
- switch (*expr->exp_str++) {
- case '\\':
- case ' ':
- case '\t':
- goto retry;
- case ';':
- post("expr: syntax error: ';' not implemented\n");
- return (1);
- case ',':
- eptr->ex_op = OP_COMMA;
- break;
- case '(':
- eptr->ex_op = OP_LP;
- break;
- case ')':
- eptr->ex_op = OP_RP;
- break;
- case ']':
- eptr->ex_op = OP_RB;
- break;
- case '~':
- eptr->ex_op = OP_NEG;
- break;
- /* we will take care of unary minus later */
- case '*':
- eptr->ex_op = OP_MUL;
- break;
- case '/':
- eptr->ex_op = OP_DIV;
- break;
- case '%':
- eptr->ex_op = OP_MOD;
- break;
- case '+':
- eptr->ex_op = OP_ADD;
- break;
- case '-':
- eptr->ex_op = OP_SUB;
- break;
- case '^':
- eptr->ex_op = OP_XOR;
- break;
- case '[':
- eptr->ex_op = OP_LB;
- break;
- case '!':
- if (*expr->exp_str == '=') {
- eptr->ex_op = OP_NE;
- expr->exp_str++;
- } else
- eptr->ex_op = OP_NOT;
- break;
- case '<':
- switch (*expr->exp_str) {
- case '<':
- eptr->ex_op = OP_SL;
- expr->exp_str++;
- break;
- case '=':
- eptr->ex_op = OP_LE;
- expr->exp_str++;
- break;
- default:
- eptr->ex_op = OP_LT;
- break;
- }
- break;
- case '>':
- switch (*expr->exp_str) {
- case '>':
- eptr->ex_op = OP_SR;
- expr->exp_str++;
- break;
- case '=':
- eptr->ex_op = OP_GE;
- expr->exp_str++;
- break;
- default:
- eptr->ex_op = OP_GT;
- break;
- }
- break;
- case '=':
- if (*expr->exp_str++ != '=') {
- post("expr: syntax error: =\n");
- return (1);
- }
- eptr->ex_op = OP_EQ;
- break;
-/* do not allow the store till the function is fixed
- if (*expr->exp_str != '=')
- eptr->ex_op = OP_STORE;
- else {
- expr->exp_str++;
- eptr->ex_op = OP_EQ;
- }
- break;
-*/
-
- case '&':
- if (*expr->exp_str == '&') {
- expr->exp_str++;
- eptr->ex_op = OP_LAND;
- } else
- eptr->ex_op = OP_AND;
- break;
-
- case '|':
- if ((*expr->exp_str == '|')) {
- expr->exp_str++;
- eptr->ex_op = OP_LOR;
- } else
- eptr->ex_op = OP_OR;
- break;
- case '$':
- switch (*expr->exp_str++) {
- case 'I':
- case 'i':
- eptr->ex_type = ET_II;
- break;
- case 'F':
- case 'f':
- eptr->ex_type = ET_FI;
- break;
- case 'S':
- case 's':
- eptr->ex_type = ET_SI;
- break;
- case 'V':
- case 'v':
- if (IS_EXPR_TILDE(expr)) {
- eptr->ex_type = ET_VI;
- break;
- }
- post("$v? works only for expr~");
- post("expr: syntax error: %s\n", &expr->exp_str[-2]);
- return (1);
- case 'X':
- case 'x':
- if (IS_FEXPR_TILDE(expr)) {
- eptr->ex_type = ET_XI;
- if (isdigit(*expr->exp_str))
- break;
- /* for $x[] is a shorhand for $x1[] */
- eptr->ex_int = 0;
- goto noinletnum;
- }
- post("$x? works only for fexpr~");
- post("expr: syntax error: %s\n", &expr->exp_str[-2]);
- return (1);
- case 'y':
- case 'Y':
- if (IS_FEXPR_TILDE(expr)) {
- eptr->ex_type = ET_YO;
- /*$y takes no number */
- if (isdigit(*expr->exp_str))
- break;
- /* for $y[] is a shorhand for $y1[] */
- eptr->ex_int = 0;
- goto noinletnum;
- }
- post("$y works only for fexpr~");
- default:
- post("expr: syntax error: %s\n", &expr->exp_str[-2]);
- return (1);
- }
- p = atoif(expr->exp_str, &eptr->ex_op, &i);
- if (!p) {
- post("expr: syntax error: %s\n", &expr->exp_str[-2]);
- return (1);
- }
- if (i != ET_INT) {
- post("expr: syntax error: %s\n", expr->exp_str);
- return (1);
- }
- /*
- * make the user inlets one based rather than zero based
- * therefore we decrement the number that user has supplied
- */
- if (!eptr->ex_op || (eptr->ex_op)-- > MAX_VARS) {
- post("expr: syntax error: inlet or outlet out of range: %s\n",
- expr->exp_str);
- return (1);
- }
-
- /*
- * until we can change the input type of inlets on
- * the fly (at pd_new()
- * time) the first input to expr~ is always a vectore
- * and $f1 or $i1 is
- * illegal for fexr~
- */
- if (eptr->ex_op == 0 &&
- (IS_FEXPR_TILDE(expr) || IS_EXPR_TILDE(expr)) &&
- (eptr->ex_type==ET_II || eptr->ex_type==ET_FI ||
- eptr->ex_type==ET_SI)) {
- post("first inlet of expr~/fexpr~ can only be a vector");
- return (1);
- }
- /* record the inlet or outlet type and check for consistency */
- if (eptr->ex_type == ET_YO ) {
- /* it is an outlet for fexpr~*/
- /* no need to do anything */
- ;
- } else if (!expr->exp_var[eptr->ex_op].ex_type)
- expr->exp_var[eptr->ex_op].ex_type = eptr->ex_type;
- else if (expr->exp_var[eptr->ex_op].ex_type != eptr->ex_type) {
- post("expr: syntax error: inlets can only have one type: %s\n", expr->exp_str);
- return (1);
- }
- expr->exp_str = p;
-noinletnum:
- break;
- case '"':
- {
- struct ex_ex ex;
-
- p = expr->exp_str;
- if (!*expr->exp_str || *expr->exp_str == '"') {
- post("expr: syntax error: empty symbol: %s\n", --expr->exp_str);
- return (1);
- }
- if (getoken(expr, &ex))
- return (1);
- switch (ex.ex_type) {
- case ET_STR:
- if (ex_getsym(ex.ex_ptr, (t_symbol **)&(eptr->ex_ptr))) {
- post("expr: syntax error: getoken: problms with ex_getsym\n");
- return (1);
- }
- eptr->ex_type = ET_SYM;
- break;
- case ET_SI:
- *eptr = ex;
- eptr->ex_type = ET_VSYM;
- break;
- default:
- post("expr: syntax error: bad symbol name: %s\n", p);
- return (1);
- }
- if (*expr->exp_str++ != '"') {
- post("expr: syntax error: missing '\"'\n");
- return (1);
- }
- break;
- }
- case '.':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- p = atoif(--expr->exp_str, &eptr->ex_int, &eptr->ex_type);
- if (!p)
- return (1);
- expr->exp_str = p;
- break;
-
- default:
- /*
- * has to be a string, it should either be a
- * function or a table
- */
- p = --expr->exp_str;
- for (i = 0; name_ok(*p); i++)
- p++;
- if (!i) {
- post("expr: syntax error: %s\n", expr->exp_str);
- return (1);
- }
- eptr->ex_ptr = (char *)fts_malloc(i + 1);
- strncpy(eptr->ex_ptr, expr->exp_str, (int) i);
- (eptr->ex_ptr)[i] = 0;
- expr->exp_str = p;
- /*
- * we mark this as a string and later we will change this
- * to either a function or a table
- */
- eptr->ex_type = ET_STR;
- break;
- }
- return (0);
-}
-
-/*
- * 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 'a':
- case 'b':
- case 'c':
- case 'd':
- case 'e':
- 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 'A':
- case 'B':
- case 'C':
- case 'D':
- case 'E':
- 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++;
- }
-}
-
-/*
- * find_func -- returns a pointer to the found function structure
- * otherwise it returns 0
- */
-t_ex_func *
-find_func(char *s)
-{
- t_ex_func *f;
-
- for (f = ex_funcs; f->f_name; f++)
- if (!strcmp(f->f_name, s))
- return (f);
- return ((t_ex_func *) 0);
-}
-
-
-/*
- * ex_print -- print an expression array
- */
-
-void
-ex_print(struct ex_ex *eptr)
-{
-
- while (eptr->ex_type) {
- switch (eptr->ex_type) {
- case ET_INT:
- post("%ld ", eptr->ex_int);
- break;
- case ET_FLT:
- post("%f ", eptr->ex_flt);
- break;
- case ET_STR:
- post("%s ", eptr->ex_ptr);
- break;
- case ET_TBL:
- case ET_VAR:
- post("%s ", ex_symname((fts_symbol_t )eptr->ex_ptr));
- break;
- case ET_SYM:
- post("\"%s\" ", ex_symname((fts_symbol_t )eptr->ex_ptr));
- break;
- case ET_VSYM:
- post("\"$s%ld\" ", eptr->ex_int + 1);
- break;
- case ET_FUNC:
- post("%s ",
- ((t_ex_func *)eptr->ex_ptr)->f_name);
- break;
- case ET_LP:
- post("%c", '(');
- break;
- /* CHANGE
- case ET_RP:
- post("%c ", ')');
- break;
- */
- case ET_LB:
- post("%c", '[');
- break;
- /* CHANGE
- case ET_RB:
- post("%c ", ']');
- break;
- */
- case ET_II:
- post("$i%ld ", eptr->ex_int + 1);
- break;
- case ET_FI:
- post("$f%ld ", eptr->ex_int + 1);
- break;
- case ET_SI:
- post("$s%lx ", eptr->ex_ptr);
- break;
- case ET_VI:
- post("$v%lx ", eptr->ex_vec);
- break;
- case ET_VEC:
- post("vec = %ld ", eptr->ex_vec);
- break;
- case ET_YOM1:
- case ET_YO:
- post("$y%d", eptr->ex_int + 1);
- break;
- case ET_XI:
- case ET_XI0:
- post("$x%d", eptr->ex_int + 1);
- break;
- case ET_OP:
- switch (eptr->ex_op) {
- case OP_LP:
- post("%c", '(');
- break;
- case OP_RP:
- post("%c ", ')');
- break;
- case OP_LB:
- post("%c", '[');
- break;
- case OP_RB:
- post("%c ", ']');
- break;
- case OP_NOT:
- post("%c", '!');
- break;
- case OP_NEG:
- post("%c", '~');
- break;
- case OP_UMINUS:
- post("%c", '-');
- break;
- case OP_MUL:
- post("%c", '*');
- break;
- case OP_DIV:
- post("%c", '/');
- break;
- case OP_MOD:
- post("%c", '%');
- break;
- case OP_ADD:
- post("%c", '+');
- break;
- case OP_SUB:
- post("%c", '-');
- break;
- case OP_SL:
- post("%s", "<<");
- break;
- case OP_SR:
- post("%s", ">>");
- break;
- case OP_LT:
- post("%c", '<');
- break;
- case OP_LE:
- post("%s", "<=");
- break;
- case OP_GT:
- post("%c", '>');
- break;
- case OP_GE:
- post("%s", ">=");
- break;
- case OP_EQ:
- post("%s", "==");
- break;
- case OP_STORE:
- post("%s", "=");
- break;
- case OP_NE:
- post("%s", "!=");
- break;
- case OP_AND:
- post("%c", '&');
- break;
- case OP_XOR:
- post("%c", '^');
- break;
- case OP_OR:
- post("%c", '|');
- break;
- case OP_LAND:
- post("%s", "&&");
- break;
- case OP_LOR:
- post("%s", "||");
- break;
- case OP_COMMA:
- post("%c", ',');
- break;
- case OP_SEMI:
- post("%c", ';');
- break;
- default:
- post("expr: ex_print: bad op 0x%lx\n", eptr->ex_op);
- }
- break;
- default:
- post("expr: ex_print: bad type 0x%lx\n", eptr->ex_type);
- }
- eptr++;
- }
- post("\n");
-}
-
-#ifdef _WIN32
-void ABORT( void) {bug("expr");}
-#endif
diff --git a/externals/extra/0.43.2/expr~/vexp.h b/externals/extra/0.43.2/expr~/vexp.h
deleted file mode 100644
index df5547ea..00000000
--- a/externals/extra/0.43.2/expr~/vexp.h
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * jMax
- * Copyright (C) 1994, 1995, 1998, 1999 by IRCAM-Centre Georges Pompidou, Paris, France.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * See file LICENSE for further informations on licensing terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Based on Max/ISPW by Miller Puckette.
- *
- * Authors: Maurizio De Cecco, Francois Dechelle, Enzo Maggi, Norbert Schnell.
- *
- */
-
-/* "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
-
-#ifdef PD
-#include "m_pd.h"
-#else /* MSP */
-#include "ext.h"
-#include "z_dsp.h"
-#endif
-
-#include "fts_to_pd.h"
-/* This is put in fts_to_pd.h
-
-#ifdef MSP
-#define t_atom Atom
-#define t_symbol Symbol
-#define pd_new(x) newobject(x);
-#define t_outlet void
-#endif
-*/
-
-/*
- * Currently the maximum number of variables (inlets) that are supported
- * is 10.
- */
-
-#define MAX_VARS 9
-#define MINODES 10 /* was 200 */
-
-/* terminal defines */
-
-/*
- * operations
- * (x<<16|y) x defines the level of precedence,
- * the lower the number the lower the precedence
- * separators are defines as operators just for convenience
- */
-
-#define OP_SEMI ((long)(1<<16|1)) /* ; */
-#define OP_COMMA ((long)(2<<16|2)) /* , */
-#define OP_LOR ((long)(3<<16|3)) /* || */
-#define OP_LAND ((long)(4<<16|4)) /* && */
-#define OP_OR ((long)(5<<16|5)) /* | */
-#define OP_XOR ((long)(6<<16|6)) /* ^ */
-#define OP_AND ((long)(7<<16|7)) /* & */
-#define OP_NE ((long)(8<<16|8)) /* != */
-#define OP_EQ ((long)(8<<16|9)) /* == */
-#define OP_GE ((long)(9<<16|10)) /* >= */
-#define OP_GT ((long)(9<<16|11)) /* > */
-#define OP_LE ((long)(9<<16|12)) /* <= */
-#define OP_LT ((long)(9<<16|13)) /* < */
-#define OP_SR ((long)(10<<16|14)) /* >> */
-#define OP_SL ((long)(10<<16|15)) /* << */
-#define OP_SUB ((long)(11<<16|16)) /* - */
-#define OP_ADD ((long)(11<<16|17)) /* + */
-#define OP_MOD ((long)(12<<16|18)) /* % */
-#define OP_DIV ((long)(12<<16|19)) /* / */
-#define OP_MUL ((long)(12<<16|20)) /* * */
-#define OP_UMINUS ((long)(13<<16|21)) /* - unary minus */
-#define OP_NEG ((long)(13<<16|22)) /* ~ one complement */
-#define OP_NOT ((long)(13<<16|23)) /* ! */
-#define OP_RB ((long)(14<<16|24)) /* ] */
-#define OP_LB ((long)(14<<16|25)) /* [ */
-#define OP_RP ((long)(14<<16|26)) /* ) */
-#define OP_LP ((long)(14<<16|27)) /* ( */
-#define OP_STORE ((long)(15<<16|28)) /* = */
-#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)
-
-struct ex_ex {
- union {
- long v_int;
- t_float v_flt;
- t_float *v_vec; /* this is an for allocated vector */
- long op;
- char *ptr;
- } ex_cont; /* content */
-#define ex_int ex_cont.v_int
-#define ex_flt ex_cont.v_flt
-#define ex_vec ex_cont.v_vec
-#define ex_op ex_cont.op
-#define ex_ptr ex_cont.ptr
- long ex_type; /* type of the node */
-};
-#define exNULL ((struct ex_ex *)0)
-
-/* defines for ex_type */
-#define ET_INT 1 /* an int */
-#define ET_FLT 2 /* a float */
-#define ET_OP 3 /* operator */
-#define ET_STR 4 /* string */
-#define ET_TBL 5 /* a table, the content is a pointer */
-#define ET_FUNC 6 /* a function */
-#define ET_SYM 7 /* symbol ("string") */
-#define ET_VSYM 8 /* variable symbol ("$s?") */
- /* we treat parenthesis and brackets */
- /* special to keep a pointer to their */
- /* match in the content */
-#define ET_LP 9 /* left parenthesis */
-#define ET_LB 10 /* left bracket */
-#define ET_II 11 /* and integer inlet */
-#define ET_FI 12 /* float inlet */
-#define ET_SI 13 /* string inlet */
-#define ET_VI 14 /* signal inlet */
-#define ET_VEC 15 /* allocated signal vector */
- /* special types for fexpr~ */
-#define ET_YO 16 /* vector output for fexpr~ */
-#define ET_YOM1 17 /* shorthand for $y?[-1] */
-#define ET_XI 18 /* vector input for fexpr~ */
-#define ET_XI0 20 /* shorthand for $x?[0] */
-#define ET_VAR 21 /* variable */
-
-/* defines for ex_flags */
-#define EF_TYPE_MASK 0x07 /* first three bits define the type of expr */
-#define EF_EXPR 0x01 /* expr - control in and out */
-#define EF_EXPR_TILDE 0x02 /* expr~ signal and control in, signal out */
-#define EF_FEXPR_TILDE 0x04 /* fexpr~ filter expression */
-
-#define EF_STOP 0x08 /* is it stopped used for expr~ and fexpr~ */
-#define EF_VERBOSE 0x10 /* verbose mode */
-
-#define IS_EXPR(x) ((((x)->exp_flags&EF_TYPE_MASK)|EF_EXPR) == EF_EXPR)
-#define IS_EXPR_TILDE(x) \
- ((((x)->exp_flags&EF_TYPE_MASK)|EF_EXPR_TILDE)==EF_EXPR_TILDE)
-#define IS_FEXPR_TILDE(x) \
- ((((x)->exp_flags&EF_TYPE_MASK)|EF_FEXPR_TILDE)==EF_FEXPR_TILDE)
-
-#define SET_EXPR(x) (x)->exp_flags |= EF_EXPR; \
- (x)->exp_flags &= ~EF_EXPR_TILDE; \
- (x)->exp_flags &= ~EF_FEXPR_TILDE;
-
-#define SET_EXPR_TILDE(x) (x)->exp_flags &= ~EF_EXPR; \
- (x)->exp_flags |= EF_EXPR_TILDE; \
- (x)->exp_flags &= ~EF_FEXPR_TILDE;
-
-#define SET_FEXPR_TILDE(x) (x)->exp_flags &= ~EF_EXPR; \
- (x)->exp_flags &= ~EF_EXPR_TILDE; \
- (x)->exp_flags |= EF_FEXPR_TILDE;
-
-/*
- * defines for expr_error
- */
-#define EE_DZ 0x01 /* divide by zero error */
-#define EE_BI_OUTPUT 0x02 /* Bad output index */
-#define EE_BI_INPUT 0x04 /* Bad input index */
-#define EE_NOTABLE 0x08 /* NO TABLE */
-#define EE_NOVAR 0x10 /* NO VARIABLE */
-
-typedef struct expr {
-#ifdef PD
- t_object exp_ob;
-#else /* MSP */
- t_pxobject exp_ob;
-#endif
- int exp_flags; /* are we expr~, fexpr~, or expr */
- int exp_error; /* reported errors */
- int exp_nexpr; /* number of expressions */
- char *exp_string; /* the full expression string */
- char *exp_str; /* current parsing position */
- t_outlet *exp_outlet[MAX_VARS];
-#ifdef PD
- struct _exprproxy *exp_proxy;
-#else /* MAX */
- void *exp_proxy[MAX_VARS];
- long exp_proxy_id;
-#endif
- struct ex_ex *exp_stack[MAX_VARS];
- struct ex_ex exp_var[MAX_VARS];
- struct ex_ex exp_res[MAX_VARS]; /* the evluation result */
- t_float *exp_p_var[MAX_VARS];
- t_float *exp_p_res[MAX_VARS]; /* the previous evaluation result */
- t_float *exp_tmpres[MAX_VARS]; /* temporty result for fexpr~ */
- int exp_vsize; /* the size of the signal vector */
- int exp_nivec; /* # of vector inlets */
- t_float exp_f; /* control value to be transformed to signal */
-} t_expr;
-
-typedef struct ex_funcs {
- char *f_name; /* function name */
- void (*f_func)(t_expr *, long, struct ex_ex *, struct ex_ex *);
- /* the real function performing the function (void, no return!!!) */
- long f_argc; /* number of arguments */
-} t_ex_func;
-
-/* function prototypes for pd-related functions called withing vexp.h */
-
-extern int max_ex_tab(struct expr *expr, t_symbol *s, struct ex_ex *arg, struct ex_ex *optr);
-extern int max_ex_var(struct expr *expr, t_symbol *s, struct ex_ex *optr);
-extern int ex_getsym(char *p, t_symbol **s);
-extern const char *ex_symname(t_symbol *s);
-void ex_mkvector(t_float *fp, t_float x, int size);
-extern void ex_size(t_expr *expr, long int argc, struct ex_ex *argv,
- struct ex_ex *optr);
-extern void ex_sum(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-extern void ex_Sum(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-extern void ex_avg(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-extern void ex_Avg(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-extern void ex_store(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-
-int value_getonly(t_symbol *s, t_float *f);
-
-
-/* These pragmas are only used for MSVC, not MinGW or Cygwin <hans@at.or.at> */
-#ifdef _MSC_VER
-#pragma warning (disable: 4305 4244)
-#endif
-
-#ifdef _WIN32
-#define abort ABORT
-void ABORT(void);
-#endif
diff --git a/externals/extra/0.43.2/expr~/vexp_fun.c b/externals/extra/0.43.2/expr~/vexp_fun.c
deleted file mode 100644
index 73c0b5c6..00000000
--- a/externals/extra/0.43.2/expr~/vexp_fun.c
+++ /dev/null
@@ -1,1315 +0,0 @@
-/*
- * jMax
- * Copyright (C) 1994, 1995, 1998, 1999 by IRCAM-Centre Georges Pompidou, Paris, France.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * See file LICENSE for further informations on licensing terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Based on Max/ISPW by Miller Puckette.
- *
- * Authors: Maurizio De Cecco, Francois Dechelle, Enzo Maggi, Norbert Schnell.
- *
- */
-
-/* "expr" was written by Shahrokh Yadegari c. 1989. -msp
- *
- * Nov. 2001 --sdy
- * conversion for expr~
- *
- * Jan, 2002 --sdy
- * added fmod()
- *
- * May 2002
- * added floor and ceil for expr -- Orm Finnendahl
- *
- * July 2002 --sdy
- * added the following math funtions:
- * cbrt - cube root
- * erf - error function
- * erfc - complementary error function
- * expm1 - exponential minus 1,
- * log1p - logarithm of 1 plus
- * isinf - is the value infinite,
- * finite - is the value finite
- * isnan -- is the resut a nan (Not a number)
- * copysign - copy sign of a number
- * ldexp - multiply floating-point number by integral power of 2
- * imodf - get signed integral value from floating-point number
- * modf - get signed fractional value from floating-point number
- * drem - floating-point remainder function
- *
- * The following are done but not popular enough in math libss
- * to be included yet
- * hypoth - Euclidean distance function
- * trunc
- * round
- * nearbyint -
- */
-
-
-
-/*
- * vexp_func.c -- this file include all the functions for vexp.
- * the first two arguments to the function are the number
- * of argument and an array of arguments (argc, argv)
- * the last argument is a pointer to a struct ex_ex for
- * the result. Up do this point, the content of the
- * struct ex_ex that these functions receive are either
- * ET_INT (long), ET_FLT (t_float), or ET_SYM (char **, it is
- * char ** and not char * since NewHandle of Mac returns
- * a char ** for relocatability.) The common practice in
- * these functions is that they figure out the type of their
- * result according to the type of the arguments. In general
- * the ET_SYM is used an ET_INT when we expect a value.
- * It is the users responsibility not to pass strings to the
- * function.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#define __STRICT_BSD__
-#include <math.h>
-#undef __STRICT_BSD__
-
-
-#include "vexp.h"
-
-/* forward declarations */
-
-static void ex_min(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_max(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_toint(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_rint(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_tofloat(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_pow(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_exp(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_log(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_ln(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_sin(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_cos(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_asin(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_acos(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_tan(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_atan(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_sinh(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_cosh(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_asinh(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_acosh(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_tanh(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_atanh(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_atan2(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_sqrt(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_fact(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_random(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_abs(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
-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);
-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
-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);
-static void ex_expm1(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_log1p(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_isinf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_finite(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_isnan(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_copysign(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_drem(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
-#endif
-#ifdef notdef
-/* the following will be added once they are more popular in math libraries */
-static void ex_round(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_trunc(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_nearbyint(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_hypoth(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
-#endif
-
-
-t_ex_func ex_funcs[] = {
- {"min", ex_min, 2},
- {"max", ex_max, 2},
- {"int", ex_toint, 1},
- {"rint", ex_rint, 1},
- {"float", ex_tofloat, 1},
- {"fmod", ex_fmod, 2},
- {"floor", ex_floor, 2},
- {"ceil", ex_ceil, 2},
- {"pow", ex_pow, 2},
- {"sqrt", ex_sqrt, 1},
- {"exp", ex_exp, 1},
- {"log10", ex_log, 1},
- {"ln", ex_ln, 1},
- {"log", ex_ln, 1},
- {"sin", ex_sin, 1},
- {"cos", ex_cos, 1},
- {"tan", ex_tan, 1},
- {"asin", ex_asin, 1},
- {"acos", ex_acos, 1},
- {"atan", ex_atan, 1},
- {"atan2", ex_atan2, 2},
- {"sinh", ex_sinh, 1},
- {"cosh", ex_cosh, 1},
- {"tanh", ex_tanh, 1},
- {"fact", ex_fact, 1},
- {"random", ex_random, 2}, /* random number */
- {"abs", ex_abs, 1},
- {"if", ex_if, 3},
- {"ldexp ", ex_ldexp, 1},
- {"imodf ", ex_imodf, 1},
- {"modf", ex_modf, 1},
-#ifndef _WIN32
- {"cbrt", ex_cbrt, 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},
- {"copysig", ex_copysign, 1},
- {"drem", ex_drem, 1},
- {"asinh", ex_asinh, 1},
- {"acosh", ex_acosh, 1},
- {"atanh", ex_atanh, 1}, /* hyperbolic atan */
-#endif
-#ifdef PD
- {"size", ex_size, 1},
- {"sum", ex_sum, 1},
- {"Sum", ex_Sum, 3},
- {"avg", ex_avg, 1},
- {"Avg", ex_Avg, 3},
- {"store", ex_store, 3},
-#endif
-#ifdef notdef
-/* the following will be added once they are more popular in math libraries */
- {"round", ex_round, 1},
- {"trunc", ex_trunc, 1},
- {"nearbyint", ex_nearbyint, 1},
- {"hypoth", ex_hypoth, 1},
-#endif
- {0, 0, 0}
-};
-
-/*
- * FUN_EVAL -- do type checking, evaluate a function,
- * if fltret is set return float
- * otherwise return value based on regular typechecking,
- */
-#define FUNC_EVAL(left, right, func, leftfuncast, rightfuncast, optr, fltret) \
-switch (left->ex_type) { \
-case ET_INT: \
- switch(right->ex_type) { \
- case ET_INT: \
- if (optr->ex_type == ET_VEC) { \
- op = optr->ex_vec; \
- scalar = (t_float)func(leftfuncast left->ex_int, \
- rightfuncast right->ex_int); \
- j = e->exp_vsize; \
- while (j--) \
- *op++ = scalar; \
- } else { \
- if (fltret) { \
- optr->ex_type = ET_FLT; \
- optr->ex_flt = (t_float)func(leftfuncast \
- left->ex_int, rightfuncast right->ex_int); \
- } else { \
- optr->ex_type = ET_INT; \
- optr->ex_int = (int)func(leftfuncast \
- left->ex_int, rightfuncast right->ex_int); \
- } \
- } \
- break; \
- case ET_FLT: \
- if (optr->ex_type == ET_VEC) { \
- op = optr->ex_vec; \
- scalar = (t_float)func(leftfuncast left->ex_int, \
- rightfuncast right->ex_flt); \
- j = e->exp_vsize; \
- while (j--) \
- *op++ = scalar; \
- } else { \
- optr->ex_type = ET_FLT; \
- optr->ex_flt = (t_float)func(leftfuncast left->ex_int, \
- rightfuncast right->ex_flt); \
- } \
- break; \
- case ET_VEC: \
- case ET_VI: \
- if (optr->ex_type != ET_VEC) { \
- if (optr->ex_type == ET_VI) { \
- post("expr~: Int. error %d", __LINE__); \
- abort(); \
- } \
- optr->ex_type = ET_VEC; \
- optr->ex_vec = (t_float *) \
- fts_malloc(sizeof (t_float)*e->exp_vsize); \
- } \
- scalar = left->ex_int; \
- rp = right->ex_vec; \
- op = optr->ex_vec; \
- j = e->exp_vsize; \
- while (j--) { \
- *op++ = (t_float)func(leftfuncast scalar, \
- rightfuncast *rp); \
- rp++; \
- } \
- break; \
- case ET_SYM: \
- default: \
- post_error((fts_object_t *) e, \
- "expr: FUNC_EVAL(%d): bad right type %ld\n", \
- __LINE__, right->ex_type);\
- } \
- break; \
-case ET_FLT: \
- switch(right->ex_type) { \
- case ET_INT: \
- if (optr->ex_type == ET_VEC) { \
- op = optr->ex_vec; \
- scalar = (t_float)func(leftfuncast left->ex_flt, \
- rightfuncast right->ex_int); \
- j = e->exp_vsize; \
- while (j--) \
- *op++ = scalar; \
- } else { \
- optr->ex_type = ET_FLT; \
- optr->ex_flt = (t_float)func(leftfuncast left->ex_flt, \
- rightfuncast right->ex_int); \
- } \
- break; \
- case ET_FLT: \
- if (optr->ex_type == ET_VEC) { \
- op = optr->ex_vec; \
- scalar = (t_float)func(leftfuncast left->ex_flt, \
- rightfuncast right->ex_flt); \
- j = e->exp_vsize; \
- while (j--) \
- *op++ = scalar; \
- } else { \
- optr->ex_type = ET_FLT; \
- optr->ex_flt = (t_float)func(leftfuncast left->ex_flt, \
- rightfuncast right->ex_flt); \
- } \
- break; \
- case ET_VEC: \
- case ET_VI: \
- if (optr->ex_type != ET_VEC) { \
- if (optr->ex_type == ET_VI) { \
- post("expr~: Int. error %d", __LINE__); \
- abort(); \
- } \
- optr->ex_type = ET_VEC; \
- optr->ex_vec = (t_float *) \
- fts_malloc(sizeof (t_float) * e->exp_vsize);\
- } \
- scalar = left->ex_flt; \
- rp = right->ex_vec; \
- op = optr->ex_vec; \
- j = e->exp_vsize; \
- while (j--) { \
- *op++ = (t_float)func(leftfuncast scalar, \
- rightfuncast *rp); \
- rp++; \
- } \
- break; \
- case ET_SYM: \
- default: \
- post_error((fts_object_t *) e, \
- "expr: FUNC_EVAL(%d): bad right type %ld\n", \
- __LINE__, right->ex_type);\
- } \
- break; \
-case ET_VEC: \
-case ET_VI: \
- if (optr->ex_type != ET_VEC) { \
- if (optr->ex_type == ET_VI) { \
- post("expr~: Int. error %d", __LINE__); \
- abort(); \
- } \
- optr->ex_type = ET_VEC; \
- optr->ex_vec = (t_float *) \
- fts_malloc(sizeof (t_float) * e->exp_vsize); \
- } \
- op = optr->ex_vec; \
- lp = left->ex_vec; \
- switch(right->ex_type) { \
- case ET_INT: \
- scalar = right->ex_int; \
- j = e->exp_vsize; \
- while (j--) { \
- *op++ = (t_float)func(leftfuncast *lp, \
- rightfuncast scalar); \
- lp++; \
- } \
- break; \
- case ET_FLT: \
- scalar = right->ex_flt; \
- j = e->exp_vsize; \
- while (j--) { \
- *op++ = (t_float)func(leftfuncast *lp, \
- rightfuncast scalar); \
- lp++; \
- } \
- break; \
- case ET_VEC: \
- case ET_VI: \
- rp = right->ex_vec; \
- j = e->exp_vsize; \
- while (j--) { \
- /* \
- * on a RISC processor one could copy \
- * 8 times in each round to get a considerable \
- * improvement \
- */ \
- *op++ = (t_float)func(leftfuncast *lp, \
- rightfuncast *rp); \
- rp++; lp++; \
- } \
- break; \
- case ET_SYM: \
- default: \
- post_error((fts_object_t *) e, \
- "expr: FUNC_EVAL(%d): bad right type %ld\n", \
- __LINE__, right->ex_type);\
- } \
- break; \
-case ET_SYM: \
-default: \
- post_error((fts_object_t *) e, \
- "expr: FUNC_EVAL(%d): bad left type %ld\n", \
- __LINE__, left->ex_type); \
-}
-
-/*
- * FUNC_EVAL_UNARY - evaluate a unary function,
- * if fltret is set return t_float
- * otherwise return value based on regular typechecking,
- */
-#define FUNC_EVAL_UNARY(left, func, leftcast, optr, fltret) \
-switch(left->ex_type) { \
-case ET_INT: \
- if (optr->ex_type == ET_VEC) { \
- ex_mkvector(optr->ex_vec, \
- (t_float)(func (leftcast left->ex_int)), e->exp_vsize);\
- break; \
- } \
- if (fltret) { \
- optr->ex_type = ET_FLT; \
- optr->ex_flt = (t_float) func(leftcast left->ex_int); \
- break; \
- } \
- optr->ex_type = ET_INT; \
- optr->ex_int = (int) func(leftcast left->ex_int); \
- break; \
-case ET_FLT: \
- if (optr->ex_type == ET_VEC) { \
- ex_mkvector(optr->ex_vec, \
- (t_float)(func (leftcast left->ex_flt)), e->exp_vsize);\
- break; \
- } \
- optr->ex_type = ET_FLT; \
- optr->ex_flt = (t_float) func(leftcast left->ex_flt); \
- break; \
-case ET_VI: \
-case ET_VEC: \
- if (optr->ex_type != ET_VEC) { \
- optr->ex_type = ET_VEC; \
- optr->ex_vec = (t_float *) \
- fts_malloc(sizeof (t_float)*e->exp_vsize); \
- } \
- op = optr->ex_vec; \
- lp = left->ex_vec; \
- j = e->exp_vsize; \
- while (j--) \
- *op++ = (t_float)(func (leftcast *lp++)); \
- break; \
-default: \
- post_error((fts_object_t *) e, \
- "expr: FUNV_EVAL_UNARY(%d): bad left type %ld\n",\
- __LINE__, left->ex_type); \
-}
-
-#undef min
-#undef max
-#define min(x,y) (x > y ? y : x)
-#define max(x,y) (x > y ? x : y)
-
-#define FUNC_DEF(ex_func, func, castleft, castright, fltret); \
-static void \
-ex_func(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)\
-{ \
- struct ex_ex *left, *right; \
- t_float *op; /* output pointer */ \
- t_float *lp, *rp; /* left and right vector pointers */ \
- t_float scalar; \
- int j; \
- \
- left = argv++; \
- right = argv; \
- FUNC_EVAL(left, right, func, castleft, castright, optr, fltret); \
-}
-
-
-#define FUNC_DEF_UNARY(ex_func, func, cast, fltret); \
-static void \
-ex_func(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)\
-{ \
- struct ex_ex *left; \
- t_float *op; /* output pointer */ \
- t_float *lp, *rp; /* left and right vector pointers */ \
- t_float scalar; \
- int j; \
- \
- left = argv++; \
- \
- FUNC_EVAL_UNARY(left, func, cast, optr, fltret); \
-}
-
-/*
- * ex_min -- if any of the arguments are or the output are vectors, a vector
- * of floats is generated otherwise the type of the result is the
- * type of the smaller value
- */
-static void
-ex_min(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left, *right;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
- right = argv;
-
- FUNC_EVAL(left, right, min, (double), (double), optr, 0);
-}
-
-/*
- * ex_max -- if any of the arguments are or the output are vectors, a vector
- * of floats is generated otherwise the type of the result is the
- * type of the larger value
- */
-static void
-ex_max(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left, *right;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
- right = argv;
-
- FUNC_EVAL(left, right, max, (double), (double), optr, 0);
-}
-
-/*
- * ex_toint -- convert to integer
- */
-static void
-ex_toint(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
-#define toint(x) ((int)(x))
- FUNC_EVAL_UNARY(left, toint, (int), optr, 0);
- }
-
-#ifdef _WIN32
-/* No rint in NT land ??? */
-double rint(double x);
-
-double
-rint(double x)
-{
- return (floor(x + 0.5));
-}
-#endif
-
-/*
- * ex_rint -- rint() round to the nearest int according to the common
- * rounding mechanism
- */
-static void
-ex_rint(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
-
- FUNC_EVAL_UNARY(left, rint, (double), optr, 1);
-}
-
-/*
- * ex_tofloat -- convert to t_float
- */
-static void
-ex_tofloat(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
-#define tofloat(x) ((t_float)(x))
- FUNC_EVAL_UNARY(left, tofloat, (int), optr, 1);
-}
-
-
-/*
- * ex_pow -- the power of
- */
-static void
-ex_pow(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left, *right;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
- right = argv;
- FUNC_EVAL(left, right, pow, (double), (double), optr, 1);
-}
-
-/*
- * ex_sqrt -- square root
- */
-static void
-ex_sqrt(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
- FUNC_EVAL_UNARY(left, sqrt, (double), optr, 1);
-}
-
-/*
- * ex_exp -- e to the power of
- */
-static void
-ex_exp(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
- FUNC_EVAL_UNARY(left, exp, (double), optr, 1);
-}
-
-/*
- * ex_log -- 10 based logarithm
- */
-static void
-ex_log(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
- FUNC_EVAL_UNARY(left, log10, (double), optr, 1);
-}
-
-/*
- * ex_ln -- natural log
- */
-static void
-ex_ln(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
- FUNC_EVAL_UNARY(left, log, (double), optr, 1);
-}
-
-static void
-ex_sin(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
- FUNC_EVAL_UNARY(left, sin, (double), optr, 1);
-}
-
-static void
-ex_cos(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
- FUNC_EVAL_UNARY(left, cos, (double), optr, 1);
-}
-
-
-static void
-ex_tan(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
- FUNC_EVAL_UNARY(left, tan, (double), optr, 1);
-}
-
-static void
-ex_asin(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
- FUNC_EVAL_UNARY(left, asin, (double), optr, 1);
-}
-
-static void
-ex_acos(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
- FUNC_EVAL_UNARY(left, acos, (double), optr, 1);
-}
-
-
-static void
-ex_atan(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
- FUNC_EVAL_UNARY(left, atan, (double), optr, 1);
-}
-
-/*
- *ex_atan2 --
- */
-static void
-ex_atan2(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left, *right;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
- right = argv;
- FUNC_EVAL(left, right, atan2, (double), (double), optr, 1);
-}
-
-/*
- * ex_fmod -- floating point modulo
- */
-static void
-ex_fmod(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left, *right;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
- right = argv;
- FUNC_EVAL(left, right, fmod, (double), (double), optr, 1);
-}
-
-
-/*
- * ex_floor -- floor
- */
-static void
-ex_floor(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
- FUNC_EVAL_UNARY(left, floor, (double), optr, 1);
-}
-
-
-/*
- * ex_ceil -- ceil
- */
-static void
-ex_ceil(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
- FUNC_EVAL_UNARY(left, ceil, (double), optr, 1);
-}
-
-static void
-ex_sinh(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
- FUNC_EVAL_UNARY(left, sinh, (double), optr, 1);
-}
-
-static void
-ex_cosh(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
- FUNC_EVAL_UNARY(left, cosh, (double), optr, 1);
-}
-
-
-static void
-ex_tanh(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
- FUNC_EVAL_UNARY(left, tanh, (double), optr, 1);
-}
-
-
-#ifndef _WIN32
-static void
-ex_asinh(t_expr *e, long argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
- FUNC_EVAL_UNARY(left, asinh, (double), optr, 1);
-}
-
-static void
-ex_acosh(t_expr *e, long argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
- FUNC_EVAL_UNARY(left, acosh, (double), optr, 1);
-}
-
-static void
-ex_atanh(t_expr *e, long argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
- FUNC_EVAL_UNARY(left, atanh, (double), optr, 1);
-}
-#endif
-
-static int
-ex_dofact(int i)
-{
- int ret = 0;
-
- if (i)
- ret = 1;
- else
- return (0);
-
- do {
- ret *= i;
- } while (--i);
-
- return(ret);
-}
-
-static void
-ex_fact(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
- FUNC_EVAL_UNARY(left, ex_dofact, (int), optr, 0);
-}
-
-static int
-ex_dorandom(int i1, int i2)
-{
- return(i1 + (((i2 - i1) * (rand() & 0x7fffL)) >> 15));
-}
-/*
- * ex_random -- return a random number
- */
-static void
-ex_random(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left, *right;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
- right = argv;
- FUNC_EVAL(left, right, ex_dorandom, (int), (int), optr, 0);
-}
-
-
-static void
-ex_abs(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float scalar;
- int j;
-
- left = argv++;
-
- FUNC_EVAL_UNARY(left, fabs, (double), optr, 0);
-}
-
-/*
- *ex_if -- floating point modulo
- */
-static void
-ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left, *right, *cond, *res;
- t_float *op; /* output pointer */
- t_float *lp, *rp; /* left and right vector pointers */
- t_float *cp; /* condition pointer */
- t_float leftvalue, rightvalue;
- int j;
-
- cond = argv++;
- left = argv++;
- right = argv;
-
- switch (cond->ex_type) {
- 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;
- }
- optr->ex_type = ET_VEC;
- optr->ex_vec = (t_float *)
- fts_malloc(sizeof (t_float) * e->exp_vsize);
- }
- op = optr->ex_vec;
- j = e->exp_vsize;
- cp = cond->ex_vec;
- switch (left->ex_type) {
- case ET_INT:
- leftvalue = left->ex_int;
- switch (right->ex_type) {
- case ET_INT:
- rightvalue = right->ex_int;
- while (j--) {
- if (*cp++)
- *op++ = leftvalue;
- else
- *op++ = rightvalue;
- }
- return;
- case ET_FLT:
- rightvalue = right->ex_flt;
- while (j--) {
- if (*cp++)
- *op++ = leftvalue;
- else
- *op++ = rightvalue;
- }
- return;
- case ET_VEC:
- case ET_VI:
- rp = right->ex_vec;
- while (j--) {
- if (*cp++)
- *op++ = leftvalue;
- else
- *op++ = *rp;
- rp++;
- }
- return;
- case ET_SYM:
- default:
- post_error((fts_object_t *) e,
- "expr: FUNC_EVAL(%d): bad right type %ld\n",
- __LINE__, right->ex_type);
- return;
- }
- case ET_FLT:
- leftvalue = left->ex_flt;
- switch (right->ex_type) {
- case ET_INT:
- rightvalue = right->ex_int;
- while (j--) {
- if (*cp++)
- *op++ = leftvalue;
- else
- *op++ = rightvalue;
- }
- return;
- case ET_FLT:
- rightvalue = right->ex_flt;
- while (j--) {
- if (*cp++)
- *op++ = leftvalue;
- else
- *op++ = rightvalue;
- }
- return;
- case ET_VEC:
- case ET_VI:
- rp = right->ex_vec;
- while (j--) {
- if (*cp++)
- *op++ = leftvalue;
- else
- *op++ = *rp;
- rp++;
- }
- return;
- case ET_SYM:
- default:
- post_error((fts_object_t *) e,
- "expr: FUNC_EVAL(%d): bad right type %ld\n",
- __LINE__, right->ex_type);
- return;
- }
- case ET_VEC:
- case ET_VI:
- lp = left->ex_vec;
- switch (right->ex_type) {
- case ET_INT:
- rightvalue = right->ex_int;
- while (j--) {
- if (*cp++)
- *op++ = *lp;
- else
- *op++ = rightvalue;
- lp++;
- }
- return;
- case ET_FLT:
- rightvalue = right->ex_flt;
- while (j--) {
- if (*cp++)
- *op++ = *lp;
- else
- *op++ = rightvalue;
- lp++;
- }
- return;
- case ET_VEC:
- case ET_VI:
- rp = right->ex_vec;
- while (j--) {
- if (*cp++)
- *op++ = *lp;
- else
- *op++ = *rp;
- lp++; rp++;
- }
- return;
- case ET_SYM:
- default:
- post_error((fts_object_t *) e,
- "expr: FUNC_EVAL(%d): bad right type %ld\n",
- __LINE__, right->ex_type);
- return;
- }
- case ET_SYM:
- default:
- post_error((fts_object_t *) e,
- "expr: FUNC_EVAL(%d): bad left type %ld\n",
- __LINE__, left->ex_type);
- return;
- }
- case ET_INT:
- if (cond->ex_int)
- res = left;
- else
- res = right;
- break;
- case ET_FLT:
- if (cond->ex_flt)
- res = left;
- else
- res = right;
- 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;
- }
- 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;
- }
- *optr = *res;
- return;
- case ET_FLT:
- if (optr->ex_type == ET_VEC) {
- ex_mkvector(optr->ex_vec, (t_float)res->ex_flt,
- e->exp_vsize);
- return;
- }
- *optr = *res;
- return;
- 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;
- }
- optr->ex_type = ET_VEC;
- optr->ex_vec = (t_float *)
- fts_malloc(sizeof (t_float) * e->exp_vsize);
- }
- memcpy(optr->ex_vec, res->ex_vec, e->exp_vsize*sizeof(t_float));
- return;
- case ET_SYM:
- default:
- post_error((fts_object_t *) e,
- "expr: FUNC_EVAL(%d): bad res type %ld\n",
- __LINE__, res->ex_type);
- return;
- }
-
-}
-
-/*
- * ex_imodf - extract signed integral value from floating-point number
- */
-static double
-imodf(double x)
-{
- double xx;
-
- modf(x, &xx);
- return (xx);
-}
-FUNC_DEF_UNARY(ex_imodf, imodf, (double), 1);
-
-/*
- * ex_modf - extract signed fractional value from floating-point number
- *
- * using fracmodf because fmodf() is alrady defined in a .h file
- */
-static double
-fracmodf(double x)
-{
- double xx;
-
- return(modf(x, &xx));
-}
-FUNC_DEF_UNARY(ex_modf, fracmodf, (double), 1);
-
-/*
- * ex_ldexp - multiply floating-point number by integral power of 2
- */
-FUNC_DEF(ex_ldexp, ldexp, (double), (int), 1);
-
-#ifndef _WIN32
-/*
- * ex_cbrt - cube root
- */
-FUNC_DEF_UNARY(ex_cbrt, cbrt, (double), 1);
-
-/*
- * ex_erf - error function
- */
-FUNC_DEF_UNARY(ex_erf, erf, (double), 1);
-
-/*
- * ex_erfc - complementary error function
- */
-FUNC_DEF_UNARY(ex_erfc, erfc, (double), 1);
-
-/*
- * ex_expm1 - exponential minus 1,
- */
-FUNC_DEF_UNARY(ex_expm1, expm1, (double), 1);
-
-/*
- * ex_log1p - logarithm of 1 plus
- */
-FUNC_DEF_UNARY(ex_log1p, log1p, (double), 1);
-
-/*
- * ex_isinf - is the value infinite,
- */
-FUNC_DEF_UNARY(ex_isinf, isinf, (double), 0);
-
-/*
- * ex_finite - is the value finite
- */
-FUNC_DEF_UNARY(ex_finite, finite, (double), 0);
-
-/*
- * ex_isnan -- is the resut a nan (Not a number)
- */
-FUNC_DEF_UNARY(ex_isnan, isnan, (double), 0);
-
-/*
- * ex_copysign - copy sign of a number
- */
-FUNC_DEF(ex_copysign, copysign, (double), (double), 1);
-
-/*
- * ex_drem - floating-point remainder function
- */
-FUNC_DEF(ex_drem, drem, (double), (double), 1);
-#endif
-
-#ifdef notdef
-/* the following will be added once they are more popular in math libraries */
-/*
- * ex_hypoth - Euclidean distance function
- */
-FUNC_DEF(ex_hypoth, hypoth, (double), (double), 1);
-
-/*
- * ex_round - round to nearest integer, away from zero
- */
-FUNC_DEF_UNARY(ex_round, round, (double), 1);
-
-/*
- * ex_trunc - round to interger, towards zero
- */
-FUNC_DEF_UNARY(ex_trunc, trunc, (double), 1);
-
-/*
- * ex_nearbyint - round to nearest integer
- */
-FUNC_DEF_UNARY(ex_nearbyint, nearbyint, (double), 1);
-#endif
diff --git a/externals/extra/0.43.2/expr~/vexp_if.c b/externals/extra/0.43.2/expr~/vexp_if.c
deleted file mode 100644
index 3028ff82..00000000
--- a/externals/extra/0.43.2/expr~/vexp_if.c
+++ /dev/null
@@ -1,1225 +0,0 @@
-/*
- * jMax
- * Copyright (C) 1994, 1995, 1998, 1999 by IRCAM-Centre Georges Pompidou, Paris, France.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * See file LICENSE for further informations on licensing terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Based on Max/ISPW by Miller Puckette.
- *
- * Authors: Maurizio De Cecco, Francois Dechelle, Enzo Maggi, Norbert Schnell.
- *
- */
-
-/* "expr" was written by Shahrokh Yadegari c. 1989. -msp */
-/* "expr~" and "fexpr~" conversion by Shahrokh Yadegari c. 1999,2000 */
-
-/*
- * Feb 2002 - added access to variables
- * multiple expression support
- * new short hand forms for fexpr~
- * now $y or $y1 = $y1[-1] and $y2 = $y2[-1]
- * --sdy
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "vexp.h"
-
-static char *exp_version = "0.4";
-
-extern struct ex_ex *ex_eval(struct expr *expr, struct ex_ex *eptr,
- struct ex_ex *optr, int n);
-
-#ifdef PD
-static t_class *expr_class;
-static t_class *expr_tilde_class;
-static t_class *fexpr_tilde_class;
-#else /* MSP */
-void *expr_tilde_class;
-#endif
-
-
-/*------------------------- expr class -------------------------------------*/
-
-extern int expr_donew(struct expr *expr, int ac, t_atom *av);
-
-/*#define EXPR_DEBUG*/
-
-static void expr_bang(t_expr *x);
-t_int *expr_perform(t_int *w);
-
-
-static void
-expr_list(t_expr *x, t_symbol *s, int argc, const fts_atom_t *argv)
-{
- int i;
-
- if (argc > MAX_VARS) argc = MAX_VARS;
-
- for (i = 0; i < argc; i++)
- {
- if (argv[i].a_type == A_FLOAT)
- {
- if (x->exp_var[i].ex_type == ET_FI)
- x->exp_var[i].ex_flt = argv[i].a_w.w_float;
- else if (x->exp_var[i].ex_type == ET_II)
- x->exp_var[i].ex_int = argv[i].a_w.w_float;
- else if (x->exp_var[i].ex_type)
- pd_error(x, "expr: type mismatch");
- }
- else if (argv[i].a_type == A_SYMBOL)
- {
- if (x->exp_var[i].ex_type == ET_SI)
- x->exp_var[i].ex_ptr = (char *)argv[i].a_w.w_symbol;
- else if (x->exp_var[i].ex_type)
- pd_error(x, "expr: type mismatch");
- }
- }
- expr_bang(x);
-}
-
-static void
-expr_flt(t_expr *x, t_float f, int in)
-{
- if (in > MAX_VARS)
- return;
-
- if (x->exp_var[in].ex_type == ET_FI)
- x->exp_var[in].ex_flt = f;
- else if (x->exp_var[in].ex_type == ET_II)
- x->exp_var[in].ex_int = f;
-}
-
-static t_class *exprproxy_class;
-
-typedef struct _exprproxy {
- t_pd p_pd;
- int p_index;
- t_expr *p_owner;
- struct _exprproxy *p_next;
-} t_exprproxy;
-
-t_exprproxy *exprproxy_new(t_expr *owner, int indx);
-void exprproxy_float(t_exprproxy *p, t_floatarg f);
-
-t_exprproxy *
-exprproxy_new(t_expr *owner, int indx)
-{
- t_exprproxy *x = (t_exprproxy *)pd_new(exprproxy_class);
- x->p_owner = owner;
- x->p_index = indx;
- x->p_next = owner->exp_proxy;
- owner->exp_proxy = x;
- return (x);
-}
-
-void
-exprproxy_float(t_exprproxy *p, t_floatarg f)
-{
- t_expr *x = p->p_owner;
- int in = p->p_index;
-
- if (in > MAX_VARS)
- return;
-
- if (x->exp_var[in].ex_type == ET_FI)
- x->exp_var[in].ex_flt = f;
- else if (x->exp_var[in].ex_type == ET_II)
- x->exp_var[in].ex_int = f;
-}
-
-/* method definitions */
-static void
-expr_ff(t_expr *x)
-{
- t_exprproxy *y;
- int i;
-
- y = x->exp_proxy;
- while (y)
- {
- x->exp_proxy = y->p_next;
-#ifdef PD
- pd_free(&y->p_pd);
-#else /*MSP */
- /* SDY find out what needs to be called for MSP */
-
-#endif
- y = x->exp_proxy;
- }
- for (i = 0 ; i < x->exp_nexpr; i++);
- if (x->exp_stack[i])
- fts_free(x->exp_stack[i]);
-/*
- * SDY free all the allocated buffers here for expr~ and fexpr~
- * check to see if there are others
- */
- for (i = 0; i < MAX_VARS; i++) {
- if (x->exp_p_var[i])
- fts_free(x->exp_p_var[i]);
- if (x->exp_p_res[i])
- fts_free(x->exp_p_res[i]);
- if (x->exp_tmpres[i])
- fts_free(x->exp_tmpres[i]);
- }
-
-
-}
-
-static void
-expr_bang(t_expr *x)
-{
- int i;
-
-#ifdef EXPR_DEBUG
- {
- struct ex_ex *eptr;
-
- for (i = 0, eptr = x->exp_var; ; eptr++, i++)
- {
- if (!eptr->ex_type)
- break;
- switch (eptr->ex_type)
- {
- case ET_II:
- fprintf(stderr,"ET_II: %d \n", eptr->ex_int);
- break;
-
- case ET_FI:
- fprintf(stderr,"ET_FT: %f \n", eptr->ex_flt);
- break;
-
- default:
- fprintf(stderr,"oups\n");
- }
- }
- }
-#endif
- /* banging a signal or filter object means nothing */
- if (!IS_EXPR(x))
- return;
-
- for (i = x->exp_nexpr - 1; i > -1 ; i--) {
- if (!ex_eval(x, x->exp_stack[i], &x->exp_res[i], 0)) {
- /*fprintf(stderr,"expr_bang(error evaluation)\n"); */
- /* SDY now that we have mutiple ones, on error we should
- * continue
- return;
- */
- }
- switch(x->exp_res[i].ex_type) {
- case ET_INT:
- outlet_float(x->exp_outlet[i],
- (t_float) x->exp_res[i].ex_int);
- break;
-
- case ET_FLT:
- outlet_float(x->exp_outlet[i], x->exp_res[i].ex_flt);
- break;
-
- case ET_SYM:
- /* CHANGE this will have to be taken care of */
-
- default:
- post("expr: bang: unrecognized result %ld\n", x->exp_res[i].ex_type);
- }
- }
-}
-
-static t_expr *
-#ifdef PD
-expr_new(t_symbol *s, int ac, t_atom *av)
-#else /* MSP */
-Nexpr_new(t_symbol *s, int ac, t_atom *av)
-#endif
-{
- struct expr *x;
- int i, ninlet;
- struct ex_ex *eptr;
- t_atom fakearg;
- int dsp_index; /* keeping track of the dsp inlets */
-
-
-/*
- * SDY - we may need to call dsp_setup() in this function
- */
-
- if (!ac)
- {
- ac = 1;
- av = &fakearg;
- SETFLOAT(&fakearg, 0);
- }
-
-#ifdef PD
- /*
- * figure out if we are expr, expr~, or fexpr~
- */
- if (!strcmp("expr", s->s_name)) {
- x = (t_expr *)pd_new(expr_class);
- SET_EXPR(x);
- } else if (!strcmp("expr~", s->s_name)) {
- x = (t_expr *)pd_new(expr_tilde_class);
- SET_EXPR_TILDE(x);
- } else if (!strcmp("fexpr~", s->s_name)) {
- x = (t_expr *)pd_new(fexpr_tilde_class);
- SET_FEXPR_TILDE(x);
- } else {
- post("expr_new: bad object name '%s'");
- /* assume expr */
- x = (t_expr *)pd_new(expr_class);
- SET_EXPR(x);
- }
-#else /* MSP */
- /* for now assume an expr~ */
- x = (t_expr *)pd_new(expr_tilde_class);
- SET_EXPR_TILDE(x);
-#endif
-
- /*
- * initialize the newly allocated object
- */
- x->exp_proxy = 0;
- x->exp_nivec = 0;
- x->exp_nexpr = 0;
- x->exp_error = 0;
- for (i = 0; i < MAX_VARS; i++) {
- x->exp_stack[i] = (struct ex_ex *)0;
- x->exp_outlet[i] = (t_outlet *)0;
- x->exp_res[i].ex_type = 0;
- x->exp_res[i].ex_int = 0;
- x->exp_p_res[i] = (t_float *)0;
- x->exp_var[i].ex_type = 0;
- x->exp_var[i].ex_int = 0;
- x->exp_p_var[i] = (t_float *)0;
- x->exp_tmpres[i] = (t_float *)0;
- x->exp_vsize = 0;
- }
- x->exp_f = 0; /* save the control value to be transformed to signal */
-
-
- if (expr_donew(x, ac, av))
- {
- pd_error(x, "expr: syntax error");
-/*
-SDY the following coredumps why?
- pd_free(&x->exp_ob.ob_pd);
-*/
- return (0);
- }
-
- ninlet = 1;
- for (i = 0, eptr = x->exp_var; i < MAX_VARS ; i++, eptr++)
- if (eptr->ex_type) {
- ninlet = i + 1;
- }
-
- /*
- * create the new inlets
- */
- for (i = 1, eptr = x->exp_var + 1, dsp_index=1; i<ninlet ; i++, eptr++)
- {
- t_exprproxy *p;
- switch (eptr->ex_type)
- {
- case 0:
- /* nothing is using this inlet */
- if (i < ninlet)
-#ifdef PD
- floatinlet_new(&x->exp_ob, &eptr->ex_flt);
-#else /* MSP */
- inlet_new(&x->exp_ob, "float");
-#endif
- break;
-
- case ET_II:
- case ET_FI:
- p = exprproxy_new(x, i);
-#ifdef PD
- inlet_new(&x->exp_ob, &p->p_pd, &s_float, &s_float);
-#else /* MSP */
- inlet_new(&x->exp_ob, "float");
-#endif
- break;
-
- case ET_SI:
-#ifdef PD
- symbolinlet_new(&x->exp_ob, (t_symbol **)&eptr->ex_ptr);
-#else /* MSP */
- inlet_new(&x->exp_ob, "symbol");
-#endif
- break;
-
- case ET_XI:
- case ET_VI:
- if (!IS_EXPR(x)) {
- dsp_index++;
-#ifdef PD
- inlet_new(&x->exp_ob, &x->exp_ob.ob_pd,
- &s_signal, &s_signal);
-#else /* MSP */
- inlet_new(&x->exp_ob, "signal");
-#endif
- break;
- } else
- post("expr: internal error expr_new");
- default:
- pd_error(x, "expr: bad type (%lx) inlet = %d\n",
- eptr->ex_type, i + 1);
- break;
- }
- }
- if (IS_EXPR(x)) {
- for (i = 0; i < x->exp_nexpr; i++)
- x->exp_outlet[i] = outlet_new(&x->exp_ob, 0);
- } else {
- for (i = 0; i < x->exp_nexpr; i++)
- x->exp_outlet[i] = outlet_new(&x->exp_ob,
- gensym("signal"));
- x->exp_nivec = dsp_index;
- }
- /*
- * for now assume a 64 sample size block but this may change once
- * expr_dsp is called
- */
- x->exp_vsize = 64;
- for (i = 0; i < x->exp_nexpr; i++) {
- x->exp_p_res[i] = fts_calloc(x->exp_vsize, sizeof (t_float));
- x->exp_tmpres[i] = fts_calloc(x->exp_vsize, sizeof (t_float));
- }
- for (i = 0; i < MAX_VARS; i++)
- x->exp_p_var[i] = fts_calloc(x->exp_vsize, sizeof (t_float));
-
- return (x);
-}
-
-t_int *
-expr_perform(t_int *w)
-{
- int i, j;
- t_expr *x = (t_expr *)w[1];
- struct ex_ex res;
- int n;
-
- /* sanity check */
- if (IS_EXPR(x)) {
- post("expr_perform: bad x->exp_flags = %d", x->exp_flags);
- abort();
- }
-
- if (x->exp_flags & EF_STOP) {
- for (i = 0; i < x->exp_nexpr; i++)
- memset(x->exp_res[i].ex_vec, 0,
- x->exp_vsize * sizeof (t_float));
- return (w + 2);
- }
-
- if (IS_EXPR_TILDE(x)) {
- /*
- * if we have only one expression, we can right on
- * on the output directly, otherwise we have to copy
- * the data because, outputs could be the same buffer as
- * inputs
- */
- if ( x->exp_nexpr == 1)
- ex_eval(x, x->exp_stack[0], &x->exp_res[0], 0);
- else {
- res.ex_type = ET_VEC;
- for (i = 0; i < x->exp_nexpr; i++) {
- res.ex_vec = x->exp_tmpres[i];
- ex_eval(x, x->exp_stack[i], &res, 0);
- }
- n = x->exp_vsize * sizeof(t_float);
- for (i = 0; i < x->exp_nexpr; i++)
- memcpy(x->exp_res[i].ex_vec, x->exp_tmpres[i],
- n);
- }
- return (w + 2);
- }
-
- if (!IS_FEXPR_TILDE(x)) {
- post("expr_perform: bad x->exp_flags = %d - expecting fexpr",
- x->exp_flags);
- return (w + 2);
- }
- /*
- * since the output buffer could be the same as one of the inputs
- * we need to keep the output in a different buffer
- */
- for (i = 0; i < x->exp_vsize; i++) for (j = 0; j < x->exp_nexpr; j++) {
- res.ex_type = 0;
- res.ex_int = 0;
- ex_eval(x, x->exp_stack[j], &res, i);
- switch (res.ex_type) {
- case ET_INT:
- x->exp_tmpres[j][i] = (t_float) res.ex_int;
- break;
- case ET_FLT:
- x->exp_tmpres[j][i] = res.ex_flt;
- break;
- default:
- post("expr_perform: bad result type %d", res.ex_type);
- }
- }
- /*
- * copy inputs and results to the save buffers
- * inputs need to be copied first as the output buffer can be
- * same as an input buffer
- */
- n = x->exp_vsize * sizeof(t_float);
- for (i = 0; i < MAX_VARS; i++)
- if (x->exp_var[i].ex_type == ET_XI)
- memcpy(x->exp_p_var[i], x->exp_var[i].ex_vec, n);
- for (i = 0; i < x->exp_nexpr; i++) {
- memcpy(x->exp_p_res[i], x->exp_tmpres[i], n);
- memcpy(x->exp_res[i].ex_vec, x->exp_tmpres[i], n);
- }
- return (w + 2);
-}
-
-static void
-expr_dsp(t_expr *x, t_signal **sp)
-{
- int i, nv;
- int newsize;
-
- x->exp_error = 0; /* reset all errors */
- newsize = (x->exp_vsize != sp[0]->s_n);
- x->exp_vsize = sp[0]->s_n; /* record the vector size */
- for (i = 0; i < x->exp_nexpr; i++) {
- x->exp_res[i].ex_type = ET_VEC;
- x->exp_res[i].ex_vec = sp[x->exp_nivec + i]->s_vec;
- }
- for (i = 0, nv = 0; i < MAX_VARS; i++)
- /*
- * the first inlet is always a signal
- *
- * SDY We are warning the user till this limitation
- * is taken away from pd
- */
- if (!i || x->exp_var[i].ex_type == ET_VI ||
- x->exp_var[i].ex_type == ET_XI) {
- if (nv >= x->exp_nivec) {
- post("expr_dsp int. err nv = %d, x->exp_nive = %d",
- nv, x->exp_nivec);
- abort();
- }
- x->exp_var[i].ex_vec = sp[nv]->s_vec;
- nv++;
- }
- /* we always have one inlet but we may not use it */
- if (nv != x->exp_nivec && (nv != 0 || x->exp_nivec != 1)) {
- post("expr_dsp internal error 2 nv = %d, x->exp_nive = %d",
- nv, x->exp_nivec);
- abort();
- }
-
- dsp_add(expr_perform, 1, (t_int *) x);
-
- /*
- * The buffer are now being allocated for expr~ and fexpr~
- * because if we have more than one expression we need the
- * temporary buffers, The save buffers are not really needed
- if (!IS_FEXPR_TILDE(x))
- return;
- */
- /*
- * if we have already allocated the buffers and we have a
- * new size free all the buffers
- */
- if (x->exp_p_res[0]) {
- if (!newsize)
- return;
- /*
- * if new size, reallocate all the previous buffers for fexpr~
- */
- for (i = 0; i < x->exp_nexpr; i++) {
- fts_free(x->exp_p_res[i]);
- fts_free(x->exp_tmpres[i]);
- }
- for (i = 0; i < MAX_VARS; i++)
- fts_free(x->exp_p_var[i]);
-
- }
- for (i = 0; i < x->exp_nexpr; i++) {
- x->exp_p_res[i] = fts_calloc(x->exp_vsize, sizeof (t_float));
- x->exp_tmpres[i] = fts_calloc(x->exp_vsize, sizeof (t_float));
- }
- for (i = 0; i < MAX_VARS; i++)
- x->exp_p_var[i] = fts_calloc(x->exp_vsize, sizeof (t_float));
-}
-
-/*
- * expr_verbose -- toggle the verbose switch
- */
-static void
-expr_verbose(t_expr *x)
-{
- if (x->exp_flags & EF_VERBOSE) {
- x->exp_flags &= ~EF_VERBOSE;
- post ("verbose off");
- } else {
- x->exp_flags |= EF_VERBOSE;
- post ("verbose on");
- }
-}
-
-/*
- * expr_start -- turn on expr processing for now only used for fexpr~
- */
-static void
-expr_start(t_expr *x)
-{
- x->exp_flags &= ~EF_STOP;
-}
-
-/*
- * expr_stop -- turn on expr processing for now only used for fexpr~
- */
-static void
-expr_stop(t_expr *x)
-{
- x->exp_flags |= EF_STOP;
-}
-static void
-fexpr_set_usage(void)
-{
- post("fexpr~: set val ...");
- post("fexpr~: set {xy}[#] val ...");
-}
-
-/*
- * fexpr_tilde_set -- set previous values of the buffers
- * set val val ... - sets the first elements of output buffers
- * set x val ... - sets the elements of the first input buffer
- * set x# val ... - sets the elements of the #th input buffers
- * set y val ... - sets the elements of the first output buffer
- * set y# val ... - sets the elements of the #th output buffers
- */
-static void
-fexpr_tilde_set(t_expr *x, t_symbol *s, int argc, t_atom *argv)
-{
- t_symbol *sx;
- int vecno;
- int i, nargs;
-
- if (!argc)
- return;
- sx = atom_getsymbolarg(0, argc, argv);
- switch(sx->s_name[0]) {
- case 'x':
- if (!sx->s_name[1])
- vecno = 0;
- else {
- vecno = atoi(sx->s_name + 1);
- if (!vecno) {
- post("fexpr~.set: bad set x vector number");
- fexpr_set_usage();
- return;
- }
- if (vecno >= MAX_VARS) {
- post("fexpr~.set: no more than %d inlets",
- MAX_VARS);
- return;
- }
- vecno--;
- }
- if (x->exp_var[vecno].ex_type != ET_XI) {
- post("fexpr~-set: no signal at inlet %d", vecno + 1);
- return;
- }
- nargs = argc - 1;
- if (!nargs) {
- post("fexpr~-set: no argument to set");
- return;
- }
- if (nargs > x->exp_vsize) {
- post("fexpr~.set: %d set values larger than vector size(%d)",
- nargs, x->exp_vsize);
- post("fexpr~.set: only the first %d values will be set",
- x->exp_vsize);
- nargs = x->exp_vsize;
- }
- for (i = 0; i < nargs; i++) {
- x->exp_p_var[vecno][x->exp_vsize - i - 1] =
- atom_getfloatarg(i + 1, argc, argv);
- }
- return;
- case 'y':
- if (!sx->s_name[1])
- vecno = 0;
- else {
- vecno = atoi(sx->s_name + 1);
- if (!vecno) {
- post("fexpr~.set: bad set y vector number");
- fexpr_set_usage();
- return;
- }
- vecno--;
- }
- if (vecno >= x->exp_nexpr) {
- post("fexpr~.set: only %d outlets", x->exp_nexpr);
- return;
- }
- nargs = argc - 1;
- if (!nargs) {
- post("fexpr~-set: no argument to set");
- return;
- }
- if (nargs > x->exp_vsize) {
- post("fexpr~-set: %d set values larger than vector size(%d)",
- nargs, x->exp_vsize);
- post("fexpr~.set: only the first %d values will be set",
- x->exp_vsize);
- nargs = x->exp_vsize;
- }
- for (i = 0; i < nargs; i++) {
- x->exp_p_res[vecno][x->exp_vsize - i - 1] =
- atom_getfloatarg(i + 1, argc, argv);
- }
- return;
- case 0:
- if (argc > x->exp_nexpr) {
- post("fexpr~.set: only %d outlets available",
- x->exp_nexpr);
- post("fexpr~.set: the extra set values are ignored");
- }
- for (i = 0; i < x->exp_nexpr && i < argc; i++)
- x->exp_p_res[i][x->exp_vsize - 1] =
- atom_getfloatarg(i, argc, argv);
- return;
- default:
- fexpr_set_usage();
- return;
- }
- return;
-}
-
-/*
- * fexpr_tilde_clear - clear the past buffers
- */
-static void
-fexpr_tilde_clear(t_expr *x, t_symbol *s, int argc, t_atom *argv)
-{
- t_symbol *sx;
- int vecno;
- int i, nargs;
-
- /*
- * if no arguement clear all input and output buffers
- */
- if (!argc) {
- for (i = 0; i < x->exp_nexpr; i++)
- memset(x->exp_p_res[i], 0, x->exp_vsize*sizeof(t_float));
- for (i = 0; i < MAX_VARS; i++)
- if (x->exp_var[i].ex_type == ET_XI)
- memset(x->exp_p_var[i], 0,
- x->exp_vsize*sizeof(t_float));
- return;
- }
- if (argc > 1) {
- post("fexpr~ usage: 'clear' or 'clear {xy}[#]'");
- return;
- }
-
- sx = atom_getsymbolarg(0, argc, argv);
- switch(sx->s_name[0]) {
- case 'x':
- if (!sx->s_name[1])
- vecno = 0;
- else {
- vecno = atoi(sx->s_name + 1);
- if (!vecno) {
- post("fexpr~.clear: bad clear x vector number");
- return;
- }
- if (vecno >= MAX_VARS) {
- post("fexpr~.clear: no more than %d inlets",
- MAX_VARS);
- return;
- }
- vecno--;
- }
- if (x->exp_var[vecno].ex_type != ET_XI) {
- post("fexpr~-clear: no signal at inlet %d", vecno + 1);
- return;
- }
- memset(x->exp_p_var[vecno], 0, x->exp_vsize*sizeof(t_float));
- return;
- case 'y':
- if (!sx->s_name[1])
- vecno = 0;
- else {
- vecno = atoi(sx->s_name + 1);
- if (!vecno) {
- post("fexpr~.clear: bad clear y vector number");
- return;
- }
- vecno--;
- }
- if (vecno >= x->exp_nexpr) {
- post("fexpr~.clear: only %d outlets", x->exp_nexpr);
- return;
- }
- memset(x->exp_p_res[vecno], 0, x->exp_vsize*sizeof(t_float));
- return;
- return;
- default:
- post("fexpr~ usage: 'clear' or 'clear {xy}[#]'");
- return;
- }
- return;
-}
-
-#ifdef PD
-
-void
-expr_setup(void)
-{
- /*
- * expr initialization
- */
- expr_class = class_new(gensym("expr"), (t_newmethod)expr_new,
- (t_method)expr_ff, sizeof(t_expr), 0, A_GIMME, 0);
- class_addlist(expr_class, expr_list);
- exprproxy_class = class_new(gensym("exprproxy"), 0,
- 0, sizeof(t_exprproxy), CLASS_PD, 0);
- class_addfloat(exprproxy_class, exprproxy_float);
-
- /*
- * expr~ initialization
- */
- expr_tilde_class = class_new(gensym("expr~"), (t_newmethod)expr_new,
- (t_method)expr_ff, sizeof(t_expr), 0, A_GIMME, 0);
- class_addmethod(expr_tilde_class, nullfn, gensym("signal"), 0);
- CLASS_MAINSIGNALIN(expr_tilde_class, t_expr, exp_f);
- class_addmethod(expr_tilde_class,(t_method)expr_dsp, gensym("dsp"), 0);
- class_sethelpsymbol(expr_tilde_class, gensym("expr"));
- /*
- * fexpr~ initialization
- */
- fexpr_tilde_class = class_new(gensym("fexpr~"), (t_newmethod)expr_new,
- (t_method)expr_ff, sizeof(t_expr), 0, A_GIMME, 0);
- class_addmethod(fexpr_tilde_class, nullfn, gensym("signal"), 0);
- class_addmethod(fexpr_tilde_class,(t_method)expr_start,
- gensym("start"), 0);
- class_addmethod(fexpr_tilde_class,(t_method)expr_stop,
- gensym("stop"), 0);
-
- class_addmethod(fexpr_tilde_class,(t_method)expr_dsp,gensym("dsp"), 0);
- class_addmethod(fexpr_tilde_class, (t_method)fexpr_tilde_set,
- gensym("set"), A_GIMME, 0);
- class_addmethod(fexpr_tilde_class, (t_method)fexpr_tilde_clear,
- gensym("clear"), A_GIMME, 0);
- class_addmethod(fexpr_tilde_class,(t_method)expr_verbose,
- gensym("verbose"), 0);
- class_sethelpsymbol(fexpr_tilde_class, gensym("expr"));
-
-
-
- post("expr, expr~, fexpr~ version %s under GNU General Public License ", exp_version);
-
-}
-
-void
-expr_tilde_setup(void)
-{
- expr_setup();
-}
-
-void
-fexpr_tilde_setup(void)
-{
- expr_setup();
-}
-#else /* MSP */
-void
-main(void)
-{
- setup((t_messlist **)&expr_tilde_class, (method)Nexpr_new,
- (method)expr_ff, (short)sizeof(t_expr), 0L, A_GIMME, 0);
- addmess((method)expr_dsp, "dsp", A_CANT, 0); // dsp method
- dsp_initclass();
-}
-#endif
-
-
-/* -- the following functions use Pd internals and so are in the "if" file. */
-
-
-int
-ex_getsym(char *p, fts_symbol_t *s)
-{
- *s = gensym(p);
- return (0);
-}
-
-const char *
-ex_symname(fts_symbol_t s)
-{
- return (fts_symbol_name(s));
-}
-
-/*
- * max_ex_tab -- evaluate this table access
- * eptr is the name of the table and arg is the index we
- * have to put the result in optr
- * return 1 on error and 0 otherwise
- *
- * Arguments:
- * the expr object
- * table
- * the argument
- * the result pointer
- */
-int
-max_ex_tab(struct expr *expr, fts_symbol_t s, struct ex_ex *arg,
- struct ex_ex *optr)
-{
-#ifdef PD
- t_garray *garray;
- int size, indx;
- t_word *wvec;
-
- if (!s || !(garray = (t_garray *)pd_findbyclass(s, garray_class)) ||
- !garray_getfloatwords(garray, &size, &wvec))
- {
- optr->ex_type = ET_FLT;
- optr->ex_flt = 0;
- pd_error(expr, "no such table '%s'", s->s_name);
- return (1);
- }
- optr->ex_type = ET_FLT;
-
- switch (arg->ex_type) {
- case ET_INT:
- indx = arg->ex_int;
- break;
- case ET_FLT:
- /* strange interpolation code deleted here -msp */
- indx = arg->ex_flt;
- break;
-
- default: /* do something with strings */
- pd_error(expr, "expr: bad argument for table '%s'\n", fts_symbol_name(s));
- indx = 0;
- }
- if (indx < 0) indx = 0;
- else if (indx >= size) indx = size - 1;
- optr->ex_flt = wvec[indx].w_float;
-#else /* MSP */
- /*
- * table lookup not done for MSP yet
- */
- post("max_ex_tab: not complete for MSP yet!");
- optr->ex_type = ET_FLT;
- optr->ex_flt = 0;
-#endif
- return (0);
-}
-
-int
-max_ex_var(struct expr *expr, fts_symbol_t var, struct ex_ex *optr)
-{
- optr->ex_type = ET_FLT;
- if (value_getfloat(var, &(optr->ex_flt))) {
- optr->ex_type = ET_FLT;
- optr->ex_flt = 0;
- pd_error(expr, "no such var '%s'", var->s_name);
- return (1);
- }
- return (0);
-}
-
-#ifdef PD /* this goes to the end of this file as the following functions
- * should be defined in the expr object in MSP
- */
-#define ISTABLE(sym, garray, size, vec) \
-if (!sym || !(garray = (t_garray *)pd_findbyclass(sym, garray_class)) || \
- !garray_getfloatwords(garray, &size, &vec)) { \
- optr->ex_type = ET_FLT; \
- optr->ex_int = 0; \
- error("no such table '%s'", sym?(sym->s_name):"(null)"); \
- return; \
-}
-
-/*
- * ex_size -- find the size of a table
- */
-void
-ex_size(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- t_symbol *s;
- t_garray *garray;
- int size;
- t_word *wvec;
-
- if (argv->ex_type != ET_SYM)
- {
- post("expr: size: need a table name\n");
- optr->ex_type = ET_INT;
- optr->ex_int = 0;
- return;
- }
-
- s = (fts_symbol_t ) argv->ex_ptr;
-
- ISTABLE(s, garray, size, wvec);
-
- optr->ex_type = ET_INT;
- optr->ex_int = size;
-}
-
-/*
- * ex_sum -- calculate the sum of all elements of a table
- */
-
-void
-ex_sum(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- t_symbol *s;
- t_garray *garray;
- int size;
- t_word *wvec;
- t_float sum;
- int indx;
-
- if (argv->ex_type != ET_SYM)
- {
- post("expr: sum: need a table name\n");
- optr->ex_type = ET_INT;
- optr->ex_int = 0;
- return;
- }
-
- s = (fts_symbol_t ) argv->ex_ptr;
-
- ISTABLE(s, garray, size, wvec);
-
- for (indx = 0, sum = 0; indx < size; indx++)
- sum += wvec[indx].w_float;
-
- optr->ex_type = ET_FLT;
- optr->ex_flt = sum;
-}
-
-
-/*
- * ex_Sum -- calculate the sum of table with the given boundries
- */
-
-void
-ex_Sum(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- t_symbol *s;
- t_garray *garray;
- int size;
- t_word *wvec;
- t_float sum;
- int indx, n1, n2;
-
- if (argv->ex_type != ET_SYM)
- {
- post("expr: sum: need a table name\n");
- optr->ex_type = ET_INT;
- optr->ex_int = 0;
- return;
- }
-
- s = (fts_symbol_t ) argv->ex_ptr;
-
- ISTABLE(s, garray, size, wvec);
-
- if (argv->ex_type != ET_INT || argv[1].ex_type != ET_INT)
- {
- post("expr: Sum: boundries have to be fix values\n");
- optr->ex_type = ET_INT;
- optr->ex_int = 0;
- return;
- }
- n1 = argv->ex_int;
- n2 = argv[1].ex_int;
-
- for (indx = n1, sum = 0; indx < n2; indx++)
- if (indx >= 0 && indx < size)
- sum += wvec[indx].w_float;
-
- optr->ex_type = ET_FLT;
- optr->ex_flt = sum;
-}
-
-/*
- * ex_avg -- calculate the avarage of a table
- */
-
-void
-ex_avg(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
-/* SDY - look into this function */
-#if 0
- fts_symbol_t s;
- fts_integer_vector_t *tw = 0;
-
- if (argv->ex_type != ET_SYM)
- {
- post("expr: avg: need a table name\n");
- optr->ex_type = ET_INT;
- optr->ex_int = 0;
- }
-
- s = (fts_symbol_t ) argv->ex_ptr;
-
- tw = table_integer_vector_get_by_name(s);
-
- if (tw)
- {
- optr->ex_type = ET_INT;
-
- if (! fts_integer_vector_get_size(tw))
- optr->ex_int = 0;
- else
- optr->ex_int = fts_integer_vector_get_sum(tw) / fts_integer_vector_get_size(tw);
- }
- else
- {
- optr->ex_type = ET_INT;
- optr->ex_int = 0;
- post("expr: avg: no such table %s\n", fts_symbol_name(s));
- }
-#endif
-}
-
-
-/*
- * ex_Avg -- calculate the avarage of table with the given boundries
- */
-
-void
-ex_Avg(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
-/* SDY - look into this function */
-#if 0
- fts_symbol_t s;
- fts_integer_vector_t *tw = 0;
-
- if (argv->ex_type != ET_SYM)
- {
- post("expr: Avg: need a table name\n");
- optr->ex_type = ET_INT;
- optr->ex_int = 0;
- }
-
- s = (fts_symbol_t ) (argv++)->ex_ptr;
-
- tw = table_integer_vector_get_by_name(s);
-
- if (! tw)
- {
- optr->ex_type = ET_INT;
- optr->ex_int = 0;
- post("expr: Avg: no such table %s\n", fts_symbol_name(s));
- return;
- }
-
- if (argv->ex_type != ET_INT || argv[1].ex_type != ET_INT)
- {
- post("expr: Avg: boundries have to be fix values\n");
- optr->ex_type = ET_INT;
- optr->ex_int = 0;
- return;
- }
-
- optr->ex_type = ET_INT;
-
- if (argv[1].ex_int - argv->ex_int <= 0)
- optr->ex_int = 0;
- else
- optr->ex_int = (fts_integer_vector_get_sub_sum(tw, argv->ex_int, argv[1].ex_int) /
- (argv[1].ex_int - argv->ex_int));
-#endif
-}
-
-/*
- * ex_store -- store a value in a table
- * if the index is greater the size of the table,
- * we will make a modulo the size of the table
- */
-
-void
-ex_store(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
-/* SDY - look into this function */
-#if 0
- fts_symbol_t s;
- fts_integer_vector_t *tw = 0;
-
- if (argv->ex_type != ET_SYM)
- {
- post("expr: store: need a table name\n");
- }
-
- s = (fts_symbol_t ) (argv++)->ex_ptr;
-
- tw = table_integer_vector_get_by_name(s);
-
- if (! tw)
- {
- optr->ex_type = ET_INT;
- optr->ex_int = 0;
- post("expr: store: no such table %s\n", fts_symbol_name(s));
- return;
- }
-
- if (argv->ex_type != ET_INT || argv[1].ex_type != ET_INT)
- {
- post("expr: store: arguments have to be integer\n");
- optr->ex_type = ET_INT;
- optr->ex_int = 0;
- }
-
- fts_integer_vector_set_element(tw, argv->ex_int < 0 ? 0 : argv->ex_int % fts_integer_vector_get_size(tw), argv[1].ex_int);
- *optr = argv[1];
-#endif
-}
-
-#else /* MSP */
-
-void
-pd_error(void *object, char *fmt, ...)
-{
- va_list ap;
- t_int arg[8];
- int i;
- static int saidit = 0;
- va_start(ap, fmt);
-/* SDY
- vsprintf(error_string, fmt, ap);
- */ post(fmt, ap);
- va_end(ap);
-/* SDY
- fprintf(stderr, "error: %s\n", error_string);
- error_object = object;
-*/
- if (!saidit)
- {
- post("... you might be able to track this down from the Find menu.");
- saidit = 1;
- }
-}
-#endif