diff options
Diffstat (limited to 'desiredata/extra/expr~')
-rw-r--r-- | desiredata/extra/expr~/LICENSE.txt | 341 | ||||
-rw-r--r-- | desiredata/extra/expr~/README.txt | 97 | ||||
-rw-r--r-- | desiredata/extra/expr~/fts_to_pd.h | 41 | ||||
-rw-r--r-- | desiredata/extra/expr~/makefile | 168 | ||||
-rw-r--r-- | desiredata/extra/expr~/vexp.c | 1175 | ||||
-rw-r--r-- | desiredata/extra/expr~/vexp.h | 243 | ||||
-rw-r--r-- | desiredata/extra/expr~/vexp_fun.c | 1315 | ||||
-rw-r--r-- | desiredata/extra/expr~/vexp_if.c | 1223 |
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 |