aboutsummaryrefslogtreecommitdiff
path: root/desiredata/extra/expr~
diff options
context:
space:
mode:
Diffstat (limited to 'desiredata/extra/expr~')
-rw-r--r--desiredata/extra/expr~/LICENSE.txt341
-rw-r--r--desiredata/extra/expr~/README.txt97
-rw-r--r--desiredata/extra/expr~/fts_to_pd.h41
-rw-r--r--desiredata/extra/expr~/makefile168
-rw-r--r--desiredata/extra/expr~/vexp.c1175
-rw-r--r--desiredata/extra/expr~/vexp.h243
-rw-r--r--desiredata/extra/expr~/vexp_fun.c1315
-rw-r--r--desiredata/extra/expr~/vexp_if.c1223
8 files changed, 0 insertions, 4603 deletions
diff --git a/desiredata/extra/expr~/LICENSE.txt b/desiredata/extra/expr~/LICENSE.txt
deleted file mode 100644
index a52b16e4..00000000
--- a/desiredata/extra/expr~/LICENSE.txt
+++ /dev/null
@@ -1,341 +0,0 @@
-
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the 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 Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
-
- 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.
-
- 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
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/desiredata/extra/expr~/README.txt b/desiredata/extra/expr~/README.txt
deleted file mode 100644
index bf84f2ae..00000000
--- a/desiredata/extra/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/desiredata/extra/expr~/fts_to_pd.h b/desiredata/extra/expr~/fts_to_pd.h
deleted file mode 100644
index 9ca2fc42..00000000
--- a/desiredata/extra/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/desiredata/extra/expr~/makefile b/desiredata/extra/expr~/makefile
deleted file mode 100644
index ff1dae4b..00000000
--- a/desiredata/extra/expr~/makefile
+++ /dev/null
@@ -1,168 +0,0 @@
-
-current: expr.pd_linux expr~.pd_linux fexpr~.pd_linux \
- ../expr.pd_linux ../expr~.pd_linux ../fexpr~.pd_linux
-
-install: install_linux
-
-clean: clean_linux
-
-clobber: clobber_linux
-
-PDEXTERN=/usr/local/lib/pd/externs
-
-# ----------------------- NT -----------------------
-
-pd_nt: expr.dll
-
-NTOBJ = vexp.obj vexp_fun.obj vexp_if.obj
-
-PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo
-VC="C:\Program Files\Microsoft Visual Studio\Vc98"
-
-PDNTINCLUDE = /I. /I..\..\src /I$(VC)\include
-
-PDNTLDIR = $(VC)\lib
-PDNTLIB = $(PDNTLDIR)\libc.lib \
- $(PDNTLDIR)\oldnames.lib \
- $(PDNTLDIR)\kernel32.lib \
- ..\..\bin\pd.lib
-
-.c.obj:
- cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c
-
-expr.dll: $(NTOBJ)
- link /dll /export:expr_setup /export:expr_tilde_setup \
- /export:fexpr_tilde_setup $(NTOBJ) $(PDNTLIB)
- ren vexp.dll expr.dll
- copy expr.dll ..\expr.dll
- copy expr.dll ..\expr~.dll
- copy expr.dll ..\fexpr~.dll
- copy help-expr.pd ..\help-expr.pd
-
-# ----------------------- IRIX 5.x -----------------------
-
-pd_irix5:
-
-.SUFFIXES: .pd_irix5
-
-SGICFLAGS5 = -o32 -DPD -DSGI -O2
-
-
-SGIINCLUDE = -I/usr/people/msp/pd/pd/src
-
-.c.pd_irix5:
- $(CC) $(SGICFLAGS5) $(SGIINCLUDE) -o $*.o -c $*.c
- ld -elf -shared -rdata_shared -o $*.pd_irix5 $*.o
- rm $*.o
-
-# ----------------------- IRIX 6.x -----------------------
-
-pd_irix6:
-
-.SUFFIXES: .pd_irix6
-
-SGICFLAGS6 = -DPD -DSGI -n32 \
- -OPT:roundoff=3 -OPT:IEEE_arithmetic=3 -OPT:cray_ivdep=true \
- -Ofast=ip32
-
-SGICFLAGS5 = -DPD -O2 -DSGI
-
-SGIINCLUDE = -I/usr/people/msp/pd/pd/src
-
-.c.pd_irix6:
- $(CC) $(SGICFLAGS6) $(SGIINCLUDE) -o $*.o -c $*.c
- ld -elf -shared -rdata_shared -o $*.pd_irix6 $*.o
- rm $*.o
-
-# ----------------------- LINUX i386 -----------------------
-
-LINUXOBJ = vexp.pd_linux_o vexp_fun.pd_linux_o vexp_if.pd_linux_o
-.SUFFIXES: .pd_linux_o
-
-LINUXCFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer -fPIC \
- -Wall -W -Wshadow -Wstrict-prototypes \
- -Wno-unused -Wno-parentheses -Wno-switch
-
-LINUXINCLUDE = -I../../src
-
-.c.pd_linux_o:
- $(CC) -g $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.pd_linux_o -c $*.c
-
-expr.pd_linux: $(LINUXOBJ)
- ld -export_dynamic -shared -o expr.pd_linux $(LINUXOBJ) -lc -lm
- strip --strip-unneeded expr.pd_linux
-
-expr~.pd_linux: expr.pd_linux
- -ln -s expr.pd_linux expr~.pd_linux
-
-fexpr~.pd_linux: expr.pd_linux
- -ln -s expr.pd_linux fexpr~.pd_linux
-
-../expr.pd_linux: expr.pd_linux
- -ln -s expr~/expr.pd_linux ../expr.pd_linux
-
-../expr~.pd_linux: expr.pd_linux
- -ln -s expr~/expr.pd_linux ../expr~.pd_linux
-
-../fexpr~.pd_linux: expr.pd_linux
- -ln -s expr~/expr.pd_linux ../fexpr~.pd_linux
-
-install_linux:
- install expr.pd_linux $(PDEXTERN)
- rm -f $(PDEXTERN)/expr~.pd_linux
- rm -f $(PDEXTERN)/fexpr~.pd_linux
- cd $(PDEXTERN); \
- -ln -s expr.pd_linux expr~.pd_linux
- -ln -s expr.pd_linux fexpr~.pd_linux
-
-
-linux_clean:
- rm -f *.pd_linux_o *.o
-
-linux_clobber: clean
- rm -f expr.pd_linux
-
-# ----------------------- MAC OSX -----------------------
-
-pd_darwin: expr.pd_darwin expr~.pd_darwin fexpr~.pd_darwin
-MACOSXOBJ = vexp.pd_darwin_o vexp_fun.pd_darwin_o vexp_if.pd_darwin_o
-.SUFFIXES: .pd_darwin_o
-
-MACOSXCFLAGS = -DMACOSX -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \
- -Wno-unused -Wno-parentheses -Wno-switch
-
-MACOSXINCLUDE = -I../../src
-
-.c.pd_darwin_o:
- $(CC) -g $(MACOSXCFLAGS) $(MACOSXINCLUDE) -o $*.pd_darwin_o -c $*.c
-
-expr.pd_darwin: $(MACOSXOBJ)
- $(CC) -bundle -undefined suppress -flat_namespace \
- -o expr.pd_darwin $(MACOSXOBJ) -lm
- rm -f ../expr.pd_darwin
- -ln -s expr~/expr.pd_darwin ..
-
-expr~.pd_darwin: expr.pd_darwin
- -ln -s expr.pd_darwin expr~.pd_darwin
- rm -f ../expr~.pd_darwin
- -ln -s expr~/expr~.pd_darwin ..
-
-fexpr~.pd_darwin: expr.pd_darwin
- -ln -s expr.pd_darwin fexpr~.pd_darwin
- rm -f ../fexpr~.pd_darwin
- -ln -s expr~/fexpr~.pd_darwin ..
-
-install_darwin:
- install expr.pd_darwin $(PDEXTERN)
- rm -f $(PDEXTERN)/expr~.pd_darwin
- rm -f $(PDEXTERN)/fexpr~.pd_darwin
- cd $(PDEXTERN); \
- -ln -s expr.pd_darwin expr~.pd_darwin; \
- -ln -s expr.pd_darwin fexpr~.pd_darwin
-
-darwin_clean:
- rm -f *.pd_darwin_o *.o
-
-darwin_clobber: clean
- rm -f expr.pd_darwin
-
diff --git a/desiredata/extra/expr~/vexp.c b/desiredata/extra/expr~/vexp.c
deleted file mode 100644
index d13682a0..00000000
--- a/desiredata/extra/expr~/vexp.c
+++ /dev/null
@@ -1,1175 +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);
-
-typedef struct ex_ex ex_ex;
-
-static ex_ex *ex_lex(struct expr *expr, long int *n);
-ex_ex *ex_match(ex_ex *eptr, long int op);
-ex_ex *ex_parse(struct expr *expr, ex_ex *iptr, ex_ex *optr, long int *argc);
-ex_ex *ex_eval(struct expr *expr, ex_ex *eptr, ex_ex *optr, int i);
-
-int expr_donew(struct expr *exprr, int ac, t_atom *av);
-ex_ex *eval_func(struct expr *expr,ex_ex *eptr, ex_ex *optr, int i);
-ex_ex *eval_tab(struct expr *expr, ex_ex *eptr, ex_ex *optr, int i);
-ex_ex *eval_var(struct expr *expr, ex_ex *eptr, ex_ex *optr, int i);
-ex_ex *eval_store(struct expr *expr, ex_ex *eptr, ex_ex *optr, int i);
-ex_ex *eval_sigidx(struct expr *expr, ex_ex *eptr, ex_ex *optr, int i);
-static int cal_sigidx(ex_ex *optr, /* The output value */
- int i, float rem_i, /* integer and fractinal part of index */
- int idx, /* index of current fexpr~ processing */
- int vsize, /* vector size */
- float *curvec, 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[];
-
-ex_ex nullex;
-
-void set_tokens (char *s);
-int getoken (struct expr *expr, ex_ex *eptr);
-void ex_print (ex_ex *eptr);
-
-/* create a new "expr" object. returns 1 on failure, 0 on success. */
-int expr_donew(struct expr *expr, int ac, t_atom *av) {
- ex_ex *list;
- 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));
- b = binbuf_new();
- binbuf_add(b, ac, av);
- binbuf_gettext(b, &exp_string, &exp_strlen);
- 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 = (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) goto error;
- expr->exp_stack[expr->exp_nexpr] = (ex_ex *)fts_malloc(max_node * sizeof(ex_ex));
- expr->exp_nexpr++;
- ret = ex_match(list,0L);
- if (!ret) 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;
-}
-
-/* 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 ex_ex. It will also put the number of the nodes in *n. */
-ex_ex *ex_lex(struct expr *expr, long int *n) {
- ex_ex *list_arr;
- ex_ex *exptr;
- long non = 0; /* number of nodes */
- long maxnode = 0;
- list_arr = (ex_ex *)fts_malloc(sizeof (ex_ex) * MINODES);
- if (!list_arr) {post("ex_lex: no mem\n"); return 0;}
- exptr = list_arr;
- maxnode = MINODES;
- for (;;) {
- if (non >= maxnode) {
- maxnode += MINODES;
- list_arr = fts_realloc((void *)list_arr, sizeof (ex_ex) * maxnode);
- if (!list_arr) {post("ex_lex: no mem\n"); return 0;}
- exptr = &(list_arr)[non];
- }
- if (getoken(expr, exptr)) {fts_free(list_arr); return 0;}
- non++;
- if (!exptr->ex_type) break;
- exptr++;
- }
- *n = non;
- return list_arr;
-}
-
-/* this routine walks through the eptr and matches the parentheses and brackets, it also converts the function
- * names to a pointer to the describing structure of the specified function operator to match */
-ex_ex *ex_match(ex_ex *eptr, long int op) {
- int firstone = 1;
- ex_ex *ret;
- t_ex_func *fun;
- for (; ; 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 0;
- 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: case ET_LB:
- post("ex_match: unexpected type, %ld\n", eptr->ex_type);
- return 0;
- 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 0;
- }
- /* 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_ptr;
- eptr->ex_type = ET_TBL;
- if (ex_getsym(tmp, (t_symbol **)&(eptr->ex_ptr))) {
- post("expr: syntax error: problms with ex_getsym\n");
- return 0;
- }
- 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 0;}
- 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 0;
- }
- /* 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 0;}
- }
- continue;
- default:
- post("ex_match: bad type\n");
- return 0;
- }
- }
- /* NOTREACHED */
-}
-
-/* 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 segment that can qualify as an argument (counting commas). returns 0 on syntax error. */
-/* number of argument separated by comma */
-ex_ex *ex_parse(struct expr *x, ex_ex *iptr, ex_ex *optr, long int *argc) {
- ex_ex *eptr;
- ex_ex *lowpre = 0; /* pointer to the lowest precedence */
- ex_ex savex;
- long pre = HI_PRE;
- long count;
- if (!iptr) {post("ex_parse: input is null, iptr = 0x%lx\n", (long)iptr); return 0;}
- if (!iptr->ex_type) return 0;
- /* 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 0;}
- 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 0;}
- /* if this table is the only token, parse the table */
- if (!count && !((ex_ex *) eptr[1].ex_ptr)[1].ex_type) {
- savex = *((ex_ex *) eptr[1].ex_ptr);
- *((ex_ex *) eptr[1].ex_ptr) = nullex;
- *optr++ = *eptr;
- lowpre = ex_parse(x, &eptr[2], optr, (long *)0);
- *((ex_ex *) eptr[1].ex_ptr) = savex;
- return(lowpre);
- }
- eptr = (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 0;
- }
- }
- if (!eptr[1].ex_type) {post("expr: syntax error: missing operand\n"); ex_print(iptr); return 0;}
- 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 0;}
- /* if this function is the only token, parse it */
- if (!count &&
- !((ex_ex *) eptr[1].ex_ptr)[1].ex_type) {
- long ac=0;
- if (eptr[1].ex_ptr==(char *)&eptr[2]) {post("expr: syntax error: missing argument\n");ex_print(eptr);return 0;}
- savex = *((ex_ex *) eptr[1].ex_ptr);
- *((ex_ex *) eptr[1].ex_ptr) = nullex;
- *optr++ = *eptr;
- lowpre = ex_parse(x, &eptr[2], optr, &ac);
- if (!lowpre) return 0;
- 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 0;
- }
- *((ex_ex *) eptr[1].ex_ptr) = savex;
- return lowpre;
- }
- eptr = (ex_ex *) eptr[1].ex_ptr;
- break;
- case ET_LP: case ET_LB:
- if (!count && !((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 0;
- }
- savex = *((ex_ex *) eptr->ex_ptr);
- *((ex_ex *) eptr->ex_ptr) = nullex;
- lowpre = ex_parse(x, &eptr[1], optr, (long *)0);
- *((ex_ex *) eptr->ex_ptr) = savex;
- return lowpre;
- }
- eptr = (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 0;
- }
- if (pre == HI_PRE) {post("expr: syntax error: missing operation\n"); ex_print(iptr); return 0;}
- if (count < 2) {post("expr: syntax error: mission operand\n"); ex_print(iptr); return 0;}
- if (count == 2) {
- if (lowpre != iptr) {post("expr: ex_parse: unary operator should be first\n"); return 0;}
- if (!unary_op(lowpre->ex_op)) {post("expr: syntax error: not a uniary operator\n"); ex_print(iptr); return 0;}
- *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 0;}
- 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 divide zero check for a a non divide 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 = (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(((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(((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((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,(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;}
-
-/* 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;
- }
-}
-
-/* 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 */
-/* the expr object data pointer */
-/* the operation stack */
-/* the result pointer */
-/* the sample number processed for fexpr~ */
-ex_ex * ex_eval(struct expr *expr, ex_ex *eptr, ex_ex *optr, int idx) {
- 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 */
- 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 0;
- switch (eptr->ex_type) {
- case ET_INT:
- if (optr->ex_type == ET_VEC) ex_mkvector(optr->ex_vec, (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 0;
- }
- *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 0;
- }
- 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 0;
- }
- 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 0;
- }
- if (eptr->ex_int == -1) {
- post_error((fts_object_t *) expr, "expr: ex_eval: inlet number not set\n");
- return 0;
- }
- 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 {post("expr int. error, optr->ex_vec = %ld",(long)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 %ld\n", eptr->ex_type);
- return 0;
- }
- if (!eptr[1].ex_type) {post_error((fts_object_t *) expr, "expr: ex_eval: not enough nodes 1\n"); return 0;}
- 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 0;
- }
- 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%lx\n", eptr->ex_op); return 0;
- }
- /* 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 0; else return eptr;
-}
-
-/* evaluate a function: call ex_eval() on all the arguments so that all of them are terminal nodes. Then call the appropriate function */
-ex_ex *eval_func(struct expr *expr, ex_ex *eptr, ex_ex *optr, int idx) {
- int i;
- ex_ex args[MAX_ARGS];
- t_ex_func *f = (t_ex_func *)(eptr++)->ex_ptr;
- if (!f || !f->f_name) return 0;
- if (f->f_argc > MAX_ARGS) {post_error((fts_object_t *) expr, "expr: eval_func: asking too many arguments\n"); return 0;}
- 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;
-}
-
-/* evaluate the '=' operator, make sure the first operator is a legal left operator and call ex_eval on the right operator */
-/* the expr object data pointer */
-/* the operation stack */
-/* the result pointer */
-ex_ex *eval_store(struct expr *expr, ex_ex *eptr, ex_ex *optr, int idx) {
- 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;
-}
-
-/* evaluate a table operation */
-ex_ex *eval_tab(struct expr *expr, ex_ex *eptr, ex_ex *optr, int idx) {
- 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 %ld", 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) max_ex_tab(expr, (t_symbol *)tbl, &arg, optr);
- if (arg.ex_type == ET_VEC) fts_free(arg.ex_vec);
- return eptr;
-}
-
-/* evaluate a variable */
-ex_ex *eval_var(struct expr *expr, ex_ex *eptr, ex_ex *optr, int idx) {
- 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 %ld", 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) max_ex_var(expr, (t_symbol *)var, optr);
- return ++eptr;
-}
-
-/* evaluate the value of an indexed signal for fexpr~ */
-ex_ex * eval_sigidx(struct expr *expr, ex_ex *eptr, ex_ex *optr, int idx) {
- ex_ex arg;
- ex_ex *reteptr;
- int i = 0, j = 0;
- float fi = 0; /* index in float */
- 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 (%ld)", 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%ld[%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%ld[%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%ld 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 (%ld)", eptr->ex_type);
- }
- return reteptr;
-}
-
-/* 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(ex_ex *optr, /* The output value */
- int i, float rem_i, /* integer and fractinal part of index */
- int idx, /* index of current fexpr~ processing */
- int vsize, /* vector size */
- float *curvec, 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;
-}
-
-/* return 1 on syntax error otherwise 0 */
-int getoken(struct expr *expr, 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;
- 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 vector and $f1 or $i1 is illegal for fexpr~ */
- 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 '"': {
- 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;
-}
-
-/* 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;
- float pos = 0;
- float flt_val = 0;
- int base = 10;
- p = s;
- if (*p == '0' && (p[1] == 'x' || p[1] == 'X')) {base = 16; p += 2;}
- for (;;) {
- switch (*p) {
- case '.':
- if (flt || base != 10) {post("expr: syntax error: %s\n", s); return 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 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 0;}
- int_val *= base;
- int_val += (*p - 'A' + 10);
- break;
- default:
- if (flt) {*type = ET_FLT; *((float *)value) = flt_val;}
- else {*type = ET_INT; * value = int_val;}
- return p;
- }
- p++;
- }
-}
-
-/* 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 0;
-}
-
-/* print an expression array */
-void ex_print(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;
- case ET_LB: 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 ", (long)eptr->ex_ptr); break;
- case ET_VI: post("$v%lx ", (long)eptr->ex_vec); break;
- case ET_VEC: post("vec = %ld ", (long)eptr->ex_vec); break;
- case ET_YOM1: case ET_YO: post("$y%ld", eptr->ex_int + 1); break;
- case ET_XI: case ET_XI0: post("$x%ld", 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 NT
-void ABORT( void) {bug("expr");}
-#endif
diff --git a/desiredata/extra/expr~/vexp.h b/desiredata/extra/expr~/vexp.h
deleted file mode 100644
index a42bd620..00000000
--- a/desiredata/extra/expr~/vexp.h
+++ /dev/null
@@ -1,243 +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;
- 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 */
-};
-
-/* 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 */
- 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);
-
-#ifdef NT
-#pragma warning (disable: 4305 4244)
-
-#define abort ABORT
-void ABORT(void);
-#endif
diff --git a/desiredata/extra/expr~/vexp_fun.c b/desiredata/extra/expr~/vexp_fun.c
deleted file mode 100644
index fba49b18..00000000
--- a/desiredata/extra/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 (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 NT
-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 NT
- {"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 = (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 = (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 = (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 = (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++ = (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 = (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 = (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 = (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 = (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++ = (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++ = (float)func(leftfuncast *lp, \
- rightfuncast scalar); \
- lp++; \
- } \
- break; \
- case ET_FLT: \
- scalar = right->ex_flt; \
- j = e->exp_vsize; \
- while (j--) { \
- *op++ = (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++ = (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 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, \
- (float)(func (leftcast left->ex_int)), e->exp_vsize);\
- break; \
- } \
- if (fltret) { \
- optr->ex_type = ET_FLT; \
- optr->ex_flt = (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, \
- (float)(func (leftcast left->ex_flt)), e->exp_vsize);\
- break; \
- } \
- optr->ex_type = ET_FLT; \
- optr->ex_flt = (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++ = (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; \
- float *op; /* output pointer */ \
- float *lp, *rp; /* left and right vector pointers */ \
- 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; \
- float *op; /* output pointer */ \
- float *lp, *rp; /* left and right vector pointers */ \
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- float scalar;
- int j;
-
- left = argv++;
-
-#define toint(x) ((int)(x))
- FUNC_EVAL_UNARY(left, toint, (int), optr, 0);
- }
-
-#ifdef NT
-/* 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- float scalar;
- int j;
-
- left = argv++;
-
-
- FUNC_EVAL_UNARY(left, rint, (double), optr, 1);
-}
-
-/*
- * ex_tofloat -- convert to float
- */
-static void
-ex_tofloat(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- float scalar;
- int j;
-
- left = argv++;
-
-#define tofloat(x) ((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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- float scalar;
- int j;
-
- left = argv++;
-
- FUNC_EVAL_UNARY(left, tanh, (double), optr, 1);
-}
-
-
-#ifndef NT
-static void
-ex_asinh(t_expr *e, long argc, struct ex_ex *argv, struct ex_ex *optr)
-{
- struct ex_ex *left;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- 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;
- float *op; /* output pointer */
- float *lp, *rp; /* left and right vector pointers */
- float *cp; /* condition pointer */
- 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, (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, (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 NT
-/*
- * 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/desiredata/extra/expr~/vexp_if.c b/desiredata/extra/expr~/vexp_if.c
deleted file mode 100644
index 08dc55c3..00000000
--- a/desiredata/extra/expr~/vexp_if.c
+++ /dev/null
@@ -1,1223 +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, 0, 0, 0);
- 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 (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(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(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(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(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_float *vec;
-
- if (!s || !(garray = (t_garray *)pd_findbyclass(s, garray_class)) ||
- !garray_getfloatarray(garray, &size, &vec))
- {
- 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 = vec[indx];
-#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_getfloatarray(garray, &size, &vec)) { \
- optr->ex_type = ET_FLT; \
- optr->ex_int = 0; \
- error("no such table '%s'", sym->s_name); \
- 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_float *vec;
-
- 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, vec);
-
- 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_float *vec, 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, vec);
-
- for (indx = 0, sum = 0; indx < size; indx++)
- sum += vec[indx];
-
- 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_float *vec, 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, vec);
-
- 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 += vec[indx];
-
- 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